Skip to content

Commit

Permalink
Allow using categories in the def file to reintroduce methods in the …
Browse files Browse the repository at this point in the history
…class

^KT-71624
  • Loading branch information
timofey-solonin authored and qodana-bot committed Sep 24, 2024
1 parent b1504e7 commit cc0919d
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,10 @@ public open class NativeIndexImpl(val library: NativeLibrary, val verbose: Boole
val categoryClassName = clang_getCursorDisplayName(categoryClassCursor).convertAndDispose()
if (className == categoryClassName) {
val categoryFile = getContainingFile(childCursor)
if (clang_File_isEqual(categoryFile, classFile) != 0) {
val isCategoryInTheSameFileAsClass = clang_File_isEqual(categoryFile, classFile) != 0
val isCategoryFromDefFile = library.allowIncludingObjCCategoriesFromDefFile
&& clang_Location_isFromMainFile(clang_getCursorLocation(childCursor)) != 0
if (isCategoryInTheSameFileAsClass || isCategoryFromDefFile) {
result += childCursor
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ data class NativeLibrary(
val headerExclusionPolicy: HeaderExclusionPolicy,
val headerFilter: NativeLibraryHeaderFilter,
val objCClassesIncludingCategories: Set<String>,
val allowIncludingObjCCategoriesFromDefFile: Boolean,
) : Compilation

data class IndexerResult(val index: NativeIndex, val compilation: CompilationWithPCH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@ internal fun buildNativeLibrary(
excludeSystemLibs = excludeSystemLibs,
headerExclusionPolicy = headerExclusionPolicy,
headerFilter = headerFilter,
objCClassesIncludingCategories = objCClassesIncludingCategories
objCClassesIncludingCategories = objCClassesIncludingCategories,
allowIncludingObjCCategoriesFromDefFile = def.config.allowIncludingObjCCategoriesFromDefFile,
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
library {
// module name: <dependency.def>

library fragment {
// package name: dependency

// class name: dependency/MyClass
// class name: dependency/MyClass.Companion
// class name: dependency/MyClassMeta
// class name: dependency/MyProtocolProtocol
// class name: dependency/MyProtocolProtocolMeta

@kotlinx/cinterop/ExternalObjCClass
public open class dependency/MyClass : kotlinx/cinterop/ObjCObjectBase {

protected /* secondary */ constructor()

// companion object: Companion

// nested class: Companion
}

public final companion object dependency/MyClass.Companion : dependency/MyClassMeta, kotlinx/cinterop/ObjCClassOf<dependency/MyClass> {

private constructor()
}

@kotlinx/cinterop/ExternalObjCClass
public open class dependency/MyClassMeta : kotlinx/cinterop/ObjCObjectBaseMeta {

protected /* secondary */ constructor()
}

@kotlinx/cinterop/ExternalObjCClass(protocolGetter = "kniprot_dependency0_MyProtocol")
public abstract interface dependency/MyProtocolProtocol : kotlinx/cinterop/ObjCObject {

@kotlinx/cinterop/ObjCMethod(selector = "wasInMyClass", encoding = "v16@0:8", isStret = false)
public abstract fun wasInMyClass(): kotlin/Unit
}

@kotlinx/cinterop/ExternalObjCClass(protocolGetter = "kniprot_dependency0_MyProtocol")
public abstract interface dependency/MyProtocolProtocolMeta : kotlinx/cinterop/ObjCClass /* = kotlinx/cinterop/ObjCObjectMeta^ */ {
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# In Apple frameworks methods are sometimes moved from class declaration into a protocol and the class conforms to the protocol in an extension
# This is a binary incompatible change in cinterop klibs
language = Objective-C
modules=dependency4
objcClassesIncludingCategories = MyClass
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
library {
// module name: <dependency.def>

library fragment {
// package name: dependency

// class name: dependency/MyClass
// class name: dependency/MyClass.Companion
// class name: dependency/MyClassMeta
// class name: dependency/MyProtocolProtocol
// class name: dependency/MyProtocolProtocolMeta

@kotlinx/cinterop/ExternalObjCClass
public open class dependency/MyClass : kotlinx/cinterop/ObjCObjectBase {

protected /* secondary */ constructor()

@kotlinx/cinterop/ObjCMethod(selector = "wasInMyClass", encoding = "v16@0:8", isStret = false)
public open external fun wasInMyClass(): kotlin/Unit

// companion object: Companion

// nested class: Companion
}

public final companion object dependency/MyClass.Companion : dependency/MyClassMeta, kotlinx/cinterop/ObjCClassOf<dependency/MyClass> {

private constructor()
}

@kotlinx/cinterop/ExternalObjCClass
public open class dependency/MyClassMeta : kotlinx/cinterop/ObjCObjectBaseMeta {

protected /* secondary */ constructor()
}

@kotlinx/cinterop/ExternalObjCClass(protocolGetter = "kniprot_dependency0_MyProtocol")
public abstract interface dependency/MyProtocolProtocol : kotlinx/cinterop/ObjCObject {

@kotlinx/cinterop/ObjCMethod(selector = "wasInMyClass", encoding = "v16@0:8", isStret = false)
public abstract fun wasInMyClass(): kotlin/Unit
}

@kotlinx/cinterop/ExternalObjCClass(protocolGetter = "kniprot_dependency0_MyProtocol")
public abstract interface dependency/MyProtocolProtocolMeta : kotlinx/cinterop/ObjCClass /* = kotlinx/cinterop/ObjCObjectMeta^ */ {
}

package {

@kotlinx/cinterop/ObjCMethod(selector = "wasInMyClass", encoding = "v16@0:8", isStret = false)
@kotlin/Deprecated(message = "Use instance method instead", replaceWith = kotlin/ReplaceWith(imports = [], expression = ""), level = kotlin/DeprecationLevel.WARNING)
public final external fun dependency/MyClass.wasInMyClass(): kotlin/Unit
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# We use the category in the def file to add back the method
language = Objective-C
modules=dependency4
objcClassesIncludingCategories = MyClass
allowIncludingObjCCategoriesFromDefFile = true
---
@interface MyClass (K)
-(void) wasInMyClass;
@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@protocol MyProtocol
-(void) wasInMyClass;
@end

@interface MyClass
@end

@interface MyClass () <MyProtocol>
@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
framework module dependency4 {
umbrella header "dependency4.h"

export *
module * { export * }
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions native/utils/src/org/jetbrains/kotlin/konan/util/DefFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProper
properties.getSpaceSeparated("objcClassesIncludingCategories")
}

val allowIncludingObjCCategoriesFromDefFile by lazy {
properties.getProperty("allowIncludingObjCCategoriesFromDefFile")?.toBoolean() ?: false
}

val userSetupHint by lazy {
properties.getProperty("userSetupHint")
}
Expand Down

0 comments on commit cc0919d

Please sign in to comment.