From 1eb56239b7898c3bb9ff4aa3fd1bc8f2f1b16a03 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 30 Mar 2012 11:24:32 +0400 Subject: [PATCH] IDEA-62353 statically imported method is more relevant than all other variants --- .../expressions/GrReferenceResolveUtil.java | 23 ++++++ .../imports/GrImportStatementImpl.java | 2 +- .../processors/MethodResolverProcessor.java | 14 ++-- .../lang/resolve/GroovyResolveTestCase.groovy | 2 +- .../lang/resolve/ResolveMethodTest.groovy | 81 ++++++++++++++++++- 5 files changed, 110 insertions(+), 12 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java index 3971c47a235c..eb8f8d681ac1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java @@ -18,15 +18,19 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; import com.intellij.psi.*; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.TypeConversionUtil; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; 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.MethodResolverProcessor; import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mSPREAD_DOT; @@ -41,6 +45,13 @@ public class GrReferenceResolveUtil { public static boolean resolveImpl(ResolverProcessor processor, GrReferenceExpression place) { GrExpression qualifier = place.getQualifier(); if (qualifier == null) { + if (processor instanceof MethodResolverProcessor || processor instanceof CompletionProcessor) { + processStaticImports(place.getContainingFile(), processor, ResolveState.initial(), place); + if (processor instanceof MethodResolverProcessor && ((MethodResolverProcessor)processor).hasApplicableCandidates()) { + return false; + } + } + if (!ResolveUtil.treeWalkUp(place, processor, true)) return false; if (!processor.hasCandidates()) { qualifier = PsiImplUtil.getRuntimeQualifier(place); @@ -65,6 +76,18 @@ public class GrReferenceResolveUtil { return true; } + private static boolean processStaticImports(PsiFile file, ResolverProcessor processor, ResolveState state, PsiElement place) { + if (file instanceof GroovyFile) { + GrImportStatement[] imports = ((GroovyFile)file).getImportStatements(); + for (GrImportStatement anImport : imports) { + if (anImport.isStatic()) { + if (!anImport.processDeclarations(processor, state, null, place)) return false; + } + } + } + return true; + } + public static boolean processIfJavaLangClass(ResolverProcessor processor, PsiType type, GroovyPsiElement resolveContext, diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/toplevel/imports/GrImportStatementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/toplevel/imports/GrImportStatementImpl.java index 422ba52791f2..8c1d8df8493c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/toplevel/imports/GrImportStatementImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/toplevel/imports/GrImportStatementImpl.java @@ -55,7 +55,7 @@ public class GrImportStatementImpl extends GroovyPsiElementImpl implements GrImp public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, - PsiElement lastParent, + @Nullable PsiElement lastParent, @NotNull PsiElement place) { if (PsiTreeUtil.isAncestor(this, place, false)) { return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java index 988607b9af11..4ff599650d90 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java @@ -60,6 +60,7 @@ public class MethodResolverProcessor extends ResolverProcessor { public MethodResolverProcessor(String name, GroovyPsiElement place, boolean isConstructor, PsiType thisType, @Nullable PsiType[] argumentTypes, PsiType[] typeArguments) { this(name, place, isConstructor, thisType, argumentTypes, typeArguments, false, false); } + public MethodResolverProcessor(String name, GroovyPsiElement place, boolean isConstructor, @@ -113,10 +114,6 @@ public class MethodResolverProcessor extends ResolverProcessor { return true; } - public PsiType getThisType() { - return myThisType; - } - @NotNull public GroovyResolveResult[] getCandidates() { if (!myAllVariants && super.hasCandidates()) { @@ -215,10 +212,11 @@ public class MethodResolverProcessor extends ResolverProcessor { return 0; } - private static boolean isMoreConcreteThan(PsiMethod method, @NotNull final PsiSubstitutor substitutor, - @NotNull PsiMethod another, - @NotNull PsiSubstitutor anotherSubstitutor, - @NotNull GroovyPsiElement context) { + private static boolean isMoreConcreteThan(@NotNull PsiMethod method, + @NotNull final PsiSubstitutor substitutor, + @NotNull PsiMethod another, + @NotNull PsiSubstitutor anotherSubstitutor, + @NotNull GroovyPsiElement context) { if (another instanceof GrGdkMethodImpl && another.getName().equals(method.getName())) { final PsiParameter[] plusParameters = method.getParameterList().getParameters(); final PsiParameter[] defParameters = another.getParameterList().getParameters(); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy index d7633e965c48..de784e23193e 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy @@ -76,7 +76,7 @@ public abstract class GroovyResolveTestCase extends LightGroovyTestCase { } protected PsiReference configureByText(String text) { - configureByText('a.groovy', text); + configureByText('_a.groovy', text); } protected PsiReference configureByText(String fileName, String text) { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy index 4f3bf149894d..5ca76c8eab4f 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.resolve; +import com.intellij.psi.util.PropertyUtil import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression @@ -29,7 +30,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrRe import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl import org.jetbrains.plugins.groovy.util.TestUtils import com.intellij.psi.* -import com.intellij.psi.util.PropertyUtil /** * @author ven @@ -37,7 +37,7 @@ import com.intellij.psi.util.PropertyUtil public class ResolveMethodTest extends GroovyResolveTestCase { @Override protected String getBasePath() { - return TestUtils.getTestDataPath() + "resolve/method/"; + return TestUtils.testDataPath + "resolve/method/"; } @@ -863,4 +863,81 @@ def scriptMethod(String s){} assertNull(ref.resolve()) } + + public void testStaticallyImportedMethodsVsDGMMethods() { + myFixture.addClass('''\ +package p; +public class Matcher{} +''' ) + myFixture.addClass('''\ +package p; +class Other { + public static Matcher is(Matcher m){} + public static Matcher create(){} +}''') + + def ref = configureByText('''\ +import static p.Other.is +import static p.Other.create + +is(create()) + +''') + + def resolved = ref.resolve() + assertInstanceOf resolved, PsiMethod + assertEquals 'Other', resolved.containingClass.name + } + + public void testStaticallyImportedMethodsVsCurrentClassMethod() { + myFixture.addClass('''\ +package p; +class Other { + public static Object is(Object m){} +}''') + + def ref = configureByText('''\ +import static p.Other.is + +class A { + public boolean is(String o){true} + + public foo() { + print is('abc') + } +} + +''') + + def resolved = ref.resolve() + assertInstanceOf resolved, PsiMethod + assertEquals 'Other', resolved.containingClass.name + } + + public void testInapplicableStaticallyImportedMethodsVsCurrentClassMethod() { + myFixture.addClass('''\ +package p; +class Other { + public static Object is(String m){} +}''') + + def ref = configureByText('''\ +import static p.Other.is + +class A { + public boolean is(Object o){true} + + public foo() { + print is(new Object()) + } +} + +''') + + def resolved = ref.resolve() + assertInstanceOf resolved, PsiMethod + assertEquals 'A', resolved.containingClass.name + } + + }