diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 96f881ed862e..e0b804182b35 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -27,8 +27,8 @@ magic.number.problem.descriptor=Magic number #ref #loc magic.number.ignore.option=Ignore constants in 'hashCode()' methods method.return.concrete.class.display.name=Method return of concrete class method.return.concrete.class.problem.descriptor=Method returns a concrete class #ref #loc -overly.strong.type.cast.display.name=Overly-strong type cast -overly.strong.type.cast.weaken.quickfix=Weaken overly-strong cast +overly.strong.type.cast.display.name=Overly strong type cast +overly.strong.type.cast.weaken.quickfix=Weaken overly strong cast concrete.class.method.parameter.display.name=Method parameter of concrete class concrete.class.method.parameter.problem.descriptor=Parameter ''{0}'' of concrete class #ref #loc public.method.not.in.interface.display.name='public' method not exposed in interface diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java index c4e04cca3653..d0f93497a37d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; -import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -41,8 +40,7 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "overly.strong.type.cast.display.name"); + return InspectionGadgetsBundle.message("overly.strong.type.cast.display.name"); } @Override @@ -50,17 +48,14 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { protected String buildErrorString(Object... infos) { final PsiType expectedType = (PsiType)infos[0]; final String typeText = expectedType.getPresentableText(); - return InspectionGadgetsBundle.message( - "overly.strong.type.cast.problem.descriptor", typeText); + return InspectionGadgetsBundle.message("overly.strong.type.cast.problem.descriptor", typeText); } @Override @Nullable public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel( - InspectionGadgetsBundle.message( - "overly.strong.type.cast.ignore.in.matching.instanceof.option"), - this, "ignoreInMatchingInstanceof"); + return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("overly.strong.type.cast.ignore.in.matching.instanceof.option"), + this, "ignoreInMatchingInstanceof"); } @Override @@ -73,21 +68,17 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { @Override @NotNull public String getName() { - return InspectionGadgetsBundle.message( - "overly.strong.type.cast.weaken.quickfix"); + return InspectionGadgetsBundle.message("overly.strong.type.cast.weaken.quickfix"); } @Override - public void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { + public void doFix(Project project, ProblemDescriptor descriptor) { final PsiElement castTypeElement = descriptor.getPsiElement(); - final PsiTypeCastExpression expression = - (PsiTypeCastExpression)castTypeElement.getParent(); + final PsiTypeCastExpression expression = (PsiTypeCastExpression)castTypeElement.getParent(); if (expression == null) { return; } - final PsiType expectedType = - ExpectedTypeUtils.findExpectedType(expression, true); + final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, true); if (expectedType == null) { return; } @@ -96,9 +87,7 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { return; } @NonNls - final String newExpression = - '(' + expectedType.getCanonicalText() + ')' + - operand.getText(); + final String newExpression = '(' + expectedType.getCanonicalText() + ')' + operand.getText(); replaceExpressionAndShorten(expression, newExpression); } } @@ -108,12 +97,10 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { return new OverlyStrongTypeCastVisitor(); } - private class OverlyStrongTypeCastVisitor - extends BaseInspectionVisitor { + private class OverlyStrongTypeCastVisitor extends BaseInspectionVisitor { @Override - public void visitTypeCastExpression( - @NotNull PsiTypeCastExpression expression) { + public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) { super.visitTypeCastExpression(expression); final PsiExpression operand = expression.getOperand(); if (operand == null) { @@ -127,8 +114,7 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { if (type == null) { return; } - final PsiType expectedType = - ExpectedTypeUtils.findExpectedType(expression, true); + final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, true); if (expectedType == null) { return; } @@ -140,7 +126,7 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { return; } if (expectedType.isAssignableFrom(operandType)) { - //then it's redundant, and caught by the built-in exception + //then it's redundant, and caught by the built-in inspection return; } if (isTypeParameter(expectedType)) { @@ -153,19 +139,15 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { return; } } - if (type instanceof PsiPrimitiveType || - expectedType instanceof PsiPrimitiveType) { + if (type instanceof PsiPrimitiveType || expectedType instanceof PsiPrimitiveType) { return; } - if (PsiPrimitiveType.getUnboxedType(type) != null || - PsiPrimitiveType.getUnboxedType(expectedType) != null) { + if (PsiPrimitiveType.getUnboxedType(type) != null || PsiPrimitiveType.getUnboxedType(expectedType) != null) { return; } if (expectedType instanceof PsiClassType) { - final PsiClassType expectedClassType = - (PsiClassType)expectedType; - final PsiClassType expectedRawType = - expectedClassType.rawType(); + final PsiClassType expectedClassType = (PsiClassType)expectedType; + final PsiClassType expectedRawType = expectedClassType.rawType(); if (type.equals(expectedRawType)) { return; } @@ -180,8 +162,7 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { return; } } - if (ignoreInMatchingInstanceof && - InstanceOfUtils.hasAgreeingInstanceof(expression)) { + if (ignoreInMatchingInstanceof && InstanceOfUtils.hasAgreeingInstanceof(expression)) { return; } final PsiTypeElement castTypeElement = expression.getCastType(); @@ -197,10 +178,7 @@ public class OverlyStrongTypeCastInspection extends BaseInspection { } final PsiClassType classType = (PsiClassType)type; final PsiClass aClass = classType.resolve(); - if (aClass == null) { - return false; - } - return aClass instanceof PsiTypeParameter; + return aClass != null && aClass instanceof PsiTypeParameter; } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java index a7efe4953637..788e43356a4b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java @@ -278,6 +278,29 @@ public class ExpectedTypeUtils { expectedType = PsiType.BOOLEAN; } + @Override + public void visitForeachStatement(PsiForeachStatement statement) { + final PsiExpression iteratedValue = statement.getIteratedValue(); + if (iteratedValue == null) { + expectedType = null; + return; + } + final PsiType iteratedValueType = iteratedValue.getType(); + if (!(iteratedValueType instanceof PsiClassType)) { + expectedType = null; + return; + } + final PsiClassType classType = (PsiClassType)iteratedValueType; + final PsiType[] parameters = classType.getParameters(); + final PsiClass iterableClass = ClassUtils.findClass(CommonClassNames.JAVA_LANG_ITERABLE, statement); + if (iterableClass == null) { + expectedType = null; + } + else { + expectedType = JavaPsiFacade.getElementFactory(statement.getProject()).createType(iterableClass, parameters); + } + } + @Override public void visitIfStatement(@NotNull PsiIfStatement statement) { expectedType = PsiType.BOOLEAN; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/CastWeakenTest.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/CastWeakenTest.java deleted file mode 100644 index 98df64c3ea6a..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/CastWeakenTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.siyeh.igtest.abstraction; - -import com.siyeh.igtest.abstraction2.SuperClass2; - -public class CastWeakenTest extends SuperClass2 { - public static void main(String[] args) { - Object a = new CastWeakenTest(); - ((CastWeakenTest)a).getHandle(); - } - - protected Object getHandle() { - return super.getHandle(); - } -} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/OverlyStrongTypeCastInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java similarity index 50% rename from plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/OverlyStrongTypeCastInspection.java rename to plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java index cd62391ff19c..bb67aa939be7 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/OverlyStrongTypeCastInspection.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java @@ -1,23 +1,28 @@ -package com.siyeh.igtest.abstraction; - -import com.siyeh.igtest.abstraction2.SubClass; -import com.siyeh.igtest.abstraction2.SuperClass; -import com.siyeh.igtest.abstraction2.SubClass2; +package com.siyeh.igtest.abstraction.overly_strong_type_cast; +import java.lang.reflect.Array; +import java.util.AbstractList; import java.util.ArrayList; import java.util.List; -import java.util.AbstractList; -import java.lang.reflect.Array; -import java.io.Serializable; + + + + interface TestInter{} -public class OverlyStrongTypeCastInspection +public class OverlyStrongTypeCast { + void iterate(Object o) { + for (Object object : (ArrayList) o) {} + for (String s : (ArrayList) o) {} + } + void optional(Object foo) { - if (foo instanceof OverlyStrongTypeCastInspection) { - ((OverlyStrongTypeCastInspection)foo).hashCode(); + if (foo instanceof SubClass2) { + ((SubClass2)foo).doSmth(); } + ((SubClass2)foo).doSmth(); } public static void main(String[] args) @@ -47,15 +52,16 @@ public class OverlyStrongTypeCastInspection ((SubClass2)testSub).doSmth(); } } -interface Task extends Serializable {} -interface ConcreteTask extends Task { - void aMethod(); +class SuperClass{ + protected void doSmth(){ + } +} +class SubClass extends SuperClass{ + public void doSmth(){ + } +} +class SubClass2 extends SubClass{ + public void doSmth(){ + super.doSmth(); + } } -class Test { - public void main(String[] argv) { - Task t = new Task() {}; - if (t instanceof ConcreteTask) - // We get a warning here that the cast can be weakened to "ConcreteTask". - ((ConcreteTask)t).aMethod(); - } -} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/expected.xml new file mode 100644 index 000000000000..ddccdf841d1a --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/expected.xml @@ -0,0 +1,30 @@ + + + + OverlyStrongTypeCast.java + 17 + Overly strong type cast + Cast to <code>ArrayList</code> can be weakened to 'Iterable' #loc + + + + OverlyStrongTypeCast.java + 18 + Overly strong type cast + Cast to <code>ArrayList<String></code> can be weakened to 'Iterable<String>' #loc + + + + OverlyStrongTypeCast.java + 25 + Overly strong type cast + Cast to <code>SubClass2</code> can be weakened to 'SuperClass' #loc + + + + OverlyStrongTypeCast.java + 31 + Overly strong type cast + Cast to <code>ArrayList</code> can be weakened to 'AbstractList' #loc + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SubClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SubClass.java deleted file mode 100644 index 35acf749617d..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SubClass.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.siyeh.igtest.abstraction2; - -public class SubClass extends SuperClass{ - public void doSmth(){ - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SubClass2.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SubClass2.java deleted file mode 100644 index 8121817ec642..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SubClass2.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.siyeh.igtest.abstraction2; - - -public class SubClass2 extends SubClass{ - public void doSmth(){ - super.doSmth(); - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SuperClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SuperClass.java deleted file mode 100644 index ac78bec543f2..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SuperClass.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.siyeh.igtest.abstraction2; - -public class SuperClass{ - protected void doSmth(){ - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SuperClass2.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SuperClass2.java deleted file mode 100644 index 56c87560b475..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction2/SuperClass2.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.siyeh.igtest.abstraction2; - -public class SuperClass2 { - protected Object getHandle() { - return null; - }; -} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java new file mode 100644 index 000000000000..2912c294528d --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java @@ -0,0 +1,12 @@ +package com.siyeh.ig.abstraction; + +import com.siyeh.ig.IGInspectionTestCase; + +public class OverlyStrongTypeCastInspectionTest extends IGInspectionTestCase { + + public void test() throws Exception { + final OverlyStrongTypeCastInspection tool = new OverlyStrongTypeCastInspection(); + tool.ignoreInMatchingInstanceof = true; + doTest("com/siyeh/igtest/abstraction/overly_strong_type_cast", tool); + } +} \ No newline at end of file