Skip to content

Commit

Permalink
Version 3.4.0-190.0.dev
Browse files Browse the repository at this point in the history
Merge fddd66f into dev
  • Loading branch information
Dart CI committed Feb 29, 2024
2 parents 80239ca + fddd66f commit 728fcf0
Show file tree
Hide file tree
Showing 21 changed files with 847 additions and 205 deletions.
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ vars = {
"boringssl_gen_rev": "9c7294fd58261a79794f5afaa26598cf1442ad20",
"boringssl_rev": "d24a38200fef19150eef00cad35b138936c08767",
"browser-compat-data_tag": "ac8cae697014da1ff7124fba33b0b4245cc6cd1b", # v1.0.22
"devtools_rev": "333b00377c092306534404c68a82e925ee2e23a3",
"devtools_rev": "171b80902ace608416eeb26cedd5420d00f50e5a",
"icu_rev": "81d656878ec611cb0b42d52c82e9dae93920d9ba",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"libcxx_rev": "44079a4cc04cdeffb9cfe8067bfb3c276fb2bab0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/source_range.dart';

/// Information about a code completion suggestion that might or might not be
/// sent to the client (that is, one that is a candidate for being sent).
Expand Down Expand Up @@ -375,6 +376,31 @@ final class NameSuggestion extends CandidateSuggestion {
String get completion => name;
}

/// The information about a candidate suggestion to create an override of an
/// inherited method.
final class OverrideSuggestion extends CandidateSuggestion {
/// The method to be overridden.
final ExecutableElement element;

/// Whether `super` should be invoked in the body of the override.
final bool shouldInvokeSuper;

/// The soruce range that should be replaced by the override.
final SourceRange replacementRange;

/// Initialize a newly created candidate suggestion to suggest the [element] by
/// inserting the [shouldInvokeSuper].
OverrideSuggestion(
{required this.element,
required this.shouldInvokeSuper,
required this.replacementRange});

@override
// TODO(brianwilkerson): This needs to be replaced with code to compute the
// actual completion when we remove SuggestionBuilder.
String get completion => '@override ${element.displayName}';
}

/// The information about a candidate suggestion based on a getter or setter.
final class PropertyAccessSuggestion extends CandidateSuggestion {
/// The element on which the suggestion is based.
Expand Down Expand Up @@ -592,6 +618,9 @@ extension SuggestionBuilderExtension on SuggestionBuilder {
replacementLength: suggestion.replacementLength);
case NameSuggestion():
suggestName(suggestion.name);
case OverrideSuggestion():
suggestOverride2(suggestion.element, suggestion.shouldInvokeSuper,
suggestion.replacementRange);
case PropertyAccessSuggestion():
var inheritanceDistance = 0.0;
var referencingClass = suggestion.referencingClass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import 'package:analysis_server/src/services/completion/dart/library_member_cont
import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/not_imported_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/override_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/record_literal_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_collector.dart';
Expand Down Expand Up @@ -133,7 +132,6 @@ class DartCompletionManager {
LibraryMemberContributor(request, builder),
LibraryPrefixContributor(request, builder),
NamedConstructorContributor(request, builder),
if (enableOverrideContributor) OverrideContributor(request, builder),
RecordLiteralContributor(request, builder),
if (enableUriContributor) UriContributor(request, builder),
VariableNameContributor(request, builder),
Expand All @@ -155,7 +153,11 @@ class DartCompletionManager {
await performance.runAsync(
'InScopeCompletionPass',
(performance) async {
_runFirstPass(request, builder, includedElementKinds != null);
_runFirstPass(
request: request,
builder: builder,
skipImports: includedElementKinds != null,
suggestOverrides: enableOverrideContributor);
},
);
for (var contributor in contributors) {
Expand Down Expand Up @@ -216,16 +218,22 @@ class DartCompletionManager {
}

// Run the first pass of the code completion algorithm.
void _runFirstPass(DartCompletionRequest request, SuggestionBuilder builder,
bool skipImports) {
void _runFirstPass(
{required DartCompletionRequest request,
required SuggestionBuilder builder,
required bool skipImports,
required bool suggestOverrides}) {
var collector = SuggestionCollector();
var selection = request.unit.select(offset: request.offset, length: 0);
if (selection == null) {
throw AbortCompletion();
}
var state = CompletionState(request, selection);
var pass = InScopeCompletionPass(
state: state, collector: collector, skipImports: skipImports);
state: state,
collector: collector,
skipImports: skipImports,
suggestOverrides: suggestOverrides);
pass.computeSuggestions();
builder.suggestFromCandidates(collector.suggestions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:analysis_server/src/services/completion/dart/completion_state.da
import 'package:analysis_server/src/services/completion/dart/declaration_helper.dart';
import 'package:analysis_server/src/services/completion/dart/keyword_helper.dart';
import 'package:analysis_server/src/services/completion/dart/label_helper.dart';
import 'package:analysis_server/src/services/completion/dart/override_helper.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_collector.dart';
import 'package:analysis_server/src/services/completion/dart/visibility_tracker.dart';
import 'package:analysis_server/src/utilities/extensions/ast.dart';
Expand All @@ -18,6 +19,7 @@ import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/ast/token.dart';
Expand All @@ -42,6 +44,9 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
/// suggestions are being produced by the various passes.
final bool skipImports;

/// Whether suggestions for overrides should be produced.
final bool suggestOverrides;

/// The helper used to suggest keywords.
late final KeywordHelper keywordHelper = KeywordHelper(
collector: collector, featureSet: featureSet, offset: offset);
Expand All @@ -52,6 +57,10 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
/// The helper used to suggest declarations that are in scope.
DeclarationHelper? _declarationHelper;

/// The helper used to suggest overrides of inherited members.
late final OverrideHelper overrideHelper =
OverrideHelper(collector: collector, state: state);

/// Initialize a newly created completion visitor that can use the [state] to
/// add candidate suggestions to the [collector].
///
Expand All @@ -60,7 +69,8 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
InScopeCompletionPass(
{required this.state,
required this.collector,
required this.skipImports});
required this.skipImports,
required this.suggestOverrides});

/// Return the feature set that applies to the library for which completions
/// are being computed.
Expand Down Expand Up @@ -454,14 +464,19 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
var members = node.members;
// TODO(brianwilkerson): Generalize this to check for unattatched
// annotations in other places.
var token =
members.elementBefore(offset)?.beginToken ?? node.leftBracket.next!;
var preceedingMember = members.elementBefore(offset);
var token = preceedingMember?.beginToken ?? node.leftBracket.next!;
if (token.type == TokenType.AT) {
// We are completing at the beginning of an annotation.
// The user is completing at the beginning of an annotation.
// TODO(brianwilkerson): We need to check the next token to see whether
// part of the annotation is already there.
_forAnnotation(node);
return;
} else if (token.keyword == Keyword.FINAL) {
// The user is completing after the keyword `final`, so they're likely
// trying to declare a field.
_forTypeAnnotation(node);
return;
}
collector.completionLocation = 'ClassDeclaration_member';
_forClassMember(node);
Expand All @@ -472,6 +487,8 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
keywordHelper.addFunctionBodyModifiers(body);
}
}
// TODO(brianwilkerson): Consider enabling the generation of overrides in
// this location.
} else {
// The cursor is immediately to the right of the right bracket, so the
// user is starting a new top-level declaration.
Expand Down Expand Up @@ -883,10 +900,22 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
_forClassLikeMember(parent);
}
} else if (offset <= type.end) {
keywordHelper.addFieldDeclarationKeywords(node);
// TODO(brianwilkerson): `var` should only be suggested if neither
// `static` nor `final` are present.
keywordHelper.addKeyword(Keyword.VAR);
// TODO(brianwilkerson): Add support for the failing test
// `OverrideTestCases.test_class_method_beforeField`.
if (node.isSingleIdentifier) {
// The user has typed only part of an identifier / keyword. Recovery
// sees this as a field, but it could be the start of any kind of
// member.
var parent = node.parent;
if (parent != null) {
_forClassLikeMember(parent);
}
} else {
keywordHelper.addFieldDeclarationKeywords(node);
// TODO(brianwilkerson): `var` should only be suggested if neither
// `static` nor `final` are present.
keywordHelper.addKeyword(Keyword.VAR);
}
}
}
}
Expand Down Expand Up @@ -1432,6 +1461,8 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
keywordHelper.addFunctionBodyModifiers(body);
}
}
// TODO(brianwilkerson): Consider enabling the generation of overrides in
// this location.
}
}

