From f3f63a458bf65b876b922e997adb6e68c71bca7f Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 17 Dec 2021 10:34:50 +0300 Subject: [PATCH] Make FirRegularTowerDataContexts immutable, SpecialTower.. just a storage --- .../resolve/FirRegularTowerDataContexts.kt | 79 ++++++++++++++----- .../resolve/FirSpecialTowerDataContexts.kt | 45 +++++++---- .../body/resolve/BodyResolveContext.kt | 52 ++++++------ 3 files changed, 114 insertions(+), 62 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirRegularTowerDataContexts.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirRegularTowerDataContexts.kt index 611f5f58098..d8f27c8fe39 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirRegularTowerDataContexts.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirRegularTowerDataContexts.kt @@ -18,30 +18,69 @@ enum class FirTowerDataMode { SPECIAL, } -class FirRegularTowerDataContexts( - forMemberDeclarations: FirTowerDataContext, - forNestedClasses: FirTowerDataContext? = null, - forCompanionObject: FirTowerDataContext? = null, - forConstructorHeaders: FirTowerDataContext? = null, - forEnumEntries: FirTowerDataContext? = null, - val primaryConstructorPureParametersScope: FirLocalScope? = null, - val primaryConstructorAllParametersScope: FirLocalScope? = null, +class FirRegularTowerDataContexts private constructor( + private val modeMap: EnumMap, + val primaryConstructorPureParametersScope: FirLocalScope?, + val primaryConstructorAllParametersScope: FirLocalScope?, + val mode: FirTowerDataMode, ) { - private val modeMap = EnumMap(FirTowerDataMode::class.java) + constructor( + forMemberDeclarations: FirTowerDataContext, + forNestedClasses: FirTowerDataContext? = null, + forCompanionObject: FirTowerDataContext? = null, + forConstructorHeaders: FirTowerDataContext? = null, + forEnumEntries: FirTowerDataContext? = null, + forSpecial: FirTowerDataContext? = null, + primaryConstructorPureParametersScope: FirLocalScope? = null, + primaryConstructorAllParametersScope: FirLocalScope? = null, + ) : this( + enumMap(forMemberDeclarations, forNestedClasses, forCompanionObject, forConstructorHeaders, forEnumEntries, forSpecial), + primaryConstructorPureParametersScope, + primaryConstructorAllParametersScope, + FirTowerDataMode.MEMBER_DECLARATION + ) - init { - modeMap[FirTowerDataMode.MEMBER_DECLARATION] = forMemberDeclarations - modeMap[FirTowerDataMode.NESTED_CLASS] = forNestedClasses - modeMap[FirTowerDataMode.COMPANION_OBJECT] = forCompanionObject - modeMap[FirTowerDataMode.CONSTRUCTOR_HEADER] = forConstructorHeaders - modeMap[FirTowerDataMode.ENUM_ENTRY] = forEnumEntries + val currentContext: FirTowerDataContext? + get() = modeMap[mode] + + fun copy(newContext: FirTowerDataContext): FirRegularTowerDataContexts { + val modeMap = EnumMap(FirTowerDataMode::class.java) + modeMap.putAll(this.modeMap) + modeMap[mode] = newContext + return FirRegularTowerDataContexts(modeMap, primaryConstructorPureParametersScope, primaryConstructorAllParametersScope, mode) } - var mode: FirTowerDataMode = FirTowerDataMode.MEMBER_DECLARATION + fun copy(newMode: FirTowerDataMode): FirRegularTowerDataContexts { + if (newMode == mode) return this + return FirRegularTowerDataContexts(modeMap, primaryConstructorPureParametersScope, primaryConstructorAllParametersScope, newMode) + } - var currentContext: FirTowerDataContext? - get() = modeMap[mode] - set(value) { - modeMap[mode] = value + fun copyWithSpecial(newContext: FirTowerDataContext): FirRegularTowerDataContexts { + val modeMap = EnumMap(FirTowerDataMode::class.java) + modeMap.putAll(this.modeMap) + modeMap[FirTowerDataMode.SPECIAL] = newContext + return FirRegularTowerDataContexts( + modeMap, primaryConstructorPureParametersScope, primaryConstructorAllParametersScope, FirTowerDataMode.SPECIAL + ) + } + + companion object { + private fun enumMap( + forMemberDeclarations: FirTowerDataContext, + forNestedClasses: FirTowerDataContext?, + forCompanionObject: FirTowerDataContext?, + forConstructorHeaders: FirTowerDataContext?, + forEnumEntries: FirTowerDataContext?, + forSpecial: FirTowerDataContext?, + ): EnumMap { + val modeMap = EnumMap(FirTowerDataMode::class.java) + modeMap[FirTowerDataMode.MEMBER_DECLARATION] = forMemberDeclarations + modeMap[FirTowerDataMode.NESTED_CLASS] = forNestedClasses + modeMap[FirTowerDataMode.COMPANION_OBJECT] = forCompanionObject + modeMap[FirTowerDataMode.CONSTRUCTOR_HEADER] = forConstructorHeaders + modeMap[FirTowerDataMode.ENUM_ENTRY] = forEnumEntries + modeMap[FirTowerDataMode.SPECIAL] = forSpecial + return modeMap } + } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirSpecialTowerDataContexts.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirSpecialTowerDataContexts.kt index 9e35a3561cd..4a91d26007f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirSpecialTowerDataContexts.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirSpecialTowerDataContexts.kt @@ -12,23 +12,38 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol class FirSpecialTowerDataContexts { val towerDataContextForAnonymousFunctions: MutableMap = mutableMapOf() val towerDataContextForCallableReferences: MutableMap = mutableMapOf() - var currentContext: FirTowerDataContext? = null - fun setAnonymousFunctionContextIfAny(symbol: FirAnonymousFunctionSymbol): Boolean { - val context = towerDataContextForAnonymousFunctions[symbol] - if (context != null) { - currentContext = context - return true - } - return false + fun getAnonymousFunctionContext(symbol: FirAnonymousFunctionSymbol): FirTowerDataContext? { + return towerDataContextForAnonymousFunctions[symbol] } - fun setCallableReferenceContextIfAny(access: FirCallableReferenceAccess): Boolean { - val context = towerDataContextForCallableReferences[access] - if (context != null) { - currentContext = context - return true - } - return false + fun getCallableReferenceContext(access: FirCallableReferenceAccess): FirTowerDataContext? { + return towerDataContextForCallableReferences[access] + } + + fun storeAnonymousFunctionContext(symbol: FirAnonymousFunctionSymbol, context: FirTowerDataContext) { + towerDataContextForAnonymousFunctions[symbol] = context + } + + fun dropAnonymousFunctionContext(symbol: FirAnonymousFunctionSymbol) { + towerDataContextForAnonymousFunctions.remove(symbol) + } + + fun storeCallableReferenceContext(access: FirCallableReferenceAccess, context: FirTowerDataContext) { + towerDataContextForCallableReferences[access] = context + } + + fun dropCallableReferenceContext(access: FirCallableReferenceAccess) { + towerDataContextForCallableReferences.remove(access) + } + + fun putAll(contexts: FirSpecialTowerDataContexts) { + towerDataContextForCallableReferences.putAll(contexts.towerDataContextForCallableReferences) + towerDataContextForAnonymousFunctions.putAll(contexts.towerDataContextForAnonymousFunctions) + } + + fun clear() { + towerDataContextForAnonymousFunctions.clear() + towerDataContextForCallableReferences.clear() } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index ae722b8a52c..06e2b735f73 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -52,32 +52,27 @@ class BodyResolveContext( @set:PrivateForInline lateinit var file: FirFile + @PrivateForInline var regularTowerDataContexts = FirRegularTowerDataContexts(forMemberDeclarations = FirTowerDataContext()) - private set + @PrivateForInline val specialTowerDataContexts = FirSpecialTowerDataContexts() + @OptIn(PrivateForInline::class) val towerDataContext: FirTowerDataContext get() = regularTowerDataContexts.currentContext - ?: specialTowerDataContexts.currentContext - ?: throw AssertionError("Not current data context found, towerDataMode = $towerDataMode") + ?: throw AssertionError("No regular data context found, towerDataMode = $towerDataMode") @OptIn(PrivateForInline::class) var towerDataMode: FirTowerDataMode get() = regularTowerDataContexts.mode set(value) { - regularTowerDataContexts.mode = value + regularTowerDataContexts = regularTowerDataContexts.copy(newMode = value) } val implicitReceiverStack: ImplicitReceiverStack get() = towerDataContext.implicitReceiverStack - private val towerDataContextForAnonymousFunctions: MutableMap - get() = specialTowerDataContexts.towerDataContextForAnonymousFunctions - - private val towerDataContextForCallableReferences: MutableMap - get() = specialTowerDataContexts.towerDataContextForCallableReferences - @set:PrivateForInline var containers: ArrayDeque = ArrayDeque() @@ -97,6 +92,7 @@ class BodyResolveContext( val topClassDeclaration: FirRegularClass? get() = containingClassDeclarations.lastOrNull() + @OptIn(PrivateForInline::class) private inline fun withNewTowerDataForClass(newContexts: FirRegularTowerDataContexts, f: () -> T): T { val old = regularTowerDataContexts regularTowerDataContexts = newContexts @@ -178,17 +174,12 @@ class BodyResolveContext( @PrivateForInline fun replaceTowerDataContext(newContext: FirTowerDataContext) { - if (towerDataMode == FirTowerDataMode.SPECIAL) { - specialTowerDataContexts.currentContext = newContext - } else { - regularTowerDataContexts.currentContext = newContext - } + regularTowerDataContexts = regularTowerDataContexts.copy(newContext) } @PrivateForInline fun clear() { - towerDataContextForAnonymousFunctions.clear() - towerDataContextForCallableReferences.clear() + specialTowerDataContexts.clear() dataFlowAnalyzerContext.reset() } @@ -286,9 +277,11 @@ class BodyResolveContext( // ANALYSIS PUBLIC API + @OptIn(PrivateForInline::class) fun getPrimaryConstructorPureParametersScope(): FirLocalScope? = regularTowerDataContexts.primaryConstructorPureParametersScope + @OptIn(PrivateForInline::class) fun getPrimaryConstructorAllParametersScope(): FirLocalScope? = regularTowerDataContexts.primaryConstructorAllParametersScope @@ -317,8 +310,9 @@ class BodyResolveContext( @OptIn(PrivateForInline::class) inline fun withAnonymousFunctionTowerDataContext(symbol: FirAnonymousFunctionSymbol, f: () -> T): T { return withTowerModeCleanup { - if (specialTowerDataContexts.setAnonymousFunctionContextIfAny(symbol)) { - regularTowerDataContexts.mode = FirTowerDataMode.SPECIAL + val newContext = specialTowerDataContexts.getAnonymousFunctionContext(symbol) + if (newContext != null) { + regularTowerDataContexts = regularTowerDataContexts.copyWithSpecial(newContext) } f() } @@ -327,15 +321,17 @@ class BodyResolveContext( @OptIn(PrivateForInline::class) inline fun withCallableReferenceTowerDataContext(access: FirCallableReferenceAccess, f: () -> T): T { return withTowerModeCleanup { - if (specialTowerDataContexts.setCallableReferenceContextIfAny(access)) { - regularTowerDataContexts.mode = FirTowerDataMode.SPECIAL + val newContext = specialTowerDataContexts.getCallableReferenceContext(access) + if (newContext != null) { + regularTowerDataContexts = regularTowerDataContexts.copyWithSpecial(newContext) } f() } } + @OptIn(PrivateForInline::class) fun dropContextForAnonymousFunction(anonymousFunction: FirAnonymousFunction) { - towerDataContextForAnonymousFunctions.remove(anonymousFunction.symbol) + specialTowerDataContexts.dropAnonymousFunctionContext(anonymousFunction.symbol) } @OptIn(PrivateForInline::class) @@ -346,8 +342,7 @@ class BodyResolveContext( BodyResolveContext(returnTypeCalculator, dataFlowAnalyzerContext, targetedLocalClasses, outerLocalClassForNested).apply { file = this@BodyResolveContext.file fileImportsScope += this@BodyResolveContext.fileImportsScope - towerDataContextForAnonymousFunctions.putAll(this@BodyResolveContext.towerDataContextForAnonymousFunctions) - towerDataContextForCallableReferences.putAll(this@BodyResolveContext.towerDataContextForCallableReferences) + specialTowerDataContexts.putAll(this@BodyResolveContext.specialTowerDataContexts) containers = this@BodyResolveContext.containers containingClassDeclarations = ArrayDeque(this@BodyResolveContext.containingClassDeclarations) containingClass = this@BodyResolveContext.containingClass @@ -477,6 +472,7 @@ class BodyResolveContext( statics, scopeForConstructorHeader, scopeForEnumEntries, + forSpecial = null, primaryConstructorPureParametersScope, primaryConstructorAllParametersScope ) @@ -573,7 +569,7 @@ class BodyResolveContext( f: () -> T ): T { if (mode !is ResolutionMode.LambdaResolution) { - towerDataContextForAnonymousFunctions[anonymousFunction.symbol] = towerDataContext + specialTowerDataContexts.storeAnonymousFunctionContext(anonymousFunction.symbol, towerDataContext) } if (mode is ResolutionMode.ContextDependent || mode is ResolutionMode.ContextDependentDelegate) { return f() @@ -756,12 +752,14 @@ class BodyResolveContext( } } + @OptIn(PrivateForInline::class) fun storeCallableReferenceContext(callableReferenceAccess: FirCallableReferenceAccess) { - towerDataContextForCallableReferences[callableReferenceAccess] = towerDataContext + specialTowerDataContexts.storeCallableReferenceContext(callableReferenceAccess, towerDataContext) } + @OptIn(PrivateForInline::class) fun dropCallableReferenceContext(callableReferenceAccess: FirCallableReferenceAccess) { - towerDataContextForCallableReferences.remove(callableReferenceAccess) + specialTowerDataContexts.dropCallableReferenceContext(callableReferenceAccess) } fun withWhenExpression(whenExpression: FirWhenExpression, session: FirSession, f: () -> T): T {