[ObjCExport] Extract header generation to shared module

^KT-64227 Fixed
This commit is contained in:
Sebastian Sellmair
2023-12-11 16:50:50 +01:00
committed by Space Team
parent 1440e66519
commit 98fda13523
2 changed files with 97 additions and 55 deletions
@@ -1151,61 +1151,13 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor(
open val shouldExportKDoc = false
fun build(): List<String> = mutableListOf<String>().apply {
addImports(foundationImports)
addImports(getAdditionalImports())
add("")
if (classForwardDeclarations.isNotEmpty()) {
add("@class ${
classForwardDeclarations.joinToString {
buildString {
append(it.className)
formatGenerics(this, it.typeDeclarations)
}
}
};")
add("")
}
if (protocolForwardDeclarations.isNotEmpty()) {
add("@protocol ${protocolForwardDeclarations.joinToString()};")
add("")
}
add("NS_ASSUME_NONNULL_BEGIN")
add("#pragma clang diagnostic push")
listOf(
"-Wunknown-warning-option",
// Protocols don't have generics, classes do. So generated header may contain
// overriding property with "incompatible" type, e.g. `Generic<T>`-typed property
// overriding `Generic<id>`. Suppress these warnings:
"-Wincompatible-property-type",
"-Wnullability"
).forEach {
add("#pragma clang diagnostic ignored \"$it\"")
}
add("")
// If _Nullable_result is not supported, then use _Nullable:
add("#pragma push_macro(\"$objcNullableResultAttribute\")")
add("#if !__has_feature(nullability_nullable_result)")
add("#undef $objcNullableResultAttribute")
add("#define $objcNullableResultAttribute $objcNullableAttribute")
add("#endif")
add("")
stubs.forEach {
addAll(StubRenderer.render(it, shouldExportKDoc))
add("")
}
add("#pragma pop_macro(\"$objcNullableResultAttribute\")")
add("#pragma clang diagnostic pop")
add("NS_ASSUME_NONNULL_END")
}
fun build(): List<String> = ObjCHeader(
stubs = stubs,
classForwardDeclarations = classForwardDeclarations,
protocolForwardDeclarations = protocolForwardDeclarations,
additionalImports = getAdditionalImports(),
exportKDoc = shouldExportKDoc
).lines
@InternalKotlinNativeApi
fun buildInterface(): ObjCExportedInterface {
@@ -0,0 +1,90 @@
/*
* 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.
*/
package org.jetbrains.kotlin.backend.konan.objcexport
data class ObjCHeader(val lines: List<String>) {
override fun toString(): String {
return lines.joinToString(System.lineSeparator())
}
}
fun ObjCHeader(
stubs: List<ObjCExportStub>,
classForwardDeclarations: Set<ObjCClassForwardDeclaration>,
protocolForwardDeclarations: Set<String>,
additionalImports: List<String> = emptyList(),
exportKDoc: Boolean = false,
): ObjCHeader = ObjCHeader(buildList {
addImports(foundationImports)
addImports(additionalImports)
add("")
if (classForwardDeclarations.isNotEmpty()) {
add("@class ${
classForwardDeclarations.joinToString {
buildString {
append(it.className)
formatGenerics(this, it.typeDeclarations)
}
}
};")
add("")
}
if (protocolForwardDeclarations.isNotEmpty()) {
add("@protocol ${protocolForwardDeclarations.joinToString()};")
add("")
}
add("NS_ASSUME_NONNULL_BEGIN")
add("#pragma clang diagnostic push")
listOf(
"-Wunknown-warning-option",
// Protocols don't have generics, classes do. So generated header may contain
// overriding property with "incompatible" type, e.g. `Generic<T>`-typed property
// overriding `Generic<id>`. Suppress these warnings:
"-Wincompatible-property-type",
"-Wnullability"
).forEach {
add("#pragma clang diagnostic ignored \"$it\"")
}
add("")
// If _Nullable_result is not supported, then use _Nullable:
add("#pragma push_macro(\"$objcNullableResultAttribute\")")
add("#if !__has_feature(nullability_nullable_result)")
add("#undef $objcNullableResultAttribute")
add("#define $objcNullableResultAttribute $objcNullableAttribute")
add("#endif")
add("")
stubs.forEach {
addAll(StubRenderer.render(it, exportKDoc))
add("")
}
add("#pragma pop_macro(\"$objcNullableResultAttribute\")")
add("#pragma clang diagnostic pop")
add("NS_ASSUME_NONNULL_END")
})
private fun MutableList<String>.addImports(imports: Iterable<String>) {
imports.forEach {
add("#import <$it>")
}
}
private val foundationImports = listOf(
"Foundation/NSArray.h",
"Foundation/NSDictionary.h",
"Foundation/NSError.h",
"Foundation/NSObject.h",
"Foundation/NSSet.h",
"Foundation/NSString.h",
"Foundation/NSValue.h"
)