inference: do not erase inferred recursive types to object

This commit is contained in:
Anna Kozlova
2016-01-08 20:15:17 +01:00
parent fda3ba7e3c
commit f732fb3742
6 changed files with 20 additions and 17 deletions
@@ -78,6 +78,7 @@ public class TypeConversionUtil {
return "FAKE TYPE";
}
};
private static final Key<PsiElement> ORIGINAL_CONTEXT = Key.create("ORIGINAL_CONTEXT");
static {
TYPE_TO_RANK_MAP.put(PsiType.BYTE, BYTE_RANK);
@@ -1291,7 +1292,7 @@ public class TypeConversionUtil {
@Override
public PsiType visitClassType(PsiClassType classType) {
final PsiClass aClass = classType.resolve();
if (aClass instanceof PsiTypeParameter) {
if (aClass instanceof PsiTypeParameter && !isFreshVariable((PsiTypeParameter)aClass)) {
return typeParameterErasure((PsiTypeParameter)aClass, beforeSubstitutor);
}
return classType.rawType();
@@ -1474,6 +1475,19 @@ public class TypeConversionUtil {
return true;
}
public static boolean areSameFreshVariables(PsiTypeParameter p1, PsiTypeParameter p2) {
final PsiElement originalContext = p1.getUserData(ORIGINAL_CONTEXT);
return originalContext != null && originalContext == p2.getUserData(ORIGINAL_CONTEXT);
}
public static boolean isFreshVariable(PsiTypeParameter typeParameter) {
return typeParameter.getUserData(ORIGINAL_CONTEXT) != null;
}
public static void markAsFreshVariable(PsiTypeParameter parameter, PsiElement context) {
parameter.putUserData(ORIGINAL_CONTEXT, context);
}
private interface Caster {
@NotNull
Object cast(@NotNull Object operand);
@@ -26,7 +26,6 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.scope.PsiConflictResolver;
@@ -535,7 +534,7 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics();
final PsiClass psiClass = resolveResult.getElement();
if (psiClass != null) {
if (psiClass instanceof PsiTypeParameter && InferenceSession.isFreshVariable((PsiTypeParameter)psiClass)) {
if (psiClass instanceof PsiTypeParameter && TypeConversionUtil.isFreshVariable((PsiTypeParameter)psiClass)) {
return false;
}
@@ -1082,7 +1082,7 @@ public class PsiClassImplUtil {
PsiTypeParameter p2 = (PsiTypeParameter)another;
return p1.getIndex() == p2.getIndex() &&
(aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner()) || InferenceSession.areSameFreshVariables(p1, p2));
(aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner()) || TypeConversionUtil.areSameFreshVariables(p1, p2));
}
else {
return false;
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqualityConstraint;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
@@ -24,6 +24,7 @@ import com.intellij.psi.impl.source.resolve.graphInference.constraints.StrictSub
import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeCompatibilityConstraint;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqualityConstraint;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Processor;
import java.util.*;
@@ -182,7 +183,7 @@ public class InferenceIncorporationPhase {
private static Boolean isInferenceVariableOrFreshTypeParameter(PsiType eqBound) {
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(eqBound);
if (psiClass instanceof InferenceVariable ||
psiClass instanceof PsiTypeParameter && InferenceSession.isFreshVariable((PsiTypeParameter)psiClass)) return true;
psiClass instanceof PsiTypeParameter && TypeConversionUtil.isFreshVariable((PsiTypeParameter)psiClass)) return true;
return false;
}
@@ -42,7 +42,6 @@ public class InferenceSession {
private static final Logger LOG = Logger.getInstance("#" + InferenceSession.class.getName());
public static final Key<PsiType> LOWER_BOUND = Key.create("LowBound");
public static final Key<PsiType> UPPER_BOUND = Key.create("UpperBound");
private static final Key<PsiElement> ORIGINAL_CONTEXT = Key.create("ORIGINAL_CONTEXT");
private static final Key<Boolean> ERASED = Key.create("UNCHECKED_CONVERSION");
private static final Function<Pair<PsiType, PsiType>, PsiType> UPPER_BOUND_FUNCTION = new Function<Pair<PsiType, PsiType>, PsiType>() {
@Override
@@ -1038,7 +1037,7 @@ public class InferenceSession {
}
parameter.putUserData(UPPER_BOUND,
composeBound(var, InferenceBound.UPPER, UPPER_BOUND_FUNCTION, ySubstitutor.putAll(substitutor), true));
parameter.putUserData(ORIGINAL_CONTEXT, myContext);
TypeConversionUtil.markAsFreshVariable(parameter, myContext);
if (!var.addBound(elementFactory.createType(parameter), InferenceBound.EQ)) {
return false;
}
@@ -1768,15 +1767,6 @@ public class InferenceSession {
return s.substitute(type);
}
public static boolean areSameFreshVariables(PsiTypeParameter p1, PsiTypeParameter p2) {
final PsiElement originalContext = p1.getUserData(ORIGINAL_CONTEXT);
return originalContext != null && originalContext == p2.getUserData(ORIGINAL_CONTEXT);
}
public static boolean isFreshVariable(PsiTypeParameter typeParameter) {
return typeParameter.getUserData(ORIGINAL_CONTEXT) != null;
}
public static PsiClass findParameterizationOfTheSameGenericClass(List<PsiType> upperBounds,
Processor<Pair<PsiType, PsiType>> processor) {
for (int i = 0; i < upperBounds.size(); i++) {