[FIR] Use PersistentList instead of guava's ImmutableList in SupertypeResolution

This commit is contained in:
Dmitriy Novozhilov
2020-08-26 14:05:53 +03:00
parent 148e8fe76e
commit eaf8af919d
@@ -5,6 +5,9 @@
package org.jetbrains.kotlin.fir.resolve.transformers package org.jetbrains.kotlin.fir.resolve.transformers
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
@@ -64,7 +67,7 @@ fun <F : FirClass<F>> F.runSupertypeResolvePhaseForLocalClass(
val supertypeComputationSession = SupertypeComputationSession() val supertypeComputationSession = SupertypeComputationSession()
val supertypeResolverVisitor = FirSupertypeResolverVisitor( val supertypeResolverVisitor = FirSupertypeResolverVisitor(
session, supertypeComputationSession, scopeSession, session, supertypeComputationSession, scopeSession,
ImmutableList.ofAll(currentScopeList), currentScopeList.toPersistentList(),
localClassesNavigationInfo localClassesNavigationInfo
) )
@@ -171,25 +174,24 @@ private class FirSupertypeResolverVisitor(
private val session: FirSession, private val session: FirSession,
private val supertypeComputationSession: SupertypeComputationSession, private val supertypeComputationSession: SupertypeComputationSession,
private val scopeSession: ScopeSession, private val scopeSession: ScopeSession,
private val scopeForLocalClass: ImmutableList<FirScope>? = null, private val scopeForLocalClass: PersistentList<FirScope>? = null,
private val localClassesNavigationInfo: LocalClassesNavigationInfo? = null private val localClassesNavigationInfo: LocalClassesNavigationInfo? = null
) : FirDefaultVisitorVoid() { ) : FirDefaultVisitorVoid() {
private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators
override fun visitElement(element: FirElement) {} override fun visitElement(element: FirElement) {}
private fun prepareFileScopes(file: FirFile): ScopeImmutableList { private fun prepareFileScopes(file: FirFile): ScopePersistentList {
return supertypeComputationSession.getOrPutFileScope(file) { return supertypeComputationSession.getOrPutFileScope(file) {
ImmutableList.ofAll(createImportingScopes(file, session, scopeSession).asReversed()) createImportingScopes(file, session, scopeSession).asReversed().toPersistentList()
} }
} }
private fun prepareScopeForNestedClasses(klass: FirClass<*>): ScopeImmutableList { private fun prepareScopeForNestedClasses(klass: FirClass<*>): ScopePersistentList {
return supertypeComputationSession.getOrPutScopeForNestedClasses(klass) { return supertypeComputationSession.getOrPutScopeForNestedClasses(klass) {
val scopes = prepareScopes(klass) val scopes = prepareScopes(klass)
resolveAllSupertypes(klass, klass.superTypeRefs) resolveAllSupertypes(klass, klass.superTypeRefs)
scopes.pushAll(createScopesForNestedClasses(klass, session, scopeSession, supertypeComputationSession)) scopes.pushAll(createScopesForNestedClasses(klass, session, scopeSession, supertypeComputationSession))
} }
} }
@@ -216,28 +218,28 @@ private class FirSupertypeResolverVisitor(
else -> emptyList() else -> emptyList()
} }
private fun prepareScopes(classLikeDeclaration: FirClassLikeDeclaration<*>): ImmutableList<FirScope> { private fun prepareScopes(classLikeDeclaration: FirClassLikeDeclaration<*>): PersistentList<FirScope> {
val classId = classLikeDeclaration.symbol.classId val classId = classLikeDeclaration.symbol.classId
val result = when { val result = when {
classId.isLocal -> { classId.isLocal -> {
// Local type aliases are not supported // Local type aliases are not supported
if (classLikeDeclaration !is FirClass<*>) return ImmutableList.empty() if (classLikeDeclaration !is FirClass<*>) return persistentListOf()
// Local classes should be treated specially and supplied with localClassesNavigationInfo, normally // Local classes should be treated specially and supplied with localClassesNavigationInfo, normally
// But it seems to be too strict to add an assertion here // But it seems to be too strict to add an assertion here
val navigationInfo = localClassesNavigationInfo ?: return ImmutableList.empty() val navigationInfo = localClassesNavigationInfo ?: return persistentListOf()
val parent = localClassesNavigationInfo.parentForClass[classLikeDeclaration] val parent = localClassesNavigationInfo.parentForClass[classLikeDeclaration]
when { when {
parent != null -> prepareScopeForNestedClasses(parent) parent != null -> prepareScopeForNestedClasses(parent)
else -> scopeForLocalClass ?: return ImmutableList.empty() else -> scopeForLocalClass ?: return persistentListOf()
} }
} }
classId.isNestedClass -> { classId.isNestedClass -> {
val outerClassFir = classId.outerClassId?.let(session.firProvider::getFirClassifierByFqName) as? FirRegularClass val outerClassFir = classId.outerClassId?.let(session.firProvider::getFirClassifierByFqName) as? FirRegularClass
prepareScopeForNestedClasses(outerClassFir ?: return ImmutableList.empty()) prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf())
} }
else -> prepareFileScopes(session.firProvider.getFirClassifierContainerFile(classLikeDeclaration.symbol)) else -> prepareFileScopes(session.firProvider.getFirClassifierContainerFile(classLikeDeclaration.symbol))
} }
@@ -346,8 +348,8 @@ private fun createErrorTypeRef(fir: FirElement, message: String) = buildErrorTyp
} }
private class SupertypeComputationSession { private class SupertypeComputationSession {
private val fileScopesMap = hashMapOf<FirFile, ScopeImmutableList>() private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
private val scopesForNestedClassesMap = hashMapOf<FirClass<*>, ScopeImmutableList>() private val scopesForNestedClassesMap = hashMapOf<FirClass<*>, ScopePersistentList>()
private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration<*>, SupertypeComputationStatus>() private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration<*>, SupertypeComputationStatus>()
val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() { val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
@@ -369,10 +371,10 @@ private class SupertypeComputationSession {
fun getSupertypesComputationStatus(classLikeDeclaration: FirClassLikeDeclaration<*>): SupertypeComputationStatus = fun getSupertypesComputationStatus(classLikeDeclaration: FirClassLikeDeclaration<*>): SupertypeComputationStatus =
supertypeStatusMap[classLikeDeclaration] ?: SupertypeComputationStatus.NotComputed supertypeStatusMap[classLikeDeclaration] ?: SupertypeComputationStatus.NotComputed
fun getOrPutFileScope(file: FirFile, scope: () -> ScopeImmutableList): ScopeImmutableList = fun getOrPutFileScope(file: FirFile, scope: () -> ScopePersistentList): ScopePersistentList =
fileScopesMap.getOrPut(file) { scope() } fileScopesMap.getOrPut(file) { scope() }
fun getOrPutScopeForNestedClasses(klass: FirClass<*>, scope: () -> ScopeImmutableList): ScopeImmutableList = fun getOrPutScopeForNestedClasses(klass: FirClass<*>, scope: () -> ScopePersistentList): ScopePersistentList =
scopesForNestedClassesMap.getOrPut(klass) { scope() } scopesForNestedClassesMap.getOrPut(klass) { scope() }
fun startComputingSupertypes(classLikeDeclaration: FirClassLikeDeclaration<*>) { fun startComputingSupertypes(classLikeDeclaration: FirClassLikeDeclaration<*>) {
@@ -455,7 +457,9 @@ sealed class SupertypeComputationStatus {
class Computed(val supertypeRefs: List<FirTypeRef>) : SupertypeComputationStatus() class Computed(val supertypeRefs: List<FirTypeRef>) : SupertypeComputationStatus()
} }
private typealias ImmutableList<E> = javaslang.collection.List<E> private typealias ScopePersistentList = PersistentList<FirScope>
private typealias ScopeImmutableList = ImmutableList<FirScope>
private fun ScopeImmutableList.pushIfNotNull(scope: FirScope?): ScopeImmutableList = if (scope == null) this else push(scope) private fun <E> PersistentList<E>.push(element: E): PersistentList<E> = add(0, element)
private fun <E> PersistentList<E>.pushAll(collection: Collection<E>): PersistentList<E> = addAll(0, collection)
private fun ScopePersistentList.pushIfNotNull(scope: FirScope?): ScopePersistentList = if (scope == null) this else push(scope)