From e53e94516f5da82b3db8ff1000a7ec97edef7bef Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Mon, 12 Feb 2024 09:16:48 +0100 Subject: [PATCH] [ObjCExport] AA: Enable generation of base declarations ^KT-65738 Fixed --- .../objcexport/KtObjCExportConfiguration.kt | 8 ++++++- .../kotlin/objcexport/objCBaseDeclarations.kt | 22 +++++++++++++++++++ .../objcexport/translateToObjCHeader.kt | 4 ++++ .../AnalysisApiBaseDeclarationsGenerator.kt | 7 +++++- .../testUtils/AnalysisApiHeaderGenerator.kt | 7 +++++- .../Fe10ObjCExportHeaderGenerator.kt | 5 +++++ .../konan/testUtils/HeaderGenerator.kt | 6 +++++ .../tests/ObjCExportBaseDeclarationsTest.kt | 3 --- 8 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/objCBaseDeclarations.kt diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/KtObjCExportConfiguration.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/KtObjCExportConfiguration.kt index 8c232174c94..a6d3dd2629f 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/KtObjCExportConfiguration.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/KtObjCExportConfiguration.kt @@ -21,5 +21,11 @@ data class KtObjCExportConfiguration( * - [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamingHelper.canBeSwiftOuter] * - [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamingHelper.canBeSwiftInner] */ - val objcGenerics: Boolean = true + val objcGenerics: Boolean = true, + + /** + * Flag to enable/disable the emission of 'base declarations' + * (see [org.jetbrains.kotlin.objcexport.objCBaseDeclarations]). + */ + val generateBaseDeclarationStubs: Boolean = true, ) diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/objCBaseDeclarations.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/objCBaseDeclarations.kt new file mode 100644 index 00000000000..a6c36fcf3d1 --- /dev/null +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/objCBaseDeclarations.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2024 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.objcexport + +import org.jetbrains.kotlin.backend.konan.objcexport.ObjCTopLevel +import org.jetbrains.kotlin.backend.konan.objcexport.objCBaseDeclarations +import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDefaultSuperClassOrProtocolName + +context(KtObjCExportSession) +internal fun objCBaseDeclarations(): List { + return objCBaseDeclarations( + topLevelNamePrefix = configuration.frameworkName.orEmpty(), + objCNameOfAny = getDefaultSuperClassOrProtocolName(), + objCNameOfNumber = "Number".getObjCKotlinStdlibClassOrProtocolName(), + objCNameOfMutableMap = "MutableDictionary".getObjCKotlinStdlibClassOrProtocolName(), + objCNameOfMutableSet = "MutableSet".getObjCKotlinStdlibClassOrProtocolName(), + objCNameForNumberBox = { classId -> classId.shortClassName.asString().getObjCKotlinStdlibClassOrProtocolName() } + ) +} diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt index 4bd3c963e68..321f405e1ac 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt @@ -127,6 +127,10 @@ fun translateToObjCHeader(files: List): ObjCHeader { classForwardDeclarations.add(errorForwardClass) } + if (configuration.generateBaseDeclarationStubs) { + stubs.addAll(0, objCBaseDeclarations()) + } + return ObjCHeader( stubs = stubs, classForwardDeclarations = classForwardDeclarations, diff --git a/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/testUtils/AnalysisApiBaseDeclarationsGenerator.kt b/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/testUtils/AnalysisApiBaseDeclarationsGenerator.kt index cbcc9b8c3ec..00ef0ac8b10 100644 --- a/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/testUtils/AnalysisApiBaseDeclarationsGenerator.kt +++ b/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/testUtils/AnalysisApiBaseDeclarationsGenerator.kt @@ -7,6 +7,9 @@ package org.jetbrains.kotlin.objcexport.testUtils import org.jetbrains.kotlin.backend.konan.objcexport.ObjCTopLevel import org.jetbrains.kotlin.backend.konan.tests.ObjCExportBaseDeclarationsTest +import org.jetbrains.kotlin.objcexport.KtObjCExportConfiguration +import org.jetbrains.kotlin.objcexport.KtObjCExportSession +import org.jetbrains.kotlin.objcexport.objCBaseDeclarations import org.junit.jupiter.api.extension.ExtensionContext import org.junit.jupiter.api.extension.ParameterContext import org.junit.jupiter.api.extension.ParameterResolver @@ -23,6 +26,8 @@ class AnalysisApiBaseDeclarationsGeneratorExtension : ParameterResolver { object AnalysisApiBaseDeclarationsGenerator : ObjCExportBaseDeclarationsTest.BaseDeclarationsGenerator { override fun invoke(topLevelPrefix: String): List { - TODO("Analysis Api based 'base declaration generation' in not yet implemented") + return KtObjCExportSession(KtObjCExportConfiguration(topLevelPrefix)) { + objCBaseDeclarations() + } } } \ No newline at end of file diff --git a/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/testUtils/AnalysisApiHeaderGenerator.kt b/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/testUtils/AnalysisApiHeaderGenerator.kt index 7b9ea47acf7..f3137f7554f 100644 --- a/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/testUtils/AnalysisApiHeaderGenerator.kt +++ b/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/testUtils/AnalysisApiHeaderGenerator.kt @@ -32,7 +32,12 @@ object AnalysisApiHeaderGenerator : HeaderGenerator { val session = createStandaloneAnalysisApiSession(root.listFiles().orEmpty().filter { it.extension == "kt" }) val (module, files) = session.modulesWithFiles.entries.single() return analyze(module) { - KtObjCExportSession(KtObjCExportConfiguration(frameworkName = configuration.frameworkName)) { + KtObjCExportSession( + KtObjCExportConfiguration( + frameworkName = configuration.frameworkName, + generateBaseDeclarationStubs = configuration.generateBaseDeclarationStubs + ) + ) { translateToObjCHeader(files.map { it as KtFile }) } } diff --git a/native/objcexport-header-generator/impl/k1/test/org/jetbrains/kotlin/backend/konan/testUtils/Fe10ObjCExportHeaderGenerator.kt b/native/objcexport-header-generator/impl/k1/test/org/jetbrains/kotlin/backend/konan/testUtils/Fe10ObjCExportHeaderGenerator.kt index 8f04a626106..39d166454be 100644 --- a/native/objcexport-header-generator/impl/k1/test/org/jetbrains/kotlin/backend/konan/testUtils/Fe10ObjCExportHeaderGenerator.kt +++ b/native/objcexport-header-generator/impl/k1/test/org/jetbrains/kotlin/backend/konan/testUtils/Fe10ObjCExportHeaderGenerator.kt @@ -45,6 +45,11 @@ class Fe10HeaderGeneratorExtension : ParameterResolver, AfterEachCallback { private class Fe10HeaderGeneratorImpl(private val disposable: Disposable) : HeaderGenerator { override fun generateHeaders(root: File, configuration: HeaderGenerator.Configuration): ObjCHeader { val headerGenerator = createObjCExportHeaderGenerator(disposable, root, configuration) + + if (configuration.generateBaseDeclarationStubs) { + headerGenerator.translateBaseDeclarations() + } + headerGenerator.translateModuleDeclarations() return headerGenerator.buildHeader() } diff --git a/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/testUtils/HeaderGenerator.kt b/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/testUtils/HeaderGenerator.kt index c479f739bb4..d7e81b294a8 100644 --- a/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/testUtils/HeaderGenerator.kt +++ b/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/testUtils/HeaderGenerator.kt @@ -12,6 +12,12 @@ interface HeaderGenerator { data class Configuration( val frameworkName: String = "", + + /** + * Base declaration stubs do not change and have dedicated tests. + * We do not generate them by default to keep test data easier to read. + */ + val generateBaseDeclarationStubs: Boolean = false, ) fun generateHeaders(root: File, configuration: Configuration = Configuration()): ObjCHeader diff --git a/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/tests/ObjCExportBaseDeclarationsTest.kt b/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/tests/ObjCExportBaseDeclarationsTest.kt index 52ae9953a46..5e3e9a7cf3d 100644 --- a/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/tests/ObjCExportBaseDeclarationsTest.kt +++ b/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/tests/ObjCExportBaseDeclarationsTest.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.konan.tests import org.jetbrains.kotlin.backend.konan.objcexport.ObjCTopLevel import org.jetbrains.kotlin.backend.konan.objcexport.StubRenderer -import org.jetbrains.kotlin.backend.konan.testUtils.TodoAnalysisApi import org.jetbrains.kotlin.backend.konan.testUtils.baseDeclarationsDir import org.jetbrains.kotlin.test.KotlinTestUtils import org.junit.jupiter.api.Test @@ -26,13 +25,11 @@ class ObjCExportBaseDeclarationsTest( ) { @Test - @TodoAnalysisApi fun `test - noTopLevelPrefix`() { doTest(baseDeclarationsDir.resolve("!noTopLevelPrefix.h"), "") } @Test - @TodoAnalysisApi fun `test - topLevelPrefix`() { doTest(baseDeclarationsDir.resolve("!topLevelPrefix.h"), "MyTopLevelPrefix") }