[FIR] KT-55033: Split runTransaction into smaller functions

^KT-55033 Fixed

Merge-request: KT-MR-7779
Merged-by: Nikolay Lunyak <Nikolay.Lunyak@jetbrains.com>
This commit is contained in:
Nikolay Lunyak
2022-11-25 09:12:15 +00:00
committed by Space Team
parent bcc0414960
commit 7147b7d17b
4 changed files with 78 additions and 42 deletions
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.runTransaction
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.calls.components.SuspendConversionStrategy
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.runTransaction
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.expressions.CoercionStrategy
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.types.model.*
interface ConstraintSystemOperation {
@@ -52,15 +49,34 @@ interface ConstraintSystemOperation {
val errors: List<ConstraintSystemError>
}
abstract class ConstraintSystemTransaction {
abstract fun closeTransaction()
abstract fun rollbackTransaction()
}
interface ConstraintSystemBuilder : ConstraintSystemOperation {
// if runOperations return true, then this operation will be applied, and function return true
fun runTransaction(runOperations: ConstraintSystemOperation.() -> Boolean): Boolean
fun prepareTransaction(): ConstraintSystemTransaction
fun buildCurrentSubstitutor(): TypeSubstitutorMarker
fun currentStorage(): ConstraintStorage
}
// if runOperations return true, then this operation will be applied, and function return true
inline fun ConstraintSystemBuilder.runTransaction(crossinline runOperations: ConstraintSystemOperation.() -> Boolean): Boolean {
val transactionState = prepareTransaction()
// typeVariablesTransaction is clear
if (runOperations()) {
transactionState.closeTransaction()
return true
}
transactionState.rollbackTransaction()
return false
}
fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(
lowerType: KotlinTypeMarker,
upperType: KotlinTypeMarker,
@@ -206,46 +206,64 @@ class NewConstraintSystemImpl(
state = beforeState
}
override fun runTransaction(runOperations: ConstraintSystemOperation.() -> Boolean): Boolean {
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
val beforeState = state
val beforeInitialConstraintCount = storage.initialConstraints.size
val beforeErrorsCount = storage.errors.size
val beforeMaxTypeDepthFromInitialConstraints = storage.maxTypeDepthFromInitialConstraints
val beforeTypeVariablesTransactionSize = typeVariablesTransaction.size
val beforeMissedConstraintsCount = storage.missedConstraints.size
val beforeConstraintCountByVariables = storage.notFixedTypeVariables.mapValues { it.value.rawConstraintsCount }
val beforeConstraintsFromAllForks = storage.constraintsFromAllForkPoints.size
state = State.TRANSACTION
// typeVariablesTransaction is clear
if (runOperations()) {
closeTransaction(beforeState, beforeTypeVariablesTransactionSize)
return true
private inner class TransactionState(
private val beforeState: State,
private val beforeInitialConstraintCount: Int,
private val beforeErrorsCount: Int,
private val beforeMaxTypeDepthFromInitialConstraints: Int,
private val beforeTypeVariablesTransactionSize: Int,
private val beforeMissedConstraintsCount: Int,
private val beforeConstraintCountByVariables: Map<TypeConstructorMarker, Int>,
private val beforeConstraintsFromAllForks: Int,
) : ConstraintSystemTransaction() {
override fun closeTransaction() {
checkState(State.TRANSACTION)
typeVariablesTransaction.trimToSize(beforeTypeVariablesTransactionSize)
state = beforeState
}
for (addedTypeVariable in typeVariablesTransaction.subList(beforeTypeVariablesTransactionSize, typeVariablesTransaction.size)) {
storage.allTypeVariables.remove(addedTypeVariable.freshTypeConstructor())
storage.notFixedTypeVariables.remove(addedTypeVariable.freshTypeConstructor())
}
storage.maxTypeDepthFromInitialConstraints = beforeMaxTypeDepthFromInitialConstraints
storage.errors.trimToSize(beforeErrorsCount)
storage.missedConstraints.trimToSize(beforeMissedConstraintsCount)
storage.constraintsFromAllForkPoints.trimToSize(beforeConstraintsFromAllForks)
val addedInitialConstraints = storage.initialConstraints.subList(beforeInitialConstraintCount, storage.initialConstraints.size)
for (variableWithConstraint in storage.notFixedTypeVariables.values) {
val sinceIndexToRemoveConstraints =
beforeConstraintCountByVariables[variableWithConstraint.typeVariable.freshTypeConstructor()]
if (sinceIndexToRemoveConstraints != null) {
variableWithConstraint.removeLastConstraints(sinceIndexToRemoveConstraints)
override fun rollbackTransaction() {
for (addedTypeVariable in typeVariablesTransaction.subList(beforeTypeVariablesTransactionSize, typeVariablesTransaction.size)) {
storage.allTypeVariables.remove(addedTypeVariable.freshTypeConstructor())
storage.notFixedTypeVariables.remove(addedTypeVariable.freshTypeConstructor())
}
}
storage.maxTypeDepthFromInitialConstraints = beforeMaxTypeDepthFromInitialConstraints
storage.errors.trimToSize(beforeErrorsCount)
storage.missedConstraints.trimToSize(beforeMissedConstraintsCount)
storage.constraintsFromAllForkPoints.trimToSize(beforeConstraintsFromAllForks)
addedInitialConstraints.clear() // remove constraint from storage.initialConstraints
closeTransaction(beforeState, beforeTypeVariablesTransactionSize)
return false
val addedInitialConstraints = storage.initialConstraints.subList(
beforeInitialConstraintCount,
storage.initialConstraints.size
)
for (variableWithConstraint in storage.notFixedTypeVariables.values) {
val sinceIndexToRemoveConstraints =
beforeConstraintCountByVariables[variableWithConstraint.typeVariable.freshTypeConstructor()]
if (sinceIndexToRemoveConstraints != null) {
variableWithConstraint.removeLastConstraints(sinceIndexToRemoveConstraints)
}
}
addedInitialConstraints.clear() // remove constraint from storage.initialConstraints
closeTransaction(beforeState, beforeTypeVariablesTransactionSize)
}
}
override fun prepareTransaction(): ConstraintSystemTransaction {
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
return TransactionState(
beforeState = state,
beforeInitialConstraintCount = storage.initialConstraints.size,
beforeErrorsCount = storage.errors.size,
beforeMaxTypeDepthFromInitialConstraints = storage.maxTypeDepthFromInitialConstraints,
beforeTypeVariablesTransactionSize = typeVariablesTransaction.size,
beforeMissedConstraintsCount = storage.missedConstraints.size,
beforeConstraintCountByVariables = storage.notFixedTypeVariables.mapValues { it.value.rawConstraintsCount },
beforeConstraintsFromAllForks = storage.constraintsFromAllForkPoints.size,
).also {
state = State.TRANSACTION
}
}
// ConstraintSystemBuilder, KotlinConstraintSystemCompleter.Context