2
2
// MIT-style license that can be found in the LICENSE file or at
3
3
// https://opensource.org/licenses/MIT.
4
4
5
+ import 'package:meta/meta.dart' ;
6
+
7
+ import '../util/nullable.dart' ;
5
8
import '../ast/sass.dart' ;
6
9
import 'interface/expression.dart' ;
7
10
import 'recursive_statement.dart' ;
@@ -10,13 +13,134 @@ import 'recursive_statement.dart';
10
13
/// AST.
11
14
///
12
15
/// This extends [RecursiveStatementVisitor] to traverse each expression in
13
- /// addition to each statement.
16
+ /// addition to each statement. It adds even more protected methods:
17
+ ///
18
+ /// * [visitArgumentInvocation]
19
+ /// * [visitSupportsCondition]
20
+ /// * [visitInterpolation]
14
21
///
15
22
/// {@category Visitor}
16
23
abstract class RecursiveAstVisitor extends RecursiveStatementVisitor
17
24
implements ExpressionVisitor <void > {
18
25
const RecursiveAstVisitor ();
19
26
27
+ void visitAtRootRule (AtRootRule node) {
28
+ super .visitAtRootRule (node);
29
+ }
30
+
31
+ void visitAtRule (AtRule node) {
32
+ visitInterpolation (node.name);
33
+ node.value.andThen (visitInterpolation);
34
+ super .visitAtRule (node);
35
+ }
36
+
37
+ void visitContentRule (ContentRule node) {
38
+ visitArgumentInvocation (node.arguments);
39
+ }
40
+
41
+ void visitDebugRule (DebugRule node) {
42
+ visitExpression (node.expression);
43
+ }
44
+
45
+ void visitDeclaration (Declaration node) {
46
+ visitInterpolation (node.name);
47
+ node.value.andThen (visitExpression);
48
+ super .visitDeclaration (node);
49
+ }
50
+
51
+ void visitEachRule (EachRule node) {
52
+ visitExpression (node.list);
53
+ super .visitEachRule (node);
54
+ }
55
+
56
+ void visitErrorRule (ErrorRule node) {
57
+ visitExpression (node.expression);
58
+ }
59
+
60
+ void visitExtendRule (ExtendRule node) {
61
+ visitInterpolation (node.selector);
62
+ }
63
+
64
+ void visitForRule (ForRule node) {
65
+ visitExpression (node.from);
66
+ visitExpression (node.to);
67
+ super .visitForRule (node);
68
+ }
69
+
70
+ void visitIfRule (IfRule node) {
71
+ for (var clause in node.clauses) {
72
+ visitExpression (clause.expression);
73
+ for (var child in clause.children) {
74
+ child.accept (this );
75
+ }
76
+ }
77
+
78
+ node.lastClause.andThen ((lastClause) {
79
+ for (var child in lastClause.children) {
80
+ child.accept (this );
81
+ }
82
+ });
83
+ }
84
+
85
+ void visitImportRule (ImportRule node) {
86
+ for (var import in node.imports) {
87
+ if (import is StaticImport ) {
88
+ visitInterpolation (import.url);
89
+ import.supports.andThen (visitSupportsCondition);
90
+ import.media.andThen (visitInterpolation);
91
+ }
92
+ }
93
+ }
94
+
95
+ void visitIncludeRule (IncludeRule node) {
96
+ visitArgumentInvocation (node.arguments);
97
+ super .visitIncludeRule (node);
98
+ }
99
+
100
+ void visitLoudComment (LoudComment node) {
101
+ visitInterpolation (node.text);
102
+ }
103
+
104
+ void visitMediaRule (MediaRule node) {
105
+ visitInterpolation (node.query);
106
+ super .visitMediaRule (node);
107
+ }
108
+
109
+ void visitMixinRule (MixinRule node) => visitCallableDeclaration (node);
110
+
111
+ void visitReturnRule (ReturnRule node) {
112
+ visitExpression (node.expression);
113
+ }
114
+
115
+ void visitStyleRule (StyleRule node) {
116
+ visitInterpolation (node.selector);
117
+ super .visitStyleRule (node);
118
+ }
119
+
120
+ void visitSupportsRule (SupportsRule node) {
121
+ visitSupportsCondition (node.condition);
122
+ super .visitSupportsRule (node);
123
+ }
124
+
125
+ void visitUseRule (UseRule node) {
126
+ for (var variable in node.configuration) {
127
+ variable.expression.accept (this );
128
+ }
129
+ }
130
+
131
+ void visitVariableDeclaration (VariableDeclaration node) {
132
+ visitExpression (node.expression);
133
+ }
134
+
135
+ void visitWarnRule (WarnRule node) {
136
+ visitExpression (node.expression);
137
+ }
138
+
139
+ void visitWhileRule (WhileRule node) {
140
+ visitExpression (node.condition);
141
+ super .visitWhileRule (node);
142
+ }
143
+
20
144
void visitExpression (Expression expression) {
21
145
expression.accept (this );
22
146
}
@@ -76,13 +200,61 @@ abstract class RecursiveAstVisitor extends RecursiveStatementVisitor
76
200
node.operand.accept (this );
77
201
}
78
202
79
- void visitUseRule (UseRule node) {
80
- for (var variable in node.configuration) {
81
- variable.expression.accept (this );
203
+ void visitValueExpression (ValueExpression node) {}
204
+
205
+ void visitVariableExpression (VariableExpression node) {}
206
+
207
+ @protected
208
+ void visitCallableDeclaration (CallableDeclaration node) {
209
+ for (var argument in node.arguments.arguments) {
210
+ argument.defaultValue.andThen (visitExpression);
82
211
}
212
+ super .visitCallableDeclaration (node);
83
213
}
84
214
85
- void visitValueExpression (ValueExpression node) {}
215
+ /// Visits each expression in an [invocation] .
216
+ ///
217
+ /// The default implementation of the visit methods calls this to visit any
218
+ /// argument invocation in a statement.
219
+ @protected
220
+ void visitArgumentInvocation (ArgumentInvocation invocation) {
221
+ for (var expression in invocation.positional) {
222
+ visitExpression (expression);
223
+ }
224
+ for (var expression in invocation.named.values) {
225
+ visitExpression (expression);
226
+ }
227
+ invocation.rest.andThen (visitExpression);
228
+ invocation.keywordRest.andThen (visitExpression);
229
+ }
86
230
87
- void visitVariableExpression (VariableExpression node) {}
231
+ /// Visits each expression in [condition] .
232
+ ///
233
+ /// The default implementation of the visit methods call this to visit any
234
+ /// [SupportsCondition] they encounter.
235
+ @protected
236
+ void visitSupportsCondition (SupportsCondition condition) {
237
+ if (condition is SupportsOperation ) {
238
+ visitSupportsCondition (condition.left);
239
+ visitSupportsCondition (condition.right);
240
+ } else if (condition is SupportsNegation ) {
241
+ visitSupportsCondition (condition.condition);
242
+ } else if (condition is SupportsInterpolation ) {
243
+ visitExpression (condition.expression);
244
+ } else if (condition is SupportsDeclaration ) {
245
+ visitExpression (condition.name);
246
+ visitExpression (condition.value);
247
+ }
248
+ }
249
+
250
+ /// Visits each expression in an [interpolation] .
251
+ ///
252
+ /// The default implementation of the visit methods call this to visit any
253
+ /// interpolation in a statement.
254
+ @protected
255
+ void visitInterpolation (Interpolation interpolation) {
256
+ for (var node in interpolation.contents) {
257
+ if (node is Expression ) visitExpression (node);
258
+ }
259
+ }
88
260
}
0 commit comments