From f732fb3742396489ae111d6355db73e19809caa0 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 8 Jan 2016 17:05:53 +0100 Subject: [PATCH] inference: do not erase inferred recursive types to object --- .../intellij/psi/util/TypeConversionUtil.java | 16 +++++++++++++++- .../src/com/intellij/psi/PsiDiamondTypeImpl.java | 3 +-- .../com/intellij/psi/impl/PsiClassImplUtil.java | 2 +- .../FunctionalInterfaceParameterizationUtil.java | 1 - .../InferenceIncorporationPhase.java | 3 ++- .../resolve/graphInference/InferenceSession.java | 12 +----------- 6 files changed, 20 insertions(+), 17 deletions(-) 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 9d482cd4d9a6..809dc516d992 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 @@ -78,6 +78,7 @@ public class TypeConversionUtil { return "FAKE TYPE"; } }; + private static final Key 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); diff --git a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java index 4b16c7183de8..6d0d853a5098 100644 --- a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java @@ -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; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java index 6f92e020a8cf..08fef26ae05d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java @@ -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; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java index e5b9763c41d7..e1531c92dc90 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java @@ -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; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java index b120d5dfac12..7e213cd0bbf2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java @@ -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; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index b64ba29df4fc..136f101bb106 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -42,7 +42,6 @@ public class InferenceSession { private static final Logger LOG = Logger.getInstance("#" + InferenceSession.class.getName()); public static final Key LOWER_BOUND = Key.create("LowBound"); public static final Key UPPER_BOUND = Key.create("UpperBound"); - private static final Key ORIGINAL_CONTEXT = Key.create("ORIGINAL_CONTEXT"); private static final Key ERASED = Key.create("UNCHECKED_CONVERSION"); private static final Function, PsiType> UPPER_BOUND_FUNCTION = new Function, 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 upperBounds, Processor> processor) { for (int i = 0; i < upperBounds.size(); i++) {