method refs: check constructor refs qualifiers (IDEA-92722)

This commit is contained in:
anna
2012-10-10 16:43:24 +02:00
parent 0706510a1e
commit a927ecf5d1
4 changed files with 51 additions and 1 deletions

View File

@@ -985,6 +985,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
if (LambdaUtil.dependsOnTypeParams(functionalInterfaceType, functionalInterfaceType, expression, null)) {
myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, "Cyclic inference")); //todo[ann] append not inferred type params info
} else {
final PsiElement referenceNameElement = expression.getReferenceNameElement();
if (referenceNameElement instanceof PsiKeyword) {
if (!LambdaUtil.isValidQualifier(expression)) {
final PsiElement qualifier = expression.getQualifier();
myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, qualifier, "Cannot find class " + qualifier.getText()));
}
}
}
}
}

View File

@@ -570,6 +570,20 @@ public class LambdaUtil {
return true;
}
public static boolean isValidQualifier(PsiMethodReferenceExpression expression) {
final PsiElement referenceNameElement = expression.getReferenceNameElement();
if (referenceNameElement instanceof PsiKeyword) {
final PsiElement qualifier = expression.getQualifier();
if (qualifier instanceof PsiTypeElement) {
return true;
}
if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass) {
return true;
}
}
return false;
}
public static boolean isAcceptable(@Nullable final PsiMethodReferenceExpression methodReferenceExpression, PsiType left) {
if (methodReferenceExpression == null) return false;
Map<PsiMethodReferenceExpression, PsiType> map = ourRefs.get();

View File

@@ -74,3 +74,31 @@ class MyTest3<X> {
test<error descr="'test(MyTest3.I<java.lang.Integer>)' in 'MyTest3' cannot be applied to '(<method reference>)'">(MyTest3<String>::new)</error>;
}
}
class MyTestInvalidQ {
class Super {}
class ConstructorRefs extends Super {
void test() {
ConstructorRefs refs = new ConstructorRefs();
BlahBlah b0 = <error descr="Cannot find class refs">refs</error>::new;
BlahBlah blahBlah = <error descr="Cannot find class this">this</error>::new;
BlahBlah1 blahBlah1 = <error descr="Cannot find class super">super</error>::new;
}
}
interface BlahBlah {
ConstructorRefs foo();
}
interface BlahBlah1 {
Super foo();
}
abstract static class A {
interface I {
A foo();
}
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTestInvalidQ.A.I'">I i = A :: new;</error>
}
}

View File

@@ -53,7 +53,7 @@ class DefaultConstructor2 {
void f() {
<error descr="Incompatible types. Found: '<method reference>', required: 'DefaultConstructor2.I'">I i1 = DefaultConstructor2 :: new;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'DefaultConstructor2.I'">I i2 = this::new;</error>
I i2 = <error descr="Cannot find class this">this</error>::new;
}
}