From eb154dce1e138b201fdbeda8aa155268ca2aae20 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 17 Mar 2020 19:06:14 +0300 Subject: [PATCH] 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 --- .../fir/resolve/BodyResolveComponents.kt | 3 +- .../fir/resolve/calls/FirTowerResolver.kt | 8 +- .../FirAbstractBodyResolveTransformer.kt | 7 +- .../body/resolve/FirBodyResolveTransformer.kt | 4 +- .../FirDeclarationsResolveTransformer.kt | 76 +++++++++---------- .../impl/FirTypeResolveScopeForBodyResolve.kt | 14 +++- 6 files changed, 63 insertions(+), 49 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt index 7679aaf9376..d2e6326c436 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt @@ -31,7 +31,8 @@ interface SessionHolder { interface BodyResolveComponents : SessionHolder { val returnTypeCalculator: ReturnTypeCalculator val implicitReceiverStack: MutableImplicitReceiverStack - val topLevelScopes: List + val fileImportsScope: List + val typeParametersScopes: List val localScopes: FirLocalScopes val localContextForAnonymousFunctions: LocalContextForAnonymousFunctions val noExpectedType: FirTypeRef diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt index b3558a03ffc..bcf9bbbfcdd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt @@ -34,7 +34,11 @@ class FirTowerResolver( resolutionStageRunner: ResolutionStageRunner, ) { private val localScopes: List get() = components.localScopes.asReversed() - private val topLevelScopes: List get() = components.topLevelScopes.asReversed() + private val topLevelScopes: List + 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 collector = CandidateCollector(components, resolutionStageRunner) @@ -496,4 +500,4 @@ class FirTowerResolver( collector.newDataSet() manager.reset() } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index c66895af762..9c4a5d24f18 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve +import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* @@ -71,7 +72,6 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb } } - protected inline val topLevelScopes: MutableList get() = components.topLevelScopes protected inline val localScopes: List get() = components.localScopes protected inline val noExpectedType: FirTypeRef get() = components.noExpectedType @@ -104,7 +104,10 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val scopeSession: ScopeSession, val transformer: FirBodyResolveTransformer ) : BodyResolveComponents { - override val topLevelScopes: MutableList = mutableListOf() + override val fileImportsScope: MutableList = mutableListOf() + + @set:PrivateForInline + override var typeParametersScopes: PersistentList = persistentListOf() @set:PrivateForInline override var localScopes: FirLocalScopes = persistentListOf() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index a956b391b38..092d158d676 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -41,8 +41,8 @@ open class FirBodyResolveTransformer( @OptIn(PrivateForInline::class) components.file = file packageFqName = file.packageFqName - return withScopeCleanup(components.topLevelScopes) { - components.topLevelScopes.addImportingScopes(file, session, components.scopeSession) + return withScopeCleanup(components.fileImportsScope) { + components.fileImportsScope.addImportingScopes(file, session, components.scopeSession) super.transformFile(file, data) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 3f756a02943..ab037d6e6e9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -5,9 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve -import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.FirFunctionTarget -import org.jetbrains.kotlin.fir.copy +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter 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.transformers.* 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.FirMemberTypeParameterScope import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol @@ -55,16 +52,6 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) 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<*>) { callableMember.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent) callableMember.transformReceiverTypeRef(transformer, ResolutionMode.ContextIndependent) @@ -76,27 +63,45 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } } + private inline fun 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 { if (property is FirSyntheticProperty) { transformSimpleFunction(property.getter.delegate, data) property.replaceReturnTypeRef(property.getter.delegate.returnTypeRef) return property.compose() } - return withScopeCleanup(topLevelScopes) { - prepareTypeParameterOwnerForBodyResolve(property) + return withTypeParametersOf(property) { if (property.isLocal) { prepareSignatureForBodyResolve(property) property.transformStatus(this, property.resolveStatus(property.status).mode()) property.getter?.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 - if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return@withScopeCleanup property.compose() - if (property.resolvePhase == transformerPhase) return@withScopeCleanup property.compose() + if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return@withTypeParametersOf property.compose() + if (property.resolvePhase == transformerPhase) return@withTypeParametersOf property.compose() if (property.resolvePhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE && transformerPhase == FirResolvePhase.BODY_RESOLVE) { property.replaceResolvePhase(transformerPhase) - return@withScopeCleanup property.compose() + return@withTypeParametersOf property.compose() } dataFlowAnalyzer.enterProperty(property) withFullBodyResolve { @@ -282,8 +287,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) prepareLocalClassForBodyResolve(declaration) } is FirCallableMemberDeclaration<*> -> { - withScopeCleanup(topLevelScopes) { - prepareTypeParameterOwnerForBodyResolve(declaration) + withTypeParametersOf(declaration) { prepareSignatureForBodyResolve(declaration) declaration.transformStatus(transformer, declaration.resolveStatus(declaration.status, klass).mode()) if (declaration is FirProperty) { @@ -304,8 +308,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult { components.storeClass(regularClass) - return withScopeCleanup(topLevelScopes) { - prepareTypeParameterOwnerForBodyResolve(regularClass) + return withTypeParametersOf(regularClass) { if (regularClass.symbol.classId.isLocal) { prepareLocalClassForBodyResolve(regularClass) } @@ -335,19 +338,17 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: ResolutionMode): CompositeTransformResult { prepareLocalClassForBodyResolve(anonymousObject) - return withScopeCleanup(topLevelScopes) { - val type = anonymousObject.defaultType() - anonymousObject.resultType = buildResolvedTypeRef { - source = anonymousObject.source - this.type = type - } - val result = withLabelAndReceiverType(null, anonymousObject, type) { - transformDeclaration(anonymousObject, data) - } - dataFlowAnalyzer.exitAnonymousObject(result.single as FirAnonymousObject) - @Suppress("UNCHECKED_CAST") - result as CompositeTransformResult + val type = anonymousObject.defaultType() + anonymousObject.resultType = buildResolvedTypeRef { + source = anonymousObject.source + this.type = type } + val result = withLabelAndReceiverType(null, anonymousObject, type) { + transformDeclaration(anonymousObject, data) + } + dataFlowAnalyzer.exitAnonymousObject(result.single as FirAnonymousObject) + @Suppress("UNCHECKED_CAST") + return result as CompositeTransformResult } private fun transformAnonymousFunctionWithLambdaResolution( @@ -388,8 +389,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) return simpleFunction.compose() } - return withScopeCleanup(topLevelScopes) { - prepareTypeParameterOwnerForBodyResolve(simpleFunction) + return withTypeParametersOf(simpleFunction) { val containingDeclaration = components.containerIfAny if (containingDeclaration != null && containingDeclaration !is FirClass<*>) { // For class members everything should be already prepared diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeResolveScopeForBodyResolve.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeResolveScopeForBodyResolve.kt index 037a6a03b81..945141b1ccf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeResolveScopeForBodyResolve.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeResolveScopeForBodyResolve.kt @@ -14,7 +14,13 @@ class FirTypeResolveScopeForBodyResolve( private val components: BodyResolveComponents ) : FirIterableScope() { override val scopes: Iterable - get() = components.localScopes.asReversed() + components.implicitReceiverStack.receiversAsReversed().mapNotNull { - (it as? ImplicitDispatchReceiverValue)?.implicitScope - } + components.topLevelScopes.asReversed() -} \ No newline at end of file + get() = mutableListOf().apply { + addAll(components.localScopes.asReversed()) + components.implicitReceiverStack.receiversAsReversed().mapNotNullTo(this) { + (it as? ImplicitDispatchReceiverValue)?.implicitScope + } + + addAll(components.typeParametersScopes.asReversed()) + addAll(components.fileImportsScope.asReversed()) + } +}