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:backend.wasm",
|
||||||
":compiler:ir.serialization.common",
|
":compiler:ir.serialization.common",
|
||||||
":compiler:ir.serialization.js",
|
":compiler:ir.serialization.js",
|
||||||
|
":compiler:ir.serialization.jvm",
|
||||||
":kotlin-util-io",
|
":kotlin-util-io",
|
||||||
":kotlin-util-klib",
|
":kotlin-util-klib",
|
||||||
":kotlin-util-klib-metadata",
|
":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.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.util.ConstantValueGenerator
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
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.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||||
|
|
||||||
@@ -57,6 +54,7 @@ object Fir2IrConverter {
|
|||||||
builtIns: IrBuiltIns
|
builtIns: IrBuiltIns
|
||||||
) {
|
) {
|
||||||
// TODO: provide StubGeneratorExtensions for correct lazy stub IR generation on JVM
|
// 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.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
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.isEffectivelyExternal
|
||||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
@@ -67,7 +68,8 @@ fun compile(
|
|||||||
|
|
||||||
// Load declarations referenced during `context` initialization
|
// Load declarations referenced during `context` initialization
|
||||||
dependencyModules.forEach {
|
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
|
val irFiles = dependencyModules.flatMap { it.files } + moduleFragment.files
|
||||||
@@ -75,8 +77,9 @@ fun compile(
|
|||||||
moduleFragment.files.clear()
|
moduleFragment.files.clear()
|
||||||
moduleFragment.files += irFiles
|
moduleFragment.files += irFiles
|
||||||
|
|
||||||
|
val irProvidersWithoutDeserializer = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable)
|
||||||
// Create stubs
|
// Create stubs
|
||||||
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns).generateUnboundSymbolsAsDependencies()
|
ExternalDependenciesGenerator(symbolTable, irProvidersWithoutDeserializer).generateUnboundSymbolsAsDependencies()
|
||||||
moduleFragment.patchDeclarationParents()
|
moduleFragment.patchDeclarationParents()
|
||||||
|
|
||||||
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
|
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ dependencies {
|
|||||||
compile(project(":compiler:ir.tree"))
|
compile(project(":compiler:ir.tree"))
|
||||||
compile(project(":compiler:ir.psi2ir"))
|
compile(project(":compiler:ir.psi2ir"))
|
||||||
compile(project(":compiler:ir.backend.common"))
|
compile(project(":compiler:ir.backend.common"))
|
||||||
|
compile(project(":compiler:ir.serialization.jvm"))
|
||||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "asm-all", "guava", rootProject = rootProject) }
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "asm-all", "guava", rootProject = rootProject) }
|
||||||
compileOnly(intellijDep()) { includeJars("trove4j", rootProject = rootProject) }
|
compileOnly(intellijDep()) { includeJars("trove4j", rootProject = rootProject) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,10 @@ class JvmBackendContext(
|
|||||||
override val irBuiltIns: IrBuiltIns,
|
override val irBuiltIns: IrBuiltIns,
|
||||||
irModuleFragment: IrModuleFragment,
|
irModuleFragment: IrModuleFragment,
|
||||||
symbolTable: SymbolTable,
|
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 {
|
) : CommonBackendContext {
|
||||||
override val transformedFunction: MutableMap<IrFunctionSymbol, IrSimpleFunctionSymbol>
|
override val transformedFunction: MutableMap<IrFunctionSymbol, IrSimpleFunctionSymbol>
|
||||||
get() = TODO("not implemented")
|
get() = TODO("not implemented")
|
||||||
@@ -86,10 +89,6 @@ class JvmBackendContext(
|
|||||||
|
|
||||||
internal val localDelegatedProperties = mutableMapOf<IrClass, List<IrLocalDelegatedPropertySymbol>>()
|
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 multifileFacadesToAdd = mutableMapOf<JvmClassName, MutableList<IrClass>>()
|
||||||
internal val multifileFacadeForPart = mutableMapOf<IrClass, JvmClassName>()
|
internal val multifileFacadeForPart = mutableMapOf<IrClass, JvmClassName>()
|
||||||
internal val multifileFacadeMemberToPartMember = mutableMapOf<IrFunction, IrFunction>()
|
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.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
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.common.phaser.PhaseConfig
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
|
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
|
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.CompilationErrorHandler
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
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.types.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -30,7 +30,7 @@ object JvmBackendFacade {
|
|||||||
errorHandler: CompilationErrorHandler,
|
errorHandler: CompilationErrorHandler,
|
||||||
phaseConfig: PhaseConfig
|
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 psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = JvmGeneratorExtensions)
|
||||||
val extensions = JvmStubGeneratorExtensions()
|
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(
|
doGenerateFilesInternal(
|
||||||
state, errorHandler, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, extensions
|
state, errorHandler, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, extensions
|
||||||
)
|
)
|
||||||
@@ -66,7 +70,7 @@ object JvmBackendFacade {
|
|||||||
extensions: JvmStubGeneratorExtensions = JvmStubGeneratorExtensions()
|
extensions: JvmStubGeneratorExtensions = JvmStubGeneratorExtensions()
|
||||||
) {
|
) {
|
||||||
val context = JvmBackendContext(
|
val context = JvmBackendContext(
|
||||||
state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment, symbolTable, phaseConfig
|
state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment, symbolTable, phaseConfig, extensions.classNameOverride
|
||||||
)
|
)
|
||||||
state.irBasedMapAsmMethod = { descriptor ->
|
state.irBasedMapAsmMethod = { descriptor ->
|
||||||
context.methodSignatureMapper.mapAsmMethod(context.referenceFunction(descriptor).owner)
|
context.methodSignatureMapper.mapAsmMethod(context.referenceFunction(descriptor).owner)
|
||||||
@@ -75,15 +79,6 @@ object JvmBackendFacade {
|
|||||||
context.typeMapper.mapType(context.referenceClass(descriptor).defaultType)
|
context.typeMapper.mapType(context.referenceClass(descriptor).defaultType)
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalDependenciesGenerator(
|
|
||||||
irModuleFragment.descriptor,
|
|
||||||
symbolTable,
|
|
||||||
irModuleFragment.irBuiltins,
|
|
||||||
extensions = extensions
|
|
||||||
).generateUnboundSymbolsAsDependencies()
|
|
||||||
|
|
||||||
context.classNameOverride = extensions.classNameOverride
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JvmLower(context).lower(irModuleFragment)
|
JvmLower(context).lower(irModuleFragment)
|
||||||
} catch (e: Throwable) {
|
} 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.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
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.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||||
@@ -39,7 +41,14 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
|
|||||||
symbolTable: SymbolTable,
|
symbolTable: SymbolTable,
|
||||||
sourceManager: PsiSourceManager
|
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 {
|
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.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.ir.backend.js.loadIr
|
import org.jetbrains.kotlin.ir.backend.js.loadIr
|
||||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
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.ir.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
@@ -37,7 +38,8 @@ fun compileWasm(
|
|||||||
|
|
||||||
// Load declarations referenced during `context` initialization
|
// Load declarations referenced during `context` initialization
|
||||||
dependencyModules.forEach {
|
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
|
val irFiles = dependencyModules.flatMap { it.files } + moduleFragment.files
|
||||||
@@ -46,7 +48,8 @@ fun compileWasm(
|
|||||||
moduleFragment.files += irFiles
|
moduleFragment.files += irFiles
|
||||||
|
|
||||||
// Create stubs
|
// Create stubs
|
||||||
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns).generateUnboundSymbolsAsDependencies()
|
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
||||||
|
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||||
moduleFragment.patchDeclarationParents()
|
moduleFragment.patchDeclarationParents()
|
||||||
|
|
||||||
wasmPhases.invokeToplevel(phaseConfig, context, moduleFragment)
|
wasmPhases.invokeToplevel(phaseConfig, context, moduleFragment)
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ typealias Psi2IrPostprocessingStep = (IrModuleFragment) -> Unit
|
|||||||
|
|
||||||
class Psi2IrTranslator(
|
class Psi2IrTranslator(
|
||||||
val languageVersionSettings: LanguageVersionSettings,
|
val languageVersionSettings: LanguageVersionSettings,
|
||||||
val configuration: Psi2IrConfiguration = Psi2IrConfiguration()
|
val configuration: Psi2IrConfiguration = Psi2IrConfiguration(),
|
||||||
|
val mangler: KotlinMangler? = null
|
||||||
) {
|
) {
|
||||||
private val postprocessingSteps = SmartList<Psi2IrPostprocessingStep>()
|
private val postprocessingSteps = SmartList<Psi2IrPostprocessingStep>()
|
||||||
|
|
||||||
@@ -51,13 +52,19 @@ class Psi2IrTranslator(
|
|||||||
stubGeneratorExtensions: StubGeneratorExtensions
|
stubGeneratorExtensions: StubGeneratorExtensions
|
||||||
): IrModuleFragment {
|
): IrModuleFragment {
|
||||||
val context = createGeneratorContext(moduleDescriptor, bindingContext, extensions = generatorExtensions)
|
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(
|
fun createGeneratorContext(
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
symbolTable: SymbolTable = SymbolTable(),
|
symbolTable: SymbolTable = SymbolTable(mangler),
|
||||||
extensions: GeneratorExtensions = GeneratorExtensions()
|
extensions: GeneratorExtensions = GeneratorExtensions()
|
||||||
): GeneratorContext =
|
): GeneratorContext =
|
||||||
GeneratorContext(configuration, moduleDescriptor, bindingContext, languageVersionSettings, symbolTable, extensions)
|
GeneratorContext(configuration, moduleDescriptor, bindingContext, languageVersionSettings, symbolTable, extensions)
|
||||||
@@ -65,16 +72,17 @@ class Psi2IrTranslator(
|
|||||||
fun generateModuleFragment(
|
fun generateModuleFragment(
|
||||||
context: GeneratorContext,
|
context: GeneratorContext,
|
||||||
ktFiles: Collection<KtFile>,
|
ktFiles: Collection<KtFile>,
|
||||||
deserializer: IrDeserializer? = null,
|
irProviders: List<IrProvider>
|
||||||
irProviders: List<IrProvider> = emptyList(),
|
|
||||||
stubGeneratorExtensions: StubGeneratorExtensions = StubGeneratorExtensions()
|
|
||||||
): IrModuleFragment {
|
): IrModuleFragment {
|
||||||
val moduleGenerator = ModuleGenerator(context)
|
val moduleGenerator = ModuleGenerator(context)
|
||||||
val irModule = moduleGenerator.generateModuleFragment(ktFiles)
|
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
|
||||||
|
|
||||||
|
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||||
irModule.patchDeclarationParents()
|
irModule.patchDeclarationParents()
|
||||||
postprocess(context, irModule)
|
postprocess(context, irModule)
|
||||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, stubGeneratorExtensions)
|
irModule.computeUniqIdForDeclarations(context.symbolTable)
|
||||||
|
|
||||||
|
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||||
return irModule
|
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.IrDeserializer
|
||||||
import org.jetbrains.kotlin.ir.util.IrProvider
|
import org.jetbrains.kotlin.ir.util.IrProvider
|
||||||
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
|
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
|
||||||
|
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
||||||
@@ -35,7 +36,12 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
|
|
||||||
private val constantValueGenerator = context.constantValueGenerator
|
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 ->
|
IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
|
||||||
irModule.files.addAll(generateFiles(ktFiles))
|
irModule.files.addAll(generateFiles(ktFiles))
|
||||||
}
|
}
|
||||||
@@ -43,12 +49,17 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
fun generateUnboundSymbolsAsDependencies(
|
fun generateUnboundSymbolsAsDependencies(
|
||||||
irModule: IrModuleFragment,
|
irModule: IrModuleFragment,
|
||||||
deserializer: IrDeserializer? = null,
|
deserializer: IrDeserializer? = null,
|
||||||
irProviders: List<IrProvider> = emptyList(),
|
|
||||||
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
|
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
|
||||||
) {
|
) {
|
||||||
ExternalDependenciesGenerator(
|
val fullIrProvidersList = generateTypicalIrProviderList(
|
||||||
irModule.descriptor, context.symbolTable, context.irBuiltIns, deserializer, irProviders, extensions
|
irModule.descriptor, context.irBuiltIns, context.symbolTable, deserializer,
|
||||||
).generateUnboundSymbolsAsDependencies()
|
extensions
|
||||||
|
)
|
||||||
|
ExternalDependenciesGenerator(context.symbolTable, fullIrProvidersList).generateUnboundSymbolsAsDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateUnboundSymbolsAsDependencies(irProviders: List<IrProvider>) {
|
||||||
|
ExternalDependenciesGenerator(context.symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateFiles(ktFiles: Collection<KtFile>): List<IrFile> {
|
private fun generateFiles(ktFiles: Collection<KtFile>): List<IrFile> {
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ abstract class WrappedDeclarationDescriptor<T : IrDeclaration>(annotations: Anno
|
|||||||
fun bind(declaration: T) {
|
fun bind(declaration: T) {
|
||||||
owner = declaration
|
owner = declaration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isBound(): Boolean = _owner != null
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class WrappedCallableDescriptor<T : IrDeclaration>(
|
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.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.lazy.*
|
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.IrErrorExpressionImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
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.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.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||||
@@ -36,9 +42,8 @@ class DeclarationStubGenerator(
|
|||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
val symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
private val irProviders: List<IrProvider> = emptyList(),
|
|
||||||
val extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
|
val extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
|
||||||
) {
|
) : IrProvider {
|
||||||
private val lazyTable = symbolTable.lazyWrapper
|
private val lazyTable = symbolTable.lazyWrapper
|
||||||
|
|
||||||
internal var unboundSymbolGeneration: Boolean
|
internal var unboundSymbolGeneration: Boolean
|
||||||
@@ -47,6 +52,12 @@ class DeclarationStubGenerator(
|
|||||||
lazyTable.stubGenerator = if (value) this else null
|
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 =
|
val typeTranslator =
|
||||||
TypeTranslator(lazyTable, languageVersionSettings, moduleDescriptor.builtIns, LazyScopedTypeParametersResolver(lazyTable), true)
|
TypeTranslator(lazyTable, languageVersionSettings, moduleDescriptor.builtIns, LazyScopedTypeParametersResolver(lazyTable), true)
|
||||||
@@ -57,13 +68,14 @@ class DeclarationStubGenerator(
|
|||||||
init {
|
init {
|
||||||
typeTranslator.constantValueGenerator = constantValueGenerator
|
typeTranslator.constantValueGenerator = constantValueGenerator
|
||||||
constantValueGenerator.typeTranslator = typeTranslator
|
constantValueGenerator.typeTranslator = typeTranslator
|
||||||
irProviders.filterIsInstance<LazyIrProvider>().forEach { it.declarationStubGenerator = this }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
|
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? = when {
|
||||||
for (irProvider in irProviders)
|
// Special case: generating field for an already generated property.
|
||||||
irProvider.getDeclaration(symbol)?.let { return it }
|
symbol is IrFieldSymbol && (symbol.descriptor as? WrappedPropertyDescriptor)?.isBound() == true ->
|
||||||
return null
|
generateStubBySymbol(symbol)
|
||||||
|
symbol.descriptor is WrappedDeclarationDescriptor<*> -> null
|
||||||
|
else -> generateStubBySymbol(symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateOrGetEmptyExternalPackageFragmentStub(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment {
|
fun generateOrGetEmptyExternalPackageFragmentStub(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment {
|
||||||
@@ -101,10 +113,21 @@ class DeclarationStubGenerator(
|
|||||||
generateFunctionStub(descriptor)
|
generateFunctionStub(descriptor)
|
||||||
is PropertyDescriptor ->
|
is PropertyDescriptor ->
|
||||||
generatePropertyStub(descriptor)
|
generatePropertyStub(descriptor)
|
||||||
|
is TypeAliasDescriptor ->
|
||||||
|
generateTypeAliasStub(descriptor)
|
||||||
else ->
|
else ->
|
||||||
throw AssertionError("Unexpected member descriptor: $descriptor")
|
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 =
|
private fun computeOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin =
|
||||||
extensions.computeExternalDeclarationOrigin(descriptor) ?: IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
|
extensions.computeExternalDeclarationOrigin(descriptor) ?: IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
|
||||||
|
|
||||||
@@ -122,8 +145,7 @@ class DeclarationStubGenerator(
|
|||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original,
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original,
|
||||||
isDelegated = @Suppress("DEPRECATION") descriptor.isDelegated
|
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)
|
else computeOrigin(descriptor)
|
||||||
|
|
||||||
return symbolTable.declareField(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original, descriptor.type.toIrType()) {
|
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) {
|
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) {
|
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 =
|
val origin =
|
||||||
@@ -166,8 +191,7 @@ class DeclarationStubGenerator(
|
|||||||
origin,
|
origin,
|
||||||
descriptor.original
|
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(
|
return symbolTable.declareConstructor(
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original
|
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)
|
val origin = computeOrigin(descriptor)
|
||||||
return symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, 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)
|
val origin = computeOrigin(descriptor)
|
||||||
return symbolTable.declareEnumEntry(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, 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)
|
val origin = computeOrigin(descriptor)
|
||||||
return symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, 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
|
package org.jetbrains.kotlin.ir.util
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
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.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import kotlin.math.min
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
|
class ExternalDependenciesGenerator(val symbolTable: SymbolTable, private val irProviders: List<IrProvider>) {
|
||||||
fun generateUnboundSymbolsAsDependencies() {
|
fun generateUnboundSymbolsAsDependencies() {
|
||||||
stubGenerator.unboundSymbolGeneration = true
|
// There should be at most one DeclarationStubGenerator (none in closed world?)
|
||||||
do {
|
irProviders.singleOrNull { it is DeclarationStubGenerator }?.let {
|
||||||
fun <T> haveNotStabilized(prev: ArrayList<T>, cur: Set<T>) =
|
(it as DeclarationStubGenerator).unboundSymbolGeneration = true
|
||||||
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() }
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
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
|
private val IrProperty.symbolName: String
|
||||||
get() {
|
get() {
|
||||||
val extensionReceiver: String = getter!!.extensionReceiverParameter?.extensionReceiverNamePart ?: ""
|
val extensionReceiver: String = getter?.extensionReceiverParameter?.extensionReceiverNamePart ?: ""
|
||||||
|
|
||||||
val containingDeclarationPart = parent.fqNameForIrSerialization.let {
|
val containingDeclarationPart = parent.fqNameForIrSerialization.let {
|
||||||
if (it.isRoot) "" else "$it."
|
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.ExpectDeclarationRemover
|
||||||
import org.jetbrains.kotlin.ir.util.IrDeserializer
|
import org.jetbrains.kotlin.ir.util.IrDeserializer
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
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.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
@@ -201,7 +202,8 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
|
|||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
deserializer: IrDeserializer? = null
|
deserializer: IrDeserializer? = null
|
||||||
): IrModuleFragment {
|
): 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)) {
|
for (extension in IrGenerationExtension.getInstances(project)) {
|
||||||
psi2Ir.addPostprocessingStep { module ->
|
psi2Ir.addPostprocessingStep { module ->
|
||||||
@@ -223,13 +225,17 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
|
|||||||
psi2Ir.generateModuleFragment(
|
psi2Ir.generateModuleFragment(
|
||||||
this,
|
this,
|
||||||
files,
|
files,
|
||||||
deserializer
|
irProviders
|
||||||
)
|
)
|
||||||
return moduleFragment
|
return moduleFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deserializer: IrDeserializer? = null) =
|
fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deserializer: IrDeserializer? = null): IrModuleFragment {
|
||||||
Psi2IrTranslator(languageVersionSettings, configuration).generateModuleFragment(this, files, deserializer)
|
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) {}
|
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.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.generateJsCode
|
import org.jetbrains.kotlin.ir.backend.js.generateJsCode
|
||||||
import org.jetbrains.kotlin.ir.backend.js.generateModuleFragment
|
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.backend.js.utils.NameTables
|
||||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
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.js.config.JSConfigurationKeys
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzer
|
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzer
|
||||||
@@ -58,7 +60,7 @@ class JsCoreScriptingCompiler(
|
|||||||
val module = analysisResult.moduleDescriptor
|
val module = analysisResult.moduleDescriptor
|
||||||
val bindingContext = analysisResult.bindingContext
|
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 psi2irContext = psi2ir.createGeneratorContext(module, bindingContext, symbolTable)
|
||||||
|
|
||||||
val irModuleFragment = psi2irContext.generateModuleFragment(listOf(snippetKtFile))
|
val irModuleFragment = psi2irContext.generateModuleFragment(listOf(snippetKtFile))
|
||||||
@@ -74,9 +76,12 @@ class JsCoreScriptingCompiler(
|
|||||||
)
|
)
|
||||||
|
|
||||||
ExternalDependenciesGenerator(
|
ExternalDependenciesGenerator(
|
||||||
irModuleFragment.descriptor,
|
|
||||||
psi2irContext.symbolTable,
|
psi2irContext.symbolTable,
|
||||||
psi2irContext.irBuiltIns
|
generateTypicalIrProviderList(
|
||||||
|
irModuleFragment.descriptor,
|
||||||
|
psi2irContext.irBuiltIns,
|
||||||
|
psi2irContext.symbolTable
|
||||||
|
)
|
||||||
).generateUnboundSymbolsAsDependencies()
|
).generateUnboundSymbolsAsDependencies()
|
||||||
|
|
||||||
environment.configuration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
environment.configuration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
|
||||||
|
|||||||
+3
-2
@@ -50,8 +50,9 @@ class JsScriptDependencyCompiler(
|
|||||||
|
|
||||||
val moduleFragment = IrModuleFragmentImpl(moduleDescriptor, irBuiltIns)
|
val moduleFragment = IrModuleFragmentImpl(moduleDescriptor, irBuiltIns)
|
||||||
val irDependencies = dependencies.map { jsLinker.deserializeFullModule(it) }
|
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()
|
moduleFragment.patchDeclarationParents()
|
||||||
|
|
||||||
val backendContext = JsIrBackendContext(
|
val backendContext = JsIrBackendContext(
|
||||||
@@ -64,7 +65,7 @@ class JsScriptDependencyCompiler(
|
|||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
ExternalDependenciesGenerator(moduleDescriptor, symbolTable, irBuiltIns, jsLinker).generateUnboundSymbolsAsDependencies()
|
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||||
moduleFragment.patchDeclarationParents()
|
moduleFragment.patchDeclarationParents()
|
||||||
|
|
||||||
moduleFragment.files += irDependencies.flatMap { it.files }
|
moduleFragment.files += irDependencies.flatMap { it.files }
|
||||||
|
|||||||
Reference in New Issue
Block a user