From cbd16a7336d07f3e6582c1df19b36bed389cf8fd Mon Sep 17 00:00:00 2001 From: "danrubel@google.com" Date: Thu, 15 Jan 2015 02:26:45 +0000 Subject: [PATCH] add local parameter info to completion suggestions BUG= R=paulberry@google.com Review URL: https://codereview.chromium.org//850003002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@42894 260f80e4-7a28-3924-810f-c04153c831b5 --- .../services/completion/local_computer.dart | 134 +++++---- .../completion/combinator_computer_test.dart | 28 +- .../completion/completion_test_util.dart | 140 ++++++---- .../completion/local_computer_test.dart | 261 +++++++++++++++++- 4 files changed, 447 insertions(+), 116 deletions(-) diff --git a/pkg/analysis_server/lib/src/services/completion/local_computer.dart b/pkg/analysis_server/lib/src/services/completion/local_computer.dart index fb4c505bb5e..0460537d294 100644 --- a/pkg/analysis_server/lib/src/services/completion/local_computer.dart +++ b/pkg/analysis_server/lib/src/services/completion/local_computer.dart @@ -14,6 +14,7 @@ import 'package:analysis_server/src/services/completion/local_declaration_visito import 'package:analysis_server/src/services/completion/optype.dart'; import 'package:analyzer/src/generated/ast.dart'; import 'package:analyzer/src/generated/scanner.dart'; +import 'package:analyzer/src/generated/utilities_dart.dart'; /** * A computer for calculating `completion.getSuggestions` request results @@ -207,15 +208,14 @@ class _LocalVisitor extends LocalDeclarationVisitor { void declaredClass(ClassDeclaration declaration) { bool isDeprecated = _isDeprecated(declaration); CompletionSuggestion suggestion = - _addSuggestion(declaration.name, NO_RETURN_TYPE, null, isDeprecated); + _addSuggestion(declaration.name, NO_RETURN_TYPE, isDeprecated); if (suggestion != null) { suggestion.element = _createElement( protocol.ElementKind.CLASS, declaration.name, - null, - NO_RETURN_TYPE, - declaration.isAbstract, - isDeprecated); + returnType: NO_RETURN_TYPE, + isAbstract: declaration.isAbstract, + isDeprecated: isDeprecated); } } @@ -223,15 +223,14 @@ class _LocalVisitor extends LocalDeclarationVisitor { void declaredClassTypeAlias(ClassTypeAlias declaration) { bool isDeprecated = _isDeprecated(declaration); CompletionSuggestion suggestion = - _addSuggestion(declaration.name, NO_RETURN_TYPE, null, isDeprecated); + _addSuggestion(declaration.name, NO_RETURN_TYPE, isDeprecated); if (suggestion != null) { suggestion.element = _createElement( protocol.ElementKind.CLASS_TYPE_ALIAS, declaration.name, - null, - NO_RETURN_TYPE, - true, - isDeprecated); + returnType: NO_RETURN_TYPE, + isAbstract: true, + isDeprecated: isDeprecated); } } @@ -243,15 +242,13 @@ class _LocalVisitor extends LocalDeclarationVisitor { bool isDeprecated = _isDeprecated(fieldDecl) || _isDeprecated(varDecl); TypeName type = fieldDecl.fields.type; CompletionSuggestion suggestion = - _addSuggestion(varDecl.name, type, fieldDecl.parent, isDeprecated); + _addSuggestion(varDecl.name, type, isDeprecated, classDecl: fieldDecl.parent); if (suggestion != null) { suggestion.element = _createElement( protocol.ElementKind.FIELD, varDecl.name, - null, - type, - false, - isDeprecated); + returnType: type, + isDeprecated: isDeprecated); } } @@ -278,16 +275,20 @@ class _LocalVisitor extends LocalDeclarationVisitor { kind = protocol.ElementKind.FUNCTION; } CompletionSuggestion suggestion = - _addSuggestion(declaration.name, returnType, null, isDeprecated); + _addSuggestion(declaration.name, returnType, isDeprecated); if (suggestion != null) { FormalParameterList param = declaration.functionExpression.parameters; suggestion.element = _createElement( kind, declaration.name, - param != null ? param.toSource() : null, - returnType, - false, - isDeprecated); + parameters: param != null ? param.toSource() : null, + returnType: returnType, + isDeprecated: isDeprecated); + if (kind == protocol.ElementKind.FUNCTION) { + _addParameterInfo( + suggestion, + declaration.functionExpression.parameters); + } } } @@ -296,16 +297,15 @@ class _LocalVisitor extends LocalDeclarationVisitor { bool isDeprecated = _isDeprecated(declaration); TypeName returnType = declaration.returnType; CompletionSuggestion suggestion = - _addSuggestion(declaration.name, returnType, null, isDeprecated); + _addSuggestion(declaration.name, returnType, isDeprecated); if (suggestion != null) { // TODO (danrubel) determine parameters and return type suggestion.element = _createElement( protocol.ElementKind.FUNCTION_TYPE_ALIAS, declaration.name, - null, - returnType, - true, - isDeprecated); + returnType: returnType, + isAbstract: true, + isDeprecated: isDeprecated); } } @@ -319,15 +319,10 @@ class _LocalVisitor extends LocalDeclarationVisitor { if (typesOnly) { return; } - CompletionSuggestion suggestion = _addSuggestion(name, type, null, false); + CompletionSuggestion suggestion = _addSuggestion(name, type, false); if (suggestion != null) { - suggestion.element = _createElement( - protocol.ElementKind.LOCAL_VARIABLE, - name, - null, - type, - false, - false); + suggestion.element = + _createElement(protocol.ElementKind.LOCAL_VARIABLE, name, returnType: type); } } @@ -356,16 +351,22 @@ class _LocalVisitor extends LocalDeclarationVisitor { parameters = declaration.parameters.toSource(); } bool isDeprecated = _isDeprecated(declaration); - CompletionSuggestion suggestion = - _addSuggestion(declaration.name, returnType, declaration.parent, isDeprecated); + CompletionSuggestion suggestion = _addSuggestion( + declaration.name, + returnType, + isDeprecated, + classDecl: declaration.parent); if (suggestion != null) { suggestion.element = _createElement( kind, declaration.name, - parameters, - returnType, - declaration.isAbstract, - isDeprecated); + parameters: parameters, + returnType: returnType, + isAbstract: declaration.isAbstract, + isDeprecated: isDeprecated); + if (kind == protocol.ElementKind.METHOD) { + _addParameterInfo(suggestion, declaration.parameters); + } } } @@ -374,10 +375,10 @@ class _LocalVisitor extends LocalDeclarationVisitor { if (typesOnly) { return; } - CompletionSuggestion suggestion = _addSuggestion(name, type, null, false); + CompletionSuggestion suggestion = _addSuggestion(name, type, false); if (suggestion != null) { suggestion.element = - _createElement(protocol.ElementKind.PARAMETER, name, null, type, false, false); + _createElement(protocol.ElementKind.PARAMETER, name, returnType: type); } } @@ -389,20 +390,53 @@ class _LocalVisitor extends LocalDeclarationVisitor { } bool isDeprecated = _isDeprecated(varList) || _isDeprecated(varDecl); CompletionSuggestion suggestion = - _addSuggestion(varDecl.name, varList.type, null, isDeprecated); + _addSuggestion(varDecl.name, varList.type, isDeprecated); if (suggestion != null) { suggestion.element = _createElement( protocol.ElementKind.TOP_LEVEL_VARIABLE, varDecl.name, - null, - varList.type, - false, - isDeprecated); + returnType: varList.type, + isDeprecated: isDeprecated); } } + void _addParameterInfo(CompletionSuggestion suggestion, + FormalParameterList parameters) { + var paramList = parameters.parameters; + suggestion.parameterNames = + paramList.map((FormalParameter param) => param.identifier.name).toList(); + suggestion.parameterTypes = paramList.map((FormalParameter param) { + TypeName type = null; + if (param is DefaultFormalParameter) { + NormalFormalParameter child = param.parameter; + if (child is SimpleFormalParameter) { + type = child.type; + } else if (child is FieldFormalParameter) { + type = child.type; + } + } + if (param is SimpleFormalParameter) { + type = param.type; + } else if (param is FieldFormalParameter) { + type = param.type; + } + if (type == null) { + return 'dynamic'; + } + Identifier typeId = type.name; + if (typeId == null) { + return 'dynamic'; + } + return typeId.name; + }).toList(); + suggestion.requiredParameterCount = paramList.where( + (FormalParameter param) => param is! DefaultFormalParameter).length; + suggestion.hasNamedParameters = + paramList.any((FormalParameter param) => param.kind == ParameterKind.NAMED); + } + CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName returnType, - ClassDeclaration classDecl, bool isDeprecated) { + bool isDeprecated, {ClassDeclaration classDecl}) { if (id != null) { String completion = id.name; if (completion != null && completion.length > 0 && completion != '_') { @@ -412,7 +446,7 @@ class _LocalVisitor extends LocalDeclarationVisitor { completion, completion.length, 0, - false, + isDeprecated, false, returnType: _nameForType(returnType)); if (classDecl != null) { @@ -436,8 +470,8 @@ class _LocalVisitor extends LocalDeclarationVisitor { * Create a new protocol Element for inclusion in a completion suggestion. */ protocol.Element _createElement(protocol.ElementKind kind, - SimpleIdentifier id, String parameters, TypeName returnType, bool isAbstract, - bool isDeprecated) { + SimpleIdentifier id, {String parameters, TypeName returnType, bool isAbstract: + false, bool isDeprecated: false}) { String name = id.name; int flags = protocol.Element.makeFlags( isAbstract: isAbstract, diff --git a/pkg/analysis_server/test/services/completion/combinator_computer_test.dart b/pkg/analysis_server/test/services/completion/combinator_computer_test.dart index 281a5fa132b..e07cae5acf4 100644 --- a/pkg/analysis_server/test/services/completion/combinator_computer_test.dart +++ b/pkg/analysis_server/test/services/completion/combinator_computer_test.dart @@ -62,16 +62,16 @@ class CombinatorComputerTest extends AbstractCompletionTest { return computeFull((bool result) { assertSuggestClass( 'A', - COMPLETION_RELEVANCE_DEFAULT, - CompletionSuggestionKind.IDENTIFIER); + relevance: COMPLETION_RELEVANCE_DEFAULT, + kind: CompletionSuggestionKind.IDENTIFIER); assertSuggestClass( 'B', - COMPLETION_RELEVANCE_DEFAULT, - CompletionSuggestionKind.IDENTIFIER); + relevance: COMPLETION_RELEVANCE_DEFAULT, + kind: CompletionSuggestionKind.IDENTIFIER); assertSuggestClass( 'PB', - COMPLETION_RELEVANCE_DEFAULT, - CompletionSuggestionKind.IDENTIFIER); + relevance: COMPLETION_RELEVANCE_DEFAULT, + kind: CompletionSuggestionKind.IDENTIFIER); assertSuggestTopLevelVar( 'T1', null, @@ -115,16 +115,16 @@ class CombinatorComputerTest extends AbstractCompletionTest { return computeFull((bool result) { assertSuggestClass( 'A', - COMPLETION_RELEVANCE_DEFAULT, - CompletionSuggestionKind.IDENTIFIER); + relevance: COMPLETION_RELEVANCE_DEFAULT, + kind: CompletionSuggestionKind.IDENTIFIER); assertSuggestClass( 'B', - COMPLETION_RELEVANCE_DEFAULT, - CompletionSuggestionKind.IDENTIFIER); + relevance: COMPLETION_RELEVANCE_DEFAULT, + kind: CompletionSuggestionKind.IDENTIFIER); assertSuggestClass( 'PB', - COMPLETION_RELEVANCE_DEFAULT, - CompletionSuggestionKind.IDENTIFIER); + relevance: COMPLETION_RELEVANCE_DEFAULT, + kind: CompletionSuggestionKind.IDENTIFIER); assertSuggestTopLevelVar( 'T1', null, @@ -138,8 +138,8 @@ class CombinatorComputerTest extends AbstractCompletionTest { CompletionSuggestionKind.IDENTIFIER); assertSuggestClass( 'Clz', - COMPLETION_RELEVANCE_DEFAULT, - CompletionSuggestionKind.IDENTIFIER); + relevance: COMPLETION_RELEVANCE_DEFAULT, + kind: CompletionSuggestionKind.IDENTIFIER); assertSuggestFunctionTypeAlias( 'F2', null, diff --git a/pkg/analysis_server/test/services/completion/completion_test_util.dart b/pkg/analysis_server/test/services/completion/completion_test_util.dart index a6ce671e42c..6d305c232ff 100644 --- a/pkg/analysis_server/test/services/completion/completion_test_util.dart +++ b/pkg/analysis_server/test/services/completion/completion_test_util.dart @@ -78,6 +78,16 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(suggestion.hasNamedParameters, isNull); } + void assertHasParameterInfo(CompletionSuggestion suggestion) { + expect(suggestion.parameterNames, isNotNull); + expect(suggestion.parameterTypes, isNotNull); + expect(suggestion.parameterNames.length, suggestion.parameterTypes.length); + expect( + suggestion.requiredParameterCount, + lessThanOrEqualTo(suggestion.parameterNames.length)); + expect(suggestion.hasNamedParameters, isNotNull); + } + void assertNoSuggestions({CompletionSuggestionKind kind: null}) { if (kind == null) { if (request.suggestions.length > 0) { @@ -170,17 +180,21 @@ abstract class AbstractCompletionTest extends AbstractContextTest { fail(msg.toString()); } - CompletionSuggestion assertSuggestClass(String name, [int relevance = - COMPLETION_RELEVANCE_DEFAULT, CompletionSuggestionKind kind = - CompletionSuggestionKind.INVOCATION]) { - CompletionSuggestion cs = - assertSuggest(name, csKind: kind, relevance: relevance); + CompletionSuggestion assertSuggestClass(String name, {int relevance: + COMPLETION_RELEVANCE_DEFAULT, CompletionSuggestionKind kind: + CompletionSuggestionKind.INVOCATION, bool isDeprecated: false}) { + CompletionSuggestion cs = assertSuggest( + name, + csKind: kind, + relevance: relevance, + isDeprecated: isDeprecated); protocol.Element element = cs.element; expect(element, isNotNull); expect(element.kind, equals(protocol.ElementKind.CLASS)); expect(element.name, equals(name)); expect(element.parameters, isNull); expect(element.returnType, isNull); + assertHasNoParameterInfo(cs); return cs; } @@ -195,6 +209,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(element.name, equals(name)); expect(element.parameters, isNull); expect(element.returnType, isNull); + assertHasNoParameterInfo(cs); return cs; } @@ -216,6 +231,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(element.parameters, isNull); // The returnType represents the type of a field expect(element.returnType, type != null ? type : 'dynamic'); + assertHasNoParameterInfo(cs); return cs; } @@ -240,6 +256,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect( element.returnType, equals(returnType != null ? returnType : 'dynamic')); + assertHasParameterInfo(cs); return cs; } @@ -263,10 +280,11 @@ abstract class AbstractCompletionTest extends AbstractContextTest { // expect(param, isNotNull); // expect(param[0], equals('(')); // expect(param[param.length - 1], equals(')')); - // TODO (danrubel) Determine why return type is null -// expect( -// element.returnType, -// equals(returnType != null ? returnType : 'dynamic')); + expect( + element.returnType, + equals(returnType != null ? returnType : 'dynamic')); + // TODO (danrubel) Determine why param info is missing +// assertHasParameterInfo(cs); return cs; } @@ -284,12 +302,11 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(element, isNotNull); expect(element.kind, equals(protocol.ElementKind.GETTER)); expect(element.name, equals(name)); - //TODO (danrubel) getter should have parameters - // but not used in code completion - //expect(element.parameters, '()'); + expect(element.parameters, isNull); expect( element.returnType, equals(returnType != null ? returnType : 'dynamic')); + assertHasNoParameterInfo(cs); return cs; } @@ -306,6 +323,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(element.name, equals(name)); expect(element.parameters, isNull); expect(element.returnType, isNull); + assertHasNoParameterInfo(cs); return cs; } @@ -321,6 +339,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(element.kind, equals(protocol.ElementKind.LIBRARY)); expect(element.parameters, isNull); expect(element.returnType, isNull); + assertHasNoParameterInfo(cs); return cs; } else { return assertNotSuggested(prefix); @@ -341,6 +360,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(element.name, equals(name)); expect(element.parameters, isNull); expect(element.returnType, returnType != null ? returnType : 'dynamic'); + assertHasNoParameterInfo(cs); return cs; } else { return assertNotSuggested(name); @@ -348,10 +368,14 @@ abstract class AbstractCompletionTest extends AbstractContextTest { } CompletionSuggestion assertSuggestMethod(String name, String declaringType, - String returnType, [int relevance = COMPLETION_RELEVANCE_DEFAULT, - CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) { - CompletionSuggestion cs = - assertSuggest(name, csKind: kind, relevance: relevance); + String returnType, {int relevance: COMPLETION_RELEVANCE_DEFAULT, + CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, + bool isDeprecated: false}) { + CompletionSuggestion cs = assertSuggest( + name, + csKind: kind, + relevance: relevance, + isDeprecated: isDeprecated); expect(cs.declaringType, equals(declaringType)); expect(cs.returnType, returnType != null ? returnType : 'dynamic'); protocol.Element element = cs.element; @@ -363,6 +387,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(param[0], equals('(')); expect(param[param.length - 1], equals(')')); expect(element.returnType, returnType != null ? returnType : 'dynamic'); + assertHasParameterInfo(cs); return cs; } @@ -381,6 +406,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(param[0], equals('(')); expect(param[param.length - 1], equals(')')); expect(element.returnType, equals(returnType)); + assertHasParameterInfo(cs); return cs; } else { return assertNotSuggested(name); @@ -427,6 +453,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { if (element.returnType != null) { expect(element.returnType, 'dynamic'); } + assertHasNoParameterInfo(cs); return cs; } @@ -442,6 +469,7 @@ abstract class AbstractCompletionTest extends AbstractContextTest { expect(element.name, equals(name)); expect(element.parameters, isNull); expect(element.returnType, returnType != null ? returnType : 'dynamic'); + assertHasNoParameterInfo(cs); return cs; } @@ -607,7 +635,11 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { String declaringType, String returnType, [int relevance = COMPLETION_RELEVANCE_DEFAULT]) { if (computer is LocalComputer) { - return assertSuggestMethod(name, declaringType, returnType, relevance); + return assertSuggestMethod( + name, + declaringType, + returnType, + relevance: relevance); } else { return assertNotSuggested(name); } @@ -617,7 +649,7 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { COMPLETION_RELEVANCE_DEFAULT, CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) { if (computer is ImportedComputer) { - return assertSuggestClass(name, relevance, kind); + return assertSuggestClass(name, relevance: relevance, kind: kind); } else { return assertNotSuggested(name); } @@ -673,7 +705,11 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { String declaringType, String returnType, [int relevance = COMPLETION_RELEVANCE_DEFAULT]) { if (computer is ImportedComputer) { - return assertSuggestMethod(name, declaringType, returnType, relevance); + return assertSuggestMethod( + name, + declaringType, + returnType, + relevance: relevance); } else { return assertNotSuggested(name); } @@ -701,7 +737,7 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { CompletionSuggestion assertSuggestInvocationClass(String name, [int relevance = COMPLETION_RELEVANCE_DEFAULT]) { if (computer is InvocationComputer) { - return assertSuggestClass(name, relevance); + return assertSuggestClass(name, relevance: relevance); } else { return assertNotSuggested(name); } @@ -730,7 +766,11 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { String declaringType, String returnType, [int relevance = COMPLETION_RELEVANCE_DEFAULT]) { if (computer is InvocationComputer) { - return assertSuggestMethod(name, declaringType, returnType, relevance); + return assertSuggestMethod( + name, + declaringType, + returnType, + relevance: relevance); } else { return assertNotSuggested(name); } @@ -754,13 +794,9 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { } } - CompletionSuggestion assertSuggestLocalClass(String name, [int relevance = - COMPLETION_RELEVANCE_DEFAULT]) { - if (computer is LocalComputer) { - return assertSuggestClass(name, relevance); - } else { - return assertNotSuggested(name); - } + CompletionSuggestion assertSuggestLocalClass(String name, {int relevance: + COMPLETION_RELEVANCE_DEFAULT, bool isDeprecated: false}) { + return assertNotSuggested(name); } CompletionSuggestion assertSuggestLocalClassTypeAlias(String name, @@ -773,7 +809,7 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { } CompletionSuggestion assertSuggestLocalField(String name, String type, - [int relevance = COMPLETION_RELEVANCE_DEFAULT]) { + {int relevance: COMPLETION_RELEVANCE_DEFAULT, bool isDeprecated: false}) { return assertNotSuggested(name); } @@ -802,22 +838,14 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { } CompletionSuggestion assertSuggestLocalGetter(String name, String returnType, - [int relevance = COMPLETION_RELEVANCE_DEFAULT]) { - if (computer is LocalComputer) { - return assertSuggestGetter(name, returnType, relevance: relevance); - } else { - return assertNotSuggested(name); - } + {int relevance: COMPLETION_RELEVANCE_DEFAULT, bool isDeprecated: false}) { + return assertNotSuggested(name); } CompletionSuggestion assertSuggestLocalMethod(String name, - String declaringType, String returnType, [int relevance = - COMPLETION_RELEVANCE_DEFAULT]) { - if (computer is LocalComputer) { - return assertSuggestMethod(name, declaringType, returnType, relevance); - } else { - return assertNotSuggested(name); - } + String declaringType, String returnType, {int relevance: + COMPLETION_RELEVANCE_DEFAULT, bool isDeprecated: false}) { + return assertNotSuggested(name); } CompletionSuggestion assertSuggestLocalSetter(String name, [int relevance = @@ -1475,8 +1503,10 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { A T;'''); computeFast(); return computeFull((bool result) { - CompletionSuggestion suggestionA = - assertSuggestLocalClass('A', COMPLETION_RELEVANCE_LOW); + CompletionSuggestion suggestionA = assertSuggestLocalClass( + 'A', + relevance: COMPLETION_RELEVANCE_LOW, + isDeprecated: true); if (suggestionA != null) { expect(suggestionA.element.isDeprecated, isTrue); expect(suggestionA.element.isPrivate, isFalse); @@ -2032,8 +2062,11 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { expect(methodA.element.isDeprecated, isFalse); expect(methodA.element.isPrivate, isFalse); } - CompletionSuggestion getterF = - assertSuggestLocalGetter('f', 'X', COMPLETION_RELEVANCE_LOW); + CompletionSuggestion getterF = assertSuggestLocalGetter( + 'f', + 'X', + relevance: COMPLETION_RELEVANCE_LOW, + isDeprecated: true); if (getterF != null) { expect(getterF.element.isDeprecated, isTrue); expect(getterF.element.isPrivate, isFalse); @@ -2056,8 +2089,11 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { expect(methodA.element.isDeprecated, isFalse); expect(methodA.element.isPrivate, isTrue); } - CompletionSuggestion getterF = - assertSuggestLocalField('f', 'X', COMPLETION_RELEVANCE_LOW); + CompletionSuggestion getterF = assertSuggestLocalField( + 'f', + 'X', + relevance: COMPLETION_RELEVANCE_LOW, + isDeprecated: true); if (getterF != null) { expect(getterF.element.isDeprecated, isTrue); expect(getterF.element.isPrivate, isFalse); @@ -2078,8 +2114,12 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest { addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}'); computeFast(); return computeFull((bool result) { - CompletionSuggestion methodA = - assertSuggestLocalMethod('a', 'A', 'Z', COMPLETION_RELEVANCE_LOW); + CompletionSuggestion methodA = assertSuggestLocalMethod( + 'a', + 'A', + 'Z', + relevance: COMPLETION_RELEVANCE_LOW, + isDeprecated: true); if (methodA != null) { expect(methodA.element.isDeprecated, isTrue); expect(methodA.element.isPrivate, isFalse); diff --git a/pkg/analysis_server/test/services/completion/local_computer_test.dart b/pkg/analysis_server/test/services/completion/local_computer_test.dart index 2399393985f..2a8e8696368 100644 --- a/pkg/analysis_server/test/services/completion/local_computer_test.dart +++ b/pkg/analysis_server/test/services/completion/local_computer_test.dart @@ -20,10 +20,45 @@ main() { @reflectiveTest class LocalComputerTest extends AbstractSelectorSuggestionTest { + @override + CompletionSuggestion assertSuggestLocalClass(String name, {int relevance: + COMPLETION_RELEVANCE_DEFAULT, bool isDeprecated: false}) { + return assertSuggestClass( + name, + relevance: relevance, + isDeprecated: isDeprecated); + } + @override CompletionSuggestion assertSuggestLocalField(String name, String type, - [int relevance = COMPLETION_RELEVANCE_DEFAULT]) { - return assertSuggestField(name, type, relevance: relevance); + {int relevance: COMPLETION_RELEVANCE_DEFAULT, bool isDeprecated: false}) { + return assertSuggestField( + name, + type, + relevance: relevance, + isDeprecated: isDeprecated); + } + + @override + CompletionSuggestion assertSuggestLocalGetter(String name, String returnType, + {int relevance: COMPLETION_RELEVANCE_DEFAULT, bool isDeprecated: false}) { + return assertSuggestGetter( + name, + returnType, + relevance: relevance, + isDeprecated: isDeprecated); + } + + @override + CompletionSuggestion assertSuggestLocalMethod(String name, + String declaringType, String returnType, {int relevance: + COMPLETION_RELEVANCE_DEFAULT, bool isDeprecated: false}) { + return assertSuggestMethod( + name, + declaringType, + returnType, + relevance: relevance, + isDeprecated: isDeprecated); } @override @@ -308,4 +343,226 @@ void main() { expect(computeFast(), isTrue); assertSuggestLabel('foo'); } + + test_function_parameters_mixed_required_and_named() { + addTestSource(''' +void m(x, {int y}) {} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 1); + expect(suggestion.hasNamedParameters, true); + } + + test_function_parameters_mixed_required_and_positional() { + addTestSource(''' +void m(x, [int y]) {} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 1); + expect(suggestion.hasNamedParameters, false); + } + + test_function_parameters_named() { + addTestSource(''' +void m({x, int y}) {} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 0); + expect(suggestion.hasNamedParameters, true); + } + + test_function_parameters_none() { + addTestSource(''' +void m() {} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); + expect(suggestion.parameterNames, isEmpty); + expect(suggestion.parameterTypes, isEmpty); + expect(suggestion.requiredParameterCount, 0); + expect(suggestion.hasNamedParameters, false); + } + + test_function_parameters_positional() { + addTestSource(''' +void m([x, int y]) {} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 0); + expect(suggestion.hasNamedParameters, false); + } + + test_function_parameters_required() { + addTestSource(''' +void m(x, int y) {} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 2); + expect(suggestion.hasNamedParameters, false); + } + + test_method_parameters_mixed_required_and_named() { + addTestSource(''' +class A { + void m(x, {int y}) {} +} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 1); + expect(suggestion.hasNamedParameters, true); + } + + test_method_parameters_mixed_required_and_positional() { + addTestSource(''' +class A { + void m(x, [int y]) {} +} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 1); + expect(suggestion.hasNamedParameters, false); + } + + test_method_parameters_named() { + addTestSource(''' +class A { + void m({x, int y}) {} +} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 0); + expect(suggestion.hasNamedParameters, true); + } + + test_method_parameters_none() { + addTestSource(''' +class A { + void m() {} +} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); + expect(suggestion.parameterNames, isEmpty); + expect(suggestion.parameterTypes, isEmpty); + expect(suggestion.requiredParameterCount, 0); + expect(suggestion.hasNamedParameters, false); + } + + test_method_parameters_positional() { + addTestSource(''' +class A { + void m([x, int y]) {} +} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 0); + expect(suggestion.hasNamedParameters, false); + } + + test_method_parameters_required() { + addTestSource(''' +class A { + void m(x, int y) {} +} +class B extends A { + main() {^} +} +'''); + expect(computeFast(), isTrue); + CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); + expect(suggestion.parameterNames, hasLength(2)); + expect(suggestion.parameterNames[0], 'x'); + expect(suggestion.parameterTypes[0], 'dynamic'); + expect(suggestion.parameterNames[1], 'y'); + expect(suggestion.parameterTypes[1], 'int'); + expect(suggestion.requiredParameterCount, 2); + expect(suggestion.hasNamedParameters, false); + } }