mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
resolve/overload resolution: collect static methods of interface called on foreign class/instance but filter them out during overload resolution (IDEA-145187)
This commit is contained in:
@@ -110,6 +110,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
checkParametersNumber(conflicts, getActualParametersLength(), false);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkStaticMethodsOfInterfaces(conflicts);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
final int applicabilityLevel = checkApplicability(conflicts);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
@@ -357,6 +360,51 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return ((MethodCandidateInfo)info).getPertinentApplicabilityLevel() != MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* choose to accept static interface methods during search to get "Static interface methods must be invoked on containing interface class only" error
|
||||
* instead of non clear javac message that symbol not found
|
||||
*
|
||||
* but these methods should be ignored during overload resolution if another methods are present
|
||||
*/
|
||||
private void checkStaticMethodsOfInterfaces(@NotNull List<CandidateInfo> conflicts) {
|
||||
if (!(myArgumentsList instanceof PsiExpressionList)) return;
|
||||
PsiClass qualifierClass = null;
|
||||
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
|
||||
CandidateInfo conflict = iterator.next();
|
||||
if (!(conflict instanceof MethodCandidateInfo)) continue;
|
||||
final PsiMethod method = ((MethodCandidateInfo)conflict).getElement();
|
||||
if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null && containingClass.isInterface()) {
|
||||
if (qualifierClass == null) {
|
||||
qualifierClass = getQualifiedClass(method);
|
||||
if (qualifierClass == null) return;
|
||||
}
|
||||
if (!containingClass.getManager().areElementsEquivalent(containingClass, qualifierClass)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PsiClass getQualifiedClass(PsiMethod method) {
|
||||
final PsiElement parent = myArgumentsList.getParent();
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
final PsiExpression expression = ((PsiMethodCallExpression)parent).getMethodExpression().getQualifierExpression();
|
||||
if (expression instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolve = ((PsiReferenceExpression)expression).resolve();
|
||||
if (resolve instanceof PsiClass) {
|
||||
return (PsiClass)resolve;
|
||||
}
|
||||
}
|
||||
else if (expression == null && !ImportsUtil.hasStaticImportOn(parent, method, true)) {
|
||||
return PsiTreeUtil.getParentOfType(parent, PsiClass.class);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean checkParametersNumber(@NotNull List<CandidateInfo> conflicts,
|
||||
final int argumentsCount,
|
||||
boolean ignoreIfStaticsProblem) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
interface A {
|
||||
static void foo110() {}
|
||||
}
|
||||
|
||||
abstract class B implements A {
|
||||
static void foo110(String... strs){
|
||||
System.out.println(strs);
|
||||
}
|
||||
static void bar110(){}
|
||||
}
|
||||
|
||||
abstract class C extends B {
|
||||
static void bar110(String... strs){
|
||||
System.out.println(strs);
|
||||
}
|
||||
}
|
||||
|
||||
class D {
|
||||
public static void main(String[] args) {
|
||||
B.foo110();
|
||||
C.bar110();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.codeInsight.daemon.lambda;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -77,6 +78,10 @@ public class Interface8MethodsHighlightingTest extends LightCodeInsightFixtureTe
|
||||
|
||||
public void testIDEA120498() { doTest(false, false); }
|
||||
|
||||
public void testIgnoreStaticInterfaceMethods() throws Exception {
|
||||
doTest(true, false);
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user