diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart index d852030b7453..8581f4ffccaa 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart @@ -9,6 +9,7 @@ import 'package:analysis_server/src/services/completion/dart/completion_manager. import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart' show SuggestionBuilder; import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/dart/element/visitor.dart'; import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; @@ -52,10 +53,14 @@ class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor { _addConstructorSuggestions(element); } if (opType.includeReturnValueSuggestions) { - if (element.isEnum) { - for (var field in element.fields) { - if (field.isEnumConstant) { - builder.suggestEnumConstant(field, prefix: prefix); + final typeSystem = request.libraryElement.typeSystem; + final contextType = request.contextType; + if (contextType is InterfaceType) { + // TODO(scheglov) This looks not ideal - we should suggest getters. + for (final field in element.fields) { + if (field.isStatic && + typeSystem.isSubtypeOf(field.type, contextType)) { + builder.suggestStaticField(field, prefix: prefix); } } } diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart index 9028362337f1..3eb06e26cbf3 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart @@ -213,24 +213,7 @@ class _LocalVisitor extends LocalDeclarationVisitor { @override void declaredClass(ClassDeclaration declaration) { - var classElt = declaration.declaredElement; - if (classElt != null && visibilityTracker._isVisible(classElt)) { - if (opType.includeTypeNameSuggestions) { - builder.suggestClass(classElt); - } - - // Generate the suggestions for the constructors. We are required to loop - // through elements here instead of using declaredConstructor() due to - // implicit constructors (i.e. there is no AstNode for an implicit - // constructor) - if (!opType.isPrefixed && opType.includeConstructorSuggestions) { - for (var constructor in classElt.constructors) { - if (!classElt.isAbstract || constructor.isFactory) { - builder.suggestConstructor(constructor); - } - } - } - } + _declaredClassElement(declaration.declaredElement); } @override @@ -248,20 +231,7 @@ class _LocalVisitor extends LocalDeclarationVisitor { @override void declaredEnum(EnumDeclaration declaration) { - var declaredElement = declaration.declaredElement; - if (declaredElement != null && - visibilityTracker._isVisible(declaredElement) && - opType.includeTypeNameSuggestions) { - builder.suggestClass(declaredElement); - for (var enumConstant in declaration.constants) { - if (!enumConstant.isSynthetic) { - var constantElement = enumConstant.declaredElement; - if (constantElement is FieldElement) { - builder.suggestEnumConstant(constantElement); - } - } - } - } + _declaredClassElement(declaration.declaredElement); } @override @@ -437,6 +407,38 @@ class _LocalVisitor extends LocalDeclarationVisitor { super.visitExtendsClause(node); } + void _declaredClassElement(ClassElement? class_) { + if (class_ != null && visibilityTracker._isVisible(class_)) { + if (opType.includeTypeNameSuggestions) { + builder.suggestClass(class_); + } + + if (!opType.isPrefixed && + opType.includeConstructorSuggestions && + !class_.isEnum) { + for (final constructor in class_.constructors) { + if (!class_.isAbstract || constructor.isFactory) { + builder.suggestConstructor(constructor); + } + } + } + + if (!opType.isPrefixed && opType.includeReturnValueSuggestions) { + final typeSystem = request.libraryElement.typeSystem; + final contextType = request.contextType; + if (contextType is InterfaceType) { + // TODO(scheglov) This looks not ideal - we should suggest getters. + for (final field in class_.fields) { + if (field.isStatic && + typeSystem.isSubtypeOf(field.type, contextType)) { + builder.suggestStaticField(field); + } + } + } + } + } + } + /// Return `true` if the [identifier] is composed of one or more underscore /// characters and nothing else. bool _isUnused(String identifier) => RegExp(r'^_+$').hasMatch(identifier); diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart index ba159244a47c..0dc24900468a 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart @@ -237,10 +237,17 @@ class SuggestionBuilder { /// invocation. The [inheritanceDistance] is the value of the inheritance /// distance feature computed for the accessor or `-1.0` if the accessor is a /// static accessor. - void suggestAccessor(PropertyAccessorElement accessor, - {required double inheritanceDistance}) { - assert(accessor.enclosingElement is ClassElement || - accessor.enclosingElement is ExtensionElement); + void suggestAccessor( + PropertyAccessorElement accessor, { + required double inheritanceDistance, + bool withEnclosingName = false, + }) { + var enclosingPrefix = ''; + var enclosingName = _enclosingClassOrExtensionName(accessor); + if (withEnclosingName && enclosingName != null) { + enclosingPrefix = '$enclosingName.'; + } + if (accessor.isSynthetic) { // Avoid visiting a field twice. All fields induce a getter, but only // non-final fields induce a setter, so we don't add a suggestion for a @@ -280,6 +287,7 @@ class SuggestionBuilder { _addBuilder( _createCompletionSuggestionBuilder( accessor, + completion: enclosingPrefix + accessor.displayName, kind: CompletionSuggestionKind.IDENTIFIER, relevance: relevance, isNotImported: isNotImportedLibrary, @@ -926,6 +934,43 @@ class SuggestionBuilder { ); } + /// Add a suggestion for a static field declared within a class or extension. + /// If the field is synthetic, add the corresponding getter instead. + /// + /// If the enclosing element can only be referenced using a prefix, then + /// the [prefix] should be provided. + void suggestStaticField(FieldElement element, {String? prefix}) { + assert(element.isStatic); + if (element.isSynthetic) { + var getter = element.getter; + if (getter != null) { + suggestAccessor( + getter, + inheritanceDistance: 0.0, + withEnclosingName: true, + ); + } + } else { + var enclosingPrefix = ''; + var enclosingName = _enclosingClassOrExtensionName(element); + if (enclosingName != null) { + enclosingPrefix = '$enclosingName.'; + } + var relevance = + _computeTopLevelRelevance(element, elementType: element.type); + _addBuilder( + _createCompletionSuggestionBuilder( + element, + completion: enclosingPrefix + element.name, + kind: CompletionSuggestionKind.IDENTIFIER, + prefix: prefix, + relevance: relevance, + isNotImported: isNotImportedLibrary, + ), + ); + } + } + /// Add a suggestion to reference a [parameter] in a super formal parameter. void suggestSuperFormalParameter(ParameterElement parameter) { _addBuilder( @@ -1289,6 +1334,22 @@ class SuggestionBuilder { ); } + /// Return the name of the enclosing class or extension. + /// + /// The enclosing element must be either a class, or extension; otherwise + /// we either fail with assertion, or return `null`. + String? _enclosingClassOrExtensionName(Element element) { + var enclosing = element.enclosingElement; + if (enclosing is ClassElement) { + return enclosing.name; + } else if (enclosing is ExtensionElement) { + return enclosing.name; + } else { + assert(false, 'Expected ClassElement or ExtensionElement'); + return null; + } + } + /// If the [element] has a documentation comment, return it. _ElementDocumentation? _getDocumentation(Element element) { var documentationCache = request.documentationCache; diff --git a/pkg/analysis_server/test/client/completion_driver_test.dart b/pkg/analysis_server/test/client/completion_driver_test.dart index 0508315ea594..9d8f5e40e1a5 100644 --- a/pkg/analysis_server/test/client/completion_driver_test.dart +++ b/pkg/analysis_server/test/client/completion_driver_test.dart @@ -267,7 +267,7 @@ class CompletionWithSuggestionsTest1 extends AbstractCompletionDriverTest @override TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1; - @failingTest + @FailingTest(reason: 'This test fails with available suggestions') @override Future test_project_lib_multipleExports() async { return super.test_project_lib_multipleExports(); @@ -329,7 +329,7 @@ export 'a.dart'; await addTestFile(''' import 'a.dart'; void f() { - ^ + E v = ^ } '''); assertSuggestion( @@ -605,7 +605,7 @@ void f() { Future test_project_lib_setters_static() async { newFile('$testPackageLibPath/a.dart', r''' class A { - static set g(int g) {} + static set foo(int _) {} } '''); @@ -619,7 +619,7 @@ void f() { } '''); - assertNoSuggestion(completion: 'A.g'); + assertNoSuggestion(completion: 'A.foo'); } /// See: https://github.com/dart-lang/sdk/issues/40626 diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart index f86e1d876fd7..3a86b88af9b3 100644 --- a/pkg/analysis_server/test/domain_completion_test.dart +++ b/pkg/analysis_server/test/domain_completion_test.dart @@ -391,44 +391,6 @@ void f() { ..suggestions.withElementClass.isEmpty; } - Future test_notImported_lowerRelevance_enumConstant() async { - newFile('$testPackageLibPath/a.dart', ''' -enum E1 { - foo01 -} -'''); - - newFile('$testPackageLibPath/b.dart', ''' -enum E2 { - foo02 -} -'''); - - await _configureWithWorkspaceRoot(); - - var response = await _getTestCodeSuggestions(''' -import 'b.dart'; - -void f() { - foo0^ -} -'''); - - check(response) - ..assertComplete() - ..hasReplacement(left: 4); - - // `foo01` relevance is decreased because it is not yet imported. - check(response).suggestions.matches([ - (suggestion) => suggestion - ..completion.isEqualTo('E2.foo02') - ..libraryUriToImport.isNull, - (suggestion) => suggestion - ..completion.isEqualTo('E1.foo01') - ..libraryUriToImport.isEqualTo('package:test/a.dart'), - ]); - } - Future test_notImported_lowerRelevance_extension_getter() async { await _configureWithWorkspaceRoot(); diff --git a/pkg/analysis_server/test/services/completion/dart/completion_check.dart b/pkg/analysis_server/test/services/completion/dart/completion_check.dart index 242212c3c6b6..0a2ffaddf4e9 100644 --- a/pkg/analysis_server/test/services/completion/dart/completion_check.dart +++ b/pkg/analysis_server/test/services/completion/dart/completion_check.dart @@ -266,6 +266,20 @@ extension CompletionSuggestionExtension element.isNotNull.kind.isSetter; } + void get isStatic { + element.isNotNull.isStatic.isTrue; + } + + void get isStaticField { + isStatic; + isField; + } + + void get isStaticGetter { + isStatic; + isGetter; + } + void get isTopLevelVariable { kind.isIdentifier; element.isNotNull.kind.isTopLevelVariable; @@ -404,6 +418,45 @@ extension CompletionSuggestionsExtension ); } + @useResult + CheckTarget> get fields { + var result = value + .where((suggestion) => + suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER && + suggestion.suggestion.element?.kind == ElementKind.FIELD) + .toList(); + return nest( + result, + (selected) => 'fields ${valueStr(selected)}', + ); + } + + @useResult + CheckTarget> get getters { + var result = value + .where((suggestion) => + suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER && + suggestion.suggestion.element?.kind == ElementKind.GETTER) + .toList(); + return nest( + result, + (selected) => 'getters ${valueStr(selected)}', + ); + } + + @useResult + CheckTarget> get methods { + var result = value + .where((suggestion) => + suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER && + suggestion.suggestion.element?.kind == ElementKind.METHOD) + .toList(); + return nest( + result, + (selected) => 'setters ${valueStr(selected)}', + ); + } + @useResult CheckTarget> get namedArguments { var result = value @@ -429,6 +482,19 @@ extension CompletionSuggestionsExtension ); } + @useResult + CheckTarget> get setters { + var result = value + .where((suggestion) => + suggestion.suggestion.kind == CompletionSuggestionKind.IDENTIFIER && + suggestion.suggestion.element?.kind == ElementKind.SETTER) + .toList(); + return nest( + result, + (selected) => 'setters ${valueStr(selected)}', + ); + } + @useResult CheckTarget> get withElementClass { return nest( @@ -453,6 +519,14 @@ extension CompletionSuggestionsExtension } extension ElementExtension on CheckTarget { + @useResult + CheckTarget get isStatic { + return nest( + value.isStatic, + (selected) => 'isStatic ${valueStr(selected)}', + ); + } + @useResult CheckTarget get kind { return nest( diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/class_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/class_test.dart new file mode 100644 index 000000000000..cd5382bb497a --- /dev/null +++ b/pkg/analysis_server/test/services/completion/dart/declaration/class_test.dart @@ -0,0 +1,249 @@ +// Copyright (c) 2022, 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:analyzer_utilities/check/check.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../../../../client/completion_driver_test.dart'; +import '../completion_check.dart'; + +void main() { + defineReflectiveSuite(() { + defineReflectiveTests(ClassStaticMembersWithoutClassNameTest); + }); +} + +@reflectiveTest +class ClassStaticMembersWithoutClassNameTest + extends AbstractCompletionDriverTest with _Helpers { + @override + TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2; + + Future test_field_hasContextType_exact() async { + await _checkLocations( + classCode: r''' +class A { + static final int foo01 = 0; + static final num foo02 = 0; + static final double foo03 = 0; + final int foo04 = 0; +} +''', + contextCode: r''' +void f() { + int a = foo0^ +} +''', + validator: (response) { + check(response).suggestions.fields.completions.matchesInAnyOrder([ + (e) => e.isEqualTo('A.foo01'), + ]); + }, + ); + } + + Future test_field_hasContextType_subtypes() async { + await _checkLocations( + classCode: r''' +class A { + static final int foo01 = 0; + static final double foo02 = 0; + static final num foo03 = 0; + static final Object foo04 = ''; +} +''', + contextCode: r''' +void f() { + num a = foo0^ +} +''', + validator: (response) { + check(response).suggestions.fields.completions.matchesInAnyOrder([ + (e) => e.isEqualTo('A.foo01'), + (e) => e.isEqualTo('A.foo02'), + (e) => e.isEqualTo('A.foo03'), + ]); + }, + ); + } + + Future test_field_noContextType() async { + await _checkLocations( + classCode: r''' +class A { + static final foo01 = 0; + static final foo02 = 0; + final foo03 = 0; +} +''', + contextCode: r''' +void f() { + foo0^ +} +''', + validator: (response) { + check(response).suggestions.fields.isEmpty; + }, + ); + } + + Future test_getter_hasContextType_exact() async { + await _checkLocations( + classCode: r''' +class A { + static int get foo01 => 0; + static num get foo02 => 0; + static double get foo03 => 0; +} +''', + contextCode: r''' +void f() { + int a = foo0^ +} +''', + validator: (response) { + check(response).suggestions.getters.completions.matchesInAnyOrder([ + (e) => e.isEqualTo('A.foo01'), + ]); + }, + ); + } + + Future test_getter_hasContextType_subtypes() async { + await _checkLocations( + classCode: r''' +class A { + static int get foo01 => 0; + static double get foo02 => 0; + static num get foo03 => 0; + static Object get foo04 => ''; +} +''', + contextCode: r''' +void f() { + num a = foo0^ +} +''', + validator: (response) { + check(response).suggestions.getters.completions.matchesInAnyOrder([ + (e) => e.isEqualTo('A.foo01'), + (e) => e.isEqualTo('A.foo02'), + (e) => e.isEqualTo('A.foo03'), + ]); + }, + ); + } + + Future test_getter_noContextType() async { + await _checkLocations( + classCode: r''' +class A { + static int get foo01 => 0; +} +''', + contextCode: r''' +void f() { + foo0^ +} +''', + validator: (response) { + check(response).suggestions.getters.isEmpty; + }, + ); + } + + Future test_method() async { + await _checkLocations( + classCode: r''' +class A { + static void foo01() {} +} +''', + contextCode: r''' +void f() { + foo0^ +} +''', + validator: (response) { + check(response).suggestions.methods.isEmpty; + }, + ); + } + + Future test_setter_hasContextType() async { + await _checkLocations( + classCode: r''' +class A { + static set foo01(int _) {} + static set foo02(num _) {} + static set foo03(double _) {} +} +''', + contextCode: r''' +void f() { + int a = foo0^ +} +''', + validator: (response) { + check(response).suggestions.setters.isEmpty; + }, + ); + } + + Future test_setter_noContextType() async { + await _checkLocations( + classCode: r''' +class A { + static set foo01(int _) {} +} +''', + contextCode: r''' +void f() { + foo0^ +} +''', + validator: (response) { + check(response).suggestions.setters.isEmpty; + }, + ); + } +} + +mixin _Helpers on AbstractCompletionDriverTest { + Future _checkLocations({ + required String classCode, + required String contextCode, + required void Function(CompletionResponseForTesting response) validator, + }) async { + // local + { + final response = await getTestCodeSuggestions(''' +$classCode + +$contextCode +'''); + validator(response); + } + + // imported, without prefix + { + newFile('$testPackageLibPath/a.dart', classCode); + final response = await getTestCodeSuggestions(''' +import 'a.dart'; + +$contextCode +'''); + validator(response); + } + + // not imported + { + newFile('$testPackageLibPath/a.dart', classCode); + final response = await getTestCodeSuggestions(''' +$contextCode +'''); + validator(response); + } + } +} diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart index cb8804786680..e15b3373fcdd 100644 --- a/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart +++ b/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart @@ -30,8 +30,12 @@ class EnumTest2 extends AbstractCompletionDriverTest with EnumTestCases { mixin EnumTestCases on AbstractCompletionDriverTest { Future test_enumConstantName() async { await _check_locations( - declaration: 'enum MyEnum { foo01 }', - codeAtCompletion: 'foo0^', + declaration: ''' +enum MyEnum { foo01 } +enum OtherEnum { foo02 } +''', + declarationForContextType: 'void useMyEnum(MyEnum _) {}', + codeAtCompletion: 'useMyEnum(foo0^);', validator: (response) { check(response).hasReplacement(left: 4); @@ -61,6 +65,7 @@ mixin EnumTestCases on AbstractCompletionDriverTest { Future test_enumConstantName_imported_withPrefix() async { newFile('$testPackageLibPath/a.dart', r''' enum MyEnum { foo01 } +enum OtherEnum { foo02 } '''); if (isProtocolVersion1) { @@ -70,8 +75,10 @@ enum MyEnum { foo01 } var response = await getTestCodeSuggestions(''' import 'a.dart' as prefix; +void useMyEnum(prefix.MyEnum _) {} + void f() { - foo0^ + useMyEnum(foo0^); } '''); @@ -223,7 +230,8 @@ void f() { Future test_nothing() async { await _check_locations( declaration: 'enum MyEnum { v }', - codeAtCompletion: '^', + declarationForContextType: 'void useMyEnum(MyEnum _) {}', + codeAtCompletion: 'useMyEnum(^);', validator: (response) { check(response).hasEmptyReplacement(); @@ -257,8 +265,10 @@ enum MyEnum { v } var response = await getTestCodeSuggestions(''' import 'a.dart' as prefix; +void useMyEnum(prefix.MyEnum _) {} + void f() { - ^ + useMyEnum(^); } '''); @@ -288,6 +298,7 @@ void f() { Future _check_locations({ required String declaration, + String declarationForContextType = '', required String codeAtCompletion, required void Function(CompletionResponseForTesting response) validator, }) async { @@ -295,6 +306,7 @@ void f() { { var response = await getTestCodeSuggestions(''' $declaration +$declarationForContextType void f() { $codeAtCompletion } @@ -312,6 +324,7 @@ $declaration } var response = await getTestCodeSuggestions(''' import 'a.dart'; +$declarationForContextType void f() { $codeAtCompletion } @@ -323,11 +336,16 @@ void f() { { newFile('$testPackageLibPath/a.dart', ''' $declaration +'''); + newFile('$testPackageLibPath/context_type.dart', ''' +import 'a.dart'; // ignore: unused_import +$declarationForContextType '''); if (isProtocolVersion1) { await waitForSetWithUri('package:test/a.dart'); } var response = await getTestCodeSuggestions(''' +import 'context_type.dart'; void f() { $codeAtCompletion } diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart b/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart index 12cf69339da7..c74d1a030347 100644 --- a/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart +++ b/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart @@ -4,12 +4,14 @@ import 'package:test_reflective_loader/test_reflective_loader.dart'; +import 'class_test.dart' as class_; import 'enum_test.dart' as enum_; import 'library_test.dart' as library_; /// Tests suggestions produced for various kinds of declarations. void main() { defineReflectiveSuite(() { + class_.main(); enum_.main(); library_.main(); }); diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart index 3b05dc916c47..e0d0fad4659c 100644 --- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart +++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart @@ -1923,8 +1923,8 @@ void f() { assertSuggestEnumConst('E.two'); assertSuggestEnum('F'); - assertSuggestEnumConst('F.three'); - assertSuggestEnumConst('F.four'); + assertNotSuggested('F.three'); + assertNotSuggested('F.four'); } Future test_ExpressionStatement_identifier() async { diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart index 3cfdb13ef75d..db03ff47ee76 100644 --- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart +++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart @@ -2312,7 +2312,7 @@ void f() {^} } Future test_enum() async { - addTestSource('enum E { one, two } void f() {^}'); + addTestSource('enum E { one, two } void f() {E v = ^}'); await computeSuggestions(); assertSuggestEnum('E'); assertSuggestEnumConst('E.one'); @@ -2322,7 +2322,7 @@ void f() {^} } Future test_enum_deprecated() async { - addTestSource('@deprecated enum E { one, two } void f() {^}'); + addTestSource('@deprecated enum E { one, two } void f() {E v = ^}'); await computeSuggestions(); assertSuggestEnum('E', isDeprecated: true); assertSuggestEnumConst('E.one', isDeprecated: true); @@ -2349,8 +2349,8 @@ void f() { assertSuggestEnumConst('E.two'); assertSuggestEnum('F'); - assertSuggestEnumConst('F.three'); - assertSuggestEnumConst('F.four'); + assertNotSuggested('F.three'); + assertNotSuggested('F.four'); } Future test_enum_filter_assignment() async { @@ -2370,8 +2370,8 @@ void f() { assertSuggestEnumConst('E.two'); assertSuggestEnum('F'); - assertSuggestEnumConst('F.three'); - assertSuggestEnumConst('F.four'); + assertNotSuggested('F.three'); + assertNotSuggested('F.four'); } Future test_enum_filter_binaryEquals() async { @@ -2412,8 +2412,8 @@ void f(E e) { assertSuggestEnumConst('E.two'); assertSuggestEnum('F'); - assertSuggestEnumConst('F.three'); - assertSuggestEnumConst('F.four'); + assertNotSuggested('F.three'); + assertNotSuggested('F.four'); } Future test_enum_filter_variableDeclaration() async { @@ -2432,8 +2432,8 @@ void f() { assertSuggestEnumConst('E.two'); assertSuggestEnum('F'); - assertSuggestEnumConst('F.three'); - assertSuggestEnumConst('F.four'); + assertNotSuggested('F.three'); + assertNotSuggested('F.four'); } Future test_enum_shadowed() async { diff --git a/pkg/analysis_server/test/src/cider/completion_test.dart b/pkg/analysis_server/test/src/cider/completion_test.dart index e270153e84d6..2fd10956fc3e 100644 --- a/pkg/analysis_server/test/src/cider/completion_test.dart +++ b/pkg/analysis_server/test/src/cider/completion_test.dart @@ -401,7 +401,7 @@ enum E { e } _assertHasClass(text: 'String'); _assertHasConstructor(text: 'A'); _assertHasConstructor(text: 'B'); - _assertHasEnumConstant(text: 'E.e'); + _assertHasEnum(text: 'E'); _assertHasMethod(text: 'foo'); _assertHasMethod(text: 'bar'); _assertHasParameter(text: 'a'); @@ -661,10 +661,10 @@ import 'a.dart'; return matching.single; } - CompletionSuggestion _assertHasEnumConstant({required String text}) { + CompletionSuggestion _assertHasEnum({required String text}) { var matching = _matchingCompletions( text: text, - elementKind: ElementKind.ENUM_CONSTANT, + elementKind: ElementKind.ENUM, ); expect(matching, hasLength(1), reason: 'Expected exactly one completion'); return matching.single;