provide 'place' language level for convertible check to allow types from old libraries to be casted to primitives (IDEA-117684)

This commit is contained in:
Anna Kozlova
2014-05-31 20:36:04 +04:00
parent 2f6d5c9e27
commit ae5717690b
4 changed files with 30 additions and 8 deletions
@@ -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));
@@ -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 ||
@@ -0,0 +1,7 @@
class Test {
Object getObj() {return null;}
{
int a = (int) getObj();
}
}
@@ -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()));