Files
kotlin-fork/compiler/testData/codegen/box/cinterop/kt64105.kt
T
Svyatoslav Scherbina 2e5a9b1416 [K/N] Make cinterop include unused Objective-C forward declarations
Previously, when an Objective-C library had an unused Objective-C
forward declaration (`@class` or `@protocol`), cinterop tool didn't
include it into the resulting klib at all.

This led to a subtle bug (KT-64105). One Obj-C library has unused
Obj-C forward declaration, and another one depends on the first and
uses this forward declaration, e.g. as a function result type.
When building the first cinterop klib, this forward declaration is not
added to `includedForwardDeclarations` in the klib manifest (the
compiler uses this property to decide whether to synthesize the
corresponding class).
When building the second cinterop klib, the forward declaration is not
added to its manifest either, because it is located in the dependency
(and therefore should've been included there).
As a result, the forward declaration is included nowhere, and any
attempt to use it in Kotlin fails, including calling the function from
the second lib.

This commit fixes this bug by including even unused Objective-C forward
declarations, which is consistent with any other kind of declarations
and seems more natural.

^KT-64105 Fixed
2024-01-25 14:06:10 +00:00

58 lines
1.1 KiB
Kotlin
Vendored

/*
* 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.
*/
// TARGET_BACKEND: NATIVE
// MODULE: lib1
// FILE: lib1.def
language=Objective-C
headers=lib1.h
// FILE: lib1.h
@class Foo;
@protocol Bar;
struct Baz;
// MODULE: lib2(lib1)
// FILE: lib2.def
language=Objective-C
headers=lib2.h
// FILE: lib2.h
#import "../lib1/lib1.h"
Foo* createFoo() {
return 0;
}
id<Bar> createBar() {
return 0;
}
struct Baz* createBaz() {
return 0;
}
// MODULE: main(lib1,lib2)
// FILE: main.kt
import kotlinx.cinterop.CPointer
import lib1.*
import lib2.*
import cnames.structs.Baz
import objcnames.classes.Foo
import objcnames.protocols.BarProtocol
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
fun box(): String {
val foo: Foo? = createFoo()
if (foo !== null) return "FAIL 1"
val bar: BarProtocol? = createBar()
if (bar !== null) return "FAIL 2"
val baz: CPointer<Baz>? = createBaz()
if (baz !== null) return "FAIL 3"
return "OK"
}