Add more methods to interface ConstraintSystem

To minimize usages of ConstraintSystemImpl
This commit is contained in:
Alexander Udalov
2015-10-28 23:12:21 +03:00
parent 9149668286
commit d320922e08
8 changed files with 35 additions and 33 deletions
@@ -207,7 +207,7 @@ public object Renderers {
public fun renderParameterConstraintError(
inferenceErrorData: InferenceErrorData, renderer: TabledDescriptorRenderer
): TabledDescriptorRenderer {
val constraintErrors = (inferenceErrorData.constraintSystem as ConstraintSystemImpl).constraintErrors
val constraintErrors = inferenceErrorData.constraintSystem.getStatus().constraintErrors
val errorPositions = constraintErrors.filter { it is ParameterConstraintError }.map { it.constraintPosition }
return renderer.table(
TabledDescriptorRenderer
@@ -308,8 +308,8 @@ public object Renderers {
public fun renderCannotCaptureTypeParameterError(
inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer
): TabledDescriptorRenderer {
val constraintSystem = inferenceErrorData.constraintSystem as ConstraintSystemImpl
val errors = constraintSystem.constraintErrors
val constraintSystem = inferenceErrorData.constraintSystem
val errors = constraintSystem.getStatus().constraintErrors
val typeParameterWithCapturedConstraint = (errors.firstOrNull { it is CannotCapture } as? CannotCapture)?.typeVariable
if (typeParameterWithCapturedConstraint == null) {
LOG.error(renderDebugMessage("An error 'cannot capture type parameter' is not found in errors", inferenceErrorData))
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
import org.jetbrains.kotlin.resolve.calls.inference.filterConstraintsOut
@@ -149,7 +148,7 @@ public class CallCompleter(
val returnType = getCandidateDescriptor().getReturnType()
if (returnType != null) {
getConstraintSystem()!!.addSupertypeConstraint(expectedType, returnType, EXPECTED_TYPE_POSITION.position())
constraintSystem!!.addSupertypeConstraint(expectedType, returnType, EXPECTED_TYPE_POSITION.position())
}
val constraintSystemCompleter = trace[CONSTRAINT_SYSTEM_COMPLETER, getCall().getCalleeExpression()]
@@ -172,10 +171,9 @@ public class CallCompleter(
}
}
val constraintSystem = getConstraintSystem() as ConstraintSystemImpl
constraintSystem.fixVariables()
constraintSystem!!.fixVariables()
setResultingSubstitutor(getConstraintSystem()!!.getResultingSubstitutor())
setResultingSubstitutor(constraintSystem!!.getResultingSubstitutor())
}
private fun <D : CallableDescriptor> MutableResolvedCall<D>.updateResolutionStatusFromConstraintSystem(
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.types.*
@@ -70,11 +69,8 @@ private fun getReturnTypeForCallable(type: KotlinType) =
type.getArguments().last().getType()
private fun CallableDescriptor.hasReturnTypeDependentOnUninferredParams(constraintSystem: ConstraintSystem): Boolean {
val returnType = getReturnType() ?: return false
val nestedTypeVariables = with (constraintSystem as ConstraintSystemImpl) {
returnType.getNestedTypeVariables()
}
val returnType = returnType ?: return false
val nestedTypeVariables = constraintSystem.getNestedTypeVariables(returnType, original = true)
return nestedTypeVariables.any { constraintSystem.getTypeBounds(it).value == null }
}
@@ -148,14 +148,13 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
val resultingCall = resolutionResults.resultingCall
if (resultingCall.isCompleted) return false
val argumentConstraintSystem = resultingCall.constraintSystem as ConstraintSystemImpl? ?: return false
val argumentConstraintSystem = resultingCall.constraintSystem ?: return false
val candidateDescriptor = resultingCall.candidateDescriptor
val returnType = candidateDescriptor.returnType ?: return false
val nestedTypeVariables = with (argumentConstraintSystem) {
returnType.getNestedTypeVariables()
}
val nestedTypeVariables = argumentConstraintSystem.getNestedTypeVariables(returnType, original = true)
// we add an additional type variable only if no information is inferred for it.
// otherwise we add currently inferred return type as before
if (nestedTypeVariables.any { argumentConstraintSystem.getTypeBounds(it).bounds.isNotEmpty() }) return false
@@ -88,6 +88,10 @@ public interface ConstraintSystem {
public fun getPartialSubstitutor(): TypeSubstitutor
public fun copy(filterConstraintPosition: (ConstraintPosition) -> Boolean = { true }): ConstraintSystem
public fun fixVariables()
public fun getNestedTypeVariables(type: KotlinType, original: Boolean): List<TypeParameterDescriptor>
}
fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem {
@@ -63,8 +63,6 @@ public class ConstraintSystemImpl : ConstraintSystem {
private val usedInBounds = HashMap<TypeParameterDescriptor, MutableList<TypeBounds.Bound>>()
private val errors = ArrayList<ConstraintError>()
public val constraintErrors: List<ConstraintError>
get() = errors
private val initialConstraints = ArrayList<Constraint>()
@@ -106,6 +104,9 @@ public class ConstraintSystemImpl : ConstraintSystem {
override fun hasTypeParameterWithUnsatisfiedOnlyInputTypesError() =
localTypeParameterBounds.values.any { it.typeVariable.hasOnlyInputTypesAnnotation() && it.value == null }
override val constraintErrors: List<ConstraintError>
get() = errors
}
private fun getParameterToInferredValueMap(
@@ -171,10 +172,10 @@ public class ConstraintSystemImpl : ConstraintSystem {
type -> type.getConstructor().getDeclarationDescriptor() in getAllTypeVariables()
}
fun KotlinType.getNestedTypeVariables(original: Boolean = true): List<TypeParameterDescriptor> {
return getNestedArguments().map { typeProjection ->
typeProjection.getType().getConstructor().getDeclarationDescriptor() as? TypeParameterDescriptor
}.filterNotNull().filter { if (original) it in originalToVariables.keySet() else it in getAllTypeVariables() }
override fun getNestedTypeVariables(type: KotlinType, original: Boolean): List<TypeParameterDescriptor> {
return type.getNestedArguments().map { typeProjection ->
typeProjection.type.constructor.declarationDescriptor as? TypeParameterDescriptor
}.filterNotNull().filter { if (original) it in originalToVariables.keys else it in getAllTypeVariables() }
}
override fun copy(filterConstraintPosition: (ConstraintPosition) -> Boolean): ConstraintSystem {
@@ -349,7 +350,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
typeBounds.addBound(bound)
if (!bound.isProper) {
for (dependentTypeVariable in bound.constrainingType.getNestedTypeVariables(original = false)) {
for (dependentTypeVariable in getNestedTypeVariables(bound.constrainingType, original = false)) {
val dependentBounds = usedInBounds.getOrPut(dependentTypeVariable) { arrayListOf() }
dependentBounds.add(bound)
}
@@ -489,7 +490,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
if (typeBounds.isFixed) return
typeBounds.setFixed()
val nestedTypeVariables = typeBounds.bounds.flatMap { it.constrainingType.getNestedTypeVariables(original = false) }
val nestedTypeVariables = typeBounds.bounds.flatMap { getNestedTypeVariables(it.constrainingType, original = false) }
nestedTypeVariables.forEach { fixVariable(it) }
val value = typeBounds.value ?: return
@@ -497,7 +498,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
addBound(typeVariable, value, TypeBounds.BoundKind.EXACT_BOUND, ConstraintContext(ConstraintPositionKind.FROM_COMPLETER.position()))
}
fun fixVariables() {
override fun fixVariables() {
// todo variables should be fixed in the right order
val (external, functionTypeParameters) = getAllTypeVariables().partition { externalTypeParameters.contains(it) }
external.forEach { fixVariable(it) }
@@ -91,4 +91,6 @@ public interface ConstraintSystemStatus {
public fun hasTypeInferenceIncorporationError(): Boolean
public fun hasTypeParameterWithUnsatisfiedOnlyInputTypesError(): Boolean
public val constraintErrors: List<ConstraintError>
}
@@ -21,12 +21,13 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl.Constra
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.SUB_TYPE
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.EXACT_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.*
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.CompoundConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.Variance.INVARIANT
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes
@@ -57,7 +58,8 @@ fun ConstraintSystemImpl.incorporateBound(newBound: Bound) {
addBound(getMyTypeVariable(constrainingType)!!, typeVariable.correspondingType, newBound.kind.reverse(), context)
return
}
constrainingType.getNestedTypeVariables().forEach {
getNestedTypeVariables(constrainingType, original = true).forEach {
val boundsForNestedVariable = getTypeBounds(it).bounds
for (index in boundsForNestedVariable.indices) {
generateNewBound(newBound, boundsForNestedVariable[index])
@@ -98,7 +100,7 @@ private fun ConstraintSystemImpl.generateNewBound(bound: Bound, substitution: Bo
fun addNewBound(newConstrainingType: KotlinType, newBoundKind: BoundKind) {
// We don't generate new recursive constraints
val nestedTypeVariables = newConstrainingType.getNestedTypeVariables(original = false)
val nestedTypeVariables = getNestedTypeVariables(newConstrainingType, original = false)
if (nestedTypeVariables.contains(bound.typeVariable)) return
// We don't generate constraint if a type variable was substituted twice