mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 21:41:24 +07:00
overload resolution: treat default methods as abstract; don't include static interface methods in conflict resolution when target expression type does not correspond to the containing interface (IDEA-146055)
This commit is contained in:
@@ -403,6 +403,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
else if (expression == null && !ImportsUtil.hasStaticImportOn(parent, method, true)) {
|
||||
return PsiTreeUtil.getParentOfType(parent, PsiClass.class);
|
||||
}
|
||||
|
||||
if (expression != null) {
|
||||
return PsiUtil.resolveClassInType(expression.getType());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -616,23 +620,16 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
if (applicable12 && !applicable21) return Specifics.SECOND;
|
||||
if (applicable21 && !applicable12) return Specifics.FIRST;
|
||||
|
||||
final boolean abstract1 = method1.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
final boolean abstract2 = method2.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
|
||||
//from 15.12.2.5 Choosing the Most Specific Method: concrete = nonabstract or default
|
||||
final boolean abstract1 = method1.hasModifierProperty(PsiModifier.ABSTRACT) || method1.hasModifierProperty(PsiModifier.DEFAULT);
|
||||
final boolean abstract2 = method2.hasModifierProperty(PsiModifier.ABSTRACT) || method2.hasModifierProperty(PsiModifier.DEFAULT);
|
||||
if (abstract1 && !abstract2) {
|
||||
return Specifics.SECOND;
|
||||
}
|
||||
if (abstract2 && !abstract1) {
|
||||
return Specifics.FIRST;
|
||||
}
|
||||
|
||||
if (method1.hasModifierProperty(PsiModifier.DEFAULT) && method2.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return Specifics.FIRST;
|
||||
}
|
||||
|
||||
if (method2.hasModifierProperty(PsiModifier.DEFAULT) && method1.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return Specifics.SECOND;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (varargsPosition) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
interface A<T> {
|
||||
void foo(T x);
|
||||
default void foo(String x) { }
|
||||
}
|
||||
|
||||
class C implements A<String> {
|
||||
@Override
|
||||
public void foo(String x) {
|
||||
A.super.foo<error descr="Ambiguous method call: both 'A.foo(String)' and 'A.foo(String)' match">(x)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
interface A2<T> {
|
||||
Object foo(T x);
|
||||
default Integer foo(String <warning descr="Parameter 'x' is never used">x</warning>) { return null; }
|
||||
}
|
||||
|
||||
abstract class C2 {
|
||||
public void foo(A2<String> x) {
|
||||
x.foo<error descr="Ambiguous method call: both 'A2.foo(String)' and 'A2.foo(String)' match">("")</error>;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,33 @@ class Test {
|
||||
public static void main(String[] args) {
|
||||
new IJ(). f();
|
||||
new JI(). f();
|
||||
|
||||
IJ.<error descr="Non-static method 'f()' cannot be referenced from a static context">f</error>();
|
||||
JI.<error descr="Non-static method 'f()' cannot be referenced from a static context">f</error>();
|
||||
|
||||
J.f();
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 {
|
||||
interface I {
|
||||
static void f(String <warning descr="Parameter 's' is never used">s</warning>) {}
|
||||
}
|
||||
|
||||
interface J<T> {
|
||||
default void f(T <warning descr="Parameter 't' is never used">t</warning>) {}
|
||||
|
||||
//another pair
|
||||
default void j(T <warning descr="Parameter 't' is never used">t</warning>) {}
|
||||
static void j(String <warning descr="Parameter 's' is never used">s</warning>) {};
|
||||
}
|
||||
|
||||
static class IJ implements I, J<String> {}
|
||||
|
||||
public static void main(IJ s, J<String> j) {
|
||||
s.f("");
|
||||
|
||||
<error descr="Static method may be invoked on containing interface class only">j.j("");</error>
|
||||
}
|
||||
|
||||
}
|
||||
@@ -89,6 +89,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDefaultAbstractConflictResolution() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testLambdaValueCompatibleWithNestedTryWithResources() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user