[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.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder 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.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability 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.components.SuspendConversionStrategy
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition 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.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.expressions.CoercionStrategy import org.jetbrains.kotlin.types.expressions.CoercionStrategy
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.resolve.calls.inference package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind import org.jetbrains.kotlin.resolve.calls.inference.model.*
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.types.model.* import org.jetbrains.kotlin.types.model.*
interface ConstraintSystemOperation { interface ConstraintSystemOperation {
@@ -52,15 +49,34 @@ interface ConstraintSystemOperation {
val errors: List<ConstraintSystemError> val errors: List<ConstraintSystemError>
} }
abstract class ConstraintSystemTransaction {
abstract fun closeTransaction()
abstract fun rollbackTransaction()
}
interface ConstraintSystemBuilder : ConstraintSystemOperation { interface ConstraintSystemBuilder : ConstraintSystemOperation {
// if runOperations return true, then this operation will be applied, and function return true fun prepareTransaction(): ConstraintSystemTransaction
fun runTransaction(runOperations: ConstraintSystemOperation.() -> Boolean): Boolean
fun buildCurrentSubstitutor(): TypeSubstitutorMarker fun buildCurrentSubstitutor(): TypeSubstitutorMarker
fun currentStorage(): ConstraintStorage 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( fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(
lowerType: KotlinTypeMarker, lowerType: KotlinTypeMarker,
upperType: KotlinTypeMarker, upperType: KotlinTypeMarker,
@@ -206,46 +206,64 @@ class NewConstraintSystemImpl(
state = beforeState state = beforeState
} }
override fun runTransaction(runOperations: ConstraintSystemOperation.() -> Boolean): Boolean { private inner class TransactionState(
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) private val beforeState: State,
val beforeState = state private val beforeInitialConstraintCount: Int,
val beforeInitialConstraintCount = storage.initialConstraints.size private val beforeErrorsCount: Int,
val beforeErrorsCount = storage.errors.size private val beforeMaxTypeDepthFromInitialConstraints: Int,
val beforeMaxTypeDepthFromInitialConstraints = storage.maxTypeDepthFromInitialConstraints private val beforeTypeVariablesTransactionSize: Int,
val beforeTypeVariablesTransactionSize = typeVariablesTransaction.size private val beforeMissedConstraintsCount: Int,
val beforeMissedConstraintsCount = storage.missedConstraints.size private val beforeConstraintCountByVariables: Map<TypeConstructorMarker, Int>,
val beforeConstraintCountByVariables = storage.notFixedTypeVariables.mapValues { it.value.rawConstraintsCount } private val beforeConstraintsFromAllForks: Int,
val beforeConstraintsFromAllForks = storage.constraintsFromAllForkPoints.size ) : ConstraintSystemTransaction() {
override fun closeTransaction() {
state = State.TRANSACTION checkState(State.TRANSACTION)
// typeVariablesTransaction is clear typeVariablesTransaction.trimToSize(beforeTypeVariablesTransactionSize)
if (runOperations()) { state = beforeState
closeTransaction(beforeState, beforeTypeVariablesTransactionSize)
return true
} }
for (addedTypeVariable in typeVariablesTransaction.subList(beforeTypeVariablesTransactionSize, typeVariablesTransaction.size)) { override fun rollbackTransaction() {
storage.allTypeVariables.remove(addedTypeVariable.freshTypeConstructor()) for (addedTypeVariable in typeVariablesTransaction.subList(beforeTypeVariablesTransactionSize, typeVariablesTransaction.size)) {
storage.notFixedTypeVariables.remove(addedTypeVariable.freshTypeConstructor()) 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)
} }
} storage.maxTypeDepthFromInitialConstraints = beforeMaxTypeDepthFromInitialConstraints
storage.errors.trimToSize(beforeErrorsCount)
storage.missedConstraints.trimToSize(beforeMissedConstraintsCount)
storage.constraintsFromAllForkPoints.trimToSize(beforeConstraintsFromAllForks)
addedInitialConstraints.clear() // remove constraint from storage.initialConstraints val addedInitialConstraints = storage.initialConstraints.subList(
closeTransaction(beforeState, beforeTypeVariablesTransactionSize) beforeInitialConstraintCount,
return false 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 // ConstraintSystemBuilder, KotlinConstraintSystemCompleter.Context