assignability to primitive: check type parameter bounds if applicable (IDEA-155551)

This commit is contained in:
Anna.Kozlova
2016-05-04 11:09:25 +02:00
parent 1b6a531c15
commit 7fb3086dc5
3 changed files with 27 additions and 6 deletions
@@ -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<PsiClassType>());
}
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<PsiClassType> 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);
}
@@ -0,0 +1,7 @@
class Test {
<T extends S, S extends Long, K extends Long & Runnable> void method1(T param, S param1, K param2) {
long l = param;
long l1 = param1;
long l2 = param2;
}
}
@@ -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());