new inference: refinement on generics array creation/forbid wildcards in ClassType qualifier

(cherry picked from commit 72a410e804b569893f0bad7739bdd9a7c1c270f1)
This commit is contained in:
anna
2013-11-19 14:08:50 +01:00
parent d42efc06bb
commit f66adc7985
6 changed files with 56 additions and 3 deletions

View File

@@ -1222,6 +1222,23 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
}
}
if (!myHolder.hasErrorResults()) {
PsiElement qualifier = expression.getQualifier();
if (qualifier instanceof PsiTypeElement) {
final PsiType psiType = ((PsiTypeElement)qualifier).getType();
final HighlightInfo genericArrayCreationInfo = GenericsHighlightUtil.checkGenericArrayCreation(qualifier, psiType);
if (genericArrayCreationInfo != null) {
myHolder.add(genericArrayCreationInfo);
} else {
final String wildcardMessage = PsiMethodReferenceUtil.checkTypeArguments((PsiTypeElement)qualifier, psiType);
if (wildcardMessage != null) {
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(wildcardMessage).create());
}
}
}
}
if (!myHolder.hasErrorResults()) {
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
}

View File

@@ -444,4 +444,19 @@ public class PsiMethodReferenceUtil {
return method.getParameterList().getParametersCount() + 1 == parameterTypes.length &&
hasReceiver(parameterTypes, qualifierResolveResult, methodRef);
}
public static String checkTypeArguments(PsiTypeElement qualifier, PsiType psiType) {
if (psiType instanceof PsiClassType) {
final PsiJavaCodeReferenceElement referenceElement = qualifier.getInnermostComponentReferenceElement();
if (referenceElement != null) {
PsiType[] typeParameters = referenceElement.getTypeParameters();
for (PsiType typeParameter : typeParameters) {
if (typeParameter instanceof PsiWildcardType) {
return "Unexpected wildcard";
}
}
}
}
return null;
}
}

View File

@@ -25,7 +25,7 @@ class Test {
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.IFactory'">IFactory c1 = Anno::new;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.IFactory'">IFactory c2 = E::new;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.IFactory'">IFactory c3 = I::new;</error>
IFactory c4 = Foo<?>::new;
IFactory c4 = <error descr="Unexpected wildcard">Foo<?></error>::new;
IFactory c5 = <error descr="Cannot find class 1">1</error>::new;
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.IFactory'">IFactory c6 = ABar::new;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.IFactory'">IFactory c7 = ABaz::new;</error>
@@ -33,7 +33,7 @@ class Test {
foo<error descr="'foo(Test.IFactory)' in 'Test' cannot be applied to '(<method reference>)'">(Anno::new)</error>;
foo<error descr="'foo(Test.IFactory)' in 'Test' cannot be applied to '(<method reference>)'">(E::new)</error>;
foo<error descr="'foo(Test.IFactory)' in 'Test' cannot be applied to '(<method reference>)'">(I::new)</error>;
foo(Foo<?>::new);
foo(<error descr="Unexpected wildcard">Foo<?></error>::new);
foo(<error descr="Cannot find class 1">1</error>::new);
foo<error descr="'foo(Test.IFactory)' in 'Test' cannot be applied to '(<method reference>)'">(ABar::new)</error>;
foo<error descr="'foo(Test.IFactory)' in 'Test' cannot be applied to '(<method reference>)'">(ABaz::new)</error>;

View File

@@ -42,7 +42,7 @@ class OnArrayTest {
<error descr="Incompatible types. Found: '<method reference>', required: 'OnArrayTest.ArrayReturnType<java.lang.String[]>'">ArrayReturnType<String[]> a3 = int[]::new;</error>
ObjectArrayReturnType a4 = Foo<?>[]::new;
ObjectArrayReturnType a5 = Foo<? extends String>[]::new;
ObjectArrayReturnType a5 = <error descr="Generic array creation">Foo<? extends String>[]</error>::new;
}
}

View File

@@ -0,0 +1,17 @@
class Test {
interface I {
Object foo();
}
static class Foo<X> { }
{
I i1 = <error descr="Unexpected wildcard">Foo<?></error>::new;
I i2 = <error descr="Unexpected wildcard">Foo<? extends String></error>::new;
I i3 = Foo<String>::new;
I i4 = <error descr="Generic array creation">Foo<? extends String>[]</error>::new;
I i5 = <error descr="Generic array creation">Foo<String>[]</error>::new;
}
}

View File

@@ -88,6 +88,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest(true);
}
public void testWildcardsInClassTypeQualifier() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}