[K/N][Tests] Move filecheck and cinterop tests to /native/

^KT-61259
This commit is contained in:
Vladimir Sukharev
2024-02-14 13:07:40 +01:00
committed by Space Team
parent 05cbe66ee0
commit bf0150108d
144 changed files with 1683 additions and 5542 deletions
@@ -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"
}
@@ -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"
}
@@ -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"
}
@@ -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
}
}