Skip to content

Commit 5c64832

Browse files
elevenetcSpace Team
authored and
Space Team
committed
[ObjCExport] Fix extensions interface name
KT-66315
1 parent 2a445a0 commit 5c64832

File tree

7 files changed

+70
-43
lines changed

7 files changed

+70
-43
lines changed
+25-19
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
44
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
55
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCInterface
66
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCInterfaceImpl
7-
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getFileName
87

98
private const val extensionsCategoryName = "Extensions"
109

@@ -49,26 +48,33 @@ internal val ObjCInterface.isExtensionsFacade: Boolean
4948
* See related [getTopLevelFacade]
5049
*/
5150
context(KtAnalysisSession, KtObjCExportSession)
52-
fun KtFileSymbol.getExtensionsFacade(): ObjCInterface? {
51+
fun KtFileSymbol.getExtensionFacades(): List<ObjCInterface> {
5352

5453
val extensions = getFileScope()
5554
.getCallableSymbols().filter { it.isExtension }
56-
.toList().sortedWith(StableCallableOrder)
57-
.ifEmpty { return null }
55+
.toList()
56+
.sortedWith(StableCallableOrder)
57+
.ifEmpty { return emptyList() }
58+
.groupBy {
59+
val classSymbol = it.receiverParameter?.type?.expandedClassSymbol
60+
classSymbol?.getObjCClassOrProtocolName()?.objCName
61+
}
62+
.mapNotNull { (key, value) ->
63+
if (key == null) return@mapNotNull null else key to value
64+
}
5865

59-
val fileName = getFileName()
60-
?: throw IllegalStateException("File '$this' cannot be translated without file name")
61-
62-
return ObjCInterfaceImpl(
63-
name = fileName,
64-
comment = null,
65-
origin = null,
66-
attributes = emptyList(),
67-
superProtocols = emptyList(),
68-
members = extensions.mapNotNull { it.translateToObjCExportStub() },
69-
categoryName = extensionsCategoryName,
70-
generics = emptyList(),
71-
superClass = null,
72-
superClassGenerics = emptyList()
73-
)
66+
return extensions.map { (objCName, extensionSymbols) ->
67+
ObjCInterfaceImpl(
68+
name = objCName,
69+
comment = null,
70+
origin = null,
71+
attributes = emptyList(),
72+
superProtocols = emptyList(),
73+
members = extensionSymbols.mapNotNull { ext -> ext.translateToObjCExportStub() },
74+
categoryName = extensionsCategoryName,
75+
generics = emptyList(),
76+
superClass = null,
77+
superClassGenerics = emptyList()
78+
)
79+
}
7480
}

native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/getTopLevelFacade.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDefaultSuperClassOrPr
4343
*
4444
* Where `FooKt` would be the "top level interface file facade" returned by this function.
4545
*
46-
* See related [getExtensionsFacade]
46+
* See related [getExtensionFacades]
4747
*/
4848
context(KtAnalysisSession, KtObjCExportSession)
4949
fun KtFileSymbol.getTopLevelFacade(): ObjCInterface? {

native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt

+9-7
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ private class KtObjCExportHeaderGenerator {
109109

110110
context(KtAnalysisSession, KtObjCExportSession)
111111
private fun translateFileSymbol(symbol: KtFileSymbol) {
112-
symbol.getExtensionsFacade()?.let { extensionFacade ->
113-
objCStubs += extensionFacade
114-
enqueueDependencyClasses(extensionFacade)
115-
objCClassForwardDeclarations += extensionFacade.name
112+
symbol.getExtensionFacades().let { extensionFacades ->
113+
extensionFacades.forEach { facade ->
114+
objCStubs += facade
115+
enqueueDependencyClasses(facade)
116+
objCClassForwardDeclarations += facade.name
117+
}
116118
}
117119

118120
symbol.getTopLevelFacade()?.let { topLevelFacade ->
@@ -146,10 +148,10 @@ private class KtObjCExportHeaderGenerator {
146148
symbol.getDeclaredSuperInterfaceSymbols()
147149
.filter { it.isVisibleInObjC() }
148150
.forEach { superInterfaceSymbol ->
149-
translateClassOrObjectSymbol(superInterfaceSymbol)?.let {
150-
objCProtocolForwardDeclarations += it.name
151+
translateClassOrObjectSymbol(superInterfaceSymbol)?.let {
152+
objCProtocolForwardDeclarations += it.name
153+
}
151154
}
152-
}
153155

154156
symbol.getSuperClassSymbolNotAny()?.let { superClassSymbol ->
155157
translateClassOrObjectSymbol(superClassSymbol)?.let {

native/objcexport-header-generator/testData/headers/extensionFunctions/!extensionFunctions.h

+17-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#import <Foundation/NSString.h>
77
#import <Foundation/NSValue.h>
88

9-
@class Foo;
9+
@class ClazzA, ClazzB;
1010

1111
NS_ASSUME_NONNULL_BEGIN
1212
#pragma clang diagnostic push
@@ -21,15 +21,27 @@ NS_ASSUME_NONNULL_BEGIN
2121
#endif
2222

2323
__attribute__((objc_subclassing_restricted))
24-
@interface Foo : Base
24+
@interface ClazzA : Base
2525
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
2626
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
2727
- (void)memberFun __attribute__((swift_name("memberFun()")));
2828
@end
2929

30-
@interface Foo (Extensions)
31-
- (void)extensionFunA __attribute__((swift_name("extensionFunA()")));
32-
- (void)extensionFunB __attribute__((swift_name("extensionFunB()")));
30+
__attribute__((objc_subclassing_restricted))
31+
@interface ClazzB : Base
32+
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
33+
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
34+
- (void)memberFun __attribute__((swift_name("memberFun()")));
35+
@end
36+
37+
@interface ClazzA (Extensions)
38+
- (void)extensionFunA1 __attribute__((swift_name("extensionFunA1()")));
39+
- (void)extensionFunA2 __attribute__((swift_name("extensionFunA2()")));
40+
@end
41+
42+
@interface ClazzB (Extensions)
43+
- (void)extensionFunB1 __attribute__((swift_name("extensionFunB1()")));
44+
- (void)extensionFunB2 __attribute__((swift_name("extensionFunB2()")));
3345
@end
3446

3547
__attribute__((objc_subclassing_restricted))
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
fun topLevelFunA() {}
22
fun topLevelFunB() {}
33

4-
fun Foo.extensionFunA() {}
5-
fun Foo.extensionFunB() {}
4+
fun ClazzA.extensionFunA1() {}
5+
fun ClazzA.extensionFunA2() {}
66

7-
class Foo {
7+
fun ClazzB.extensionFunB1() {}
8+
fun ClazzB.extensionFunB2() {}
9+
10+
class ClazzA {
811
fun memberFun() {}
912
}
13+
14+
class ClazzB {
15+
fun memberFun() {}
16+
}

native/objcexport-header-generator/testData/headers/extensionProperties/!extensionProperties.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#import <Foundation/NSString.h>
77
#import <Foundation/NSValue.h>
88

9-
@class Foo;
9+
@class Clazz;
1010

1111
NS_ASSUME_NONNULL_BEGIN
1212
#pragma clang diagnostic push
@@ -21,13 +21,13 @@ NS_ASSUME_NONNULL_BEGIN
2121
#endif
2222

2323
__attribute__((objc_subclassing_restricted))
24-
@interface Foo : Base
24+
@interface Clazz : Base
2525
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
2626
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
2727
- (void)memberFun __attribute__((swift_name("memberFun()")));
2828
@end
2929

30-
@interface Foo (Extensions)
30+
@interface Clazz (Extensions)
3131
@property (readonly) int32_t extensionValA __attribute__((swift_name("extensionValA")));
3232
@property (readonly) int32_t extensionValB __attribute__((swift_name("extensionValB")));
3333
@property int32_t extensionVarA __attribute__((swift_name("extensionVarA")));
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
val topLevelPropA = 0
22
val topLevelPropB = 1
33

4-
val Foo.extensionValA
4+
val Clazz.extensionValA
55
get() = 0
6-
val Foo.extensionValB
6+
val Clazz.extensionValB
77
get() = 1
88

9-
var Foo.extensionVarA
9+
var Clazz.extensionVarA
1010
get() = 0
1111
set(value) {}
12-
var Foo.extensionVarB
12+
var Clazz.extensionVarB
1313
get() = 1
1414
set(value) {}
1515

16-
class Foo {
16+
class Clazz {
1717
fun memberFun() {}
1818
}

0 commit comments

Comments
 (0)