more specific method should be chosen before static access is checked (IDEA-101480)

This commit is contained in:
anna
2013-02-21 15:23:11 +01:00
parent e869310a92
commit 985efd2362
4 changed files with 26 additions and 8 deletions
@@ -67,7 +67,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
checkSameSignatures(conflicts);
if (conflicts.size() == 1) return conflicts.get(0);
checkAccessLevels(conflicts);
checkAccessStaticLevels(conflicts, true);
if (conflicts.size() == 1) return conflicts.get(0);
checkParametersNumber(conflicts, myActualParameterTypes.length, false);
@@ -89,6 +89,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
checkPrimitiveVarargs(conflicts, myActualParameterTypes.length);
if (conflicts.size() == 1) return conflicts.get(0);
checkAccessStaticLevels(conflicts, false);
if (conflicts.size() == 1) return conflicts.get(0);
THashSet<CandidateInfo> uniques = new THashSet<CandidateInfo>(conflicts);
if (uniques.size() == 1) return uniques.iterator().next();
return null;
@@ -158,7 +161,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
}
private static void checkAccessLevels(List<CandidateInfo> conflicts) {
private static void checkAccessStaticLevels(List<CandidateInfo> conflicts, boolean checkAccessible) {
int conflictsCount = conflicts.size();
int maxCheckLevel = -1;
@@ -166,7 +169,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
int index = 0;
for (final CandidateInfo conflict : conflicts) {
final MethodCandidateInfo method = (MethodCandidateInfo)conflict;
final int level = getCheckLevel(method);
final int level = checkAccessible ? getCheckAccessLevel(method) : getCheckStaticLevel(method);
checkLevels[index++] = level;
maxCheckLevel = Math.max(maxCheckLevel, level);
}
@@ -379,11 +382,14 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return level;
}
private static int getCheckLevel(MethodCandidateInfo method){
boolean visible = method.isAccessible();// && !method.myStaticProblem;
private static int getCheckAccessLevel(MethodCandidateInfo method){
boolean visible = method.isAccessible();
return visible ? 1 : 0;
}
private static int getCheckStaticLevel(MethodCandidateInfo method){
boolean available = method.isStaticsScopeCorrect();
return (visible ? 1 : 0) << 2 |
(available ? 1 : 0) << 1 |
return (available ? 1 : 0) << 1 |
(method.getCurrentFileResolveScope() instanceof PsiImportStaticStatement ? 0 : 1);
}
@@ -0,0 +1,11 @@
class Foo {
public void foo() {}
public static void foo(String... s){}
}
class A {
{
Foo.<error descr="Non-static method 'foo()' cannot be referenced from a static context">foo</error>();
}
}
@@ -166,4 +166,5 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
public void testWrongArgsAndUnknownTypeParams() throws Exception { doTest(false, false); }
public void testAmbiguousMethodCallIDEA97983() throws Exception { doTest(false, false); }
public void testAmbiguousMethodCallIDEA100314() throws Exception { doTest(false, false); }
public void testInstanceMemberNotAccessibleInStaticContext() throws Exception { doTest(false, false); }
}
@@ -204,7 +204,7 @@ public class ResolveMethodTest extends ResolveTestCase {
PsiElement target = resolve();
assertTrue(target instanceof PsiMethod);
PsiMethod method = (PsiMethod) target;
assertEquals(1, method.getParameterList().getParametersCount());
assertEquals(0, method.getParameterList().getParametersCount());
}
public void testClone() throws Exception{