Skip to content

Commit

Permalink
Version 3.4.0-239.0.dev
Browse files Browse the repository at this point in the history
Merge f792cc1 into dev
  • Loading branch information
Dart CI committed Mar 16, 2024
2 parents 2241333 + f792cc1 commit 934c41c
Show file tree
Hide file tree
Showing 127 changed files with 1,488 additions and 1,219 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ advantage of these improvements, set your package's
`ignored_advisories` section in the `pubspec.yaml` file. To learn more about
pub's support for security advisories, visit
[dart.dev/go/pub-security-advisories][pub-security-advisories].
- `path`-dependencies inside `git`-dependencies are now resolved relative to the git
repo.
- New command `dart pub unpack` that downloads a package from pub.dev and
extracts it to a subfolder of the current directory.

Expand Down
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ vars = {
"path_rev": "a7b696071bd83d3ee0a0f1b57ac94d6b1f05cac4",
"pool_rev": "c118f69d8a6441a8453bf7d455fd7c79d3ee1497",
"protobuf_rev": "b7613581d847e1e36e76f0e36db3a412d8fea5b1",
"pub_rev": "5b5fdd320a3b60a6a00bdd3122f03c6f67a39eeb", # disable tools/rev_sdk_deps.dart
"pub_rev": "e519de6b6da5aea4f78e58f8906059cc6c2a5993", # disable tools/rev_sdk_deps.dart
"pub_semver_rev": "3175ba0a58a96fb23f8d68b5f5c44d1a5b30cc16",
"shelf_rev": "1acbc673326e5b31280184744f2864a8f92c5b46",
"source_map_stack_trace_rev": "c75649651d01826236e3ab7093d277a70756905a",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import 'package:analysis_server/src/services/completion/dart/record_literal_cont
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_collector.dart';
import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart';
import 'package:analysis_server/src/utilities/selection.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
Expand Down Expand Up @@ -130,7 +129,6 @@ class DartCompletionManager {
LibraryPrefixContributor(request, builder),
RecordLiteralContributor(request, builder),
if (enableUriContributor) UriContributor(request, builder),
VariableNameContributor(request, builder),
];

if (includedElementKinds != null) {
Expand Down Expand Up @@ -292,6 +290,12 @@ class DartCompletionRequest {

bool _aborted = false;

/// Return `true` if the completion is occurring in a constant context.
late final bool inConstantContext = () {
var entity = target.entity;
return entity is Expression && entity.inConstantContext;
}();

factory DartCompletionRequest({
required AnalysisSession analysisSession,
required String filePath,
Expand Down Expand Up @@ -389,12 +393,6 @@ class DartCompletionRequest {
return opType.includeIdentifiers;
}

/// Return `true` if the completion is occurring in a constant context.
bool get inConstantContext {
var entity = target.entity;
return entity is Expression && entity.inConstantContext;
}

InheritanceManager3 get inheritanceManager {
return analysisSession.inheritanceManager;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analysis_server/src/services/completion/dart/candidate_suggestion.dart';
import 'package:analysis_server/src/services/completion/dart/completion_state.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_collector.dart';
import 'package:analysis_server/src/services/correction/name_suggestion.dart';
import 'package:analysis_server/src/utilities/extensions/string.dart';
import 'package:analyzer/dart/ast/ast.dart';

/// A helper class that produces candidate suggestions for identifiers when the
/// completion location is in a declaration site.
class IdentifierHelper {
/// The state used to compute the candidate suggestions.
final CompletionState state;

/// The suggestion collector to which suggestions will be added.
final SuggestionCollector collector;

/// Whether private version of names should be included.
final bool includePrivateIdentifiers;

/// Initialize a newly created helper to add suggestions to the [collector].
IdentifierHelper(
{required this.state,
required this.collector,
required this.includePrivateIdentifiers});

/// Adds any suggestions for the name of the [parameter].
void addParameterName(FormalParameter parameter) {
if (parameter is DefaultFormalParameter) {
parameter = parameter.parameter;
}
if (parameter is SimpleFormalParameter) {
addVariable(parameter.type);
}
}

/// Adds suggestions based on the [typeName].
void addSuggestionsFromTypeName(String typeName) {
var variableNameSuggestions = getCamelWordCombinations(typeName);
variableNameSuggestions.remove(typeName);
for (var varName in variableNameSuggestions) {
_createNameSuggestion(varName);
if (includePrivateIdentifiers) {
_createNameSuggestion('_$varName');
}
}
}

/// Adds any suggestions for the name of a top-level declaration (class, enum,
/// mixin, function, etc.).
void addTopLevelName() {
var context = state.request.analysisSession.resourceProvider.pathContext;
var path = state.request.path;
var candidateName = context.basenameWithoutExtension(path).toUpperCamelCase;
if (candidateName == null) {
return;
}
for (var unit in state.libraryElement.units) {
for (var childElement in unit.children) {
if (childElement.name == candidateName) {
// Don't suggest a name that's already declared in the library.
return;
}
}
}
collector.addSuggestion(IdentifierSuggestion(identifier: candidateName));
}

/// Adds any suggestions for a variable with the given [type].
void addVariable(TypeAnnotation? type) {
if (type is NamedType) {
addSuggestionsFromTypeName(type.name2.lexeme);
}
}

/// Adds a suggestion for the [name] (unless the name is `null` or empty).
void _createNameSuggestion(String name) {
if (name.isNotEmpty) {
collector.addSuggestion(IdentifierSuggestion(identifier: name));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'package:analysis_server/src/services/completion/dart/candidate_suggestion.dart';
import 'package:analysis_server/src/services/completion/dart/completion_state.dart';
import 'package:analysis_server/src/services/completion/dart/declaration_helper.dart';
import 'package:analysis_server/src/services/completion/dart/identifier_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';
Expand Down Expand Up @@ -49,6 +50,9 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
/// Whether suggestions for overrides should be produced.
final bool suggestOverrides;

/// The helper used to suggest names at the declaration site.
IdentifierHelper? _identifierHelper;

/// The helper used to suggest keywords.
late final KeywordHelper keywordHelper = KeywordHelper(
collector: collector, featureSet: featureSet, offset: offset);
Expand Down Expand Up @@ -194,6 +198,22 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
);
}

/// Returns the helper used to suggest names at the declaration site.
IdentifierHelper identifierHelper({required bool includePrivateIdentifiers}) {
// Ensure that we aren't attempting to create multiple declaration helpers
// with inconsistent states.
assert(() {
var helper = _identifierHelper;
return helper == null ||
(helper.includePrivateIdentifiers == includePrivateIdentifiers);
}());
return _identifierHelper ??= IdentifierHelper(
collector: collector,
includePrivateIdentifiers: includePrivateIdentifiers,
state: state,
);
}

@override
void visitAdjacentStrings(AdjacentStrings node) {
_visitParentIfAtOrBeforeNode(node);
Expand Down Expand Up @@ -506,7 +526,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
} else if (offset <= node.classKeyword.end) {
keywordHelper.addKeyword(Keyword.CLASS);
} else if (offset <= node.name.end) {
// TODO(brianwilkerson): Suggest a name for the class.
identifierHelper(includePrivateIdentifiers: false).addTopLevelName();
} else if (offset <= node.leftBracket.offset) {
keywordHelper.addClassDeclarationKeywords(node);
} else if (offset >= node.leftBracket.end &&
Expand Down Expand Up @@ -786,7 +806,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
return;
}
if (offset <= node.name.end) {
// TODO(brianwilkerson): Suggest a name for the mixin.
identifierHelper(includePrivateIdentifiers: false).addTopLevelName();
return;
}
if (offset <= node.leftBracket.offset) {
Expand Down Expand Up @@ -866,6 +886,16 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
}
} else if (expression is IsExpression) {
expression.accept(this);
} else if (expression is FunctionReference) {
if (offset > expression.end) {
var function = expression.function;
if (function is SimpleIdentifier) {
/// This might be the beginning of a local variable declatation
/// consisting of a type name with type arguments.
identifierHelper(includePrivateIdentifiers: false)
.addSuggestionsFromTypeName(function.name);
}
}
} else if (expression is MethodInvocation) {
if (offset <= expression.beginToken.end) {
_forStatement(node);
Expand All @@ -878,9 +908,21 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
).addLexicalDeclarations(node);
} else if (offset <= expression.identifier.end) {
// TODO(brianwilkerson): Suggest members of the identifier's type.
} else {
/// This might be the beginning of a local variable declatation
/// consisting of a prefixed type name.
identifierHelper(includePrivateIdentifiers: false)
.addSuggestionsFromTypeName(expression.identifier.name);
}
} else if (expression is SimpleIdentifier) {
if (offset <= expression.end) {
_forStatement(node);
} else {
/// This might be the beginning of a local variable declatation
/// consisting of a simple type name.
identifierHelper(includePrivateIdentifiers: false)
.addSuggestionsFromTypeName(expression.name);
}
} else if (expression is SimpleIdentifier && offset <= expression.end) {
_forStatement(node);
}
}

Expand Down Expand Up @@ -915,8 +957,10 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
if (featureSet.isEnabled(Feature.inline_class)) {
keywordHelper.addPseudoKeyword('type');
}
// TODO(brianwilkerson): Suggest a name for the extension.
identifierHelper(includePrivateIdentifiers: false).addTopLevelName();
return;
} else {
identifierHelper(includePrivateIdentifiers: false).addTopLevelName();
}
if (offset <= node.leftBracket.offset) {
if (node.onKeyword.isSynthetic) {
Expand All @@ -942,6 +986,8 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
if (offset == node.offset) {
_forCompilationUnitMemberBefore(node);
} else if (offset <= node.name.end) {
identifierHelper(includePrivateIdentifiers: false).addTopLevelName();
} else if (offset >= node.representation.end &&
(offset <= node.leftBracket.offset || node.leftBracket.isSynthetic)) {
keywordHelper.addKeyword(Keyword.IMPLEMENTS);
Expand Down Expand Up @@ -1055,9 +1101,23 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
}
var parameters = node.parameters;
var precedingParameter = parameters.elementBefore(offset);
if (precedingParameter != null && precedingParameter.isIncomplete) {
precedingParameter.accept(this);
return;
if (precedingParameter != null) {
if (precedingParameter.isIncomplete) {
precedingParameter.accept(this);
return;
}
if (precedingParameter is SimpleFormalParameter) {
if (precedingParameter.type == null &&
offset > precedingParameter.end) {
// The name might be a type and the user might be trying to type a
// name for the parameter.
var name = precedingParameter.name?.lexeme;
if (name != null) {
identifierHelper(includePrivateIdentifiers: false)
.addSuggestionsFromTypeName(name);
}
}
}
}

collector.completionLocation = 'FormalParameterList_parameter';
Expand Down Expand Up @@ -1543,7 +1603,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
return;
}
if (offset <= node.name.end) {
// TODO(brianwilkerson): Suggest a name for the mixin.
identifierHelper(includePrivateIdentifiers: false).addTopLevelName();
return;
}
if (offset <= node.leftBracket.offset) {
Expand Down Expand Up @@ -1852,6 +1912,8 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
) {
if (node.type.coversOffset(offset)) {
_forTypeAnnotation(node);
} else if (node.name.coversOffset(offset)) {
identifierHelper(includePrivateIdentifiers: false).addVariable(node.type);
}
}

Expand Down Expand Up @@ -1917,12 +1979,23 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
}

var fieldName = node.fieldName;
if (offset <= fieldName.end && node.fieldType.isFullySynthetic) {
if (fieldName.isSynthetic && hasIncompleteAnnotation()) {
_forAnnotation(node);
if (offset <= fieldName.end) {
var fieldType = node.fieldType;
if (fieldType.isFullySynthetic) {
if (fieldName.isSynthetic && hasIncompleteAnnotation()) {
_forAnnotation(node);
} else {
declarationHelper(mustBeType: true).addLexicalDeclarations(node);
}
} else {
declarationHelper(mustBeType: true).addLexicalDeclarations(node);
identifierHelper(includePrivateIdentifiers: true)
.addVariable(fieldType);
}
} else {
// The name might be a type and the user might be trying to type a name
// for the variable.
identifierHelper(includePrivateIdentifiers: true)
.addSuggestionsFromTypeName(fieldName.lexeme);
}
}

Expand Down Expand Up @@ -2186,7 +2259,17 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
}
var variableDeclarationList = node.variables;
var variables = variableDeclarationList.variables;
if (variables.isEmpty || offset > variables.first.beginToken.end) {
if (variables.isEmpty) {
return;
}
var firstVariable = variables.first;
if (offset > firstVariable.beginToken.end) {
if (variableDeclarationList.type == null) {
// The name might be a type and the user might be trying to type a name
// for the variable.
identifierHelper(includePrivateIdentifiers: true)
.addSuggestionsFromTypeName(firstVariable.name.lexeme);
}
return;
}
if (node.externalKeyword == null) {
Expand Down Expand Up @@ -2308,7 +2391,8 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
if (offset <= node.name.end) {
var container = grandparent?.parent;
var keyword = parent.keyword;
if (parent.type == null) {
var type = parent.type;
if (type == null) {
if (keyword == null) {
keywordHelper.addKeyword(Keyword.CONST);
keywordHelper.addKeyword(Keyword.FINAL);
Expand All @@ -2317,6 +2401,11 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
if (keyword == null || keyword.keyword != Keyword.VAR) {
_forTypeAnnotation(node);
}
} else {
var canBePrivate = grandparent is FieldDeclaration ||
grandparent is TopLevelVariableDeclaration;
identifierHelper(includePrivateIdentifiers: canBePrivate)
.addVariable(type);
}
if (grandparent is FieldDeclaration) {
if (grandparent.externalKeyword == null) {
Expand Down Expand Up @@ -2685,7 +2774,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
case IfStatement declaration:
if (declaration.elseKeyword == null) {
keywordHelper.addKeyword(Keyword.ELSE);
return true;
return false;
}
case TryStatement declaration:
if (declaration.finallyBlock == null) {
Expand Down
Loading

0 comments on commit 934c41c

Please sign in to comment.