mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
TypeName::Identifier method reference applicability when TypeName denotes interface
This commit is contained in:
+18
@@ -1448,6 +1448,24 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
return HighlightClassUtil.reportIllegalEnclosingUsage(expr, null, aClass, expr);
|
||||
}
|
||||
|
||||
if (qualifier != null && expr.getParent() instanceof PsiMethodReferenceExpression && aClass.isInterface()) {
|
||||
//15.13
|
||||
//If TypeName denotes an interface, I, then let T be the type declaration immediately enclosing the method reference expression.
|
||||
//It is a compile-time error if I is not a direct superinterface of T,
|
||||
//or if there exists some other direct superclass or direct superinterface of T, J, such that J is a subtype of I.
|
||||
final PsiClass classT = PsiTreeUtil.getParentOfType(expr, PsiClass.class);
|
||||
if (classT != null) {
|
||||
for (PsiClass superClass : classT.getSupers()) {
|
||||
if (superClass.isInterface() && //check spec-javac relations
|
||||
superClass.isInheritor(aClass, true)) {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(qualifier)
|
||||
.descriptionAndTooltip(JavaErrorMessages.message("bad.qualifier.in.super.method.reference", format(aClass), formatClass(superClass))).create();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof PsiThisExpression) {
|
||||
final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(expr, PsiMethod.class);
|
||||
if (psiMethod == null || psiMethod.getContainingClass() != aClass && !isInsideDefaultMethod(psiMethod, aClass)) {
|
||||
|
||||
@@ -388,3 +388,4 @@ feature.method.references=Method references
|
||||
feature.lambda.expressions=Lambda expressions
|
||||
feature.type.annotations=Type annotations
|
||||
insufficient.language.level={0} are not supported at this language level
|
||||
bad.qualifier.in.super.method.reference=Bad type qualifier in default super call: redundant interface {0} is extended by {1}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
interface I {
|
||||
default void a() {}
|
||||
}
|
||||
|
||||
interface J extends I {}
|
||||
|
||||
class A implements I {}
|
||||
class B extends A {}
|
||||
class C implements J {}
|
||||
|
||||
class Test1 implements I { { Runnable r = I.super::a; } }
|
||||
class Test2 implements J { { Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a; } }
|
||||
class Test3 implements I, J { { Runnable r = <error descr="Bad type qualifier in default super call: redundant interface I is extended by J">I</error>.super::a; } }
|
||||
class Test5 extends A implements I { { Runnable r = I.super::a; } }
|
||||
class Test6 extends A implements J { { Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a; } }
|
||||
class Test7 extends B { { Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a; } }
|
||||
class Test8 extends C { { Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a; } }
|
||||
|
||||
class Test {
|
||||
{
|
||||
class LocalJ implements I {
|
||||
}
|
||||
class Test3 extends LocalJ implements I {
|
||||
{
|
||||
Runnable r = I.super::a;
|
||||
}
|
||||
}
|
||||
|
||||
new I() {
|
||||
{
|
||||
Runnable r = I.super::a;
|
||||
}
|
||||
};
|
||||
|
||||
new A() {
|
||||
{
|
||||
Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -350,6 +350,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testTypeNameInterfaceSuperMethodReferenceApplicability() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user