66library ;
77
88import 'package:analysis_server/src/services/search/search_engine.dart' ;
9+ import 'package:analysis_server/src/utilities/element_location2.dart' ;
910import 'package:analyzer/dart/analysis/results.dart' ;
10- import 'package:analyzer/dart/analysis/session.dart' ;
1111import 'package:analyzer/dart/ast/ast.dart' ;
1212import 'package:analyzer/dart/element/element2.dart' ;
1313import 'package:analyzer/dart/element/type.dart' ;
1414import 'package:analyzer/source/source_range.dart' ;
1515import 'package:analyzer/src/dart/element/element.dart' ;
1616import 'package:analyzer/src/utilities/extensions/ast.dart' ;
17- import 'package:collection/collection.dart' ;
1817
1918/// A lazy computer for Type Hierarchies.
2019///
@@ -36,9 +35,9 @@ class DartLazyTypeHierarchyComputer {
3635
3736 DartLazyTypeHierarchyComputer (this ._result);
3837
39- /// Finds subtypes for [Element ] at [location] .
38+ /// Finds subtypes for the [Element2 ] at [location] .
4039 Future <List <TypeHierarchyRelatedItem >?> findSubtypes (
41- TypeHierarchyItemLocation location,
40+ ElementLocation2 location,
4241 SearchEngine searchEngine,
4342 ) async {
4443 var targetElement = await _findTargetElement (location);
@@ -49,7 +48,7 @@ class DartLazyTypeHierarchyComputer {
4948 return _getSubtypes (targetElement, searchEngine);
5049 }
5150
52- /// Finds supertypes for the [Element ] at [location] .
51+ /// Finds supertypes for the [Element2 ] at [location] .
5352 ///
5453 /// If [anchor] is provided, it will be used to navigate to the element at
5554 /// [location] to preserve type arguments that have been provided along the
@@ -58,7 +57,7 @@ class DartLazyTypeHierarchyComputer {
5857 /// Anchors are included in returned types (where necessary to preserve type
5958 /// arguments) that can be used when calling for the next level of types.
6059 Future <List <TypeHierarchyRelatedItem >?> findSupertypes (
61- TypeHierarchyItemLocation location, {
60+ ElementLocation2 location, {
6261 TypeHierarchyAnchor ? anchor,
6362 }) async {
6463 var targetElement = await _findTargetElement (location);
@@ -105,11 +104,11 @@ class DartLazyTypeHierarchyComputer {
105104 return type is InterfaceType ? TypeHierarchyItem .forType (type) : null ;
106105 }
107106
108- /// Locate the [Element ] referenced by [location] .
107+ /// Locate the [Element2 ] referenced by [location] .
109108 Future <InterfaceElement2 ?> _findTargetElement (
110- TypeHierarchyItemLocation location,
109+ ElementLocation2 location,
111110 ) async {
112- var element = await location._locateIn (_result.session);
111+ var element = await location.locateIn (_result.session);
113112 return element is InterfaceElement2 ? element : null ;
114113 }
115114
@@ -119,7 +118,7 @@ class DartLazyTypeHierarchyComputer {
119118 SearchEngine searchEngine,
120119 ) async {
121120 /// Helper to convert a [SearchMatch] to a [TypeHierarchyRelatedItem] .
122- TypeHierarchyRelatedItem toHierarchyItem (SearchMatch match) {
121+ TypeHierarchyRelatedItem ? toHierarchyItem (SearchMatch match) {
123122 var element = match.element2 as InterfaceElement2 ;
124123 var type = element.thisType;
125124 switch (match.kind) {
@@ -145,6 +144,7 @@ class DartLazyTypeHierarchyComputer {
145144 return matches
146145 .where ((match) => seenElements.add (match.element2))
147146 .map (toHierarchyItem)
147+ .nonNulls
148148 .toList ();
149149 }
150150
@@ -162,12 +162,13 @@ class DartLazyTypeHierarchyComputer {
162162 var mixins = type.mixins;
163163 var superclassConstraints = type.superclassConstraints;
164164
165- var supertypes = [
166- if (supertype != null ) TypeHierarchyRelatedItem .extends_ (supertype),
167- ...superclassConstraints.map (TypeHierarchyRelatedItem .constrainedTo),
168- ...interfaces.map (TypeHierarchyRelatedItem .implements ),
169- ...mixins.map (TypeHierarchyRelatedItem .mixesIn),
170- ];
165+ var supertypes =
166+ [
167+ if (supertype != null ) TypeHierarchyRelatedItem .extends_ (supertype),
168+ ...superclassConstraints.map (TypeHierarchyRelatedItem .constrainedTo),
169+ ...interfaces.map (TypeHierarchyRelatedItem .implements ),
170+ ...mixins.map (TypeHierarchyRelatedItem .mixesIn),
171+ ].nonNulls.toList ();
171172
172173 if (anchor != null ) {
173174 for (var (index, item) in supertypes.indexed) {
@@ -219,7 +220,7 @@ class DartLazyTypeHierarchyComputer {
219220
220221class TypeHierarchyAnchor {
221222 /// The location of the anchor element.
222- final TypeHierarchyItemLocation location;
223+ final ElementLocation2 location;
223224
224225 /// The supertype path from [location] to the target element.
225226 final List <int > path;
@@ -238,7 +239,7 @@ class TypeHierarchyItem {
238239 /// `findSubtypes` /`findSupertypes` so that if code has been modified since
239240 /// the `findTarget` call the element can still be located (provided the
240241 /// names/identifiers have not changed).
241- final TypeHierarchyItemLocation location;
242+ final ElementLocation2 location;
242243
243244 /// The type being displayed.
244245 final InterfaceType _type;
@@ -261,15 +262,21 @@ class TypeHierarchyItem {
261262 required this .codeRange,
262263 }) : _type = type;
263264
264- TypeHierarchyItem .forType (InterfaceType type)
265- : this (
266- type: type,
267- displayName: _displayNameForType (type),
268- location: TypeHierarchyItemLocation .forElement (type.element3),
269- nameRange: _nameRangeForElement (type.element3),
270- codeRange: _codeRangeForElement (type.element3),
271- file: type.element3.firstFragment.libraryFragment.source.fullName,
272- );
265+ TypeHierarchyItem ._forType ({
266+ required InterfaceType type,
267+ required this .location,
268+ }) : _type = type,
269+ displayName = _displayNameForType (type),
270+ nameRange = _nameRangeForElement (type.element3),
271+ codeRange = _codeRangeForElement (type.element3),
272+ file = type.element3.firstFragment.libraryFragment.source.fullName;
273+
274+ static TypeHierarchyItem ? forType (InterfaceType type) {
275+ var location = ElementLocation2 .forElement (type.element3);
276+ if (location == null ) return null ;
277+
278+ return TypeHierarchyItem ._forType (type: type, location: location);
279+ }
273280
274281 /// Returns the [SourceRange] of the code for [element] .
275282 static SourceRange _codeRangeForElement (Element2 element) {
@@ -296,58 +303,6 @@ class TypeHierarchyItem {
296303 }
297304}
298305
299- /// Represents the location of an item that can appear in Type Hierarchy that
300- /// can be encoded to/from a [String] for round-tripping to the client.
301- class TypeHierarchyItemLocation {
302- /// The URI of the Library that contains this type.
303- final String _libraryUri;
304-
305- /// The [Element2.name3] for this type.
306- final String _name;
307-
308- factory TypeHierarchyItemLocation .decode (String encoded) {
309- var parts = encoded.split (';' );
310- if (parts.length != 2 ) {
311- throw ArgumentError (
312- "Encoded string should be in format 'libraryUri;name' encoded" ,
313- );
314- }
315- return TypeHierarchyItemLocation ._(libraryUri: parts[0 ], name: parts[1 ]);
316- }
317-
318- factory TypeHierarchyItemLocation .forElement (InterfaceElement2 element) {
319- var name = element.name3;
320-
321- if (name == null ) {
322- throw ArgumentError (
323- 'Cannot create TypeHierarchyItemLocation for an element with no name: $element ' ,
324- );
325- }
326-
327- return TypeHierarchyItemLocation ._(
328- libraryUri: element.library2.uri.toString (),
329- name: name,
330- );
331- }
332-
333- TypeHierarchyItemLocation ._({
334- required String libraryUri,
335- required String name,
336- }) : _name = name,
337- _libraryUri = libraryUri;
338-
339- String get encoding => '$_libraryUri ;$_name ' ;
340-
341- Future <InterfaceElement2 ?> _locateIn (AnalysisSession session) async {
342- var result = await session.getLibraryByUri (_libraryUri);
343- return result is LibraryElementResult
344- ? result.element2.children2
345- .whereType <InterfaceElement2 >()
346- .firstWhereOrNull ((element2) => element2.name3 == _name)
347- : null ;
348- }
349- }
350-
351306enum TypeHierarchyItemRelationship {
352307 unknown,
353308 implements ,
@@ -363,29 +318,51 @@ class TypeHierarchyRelatedItem extends TypeHierarchyItem {
363318
364319 TypeHierarchyAnchor ? _anchor;
365320
366- TypeHierarchyRelatedItem .constrainedTo (InterfaceType type)
367- : this ._forType (
368- type,
369- relationship: TypeHierarchyItemRelationship .constrainedTo,
370- );
371- TypeHierarchyRelatedItem .extends_ (InterfaceType type)
372- : this ._forType (type, relationship: TypeHierarchyItemRelationship .extends_);
321+ TypeHierarchyRelatedItem ({
322+ required super .type,
323+ required this .relationship,
324+ required super .displayName,
325+ required super .location,
326+ required super .file,
327+ required super .nameRange,
328+ required super .codeRange,
329+ });
330+
331+ TypeHierarchyRelatedItem .forType ({
332+ required super .type,
333+ required this .relationship,
334+ required super .location,
335+ }) : super ._forType ();
373336
374- TypeHierarchyRelatedItem .implements (InterfaceType type)
375- : this ._forType (
376- type,
377- relationship: TypeHierarchyItemRelationship .implements ,
378- );
337+ /// An optional anchor element used to preserve type args.
338+ TypeHierarchyAnchor ? get anchor => _anchor;
379339
380- TypeHierarchyRelatedItem . mixesIn (InterfaceType type)
381- : this . _forType (type, relationship: TypeHierarchyItemRelationship .mixesIn );
340+ static TypeHierarchyRelatedItem ? constrainedTo (InterfaceType type) =>
341+ _forType (type, relationship: TypeHierarchyItemRelationship .constrainedTo );
382342
383- TypeHierarchyRelatedItem . unknown (InterfaceType type)
384- : this . _forType (type, relationship: TypeHierarchyItemRelationship .unknown );
343+ static TypeHierarchyRelatedItem ? extends_ (InterfaceType type) =>
344+ _forType (type, relationship: TypeHierarchyItemRelationship .extends_ );
385345
386- TypeHierarchyRelatedItem . _forType ( super .type, { required this .relationship})
387- : super . forType ( );
346+ static TypeHierarchyRelatedItem ? implements ( InterfaceType type) =>
347+ _forType (type, relationship : TypeHierarchyItemRelationship . implements );
388348
389- /// An optional anchor element used to preserve type args.
390- TypeHierarchyAnchor ? get anchor => _anchor;
349+ static TypeHierarchyRelatedItem ? mixesIn (InterfaceType type) =>
350+ _forType (type, relationship: TypeHierarchyItemRelationship .mixesIn);
351+
352+ static TypeHierarchyRelatedItem ? unknown (InterfaceType type) =>
353+ _forType (type, relationship: TypeHierarchyItemRelationship .unknown);
354+
355+ static TypeHierarchyRelatedItem ? _forType (
356+ InterfaceType type, {
357+ required TypeHierarchyItemRelationship relationship,
358+ }) {
359+ var location = ElementLocation2 .forElement (type.element3);
360+ if (location == null ) return null ;
361+
362+ return TypeHierarchyRelatedItem .forType (
363+ type: type,
364+ relationship: relationship,
365+ location: location,
366+ );
367+ }
391368}
0 commit comments