From ee51eccbf37e7d507a5943ba377444a31a74740c Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 2 Aug 2013 15:37:37 +0200 Subject: [PATCH] dfa should box primitive values coerced into Object (IDEA-111445) --- .../dataFlow/ControlFlowAnalyzer.java | 2 +- .../com/intellij/psi/util/TypeConversionUtil.java | 13 +++++++++++++ .../fixture/LargeIntegersAreNotEqualWhenBoxed.java | 7 +++++++ .../codeInspection/DataFlowInspectionTest.java | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/LargeIntegersAreNotEqualWhenBoxed.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 8f2bc4db3ceb..409a8a99fc5f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -1074,7 +1074,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { if (TypeConversionUtil.isPrimitiveAndNotNull(expectedType) && TypeConversionUtil.isPrimitiveWrapper(exprType)) { addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING, expectedType)); } - else if (TypeConversionUtil.isPrimitiveWrapper(expectedType) && TypeConversionUtil.isPrimitiveAndNotNull(exprType)) { + else if (TypeConversionUtil.isAssignableFromPrimitiveWrapper(expectedType) && TypeConversionUtil.isPrimitiveAndNotNull(exprType)) { addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING, expectedType)); } else if (exprType != expectedType && diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java index 2675e3927d15..46de3614f352 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java @@ -29,6 +29,7 @@ import com.intellij.util.containers.HashMap; import gnu.trove.THashMap; import gnu.trove.THashSet; import gnu.trove.TObjectIntHashMap; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -1202,10 +1203,20 @@ public class TypeConversionUtil { public static boolean isPrimitiveWrapper(String typeName) { return PRIMITIVE_WRAPPER_TYPES.contains(typeName); } + @Contract("null -> false") + public static boolean isAssignableFromPrimitiveWrapper(final PsiType type) { + if (type == null) return false; + return isPrimitiveWrapper(type) || + type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || + type.equalsToText(CommonClassNames.JAVA_LANG_NUMBER); + } + + @Contract("null -> false") public static boolean isPrimitiveWrapper(final PsiType type) { return type != null && isPrimitiveWrapper(type.getCanonicalText()); } + @Contract("null -> false") public static boolean isComposite(final PsiType type) { return type instanceof PsiDisjunctionType || type instanceof PsiIntersectionType; } @@ -1256,10 +1267,12 @@ public class TypeConversionUtil { return PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope()); } + @Contract("null -> null") public static PsiType erasure(@Nullable PsiType type) { return erasure(type, PsiSubstitutor.EMPTY); } + @Contract("null, _ -> null") public static PsiType erasure(@Nullable final PsiType type, @NotNull final PsiSubstitutor beforeSubstitutor) { if (type == null) return null; return type.accept(new PsiTypeVisitor() { diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LargeIntegersAreNotEqualWhenBoxed.java b/java/java-tests/testData/inspection/dataFlow/fixture/LargeIntegersAreNotEqualWhenBoxed.java new file mode 100644 index 000000000000..64e270cb666e --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/LargeIntegersAreNotEqualWhenBoxed.java @@ -0,0 +1,7 @@ +class X { + public static void main(String[] args) { + int primitive = 1024; + Object object = primitive; + System.out.println(primitive == object); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index bbf49761727c..32fc5d688f6c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -279,4 +279,5 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase { public void testContractAnnotation() { doTest(); } public void testBoxingImpliesNotNull() { doTest(); } + public void testLargeIntegersAreNotEqualWhenBoxed() { doTest(); } }