Inline and move out utilities from ConstraintSystem

This commit is contained in:
Alexander Udalov
2015-11-12 22:16:47 +03:00
parent d4664af4e5
commit 3e27fdb964
5 changed files with 24 additions and 18 deletions
@@ -24,18 +24,11 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
interface ConstraintSystem { interface ConstraintSystem {
val status: ConstraintSystemStatus val status: ConstraintSystemStatus
/**
* Returns a set of all non-external type parameter descriptors.
*/
val typeParameterDescriptors: Set<TypeParameterDescriptor>
/** /**
* Returns a set of all registered type variables. * Returns a set of all registered type variables.
*/ */
val typeVariables: Set<TypeVariable> val typeVariables: Set<TypeVariable>
fun descriptorToVariable(call: CallHandle, descriptor: TypeParameterDescriptor): TypeVariable
/** /**
* Returns the resulting type constraints of solving the constraint system for specific type parameter descriptor. * Returns the resulting type constraints of solving the constraint system for specific type parameter descriptor.
* Throws IllegalArgumentException if the type parameter descriptor is not known to the system. * Throws IllegalArgumentException if the type parameter descriptor is not known to the system.
@@ -105,17 +105,9 @@ internal class ConstraintSystemImpl(
return SubstitutionFilteringInternalResolveAnnotations(substitution).buildSubstitutor() return SubstitutionFilteringInternalResolveAnnotations(substitution).buildSubstitutor()
} }
override val typeParameterDescriptors: Set<TypeParameterDescriptor>
get() = typeVariables.map { it.originalTypeParameter }.toSet()
override val typeVariables: Set<TypeVariable> override val typeVariables: Set<TypeVariable>
get() = allTypeParameterBounds.keys get() = allTypeParameterBounds.keys
override fun descriptorToVariable(call: CallHandle, descriptor: TypeParameterDescriptor): TypeVariable =
typeVariables.firstOrNull {
it.call == call && it.originalTypeParameter == descriptor
} ?: throw IllegalArgumentException("Unknown descriptor: $descriptor, call: $call")
override fun getTypeBounds(typeVariable: TypeVariable): TypeBoundsImpl { override fun getTypeBounds(typeVariable: TypeVariable): TypeBoundsImpl {
return allTypeParameterBounds[typeVariable] ?: return allTypeParameterBounds[typeVariable] ?:
throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $typeVariable") throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $typeVariable")
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.resolve.calls.inference;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import kotlin.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
@@ -88,12 +90,25 @@ public class ConstraintsUtil {
@NotNull Call call, @NotNull Call call,
boolean substituteOtherTypeParametersInBound boolean substituteOtherTypeParametersInBound
) { ) {
TypeVariable typeVariable = constraintSystem.descriptorToVariable(TypeVariableKt.toHandle(call), typeParameter); TypeVariable typeVariable = ConstraintSystemUtilsKt.descriptorToVariable(
constraintSystem, TypeVariableKt.toHandle(call), typeParameter
);
KotlinType type = constraintSystem.getTypeBounds(typeVariable).getValue(); KotlinType type = constraintSystem.getTypeBounds(typeVariable).getValue();
if (type == null) return true; if (type == null) return true;
List<TypeParameterDescriptor> typeParametersUsedInSystem = CollectionsKt.map(
constraintSystem.getTypeVariables(),
new Function1<TypeVariable, TypeParameterDescriptor>() {
@Override
public TypeParameterDescriptor invoke(TypeVariable variable) {
return variable.getOriginalTypeParameter();
}
}
);
for (KotlinType upperBound : typeParameter.getUpperBounds()) { for (KotlinType upperBound : typeParameter.getUpperBounds()) {
if (!substituteOtherTypeParametersInBound && if (!substituteOtherTypeParametersInBound &&
TypeUtils.dependsOnTypeParameters(upperBound, constraintSystem.getTypeParameterDescriptors())) { TypeUtils.dependsOnTypeParameters(upperBound, typeParametersUsedInSystem)) {
continue; continue;
} }
KotlinType substitutedUpperBound = constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT); KotlinType substitutedUpperBound = constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
@@ -33,6 +33,12 @@ fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositio
return toBuilder { !it.derivedFrom(excludePositionKind) }.build() return toBuilder { !it.derivedFrom(excludePositionKind) }.build()
} }
fun ConstraintSystem.descriptorToVariable(call: CallHandle, descriptor: TypeParameterDescriptor): TypeVariable {
return typeVariables.firstOrNull {
it.call == call && it.originalTypeParameter == descriptor
} ?: throw IllegalArgumentException("Unknown descriptor: $descriptor, call: $call")
}
internal fun KotlinType.getNestedArguments(): List<TypeProjection> { internal fun KotlinType.getNestedArguments(): List<TypeProjection> {
val result = ArrayList<TypeProjection>() val result = ArrayList<TypeProjection>()
@@ -143,7 +143,7 @@ class FuzzyType(
if (otherSubstitutedType.isError) return null if (otherSubstitutedType.isError) return null
if (!substitutedType.checkInheritance(otherSubstitutedType)) return null if (!substitutedType.checkInheritance(otherSubstitutedType)) return null
val substitution = constraintSystem.typeParameterDescriptors.toMap({ it.typeConstructor }) { val substitution = constraintSystem.typeVariables.map { it.originalTypeParameter }.toMap({ it.typeConstructor }) {
val type = it.defaultType val type = it.defaultType
val solution = substitutor.substitute(type, Variance.INVARIANT) val solution = substitutor.substitute(type, Variance.INVARIANT)
TypeProjectionImpl(if (solution != null && !ErrorUtils.containsUninferredParameter(solution)) solution else type) TypeProjectionImpl(if (solution != null && !ErrorUtils.containsUninferredParameter(solution)) solution else type)