From ae5717690b47af6953c0fa658934ea9c3b15102d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Sat, 31 May 2014 20:05:17 +0400 Subject: [PATCH] provide 'place' language level for convertible check to allow types from old libraries to be casted to primitives (IDEA-117684) --- .../daemon/impl/analysis/HighlightUtil.java | 2 +- .../intellij/psi/util/TypeConversionUtil.java | 27 ++++++++++++++----- .../CastObjectToIntJdk14.java | 7 +++++ .../daemon/GenericsHighlightingTest.java | 2 ++ 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/CastObjectToIntJdk14.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 086d3546d2c8..d9eadce49b15 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -347,7 +347,7 @@ public class HighlightUtil extends HighlightUtilBase { PsiType operandType = operand.getType(); if (operandType != null && - !TypeConversionUtil.areTypesConvertible(operandType, castType) && + !TypeConversionUtil.areTypesConvertible(operandType, castType, PsiUtil.getLanguageLevel(expression)) && !RedundantCastUtil.isInPolymorphicCall(expression)) { String message = JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil .formatType(castType)); 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 e1533448dda3..5a793b9ef340 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 @@ -96,6 +96,13 @@ public class TypeConversionUtil { * @return true if fromType can be casted to toType */ public static boolean areTypesConvertible(@NotNull PsiType fromType, @NotNull PsiType toType) { + return areTypesConvertible(fromType, toType, null); + } + + /** + * @return true if fromType can be casted to toType + */ + public static boolean areTypesConvertible(@NotNull PsiType fromType, @NotNull PsiType toType, @Nullable LanguageLevel languageLevel) { if (fromType == toType) return true; final boolean fromIsPrimitive = isPrimitiveAndNotNull(fromType); final boolean toIsPrimitive = isPrimitiveAndNotNull(toType); @@ -119,13 +126,19 @@ public class TypeConversionUtil { return boxedType != null && areTypesConvertible(boxedType, toType); } if (!fromIsPrimitive) { - if (fromType instanceof PsiClassType && ((PsiClassType)fromType).getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_7)) { - final PsiClassType classType = (PsiClassType)fromType; - final PsiClass psiClass = classType.resolve(); - if (psiClass == null || psiClass instanceof PsiTypeParameter) return false; - final PsiClassType boxedType = ((PsiPrimitiveType)toType).getBoxedType(psiClass.getManager(), psiClass.getResolveScope()); - if (boxedType != null && isAssignable(fromType, boxedType)) { - return true; + if (fromType instanceof PsiClassType) { + if (languageLevel == null) { + languageLevel = ((PsiClassType)fromType).getLanguageLevel(); + } + + if (languageLevel.isAtLeast(LanguageLevel.JDK_1_7)) { + final PsiClassType classType = (PsiClassType)fromType; + final PsiClass psiClass = classType.resolve(); + if (psiClass == null || psiClass instanceof PsiTypeParameter) return false; + final PsiClassType boxedType = ((PsiPrimitiveType)toType).getBoxedType(psiClass.getManager(), psiClass.getResolveScope()); + if (boxedType != null && isAssignable(fromType, boxedType)) { + return true; + } } } return fromTypeRank == toTypeRank || diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/CastObjectToIntJdk14.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/CastObjectToIntJdk14.java new file mode 100644 index 000000000000..4dc0dae7765d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/CastObjectToIntJdk14.java @@ -0,0 +1,7 @@ +class Test { + + Object getObj() {return null;} + { + int a = (int) getObj(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 7db702fded42..c40cdf5671a5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -358,6 +358,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA125423() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA118533() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA112117() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + //jdk should propagate LL 1.4 but actually it provides LL 1.7?! + public void testCastObjectToIntJdk14() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_4, false); } public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));