Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2017-04-09 21:54:18 +0000
committerStephan Herrmann2017-04-11 13:05:21 +0000
commit8e7f77d85abf81407daed23fef4b3a32a6ec4955 (patch)
tree2f1c781648387af088ac48e1e653c9dff99b0b24
parent7fde25559f0d9bae5414d15e552cebaf117cd858 (diff)
downloadeclipse.jdt.core-8e7f77d85abf81407daed23fef4b3a32a6ec4955.tar.gz
eclipse.jdt.core-8e7f77d85abf81407daed23fef4b3a32a6ec4955.tar.xz
eclipse.jdt.core-8e7f77d85abf81407daed23fef4b3a32a6ec4955.zip
Bug 514956: Don't warn about "unnecessary" cast that is used to avoidI20170411-2000
"unlikely argument type" warning Change-Id: I22fc9861bbc8e7cd5e5807babe1488c36163783c Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de>
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java76
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java24
2 files changed, 98 insertions, 2 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java
index 47ee79b629..29ed4e81c4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java
@@ -3221,6 +3221,82 @@ public void testBug410218f() {
true/*shouldFlushOutputDirectory*/,
customOptions);
}
+public void testBug514956a() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5)
+ return;
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_PB_UNLIKELY_COLLECTION_METHOD_ARGUMENT_TYPE, JavaCore.WARNING);
+ customOptions.put(JavaCore.COMPILER_PB_UNNECESSARY_TYPE_CHECK, JavaCore.ERROR);
+ runConformTest(
+ new String[] {
+ "Unlikely.java",
+ "import java.util.Map;\n" +
+ "\n" +
+ "interface MApplicationElement {}\n" +
+ "interface EObject {}\n" +
+ "public class Unlikely {\n" +
+ " void m(Map<MApplicationElement, MApplicationElement> map, EObject key) {\n" +
+ " map.get((MApplicationElement)key);\n" +
+ " }\n" +
+ "}\n"
+ },
+ customOptions);
+}
+public void testBug514956b() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_PB_UNLIKELY_EQUALS_ARGUMENT_TYPE, JavaCore.WARNING);
+ customOptions.put(JavaCore.COMPILER_PB_UNNECESSARY_TYPE_CHECK, JavaCore.ERROR);
+ runConformTest(
+ new String[] {
+ "Unlikely.java",
+ "interface EObject {}\n" +
+ "public class Unlikely {\n" +
+ " boolean m(EObject key) {\n" +
+ " return this.equals((Unlikely)key);\n" +
+ " }\n" +
+ "}\n"
+ },
+ customOptions);
+}
+public void testBug514956c() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_PB_UNLIKELY_EQUALS_ARGUMENT_TYPE, JavaCore.WARNING);
+ customOptions.put(JavaCore.COMPILER_PB_UNNECESSARY_TYPE_CHECK, JavaCore.ERROR);
+ runNegativeTest(
+ new String[] {
+ "Unlikely.java",
+ "interface I1 {}\n" +
+ "interface I2 {}\n" +
+ "interface I3 {}\n" +
+ "public class Unlikely implements I1 {\n" +
+ " boolean m1(I1 i1) {\n" +
+ " return i1.equals((I1)this);\n" + // not a downcast
+ " }\n" +
+ " boolean m2(I1 i1, I2 i2) {\n" +
+ " return i1.equals((I3)i2);\n" + // cast doesn't fix a problem
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Unlikely.java (at line 6)\n" +
+ " return i1.equals((I1)this);\n" +
+ " ^^^^^^^^\n" +
+ "Unnecessary cast from Unlikely to I1\n" +
+ "----------\n" +
+ "2. ERROR in Unlikely.java (at line 9)\n" +
+ " return i1.equals((I3)i2);\n" +
+ " ^^^^^^\n" +
+ "Unnecessary cast from I2 to I3\n" +
+ "----------\n" +
+ "3. WARNING in Unlikely.java (at line 9)\n" +
+ " return i1.equals((I3)i2);\n" +
+ " ^^^^^^\n" +
+ "Unlikely argument type for equals(): I3 seems to be unrelated to I1\n" +
+ "----------\n",
+ null, // classlibs
+ false, // flush output dir
+ customOptions);
+}
// mixture of raw type an parametrized type
public void testBug513310() {
if (this.complianceLevel < ClassFileConstants.JDK1_5)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index 1c7dafb98c..0c12277070 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -37,6 +37,7 @@ import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
@@ -322,12 +323,31 @@ private static void checkAlternateBinding(BlockScope scope, Expression receiver,
for (int i = 0; i < argumentLength; i++) {
if (TypeBinding.notEquals(originalArgumentTypes[i], alternateArgumentTypes[i])
/*&& !originalArgumentTypes[i].needsUncheckedConversion(alternateArgumentTypes[i])*/) {
- scope.problemReporter().unnecessaryCast((CastExpression)arguments[i]);
+ if (!preventsUnlikelyTypeWarning(originalArgumentTypes[i], alternateArgumentTypes[i], receiverType, binding, scope))
+ scope.problemReporter().unnecessaryCast((CastExpression)arguments[i]);
}
}
}
}
+private static boolean preventsUnlikelyTypeWarning(TypeBinding castedType, TypeBinding uncastedType, TypeBinding receiverType, MethodBinding binding, BlockScope scope) {
+ if (!scope.compilerOptions().isAnyEnabled(IrritantSet.UNLIKELY_ARGUMENT_TYPE))
+ return false;
+ if (binding.isStatic() || binding.parameters.length != 1)
+ return false;
+ // would using the uncastedType be considered as dangerous?
+ UnlikelyArgumentCheck argumentChecks = UnlikelyArgumentCheck.determineCheckForNonStaticSingleArgumentMethod(
+ uncastedType, scope, binding.selector, receiverType, binding.parameters);
+ if (argumentChecks != null && argumentChecks.isDangerous(scope)) {
+ // does the cast help?
+ argumentChecks = UnlikelyArgumentCheck.determineCheckForNonStaticSingleArgumentMethod(
+ castedType, scope, binding.selector, receiverType, binding.parameters);
+ if (argumentChecks == null || !argumentChecks.isDangerous(scope))
+ return true;
+ }
+ return false;
+}
+
public boolean checkUnsafeCast(Scope scope, TypeBinding castType, TypeBinding expressionType, TypeBinding match, boolean isNarrowing) {
if (TypeBinding.equalsEquals(match, castType)) {
if (!isNarrowing && TypeBinding.equalsEquals(match, this.resolvedType.leafComponentType()) // do not tag as unnecessary when recursing through upper bounds

Back to the top