Move original descriptor to TypeVariable, minimize usages of freshTypeParameter
This commit is contained in:
@@ -320,7 +320,7 @@ public object Renderers {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
val typeParameter = system.variableToDescriptor(typeVariableWithCapturedConstraint)
|
val typeParameter = typeVariableWithCapturedConstraint.originalTypeParameter
|
||||||
|
|
||||||
val explanation: String
|
val explanation: String
|
||||||
val upperBound = TypeIntersector.getUpperBoundsAsType(typeParameter)
|
val upperBound = TypeIntersector.getUpperBoundsAsType(typeParameter)
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ interface ConstraintSystem {
|
|||||||
|
|
||||||
fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable
|
fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable
|
||||||
|
|
||||||
fun variableToDescriptor(typeVariable: TypeVariable): TypeParameterDescriptor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
|||||||
+17
-22
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
|||||||
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
|
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
|
||||||
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedureCallbacks
|
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedureCallbacks
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.defaultProjections
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
|
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -51,7 +52,6 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
internal val errors = ArrayList<ConstraintError>()
|
internal val errors = ArrayList<ConstraintError>()
|
||||||
internal val initialConstraints = ArrayList<Constraint>()
|
internal val initialConstraints = ArrayList<Constraint>()
|
||||||
internal val descriptorToVariable = LinkedHashMap<TypeParameterDescriptor, TypeVariable>()
|
internal val descriptorToVariable = LinkedHashMap<TypeParameterDescriptor, TypeVariable>()
|
||||||
internal val variableToDescriptor = LinkedHashMap<TypeVariable, TypeParameterDescriptor>()
|
|
||||||
|
|
||||||
private val descriptorToVariableSubstitutor: TypeSubstitutor by lazy {
|
private val descriptorToVariableSubstitutor: TypeSubstitutor by lazy {
|
||||||
TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||||
@@ -74,26 +74,26 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
DescriptorSubstitutor.substituteTypeParameters(
|
DescriptorSubstitutor.substituteTypeParameters(
|
||||||
typeParameters.toList(), TypeSubstitution.EMPTY, typeParameters.first().containingDeclaration, this
|
typeParameters.toList(), TypeSubstitution.EMPTY, typeParameters.first().containingDeclaration, this
|
||||||
)
|
)
|
||||||
}).map { typeParameter ->
|
}).zip(typeParameters).map {
|
||||||
TypeVariable(typeParameter, external)
|
val (fresh, original) = it
|
||||||
|
TypeVariable(fresh, original, external)
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) {
|
for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) {
|
||||||
allTypeParameterBounds.put(typeVariable, TypeBoundsImpl(typeVariable))
|
allTypeParameterBounds.put(typeVariable, TypeBoundsImpl(typeVariable))
|
||||||
descriptorToVariable[descriptor] = typeVariable
|
descriptorToVariable[descriptor] = typeVariable
|
||||||
variableToDescriptor[typeVariable] = descriptor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((typeVariable, typeBounds) in allTypeParameterBounds) {
|
for ((typeVariable, typeBounds) in allTypeParameterBounds) {
|
||||||
for (declaredUpperBound in typeVariable.freshTypeParameter.upperBounds) {
|
for (declaredUpperBound in typeVariable.freshTypeParameter.upperBounds) {
|
||||||
if (declaredUpperBound.isDefaultBound()) continue //todo remove this line (?)
|
if (declaredUpperBound.isDefaultBound()) continue //todo remove this line (?)
|
||||||
val context = ConstraintContext(TYPE_BOUND_POSITION.position(typeVariable.freshTypeParameter.index))
|
val context = ConstraintContext(TYPE_BOUND_POSITION.position(typeVariable.originalTypeParameter.index))
|
||||||
addBound(typeVariable, declaredUpperBound, UPPER_BOUND, context)
|
addBound(typeVariable, declaredUpperBound, UPPER_BOUND, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TypeSubstitutor.create(TypeConstructorSubstitution.createByParametersMap(
|
return TypeSubstitutor.create(TypeConstructorSubstitution.createByParametersMap(
|
||||||
typeParameters.zip(TypeUtils.getDefaultTypeProjections(typeVariables.map { it.freshTypeParameter })).toMap()
|
typeParameters.zip(typeVariables.map { it.type }.defaultProjections()).toMap()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,12 +101,8 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
type -> type.constructor.declarationDescriptor.let { it is TypeParameterDescriptor && isMyTypeVariable(it) }
|
type -> type.constructor.declarationDescriptor.let { it is TypeParameterDescriptor && isMyTypeVariable(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getNestedTypeVariables(type: KotlinType): List<TypeVariable> {
|
internal fun getNestedTypeVariables(type: KotlinType): List<TypeVariable> =
|
||||||
val allTypeVariables = allTypeParameterBounds.keys
|
type.getNestedTypeParameters().map { getMyTypeVariable(it) }.filterNotNull()
|
||||||
return type.getNestedTypeParameters().map { nestedTypeParameter ->
|
|
||||||
allTypeVariables.find { it.freshTypeParameter == nestedTypeParameter }
|
|
||||||
}.filterNotNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun addSupertypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition) {
|
override fun addSupertypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition) {
|
||||||
val newSubjectType = descriptorToVariableSubstitutor.substitute(subjectType, Variance.INVARIANT)
|
val newSubjectType = descriptorToVariableSubstitutor.substitute(subjectType, Variance.INVARIANT)
|
||||||
@@ -317,7 +313,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
constraintContext: ConstraintContext,
|
constraintContext: ConstraintContext,
|
||||||
isTypeMarkedNullable: Boolean
|
isTypeMarkedNullable: Boolean
|
||||||
) {
|
) {
|
||||||
if (!typeVariable.freshTypeParameter.upperBounds.let { it.size == 1 && it.single().isDefaultBound() } &&
|
if (!typeVariable.originalTypeParameter.upperBounds.let { it.size == 1 && it.single().isDefaultBound() } &&
|
||||||
constrainingTypeProjection.projectionKind == Variance.IN_VARIANCE) {
|
constrainingTypeProjection.projectionKind == Variance.IN_VARIANCE) {
|
||||||
errors.add(CannotCapture(constraintContext.position, typeVariable))
|
errors.add(CannotCapture(constraintContext.position, typeVariable))
|
||||||
}
|
}
|
||||||
@@ -339,17 +335,18 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isMyTypeVariable(typeParameter: TypeParameterDescriptor) =
|
private fun isMyTypeVariable(typeParameter: TypeParameterDescriptor) =
|
||||||
allTypeParameterBounds.keys.any { it.freshTypeParameter == typeParameter }
|
getMyTypeVariable(typeParameter) != null
|
||||||
|
|
||||||
internal fun isMyTypeVariable(type: KotlinType): Boolean = getMyTypeVariable(type) != null
|
internal fun isMyTypeVariable(type: KotlinType): Boolean =
|
||||||
|
getMyTypeVariable(type) != null
|
||||||
|
|
||||||
internal fun getMyTypeVariable(type: KotlinType): TypeVariable? {
|
internal fun getMyTypeVariable(type: KotlinType): TypeVariable? {
|
||||||
val typeParameterDescriptor = type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
return getMyTypeVariable(type.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return null)
|
||||||
return if (typeParameterDescriptor != null)
|
|
||||||
allTypeParameterBounds.keys.find { it.freshTypeParameter == typeParameterDescriptor }
|
|
||||||
else null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getMyTypeVariable(typeParameter: TypeParameterDescriptor): TypeVariable? =
|
||||||
|
allTypeParameterBounds.keys.find { it.freshTypeParameter == typeParameter }
|
||||||
|
|
||||||
private fun storeInitialConstraint(constraintKind: ConstraintKind, subType: KotlinType, superType: KotlinType, position: ConstraintPosition) {
|
private fun storeInitialConstraint(constraintKind: ConstraintKind, subType: KotlinType, superType: KotlinType, position: ConstraintPosition) {
|
||||||
initialConstraints.add(Constraint(constraintKind, subType, superType, position))
|
initialConstraints.add(Constraint(constraintKind, subType, superType, position))
|
||||||
}
|
}
|
||||||
@@ -375,9 +372,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun build(): ConstraintSystem {
|
override fun build(): ConstraintSystem {
|
||||||
return ConstraintSystemImpl(
|
return ConstraintSystemImpl(allTypeParameterBounds, usedInBounds, errors, initialConstraints, descriptorToVariable)
|
||||||
allTypeParameterBounds, usedInBounds, errors, initialConstraints, descriptorToVariable, variableToDescriptor
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-8
@@ -38,8 +38,7 @@ internal class ConstraintSystemImpl(
|
|||||||
private val usedInBounds: Map<TypeVariable, MutableList<TypeBounds.Bound>>,
|
private val usedInBounds: Map<TypeVariable, MutableList<TypeBounds.Bound>>,
|
||||||
private val errors: List<ConstraintError>,
|
private val errors: List<ConstraintError>,
|
||||||
private val initialConstraints: List<ConstraintSystemBuilderImpl.Constraint>,
|
private val initialConstraints: List<ConstraintSystemBuilderImpl.Constraint>,
|
||||||
private val descriptorToVariable: Map<TypeParameterDescriptor, TypeVariable>,
|
private val descriptorToVariable: Map<TypeParameterDescriptor, TypeVariable>
|
||||||
private val variableToDescriptor: Map<TypeVariable, TypeParameterDescriptor>
|
|
||||||
) : ConstraintSystem {
|
) : ConstraintSystem {
|
||||||
private val localTypeParameterBounds: Map<TypeVariable, TypeBoundsImpl>
|
private val localTypeParameterBounds: Map<TypeVariable, TypeBoundsImpl>
|
||||||
get() = allTypeParameterBounds.filterNot { it.key.isExternal }
|
get() = allTypeParameterBounds.filterNot { it.key.isExternal }
|
||||||
@@ -88,7 +87,7 @@ internal class ConstraintSystemImpl(
|
|||||||
val substitutionContext = HashMap<TypeParameterDescriptor, TypeProjection>()
|
val substitutionContext = HashMap<TypeParameterDescriptor, TypeProjection>()
|
||||||
for ((variable, typeBounds) in typeParameterBounds) {
|
for ((variable, typeBounds) in typeParameterBounds) {
|
||||||
val value = typeBounds.value
|
val value = typeBounds.value
|
||||||
val typeParameter = if (substituteOriginal) variableToDescriptor[variable]!! else variable.freshTypeParameter
|
val typeParameter = if (substituteOriginal) variable.originalTypeParameter else variable.freshTypeParameter
|
||||||
val type =
|
val type =
|
||||||
if (value != null && !TypeUtils.containsSpecialType(value, DONT_CARE)) value
|
if (value != null && !TypeUtils.containsSpecialType(value, DONT_CARE)) value
|
||||||
else getDefaultType(typeParameter)
|
else getDefaultType(typeParameter)
|
||||||
@@ -110,14 +109,11 @@ internal class ConstraintSystemImpl(
|
|||||||
get() = descriptorToVariable.keys
|
get() = descriptorToVariable.keys
|
||||||
|
|
||||||
override val typeVariables: Set<TypeVariable>
|
override val typeVariables: Set<TypeVariable>
|
||||||
get() = variableToDescriptor.keys
|
get() = allTypeParameterBounds.keys
|
||||||
|
|
||||||
override fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable =
|
override fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable =
|
||||||
descriptorToVariable[descriptor] ?: throw IllegalArgumentException("Unknown descriptor: $descriptor")
|
descriptorToVariable[descriptor] ?: throw IllegalArgumentException("Unknown descriptor: $descriptor")
|
||||||
|
|
||||||
override fun variableToDescriptor(typeVariable: TypeVariable): TypeParameterDescriptor =
|
|
||||||
variableToDescriptor[typeVariable] ?: throw IllegalArgumentException("Unknown type variable: $typeVariable")
|
|
||||||
|
|
||||||
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")
|
||||||
@@ -171,7 +167,6 @@ internal class ConstraintSystemImpl(
|
|||||||
|
|
||||||
result.initialConstraints.addAll(initialConstraints.filter { filterConstraintPosition(it.position) })
|
result.initialConstraints.addAll(initialConstraints.filter { filterConstraintPosition(it.position) })
|
||||||
result.descriptorToVariable.putAll(descriptorToVariable)
|
result.descriptorToVariable.putAll(descriptorToVariable)
|
||||||
result.variableToDescriptor.putAll(variableToDescriptor)
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -44,7 +44,7 @@ public class ConstraintsUtil {
|
|||||||
public static Collection<TypeSubstitutor> getSubstitutorsForConflictingParameters(@NotNull ConstraintSystem constraintSystem) {
|
public static Collection<TypeSubstitutor> getSubstitutorsForConflictingParameters(@NotNull ConstraintSystem constraintSystem) {
|
||||||
TypeVariable firstConflictingVariable = getFirstConflictingVariable(constraintSystem);
|
TypeVariable firstConflictingVariable = getFirstConflictingVariable(constraintSystem);
|
||||||
if (firstConflictingVariable == null) return Collections.emptyList();
|
if (firstConflictingVariable == null) return Collections.emptyList();
|
||||||
TypeParameterDescriptor firstConflictingParameter = constraintSystem.variableToDescriptor(firstConflictingVariable);
|
TypeParameterDescriptor firstConflictingParameter = firstConflictingVariable.getOriginalTypeParameter();
|
||||||
|
|
||||||
Collection<KotlinType> conflictingTypes = constraintSystem.getTypeBounds(firstConflictingVariable).getValues();
|
Collection<KotlinType> conflictingTypes = constraintSystem.getTypeBounds(firstConflictingVariable).getValues();
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ public class ConstraintsUtil {
|
|||||||
KotlinType safeType = getSafeValue(constraintSystem, typeVariable);
|
KotlinType safeType = getSafeValue(constraintSystem, typeVariable);
|
||||||
for (Map<TypeConstructor, TypeProjection> context : substitutionContexts) {
|
for (Map<TypeConstructor, TypeProjection> context : substitutionContexts) {
|
||||||
TypeProjection typeProjection = new TypeProjectionImpl(safeType);
|
TypeProjection typeProjection = new TypeProjectionImpl(safeType);
|
||||||
context.put(constraintSystem.variableToDescriptor(typeVariable).getTypeConstructor(), typeProjection);
|
context.put(typeVariable.getOriginalTypeParameter().getTypeConstructor(), typeProjection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collection<TypeSubstitutor> typeSubstitutors = new ArrayList<TypeSubstitutor>(substitutionContexts.size());
|
Collection<TypeSubstitutor> typeSubstitutors = new ArrayList<TypeSubstitutor>(substitutionContexts.size());
|
||||||
@@ -78,7 +78,7 @@ public class ConstraintsUtil {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
//todo may be error type
|
//todo may be error type
|
||||||
return TypeIntersector.getUpperBoundsAsType(constraintSystem.variableToDescriptor(typeVariable));
|
return TypeIntersector.getUpperBoundsAsType(typeVariable.getOriginalTypeParameter());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkUpperBoundIsSatisfied(
|
public static boolean checkUpperBoundIsSatisfied(
|
||||||
|
|||||||
@@ -24,11 +24,15 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.KotlinTypeImpl
|
import org.jetbrains.kotlin.types.KotlinTypeImpl
|
||||||
|
|
||||||
class TypeVariable(val freshTypeParameter: TypeParameterDescriptor, val isExternal: Boolean) {
|
class TypeVariable(
|
||||||
val name: Name get() = freshTypeParameter.name
|
val freshTypeParameter: TypeParameterDescriptor,
|
||||||
|
val originalTypeParameter: TypeParameterDescriptor,
|
||||||
|
val isExternal: Boolean
|
||||||
|
) {
|
||||||
|
val name: Name get() = originalTypeParameter.name
|
||||||
|
|
||||||
val type: KotlinType get() = freshTypeParameter.defaultType
|
val type: KotlinType get() = freshTypeParameter.defaultType
|
||||||
|
|
||||||
fun hasOnlyInputTypesAnnotation(): Boolean =
|
fun hasOnlyInputTypesAnnotation(): Boolean =
|
||||||
freshTypeParameter.hasOnlyInputTypesAnnotation()
|
originalTypeParameter.hasOnlyInputTypesAnnotation()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user