Skip to content

Commit cc0919d

Browse files
timofey-soloninSpace Team
authored and
Space Team
committed
Allow using categories in the def file to reintroduce methods in the class
^KT-71624
1 parent b1504e7 commit cc0919d

File tree

11 files changed

+152
-2
lines changed

11 files changed

+152
-2
lines changed

Diff for: kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,10 @@ public open class NativeIndexImpl(val library: NativeLibrary, val verbose: Boole
447447
val categoryClassName = clang_getCursorDisplayName(categoryClassCursor).convertAndDispose()
448448
if (className == categoryClassName) {
449449
val categoryFile = getContainingFile(childCursor)
450-
if (clang_File_isEqual(categoryFile, classFile) != 0) {
450+
val isCategoryInTheSameFileAsClass = clang_File_isEqual(categoryFile, classFile) != 0
451+
val isCategoryFromDefFile = library.allowIncludingObjCCategoriesFromDefFile
452+
&& clang_Location_isFromMainFile(clang_getCursorLocation(childCursor)) != 0
453+
if (isCategoryInTheSameFileAsClass || isCategoryFromDefFile) {
451454
result += childCursor
452455
}
453456
}

Diff for: kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ data class NativeLibrary(
116116
val headerExclusionPolicy: HeaderExclusionPolicy,
117117
val headerFilter: NativeLibraryHeaderFilter,
118118
val objCClassesIncludingCategories: Set<String>,
119+
val allowIncludingObjCCategoriesFromDefFile: Boolean,
119120
) : Compilation
120121

121122
data class IndexerResult(val index: NativeIndex, val compilation: CompilationWithPCH)

Diff for: kotlin-native/Interop/StubGenerator/src/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,8 @@ internal fun buildNativeLibrary(
595595
excludeSystemLibs = excludeSystemLibs,
596596
headerExclusionPolicy = headerExclusionPolicy,
597597
headerFilter = headerFilter,
598-
objCClassesIncludingCategories = objCClassesIncludingCategories
598+
objCClassesIncludingCategories = objCClassesIncludingCategories,
599+
allowIncludingObjCCategoriesFromDefFile = def.config.allowIncludingObjCCategoriesFromDefFile,
599600
)
600601
}
601602

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
library {
2+
// module name: <dependency.def>
3+
4+
library fragment {
5+
// package name: dependency
6+
7+
// class name: dependency/MyClass
8+
// class name: dependency/MyClass.Companion
9+
// class name: dependency/MyClassMeta
10+
// class name: dependency/MyProtocolProtocol
11+
// class name: dependency/MyProtocolProtocolMeta
12+
13+
@kotlinx/cinterop/ExternalObjCClass
14+
public open class dependency/MyClass : kotlinx/cinterop/ObjCObjectBase {
15+
16+
protected /* secondary */ constructor()
17+
18+
// companion object: Companion
19+
20+
// nested class: Companion
21+
}
22+
23+
public final companion object dependency/MyClass.Companion : dependency/MyClassMeta, kotlinx/cinterop/ObjCClassOf<dependency/MyClass> {
24+
25+
private constructor()
26+
}
27+
28+
@kotlinx/cinterop/ExternalObjCClass
29+
public open class dependency/MyClassMeta : kotlinx/cinterop/ObjCObjectBaseMeta {
30+
31+
protected /* secondary */ constructor()
32+
}
33+
34+
@kotlinx/cinterop/ExternalObjCClass(protocolGetter = "kniprot_dependency0_MyProtocol")
35+
public abstract interface dependency/MyProtocolProtocol : kotlinx/cinterop/ObjCObject {
36+
37+
@kotlinx/cinterop/ObjCMethod(selector = "wasInMyClass", encoding = "v16@0:8", isStret = false)
38+
public abstract fun wasInMyClass(): kotlin/Unit
39+
}
40+
41+
@kotlinx/cinterop/ExternalObjCClass(protocolGetter = "kniprot_dependency0_MyProtocol")
42+
public abstract interface dependency/MyProtocolProtocolMeta : kotlinx/cinterop/ObjCClass /* = kotlinx/cinterop/ObjCObjectMeta^ */ {
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# In Apple frameworks methods are sometimes moved from class declaration into a protocol and the class conforms to the protocol in an extension
2+
# This is a binary incompatible change in cinterop klibs
3+
language = Objective-C
4+
modules=dependency4
5+
objcClassesIncludingCategories = MyClass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
library {
2+
// module name: <dependency.def>
3+
4+
library fragment {
5+
// package name: dependency
6+
7+
// class name: dependency/MyClass
8+
// class name: dependency/MyClass.Companion
9+
// class name: dependency/MyClassMeta
10+
// class name: dependency/MyProtocolProtocol
11+
// class name: dependency/MyProtocolProtocolMeta
12+
13+
@kotlinx/cinterop/ExternalObjCClass
14+
public open class dependency/MyClass : kotlinx/cinterop/ObjCObjectBase {
15+
16+
protected /* secondary */ constructor()
17+
18+
@kotlinx/cinterop/ObjCMethod(selector = "wasInMyClass", encoding = "v16@0:8", isStret = false)
19+
public open external fun wasInMyClass(): kotlin/Unit
20+
21+
// companion object: Companion
22+
23+
// nested class: Companion
24+
}
25+
26+
public final companion object dependency/MyClass.Companion : dependency/MyClassMeta, kotlinx/cinterop/ObjCClassOf<dependency/MyClass> {
27+
28+
private constructor()
29+
}
30+
31+
@kotlinx/cinterop/ExternalObjCClass
32+
public open class dependency/MyClassMeta : kotlinx/cinterop/ObjCObjectBaseMeta {
33+
34+
protected /* secondary */ constructor()
35+
}
36+
37+
@kotlinx/cinterop/ExternalObjCClass(protocolGetter = "kniprot_dependency0_MyProtocol")
38+
public abstract interface dependency/MyProtocolProtocol : kotlinx/cinterop/ObjCObject {
39+
40+
@kotlinx/cinterop/ObjCMethod(selector = "wasInMyClass", encoding = "v16@0:8", isStret = false)
41+
public abstract fun wasInMyClass(): kotlin/Unit
42+
}
43+
44+
@kotlinx/cinterop/ExternalObjCClass(protocolGetter = "kniprot_dependency0_MyProtocol")
45+
public abstract interface dependency/MyProtocolProtocolMeta : kotlinx/cinterop/ObjCClass /* = kotlinx/cinterop/ObjCObjectMeta^ */ {
46+
}
47+
48+
package {
49+
50+
@kotlinx/cinterop/ObjCMethod(selector = "wasInMyClass", encoding = "v16@0:8", isStret = false)
51+
@kotlin/Deprecated(message = "Use instance method instead", replaceWith = kotlin/ReplaceWith(imports = [], expression = ""), level = kotlin/DeprecationLevel.WARNING)
52+
public final external fun dependency/MyClass.wasInMyClass(): kotlin/Unit
53+
}
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# We use the category in the def file to add back the method
2+
language = Objective-C
3+
modules=dependency4
4+
objcClassesIncludingCategories = MyClass
5+
allowIncludingObjCCategoriesFromDefFile = true
6+
---
7+
@interface MyClass (K)
8+
-(void) wasInMyClass;
9+
@end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@protocol MyProtocol
2+
-(void) wasInMyClass;
3+
@end
4+
5+
@interface MyClass
6+
@end
7+
8+
@interface MyClass () <MyProtocol>
9+
@end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
framework module dependency4 {
2+
umbrella header "dependency4.h"
3+
4+
export *
5+
module * { export * }
6+
}

Diff for: native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/blackbox/CInteropIncludeCategoriesTestGenerated.java

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: native/utils/src/org/jetbrains/kotlin/konan/util/DefFile.kt

+4
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProper
140140
properties.getSpaceSeparated("objcClassesIncludingCategories")
141141
}
142142

143+
val allowIncludingObjCCategoriesFromDefFile by lazy {
144+
properties.getProperty("allowIncludingObjCCategoriesFromDefFile")?.toBoolean() ?: false
145+
}
146+
143147
val userSetupHint by lazy {
144148
properties.getProperty("userSetupHint")
145149
}

0 commit comments

Comments
 (0)