Skip to content

Commit 54d62b4

Browse files
DanTupCommit Queue
authored andcommitted
[analysis_server] Move Type Hierarchy off ElementLocation to its own internal uri/name encoding
This uses a simplified version of `ElementLocation` for `InterfaceElement`s in Type Hierarchy that are just made of Library URI + Name. Change-Id: I2b5279f53d8eb199e31b3aed59e113c5f34e941a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400960 Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent b67f61a commit 54d62b4

File tree

2 files changed

+68
-13
lines changed

2 files changed

+68
-13
lines changed

pkg/analysis_server/lib/src/computer/computer_lazy_type_hierarchy.dart

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
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+
58
import 'package:analysis_server/src/services/search/search_engine.dart';
69
import 'package:analyzer/dart/analysis/results.dart';
10+
import 'package:analyzer/dart/analysis/session.dart';
711
import 'package:analyzer/dart/ast/ast.dart';
812
import 'package:analyzer/dart/element/element2.dart';
913
import 'package:analyzer/dart/element/type.dart';
1014
import 'package:analyzer/source/source_range.dart';
1115
import 'package:analyzer/src/dart/element/element.dart';
12-
import 'package:analyzer/src/utilities/extensions/analysis_session.dart';
1316
import '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

216220
class 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+
295351
enum TypeHierarchyItemRelationship {
296352
unknown,
297353
implements,

pkg/analysis_server/lib/src/lsp/handlers/handler_type_hierarchy.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import 'package:analyzer/dart/analysis/results.dart';
1616
import 'package:analyzer/dart/analysis/session.dart';
1717
import 'package:analyzer/source/line_info.dart';
1818
import 'package:analyzer/source/source_range.dart';
19-
import 'package:analyzer/src/dart/element/element.dart';
2019

2120
typedef StaticOptions =
2221
Either3<bool, TypeHierarchyOptions, TypeHierarchyRegistrationOptions>;
@@ -141,7 +140,7 @@ class TypeHierarchySubtypesHandler
141140
);
142141
}
143142

144-
var location = ElementLocationImpl.con2(data.ref);
143+
var location = type_hierarchy.TypeHierarchyItemLocation.decode(data.ref);
145144
var calls = await computer.findSubtypes(location, server.searchEngine);
146145
var results = calls != null ? _convertItems(unit, calls) : null;
147146
return success(results);
@@ -189,7 +188,7 @@ class TypeHierarchySupertypesHandler
189188
);
190189
}
191190

192-
var location = ElementLocationImpl.con2(data.ref);
191+
var location = type_hierarchy.TypeHierarchyItemLocation.decode(data.ref);
193192
var anchor = _toServerAnchor(data);
194193
var calls = await computer.findSupertypes(location, anchor: anchor);
195194
var results = calls != null ? _convertItems(unit, calls) : null;
@@ -205,7 +204,7 @@ class TypeHierarchySupertypesHandler
205204
var anchor = data.anchor;
206205
return anchor != null
207206
? type_hierarchy.TypeHierarchyAnchor(
208-
location: ElementLocationImpl.con2(anchor.ref),
207+
location: type_hierarchy.TypeHierarchyItemLocation.decode(anchor.ref),
209208
path: anchor.path,
210209
)
211210
: null;

0 commit comments

Comments
 (0)