Assertions for EA-33908 - SOE: TypeSubstitutor.substituteInProjection

+ toString() in substitutions, for debugging
This commit is contained in:
Andrey Breslav
2012-03-16 19:23:14 +04:00
parent 3d9b115f90
commit 6232e45c10
5 changed files with 82 additions and 9 deletions
@@ -44,6 +44,11 @@ public class FunctionDescriptorUtil {
public boolean isEmpty() {
return false;
}
@Override
public String toString() {
return "FunctionDescriptorUtil.MAKE_TYPE_PARAMETERS_FRESH";
}
});
public static Map<TypeConstructor, TypeProjection> createSubstitutionContext(@NotNull FunctionDescriptor functionDescriptor, List<JetType> typeArguments) {
@@ -490,6 +490,11 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
public boolean isEmpty() {
return false;
}
@Override
public String toString() {
return unknownTypes.toString();
}
});
private SolutionStatus status;
@@ -44,4 +44,13 @@ public class CompositeTypeSubstitution implements TypeSubstitutor.TypeSubstituti
}
return true;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (TypeSubstitutor.TypeSubstitution substitution : inner) {
builder.append(substitution).append(" * ");
}
return builder.toString();
}
}
@@ -50,6 +50,11 @@ public class DescriptorSubstitutor {
public boolean isEmpty() {
return originalSubstitutor.isEmpty() && mutableSubstitution.isEmpty();
}
@Override
public String toString() {
return "DescriptorSubstitutor.substituteTypeParameters(" + mutableSubstitution + " / " + originalSubstitutor.getSubstitution() + ")";
}
});
for (TypeParameterDescriptor descriptor : typeParameters) {
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.types;
import com.google.common.collect.Sets;
import com.intellij.openapi.progress.ProcessCanceledException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
@@ -29,6 +30,8 @@ import java.util.*;
*/
public class TypeSubstitutor {
private static final int MAX_RECURSION_DEPTH = 100;
public static TypeSubstitutor makeConstantSubstitutor(Collection<TypeParameterDescriptor> typeParameterDescriptors, JetType type) {
final Set<TypeConstructor> constructors = Sets.newHashSet();
for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) {
@@ -49,6 +52,11 @@ public class TypeSubstitutor {
public boolean isEmpty() {
return false;
}
@Override
public String toString() {
return "TypeConstructor.makeConstantSubstitutor(" + constructors + " -> " + projection + ")";
}
});
}
@@ -63,6 +71,11 @@ public class TypeSubstitutor {
public boolean isEmpty() {
return true;
}
@Override
public String toString() {
return "Empty TypeSubstitution";
}
};
@Nullable
@@ -86,6 +99,11 @@ public class TypeSubstitutor {
public boolean isEmpty() {
return substitutionContext.isEmpty();
}
@Override
public String toString() {
return substitutionContext.toString();
}
}
public static final TypeSubstitutor EMPTY = create(TypeSubstitution.EMPTY);
@@ -170,12 +188,12 @@ public class TypeSubstitutor {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) constructor.getDeclarationDescriptor();
TypeProjection result = substitutionResult(typeParameterDescriptor, howThisTypeIsUsed, Variance.INVARIANT, value);
TypeProjection result = substitutionResult(typeParameterDescriptor, howThisTypeIsUsed, Variance.INVARIANT, value, 0);
return TypeUtils.makeNullableIfNeeded(result.getType(), type.isNullable());
}
return specializeType(type, howThisTypeIsUsed);
return specializeType(type, howThisTypeIsUsed, 0);
}
private TypeProjection getValueWithCorrectNullability(TypeSubstitution substitution, JetType type) {
@@ -190,7 +208,8 @@ public class TypeSubstitutor {
return new TypeProjection(value.getProjectionKind(), TypeUtils.makeNullable(value.getType()));
}
private JetType specializeType(JetType subjectType, Variance callSiteVariance) throws SubstitutionException {
private JetType specializeType(JetType subjectType, Variance callSiteVariance, int recursionDepth) throws SubstitutionException {
assertRecursionDepth(recursionDepth, subjectType, substitution);
if (ErrorUtils.isErrorType(subjectType)) return subjectType;
List<TypeProjection> newArguments = new ArrayList<TypeProjection>();
@@ -202,7 +221,7 @@ public class TypeSubstitutor {
substitution,
argument,
parameterDescriptor,
callSiteVariance));
callSiteVariance, recursionDepth + 1));
}
return new JetTypeImpl(
subjectType.getAnnotations(),
@@ -217,7 +236,10 @@ public class TypeSubstitutor {
@NotNull TypeSubstitution substitutionContext,
@NotNull TypeProjection passedProjection,
@NotNull TypeParameterDescriptor correspondingTypeParameter,
@NotNull Variance contextCallSiteVariance) throws SubstitutionException {
@NotNull Variance contextCallSiteVariance,
int recursionDepth) throws SubstitutionException {
assertRecursionDepth(recursionDepth, correspondingTypeParameter, passedProjection, substitution);
JetType typeToSubstituteIn = passedProjection.getType();
if (ErrorUtils.isErrorType(typeToSubstituteIn)) return passedProjection;
@@ -235,20 +257,23 @@ public class TypeSubstitutor {
return TypeUtils.makeStarProjection(correspondingTypeParameter);
}
return substitutionResult(correspondingTypeParameter, effectiveContextVariance, passedProjectionKind, projectionValue);
return substitutionResult(correspondingTypeParameter, effectiveContextVariance, passedProjectionKind, projectionValue, recursionDepth + 1);
}
return new TypeProjection(
passedProjectionKind,
specializeType(
typeToSubstituteIn,
effectiveContextVariance));
effectiveContextVariance, recursionDepth + 1));
}
private TypeProjection substitutionResult(
TypeParameterDescriptor correspondingTypeParameter,
Variance effectiveContextVariance,
Variance passedProjectionKind,
TypeProjection value) throws SubstitutionException {
TypeProjection value,
int recursionDepth) throws SubstitutionException {
assertRecursionDepth(recursionDepth, correspondingTypeParameter, value, substitution);
Variance projectionKindValue = value.getProjectionKind();
JetType typeValue = value.getType();
Variance effectiveProjectionKindValue = asymmetricOr(passedProjectionKind, projectionKindValue);
@@ -285,7 +310,7 @@ public class TypeSubstitutor {
// throw new SubstitutionException(""); // TODO : error message
// }
//
return new TypeProjection(effectiveProjectionKindValue, specializeType(effectiveTypeValue, effectiveContextVariance));
return new TypeProjection(effectiveProjectionKindValue, specializeType(effectiveTypeValue, effectiveContextVariance, recursionDepth + 1));
}
private static Variance asymmetricOr(Variance a, Variance b) {
@@ -300,4 +325,28 @@ public class TypeSubstitutor {
}
throw new IllegalStateException(declarationSiteVariance.toString());
}
private static void assertRecursionDepth(int recursionDepth, TypeParameterDescriptor parameter, TypeProjection value, TypeSubstitution substitution) {
if (recursionDepth > MAX_RECURSION_DEPTH) {
throw new IllegalStateException("Recursion too deep. Most likely infinite loop while substituting " + safeToString(value) + " for " + safeToString(parameter) + "; substitution: " + safeToString(substitution));
}
}
private static void assertRecursionDepth(int recursionDepth, JetType type, TypeSubstitution substitution) {
if (recursionDepth > MAX_RECURSION_DEPTH) {
throw new IllegalStateException("Recursion too deep. Most likely infinite loop while substituting " + safeToString(type) + "; substitution: " + safeToString(substitution));
}
}
private static String safeToString(Object o) {
try {
return o.toString();
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable e) {
return "[Exception while computing toString(): " + e + "]";
}
}
}