Optimize constraints simplification

simplify only when affecting changes are detected
This commit is contained in:
Ilya Chernikov
2020-03-09 14:25:20 +01:00
parent c2b866fe7a
commit 3cbfdd19f5
@@ -9,13 +9,11 @@ import org.jetbrains.kotlin.resolve.calls.inference.trimToSize
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.TypeVariableMarker import org.jetbrains.kotlin.types.model.TypeVariableMarker
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.typeUtil.unCapture import org.jetbrains.kotlin.types.typeUtil.unCapture
import kotlin.collections.ArrayList
import kotlin.collections.LinkedHashMap
class MutableVariableWithConstraints private constructor( class MutableVariableWithConstraints private constructor(
@@ -43,29 +41,24 @@ class MutableVariableWithConstraints private constructor(
private val mutableConstraints = if (constraints == null) ArrayList() else ArrayList(constraints) private val mutableConstraints = if (constraints == null) ArrayList() else ArrayList(constraints)
private var simplifiedConstraints: List<Constraint>? = mutableConstraints private var simplifiedConstraints: ArrayList<Constraint>? = mutableConstraints
// return new actual constraint, if this constraint is new // return new actual constraint, if this constraint is new
fun addConstraint(constraint: Constraint): Constraint? { fun addConstraint(constraint: Constraint): Constraint? {
val previousConstraintWithSameType = constraints.filter { oldConstraint ->
oldConstraint.typeHashCode == constraint.typeHashCode
&& oldConstraint.type == constraint.type
&& oldConstraint.isNullabilityConstraint == constraint.isNullabilityConstraint
}
if (previousConstraintWithSameType.any { previous -> newConstraintIsUseless(previous, constraint) }) for (previousConstraint in constraints) {
return null if (previousConstraint.typeHashCode == constraint.typeHashCode
&& previousConstraint.type == constraint.type
val addAsEqualityConstraint = previousConstraintWithSameType.any { previous -> && previousConstraint.isNullabilityConstraint == constraint.isNullabilityConstraint
when (previous.kind) { ) {
if (newConstraintIsUseless(previousConstraint, constraint)) return null
val isMatchingForSimplification = when (previousConstraint.kind) {
ConstraintKind.LOWER -> constraint.kind.isUpper() ConstraintKind.LOWER -> constraint.kind.isUpper()
ConstraintKind.UPPER -> constraint.kind.isLower() ConstraintKind.UPPER -> constraint.kind.isLower()
ConstraintKind.EQUALITY -> true ConstraintKind.EQUALITY -> true
} }
} if (isMatchingForSimplification) {
val actualConstraint = Constraint(
val actualConstraint = if (addAsEqualityConstraint)
Constraint(
ConstraintKind.EQUALITY, ConstraintKind.EQUALITY,
constraint.type, constraint.type,
constraint.position, constraint.position,
@@ -73,13 +66,19 @@ class MutableVariableWithConstraints private constructor(
derivedFrom = constraint.derivedFrom, derivedFrom = constraint.derivedFrom,
isNullabilityConstraint = false isNullabilityConstraint = false
) )
else
constraint
mutableConstraints.add(actualConstraint) mutableConstraints.add(actualConstraint)
simplifiedConstraints = null simplifiedConstraints = null
return actualConstraint return actualConstraint
} }
}
}
mutableConstraints.add(constraint)
if (simplifiedConstraints != null && simplifiedConstraints !== mutableConstraints) {
simplifiedConstraints!!.add(constraint)
}
return constraint
}
// This method should be used only for transaction in constraint system // This method should be used only for transaction in constraint system
// shouldRemove should give true only for tail elements // shouldRemove should give true only for tail elements
@@ -111,13 +110,13 @@ class MutableVariableWithConstraints private constructor(
} }
} }
private fun List<Constraint>.simplifyConstraints(): List<Constraint> { private fun ArrayList<Constraint>.simplifyConstraints(): ArrayList<Constraint> {
val equalityConstraints = val equalityConstraints =
filter { it.kind == ConstraintKind.EQUALITY } filter { it.kind == ConstraintKind.EQUALITY }
.groupBy { it.typeHashCode } .groupBy { it.typeHashCode }
return when { return when {
equalityConstraints.isEmpty() -> this equalityConstraints.isEmpty() -> this
else -> filter { isUsefulConstraint(it, equalityConstraints) } else -> filterTo(ArrayList()) { isUsefulConstraint(it, equalityConstraints) }
} }
} }