@@ -7,23 +7,25 @@ import 'package:analysis_server/src/services/search/search_engine.dart';
77import 'package:analyzer/dart/analysis/results.dart' ;
88import 'package:analyzer/dart/ast/ast.dart' ;
99import 'package:analyzer/dart/ast/visitor.dart' ;
10- import 'package:analyzer/dart/element/element .dart' ;
10+ import 'package:analyzer/dart/element/element2 .dart' ;
1111import 'package:analyzer/source/source_range.dart' ;
1212import 'package:analyzer/src/dart/ast/element_locator.dart' ;
1313import 'package:analyzer/src/dart/ast/utilities.dart' ;
1414import 'package:analyzer/src/dart/element/element.dart' ;
15- import 'package:analyzer/src/utilities/extensions/element.dart' ;
1615
1716/// Returns the container for [element] that should be used in Call Hierarchy.
1817///
1918/// Returns `null` if none of [elements] are valid containers.
2019///
2120/// This is used to construct (and group calls by) a [CallHierarchyItem] that
2221/// contains calls and also locate their containers for additional labelling.
23- Element ? _getContainer (Element element) {
22+ Element2 ? _getContainer (Element2 element) {
23+ // TODO(brianwilkerson): This used to use the compilation unit as a container
24+ // which allowed users to see the path to the containing file, but that's
25+ // been lost. Consider trying to restore that behavior.
2426 const containerKinds = {
2527 ElementKind .CLASS ,
26- ElementKind .COMPILATION_UNIT ,
28+ ElementKind .LIBRARY ,
2729 ElementKind .CONSTRUCTOR ,
2830 ElementKind .ENUM ,
2931 ElementKind .EXTENSION ,
@@ -34,29 +36,27 @@ Element? _getContainer(Element element) {
3436 ElementKind .MIXIN ,
3537 ElementKind .SETTER ,
3638 };
37- return element.thisOrAncestorMatching (
39+ return element.thisOrAncestorMatching2 (
3840 (ancestor) => containerKinds.contains (ancestor.kind),
3941 );
4042}
4143
4244/// Gets a user-friendly display name for [element] .
43- String _getDisplayName (Element element) {
44- return element is CompilationUnitElement
45- ? element.source.shortName
46- : element is PropertyAccessorElement
47- ? element.isGetter
48- ? 'get ${element .displayName }'
49- : 'set ${element .displayName }'
50- : element.displayName;
45+ String _getDisplayName (Element2 element) {
46+ return switch (element) {
47+ LibraryElement2 () => element.firstFragment.source.shortName,
48+ GetterElement () => 'get ${element .displayName }' ,
49+ SetterElement () => 'set ${element .displayName }' ,
50+ _ => element.displayName,
51+ };
5152}
5253
5354/// A [CallHierarchyItem] and a set of ranges that call to or from it.
5455class CallHierarchyCalls {
5556 final CallHierarchyItem item;
56- final List <SourceRange > ranges;
57+ final List <SourceRange > ranges = [] ;
5758
58- CallHierarchyCalls (this .item, [List <SourceRange >? ranges])
59- : ranges = ranges ?? [];
59+ CallHierarchyCalls (this .item);
6060}
6161
6262/// An item that can appear in a Call Hierarchy.
@@ -102,39 +102,53 @@ class CallHierarchyItem {
102102 required this .codeRange,
103103 });
104104
105- CallHierarchyItem .forElement (Element element)
105+ CallHierarchyItem .forElement (Element2 element)
106106 : displayName = _getDisplayName (element),
107107 nameRange = _nameRangeForElement (element),
108108 codeRange = _codeRangeForElement (element),
109- file = element.source ! .fullName,
109+ file = element.firstFragment.libraryFragment ! .source .fullName,
110110 kind = CallHierarchyKind .forElement (element) {
111- var enclosingElement = element.enclosingElement3;
111+ var enclosingElement =
112+ element.enclosingElement2 ??
113+ element.firstFragment.enclosingFragment? .element;
112114 var container =
113115 enclosingElement != null ? _getContainer (enclosingElement) : null ;
114116 containerName = container != null ? _getDisplayName (container) : null ;
115117 }
116118
117119 /// Returns the [SourceRange] of the code for [element] .
118- static SourceRange _codeRangeForElement (Element element) {
120+ static SourceRange _codeRangeForElement (Element2 element) {
119121 // For synthetic items (like implicit constructors), use the nonSynthetic
120122 // element for the location.
121- var elementImpl = element.nonSynthetic as ElementImpl ;
123+ element = _nonSynthetic (element);
124+ var fragment = element.firstFragment as ElementImpl ;
122125
123126 // Non-synthetic elements should always have code locations.
124- return SourceRange (elementImpl.codeOffset! , elementImpl.codeLength! );
127+ // TODO(brianwilkerson): Figure out why that's no longer true and possibly
128+ // remove the conditionals below.
129+ return SourceRange (fragment.codeOffset ?? 0 , fragment.codeLength ?? 0 );
125130 }
126131
127132 /// Returns the [SourceRange] of the name for [element] .
128- static SourceRange _nameRangeForElement (Element element) {
133+ static SourceRange _nameRangeForElement (Element2 element) {
129134 // For synthetic items (like implicit constructors), use the nonSynthetic
130135 // element for the location.
131- element = element.nonSynthetic;
136+ element = _nonSynthetic (element);
137+ var fragment = element.firstFragment as ElementImpl ;
132138
133139 // Compilation units will return -1 for nameOffset which is not valid, so
134- //use 0:0.
135- return element .nameOffset == - 1
140+ // use 0:0.
141+ return fragment .nameOffset == - 1
136142 ? SourceRange (0 , 0 )
137- : SourceRange (element.nameOffset, element.nameLength);
143+ : SourceRange (fragment.nameOffset, fragment.nameLength);
144+ }
145+
146+ static Element2 _nonSynthetic (Element2 element) {
147+ element = element.nonSynthetic2;
148+ if (element.isSynthetic) {
149+ element = element.enclosingElement2 ?? element;
150+ }
151+ return element;
138152 }
139153}
140154
@@ -153,7 +167,7 @@ enum CallHierarchyKind {
153167
154168 static const _elementMapping = {
155169 ElementKind .CLASS : class_,
156- ElementKind .COMPILATION_UNIT : file,
170+ ElementKind .LIBRARY : file,
157171 ElementKind .CONSTRUCTOR : constructor,
158172 ElementKind .EXTENSION : extension ,
159173 ElementKind .FUNCTION : function,
@@ -163,7 +177,7 @@ enum CallHierarchyKind {
163177 ElementKind .SETTER : property,
164178 };
165179
166- static CallHierarchyKind forElement (Element element) =>
180+ static CallHierarchyKind forElement (Element2 element) =>
167181 _elementMapping[element.kind] ?? unknown;
168182}
169183
@@ -210,28 +224,28 @@ class DartCallHierarchyComputer {
210224 // implicit constructors do not have.
211225 // Here, we map them back to the synthetic constructor element.
212226 var isImplicitConstructor =
213- element is InterfaceElement &&
227+ element is InterfaceElement2 &&
214228 target.kind == CallHierarchyKind .constructor;
215229 if (isImplicitConstructor) {
216- element = element.unnamedConstructor ;
230+ element = element.unnamedConstructor2 ;
217231 }
218232
219233 // We only find incoming calls to executable elements.
220- if (element is ! ExecutableElement ) {
234+ if (element is ! ExecutableElement2 ) {
221235 return [];
222236 }
223237
224238 var computer = ElementReferencesComputer (searchEngine);
225- var references = await computer.compute (element.asElement2 , false );
239+ var references = await computer.compute (element, false );
226240
227241 // Group results by their container, since we only want to return a single
228242 // entry for a body, with a set of ranges within.
229- var resultsByContainer = < Element , CallHierarchyCalls > {};
243+ var resultsByContainer = < Element2 , CallHierarchyCalls > {};
230244 // We may need to fetch parsed results for the other files, reuse them
231245 // across calls.
232246 var parsedUnits = < String , SomeParsedUnitResult ? > {};
233247 for (var reference in references) {
234- var container = _getContainer (reference.element );
248+ var container = _getContainer (reference.element2 );
235249 if (container == null ) {
236250 continue ;
237251 }
@@ -279,7 +293,7 @@ class DartCallHierarchyComputer {
279293
280294 // Group results by their target, since we only want to return a single
281295 // entry for each target, with a set of ranges that call it.
282- var resultsByTarget = < Element , CallHierarchyCalls > {};
296+ var resultsByTarget = < Element2 , CallHierarchyCalls > {};
283297 for (var referenceNode in referenceNodes) {
284298 var target = _getElementOfNode (referenceNode);
285299 if (target == null ) {
@@ -309,7 +323,7 @@ class DartCallHierarchyComputer {
309323 var element = _getElementOfNode (node);
310324
311325 // We only return targets that are executable elements.
312- return element is ExecutableElement
326+ return element is ExecutableElement2
313327 ? CallHierarchyItem .forElement (element)
314328 : null ;
315329 }
@@ -348,7 +362,7 @@ class DartCallHierarchyComputer {
348362 /// Return the [Element] of the given [node] , or `null` if [node] is `null` ,
349363 /// does not have an element, or the element is not a valid target for call
350364 /// hierarchy.
351- Element ? _getElementOfNode (AstNode ? node) {
365+ Element2 ? _getElementOfNode (AstNode ? node) {
352366 if (node == null ) {
353367 return null ;
354368 }
@@ -357,18 +371,18 @@ class DartCallHierarchyComputer {
357371 // ElementLocator returns the class for default constructor calls and null
358372 // for constructor names.
359373 if (node is NamedType && parent is ConstructorName ) {
360- return parent.staticElement ;
374+ return parent.element ;
361375 } else if (node is ConstructorName ) {
362- return node.staticElement ;
376+ return node.element ;
363377 } else if (node is PropertyAccess ) {
364378 node = node.propertyName;
365379 }
366380
367- var element = ElementLocator .locate (node);
381+ var element = ElementLocator .locate2 (node);
368382
369383 // Don't consider synthetic getter/setter for a field to be executable
370384 // since they don't contain any executable code.
371- if (element is PropertyAccessorElement && element.isSynthetic) {
385+ if (element is PropertyAccessorElement2 && element.isSynthetic) {
372386 return null ;
373387 }
374388
@@ -380,7 +394,7 @@ class DartCallHierarchyComputer {
380394 /// This is used to ensure calls are only returned for the expected target
381395 /// if source code has changed since the earlier request that provided
382396 /// [target] to the client.
383- bool _isMatchingElement (Element element, CallHierarchyItem target) {
397+ bool _isMatchingElement (Element2 element, CallHierarchyItem target) {
384398 return _getDisplayName (element) == target.displayName;
385399 }
386400
@@ -494,7 +508,10 @@ class _OutboundCallVisitor extends RecursiveAstVisitor<void> {
494508
495509 @override
496510 void visitSimpleIdentifier (SimpleIdentifier node) {
497- if (node.staticElement is FunctionElement && ! node.inDeclarationContext ()) {
511+ var element = node.element;
512+ if ((element is LocalFunctionElement ||
513+ element is TopLevelFunctionElement ) &&
514+ ! node.inDeclarationContext ()) {
498515 collect (node);
499516 }
500517 super .visitSimpleIdentifier (node);
0 commit comments