Native: emit _Nullable_result attribute when generating Objective-C header

^KT-47042 Fixed
This commit is contained in:
Svyatoslav Scherbina
2021-06-22 16:12:37 +00:00
committed by Space
parent 9bf802a188
commit 04e8140162
4 changed files with 35 additions and 20 deletions
@@ -654,10 +654,14 @@ internal class ObjCExportTranslatorImpl(
ObjCPointerType(ObjCNullableReferenceType(ObjCClassType("NSError")), nullable = true) ObjCPointerType(ObjCNullableReferenceType(ObjCClassType("NSError")), nullable = true)
MethodBridgeValueParameter.SuspendCompletion -> { MethodBridgeValueParameter.SuspendCompletion -> {
val resultType = when (val it = mapReferenceType(method.returnType!!, objCExportScope)) {
is ObjCNonNullReferenceType -> ObjCNullableReferenceType(it, isNullableResult = false)
is ObjCNullableReferenceType -> ObjCNullableReferenceType(it.nonNullType, isNullableResult = true)
}
ObjCBlockPointerType( ObjCBlockPointerType(
returnType = ObjCVoidType, returnType = ObjCVoidType,
parameterTypes = listOf( parameterTypes = listOf(
mapReferenceType(method.returnType!!, objCExportScope).makeNullable(), resultType,
ObjCNullableReferenceType(ObjCClassType("NSError")) ObjCNullableReferenceType(ObjCClassType("NSError"))
) )
) )
@@ -1049,11 +1053,20 @@ abstract class ObjCExportHeaderGenerator internal constructor(
} }
add("") 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 { stubs.forEach {
addAll(StubRenderer.render(it, shouldExportKDoc)) addAll(StubRenderer.render(it, shouldExportKDoc))
add("") add("")
} }
add("#pragma pop_macro(\"$objcNullableResultAttribute\")")
add("#pragma clang diagnostic pop") add("#pragma clang diagnostic pop")
add("NS_ASSUME_NONNULL_END") add("NS_ASSUME_NONNULL_END")
} }
@@ -30,9 +30,13 @@ sealed class ObjCReferenceType : ObjCType()
sealed class ObjCNonNullReferenceType : ObjCReferenceType() sealed class ObjCNonNullReferenceType : ObjCReferenceType()
data class ObjCNullableReferenceType( data class ObjCNullableReferenceType(
val nonNullType: ObjCNonNullReferenceType val nonNullType: ObjCNonNullReferenceType,
val isNullableResult: Boolean = false
) : ObjCReferenceType() { ) : ObjCReferenceType() {
override fun render(attrsAndName: String) = nonNullType.render(" _Nullable".withAttrsAndName(attrsAndName)) override fun render(attrsAndName: String): String {
val attribute = if (isNullableResult) objcNullableResultAttribute else objcNullableAttribute
return nonNullType.render(" $attribute".withAttrsAndName(attrsAndName))
}
} }
data class ObjCClassType( data class ObjCClassType(
@@ -139,7 +143,7 @@ data class ObjCPointerType(
) : ObjCType() { ) : ObjCType() {
override fun render(attrsAndName: String) = override fun render(attrsAndName: String) =
pointee.render("*${if (nullable) { pointee.render("*${if (nullable) {
" _Nullable".withAttrsAndName(attrsAndName) " $objcNullableAttribute".withAttrsAndName(attrsAndName)
} else { } else {
attrsAndName attrsAndName
}}") }}")
@@ -208,7 +212,5 @@ internal fun ObjCType.makeNullableIfReferenceOrPointer(): ObjCType = when (this)
is ObjCNullableReferenceType, is ObjCRawType, is ObjCPrimitiveType, ObjCVoidType -> this is ObjCNullableReferenceType, is ObjCRawType, is ObjCPrimitiveType, ObjCVoidType -> this
} }
internal fun ObjCReferenceType.makeNullable(): ObjCNullableReferenceType = when (this) { const val objcNullableAttribute = "_Nullable"
is ObjCNonNullReferenceType -> ObjCNullableReferenceType(this) const val objcNullableResultAttribute = "_Nullable_result"
is ObjCNullableReferenceType -> this
}
@@ -174,7 +174,7 @@ __attribute__((swift_name("SuspendBridge")))
@note This method converts instances of CancellationException to errors. @note This method converts instances of CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
- (void)intAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)"))); - (void)intAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)")));
/** /**
@note This method converts instances of CancellationException to errors. @note This method converts instances of CancellationException to errors.
@@ -186,7 +186,7 @@ __attribute__((swift_name("SuspendBridge")))
@note This method converts instances of CancellationException to errors. @note This method converts instances of CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
- (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)"))); - (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
/** /**
@note This method converts all Kotlin exceptions to errors. @note This method converts all Kotlin exceptions to errors.
@@ -201,7 +201,7 @@ __attribute__((swift_name("SuspendBridge")))
/** /**
@note This method converts all Kotlin exceptions to errors. @note This method converts all Kotlin exceptions to errors.
*/ */
- (void)nothingAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsAny(value:completionHandler:)"))); - (void)nothingAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsAny(value:completionHandler:)")));
/** /**
@note This method converts all Kotlin exceptions to errors. @note This method converts all Kotlin exceptions to errors.
@@ -275,13 +275,13 @@ __attribute__((swift_name("CoroutinesKt")))
@note This method converts instances of CoroutineException, CancellationException to errors. @note This method converts instances of CoroutineException, CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
+ (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)"))); + (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)")));
/** /**
@note This method converts instances of CoroutineException, CancellationException to errors. @note This method converts instances of CoroutineException, CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
+ (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder<id> *)continuationHolder completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)"))); + (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder<id> *)continuationHolder completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)")));
/** /**
@note This method converts instances of CoroutineException, CancellationException to errors. @note This method converts instances of CoroutineException, CancellationException to errors.
@@ -315,7 +315,7 @@ __attribute__((swift_name("CoroutinesKt")))
@note This method converts instances of CancellationException to errors. @note This method converts instances of CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
+ (void)invoke1Block:(id<KtKotlinSuspendFunction1>)block argument:(id _Nullable)argument completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("invoke1(block:argument:completionHandler:)"))); + (void)invoke1Block:(id<KtKotlinSuspendFunction1>)block argument:(id _Nullable)argument completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("invoke1(block:argument:completionHandler:)")));
@end; @end;
__attribute__((swift_name("DeallocRetainBase"))) __attribute__((swift_name("DeallocRetainBase")))
@@ -174,7 +174,7 @@ __attribute__((swift_name("SuspendBridge")))
@note This method converts instances of CancellationException to errors. @note This method converts instances of CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
- (void)intAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)"))); - (void)intAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)")));
/** /**
@note This method converts instances of CancellationException to errors. @note This method converts instances of CancellationException to errors.
@@ -186,7 +186,7 @@ __attribute__((swift_name("SuspendBridge")))
@note This method converts instances of CancellationException to errors. @note This method converts instances of CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
- (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)"))); - (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)")));
/** /**
@note This method converts all Kotlin exceptions to errors. @note This method converts all Kotlin exceptions to errors.
@@ -201,7 +201,7 @@ __attribute__((swift_name("SuspendBridge")))
/** /**
@note This method converts all Kotlin exceptions to errors. @note This method converts all Kotlin exceptions to errors.
*/ */
- (void)nothingAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsAny(value:completionHandler:)"))); - (void)nothingAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsAny(value:completionHandler:)")));
/** /**
@note This method converts all Kotlin exceptions to errors. @note This method converts all Kotlin exceptions to errors.
@@ -275,13 +275,13 @@ __attribute__((swift_name("CoroutinesKt")))
@note This method converts instances of CoroutineException, CancellationException to errors. @note This method converts instances of CoroutineException, CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
+ (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)"))); + (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)")));
/** /**
@note This method converts instances of CoroutineException, CancellationException to errors. @note This method converts instances of CoroutineException, CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
+ (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)"))); + (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)")));
/** /**
@note This method converts instances of CoroutineException, CancellationException to errors. @note This method converts instances of CoroutineException, CancellationException to errors.
@@ -315,7 +315,7 @@ __attribute__((swift_name("CoroutinesKt")))
@note This method converts instances of CancellationException to errors. @note This method converts instances of CancellationException to errors.
Other uncaught Kotlin exceptions are fatal. Other uncaught Kotlin exceptions are fatal.
*/ */
+ (void)invoke1Block:(id<KtKotlinSuspendFunction1>)block argument:(id _Nullable)argument completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("invoke1(block:argument:completionHandler:)"))); + (void)invoke1Block:(id<KtKotlinSuspendFunction1>)block argument:(id _Nullable)argument completionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("invoke1(block:argument:completionHandler:)")));
@end; @end;
__attribute__((swift_name("DeallocRetainBase"))) __attribute__((swift_name("DeallocRetainBase")))