From 860f873ac7ad10016e120b37d25d24ff2ff3fccb Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Mon, 3 Oct 2022 15:25:08 +0300 Subject: [PATCH] [K/N] DI some properties of ObjCExport Move `exportedInterface` and `codeSpec` to constructor's parameters, so in the future "dynamic" compiler pipeline they can be created independently. --- .../kotlin/backend/konan/ToplevelPhases.kt | 10 ++- .../backend/konan/objcexport/ObjCExport.kt | 70 +++++++++---------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index 230427bd47f..f1cbe0cd21a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -17,6 +17,8 @@ import org.jetbrains.kotlin.backend.konan.lower.CacheInfoBuilder import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier import org.jetbrains.kotlin.backend.konan.lower.SamSuperTypesChecker import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport +import org.jetbrains.kotlin.backend.konan.objcexport.createCodeSpec +import org.jetbrains.kotlin.backend.konan.objcexport.produceObjCExportInterface import org.jetbrains.kotlin.backend.konan.serialization.* import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings @@ -86,7 +88,13 @@ internal val createSymbolTablePhase = konanUnitPhase( internal val objCExportPhase = konanUnitPhase( op = { - objCExport = ObjCExport(this, symbolTable!!) + val objcInterface = when { + !config.target.family.isAppleFamily -> null + config.produce != CompilerOutputKind.FRAMEWORK -> null + else -> produceObjCExportInterface(this) + } + val codeSpec = objcInterface?.createCodeSpec(symbolTable!!) + objCExport = ObjCExport(this, objcInterface, codeSpec) }, name = "ObjCExport", description = "Objective-C header generation", diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt index c966a8a24ba..dd9720e4c06 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt @@ -6,11 +6,9 @@ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.konan.* -import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.KonanConfigKeys.Companion.BUNDLE_ID import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments import org.jetbrains.kotlin.backend.konan.descriptors.isInterface -import org.jetbrains.kotlin.backend.konan.getExportedDependencies import org.jetbrains.kotlin.backend.konan.llvm.CodeGenerator import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportBlockCodeGenerator import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportCodeGenerator @@ -19,7 +17,6 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.SourceFile -import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.createTempFile @@ -37,43 +34,42 @@ internal class ObjCExportedInterface( val mapper: ObjCExportMapper ) -internal class ObjCExport(val context: Context, symbolTable: SymbolTable) { +// TODO: Replace Context with a more lightweight class. +internal fun produceObjCExportInterface(context: Context): ObjCExportedInterface { + require(context.config.target.family.isAppleFamily) + require(context.config.produce == CompilerOutputKind.FRAMEWORK) + + val topLevelNamePrefix = context.objCExportTopLevelNamePrefix + + // TODO: emit RTTI to the same modules as classes belong to. + // Not possible yet, since ObjCExport translates the entire "world" API at once + // and can't do this per-module, e.g. due to global name conflict resolution. + + val unitSuspendFunctionExport = context.config.unitSuspendFunctionObjCExport + val mapper = ObjCExportMapper(context.frontendServices.deprecationResolver, unitSuspendFunctionExport = unitSuspendFunctionExport) + val moduleDescriptors = listOf(context.moduleDescriptor) + context.getExportedDependencies() + val objcGenerics = context.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS) + val namer = ObjCExportNamerImpl( + moduleDescriptors.toSet(), + context.moduleDescriptor.builtIns, + mapper, + topLevelNamePrefix, + local = false, + objcGenerics = objcGenerics + ) + val headerGenerator = ObjCExportHeaderGeneratorImpl(context, moduleDescriptors, mapper, namer, objcGenerics) + headerGenerator.translateModule() + return headerGenerator.buildInterface() +} + +internal class ObjCExport( + val context: Context, + private val exportedInterface: ObjCExportedInterface?, + private val codeSpec: ObjCExportCodeSpec? +) { private val target get() = context.config.target private val topLevelNamePrefix get() = context.objCExportTopLevelNamePrefix - private val exportedInterface = produceInterface() - private val codeSpec = exportedInterface?.createCodeSpec(symbolTable) - - private fun produceInterface(): ObjCExportedInterface? { - if (!target.family.isAppleFamily) return null - - // TODO: emit RTTI to the same modules as classes belong to. - // Not possible yet, since ObjCExport translates the entire "world" API at once - // and can't do this per-module, e.g. due to global name conflict resolution. - - val produceFramework = context.config.produce == CompilerOutputKind.FRAMEWORK - - return if (produceFramework) { - val unitSuspendFunctionExport = context.config.unitSuspendFunctionObjCExport - val mapper = ObjCExportMapper(context.frontendServices.deprecationResolver, unitSuspendFunctionExport = unitSuspendFunctionExport) - val moduleDescriptors = listOf(context.moduleDescriptor) + context.getExportedDependencies() - val objcGenerics = context.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS) - val namer = ObjCExportNamerImpl( - moduleDescriptors.toSet(), - context.moduleDescriptor.builtIns, - mapper, - topLevelNamePrefix, - local = false, - objcGenerics = objcGenerics - ) - val headerGenerator = ObjCExportHeaderGeneratorImpl(context, moduleDescriptors, mapper, namer, objcGenerics) - headerGenerator.translateModule() - headerGenerator.buildInterface() - } else { - null - } - } - lateinit var namer: ObjCExportNamer internal fun generate(codegen: CodeGenerator) {