Completion suggestion relevance influenced by parameter types (issue 31592)

Change-Id: I8f03dea74fac8080bc628128a0f32b09784d0248
Reviewed-on: https://dart-review.googlesource.com/28780
Reviewed-by: Dan Rubel <danrubel@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Brian Wilkerson 2017-12-12 18:40:59 +00:00 committed by commit-bot@chromium.org
parent 962c18b627
commit 081074ebf4
2 changed files with 43 additions and 7 deletions

View file

@ -16,6 +16,7 @@ import 'package:analyzer/dart/ast/ast.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/src/dart/ast/ast.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
part 'common_usage_sorter.g.dart';
@ -101,27 +102,44 @@ class CommonUsageSorter implements DartContributionSorter {
/**
* An [AstVisitor] used to determine the best defining type of a node.
*/
class _BestTypeVisitor extends GeneralizingAstVisitor<DartType> {
class _BestTypeVisitor extends UnifyingAstVisitor<DartType> {
/**
* The entity which the completed text will replace (or which will be
* displaced once the completed text is inserted). This may be an AstNode or
* a Token, or it may be null if the cursor is after all tokens in the file.
* a Token, or it may be `null` if the cursor is after all tokens in the file.
* See field of the same name in [CompletionTarget].
*/
final Object entity;
_BestTypeVisitor(this.entity);
@override
DartType visitConstructorName(ConstructorName node) =>
node.period != null && node.name == entity ? node.type?.type : null;
@override
DartType visitNamedExpression(NamedExpression node) {
AstNode parent = node.parent;
if (parent is ArgumentListImpl) {
List<ParameterElement> params = parent.correspondingStaticParameters;
if (params != null) {
int index = parent.arguments.indexOf(node);
return params[index]?.type;
}
}
return super.visitNamedExpression(node);
}
@override
DartType visitNode(AstNode node) {
return null;
}
@override
DartType visitPrefixedIdentifier(PrefixedIdentifier node) =>
node.identifier == entity ? node.prefix?.bestType : null;
@override
DartType visitPropertyAccess(PropertyAccess node) =>
node.propertyName == entity ? node.realTarget?.bestType : null;
}

View file

@ -48,8 +48,26 @@ class CommonUsageSorterTest extends AbstractCompletionDomainTest {
assertNoResult('A');
}
test_namedArgument_enum() async {
addTestFile('''
enum E {e1, e2}
f({E e}) {}
main() {
f(e: ^);
}
''');
await getSuggestionsWith(<String, List<String>>{});
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
assertHasResult(CompletionSuggestionKind.INVOCATION, 'E');
assertHasResult(CompletionSuggestionKind.INVOCATION, 'E.e1',
relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT);
assertHasResult(CompletionSuggestionKind.INVOCATION, 'E.e2',
relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT);
}
test_PrefixedIdentifier_field() async {
// SimpleIdentifier PrefixedIdentifeir ExpressionStatement
// SimpleIdentifier PrefixedIdentifier ExpressionStatement
addTestFile('class A {static int s1; static int s2; x() {A.^}}');
await getSuggestionsWith({
'.A': ['s2']
@ -65,7 +83,7 @@ class CommonUsageSorterTest extends AbstractCompletionDomainTest {
}
test_PrefixedIdentifier_field_inPart() async {
// SimpleIdentifier PrefixedIdentifeir ExpressionStatement
// SimpleIdentifier PrefixedIdentifier ExpressionStatement
addFile('/project/bin/myLib.dart',
'library L; part "$testFile"; class A {static int s2;}');
addTestFile('part of L; foo() {A.^}');
@ -82,7 +100,7 @@ class CommonUsageSorterTest extends AbstractCompletionDomainTest {
}
test_PrefixedIdentifier_getter() async {
// SimpleIdentifier PrefixedIdentifeir ExpressionStatement
// SimpleIdentifier PrefixedIdentifier ExpressionStatement
addTestFile('class A {int get g1 => 1; int get g2 => 2; x() {new A().^}}');
await getSuggestionsWith({
'.A': ['g2']
@ -98,7 +116,7 @@ class CommonUsageSorterTest extends AbstractCompletionDomainTest {
}
test_PrefixedIdentifier_setter() async {
// SimpleIdentifier PrefixedIdentifeir ExpressionStatement
// SimpleIdentifier PrefixedIdentifier ExpressionStatement
addTestFile('class A {set s1(v) {}; set s2(v) {}; x() {new A().^}}');
await getSuggestionsWith({
'.A': ['s2']
@ -114,7 +132,7 @@ class CommonUsageSorterTest extends AbstractCompletionDomainTest {
}
test_PrefixedIdentifier_static_method() async {
// SimpleIdentifier PrefixedIdentifeir ExpressionStatement
// SimpleIdentifier PrefixedIdentifier ExpressionStatement
addTestFile('import "dart:async"; class A {x() {Future.^}}');
await getSuggestionsWith({
'dart.async.Future': ['value', 'wait']