[KLIB] Create an abstract class for module deserializer
- Introduce Ir-based Functional interface factory - Switch from LazyIr to pure - Use kotlin library to access raw bytes - Link dirty files against IC cache and dependencies instead of LazyIr - Move `DescriptorByIdSignatureFinder` from K/N to common - Support inline-bodies only MODE
This commit is contained in:
+4
-1
@@ -10,8 +10,11 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
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.util.IrExtensionGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -26,7 +29,7 @@ class IrPluginContext(
|
|||||||
val symbols: BuiltinSymbolsBase = BuiltinSymbolsBase(irBuiltIns.builtIns, symbolTable)
|
val symbols: BuiltinSymbolsBase = BuiltinSymbolsBase(irBuiltIns.builtIns, symbolTable)
|
||||||
) : IrGeneratorContext()
|
) : IrGeneratorContext()
|
||||||
|
|
||||||
interface IrGenerationExtension {
|
interface IrGenerationExtension : IrExtensionGenerator {
|
||||||
companion object :
|
companion object :
|
||||||
ProjectExtensionDescriptor<IrGenerationExtension>("org.jetbrains.kotlin.irGenerationExtension", IrGenerationExtension::class.java)
|
ProjectExtensionDescriptor<IrGenerationExtension>("org.jetbrains.kotlin.irGenerationExtension", IrGenerationExtension::class.java)
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.NameTables
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.declarations.StageController
|
import org.jetbrains.kotlin.ir.declarations.StageController
|
||||||
import org.jetbrains.kotlin.ir.declarations.stageController
|
import org.jetbrains.kotlin.ir.declarations.stageController
|
||||||
|
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||||
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.generateTypicalIrProviderList
|
||||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
@@ -58,11 +59,8 @@ fun compile(
|
|||||||
val context = JsIrBackendContext(moduleDescriptor, irBuiltIns, symbolTable, moduleFragment, exportedDeclarations, configuration)
|
val context = JsIrBackendContext(moduleDescriptor, irBuiltIns, symbolTable, moduleFragment, exportedDeclarations, configuration)
|
||||||
|
|
||||||
// Load declarations referenced during `context` initialization
|
// Load declarations referenced during `context` initialization
|
||||||
dependencyModules.forEach {
|
val irProviders = listOf(deserializer)
|
||||||
val irProviders = generateTypicalIrProviderList(it.descriptor, irBuiltIns, symbolTable, deserializer)
|
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings).generateUnboundSymbolsAsDependencies()
|
||||||
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings)
|
|
||||||
.generateUnboundSymbolsAsDependencies()
|
|
||||||
}
|
|
||||||
|
|
||||||
val allModules = when (mainModule) {
|
val allModules = when (mainModule) {
|
||||||
is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment)
|
is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment)
|
||||||
@@ -71,16 +69,12 @@ fun compile(
|
|||||||
|
|
||||||
val irFiles = allModules.flatMap { it.files }
|
val irFiles = allModules.flatMap { it.files }
|
||||||
|
|
||||||
|
deserializer.postProcess()
|
||||||
|
|
||||||
moduleFragment.files.clear()
|
moduleFragment.files.clear()
|
||||||
moduleFragment.files += irFiles
|
moduleFragment.files += irFiles
|
||||||
|
|
||||||
val irProvidersWithoutDeserializer = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable)
|
symbolTable.lazyWrapper.stubGenerator = DeclarationStubGenerator(moduleDescriptor, symbolTable, irBuiltIns.languageVersionSettings)
|
||||||
// Create stubs
|
|
||||||
ExternalDependenciesGenerator(symbolTable, irProvidersWithoutDeserializer, configuration.languageVersionSettings)
|
|
||||||
.generateUnboundSymbolsAsDependencies()
|
|
||||||
moduleFragment.patchDeclarationParents()
|
|
||||||
|
|
||||||
deserializer.finalizeExpectActualLinker()
|
|
||||||
|
|
||||||
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
|
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,11 @@ 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.JvmIdSignatureDescriptor
|
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||||
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
|
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.EmptyLoggingContext
|
import org.jetbrains.kotlin.ir.backend.jvm.serialization.EmptyLoggingContext
|
||||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrLinker
|
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrLinker
|
||||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmManglerDesc
|
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmManglerDesc
|
||||||
@@ -33,8 +36,9 @@ object JvmBackendFacade {
|
|||||||
val signaturer = JvmIdSignatureDescriptor(mangler)
|
val signaturer = JvmIdSignatureDescriptor(mangler)
|
||||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, signaturer = signaturer)
|
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, signaturer = signaturer)
|
||||||
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = extensions)
|
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = extensions)
|
||||||
|
val pluginExtensions = IrGenerationExtension.getInstances(state.project)
|
||||||
|
|
||||||
for (extension in IrGenerationExtension.getInstances(state.project)) {
|
for (extension in pluginExtensions) {
|
||||||
psi2ir.addPostprocessingStep { module ->
|
psi2ir.addPostprocessingStep { module ->
|
||||||
extension.generate(
|
extension.generate(
|
||||||
module,
|
module,
|
||||||
@@ -53,22 +57,22 @@ object JvmBackendFacade {
|
|||||||
val stubGenerator = DeclarationStubGenerator(
|
val stubGenerator = DeclarationStubGenerator(
|
||||||
psi2irContext.moduleDescriptor, psi2irContext.symbolTable, psi2irContext.irBuiltIns.languageVersionSettings, extensions
|
psi2irContext.moduleDescriptor, psi2irContext.symbolTable, psi2irContext.irBuiltIns.languageVersionSettings, extensions
|
||||||
)
|
)
|
||||||
val deserializer = JvmIrLinker(
|
val irLinker = JvmIrLinker(psi2irContext.moduleDescriptor, EmptyLoggingContext, psi2irContext.irBuiltIns, psi2irContext.symbolTable, stubGenerator, mangler)
|
||||||
EmptyLoggingContext, psi2irContext.irBuiltIns, psi2irContext.symbolTable
|
val dependencies = psi2irContext.moduleDescriptor.allDependencyModules.map {
|
||||||
)
|
val kotlinLibrary = (it.getCapability(KlibModuleOrigin.CAPABILITY) as? DeserializedKlibModuleOrigin)?.library
|
||||||
psi2irContext.moduleDescriptor.allDependencyModules.filter { it.getCapability(KlibModuleOrigin.CAPABILITY) != null }.forEach {
|
irLinker.deserializeIrModuleHeader(it, kotlinLibrary)
|
||||||
deserializer.deserializeIrModuleHeader(it)
|
|
||||||
}
|
}
|
||||||
val irProviders = listOf(deserializer, stubGenerator)
|
val irProviders = listOf(irLinker)
|
||||||
|
|
||||||
stubGenerator.setIrProviders(irProviders)
|
stubGenerator.setIrProviders(irProviders)
|
||||||
|
|
||||||
val irModuleFragment = psi2ir.generateModuleFragment(
|
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, irProviders, expectDescriptorToSymbol = null, pluginExtensions)
|
||||||
psi2irContext, files,
|
irLinker.postProcess()
|
||||||
irProviders = irProviders,
|
|
||||||
expectDescriptorToSymbol = null
|
stubGenerator.unboundSymbolGeneration = true
|
||||||
)
|
|
||||||
// We need to compile all files we reference in Klibs
|
// We need to compile all files we reference in Klibs
|
||||||
irModuleFragment.files.addAll(deserializer.getAllIrFiles())
|
irModuleFragment.files.addAll(dependencies.flatMap { it.files })
|
||||||
|
|
||||||
doGenerateFilesInternal(
|
doGenerateFilesInternal(
|
||||||
state, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, irProviders, extensions
|
state, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, irProviders, extensions
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ fun compileWasm(
|
|||||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
||||||
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings).generateUnboundSymbolsAsDependencies()
|
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings).generateUnboundSymbolsAsDependencies()
|
||||||
moduleFragment.patchDeclarationParents()
|
moduleFragment.patchDeclarationParents()
|
||||||
deserializer.finalizeExpectActualLinker()
|
deserializer.postProcess()
|
||||||
|
|
||||||
wasmPhases.invokeToplevel(phaseConfig, context, moduleFragment)
|
wasmPhases.invokeToplevel(phaseConfig, context, moduleFragment)
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ class Psi2IrTranslator(
|
|||||||
postprocessingSteps.add(step)
|
postprocessingSteps.add(step)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: used only for test purpose
|
||||||
fun generateModule(
|
fun generateModule(
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
ktFiles: Collection<KtFile>,
|
ktFiles: Collection<KtFile>,
|
||||||
@@ -68,7 +69,8 @@ class Psi2IrTranslator(
|
|||||||
context: GeneratorContext,
|
context: GeneratorContext,
|
||||||
ktFiles: Collection<KtFile>,
|
ktFiles: Collection<KtFile>,
|
||||||
irProviders: List<IrProvider>,
|
irProviders: List<IrProvider>,
|
||||||
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
|
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null,
|
||||||
|
pluginExtensions: Collection<IrExtensionGenerator> = emptyList()
|
||||||
): IrModuleFragment {
|
): IrModuleFragment {
|
||||||
val moduleGenerator = ModuleGenerator(context)
|
val moduleGenerator = ModuleGenerator(context)
|
||||||
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
|
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
|
||||||
@@ -76,8 +78,14 @@ class Psi2IrTranslator(
|
|||||||
irModule.patchDeclarationParents()
|
irModule.patchDeclarationParents()
|
||||||
expectDescriptorToSymbol?.let { referenceExpectsForUsedActuals(it, context.symbolTable, irModule) }
|
expectDescriptorToSymbol?.let { referenceExpectsForUsedActuals(it, context.symbolTable, irModule) }
|
||||||
postprocess(context, irModule)
|
postprocess(context, irModule)
|
||||||
// do not generate unbound symbols before postprocessing,
|
|
||||||
// since plugins must work with non-lazy IR
|
irProviders.filterIsInstance<IrDeserializer>().forEach { it.init(irModule, pluginExtensions) }
|
||||||
|
|
||||||
|
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||||
|
|
||||||
|
postprocessingSteps.forEach { it.invoke(irModule) }
|
||||||
|
|
||||||
|
// TODO: remove it once plugin API improved
|
||||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||||
|
|
||||||
return irModule
|
return irModule
|
||||||
@@ -87,8 +95,6 @@ class Psi2IrTranslator(
|
|||||||
insertImplicitCasts(irElement, context)
|
insertImplicitCasts(irElement, context)
|
||||||
generateAnnotationsForDeclarations(context, irElement)
|
generateAnnotationsForDeclarations(context, irElement)
|
||||||
|
|
||||||
postprocessingSteps.forEach { it(irElement) }
|
|
||||||
|
|
||||||
irElement.patchDeclarationParents()
|
irElement.patchDeclarationParents()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,457 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.ir.descriptors
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
|
abstract class IrAbstractFunctionFactory {
|
||||||
|
|
||||||
|
abstract fun functionClassDescriptor(arity: Int): FunctionClassDescriptor
|
||||||
|
abstract fun kFunctionClassDescriptor(arity: Int): FunctionClassDescriptor
|
||||||
|
abstract fun suspendFunctionClassDescriptor(arity: Int): FunctionClassDescriptor
|
||||||
|
abstract fun kSuspendFunctionClassDescriptor(arity: Int): FunctionClassDescriptor
|
||||||
|
|
||||||
|
abstract fun functionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass
|
||||||
|
abstract fun kFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass
|
||||||
|
abstract fun suspendFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass
|
||||||
|
abstract fun kSuspendFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass
|
||||||
|
|
||||||
|
fun functionN(n: Int) = functionN(n) { callback ->
|
||||||
|
val descriptor = functionClassDescriptor(n)
|
||||||
|
declareClass(offset, offset, classOrigin, descriptor) { symbol ->
|
||||||
|
callback(symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kFunctionN(n: Int): IrClass {
|
||||||
|
return kFunctionN(n) { callback ->
|
||||||
|
val descriptor = kFunctionClassDescriptor(n)
|
||||||
|
declareClass(offset, offset, classOrigin, descriptor) { symbol ->
|
||||||
|
callback(symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun suspendFunctionN(n: Int): IrClass = suspendFunctionN(n) { callback ->
|
||||||
|
val descriptor = suspendFunctionClassDescriptor(n)
|
||||||
|
declareClass(offset, offset, classOrigin, descriptor) { symbol ->
|
||||||
|
callback(symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kSuspendFunctionN(n: Int): IrClass = kSuspendFunctionN(n) { callback ->
|
||||||
|
val descriptor = kSuspendFunctionClassDescriptor(n)
|
||||||
|
declareClass(offset, offset, classOrigin, descriptor) { symbol ->
|
||||||
|
callback(symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val classOrigin = object : IrDeclarationOriginImpl("FUNCTION_INTERFACE_CLASS") {}
|
||||||
|
val memberOrigin = object : IrDeclarationOriginImpl("FUNCTION_INTERFACE_MEMBER") {}
|
||||||
|
const val offset = SYNTHETIC_OFFSET
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IrFunctionFactory(private val irBuiltIns: IrBuiltIns, private val symbolTable: SymbolTable) : IrAbstractFunctionFactory() {
|
||||||
|
|
||||||
|
// TODO: Lazieness
|
||||||
|
|
||||||
|
private val functionNMap = mutableMapOf<Int, IrClass>()
|
||||||
|
private val kFunctionNMap = mutableMapOf<Int, IrClass>()
|
||||||
|
private val suspendFunctionNMap = mutableMapOf<Int, IrClass>()
|
||||||
|
private val kSuspendFunctionNMap = mutableMapOf<Int, IrClass>()
|
||||||
|
|
||||||
|
override fun functionClassDescriptor(arity: Int): FunctionClassDescriptor =
|
||||||
|
irBuiltIns.builtIns.getFunction(arity) as FunctionClassDescriptor
|
||||||
|
|
||||||
|
override fun functionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass {
|
||||||
|
return functionNMap.getOrPut(arity) {
|
||||||
|
symbolTable.declarator { symbol ->
|
||||||
|
val descriptor = symbol.descriptor as FunctionClassDescriptor
|
||||||
|
val descriptorFactory = FunctionDescriptorFactory.RealDescriptorFactory(descriptor, symbolTable)
|
||||||
|
createFunctionClass(symbol, false, false, arity, irBuiltIns.functionClass, kotlinPackageFragment, descriptorFactory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun suspendFunctionClassDescriptor(arity: Int): FunctionClassDescriptor =
|
||||||
|
irBuiltIns.builtIns.getSuspendFunction(arity) as FunctionClassDescriptor
|
||||||
|
|
||||||
|
override fun suspendFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass {
|
||||||
|
return suspendFunctionNMap.getOrPut(arity) {
|
||||||
|
symbolTable.declarator { symbol ->
|
||||||
|
val descriptor = symbol.descriptor as FunctionClassDescriptor
|
||||||
|
val descriptorFactory = FunctionDescriptorFactory.RealDescriptorFactory(descriptor, symbolTable)
|
||||||
|
createFunctionClass(symbol, false, true, arity, irBuiltIns.functionClass, kotlinCoroutinesPackageFragment, descriptorFactory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun kFunctionClassDescriptor(arity: Int): FunctionClassDescriptor {
|
||||||
|
val kFunctionFqn = reflectFunctionClassFqn(reflectionFunctionClassName(false, arity))
|
||||||
|
return irBuiltIns.builtIns.getBuiltInClassByFqName(kFunctionFqn) as FunctionClassDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun kFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass {
|
||||||
|
return kFunctionNMap.getOrPut(arity) {
|
||||||
|
symbolTable.declarator { symbol ->
|
||||||
|
val descriptor = symbol.descriptor as FunctionClassDescriptor
|
||||||
|
val descriptorFactory = FunctionDescriptorFactory.RealDescriptorFactory(descriptor, symbolTable)
|
||||||
|
createFunctionClass(symbol, true, false, arity, irBuiltIns.kFunctionClass, kotlinReflectPackageFragment, descriptorFactory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun kSuspendFunctionClassDescriptor(arity: Int): FunctionClassDescriptor {
|
||||||
|
val kFunctionFqn = reflectFunctionClassFqn(reflectionFunctionClassName(true, arity))
|
||||||
|
return irBuiltIns.builtIns.getBuiltInClassByFqName(kFunctionFqn) as FunctionClassDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun kSuspendFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass {
|
||||||
|
return kSuspendFunctionNMap.getOrPut(arity) {
|
||||||
|
symbolTable.declarator { symbol ->
|
||||||
|
val descriptor = symbol.descriptor as FunctionClassDescriptor
|
||||||
|
val descriptorFactory = FunctionDescriptorFactory.RealDescriptorFactory(descriptor, symbolTable)
|
||||||
|
createFunctionClass(symbol, true, true, arity, irBuiltIns.kFunctionClass, kotlinReflectPackageFragment, descriptorFactory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun reflectFunctionClassFqn(shortName: Name): FqName = KOTLIN_REFLECT_FQ_NAME.child(shortName)
|
||||||
|
private fun reflectionFunctionClassName(isSuspend: Boolean, arity: Int): Name =
|
||||||
|
Name.identifier("K${if (isSuspend) "Suspend" else ""}Function$arity")
|
||||||
|
|
||||||
|
private fun functionClassName(isK: Boolean, isSuspend: Boolean, arity: Int): String =
|
||||||
|
"${if (isK) "K" else ""}${if (isSuspend) "Suspend" else ""}Function$arity"
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class FunctionDescriptorFactory(protected val symbolTable: SymbolTable) {
|
||||||
|
abstract fun memberDescriptor(name: String, factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction): IrSimpleFunctionSymbol
|
||||||
|
abstract fun FunctionDescriptor.valueParameterDescriptor(index: Int): ValueParameterDescriptor
|
||||||
|
abstract fun typeParameterDescriptor(index: Int, factory: (IrTypeParameterSymbol) -> IrTypeParameter): IrTypeParameterSymbol
|
||||||
|
abstract fun classReceiverParameterDescriptor(): ReceiverParameterDescriptor
|
||||||
|
abstract fun FunctionDescriptor.memberReceiverParameterDescriptor(): ReceiverParameterDescriptor
|
||||||
|
|
||||||
|
class RealDescriptorFactory(private val classDescriptor: FunctionClassDescriptor, symbolTable: SymbolTable) :
|
||||||
|
FunctionDescriptorFactory(symbolTable) {
|
||||||
|
override fun memberDescriptor(name: String, factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction): IrSimpleFunctionSymbol {
|
||||||
|
val descriptor = classDescriptor.unsubstitutedMemberScope.run {
|
||||||
|
if (name[0] == '<') {
|
||||||
|
val propertyName = name.drop(5).dropLast(1)
|
||||||
|
val property = getContributedVariables(Name.identifier(propertyName), NoLookupLocation.FROM_BACKEND).single()
|
||||||
|
property.accessors.first { it.name.asString() == name }
|
||||||
|
} else {
|
||||||
|
getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).first()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return symbolTable.declareSimpleFunction(offset, offset, memberOrigin, descriptor, factory).symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun FunctionDescriptor.valueParameterDescriptor(index: Int): ValueParameterDescriptor {
|
||||||
|
assert(containingDeclaration === classDescriptor)
|
||||||
|
return valueParameters[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun typeParameterDescriptor(index: Int, factory: (IrTypeParameterSymbol) -> IrTypeParameter): IrTypeParameterSymbol {
|
||||||
|
val descriptor = classDescriptor.declaredTypeParameters[index]
|
||||||
|
return symbolTable.declareGlobalTypeParameter(offset, offset, classOrigin, descriptor, factory).symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun classReceiverParameterDescriptor(): ReceiverParameterDescriptor {
|
||||||
|
return classDescriptor.thisAsReceiverParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun FunctionDescriptor.memberReceiverParameterDescriptor(): ReceiverParameterDescriptor {
|
||||||
|
assert(containingDeclaration === classDescriptor)
|
||||||
|
return dispatchReceiverParameter ?: error("Expected dispatch receiver at $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrTypeParametersContainer.createTypeParameters(n: Int, descriptorFactory: FunctionDescriptorFactory): IrTypeParameter {
|
||||||
|
|
||||||
|
var index = 0
|
||||||
|
|
||||||
|
val typeParametersArray = ArrayList<IrTypeParameter>(n + 1)
|
||||||
|
|
||||||
|
for (i in 1 until (n + 1)) {
|
||||||
|
val pName = Name.identifier("P$i")
|
||||||
|
|
||||||
|
val pSymbol = descriptorFactory.typeParameterDescriptor(index) {
|
||||||
|
IrTypeParameterImpl(offset, offset, classOrigin, it, pName, index++, false, Variance.IN_VARIANCE)
|
||||||
|
}
|
||||||
|
val pDeclaration = pSymbol.owner
|
||||||
|
|
||||||
|
pDeclaration.superTypes += irBuiltIns.anyNType
|
||||||
|
pDeclaration.parent = this
|
||||||
|
typeParametersArray.add(pDeclaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
val rSymbol = descriptorFactory.typeParameterDescriptor(index) {
|
||||||
|
IrTypeParameterImpl(offset, offset, classOrigin, it, Name.identifier("R"), index, false, Variance.OUT_VARIANCE)
|
||||||
|
}
|
||||||
|
val rDeclaration = rSymbol.owner
|
||||||
|
|
||||||
|
rDeclaration.superTypes += irBuiltIns.anyNType
|
||||||
|
rDeclaration.parent = this
|
||||||
|
typeParametersArray.add(rDeclaration)
|
||||||
|
|
||||||
|
typeParameters = typeParametersArray
|
||||||
|
|
||||||
|
return rDeclaration
|
||||||
|
}
|
||||||
|
|
||||||
|
private val kotlinPackageFragment: IrPackageFragment by lazy {
|
||||||
|
irBuiltIns.builtIns.getFunction(0).let {
|
||||||
|
symbolTable.declareExternalPackageFragment(it.containingDeclaration as PackageFragmentDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private val kotlinCoroutinesPackageFragment: IrPackageFragment by lazy {
|
||||||
|
irBuiltIns.builtIns.getSuspendFunction(0).let {
|
||||||
|
symbolTable.declareExternalPackageFragment(it.containingDeclaration as PackageFragmentDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val kotlinReflectPackageFragment: IrPackageFragment by lazy {
|
||||||
|
irBuiltIns.kPropertyClass.descriptor.let {
|
||||||
|
symbolTable.declareExternalPackageFragment(it.containingDeclaration as PackageFragmentDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.createThisReceiver(descriptorFactory: FunctionDescriptorFactory): IrValueParameter {
|
||||||
|
val vDescriptor = descriptorFactory.classReceiverParameterDescriptor()
|
||||||
|
val vSymbol = IrValueParameterSymbolImpl(vDescriptor)
|
||||||
|
val type = with(IrSimpleTypeBuilder()) {
|
||||||
|
classifier = symbol
|
||||||
|
arguments = typeParameters.run {
|
||||||
|
val builder = IrSimpleTypeBuilder()
|
||||||
|
mapTo(ArrayList(size)) {
|
||||||
|
builder.classifier = it.symbol
|
||||||
|
buildTypeProjection()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildSimpleType()
|
||||||
|
}
|
||||||
|
val vDeclaration = IrValueParameterImpl(
|
||||||
|
offset, offset, classOrigin, vSymbol, Name.special("<this>"), -1, type, null,
|
||||||
|
isCrossinline = false,
|
||||||
|
isNoinline = false
|
||||||
|
)
|
||||||
|
|
||||||
|
if (vDescriptor is WrappedReceiverParameterDescriptor) vDescriptor.bind(vDeclaration)
|
||||||
|
|
||||||
|
return vDeclaration
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FunctionClassDescriptor.createFunctionClass(): IrClass {
|
||||||
|
val s = symbolTable.referenceClass(this)
|
||||||
|
if (s.isBound) return s.owner
|
||||||
|
return symbolTable.declareClass(offset, offset, classOrigin, this, modality) {
|
||||||
|
val factory = FunctionDescriptorFactory.RealDescriptorFactory(this, symbolTable)
|
||||||
|
when (functionKind) {
|
||||||
|
FunctionClassDescriptor.Kind.Function ->
|
||||||
|
createFunctionClass(it, false, false, arity, irBuiltIns.functionClass, kotlinPackageFragment, factory)
|
||||||
|
FunctionClassDescriptor.Kind.SuspendFunction ->
|
||||||
|
createFunctionClass(it, false, true, arity, irBuiltIns.functionClass, kotlinCoroutinesPackageFragment, factory)
|
||||||
|
FunctionClassDescriptor.Kind.KFunction ->
|
||||||
|
createFunctionClass(it, true, false, arity, irBuiltIns.kFunctionClass, kotlinReflectPackageFragment, factory)
|
||||||
|
FunctionClassDescriptor.Kind.KSuspendFunction ->
|
||||||
|
createFunctionClass(it, true, true, arity, irBuiltIns.kFunctionClass, kotlinReflectPackageFragment, factory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.createMembers(isK: Boolean, isSuspend: Boolean, arity: Int, name: String, descriptorFactory: FunctionDescriptorFactory) {
|
||||||
|
if (!isK) {
|
||||||
|
val invokeSymbol = descriptorFactory.memberDescriptor("invoke") {
|
||||||
|
val returnType = with(IrSimpleTypeBuilder()) {
|
||||||
|
classifier = typeParameters.last().symbol
|
||||||
|
buildSimpleType()
|
||||||
|
}
|
||||||
|
|
||||||
|
IrFunctionImpl(offset, offset, memberOrigin, it, Name.identifier("invoke"), Visibilities.PUBLIC, Modality.ABSTRACT,
|
||||||
|
returnType,
|
||||||
|
isInline = false,
|
||||||
|
isExternal = false,
|
||||||
|
isTailrec = false,
|
||||||
|
isSuspend = isSuspend,
|
||||||
|
isOperator = true,
|
||||||
|
isExpect = false,
|
||||||
|
isFakeOverride = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val fDeclaration = invokeSymbol.owner
|
||||||
|
|
||||||
|
fDeclaration.dispatchReceiverParameter = createThisReceiver(descriptorFactory).also { it.parent = fDeclaration }
|
||||||
|
|
||||||
|
val typeBuilder = IrSimpleTypeBuilder()
|
||||||
|
for (i in 1 until typeParameters.size) {
|
||||||
|
val vTypeParam = typeParameters[i - 1]
|
||||||
|
val vDescriptor = with(descriptorFactory) { invokeSymbol.descriptor.valueParameterDescriptor(i - 1) }
|
||||||
|
val vSymbol = IrValueParameterSymbolImpl(vDescriptor)
|
||||||
|
val vType = with(typeBuilder) {
|
||||||
|
classifier = vTypeParam.symbol
|
||||||
|
buildSimpleType()
|
||||||
|
}
|
||||||
|
val vDeclaration = IrValueParameterImpl(
|
||||||
|
offset, offset, memberOrigin, vSymbol, Name.identifier("p$i"), i - 1, vType, null,
|
||||||
|
isCrossinline = false,
|
||||||
|
isNoinline = false
|
||||||
|
)
|
||||||
|
vDeclaration.parent = fDeclaration
|
||||||
|
if (vDescriptor is WrappedValueParameterDescriptor) vDescriptor.bind(vDeclaration)
|
||||||
|
fDeclaration.valueParameters += vDeclaration
|
||||||
|
}
|
||||||
|
|
||||||
|
fDeclaration.parent = this
|
||||||
|
declarations += fDeclaration
|
||||||
|
}
|
||||||
|
|
||||||
|
addFakeOverrides()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toIrType(wrapped: KotlinType): IrType {
|
||||||
|
val kotlinType = wrapped.unwrap()
|
||||||
|
return with(IrSimpleTypeBuilder()) {
|
||||||
|
classifier =
|
||||||
|
symbolTable.referenceClassifier(kotlinType.constructor.declarationDescriptor ?: error("No classifier for type $kotlinType"))
|
||||||
|
hasQuestionMark = kotlinType.isMarkedNullable
|
||||||
|
arguments = kotlinType.arguments.map {
|
||||||
|
if (it.isStarProjection) IrStarProjectionImpl
|
||||||
|
else makeTypeProjection(toIrType(it.type), it.projectionKind)
|
||||||
|
}
|
||||||
|
buildSimpleType()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrFunction.createValueParameter(descriptor: ParameterDescriptor): IrValueParameter {
|
||||||
|
val symbol = IrValueParameterSymbolImpl(descriptor)
|
||||||
|
val varargType = if (descriptor is ValueParameterDescriptor) descriptor.varargElementType else null
|
||||||
|
return IrValueParameterImpl(
|
||||||
|
offset,
|
||||||
|
offset,
|
||||||
|
memberOrigin,
|
||||||
|
symbol,
|
||||||
|
toIrType(descriptor.type),
|
||||||
|
varargType?.let { toIrType(it) }).also {
|
||||||
|
it.parent = this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.addFakeOverrides() {
|
||||||
|
|
||||||
|
val fakeOverrideDescriptors = descriptor.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.CALLABLES)
|
||||||
|
.filterIsInstance<CallableMemberDescriptor>().filter { it.kind === CallableMemberDescriptor.Kind.FAKE_OVERRIDE }
|
||||||
|
|
||||||
|
fun createFakeOverrideFunction(descriptor: FunctionDescriptor, property: IrPropertySymbol?): IrSimpleFunction {
|
||||||
|
val returnType = descriptor.returnType?.let { toIrType(it) } ?: error("No return type for $descriptor")
|
||||||
|
val newFunction = symbolTable.declareSimpleFunction(offset, offset, memberOrigin, descriptor) {
|
||||||
|
descriptor.run {
|
||||||
|
IrFunctionImpl(
|
||||||
|
offset, offset, memberOrigin, it, name, visibility, modality, returnType,
|
||||||
|
isInline, isExternal, isTailrec, isSuspend, isOperator, isExpect, true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newFunction.parent = this
|
||||||
|
newFunction.overriddenSymbols = descriptor.overriddenDescriptors.map { symbolTable.referenceSimpleFunction(it.original) }
|
||||||
|
newFunction.dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.let { newFunction.createValueParameter(it) }
|
||||||
|
newFunction.extensionReceiverParameter = descriptor.extensionReceiverParameter?.let { newFunction.createValueParameter(it) }
|
||||||
|
newFunction.valueParameters = descriptor.valueParameters.map { newFunction.createValueParameter(it) }
|
||||||
|
newFunction.correspondingPropertySymbol = property
|
||||||
|
|
||||||
|
return newFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createFakeOverrideProperty(descriptor: PropertyDescriptor): IrProperty {
|
||||||
|
return symbolTable.declareProperty(offset, offset, memberOrigin, descriptor) {
|
||||||
|
IrPropertyImpl(offset, offset, memberOrigin, it, descriptor.name).apply {
|
||||||
|
parent = this@addFakeOverrides
|
||||||
|
getter = descriptor.getter?.let { g -> createFakeOverrideFunction(g, symbol) }
|
||||||
|
setter = descriptor.setter?.let { s -> createFakeOverrideFunction(s, symbol) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun createFakeOverride(descriptor: CallableMemberDescriptor): IrDeclaration {
|
||||||
|
return when (descriptor) {
|
||||||
|
is FunctionDescriptor -> createFakeOverrideFunction(descriptor, null)
|
||||||
|
is PropertyDescriptor -> createFakeOverrideProperty(descriptor)
|
||||||
|
else -> error("Unexpected member $descriptor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declarations += fakeOverrideDescriptors.map { createFakeOverride(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFunctionClass(
|
||||||
|
symbol: IrClassSymbol,
|
||||||
|
isK: Boolean,
|
||||||
|
isSuspend: Boolean,
|
||||||
|
n: Int,
|
||||||
|
baseClass: IrClassSymbol,
|
||||||
|
packageFragment: IrPackageFragment,
|
||||||
|
descriptorFactory: FunctionDescriptorFactory
|
||||||
|
): IrClass {
|
||||||
|
val name = functionClassName(isK, isSuspend, n)
|
||||||
|
val klass = IrClassImpl(
|
||||||
|
offset, offset, classOrigin, symbol, Name.identifier(name), ClassKind.INTERFACE, Visibilities.PUBLIC, Modality.ABSTRACT,
|
||||||
|
isCompanion = false,
|
||||||
|
isInner = false,
|
||||||
|
isData = false,
|
||||||
|
isExternal = false,
|
||||||
|
isInline = false,
|
||||||
|
isExpect = false,
|
||||||
|
isFun = false
|
||||||
|
)
|
||||||
|
|
||||||
|
val r = klass.createTypeParameters(n, descriptorFactory)
|
||||||
|
|
||||||
|
klass.thisReceiver = klass.createThisReceiver(descriptorFactory).also { it.parent = klass }
|
||||||
|
|
||||||
|
klass.superTypes = listOf(with(IrSimpleTypeBuilder()) {
|
||||||
|
classifier = baseClass
|
||||||
|
arguments = listOf(
|
||||||
|
with(IrSimpleTypeBuilder()) {
|
||||||
|
classifier = r.symbol
|
||||||
|
buildTypeProjection()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
buildSimpleType()
|
||||||
|
})
|
||||||
|
|
||||||
|
klass.createMembers(isK, isSuspend, n, klass.name.identifier, descriptorFactory)
|
||||||
|
|
||||||
|
klass.parent = packageFragment
|
||||||
|
packageFragment.declarations += klass
|
||||||
|
|
||||||
|
return klass
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,8 +52,6 @@ class ExternalDependenciesGenerator(
|
|||||||
assert(symbol.isBound) { "$symbol unbound even after deserialization attempt" }
|
assert(symbol.isBound) { "$symbol unbound even after deserialization attempt" }
|
||||||
}
|
}
|
||||||
} while (unbound.isNotEmpty())
|
} while (unbound.isNotEmpty())
|
||||||
|
|
||||||
irProviders.forEach { (it as? IrDeserializer)?.declareForwardDeclarations() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,12 @@ interface LazyIrProvider : IrProvider {
|
|||||||
override fun getDeclaration(symbol: IrSymbol): IrLazyDeclarationBase?
|
override fun getDeclaration(symbol: IrSymbol): IrLazyDeclarationBase?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IrExtensionGenerator {
|
||||||
|
fun declare(symbol: IrSymbol): IrDeclaration? = null
|
||||||
|
}
|
||||||
|
|
||||||
interface IrDeserializer : IrProvider {
|
interface IrDeserializer : IrProvider {
|
||||||
fun declareForwardDeclarations()
|
fun init(moduleFragment: IrModuleFragment?, extensions: Collection<IrExtensionGenerator>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ReferenceSymbolTable {
|
interface ReferenceSymbolTable {
|
||||||
@@ -846,6 +850,25 @@ open class SymbolTable(val signaturer: IdSignatureComposer) : ReferenceSymbolTab
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <D : DeclarationDescriptor, IR : IrSymbolOwner, S : IrBindableSymbol<D, IR>> FlatSymbolTable<D, IR, S>.forEachPublicSymbolImpl(
|
||||||
|
block: (IrSymbol) -> Unit
|
||||||
|
) {
|
||||||
|
idSigToSymbol.forEach { (_, sym) ->
|
||||||
|
assert(sym.isPublicApi)
|
||||||
|
block(sym)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun forEachPublicSymbol(block: (IrSymbol) -> Unit) {
|
||||||
|
classSymbolTable.forEachPublicSymbolImpl { block(it) }
|
||||||
|
constructorSymbolTable.forEachPublicSymbolImpl { block(it) }
|
||||||
|
simpleFunctionSymbolTable.forEachPublicSymbolImpl { block(it) }
|
||||||
|
propertySymbolTable.forEachPublicSymbolImpl { block(it) }
|
||||||
|
enumEntrySymbolTable.forEachPublicSymbolImpl { block(it) }
|
||||||
|
typeAliasSymbolTable.forEachPublicSymbolImpl { block(it) }
|
||||||
|
fieldSymbolTable.forEachPublicSymbolImpl { block(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T, D : DeclarationDescriptor> SymbolTable.withScope(owner: D, block: SymbolTable.(D) -> T): T {
|
inline fun <T, D : DeclarationDescriptor> SymbolTable.withScope(owner: D, block: SymbolTable.(D) -> T): T {
|
||||||
|
|||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.backend.common.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
|
import org.jetbrains.kotlin.ir.util.KotlinMangler
|
||||||
|
|
||||||
|
class DescriptorByIdSignatureFinder(private val moduleDescriptor: ModuleDescriptor, private val mangler: KotlinMangler.DescriptorMangler) {
|
||||||
|
fun findDescriptorBySignature(signature: IdSignature): DeclarationDescriptor? = when (signature) {
|
||||||
|
is IdSignature.AccessorSignature -> findDescriptorForAccessorSignature(signature)
|
||||||
|
is IdSignature.PublicSignature -> findDescriptorForPublicSignature(signature)
|
||||||
|
else -> error("only PublicSignature or AccessorSignature should reach this point, got $signature")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findDescriptorForAccessorSignature(signature: IdSignature.AccessorSignature): DeclarationDescriptor? {
|
||||||
|
val propertyDescriptor = findDescriptorBySignature(signature.propertySignature) as? PropertyDescriptor
|
||||||
|
?: return null
|
||||||
|
return propertyDescriptor.accessors.singleOrNull {
|
||||||
|
it.name == signature.accessorSignature.declarationFqn.shortName()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findDescriptorForPublicSignature(signature: IdSignature.PublicSignature): DeclarationDescriptor? {
|
||||||
|
val packageDescriptor = moduleDescriptor.getPackage(signature.packageFqName())
|
||||||
|
val pathSegments = signature.declarationFqn.pathSegments()
|
||||||
|
val toplevelDescriptors = packageDescriptor.memberScope.getContributedDescriptors { name -> name == pathSegments.first() }
|
||||||
|
.filter { it.name == pathSegments.first() }
|
||||||
|
val candidates = pathSegments.drop(1).fold(toplevelDescriptors) { acc, current ->
|
||||||
|
acc.flatMap { container ->
|
||||||
|
val classDescriptor = container as? ClassDescriptor
|
||||||
|
?: return@flatMap emptyList<DeclarationDescriptor>()
|
||||||
|
val nextStepCandidates = classDescriptor.constructors +
|
||||||
|
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors { name -> name == current } +
|
||||||
|
// Static scope is required only for Enum.values() and Enum.valueOf().
|
||||||
|
classDescriptor.staticScope.getContributedDescriptors { name -> name == current }
|
||||||
|
nextStepCandidates.filter { it.name == current }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (candidates.size) {
|
||||||
|
1 -> candidates.first()
|
||||||
|
else -> {
|
||||||
|
findDescriptorByHash(candidates, signature.id)
|
||||||
|
?: error("No descriptor found for $signature")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findDescriptorByHash(candidates: List<DeclarationDescriptor>, id: Long?): DeclarationDescriptor? =
|
||||||
|
candidates.firstOrNull { candidate ->
|
||||||
|
if (id == null) {
|
||||||
|
// We don't compute id for typealiases and classes.
|
||||||
|
candidate is ClassDescriptor || candidate is TypeAliasDescriptor
|
||||||
|
} else {
|
||||||
|
val candidateHash = with(mangler) { candidate.signatureMangle }
|
||||||
|
candidateHash == id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+137
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.backend.common.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeserializedDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.library.IrLibrary
|
||||||
|
import org.jetbrains.kotlin.library.SerializedIrFile
|
||||||
|
import org.jetbrains.kotlin.library.impl.*
|
||||||
|
|
||||||
|
|
||||||
|
class ICKotlinLibrary(private val icData: List<SerializedIrFile>) : IrLibrary {
|
||||||
|
override val dataFlowGraph: ByteArray? = null
|
||||||
|
|
||||||
|
private inline fun <K, R : IrTableReader<K>> Array<R?>.itemBytes(fileIndex: Int, key: K, factory: () -> R): ByteArray {
|
||||||
|
val reader = this[fileIndex] ?: factory().also { this[fileIndex] = it }
|
||||||
|
|
||||||
|
return reader.tableItemBytes(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <R : IrArrayReader> Array<R?>.itemBytes(fileIndex: Int, index: Int, factory: () -> R): ByteArray {
|
||||||
|
val reader = this[fileIndex] ?: factory().also { this[fileIndex] = it }
|
||||||
|
|
||||||
|
return reader.tableItemBytes(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val indexedDeclarations = arrayOfNulls<DeclarationIrTableMemoryReader>(icData.size)
|
||||||
|
private val indexedTypes = arrayOfNulls<IrArrayMemoryReader>(icData.size)
|
||||||
|
private val indexedSignatures = arrayOfNulls<IrArrayMemoryReader>(icData.size)
|
||||||
|
private val indexedStrings = arrayOfNulls<IrArrayMemoryReader>(icData.size)
|
||||||
|
private val indexedBodies = arrayOfNulls<IrArrayMemoryReader>(icData.size)
|
||||||
|
|
||||||
|
override fun irDeclaration(index: Int, fileIndex: Int): ByteArray =
|
||||||
|
indexedDeclarations.itemBytes(fileIndex, DeclarationId(index)) {
|
||||||
|
DeclarationIrTableMemoryReader(icData[fileIndex].declarations)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun type(index: Int, fileIndex: Int): ByteArray =
|
||||||
|
indexedTypes.itemBytes(fileIndex, index) {
|
||||||
|
IrArrayMemoryReader(icData[fileIndex].types)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun signature(index: Int, fileIndex: Int): ByteArray =
|
||||||
|
indexedSignatures.itemBytes(fileIndex, index) {
|
||||||
|
IrArrayMemoryReader(icData[fileIndex].signatures)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun string(index: Int, fileIndex: Int): ByteArray =
|
||||||
|
indexedStrings.itemBytes(fileIndex, index) {
|
||||||
|
IrArrayMemoryReader(icData[fileIndex].strings)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun body(index: Int, fileIndex: Int): ByteArray =
|
||||||
|
indexedBodies.itemBytes(fileIndex, index) {
|
||||||
|
IrArrayMemoryReader(icData[fileIndex].bodies)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun file(index: Int): ByteArray = icData[index].fileData
|
||||||
|
|
||||||
|
override fun fileCount(): Int = icData.size
|
||||||
|
}
|
||||||
|
|
||||||
|
class CurrentModuleWithICDeserializer(
|
||||||
|
private val delegate: IrModuleDeserializer,
|
||||||
|
private val symbolTable: SymbolTable,
|
||||||
|
private val irBuiltIns: IrBuiltIns,
|
||||||
|
icData: List<SerializedIrFile>,
|
||||||
|
icReaderFactory: (IrLibrary) -> IrModuleDeserializer) :
|
||||||
|
IrModuleDeserializer(delegate.moduleDescriptor) {
|
||||||
|
|
||||||
|
private val dirtyDeclarations = mutableMapOf<IdSignature, IrSymbol>()
|
||||||
|
private val icKlib = ICKotlinLibrary(icData)
|
||||||
|
|
||||||
|
private val icDeserializer: IrModuleDeserializer = icReaderFactory(icKlib)
|
||||||
|
|
||||||
|
override fun contains(idSig: IdSignature): Boolean {
|
||||||
|
return idSig in dirtyDeclarations || idSig.topLevelSignature() in icDeserializer || idSig in delegate
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
dirtyDeclarations[idSig]?.let { return it }
|
||||||
|
|
||||||
|
if (idSig.topLevelSignature() in icDeserializer) return icDeserializer.deserializeIrSymbol(idSig, symbolKind)
|
||||||
|
|
||||||
|
return delegate.deserializeIrSymbol(idSig, symbolKind)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addModuleReachableTopLevel(idSig: IdSignature) {
|
||||||
|
assert(idSig in icDeserializer)
|
||||||
|
icDeserializer.addModuleReachableTopLevel(idSig)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeReachableDeclarations() {
|
||||||
|
icDeserializer.deserializeReachableDeclarations()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postProcess() {
|
||||||
|
icDeserializer.postProcess()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DeclarationDescriptor.isDirtyDescriptor(): Boolean {
|
||||||
|
if (this is PropertyAccessorDescriptor) return correspondingProperty.isDirtyDescriptor()
|
||||||
|
return this !is DeserializedDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
val knownBuiltIns = irBuiltIns.knownBuiltins.map { (it as IrSymbolOwner).symbol }.toSet()
|
||||||
|
symbolTable.forEachPublicSymbol {
|
||||||
|
if (it.descriptor.isDirtyDescriptor()) { // public && non-deserialized should be dirty symbol
|
||||||
|
if (it !in knownBuiltIns) {
|
||||||
|
dirtyDeclarations[it.signature] = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
icDeserializer.init(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val klib: IrLibrary
|
||||||
|
get() = icDeserializer.klib
|
||||||
|
|
||||||
|
override val moduleFragment: IrModuleFragment
|
||||||
|
get() = delegate.moduleFragment
|
||||||
|
override val moduleDependencies: Collection<IrModuleDeserializer>
|
||||||
|
get() = delegate.moduleDependencies
|
||||||
|
}
|
||||||
-76
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 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.backend.common.serialization
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrBindableSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.util.isReal
|
|
||||||
import org.jetbrains.kotlin.ir.util.original
|
|
||||||
|
|
||||||
// We may get several real supers here (e.g. see the code snippet from KT-33034).
|
|
||||||
// TODO: Consider reworking the resolution algorithm to get a determined super declaration.
|
|
||||||
private fun <S: IrBindableSymbol<*, D>, D: IrOverridableDeclaration<S>> D.getRealSupers(): Set<D> {
|
|
||||||
if (this.isReal) {
|
|
||||||
return setOf(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
val visited = mutableSetOf<D>()
|
|
||||||
val realSupers = mutableSetOf<D>()
|
|
||||||
|
|
||||||
fun findRealSupers(declaration: D) {
|
|
||||||
if (declaration in visited) return
|
|
||||||
visited += declaration
|
|
||||||
if (declaration.isReal) {
|
|
||||||
realSupers += declaration
|
|
||||||
} else {
|
|
||||||
declaration.overriddenSymbols.forEach { findRealSupers(it.owner) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
findRealSupers(this)
|
|
||||||
|
|
||||||
if (realSupers.size > 1) {
|
|
||||||
visited.clear()
|
|
||||||
|
|
||||||
fun excludeOverridden(declaration: D) {
|
|
||||||
if (declaration in visited) return
|
|
||||||
visited += declaration
|
|
||||||
declaration.overriddenSymbols.forEach {
|
|
||||||
realSupers.remove(it.owner)
|
|
||||||
excludeOverridden(it.owner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
realSupers.toList().forEach { excludeOverridden(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
return realSupers
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of given method.
|
|
||||||
*
|
|
||||||
* TODO: this method is actually a part of resolve and probably duplicates another one
|
|
||||||
*/
|
|
||||||
fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false): IrSimpleFunction {
|
|
||||||
val realSupers = getRealSupers()
|
|
||||||
|
|
||||||
return if (allowAbstract) {
|
|
||||||
realSupers.first()
|
|
||||||
} else {
|
|
||||||
realSupers.single { it.modality != Modality.ABSTRACT }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val IrSimpleFunction.target: IrSimpleFunction
|
|
||||||
get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original
|
|
||||||
|
|
||||||
val IrFunction.target: IrFunction get() = when (this) {
|
|
||||||
is IrSimpleFunction -> this.target
|
|
||||||
is IrConstructor -> this
|
|
||||||
else -> error(this)
|
|
||||||
}
|
|
||||||
+67
-32
@@ -104,7 +104,7 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.PublicIdSignature
|
|||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
|
import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.FileLocalIdSignature as ProtoFileLocalIdSignature
|
import org.jetbrains.kotlin.backend.common.serialization.proto.FileLocalIdSignature as ProtoFileLocalIdSignature
|
||||||
|
|
||||||
abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBuiltIns, val symbolTable: SymbolTable) {
|
abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBuiltIns, val symbolTable: SymbolTable, protected var deserializeBodies: Boolean) {
|
||||||
|
|
||||||
abstract fun deserializeIrSymbolToDeclare(code: Long): Pair<IrSymbol, IdSignature>
|
abstract fun deserializeIrSymbolToDeclare(code: Long): Pair<IrSymbol, IdSignature>
|
||||||
abstract fun deserializeIrSymbol(code: Long): IrSymbol
|
abstract fun deserializeIrSymbol(code: Long): IrSymbol
|
||||||
@@ -118,6 +118,9 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
abstract fun referenceIrSymbol(symbol: IrSymbol, signature: IdSignature)
|
abstract fun referenceIrSymbol(symbol: IrSymbol, signature: IdSignature)
|
||||||
|
|
||||||
private val parentsStack = mutableListOf<IrDeclarationParent>()
|
private val parentsStack = mutableListOf<IrDeclarationParent>()
|
||||||
|
private val delegatedSymbolMap = mutableMapOf<IrSymbol, IrSymbol>()
|
||||||
|
|
||||||
|
abstract val deserializeInlineFunctions: Boolean
|
||||||
|
|
||||||
fun deserializeFqName(fqn: List<Int>): FqName {
|
fun deserializeFqName(fqn: List<Int>): FqName {
|
||||||
return fqn.run {
|
return fqn.run {
|
||||||
@@ -125,6 +128,13 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun deserializeIrSymbolAndRemap(code: Long): IrSymbol {
|
||||||
|
// TODO: could be simplified
|
||||||
|
return deserializeIrSymbol(code).let {
|
||||||
|
delegatedSymbolMap[it] ?: it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun deserializeName(index: Int): Name {
|
private fun deserializeName(index: Int): Name {
|
||||||
val name = deserializeString(index)
|
val name = deserializeString(index)
|
||||||
return Name.guessByFirstCharacter(name)
|
return Name.guessByFirstCharacter(name)
|
||||||
@@ -145,7 +155,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeSimpleType(proto: ProtoSimpleType): IrSimpleType {
|
private fun deserializeSimpleType(proto: ProtoSimpleType): IrSimpleType {
|
||||||
val symbol = deserializeIrSymbol(proto.classifier) as? IrClassifierSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.classifier) as? IrClassifierSymbol
|
||||||
?: error("could not convert sym to ClassifierSymbol")
|
?: error("could not convert sym to ClassifierSymbol")
|
||||||
logger.log { "deserializeSimpleType: symbol=$symbol" }
|
logger.log { "deserializeSimpleType: symbol=$symbol" }
|
||||||
|
|
||||||
@@ -167,7 +177,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
|
|
||||||
private fun deserializeTypeAbbreviation(proto: ProtoTypeAbbreviation): IrTypeAbbreviation =
|
private fun deserializeTypeAbbreviation(proto: ProtoTypeAbbreviation): IrTypeAbbreviation =
|
||||||
IrTypeAbbreviationImpl(
|
IrTypeAbbreviationImpl(
|
||||||
deserializeIrSymbol(proto.typeAlias).let {
|
deserializeIrSymbolAndRemap(proto.typeAlias).let {
|
||||||
it as? IrTypeAliasSymbol
|
it as? IrTypeAliasSymbol
|
||||||
?: error("IrTypeAliasSymbol expected: $it")
|
?: error("IrTypeAliasSymbol expected: $it")
|
||||||
},
|
},
|
||||||
@@ -344,14 +354,14 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
end: Int,
|
end: Int,
|
||||||
type: IrType
|
type: IrType
|
||||||
): IrClassReference {
|
): IrClassReference {
|
||||||
val symbol = deserializeIrSymbol(proto.classSymbol) as IrClassifierSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.classSymbol) as IrClassifierSymbol
|
||||||
val classType = deserializeIrType(proto.classType)
|
val classType = deserializeIrType(proto.classType)
|
||||||
/** TODO: [createClassifierSymbolForClassReference] is internal function */
|
/** TODO: [createClassifierSymbolForClassReference] is internal function */
|
||||||
return IrClassReferenceImpl(start, end, type, symbol, classType)
|
return IrClassReferenceImpl(start, end, type, symbol, classType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeConstructorCall(proto: ProtoConstructorCall, start: Int, end: Int, type: IrType): IrConstructorCall {
|
private fun deserializeConstructorCall(proto: ProtoConstructorCall, start: Int, end: Int, type: IrType): IrConstructorCall {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrConstructorSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrConstructorSymbol
|
||||||
return IrConstructorCallImpl(
|
return IrConstructorCallImpl(
|
||||||
start, end, type,
|
start, end, type,
|
||||||
symbol, typeArgumentsCount = proto.memberAccess.typeArgumentCount,
|
symbol, typeArgumentsCount = proto.memberAccess.typeArgumentCount,
|
||||||
@@ -363,10 +373,10 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeCall(proto: ProtoCall, start: Int, end: Int, type: IrType): IrCall {
|
private fun deserializeCall(proto: ProtoCall, start: Int, end: Int, type: IrType): IrCall {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrFunctionSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrFunctionSymbol
|
||||||
|
|
||||||
val superSymbol = if (proto.hasSuper()) {
|
val superSymbol = if (proto.hasSuper()) {
|
||||||
deserializeIrSymbol(proto.`super`) as IrClassSymbol
|
deserializeIrSymbolAndRemap(proto.`super`) as IrClassSymbol
|
||||||
} else null
|
} else null
|
||||||
|
|
||||||
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
||||||
@@ -400,7 +410,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
start: Int,
|
start: Int,
|
||||||
end: Int
|
end: Int
|
||||||
): IrDelegatingConstructorCall {
|
): IrDelegatingConstructorCall {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrConstructorSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrConstructorSymbol
|
||||||
val call = IrDelegatingConstructorCallImpl(
|
val call = IrDelegatingConstructorCallImpl(
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
@@ -421,7 +431,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
end: Int,
|
end: Int,
|
||||||
type: IrType
|
type: IrType
|
||||||
): IrEnumConstructorCall {
|
): IrEnumConstructorCall {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrConstructorSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrConstructorSymbol
|
||||||
val call = IrEnumConstructorCallImpl(
|
val call = IrEnumConstructorCallImpl(
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
@@ -451,10 +461,10 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
start: Int, end: Int, type: IrType
|
start: Int, end: Int, type: IrType
|
||||||
): IrFunctionReference {
|
): IrFunctionReference {
|
||||||
|
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrFunctionSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrFunctionSymbol
|
||||||
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
||||||
val reflectionTarget =
|
val reflectionTarget =
|
||||||
if (proto.hasReflectionTargetSymbol()) deserializeIrSymbol(proto.reflectionTargetSymbol) as IrFunctionSymbol else null
|
if (proto.hasReflectionTargetSymbol()) deserializeIrSymbolAndRemap(proto.reflectionTargetSymbol) as IrFunctionSymbol else null
|
||||||
val callable = IrFunctionReferenceImpl(
|
val callable = IrFunctionReferenceImpl(
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
@@ -477,11 +487,11 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
|
|
||||||
private fun deserializeGetField(proto: ProtoGetField, start: Int, end: Int, type: IrType): IrGetField {
|
private fun deserializeGetField(proto: ProtoGetField, start: Int, end: Int, type: IrType): IrGetField {
|
||||||
val access = proto.fieldAccess
|
val access = proto.fieldAccess
|
||||||
val symbol = deserializeIrSymbol(access.symbol) as IrFieldSymbol
|
val symbol = deserializeIrSymbolAndRemap(access.symbol) as IrFieldSymbol
|
||||||
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
||||||
|
|
||||||
val superQualifier = if (access.hasSuper()) {
|
val superQualifier = if (access.hasSuper()) {
|
||||||
deserializeIrSymbol(access.symbol) as IrClassSymbol
|
deserializeIrSymbolAndRemap(access.symbol) as IrClassSymbol
|
||||||
} else null
|
} else null
|
||||||
val receiver = if (access.hasReceiver()) {
|
val receiver = if (access.hasReceiver()) {
|
||||||
deserializeExpression(access.receiver)
|
deserializeExpression(access.receiver)
|
||||||
@@ -491,7 +501,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeGetValue(proto: ProtoGetValue, start: Int, end: Int, type: IrType): IrGetValue {
|
private fun deserializeGetValue(proto: ProtoGetValue, start: Int, end: Int, type: IrType): IrGetValue {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrValueSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrValueSymbol
|
||||||
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
||||||
// TODO: origin!
|
// TODO: origin!
|
||||||
return IrGetValueImpl(start, end, type, symbol, origin)
|
return IrGetValueImpl(start, end, type, symbol, origin)
|
||||||
@@ -503,7 +513,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
end: Int,
|
end: Int,
|
||||||
type: IrType
|
type: IrType
|
||||||
): IrGetEnumValue {
|
): IrGetEnumValue {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrEnumEntrySymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrEnumEntrySymbol
|
||||||
return IrGetEnumValueImpl(start, end, type, symbol)
|
return IrGetEnumValueImpl(start, end, type, symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,7 +523,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
end: Int,
|
end: Int,
|
||||||
type: IrType
|
type: IrType
|
||||||
): IrGetObjectValue {
|
): IrGetObjectValue {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrClassSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrClassSymbol
|
||||||
return IrGetObjectValueImpl(start, end, type, symbol)
|
return IrGetObjectValueImpl(start, end, type, symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,7 +532,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
start: Int,
|
start: Int,
|
||||||
end: Int
|
end: Int
|
||||||
): IrInstanceInitializerCall {
|
): IrInstanceInitializerCall {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrClassSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrClassSymbol
|
||||||
return IrInstanceInitializerCallImpl(start, end, symbol, builtIns.unitType)
|
return IrInstanceInitializerCallImpl(start, end, symbol, builtIns.unitType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,10 +543,10 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
type: IrType
|
type: IrType
|
||||||
): IrLocalDelegatedPropertyReference {
|
): IrLocalDelegatedPropertyReference {
|
||||||
|
|
||||||
val delegate = deserializeIrSymbol(proto.delegate) as IrVariableSymbol
|
val delegate = deserializeIrSymbolAndRemap(proto.delegate) as IrVariableSymbol
|
||||||
val getter = deserializeIrSymbol(proto.getter) as IrSimpleFunctionSymbol
|
val getter = deserializeIrSymbolAndRemap(proto.getter) as IrSimpleFunctionSymbol
|
||||||
val setter = if (proto.hasSetter()) deserializeIrSymbol(proto.setter) as IrSimpleFunctionSymbol else null
|
val setter = if (proto.hasSetter()) deserializeIrSymbolAndRemap(proto.setter) as IrSimpleFunctionSymbol else null
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrLocalDelegatedPropertySymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrLocalDelegatedPropertySymbol
|
||||||
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
||||||
|
|
||||||
return IrLocalDelegatedPropertyReferenceImpl(
|
return IrLocalDelegatedPropertyReferenceImpl(
|
||||||
@@ -551,11 +561,11 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
|
|
||||||
private fun deserializePropertyReference(proto: ProtoPropertyReference, start: Int, end: Int, type: IrType): IrPropertyReference {
|
private fun deserializePropertyReference(proto: ProtoPropertyReference, start: Int, end: Int, type: IrType): IrPropertyReference {
|
||||||
|
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrPropertySymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrPropertySymbol
|
||||||
|
|
||||||
val field = if (proto.hasField()) deserializeIrSymbol(proto.field) as IrFieldSymbol else null
|
val field = if (proto.hasField()) deserializeIrSymbolAndRemap(proto.field) as IrFieldSymbol else null
|
||||||
val getter = if (proto.hasGetter()) deserializeIrSymbol(proto.getter) as IrSimpleFunctionSymbol else null
|
val getter = if (proto.hasGetter()) deserializeIrSymbolAndRemap(proto.getter) as IrSimpleFunctionSymbol else null
|
||||||
val setter = if (proto.hasSetter()) deserializeIrSymbol(proto.setter) as IrSimpleFunctionSymbol else null
|
val setter = if (proto.hasSetter()) deserializeIrSymbolAndRemap(proto.setter) as IrSimpleFunctionSymbol else null
|
||||||
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
||||||
|
|
||||||
val callable = IrPropertyReferenceImpl(
|
val callable = IrPropertyReferenceImpl(
|
||||||
@@ -572,16 +582,16 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeReturn(proto: ProtoReturn, start: Int, end: Int, type: IrType): IrReturn {
|
private fun deserializeReturn(proto: ProtoReturn, start: Int, end: Int, type: IrType): IrReturn {
|
||||||
val symbol = deserializeIrSymbol(proto.returnTarget) as IrReturnTargetSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.returnTarget) as IrReturnTargetSymbol
|
||||||
val value = deserializeExpression(proto.value)
|
val value = deserializeExpression(proto.value)
|
||||||
return IrReturnImpl(start, end, builtIns.nothingType, symbol, value)
|
return IrReturnImpl(start, end, builtIns.nothingType, symbol, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeSetField(proto: ProtoSetField, start: Int, end: Int): IrSetField {
|
private fun deserializeSetField(proto: ProtoSetField, start: Int, end: Int): IrSetField {
|
||||||
val access = proto.fieldAccess
|
val access = proto.fieldAccess
|
||||||
val symbol = deserializeIrSymbol(access.symbol) as IrFieldSymbol
|
val symbol = deserializeIrSymbolAndRemap(access.symbol) as IrFieldSymbol
|
||||||
val superQualifier = if (access.hasSuper()) {
|
val superQualifier = if (access.hasSuper()) {
|
||||||
deserializeIrSymbol(access.symbol) as IrClassSymbol
|
deserializeIrSymbolAndRemap(access.symbol) as IrClassSymbol
|
||||||
} else null
|
} else null
|
||||||
val receiver = if (access.hasReceiver()) {
|
val receiver = if (access.hasReceiver()) {
|
||||||
deserializeExpression(access.receiver)
|
deserializeExpression(access.receiver)
|
||||||
@@ -593,7 +603,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeSetVariable(proto: ProtoSetVariable, start: Int, end: Int): IrSetVariable {
|
private fun deserializeSetVariable(proto: ProtoSetVariable, start: Int, end: Int): IrSetVariable {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrVariableSymbol
|
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrVariableSymbol
|
||||||
val value = deserializeExpression(proto.value)
|
val value = deserializeExpression(proto.value)
|
||||||
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
|
||||||
return IrSetVariableImpl(start, end, builtIns.unitType, symbol, value, origin)
|
return IrSetVariableImpl(start, end, builtIns.unitType, symbol, value, origin)
|
||||||
@@ -902,6 +912,16 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun recordDelegatedSymbol(symbol: IrSymbol) {
|
||||||
|
if (symbol is IrDelegatingSymbol<*, *, *>) {
|
||||||
|
delegatedSymbolMap[symbol] = symbol.delegate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun eraseDelegatedSymbol(symbol: IrSymbol) {
|
||||||
|
delegatedSymbolMap.remove(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun <T : IrDeclarationParent> T.usingParent(block: T.() -> Unit): T =
|
private inline fun <T : IrDeclarationParent> T.usingParent(block: T.() -> Unit): T =
|
||||||
this.apply { usingParent(this) { block(it) } }
|
this.apply { usingParent(this) { block(it) } }
|
||||||
|
|
||||||
@@ -911,6 +931,8 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
): T where T : IrDeclaration, T : IrSymbolOwner {
|
): T where T : IrDeclaration, T : IrSymbolOwner {
|
||||||
val (s, uid) = deserializeIrSymbolToDeclare(proto.symbol)
|
val (s, uid) = deserializeIrSymbolToDeclare(proto.symbol)
|
||||||
val coordinates = BinaryCoordinates.decode(proto.coordinates)
|
val coordinates = BinaryCoordinates.decode(proto.coordinates)
|
||||||
|
try {
|
||||||
|
recordDelegatedSymbol(s)
|
||||||
val result = block(
|
val result = block(
|
||||||
s,
|
s,
|
||||||
uid,
|
uid,
|
||||||
@@ -920,6 +942,9 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
result.annotations += deserializeAnnotations(proto.annotationList)
|
result.annotations += deserializeAnnotations(proto.annotationList)
|
||||||
result.parent = parentsStack.peek()!!
|
result.parent = parentsStack.peek()!!
|
||||||
return result
|
return result
|
||||||
|
} finally {
|
||||||
|
eraseDelegatedSymbol(s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrTypeParameter(proto: ProtoTypeParameter, index: Int, isGlobal: Boolean): IrTypeParameter {
|
private fun deserializeIrTypeParameter(proto: ProtoTypeParameter, index: Int, isGlobal: Boolean): IrTypeParameter {
|
||||||
@@ -1067,12 +1092,23 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <T : IrFunction> T.withInlineGuard(block: T.() -> Unit) {
|
||||||
|
val oldInline = deserializeBodies
|
||||||
|
try {
|
||||||
|
deserializeBodies = oldInline || (deserializeInlineFunctions && this is IrSimpleFunction && isInline)
|
||||||
|
block()
|
||||||
|
} finally {
|
||||||
|
deserializeBodies = oldInline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun <T : IrFunction> withDeserializedIrFunctionBase(
|
private inline fun <T : IrFunction> withDeserializedIrFunctionBase(
|
||||||
proto: ProtoFunctionBase,
|
proto: ProtoFunctionBase,
|
||||||
block: (IrFunctionSymbol, IdSignature, Int, Int, IrDeclarationOrigin, Long) -> T
|
block: (IrFunctionSymbol, IdSignature, Int, Int, IrDeclarationOrigin, Long) -> T
|
||||||
) = withDeserializedIrDeclarationBase(proto.base) { symbol, idSig, startOffset, endOffset, origin, fcode ->
|
) = withDeserializedIrDeclarationBase(proto.base) { symbol, idSig, startOffset, endOffset, origin, fcode ->
|
||||||
symbolTable.withScope(symbol.descriptor) {
|
symbolTable.withScope(symbol.descriptor) {
|
||||||
block(symbol as IrFunctionSymbol, idSig, startOffset, endOffset, origin, fcode).usingParent {
|
block(symbol as IrFunctionSymbol, idSig, startOffset, endOffset, origin, fcode).usingParent {
|
||||||
|
withInlineGuard {
|
||||||
typeParameters = deserializeTypeParameters(proto.typeParameterList, false)
|
typeParameters = deserializeTypeParameters(proto.typeParameterList, false)
|
||||||
valueParameters = deserializeValueParameters(proto.valueParameterList)
|
valueParameters = deserializeValueParameters(proto.valueParameterList)
|
||||||
|
|
||||||
@@ -1089,6 +1125,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun deserializeIrFunction(proto: ProtoFunction): IrSimpleFunction {
|
private fun deserializeIrFunction(proto: ProtoFunction): IrSimpleFunction {
|
||||||
return withDeserializedIrFunctionBase(proto.base) { symbol, idSig, startOffset, endOffset, origin, fcode ->
|
return withDeserializedIrFunctionBase(proto.base) { symbol, idSig, startOffset, endOffset, origin, fcode ->
|
||||||
@@ -1111,7 +1148,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
flags.isFakeOverride
|
flags.isFakeOverride
|
||||||
)
|
)
|
||||||
}.apply {
|
}.apply {
|
||||||
overriddenSymbols = proto.overriddenList.map { deserializeIrSymbol(it) as IrSimpleFunctionSymbol }
|
overriddenSymbols = proto.overriddenList.map { deserializeIrSymbolAndRemap(it) as IrSimpleFunctionSymbol }
|
||||||
|
|
||||||
(descriptor as? WrappedSimpleFunctionDescriptor)?.bind(this)
|
(descriptor as? WrappedSimpleFunctionDescriptor)?.bind(this)
|
||||||
}
|
}
|
||||||
@@ -1329,5 +1366,3 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
|||||||
deserializeDeclaration(proto)
|
deserializeDeclaration(proto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val irrelevantOrigin = object : IrDeclarationOriginImpl("irrelevant") {}
|
|
||||||
|
|||||||
+276
@@ -0,0 +1,276 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.backend.common.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.WrappedDeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
|
import org.jetbrains.kotlin.ir.util.IrExtensionGenerator
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.library.IrLibrary
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
internal fun IrSymbol.kind(): BinarySymbolData.SymbolKind {
|
||||||
|
return when (this) {
|
||||||
|
is IrClassSymbol -> BinarySymbolData.SymbolKind.CLASS_SYMBOL
|
||||||
|
is IrConstructorSymbol -> BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL
|
||||||
|
is IrSimpleFunctionSymbol -> BinarySymbolData.SymbolKind.FUNCTION_SYMBOL
|
||||||
|
is IrPropertySymbol -> BinarySymbolData.SymbolKind.PROPERTY_SYMBOL
|
||||||
|
is IrEnumEntrySymbol -> BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL
|
||||||
|
is IrTypeAliasSymbol -> BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL
|
||||||
|
else -> error("Unexpected symbol kind $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor) {
|
||||||
|
abstract operator fun contains(idSig: IdSignature): Boolean
|
||||||
|
abstract fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol
|
||||||
|
|
||||||
|
open fun declareIrSymbol(symbol: IrSymbol) {
|
||||||
|
assert(symbol.isPublicApi)
|
||||||
|
assert(symbol.descriptor !is WrappedDeclarationDescriptor<*>)
|
||||||
|
deserializeIrSymbol(symbol.signature, symbol.kind())
|
||||||
|
}
|
||||||
|
|
||||||
|
open val klib: IrLibrary get() = error("Unsupported operation")
|
||||||
|
|
||||||
|
open fun init() = init(this)
|
||||||
|
|
||||||
|
open fun init(delegate: IrModuleDeserializer) {}
|
||||||
|
|
||||||
|
open fun addModuleReachableTopLevel(idSig: IdSignature) { error("Unsupported Operation (sig: $idSig") }
|
||||||
|
|
||||||
|
open fun deserializeReachableDeclarations() { error("Unsupported Operation") }
|
||||||
|
|
||||||
|
open fun postProcess() {}
|
||||||
|
|
||||||
|
abstract val moduleFragment: IrModuleFragment
|
||||||
|
|
||||||
|
abstract val moduleDependencies: Collection<IrModuleDeserializer>
|
||||||
|
|
||||||
|
open val strategy: DeserializationStrategy = DeserializationStrategy.ONLY_DECLARATION_HEADERS
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to resolve built in symbols like `kotlin.ir.internal.*` or `kotlin.FunctionN`
|
||||||
|
class IrModuleDeserializerWithBuiltIns(
|
||||||
|
private val builtIns: IrBuiltIns,
|
||||||
|
private val functionFactory: IrAbstractFunctionFactory,
|
||||||
|
private val delegate: IrModuleDeserializer
|
||||||
|
) : IrModuleDeserializer(delegate.moduleDescriptor) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
// TODO: figure out how it should work for K/N
|
||||||
|
// assert(builtIns.builtIns.builtInsModule === delegate.moduleDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val irBuiltInsMap = builtIns.knownBuiltins.map {
|
||||||
|
val symbol = (it as IrSymbolOwner).symbol
|
||||||
|
symbol.signature to symbol
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
private fun checkIsFunctionInterface(idSig: IdSignature): Boolean {
|
||||||
|
val publicSig = idSig.asPublic() ?: return false
|
||||||
|
|
||||||
|
if (publicSig.packageFqn !in functionalPackages) return false
|
||||||
|
|
||||||
|
val declarationFqn = publicSig.declarationFqn
|
||||||
|
|
||||||
|
if (declarationFqn.isRoot) return false
|
||||||
|
|
||||||
|
val fqnParts = declarationFqn.pathSegments()
|
||||||
|
|
||||||
|
val className = fqnParts.first()
|
||||||
|
|
||||||
|
return functionPattern.matcher(className.asString()).find()
|
||||||
|
}
|
||||||
|
|
||||||
|
override operator fun contains(idSig: IdSignature): Boolean {
|
||||||
|
if (idSig in irBuiltInsMap) return true
|
||||||
|
|
||||||
|
return checkIsFunctionInterface(idSig) || idSig in delegate
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeReachableDeclarations() {
|
||||||
|
delegate.deserializeReachableDeclarations()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun computeFunctionDescriptor(className: Name): FunctionClassDescriptor {
|
||||||
|
val nameString = className.asString()
|
||||||
|
val isK = nameString[0] == 'K'
|
||||||
|
val isSuspend = (if (isK) nameString[1] else nameString[0]) == 'S'
|
||||||
|
val arity = nameString.run { substring(indexOfFirst { it.isDigit() }).toInt(10) }
|
||||||
|
return functionFactory.run {
|
||||||
|
when {
|
||||||
|
isK && isSuspend -> kSuspendFunctionClassDescriptor(arity)
|
||||||
|
isK -> kFunctionClassDescriptor(arity)
|
||||||
|
isSuspend -> suspendFunctionClassDescriptor(arity)
|
||||||
|
else -> functionClassDescriptor(arity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveFunctionalInterface(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
val publicSig = idSig.asPublic() ?: error("$idSig has to be public")
|
||||||
|
|
||||||
|
val fqnParts = publicSig.declarationFqn.pathSegments()
|
||||||
|
val className = fqnParts.firstOrNull() ?: error("Expected class name for $idSig")
|
||||||
|
|
||||||
|
val functionDescriptor = computeFunctionDescriptor(className)
|
||||||
|
val topLevelSignature = IdSignature.PublicSignature(publicSig.packageFqn, FqName(className.asString()), null, publicSig.mask)
|
||||||
|
|
||||||
|
val functionClass = when (functionDescriptor.functionKind) {
|
||||||
|
FunctionClassDescriptor.Kind.KSuspendFunction -> functionFactory.kSuspendFunctionN(functionDescriptor.arity) { callback ->
|
||||||
|
declareClassFromLinker(functionDescriptor, topLevelSignature) { callback(it) }
|
||||||
|
}
|
||||||
|
FunctionClassDescriptor.Kind.KFunction -> functionFactory.kFunctionN(functionDescriptor.arity) { callback ->
|
||||||
|
declareClassFromLinker(functionDescriptor, topLevelSignature) { callback(it) }
|
||||||
|
}
|
||||||
|
FunctionClassDescriptor.Kind.SuspendFunction -> functionFactory.suspendFunctionN(functionDescriptor.arity) { callback ->
|
||||||
|
declareClassFromLinker(functionDescriptor, topLevelSignature) { callback(it) }
|
||||||
|
}
|
||||||
|
FunctionClassDescriptor.Kind.Function -> functionFactory.functionN(functionDescriptor.arity) { callback ->
|
||||||
|
declareClassFromLinker(functionDescriptor, topLevelSignature) { callback(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (fqnParts.size) {
|
||||||
|
1 -> functionClass.symbol.also { assert(symbolKind == BinarySymbolData.SymbolKind.CLASS_SYMBOL) }
|
||||||
|
2 -> {
|
||||||
|
val memberName = fqnParts[1]!!
|
||||||
|
functionClass.declarations.single { it is IrDeclarationWithName && it.name == memberName }.let {
|
||||||
|
(it as IrSymbolOwner).symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
3 -> {
|
||||||
|
assert(idSig is IdSignature.AccessorSignature)
|
||||||
|
assert(symbolKind == BinarySymbolData.SymbolKind.FUNCTION_SYMBOL)
|
||||||
|
val propertyName = fqnParts[1]!!
|
||||||
|
val accessorName = fqnParts[2]!!
|
||||||
|
functionClass.declarations.filterIsInstance<IrProperty>().single { it.name == propertyName }.let { p ->
|
||||||
|
p.getter?.let { g -> if (g.name == accessorName) return g.symbol }
|
||||||
|
p.setter?.let { s -> if (s.name == accessorName) return s.symbol }
|
||||||
|
error("No accessor found for signature $idSig")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> error("No member found for signature $idSig")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
irBuiltInsMap[idSig]?.let { return it }
|
||||||
|
|
||||||
|
if (checkIsFunctionInterface(idSig)) return resolveFunctionalInterface(idSig, symbolKind)
|
||||||
|
|
||||||
|
return delegate.deserializeIrSymbol(idSig, symbolKind)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postProcess() {
|
||||||
|
delegate.postProcess()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
delegate.init(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val klib: IrLibrary
|
||||||
|
get() = delegate.klib
|
||||||
|
|
||||||
|
override val strategy: DeserializationStrategy
|
||||||
|
get() = delegate.strategy
|
||||||
|
|
||||||
|
override fun addModuleReachableTopLevel(idSig: IdSignature) {
|
||||||
|
delegate.addModuleReachableTopLevel(idSig)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val moduleFragment: IrModuleFragment get() = delegate.moduleFragment
|
||||||
|
override val moduleDependencies: Collection<IrModuleDeserializer> get() = delegate.moduleDependencies
|
||||||
|
}
|
||||||
|
|
||||||
|
open class CurrentModuleDeserializer(
|
||||||
|
override val moduleFragment: IrModuleFragment,
|
||||||
|
override val moduleDependencies: Collection<IrModuleDeserializer>,
|
||||||
|
private val symbolTable: SymbolTable,
|
||||||
|
private val extensions: Collection<IrExtensionGenerator>
|
||||||
|
) : IrModuleDeserializer(moduleFragment.descriptor) {
|
||||||
|
override fun contains(idSig: IdSignature): Boolean = false // TODO:
|
||||||
|
|
||||||
|
override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
error("Unreachable execution: there could not be back-links")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun declareIrSymbol(symbol: IrSymbol) {
|
||||||
|
declareIrSymbolImpl(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun referenceParentDescriptor(descriptor: DeclarationDescriptor): IrSymbol {
|
||||||
|
return when (descriptor) {
|
||||||
|
is ClassDescriptor -> symbolTable.referenceClass(descriptor)
|
||||||
|
is PropertyDescriptor -> symbolTable.referenceProperty(descriptor)
|
||||||
|
is PackageFragmentDescriptor -> moduleFragment.files.single { it.symbol.descriptor === descriptor }.symbol
|
||||||
|
else -> error("Unexpected declaration parent $descriptor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun declareIrDeclaration(symbol: IrSymbol): IrDeclaration {
|
||||||
|
for (extension in extensions) {
|
||||||
|
extension.declare(symbol)?.let { return it }
|
||||||
|
}
|
||||||
|
|
||||||
|
return declareIrDeclarationDefault(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun declareIrDeclarationDefault(symbol: IrSymbol): IrDeclaration {
|
||||||
|
return when (symbol) {
|
||||||
|
is IrClassSymbol -> symbolTable.declareClass(offset, offset, IrDeclarationOrigin.DEFINED, symbol.descriptor)
|
||||||
|
is IrConstructorSymbol -> symbolTable.declareConstructor(offset, offset, IrDeclarationOrigin.DEFINED, symbol.descriptor)
|
||||||
|
is IrSimpleFunctionSymbol -> symbolTable.declareSimpleFunction(offset, offset, IrDeclarationOrigin.DEFINED, symbol.descriptor)
|
||||||
|
is IrPropertySymbol -> symbolTable.declareProperty(offset, offset, IrDeclarationOrigin.DEFINED, symbol.descriptor)
|
||||||
|
is IrTypeAliasSymbol -> TODO("Implement type alias $symbol")
|
||||||
|
is IrEnumEntrySymbol -> symbolTable.declareEnumEntry(offset, offset, IrDeclarationOrigin.DEFINED, symbol.descriptor)
|
||||||
|
else -> error("Unexpected symbol $symbol")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun declareIrSymbolImpl(symbol: IrSymbol): IrSymbolOwner {
|
||||||
|
if (symbol.isBound) return symbol.owner
|
||||||
|
val descriptor = symbol.descriptor
|
||||||
|
|
||||||
|
assert(descriptor !is WrappedDeclarationDescriptor<*>)
|
||||||
|
|
||||||
|
val accessor = descriptor as? PropertyAccessorDescriptor
|
||||||
|
|
||||||
|
val parent = descriptor.containingDeclaration ?: error("Expect non-root declaration $descriptor")
|
||||||
|
val parentDeclaration = declareIrSymbolImpl(referenceParentDescriptor(parent)) as IrDeclarationContainer
|
||||||
|
|
||||||
|
val declaredDeclaration = declareIrDeclaration(symbol).also {
|
||||||
|
it.parent = parentDeclaration
|
||||||
|
if (accessor != null) {
|
||||||
|
val property = accessor.correspondingProperty
|
||||||
|
val irProperty = declareIrSymbolImpl(referenceParentDescriptor(property)) as IrProperty
|
||||||
|
val irAccessor = it as IrSimpleFunction
|
||||||
|
irAccessor.correspondingPropertySymbol = irProperty.symbol
|
||||||
|
if (accessor === property.getter) irProperty.getter = irAccessor
|
||||||
|
if (accessor === property.setter) irProperty.setter = irAccessor
|
||||||
|
} else {
|
||||||
|
parentDeclaration.declarations.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return declaredDeclaration as IrSymbolOwner
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val offset = UNDEFINED_OFFSET
|
||||||
|
}
|
||||||
|
}
|
||||||
+305
-470
@@ -7,13 +7,12 @@ package org.jetbrains.kotlin.backend.common.serialization
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||||
import org.jetbrains.kotlin.ir.descriptors.*
|
import org.jetbrains.kotlin.ir.descriptors.*
|
||||||
@@ -26,139 +25,224 @@ import org.jetbrains.kotlin.ir.symbols.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.library.IrLibrary
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.protobuf.CodedInputStream
|
||||||
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance
|
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoFile
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrType as ProtoType
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrStatement as ProtoStatement
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrExpression as ProtoExpression
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrConstructorCall as ProtoConstructorCall
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual
|
import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature as ProtoIdSignature
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature as ProtoIdSignature
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrConstructorCall as ProtoConstructorCall
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrExpression as ProtoExpression
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoFile
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrStatement as ProtoStatement
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrType as ProtoType
|
||||||
|
|
||||||
abstract class KotlinIrLinker(
|
abstract class KotlinIrLinker(
|
||||||
|
private val currentModule: ModuleDescriptor?,
|
||||||
val logger: LoggingContext,
|
val logger: LoggingContext,
|
||||||
val builtIns: IrBuiltIns,
|
val builtIns: IrBuiltIns,
|
||||||
val symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
private val exportedDependencies: List<ModuleDescriptor>,
|
private val exportedDependencies: List<ModuleDescriptor>
|
||||||
private val forwardModuleDescriptor: ModuleDescriptor?
|
|
||||||
) : IrDeserializer {
|
) : IrDeserializer {
|
||||||
|
|
||||||
|
// Kotlin-MPP related data. Consider some refactoring
|
||||||
private val expectUniqIdToActualUniqId = mutableMapOf<IdSignature, IdSignature>()
|
private val expectUniqIdToActualUniqId = mutableMapOf<IdSignature, IdSignature>()
|
||||||
private val topLevelActualUniqItToDeserializer = mutableMapOf<IdSignature, IrModuleDeserializer>()
|
private val topLevelActualUniqItToDeserializer = mutableMapOf<IdSignature, IrModuleDeserializer>()
|
||||||
private val expectSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
private val expectSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
||||||
private val actualSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
private val actualSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
||||||
|
|
||||||
sealed class DeserializationState<T> {
|
private val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>()
|
||||||
val deserializedSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
|
||||||
|
|
||||||
operator fun contains(key: IdSignature) = key in deserializedSymbols
|
protected val deserializersForModules = mutableMapOf<ModuleDescriptor, IrModuleDeserializer>()
|
||||||
operator fun get(key: IdSignature): IrSymbol = deserializedSymbols[key] ?: error("No deserialized symbol found for $key")
|
|
||||||
|
|
||||||
abstract fun addIdSignature(key: IdSignature)
|
abstract inner class BasicIrModuleDeserializer(moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, override val strategy: DeserializationStrategy) :
|
||||||
abstract fun processPendingDeclarations(processor: (T) -> Unit)
|
IrModuleDeserializer(moduleDescriptor) {
|
||||||
|
|
||||||
class ModuleDeserializationState(val module: IrModuleDeserializer) :
|
private val fileToDeserializerMap = mutableMapOf<IrFile, IrDeserializerForFile>()
|
||||||
DeserializationState<IrModuleDeserializer.IrDeserializerForFile>() {
|
|
||||||
private val filesWithPendingTopLevels = mutableSetOf<IrModuleDeserializer.IrDeserializerForFile>()
|
|
||||||
|
|
||||||
fun enqueueFile(fileDeserializer: IrModuleDeserializer.IrDeserializerForFile) {
|
private inner class ModuleDeserializationState {
|
||||||
|
private val filesWithPendingTopLevels = mutableSetOf<IrDeserializerForFile>()
|
||||||
|
|
||||||
|
fun enqueueFile(fileDeserializer: IrDeserializerForFile) {
|
||||||
filesWithPendingTopLevels.add(fileDeserializer)
|
filesWithPendingTopLevels.add(fileDeserializer)
|
||||||
module.enqueueModule()
|
enqueueModule()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addIdSignature(key: IdSignature) {
|
fun addIdSignature(key: IdSignature) {
|
||||||
val fileDeserializer = module.moduleReversedFileIndex[key] ?: error("No file found for key $key")
|
val fileDeserializer = moduleReversedFileIndex[key] ?: error("No file found for key $key")
|
||||||
fileDeserializer.fileLocalDeserializationState.addIdSignature(key)
|
fileDeserializer.fileLocalDeserializationState.addIdSignature(key)
|
||||||
|
|
||||||
enqueueFile(fileDeserializer)
|
enqueueFile(fileDeserializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processPendingDeclarations(processor: (IrModuleDeserializer.IrDeserializerForFile) -> Unit) {
|
fun processPendingDeclarations() {
|
||||||
while (filesWithPendingTopLevels.isNotEmpty()) {
|
while (filesWithPendingTopLevels.isNotEmpty()) {
|
||||||
val pendingDeserializer = filesWithPendingTopLevels.first()
|
val pendingDeserializer = filesWithPendingTopLevels.first()
|
||||||
|
|
||||||
processor(pendingDeserializer)
|
pendingDeserializer.deserializeFileImplicitDataIfFirstUse()
|
||||||
|
pendingDeserializer.deserializeAllFileReachableTopLevel()
|
||||||
|
|
||||||
filesWithPendingTopLevels.remove(pendingDeserializer)
|
filesWithPendingTopLevels.remove(pendingDeserializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleDeserializationState(private val checker: (IdSignature) -> Boolean) : DeserializationState<IdSignature>() {
|
private val moduleDeserializationState = ModuleDeserializationState()
|
||||||
|
private val moduleReversedFileIndex = mutableMapOf<IdSignature, IrDeserializerForFile>()
|
||||||
|
override val moduleDependencies by lazy {
|
||||||
|
moduleDescriptor.allDependencyModules.filter { it != moduleDescriptor }.map { resolveModuleDeserializer(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun init(delegate: IrModuleDeserializer) {
|
||||||
|
val fileCount = klib.fileCount()
|
||||||
|
|
||||||
|
val files = ArrayList<IrFile>(fileCount)
|
||||||
|
|
||||||
|
for (i in 0 until fileCount) {
|
||||||
|
val fileStream = klib.file(i).codedInputStream
|
||||||
|
files.add(deserializeIrFile(ProtoFile.parseFrom(fileStream, newInstance()), i, delegate))
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleFragment.files.addAll(files)
|
||||||
|
|
||||||
|
fileToDeserializerMap.values.forEach { it.deserializeExpectActualMapping() }
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fix to topLevel checker
|
||||||
|
override fun contains(idSig: IdSignature): Boolean = idSig in moduleReversedFileIndex
|
||||||
|
|
||||||
|
override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
assert(idSig.isPublic)
|
||||||
|
|
||||||
|
val topLevelSignature = idSig.topLevelSignature()
|
||||||
|
val fileDeserializer = moduleReversedFileIndex[topLevelSignature]
|
||||||
|
?: error("No file for $topLevelSignature (@ $idSig) in module $moduleDescriptor")
|
||||||
|
|
||||||
|
val fileDeserializationState = fileDeserializer.fileLocalDeserializationState
|
||||||
|
|
||||||
|
fileDeserializationState.addIdSignature(topLevelSignature)
|
||||||
|
moduleDeserializationState.enqueueFile(fileDeserializer)
|
||||||
|
|
||||||
|
return fileDeserializationState.deserializedSymbols.getOrPut(idSig) {
|
||||||
|
// val descriptor = resolveSpecialSignature(idSig)
|
||||||
|
val symbol = referenceDeserializedSymbol(symbolKind, idSig)
|
||||||
|
|
||||||
|
handleExpectActualMapping(idSig, symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postProcess() {}
|
||||||
|
|
||||||
|
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
|
||||||
|
|
||||||
|
private fun deserializeIrFile(fileProto: ProtoFile, fileIndex: Int, moduleDeserializer: IrModuleDeserializer): IrFile {
|
||||||
|
|
||||||
|
val fileName = fileProto.fileEntry.name
|
||||||
|
|
||||||
|
val fileEntry = NaiveSourceBasedFileEntryImpl(fileName, fileProto.fileEntry.lineStartOffsetsList.toIntArray())
|
||||||
|
|
||||||
|
val fileDeserializer =
|
||||||
|
IrDeserializerForFile(fileProto.annotationList, fileProto.actualsList, fileIndex, !strategy.needBodies, strategy.inlineBodies, moduleDeserializer).apply {
|
||||||
|
|
||||||
|
// Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations.
|
||||||
|
// Thus we schedule their deserialization in deserializer's constructor.
|
||||||
|
fileProto.explicitlyExportedToCompilerList.forEach {
|
||||||
|
val symbolData = parseSymbolData(it)
|
||||||
|
val sig = deserializeIdSignature(symbolData.signatureId)
|
||||||
|
assert(!sig.isPackageSignature())
|
||||||
|
fileLocalDeserializationState.addIdSignature(sig.topLevelSignature())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val fqName = fileDeserializer.deserializeFqName(fileProto.fqNameList)
|
||||||
|
|
||||||
|
val packageFragmentDescriptor = EmptyPackageFragmentDescriptor(moduleDescriptor, fqName)
|
||||||
|
|
||||||
|
val symbol = IrFileSymbolImpl(packageFragmentDescriptor)
|
||||||
|
val file = IrFileImpl(fileEntry, symbol, fqName)
|
||||||
|
|
||||||
|
fileDeserializer.file = file
|
||||||
|
fileToDeserializerMap[file] = fileDeserializer
|
||||||
|
|
||||||
|
val fileSignatureIndex = fileProto.declarationIdList.map { fileDeserializer.deserializeIdSignature(it) to it }
|
||||||
|
|
||||||
|
fileSignatureIndex.forEach {
|
||||||
|
moduleReversedFileIndex.getOrPut(it.first) { fileDeserializer }
|
||||||
|
}
|
||||||
|
|
||||||
|
fileDeserializer.reversedSignatureIndex = fileSignatureIndex.toMap()
|
||||||
|
|
||||||
|
if (strategy.theWholeWorld) {
|
||||||
|
for (id in fileSignatureIndex) {
|
||||||
|
moduleDeserializationState.addIdSignature(id.first)
|
||||||
|
}
|
||||||
|
moduleDeserializationState.enqueueFile(fileDeserializer)
|
||||||
|
} else if (strategy.explicitlyExported) {
|
||||||
|
moduleDeserializationState.enqueueFile(fileDeserializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeReachableDeclarations() {
|
||||||
|
moduleDeserializationState.processPendingDeclarations()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun enqueueModule() {
|
||||||
|
modulesWithReachableTopLevels.add(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addModuleReachableTopLevel(idSig: IdSignature) {
|
||||||
|
moduleDeserializationState.addIdSignature(idSig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class IrDeserializerForFile(
|
||||||
|
private var annotations: List<ProtoConstructorCall>?,
|
||||||
|
private val actuals: List<ProtoActual>,
|
||||||
|
private val fileIndex: Int,
|
||||||
|
onlyHeaders: Boolean,
|
||||||
|
inlineBodies: Boolean,
|
||||||
|
private val moduleDeserializer: IrModuleDeserializer
|
||||||
|
) : IrFileDeserializer(logger, builtIns, symbolTable, !onlyHeaders) {
|
||||||
|
|
||||||
|
private var fileLoops = mutableMapOf<Int, IrLoopBase>()
|
||||||
|
|
||||||
|
lateinit var file: IrFile
|
||||||
|
|
||||||
|
private val irTypeCache = mutableMapOf<Int, IrType>()
|
||||||
|
|
||||||
|
override val deserializeInlineFunctions: Boolean = inlineBodies
|
||||||
|
|
||||||
|
var reversedSignatureIndex = emptyMap<IdSignature, Int>()
|
||||||
|
|
||||||
|
inner class FileDeserializationState {
|
||||||
private val reachableTopLevels = LinkedHashSet<IdSignature>()
|
private val reachableTopLevels = LinkedHashSet<IdSignature>()
|
||||||
|
val deserializedSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
||||||
|
|
||||||
private fun shouldBeProcessed(idSig: IdSignature): Boolean = checker(idSig)
|
fun addIdSignature(key: IdSignature) {
|
||||||
|
|
||||||
override fun addIdSignature(key: IdSignature) {
|
|
||||||
reachableTopLevels.add(key)
|
reachableTopLevels.add(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processPendingDeclarations(processor: (IdSignature) -> Unit) {
|
fun processPendingDeclarations() {
|
||||||
while (reachableTopLevels.isNotEmpty()) {
|
while (reachableTopLevels.isNotEmpty()) {
|
||||||
val reachableKey = reachableTopLevels.first()
|
val reachableKey = reachableTopLevels.first()
|
||||||
|
|
||||||
if (shouldBeProcessed(reachableKey)) {
|
|
||||||
val existedSymbol = deserializedSymbols[reachableKey]
|
val existedSymbol = deserializedSymbols[reachableKey]
|
||||||
if (existedSymbol == null || !existedSymbol.isBound) {
|
if (existedSymbol == null || !existedSymbol.isBound) {
|
||||||
processor(reachableKey)
|
val declaration = deserializeDeclaration(reachableKey)
|
||||||
}
|
file.declarations.add(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
reachableTopLevels.remove(reachableKey)
|
reachableTopLevels.remove(reachableKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected val globalDeserializationState = DeserializationState.SimpleDeserializationState { true }
|
val fileLocalDeserializationState = FileDeserializationState()
|
||||||
private val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>()
|
|
||||||
|
|
||||||
//TODO: This is Native specific. Eliminate me.
|
|
||||||
private val forwardDeclarations = mutableSetOf<IrSymbol>()
|
|
||||||
|
|
||||||
protected val deserializersForModules = mutableMapOf<ModuleDescriptor, IrModuleDeserializer>()
|
|
||||||
|
|
||||||
abstract inner class IrModuleDeserializer(
|
|
||||||
private val moduleDescriptor: ModuleDescriptor,
|
|
||||||
private val strategy: DeserializationStrategy) {
|
|
||||||
|
|
||||||
val fileToDeserializerMap = mutableMapOf<IrFile, IrDeserializerForFile>()
|
|
||||||
|
|
||||||
private val moduleDeserializationState = DeserializationState.ModuleDeserializationState(this)
|
|
||||||
val moduleReversedFileIndex = mutableMapOf<IdSignature, IrDeserializerForFile>()
|
|
||||||
private val moduleDependencies by lazy {
|
|
||||||
moduleDescriptor.allDependencyModules.filter { it != moduleDescriptor }.mapNotNull { resolveModuleDeserializer(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun containsIdSignature(idSig: IdSignature): Boolean = idSig in moduleReversedFileIndex
|
|
||||||
|
|
||||||
// This is a heavy initializer
|
|
||||||
val module = deserializeIrModuleHeader()
|
|
||||||
|
|
||||||
inner class IrDeserializerForFile(
|
|
||||||
private var annotations: List<ProtoConstructorCall>?,
|
|
||||||
private val actuals: List<ProtoActual>,
|
|
||||||
private val fileIndex: Int,
|
|
||||||
onlyHeaders: Boolean
|
|
||||||
) : IrFileDeserializer(logger, builtIns, symbolTable) {
|
|
||||||
|
|
||||||
private var fileLoops = mutableMapOf<Int, IrLoopBase>()
|
|
||||||
|
|
||||||
lateinit var file: IrFile
|
|
||||||
|
|
||||||
private val deserializeBodies: Boolean = !onlyHeaders
|
|
||||||
|
|
||||||
private val irTypeCache = mutableMapOf<Int, IrType>()
|
|
||||||
|
|
||||||
var reversedSignatureIndex = emptyMap<IdSignature, Int>()
|
|
||||||
|
|
||||||
val fileLocalDeserializationState = DeserializationState.SimpleDeserializationState {
|
|
||||||
moduleDeserializationState.deserializedSymbols[it]?.isBound != true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deserializeDeclaration(idSig: IdSignature): IrDeclaration {
|
fun deserializeDeclaration(idSig: IdSignature): IrDeclaration {
|
||||||
return deserializeDeclaration(loadTopLevelDeclarationProto(idSig), file)
|
return deserializeDeclaration(loadTopLevelDeclarationProto(idSig), file)
|
||||||
@@ -185,176 +269,77 @@ abstract class KotlinIrLinker(
|
|||||||
return reversedSignatureIndex[idSig] ?: error("Not found Idx for $idSig")
|
return reversedSignatureIndex[idSig] ?: error("Not found Idx for $idSig")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun readDeclaration(index: Int): CodedInputStream =
|
||||||
|
moduleDeserializer.klib.irDeclaration(index, fileIndex).codedInputStream
|
||||||
|
|
||||||
private fun loadTopLevelDeclarationProto(idSig: IdSignature): ProtoDeclaration {
|
private fun loadTopLevelDeclarationProto(idSig: IdSignature): ProtoDeclaration {
|
||||||
val idSigIndex = resolveSignatureIndex(idSig)
|
val idSigIndex = resolveSignatureIndex(idSig)
|
||||||
val stream = reader(moduleDescriptor, fileIndex, idSigIndex).codedInputStream
|
return ProtoDeclaration.parseFrom(readDeclaration(idSigIndex), newInstance())
|
||||||
return ProtoDeclaration.parseFrom(stream, newInstance())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun readType(index: Int): CodedInputStream =
|
||||||
|
moduleDeserializer.klib.type(index, fileIndex).codedInputStream
|
||||||
|
|
||||||
private fun loadTypeProto(index: Int): ProtoType {
|
private fun loadTypeProto(index: Int): ProtoType {
|
||||||
val stream = readType(moduleDescriptor, fileIndex, index).codedInputStream
|
return ProtoType.parseFrom(readType(index), newInstance())
|
||||||
return ProtoType.parseFrom(stream, newInstance())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun readSignature(index: Int): CodedInputStream =
|
||||||
|
moduleDeserializer.klib.signature(index, fileIndex).codedInputStream
|
||||||
|
|
||||||
private fun loadSignatureProto(index: Int): ProtoIdSignature {
|
private fun loadSignatureProto(index: Int): ProtoIdSignature {
|
||||||
val stream = readSignature(moduleDescriptor, fileIndex, index).codedInputStream
|
return ProtoIdSignature.parseFrom(readSignature(index), newInstance())
|
||||||
return ProtoIdSignature.parseFrom(stream, newInstance())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun readBody(index: Int): CodedInputStream =
|
||||||
|
moduleDeserializer.klib.body(index, fileIndex).codedInputStream
|
||||||
|
|
||||||
private fun loadStatementBodyProto(index: Int): ProtoStatement {
|
private fun loadStatementBodyProto(index: Int): ProtoStatement {
|
||||||
val stream = readBody(moduleDescriptor, fileIndex, index).codedInputStream
|
return ProtoStatement.parseFrom(readBody(index), newInstance())
|
||||||
return ProtoStatement.parseFrom(stream, newInstance())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadExpressionBodyProto(index: Int): ProtoExpression {
|
private fun loadExpressionBodyProto(index: Int): ProtoExpression {
|
||||||
val stream = readBody(moduleDescriptor, fileIndex, index).codedInputStream
|
return ProtoExpression.parseFrom(readBody(index), newInstance())
|
||||||
return ProtoExpression.parseFrom(stream, newInstance())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadStringProto(index: Int): String {
|
private fun loadStringProto(index: Int): String {
|
||||||
return String(readString(moduleDescriptor, fileIndex, index))
|
return String(moduleDeserializer.klib.string(index, fileIndex))
|
||||||
}
|
|
||||||
// TODO: this function allows passing descriptor for all kinds of symbols.
|
|
||||||
// It is incorrect.
|
|
||||||
private fun referenceDeserializedSymbol(
|
|
||||||
symbolKind: BinarySymbolData.SymbolKind,
|
|
||||||
idSignature: IdSignature,
|
|
||||||
descriptor: DeclarationDescriptor?
|
|
||||||
): IrSymbol {
|
|
||||||
fun checkDescriptorIsNull(symbolKind: BinarySymbolData.SymbolKind) {
|
|
||||||
assert(descriptor == null) { "Symbol with kind $symbolKind should not have non-wrapped descriptor" }
|
|
||||||
}
|
|
||||||
|
|
||||||
return symbolTable.run {
|
|
||||||
when (symbolKind) {
|
|
||||||
BinarySymbolData.SymbolKind.ANONYMOUS_INIT_SYMBOL -> {
|
|
||||||
checkDescriptorIsNull(symbolKind)
|
|
||||||
IrAnonymousInitializerSymbolImpl(WrappedClassDescriptor())
|
|
||||||
.also { require(idSignature.isLocal) }
|
|
||||||
}
|
|
||||||
// TODO: FunctionInterfaces
|
|
||||||
BinarySymbolData.SymbolKind.CLASS_SYMBOL -> referenceClassFromLinker(
|
|
||||||
descriptor as? ClassDescriptor ?: WrappedClassDescriptor(), idSignature
|
|
||||||
)
|
|
||||||
BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL -> referenceConstructorFromLinker(
|
|
||||||
descriptor as? ClassConstructorDescriptor ?: WrappedClassConstructorDescriptor(), idSignature
|
|
||||||
)
|
|
||||||
BinarySymbolData.SymbolKind.TYPE_PARAMETER_SYMBOL -> {
|
|
||||||
checkDescriptorIsNull(symbolKind)
|
|
||||||
referenceTypeParameterFromLinker(WrappedTypeParameterDescriptor(), idSignature)
|
|
||||||
}
|
|
||||||
BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL -> referenceEnumEntryFromLinker(
|
|
||||||
descriptor as? ClassDescriptor ?: WrappedEnumEntryDescriptor(), idSignature
|
|
||||||
)
|
|
||||||
BinarySymbolData.SymbolKind.STANDALONE_FIELD_SYMBOL -> {
|
|
||||||
checkDescriptorIsNull(symbolKind)
|
|
||||||
referenceFieldFromLinker(WrappedFieldDescriptor(), idSignature)
|
|
||||||
}
|
|
||||||
BinarySymbolData.SymbolKind.FIELD_SYMBOL -> {
|
|
||||||
checkDescriptorIsNull(symbolKind)
|
|
||||||
referenceFieldFromLinker(WrappedPropertyDescriptor(), idSignature)
|
|
||||||
}
|
|
||||||
//TODO: FunctionInterfaces
|
|
||||||
BinarySymbolData.SymbolKind.FUNCTION_SYMBOL -> referenceSimpleFunctionFromLinker(
|
|
||||||
descriptor as? FunctionDescriptor ?: WrappedSimpleFunctionDescriptor(), idSignature
|
|
||||||
)
|
|
||||||
BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL -> referenceTypeAliasFromLinker(
|
|
||||||
descriptor as? TypeAliasDescriptor ?: WrappedTypeAliasDescriptor(), idSignature
|
|
||||||
)
|
|
||||||
BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> referencePropertyFromLinker(
|
|
||||||
descriptor as? PropertyDescriptor ?: WrappedPropertyDescriptor(), idSignature
|
|
||||||
)
|
|
||||||
BinarySymbolData.SymbolKind.VARIABLE_SYMBOL -> {
|
|
||||||
checkDescriptorIsNull(symbolKind)
|
|
||||||
IrVariableSymbolImpl(WrappedVariableDescriptor())
|
|
||||||
}
|
|
||||||
BinarySymbolData.SymbolKind.VALUE_PARAMETER_SYMBOL -> {
|
|
||||||
checkDescriptorIsNull(symbolKind)
|
|
||||||
IrValueParameterSymbolImpl(WrappedValueParameterDescriptor())
|
|
||||||
}
|
|
||||||
BinarySymbolData.SymbolKind.RECEIVER_PARAMETER_SYMBOL -> IrValueParameterSymbolImpl(
|
|
||||||
descriptor as? ReceiverParameterDescriptor ?: WrappedReceiverParameterDescriptor()
|
|
||||||
)
|
|
||||||
BinarySymbolData.SymbolKind.LOCAL_DELEGATED_PROPERTY_SYMBOL -> {
|
|
||||||
checkDescriptorIsNull(symbolKind)
|
|
||||||
IrLocalDelegatedPropertySymbolImpl(WrappedVariableDescriptorWithAccessor())
|
|
||||||
}
|
|
||||||
else -> error("Unexpected classifier symbol kind: $symbolKind")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isGlobalIdSignature(isSignature: IdSignature): Boolean {
|
|
||||||
return isSignature in globalDeserializationState || isSpecialSignature(isSignature)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getModuleForTopLevelId(idSignature: IdSignature): IrModuleDeserializer? {
|
private fun getModuleForTopLevelId(idSignature: IdSignature): IrModuleDeserializer? {
|
||||||
if (containsIdSignature(idSignature)) return this@IrModuleDeserializer
|
if (idSignature in moduleDeserializer) return moduleDeserializer
|
||||||
return moduleDependencies.firstOrNull { it.containsIdSignature(idSignature) }
|
return moduleDeserializer.moduleDependencies.firstOrNull { idSignature in it }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getStateForID(isSignature: IdSignature): DeserializationState<*> {
|
private fun findModuleDeserializer(idSig: IdSignature): IrModuleDeserializer {
|
||||||
if (isSignature.isLocal) return fileLocalDeserializationState
|
assert(idSig.isPublic)
|
||||||
if (isGlobalIdSignature(isSignature)) return globalDeserializationState
|
|
||||||
return getModuleForTopLevelId(isSignature)?.moduleDeserializationState ?: handleNoModuleDeserializerFound(isSignature)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findDeserializationState(idSignature: IdSignature): DeserializationState<*> {
|
val topLevelSig = idSig.topLevelSignature()
|
||||||
if (idSignature.hasTopLevel) {
|
if (topLevelSig in moduleDeserializer) return moduleDeserializer
|
||||||
val topLevelSignature = idSignature.topLevelSignature()
|
return moduleDeserializer.moduleDependencies.firstOrNull { topLevelSig in it } ?: handleNoModuleDeserializerFound(idSig)
|
||||||
|
|
||||||
val topLevelDeserializationState = getStateForID(topLevelSignature)
|
|
||||||
|
|
||||||
if (topLevelSignature !in topLevelDeserializationState) {
|
|
||||||
topLevelDeserializationState.addIdSignature(topLevelSignature)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If topLevel declaration is module-public and current declaration iы not (e.g. value parameter)
|
|
||||||
// they should be processed via different tables
|
|
||||||
if (idSignature.isLocal) return fileLocalDeserializationState
|
|
||||||
|
|
||||||
return topLevelDeserializationState
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(idSignature.isLocal)
|
|
||||||
return fileLocalDeserializationState
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun referenceIrSymbolData(symbol: IrSymbol, signature: IdSignature) {
|
private fun referenceIrSymbolData(symbol: IrSymbol, signature: IdSignature) {
|
||||||
val deserializationState = findDeserializationState(signature)
|
assert(signature.isLocal)
|
||||||
deserializationState.deserializedSymbols.putIfAbsent(signature, symbol)
|
fileLocalDeserializationState.deserializedSymbols.putIfAbsent(signature, symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deserializeIrLocalSymbolData(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
assert(idSig.isLocal)
|
||||||
|
|
||||||
|
if (idSig.hasTopLevel) {
|
||||||
|
fileLocalDeserializationState.addIdSignature(idSig.topLevelSignature())
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileLocalDeserializationState.deserializedSymbols.getOrPut(idSig) {
|
||||||
|
referenceDeserializedSymbol(symbolKind, idSig)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrSymbolData(idSignature: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
private fun deserializeIrSymbolData(idSignature: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
val deserializationState = findDeserializationState(idSignature)
|
if (idSignature.isLocal) return deserializeIrLocalSymbolData(idSignature, symbolKind)
|
||||||
|
|
||||||
val symbol = deserializationState.deserializedSymbols.getOrPut(idSignature) {
|
return findModuleDeserializer(idSignature).deserializeIrSymbol(idSignature, symbolKind)
|
||||||
val descriptor = resolveSpecialSignature(idSignature)
|
|
||||||
|
|
||||||
// TODO: move this logic out there
|
|
||||||
postProcessPlatformSpecificDeclaration(idSignature, descriptor) {
|
|
||||||
val fdState = getStateForID(it)
|
|
||||||
assert(it.isPublic && it.topLevelSignature() == it)
|
|
||||||
if (it !in fdState) fdState.addIdSignature(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
val symbol = referenceDeserializedSymbol(symbolKind, idSignature, descriptor).let {
|
|
||||||
if (expectUniqIdToActualUniqId[idSignature] != null) wrapInDelegatedSymbol(it) else it
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idSignature in expectUniqIdToActualUniqId.keys) expectSymbols[idSignature] = symbol
|
|
||||||
if (idSignature in expectUniqIdToActualUniqId.values) actualSymbols[idSignature] = symbol
|
|
||||||
|
|
||||||
symbol
|
|
||||||
}
|
|
||||||
if (symbol.descriptor is ClassDescriptor &&
|
|
||||||
symbol.descriptor !is WrappedDeclarationDescriptor<*> &&
|
|
||||||
symbol.descriptor.module.isForwardDeclarationModule
|
|
||||||
) {
|
|
||||||
forwardDeclarations.add(symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
return symbol
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeIrSymbolToDeclare(code: Long): Pair<IrSymbol, IdSignature> {
|
override fun deserializeIrSymbolToDeclare(code: Long): Pair<IrSymbol, IdSignature> {
|
||||||
@@ -400,12 +385,12 @@ abstract class KotlinIrLinker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeStatementBody(index: Int): IrElement {
|
override fun deserializeStatementBody(index: Int): IrElement {
|
||||||
if (deserializeBodies) {
|
return if (deserializeBodies) {
|
||||||
val bodyData = loadStatementBodyProto(index)
|
val bodyData = loadStatementBodyProto(index)
|
||||||
return deserializeStatement(bodyData)
|
deserializeStatement(bodyData)
|
||||||
} else {
|
} else {
|
||||||
val errorType = IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT)
|
val errorType = IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||||
return IrBlockBodyImpl(-1, -1, listOf(IrErrorExpressionImpl(-1, -1, errorType, "Statement body is not deserialized yet")))
|
IrBlockBodyImpl(-1, -1, listOf(IrErrorExpressionImpl(-1, -1, errorType, "Statement body is not deserialized yet")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,241 +406,106 @@ abstract class KotlinIrLinker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeAllFileReachableTopLevel() {
|
fun deserializeAllFileReachableTopLevel() {
|
||||||
fileLocalDeserializationState.processPendingDeclarations {
|
fileLocalDeserializationState.processPendingDeclarations()
|
||||||
val declaration = deserializeDeclaration(it)
|
|
||||||
file.declarations.add(declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun deserializeIrFile(fileProto: ProtoFile, fileIndex: Int): IrFile {
|
|
||||||
|
|
||||||
val fileName = fileProto.fileEntry.name
|
|
||||||
|
|
||||||
val fileEntry = NaiveSourceBasedFileEntryImpl(fileName, fileProto.fileEntry.lineStartOffsetsList.toIntArray())
|
|
||||||
|
|
||||||
val fileDeserializer =
|
|
||||||
IrDeserializerForFile(fileProto.annotationList, fileProto.actualsList, fileIndex, !strategy.needBodies).apply {
|
|
||||||
|
|
||||||
// Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations.
|
|
||||||
// Thus we schedule their deserialization in deserializer's constructor.
|
|
||||||
fileProto.explicitlyExportedToCompilerList.forEach {
|
|
||||||
val symbolData = parseSymbolData(it)
|
|
||||||
val sig = deserializeIdSignature(symbolData.signatureId)
|
|
||||||
assert(!sig.isPackageSignature())
|
|
||||||
fileLocalDeserializationState.addIdSignature(sig.topLevelSignature())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val fqName = fileDeserializer.deserializeFqName(fileProto.fqNameList)
|
private val ByteArray.codedInputStream: CodedInputStream
|
||||||
|
|
||||||
val packageFragmentDescriptor = EmptyPackageFragmentDescriptor(moduleDescriptor, fqName)
|
|
||||||
|
|
||||||
val symbol = IrFileSymbolImpl(packageFragmentDescriptor)
|
|
||||||
val file = IrFileImpl(fileEntry, symbol, fqName)
|
|
||||||
|
|
||||||
fileDeserializer.file = file
|
|
||||||
fileToDeserializerMap[file] = fileDeserializer
|
|
||||||
|
|
||||||
val fileSignatureIndex = fileProto.declarationIdList.map { fileDeserializer.deserializeIdSignature(it) to it }
|
|
||||||
|
|
||||||
fileSignatureIndex.forEach {
|
|
||||||
moduleReversedFileIndex.getOrPut(it.first) { fileDeserializer }
|
|
||||||
}
|
|
||||||
|
|
||||||
fileDeserializer.reversedSignatureIndex = fileSignatureIndex.toMap()
|
|
||||||
|
|
||||||
if (strategy.theWholeWorld) {
|
|
||||||
for (id in fileSignatureIndex) {
|
|
||||||
moduleDeserializationState.addIdSignature(id.first)
|
|
||||||
}
|
|
||||||
moduleDeserializationState.enqueueFile(fileDeserializer)
|
|
||||||
} else if (strategy.explicitlyExported) {
|
|
||||||
moduleDeserializationState.enqueueFile(fileDeserializer)
|
|
||||||
}
|
|
||||||
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun deserializeIrModuleHeader(): IrModuleFragment {
|
|
||||||
val fileCount = readFileCount(moduleDescriptor)
|
|
||||||
|
|
||||||
val files = ArrayList<IrFile>(fileCount)
|
|
||||||
|
|
||||||
for (i in 0 until fileCount) {
|
|
||||||
files.add(deserializeIrFile(ProtoFile.parseFrom(readFile(moduleDescriptor, i), newInstance()), i))
|
|
||||||
}
|
|
||||||
|
|
||||||
return IrModuleFragmentImpl(moduleDescriptor, builtIns, files)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deserializeAllModuleReachableTopLevels() {
|
|
||||||
moduleDeserializationState.processPendingDeclarations { fileDeserializer ->
|
|
||||||
fileDeserializer.deserializeFileImplicitDataIfFirstUse()
|
|
||||||
fileDeserializer.deserializeAllFileReachableTopLevel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun enqueueModule() {
|
|
||||||
modulesWithReachableTopLevels.add(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addModuleReachableTopLevel(idSig: IdSignature) {
|
|
||||||
moduleDeserializationState.addIdSignature(idSig)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadKnownBuiltinSymbols() {
|
|
||||||
val globalDeserializedSymbols = globalDeserializationState.deserializedSymbols
|
|
||||||
builtIns.knownBuiltins.forEach {
|
|
||||||
val symbol = (it as IrSymbolOwner).symbol
|
|
||||||
val signature = symbol.signature
|
|
||||||
globalDeserializedSymbols[signature] = symbol
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
loadKnownBuiltinSymbols()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream
|
|
||||||
get() {
|
get() {
|
||||||
val codedInputStream = org.jetbrains.kotlin.protobuf.CodedInputStream.newInstance(this)
|
val codedInputStream = CodedInputStream.newInstance(this)
|
||||||
codedInputStream.setRecursionLimit(65535) // The default 64 is blatantly not enough for IR.
|
codedInputStream.setRecursionLimit(65535) // The default 64 is blatantly not enough for IR.
|
||||||
return codedInputStream
|
return codedInputStream
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun reader(moduleDescriptor: ModuleDescriptor, fileIndex: Int, idSigIndex: Int): ByteArray
|
protected open fun handleNoModuleDeserializerFound(idSignature: IdSignature): IrModuleDeserializer {
|
||||||
protected abstract fun readType(moduleDescriptor: ModuleDescriptor, fileIndex: Int, typeIndex: Int): ByteArray
|
|
||||||
protected abstract fun readSignature(moduleDescriptor: ModuleDescriptor, fileIndex: Int, signatureIndex: Int): ByteArray
|
|
||||||
protected abstract fun readString(moduleDescriptor: ModuleDescriptor, fileIndex: Int, stringIndex: Int): ByteArray
|
|
||||||
protected abstract fun readBody(moduleDescriptor: ModuleDescriptor, fileIndex: Int, bodyIndex: Int): ByteArray
|
|
||||||
protected abstract fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int): ByteArray
|
|
||||||
protected abstract fun readFileCount(moduleDescriptor: ModuleDescriptor): Int
|
|
||||||
|
|
||||||
protected open fun handleNoModuleDeserializerFound(idSignature: IdSignature): DeserializationState<*> {
|
|
||||||
error("Deserializer for declaration $idSignature is not found")
|
error("Deserializer for declaration $idSignature is not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun resolveModuleDeserializer(moduleDescriptor: ModuleDescriptor): IrModuleDeserializer? {
|
protected open fun resolveModuleDeserializer(moduleDescriptor: ModuleDescriptor): IrModuleDeserializer {
|
||||||
return deserializersForModules[moduleDescriptor] ?: error("No module deserializer found for $moduleDescriptor")
|
return deserializersForModules[moduleDescriptor] ?:
|
||||||
|
error("No module deserializer found for $moduleDescriptor")
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun createModuleDeserializer(
|
protected abstract fun createModuleDeserializer(
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
klib: IrLibrary?,
|
||||||
strategy: DeserializationStrategy,
|
strategy: DeserializationStrategy,
|
||||||
): IrModuleDeserializer
|
): IrModuleDeserializer
|
||||||
|
|
||||||
// TODO: the following code worths some refactoring in the nearest future
|
protected abstract val functionalInteraceFactory: IrAbstractFunctionFactory
|
||||||
|
|
||||||
private fun isSpecialSignature(idSig: IdSignature): Boolean {
|
protected abstract fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean
|
||||||
return isSpecialPlatformSignature(idSig) || isSpecialFunctionDescriptor(idSig)
|
|
||||||
}
|
// TODO: the following code worth some refactoring in the nearest future
|
||||||
private fun resolveSpecialSignature(idSig: IdSignature): DeclarationDescriptor? {
|
|
||||||
return resolvePlatformDescriptor(idSig) ?: resolveFunctionDescriptor(idSig)
|
private fun handleExpectActualMapping(idSig: IdSignature, rawSymbol: IrSymbol): IrSymbol {
|
||||||
|
val referencingSymbol = if (idSig in expectUniqIdToActualUniqId.keys) {
|
||||||
|
assert(idSig.run { IdSignature.Flags.IS_EXPECT.test() })
|
||||||
|
wrapInDelegatedSymbol(rawSymbol).also { expectSymbols[idSig] = it }
|
||||||
|
} else rawSymbol
|
||||||
|
|
||||||
|
if (idSig in expectUniqIdToActualUniqId.values) {
|
||||||
|
actualSymbols[idSig] = rawSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun resolvePlatformDescriptor(idSig: IdSignature): DeclarationDescriptor? = null
|
return referencingSymbol
|
||||||
protected open fun isSpecialPlatformSignature(idSig: IdSignature): Boolean = false
|
|
||||||
|
|
||||||
protected open fun postProcessPlatformSpecificDeclaration(idSig: IdSignature, descriptor: DeclarationDescriptor?, block: (IdSignature) -> Unit) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSpecialFunctionDescriptor(idSig: IdSignature): Boolean {
|
private fun referenceDeserializedSymbol(symbolKind: BinarySymbolData.SymbolKind, idSig: IdSignature): IrSymbol = symbolTable.run {
|
||||||
|
when (symbolKind) {
|
||||||
val publicSig = idSig.asPublic() ?: return false
|
BinarySymbolData.SymbolKind.ANONYMOUS_INIT_SYMBOL -> IrAnonymousInitializerSymbolImpl(WrappedClassDescriptor())
|
||||||
|
BinarySymbolData.SymbolKind.CLASS_SYMBOL -> referenceClassFromLinker(WrappedClassDescriptor(), idSig)
|
||||||
if (publicSig.packageFqn !in functionalPackages) return false
|
BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL -> referenceConstructorFromLinker(WrappedClassConstructorDescriptor(), idSig)
|
||||||
|
BinarySymbolData.SymbolKind.TYPE_PARAMETER_SYMBOL -> referenceTypeParameterFromLinker(WrappedTypeParameterDescriptor(), idSig)
|
||||||
val declarationFqn = publicSig.declarationFqn
|
BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL -> referenceEnumEntryFromLinker(WrappedEnumEntryDescriptor(), idSig)
|
||||||
|
BinarySymbolData.SymbolKind.STANDALONE_FIELD_SYMBOL -> referenceFieldFromLinker(WrappedFieldDescriptor(), idSig)
|
||||||
if (declarationFqn.isRoot) return false
|
BinarySymbolData.SymbolKind.FIELD_SYMBOL -> referenceFieldFromLinker(WrappedPropertyDescriptor(), idSig)
|
||||||
|
BinarySymbolData.SymbolKind.FUNCTION_SYMBOL -> referenceSimpleFunctionFromLinker(WrappedSimpleFunctionDescriptor(), idSig)
|
||||||
val fqnParts = declarationFqn.pathSegments()
|
BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL -> referenceTypeAliasFromLinker(WrappedTypeAliasDescriptor(), idSig)
|
||||||
|
BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> referencePropertyFromLinker(WrappedPropertyDescriptor(), idSig)
|
||||||
val className = fqnParts.first()
|
BinarySymbolData.SymbolKind.VARIABLE_SYMBOL -> IrVariableSymbolImpl(WrappedVariableDescriptor())
|
||||||
|
BinarySymbolData.SymbolKind.VALUE_PARAMETER_SYMBOL -> IrValueParameterSymbolImpl(WrappedValueParameterDescriptor())
|
||||||
return functionPattern.matcher(className.asString()).find()
|
BinarySymbolData.SymbolKind.RECEIVER_PARAMETER_SYMBOL -> IrValueParameterSymbolImpl(WrappedReceiverParameterDescriptor())
|
||||||
}
|
BinarySymbolData.SymbolKind.LOCAL_DELEGATED_PROPERTY_SYMBOL ->
|
||||||
|
IrLocalDelegatedPropertySymbolImpl(WrappedVariableDescriptorWithAccessor())
|
||||||
private fun resolveFunctionDescriptor(idSig: IdSignature): DeclarationDescriptor? {
|
else -> error("Unexpected classifier symbol kind: $symbolKind for signature $idSig")
|
||||||
if (isSpecialFunctionDescriptor(idSig)) {
|
|
||||||
val publicSig = idSig.asPublic() ?: error("$idSig has to be public")
|
|
||||||
|
|
||||||
val fqnParts = publicSig.declarationFqn.pathSegments()
|
|
||||||
val className = fqnParts.first()
|
|
||||||
val classDescriptor = builtIns.builtIns.getBuiltInClassByFqName(publicSig.packageFqn.child(className))
|
|
||||||
|
|
||||||
fun findMemberDescriptor(): DeclarationDescriptor {
|
|
||||||
val memberName = fqnParts[1]!!
|
|
||||||
val memberDescriptors = classDescriptor.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.CALLABLES).filter { d -> d.name == memberName }
|
|
||||||
|
|
||||||
return memberDescriptors.single()
|
|
||||||
}
|
|
||||||
return when (fqnParts.size) {
|
|
||||||
1 -> classDescriptor
|
|
||||||
2 -> findMemberDescriptor()
|
|
||||||
3 -> {
|
|
||||||
assert(idSig is IdSignature.AccessorSignature)
|
|
||||||
val propertyDescriptor = findMemberDescriptor() as PropertyDescriptor
|
|
||||||
val accessorName = fqnParts[2]
|
|
||||||
propertyDescriptor.accessors.single { it.name == accessorName }
|
|
||||||
}
|
|
||||||
else -> error("No member found for signature $idSig")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that descriptor shouldn't be processed by some backend-specific logic.
|
|
||||||
* For example, it is the case for Native interop libraries where there is no IR in libraries.
|
|
||||||
*/
|
|
||||||
protected open fun IdSignature.shouldBeDeserialized(): Boolean = true
|
|
||||||
|
|
||||||
private fun deserializeAllReachableTopLevels() {
|
private fun deserializeAllReachableTopLevels() {
|
||||||
do {
|
while (modulesWithReachableTopLevels.isNotEmpty()) {
|
||||||
val moduleDeserializer = modulesWithReachableTopLevels.first()
|
val moduleDeserializer = modulesWithReachableTopLevels.first()
|
||||||
modulesWithReachableTopLevels.remove(moduleDeserializer)
|
modulesWithReachableTopLevels.remove(moduleDeserializer)
|
||||||
|
|
||||||
moduleDeserializer.deserializeAllModuleReachableTopLevels()
|
moduleDeserializer.deserializeReachableDeclarations()
|
||||||
} while (modulesWithReachableTopLevels.isNotEmpty())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findDeserializedDeclarationForSymbol(symbol: IrSymbol): DeclarationDescriptor? {
|
private fun findDeserializedDeclarationForSymbol(symbol: IrSymbol): DeclarationDescriptor? {
|
||||||
require(symbol.isPublicApi)
|
assert(symbol.isPublicApi || symbol.descriptor.module === currentModule || platformSpecificSymbol(symbol))
|
||||||
|
|
||||||
val signature = symbol.signature
|
|
||||||
|
|
||||||
// This is Native specific. Try to eliminate.
|
|
||||||
if (!signature.shouldBeDeserialized()) return null
|
|
||||||
|
|
||||||
val descriptor = symbol.descriptor
|
val descriptor = symbol.descriptor
|
||||||
|
|
||||||
/*
|
val moduleDeserializer = resolveModuleDeserializer(descriptor.module)
|
||||||
Wrapped descriptors come from inside IrLinker. If a symbol with such a descriptor ends up here, this means we
|
|
||||||
have already looked for it in IrLinker and failed.
|
|
||||||
*/
|
|
||||||
if (descriptor is WrappedDeclarationDescriptor<*>) return null
|
|
||||||
|
|
||||||
if (descriptor is FunctionClassDescriptor || (descriptor.containingDeclaration is FunctionClassDescriptor)) {
|
// moduleDeserializer.deserializeIrSymbol(signature, symbol.kind())
|
||||||
return null
|
moduleDeserializer.declareIrSymbol(symbol)
|
||||||
}
|
|
||||||
|
|
||||||
val topLevelSignature = signature.topLevelSignature()
|
|
||||||
val moduleDeserializer = resolveModuleDeserializer(descriptor.module) ?: return null
|
|
||||||
|
|
||||||
moduleDeserializer.addModuleReachableTopLevel(topLevelSignature)
|
|
||||||
|
|
||||||
deserializeAllReachableTopLevels()
|
deserializeAllReachableTopLevels()
|
||||||
return descriptor
|
return descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun platformSpecificSymbol(symbol: IrSymbol): Boolean = false
|
||||||
|
|
||||||
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
|
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
|
||||||
|
|
||||||
if (!symbol.isPublicApi) return null
|
if (!symbol.isPublicApi) {
|
||||||
|
val descriptor = symbol.descriptor
|
||||||
|
if (descriptor is WrappedDeclarationDescriptor<*>) return null
|
||||||
|
if (!platformSpecificSymbol(symbol)) {
|
||||||
|
if (descriptor.module !== currentModule) return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!symbol.isBound) {
|
if (!symbol.isBound) {
|
||||||
findDeserializedDeclarationForSymbol(symbol) ?: return null
|
findDeserializedDeclarationForSymbol(symbol) ?: return null
|
||||||
@@ -672,54 +522,31 @@ abstract class KotlinIrLinker(
|
|||||||
return symbol.owner as IrDeclaration
|
return symbol.owner as IrDeclaration
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This is Native specific. Eliminate me.
|
protected open fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>, extensions: Collection<IrExtensionGenerator>): IrModuleDeserializer =
|
||||||
override fun declareForwardDeclarations() {
|
CurrentModuleDeserializer(moduleFragment, dependencies, symbolTable, extensions)
|
||||||
if (forwardModuleDescriptor == null) return
|
|
||||||
|
|
||||||
val packageFragments = forwardDeclarations.map { it.descriptor.findPackage() }.distinct()
|
override fun init(moduleFragment: IrModuleFragment?, extensions: Collection<IrExtensionGenerator>) {
|
||||||
|
if (moduleFragment != null) {
|
||||||
// We don't bother making a real IR module here, as we have no need in it any later.
|
val currentModuleDependencies = moduleFragment.descriptor.allDependencyModules.map {
|
||||||
// All we need is just to declare forward declarations in the symbol table
|
deserializersForModules[it] ?: error("No deserializer found for $it")
|
||||||
// In case you need a full fledged module, turn the forEach into a map and collect
|
|
||||||
// produced files into an IrModuleFragment.
|
|
||||||
|
|
||||||
packageFragments.forEach { packageFragment ->
|
|
||||||
val symbol = IrFileSymbolImpl(packageFragment)
|
|
||||||
val file = IrFileImpl(NaiveSourceBasedFileEntryImpl("forward declarations pseudo-file"), symbol)
|
|
||||||
val symbols = forwardDeclarations
|
|
||||||
.filter { !it.isBound }
|
|
||||||
.filter { it.descriptor.findPackage() == packageFragment }
|
|
||||||
val declarations = symbols.map {
|
|
||||||
|
|
||||||
val classDescriptor = it.descriptor as ClassDescriptor
|
|
||||||
val declaration = symbolTable.declareClass(
|
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
|
||||||
classDescriptor,
|
|
||||||
classDescriptor.modality
|
|
||||||
) { symbol: IrClassSymbol -> IrClassImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin, symbol) }
|
|
||||||
.also {
|
|
||||||
it.parent = file
|
|
||||||
}
|
}
|
||||||
declaration
|
val currentModuleDeserializer = createCurrentModuleDeserializer(moduleFragment, currentModuleDependencies, extensions)
|
||||||
|
deserializersForModules[moduleFragment.descriptor] =
|
||||||
}
|
maybeWrapWithBuiltInAndInit(moduleFragment.descriptor, currentModuleDeserializer)
|
||||||
file.declarations.addAll(declarations)
|
|
||||||
}
|
}
|
||||||
|
deserializersForModules.values.forEach { it.init() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initializeExpectActualLinker() {
|
fun postProcess() {
|
||||||
deserializersForModules.values.forEach {
|
deserializersForModules.values.forEach { it.postProcess() }
|
||||||
it.fileToDeserializerMap.values.forEach {
|
finalizeExpectActualLinker()
|
||||||
it.deserializeExpectActualMapping()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The issue here is that an expect can not trigger its actual deserialization by reachability
|
// The issue here is that an expect can not trigger its actual deserialization by reachability
|
||||||
// because the expect can not see the actual higher in the module dependency dag.
|
// because the expect can not see the actual higher in the module dependency dag.
|
||||||
// So we force deserialization of actuals for all deserialized expect symbols here.
|
// So we force deserialization of actuals for all deserialized expect symbols here.
|
||||||
fun finalizeExpectActualLinker() {
|
private fun finalizeExpectActualLinker() {
|
||||||
expectUniqIdToActualUniqId.filter{ topLevelActualUniqItToDeserializer[it.value] != null}.forEach {
|
expectUniqIdToActualUniqId.filter { topLevelActualUniqItToDeserializer[it.value] != null }.forEach {
|
||||||
val expectSymbol = expectSymbols[it.key]
|
val expectSymbol = expectSymbols[it.key]
|
||||||
val actualSymbol = actualSymbols[it.value]
|
val actualSymbol = actualSymbols[it.value]
|
||||||
if (expectSymbol != null && (actualSymbol == null || !actualSymbol.isBound)) {
|
if (expectSymbol != null && (actualSymbol == null || !actualSymbol.isBound)) {
|
||||||
@@ -752,16 +579,24 @@ abstract class KotlinIrLinker(
|
|||||||
|
|
||||||
fun deserializeIrModuleHeader(
|
fun deserializeIrModuleHeader(
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
kotlinLibrary: KotlinLibrary?,
|
||||||
deserializationStrategy: DeserializationStrategy = DeserializationStrategy.ONLY_REFERENCED
|
deserializationStrategy: DeserializationStrategy = DeserializationStrategy.ONLY_REFERENCED
|
||||||
): IrModuleFragment {
|
): IrModuleFragment {
|
||||||
val deserializerForModule = deserializersForModules.getOrPut(moduleDescriptor) {
|
val deserializerForModule = deserializersForModules.getOrPut(moduleDescriptor) {
|
||||||
createModuleDeserializer(moduleDescriptor, deserializationStrategy)
|
maybeWrapWithBuiltInAndInit(moduleDescriptor, createModuleDeserializer(moduleDescriptor, kotlinLibrary, deserializationStrategy))
|
||||||
}
|
}
|
||||||
// The IrModule and its IrFiles have been created during module initialization.
|
// The IrModule and its IrFiles have been created during module initialization.
|
||||||
return deserializerForModule.module
|
return deserializerForModule.moduleFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrModuleHeader(moduleDescriptor: ModuleDescriptor): IrModuleFragment? {
|
private fun maybeWrapWithBuiltInAndInit(
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
moduleDeserializer: IrModuleDeserializer
|
||||||
|
): IrModuleDeserializer =
|
||||||
|
if (isBuiltInModule(moduleDescriptor)) IrModuleDeserializerWithBuiltIns(builtIns, functionalInteraceFactory, moduleDeserializer)
|
||||||
|
else moduleDeserializer
|
||||||
|
|
||||||
|
fun deserializeIrModuleHeader(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?): IrModuleFragment {
|
||||||
// TODO: consider skip deserializing explicitly exported declarations for libraries.
|
// TODO: consider skip deserializing explicitly exported declarations for libraries.
|
||||||
// Now it's not valid because of all dependencies that must be computed.
|
// Now it's not valid because of all dependencies that must be computed.
|
||||||
val deserializationStrategy =
|
val deserializationStrategy =
|
||||||
@@ -770,23 +605,23 @@ abstract class KotlinIrLinker(
|
|||||||
} else {
|
} else {
|
||||||
DeserializationStrategy.EXPLICITLY_EXPORTED
|
DeserializationStrategy.EXPLICITLY_EXPORTED
|
||||||
}
|
}
|
||||||
return deserializeIrModuleHeader(moduleDescriptor, deserializationStrategy)
|
return deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, deserializationStrategy)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeFullModule(moduleDescriptor: ModuleDescriptor): IrModuleFragment =
|
fun deserializeFullModule(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?): IrModuleFragment =
|
||||||
deserializeIrModuleHeader(moduleDescriptor, DeserializationStrategy.ALL)
|
deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, DeserializationStrategy.ALL)
|
||||||
|
|
||||||
fun deserializeOnlyHeaderModule(moduleDescriptor: ModuleDescriptor): IrModuleFragment =
|
fun deserializeOnlyHeaderModule(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?): IrModuleFragment =
|
||||||
deserializeIrModuleHeader(moduleDescriptor, DeserializationStrategy.ONLY_DECLARATION_HEADERS)
|
deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, DeserializationStrategy.ONLY_DECLARATION_HEADERS)
|
||||||
|
|
||||||
fun getAllIrFiles(): List<IrFile> {
|
fun deserializeHeadersWithInlineBodies(moduleDescriptor: ModuleDescriptor, kotlinLibrary: KotlinLibrary?): IrModuleFragment =
|
||||||
return deserializersForModules.values.flatMap { it.module.files }
|
deserializeIrModuleHeader(moduleDescriptor, kotlinLibrary, DeserializationStrategy.WITH_INLINE_BODIES)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class DeserializationStrategy(val needBodies: Boolean, val explicitlyExported: Boolean, val theWholeWorld: Boolean) {
|
enum class DeserializationStrategy(val needBodies: Boolean, val explicitlyExported: Boolean, val theWholeWorld: Boolean, val inlineBodies: Boolean) {
|
||||||
ONLY_REFERENCED(true, false, false),
|
ONLY_REFERENCED(true, false, false, true),
|
||||||
ALL(true, true, true),
|
ALL(true, true, true, true),
|
||||||
EXPLICITLY_EXPORTED(true, true, false),
|
EXPLICITLY_EXPORTED(true, true, false, true),
|
||||||
ONLY_DECLARATION_HEADERS(false, false, false)
|
ONLY_DECLARATION_HEADERS(false, false, false, false),
|
||||||
|
WITH_INLINE_BODIES(false, false, false, true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ fun generateKLib(
|
|||||||
val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER)
|
val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER)
|
||||||
|
|
||||||
val icData: List<KotlinFileSerializedData>
|
val icData: List<KotlinFileSerializedData>
|
||||||
|
val serializedIrFiles: List<SerializedIrFile>?
|
||||||
|
|
||||||
if (incrementalDataProvider != null) {
|
if (incrementalDataProvider != null) {
|
||||||
val nonCompiledSources = files.map { VfsUtilCore.virtualToIoFile(it.virtualFile) to it }.toMap()
|
val nonCompiledSources = files.map { VfsUtilCore.virtualToIoFile(it.virtualFile) to it }.toMap()
|
||||||
@@ -124,8 +125,10 @@ fun generateKLib(
|
|||||||
}
|
}
|
||||||
|
|
||||||
icData = storage
|
icData = storage
|
||||||
|
serializedIrFiles = storage.map { it.irData }
|
||||||
} else {
|
} else {
|
||||||
icData = emptyList()
|
icData = emptyList()
|
||||||
|
serializedIrFiles = null
|
||||||
}
|
}
|
||||||
|
|
||||||
val depsDescriptors =
|
val depsDescriptors =
|
||||||
@@ -135,8 +138,13 @@ fun generateKLib(
|
|||||||
|
|
||||||
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
||||||
|
|
||||||
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files,
|
val irLinker = JsIrLinker(psi2IrContext.moduleDescriptor, emptyLoggingContext, psi2IrContext.irBuiltIns, psi2IrContext.symbolTable, serializedIrFiles)
|
||||||
deserializer = null, expectDescriptorToSymbol = expectDescriptorToSymbol)
|
|
||||||
|
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
|
||||||
|
irLinker.deserializeOnlyHeaderModule(depsDescriptors.getModuleDescriptor(it), it)
|
||||||
|
}
|
||||||
|
|
||||||
|
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, irLinker, expectDescriptorToSymbol)
|
||||||
|
|
||||||
moduleFragment.acceptVoid(ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc)))
|
moduleFragment.acceptVoid(ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc)))
|
||||||
|
|
||||||
@@ -193,22 +201,20 @@ fun loadIr(
|
|||||||
val irBuiltIns = psi2IrContext.irBuiltIns
|
val irBuiltIns = psi2IrContext.irBuiltIns
|
||||||
val symbolTable = psi2IrContext.symbolTable
|
val symbolTable = psi2IrContext.symbolTable
|
||||||
|
|
||||||
val deserializer = JsIrLinker(emptyLoggingContext, irBuiltIns, symbolTable)
|
val irLinker = JsIrLinker(psi2IrContext.moduleDescriptor, emptyLoggingContext, irBuiltIns, symbolTable, null)
|
||||||
|
|
||||||
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
|
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
|
||||||
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
|
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), it)
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.initializeExpectActualLinker()
|
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, mainModule.files, irLinker)
|
||||||
|
|
||||||
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, mainModule.files, deserializer)
|
|
||||||
|
|
||||||
// TODO: not sure whether this check should be enabled by default. Add configuration key for it.
|
// TODO: not sure whether this check should be enabled by default. Add configuration key for it.
|
||||||
val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc))
|
val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc))
|
||||||
moduleFragment.acceptVoid(mangleChecker)
|
moduleFragment.acceptVoid(mangleChecker)
|
||||||
irBuiltIns.knownBuiltins.forEach { it.acceptVoid(mangleChecker) }
|
irBuiltIns.knownBuiltins.forEach { it.acceptVoid(mangleChecker) }
|
||||||
|
|
||||||
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, deserializer)
|
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker)
|
||||||
}
|
}
|
||||||
is MainModule.Klib -> {
|
is MainModule.Klib -> {
|
||||||
val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModule.lib)
|
val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModule.lib)
|
||||||
@@ -224,7 +230,7 @@ fun loadIr(
|
|||||||
typeTranslator.constantValueGenerator = constantValueGenerator
|
typeTranslator.constantValueGenerator = constantValueGenerator
|
||||||
constantValueGenerator.typeTranslator = typeTranslator
|
constantValueGenerator.typeTranslator = typeTranslator
|
||||||
val irBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable)
|
val irBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable)
|
||||||
val deserializer = JsIrLinker(emptyLoggingContext, irBuiltIns, symbolTable)
|
val irLinker = JsIrLinker(null, emptyLoggingContext, irBuiltIns, symbolTable, null)
|
||||||
|
|
||||||
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
|
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
|
||||||
val strategy =
|
val strategy =
|
||||||
@@ -233,16 +239,16 @@ fun loadIr(
|
|||||||
else
|
else
|
||||||
DeserializationStrategy.EXPLICITLY_EXPORTED
|
DeserializationStrategy.EXPLICITLY_EXPORTED
|
||||||
|
|
||||||
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), strategy)
|
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), it, strategy)
|
||||||
}
|
}
|
||||||
deserializer.initializeExpectActualLinker()
|
|
||||||
val moduleFragment = deserializedModuleFragments.last()
|
val moduleFragment = deserializedModuleFragments.last()
|
||||||
|
|
||||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
irLinker.init(null, emptyList())
|
||||||
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings)
|
ExternalDependenciesGenerator(symbolTable, listOf(irLinker), configuration.languageVersionSettings).generateUnboundSymbolsAsDependencies()
|
||||||
.generateUnboundSymbolsAsDependencies()
|
irLinker.postProcess()
|
||||||
|
|
||||||
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, deserializer)
|
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,14 +272,15 @@ private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure): Gene
|
|||||||
fun GeneratorContext.generateModuleFragmentWithPlugins(
|
fun GeneratorContext.generateModuleFragmentWithPlugins(
|
||||||
project: Project,
|
project: Project,
|
||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
deserializer: IrDeserializer? = null,
|
irLinker: IrDeserializer,
|
||||||
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
|
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
|
||||||
): IrModuleFragment {
|
): IrModuleFragment {
|
||||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
|
||||||
val signaturer = IdSignatureDescriptor(JsManglerDesc)
|
val signaturer = IdSignatureDescriptor(JsManglerDesc)
|
||||||
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, signaturer)
|
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, signaturer)
|
||||||
|
|
||||||
for (extension in IrGenerationExtension.getInstances(project)) {
|
val extensions = IrGenerationExtension.getInstances(project)
|
||||||
|
|
||||||
|
for (extension in extensions) {
|
||||||
psi2Ir.addPostprocessingStep { module ->
|
psi2Ir.addPostprocessingStep { module ->
|
||||||
extension.generate(
|
extension.generate(
|
||||||
module,
|
module,
|
||||||
@@ -289,26 +296,9 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val moduleFragment =
|
return psi2Ir.generateModuleFragment(this, files, listOf(irLinker), expectDescriptorToSymbol, extensions)
|
||||||
psi2Ir.generateModuleFragment(
|
|
||||||
this,
|
|
||||||
files,
|
|
||||||
irProviders,
|
|
||||||
expectDescriptorToSymbol
|
|
||||||
)
|
|
||||||
return moduleFragment
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deserializer: IrDeserializer? = null, expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null): IrModuleFragment {
|
|
||||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
|
|
||||||
val mangler = JsManglerDesc
|
|
||||||
val signaturer = IdSignatureDescriptor(mangler)
|
|
||||||
return Psi2IrTranslator(
|
|
||||||
languageVersionSettings, configuration, signaturer
|
|
||||||
).generateModuleFragment(this, files, irProviders, expectDescriptorToSymbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun createBuiltIns(storageManager: StorageManager) = object : KotlinBuiltIns(storageManager) {}
|
private fun createBuiltIns(storageManager: StorageManager) = object : KotlinBuiltIns(storageManager) {}
|
||||||
internal val JsFactories = KlibMetadataFactories(::createBuiltIns, DynamicTypeDeserializer)
|
internal val JsFactories = KlibMetadataFactories(::createBuiltIns, DynamicTypeDeserializer)
|
||||||
|
|
||||||
|
|||||||
+30
-25
@@ -6,40 +6,45 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.CurrentModuleWithICDeserializer
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
|
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.IrModuleDeserializer
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker
|
import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrFunctionFactory
|
||||||
|
import org.jetbrains.kotlin.ir.util.IrExtensionGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.library.IrLibrary
|
||||||
|
import org.jetbrains.kotlin.library.SerializedIrFile
|
||||||
|
|
||||||
class JsIrLinker(logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable) :
|
class JsIrLinker(currentModule: ModuleDescriptor?, logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable, private val icData: List<SerializedIrFile>? = null) :
|
||||||
KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null) {
|
KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList()) {
|
||||||
|
|
||||||
override fun reader(moduleDescriptor: ModuleDescriptor, fileIndex: Int, idSigIndex: Int) =
|
override val functionalInteraceFactory: IrAbstractFunctionFactory = IrFunctionFactory(builtIns, symbolTable)
|
||||||
moduleDescriptor.kotlinLibrary.irDeclaration(idSigIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readType(moduleDescriptor: ModuleDescriptor, fileIndex: Int, typeIndex: Int) =
|
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
|
||||||
moduleDescriptor.kotlinLibrary.type(typeIndex, fileIndex)
|
moduleDescriptor === moduleDescriptor.builtIns.builtInsModule
|
||||||
|
|
||||||
override fun readSignature(moduleDescriptor: ModuleDescriptor, fileIndex: Int, signatureIndex: Int) =
|
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer =
|
||||||
moduleDescriptor.kotlinLibrary.signature(signatureIndex, fileIndex)
|
JsModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy)
|
||||||
|
|
||||||
override fun readString(moduleDescriptor: ModuleDescriptor, fileIndex: Int, stringIndex: Int) =
|
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy) :
|
||||||
moduleDescriptor.kotlinLibrary.string(stringIndex, fileIndex)
|
KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy)
|
||||||
|
|
||||||
override fun readBody(moduleDescriptor: ModuleDescriptor, fileIndex: Int, bodyIndex: Int) =
|
override fun createCurrentModuleDeserializer(
|
||||||
moduleDescriptor.kotlinLibrary.body(bodyIndex, fileIndex)
|
moduleFragment: IrModuleFragment,
|
||||||
|
dependencies: Collection<IrModuleDeserializer>,
|
||||||
override fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int) =
|
extensions: Collection<IrExtensionGenerator>
|
||||||
moduleDescriptor.kotlinLibrary.file(fileIndex)
|
): IrModuleDeserializer {
|
||||||
|
val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies, extensions)
|
||||||
override fun readFileCount(moduleDescriptor: ModuleDescriptor) =
|
icData?.let {
|
||||||
moduleDescriptor.kotlinLibrary.fileCount()
|
return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it) { lib ->
|
||||||
|
JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy)
|
||||||
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, strategy: DeserializationStrategy): IrModuleDeserializer =
|
}
|
||||||
JsModuleDeserializer(moduleDescriptor, strategy)
|
}
|
||||||
|
return currentModuleDeserializer
|
||||||
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, strategy: DeserializationStrategy) :
|
}
|
||||||
KotlinIrLinker.IrModuleDeserializer(moduleDescriptor, strategy)
|
|
||||||
}
|
}
|
||||||
+133
-38
@@ -6,51 +6,146 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.jvm.serialization
|
package org.jetbrains.kotlin.ir.backend.jvm.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
|
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
|
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
|
import org.jetbrains.kotlin.ir.util.IrExtensionGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.library.IrLibrary
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class JvmIrLinker(logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable) :
|
class JvmIrLinker(currentModule: ModuleDescriptor?, logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable, private val stubGenerator: DeclarationStubGenerator, private val manglerDesc: JvmManglerDesc) :
|
||||||
KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null) {
|
KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList()) {
|
||||||
|
|
||||||
override fun handleNoModuleDeserializerFound(idSignature: IdSignature): DeserializationState<*> {
|
override val functionalInteraceFactory: IrAbstractFunctionFactory = IrFunctionFactory(builtIns, symbolTable)
|
||||||
// TODO: Implement special java-module deserializer instead of this hack
|
|
||||||
return globalDeserializationState // !!!!!! Wrong, as external references will all have UniqId.NONE
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reader(moduleDescriptor: ModuleDescriptor, fileIndex: Int, idSigIndex: Int) =
|
private val javaName = Name.identifier("java")
|
||||||
moduleDescriptor.kotlinLibrary.irDeclaration(idSigIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readType(moduleDescriptor: ModuleDescriptor, fileIndex: Int, typeIndex: Int) =
|
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
|
||||||
moduleDescriptor.kotlinLibrary.type(typeIndex, fileIndex)
|
moduleDescriptor.name.asString() == "<built-ins module>"
|
||||||
|
|
||||||
override fun readSignature(moduleDescriptor: ModuleDescriptor, fileIndex: Int, signatureIndex: Int) =
|
|
||||||
moduleDescriptor.kotlinLibrary.signature(signatureIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readString(moduleDescriptor: ModuleDescriptor, fileIndex: Int, stringIndex: Int) =
|
|
||||||
moduleDescriptor.kotlinLibrary.string(stringIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readBody(moduleDescriptor: ModuleDescriptor, fileIndex: Int, bodyIndex: Int) =
|
|
||||||
moduleDescriptor.kotlinLibrary.body(bodyIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int) =
|
|
||||||
moduleDescriptor.kotlinLibrary.file(fileIndex)
|
|
||||||
|
|
||||||
override fun readFileCount(moduleDescriptor: ModuleDescriptor) =
|
|
||||||
moduleDescriptor.kotlinLibrary.fileCount()
|
|
||||||
|
|
||||||
override fun resolveModuleDeserializer(moduleDescriptor: ModuleDescriptor): IrModuleDeserializer? {
|
|
||||||
return deserializersForModules[moduleDescriptor]
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: implement special Java deserializer
|
// TODO: implement special Java deserializer
|
||||||
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, strategy: DeserializationStrategy): IrModuleDeserializer =
|
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {
|
||||||
JvmModuleDeserializer(moduleDescriptor, strategy)
|
if (klib != null) {
|
||||||
|
assert(moduleDescriptor.getCapability(KlibModuleOrigin.CAPABILITY) != null)
|
||||||
|
return JvmModuleDeserializer(moduleDescriptor, klib, strategy)
|
||||||
|
}
|
||||||
|
|
||||||
private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, strategy: DeserializationStrategy) :
|
return MetadataJVMModuleDeserializer(moduleDescriptor, emptyList())
|
||||||
KotlinIrLinker.IrModuleDeserializer(moduleDescriptor, strategy)
|
}
|
||||||
|
|
||||||
|
private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy) :
|
||||||
|
KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy)
|
||||||
|
|
||||||
|
private fun DeclarationDescriptor.isJavaDescriptor(): Boolean {
|
||||||
|
if (this is PackageFragmentDescriptor) {
|
||||||
|
return this is LazyJavaPackageFragment || fqName.startsWith(javaName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this is JavaClassDescriptor || this is JavaCallableMemberDescriptor || (containingDeclaration?.isJavaDescriptor() == true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DeclarationDescriptor.isCleanDescriptor(): Boolean {
|
||||||
|
if (this is PropertyAccessorDescriptor) return correspondingProperty.isCleanDescriptor()
|
||||||
|
return this is DeserializedDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun platformSpecificSymbol(symbol: IrSymbol): Boolean {
|
||||||
|
return symbol.descriptor.isJavaDescriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun declareJavaFieldStub(symbol: IrFieldSymbol): IrField {
|
||||||
|
return with(stubGenerator) {
|
||||||
|
val old = stubGenerator.unboundSymbolGeneration
|
||||||
|
try {
|
||||||
|
stubGenerator.unboundSymbolGeneration = true
|
||||||
|
generateFieldStub(symbol.descriptor)
|
||||||
|
} finally {
|
||||||
|
stubGenerator.unboundSymbolGeneration = old
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>, extensions: Collection<IrExtensionGenerator>): IrModuleDeserializer =
|
||||||
|
JvmCurrentModuleDeserializer(moduleFragment, dependencies, extensions)
|
||||||
|
|
||||||
|
private inner class JvmCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>, extensions: Collection<IrExtensionGenerator>) :
|
||||||
|
CurrentModuleDeserializer(moduleFragment, dependencies, symbolTable, extensions) {
|
||||||
|
override fun declareIrSymbol(symbol: IrSymbol) {
|
||||||
|
val descriptor = symbol.descriptor
|
||||||
|
|
||||||
|
if (descriptor.isJavaDescriptor()) {
|
||||||
|
// Wrap java declaration with lazy ir
|
||||||
|
if (symbol is IrFieldSymbol) {
|
||||||
|
declareJavaFieldStub(symbol)
|
||||||
|
} else {
|
||||||
|
stubGenerator.generateMemberStub(descriptor)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor.isCleanDescriptor()) {
|
||||||
|
stubGenerator.generateMemberStub(descriptor)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
super.declareIrSymbol(symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class MetadataJVMModuleDeserializer(moduleDescriptor: ModuleDescriptor, dependencies: List<IrModuleDeserializer>) :
|
||||||
|
IrModuleDeserializer(moduleDescriptor) {
|
||||||
|
|
||||||
|
// TODO: implement proper check whether `idSig` belongs to this module
|
||||||
|
override fun contains(idSig: IdSignature): Boolean = true
|
||||||
|
|
||||||
|
private val descriptorFinder = DescriptorByIdSignatureFinder(moduleDescriptor, manglerDesc)
|
||||||
|
|
||||||
|
private fun resolveDescriptor(idSig: IdSignature): DeclarationDescriptor {
|
||||||
|
return descriptorFinder.findDescriptorBySignature(idSig) ?: error("No descriptor found for $idSig")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
val descriptor = resolveDescriptor(idSig)
|
||||||
|
|
||||||
|
val declaration = stubGenerator.run {
|
||||||
|
when (symbolKind) {
|
||||||
|
BinarySymbolData.SymbolKind.CLASS_SYMBOL -> generateClassStub(descriptor as ClassDescriptor)
|
||||||
|
BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> generatePropertyStub(descriptor as PropertyDescriptor)
|
||||||
|
BinarySymbolData.SymbolKind.FUNCTION_SYMBOL -> generateFunctionStub(descriptor as FunctionDescriptor)
|
||||||
|
BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL -> generateConstructorStub(descriptor as ClassConstructorDescriptor)
|
||||||
|
BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL -> generateEnumEntryStub(descriptor as ClassDescriptor)
|
||||||
|
BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL -> generateTypeAliasStub(descriptor as TypeAliasDescriptor)
|
||||||
|
else -> error("Unexpected type $symbolKind for sig $idSig")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return declaration.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun declareIrSymbol(symbol: IrSymbol) {
|
||||||
|
assert(symbol.isPublicApi || symbol.descriptor.isJavaDescriptor())
|
||||||
|
if (symbol is IrFieldSymbol) {
|
||||||
|
declareJavaFieldStub(symbol)
|
||||||
|
} else {
|
||||||
|
stubGenerator.generateMemberStub(symbol.descriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
|
||||||
|
override val moduleDependencies: Collection<IrModuleDeserializer> = dependencies
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.config.languageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
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.lower.serialization.ir.JsManglerDesc
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
||||||
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
|
||||||
@@ -58,14 +57,15 @@ class JsCoreScriptingCompiler(
|
|||||||
if (messageCollector.hasErrors()) return ReplCompileResult.Error("Error while analysis")
|
if (messageCollector.hasErrors()) return ReplCompileResult.Error("Error while analysis")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val files = listOf(snippetKtFile)
|
||||||
val module = analysisResult.moduleDescriptor
|
val module = analysisResult.moduleDescriptor
|
||||||
val bindingContext = analysisResult.bindingContext
|
val bindingContext = analysisResult.bindingContext
|
||||||
val mangler = JsManglerDesc
|
val mangler = JsManglerDesc
|
||||||
val signaturer = IdSignatureDescriptor(mangler)
|
val signaturer = IdSignatureDescriptor(mangler)
|
||||||
val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, signaturer = signaturer)
|
val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, signaturer = signaturer)
|
||||||
val psi2irContext = psi2ir.createGeneratorContext(module, bindingContext, symbolTable)
|
val psi2irContext = psi2ir.createGeneratorContext(module, bindingContext, symbolTable)
|
||||||
|
val providers = generateTypicalIrProviderList(module, psi2irContext.irBuiltIns, psi2irContext.symbolTable)
|
||||||
val irModuleFragment = psi2irContext.generateModuleFragment(listOf(snippetKtFile))
|
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, providers, null) // TODO: deserializer
|
||||||
|
|
||||||
val context = JsIrBackendContext(
|
val context = JsIrBackendContext(
|
||||||
irModuleFragment.descriptor,
|
irModuleFragment.descriptor,
|
||||||
|
|||||||
+3
-2
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.config.languageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.emptyLoggingContext
|
import org.jetbrains.kotlin.ir.backend.js.emptyLoggingContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.generateJsCode
|
import org.jetbrains.kotlin.ir.backend.js.generateJsCode
|
||||||
@@ -49,10 +50,10 @@ class JsScriptDependencyCompiler(
|
|||||||
|
|
||||||
val signaturer = IdSignatureDescriptor(JsManglerDesc)
|
val signaturer = IdSignatureDescriptor(JsManglerDesc)
|
||||||
val irBuiltIns = IrBuiltIns(builtIns, typeTranslator, signaturer, symbolTable)
|
val irBuiltIns = IrBuiltIns(builtIns, typeTranslator, signaturer, symbolTable)
|
||||||
val jsLinker = JsIrLinker(emptyLoggingContext, irBuiltIns, symbolTable)
|
val jsLinker = JsIrLinker(null, emptyLoggingContext, irBuiltIns, symbolTable, null)
|
||||||
|
|
||||||
val moduleFragment = IrModuleFragmentImpl(moduleDescriptor, irBuiltIns)
|
val moduleFragment = IrModuleFragmentImpl(moduleDescriptor, irBuiltIns)
|
||||||
val irDependencies = dependencies.map { jsLinker.deserializeFullModule(it) }
|
val irDependencies = dependencies.map { jsLinker.deserializeFullModule(it, it.kotlinLibrary) }
|
||||||
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer = jsLinker)
|
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer = jsLinker)
|
||||||
|
|
||||||
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings)
|
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings)
|
||||||
|
|||||||
Reference in New Issue
Block a user