[ann] Exceptions with interfaces in multi-catch: correct erasure

This commit is contained in:
Roman Shevchenko
2011-05-18 17:18:49 +04:00
parent b11605125c
commit 00f10ef907
3 changed files with 32 additions and 6 deletions
@@ -56,6 +56,13 @@ abstract class C {
try { f(); } catch (E1 | E2 e) { <error descr="Incompatible types. Found: 'C.E1 | C.E2', required: 'C.E2'">E2 ee = e;</error> }
try { f(); } catch (E1 | E2 e) { <error descr="Cannot assign a value to final variable 'e'">e = new E1()</error>; }
try { f(); } catch (E1 | E2 e) { <error descr="Incompatible types. Found: 'C.E', required: 'C.E1 | C.E2'">e = new E()</error>; }
try { g(); }
catch (IE1 | IE2 e) {
Class<? extends E> clazz1 = e.getClass();
<error descr="Incompatible types. Found: 'java.lang.Class<? extends C.E>', required: 'java.lang.Class<? extends C.IE1>'">Class<? extends IE1> clazz2 = e.getClass();</error>
<error descr="Incompatible types. Found: 'java.lang.Class<? extends C.E>', required: 'java.lang.Class<? extends C.I>'">Class<? extends I> clazz3 = e.getClass();</error>
}
}
}
@@ -116,4 +116,23 @@ public class PsiTypesUtil {
public static PsiClassType getClassType(@NotNull PsiClass psiClass) {
return JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass);
}
@Nullable
public static PsiClassType getLowestUpperBoundClassType(@NotNull final PsiDisjunctionType type) {
final PsiType lub = type.getLeastUpperBound();
if (lub instanceof PsiClassType) {
return (PsiClassType)lub;
}
else if (lub instanceof PsiIntersectionType) {
for (PsiType subType : ((PsiIntersectionType)lub).getConjuncts()) {
if (subType instanceof PsiClassType) {
final PsiClass aClass = ((PsiClassType)subType).resolve();
if (aClass != null && !aClass.isInterface()) {
return (PsiClassType)subType;
}
}
}
}
return null;
}
}
@@ -23,7 +23,6 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
@@ -33,7 +32,10 @@ import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TypeConversionUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.TypeConversionUtil");
@@ -1189,10 +1191,8 @@ public class TypeConversionUtil {
@Override
public PsiType visitDisjunctionType(PsiDisjunctionType disjunctionType) {
final List<PsiType> erased = ContainerUtil.map(disjunctionType.getDisjunctions(), new Function<PsiType, PsiType>() {
@Override public PsiType fun(PsiType psiType) { return erasure(psiType, beforeSubstitutor); }
});
return disjunctionType.newDisjunctionType(erased);
final PsiClassType lub = PsiTypesUtil.getLowestUpperBoundClassType(disjunctionType);
return lub != null ? erasure(lub, beforeSubstitutor) : disjunctionType;
}
});
}