TypeName::Identifier method reference applicability when TypeName denotes interface

This commit is contained in:
Anna Kozlova
2015-01-31 16:13:13 +03:00
parent e41b02e277
commit 82246db879
4 changed files with 65 additions and 0 deletions
@@ -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}
@@ -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;
}
};
}
}
@@ -350,6 +350,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testTypeNameInterfaceSuperMethodReferenceApplicability() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}