From 7147b7d17b1b754ddbce665d2331afb2f169e1bf Mon Sep 17 00:00:00 2001 From: Nikolay Lunyak Date: Fri, 25 Nov 2022 09:12:15 +0000 Subject: [PATCH] [FIR] KT-55033: Split `runTransaction` into smaller functions ^KT-55033 Fixed Merge-request: KT-MR-7779 Merged-by: Nikolay Lunyak --- .../jetbrains/kotlin/fir/FirCallResolver.kt | 1 + .../calls/CallableReferenceResolution.kt | 1 + .../inference/ConstraintSystemBuilder.kt | 28 ++++-- .../model/NewConstraintSystemImpl.kt | 90 +++++++++++-------- 4 files changed, 78 insertions(+), 42 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 14eba54b509..f947b7d7e61 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt index 8f40ed3528f..ef66f79a159 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt @@ -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 diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt index 65cf9bf00cb..8286fcb4768 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt @@ -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 } +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, diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index 41b97d8815e..45ab1b71f8c 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -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, + 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