Skip to content

Commit b10ca79

Browse files
committed
Add sass-parser support for @function
1 parent ea47287 commit b10ca79

20 files changed

+2654
-73
lines changed

lib/src/js/parser.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ void _updateAstPrototypes() {
8888
'accept',
8989
(Expression self, ExpressionVisitor<Object?> visitor) =>
9090
self.accept(visitor));
91+
var arguments = ArgumentDeclaration([], bogusSpan);
92+
getJSClass(arguments)
93+
.defineGetter('arguments', (ArgumentDeclaration self) => self.arguments);
94+
var function = FunctionRule('a', arguments, [], bogusSpan);
95+
getJSClass(function)
96+
.defineGetter('arguments', (FunctionRule self) => self.arguments);
9197

9298
_addSupportsConditionToInterpolation();
9399

pkg/sass-parser/lib/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export {
2020
ConfiguredVariableProps,
2121
ConfiguredVariableRaws,
2222
} from './src/configured-variable';
23+
export {Container} from './src/container';
2324
export {AnyNode, Node, NodeProps, NodeType} from './src/node';
2425
export {RawWithValue} from './src/raw-with-value';
2526
export {
@@ -55,6 +56,20 @@ export {
5556
InterpolationRaws,
5657
NewNodeForInterpolation,
5758
} from './src/interpolation';
59+
export {
60+
NewParameters,
61+
ParameterListObjectProps,
62+
ParameterListProps,
63+
ParameterListRaws,
64+
ParameterList,
65+
} from './src/parameter-list';
66+
export {
67+
ParameterObjectProps,
68+
ParameterRaws,
69+
ParameterExpressionProps,
70+
ParameterProps,
71+
Parameter,
72+
} from './src/parameter';
5873
export {
5974
CssComment,
6075
CssCommentProps,
@@ -79,6 +94,11 @@ export {
7994
ForwardRuleProps,
8095
ForwardRuleRaws,
8196
} from './src/statement/forward-rule';
97+
export {
98+
FunctionRuleRaws,
99+
FunctionRuleProps,
100+
FunctionRule,
101+
} from './src/statement/function-rule';
82102
export {
83103
GenericAtRule,
84104
GenericAtRuleProps,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`a parameter list toJSON 1`] = `
4+
{
5+
"inputs": [
6+
{
7+
"css": "@function x($foo, $bar...) {}",
8+
"hasBOM": false,
9+
"id": "<input css _____>",
10+
},
11+
],
12+
"nodes": [
13+
<$foo>,
14+
],
15+
"raws": {},
16+
"restParameter": "bar",
17+
"sassType": "parameter-list",
18+
"source": <1:12-1:27 in 0>,
19+
}
20+
`;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`a parameter toJSON with a default 1`] = `
4+
{
5+
"defaultValue": <"qux">,
6+
"inputs": [
7+
{
8+
"css": "@function x($baz: "qux") {}",
9+
"hasBOM": false,
10+
"id": "<input css _____>",
11+
},
12+
],
13+
"name": "baz",
14+
"raws": {},
15+
"sassType": "parameter",
16+
"source": <1:13-1:24 in 0>,
17+
}
18+
`;
19+
20+
exports[`a parameter toJSON with no default 1`] = `
21+
{
22+
"inputs": [
23+
{
24+
"css": "@function x($baz) {}",
25+
"hasBOM": false,
26+
"id": "<input css _____>",
27+
},
28+
],
29+
"name": "baz",
30+
"raws": {},
31+
"sassType": "parameter",
32+
"source": <1:13-1:17 in 0>,
33+
}
34+
`;

pkg/sass-parser/lib/src/configuration.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ export interface ConfigurationProps {
4444
| Array<ConfiguredVariable | ConfiguredVariableProps>;
4545
}
4646

47+
// TODO: This should probably implement a similar interface to `ParameterList`
48+
// as well as or instead of its current map-like interface.
49+
4750
/**
4851
* A configuration map for a `@use` or `@forward` rule.
4952
*

pkg/sass-parser/lib/src/configured-variable.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ describe('a configured variable', () => {
298298
}).toString(),
299299
).toBe('$foo: "bar"'));
300300

301-
// raws.before is only used as part of a Configuration
301+
// raws.after is only used as part of a Configuration
302302
describe('ignores after', () => {
303303
it('with no guard', () =>
304304
expect(

pkg/sass-parser/lib/src/container.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright 2024 Google Inc. Use of this source code is governed by an
2+
// MIT-style license that can be found in the LICENSE file or at
3+
// https://opensource.org/licenses/MIT.
4+
5+
// Used in TypeDoc
6+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
7+
import type * as postcss from 'postcss';
8+
9+
// Used in TypeDoc
10+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
11+
import type {Interpolation} from './interpolation';
12+
13+
/**
14+
* A Sass AST container. While this tries to maintain the general shape of the
15+
* {@link postcss.Container} interface, it's more broadly used to contain
16+
* other node types (and even strings in the case of {@link Interpolation}.
17+
*
18+
* @typeParam Child - The type of child nodes that this container can contain.
19+
* @typeParam NewChild - The type of values that can be passed in to create one
20+
* or more new child nodes for this container.
21+
*/
22+
export interface Container<Child, NewChild> {
23+
/**
24+
* The nodes in this container.
25+
*
26+
* This shouldn't be modified directly; instead, the various methods defined
27+
* in {@link Container} should be used to modify it.
28+
*/
29+
get nodes(): ReadonlyArray<Child>;
30+
31+
/** Inserts new nodes at the end of this interpolation. */
32+
append(...nodes: NewChild[]): this;
33+
34+
/**
35+
* Iterates through {@link nodes}, calling `callback` for each child.
36+
*
37+
* Returning `false` in the callback will break iteration.
38+
*
39+
* Unlike a `for` loop or `Array#forEach`, this iterator is safe to use while
40+
* modifying the interpolation's children.
41+
*
42+
* @param callback The iterator callback, which is passed each child
43+
* @return Returns `false` if any call to `callback` returned false
44+
*/
45+
each(
46+
callback: (node: Child, index: number) => false | void,
47+
): false | undefined;
48+
49+
/**
50+
* Returns `true` if {@link condition} returns `true` for all of the
51+
* container’s children.
52+
*/
53+
every(
54+
condition: (
55+
node: Child,
56+
index: number,
57+
nodes: ReadonlyArray<Child>,
58+
) => boolean,
59+
): boolean;
60+
61+
/**
62+
* Returns the first index of {@link child} in {@link nodes}.
63+
*
64+
* If {@link child} is a number, returns it as-is.
65+
*/
66+
index(child: Child | number): number;
67+
68+
/**
69+
* Inserts {@link newNode} immediately after the first occurance of
70+
* {@link oldNode} in {@link nodes}.
71+
*
72+
* If {@link oldNode} is a number, inserts {@link newNode} immediately after
73+
* that index instead.
74+
*/
75+
insertAfter(oldNode: Child | number, newNode: NewChild): this;
76+
77+
/**
78+
* Inserts {@link newNode} immediately before the first occurance of
79+
* {@link oldNode} in {@link nodes}.
80+
*
81+
* If {@link oldNode} is a number, inserts {@link newNode} at that index
82+
* instead.
83+
*/
84+
insertBefore(oldNode: Child | number, newNode: NewChild): this;
85+
86+
/** Inserts {@link nodes} at the beginning of the container. */
87+
prepend(...nodes: NewChild[]): this;
88+
89+
/** Adds {@link child} to the end of this interpolation. */
90+
push(child: Child): this;
91+
92+
/**
93+
* Removes all {@link nodes} from this container and cleans their {@link
94+
* Node.parent} properties.
95+
*/
96+
removeAll(): this;
97+
98+
/**
99+
* Removes the first occurance of {@link child} from the container and cleans
100+
* the parent properties from the node and its children.
101+
*
102+
* If {@link child} is a number, removes the child at that index.
103+
*/
104+
removeChild(child: Child | number): this;
105+
106+
/**
107+
* Returns `true` if {@link condition} returns `true` for (at least) one of
108+
* the container’s children.
109+
*/
110+
some(
111+
condition: (
112+
node: Child,
113+
index: number,
114+
nodes: ReadonlyArray<Child>,
115+
) => boolean,
116+
): boolean;
117+
118+
/** The first node in {@link nodes}. */
119+
get first(): Child | undefined;
120+
121+
/**
122+
* The container’s last child.
123+
*
124+
* ```js
125+
* rule.last === rule.nodes[rule.nodes.length - 1]
126+
* ```
127+
*/
128+
get last(): Child | undefined;
129+
}

pkg/sass-parser/lib/src/interpolation.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ describe('an interpolation', () => {
430430

431431
it("removes a node's parents", () => {
432432
const string = node.nodes[1];
433-
node.removeAll();
433+
node.removeChild(1);
434434
expect(string).toHaveProperty('parent', undefined);
435435
});
436436

0 commit comments

Comments
 (0)