IDEA-230729 Good code red: Illegal generic type for instanceof

GitOrigin-RevId: 03fa8e1c2e663e50bd0968423fe07a9a7e05a0d1
This commit is contained in:
Tagir Valeev
2020-01-24 08:03:38 +00:00
committed by intellij-monorepo-bot
parent 477d0289c9
commit e43800cb62
5 changed files with 43 additions and 4 deletions
@@ -820,7 +820,7 @@ public class GenericsHighlightUtil {
if (type instanceof PsiClassType && ((PsiClassType)type).resolve() == aClass) return null;
}
if (PsiUtil.isCompileTimeConstant((PsiVariable)field)) return null;
if (PsiUtil.isCompileTimeConstant(field)) return null;
String description = JavaErrorBundle.message(
"illegal.to.access.static.member.from.enum.constructor.or.instance.initializer",
@@ -925,10 +925,23 @@ public class GenericsHighlightUtil {
return result;
}
static HighlightInfo checkInstanceOfGenericType(@NotNull PsiInstanceOfExpression expression) {
static HighlightInfo checkInstanceOfGenericType(@NotNull LanguageLevel languageLevel, @NotNull PsiInstanceOfExpression expression) {
final PsiTypeElement checkTypeElement = expression.getCheckType();
if (checkTypeElement == null) return null;
return isIllegalForInstanceOf(checkTypeElement.getType(), checkTypeElement);
PsiType checkType = checkTypeElement.getType();
if (HighlightUtil.Feature.PATTERNS.isSufficient(languageLevel)) {
return isUnsafeCastInInstanceOf(checkTypeElement, checkType, expression.getOperand().getType());
}
return isIllegalForInstanceOf(checkType, checkTypeElement);
}
private static HighlightInfo isUnsafeCastInInstanceOf(PsiTypeElement checkTypeElement, PsiType checkType, PsiType expressionType) {
if (expressionType != null && JavaGenericsUtil.isUncheckedCast(checkType, expressionType)) {
String description = JavaErrorBundle.message("unsafe.cast.in.instanceof",
expressionType.getPresentableText(), checkType.getPresentableText());
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(checkTypeElement).descriptionAndTooltip(description).create();
}
return null;
}
/**
@@ -819,7 +819,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
super.visitInstanceOfExpression(expression);
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInstanceOfApplicable(expression));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInstanceOfGenericType(expression));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInstanceOfGenericType(myLanguageLevel, expression));
}
@Override
@@ -102,6 +102,7 @@ generics.duplicate.type.parameter=Duplicate type parameter: ''{0}''
generics.cannot.catch.type.parameters=Cannot catch type parameters
generics.cannot.instanceof.type.parameters=Class or array expected
illegal.generic.type.for.instanceof=Illegal generic type for instanceof
unsafe.cast.in.instanceof=''{0}'' cannot be safely cast to ''{1}''
cannot.select.dot.class.from.type.variable=Cannot select from a type variable
method.does.not.override.super=Method does not override method from its superclass
call.to.super.is.not.allowed.in.enum.constructor=Call to super is not allowed in enum constructor
@@ -0,0 +1,22 @@
import java.util.ArrayList;
import java.util.List;
interface Iface {}
class Cls implements Iface {}
class Foo<T> {}
class InstanceOfNonReified {
void test(List<Cls> o) {
boolean b1 = o instanceof ArrayList<Cls>;
boolean b2 = <error descr="Inconvertible types; cannot cast 'java.util.List<Cls>' to 'java.util.ArrayList<Iface>'">o instanceof ArrayList<Iface></error>;
boolean b3 = o instanceof <error descr="'List<Cls>' cannot be safely cast to 'Foo<Cls>'">Foo<Cls></error>;
}
public static void main(String [] args) {
Object o = new ArrayList<Object>();
if (o instanceof <error descr="'Object' cannot be safely cast to 'ArrayList<Integer>'">ArrayList<Integer></error> ai) {
System.out.println("");
}
}
}
@@ -38,6 +38,9 @@ public class LightPatternsHighlightingTest extends LightJavaCodeInsightFixtureTe
myFixture.enableInspections(new UnusedDeclarationInspection());
doTest();
}
public void testInstanceOfNonReified() {
doTest();
}
private void doTest() {
myFixture.configureByFile(getTestName(false) + ".java");