[K/N] Modularise :kotlin-native:native.backend to extract objc header generation (1/2)

^KT-63905
This commit is contained in:
Sebastian Sellmair
2023-11-29 11:27:55 +01:00
committed by Space Team
parent 4294c7bab7
commit ae9f3d66c2
69 changed files with 0 additions and 0 deletions
@@ -1,39 +0,0 @@
/*
* Copyright 2010-2023 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.konan.testUtils
import com.intellij.openapi.Disposable
import com.intellij.openapi.util.Disposer
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.junit.After
import java.io.File
import kotlin.test.fail
abstract class AbstractObjCExportHeaderGeneratorTest(
private val generator: ObjCExportHeaderGenerator
) {
fun interface ObjCExportHeaderGenerator {
fun generateHeaders(disposable: Disposable, root: File): String
}
private val testRootDisposable = Disposer.newDisposable()
protected val objCExportTestDataDir = testDataDir.resolve("objcexport")
@After
fun dispose() {
Disposer.dispose(testRootDisposable)
}
protected fun doTest(root: File) {
if (!root.isDirectory) fail("Expected ${root.absolutePath} to be directory")
val generatedHeaders = generator.generateHeaders(testRootDisposable, root)
KotlinTestUtils.assertEqualsToFile(root.resolve("!${root.nameWithoutExtension}.h"), generatedHeaders)
}
}
abstract class AbstractFE10ObjCExportHeaderGeneratorTest : AbstractObjCExportHeaderGeneratorTest(Fe10ObjCExportHeaderGenerator)
@@ -1,88 +0,0 @@
/*
* Copyright 2010-2023 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.konan.testUtils
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
import org.jetbrains.kotlin.backend.konan.KlibFactories
import org.jetbrains.kotlin.backend.konan.KonanConfig
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys.Companion.KONAN_HOME
import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport
import org.jetbrains.kotlin.backend.konan.driver.BasicPhaseContext
import org.jetbrains.kotlin.backend.konan.objcexport.*
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportHeaderGeneratorImpl
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportMapper
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamerImpl
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments
import org.jetbrains.kotlin.cli.common.createFlexiblePhaseConfig
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.library.resolveSingleFileKlib
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.testFramework.MockProjectEx
import org.jetbrains.kotlin.test.util.KtTestUtil
import java.io.File
object Fe10ObjCExportHeaderGenerator : AbstractObjCExportHeaderGeneratorTest.ObjCExportHeaderGenerator {
override fun generateHeaders(disposable: Disposable, root: File): String {
val headerGenerator = createObjCExportHeaderGenerator(disposable, root)
headerGenerator.translateModuleDeclarations()
return headerGenerator.build().joinToString(System.lineSeparator())
}
private fun createObjCExportHeaderGenerator(disposable: Disposable, root: File): ObjCExportHeaderGenerator {
val mapper = ObjCExportMapper(
unitSuspendFunctionExport = UnitSuspendFunctionObjCExport.DEFAULT
)
val namer = ObjCExportNamerImpl(
mapper = mapper,
builtIns = DefaultBuiltIns.Instance,
local = false,
problemCollector = ObjCExportProblemCollector.SILENT,
configuration = object : ObjCExportNamer.Configuration {
override val topLevelNamePrefix: String get() = ""
override fun getAdditionalPrefix(module: ModuleDescriptor): String? = null
override val objcGenerics: Boolean = true
}
)
val environment: KotlinCoreEnvironment = createKotlinCoreEnvironment(disposable)
val phaseContext = BasicPhaseContext(
KonanConfig(environment.project, environment.configuration)
)
val kotlinFiles = root.walkTopDown().filter { it.isFile }.filter { it.extension == "kt" }.toList()
return ObjCExportHeaderGeneratorImpl(
context = phaseContext,
moduleDescriptors = listOf(createModuleDescriptor(environment, kotlinFiles)),
mapper = mapper,
namer = namer,
problemCollector = ObjCExportProblemCollector.SILENT,
objcGenerics = true
)
}
}
@@ -1,140 +0,0 @@
/*
* Copyright 2010-2023 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.konan.testUtils
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
import org.jetbrains.kotlin.backend.konan.KlibFactories
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments
import org.jetbrains.kotlin.cli.common.createFlexiblePhaseConfig
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.library.resolveSingleFileKlib
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.util.KtTestUtil
import java.io.File
fun createModuleDescriptor(
environment: KotlinCoreEnvironment,
tempDir: File,
kotlinSources: List<String>
): ModuleDescriptor {
val testModuleRoot = tempDir.resolve("testModule")
testModuleRoot.mkdirs()
val testSourcesFiles = kotlinSources.mapIndexed { index, kotlinSource ->
testModuleRoot.resolve("TestSources$index.kt").apply {
writeText(kotlinSource)
}
}
return createModuleDescriptor(environment, testSourcesFiles)
}
fun createModuleDescriptor(
environment: KotlinCoreEnvironment,
kotlinFiles: List<File>,
): ModuleDescriptor {
val psiFactory = KtPsiFactory(environment.project)
val kotlinPsiFiles = kotlinFiles.map { file -> psiFactory.createFile(file.name, KtTestUtil.doLoadFile(file)) }
val analysisResult = CommonResolverForModuleFactory.analyzeFiles(
files = kotlinPsiFiles,
moduleName = Name.special("<test_module>"),
dependOnBuiltIns = true,
languageVersionSettings = environment.configuration.languageVersionSettings,
targetPlatform = CommonPlatforms.defaultCommonPlatform,
targetEnvironment = CompilerEnvironment,
dependenciesContainer = DependenciesContainerImpl,
) { content ->
environment.createPackagePartProvider(content.moduleContentScope)
}
return analysisResult.moduleDescriptor
}
fun createKotlinCoreEnvironment(
disposable: Disposable, compilerConfiguration: CompilerConfiguration = createCompilerConfiguration()
): KotlinCoreEnvironment {
return KotlinCoreEnvironment.createForTests(
parentDisposable = disposable,
initialConfiguration = compilerConfiguration,
extensionConfigs = EnvironmentConfigFiles.METADATA_CONFIG_FILES
)
}
private fun createCompilerConfiguration(): CompilerConfiguration {
val configuration = KotlinTestUtils.newConfiguration()
configuration.put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, createLanguageVersionSettings())
configuration.put(CLIConfigurationKeys.FLEXIBLE_PHASE_CONFIG, createFlexiblePhaseConfig(K2NativeCompilerArguments()))
configuration.put(KonanConfigKeys.KONAN_HOME, konanHomePath)
configuration.put(KonanConfigKeys.PRODUCE, CompilerOutputKind.FRAMEWORK)
configuration.put(KonanConfigKeys.AUTO_CACHEABLE_FROM, emptyList())
configuration.put(KonanConfigKeys.CACHE_DIRECTORIES, emptyList())
configuration.put(KonanConfigKeys.CACHED_LIBRARIES, emptyMap())
configuration.put(KonanConfigKeys.FRAMEWORK_IMPORT_HEADERS, emptyList())
configuration.put(KonanConfigKeys.EXPORT_KDOC, true)
return configuration
}
private fun createLanguageVersionSettings() = LanguageVersionSettingsImpl(
languageVersion = LanguageVersion.LATEST_STABLE,
apiVersion = ApiVersion.LATEST_STABLE
)
private object DependenciesContainerImpl : CommonDependenciesContainer {
override val moduleInfos: List<ModuleInfo> get() = listOf(DefaultBuiltInsModuleInfo, KotlinNativeStdlibModuleInfo)
override val friendModuleInfos: List<ModuleInfo> get() = emptyList()
override val refinesModuleInfos: List<ModuleInfo> get() = emptyList()
override fun registerDependencyForAllModules(moduleInfo: ModuleInfo, descriptorForModule: ModuleDescriptorImpl) = Unit
override fun packageFragmentProviderForModuleInfo(moduleInfo: ModuleInfo): PackageFragmentProvider? = null
private val stdlibModuleDescriptor = KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor(
library = resolveSingleFileKlib(org.jetbrains.kotlin.konan.file.File("$konanHomePath/klib/common/stdlib")),
languageVersionSettings = createLanguageVersionSettings(),
builtIns = DefaultBuiltIns.Instance,
storageManager = LockBasedStorageManager.NO_LOCKS,
packageAccessHandler = null
).also { it.setDependencies(it) }
override fun moduleDescriptorForModuleInfo(moduleInfo: ModuleInfo): ModuleDescriptor {
if (moduleInfo == DefaultBuiltInsModuleInfo) return DefaultBuiltIns.Instance.builtInsModule
if (moduleInfo == KotlinNativeStdlibModuleInfo) return stdlibModuleDescriptor
error("Unknown module info $moduleInfo")
}
}
private object DefaultBuiltInsModuleInfo : ModuleInfo {
override val name get() = DefaultBuiltIns.Instance.builtInsModule.name
override fun dependencies() = listOf(this)
override fun dependencyOnBuiltIns() = ModuleInfo.DependencyOnBuiltIns.LAST
override val platform get() = NativePlatforms.unspecifiedNativePlatform
override val analyzerServices get() = NativePlatformAnalyzerServices
}
private object KotlinNativeStdlibModuleInfo : ModuleInfo {
override val analyzerServices: PlatformDependentAnalyzerServices = NativePlatformAnalyzerServices
override val name: Name = Name.special("<stdlib>")
override val platform: TargetPlatform = NativePlatforms.unspecifiedNativePlatform
override fun dependencies(): List<ModuleInfo> = listOf(this)
}
@@ -1,72 +0,0 @@
/*
* Copyright 2010-2023 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.konan.testUtils
import com.intellij.openapi.Disposable
import org.intellij.lang.annotations.Language
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import java.io.File
/**
* Test Environment that enables quick 'inline' creation of [ModuleDescriptor] instances.
*
* # Examples
* ## Test operating on a single Kotlin Source file:
*
* ```kotlin
* class MyTest : InlineSourceTestEnvironment {
* @Test
* fun `test - my unit`() {
* val moduleDescriptor = createModuleDescriptor("""
* package com.example
* class MyClassUnderTest
* """.trimIndent()
* )
*
* // my test!
* }
* }
* ```
*
* ## Test that requires several source files (e.g. multiple packages are involved)
* ```kotlin
* @Test
* fun `test - my unit`() {
* val moduleDescriptor = createModuleDescriptor {
* source("class Foo")
* source("""
* package com.example
* class Foo
* """)
* }
* }
* ```
*/
interface InlineSourceTestEnvironment {
val kotlinCoreEnvironment: KotlinCoreEnvironment
val testDisposable: Disposable
val testTempDir: File
}
interface InlineSourceCodeCollector {
fun source(@Language("kotlin") sourceCode: String)
}
fun InlineSourceTestEnvironment.createModuleDescriptor(@Language("kotlin") sourceCode: String): ModuleDescriptor =
createModuleDescriptor(kotlinCoreEnvironment, testTempDir, listOf(sourceCode))
fun InlineSourceTestEnvironment.createModuleDescriptor(build: InlineSourceCodeCollector.() -> Unit): ModuleDescriptor {
val sources = mutableListOf<String>()
object : InlineSourceCodeCollector {
override fun source(sourceCode: String) {
sources.add(sourceCode)
}
}.build()
return createModuleDescriptor(kotlinCoreEnvironment, testTempDir, sources.toList())
}
@@ -1,52 +0,0 @@
/*
* Copyright 2010-2023 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.konan.testUtils
import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportMapper
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamerImpl
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportProblemCollector
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
internal fun createObjCExportNamerConfiguration(
topLevelNamePrefix: String = "",
additionalPrefix: (moduleName: Name) -> String? = { null }
): ObjCExportNamer.Configuration {
return object : ObjCExportNamer.Configuration {
override val topLevelNamePrefix: String get() = topLevelNamePrefix
override fun getAdditionalPrefix(module: ModuleDescriptor): String? = additionalPrefix(module.name)
override val objcGenerics: Boolean = true
}
}
internal fun createObjCExportMapper(
deprecationResolver: DeprecationResolver? = null,
local: Boolean = false,
unitSuspendFunctionObjCExport: UnitSuspendFunctionObjCExport = UnitSuspendFunctionObjCExport.DEFAULT
): ObjCExportMapper {
return ObjCExportMapper(deprecationResolver, local, unitSuspendFunctionObjCExport)
}
internal fun createObjCExportNamer(
configuration: ObjCExportNamer.Configuration = createObjCExportNamerConfiguration(),
builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
local: Boolean = false,
problemCollector: ObjCExportProblemCollector = ObjCExportProblemCollector.SILENT,
mapper: ObjCExportMapper = createObjCExportMapper(local = local),
): ObjCExportNamer {
return ObjCExportNamerImpl(
builtIns = builtIns,
mapper = mapper,
local = local,
problemCollector = problemCollector,
configuration = configuration
)
}
@@ -1,11 +0,0 @@
/*
* Copyright 2010-2023 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.konan.testUtils
private const val konanHomePropertyKey = "org.jetbrains.kotlin.native.home"
val konanHomePath: String
get() = System.getProperty(konanHomePropertyKey) ?: error("Missing System property: '$konanHomePropertyKey'")
@@ -1,11 +0,0 @@
/*
* Copyright 2010-2023 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.konan.testUtils
import java.io.File
val projectDir = File("kotlin-native/backend.native")
val testDataDir = projectDir.resolve("functionalTest/testData")
@@ -1,110 +0,0 @@
/*
* Copyright 2010-2023 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.konan.tests
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportHeaderGenerator
import org.jetbrains.kotlin.backend.konan.testUtils.AbstractFE10ObjCExportHeaderGeneratorTest
import org.junit.jupiter.api.Test
/**
* ## Test Scope
* This test will cover the generation of 'objc' headers.
* The corresponding class in would be [ObjCExportHeaderGenerator].
*
* The input of the test are Kotlin source files;
* The output is the generated header files;
* The output will be compared to already checked in golden files.
*
* ## How to create a new test
* Every test has a corresponding 'root' directory.
* All directories are found in `backend.native/functionalTest/testData/objcexport`.
*
* 1) Create new root directory (e.g. myTest) in testData/objcexport
* 2) Place kotlin files into the directory e.g. testData/objcexport/myTest/Foo.kt
* 3) Create a test function and call ` doTest(objCExportTestDataDir.resolve("myTest"))`
* 4) The first invocation will fail the test, but generates the header that can be checked in (if sufficient)
*/
class Fe10ObjCExportHeaderGeneratorTest : AbstractFE10ObjCExportHeaderGeneratorTest() {
@Test
fun `test - simpleClass`() {
doTest(objCExportTestDataDir.resolve("simpleClass"))
}
@Test
fun `test - simpleInterface`() {
doTest(objCExportTestDataDir.resolve("simpleInterface"))
}
@Test
fun `test - simpleEnumClass`() {
doTest(objCExportTestDataDir.resolve("simpleEnumClass"))
}
@Test
fun `test - simpleObject`() {
doTest(objCExportTestDataDir.resolve("simpleObject"))
}
@Test
fun `test - topLevelFunction`() {
doTest(objCExportTestDataDir.resolve("topLevelFunction"))
}
@Test
fun `test - topLevelProperty`() {
doTest(objCExportTestDataDir.resolve("topLevelProperty"))
}
@Test
fun `test - sameClassNameInDifferentPackage`() {
doTest(objCExportTestDataDir.resolve("sameClassNameInDifferentPackage"))
}
@Test
fun `test - samePropertyAndFunctionName`() {
doTest(objCExportTestDataDir.resolve("samePropertyAndFunctionName"))
}
@Test
fun `test - classImplementingInterface`() {
doTest(objCExportTestDataDir.resolve("classImplementingInterface"))
}
@Test
fun `test - interfaceImplementingInterface`() {
doTest(objCExportTestDataDir.resolve("interfaceImplementingInterface"))
}
@Test
fun `test - classWithObjCNameAnnotation`() {
doTest(objCExportTestDataDir.resolve("classWithObjCNameAnnotation"))
}
@Test
fun `test - functionWithObjCNameAnnotation`() {
doTest(objCExportTestDataDir.resolve("functionWithObjCNameAnnotation"))
}
@Test
fun `test - classWithKDoc`() {
doTest(objCExportTestDataDir.resolve("classWithKDoc"))
}
@Test
fun `test - classWithHidesFromObjCAnnotation`() {
doTest(objCExportTestDataDir.resolve("classWithHidesFromObjCAnnotation"))
}
@Test
fun `test - functionWithThrowsAnnotation`() {
doTest(objCExportTestDataDir.resolve("functionWithThrowsAnnotation"))
}
@Test
fun `test - functionWithErrorType`() {
doTest(objCExportTestDataDir.resolve("functionWithErrorType"))
}
}
@@ -1,101 +0,0 @@
/*
* Copyright 2010-2023 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.konan.tests
import com.intellij.openapi.util.Disposer
import org.jetbrains.kotlin.backend.konan.KonanConfig
import org.jetbrains.kotlin.backend.konan.driver.BasicPhaseContext
import org.jetbrains.kotlin.backend.konan.objcexport.*
import org.jetbrains.kotlin.backend.konan.testUtils.*
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.TypeAttributes
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
/**
* ## Test Scope
* This test shall cover test the [ObjCExportMapper];
* The test will invoke the type mapping a known type (e.g. List<Int>) and check
* the corresponding conversion to [ObjCNonNullReferenceType].
*
* The test also acts as quick entry point for debugging the [ObjCExportMapper]
*/
class ObjCExportMapperTest : InlineSourceTestEnvironment {
override val testDisposable = Disposer.newDisposable()
override val kotlinCoreEnvironment: KotlinCoreEnvironment = createKotlinCoreEnvironment(testDisposable)
@TempDir
override lateinit var testTempDir: File
@AfterEach
fun dispose() {
Disposer.dispose(testDisposable)
}
/**
* No 'type mapper' expected for a simple Kotlin class like 'Foo'.
* Only well known standard types (List, ...) will get mapped to their corresponding
* ObjC counterpart (NSArray, ...)
*/
@Test
fun `test - simple class`() {
val module = createModuleDescriptor("class Foo")
val foo = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!!
assertNull(createObjCExportMapper().getCustomTypeMapper(foo))
}
/**
* Will test ObjC type mapping from List<Int> to NSArray<Int *> *
*/
@Test
fun `test - List of int`() {
/* We are only using built in / stdlib parts, so we can provide empty source code */
val module = createModuleDescriptor("")
val objcExportMapper = createObjCExportMapper()
val objcExportNamer = createObjCExportNamer(mapper = objcExportMapper)
val objcExportTranslator = ObjCExportTranslatorImpl(
generator = ObjCExportHeaderGeneratorImpl(
context = BasicPhaseContext(
KonanConfig(kotlinCoreEnvironment.project, kotlinCoreEnvironment.configuration)
),
moduleDescriptors = listOf(module),
mapper = objcExportMapper,
namer = objcExportNamer,
problemCollector = ObjCExportProblemCollector.SILENT,
objcGenerics = true
),
mapper = objcExportMapper,
namer = objcExportNamer,
problemCollector = ObjCExportProblemCollector.SILENT,
objcGenerics = true
)
val listClassDescriptor = module.findClassAcrossModuleDependencies(ClassId.fromString("kotlin/collections/List"))!!
val intClassDescriptor = module.findClassAcrossModuleDependencies(ClassId.fromString("kotlin/Int"))!!
/* Represents List<Int> */
val listOfIntType = KotlinTypeFactory.simpleNotNullType(TypeAttributes.Empty, listClassDescriptor, listOf(
TypeProjectionImpl(KotlinTypeFactory.simpleNotNullType(TypeAttributes.Empty, intClassDescriptor, emptyList()))
))
val typeMapper = assertNotNull(objcExportMapper.getCustomTypeMapper(listClassDescriptor))
assertEquals(ClassId.fromString("kotlin/collections/List"), typeMapper.mappedClassId)
val listOfIntMapped = typeMapper.mapType(listOfIntType, objcExportTranslator, objCExportScope = ObjCRootExportScope)
assertEquals(ObjCClassType("NSArray", typeArguments = listOf(ObjCClassType("Int"))), listOfIntMapped)
assertEquals("NSArray<Int *> *", listOfIntMapped.toString())
}
}
@@ -1,192 +0,0 @@
/*
* Copyright 2010-2023 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.konan.tests
import com.intellij.openapi.util.Disposer
import org.jetbrains.kotlin.backend.konan.descriptors.enumEntries
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer.ClassOrProtocolName
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer.PropertyName
import org.jetbrains.kotlin.backend.konan.testUtils.*
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.findSingleFunction
import org.jetbrains.kotlin.resolve.scopes.findFirstVariable
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import java.io.File
import kotlin.test.assertEquals
/**
* ## Test Scope
* This test will cover basic cases of the [ObjCExportNamer]. <br>
*
* The __input__ to this test will be descriptors defined as 'inline source code'.
* (e.g. a String like "class Foo").<br>
*
* The __output__ of this test will be result of the request to the [ObjCExportNamer].
* (e.g. the [ClassOrProtocolName])
*/
class ObjCExportNamerTest : InlineSourceTestEnvironment {
override val testDisposable = Disposer.newDisposable()
override val kotlinCoreEnvironment = createKotlinCoreEnvironment(testDisposable)
@TempDir
override lateinit var testTempDir: File
@AfterEach
fun dispose() {
Disposer.dispose(testDisposable)
}
@Test
fun `test - simple class`() {
val module = createModuleDescriptor("class Foo")
val clazz = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!!
assertEquals(
ClassOrProtocolName("Foo", "Foo"),
createObjCExportNamer().getClassOrProtocolName(clazz)
)
}
@Test
fun `test - simple class - with prefix`() {
val module = createModuleDescriptor("class Foo")
val clazz = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!!
assertEquals(
ClassOrProtocolName("Foo", "XFoo"),
createObjCExportNamer(createObjCExportNamerConfiguration(topLevelNamePrefix = "X")).getClassOrProtocolName(clazz)
)
}
@Test
fun `test - simple function`() {
val module = createModuleDescriptor("fun foo() = 42")
val foo = module.getPackage(FqName.ROOT).memberScope.findSingleFunction(Name.identifier("foo"))
assertEquals("foo()", createObjCExportNamer().getSwiftName(foo))
assertEquals("foo", createObjCExportNamer().getSelector(foo))
}
@Test
fun `test - function with parameters`() {
val module = createModuleDescriptor("fun foo(a: Int, b: Int) = a + b")
val foo = module.getPackage(FqName.ROOT).memberScope.findSingleFunction(Name.identifier("foo"))
assertEquals("foo(a:b:)", createObjCExportNamer().getSwiftName(foo))
assertEquals("fooA:b:", createObjCExportNamer().getSelector(foo))
}
@Test
fun `test - simple property`() {
val module = createModuleDescriptor("val foo = 42")
val foo = module.getPackage(FqName.ROOT).memberScope.findFirstVariable("foo") { true }!!
assertEquals(PropertyName("foo", "foo"), createObjCExportNamer().getPropertyName(foo))
}
@Test
fun `test - simple property - with prefix`() {
val module = createModuleDescriptor("val foo = 42")
val foo = module.getPackage(FqName.ROOT).memberScope.findFirstVariable("foo") { true }!!
assertEquals(
PropertyName("foo", "foo"),
createObjCExportNamer(createObjCExportNamerConfiguration(topLevelNamePrefix = "X")).getPropertyName(foo))
}
@Test
fun `test - function inside class`() {
val module = createModuleDescriptor("""
package bar
class Foo {
fun someFunction(a: Int, b: Int) = a + b
}
""".trimIndent()
)
val fooClass = module.findClassAcrossModuleDependencies(ClassId.fromString("bar/Foo"))!!
val someFunction = fooClass.unsubstitutedMemberScope.findSingleFunction(Name.identifier("someFunction"))
assertEquals("someFunction(a:b:)", createObjCExportNamer().getSwiftName(someFunction))
assertEquals("someFunctionA:b:", createObjCExportNamer().getSelector(someFunction))
}
@Test
fun `test - class with ObjCName annotation`() {
val module = createModuleDescriptor("""
@kotlin.native.ObjCName("ObjCFoo", "SwiftFoo")
class Foo
""".trimIndent())
val fooClass = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!!
assertEquals(
ClassOrProtocolName(swiftName = "SwiftFoo", objCName = "ObjCFoo"),
createObjCExportNamer().getClassOrProtocolName(fooClass)
)
}
@Test
fun `test - simple parameter`() {
val module = createModuleDescriptor("fun foo(a: Int)")
val foo = module.getPackage(FqName.ROOT).memberScope.findSingleFunction(Name.identifier("foo"))
val parameterA = foo.valueParameters.find { it.name == Name.identifier("a") }!!
assertEquals("a", createObjCExportNamer().getParameterName(parameterA))
}
@Test
fun `test - parameter with ObjCName annotation`() {
val module = createModuleDescriptor("""
import kotlin.native.ObjCName
fun foo(@ObjCName("aObjC", "aSwift") a: Int)
""".trimIndent())
val foo = module.getPackage(FqName.ROOT).memberScope.findSingleFunction(Name.identifier("foo"))
val parameterA = foo.valueParameters.find { it.name == Name.identifier("a") }!!
assertEquals("aObjC", createObjCExportNamer().getParameterName(parameterA))
}
@Test
fun `test - class mangling`() {
val module = createModuleDescriptor {
source("""
package a
class Foo
""".trimIndent())
source("""
package b
class Foo
""".trimIndent())
}
val aFoo = module.findClassAcrossModuleDependencies(ClassId.fromString("a/Foo"))!!
val bFoo = module.findClassAcrossModuleDependencies(ClassId.fromString("b/Foo"))!!
val namer = createObjCExportNamer()
assertEquals(ClassOrProtocolName("Foo", "Foo"), namer.getClassOrProtocolName(aFoo))
assertEquals(ClassOrProtocolName("Foo_", "Foo_"), namer.getClassOrProtocolName(bFoo))
/* Check caching in namer: Should return same name again */
assertEquals(ClassOrProtocolName("Foo", "Foo"), namer.getClassOrProtocolName(aFoo))
}
@Test
fun `test - simple enum`() {
val module = createModuleDescriptor("""
enum class Foo {
A, B, C
}
""".trimIndent())
val foo = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!!
val fooA = foo.enumEntries.find { it.name == Name.identifier("A") }!!
val namer = createObjCExportNamer()
assertEquals(ClassOrProtocolName("Foo", "Foo"), namer.getClassOrProtocolName(foo))
assertEquals("a", namer.getEnumEntrySelector(fooA))
assertEquals("a", namer.getEnumEntrySwiftName(fooA))
}
}
@@ -1,41 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
@protocol Foo;
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
@protocol Foo
@required
- (id)someMethod __attribute__((swift_name("someMethod()")));
- (id)someMethodWithCovariantOverwrite __attribute__((swift_name("someMethodWithCovariantOverwrite()")));
@property (readonly) int32_t someProperty __attribute__((swift_name("someProperty")));
@end
__attribute__((objc_subclassing_restricted))
@interface Bar : Base <Foo>
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (id)someMethod __attribute__((swift_name("someMethod()")));
- (NSString *)someMethodWithCovariantOverwrite __attribute__((swift_name("someMethodWithCovariantOverwrite()")));
@property (readonly) int32_t someProperty __attribute__((swift_name("someProperty")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,11 +0,0 @@
interface Foo {
val someProperty: Int
fun someMethod(): Any
fun someMethodWithCovariantOverwrite(): Any
}
class Bar : Foo {
override val someProperty: Int = 42
override fun someMethod(): Any = ""
override fun someMethodWithCovariantOverwrite(): String = ""
}
@@ -1,29 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface NotHidden : Base
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,14 +0,0 @@
import kotlin.experimental.ExperimentalObjCRefinement
@ExperimentalObjCRefinement
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
@MustBeDocumented
@kotlin.native.HidesFromObjC
annotation class MyHiddenFromObjC
@OptIn(ExperimentalObjCRefinement::class)
@MyHiddenFromObjC
class Hidden
class NotHidden
@@ -1,52 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
/**
* This class [Foo] is documented.
*/
__attribute__((objc_subclassing_restricted))
@interface Foo : Base
/**
* This class [Foo] is documented.
*/
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
/**
* This class [Foo] is documented.
*/
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
/**
* This member function is documented
*/
- (void)someMemberFunction __attribute__((swift_name("someMemberFunction()")));
/**
* This member property is documented.
* It will return the 'The Answer to the Ultimate Question of Life, The Universe, and Everything'
*/
@property (readonly) int32_t someMemberProperty __attribute__((swift_name("someMemberProperty")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,17 +0,0 @@
/**
* This class [Foo] is documented.
*/
class Foo {
/**
* This member function is documented
*/
fun someMemberFunction() {
}
/**
* This member property is documented.
* It will return the 'The Answer to the Ultimate Question of Life, The Universe, and Everything'
*/
val someMemberProperty = 42
}
@@ -1,30 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("FooInSwift")))
@interface FooInObjC : Base
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,5 +0,0 @@
import kotlin.experimental.ExperimentalObjCName
@OptIn(ExperimentalObjCName::class)
@kotlin.native.ObjCName("FooInObjC", "FooInSwift")
class Foo
@@ -1,33 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
@class ERROR;
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface FooKt : Base
+ (ERROR *)foo __attribute__((swift_name("foo()")));
@end
@interface ERROR : Base
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1 +0,0 @@
fun foo() = Unresolved
@@ -1,35 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface Foo : Base
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (void)objcMemberFunction __attribute__((swift_name("swiftMemberFunction()")));
@end
__attribute__((objc_subclassing_restricted))
@interface FooKt : Base
+ (NSString *)objcTopLevelFunction __attribute__((swift_name("swiftTopLevelFunction()")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,11 +0,0 @@
@file:OptIn(ExperimentalObjCName::class)
import kotlin.experimental.ExperimentalObjCName
@kotlin.native.ObjCName("objcTopLevelFunction", "swiftTopLevelFunction")
fun someTopLevelFunction() = ""
class Foo {
@kotlin.native.ObjCName("objcMemberFunction", "swiftMemberFunction")
fun someMemberFunction() = Unit
}
@@ -1,65 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
@class Throwable;
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
@interface Throwable : Base
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer));
- (instancetype)initWithCause:(Throwable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer));
- (instancetype)initWithMessage:(NSString * _Nullable)message cause:(Throwable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer));
@property (readonly) Throwable * _Nullable cause __attribute__((swift_name("cause")));
@property (readonly) NSString * _Nullable message __attribute__((swift_name("message")));
- (NSError *)asError __attribute__((swift_name("asError()")));
@end
__attribute__((objc_subclassing_restricted))
@interface MyError : Throwable
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
- (instancetype)initWithCause:(Throwable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
- (instancetype)initWithMessage:(NSString * _Nullable)message cause:(Throwable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
@end
__attribute__((objc_subclassing_restricted))
@interface FooKt : Base
/**
* @note This method converts all Kotlin exceptions to errors.
*/
+ (BOOL)barAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("bar()")));
/**
* @note This method converts instances of MyError to errors.
* Other uncaught Kotlin exceptions are fatal.
*/
+ (BOOL)fooAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo()")));
/**
* @note This method converts all Kotlin exceptions to errors.
*/
+ (NSString * _Nullable)someStringAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("someString()")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,10 +0,0 @@
class MyError : Throwable()
@Throws(MyError::class)
fun foo() = Unit
@Throws(Throwable::class)
fun bar() = Unit
@Throws(Throwable::class)
fun someString() = ""
@@ -1,36 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
@protocol Foo;
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
@protocol Foo
@required
- (id)someMethod __attribute__((swift_name("someMethod()")));
- (id)someMethodWithCovariantOverwrite __attribute__((swift_name("someMethodWithCovariantOverwrite()")));
@property (readonly) int32_t someProperty __attribute__((swift_name("someProperty")));
@end
@protocol Bar <Foo>
@required
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,9 +0,0 @@
interface Foo {
val someProperty: Int
fun someMethod(): Any
fun someMethodWithCovariantOverwrite(): Any
}
interface Bar : Foo {
override fun someMethodWithCovariantOverwrite(): String = ""
}
@@ -1,37 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface Foo : Base
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (NSString *)someMethodInFooA __attribute__((swift_name("someMethodInFooA()")));
@end
__attribute__((objc_subclassing_restricted))
@interface Foo_ : Base
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (NSString *)someMethodInFooB __attribute__((swift_name("someMethodInFooB()")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,5 +0,0 @@
package a
class Foo {
fun someMethodInFooA() = ""
}
@@ -1,5 +0,0 @@
package b
class Foo {
fun someMethodInFooB() = ""
}
@@ -1,29 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface FooKt : Base
+ (NSString *)foo __attribute__((swift_name("foo()")));
@property (class, readonly, getter=foo_) int32_t foo __attribute__((swift_name("foo")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,2 +0,0 @@
fun foo() = ""
val foo = 42
@@ -1,31 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface Foo : Base
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (NSString *)someMethod __attribute__((swift_name("someMethod()")));
@property (readonly) int32_t someProperty __attribute__((swift_name("someProperty")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,4 +0,0 @@
class Foo {
val someProperty: Int = 42
fun someMethod(): String = ""
}
@@ -1,85 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
@class EnumCompanion, Enum<E>, Foo, Array<T>;
@protocol Comparable, Iterator;
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
@protocol Comparable
@required
- (int32_t)compareToOther:(id _Nullable)other __attribute__((swift_name("compareTo(other:)")));
@end
@interface Enum<E> : Base <Comparable>
- (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer));
@property (class, readonly, getter=companion) EnumCompanion *companion __attribute__((swift_name("companion")));
/**
* @note This method has protected visibility in Kotlin source and is intended only for use by subclasses.
*/
- (id)clone __attribute__((swift_name("clone()")));
- (int32_t)compareToOther:(E)other __attribute__((swift_name("compareTo(other:)")));
- (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)")));
- (NSUInteger)hash __attribute__((swift_name("hash()")));
- (NSString *)description __attribute__((swift_name("description()")));
@property (readonly) NSString *name __attribute__((swift_name("name")));
@property (readonly) int32_t ordinal __attribute__((swift_name("ordinal")));
@end
__attribute__((objc_subclassing_restricted))
@interface Foo : Enum<Foo *>
+ (instancetype)alloc __attribute__((unavailable));
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
- (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
@property (class, readonly) Foo *a __attribute__((swift_name("a")));
@property (class, readonly) Foo *b __attribute__((swift_name("b")));
@property (class, readonly) Foo *c __attribute__((swift_name("c")));
+ (Array<Foo *> *)values __attribute__((swift_name("values()")));
@property (class, readonly) NSArray<Foo *> *entries __attribute__((swift_name("entries")));
@end
__attribute__((objc_subclassing_restricted))
@interface EnumCompanion : Base
+ (instancetype)alloc __attribute__((unavailable));
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
+ (instancetype)companion __attribute__((swift_name("init()")));
@property (class, readonly, getter=shared) EnumCompanion *shared __attribute__((swift_name("shared")));
@end
__attribute__((objc_subclassing_restricted))
@interface Array<T> : Base
+ (instancetype)arrayWithSize:(int32_t)size init:(T _Nullable (^)(Int *))init __attribute__((swift_name("init(size:init:)")));
+ (instancetype)alloc __attribute__((unavailable));
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
- (T _Nullable)getIndex:(int32_t)index __attribute__((swift_name("get(index:)")));
- (id<Iterator>)iterator __attribute__((swift_name("iterator()")));
- (void)setIndex:(int32_t)index value:(T _Nullable)value __attribute__((swift_name("set(index:value:)")));
@property (readonly) int32_t size __attribute__((swift_name("size")));
@end
@protocol Iterator
@required
- (BOOL)hasNext __attribute__((swift_name("hasNext()")));
- (id _Nullable)next __attribute__((swift_name("next()")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,3 +0,0 @@
enum class Foo {
A, B, C
}
@@ -1,29 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
@protocol Foo
@required
- (NSString *)someMethod __attribute__((swift_name("someMethod()")));
@property (readonly) int32_t someProperty __attribute__((swift_name("someProperty")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,4 +0,0 @@
interface Foo {
val someProperty: Int
fun someMethod(): String
}
@@ -1,35 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
@class Foo;
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface Foo : Base
+ (instancetype)alloc __attribute__((unavailable));
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
+ (instancetype)foo __attribute__((swift_name("init()")));
@property (class, readonly, getter=shared) Foo *shared __attribute__((swift_name("shared")));
- (NSString *)someMethod __attribute__((swift_name("someMethod()")));
@property (readonly) int32_t someProperty __attribute__((swift_name("someProperty")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1,4 +0,0 @@
object Foo {
val someProperty = 42
fun someMethod() = ""
}
@@ -1,28 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface FooKt : Base
+ (NSString *)myTopLevelFunction __attribute__((swift_name("myTopLevelFunction()")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1 +0,0 @@
fun myTopLevelFunction() = ""
@@ -1,28 +0,0 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSError.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wincompatible-property-type"
#pragma clang diagnostic ignored "-Wnullability"
#pragma push_macro("_Nullable_result")
#if !__has_feature(nullability_nullable_result)
#undef _Nullable_result
#define _Nullable_result _Nullable
#endif
__attribute__((objc_subclassing_restricted))
@interface FooKt : Base
@property (class, readonly) int32_t myTopLevelProperty __attribute__((swift_name("myTopLevelProperty")));
@end
#pragma pop_macro("_Nullable_result")
#pragma clang diagnostic pop
NS_ASSUME_NONNULL_END
@@ -1 +0,0 @@
val myTopLevelProperty = 42