Make FirRegularTowerDataContexts immutable, SpecialTower.. just a storage

This commit is contained in:
Mikhail Glukhikh
2021-12-17 10:34:50 +03:00
committed by Space
parent 87e11c0f42
commit f3f63a458b
3 changed files with 114 additions and 62 deletions
@@ -18,30 +18,69 @@ enum class FirTowerDataMode {
SPECIAL, SPECIAL,
} }
class FirRegularTowerDataContexts( class FirRegularTowerDataContexts private constructor(
forMemberDeclarations: FirTowerDataContext, private val modeMap: EnumMap<FirTowerDataMode, FirTowerDataContext>,
forNestedClasses: FirTowerDataContext? = null, val primaryConstructorPureParametersScope: FirLocalScope?,
forCompanionObject: FirTowerDataContext? = null, val primaryConstructorAllParametersScope: FirLocalScope?,
forConstructorHeaders: FirTowerDataContext? = null, val mode: FirTowerDataMode,
forEnumEntries: FirTowerDataContext? = null,
val primaryConstructorPureParametersScope: FirLocalScope? = null,
val primaryConstructorAllParametersScope: FirLocalScope? = null,
) { ) {
private val modeMap = EnumMap<FirTowerDataMode, FirTowerDataContext>(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 { val currentContext: FirTowerDataContext?
modeMap[FirTowerDataMode.MEMBER_DECLARATION] = forMemberDeclarations get() = modeMap[mode]
modeMap[FirTowerDataMode.NESTED_CLASS] = forNestedClasses
modeMap[FirTowerDataMode.COMPANION_OBJECT] = forCompanionObject fun copy(newContext: FirTowerDataContext): FirRegularTowerDataContexts {
modeMap[FirTowerDataMode.CONSTRUCTOR_HEADER] = forConstructorHeaders val modeMap = EnumMap<FirTowerDataMode, FirTowerDataContext>(FirTowerDataMode::class.java)
modeMap[FirTowerDataMode.ENUM_ENTRY] = forEnumEntries 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? fun copyWithSpecial(newContext: FirTowerDataContext): FirRegularTowerDataContexts {
get() = modeMap[mode] val modeMap = EnumMap<FirTowerDataMode, FirTowerDataContext>(FirTowerDataMode::class.java)
set(value) { modeMap.putAll(this.modeMap)
modeMap[mode] = value 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<FirTowerDataMode, FirTowerDataContext> {
val modeMap = EnumMap<FirTowerDataMode, FirTowerDataContext>(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
} }
}
} }
@@ -12,23 +12,38 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
class FirSpecialTowerDataContexts { class FirSpecialTowerDataContexts {
val towerDataContextForAnonymousFunctions: MutableMap<FirAnonymousFunctionSymbol, FirTowerDataContext> = mutableMapOf() val towerDataContextForAnonymousFunctions: MutableMap<FirAnonymousFunctionSymbol, FirTowerDataContext> = mutableMapOf()
val towerDataContextForCallableReferences: MutableMap<FirCallableReferenceAccess, FirTowerDataContext> = mutableMapOf() val towerDataContextForCallableReferences: MutableMap<FirCallableReferenceAccess, FirTowerDataContext> = mutableMapOf()
var currentContext: FirTowerDataContext? = null
fun setAnonymousFunctionContextIfAny(symbol: FirAnonymousFunctionSymbol): Boolean { fun getAnonymousFunctionContext(symbol: FirAnonymousFunctionSymbol): FirTowerDataContext? {
val context = towerDataContextForAnonymousFunctions[symbol] return towerDataContextForAnonymousFunctions[symbol]
if (context != null) {
currentContext = context
return true
}
return false
} }
fun setCallableReferenceContextIfAny(access: FirCallableReferenceAccess): Boolean { fun getCallableReferenceContext(access: FirCallableReferenceAccess): FirTowerDataContext? {
val context = towerDataContextForCallableReferences[access] return towerDataContextForCallableReferences[access]
if (context != null) { }
currentContext = context
return true fun storeAnonymousFunctionContext(symbol: FirAnonymousFunctionSymbol, context: FirTowerDataContext) {
} towerDataContextForAnonymousFunctions[symbol] = context
return false }
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()
} }
} }
@@ -52,32 +52,27 @@ class BodyResolveContext(
@set:PrivateForInline @set:PrivateForInline
lateinit var file: FirFile lateinit var file: FirFile
@PrivateForInline
var regularTowerDataContexts = FirRegularTowerDataContexts(forMemberDeclarations = FirTowerDataContext()) var regularTowerDataContexts = FirRegularTowerDataContexts(forMemberDeclarations = FirTowerDataContext())
private set
@PrivateForInline
val specialTowerDataContexts = FirSpecialTowerDataContexts() val specialTowerDataContexts = FirSpecialTowerDataContexts()
@OptIn(PrivateForInline::class)
val towerDataContext: FirTowerDataContext val towerDataContext: FirTowerDataContext
get() = regularTowerDataContexts.currentContext get() = regularTowerDataContexts.currentContext
?: specialTowerDataContexts.currentContext ?: throw AssertionError("No regular data context found, towerDataMode = $towerDataMode")
?: throw AssertionError("Not current data context found, towerDataMode = $towerDataMode")
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
var towerDataMode: FirTowerDataMode var towerDataMode: FirTowerDataMode
get() = regularTowerDataContexts.mode get() = regularTowerDataContexts.mode
set(value) { set(value) {
regularTowerDataContexts.mode = value regularTowerDataContexts = regularTowerDataContexts.copy(newMode = value)
} }
val implicitReceiverStack: ImplicitReceiverStack val implicitReceiverStack: ImplicitReceiverStack
get() = towerDataContext.implicitReceiverStack get() = towerDataContext.implicitReceiverStack
private val towerDataContextForAnonymousFunctions: MutableMap<FirAnonymousFunctionSymbol, FirTowerDataContext>
get() = specialTowerDataContexts.towerDataContextForAnonymousFunctions
private val towerDataContextForCallableReferences: MutableMap<FirCallableReferenceAccess, FirTowerDataContext>
get() = specialTowerDataContexts.towerDataContextForCallableReferences
@set:PrivateForInline @set:PrivateForInline
var containers: ArrayDeque<FirDeclaration> = ArrayDeque() var containers: ArrayDeque<FirDeclaration> = ArrayDeque()
@@ -97,6 +92,7 @@ class BodyResolveContext(
val topClassDeclaration: FirRegularClass? val topClassDeclaration: FirRegularClass?
get() = containingClassDeclarations.lastOrNull() get() = containingClassDeclarations.lastOrNull()
@OptIn(PrivateForInline::class)
private inline fun <T> withNewTowerDataForClass(newContexts: FirRegularTowerDataContexts, f: () -> T): T { private inline fun <T> withNewTowerDataForClass(newContexts: FirRegularTowerDataContexts, f: () -> T): T {
val old = regularTowerDataContexts val old = regularTowerDataContexts
regularTowerDataContexts = newContexts regularTowerDataContexts = newContexts
@@ -178,17 +174,12 @@ class BodyResolveContext(
@PrivateForInline @PrivateForInline
fun replaceTowerDataContext(newContext: FirTowerDataContext) { fun replaceTowerDataContext(newContext: FirTowerDataContext) {
if (towerDataMode == FirTowerDataMode.SPECIAL) { regularTowerDataContexts = regularTowerDataContexts.copy(newContext)
specialTowerDataContexts.currentContext = newContext
} else {
regularTowerDataContexts.currentContext = newContext
}
} }
@PrivateForInline @PrivateForInline
fun clear() { fun clear() {
towerDataContextForAnonymousFunctions.clear() specialTowerDataContexts.clear()
towerDataContextForCallableReferences.clear()
dataFlowAnalyzerContext.reset() dataFlowAnalyzerContext.reset()
} }
@@ -286,9 +277,11 @@ class BodyResolveContext(
// ANALYSIS PUBLIC API // ANALYSIS PUBLIC API
@OptIn(PrivateForInline::class)
fun getPrimaryConstructorPureParametersScope(): FirLocalScope? = fun getPrimaryConstructorPureParametersScope(): FirLocalScope? =
regularTowerDataContexts.primaryConstructorPureParametersScope regularTowerDataContexts.primaryConstructorPureParametersScope
@OptIn(PrivateForInline::class)
fun getPrimaryConstructorAllParametersScope(): FirLocalScope? = fun getPrimaryConstructorAllParametersScope(): FirLocalScope? =
regularTowerDataContexts.primaryConstructorAllParametersScope regularTowerDataContexts.primaryConstructorAllParametersScope
@@ -317,8 +310,9 @@ class BodyResolveContext(
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
inline fun <T> withAnonymousFunctionTowerDataContext(symbol: FirAnonymousFunctionSymbol, f: () -> T): T { inline fun <T> withAnonymousFunctionTowerDataContext(symbol: FirAnonymousFunctionSymbol, f: () -> T): T {
return withTowerModeCleanup { return withTowerModeCleanup {
if (specialTowerDataContexts.setAnonymousFunctionContextIfAny(symbol)) { val newContext = specialTowerDataContexts.getAnonymousFunctionContext(symbol)
regularTowerDataContexts.mode = FirTowerDataMode.SPECIAL if (newContext != null) {
regularTowerDataContexts = regularTowerDataContexts.copyWithSpecial(newContext)
} }
f() f()
} }
@@ -327,15 +321,17 @@ class BodyResolveContext(
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
inline fun <T> withCallableReferenceTowerDataContext(access: FirCallableReferenceAccess, f: () -> T): T { inline fun <T> withCallableReferenceTowerDataContext(access: FirCallableReferenceAccess, f: () -> T): T {
return withTowerModeCleanup { return withTowerModeCleanup {
if (specialTowerDataContexts.setCallableReferenceContextIfAny(access)) { val newContext = specialTowerDataContexts.getCallableReferenceContext(access)
regularTowerDataContexts.mode = FirTowerDataMode.SPECIAL if (newContext != null) {
regularTowerDataContexts = regularTowerDataContexts.copyWithSpecial(newContext)
} }
f() f()
} }
} }
@OptIn(PrivateForInline::class)
fun dropContextForAnonymousFunction(anonymousFunction: FirAnonymousFunction) { fun dropContextForAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
towerDataContextForAnonymousFunctions.remove(anonymousFunction.symbol) specialTowerDataContexts.dropAnonymousFunctionContext(anonymousFunction.symbol)
} }
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
@@ -346,8 +342,7 @@ class BodyResolveContext(
BodyResolveContext(returnTypeCalculator, dataFlowAnalyzerContext, targetedLocalClasses, outerLocalClassForNested).apply { BodyResolveContext(returnTypeCalculator, dataFlowAnalyzerContext, targetedLocalClasses, outerLocalClassForNested).apply {
file = this@BodyResolveContext.file file = this@BodyResolveContext.file
fileImportsScope += this@BodyResolveContext.fileImportsScope fileImportsScope += this@BodyResolveContext.fileImportsScope
towerDataContextForAnonymousFunctions.putAll(this@BodyResolveContext.towerDataContextForAnonymousFunctions) specialTowerDataContexts.putAll(this@BodyResolveContext.specialTowerDataContexts)
towerDataContextForCallableReferences.putAll(this@BodyResolveContext.towerDataContextForCallableReferences)
containers = this@BodyResolveContext.containers containers = this@BodyResolveContext.containers
containingClassDeclarations = ArrayDeque(this@BodyResolveContext.containingClassDeclarations) containingClassDeclarations = ArrayDeque(this@BodyResolveContext.containingClassDeclarations)
containingClass = this@BodyResolveContext.containingClass containingClass = this@BodyResolveContext.containingClass
@@ -477,6 +472,7 @@ class BodyResolveContext(
statics, statics,
scopeForConstructorHeader, scopeForConstructorHeader,
scopeForEnumEntries, scopeForEnumEntries,
forSpecial = null,
primaryConstructorPureParametersScope, primaryConstructorPureParametersScope,
primaryConstructorAllParametersScope primaryConstructorAllParametersScope
) )
@@ -573,7 +569,7 @@ class BodyResolveContext(
f: () -> T f: () -> T
): T { ): T {
if (mode !is ResolutionMode.LambdaResolution) { if (mode !is ResolutionMode.LambdaResolution) {
towerDataContextForAnonymousFunctions[anonymousFunction.symbol] = towerDataContext specialTowerDataContexts.storeAnonymousFunctionContext(anonymousFunction.symbol, towerDataContext)
} }
if (mode is ResolutionMode.ContextDependent || mode is ResolutionMode.ContextDependentDelegate) { if (mode is ResolutionMode.ContextDependent || mode is ResolutionMode.ContextDependentDelegate) {
return f() return f()
@@ -756,12 +752,14 @@ class BodyResolveContext(
} }
} }
@OptIn(PrivateForInline::class)
fun storeCallableReferenceContext(callableReferenceAccess: FirCallableReferenceAccess) { fun storeCallableReferenceContext(callableReferenceAccess: FirCallableReferenceAccess) {
towerDataContextForCallableReferences[callableReferenceAccess] = towerDataContext specialTowerDataContexts.storeCallableReferenceContext(callableReferenceAccess, towerDataContext)
} }
@OptIn(PrivateForInline::class)
fun dropCallableReferenceContext(callableReferenceAccess: FirCallableReferenceAccess) { fun dropCallableReferenceContext(callableReferenceAccess: FirCallableReferenceAccess) {
towerDataContextForCallableReferences.remove(callableReferenceAccess) specialTowerDataContexts.dropCallableReferenceContext(callableReferenceAccess)
} }
fun <T> withWhenExpression(whenExpression: FirWhenExpression, session: FirSession, f: () -> T): T { fun <T> withWhenExpression(whenExpression: FirWhenExpression, session: FirSession, f: () -> T): T {