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 8ccab9517a7b..99e2a24aa5fc 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 @@ -33,10 +33,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; +import java.util.*; import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING; @@ -839,7 +836,7 @@ public class TypeConversionUtil { return false; // must be TypeCook's PsiTypeVariable } if (left instanceof PsiPrimitiveType) { - return isUnboxable((PsiPrimitiveType)left, (PsiClassType)right); + return isUnboxable((PsiPrimitiveType)left, (PsiClassType)right, new HashSet()); } final PsiClassType.ClassResolveResult leftResult = PsiUtil.resolveGenericsClassInType(left); final PsiClassType.ClassResolveResult rightResult = PsiUtil.resolveGenericsClassInType(right); @@ -880,7 +877,20 @@ public class TypeConversionUtil { return isAssignable(wildcardType.getExtendsBound(), right); } - private static boolean isUnboxable(@NotNull PsiPrimitiveType left, @NotNull PsiClassType right) { + private static boolean isUnboxable(@NotNull PsiPrimitiveType left, @NotNull PsiClassType right, @NotNull Set types) { + if (!right.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_5)) return false; + final PsiClass psiClass = right.resolve(); + if (psiClass == null) return false; + + if (psiClass instanceof PsiTypeParameter) { + for (PsiClassType bound : psiClass.getExtendsListTypes()) { + if (types.add(bound) && isUnboxable(left, bound, types)) { + return true; + } + } + return false; + } + final PsiPrimitiveType rightUnboxedType = PsiPrimitiveType.getUnboxedType(right); return rightUnboxedType != null && isAssignable(left, rightUnboxedType); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/UnboxingFromTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/UnboxingFromTypeParameter.java new file mode 100644 index 000000000000..b757661e275d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/UnboxingFromTypeParameter.java @@ -0,0 +1,7 @@ +class Test { + void method1(T param, S param1, K param2) { + long l = param; + long l1 = param1; + long l2 = param2; + } +} \ 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 90a76764c9c0..2b10c698a0c4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -575,6 +575,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testUnboxingFromTypeParameter() throws Exception { + doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); + } + public void testLeastUpperBoundWithRecursiveTypes() throws Exception { final PsiManager manager = getPsiManager(); final GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());