Skip to content

Commit

Permalink
Version 3.7.0-273.0.dev
Browse files Browse the repository at this point in the history
Merge 3b58e14 into dev
  • Loading branch information
Dart CI committed Dec 20, 2024
2 parents e0944bc + 3b58e14 commit c9b0bac
Show file tree
Hide file tree
Showing 62 changed files with 903 additions and 547 deletions.
2 changes: 0 additions & 2 deletions pkg/analysis_server/analyzer_use_new_elements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ lib/src/lsp/handlers/handler_rename.dart
lib/src/protocol_server.dart
lib/src/services/correction/namespace.dart
lib/src/services/kythe/kythe_visitors.dart
lib/src/services/refactoring/agnostic/change_method_signature.dart
lib/src/services/refactoring/framework/formal_parameter.dart
lib/src/services/refactoring/legacy/extract_method.dart
lib/src/services/refactoring/legacy/move_file.dart
lib/src/services/refactoring/legacy/refactoring.dart
Expand Down
175 changes: 76 additions & 99 deletions pkg/analysis_server/lib/src/computer/computer_lazy_type_hierarchy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
library;

import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/utilities/element_location2.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/utilities/extensions/ast.dart';
import 'package:collection/collection.dart';

/// A lazy computer for Type Hierarchies.
///
Expand All @@ -36,9 +35,9 @@ class DartLazyTypeHierarchyComputer {

DartLazyTypeHierarchyComputer(this._result);

/// Finds subtypes for [Element] at [location].
/// Finds subtypes for the [Element2] at [location].
Future<List<TypeHierarchyRelatedItem>?> findSubtypes(
TypeHierarchyItemLocation location,
ElementLocation2 location,
SearchEngine searchEngine,
) async {
var targetElement = await _findTargetElement(location);
Expand All @@ -49,7 +48,7 @@ class DartLazyTypeHierarchyComputer {
return _getSubtypes(targetElement, searchEngine);
}

/// Finds supertypes for the [Element] at [location].
/// Finds supertypes for the [Element2] at [location].
///
/// If [anchor] is provided, it will be used to navigate to the element at
/// [location] to preserve type arguments that have been provided along the
Expand All @@ -58,7 +57,7 @@ class DartLazyTypeHierarchyComputer {
/// Anchors are included in returned types (where necessary to preserve type
/// arguments) that can be used when calling for the next level of types.
Future<List<TypeHierarchyRelatedItem>?> findSupertypes(
TypeHierarchyItemLocation location, {
ElementLocation2 location, {
TypeHierarchyAnchor? anchor,
}) async {
var targetElement = await _findTargetElement(location);
Expand Down Expand Up @@ -105,11 +104,11 @@ class DartLazyTypeHierarchyComputer {
return type is InterfaceType ? TypeHierarchyItem.forType(type) : null;
}

/// Locate the [Element] referenced by [location].
/// Locate the [Element2] referenced by [location].
Future<InterfaceElement2?> _findTargetElement(
TypeHierarchyItemLocation location,
ElementLocation2 location,
) async {
var element = await location._locateIn(_result.session);
var element = await location.locateIn(_result.session);
return element is InterfaceElement2 ? element : null;
}

Expand All @@ -119,7 +118,7 @@ class DartLazyTypeHierarchyComputer {
SearchEngine searchEngine,
) async {
/// Helper to convert a [SearchMatch] to a [TypeHierarchyRelatedItem].
TypeHierarchyRelatedItem toHierarchyItem(SearchMatch match) {
TypeHierarchyRelatedItem? toHierarchyItem(SearchMatch match) {
var element = match.element2 as InterfaceElement2;
var type = element.thisType;
switch (match.kind) {
Expand All @@ -145,6 +144,7 @@ class DartLazyTypeHierarchyComputer {
return matches
.where((match) => seenElements.add(match.element2))
.map(toHierarchyItem)
.nonNulls
.toList();
}

Expand All @@ -162,12 +162,13 @@ class DartLazyTypeHierarchyComputer {
var mixins = type.mixins;
var superclassConstraints = type.superclassConstraints;

var supertypes = [
if (supertype != null) TypeHierarchyRelatedItem.extends_(supertype),
...superclassConstraints.map(TypeHierarchyRelatedItem.constrainedTo),
...interfaces.map(TypeHierarchyRelatedItem.implements),
...mixins.map(TypeHierarchyRelatedItem.mixesIn),
];
var supertypes =
[
if (supertype != null) TypeHierarchyRelatedItem.extends_(supertype),
...superclassConstraints.map(TypeHierarchyRelatedItem.constrainedTo),
...interfaces.map(TypeHierarchyRelatedItem.implements),
...mixins.map(TypeHierarchyRelatedItem.mixesIn),
].nonNulls.toList();

if (anchor != null) {
for (var (index, item) in supertypes.indexed) {
Expand Down Expand Up @@ -219,7 +220,7 @@ class DartLazyTypeHierarchyComputer {

class TypeHierarchyAnchor {
/// The location of the anchor element.
final TypeHierarchyItemLocation location;
final ElementLocation2 location;

/// The supertype path from [location] to the target element.
final List<int> path;
Expand All @@ -238,7 +239,7 @@ class TypeHierarchyItem {
/// `findSubtypes`/`findSupertypes` so that if code has been modified since
/// the `findTarget` call the element can still be located (provided the
/// names/identifiers have not changed).
final TypeHierarchyItemLocation location;
final ElementLocation2 location;

/// The type being displayed.
final InterfaceType _type;
Expand All @@ -261,15 +262,21 @@ class TypeHierarchyItem {
required this.codeRange,
}) : _type = type;

TypeHierarchyItem.forType(InterfaceType type)
: this(
type: type,
displayName: _displayNameForType(type),
location: TypeHierarchyItemLocation.forElement(type.element3),
nameRange: _nameRangeForElement(type.element3),
codeRange: _codeRangeForElement(type.element3),
file: type.element3.firstFragment.libraryFragment.source.fullName,
);
TypeHierarchyItem._forType({
required InterfaceType type,
required this.location,
}) : _type = type,
displayName = _displayNameForType(type),
nameRange = _nameRangeForElement(type.element3),
codeRange = _codeRangeForElement(type.element3),
file = type.element3.firstFragment.libraryFragment.source.fullName;

static TypeHierarchyItem? forType(InterfaceType type) {
var location = ElementLocation2.forElement(type.element3);
if (location == null) return null;

return TypeHierarchyItem._forType(type: type, location: location);
}

/// Returns the [SourceRange] of the code for [element].
static SourceRange _codeRangeForElement(Element2 element) {
Expand All @@ -296,58 +303,6 @@ class TypeHierarchyItem {
}
}

/// Represents the location of an item that can appear in Type Hierarchy that
/// can be encoded to/from a [String] for round-tripping to the client.
class TypeHierarchyItemLocation {
/// The URI of the Library that contains this type.
final String _libraryUri;

/// The [Element2.name3] for this type.
final String _name;

factory TypeHierarchyItemLocation.decode(String encoded) {
var parts = encoded.split(';');
if (parts.length != 2) {
throw ArgumentError(
"Encoded string should be in format 'libraryUri;name' encoded",
);
}
return TypeHierarchyItemLocation._(libraryUri: parts[0], name: parts[1]);
}

factory TypeHierarchyItemLocation.forElement(InterfaceElement2 element) {
var name = element.name3;

if (name == null) {
throw ArgumentError(
'Cannot create TypeHierarchyItemLocation for an element with no name: $element',
);
}

return TypeHierarchyItemLocation._(
libraryUri: element.library2.uri.toString(),
name: name,
);
}

TypeHierarchyItemLocation._({
required String libraryUri,
required String name,
}) : _name = name,
_libraryUri = libraryUri;

String get encoding => '$_libraryUri;$_name';

Future<InterfaceElement2?> _locateIn(AnalysisSession session) async {
var result = await session.getLibraryByUri(_libraryUri);
return result is LibraryElementResult
? result.element2.children2
.whereType<InterfaceElement2>()
.firstWhereOrNull((element2) => element2.name3 == _name)
: null;
}
}

enum TypeHierarchyItemRelationship {
unknown,
implements,
Expand All @@ -363,29 +318,51 @@ class TypeHierarchyRelatedItem extends TypeHierarchyItem {

TypeHierarchyAnchor? _anchor;

TypeHierarchyRelatedItem.constrainedTo(InterfaceType type)
: this._forType(
type,
relationship: TypeHierarchyItemRelationship.constrainedTo,
);
TypeHierarchyRelatedItem.extends_(InterfaceType type)
: this._forType(type, relationship: TypeHierarchyItemRelationship.extends_);
TypeHierarchyRelatedItem({
required super.type,
required this.relationship,
required super.displayName,
required super.location,
required super.file,
required super.nameRange,
required super.codeRange,
});

TypeHierarchyRelatedItem.forType({
required super.type,
required this.relationship,
required super.location,
}) : super._forType();

TypeHierarchyRelatedItem.implements(InterfaceType type)
: this._forType(
type,
relationship: TypeHierarchyItemRelationship.implements,
);
/// An optional anchor element used to preserve type args.
TypeHierarchyAnchor? get anchor => _anchor;

TypeHierarchyRelatedItem.mixesIn(InterfaceType type)
: this._forType(type, relationship: TypeHierarchyItemRelationship.mixesIn);
static TypeHierarchyRelatedItem? constrainedTo(InterfaceType type) =>
_forType(type, relationship: TypeHierarchyItemRelationship.constrainedTo);

TypeHierarchyRelatedItem.unknown(InterfaceType type)
: this._forType(type, relationship: TypeHierarchyItemRelationship.unknown);
static TypeHierarchyRelatedItem? extends_(InterfaceType type) =>
_forType(type, relationship: TypeHierarchyItemRelationship.extends_);

TypeHierarchyRelatedItem._forType(super.type, {required this.relationship})
: super.forType();
static TypeHierarchyRelatedItem? implements(InterfaceType type) =>
_forType(type, relationship: TypeHierarchyItemRelationship.implements);

/// An optional anchor element used to preserve type args.
TypeHierarchyAnchor? get anchor => _anchor;
static TypeHierarchyRelatedItem? mixesIn(InterfaceType type) =>
_forType(type, relationship: TypeHierarchyItemRelationship.mixesIn);

static TypeHierarchyRelatedItem? unknown(InterfaceType type) =>
_forType(type, relationship: TypeHierarchyItemRelationship.unknown);

static TypeHierarchyRelatedItem? _forType(
InterfaceType type, {
required TypeHierarchyItemRelationship relationship,
}) {
var location = ElementLocation2.forElement(type.element3);
if (location == null) return null;

return TypeHierarchyRelatedItem.forType(
type: type,
relationship: relationship,
location: location,
);
}
}
15 changes: 7 additions & 8 deletions pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.d
import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
import 'package:analysis_server/src/services/snippets/dart_snippet_request.dart';
import 'package:analysis_server/src/services/snippets/snippet_manager.dart';
import 'package:analysis_server/src/utilities/element_location2.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart' as ast;
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/utilities/extensions/element.dart';
import 'package:analyzer/src/utilities/fuzzy_matcher.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
Expand Down Expand Up @@ -478,27 +478,26 @@ class CompletionHandler
CompletionItemResolutionInfo? resolutionInfo;

if (item is ElementBasedSuggestion && item is ImportableSuggestion) {
var elementLocation =
(item as ElementBasedSuggestion).element.asElement!.location;
var importUri = item.importData?.libraryUri;
var element = (item as ElementBasedSuggestion).element;

var importUri = item.importData?.libraryUri;
if (importUri != null) {
resolutionInfo = DartCompletionResolutionInfo(
file: unit.path,
importUris: [importUri.toString()],
ref: elementLocation?.encoding,
ref: ElementLocation2.forElement(element)?.encoding,
);
}
} else if (item is OverrideSuggestion) {
var overrideData = item.data;
if (overrideData != null && overrideData.imports.isNotEmpty) {
var elementLocation =
(item as ElementBasedSuggestion).element.location;
var element = (item as ElementBasedSuggestion).element;

var importUris = overrideData.imports;
resolutionInfo = DartCompletionResolutionInfo(
file: unit.path,
importUris: importUris.map((uri) => uri.toString()).toList(),
ref: elementLocation?.encoding,
ref: ElementLocation2.forElement(element)?.encoding,
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/error_or.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analysis_server/src/utilities/element_location2.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/utilities/extensions/analysis_session.dart';
import 'package:analyzer/src/utilities/extensions/element.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';

class CompletionResolveHandler
Expand Down Expand Up @@ -63,11 +61,7 @@ class CompletionResolveHandler
) async {
var file = data.file;
var importUris = data.importUris.map(Uri.parse).toList();
var elementLocationReference = data.ref;
var elementLocation =
elementLocationReference != null
? ElementLocationImpl.con2(elementLocationReference)
: null;
var elementReference = data.ref;

const timeout = Duration(milliseconds: 1000);
var timer = Stopwatch()..start();
Expand Down Expand Up @@ -130,8 +124,10 @@ class CompletionResolveHandler
// Look up documentation if we can get an element for this item.
Either2<MarkupContent, String>? documentation;
var element =
elementLocation != null
? (await session.locateElement(elementLocation)).asElement2
elementReference != null
? await ElementLocation2.decode(
elementReference,
).locateIn(session)
: null;
if (element != null) {
var formats = clientCapabilities.completionDocumentationFormats;
Expand Down
Loading

0 comments on commit c9b0bac

Please sign in to comment.