include locally inherited members in suggestions

BUG=
R=scheglov@google.com

Review URL: https://codereview.chromium.org//657593002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@41114 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
danrubel@google.com
2014-10-15 03:25:20 +00:00
parent ef22e9f989
commit 8465275f69
2 changed files with 106 additions and 6 deletions
@@ -103,6 +103,66 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
@override
visitClassDeclaration(ClassDeclaration node) {
_addClassDeclarationMembers(node);
_addInheritedTypeMembers(node);
visitNode(node);
}
void _addInheritedTypeMembers(ClassDeclaration node) {
ExtendsClause extendsClause = node.extendsClause;
if (extendsClause != null) {
_addLocalTypeMembers(extendsClause.superclass, node);
}
ImplementsClause implementsClause = node.implementsClause;
if (implementsClause != null) {
NodeList<TypeName> interfaces = implementsClause.interfaces;
if (interfaces != null) {
interfaces.forEach((TypeName type) {
_addLocalTypeMembers(type, node);
});
}
}
WithClause withClause = node.withClause;
if (withClause != null) {
NodeList<TypeName> mixinTypes = withClause.mixinTypes;
if (mixinTypes != null) {
mixinTypes.forEach((TypeName type) {
_addLocalTypeMembers(type, node);
});
}
}
}
void _addLocalTypeMembers(TypeName type, ClassDeclaration node) {
if (type == null) {
return;
}
Identifier typeId = type.name;
if (typeId == null) {
return;
}
String typeName = typeId.name;
if (typeName == null || typeName.length == 0) {
return;
}
CompilationUnit unit = node.getAncestor((p) => p is CompilationUnit);
if (unit == null) {
return;
}
unit.declarations.forEach((CompilationUnitMember m) {
if (m is ClassDeclaration) {
SimpleIdentifier id = m.name;
if (id != null) {
if (id.name == typeName) {
_addClassDeclarationMembers(m);
_addInheritedTypeMembers(m);
}
}
}
});
}
void _addClassDeclarationMembers(ClassDeclaration node) {
node.members.forEach((ClassMember classMbr) {
if (classMbr is FieldDeclaration) {
_addFieldSuggestions(node, classMbr);
@@ -110,7 +170,6 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
_addMethodSuggestion(node, classMbr);
}
});
visitNode(node);
}
@override
@@ -404,6 +404,26 @@ class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
}
}
CompletionSuggestion assertSuggestImportedGetter(String name,
String returnType, [CompletionRelevance relevance =
CompletionRelevance.DEFAULT]) {
if (computer is ImportedComputer) {
return assertSuggestGetter(name, returnType, relevance);
} else {
return assertNotSuggested(name);
}
}
CompletionSuggestion assertSuggestImportedMethod(String name,
String declaringType, String returnType, [CompletionRelevance relevance =
CompletionRelevance.DEFAULT]) {
if (computer is ImportedComputer) {
return assertSuggestMethod(name, declaringType, returnType, relevance);
} else {
return assertNotSuggested(name);
}
}
CompletionSuggestion assertSuggestImportedTopLevelVar(String name,
String returnType, [CompletionRelevance relevance =
CompletionRelevance.DEFAULT]) {
@@ -659,6 +679,27 @@ class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
});
}
test_Block_inherited_local() {
// Block BlockFunctionBody MethodDeclaration ClassDeclaration
addTestSource('''
class F { var f1; f2() { } }
class E extends F { var e1; e2() { } }
class I { int i1; i2() { } }
class M { var m1; int m2() { } }
class A extends E implements I with M {a() {^}}''');
computeFast();
return computeFull(true).then((_) {
assertSuggestLocalGetter('e1', null);
assertSuggestLocalGetter('f1', null);
assertSuggestLocalGetter('i1', 'int');
assertSuggestLocalGetter('m1', null);
assertSuggestLocalMethod('e2', 'E', null);
assertSuggestLocalMethod('f2', 'F', null);
assertSuggestLocalMethod('i2', 'I', null);
assertSuggestLocalMethod('m2', 'M', 'int');
});
}
test_CascadeExpression_selector1() {
// PropertyAccess CascadeExpression ExpressionStatement Block
addSource('/testB.dart', '''
@@ -752,11 +793,11 @@ class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
// ClassDeclaration CompilationUnit
addSource('/testB.dart', '''
class B { }''');
addTestSource( //
'import "testB.dart" as x;' //
' @deprecated class A {^}' //
' class _B {}' //
' A T;');
addTestSource('''
import "testB.dart" as x;
@deprecated class A {^}
class _B {}
A T;''');
computeFast();
return computeFull(true).then((_) {
CompletionSuggestion suggestionA = assertSuggestLocalClass('A');