22// for details. All rights reserved. Use of this source code is governed by a
33// BSD-style license that can be found in the LICENSE file.
44
5+ /// @docImport 'package:analysis_server/src/search/type_hierarchy.dart';
6+ library ;
7+
58import 'package:analysis_server/src/services/search/search_engine.dart' ;
69import 'package:analyzer/dart/analysis/results.dart' ;
10+ import 'package:analyzer/dart/analysis/session.dart' ;
711import 'package:analyzer/dart/ast/ast.dart' ;
812import 'package:analyzer/dart/element/element2.dart' ;
913import 'package:analyzer/dart/element/type.dart' ;
1014import 'package:analyzer/source/source_range.dart' ;
1115import 'package:analyzer/src/dart/element/element.dart' ;
12- import 'package:analyzer/src/utilities/extensions/analysis_session.dart' ;
1316import 'package:analyzer/src/utilities/extensions/ast.dart' ;
17+ import 'package:collection/collection.dart' ;
1418
1519/// A lazy computer for Type Hierarchies.
1620///
@@ -34,7 +38,7 @@ class DartLazyTypeHierarchyComputer {
3438
3539 /// Finds subtypes for [Element] at [location] .
3640 Future <List <TypeHierarchyRelatedItem >?> findSubtypes (
37- ElementLocation location,
41+ TypeHierarchyItemLocation location,
3842 SearchEngine searchEngine,
3943 ) async {
4044 var targetElement = await _findTargetElement (location);
@@ -54,7 +58,7 @@ class DartLazyTypeHierarchyComputer {
5458 /// Anchors are included in returned types (where necessary to preserve type
5559 /// arguments) that can be used when calling for the next level of types.
5660 Future <List <TypeHierarchyRelatedItem >?> findSupertypes (
57- ElementLocation location, {
61+ TypeHierarchyItemLocation location, {
5862 TypeHierarchyAnchor ? anchor,
5963 }) async {
6064 var targetElement = await _findTargetElement (location);
@@ -103,9 +107,9 @@ class DartLazyTypeHierarchyComputer {
103107
104108 /// Locate the [Element] referenced by [location] .
105109 Future <InterfaceElement2 ?> _findTargetElement (
106- ElementLocation location,
110+ TypeHierarchyItemLocation location,
107111 ) async {
108- var element = await _result.session. locateElement2 (location );
112+ var element = await location. _locateIn ( _result.session);
109113 return element is InterfaceElement2 ? element : null ;
110114 }
111115
@@ -144,7 +148,7 @@ class DartLazyTypeHierarchyComputer {
144148 .toList ();
145149 }
146150
147- /// Gets immediate super types for the class/mixin [element ] .
151+ /// Gets immediate super types for the class/mixin [type ] .
148152 ///
149153 /// Includes all elements that contribute implementation to the type
150154 /// such as supertypes and mixins, but not interfaces, constraints or
@@ -215,7 +219,7 @@ class DartLazyTypeHierarchyComputer {
215219
216220class TypeHierarchyAnchor {
217221 /// The location of the anchor element.
218- final ElementLocation location;
222+ final TypeHierarchyItemLocation location;
219223
220224 /// The supertype path from [location] to the target element.
221225 final List <int > path;
@@ -234,7 +238,7 @@ class TypeHierarchyItem {
234238 /// `findSubtypes` /`findSupertypes` so that if code has been modified since
235239 /// the `findTarget` call the element can still be located (provided the
236240 /// names/identifiers have not changed).
237- final ElementLocation location;
241+ final TypeHierarchyItemLocation location;
238242
239243 /// The type being displayed.
240244 final InterfaceType _type;
@@ -261,7 +265,7 @@ class TypeHierarchyItem {
261265 : this (
262266 type: type,
263267 displayName: _displayNameForType (type),
264- location: type.element3.location ! ,
268+ location: TypeHierarchyItemLocation . forElement ( type.element3) ,
265269 nameRange: _nameRangeForElement (type.element3),
266270 codeRange: _codeRangeForElement (type.element3),
267271 file: type.element3.firstFragment.libraryFragment.source.fullName,
@@ -292,6 +296,58 @@ class TypeHierarchyItem {
292296 }
293297}
294298
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+
295351enum TypeHierarchyItemRelationship {
296352 unknown,
297353 implements ,
0 commit comments