From 13e85cbe8b44aae6df2c6cfaeb2dbbb1cb9152c4 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 14 Aug 2012 17:23:38 +0200 Subject: [PATCH] IDEA-87725 (Inspection catching "suspicious array casts" would be very useful) --- .../InspectionGadgets/src/META-INF/plugin.xml | 4 + .../siyeh/InspectionGadgetsBundle.properties | 2 + .../bugs/SuspiciousArrayCastInspection.java | 93 +++++++++++++++++++ .../SuspiciousArrayCast.html | 9 ++ .../SuspiciousArrayCast.java | 11 +++ .../bugs/suspicious_array_cast/expected.xml | 9 ++ .../SuspiciousArrayCastInspectionTest.java | 10 ++ 7 files changed, 138 insertions(+) create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/bugs/SuspiciousArrayCastInspection.java create mode 100644 plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousArrayCast.html create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/suspicious_array_cast/SuspiciousArrayCast.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/suspicious_array_cast/expected.xml create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/SuspiciousArrayCastInspectionTest.java diff --git a/plugins/InspectionGadgets/src/META-INF/plugin.xml b/plugins/InspectionGadgets/src/META-INF/plugin.xml index 847c3b17bcaf..0f979f533279 100644 --- a/plugins/InspectionGadgets/src/META-INF/plugin.xml +++ b/plugins/InspectionGadgets/src/META-INF/plugin.xml @@ -360,6 +360,10 @@ key="subtraction.in.compareto.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.probable.bugs" enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.bugs.SubtractionInCompareToInspection"/> + #ref diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/SuspiciousArrayCastInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/SuspiciousArrayCastInspection.java new file mode 100644 index 000000000000..0a56e13387af --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/SuspiciousArrayCastInspection.java @@ -0,0 +1,93 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.bugs; + +import com.intellij.psi.*; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +/** + * @author Bas Leijdekkers + */ +public class SuspiciousArrayCastInspection extends BaseInspection { + + @Nls + @NotNull + @Override + public String getDisplayName() { + return InspectionGadgetsBundle.message("suspicious.array.cast.display.name"); + } + + @NotNull + @Override + protected String buildErrorString(Object... infos) { + return InspectionGadgetsBundle.message("suspicious.array.cast.problem.descriptor"); + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new SuspiciousArrayCastVisitor(); + } + + private static class SuspiciousArrayCastVisitor extends BaseInspectionVisitor { + + @Override + public void visitTypeCastExpression(PsiTypeCastExpression expression) { + super.visitTypeCastExpression(expression); + final PsiTypeElement typeElement = expression.getCastType(); + if (typeElement == null) { + return; + } + final PsiType castType = typeElement.getType(); + if (!(castType instanceof PsiArrayType)) { + return; + } + final PsiExpression operand = expression.getOperand(); + if (operand == null) { + return; + } + final PsiType type = operand.getType(); + if (!(type instanceof PsiArrayType)) { + return; + } + final PsiType castComponentType = castType.getDeepComponentType(); + if (!(castComponentType instanceof PsiClassType)) { + return; + } + final PsiClassType castClassType = (PsiClassType)castComponentType; + final PsiClass castClass = castClassType.resolve(); + if (castClass == null) { + return; + } + final PsiType componentType = type.getDeepComponentType(); + if (!(componentType instanceof PsiClassType)) { + return; + } + final PsiClassType classType = (PsiClassType)componentType; + final PsiClass aClass = classType.resolve(); + if (aClass == null) { + return; + } + if (!castClass.isInheritor(aClass, true)) { + return; + } + registerError(typeElement); + } + } +} diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousArrayCast.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousArrayCast.html new file mode 100644 index 000000000000..79386eb05bf8 --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousArrayCast.html @@ -0,0 +1,9 @@ + + +This inspection reports suspicious array casts. An array cast is suspicious when it casts to a more specific array type. Such +a cast is legal at compile time but may fail with a ClassCastException at runtime. + +

+New in 12, Powered by InspectionGadgets + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/suspicious_array_cast/SuspiciousArrayCast.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/suspicious_array_cast/SuspiciousArrayCast.java new file mode 100644 index 000000000000..6eb91bd28a3d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/suspicious_array_cast/SuspiciousArrayCast.java @@ -0,0 +1,11 @@ +package com.siyeh.igtest.bugs.suspicious_array_cast; + +class SuspiciousArrayCast { + + private Long[] longs = (Long[])getNumbers(); + private Number[] numbers = (Number[])getNumbers(); + + private Number[] getNumbers() { + return new Number[]{1L, 2L, 4L}; + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/suspicious_array_cast/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/suspicious_array_cast/expected.xml new file mode 100644 index 000000000000..3cada1d87fe5 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/suspicious_array_cast/expected.xml @@ -0,0 +1,9 @@ + + + + SuspiciousArrayCast.java + 5 + Suspicious array cast + Suspicious cast to <code>Long[]</code> + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/SuspiciousArrayCastInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/SuspiciousArrayCastInspectionTest.java new file mode 100644 index 000000000000..6038046d3fb5 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/SuspiciousArrayCastInspectionTest.java @@ -0,0 +1,10 @@ +package com.siyeh.ig.bugs; + +import com.siyeh.ig.IGInspectionTestCase; + +public class SuspiciousArrayCastInspectionTest extends IGInspectionTestCase { + + public void test() throws Exception { + doTest("com/siyeh/igtest/bugs/suspicious_array_cast", new SuspiciousArrayCastInspection()); + } +} \ No newline at end of file