[FIR] Use PersistentList instead of guava's ImmutableList in SupertypeResolution
This commit is contained in:
+22
-18
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user