@@ -11,29 +11,6 @@ import 'package:collection/collection.dart';
1111
1212import 'util/dart_type_utilities.dart' ;
1313
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-
3714class EnumLikeClassDescription {
3815 final Map <DartObject , Set <FieldElement >> _enumConstants;
3916 EnumLikeClassDescription (this ._enumConstants);
@@ -42,6 +19,53 @@ class EnumLikeClassDescription {
4219 Map <DartObject , Set <FieldElement >> get enumConstants => {..._enumConstants};
4320}
4421
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+
4569extension ClassElementExtension on ClassElement {
4670 /// Returns an [EnumLikeClassDescription] for this if the latter is a valid
4771 /// "enum-like" class.
@@ -120,12 +144,17 @@ extension ClassElementExtension on ClassElement {
120144 return false ;
121145 }
122146
147+ bool get isEnumLikeClass => asEnumLikeClass != null ;
148+
123149 /// Returns whether this class is exactly [otherName] declared in
124150 /// [otherLibrary] .
125151 bool isClass (String otherName, String otherLibrary) =>
126152 name == otherName && library.name == otherLibrary;
153+ }
127154
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);
129158}
130159
131160extension ConstructorElementExtension on ConstructorElement {
@@ -141,80 +170,6 @@ extension ConstructorElementExtension on ConstructorElement {
141170 name == constructorName;
142171}
143172
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-
218173extension DartTypeExtension on DartType ? {
219174 bool extendsClass (String ? className, String library) {
220175 var self = this ;
@@ -269,10 +224,40 @@ extension DartTypeExtension on DartType? {
269224 _extendsClass (type.superclass, seenElements, className, library));
270225}
271226
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+
272250extension ExpressionExtension on Expression ? {
273251 bool get isNullLiteral => this ? .unParenthesized is NullLiteral ;
274252}
275253
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+
276261extension InterfaceTypeExtension on InterfaceType {
277262 /// Returns the collection of all interfaces that this type implements,
278263 /// including itself.
@@ -336,7 +321,7 @@ extension MethodDeclarationExtension on MethodDeclaration {
336321 return null ;
337322 }
338323 var parent = declaredElement.enclosingElement3;
339- if (parent is ClassElement ) {
324+ if (parent is InterfaceElement ) {
340325 return parent.lookUpGetter (name2.lexeme, declaredElement.library);
341326 }
342327 if (parent is ExtensionElement ) {
@@ -351,7 +336,7 @@ extension MethodDeclarationExtension on MethodDeclaration {
351336 return null ;
352337 }
353338 var parent = declaredElement.enclosingElement3;
354- if (parent is ClassElement ) {
339+ if (parent is InterfaceElement ) {
355340 return parent.lookUpInheritedConcreteGetter (
356341 name2.lexeme, declaredElement.library);
357342 }
@@ -363,7 +348,7 @@ extension MethodDeclarationExtension on MethodDeclaration {
363348 var declaredElement = declaredElement2;
364349 if (declaredElement != null ) {
365350 var parent = declaredElement.enclosingElement3;
366- if (parent is ClassElement ) {
351+ if (parent is InterfaceElement ) {
367352 return parent.lookUpInheritedConcreteMethod (
368353 name2.lexeme, declaredElement.library);
369354 }
@@ -376,7 +361,7 @@ extension MethodDeclarationExtension on MethodDeclaration {
376361 var declaredElement = declaredElement2;
377362 if (declaredElement != null ) {
378363 var parent = declaredElement.enclosingElement3;
379- if (parent is ClassElement ) {
364+ if (parent is InterfaceElement ) {
380365 return parent.lookUpInheritedConcreteSetter (
381366 name2.lexeme, declaredElement.library);
382367 }
@@ -389,11 +374,26 @@ extension MethodDeclarationExtension on MethodDeclaration {
389374 var declaredElement = declaredElement2;
390375 if (declaredElement != null ) {
391376 var parent = declaredElement.enclosingElement3;
392- if (parent is ClassElement ) {
377+ if (parent is InterfaceElement ) {
393378 return parent.lookUpInheritedMethod (
394379 name2.lexeme, declaredElement.library);
395380 }
396381 }
397382 return null ;
398383 }
399384}
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