Skip to content

Commit 7d5ef8d

Browse files
committed
Add ArgumentList.namedSpans
This makes it easier for the migrator to handle functions with named arguments.
1 parent bbba40c commit 7d5ef8d

File tree

9 files changed

+32
-10
lines changed

9 files changed

+32
-10
lines changed

lib/src/ast/sass/argument_list.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5+
import 'package:sass/src/utils.dart';
56
import 'package:source_span/source_span.dart';
67

78
import '../../value/list.dart';
@@ -20,6 +21,11 @@ final class ArgumentList implements SassNode {
2021
/// The arguments passed by name.
2122
final Map<String, Expression> named;
2223

24+
/// The spans for the arguments passed by name, including their argument names.
25+
///
26+
/// This always has the same keys as [named] in the same order.
27+
final Map<String, FileSpan> namedSpans;
28+
2329
/// The first rest argument (as in `$args...`).
2430
final Expression? rest;
2531

@@ -34,18 +40,22 @@ final class ArgumentList implements SassNode {
3440
ArgumentList(
3541
Iterable<Expression> positional,
3642
Map<String, Expression> named,
43+
Map<String, FileSpan> namedSpans,
3744
this.span, {
3845
this.rest,
3946
this.keywordRest,
4047
}) : positional = List.unmodifiable(positional),
41-
named = Map.unmodifiable(named) {
48+
named = Map.unmodifiable(named),
49+
namedSpans = Map.unmodifiable(namedSpans) {
4250
assert(rest != null || keywordRest == null);
51+
assert(iterableEquals(named.keys, namedSpans.keys));
4352
}
4453

4554
/// Creates an invocation that passes no arguments.
4655
ArgumentList.empty(this.span)
4756
: positional = const [],
4857
named = const {},
58+
namedSpans = const {},
4959
rest = null,
5060
keywordRest = null;
5161

lib/src/js/parser.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ void _updateAstPrototypes() {
147147
IfConditionExpressionVisitor<Object?> visitor) =>
148148
self.accept(visitor),
149149
);
150-
var arguments = ArgumentList([], {}, bogusSpan);
150+
var arguments = ArgumentList(const [], const {}, const {}, bogusSpan);
151151
getJSClass(
152152
IncludeRule('a', arguments, bogusSpan),
153153
).defineGetter('arguments', (IncludeRule self) => self.arguments);

lib/src/parse/css.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class CssParser extends ScssParser {
203203

204204
return FunctionExpression(
205205
plain,
206-
ArgumentList(arguments, const {}, spanFrom(beforeArguments)),
206+
ArgumentList(arguments, const {}, const {}, spanFrom(beforeArguments)),
207207
spanFrom(start),
208208
);
209209
}

lib/src/parse/stylesheet.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,7 @@ abstract class StylesheetParser extends Parser {
18621862

18631863
var positional = <Expression>[];
18641864
var named = <String, Expression>{};
1865+
var namedSpans = <String, FileSpan>{};
18651866
Expression? rest;
18661867
Expression? keywordRest;
18671868
var emittedRestDeprecation = false;
@@ -1874,7 +1875,9 @@ abstract class StylesheetParser extends Parser {
18741875
if (named.containsKey(expression.name)) {
18751876
error("Duplicate argument.", expression.span);
18761877
}
1877-
named[expression.name] = expressionUntilComma(singleEquals: !mixin);
1878+
var value = expressionUntilComma(singleEquals: !mixin);
1879+
named[expression.name] = value;
1880+
namedSpans[expression.name] = expression.span.expand(value.span);
18781881

18791882
if (rest != null && !emittedRestDeprecation) {
18801883
emittedRestDeprecation = true;
@@ -1935,6 +1938,7 @@ abstract class StylesheetParser extends Parser {
19351938
return ArgumentList(
19361939
positional,
19371940
named,
1941+
namedSpans,
19381942
spanFrom(start),
19391943
rest: rest,
19401944
keywordRest: keywordRest,

lib/src/visitor/async_evaluate.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,8 +517,9 @@ final class _EvaluateVisitor
517517

518518
var callableNode = _callableNode!;
519519
var invocation = ArgumentList(
520-
[],
521-
{},
520+
const [],
521+
const {},
522+
const {},
522523
callableNode.span,
523524
rest: ValueExpression(args, callableNode.span),
524525
keywordRest: args.keywords.isEmpty
@@ -625,6 +626,7 @@ final class _EvaluateVisitor
625626
var invocation = ArgumentList(
626627
const [],
627628
const {},
629+
const {},
628630
callableNode.span,
629631
rest: ValueExpression(args, callableNode.span),
630632
);

lib/src/visitor/evaluate.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_evaluate.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: 0f55a90c029d7b2041baf51afba2694bc1aa115d
8+
// Checksum: aa53924147f65640b94768e22bb339b0d5c5714a
99
//
1010
// ignore_for_file: unused_import
1111

@@ -525,8 +525,9 @@ final class _EvaluateVisitor
525525

526526
var callableNode = _callableNode!;
527527
var invocation = ArgumentList(
528-
[],
529-
{},
528+
const [],
529+
const {},
530+
const {},
530531
callableNode.span,
531532
rest: ValueExpression(args, callableNode.span),
532533
keywordRest: args.keywords.isEmpty
@@ -633,6 +634,7 @@ final class _EvaluateVisitor
633634
var invocation = ArgumentList(
634635
const [],
635636
const {},
637+
const {},
636638
callableNode.span,
637639
rest: ValueExpression(args, callableNode.span),
638640
);

lib/src/visitor/expression_to_calc.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ FunctionExpression expressionToCalc(Expression expression) =>
1616
ArgumentList(
1717
[expression.accept(const _MakeExpressionCalculationSafe())],
1818
const {},
19+
const {},
1920
expression.span,
2021
),
2122
expression.span,
@@ -34,7 +35,7 @@ class _MakeExpressionCalculationSafe with ReplaceExpressionVisitor {
3435
// to work around it by wrapping the call in a Sass function.
3536
? FunctionExpression(
3637
'max',
37-
ArgumentList([node], const {}, node.span),
38+
ArgumentList([node], const {}, const {}, node.span),
3839
node.span,
3940
namespace: 'math',
4041
)

lib/src/visitor/replace_expression.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ mixin ReplaceExpressionVisitor
134134
for (var (name, value) in invocation.named.pairs)
135135
name: value.accept(this),
136136
},
137+
invocation.namedSpans,
137138
invocation.span,
138139
rest: invocation.rest?.accept(this),
139140
keywordRest: invocation.keywordRest?.accept(this),

pkg/sass_api/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* Add an `ExpressionVisitable` interface for anything visitable by an
1414
`ExpressionVisitor` (currently `Expression` and `IfConditionExpression`).
1515

16+
* Add a `ArgumentList.namedSpans` field.
17+
1618
## 16.0.3
1719

1820
* Add the missing members of `RecursiveAstVisitor`.

0 commit comments

Comments
 (0)