FIR: Refactor scopes structure in body resolution

- Split top-level scopes into file imports and type parameters
- Make type parameters to be a persistent list
This commit is contained in:
Denis Zharkov
2020-03-17 19:06:14 +03:00
parent 38b1a3d9f1
commit eb154dce1e
6 changed files with 63 additions and 49 deletions
@@ -31,7 +31,8 @@ interface SessionHolder {
interface BodyResolveComponents : SessionHolder { interface BodyResolveComponents : SessionHolder {
val returnTypeCalculator: ReturnTypeCalculator val returnTypeCalculator: ReturnTypeCalculator
val implicitReceiverStack: MutableImplicitReceiverStack val implicitReceiverStack: MutableImplicitReceiverStack
val topLevelScopes: List<FirScope> val fileImportsScope: List<FirScope>
val typeParametersScopes: List<FirScope>
val localScopes: FirLocalScopes val localScopes: FirLocalScopes
val localContextForAnonymousFunctions: LocalContextForAnonymousFunctions val localContextForAnonymousFunctions: LocalContextForAnonymousFunctions
val noExpectedType: FirTypeRef val noExpectedType: FirTypeRef
@@ -34,7 +34,11 @@ class FirTowerResolver(
resolutionStageRunner: ResolutionStageRunner, resolutionStageRunner: ResolutionStageRunner,
) { ) {
private val localScopes: List<FirLocalScope> get() = components.localScopes.asReversed() private val localScopes: List<FirLocalScope> get() = components.localScopes.asReversed()
private val topLevelScopes: List<FirScope> get() = components.topLevelScopes.asReversed() private val topLevelScopes: List<FirScope>
get() {
if (components.typeParametersScopes.isEmpty()) return components.fileImportsScope.asReversed()
return components.typeParametersScopes.asReversed() + components.fileImportsScope.asReversed()
}
private val session: FirSession get() = components.session private val session: FirSession get() = components.session
private val collector = CandidateCollector(components, resolutionStageRunner) private val collector = CandidateCollector(components, resolutionStageRunner)
@@ -496,4 +500,4 @@ class FirTowerResolver(
collector.newDataSet() collector.newDataSet()
manager.reset() manager.reset()
} }
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
@@ -71,7 +72,6 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
} }
} }
protected inline val topLevelScopes: MutableList<FirScope> get() = components.topLevelScopes
protected inline val localScopes: List<FirLocalScope> get() = components.localScopes protected inline val localScopes: List<FirLocalScope> get() = components.localScopes
protected inline val noExpectedType: FirTypeRef get() = components.noExpectedType protected inline val noExpectedType: FirTypeRef get() = components.noExpectedType
@@ -104,7 +104,10 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
override val scopeSession: ScopeSession, override val scopeSession: ScopeSession,
val transformer: FirBodyResolveTransformer val transformer: FirBodyResolveTransformer
) : BodyResolveComponents { ) : BodyResolveComponents {
override val topLevelScopes: MutableList<FirScope> = mutableListOf() override val fileImportsScope: MutableList<FirScope> = mutableListOf()
@set:PrivateForInline
override var typeParametersScopes: PersistentList<FirScope> = persistentListOf()
@set:PrivateForInline @set:PrivateForInline
override var localScopes: FirLocalScopes = persistentListOf() override var localScopes: FirLocalScopes = persistentListOf()
@@ -41,8 +41,8 @@ open class FirBodyResolveTransformer(
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
components.file = file components.file = file
packageFqName = file.packageFqName packageFqName = file.packageFqName
return withScopeCleanup(components.topLevelScopes) { return withScopeCleanup(components.fileImportsScope) {
components.topLevelScopes.addImportingScopes(file, session, components.scopeSession) components.fileImportsScope.addImportingScopes(file, session, components.scopeSession)
super.transformFile(file, data) super.transformFile(file, data)
} }
} }
@@ -5,9 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirFunctionTarget
import org.jetbrains.kotlin.fir.copy
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
@@ -25,7 +23,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctiona
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.* import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolveTransformer.Companion.resolveStatus import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolveTransformer.Companion.resolveStatus
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
@@ -55,16 +52,6 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
return ((data as? ResolutionMode.WithStatus)?.status ?: declarationStatus).compose() return ((data as? ResolutionMode.WithStatus)?.status ?: declarationStatus).compose()
} }
private fun prepareTypeParameterOwnerForBodyResolve(declaration: FirMemberDeclaration) {
if (declaration.typeParameters.isNotEmpty()) {
topLevelScopes += FirMemberTypeParameterScope(declaration)
for (typeParameter in declaration.typeParameters) {
typeParameter.transformChildren(transformer, ResolutionMode.ContextIndependent)
typeParameter.replaceResolvePhase(FirResolvePhase.STATUS)
}
}
}
private fun prepareSignatureForBodyResolve(callableMember: FirCallableMemberDeclaration<*>) { private fun prepareSignatureForBodyResolve(callableMember: FirCallableMemberDeclaration<*>) {
callableMember.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent) callableMember.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent)
callableMember.transformReceiverTypeRef(transformer, ResolutionMode.ContextIndependent) callableMember.transformReceiverTypeRef(transformer, ResolutionMode.ContextIndependent)
@@ -76,27 +63,45 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
} }
} }
private inline fun <T> withTypeParametersOf(declaration: FirMemberDeclaration, crossinline l: () -> T): T {
if (declaration.typeParameters.isEmpty()) return l()
for (typeParameter in declaration.typeParameters) {
typeParameter.replaceResolvePhase(FirResolvePhase.STATUS)
typeParameter.transformChildren(transformer, ResolutionMode.ContextIndependent)
}
val before = components.typeParametersScopes
@OptIn(PrivateForInline::class)
components.typeParametersScopes = components.typeParametersScopes.add(FirMemberTypeParameterScope(declaration))
return try {
l()
} finally {
@OptIn(PrivateForInline::class)
components.typeParametersScopes = before
}
}
override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult<FirProperty> { override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult<FirProperty> {
if (property is FirSyntheticProperty) { if (property is FirSyntheticProperty) {
transformSimpleFunction(property.getter.delegate, data) transformSimpleFunction(property.getter.delegate, data)
property.replaceReturnTypeRef(property.getter.delegate.returnTypeRef) property.replaceReturnTypeRef(property.getter.delegate.returnTypeRef)
return property.compose() return property.compose()
} }
return withScopeCleanup(topLevelScopes) { return withTypeParametersOf(property) {
prepareTypeParameterOwnerForBodyResolve(property)
if (property.isLocal) { if (property.isLocal) {
prepareSignatureForBodyResolve(property) prepareSignatureForBodyResolve(property)
property.transformStatus(this, property.resolveStatus(property.status).mode()) property.transformStatus(this, property.resolveStatus(property.status).mode())
property.getter?.let { it.transformStatus(this, it.resolveStatus(it.status).mode()) } property.getter?.let { it.transformStatus(this, it.resolveStatus(it.status).mode()) }
property.setter?.let { it.transformStatus(this, it.resolveStatus(it.status).mode()) } property.setter?.let { it.transformStatus(this, it.resolveStatus(it.status).mode()) }
return@withScopeCleanup transformLocalVariable(property) return@withTypeParametersOf transformLocalVariable(property)
} }
val returnTypeRef = property.returnTypeRef val returnTypeRef = property.returnTypeRef
if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return@withScopeCleanup property.compose() if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return@withTypeParametersOf property.compose()
if (property.resolvePhase == transformerPhase) return@withScopeCleanup property.compose() if (property.resolvePhase == transformerPhase) return@withTypeParametersOf property.compose()
if (property.resolvePhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE && transformerPhase == FirResolvePhase.BODY_RESOLVE) { if (property.resolvePhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE && transformerPhase == FirResolvePhase.BODY_RESOLVE) {
property.replaceResolvePhase(transformerPhase) property.replaceResolvePhase(transformerPhase)
return@withScopeCleanup property.compose() return@withTypeParametersOf property.compose()
} }
dataFlowAnalyzer.enterProperty(property) dataFlowAnalyzer.enterProperty(property)
withFullBodyResolve { withFullBodyResolve {
@@ -282,8 +287,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
prepareLocalClassForBodyResolve(declaration) prepareLocalClassForBodyResolve(declaration)
} }
is FirCallableMemberDeclaration<*> -> { is FirCallableMemberDeclaration<*> -> {
withScopeCleanup(topLevelScopes) { withTypeParametersOf(declaration) {
prepareTypeParameterOwnerForBodyResolve(declaration)
prepareSignatureForBodyResolve(declaration) prepareSignatureForBodyResolve(declaration)
declaration.transformStatus(transformer, declaration.resolveStatus(declaration.status, klass).mode()) declaration.transformStatus(transformer, declaration.resolveStatus(declaration.status, klass).mode())
if (declaration is FirProperty) { if (declaration is FirProperty) {
@@ -304,8 +308,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult<FirStatement> { override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult<FirStatement> {
components.storeClass(regularClass) components.storeClass(regularClass)
return withScopeCleanup(topLevelScopes) { return withTypeParametersOf(regularClass) {
prepareTypeParameterOwnerForBodyResolve(regularClass)
if (regularClass.symbol.classId.isLocal) { if (regularClass.symbol.classId.isLocal) {
prepareLocalClassForBodyResolve(regularClass) prepareLocalClassForBodyResolve(regularClass)
} }
@@ -335,19 +338,17 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: ResolutionMode): CompositeTransformResult<FirStatement> { override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: ResolutionMode): CompositeTransformResult<FirStatement> {
prepareLocalClassForBodyResolve(anonymousObject) prepareLocalClassForBodyResolve(anonymousObject)
return withScopeCleanup(topLevelScopes) { val type = anonymousObject.defaultType()
val type = anonymousObject.defaultType() anonymousObject.resultType = buildResolvedTypeRef {
anonymousObject.resultType = buildResolvedTypeRef { source = anonymousObject.source
source = anonymousObject.source this.type = type
this.type = type
}
val result = withLabelAndReceiverType(null, anonymousObject, type) {
transformDeclaration(anonymousObject, data)
}
dataFlowAnalyzer.exitAnonymousObject(result.single as FirAnonymousObject)
@Suppress("UNCHECKED_CAST")
result as CompositeTransformResult<FirStatement>
} }
val result = withLabelAndReceiverType(null, anonymousObject, type) {
transformDeclaration(anonymousObject, data)
}
dataFlowAnalyzer.exitAnonymousObject(result.single as FirAnonymousObject)
@Suppress("UNCHECKED_CAST")
return result as CompositeTransformResult<FirStatement>
} }
private fun transformAnonymousFunctionWithLambdaResolution( private fun transformAnonymousFunctionWithLambdaResolution(
@@ -388,8 +389,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
return simpleFunction.compose() return simpleFunction.compose()
} }
return withScopeCleanup(topLevelScopes) { return withTypeParametersOf(simpleFunction) {
prepareTypeParameterOwnerForBodyResolve(simpleFunction)
val containingDeclaration = components.containerIfAny val containingDeclaration = components.containerIfAny
if (containingDeclaration != null && containingDeclaration !is FirClass<*>) { if (containingDeclaration != null && containingDeclaration !is FirClass<*>) {
// For class members everything should be already prepared // For class members everything should be already prepared
@@ -14,7 +14,13 @@ class FirTypeResolveScopeForBodyResolve(
private val components: BodyResolveComponents private val components: BodyResolveComponents
) : FirIterableScope() { ) : FirIterableScope() {
override val scopes: Iterable<FirScope> override val scopes: Iterable<FirScope>
get() = components.localScopes.asReversed() + components.implicitReceiverStack.receiversAsReversed().mapNotNull { get() = mutableListOf<FirScope>().apply {
(it as? ImplicitDispatchReceiverValue)?.implicitScope addAll(components.localScopes.asReversed())
} + components.topLevelScopes.asReversed() components.implicitReceiverStack.receiversAsReversed().mapNotNullTo(this) {
} (it as? ImplicitDispatchReceiverValue)?.implicitScope
}
addAll(components.typeParametersScopes.asReversed())
addAll(components.fileImportsScope.asReversed())
}
}