Skip to content

Commit

Permalink
Add sass-parser support for @function
Browse files Browse the repository at this point in the history
  • Loading branch information
nex3 committed Nov 20, 2024
1 parent ea47287 commit 3767890
Show file tree
Hide file tree
Showing 20 changed files with 2,658 additions and 73 deletions.
6 changes: 6 additions & 0 deletions lib/src/js/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ void _updateAstPrototypes() {
'accept',
(Expression self, ExpressionVisitor<Object?> visitor) =>
self.accept(visitor));
var arguments = ArgumentDeclaration([], bogusSpan);
getJSClass(arguments)
.defineGetter('arguments', (ArgumentDeclaration self) => self.arguments);
var function = FunctionRule('a', arguments, [], bogusSpan);
getJSClass(function)
.defineGetter('arguments', (FunctionRule self) => self.arguments);

_addSupportsConditionToInterpolation();

Expand Down
20 changes: 20 additions & 0 deletions pkg/sass-parser/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export {
ConfiguredVariableProps,
ConfiguredVariableRaws,
} from './src/configured-variable';
export {Container} from './src/container';
export {AnyNode, Node, NodeProps, NodeType} from './src/node';
export {RawWithValue} from './src/raw-with-value';
export {
Expand Down Expand Up @@ -55,6 +56,20 @@ export {
InterpolationRaws,
NewNodeForInterpolation,
} from './src/interpolation';
export {
NewParameters,
ParameterListObjectProps,
ParameterListProps,
ParameterListRaws,
ParameterList,
} from './src/parameter-list';
export {
ParameterObjectProps,
ParameterRaws,
ParameterExpressionProps,
ParameterProps,
Parameter,
} from './src/parameter';
export {
CssComment,
CssCommentProps,
Expand All @@ -79,6 +94,11 @@ export {
ForwardRuleProps,
ForwardRuleRaws,
} from './src/statement/forward-rule';
export {
FunctionRuleRaws,
FunctionRuleProps,
FunctionRule,
} from './src/statement/function-rule';
export {
GenericAtRule,
GenericAtRuleProps,
Expand Down
20 changes: 20 additions & 0 deletions pkg/sass-parser/lib/src/__snapshots__/parameter-list.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`a parameter list toJSON 1`] = `
{
"inputs": [
{
"css": "@function x($foo, $bar...) {}",
"hasBOM": false,
"id": "<input css _____>",
},
],
"nodes": [
<$foo>,
],
"raws": {},
"restParameter": "bar",
"sassType": "parameter-list",
"source": <1:12-1:27 in 0>,
}
`;
34 changes: 34 additions & 0 deletions pkg/sass-parser/lib/src/__snapshots__/parameter.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`a parameter toJSON with a default 1`] = `
{
"defaultValue": <"qux">,
"inputs": [
{
"css": "@function x($baz: "qux") {}",
"hasBOM": false,
"id": "<input css _____>",
},
],
"name": "baz",
"raws": {},
"sassType": "parameter",
"source": <1:13-1:24 in 0>,
}
`;

exports[`a parameter toJSON with no default 1`] = `
{
"inputs": [
{
"css": "@function x($baz) {}",
"hasBOM": false,
"id": "<input css _____>",
},
],
"name": "baz",
"raws": {},
"sassType": "parameter",
"source": <1:13-1:17 in 0>,
}
`;
3 changes: 3 additions & 0 deletions pkg/sass-parser/lib/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export interface ConfigurationProps {
| Array<ConfiguredVariable | ConfiguredVariableProps>;
}

// TODO: This should probably implement a similar interface to `ParameterList`
// as well as or instead of its current map-like interface.

/**
* A configuration map for a `@use` or `@forward` rule.
*
Expand Down
2 changes: 1 addition & 1 deletion pkg/sass-parser/lib/src/configured-variable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ describe('a configured variable', () => {
}).toString(),
).toBe('$foo: "bar"'));

// raws.before is only used as part of a Configuration
// raws.after is only used as part of a Configuration
describe('ignores after', () => {
it('with no guard', () =>
expect(
Expand Down
129 changes: 129 additions & 0 deletions pkg/sass-parser/lib/src/container.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2024 Google Inc. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

// Used in TypeDoc
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type * as postcss from 'postcss';

// Used in TypeDoc
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type {Interpolation} from './interpolation';

/**
* A Sass AST container. While this tries to maintain the general shape of the
* {@link postcss.Container} interface, it's more broadly used to contain
* other node types (and even strings in the case of {@link Interpolation}.
*
* @typeParam Child - The type of child nodes that this container can contain.
* @typeParam NewChild - The type of values that can be passed in to create one
* or more new child nodes for this container.
*/
export interface Container<Child, NewChild> {
/**
* The nodes in this container.
*
* This shouldn't be modified directly; instead, the various methods defined
* in {@link Container} should be used to modify it.
*/
get nodes(): ReadonlyArray<Child>;

/** Inserts new nodes at the end of this interpolation. */
append(...nodes: NewChild[]): this;

/**
* Iterates through {@link nodes}, calling `callback` for each child.
*
* Returning `false` in the callback will break iteration.
*
* Unlike a `for` loop or `Array#forEach`, this iterator is safe to use while
* modifying the interpolation's children.
*
* @param callback The iterator callback, which is passed each child
* @return Returns `false` if any call to `callback` returned false
*/
each(
callback: (node: Child, index: number) => false | void,
): false | undefined;

/**
* Returns `true` if {@link condition} returns `true` for all of the
* container’s children.
*/
every(
condition: (
node: Child,
index: number,
nodes: ReadonlyArray<Child>,
) => boolean,
): boolean;

/**
* Returns the first index of {@link child} in {@link nodes}.
*
* If {@link child} is a number, returns it as-is.
*/
index(child: Child | number): number;

/**
* Inserts {@link newNode} immediately after the first occurance of
* {@link oldNode} in {@link nodes}.
*
* If {@link oldNode} is a number, inserts {@link newNode} immediately after
* that index instead.
*/
insertAfter(oldNode: Child | number, newNode: NewChild): this;

/**
* Inserts {@link newNode} immediately before the first occurance of
* {@link oldNode} in {@link nodes}.
*
* If {@link oldNode} is a number, inserts {@link newNode} at that index
* instead.
*/
insertBefore(oldNode: Child | number, newNode: NewChild): this;

/** Inserts {@link nodes} at the beginning of the container. */
prepend(...nodes: NewChild[]): this;

/** Adds {@link child} to the end of this interpolation. */
push(child: Child): this;

/**
* Removes all {@link nodes} from this container and cleans their {@link
* Node.parent} properties.
*/
removeAll(): this;

/**
* Removes the first occurance of {@link child} from the container and cleans
* the parent properties from the node and its children.
*
* If {@link child} is a number, removes the child at that index.
*/
removeChild(child: Child | number): this;

/**
* Returns `true` if {@link condition} returns `true` for (at least) one of
* the container’s children.
*/
some(
condition: (
node: Child,
index: number,
nodes: ReadonlyArray<Child>,
) => boolean,
): boolean;

/** The first node in {@link nodes}. */
get first(): Child | undefined;

/**
* The container’s last child.
*
* ```js
* rule.last === rule.nodes[rule.nodes.length - 1]
* ```
*/
get last(): Child | undefined;
}
2 changes: 1 addition & 1 deletion pkg/sass-parser/lib/src/interpolation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ describe('an interpolation', () => {

it("removes a node's parents", () => {
const string = node.nodes[1];
node.removeAll();
node.removeChild(1);
expect(string).toHaveProperty('parent', undefined);
});

Expand Down
Loading

0 comments on commit 3767890

Please sign in to comment.