@@ -11,29 +11,6 @@ import 'package:collection/collection.dart';
11
11
12
12
import 'util/dart_type_utilities.dart' ;
13
13
14
- extension ElementExtension on Element {
15
- Element get canonicalElement {
16
- var self = this ;
17
- if (self is PropertyAccessorElement ) {
18
- var variable = self.variable;
19
- if (variable is FieldMember ) {
20
- // A field element defined in a parameterized type where the values of
21
- // the type parameters are known.
22
- //
23
- // This concept should be invisible when comparing FieldElements, but a
24
- // bug in the analyzer causes FieldElements to not evaluate as
25
- // equivalent to equivalent FieldMembers. See
26
- // https://github.com/dart-lang/sdk/issues/35343.
27
- return variable.declaration;
28
- } else {
29
- return variable;
30
- }
31
- } else {
32
- return self;
33
- }
34
- }
35
- }
36
-
37
14
class EnumLikeClassDescription {
38
15
final Map <DartObject , Set <FieldElement >> _enumConstants;
39
16
EnumLikeClassDescription (this ._enumConstants);
@@ -42,6 +19,53 @@ class EnumLikeClassDescription {
42
19
Map <DartObject , Set <FieldElement >> get enumConstants => {..._enumConstants};
43
20
}
44
21
22
+ extension AstNodeExtension on AstNode {
23
+ Iterable <AstNode > get childNodes => childEntities.whereType <AstNode >();
24
+
25
+ /// Builds the list resulting from traversing the node in DFS and does not
26
+ /// include the node itself.
27
+ ///
28
+ /// It excludes the nodes for which the [excludeCriteria] returns true. If
29
+ /// [excludeCriteria] is not provided, all nodes are included.
30
+ Iterable <AstNode > traverseNodesInDFS ({AstNodePredicate ? excludeCriteria}) {
31
+ var nodes = < AstNode > {};
32
+ var nodesToVisit = List .of (childNodes);
33
+ if (excludeCriteria == null ) {
34
+ while (nodesToVisit.isNotEmpty) {
35
+ var node = nodesToVisit.removeAt (0 );
36
+ nodes.add (node);
37
+ nodesToVisit.insertAll (0 , node.childNodes);
38
+ }
39
+ } else {
40
+ while (nodesToVisit.isNotEmpty) {
41
+ var node = nodesToVisit.removeAt (0 );
42
+ if (excludeCriteria (node)) continue ;
43
+ nodes.add (node);
44
+ nodesToVisit.insertAll (0 , node.childNodes);
45
+ }
46
+ }
47
+
48
+ return nodes;
49
+ }
50
+ }
51
+
52
+ extension BlockExtension on Block {
53
+ /// Returns the last statement of this block, or `null` if this is empty.
54
+ ///
55
+ /// If the last immediate statement of this block is a [Block] , recurses into
56
+ /// it to find the last statement.
57
+ Statement ? get lastStatement {
58
+ if (statements.isEmpty) {
59
+ return null ;
60
+ }
61
+ var lastStatement = statements.last;
62
+ if (lastStatement is Block ) {
63
+ return lastStatement.lastStatement;
64
+ }
65
+ return lastStatement;
66
+ }
67
+ }
68
+
45
69
extension ClassElementExtension on ClassElement {
46
70
/// Returns an [EnumLikeClassDescription] for this if the latter is a valid
47
71
/// "enum-like" class.
@@ -120,12 +144,17 @@ extension ClassElementExtension on ClassElement {
120
144
return false ;
121
145
}
122
146
147
+ bool get isEnumLikeClass => asEnumLikeClass != null ;
148
+
123
149
/// Returns whether this class is exactly [otherName] declared in
124
150
/// [otherLibrary] .
125
151
bool isClass (String otherName, String otherLibrary) =>
126
152
name == otherName && library.name == otherLibrary;
153
+ }
127
154
128
- bool get isEnumLikeClass => asEnumLikeClass != null ;
155
+ extension ClassMemberListExtension on List <ClassMember > {
156
+ MethodDeclaration ? getMethod (String name) => whereType <MethodDeclaration >()
157
+ .firstWhereOrNull ((node) => node.name2.lexeme == name);
129
158
}
130
159
131
160
extension ConstructorElementExtension on ConstructorElement {
@@ -141,80 +170,6 @@ extension ConstructorElementExtension on ConstructorElement {
141
170
name == constructorName;
142
171
}
143
172
144
- extension InterfaceElementExtension on InterfaceElement {
145
- /// Returns whether this element is exactly [otherName] declared in
146
- /// [otherLibrary] .
147
- bool isClass (String otherName, String otherLibrary) =>
148
- name == otherName && library.name == otherLibrary;
149
- }
150
-
151
- extension NullableAstNodeExtension on AstNode ? {
152
- Element ? get canonicalElement {
153
- var self = this ;
154
- if (self is Expression ) {
155
- var node = self.unParenthesized;
156
- if (node is Identifier ) {
157
- return node.staticElement? .canonicalElement;
158
- } else if (node is PropertyAccess ) {
159
- return node.propertyName.staticElement? .canonicalElement;
160
- }
161
- }
162
- return null ;
163
- }
164
- }
165
-
166
- extension AstNodeExtension on AstNode {
167
- /// Builds the list resulting from traversing the node in DFS and does not
168
- /// include the node itself.
169
- ///
170
- /// It excludes the nodes for which the [excludeCriteria] returns true. If
171
- /// [excludeCriteria] is not provided, all nodes are included.
172
- Iterable <AstNode > traverseNodesInDFS ({AstNodePredicate ? excludeCriteria}) {
173
- var nodes = < AstNode > {};
174
- var nodesToVisit = List .of (childNodes);
175
- if (excludeCriteria == null ) {
176
- while (nodesToVisit.isNotEmpty) {
177
- var node = nodesToVisit.removeAt (0 );
178
- nodes.add (node);
179
- nodesToVisit.insertAll (0 , node.childNodes);
180
- }
181
- } else {
182
- while (nodesToVisit.isNotEmpty) {
183
- var node = nodesToVisit.removeAt (0 );
184
- if (excludeCriteria (node)) continue ;
185
- nodes.add (node);
186
- nodesToVisit.insertAll (0 , node.childNodes);
187
- }
188
- }
189
-
190
- return nodes;
191
- }
192
-
193
- Iterable <AstNode > get childNodes => childEntities.whereType <AstNode >();
194
- }
195
-
196
- extension BlockExtension on Block {
197
- /// Returns the last statement of this block, or `null` if this is empty.
198
- ///
199
- /// If the last immediate statement of this block is a [Block] , recurses into
200
- /// it to find the last statement.
201
- Statement ? get lastStatement {
202
- if (statements.isEmpty) {
203
- return null ;
204
- }
205
- var lastStatement = statements.last;
206
- if (lastStatement is Block ) {
207
- return lastStatement.lastStatement;
208
- }
209
- return lastStatement;
210
- }
211
- }
212
-
213
- extension ClassMemberListExtension on List <ClassMember > {
214
- MethodDeclaration ? getMethod (String name) => whereType <MethodDeclaration >()
215
- .firstWhereOrNull ((node) => node.name2.lexeme == name);
216
- }
217
-
218
173
extension DartTypeExtension on DartType ? {
219
174
bool extendsClass (String ? className, String library) {
220
175
var self = this ;
@@ -269,10 +224,40 @@ extension DartTypeExtension on DartType? {
269
224
_extendsClass (type.superclass, seenElements, className, library));
270
225
}
271
226
227
+ extension ElementExtension on Element {
228
+ Element get canonicalElement {
229
+ var self = this ;
230
+ if (self is PropertyAccessorElement ) {
231
+ var variable = self.variable;
232
+ if (variable is FieldMember ) {
233
+ // A field element defined in a parameterized type where the values of
234
+ // the type parameters are known.
235
+ //
236
+ // This concept should be invisible when comparing FieldElements, but a
237
+ // bug in the analyzer causes FieldElements to not evaluate as
238
+ // equivalent to equivalent FieldMembers. See
239
+ // https://github.com/dart-lang/sdk/issues/35343.
240
+ return variable.declaration;
241
+ } else {
242
+ return variable;
243
+ }
244
+ } else {
245
+ return self;
246
+ }
247
+ }
248
+ }
249
+
272
250
extension ExpressionExtension on Expression ? {
273
251
bool get isNullLiteral => this ? .unParenthesized is NullLiteral ;
274
252
}
275
253
254
+ extension InterfaceElementExtension on InterfaceElement {
255
+ /// Returns whether this element is exactly [otherName] declared in
256
+ /// [otherLibrary] .
257
+ bool isClass (String otherName, String otherLibrary) =>
258
+ name == otherName && library.name == otherLibrary;
259
+ }
260
+
276
261
extension InterfaceTypeExtension on InterfaceType {
277
262
/// Returns the collection of all interfaces that this type implements,
278
263
/// including itself.
@@ -336,7 +321,7 @@ extension MethodDeclarationExtension on MethodDeclaration {
336
321
return null ;
337
322
}
338
323
var parent = declaredElement.enclosingElement3;
339
- if (parent is ClassElement ) {
324
+ if (parent is InterfaceElement ) {
340
325
return parent.lookUpGetter (name2.lexeme, declaredElement.library);
341
326
}
342
327
if (parent is ExtensionElement ) {
@@ -351,7 +336,7 @@ extension MethodDeclarationExtension on MethodDeclaration {
351
336
return null ;
352
337
}
353
338
var parent = declaredElement.enclosingElement3;
354
- if (parent is ClassElement ) {
339
+ if (parent is InterfaceElement ) {
355
340
return parent.lookUpInheritedConcreteGetter (
356
341
name2.lexeme, declaredElement.library);
357
342
}
@@ -363,7 +348,7 @@ extension MethodDeclarationExtension on MethodDeclaration {
363
348
var declaredElement = declaredElement2;
364
349
if (declaredElement != null ) {
365
350
var parent = declaredElement.enclosingElement3;
366
- if (parent is ClassElement ) {
351
+ if (parent is InterfaceElement ) {
367
352
return parent.lookUpInheritedConcreteMethod (
368
353
name2.lexeme, declaredElement.library);
369
354
}
@@ -376,7 +361,7 @@ extension MethodDeclarationExtension on MethodDeclaration {
376
361
var declaredElement = declaredElement2;
377
362
if (declaredElement != null ) {
378
363
var parent = declaredElement.enclosingElement3;
379
- if (parent is ClassElement ) {
364
+ if (parent is InterfaceElement ) {
380
365
return parent.lookUpInheritedConcreteSetter (
381
366
name2.lexeme, declaredElement.library);
382
367
}
@@ -389,11 +374,26 @@ extension MethodDeclarationExtension on MethodDeclaration {
389
374
var declaredElement = declaredElement2;
390
375
if (declaredElement != null ) {
391
376
var parent = declaredElement.enclosingElement3;
392
- if (parent is ClassElement ) {
377
+ if (parent is InterfaceElement ) {
393
378
return parent.lookUpInheritedMethod (
394
379
name2.lexeme, declaredElement.library);
395
380
}
396
381
}
397
382
return null ;
398
383
}
399
384
}
385
+
386
+ extension NullableAstNodeExtension on AstNode ? {
387
+ Element ? get canonicalElement {
388
+ var self = this ;
389
+ if (self is Expression ) {
390
+ var node = self.unParenthesized;
391
+ if (node is Identifier ) {
392
+ return node.staticElement? .canonicalElement;
393
+ } else if (node is PropertyAccess ) {
394
+ return node.propertyName.staticElement? .canonicalElement;
395
+ }
396
+ }
397
+ return null ;
398
+ }
399
+ }
0 commit comments