[K/N][Tests] Move filecheck and cinterop tests to /native/
^KT-61259
This commit is contained in:
committed by
Space Team
parent
05cbe66ee0
commit
bf0150108d
@@ -0,0 +1,125 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// LANGUAGE: +ImplicitSignedToUnsignedIntegerConversion
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: direct.def
|
||||
language = Objective-C
|
||||
headers = direct.h
|
||||
headerFilter = direct.h
|
||||
|
||||
// FILE: direct.h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__attribute__((objc_runtime_name("CC")))
|
||||
__attribute__((swift_name("CC")))
|
||||
@interface CallingConventions : NSObject
|
||||
|
||||
+ (uint64_t)regular:(uint64_t)arg;
|
||||
- (uint64_t)regular:(uint64_t)arg;
|
||||
|
||||
+ (uint64_t)direct:(uint64_t)arg __attribute__((objc_direct));
|
||||
- (uint64_t)direct:(uint64_t)arg __attribute__((objc_direct));
|
||||
|
||||
@end
|
||||
|
||||
@interface CallingConventions(Ext)
|
||||
|
||||
+ (uint64_t)regularExt:(uint64_t)arg;
|
||||
- (uint64_t)regularExt:(uint64_t)arg;
|
||||
|
||||
+ (uint64_t)directExt:(uint64_t)arg __attribute__((objc_direct));
|
||||
- (uint64_t)directExt:(uint64_t)arg __attribute__((objc_direct));
|
||||
|
||||
@end
|
||||
|
||||
__attribute__((objc_runtime_name("CCH")))
|
||||
__attribute__((swift_name("CCH")))
|
||||
@interface CallingConventionsHeir : CallingConventions
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
// FILE: direct.m
|
||||
#import "direct.h"
|
||||
|
||||
#define TEST_METHOD_IMPL(NAME) (uint64_t)NAME:(uint64_t)arg { return arg; }
|
||||
|
||||
@implementation CallingConventions : NSObject
|
||||
|
||||
+ TEST_METHOD_IMPL(regular);
|
||||
- TEST_METHOD_IMPL(regular);
|
||||
|
||||
+ TEST_METHOD_IMPL(direct);
|
||||
- TEST_METHOD_IMPL(direct);
|
||||
|
||||
@end
|
||||
|
||||
@implementation CallingConventions(Ext)
|
||||
|
||||
+ TEST_METHOD_IMPL(regularExt);
|
||||
- TEST_METHOD_IMPL(regularExt);
|
||||
|
||||
+ TEST_METHOD_IMPL(directExt);
|
||||
- TEST_METHOD_IMPL(directExt);
|
||||
|
||||
@end
|
||||
|
||||
@implementation CallingConventionsHeir
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import direct.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
class CallingConventionsNativeHeir() : CallingConventions() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
typealias CC = CallingConventions
|
||||
typealias CCH = CallingConventionsHeir
|
||||
typealias CCN = CallingConventionsNativeHeir
|
||||
|
||||
// KT-54610
|
||||
fun box(): String {
|
||||
autoreleasepool {
|
||||
val cc = CC()
|
||||
val cch = CCH()
|
||||
val ccn = CCN()
|
||||
|
||||
assertEquals(42UL, CC.regular(42))
|
||||
assertEquals(42UL, cc.regular(42))
|
||||
assertEquals(42UL, CC.regularExt(42))
|
||||
assertEquals(42UL, cc.regularExt(42))
|
||||
|
||||
assertEquals(42UL, CCH.regular(42))
|
||||
assertEquals(42UL, cch.regular(42))
|
||||
assertEquals(42UL, CCH.regularExt(42))
|
||||
assertEquals(42UL, cch.regularExt(42))
|
||||
|
||||
assertEquals(42UL, ccn.regular(42UL))
|
||||
assertEquals(42UL, ccn.regularExt(42UL))
|
||||
|
||||
assertEquals(42UL, CC.direct(42))
|
||||
assertEquals(42UL, cc.direct(42))
|
||||
assertEquals(42UL, CC.directExt(42))
|
||||
assertEquals(42UL, cc.directExt(42))
|
||||
|
||||
assertEquals(42UL, CCH.direct(42))
|
||||
assertEquals(42UL, cch .direct(42))
|
||||
assertEquals(42UL, CCH.directExt(42))
|
||||
assertEquals(42UL, cch .directExt(42))
|
||||
|
||||
assertEquals(42UL, ccn .direct(42UL))
|
||||
assertEquals(42UL, ccn .directExt(42UL))
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// `import objcnames` somehow works only with NATIVE_STANDALONE test directive
|
||||
// NATIVE_STANDALONE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// MODULE: a
|
||||
// FILE: a.def
|
||||
language = Objective-C
|
||||
---
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct ForwardDeclaredStruct;
|
||||
@class ForwardDeclaredClass;
|
||||
@protocol ForwardDeclaredProtocol;
|
||||
|
||||
NSString* consumeProtocol(id<ForwardDeclaredProtocol> s) {
|
||||
return [NSString stringWithUTF8String:"Protocol"];
|
||||
}
|
||||
NSString* consumeClass(ForwardDeclaredClass* s) {
|
||||
return [NSString stringWithUTF8String:"Class"];
|
||||
}
|
||||
NSString* consumeStruct(struct ForwardDeclaredStruct* s) {
|
||||
return [NSString stringWithUTF8String:"Struct"];
|
||||
}
|
||||
|
||||
// MODULE: b
|
||||
// FILE: b.def
|
||||
language = Objective-C
|
||||
headers = b.h
|
||||
---
|
||||
|
||||
// FILE: b.h
|
||||
#define NS_FORMAT_ARGUMENT(X)
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol ForwardDeclaredProtocol
|
||||
@end
|
||||
|
||||
@interface ForwardDeclaredProtocolImpl : NSObject<ForwardDeclaredProtocol>
|
||||
@end;
|
||||
|
||||
|
||||
@interface ForwardDeclaredClass : NSObject
|
||||
@end;
|
||||
|
||||
struct ForwardDeclaredStruct {};
|
||||
|
||||
id<ForwardDeclaredProtocol> produceProtocol();
|
||||
ForwardDeclaredClass* produceClass();
|
||||
struct ForwardDeclaredStruct* produceStruct();
|
||||
|
||||
// FILE: b.m
|
||||
#import "b.h"
|
||||
|
||||
@implementation ForwardDeclaredProtocolImpl : NSObject
|
||||
@end;
|
||||
|
||||
@implementation ForwardDeclaredClass : NSObject
|
||||
@end;
|
||||
|
||||
id<ForwardDeclaredProtocol> produceProtocol() {
|
||||
return [ForwardDeclaredProtocolImpl new];
|
||||
}
|
||||
|
||||
ForwardDeclaredClass* produceClass() {
|
||||
return [ForwardDeclaredClass new];
|
||||
}
|
||||
|
||||
struct ForwardDeclaredStruct S;
|
||||
|
||||
struct ForwardDeclaredStruct* produceStruct() {
|
||||
return &S;
|
||||
}
|
||||
|
||||
// MODULE: lib(a)
|
||||
// FILE: lib.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cnames.structs.ForwardDeclaredStruct
|
||||
import objcnames.classes.ForwardDeclaredClass
|
||||
import objcnames.protocols.ForwardDeclaredProtocolProtocol
|
||||
import a.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun testStruct(s: Any?) = consumeStruct(s as CPointer<ForwardDeclaredStruct>)
|
||||
fun testClass(s: Any?) = consumeClass(s as ForwardDeclaredClass)
|
||||
fun testProtocol(s: Any?) = consumeProtocol(s as ForwardDeclaredProtocolProtocol)
|
||||
|
||||
|
||||
fun <T : ForwardDeclaredClass> testClass2Impl(s: Any?) = consumeClass(s as T)
|
||||
fun <T : ForwardDeclaredProtocolProtocol> testProtocol2Impl(s: Any?) = consumeProtocol(s as T)
|
||||
|
||||
fun testClass2(s: Any?) = testClass2Impl<ForwardDeclaredClass>(s)
|
||||
fun testProtocol2(s: Any?) = testProtocol2Impl<ForwardDeclaredProtocolProtocol>(s)
|
||||
|
||||
// MODULE: main(lib, b)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import a.*
|
||||
import b.*
|
||||
|
||||
|
||||
fun box(): String {
|
||||
if (testStruct(produceStruct()) != "Struct") throw IllegalStateException()
|
||||
if (testClass(produceClass()) != "Class") throw IllegalStateException()
|
||||
if (testProtocol(produceProtocol()) != "Protocol") throw IllegalStateException()
|
||||
if (testClass2(produceClass()) != "Class") throw IllegalStateException()
|
||||
if (testProtocol2(produceProtocol()) != "Protocol") throw IllegalStateException()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// FREE_CINTEROP_ARGS: -compiler-option -fmodule-map-file=$generatedSourcesDir/cinterop/module_library.modulemap
|
||||
// MODULE: cinterop
|
||||
// FILE: module_library.def
|
||||
language = Objective-C
|
||||
modules = module_library
|
||||
|
||||
// FILE: module_library.modulemap
|
||||
module module_library {
|
||||
umbrella header "module_library_umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
|
||||
// FILE: module_library_umbrella.h
|
||||
#import <foo.h>
|
||||
|
||||
// FILE: foo.h
|
||||
#define ANSWER 42
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import module_library.*
|
||||
|
||||
fun box(): String {
|
||||
val answer = ANSWER
|
||||
if (answer != 42)
|
||||
return "FAIL: $answer"
|
||||
return "OK"
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// Without a fix, fails in two-stage mode.
|
||||
// The bug was accidentally fixed with lazy IR for caches, so testing it with this feature disabled:
|
||||
// FREE_COMPILER_ARGS: -Xlazy-ir-for-caches=disable
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: objclib.def
|
||||
language = Objective-C
|
||||
headers = objclib.h
|
||||
headerFilter = objclib.h **/NSObject.h **/NSDate.h **/NSUUID.h
|
||||
|
||||
// FILE: objclib.h
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSUUID.h>
|
||||
|
||||
@interface MyClass1 : NSObject
|
||||
@end
|
||||
|
||||
@interface MyClass2 : NSObject
|
||||
@end
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.reflect.*
|
||||
import kotlin.test.*
|
||||
import objclib.*
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-48816
|
||||
open class Base<Ref> {
|
||||
operator fun KProperty1<Ref, NSUUID>.getValue(ref: Base<Ref>, property: KProperty<*>): NSUUID? {
|
||||
return null
|
||||
}
|
||||
operator fun KProperty1<Ref, NSDate>.getValue(ref: Base<Ref>, property: KProperty<*>): NSDate? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
class Usage: Base<B>()
|
||||
class B
|
||||
|
||||
// The compilation should fail with the above;
|
||||
// but anyway try to actually use the code, just to ensure it doesn't get DCEd:
|
||||
|
||||
val B.uuid: NSUUID get() = fail()
|
||||
val B.date: NSDate get() = fail()
|
||||
|
||||
fun test1() {
|
||||
val uuidProperty = B::uuid
|
||||
val dateProperty = B::date
|
||||
val usage = Usage()
|
||||
with(usage) {
|
||||
assertNull(uuidProperty.getValue(usage, uuidProperty))
|
||||
assertNull(dateProperty.getValue(usage, dateProperty))
|
||||
}
|
||||
}
|
||||
|
||||
// One more reproducer, just in case:
|
||||
class Property<out R>
|
||||
|
||||
open class Base2 {
|
||||
fun getValue(property: Property<MyClass1>) = null
|
||||
fun getValue(property: Property<MyClass2>) = null
|
||||
}
|
||||
class Usage2 : Base2()
|
||||
|
||||
fun test2() {
|
||||
val usage = Usage2()
|
||||
assertNull(usage.getValue(Property<MyClass1>()))
|
||||
assertNull(usage.getValue(Property<MyClass2>()))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
test1()
|
||||
test2()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// The bug was accidentally fixed with lazy IR for caches, so testing it with this feature enabled, and disabled(in other test file):
|
||||
// FREE_COMPILER_ARGS: -Xlazy-ir-for-caches=enable
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: objclib.def
|
||||
language = Objective-C
|
||||
headers = objclib.h
|
||||
headerFilter = objclib.h **/NSObject.h **/NSDate.h **/NSUUID.h
|
||||
|
||||
// FILE: objclib.h
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSUUID.h>
|
||||
|
||||
@interface MyClass1 : NSObject
|
||||
@end
|
||||
|
||||
@interface MyClass2 : NSObject
|
||||
@end
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.reflect.*
|
||||
import kotlin.test.*
|
||||
import objclib.*
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-48816
|
||||
open class Base<Ref> {
|
||||
operator fun KProperty1<Ref, NSUUID>.getValue(ref: Base<Ref>, property: KProperty<*>): NSUUID? {
|
||||
return null
|
||||
}
|
||||
operator fun KProperty1<Ref, NSDate>.getValue(ref: Base<Ref>, property: KProperty<*>): NSDate? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
class Usage: Base<B>()
|
||||
class B
|
||||
|
||||
// The compilation should fail with the above;
|
||||
// but anyway try to actually use the code, just to ensure it doesn't get DCEd:
|
||||
|
||||
val B.uuid: NSUUID get() = fail()
|
||||
val B.date: NSDate get() = fail()
|
||||
|
||||
fun test1() {
|
||||
val uuidProperty = B::uuid
|
||||
val dateProperty = B::date
|
||||
val usage = Usage()
|
||||
with(usage) {
|
||||
assertNull(uuidProperty.getValue(usage, uuidProperty))
|
||||
assertNull(dateProperty.getValue(usage, dateProperty))
|
||||
}
|
||||
}
|
||||
|
||||
// One more reproducer, just in case:
|
||||
class Property<out R>
|
||||
|
||||
open class Base2 {
|
||||
fun getValue(property: Property<MyClass1>) = null
|
||||
fun getValue(property: Property<MyClass2>) = null
|
||||
}
|
||||
class Usage2 : Base2()
|
||||
|
||||
fun test2() {
|
||||
val usage = Usage2()
|
||||
assertNull(usage.getValue(Property<MyClass1>()))
|
||||
assertNull(usage.getValue(Property<MyClass2>()))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
test1()
|
||||
test2()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// `import objcnames` somehow works only with NATIVE_STANDALONE test directive
|
||||
// NATIVE_STANDALONE
|
||||
// The test checks no collision between kt49034.__darwin_fp_control and platform.posix.__darwin_fp_control
|
||||
// The test makes sense only on Apple x64 targets, where `class __darwin_fp_control` present in posix platform lib
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// DISABLE_NATIVE: targetArchitecture=ARM64
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: kt49034.def
|
||||
headers = kt49034.h
|
||||
language = Objective-C
|
||||
|
||||
// FILE: kt49034.h
|
||||
@class __darwin_fp_control;
|
||||
void foo(__darwin_fp_control*);
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import objcnames.classes.__darwin_fp_control
|
||||
|
||||
open class C<T : kotlinx.cinterop.ObjCObject>
|
||||
|
||||
class D : C<__darwin_fp_control>()
|
||||
|
||||
fun box(): String {
|
||||
println(D())
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: checkPlatformDarwinFPControl.kt
|
||||
import platform.posix.__darwin_fp_control
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// The test depends on collision between kt49034.JSContext and platform.JavaScriptCore.JSContext
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// There is no JavaScriptCore on watchOS.
|
||||
// DISABLE_NATIVE: targetFamily=WATCHOS
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: kt49034.def
|
||||
headers = kt49034.h
|
||||
|
||||
// FILE: kt49034.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct JSContext;
|
||||
|
||||
struct JSContext* bar();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: impl.c
|
||||
#include "kt49034.h"
|
||||
|
||||
struct JSContext {
|
||||
int field;
|
||||
};
|
||||
|
||||
struct JSContext global = { 15 };
|
||||
|
||||
extern "C" struct JSContext* bar() {
|
||||
return &global;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kt49034.bar
|
||||
import cnames.structs.JSContext
|
||||
import kotlinx.cinterop.CPointer
|
||||
|
||||
fun baz(s: CPointer<JSContext>) {
|
||||
println(s)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
baz(bar()!!)
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: checkPlatformJavaScriptCore.kt
|
||||
import platform.JavaScriptCore.JSContext
|
||||
@@ -0,0 +1,39 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// FREE_CINTEROP_ARGS: -compiler-option -F$generatedSourcesDir/cinterop
|
||||
// MODULE: cinterop
|
||||
// FILE: objclib.def
|
||||
language = Objective-C
|
||||
modules = Foo
|
||||
---
|
||||
static int getDefInt() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int getFrameworkIntFromDef() {
|
||||
return getFrameworkInt();
|
||||
}
|
||||
|
||||
// FILE: Foo.framework/Headers/Foo.h
|
||||
static int getFrameworkInt() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// FILE: Foo.framework/Modules/module.modulemap
|
||||
framework module Foo {
|
||||
umbrella header "Foo.h"
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.test.*
|
||||
import objclib.*
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(1, getFrameworkInt())
|
||||
assertEquals(2, getDefInt())
|
||||
assertEquals(1, getFrameworkIntFromDef())
|
||||
return "OK"
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: lib.def
|
||||
language = Objective-C
|
||||
headers = lib.h
|
||||
headerFilter = lib.h
|
||||
|
||||
// FILE: lib.h
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSUUID.h>
|
||||
|
||||
@interface ObjCClass : NSObject
|
||||
- (NSString*)fooWithArg:(int)arg arg2:(NSString*)arg2;
|
||||
- (NSString*)fooWithArg:(int)ohNoOtherName name2:(NSString*)name2;
|
||||
- (NSString*)fooWithArg:(int)arg name3:(NSString*)name3;
|
||||
@end
|
||||
|
||||
// FILE: lib.m
|
||||
#import "lib.h"
|
||||
|
||||
@implementation ObjCClass {
|
||||
}
|
||||
|
||||
- (NSString*)fooWithArg:(int)arg arg2:(NSString*)arg2 {
|
||||
return @"A";
|
||||
}
|
||||
|
||||
- (NSString*)fooWithArg:(int)ohNoOtherName name2:(NSString*)name2 {
|
||||
return @"B";
|
||||
}
|
||||
|
||||
- (NSString*)fooWithArg:(int)arg name3:(NSString*)name3 {
|
||||
return @"C";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
// required for K1
|
||||
@file:Suppress("CONFLICTING_OVERLOADS", "UNRESOLVED_REFERENCE", "API_NOT_AVAILABLE")
|
||||
|
||||
import lib.ObjCClass
|
||||
import kotlinx.cinterop.ObjCSignatureOverride
|
||||
|
||||
class OverrideAll : ObjCClass() {
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(arg: Int, arg2: String?) = "D"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(ohNoOtherName: Int, name2: String?) = "E"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(arg: Int, name3: String?) = "F"
|
||||
}
|
||||
|
||||
class OverrideNone : ObjCClass() {
|
||||
}
|
||||
|
||||
class OverrideOne : ObjCClass() {
|
||||
override fun fooWithArg(arg: Int, arg2: String?) = "G"
|
||||
}
|
||||
|
||||
class OverrideWithDifferentFirstArgName : ObjCClass() {
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(a: Int, arg2: String?) = "H"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(b: Int, name2: String?) = "I"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(c: Int, name3: String?) = "J"
|
||||
}
|
||||
|
||||
fun test(x: ObjCClass, expected: String) {
|
||||
val res = x.fooWithArg(arg = 0, arg2 = "") +
|
||||
x.fooWithArg(ohNoOtherName = 0, name2="") +
|
||||
x.fooWithArg(arg = 0, name3 = "")
|
||||
if (res != expected) throw IllegalStateException("Fail ${x::class}: ${res} instead of $expected")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
test(ObjCClass(), "ABC")
|
||||
test(OverrideAll(), "DEF")
|
||||
test(OverrideNone(), "ABC")
|
||||
test(OverrideOne(), "GBC")
|
||||
test(OverrideWithDifferentFirstArgName(), "HIJ")
|
||||
|
||||
// Also test non-virtual calls
|
||||
val x1 = OverrideAll()
|
||||
val res1 = x1.fooWithArg(arg = 0, arg2 = "") +
|
||||
x1.fooWithArg(ohNoOtherName = 0, name2="") +
|
||||
x1.fooWithArg(arg = 0, name3 = "")
|
||||
if (res1 != "DEF") throw IllegalStateException("Fail OverrideAll non-virtual: ${res1} instead of DEF")
|
||||
|
||||
val x2 = OverrideNone()
|
||||
val res2 = x2.fooWithArg(arg = 0, arg2 = "") +
|
||||
x2.fooWithArg(ohNoOtherName = 0, name2="") +
|
||||
x2.fooWithArg(arg = 0, name3 = "")
|
||||
if (res2 != "ABC") throw IllegalStateException("Fail OverrideNone non-virtual: ${res2} instead of ABC")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: objclib.def
|
||||
language = Objective-C
|
||||
headers = objclib.h
|
||||
headerFilter = objclib.h
|
||||
|
||||
// FILE: objclib.h
|
||||
#import <objc/NSObject.h>
|
||||
|
||||
static NSObject* __weak globalObject = nil;
|
||||
|
||||
void setObject(NSObject* obj) {
|
||||
globalObject = obj;
|
||||
}
|
||||
|
||||
bool isObjectAlive() {
|
||||
return globalObject != nil;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(ObsoleteWorkersApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.autoreleasepool
|
||||
import objclib.*
|
||||
|
||||
fun box(): String {
|
||||
val success = autoreleasepool {
|
||||
run()
|
||||
}
|
||||
// Experimental MM supports arbitrary object sharing.
|
||||
return if (success) "OK" else "FAIL"
|
||||
}
|
||||
|
||||
private class NSObjectImpl : NSObject() {
|
||||
var x = 111
|
||||
}
|
||||
|
||||
fun run() = withWorker {
|
||||
val obj = NSObjectImpl()
|
||||
setObject(obj)
|
||||
|
||||
try {
|
||||
execute(TransferMode.SAFE, {}) {
|
||||
isObjectAlive()
|
||||
}.result
|
||||
} catch (e: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user