IDEA-87725 (Inspection catching "suspicious array casts" would be very useful)

This commit is contained in:
Bas Leijdekkers
2012-08-14 17:23:38 +02:00
parent c49ed8f751
commit 13e85cbe8b
7 changed files with 138 additions and 0 deletions
@@ -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"/>
<localInspection language="JAVA" shortName="SuspiciousArrayCast" bundle="com.siyeh.InspectionGadgetsBundle"
key="suspicious.array.cast.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.probable.bugs" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.bugs.SuspiciousArrayCastInspection"/>
<localInspection language="JAVA" shortName="SuspiciousIndentAfterControlStatement" bundle="com.siyeh.InspectionGadgetsBundle"
key="suspicious.indent.after.control.statement.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.probable.bugs" enabledByDefault="false" level="WARNING"
@@ -1974,3 +1974,5 @@ string.concatenation.missing.whitespace.option=Ignore when not both sides are st
negated.equality.expression.display.name=Negated equality expression
negated.equality.expression.problem.descriptor=Negating ''{0}'' #loc
negated.equality.expression.quickfix=Remove negation
suspicious.array.cast.display.name=Suspicious array cast
suspicious.array.cast.problem.descriptor=Suspicious cast to <code>#ref</code>
@@ -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);
}
}
}
@@ -0,0 +1,9 @@
<html>
<body>
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 <b>ClassCastException</b> at runtime.
<!-- tooltip end -->
<p>
<small>New in 12, Powered by InspectionGadgets</small>
</body>
</html>
@@ -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};
}
}
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>SuspiciousArrayCast.java</file>
<line>5</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Suspicious array cast</problem_class>
<description>Suspicious cast to &lt;code&gt;Long[]&lt;/code&gt;</description>
</problem>
</problems>
@@ -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());
}
}