Expand Down Expand Up @@ -2103,7 +2134,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
keywordHelper.addKeyword(Keyword.LATE);
}
}
if (node.name == grandparent.beginToken) {
if (node.name == grandparent.firstTokenAfterCommentAndMetadata) {
// The parser often recovers from incomplete code by assuming that
// the user is typing a field declaration, but it's quite possible
// that the user is trying to type a different kind of declaration.
Expand All @@ -2115,6 +2146,13 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
keywordHelper.addKeyword(Keyword.OPERATOR);
keywordHelper.addKeyword(Keyword.SET);
}
if (grandparent.isSingleIdentifier) {
_suggestOverridesFor(switch (container) {
ClassDeclaration() => container.declaredElement,
MixinDeclaration() => container.declaredElement,
_ => null,
});
}
} else if (grandparent is TopLevelVariableDeclaration) {
if (grandparent.externalKeyword == null) {
keywordHelper.addKeyword(Keyword.EXTERNAL);
Expand Down Expand Up @@ -2239,6 +2277,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
void _forClassMember(ClassDeclaration node) {
keywordHelper.addClassMemberKeywords();
declarationHelper(mustBeType: true).addLexicalDeclarations(node);
_suggestOverridesFor(node.declaredElement);
}

/// Add the suggestions that are appropriate when the selection is at the
Expand Down Expand Up @@ -2464,6 +2503,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
void _forMixinMember(MixinDeclaration node) {
keywordHelper.addMixinMemberKeywords();
declarationHelper(mustBeType: true).addLexicalDeclarations(node);
_suggestOverridesFor(node.declaredElement);
}

/// Adds the suggestions that are appropriate when the selection is in the
Expand Down Expand Up @@ -2685,6 +2725,15 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
return false;
}

/// If allowed, suggest overrides in the context of the given [element].
void _suggestOverridesFor(InterfaceElement? element) {
// TODO(brianwilkerson): Check whether there's sufficient remaining time
// before computing suggestions for overrides.
if (suggestOverrides && element != null) {
overrideHelper.computeOverridesFor(element, SourceRange(offset, 0));
}
}

void _visitForEachParts(ForEachParts node) {
if (node.inKeyword.coversOffset(offset)) {
var previous = node.findPrevious(node.inKeyword);
Expand Down Expand Up @@ -3015,7 +3064,7 @@ extension on ExtensionTypeDeclaration {
extension on FieldDeclaration {
/// Whether this field declaration consists of a single identifier.
bool get isSingleIdentifier {
var first = beginToken;
var first = firstTokenAfterCommentAndMetadata;
var last = endToken;
return first.isKeywordOrIdentifier &&
last.isSynthetic &&
Expand Down
Loading

0 comments on commit 728fcf0

Please sign in to comment.