[K/N] Implement lightweight tests for ObjC header generation

This commit is contained in:
Sebastian Sellmair
2023-11-21 13:59:09 +01:00
committed by Space Team
parent 06811dfc2f
commit ddd97e84b9
41 changed files with 1074 additions and 2 deletions
+30 -2
View File
@@ -29,6 +29,12 @@ sourceSets {
cli_bc {
kotlin.srcDir 'cli.bc/src'
}
test {
kotlin {
srcDir 'functionalTest/src'
}
}
}
compileCompilerKotlin {
@@ -119,7 +125,6 @@ kotlinNativeInterop {
}
}
configurations {
compilerApi {
extendsFrom kotlinNativeInterop['llvm'].configuration
@@ -182,8 +187,9 @@ dependencies {
cli_bcApi sourceSets.compiler.output
cli_bcApiElements sourceSets.cli_bc.output
}
testImplementation(project(path: ":compiler:tests-common", configuration: "tests-jar"))
}
classes.dependsOn 'compilerClasses', 'cli_bcClasses'
@@ -243,3 +249,25 @@ RepoArtifacts.sourcesJar(project) {
}
RepoArtifacts.javadocJar(project)
/*
Configure 'test' task
*/
TasksKt.projectTest(project)
tasks {
test {
dependsOn ':kotlin-native:dist'
systemProperty("org.jetbrains.kotlin.native.home", distDir.canonicalPath)
workingDir(rootProject.projectDir)
}
}
kotlin {
target {
compilations {
test.associateWith(compiler)
}
}
}
@@ -0,0 +1,2 @@
[*]
ij_continuation_indent_size = 4
@@ -0,0 +1,39 @@
/*
* 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)
@@ -0,0 +1,174 @@
/*
* 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 compilerConfiguration = createCompilerConfiguration()
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 = KotlinCoreEnvironment.createForTests(
parentDisposable = disposable,
initialConfiguration = compilerConfiguration,
extensionConfigs = EnvironmentConfigFiles.METADATA_CONFIG_FILES
)
val phaseContext = BasicPhaseContext(
KonanConfig(environment.project, compilerConfiguration)
)
val kotlinFiles = root.walkTopDown().filter { it.isFile }.filter { it.extension == "kt" }.toList()
return ObjCExportHeaderGeneratorImpl(
context = phaseContext,
moduleDescriptors = listOf(getModuleDescriptor(environment, kotlinFiles)),
mapper = mapper,
namer = namer,
problemCollector = ObjCExportProblemCollector.SILENT,
objcGenerics = true
)
}
private fun getModuleDescriptor(
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
}
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)
}
private fun createCompilerConfiguration(): CompilerConfiguration {
val configuration = KotlinTestUtils.newConfiguration()
configuration.put(KONAN_HOME, konanHomePath)
configuration.put(CLIConfigurationKeys.FLEXIBLE_PHASE_CONFIG, createFlexiblePhaseConfig(K2NativeCompilerArguments()))
configuration.put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, createLanguageVersionSettings())
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
)
}
@@ -0,0 +1,11 @@
/*
* 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'")
@@ -0,0 +1,11 @@
/*
* 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")
@@ -0,0 +1,105 @@
/*
* 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.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"))
}
}
@@ -0,0 +1,41 @@
#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
@@ -0,0 +1,11 @@
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 = ""
}
@@ -0,0 +1,29 @@
#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
@@ -0,0 +1,14 @@
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
@@ -0,0 +1,52 @@
#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
@@ -0,0 +1,17 @@
/**
* 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
}
@@ -0,0 +1,30 @@
#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
@@ -0,0 +1,5 @@
import kotlin.experimental.ExperimentalObjCName
@OptIn(ExperimentalObjCName::class)
@kotlin.native.ObjCName("FooInObjC", "FooInSwift")
class Foo
@@ -0,0 +1,35 @@
#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
@@ -0,0 +1,11 @@
@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
}
@@ -0,0 +1,65 @@
#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
@@ -0,0 +1,10 @@
class MyError : Throwable()
@Throws(MyError::class)
fun foo() = Unit
@Throws(Throwable::class)
fun bar() = Unit
@Throws(Throwable::class)
fun someString() = ""
@@ -0,0 +1,36 @@
#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
@@ -0,0 +1,9 @@
interface Foo {
val someProperty: Int
fun someMethod(): Any
fun someMethodWithCovariantOverwrite(): Any
}
interface Bar : Foo {
override fun someMethodWithCovariantOverwrite(): String = ""
}
@@ -0,0 +1,37 @@
#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
@@ -0,0 +1,5 @@
package a
class Foo {
fun someMethodInFooA() = ""
}
@@ -0,0 +1,5 @@
package b
class Foo {
fun someMethodInFooB() = ""
}
@@ -0,0 +1,29 @@
#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
@@ -0,0 +1,2 @@
fun foo() = ""
val foo = 42
@@ -0,0 +1,31 @@
#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
@@ -0,0 +1,4 @@
class Foo {
val someProperty: Int = 42
fun someMethod(): String = ""
}
@@ -0,0 +1,85 @@
#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
@@ -0,0 +1,3 @@
enum class Foo {
A, B, C
}
@@ -0,0 +1,29 @@
#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
@@ -0,0 +1,4 @@
interface Foo {
val someProperty: Int
fun someMethod(): String
}
@@ -0,0 +1,35 @@
#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
@@ -0,0 +1,4 @@
object Foo {
val someProperty = 42
fun someMethod() = ""
}
@@ -0,0 +1,28 @@
#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
@@ -0,0 +1 @@
fun myTopLevelFunction() = ""
@@ -0,0 +1,28 @@
#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
@@ -0,0 +1 @@
val myTopLevelProperty = 42
@@ -192,6 +192,7 @@ tasks.named("run") {
dependsOn(":kotlin-native:Interop:Indexer:check")
dependsOn(":kotlin-native:Interop:StubGenerator:check")
dependsOn(":native:kotlin-native-utils:check")
dependsOn(":kotlin-native:backend.native:check")
}
// Was a subset of tests.
@@ -103,6 +103,11 @@ enum class JUnitMode {
JUnit4, JUnit5
}
/**
* Convenience function to expose Project.projectTest for groovy
*/
fun projectTest(project: Project) = project.projectTest()
/**
* @param parallel is redundant if @param jUnit5Enabled is true, because
* JUnit5 supports parallel test execution by itself, without gradle help