Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sass-parser support for @function #2439

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ exports[`a configured variable toJSON 1`] = `
"id": "<input css _____>",
},
],
"name": "baz",
"raws": {},
"sassType": "configured-variable",
"source": <1:18-1:29 in 0>,
"variableName": "baz",
}
`;
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>,
}
`;
56 changes: 27 additions & 29 deletions pkg/sass-parser/lib/src/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('a configuration map', () => {
it('contains the variable', () => {
expect(node.size).toBe(1);
const variable = [...node.variables()][0];
expect(variable.variableName).toEqual('bar');
expect(variable.name).toEqual('bar');
expect(variable).toHaveStringExpression('expression', 'baz');
});
});
Expand All @@ -101,9 +101,7 @@ describe('a configuration map', () => {
'variables array',
() =>
new Configuration({
variables: [
{variableName: 'bar', expression: {text: 'baz', quotes: true}},
],
variables: [{name: 'bar', expression: {text: 'baz', quotes: true}}],
}),
);

Expand All @@ -127,7 +125,7 @@ describe('a configuration map', () => {
describe('add()', () => {
test('with a ConfiguredVariable', () => {
const variable = new ConfiguredVariable({
variableName: 'foo',
name: 'foo',
expression: {text: 'bar', quotes: true},
});
expect(node.add(variable)).toBe(node);
Expand All @@ -137,29 +135,29 @@ describe('a configuration map', () => {
});

test('with a ConfiguredVariableProps', () => {
node.add({variableName: 'foo', expression: {text: 'bar', quotes: true}});
node.add({name: 'foo', expression: {text: 'bar', quotes: true}});
expect(node.size).toBe(1);
const variable = node.get('foo');
expect(variable?.variableName).toBe('foo');
expect(variable?.name).toBe('foo');
expect(variable).toHaveStringExpression('expression', 'bar');
expect(variable?.parent).toBe(node);
});

test('overwrites on old variable', () => {
node.add({variableName: 'foo', expression: {text: 'old', quotes: true}});
node.add({name: 'foo', expression: {text: 'old', quotes: true}});
const old = node.get('foo');
expect(old?.parent).toBe(node);

node.add({variableName: 'foo', expression: {text: 'new', quotes: true}});
node.add({name: 'foo', expression: {text: 'new', quotes: true}});
expect(node.size).toBe(1);
expect(old?.parent).toBeUndefined();
expect(node.get('foo')).toHaveStringExpression('expression', 'new');
});
});

test('clear() removes all variables', () => {
node.add({variableName: 'foo', expression: {text: 'bar', quotes: true}});
node.add({variableName: 'baz', expression: {text: 'bang', quotes: true}});
node.add({name: 'foo', expression: {text: 'bar', quotes: true}});
node.add({name: 'baz', expression: {text: 'bang', quotes: true}});
const foo = node.get('foo');
const bar = node.get('bar');
node.clear();
Expand All @@ -172,8 +170,8 @@ describe('a configuration map', () => {

describe('delete()', () => {
beforeEach(() => {
node.add({variableName: 'foo', expression: {text: 'bar', quotes: true}});
node.add({variableName: 'baz', expression: {text: 'bang', quotes: true}});
node.add({name: 'foo', expression: {text: 'bar', quotes: true}});
node.add({name: 'baz', expression: {text: 'bang', quotes: true}});
});

test('removes a matching variable', () => {
Expand All @@ -192,12 +190,12 @@ describe('a configuration map', () => {

describe('get()', () => {
beforeEach(() => {
node.add({variableName: 'foo', expression: {text: 'bar', quotes: true}});
node.add({name: 'foo', expression: {text: 'bar', quotes: true}});
});

test('returns a variable in the configuration', () => {
const variable = node.get('foo');
expect(variable?.variableName).toBe('foo');
expect(variable?.name).toBe('foo');
expect(variable).toHaveStringExpression('expression', 'bar');
});

Expand All @@ -208,7 +206,7 @@ describe('a configuration map', () => {

describe('has()', () => {
beforeEach(() => {
node.add({variableName: 'foo', expression: {text: 'bar', quotes: true}});
node.add({name: 'foo', expression: {text: 'bar', quotes: true}});
});

test('returns true for a variable in the configuration', () =>
Expand All @@ -220,7 +218,7 @@ describe('a configuration map', () => {

describe('set()', () => {
beforeEach(() => {
node.add({variableName: 'foo', expression: {text: 'bar', quotes: true}});
node.add({name: 'foo', expression: {text: 'bar', quotes: true}});
});

describe('adds a new variable', () => {
Expand All @@ -233,7 +231,7 @@ describe('a configuration map', () => {
expect(node.size).toBe(2);
const variable = node.get('baz');
expect(variable?.parent).toBe(node);
expect(variable?.variableName).toBe('baz');
expect(variable?.name).toBe('baz');
expect(variable).toHaveStringExpression('expression', 'bang');
});
}
Expand Down Expand Up @@ -285,15 +283,15 @@ describe('a configuration map', () => {
}).toString(),
).toBe('($foo: "bar", $baz: "bang",)'));

it('with comma: true and afterValue', () =>
it('with comma: true and after', () =>
expect(
new Configuration({
raws: {comma: true},
variables: {
foo: {text: 'bar', quotes: true},
baz: {
expression: {text: 'bang', quotes: true},
raws: {afterValue: '/**/'},
raws: {after: '/**/'},
},
},
}).toString(),
Expand All @@ -310,28 +308,28 @@ describe('a configuration map', () => {
}).toString(),
).toBe('($foo: "bar", $baz: "bang"/**/)'));

it('with after and afterValue', () =>
it('with after and after', () =>
expect(
new Configuration({
raws: {after: '/**/'},
variables: {
foo: {text: 'bar', quotes: true},
baz: {
expression: {text: 'bang', quotes: true},
raws: {afterValue: ' '},
raws: {after: ' '},
},
},
}).toString(),
).toBe('($foo: "bar", $baz: "bang" /**/)'));

it('with afterValue and a guard', () =>
it('with after and a guard', () =>
expect(
new Configuration({
variables: {
foo: {text: 'bar', quotes: true},
baz: {
expression: {text: 'bang', quotes: true},
raws: {afterValue: '/**/'},
raws: {after: '/**/'},
guarded: true,
},
},
Expand Down Expand Up @@ -359,10 +357,10 @@ describe('a configuration map', () => {
it('variables', () => {
expect(clone.size).toBe(2);
const variables = [...clone.variables()];
expect(variables[0]?.variableName).toBe('foo');
expect(variables[0]?.name).toBe('foo');
expect(variables[0]?.parent).toBe(clone);
expect(variables[0]).toHaveStringExpression('expression', 'bar');
expect(variables[1]?.variableName).toBe('baz');
expect(variables[1]?.name).toBe('baz');
expect(variables[1]?.parent).toBe(clone);
expect(variables[1]).toHaveStringExpression('expression', 'bang');
});
Expand Down Expand Up @@ -399,7 +397,7 @@ describe('a configuration map', () => {
});
expect(clone.size).toBe(1);
const variables = [...clone.variables()];
expect(variables[0]?.variableName).toBe('zip');
expect(variables[0]?.name).toBe('zip');
expect(variables[0]?.parent).toBe(clone);
expect(variables[0]).toHaveStringExpression('expression', 'zap');
});
Expand All @@ -408,10 +406,10 @@ describe('a configuration map', () => {
const clone = original.clone({variables: undefined});
expect(clone.size).toBe(2);
const variables = [...clone.variables()];
expect(variables[0]?.variableName).toBe('foo');
expect(variables[0]?.name).toBe('foo');
expect(variables[0]?.parent).toBe(clone);
expect(variables[0]).toHaveStringExpression('expression', 'bar');
expect(variables[1]?.variableName).toBe('baz');
expect(variables[1]?.name).toBe('baz');
expect(variables[1]?.parent).toBe(clone);
expect(variables[1]).toHaveStringExpression('expression', 'bang');
});
Expand Down
9 changes: 6 additions & 3 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 Expand Up @@ -101,9 +104,9 @@ export class Configuration extends Node {
const realVariable =
'sassType' in variable ? variable : new ConfiguredVariable(variable);
realVariable.parent = this;
const old = this._variables.get(realVariable.variableName);
const old = this._variables.get(realVariable.name);
if (old) old.parent = undefined;
this._variables.set(realVariable.variableName, realVariable);
this._variables.set(realVariable.name, realVariable);
return this;
}

Expand Down Expand Up @@ -189,7 +192,7 @@ export class Configuration extends Node {
result += variable.raws.before ?? ' ';
}
result += variable.toString();
result += variable.raws.afterValue ?? '';
result += variable.raws.after ?? '';
}
return result + `${this.raws.comma ? ',' : ''}${this.raws.after ?? ''})`;
}
Expand Down
Loading