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:
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user