From e43800cb62749a5ff325663a3c355fda363d2cfe Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 24 Jan 2020 14:34:30 +0700 Subject: [PATCH] IDEA-230729 Good code red: Illegal generic type for instanceof GitOrigin-RevId: 03fa8e1c2e663e50bd0968423fe07a9a7e05a0d1 --- .../impl/analysis/GenericsHighlightUtil.java | 19 +++++++++++++--- .../impl/analysis/HighlightVisitorImpl.java | 2 +- .../src/messages/JavaErrorBundle.properties | 1 + .../InstanceOfNonReified.java | 22 +++++++++++++++++++ .../daemon/LightPatternsHighlightingTest.java | 3 +++ 5 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingPatterns/InstanceOfNonReified.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index 552c3d9b4e9d..2ddff7ec9b0a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -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; } /** diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 16d9031bc07b..a4e70fb03071 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -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 diff --git a/java/java-psi-impl/src/messages/JavaErrorBundle.properties b/java/java-psi-impl/src/messages/JavaErrorBundle.properties index a93c18397341..2a81fa4dbdeb 100644 --- a/java/java-psi-impl/src/messages/JavaErrorBundle.properties +++ b/java/java-psi-impl/src/messages/JavaErrorBundle.properties @@ -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 diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingPatterns/InstanceOfNonReified.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingPatterns/InstanceOfNonReified.java new file mode 100644 index 000000000000..f80a6f162ec0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingPatterns/InstanceOfNonReified.java @@ -0,0 +1,22 @@ +import java.util.ArrayList; +import java.util.List; + +interface Iface {} +class Cls implements Iface {} +class Foo {} + +class InstanceOfNonReified { + void test(List o) { + boolean b1 = o instanceof ArrayList; + boolean b2 = o instanceof ArrayList; + boolean b3 = o instanceof Foo; + } + + public static void main(String [] args) { + + Object o = new ArrayList(); + if (o instanceof ArrayList ai) { + System.out.println(""); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightPatternsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightPatternsHighlightingTest.java index c78146c847c3..7c352c7e9bae 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightPatternsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightPatternsHighlightingTest.java @@ -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");