Optimize constraints simplification
simplify only when affecting changes are detected
This commit is contained in:
+33
-34
@@ -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) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user