FIR: Leave only one composite-like scope implementation

This commit is contained in:
Denis Zharkov
2020-06-26 11:53:18 +03:00
parent 09bb755088
commit 66e53305bf
9 changed files with 55 additions and 98 deletions
@@ -19,9 +19,9 @@ import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolve.transformQualifiedAccessUsingSmartcastInfo
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
@@ -456,7 +456,7 @@ class FirTowerResolverSession internal constructor(
val scope = when (superTypeRef) {
is FirResolvedTypeRef -> superTypeRef.type.scope(session, components.scopeSession)
is FirComposedSuperTypeRef -> FirCompositeScope(
superTypeRef.superTypeRefs.mapNotNullTo(mutableListOf()) { it.type.scope(session, components.scopeSession) }
superTypeRef.superTypeRefs.mapNotNull { it.type.scope(session, components.scopeSession) }
)
else -> null
} ?: return
@@ -10,25 +10,28 @@ import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.providers.getNestedClassifierScope
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.resolve.providers.getNestedClassifierScope
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
abstract class FirAbstractTreeTransformerWithSuperTypes(
phase: FirResolvePhase,
reversedScopePriority: Boolean
phase: FirResolvePhase
) : FirAbstractTreeTransformer<Nothing?>(phase) {
protected val towerScope = FirCompositeScope(mutableListOf(), reversedPriority = reversedScopePriority)
protected val scopes = mutableListOf<FirScope>()
protected val towerScope = FirCompositeScope(scopes.asReversed())
protected inline fun <T> withScopeCleanup(crossinline l: () -> T): T {
val sizeBefore = towerScope.scopes.size
val sizeBefore = scopes.size
val result = l()
val size = towerScope.scopes.size
val size = scopes.size
assert(size >= sizeBefore)
towerScope.dropLastScopes(size - sizeBefore)
repeat(size - sizeBefore) {
scopes.removeAt(scopes.lastIndex)
}
return result
}
@@ -41,18 +44,18 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
val superTypes = lookupSuperTypes(firClass, lookupInterfaces = false, deep = true, useSiteSession = session).asReversed()
for (superType in superTypes) {
session.getNestedClassifierScope(superType.lookupTag)?.let {
towerScope.addScope(it)
scopes.add(it)
}
}
if (firClass is FirRegularClass) {
firClass.addTypeParametersScope()
val companionObject = firClass.companionObject
if (companionObject != null) {
nestedClassifierScope(companionObject)?.let(towerScope::addScope)
nestedClassifierScope(companionObject)?.let(scopes::add)
}
}
nestedClassifierScope(firClass)?.let(towerScope::addScope)
nestedClassifierScope(firClass)?.let(scopes::add)
transformElement(firClass, data)
}
@@ -60,7 +63,7 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
protected fun FirMemberDeclaration.addTypeParametersScope() {
if (typeParameters.isNotEmpty()) {
towerScope.addScope(FirMemberTypeParameterScope(this))
scopes.add(FirMemberTypeParameterScope(this))
}
}
}
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.extensions.supertypeGenerators
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.providers.getNestedClassifierScope
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
import org.jetbrains.kotlin.fir.scopes.FirIterableScope
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
@@ -62,7 +62,7 @@ fun <F : FirClass<F>> F.runSupertypeResolvePhaseForLocalClass(
val supertypeComputationSession = SupertypeComputationSession()
val supertypeResolverVisitor = FirSupertypeResolverVisitor(
session, supertypeComputationSession, scopeSession,
FirImmutableCompositeScope(ImmutableList.ofAll(currentScopeList)),
ImmutableList.ofAll(currentScopeList),
localClassesNavigationInfo
)
@@ -167,26 +167,26 @@ private class FirSupertypeResolverVisitor(
private val session: FirSession,
private val supertypeComputationSession: SupertypeComputationSession,
private val scopeSession: ScopeSession,
private val scopeForLocalClass: FirImmutableCompositeScope? = null,
private val scopeForLocalClass: ImmutableList<FirScope>? = null,
private val localClassesNavigationInfo: LocalClassesNavigationInfo? = null
) : FirDefaultVisitorVoid() {
private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators
override fun visitElement(element: FirElement) {}
private fun prepareFileScope(file: FirFile): FirImmutableCompositeScope {
private fun prepareFileScopes(file: FirFile): ScopeImmutableList {
return supertypeComputationSession.getOrPutFileScope(file) {
FirImmutableCompositeScope(ImmutableList.ofAll(createImportingScopes(file, session, scopeSession).asReversed()))
ImmutableList.ofAll(createImportingScopes(file, session, scopeSession).asReversed())
}
}
private fun prepareScopeForNestedClasses(klass: FirClass<*>): FirImmutableCompositeScope {
private fun prepareScopeForNestedClasses(klass: FirClass<*>): ScopeImmutableList {
return supertypeComputationSession.getOrPutScopeForNestedClasses(klass) {
val scope = prepareScope(klass)
val scopes = prepareScopes(klass)
resolveAllSupertypes(klass, klass.superTypeRefs)
scope.childScope(createScopesForNestedClasses(klass, session, supertypeComputationSession))
scopes.pushAll(createScopesForNestedClasses(klass, session, supertypeComputationSession))
}
}
@@ -213,33 +213,33 @@ private class FirSupertypeResolverVisitor(
else -> emptyList()
}
private fun prepareScope(classLikeDeclaration: FirClassLikeDeclaration<*>): FirImmutableCompositeScope {
private fun prepareScopes(classLikeDeclaration: FirClassLikeDeclaration<*>): ImmutableList<FirScope> {
val classId = classLikeDeclaration.symbol.classId
val result = when {
classId.isLocal -> {
// Local type aliases are not supported
if (classLikeDeclaration !is FirClass<*>) return FirImmutableCompositeScope.EMPTY
if (classLikeDeclaration !is FirClass<*>) return ImmutableList.empty()
// Local classes should be treated specially and supplied with localClassesNavigationInfo, normally
// But it seems to be too strict to add an assertion here
val navigationInfo = localClassesNavigationInfo ?: return FirImmutableCompositeScope.EMPTY
val navigationInfo = localClassesNavigationInfo ?: return ImmutableList.empty()
val parent = localClassesNavigationInfo.parentForClass[classLikeDeclaration]
when {
parent != null -> prepareScopeForNestedClasses(parent)
else -> scopeForLocalClass ?: return FirImmutableCompositeScope.EMPTY
else -> scopeForLocalClass ?: return ImmutableList.empty()
}
}
classId.isNestedClass -> {
val outerClassFir = classId.outerClassId?.let(session.firProvider::getFirClassifierByFqName) as? FirRegularClass
prepareScopeForNestedClasses(outerClassFir ?: return FirImmutableCompositeScope.EMPTY)
prepareScopeForNestedClasses(outerClassFir ?: return ImmutableList.empty())
}
else -> prepareFileScope(session.firProvider.getFirClassifierContainerFile(classId))
else -> prepareFileScopes(session.firProvider.getFirClassifierContainerFile(classId))
}
return result.childScope(classLikeDeclaration.typeParametersScope())
return result.pushIfNotNull(classLikeDeclaration.typeParametersScope())
}
private fun resolveSpecificClassLikeSupertypes(
@@ -254,10 +254,10 @@ private class FirSupertypeResolverVisitor(
}
supertypeComputationSession.startComputingSupertypes(classLikeDeclaration)
val scope = prepareScope(classLikeDeclaration)
val scopes = prepareScopes(classLikeDeclaration)
val transformer = FirSpecificTypeResolverTransformer(session)
val resolvedTypesRefs = resolveSuperTypeRefs(transformer, scope)
val resolvedTypesRefs = resolveSuperTypeRefs(transformer, FirCompositeScope(scopes))
supertypeComputationSession.storeSupertypes(classLikeDeclaration, resolvedTypesRefs)
return resolvedTypesRefs
@@ -343,8 +343,8 @@ private fun createErrorTypeRef(fir: FirElement, message: String) = buildErrorTyp
}
private class SupertypeComputationSession {
private val fileScopesMap = hashMapOf<FirFile, FirImmutableCompositeScope>()
private val scopesForNestedClassesMap = hashMapOf<FirClass<*>, FirImmutableCompositeScope>()
private val fileScopesMap = hashMapOf<FirFile, ScopeImmutableList>()
private val scopesForNestedClassesMap = hashMapOf<FirClass<*>, ScopeImmutableList>()
private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration<*>, SupertypeComputationStatus>()
val supertypesSupplier = object : SupertypeSupplier() {
@@ -366,10 +366,10 @@ private class SupertypeComputationSession {
fun getSupertypesComputationStatus(classLikeDeclaration: FirClassLikeDeclaration<*>): SupertypeComputationStatus =
supertypeStatusMap[classLikeDeclaration] ?: SupertypeComputationStatus.NotComputed
fun getOrPutFileScope(file: FirFile, scope: () -> FirImmutableCompositeScope): FirImmutableCompositeScope =
fun getOrPutFileScope(file: FirFile, scope: () -> ScopeImmutableList): ScopeImmutableList =
fileScopesMap.getOrPut(file) { scope() }
fun getOrPutScopeForNestedClasses(klass: FirClass<*>, scope: () -> FirImmutableCompositeScope): FirImmutableCompositeScope =
fun getOrPutScopeForNestedClasses(klass: FirClass<*>, scope: () -> ScopeImmutableList): ScopeImmutableList =
scopesForNestedClassesMap.getOrPut(klass) { scope() }
fun startComputingSupertypes(classLikeDeclaration: FirClassLikeDeclaration<*>) {
@@ -453,15 +453,6 @@ sealed class SupertypeComputationStatus {
}
private typealias ImmutableList<E> = javaslang.collection.List<E>
private typealias ScopeImmutableList = ImmutableList<FirScope>
private class FirImmutableCompositeScope(
override val scopes: ImmutableList<FirScope>
) : FirIterableScope() {
companion object {
val EMPTY = FirImmutableCompositeScope(ImmutableList.empty())
}
fun childScope(newScope: FirScope?) = newScope?.let { FirImmutableCompositeScope(scopes.push(newScope)) } ?: this
fun childScope(newScopes: Collection<FirScope>) = FirImmutableCompositeScope(scopes.pushAll(newScopes))
}
private fun ScopeImmutableList.pushIfNotNull(scope: FirScope?): ScopeImmutableList = if (scope == null) this else push(scope)
@@ -37,12 +37,11 @@ class FirTypeResolveTransformer(
private val scopeSession: ScopeSession,
initialScopes: List<FirScope> = emptyList()
) : FirAbstractTreeTransformerWithSuperTypes(
phase = FirResolvePhase.TYPES,
reversedScopePriority = true
phase = FirResolvePhase.TYPES
) {
init {
towerScope.addScopes(initialScopes.asReversed())
scopes.addAll(initialScopes.asReversed())
}
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(session)
@@ -50,7 +49,7 @@ class FirTypeResolveTransformer(
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
checkSessionConsistency(file)
return withScopeCleanup {
towerScope.addScopes(createImportingScopes(file, session, scopeSession))
scopes.addAll(createImportingScopes(file, session, scopeSession))
super.transformFile(file, data)
}
}
@@ -15,8 +15,8 @@ import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
import org.jetbrains.kotlin.fir.resolve.transformers.withScopeCleanup
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.impl.createCurrentScopeList
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
@@ -12,9 +12,9 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.withScopeCleanup
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
@@ -26,16 +26,14 @@ internal abstract class FirAbstractAnnotationResolveTransformer<D, S>(
) : FirDefaultTransformer<D>() {
abstract override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: D): CompositeTransformResult<FirStatement>
protected val towerScope = FirCompositeScope(mutableListOf())
protected lateinit var scope: FirScope
override fun transformFile(file: FirFile, data: D): CompositeTransformResult<FirDeclaration> {
return withScopeCleanup(towerScope.scopes) {
towerScope.addScopes(createImportingScopes(file, session, scopeSession, useCaching = false))
val state = beforeChildren(file)
file.transformDeclarations(this, data)
afterChildren(state)
transformAnnotatedDeclaration(file, data)
}
scope = FirCompositeScope(createImportingScopes(file, session, scopeSession, useCaching = false))
val state = beforeChildren(file)
file.transformDeclarations(this, data)
afterChildren(state)
return transformAnnotatedDeclaration(file, data)
}
override fun transformProperty(property: FirProperty, data: D): CompositeTransformResult<FirDeclaration> {
@@ -119,4 +117,4 @@ internal abstract class FirAbstractAnnotationResolveTransformer<D, S>(
}
protected open fun afterChildren(state: S?) {}
}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.scopes.FirIterableScope
import org.jetbrains.kotlin.fir.scopes.FirScope
class FirCompositeScope(
private val scopeList: MutableList<FirScope>,
private val reversedPriority: Boolean = false
) : FirIterableScope() {
override val scopes get() = if (reversedPriority) scopeList.asReversed() else scopeList
fun addScopes(scopes: List<FirScope>) {
scopeList += scopes
}
fun addScope(scope: FirScope) {
scopeList += scope
}
fun dropLastScopes(number: Int) {
repeat(number) {
scopeList.removeAt(scopeList.size - 1)
}
}
}
@@ -11,8 +11,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.Name
abstract class FirIterableScope : FirScope() {
protected abstract val scopes: Iterable<FirScope>
class FirCompositeScope(private val scopes: Iterable<FirScope>) : FirScope() {
override fun processClassifiersByNameWithSubstitution(
name: Name,
@@ -38,10 +38,8 @@ abstract class FirScopeProvider {
return when {
nestedClassifierScope != null && callableScope != null ->
FirReadOnlyCompositeScope(listOf(nestedClassifierScope, callableScope))
FirCompositeScope(listOf(nestedClassifierScope, callableScope))
else -> nestedClassifierScope ?: callableScope
}
}
}
private class FirReadOnlyCompositeScope(override val scopes: Iterable<FirScope>) : FirIterableScope()