gdsl 'delegatesTo' should process non code members too (IDEA-63554)

This commit is contained in:
Maxim.Medvedev
2012-05-12 19:54:05 +04:00
parent c7b955e67d
commit 86fe64c310
3 changed files with 67 additions and 19 deletions
@@ -22,6 +22,8 @@ import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.dsl.GdslMembersHolderConsumer;
import org.jetbrains.plugins.groovy.dsl.holders.DelegatedMembersHolder;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
@@ -29,6 +31,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.CompletionProcessor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
/**
* @author ilyas
@@ -37,7 +43,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM
public class GroovyDslDefaultMembers implements GdslMembersProvider {
/**
* Find a class by its full-qulified name
* Find a class by its full-qualified name
*
* @param fqn
* @return
@@ -45,8 +51,7 @@ public class GroovyDslDefaultMembers implements GdslMembersProvider {
@Nullable
public PsiClass findClass(String fqn, GdslMembersHolderConsumer consumer) {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(consumer.getProject());
final PsiClass clazz = facade.findClass(fqn, GlobalSearchScope.allScope(consumer.getProject()));
return clazz;
return facade.findClass(fqn, GlobalSearchScope.allScope(consumer.getProject()));
}
/**
@@ -59,11 +64,26 @@ public class GroovyDslDefaultMembers implements GdslMembersProvider {
if (elem instanceof PsiClass) {
final PsiClass clazz = (PsiClass)elem;
final DelegatedMembersHolder holder = new DelegatedMembersHolder();
for (PsiMethod method : clazz.getAllMethods()) {
if (!method.isConstructor()) holder.addMember(method);
if (clazz instanceof GrTypeDefinition) {
final PsiClassType type = JavaPsiFacade.getElementFactory(consumer.getProject()).createType(clazz);
final ResolverProcessor processor = CompletionProcessor.createPropertyCompletionProcessor(clazz);
final GroovyPsiElement context = (GroovyPsiElement)clazz;
ResolveUtil.processAllDeclarations(type, processor, ResolveState.initial(), context);
for (GroovyResolveResult result : processor.getCandidates()) {
final PsiElement element = result.getElement();
if (element instanceof PsiMethod && !((PsiMethod)element).isConstructor() || element instanceof PsiField) {
holder.addMember((PsiMember)element);
}
}
}
for (PsiField field : clazz.getAllFields()) {
holder.addMember(field);
else {
for (PsiMethod method : clazz.getAllMethods()) {
if (!method.isConstructor()) holder.addMember(method);
}
for (PsiField field : clazz.getAllFields()) {
holder.addMember(field);
}
}
consumer.addMemberHolder(holder);
}
@@ -155,5 +175,4 @@ public class GroovyDslDefaultMembers implements GdslMembersProvider {
}
return null;
}
}
@@ -65,25 +65,23 @@ public class GDKSuperMethodSearcher implements QueryExecutor<MethodSignatureBack
final GroovyResolveResult[] candidates = processor.getCandidates();
final List<PsiMethod> allMethods = new ArrayList<PsiMethod>();
final PsiManager psiManager = PsiManager.getInstance(project);
final MethodSignature signature = method.getHierarchicalMethodSignature();
List<PsiMethod> goodSupers = new ArrayList<PsiMethod>();
for (GroovyResolveResult candidate : candidates) {
final PsiElement element = candidate.getElement();
if (element instanceof PsiMethod) {
allMethods.add((PsiMethod)element);
final PsiMethod m = (PsiMethod)element;
if (!isTheSameMethod(method, psiManager, m) && PsiImplUtil.isExtendsSignature(m.getHierarchicalMethodSignature(), signature)) {
goodSupers.add(m);
}
}
}
final MethodSignature signature = method.getHierarchicalMethodSignature();
List<PsiMethod> goodSupers = new ArrayList<PsiMethod>();
for (PsiMethod m : allMethods) {
if (PsiImplUtil.isExtendsSignature(m.getHierarchicalMethodSignature(), signature)) {
goodSupers.add(m);
}
}
if (goodSupers.size() == 0) return true;
final PsiManager psiManager = PsiManager.getInstance(project);
final GlobalSearchScope searchScope = GlobalSearchScope.allScope(project);
List<PsiMethod> result = new ArrayList<PsiMethod>(goodSupers.size());
@@ -125,6 +123,10 @@ public class GDKSuperMethodSearcher implements QueryExecutor<MethodSignatureBack
return true;
}
private static boolean isTheSameMethod(PsiMethod method, PsiManager psiManager, PsiMethod m) {
return psiManager.areElementsEquivalent(m, method) || psiManager.areElementsEquivalent(m.getNavigationElement(), method);
}
private static PsiMethod getRealMethod(PsiMethod method) {
final PsiElement element = method.getNavigationElement();
if (element instanceof PsiMethod && ((PsiMethod)element).getParameterList().getParametersCount() > 0) {
@@ -1026,4 +1026,31 @@ fo<caret>o()
assertNotNull(ref.resolve())
}
public void testMixin() {
def ref = configureByText('''\
@Mixin([Category1, Category2])
class A {
def test1(){}
}
@Category(A)
class Category1 {
boolean foo() {
true
}
}
@Category(A)
class Category2 {
void bar() {
fo<caret>o()
}
}
''')
assertNotNull(ref.resolve())
}
}