FIR: extract BodyResolveContext.withAnonymousObject

This commit is contained in:
Mikhail Glukhikh
2021-03-04 13:29:35 +03:00
parent e5325e70fc
commit db2b6e92e5
2 changed files with 21 additions and 90 deletions
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.declarations.*
@@ -25,7 +26,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.name.Name
class BodyResolveContext(
@@ -272,19 +272,28 @@ class BodyResolveContext(
}
}
withScopesForClass(regularClass.name, regularClass, regularClass.defaultType(), holder) {
f()
}
withScopesForClass(regularClass, holder, f)
}
}
inline fun <T> withAnonymousObject(
anonymousObject: FirAnonymousObject,
holder: SessionHolder,
crossinline f: () -> T
): T {
return withScopesForClass(anonymousObject, holder, f)
}
inline fun <T> withScopesForClass(
labelName: Name?,
owner: FirClass<*>,
type: ConeKotlinType,
holder: SessionHolder,
f: () -> T
): T {
val labelName = (owner as? FirRegularClass)?.name
?: if (owner.classKind == ClassKind.ENUM_ENTRY) {
owner.primaryConstructor?.symbol?.callableId?.className?.shortName()
} else null
val type = owner.defaultType()
val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type)
val base = towerDataContext.addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers)
@@ -298,7 +307,7 @@ class BodyResolveContext(
.addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope)
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
val typeParameterScope = (owner as? FirRegularClass)?.let(this::createTypeParameterScope)
val typeParameterScope = (owner as? FirRegularClass)?.typeParameterScope()
val forMembersResolution =
staticsAndCompanion
@@ -336,9 +345,9 @@ class BodyResolveContext(
}
}
fun createTypeParameterScope(declaration: FirMemberDeclaration): FirMemberTypeParameterScope? {
if (declaration.typeParameters.isEmpty()) return null
return FirMemberTypeParameterScope(declaration)
fun FirMemberDeclaration.typeParameterScope(): FirMemberTypeParameterScope? {
if (typeParameters.isEmpty()) return null
return FirMemberTypeParameterScope(this)
}
fun FirConstructor.scopesWithPrimaryConstructorParameters(
@@ -431,18 +431,13 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
return anonymousObject.runAllPhasesForLocalClass(transformer, components, data).compose()
}
dataFlowAnalyzer.enterClass()
val type = anonymousObject.defaultType()
if (anonymousObject.typeRef !is FirResolvedTypeRef) {
anonymousObject.resultType = buildResolvedTypeRef {
source = anonymousObject.source
this.type = type
this.type = anonymousObject.defaultType()
}
}
val labelName =
if (anonymousObject.classKind == ClassKind.ENUM_ENTRY) {
anonymousObject.primaryConstructor?.symbol?.callableId?.className?.shortName()
} else null
val result = withScopesForClass(labelName, anonymousObject, type) {
val result = context.withAnonymousObject(anonymousObject, components) {
transformDeclarationContent(anonymousObject, data).single as FirAnonymousObject
}
if (!implicitTypeOnly && result.controlFlowGraphReference == null) {
@@ -879,83 +874,10 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
return this
}
private inline fun <T> withScopesForClass(
labelName: Name?,
owner: FirClass<*>,
type: ConeKotlinType,
block: () -> T
): T {
val towerElementsForClass = components.collectTowerDataElementsForClass(owner, type)
val base = context.towerDataContext.addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers)
val statics = base
.addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope)
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
val companionReceiver = towerElementsForClass.companionReceiver
val staticsAndCompanion = if (companionReceiver == null) statics else base
.addReceiver(null, companionReceiver)
.addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope)
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
val typeParameterScope = (owner as? FirRegularClass)?.let(this::createTypeParameterScope)
val forMembersResolution =
staticsAndCompanion
.addReceiver(labelName, towerElementsForClass.thisReceiver)
.addNonLocalScopeIfNotNull(typeParameterScope)
val scopeForConstructorHeader =
staticsAndCompanion.addNonLocalScopeIfNotNull(typeParameterScope)
val newTowerDataContextForStaticNestedClasses =
if ((owner as? FirRegularClass)?.classKind?.isSingleton == true)
forMembersResolution
else
staticsAndCompanion
val constructor = (owner as? FirRegularClass)?.declarations?.firstOrNull { it is FirConstructor } as? FirConstructor
val (primaryConstructorPureParametersScope, primaryConstructorAllParametersScope) =
if (constructor?.isPrimary == true) {
constructor.scopesWithPrimaryConstructorParameters(owner)
} else {
null to null
}
val newContexts = FirTowerDataContextsForClassParts(
forMembersResolution,
newTowerDataContextForStaticNestedClasses,
statics,
scopeForConstructorHeader,
primaryConstructorPureParametersScope,
primaryConstructorAllParametersScope
)
return context.withNewTowerDataForClassParts(newContexts) {
block()
}
}
private fun FirConstructor.scopeWithParameters(): FirLocalScope {
return valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
}
private fun FirConstructor.scopesWithPrimaryConstructorParameters(
ownerClass: FirClass<*>
): Pair<FirLocalScope, FirLocalScope> {
var parameterScope = FirLocalScope()
var allScope = FirLocalScope()
val properties = ownerClass.declarations.filterIsInstance<FirProperty>().associateBy { it.name }
for (parameter in valueParameters) {
allScope = allScope.storeVariable(parameter)
val property = properties[parameter.name]
if (property?.source?.kind != FirFakeSourceElementKind.PropertyFromParameter) {
parameterScope = parameterScope.storeVariable(parameter)
}
}
return parameterScope to allScope
}
protected inline fun <T> withLabelAndReceiverType(
labelName: Name?,
owner: FirCallableDeclaration<*>,