IR: reorganize IrProvider handling
Make DeclarationStubGenerator a subclass of IrProvider, anticipating deserialization of IR structures for JVM_IR backend.
This commit is contained in:
@@ -214,6 +214,7 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:backend.wasm",
|
||||
":compiler:ir.serialization.common",
|
||||
":compiler:ir.serialization.js",
|
||||
":compiler:ir.serialization.jvm",
|
||||
":kotlin-util-io",
|
||||
":kotlin-util-klib",
|
||||
":kotlin-util-klib-metadata",
|
||||
|
||||
@@ -14,10 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.util.ConstantValueGenerator
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
@@ -57,6 +54,7 @@ object Fir2IrConverter {
|
||||
builtIns: IrBuiltIns
|
||||
) {
|
||||
// TODO: provide StubGeneratorExtensions for correct lazy stub IR generation on JVM
|
||||
ExternalDependenciesGenerator(irModule.descriptor, symbolTable, builtIns).generateUnboundSymbolsAsDependencies()
|
||||
ExternalDependenciesGenerator(symbolTable, generateTypicalIrProviderList(irModule.descriptor, builtIns, symbolTable))
|
||||
.generateUnboundSymbolsAsDependencies()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
@@ -67,7 +68,8 @@ fun compile(
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
dependencyModules.forEach {
|
||||
ExternalDependenciesGenerator(it.descriptor, symbolTable, irBuiltIns, deserializer).generateUnboundSymbolsAsDependencies()
|
||||
val irProviders = generateTypicalIrProviderList(it.descriptor, irBuiltIns, symbolTable, deserializer)
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
}
|
||||
|
||||
val irFiles = dependencyModules.flatMap { it.files } + moduleFragment.files
|
||||
@@ -75,8 +77,9 @@ fun compile(
|
||||
moduleFragment.files.clear()
|
||||
moduleFragment.files += irFiles
|
||||
|
||||
val irProvidersWithoutDeserializer = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable)
|
||||
// Create stubs
|
||||
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns).generateUnboundSymbolsAsDependencies()
|
||||
ExternalDependenciesGenerator(symbolTable, irProvidersWithoutDeserializer).generateUnboundSymbolsAsDependencies()
|
||||
moduleFragment.patchDeclarationParents()
|
||||
|
||||
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
|
||||
|
||||
@@ -9,6 +9,7 @@ dependencies {
|
||||
compile(project(":compiler:ir.tree"))
|
||||
compile(project(":compiler:ir.psi2ir"))
|
||||
compile(project(":compiler:ir.backend.common"))
|
||||
compile(project(":compiler:ir.serialization.jvm"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "asm-all", "guava", rootProject = rootProject) }
|
||||
compileOnly(intellijDep()) { includeJars("trove4j", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
@@ -47,7 +47,10 @@ class JvmBackendContext(
|
||||
override val irBuiltIns: IrBuiltIns,
|
||||
irModuleFragment: IrModuleFragment,
|
||||
symbolTable: SymbolTable,
|
||||
val phaseConfig: PhaseConfig
|
||||
val phaseConfig: PhaseConfig,
|
||||
// If the JVM fqname of a class differs from what is implied by its parent, e.g. if it's a file class
|
||||
// annotated with @JvmPackageName, the correct name is recorded here.
|
||||
internal val classNameOverride: MutableMap<IrClass, JvmClassName>
|
||||
) : CommonBackendContext {
|
||||
override val transformedFunction: MutableMap<IrFunctionSymbol, IrSimpleFunctionSymbol>
|
||||
get() = TODO("not implemented")
|
||||
@@ -86,10 +89,6 @@ class JvmBackendContext(
|
||||
|
||||
internal val localDelegatedProperties = mutableMapOf<IrClass, List<IrLocalDelegatedPropertySymbol>>()
|
||||
|
||||
// If the JVM fqname of a class differs from what is implied by its parent, e.g. if it's a file class
|
||||
// annotated with @JvmPackageName, the correct name is recorded here.
|
||||
internal lateinit var classNameOverride: MutableMap<IrClass, JvmClassName>
|
||||
|
||||
internal val multifileFacadesToAdd = mutableMapOf<JvmClassName, MutableList<IrClass>>()
|
||||
internal val multifileFacadeForPart = mutableMapOf<IrClass, JvmClassName>()
|
||||
internal val multifileFacadeMemberToPartMember = mutableMapOf<IrFunction, IrFunction>()
|
||||
|
||||
@@ -7,16 +7,16 @@ package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
|
||||
import org.jetbrains.kotlin.backend.jvm.serialization.JvmMangler
|
||||
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -30,7 +30,7 @@ object JvmBackendFacade {
|
||||
errorHandler: CompilationErrorHandler,
|
||||
phaseConfig: PhaseConfig
|
||||
) {
|
||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings)
|
||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, mangler = JvmMangler)
|
||||
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = JvmGeneratorExtensions)
|
||||
val extensions = JvmStubGeneratorExtensions()
|
||||
|
||||
@@ -50,7 +50,11 @@ object JvmBackendFacade {
|
||||
}
|
||||
}
|
||||
|
||||
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, stubGeneratorExtensions = extensions)
|
||||
val irProviders = generateTypicalIrProviderList(
|
||||
psi2irContext.moduleDescriptor, psi2irContext.irBuiltIns, psi2irContext.symbolTable,
|
||||
extensions = extensions
|
||||
)
|
||||
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, irProviders = irProviders)
|
||||
doGenerateFilesInternal(
|
||||
state, errorHandler, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, extensions
|
||||
)
|
||||
@@ -66,7 +70,7 @@ object JvmBackendFacade {
|
||||
extensions: JvmStubGeneratorExtensions = JvmStubGeneratorExtensions()
|
||||
) {
|
||||
val context = JvmBackendContext(
|
||||
state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment, symbolTable, phaseConfig
|
||||
state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment, symbolTable, phaseConfig, extensions.classNameOverride
|
||||
)
|
||||
state.irBasedMapAsmMethod = { descriptor ->
|
||||
context.methodSignatureMapper.mapAsmMethod(context.referenceFunction(descriptor).owner)
|
||||
@@ -75,15 +79,6 @@ object JvmBackendFacade {
|
||||
context.typeMapper.mapType(context.referenceClass(descriptor).defaultType)
|
||||
}
|
||||
|
||||
ExternalDependenciesGenerator(
|
||||
irModuleFragment.descriptor,
|
||||
symbolTable,
|
||||
irModuleFragment.irBuiltins,
|
||||
extensions = extensions
|
||||
).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
context.classNameOverride = extensions.classNameOverride
|
||||
|
||||
try {
|
||||
JvmLower(context).lower(irModuleFragment)
|
||||
} catch (e: Throwable) {
|
||||
|
||||
+10
-1
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
@@ -39,7 +41,14 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
|
||||
symbolTable: SymbolTable,
|
||||
sourceManager: PsiSourceManager
|
||||
) {
|
||||
JvmBackendFacade.doGenerateFilesInternal(state, errorHandler, irModuleFragment, symbolTable, sourceManager, phaseConfig)
|
||||
val stubGeneratorExtensions = JvmStubGeneratorExtensions()
|
||||
val irProviders = generateTypicalIrProviderList(
|
||||
irModuleFragment.descriptor, irModuleFragment.irBuiltins, symbolTable, extensions = stubGeneratorExtensions
|
||||
)
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
JvmBackendFacade.doGenerateFilesInternal(
|
||||
state, errorHandler, irModuleFragment, symbolTable, sourceManager, phaseConfig, stubGeneratorExtensions
|
||||
)
|
||||
}
|
||||
|
||||
override fun createPackageCodegen(state: GenerationState, files: Collection<KtFile>, fqName: FqName): PackageCodegen {
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.wasm.codegen.IrModuleToWasm
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.loadIr
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||
@@ -37,7 +38,8 @@ fun compileWasm(
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
dependencyModules.forEach {
|
||||
ExternalDependenciesGenerator(it.descriptor, symbolTable, irBuiltIns, deserializer).generateUnboundSymbolsAsDependencies()
|
||||
val irProviders = generateTypicalIrProviderList(it.descriptor, irBuiltIns, symbolTable, deserializer)
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
}
|
||||
|
||||
val irFiles = dependencyModules.flatMap { it.files } + moduleFragment.files
|
||||
@@ -46,10 +48,11 @@ fun compileWasm(
|
||||
moduleFragment.files += irFiles
|
||||
|
||||
// Create stubs
|
||||
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns).generateUnboundSymbolsAsDependencies()
|
||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
moduleFragment.patchDeclarationParents()
|
||||
|
||||
wasmPhases.invokeToplevel(phaseConfig, context, moduleFragment)
|
||||
|
||||
return IrModuleToWasm(context).generateModule(moduleFragment)
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,8 @@ typealias Psi2IrPostprocessingStep = (IrModuleFragment) -> Unit
|
||||
|
||||
class Psi2IrTranslator(
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val configuration: Psi2IrConfiguration = Psi2IrConfiguration()
|
||||
val configuration: Psi2IrConfiguration = Psi2IrConfiguration(),
|
||||
val mangler: KotlinMangler? = null
|
||||
) {
|
||||
private val postprocessingSteps = SmartList<Psi2IrPostprocessingStep>()
|
||||
|
||||
@@ -51,13 +52,19 @@ class Psi2IrTranslator(
|
||||
stubGeneratorExtensions: StubGeneratorExtensions
|
||||
): IrModuleFragment {
|
||||
val context = createGeneratorContext(moduleDescriptor, bindingContext, extensions = generatorExtensions)
|
||||
return generateModuleFragment(context, ktFiles, stubGeneratorExtensions = stubGeneratorExtensions)
|
||||
return generateModuleFragment(
|
||||
context, ktFiles,
|
||||
irProviders = generateTypicalIrProviderList(
|
||||
moduleDescriptor, context.irBuiltIns, context.symbolTable,
|
||||
extensions = stubGeneratorExtensions
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun createGeneratorContext(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
bindingContext: BindingContext,
|
||||
symbolTable: SymbolTable = SymbolTable(),
|
||||
symbolTable: SymbolTable = SymbolTable(mangler),
|
||||
extensions: GeneratorExtensions = GeneratorExtensions()
|
||||
): GeneratorContext =
|
||||
GeneratorContext(configuration, moduleDescriptor, bindingContext, languageVersionSettings, symbolTable, extensions)
|
||||
@@ -65,16 +72,17 @@ class Psi2IrTranslator(
|
||||
fun generateModuleFragment(
|
||||
context: GeneratorContext,
|
||||
ktFiles: Collection<KtFile>,
|
||||
deserializer: IrDeserializer? = null,
|
||||
irProviders: List<IrProvider> = emptyList(),
|
||||
stubGeneratorExtensions: StubGeneratorExtensions = StubGeneratorExtensions()
|
||||
irProviders: List<IrProvider>
|
||||
): IrModuleFragment {
|
||||
val moduleGenerator = ModuleGenerator(context)
|
||||
val irModule = moduleGenerator.generateModuleFragment(ktFiles)
|
||||
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
|
||||
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||
irModule.patchDeclarationParents()
|
||||
postprocess(context, irModule)
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, stubGeneratorExtensions)
|
||||
irModule.computeUniqIdForDeclarations(context.symbolTable)
|
||||
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||
return irModule
|
||||
}
|
||||
|
||||
|
||||
+16
-5
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.IrDeserializer
|
||||
import org.jetbrains.kotlin.ir.util.IrProvider
|
||||
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
|
||||
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
||||
@@ -35,7 +36,12 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
|
||||
private val constantValueGenerator = context.constantValueGenerator
|
||||
|
||||
fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment =
|
||||
fun generateModuleFragment(ktFiles: Collection<KtFile>, deserializer: IrDeserializer, extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY): IrModuleFragment =
|
||||
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
|
||||
generateUnboundSymbolsAsDependencies(irModule, deserializer, extensions)
|
||||
}
|
||||
|
||||
fun generateModuleFragmentWithoutDependencies(ktFiles: Collection<KtFile>): IrModuleFragment =
|
||||
IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
|
||||
irModule.files.addAll(generateFiles(ktFiles))
|
||||
}
|
||||
@@ -43,12 +49,17 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
fun generateUnboundSymbolsAsDependencies(
|
||||
irModule: IrModuleFragment,
|
||||
deserializer: IrDeserializer? = null,
|
||||
irProviders: List<IrProvider> = emptyList(),
|
||||
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
|
||||
) {
|
||||
ExternalDependenciesGenerator(
|
||||
irModule.descriptor, context.symbolTable, context.irBuiltIns, deserializer, irProviders, extensions
|
||||
).generateUnboundSymbolsAsDependencies()
|
||||
val fullIrProvidersList = generateTypicalIrProviderList(
|
||||
irModule.descriptor, context.irBuiltIns, context.symbolTable, deserializer,
|
||||
extensions
|
||||
)
|
||||
ExternalDependenciesGenerator(context.symbolTable, fullIrProvidersList).generateUnboundSymbolsAsDependencies()
|
||||
}
|
||||
|
||||
fun generateUnboundSymbolsAsDependencies(irProviders: List<IrProvider>) {
|
||||
ExternalDependenciesGenerator(context.symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
}
|
||||
|
||||
private fun generateFiles(ktFiles: Collection<KtFile>): List<IrFile> {
|
||||
|
||||
@@ -101,6 +101,8 @@ abstract class WrappedDeclarationDescriptor<T : IrDeclaration>(annotations: Anno
|
||||
fun bind(declaration: T) {
|
||||
owner = declaration
|
||||
}
|
||||
|
||||
fun isBound(): Boolean = _owner != null
|
||||
}
|
||||
|
||||
abstract class WrappedCallableDescriptor<T : IrDeclaration>(
|
||||
|
||||
@@ -22,9 +22,15 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.WrappedDeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.WrappedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
@@ -36,9 +42,8 @@ class DeclarationStubGenerator(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
val symbolTable: SymbolTable,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
private val irProviders: List<IrProvider> = emptyList(),
|
||||
val extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
|
||||
) {
|
||||
) : IrProvider {
|
||||
private val lazyTable = symbolTable.lazyWrapper
|
||||
|
||||
internal var unboundSymbolGeneration: Boolean
|
||||
@@ -47,6 +52,12 @@ class DeclarationStubGenerator(
|
||||
lazyTable.stubGenerator = if (value) this else null
|
||||
}
|
||||
|
||||
private lateinit var irProviders_: List<IrProvider>
|
||||
|
||||
fun setIrProviders(value: List<IrProvider>) {
|
||||
irProviders_ = value
|
||||
irProviders_.filterIsInstance<LazyIrProvider>().forEach { it.declarationStubGenerator = this }
|
||||
}
|
||||
|
||||
val typeTranslator =
|
||||
TypeTranslator(lazyTable, languageVersionSettings, moduleDescriptor.builtIns, LazyScopedTypeParametersResolver(lazyTable), true)
|
||||
@@ -57,14 +68,15 @@ class DeclarationStubGenerator(
|
||||
init {
|
||||
typeTranslator.constantValueGenerator = constantValueGenerator
|
||||
constantValueGenerator.typeTranslator = typeTranslator
|
||||
irProviders.filterIsInstance<LazyIrProvider>().forEach { it.declarationStubGenerator = this }
|
||||
}
|
||||
|
||||
private fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
|
||||
for (irProvider in irProviders)
|
||||
irProvider.getDeclaration(symbol)?.let { return it }
|
||||
return null
|
||||
}
|
||||
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? = when {
|
||||
// Special case: generating field for an already generated property.
|
||||
symbol is IrFieldSymbol && (symbol.descriptor as? WrappedPropertyDescriptor)?.isBound() == true ->
|
||||
generateStubBySymbol(symbol)
|
||||
symbol.descriptor is WrappedDeclarationDescriptor<*> -> null
|
||||
else -> generateStubBySymbol(symbol)
|
||||
}
|
||||
|
||||
fun generateOrGetEmptyExternalPackageFragmentStub(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment {
|
||||
val referenced = symbolTable.referenceExternalPackageFragment(descriptor)
|
||||
@@ -101,10 +113,21 @@ class DeclarationStubGenerator(
|
||||
generateFunctionStub(descriptor)
|
||||
is PropertyDescriptor ->
|
||||
generatePropertyStub(descriptor)
|
||||
is TypeAliasDescriptor ->
|
||||
generateTypeAliasStub(descriptor)
|
||||
else ->
|
||||
throw AssertionError("Unexpected member descriptor: $descriptor")
|
||||
}
|
||||
|
||||
private fun generateStubBySymbol(symbol: IrSymbol): IrDeclaration = when (symbol) {
|
||||
is IrFieldSymbol ->
|
||||
generateFieldStub(symbol.descriptor)
|
||||
is IrTypeParameterSymbol ->
|
||||
generateOrGetTypeParameterStub(symbol.descriptor)
|
||||
else ->
|
||||
generateMemberStub(symbol.descriptor)
|
||||
}
|
||||
|
||||
private fun computeOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin =
|
||||
extensions.computeExternalDeclarationOrigin(descriptor) ?: IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
|
||||
|
||||
@@ -122,8 +145,7 @@ class DeclarationStubGenerator(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original,
|
||||
isDelegated = @Suppress("DEPRECATION") descriptor.isDelegated
|
||||
) {
|
||||
getDeclaration(referenced) as? IrProperty
|
||||
?: IrLazyProperty(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator, bindingContext)
|
||||
IrLazyProperty(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator, bindingContext)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,8 +161,7 @@ class DeclarationStubGenerator(
|
||||
else computeOrigin(descriptor)
|
||||
|
||||
return symbolTable.declareField(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original, descriptor.type.toIrType()) {
|
||||
getDeclaration(referenced) as? IrField
|
||||
?: IrLazyField(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
IrLazyField(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,10 +172,14 @@ class DeclarationStubGenerator(
|
||||
}
|
||||
|
||||
if (createPropertyIfNeeded && descriptor is PropertyGetterDescriptor) {
|
||||
return generatePropertyStub(descriptor.correspondingProperty).getter!!
|
||||
val propertySymbol = symbolTable.referenceProperty(descriptor.correspondingProperty)
|
||||
val property = irProviders_.getDeclaration(propertySymbol) as IrProperty
|
||||
return property.getter!!
|
||||
}
|
||||
if (createPropertyIfNeeded && descriptor is PropertySetterDescriptor) {
|
||||
return generatePropertyStub(descriptor.correspondingProperty).setter!!
|
||||
val propertySymbol = symbolTable.referenceProperty(descriptor.correspondingProperty)
|
||||
val property = irProviders_.getDeclaration(propertySymbol) as IrProperty
|
||||
return property.setter!!
|
||||
}
|
||||
|
||||
val origin =
|
||||
@@ -166,8 +191,7 @@ class DeclarationStubGenerator(
|
||||
origin,
|
||||
descriptor.original
|
||||
) {
|
||||
getDeclaration(referenced) as? IrSimpleFunction
|
||||
?: IrLazyFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
IrLazyFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +205,7 @@ class DeclarationStubGenerator(
|
||||
return symbolTable.declareConstructor(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original
|
||||
) {
|
||||
getDeclaration(referenced) as? IrConstructor
|
||||
?: IrLazyConstructor(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
IrLazyConstructor(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,8 +235,7 @@ class DeclarationStubGenerator(
|
||||
}
|
||||
val origin = computeOrigin(descriptor)
|
||||
return symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
|
||||
getDeclaration(referenceClass) as? IrClass
|
||||
?: IrLazyClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
IrLazyClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,8 +246,7 @@ class DeclarationStubGenerator(
|
||||
}
|
||||
val origin = computeOrigin(descriptor)
|
||||
return symbolTable.declareEnumEntry(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
|
||||
getDeclaration(referenced) as? IrEnumEntry
|
||||
?: IrLazyEnumEntryImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
IrLazyEnumEntryImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,8 +257,7 @@ class DeclarationStubGenerator(
|
||||
}
|
||||
val origin = computeOrigin(descriptor)
|
||||
return symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
|
||||
getDeclaration(referenced) as? IrTypeParameter
|
||||
?: IrLazyTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
IrLazyTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+58
-60
@@ -17,70 +17,68 @@
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import kotlin.math.min
|
||||
|
||||
class ExternalDependenciesGenerator(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
val symbolTable: SymbolTable,
|
||||
val irBuiltIns: IrBuiltIns,
|
||||
private val deserializer: IrDeserializer? = null,
|
||||
irProviders: List<IrProvider> = emptyList(),
|
||||
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
|
||||
) {
|
||||
private val stubGenerator = DeclarationStubGenerator(
|
||||
moduleDescriptor, symbolTable, irBuiltIns.languageVersionSettings, listOfNotNull(deserializer) + irProviders, extensions
|
||||
)
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
class ExternalDependenciesGenerator(val symbolTable: SymbolTable, private val irProviders: List<IrProvider>) {
|
||||
fun generateUnboundSymbolsAsDependencies() {
|
||||
stubGenerator.unboundSymbolGeneration = true
|
||||
do {
|
||||
fun <T> haveNotStabilized(prev: ArrayList<T>, cur: Set<T>) =
|
||||
cur.isNotEmpty() && (prev.size != cur.size || prev.any { !cur.contains(it) })
|
||||
|
||||
val unboundClasses = ArrayList(symbolTable.unboundClasses)
|
||||
val unboundConstructors = ArrayList(symbolTable.unboundConstructors)
|
||||
val unboundEnumEntries = ArrayList(symbolTable.unboundEnumEntries)
|
||||
val unboundFields = ArrayList(symbolTable.unboundFields)
|
||||
val unboundSimpleFunctions = ArrayList(symbolTable.unboundSimpleFunctions)
|
||||
val unboundProperties = ArrayList(symbolTable.unboundProperties)
|
||||
val unboundTypeParameters = ArrayList(symbolTable.unboundTypeParameters)
|
||||
val unboundTypeAliases = ArrayList(symbolTable.unboundTypeAliases)
|
||||
unboundClasses.forEach { stubGenerator.generateClassStub(it.descriptor) }
|
||||
unboundConstructors.forEach { stubGenerator.generateConstructorStub(it.descriptor) }
|
||||
unboundEnumEntries.forEach { stubGenerator.generateEnumEntryStub(it.descriptor) }
|
||||
unboundFields.forEach { stubGenerator.generateFieldStub(it.descriptor) }
|
||||
unboundSimpleFunctions.forEach { stubGenerator.generateFunctionStub(it.descriptor) }
|
||||
unboundProperties.forEach { stubGenerator.generatePropertyStub(it.descriptor) }
|
||||
unboundTypeParameters.forEach { stubGenerator.generateOrGetTypeParameterStub(it.descriptor) }
|
||||
unboundTypeAliases.forEach { stubGenerator.generateTypeAliasStub(it.descriptor) }
|
||||
} while (haveNotStabilized(unboundClasses, symbolTable.unboundClasses)
|
||||
|| haveNotStabilized(unboundConstructors, symbolTable.unboundConstructors)
|
||||
|| haveNotStabilized(unboundEnumEntries, symbolTable.unboundEnumEntries)
|
||||
|| haveNotStabilized(unboundFields, symbolTable.unboundFields)
|
||||
|| haveNotStabilized(unboundSimpleFunctions, symbolTable.unboundSimpleFunctions)
|
||||
|| haveNotStabilized(unboundProperties, symbolTable.unboundProperties)
|
||||
|| haveNotStabilized(unboundTypeParameters, symbolTable.unboundTypeParameters)
|
||||
|| haveNotStabilized(unboundTypeAliases, symbolTable.unboundTypeAliases)
|
||||
)
|
||||
|
||||
deserializer?.declareForwardDeclarations()
|
||||
|
||||
assertEmpty(symbolTable.unboundClasses, "classes")
|
||||
assertEmpty(symbolTable.unboundConstructors, "constructors")
|
||||
assertEmpty(symbolTable.unboundEnumEntries, "enum entries")
|
||||
assertEmpty(symbolTable.unboundFields, "fields")
|
||||
assertEmpty(symbolTable.unboundSimpleFunctions, "simple functions")
|
||||
assertEmpty(symbolTable.unboundProperties, "properties")
|
||||
assertEmpty(symbolTable.unboundTypeParameters, "type parameters")
|
||||
assertEmpty(symbolTable.unboundTypeAliases, "type aliases")
|
||||
}
|
||||
|
||||
private fun assertEmpty(s: Set<IrSymbol>, marker: String) {
|
||||
assert(s.isEmpty()) {
|
||||
"$marker: ${s.size} unbound:\n" +
|
||||
s.toList().subList(0, min(10, s.size)).joinToString(separator = "\n") { it.descriptor.toString() }
|
||||
// There should be at most one DeclarationStubGenerator (none in closed world?)
|
||||
irProviders.singleOrNull { it is DeclarationStubGenerator }?.let {
|
||||
(it as DeclarationStubGenerator).unboundSymbolGeneration = true
|
||||
}
|
||||
/*
|
||||
Deserializing a reference may lead to new unbound references, so we loop until none are left.
|
||||
*/
|
||||
lateinit var unbound: List<IrSymbol>
|
||||
do {
|
||||
unbound = symbolTable.allUnbound
|
||||
|
||||
for (symbol in unbound) {
|
||||
// Symbol could get bound as a side effect of deserializing other symbols.
|
||||
if (!symbol.isBound) {
|
||||
irProviders.getDeclaration(symbol)
|
||||
}
|
||||
assert(symbol.isBound) { "$symbol unbound even after deserialization attempt" }
|
||||
}
|
||||
} while (unbound.isNotEmpty())
|
||||
|
||||
irProviders.forEach { (it as? IrDeserializer)?.declareForwardDeclarations() }
|
||||
}
|
||||
}
|
||||
|
||||
private val SymbolTable.allUnbound: List<IrSymbol>
|
||||
get() {
|
||||
val r = mutableListOf<IrSymbol>()
|
||||
r.addAll(unboundClasses)
|
||||
r.addAll(unboundConstructors)
|
||||
r.addAll(unboundEnumEntries)
|
||||
r.addAll(unboundFields)
|
||||
r.addAll(unboundSimpleFunctions)
|
||||
r.addAll(unboundProperties)
|
||||
r.addAll(unboundTypeParameters)
|
||||
r.addAll(unboundTypeAliases)
|
||||
return r
|
||||
}
|
||||
|
||||
fun List<IrProvider>.getDeclaration(symbol: IrSymbol): IrDeclaration =
|
||||
firstNotNullResult { provider ->
|
||||
provider.getDeclaration(symbol)
|
||||
} ?: error("Could not find declaration for unbound symbol $symbol")
|
||||
|
||||
// In most cases, IrProviders list consist of an optional deserializer and a DeclarationStubGenerator.
|
||||
fun generateTypicalIrProviderList(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
irBuiltins: IrBuiltIns,
|
||||
symbolTable: SymbolTable,
|
||||
deserializer: IrDeserializer? = null,
|
||||
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
|
||||
): List<IrProvider> {
|
||||
val stubGenerator = DeclarationStubGenerator(
|
||||
moduleDescriptor, symbolTable, irBuiltins.languageVersionSettings, extensions
|
||||
)
|
||||
return listOfNotNull(deserializer, stubGenerator).also {
|
||||
stubGenerator.setIrProviders(it)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -257,7 +257,7 @@ abstract class KotlinManglerImpl : KotlinMangler {
|
||||
|
||||
private val IrProperty.symbolName: String
|
||||
get() {
|
||||
val extensionReceiver: String = getter!!.extensionReceiverParameter?.extensionReceiverNamePart ?: ""
|
||||
val extensionReceiver: String = getter?.extensionReceiverParameter?.extensionReceiverNamePart ?: ""
|
||||
|
||||
val containingDeclarationPart = parent.fqNameForIrSerialization.let {
|
||||
if (it.isRoot) "" else "$it."
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.util.ExpectDeclarationRemover
|
||||
import org.jetbrains.kotlin.ir.util.IrDeserializer
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
@@ -201,7 +202,8 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
|
||||
files: List<KtFile>,
|
||||
deserializer: IrDeserializer? = null
|
||||
): IrModuleFragment {
|
||||
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration)
|
||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
||||
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, mangler = JsMangler)
|
||||
|
||||
for (extension in IrGenerationExtension.getInstances(project)) {
|
||||
psi2Ir.addPostprocessingStep { module ->
|
||||
@@ -223,13 +225,17 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
|
||||
psi2Ir.generateModuleFragment(
|
||||
this,
|
||||
files,
|
||||
deserializer
|
||||
irProviders
|
||||
)
|
||||
return moduleFragment
|
||||
}
|
||||
|
||||
fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deserializer: IrDeserializer? = null) =
|
||||
Psi2IrTranslator(languageVersionSettings, configuration).generateModuleFragment(this, files, deserializer)
|
||||
fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deserializer: IrDeserializer? = null): IrModuleFragment {
|
||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
||||
return Psi2IrTranslator(
|
||||
languageVersionSettings, configuration, mangler = JsMangler
|
||||
).generateModuleFragment(this, files, irProviders)
|
||||
}
|
||||
|
||||
|
||||
private fun createBuiltIns(storageManager: StorageManager) = object : KotlinBuiltIns(storageManager) {}
|
||||
|
||||
+8
-3
@@ -18,9 +18,11 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.generateJsCode
|
||||
import org.jetbrains.kotlin.ir.backend.js.generateModuleFragment
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsMangler
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.NameTables
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzer
|
||||
@@ -58,7 +60,7 @@ class JsCoreScriptingCompiler(
|
||||
val module = analysisResult.moduleDescriptor
|
||||
val bindingContext = analysisResult.bindingContext
|
||||
|
||||
val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings)
|
||||
val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, mangler = JsMangler)
|
||||
val psi2irContext = psi2ir.createGeneratorContext(module, bindingContext, symbolTable)
|
||||
|
||||
val irModuleFragment = psi2irContext.generateModuleFragment(listOf(snippetKtFile))
|
||||
@@ -74,9 +76,12 @@ class JsCoreScriptingCompiler(
|
||||
)
|
||||
|
||||
ExternalDependenciesGenerator(
|
||||
irModuleFragment.descriptor,
|
||||
psi2irContext.symbolTable,
|
||||
psi2irContext.irBuiltIns
|
||||
generateTypicalIrProviderList(
|
||||
irModuleFragment.descriptor,
|
||||
psi2irContext.irBuiltIns,
|
||||
psi2irContext.symbolTable
|
||||
)
|
||||
).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
environment.configuration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
||||
|
||||
+3
-2
@@ -50,8 +50,9 @@ class JsScriptDependencyCompiler(
|
||||
|
||||
val moduleFragment = IrModuleFragmentImpl(moduleDescriptor, irBuiltIns)
|
||||
val irDependencies = dependencies.map { jsLinker.deserializeFullModule(it) }
|
||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer = jsLinker)
|
||||
|
||||
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns, jsLinker).generateUnboundSymbolsAsDependencies()
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
moduleFragment.patchDeclarationParents()
|
||||
|
||||
val backendContext = JsIrBackendContext(
|
||||
@@ -64,7 +65,7 @@ class JsScriptDependencyCompiler(
|
||||
true
|
||||
)
|
||||
|
||||
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns, jsLinker).generateUnboundSymbolsAsDependencies()
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
moduleFragment.patchDeclarationParents()
|
||||
|
||||
moduleFragment.files += irDependencies.flatMap { it.files }
|
||||
|
||||
Reference in New Issue
Block a user