[FIR2IR] Add Fir2IrCommonMemberStorage, get rid of merge in Fir2Ir storages

Extract DescriptorSignatureComposerStub and WrappedDescriptorSignatureComposer to separate classes
This commit is contained in:
Ivan Kochurkin
2023-01-30 16:33:18 +01:00
committed by Space Team
parent c89770c450
commit 6bdd0edd6c
15 changed files with 160 additions and 181 deletions
@@ -17,11 +17,9 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.util.SymbolTable
data class FirResult(
val platformOutput: ModuleCompilerAnalyzedOutput,
@@ -41,7 +39,7 @@ fun FirResult.convertToIrAndActualize(
): Fir2IrResult {
val result: Fir2IrResult
val (signatureComposer, symbolTable) = Fir2IrConverter.createSignatureComposerAndSymbolTable(
val commonMemberStorage = Fir2IrCommonMemberStorage(
generateSignatures = linkViaSignatures,
signatureComposerCreator = { JvmIdSignatureDescriptor(JvmDescriptorMangler(null)) },
manglerCreator = { FirJvmKotlinMangler() }
@@ -52,18 +50,14 @@ fun FirResult.convertToIrAndActualize(
fir2IrExtensions,
irGeneratorExtensions,
linkViaSignatures = linkViaSignatures,
signatureComposer = signatureComposer,
symbolTable = symbolTable,
dependentComponents = emptyList(),
commonMemberStorage = commonMemberStorage,
irBuiltIns = null
)
result = platformOutput.convertToIr(
fir2IrExtensions,
irGeneratorExtensions,
linkViaSignatures = linkViaSignatures,
signatureComposer = signatureComposer,
symbolTable = symbolTable,
dependentComponents = listOf(commonIrOutput.components),
commonMemberStorage = commonMemberStorage,
irBuiltIns = commonIrOutput.components.irBuiltIns
)
IrActualizer.actualize(
@@ -75,9 +69,7 @@ fun FirResult.convertToIrAndActualize(
fir2IrExtensions,
irGeneratorExtensions,
linkViaSignatures = linkViaSignatures,
signatureComposer = signatureComposer,
symbolTable = symbolTable,
dependentComponents = emptyList(),
commonMemberStorage = commonMemberStorage,
irBuiltIns = null
)
}
@@ -89,9 +81,7 @@ private fun ModuleCompilerAnalyzedOutput.convertToIr(
fir2IrExtensions: Fir2IrExtensions,
irGeneratorExtensions: Collection<IrGenerationExtension>,
linkViaSignatures: Boolean,
signatureComposer: FirBasedSignatureComposer,
symbolTable: SymbolTable,
dependentComponents: List<Fir2IrComponents>,
commonMemberStorage: Fir2IrCommonMemberStorage,
irBuiltIns: IrBuiltInsOverFir?
): Fir2IrResult {
return Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded(
@@ -102,9 +92,7 @@ private fun ModuleCompilerAnalyzedOutput.convertToIr(
irGeneratorExtensions,
kotlinBuiltIns = DefaultBuiltIns.Instance, // TODO: consider passing externally
generateSignatures = linkViaSignatures,
signatureComposer = signatureComposer,
symbolTable = symbolTable,
dependentComponents = dependentComponents,
commonMemberStorage = commonMemberStorage,
initializedIrBuiltIns = irBuiltIns
)
}
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2023 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.backend
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.IdSignatureComposer
class DescriptorSignatureComposerStub : IdSignatureComposer {
override fun composeSignature(descriptor: DeclarationDescriptor): IdSignature? {
return null
}
override fun composeEnumEntrySignature(descriptor: ClassDescriptor): IdSignature? {
return null
}
override fun composeFieldSignature(descriptor: PropertyDescriptor): IdSignature? {
return null
}
override fun composeAnonInitSignature(descriptor: ClassDescriptor): IdSignature? {
return null
}
override fun withFileSignature(fileSignature: IdSignature.FileSignature, body: () -> Unit) {
body()
}
}
@@ -40,11 +40,11 @@ import org.jetbrains.kotlin.utils.addToStdlib.runUnless
class Fir2IrClassifierStorage(
private val components: Fir2IrComponents,
private val dependentStorages: List<Fir2IrClassifierStorage>
commonMemberStorage: Fir2IrCommonMemberStorage
) : Fir2IrComponents by components {
private val firProvider = session.firProvider
private val classCache: MutableMap<FirRegularClass, IrClass> = merge { it.classCache }
private val classCache: MutableMap<FirRegularClass, IrClass> = commonMemberStorage.classCache
private val localClassesCreatedOnTheFly: MutableMap<FirClass, IrClass> = mutableMapOf()
@@ -52,29 +52,19 @@ class Fir2IrClassifierStorage(
private val typeAliasCache: MutableMap<FirTypeAlias, IrTypeAlias> = mutableMapOf()
private val typeParameterCache: MutableMap<FirTypeParameter, IrTypeParameter> = merge { it.typeParameterCache }
private val typeParameterCache: MutableMap<FirTypeParameter, IrTypeParameter> = commonMemberStorage.typeParameterCache
private val typeParameterCacheForSetter: MutableMap<FirTypeParameter, IrTypeParameter> = mutableMapOf()
private val enumEntryCache: MutableMap<FirEnumEntry, IrEnumEntry> = merge { it.enumEntryCache }
private val enumEntryCache: MutableMap<FirEnumEntry, IrEnumEntry> = commonMemberStorage.enumEntryCache
private val fieldsForContextReceivers: MutableMap<IrClass, List<IrField>> = mutableMapOf()
private val localStorage: Fir2IrLocalClassStorage = Fir2IrLocalClassStorage(
// Merge is necessary here to be able to serialize local classes from common code in expression codegen
dependentStorages.map { it.localStorage }.fold(mutableMapOf()) { result, storage ->
result.putAll(storage.localClassCache)
result
}
// Using existing cache is necessary here to be able to serialize local classes from common code in expression codegen
commonMemberStorage.localClassCache
)
private fun <K, V> merge(mapFunc: (Fir2IrClassifierStorage) -> MutableMap<K, V>): MutableMap<K, V> {
return dependentStorages.map { mapFunc(it) }.fold(mutableMapOf()) { result, map ->
result.putAll(map)
result
}
}
private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
with(typeConverter) { toIrType(typeContext) }
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2023 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.backend
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
import org.jetbrains.kotlin.fir.signaturer.FirMangler
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.util.IdSignatureComposer
import org.jetbrains.kotlin.ir.util.SymbolTable
import java.util.concurrent.ConcurrentHashMap
class Fir2IrCommonMemberStorage(
generateSignatures: Boolean,
signatureComposerCreator: (() -> IdSignatureComposer)?,
manglerCreator: () -> FirMangler
) {
val signatureComposer: FirBasedSignatureComposer
val symbolTable: SymbolTable
init {
val signaturer = if (generateSignatures && signatureComposerCreator != null)
signatureComposerCreator()
else
DescriptorSignatureComposerStub()
signatureComposer = FirBasedSignatureComposer(manglerCreator())
symbolTable = SymbolTable(
signaturer = WrappedDescriptorSignatureComposer(signaturer, signatureComposer),
irFactory = IrFactoryImpl
)
}
val classCache: MutableMap<FirRegularClass, IrClass> = mutableMapOf()
val typeParameterCache: MutableMap<FirTypeParameter, IrTypeParameter> = mutableMapOf()
val enumEntryCache: MutableMap<FirEnumEntry, IrEnumEntry> = mutableMapOf()
val localClassCache: MutableMap<FirClass, IrClass> = mutableMapOf()
val functionCache: ConcurrentHashMap<FirFunction, IrSimpleFunction> = ConcurrentHashMap()
val propertyCache: ConcurrentHashMap<FirProperty, IrProperty> = ConcurrentHashMap()
val fakeOverridesInClass: MutableMap<IrClass, MutableMap<FirCallableDeclaration, FirCallableDeclaration>> = mutableMapOf()
}
@@ -15,12 +15,8 @@ import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.generators.*
import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
@@ -30,18 +26,16 @@ import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.generatedMembers
import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
import org.jetbrains.kotlin.fir.signaturer.FirMangler
import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver
import org.jetbrains.kotlin.ir.PsiIrFileEntry
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode
import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.psi.KtFile
@@ -430,23 +424,6 @@ class Fir2IrConverter(
}
}
fun createSignatureComposerAndSymbolTable(
generateSignatures: Boolean,
signatureComposerCreator: (() -> IdSignatureComposer)?,
manglerCreator: () -> FirMangler,
): Pair<FirBasedSignatureComposer, SymbolTable> {
val signaturer = if (generateSignatures && signatureComposerCreator != null)
signatureComposerCreator()
else
DescriptorSignatureComposerStub()
val signatureComposer = FirBasedSignatureComposer(manglerCreator())
val symbolTable = SymbolTable(
signaturer = WrappedDescriptorSignatureComposer(signaturer, signatureComposer),
irFactory = IrFactoryImpl
)
return Pair(signatureComposer, symbolTable)
}
fun createModuleFragmentWithSignaturesIfNeeded(
session: FirSession,
scopeSession: ScopeSession,
@@ -460,23 +437,27 @@ class Fir2IrConverter(
irGenerationExtensions: Collection<IrGenerationExtension>,
generateSignatures: Boolean,
kotlinBuiltIns: KotlinBuiltIns,
signatureComposer: FirBasedSignatureComposer,
symbolTable: SymbolTable,
dependentComponents: List<Fir2IrComponents>,
commonMemberStorage: Fir2IrCommonMemberStorage,
initializedIrBuiltIns: IrBuiltInsOverFir?
): Fir2IrResult {
val moduleDescriptor = FirModuleDescriptor(session, kotlinBuiltIns)
val components = Fir2IrComponentsStorage(
session, scopeSession, symbolTable, irFactory, signatureComposer, fir2IrExtensions, generateSignatures
session,
scopeSession,
commonMemberStorage.symbolTable,
irFactory,
commonMemberStorage.signatureComposer,
fir2IrExtensions,
generateSignatures
)
val converter = Fir2IrConverter(moduleDescriptor, components)
components.converter = converter
val classifierStorage = Fir2IrClassifierStorage(components, dependentComponents.map { it.classifierStorage })
val classifierStorage = Fir2IrClassifierStorage(components, commonMemberStorage)
components.classifierStorage = classifierStorage
components.delegatedMemberGenerator = DelegatedMemberGenerator(components)
val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor, dependentComponents.map { it.declarationStorage })
val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor, commonMemberStorage)
components.declarationStorage = declarationStorage
components.visibilityConverter = visibilityConverter
val typeConverter = Fir2IrTypeConverter(components)
@@ -499,7 +480,7 @@ class Fir2IrConverter(
val irProvider = FirIrProvider(components)
components.irProviders = listOf(irProvider)
fir2IrExtensions.registerDeclarations(symbolTable)
fir2IrExtensions.registerDeclarations(commonMemberStorage.symbolTable)
val irModuleFragment = IrModuleFragmentImpl(moduleDescriptor, irBuiltIns)
@@ -516,37 +497,4 @@ class Fir2IrConverter(
return Fir2IrResult(irModuleFragment, components, moduleDescriptor)
}
}
}
private class WrappedDescriptorSignatureComposer(
private val delegate: IdSignatureComposer,
private val firComposer: Fir2IrSignatureComposer
) : IdSignatureComposer by delegate {
override fun withFileSignature(fileSignature: IdSignature.FileSignature, body: () -> Unit) {
firComposer.withFileSignature(fileSignature) {
delegate.withFileSignature(fileSignature, body)
}
}
}
private class DescriptorSignatureComposerStub : IdSignatureComposer {
override fun composeSignature(descriptor: DeclarationDescriptor): IdSignature? {
return null
}
override fun composeEnumEntrySignature(descriptor: ClassDescriptor): IdSignature? {
return null
}
override fun composeFieldSignature(descriptor: PropertyDescriptor): IdSignature? {
return null
}
override fun composeAnonInitSignature(descriptor: ClassDescriptor): IdSignature? {
return null
}
override fun withFileSignature(fileSignature: IdSignature.FileSignature, body: () -> Unit) {
body()
}
}
}
@@ -65,7 +65,7 @@ import java.util.concurrent.ConcurrentHashMap
class Fir2IrDeclarationStorage(
private val components: Fir2IrComponents,
private val moduleDescriptor: FirModuleDescriptor,
dependentStorages: List<Fir2IrDeclarationStorage>
commonMemberStorage: Fir2IrCommonMemberStorage
) : Fir2IrComponents by components {
private val firProvider = session.firProvider
@@ -78,13 +78,13 @@ class Fir2IrDeclarationStorage(
private val scriptCache: ConcurrentHashMap<FirScript, IrScript> = ConcurrentHashMap()
private val functionCache: ConcurrentHashMap<FirFunction, IrSimpleFunction> = merge(dependentStorages) { it.functionCache }
private val functionCache: ConcurrentHashMap<FirFunction, IrSimpleFunction> = commonMemberStorage.functionCache
private val constructorCache: ConcurrentHashMap<FirConstructor, IrConstructor> = ConcurrentHashMap()
private val initializerCache: ConcurrentHashMap<FirAnonymousInitializer, IrAnonymousInitializer> = ConcurrentHashMap()
private val propertyCache: ConcurrentHashMap<FirProperty, IrProperty> = merge(dependentStorages) { it.propertyCache }
private val propertyCache: ConcurrentHashMap<FirProperty, IrProperty> = commonMemberStorage.propertyCache
// interface A { /* $1 */ fun foo() }
// interface B : A {
@@ -101,13 +101,11 @@ class Fir2IrDeclarationStorage(
// so remember that in class B there's a fake override $2 for real $1.
//
// Thus, we may obtain it by fakeOverridesInClass[ir(B)][fir(A::foo)] -> fir(B::foo)
//
// Note: reusing is necessary here, because sometimes (see testFakeOverridesInPlatformModule)
// we have to match fake override in platform class with overridden fake overrides in common class
private val fakeOverridesInClass: MutableMap<IrClass, MutableMap<FirCallableDeclaration, FirCallableDeclaration>> =
dependentStorages.map { it.fakeOverridesInClass }.fold(mutableMapOf()) { result, map ->
// Note: merge is necessary here, because sometimes (see testFakeOverridesInPlatformModule)
// we have to match fake override in platform class with overridden fake overrides in common class
result.putAll(map)
result
}
commonMemberStorage.fakeOverridesInClass
// For pure fields (from Java) only
private val fieldToPropertyCache: ConcurrentHashMap<Pair<FirField, IrDeclarationParent>, IrProperty> = ConcurrentHashMap()
@@ -122,16 +120,6 @@ class Fir2IrDeclarationStorage(
private val localStorage: Fir2IrLocalCallableStorage by threadLocal { Fir2IrLocalCallableStorage() }
private fun <K, V> merge(
dependentStorages: List<Fir2IrDeclarationStorage>,
mapFunc: (Fir2IrDeclarationStorage) -> ConcurrentHashMap<K, V>
): ConcurrentHashMap<K, V> {
return dependentStorages.map { mapFunc(it) }.fold(ConcurrentHashMap()) { result, map ->
result.putAll(map)
result
}
}
private fun areCompatible(firFunction: FirFunction, irFunction: IrFunction): Boolean {
if (firFunction is FirSimpleFunction && irFunction is IrSimpleFunction) {
if (irFunction.name != firFunction.name) return false
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.ir.declarations.IrClass
class Fir2IrLocalClassStorage(internal val localClassCache: MutableMap<FirClass, IrClass> = mutableMapOf()) {
class Fir2IrLocalClassStorage(private val localClassCache: MutableMap<FirClass, IrClass> = mutableMapOf()) {
operator fun get(localClass: FirClass): IrClass? {
return localClassCache[localClass]
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2023 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.backend
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.IdSignatureComposer
class WrappedDescriptorSignatureComposer(
private val delegate: IdSignatureComposer,
private val firComposer: Fir2IrSignatureComposer
) : IdSignatureComposer by delegate {
override fun withFileSignature(fileSignature: IdSignature.FileSignature, body: () -> Unit) {
firComposer.withFileSignature(fileSignature) {
delegate.withFileSignature(fileSignature, body)
}
}
}