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,42 +41,43 @@ 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) { ) {
ConstraintKind.LOWER -> constraint.kind.isUpper() if (newConstraintIsUseless(previousConstraint, constraint)) return null
ConstraintKind.UPPER -> constraint.kind.isLower() val isMatchingForSimplification = when (previousConstraint.kind) {
ConstraintKind.EQUALITY -> true ConstraintKind.LOWER -> constraint.kind.isUpper()
ConstraintKind.UPPER -> constraint.kind.isLower()
ConstraintKind.EQUALITY -> true
}
if (isMatchingForSimplification) {
val actualConstraint = Constraint(
ConstraintKind.EQUALITY,
constraint.type,
constraint.position,
constraint.typeHashCode,
derivedFrom = constraint.derivedFrom,
isNullabilityConstraint = false
)
mutableConstraints.add(actualConstraint)
simplifiedConstraints = null
return actualConstraint
}
} }
} }
val actualConstraint = if (addAsEqualityConstraint) mutableConstraints.add(constraint)
Constraint( if (simplifiedConstraints != null && simplifiedConstraints !== mutableConstraints) {
ConstraintKind.EQUALITY, simplifiedConstraints!!.add(constraint)
constraint.type, }
constraint.position, return constraint
constraint.typeHashCode,
derivedFrom = constraint.derivedFrom,
isNullabilityConstraint = false
)
else
constraint
mutableConstraints.add(actualConstraint)
simplifiedConstraints = null
return actualConstraint
} }
// This method should be used only for transaction in constraint system // This method should be used only for transaction in constraint system
@@ -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) }
} }
} }