[KLIB] Make K/N work with new linker
(cherry picked from commit 19a301ee517ad89e82e4b65347a6ff112042e781)
This commit is contained in:
committed by
Vasily Levchenko
parent
9021273001
commit
98ad71fc11
+170
-55
@@ -12,16 +12,24 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
|
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.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||||
import org.jetbrains.kotlin.ir.types.defaultType
|
import org.jetbrains.kotlin.ir.types.defaultType
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
internal object DECLARATION_ORIGIN_FUNCTION_CLASS : IrDeclarationOriginImpl("DECLARATION_ORIGIN_FUNCTION_CLASS")
|
internal object DECLARATION_ORIGIN_FUNCTION_CLASS : IrDeclarationOriginImpl("DECLARATION_ORIGIN_FUNCTION_CLASS")
|
||||||
@@ -30,10 +38,12 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
|||||||
var symbolTable: SymbolTable?,
|
var symbolTable: SymbolTable?,
|
||||||
private val irBuiltIns: IrBuiltIns,
|
private val irBuiltIns: IrBuiltIns,
|
||||||
private val reflectionTypes: KonanReflectionTypes
|
private val reflectionTypes: KonanReflectionTypes
|
||||||
) : IrProvider {
|
) : IrAbstractFunctionFactory(), IrProvider {
|
||||||
|
|
||||||
override fun getDeclaration(symbol: IrSymbol) =
|
override fun getDeclaration(symbol: IrSymbol) =
|
||||||
(symbol.descriptor as? FunctionClassDescriptor)?.let { buildClass(it) }
|
(symbol.descriptor as? FunctionClassDescriptor)?.let { descriptor ->
|
||||||
|
buildClass(descriptor) { declareClass(offset, offset, DECLARATION_ORIGIN_FUNCTION_CLASS, descriptor) }
|
||||||
|
}
|
||||||
|
|
||||||
var module: IrModuleFragment? = null
|
var module: IrModuleFragment? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -43,7 +53,7 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
|||||||
error("Module has already been set")
|
error("Module has already been set")
|
||||||
field = value
|
field = value
|
||||||
value.files += filesMap.values
|
value.files += filesMap.values
|
||||||
builtClasses.forEach { it.addFakeOverrides() }
|
// builtClasses.forEach { it.addFakeOverrides() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class FunctionalInterface(val irClass: IrClass, val arity: Int)
|
class FunctionalInterface(val irClass: IrClass, val arity: Int)
|
||||||
@@ -51,17 +61,36 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
|||||||
fun buildAllClasses() {
|
fun buildAllClasses() {
|
||||||
val maxArity = 255 // See [BuiltInFictitiousFunctionClassFactory].
|
val maxArity = 255 // See [BuiltInFictitiousFunctionClassFactory].
|
||||||
(0 .. maxArity).forEach { arity ->
|
(0 .. maxArity).forEach { arity ->
|
||||||
function(arity)
|
functionN(arity)
|
||||||
kFunction(arity)
|
kFunctionN(arity)
|
||||||
suspendFunction(arity)
|
suspendFunctionN(arity)
|
||||||
kSuspendFunction(arity)
|
kSuspendFunctionN(arity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun function(n: Int) = buildClass(irBuiltIns.builtIns.getFunction(n) as FunctionClassDescriptor)
|
override fun functionClassDescriptor(arity: Int): FunctionClassDescriptor =
|
||||||
fun kFunction(n: Int) = buildClass(reflectionTypes.getKFunction(n) as FunctionClassDescriptor)
|
irBuiltIns.builtIns.getFunction(arity) as FunctionClassDescriptor
|
||||||
fun suspendFunction(n: Int) = buildClass(irBuiltIns.builtIns.getSuspendFunction(n) as FunctionClassDescriptor)
|
|
||||||
fun kSuspendFunction(n: Int) = buildClass(reflectionTypes.getKSuspendFunction(n) as FunctionClassDescriptor)
|
override fun kFunctionClassDescriptor(arity: Int): FunctionClassDescriptor =
|
||||||
|
reflectionTypes.getKFunction(arity) as FunctionClassDescriptor
|
||||||
|
|
||||||
|
override fun suspendFunctionClassDescriptor(arity: Int): FunctionClassDescriptor =
|
||||||
|
irBuiltIns.builtIns.getSuspendFunction(arity) as FunctionClassDescriptor
|
||||||
|
|
||||||
|
override fun kSuspendFunctionClassDescriptor(arity: Int): FunctionClassDescriptor =
|
||||||
|
reflectionTypes.getKSuspendFunction(arity) as FunctionClassDescriptor
|
||||||
|
|
||||||
|
override fun functionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass =
|
||||||
|
buildClass(irBuiltIns.builtIns.getFunction(arity) as FunctionClassDescriptor, declarator)
|
||||||
|
|
||||||
|
override fun kFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass =
|
||||||
|
buildClass(reflectionTypes.getKFunction(arity) as FunctionClassDescriptor, declarator)
|
||||||
|
|
||||||
|
override fun suspendFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass =
|
||||||
|
buildClass(irBuiltIns.builtIns.getSuspendFunction(arity) as FunctionClassDescriptor, declarator)
|
||||||
|
|
||||||
|
override fun kSuspendFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass =
|
||||||
|
buildClass(reflectionTypes.getKSuspendFunction(arity) as FunctionClassDescriptor, declarator)
|
||||||
|
|
||||||
private val functionSymbol = symbolTable!!.referenceClass(
|
private val functionSymbol = symbolTable!!.referenceClass(
|
||||||
irBuiltIns.builtIns.builtInsModule.findClassAcrossModuleDependencies(
|
irBuiltIns.builtIns.builtInsModule.findClassAcrossModuleDependencies(
|
||||||
@@ -112,19 +141,16 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
|||||||
returnType
|
returnType
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createClass(descriptor: FunctionClassDescriptor) =
|
private val createClassLambda =
|
||||||
symbolTable?.declareClass(
|
{ s: IrClassSymbol -> IrClassImpl(offset, offset, DECLARATION_ORIGIN_FUNCTION_CLASS, s) }
|
||||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, DECLARATION_ORIGIN_FUNCTION_CLASS,
|
|
||||||
descriptor
|
|
||||||
)
|
|
||||||
?: IrClassImpl(
|
|
||||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, DECLARATION_ORIGIN_FUNCTION_CLASS,
|
|
||||||
IrClassSymbolImpl(descriptor)
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun buildClass(descriptor: FunctionClassDescriptor): IrClass =
|
private fun createClass(descriptor: FunctionClassDescriptor, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass {
|
||||||
|
return symbolTable?.declarator(createClassLambda) ?: createClassLambda(IrClassSymbolImpl(descriptor))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildClass(descriptor: FunctionClassDescriptor, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass =
|
||||||
builtClassesMap.getOrPut(descriptor) {
|
builtClassesMap.getOrPut(descriptor) {
|
||||||
createClass(descriptor).apply {
|
createClass(descriptor, declarator).apply {
|
||||||
val functionClass = this
|
val functionClass = this
|
||||||
typeParameters += descriptor.declaredTypeParameters.map { typeParameterDescriptor ->
|
typeParameters += descriptor.declaredTypeParameters.map { typeParameterDescriptor ->
|
||||||
createTypeParameter(typeParameterDescriptor).also {
|
createTypeParameter(typeParameterDescriptor).also {
|
||||||
@@ -142,7 +168,9 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
|||||||
makeTypeProjection(argumentClassifierSymbol.defaultType, argument.projectionKind)
|
makeTypeProjection(argumentClassifierSymbol.defaultType, argument.projectionKind)
|
||||||
}
|
}
|
||||||
val superTypeSymbol = when (val superTypeDescriptor = superType.constructor.declarationDescriptor) {
|
val superTypeSymbol = when (val superTypeDescriptor = superType.constructor.declarationDescriptor) {
|
||||||
is FunctionClassDescriptor -> buildClass(superTypeDescriptor).symbol
|
is FunctionClassDescriptor -> buildClass(superTypeDescriptor) {
|
||||||
|
declareClass(offset, offset, DECLARATION_ORIGIN_FUNCTION_CLASS, superTypeDescriptor)
|
||||||
|
}.symbol
|
||||||
functionSymbol.descriptor -> functionSymbol
|
functionSymbol.descriptor -> functionSymbol
|
||||||
kFunctionSymbol.descriptor -> kFunctionSymbol
|
kFunctionSymbol.descriptor -> kFunctionSymbol
|
||||||
else -> error("Unexpected super type: $superTypeDescriptor")
|
else -> error("Unexpected super type: $superTypeDescriptor")
|
||||||
@@ -155,40 +183,42 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
|||||||
val invokeFunctionDescriptor = descriptor.unsubstitutedMemberScope.getContributedFunctions(
|
val invokeFunctionDescriptor = descriptor.unsubstitutedMemberScope.getContributedFunctions(
|
||||||
OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND).single()
|
OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND).single()
|
||||||
val isFakeOverride = invokeFunctionDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
val isFakeOverride = invokeFunctionDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||||
val invokeFunctionOrigin =
|
if (!isFakeOverride) {
|
||||||
if (isFakeOverride)
|
val invokeFunctionOrigin =
|
||||||
IrDeclarationOrigin.FAKE_OVERRIDE
|
if (isFakeOverride)
|
||||||
else
|
IrDeclarationOrigin.FAKE_OVERRIDE
|
||||||
DECLARATION_ORIGIN_FUNCTION_CLASS
|
else
|
||||||
declarations += createSimpleFunction(
|
DECLARATION_ORIGIN_FUNCTION_CLASS
|
||||||
invokeFunctionDescriptor, invokeFunctionOrigin,
|
declarations += createSimpleFunction(
|
||||||
typeParameters.last().defaultType
|
invokeFunctionDescriptor, invokeFunctionOrigin,
|
||||||
).apply {
|
typeParameters.last().defaultType
|
||||||
parent = functionClass
|
).apply {
|
||||||
valueParameters += invokeFunctionDescriptor.valueParameters.map {
|
parent = functionClass
|
||||||
IrValueParameterImpl(
|
valueParameters += invokeFunctionDescriptor.valueParameters.map {
|
||||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
|
IrValueParameterImpl(
|
||||||
invokeFunctionOrigin,
|
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
|
||||||
it,
|
invokeFunctionOrigin,
|
||||||
functionClass.typeParameters[it.index].defaultType,
|
it,
|
||||||
null
|
functionClass.typeParameters[it.index].defaultType,
|
||||||
).also { it.parent = this }
|
null
|
||||||
}
|
).also { it.parent = this }
|
||||||
if (!isFakeOverride)
|
}
|
||||||
createDispatchReceiverParameter(invokeFunctionOrigin)
|
if (!isFakeOverride)
|
||||||
else {
|
createDispatchReceiverParameter(invokeFunctionOrigin)
|
||||||
val overriddenFunction = superTypes
|
else {
|
||||||
.mapNotNull { it.classOrNull?.owner }
|
val overriddenFunction = superTypes
|
||||||
.single { it.descriptor is FunctionClassDescriptor }
|
.mapNotNull { it.classOrNull?.owner }
|
||||||
.simpleFunctions()
|
.single { it.descriptor is FunctionClassDescriptor }
|
||||||
.single { it.name == OperatorNameConventions.INVOKE }
|
.simpleFunctions()
|
||||||
overriddenSymbols += overriddenFunction.symbol
|
.single { it.name == OperatorNameConventions.INVOKE }
|
||||||
dispatchReceiverParameter = overriddenFunction.dispatchReceiverParameter?.copyTo(this)
|
overriddenSymbols += overriddenFunction.symbol
|
||||||
|
dispatchReceiverParameter = overriddenFunction.dispatchReceiverParameter?.copyTo(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Unfortunately, addFakeOverrides() uses some parents but they are only set after PsiToIr phase.
|
// Unfortunately, addFakeOverrides() uses some parents but they are only set after PsiToIr phase.
|
||||||
// So we add all the fake overrides only when we're supplied with the module (this is done after PsiToIr).
|
// So we add all the fake overrides only when we're supplied with the module (this is done after PsiToIr).
|
||||||
if (this@BuiltInFictitiousFunctionIrClassFactory.module != null)
|
// if (this@BuiltInFictitiousFunctionIrClassFactory.module != null)
|
||||||
addFakeOverrides()
|
addFakeOverrides()
|
||||||
|
|
||||||
val packageFragmentDescriptor = descriptor.findPackage()
|
val packageFragmentDescriptor = descriptor.findPackage()
|
||||||
@@ -201,4 +231,89 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
|||||||
file.declarations += this
|
file.declarations += this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 functionDeclare = { s: IrSimpleFunctionSymbol ->
|
||||||
|
descriptor.run {
|
||||||
|
IrFunctionImpl(
|
||||||
|
offset, offset, memberOrigin, s, name, visibility, modality, returnType,
|
||||||
|
isInline, isExternal, isTailrec, isSuspend, isOperator, isExpect, true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val newFunction = symbolTable?.declareSimpleFunction(offset, offset, memberOrigin, descriptor, functionDeclare)
|
||||||
|
?: functionDeclare(IrSimpleFunctionSymbolImpl(descriptor))
|
||||||
|
|
||||||
|
newFunction.parent = this
|
||||||
|
newFunction.overriddenSymbols = descriptor.overriddenDescriptors.mapNotNull { 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 {
|
||||||
|
val propertyDeclare = { s: IrPropertySymbol ->
|
||||||
|
IrPropertyImpl(offset, offset, memberOrigin, s, descriptor.name)
|
||||||
|
}
|
||||||
|
val property = symbolTable?.declareProperty(offset, offset, memberOrigin, descriptor, propertyFactory = propertyDeclare)
|
||||||
|
?: propertyDeclare(IrPropertySymbolImpl(descriptor))
|
||||||
|
|
||||||
|
property.parent = this
|
||||||
|
property.getter = descriptor.getter?.let { g -> createFakeOverrideFunction(g, property.symbol) }
|
||||||
|
property.setter = descriptor.setter?.let { s -> createFakeOverrideFunction(s, property.symbol) }
|
||||||
|
|
||||||
|
return property
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+30
-32
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMo
|
|||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
|
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForInteropStubs
|
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
|
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||||
@@ -21,6 +20,8 @@ import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
|||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
|
||||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
@@ -144,8 +145,9 @@ internal val psiToIrPhase = konanUnitPhase(
|
|||||||
Psi2IrConfiguration(false), KonanIdSignaturer(KonanManglerDesc))
|
Psi2IrConfiguration(false), KonanIdSignaturer(KonanManglerDesc))
|
||||||
val generatorContext = translator.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable)
|
val generatorContext = translator.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable)
|
||||||
|
|
||||||
|
val pluginExtensions = IrGenerationExtension.getInstances(config.project)
|
||||||
|
|
||||||
translator.addPostprocessingStep { module ->
|
translator.addPostprocessingStep { module ->
|
||||||
val extensions = IrGenerationExtension.getInstances(config.project)
|
|
||||||
val pluginContext = IrPluginContext(
|
val pluginContext = IrPluginContext(
|
||||||
generatorContext.moduleDescriptor,
|
generatorContext.moduleDescriptor,
|
||||||
generatorContext.bindingContext,
|
generatorContext.bindingContext,
|
||||||
@@ -154,7 +156,7 @@ internal val psiToIrPhase = konanUnitPhase(
|
|||||||
generatorContext.typeTranslator,
|
generatorContext.typeTranslator,
|
||||||
generatorContext.irBuiltIns
|
generatorContext.irBuiltIns
|
||||||
)
|
)
|
||||||
extensions.forEach { extension ->
|
pluginExtensions.forEach { extension ->
|
||||||
extension.generate(module, pluginContext)
|
extension.generate(module, pluginContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,12 +169,25 @@ internal val psiToIrPhase = konanUnitPhase(
|
|||||||
// Note: using [llvmModuleSpecification] since this phase produces IR for generating single LLVM module.
|
// Note: using [llvmModuleSpecification] since this phase produces IR for generating single LLVM module.
|
||||||
|
|
||||||
val exportedDependencies = (getExportedDependencies() + modulesWithoutDCE).distinct()
|
val exportedDependencies = (getExportedDependencies() + modulesWithoutDCE).distinct()
|
||||||
|
val functionIrClassFactory = BuiltInFictitiousFunctionIrClassFactory(
|
||||||
|
symbolTable, generatorContext.irBuiltIns, reflectionTypes)
|
||||||
|
val stubGenerator = DeclarationStubGenerator(
|
||||||
|
moduleDescriptor, symbolTable,
|
||||||
|
config.configuration.languageVersionSettings
|
||||||
|
)
|
||||||
|
val symbols = KonanSymbols(this, symbolTable, symbolTable.lazyWrapper, functionIrClassFactory)
|
||||||
|
|
||||||
|
val irProviderForCEnumsAndCStructs =
|
||||||
|
IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols)
|
||||||
val deserializer = KonanIrLinker(
|
val deserializer = KonanIrLinker(
|
||||||
moduleDescriptor,
|
moduleDescriptor,
|
||||||
|
functionIrClassFactory,
|
||||||
this as LoggingContext,
|
this as LoggingContext,
|
||||||
generatorContext.irBuiltIns,
|
generatorContext.irBuiltIns,
|
||||||
symbolTable,
|
symbolTable,
|
||||||
forwardDeclarationsModuleDescriptor,
|
forwardDeclarationsModuleDescriptor,
|
||||||
|
stubGenerator,
|
||||||
|
irProviderForCEnumsAndCStructs,
|
||||||
exportedDependencies
|
exportedDependencies
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -190,40 +205,22 @@ internal val psiToIrPhase = konanUnitPhase(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (dependency in sortDependencies(dependencies)) {
|
for (dependency in sortDependencies(dependencies)) {
|
||||||
deserializer.deserializeIrModuleHeader(dependency)
|
val kotlinLibrary = dependency.getCapability(KlibModuleOrigin.CAPABILITY)?.let {
|
||||||
|
(it as? DeserializedKlibModuleOrigin)?.library
|
||||||
|
}
|
||||||
|
deserializer.deserializeIrModuleHeader(dependency, kotlinLibrary)
|
||||||
}
|
}
|
||||||
if (dependencies.size == dependenciesCount) break
|
if (dependencies.size == dependenciesCount) break
|
||||||
dependenciesCount = dependencies.size
|
dependenciesCount = dependencies.size
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.initializeExpectActualLinker()
|
|
||||||
|
|
||||||
val functionIrClassFactory = BuiltInFictitiousFunctionIrClassFactory(
|
|
||||||
symbolTable, generatorContext.irBuiltIns, reflectionTypes)
|
|
||||||
val symbols = KonanSymbols(this, symbolTable, symbolTable.lazyWrapper, functionIrClassFactory)
|
|
||||||
val stubGenerator = DeclarationStubGenerator(
|
|
||||||
moduleDescriptor, symbolTable,
|
|
||||||
config.configuration.languageVersionSettings
|
|
||||||
)
|
|
||||||
val irProviderForCEnumsAndCStructs = IrProviderForCEnumAndCStructStubs(
|
|
||||||
generatorContext, interopBuiltIns, symbols, llvmModuleSpecification::containsModule
|
|
||||||
)
|
|
||||||
// We need to run `buildAllEnumsAndStructsFrom` before `generateModuleFragment` because it adds references to symbolTable
|
// We need to run `buildAllEnumsAndStructsFrom` before `generateModuleFragment` because it adds references to symbolTable
|
||||||
// that should be bound.
|
// that should be bound.
|
||||||
modulesWithoutDCE
|
modulesWithoutDCE
|
||||||
.filter(ModuleDescriptor::isFromInteropLibrary)
|
.filter(ModuleDescriptor::isFromInteropLibrary)
|
||||||
.forEach(irProviderForCEnumsAndCStructs::buildAllEnumsAndStructsFrom)
|
.forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom)
|
||||||
val irProviderForInteropStubs = IrProviderForInteropStubs(
|
|
||||||
stubGenerator,
|
val irProviders = listOf(deserializer)
|
||||||
irProviderForCEnumsAndCStructs::canHandleSymbol
|
|
||||||
)
|
|
||||||
val irProviders = listOf(
|
|
||||||
irProviderForCEnumsAndCStructs,
|
|
||||||
irProviderForInteropStubs,
|
|
||||||
functionIrClassFactory,
|
|
||||||
deserializer,
|
|
||||||
stubGenerator
|
|
||||||
)
|
|
||||||
stubGenerator.setIrProviders(irProviders)
|
stubGenerator.setIrProviders(irProviders)
|
||||||
|
|
||||||
expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
||||||
@@ -238,14 +235,16 @@ internal val psiToIrPhase = konanUnitPhase(
|
|||||||
if (expectActualLinker) expectDescriptorToSymbol else null
|
if (expectActualLinker) expectDescriptorToSymbol else null
|
||||||
)
|
)
|
||||||
|
|
||||||
deserializer.finalizeExpectActualLinker()
|
deserializer.postProcess()
|
||||||
|
|
||||||
if (this.stdlibModule in modulesWithoutDCE) {
|
if (this.stdlibModule in modulesWithoutDCE) {
|
||||||
functionIrClassFactory.buildAllClasses()
|
functionIrClassFactory.buildAllClasses()
|
||||||
}
|
}
|
||||||
module.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc)))
|
|
||||||
|
|
||||||
module.files += irProviderForCEnumsAndCStructs.outputFiles
|
// Enable lazy IR genration for newly-created symbols inside BE
|
||||||
|
stubGenerator.unboundSymbolGeneration = true
|
||||||
|
|
||||||
|
module.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc)))
|
||||||
|
|
||||||
irModule = module
|
irModule = module
|
||||||
irModules = deserializer.modules.filterValues { llvmModuleSpecification.containsModule(it) }
|
irModules = deserializer.modules.filterValues { llvmModuleSpecification.containsModule(it) }
|
||||||
@@ -263,7 +262,6 @@ internal val psiToIrPhase = konanUnitPhase(
|
|||||||
internal val destroySymbolTablePhase = konanUnitPhase(
|
internal val destroySymbolTablePhase = konanUnitPhase(
|
||||||
op = {
|
op = {
|
||||||
this.symbolTable = null // TODO: invalidate symbolTable itself.
|
this.symbolTable = null // TODO: invalidate symbolTable itself.
|
||||||
ir.symbols.functionIrClassFactory.symbolTable = null
|
|
||||||
},
|
},
|
||||||
name = "DestroySymbolTable",
|
name = "DestroySymbolTable",
|
||||||
description = "Destroy SymbolTable",
|
description = "Destroy SymbolTable",
|
||||||
|
|||||||
+4
-4
@@ -514,13 +514,13 @@ internal class KonanSymbols(
|
|||||||
.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun functionN(n: Int) = functionIrClassFactory.function(n).symbol
|
override fun functionN(n: Int) = functionIrClassFactory.functionN(n).symbol
|
||||||
|
|
||||||
override fun suspendFunctionN(n: Int) = functionIrClassFactory.suspendFunction(n).symbol
|
override fun suspendFunctionN(n: Int) = functionIrClassFactory.suspendFunctionN(n).symbol
|
||||||
|
|
||||||
fun kFunctionN(n: Int) = functionIrClassFactory.kFunction(n).symbol
|
fun kFunctionN(n: Int) = functionIrClassFactory.kFunctionN(n).symbol
|
||||||
|
|
||||||
fun kSuspendFunctionN(n: Int) = functionIrClassFactory.kSuspendFunction(n).symbol
|
fun kSuspendFunctionN(n: Int) = functionIrClassFactory.kSuspendFunctionN(n).symbol
|
||||||
|
|
||||||
fun getKFunctionType(returnType: IrType, parameterTypes: List<IrType>) =
|
fun getKFunctionType(returnType: IrType, parameterTypes: List<IrType>) =
|
||||||
kFunctionN(parameterTypes.size).typeWith(parameterTypes + returnType)
|
kFunctionN(parameterTypes.size).typeWith(parameterTypes + returnType)
|
||||||
|
|||||||
+8
-6
@@ -160,9 +160,10 @@ internal fun ClassDescriptor.inheritsFromCStructVar(interopBuiltIns: InteropBuil
|
|||||||
* CEnum inheritor.
|
* CEnum inheritor.
|
||||||
*/
|
*/
|
||||||
internal fun IrSymbol.findCEnumDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? =
|
internal fun IrSymbol.findCEnumDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? =
|
||||||
descriptor.parentsWithSelf
|
descriptor.findCEnumDescriptor(interopBuiltIns)
|
||||||
.filterIsInstance<ClassDescriptor>()
|
|
||||||
.firstOrNull { it.implementsCEnum(interopBuiltIns) }
|
internal fun DeclarationDescriptor.findCEnumDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? =
|
||||||
|
parentsWithSelf.filterIsInstance<ClassDescriptor>().firstOrNull { it.implementsCEnum(interopBuiltIns) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All structs that come from interop library inherit from CStructVar class.
|
* All structs that come from interop library inherit from CStructVar class.
|
||||||
@@ -170,6 +171,7 @@ internal fun IrSymbol.findCEnumDescriptor(interopBuiltIns: InteropBuiltIns): Cla
|
|||||||
* CStructVar inheritor.
|
* CStructVar inheritor.
|
||||||
*/
|
*/
|
||||||
internal fun IrSymbol.findCStructDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? =
|
internal fun IrSymbol.findCStructDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? =
|
||||||
descriptor.parentsWithSelf
|
descriptor.findCStructDescriptor(interopBuiltIns)
|
||||||
.filterIsInstance<ClassDescriptor>()
|
|
||||||
.firstOrNull { it.inheritsFromCStructVar(interopBuiltIns) }
|
internal fun DeclarationDescriptor.findCStructDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? =
|
||||||
|
parentsWithSelf.filterIsInstance<ClassDescriptor>().firstOrNull { it.inheritsFromCStructVar(interopBuiltIns) }
|
||||||
+37
-63
@@ -4,28 +4,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.kotlin.backend.konan.ir.interop
|
package org.jetbrains.kotlin.backend.konan.ir.interop
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
|
||||||
import org.jetbrains.kotlin.backend.konan.InteropBuiltIns
|
import org.jetbrains.kotlin.backend.konan.InteropBuiltIns
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
|
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments
|
import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumByValueFunctionGenerator
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumByValueFunctionGenerator
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumClassGenerator
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumClassGenerator
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumCompanionGenerator
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumCompanionGenerator
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumVarClassGenerator
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumVarClassGenerator
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarClassGenerator
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarClassGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,23 +30,18 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
|||||||
* compiler phases.
|
* compiler phases.
|
||||||
* 2. It is an easier and more obvious approach. Since implementation of metadata-based
|
* 2. It is an easier and more obvious approach. Since implementation of metadata-based
|
||||||
* libraries generation already took too much time we take an easier approach here.
|
* libraries generation already took too much time we take an easier approach here.
|
||||||
*
|
|
||||||
* [moduleFilter] -- We want to select modules that should be part of compiler's output.
|
|
||||||
*
|
|
||||||
* For example, when we generate compiler cache,
|
|
||||||
* declarations from dependencies should not be added to the current module.
|
|
||||||
*/
|
*/
|
||||||
internal class IrProviderForCEnumAndCStructStubs(
|
internal class IrProviderForCEnumAndCStructStubs(
|
||||||
context: GeneratorContext,
|
context: GeneratorContext,
|
||||||
private val interopBuiltIns: InteropBuiltIns,
|
private val interopBuiltIns: InteropBuiltIns,
|
||||||
symbols: KonanSymbols,
|
symbols: KonanSymbols
|
||||||
private val moduleFilter: (ModuleDescriptor) -> Boolean
|
) {
|
||||||
) : IrProvider {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: integrate this provider into [KonanIrLinker.KonanInteropModuleDeserializer]
|
||||||
|
*/
|
||||||
private val symbolTable: SymbolTable = context.symbolTable
|
private val symbolTable: SymbolTable = context.symbolTable
|
||||||
|
|
||||||
private val filesMap = mutableMapOf<PackageFragmentDescriptor, IrFile>()
|
|
||||||
|
|
||||||
private val cEnumByValueFunctionGenerator =
|
private val cEnumByValueFunctionGenerator =
|
||||||
CEnumByValueFunctionGenerator(context, symbols)
|
CEnumByValueFunctionGenerator(context, symbols)
|
||||||
private val cEnumCompanionGenerator =
|
private val cEnumCompanionGenerator =
|
||||||
@@ -66,60 +53,47 @@ internal class IrProviderForCEnumAndCStructStubs(
|
|||||||
private val cStructClassGenerator =
|
private val cStructClassGenerator =
|
||||||
CStructVarClassGenerator(context, interopBuiltIns)
|
CStructVarClassGenerator(context, interopBuiltIns)
|
||||||
|
|
||||||
/**
|
fun isCEnumOrCStruct(declarationDescriptor: DeclarationDescriptor): Boolean =
|
||||||
* The final output of this provider is a list of files which contain IR declarations
|
declarationDescriptor.run { findCEnumDescriptor(interopBuiltIns) ?: findCStructDescriptor(interopBuiltIns) } != null
|
||||||
* of enums and structs that should be generated.
|
|
||||||
*/
|
|
||||||
val outputFiles: List<IrFile>
|
|
||||||
get() = filesMap.filterKeys { moduleFilter(it.module) }.values.toList()
|
|
||||||
|
|
||||||
fun canHandleSymbol(symbol: IrSymbol): Boolean {
|
fun referenceAllEnumsAndStructsFrom(interopModule: ModuleDescriptor) = interopModule.getPackageFragments()
|
||||||
if (!symbol.isPublicApi) return false
|
|
||||||
if (symbol.signature.run { !IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.test() }) return false
|
|
||||||
return symbol.findCEnumDescriptor(interopBuiltIns) != null
|
|
||||||
|| symbol.findCStructDescriptor(interopBuiltIns) != null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun buildAllEnumsAndStructsFrom(interopModule: ModuleDescriptor) = interopModule.getPackageFragments()
|
|
||||||
.flatMap { it.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) }
|
.flatMap { it.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) }
|
||||||
.filterIsInstance<ClassDescriptor>()
|
.filterIsInstance<ClassDescriptor>()
|
||||||
.forEach {
|
.filter { it.implementsCEnum(interopBuiltIns) || it.inheritsFromCStructVar(interopBuiltIns) }
|
||||||
when {
|
.forEach { symbolTable.referenceClass(it) }
|
||||||
it.implementsCEnum(interopBuiltIns) ->
|
|
||||||
cEnumClassGenerator.findOrGenerateCEnum(it, irParentFor(it))
|
|
||||||
it.inheritsFromCStructVar(interopBuiltIns) ->
|
|
||||||
cStructClassGenerator.findOrGenerateCStruct(it, irParentFor(it))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateIrIfNeeded(symbol: IrSymbol) {
|
private fun generateIrIfNeeded(symbol: IrSymbol, file: IrFile) {
|
||||||
// TODO: These `findOrGenerate` calls generate a whole subtree.
|
// TODO: These `findOrGenerate` calls generate a whole subtree.
|
||||||
// This a simple but clearly suboptimal solution.
|
// This a simple but clearly suboptimal solution.
|
||||||
symbol.findCEnumDescriptor(interopBuiltIns)?.let { enumDescriptor ->
|
symbol.findCEnumDescriptor(interopBuiltIns)?.let { enumDescriptor ->
|
||||||
cEnumClassGenerator.findOrGenerateCEnum(enumDescriptor, irParentFor(enumDescriptor))
|
cEnumClassGenerator.findOrGenerateCEnum(enumDescriptor, file)
|
||||||
}
|
}
|
||||||
symbol.findCStructDescriptor(interopBuiltIns)?.let { structDescriptor ->
|
symbol.findCStructDescriptor(interopBuiltIns)?.let { structDescriptor ->
|
||||||
cStructClassGenerator.findOrGenerateCStruct(structDescriptor, irParentFor(structDescriptor))
|
cStructClassGenerator.findOrGenerateCStruct(structDescriptor, file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
|
fun getDeclaration(descriptor: DeclarationDescriptor, idSignature: IdSignature, file: IrFile, symbolKind: BinarySymbolData.SymbolKind): IrSymbolOwner {
|
||||||
if (symbol.isBound) return symbol.owner as IrDeclaration
|
return symbolTable.run {
|
||||||
if (!canHandleSymbol(symbol)) return null
|
when (symbolKind) {
|
||||||
generateIrIfNeeded(symbol)
|
BinarySymbolData.SymbolKind.CLASS_SYMBOL -> declareClassFromLinker(descriptor as ClassDescriptor, idSignature) { s ->
|
||||||
return when (symbol) {
|
generateIrIfNeeded(s, file)
|
||||||
is IrClassSymbol -> symbolTable.referenceClass(symbol.descriptor).owner
|
s.owner
|
||||||
is IrEnumEntrySymbol -> symbolTable.referenceEnumEntry(symbol.descriptor).owner
|
}
|
||||||
is IrFunctionSymbol -> symbolTable.referenceFunction(symbol.descriptor).owner
|
BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL -> declareEnumEntryFromLinker(descriptor as ClassDescriptor, idSignature) { s ->
|
||||||
is IrPropertySymbol -> symbolTable.referenceProperty(symbol.descriptor).owner
|
generateIrIfNeeded(s, file)
|
||||||
else -> error(symbol)
|
s.owner
|
||||||
}
|
}
|
||||||
}
|
BinarySymbolData.SymbolKind.FUNCTION_SYMBOL -> declareSimpleFunctionFromLinker(descriptor as FunctionDescriptor, idSignature) { s ->
|
||||||
|
generateIrIfNeeded(s, file)
|
||||||
private fun irParentFor(descriptor: ClassDescriptor): IrDeclarationContainer {
|
s.owner
|
||||||
val packageFragmentDescriptor = descriptor.findPackage()
|
}
|
||||||
return filesMap.getOrPut(packageFragmentDescriptor) {
|
BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> declarePropertyFromLinker(descriptor as PropertyDescriptor, idSignature) { s ->
|
||||||
IrFileImpl(NaiveSourceBasedFileEntryImpl(cTypeDefinitionsFileName), packageFragmentDescriptor)
|
generateIrIfNeeded(s, file)
|
||||||
|
s.owner
|
||||||
|
}
|
||||||
|
else -> error("Unexpected symbol kind $symbolKind for sig $idSignature")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-66
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
package org.jetbrains.kotlin.backend.konan.serialization
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
|
||||||
|
|
||||||
// The code here is intentionally copy-pasted from DeclarationStubGenerator with
|
|
||||||
// minor changes.
|
|
||||||
// "Find descriptor by IdSignature" task appears to be common and should be unified later.
|
|
||||||
class DescriptorByIdSignatureFinder(
|
|
||||||
private val moduleDescriptor: ModuleDescriptor
|
|
||||||
) {
|
|
||||||
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(KonanManglerDesc) { candidate.signatureMangle }
|
|
||||||
candidateHash == id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+154
-88
@@ -18,123 +18,189 @@ package org.jetbrains.kotlin.backend.konan.serialization
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.*
|
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||||
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.descriptors.IrAbstractFunctionFactory
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
|
import org.jetbrains.kotlin.library.IrLibrary
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
|
||||||
class KonanIrLinker(
|
internal class KonanIrLinker(
|
||||||
private val currentModule: ModuleDescriptor,
|
private val currentModule: ModuleDescriptor,
|
||||||
logger: LoggingContext,
|
override val functionalInteraceFactory: IrAbstractFunctionFactory,
|
||||||
builtIns: IrBuiltIns,
|
logger: LoggingContext,
|
||||||
symbolTable: SymbolTable,
|
builtIns: IrBuiltIns,
|
||||||
private val forwardModuleDescriptor: ModuleDescriptor?,
|
symbolTable: SymbolTable,
|
||||||
exportedDependencies: List<ModuleDescriptor>
|
private val forwardModuleDescriptor: ModuleDescriptor?,
|
||||||
) : KotlinIrLinker(logger, builtIns, symbolTable, exportedDependencies, forwardModuleDescriptor) {
|
private val stubGenerator: DeclarationStubGenerator,
|
||||||
|
private val cenumsProvider: IrProviderForCEnumAndCStructStubs,
|
||||||
private val descriptorByIdSignatureFinder = DescriptorByIdSignatureFinder(currentModule)
|
exportedDependencies: List<ModuleDescriptor>
|
||||||
|
) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, exportedDependencies) {
|
||||||
override fun reader(moduleDescriptor: ModuleDescriptor, fileIndex: Int, idSigIndex: Int) =
|
|
||||||
moduleDescriptor.konanLibrary!!.irDeclaration(idSigIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readType(moduleDescriptor: ModuleDescriptor, fileIndex: Int, typeIndex: Int) =
|
|
||||||
moduleDescriptor.konanLibrary!!.type(typeIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readSignature(moduleDescriptor: ModuleDescriptor, fileIndex: Int, signatureIndex: Int) =
|
|
||||||
moduleDescriptor.konanLibrary!!.signature(signatureIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readString(moduleDescriptor: ModuleDescriptor, fileIndex: Int, stringIndex: Int) =
|
|
||||||
moduleDescriptor.konanLibrary!!.string(stringIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readBody(moduleDescriptor: ModuleDescriptor, fileIndex: Int, bodyIndex: Int) =
|
|
||||||
moduleDescriptor.konanLibrary!!.body(bodyIndex, fileIndex)
|
|
||||||
|
|
||||||
override fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int) =
|
|
||||||
moduleDescriptor.konanLibrary!!.file(fileIndex)
|
|
||||||
|
|
||||||
override fun readFileCount(moduleDescriptor: ModuleDescriptor) =
|
|
||||||
moduleDescriptor.run { if (this === forwardModuleDescriptor || moduleDescriptor.isFromInteropLibrary()) 0 else konanLibrary!!.fileCount() }
|
|
||||||
|
|
||||||
override fun handleNoModuleDeserializerFound(idSignature: IdSignature): DeserializationState<*> {
|
|
||||||
return globalDeserializationState
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val C_NAMES_NAME = Name.identifier("cnames")
|
private val C_NAMES_NAME = Name.identifier("cnames")
|
||||||
private val OBJC_NAMES_NAME = Name.identifier("objcnames")
|
private val OBJC_NAMES_NAME = Name.identifier("objcnames")
|
||||||
|
|
||||||
|
val FORWARD_DECLARATION_ORIGIN = object : IrDeclarationOriginImpl("FORWARD_DECLARATION_ORIGIN") {}
|
||||||
|
|
||||||
|
const val offset = SYNTHETIC_OFFSET
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSpecialPlatformSignature(idSig: IdSignature): Boolean = idSig.isForwardDeclarationSignature()
|
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor.isNativeStdlib()
|
||||||
|
|
||||||
override fun postProcessPlatformSpecificDeclaration(idSig: IdSignature, descriptor: DeclarationDescriptor?, block: (IdSignature) -> Unit) {
|
private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserialier(it) }
|
||||||
if (descriptor == null) return
|
|
||||||
|
|
||||||
if (!idSig.isForwardDeclarationSignature()) return
|
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {
|
||||||
|
if (moduleDescriptor === forwardModuleDescriptor) {
|
||||||
val fqn = descriptor.fqNameSafe
|
return forwardDeclarationDeserializer ?: error("forward declaration deserializer expected")
|
||||||
if (!fqn.startsWith(C_NAMES_NAME) && !fqn.startsWith(OBJC_NAMES_NAME)) {
|
|
||||||
val signature = IdSignature.PublicSignature(fqn.parent(), FqName(fqn.shortName().asString()), null, 0)
|
|
||||||
block(signature)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (klib is KotlinLibrary && klib.isInteropLibrary()) {
|
||||||
|
return KonanInteropModuleDeserializer(moduleDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun resolvePlatformDescriptor(idSig: IdSignature): DeclarationDescriptor? {
|
private inner class KonanModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy):
|
||||||
if (idSig.isInteropSignature()) {
|
KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy)
|
||||||
return descriptorByIdSignatureFinder.findDescriptorBySignature(idSig)
|
|
||||||
|
private inner class KonanInteropModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor) {
|
||||||
|
init {
|
||||||
|
assert(moduleDescriptor.kotlinLibrary.isInteropLibrary())
|
||||||
}
|
}
|
||||||
if (!idSig.isForwardDeclarationSignature()) return null
|
|
||||||
|
|
||||||
val fwdModule = forwardModuleDescriptor ?: error("Forward declaration module should not be null")
|
private val descriptorByIdSignatureFinder = DescriptorByIdSignatureFinder(moduleDescriptor, KonanManglerDesc)
|
||||||
|
private fun IdSignature.isInteropSignature(): Boolean = IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.test()
|
||||||
|
|
||||||
return with(idSig as IdSignature.PublicSignature) {
|
override fun contains(idSig: IdSignature): Boolean {
|
||||||
val classId = ClassId(packageFqn, declarationFqn, false)
|
|
||||||
fwdModule.findClassAcrossModuleDependencies(classId)
|
if (idSig.isPublic) {
|
||||||
|
if (idSig.isInteropSignature()) {
|
||||||
|
// TODO: add descriptor cache??
|
||||||
|
return descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) != null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun IdSignature.isInteropSignature(): Boolean = IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.test()
|
private fun DeclarationDescriptor.isCEnumsOrCStruct(): Boolean = cenumsProvider.isCEnumOrCStruct(this)
|
||||||
|
|
||||||
private fun IdSignature.isForwardDeclarationSignature(): Boolean {
|
private val fileMap = mutableMapOf<PackageFragmentDescriptor, IrFile>()
|
||||||
if (isPublic) {
|
|
||||||
return packageFqName().run {
|
private fun getIrFile(packageFragment: PackageFragmentDescriptor): IrFile = fileMap.getOrPut(packageFragment) {
|
||||||
startsWith(C_NAMES_NAME) || startsWith(OBJC_NAMES_NAME)
|
IrFileImpl(NaiveSourceBasedFileEntryImpl(IrProviderForCEnumAndCStructStubs.cTypeDefinitionsFileName), packageFragment).also {
|
||||||
|
moduleFragment.files.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
private fun resolveCEnumsOrStruct(descriptor: DeclarationDescriptor, idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
}
|
val file = getIrFile(descriptor.findPackage())
|
||||||
|
return cenumsProvider.getDeclaration(descriptor, idSig, file, symbolKind).symbol
|
||||||
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, strategy: DeserializationStrategy): IrModuleDeserializer {
|
|
||||||
return KonanModuleDeserializer(moduleDescriptor, strategy)
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class KonanModuleDeserializer(moduleDescriptor: ModuleDescriptor, strategy: DeserializationStrategy):
|
|
||||||
IrModuleDeserializer(moduleDescriptor, strategy)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If declaration is from interop library then IR for it is generated by IrProviderForInteropStubs.
|
|
||||||
*/
|
|
||||||
override fun IdSignature.shouldBeDeserialized(): Boolean = !isInteropSignature() && !isForwardDeclarationSignature()
|
|
||||||
|
|
||||||
val modules: Map<String, IrModuleFragment> get() = mutableMapOf<String, IrModuleFragment>().apply {
|
|
||||||
deserializersForModules.filter { !it.key.isForwardDeclarationModule }.forEach {
|
|
||||||
this.put(it.key.konanLibrary!!.libraryName, it.value.module)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
val descriptor = descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) ?: error("Expecting descriptor for $idSig")
|
||||||
|
|
||||||
|
if (descriptor.isCEnumsOrCStruct()) return resolveCEnumsOrStruct(descriptor, idSig, symbolKind)
|
||||||
|
|
||||||
|
val symbolOwner = stubGenerator.generateMemberStub(descriptor) as IrSymbolOwner
|
||||||
|
|
||||||
|
return symbolOwner.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||||
|
override val moduleDependencies: Collection<IrModuleDeserializer> = listOfNotNull(forwardDeclarationDeserializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inner class KonanForwardDeclarationModuleDeserialier(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor) {
|
||||||
|
init {
|
||||||
|
assert(moduleDescriptor.isForwardDeclarationModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val declaredDeclaration = mutableMapOf<IdSignature, IrClass>()
|
||||||
|
private val packageToFileMap = mutableMapOf<FqName, IrFile>()
|
||||||
|
|
||||||
|
private fun IdSignature.isForwardDeclarationSignature(): Boolean {
|
||||||
|
if (isPublic) {
|
||||||
|
return packageFqName().run {
|
||||||
|
startsWith(C_NAMES_NAME) || startsWith(OBJC_NAMES_NAME)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun contains(idSig: IdSignature): Boolean = idSig.isForwardDeclarationSignature()
|
||||||
|
|
||||||
|
private fun resolveDescriptor(idSig: IdSignature): ClassDescriptor =
|
||||||
|
with(idSig as IdSignature.PublicSignature) {
|
||||||
|
val classId = ClassId(packageFqn, declarationFqn, false)
|
||||||
|
moduleDescriptor.findClassAcrossModuleDependencies(classId) ?: error("No declaration found with $idSig")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getIrFile(packageFragment: PackageFragmentDescriptor): IrFile {
|
||||||
|
val fqn = packageFragment.fqName
|
||||||
|
return packageToFileMap.getOrPut(packageFragment.fqName) {
|
||||||
|
val fileSymbol = IrFileSymbolImpl(packageFragment)
|
||||||
|
IrFileImpl(NaiveSourceBasedFileEntryImpl("forward declarations for $fqn"), fileSymbol).also {
|
||||||
|
moduleFragment.files.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildForwardDeclarationStub(idSig: IdSignature, descriptor: ClassDescriptor): IrClass {
|
||||||
|
val packageDescriptor = descriptor.containingDeclaration as PackageFragmentDescriptor
|
||||||
|
val irFile = getIrFile(packageDescriptor)
|
||||||
|
|
||||||
|
val klass = symbolTable.declareClassFromLinker(descriptor, idSig) { s ->
|
||||||
|
IrClassImpl(offset, offset, FORWARD_DECLARATION_ORIGIN, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
klass.parent = irFile
|
||||||
|
irFile.declarations.add(klass)
|
||||||
|
|
||||||
|
return klass
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||||
|
assert(symbolKind == BinarySymbolData.SymbolKind.CLASS_SYMBOL) { "Only class could be a Forward declaration $idSig (kind $symbolKind)" }
|
||||||
|
val descriptor = resolveDescriptor(idSig)
|
||||||
|
val actualModule = descriptor.module
|
||||||
|
if (actualModule !== moduleDescriptor) {
|
||||||
|
val moduleDeserializer = deserializersForModules[actualModule] ?: error("No module deserializer for $actualModule")
|
||||||
|
moduleDeserializer.addModuleReachableTopLevel(idSig)
|
||||||
|
return symbolTable.referenceClassFromLinker(descriptor, idSig)
|
||||||
|
}
|
||||||
|
|
||||||
|
return declaredDeclaration.getOrPut(idSig) { buildForwardDeclarationStub(idSig, descriptor) }.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||||
|
override val moduleDependencies: Collection<IrModuleDeserializer> = emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val modules: Map<String, IrModuleFragment>
|
||||||
|
get() = mutableMapOf<String, IrModuleFragment>().apply {
|
||||||
|
deserializersForModules
|
||||||
|
.filter { !it.key.isForwardDeclarationModule && it.value.moduleDescriptor !== currentModule }
|
||||||
|
.forEach { this.put(it.key.konanLibrary!!.libraryName, it.value.moduleFragment) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user