diff --git a/docs/docs/types/arrays.md b/docs/docs/types/arrays.md index 0b29252640..f225ddcae9 100644 --- a/docs/docs/types/arrays.md +++ b/docs/docs/types/arrays.md @@ -56,3 +56,8 @@ into `Object`s, and provides bulk copy methods. This makes all array operations - `Array` -> [`DoubleArray`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-double-array/) - `Array` -> [`BooleanArray`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean-array/) - `Array` -> [`LongArray`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long-array/) +- `Array` -> [`ULongArray`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-u-long-array/) + +`ULongArray` shares its `LongArray` with JNI, so `UInt64[]` crosses without copying. Kotlin still marks `ULongArray` as experimental, so +Nitrogen's generated `+autolinking.gradle` opts your module in to `kotlin.ExperimentalUnsignedTypes`. Generated code and your +implementations can use it without warnings. Other modules that use these APIs, such as your app, need their own opt-in. diff --git a/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/utils/JNIArrays.kt b/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/utils/JNIArrays.kt index ec87d767c1..8719015e41 100644 --- a/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/utils/JNIArrays.kt +++ b/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/utils/JNIArrays.kt @@ -3,9 +3,3 @@ package com.margelo.nitro.utils /** Maps object array elements without an intermediate List. */ inline fun Array.mapToArray(transform: (Element) -> Result): Array = Array(size) { transform(this[it]) } - -/** Maps primitive LongArray elements to an object array without an intermediate List. */ -inline fun LongArray.mapToArray(transform: (Long) -> Result): Array = Array(size) { transform(this[it]) } - -/** Maps object array elements to a primitive LongArray in one allocation. */ -inline fun Array.mapToLongArray(transform: (Element) -> Long): LongArray = LongArray(size) { transform(this[it]) } diff --git a/packages/nitrogen/src/autolinking/android/createGradleExtension.ts b/packages/nitrogen/src/autolinking/android/createGradleExtension.ts index 79a69ded94..fd566e525c 100644 --- a/packages/nitrogen/src/autolinking/android/createGradleExtension.ts +++ b/packages/nitrogen/src/autolinking/android/createGradleExtension.ts @@ -12,6 +12,13 @@ ${createFileMetadataString(name)} // Resolve beside this script so custom Nitrogen output directories work too. def nitrogenDirectory = buildscript.sourceFile.parentFile android.sourceSets.main.java.srcDirs += [new File(nitrogenDirectory, 'kotlin')] + +// UInt64 arrays are Kotlin ULongArrays, which still require an opt-in. +plugins.withId('org.jetbrains.kotlin.android') { + kotlin.sourceSets.configureEach { + languageSettings.optIn('kotlin.ExperimentalUnsignedTypes') + } +} `.trim() return { language: 'gradle', diff --git a/packages/nitrogen/src/syntax/kotlin/KotlinStruct.ts b/packages/nitrogen/src/syntax/kotlin/KotlinStruct.ts index 58a6c05c46..6db1913d51 100644 --- a/packages/nitrogen/src/syntax/kotlin/KotlinStruct.ts +++ b/packages/nitrogen/src/syntax/kotlin/KotlinStruct.ts @@ -2,6 +2,7 @@ import { capitalizeName, indent } from '../../utils.js' import { createFileMetadataString } from '../helpers.js' import type { SourceFile } from '../SourceFile.js' import type { KotlinStructType } from './types/KotlinStructType.js' +import type { KotlinNamedType } from './types/KotlinNamedType.js' import { getImportsCode } from '../getImportCode.js' import { convertJniValue, getJniCode } from './types/KotlinType.js' @@ -50,8 +51,17 @@ private fun get${name}_cxx(): ${type} { }) .join('\n\n') - const equalityComparators = structType.properties.map((p) => `Objects.deepEquals(this.${p.escapedName}, other.${p.escapedName})`) - const propertiesList = structType.properties.map((p) => p.escapedName).join(',\n') + // Values whose boxes compare by identity, such as `ULongArray`, compare by their JNI representation. + const getEqualityValue = (property: KotlinNamedType, value: string): string => { + if (property.isKotlinEqualityCompatible) return value + return property.convert(value, { from: 'kotlin', to: 'c++', in: 'kotlin' }) + } + const equalityComparators = structType.properties.map((property) => { + const value = getEqualityValue(property, `this.${property.escapedName}`) + const otherValue = getEqualityValue(property, `other.${property.escapedName}`) + return `Objects.deepEquals(${value}, ${otherValue})` + }) + const propertiesList = structType.properties.map((property) => getEqualityValue(property, property.escapedName)).join(',\n') const code = ` ${createFileMetadataString(`${structType.structName}.kt`)} diff --git a/packages/nitrogen/src/syntax/kotlin/types/KotlinArrayType.ts b/packages/nitrogen/src/syntax/kotlin/types/KotlinArrayType.ts index d99a2b250a..b582d5b349 100644 --- a/packages/nitrogen/src/syntax/kotlin/types/KotlinArrayType.ts +++ b/packages/nitrogen/src/syntax/kotlin/types/KotlinArrayType.ts @@ -28,25 +28,32 @@ export class KotlinArrayType extends ArrayType implements KotlinType { get needsKotlinConversion(): boolean { return this.itemType.needsKotlinConversion } + /** `ULongArray` is a value class, so its field holds the `long[]` JNI uses. */ + get isKotlinFieldCompatible(): boolean { + return this.isULongArray || !this.needsKotlinConversion + } + /** `ULongArray` boxes compare by identity, so compare their `long[]`s instead. */ + get isKotlinEqualityCompatible(): boolean { + return !this.isULongArray && (this.itemType.isKotlinEqualityCompatible ?? true) + } + private get isULongArray(): boolean { + return this.itemType.kind === 'uint64' + } convert(value: string, conversion: KotlinConversion): string { switch (conversion.in) { case 'kotlin': { if (!this.needsKotlinConversion) return value + if (this.isULongArray) { + // Both reinterpret the same array without copying it. + return conversion.from === 'kotlin' ? `${value}.asLongArray()` : `${value}.asULongArray()` + } const item = this.itemType.convert('__item', conversion) + const sourceType = conversion.from === 'c++' ? this.itemType : this.type.itemType const resultType = conversion.from === 'c++' ? this.type.itemType : this.itemType - const resultCode = resultType.getCode('kotlin', { - context: 'type-argument', - }) - let conversionFunction: string - if (this.itemType.kind === 'uint64') { - conversionFunction = conversion.from === 'kotlin' ? 'mapToLongArray' : `mapToArray<${resultCode}>` - } else { - const sourceType = conversion.from === 'c++' ? this.itemType : this.type.itemType - const sourceCode = sourceType.getCode('kotlin', { context: 'type-argument' }) - conversionFunction = `mapToArray<${sourceCode}, ${resultCode}>` - } + const sourceCode = sourceType.getCode('kotlin', { context: 'type-argument' }) + const resultCode = resultType.getCode('kotlin', { context: 'type-argument' }) return ` -${value}.${conversionFunction} { __item -> ${item} } +${value}.mapToArray<${sourceCode}, ${resultCode}> { __item -> ${item} } `.trim() } case 'c++': { @@ -130,11 +137,8 @@ ${value}.${conversionFunction} { __item -> ${item} } break } case 'kotlin': - if (this.needsKotlinConversion) { - imports.push( - { language: language, name: 'com.margelo.nitro.utils.mapToArray' }, - { language: language, name: 'com.margelo.nitro.utils.mapToLongArray' } - ) + if (this.needsKotlinConversion && !this.isULongArray) { + imports.push({ language: language, name: 'com.margelo.nitro.utils.mapToArray' }) } imports.push(...this.type.getRequiredImports(language)) break diff --git a/packages/nitrogen/src/syntax/kotlin/types/KotlinNamedType.ts b/packages/nitrogen/src/syntax/kotlin/types/KotlinNamedType.ts index cf665ff810..c0839d6d03 100644 --- a/packages/nitrogen/src/syntax/kotlin/types/KotlinNamedType.ts +++ b/packages/nitrogen/src/syntax/kotlin/types/KotlinNamedType.ts @@ -22,6 +22,9 @@ export class KotlinNamedType extends NamedWrappingType implements Ko get isKotlinFieldCompatible(): boolean { return this.type.isKotlinFieldCompatible ?? !this.type.needsKotlinConversion } + get isKotlinEqualityCompatible(): boolean { + return this.type.isKotlinEqualityCompatible ?? true + } get needsKotlinConversion(): boolean { return this.type.needsKotlinConversion diff --git a/packages/nitrogen/src/syntax/kotlin/types/KotlinOptionalType.ts b/packages/nitrogen/src/syntax/kotlin/types/KotlinOptionalType.ts index 06e26d594f..193377b531 100644 --- a/packages/nitrogen/src/syntax/kotlin/types/KotlinOptionalType.ts +++ b/packages/nitrogen/src/syntax/kotlin/types/KotlinOptionalType.ts @@ -29,6 +29,10 @@ export class KotlinOptionalType extends OptionalType implements KotlinType { return this.wrappingType.jniValueKind } + get isKotlinEqualityCompatible(): boolean { + return this.wrappingType.isKotlinEqualityCompatible ?? true + } + getCppConverter(cppType: Type): KotlinCppConverter { return new KotlinCxxOptionalType(getTypeAs(cppType, OptionalType), this).getConverter() } diff --git a/packages/nitrogen/src/syntax/kotlin/types/KotlinType.ts b/packages/nitrogen/src/syntax/kotlin/types/KotlinType.ts index 8ea1fb5294..eb00492134 100644 --- a/packages/nitrogen/src/syntax/kotlin/types/KotlinType.ts +++ b/packages/nitrogen/src/syntax/kotlin/types/KotlinType.ts @@ -66,6 +66,11 @@ export interface KotlinType extends Type { readonly hasStaticJNIReference?: boolean /** Whether a generated Kotlin backing field already has this JNI representation. */ readonly isKotlinFieldCompatible?: boolean + /** + * Whether `Objects.deepEquals` and `contentDeepHashCode` compare the public Kotlin value + * by its contents. Otherwise, generated structs compare its JNI representation. + */ + readonly isKotlinEqualityCompatible?: boolean /** Overrides a native value's printer only when its JVM signature differs. */ getJniCode?(options: GetKotlinCodeOptions): string /** Adapts a native scalar at the JNI boundary when its JVM ABI differs. */ diff --git a/packages/nitrogen/src/syntax/types/ArrayType.ts b/packages/nitrogen/src/syntax/types/ArrayType.ts index 8c24ea1b4f..9277a45edc 100644 --- a/packages/nitrogen/src/syntax/types/ArrayType.ts +++ b/packages/nitrogen/src/syntax/types/ArrayType.ts @@ -38,7 +38,7 @@ export class ArrayType implements Type { case 'int64': return 'LongArray' case 'uint64': - return 'Array' + return 'ULongArray' default: return `Array<${itemCode}>` } diff --git a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.gradle b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.gradle index 434f28835b..438b138cc0 100644 --- a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.gradle +++ b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.gradle @@ -8,3 +8,10 @@ // Resolve beside this script so custom Nitrogen output directories work too. def nitrogenDirectory = buildscript.sourceFile.parentFile android.sourceSets.main.java.srcDirs += [new File(nitrogenDirectory, 'kotlin')] + +// UInt64 arrays are Kotlin ULongArrays, which still require an opt-in. +plugins.withId('org.jetbrains.kotlin.android') { + kotlin.sourceSets.configureEach { + languageSettings.optIn('kotlin.ExperimentalUnsignedTypes') + } +} diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/NitroTest+autolinking.gradle b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/NitroTest+autolinking.gradle index d79490161a..72f716e055 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/NitroTest+autolinking.gradle +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/NitroTest+autolinking.gradle @@ -8,3 +8,10 @@ // Resolve beside this script so custom Nitrogen output directories work too. def nitrogenDirectory = buildscript.sourceFile.parentFile android.sourceSets.main.java.srcDirs += [new File(nitrogenDirectory, 'kotlin')] + +// UInt64 arrays are Kotlin ULongArrays, which still require an opt-in. +plugins.withId('org.jetbrains.kotlin.android') { + kotlin.sourceSets.configureEach { + languageSettings.optIn('kotlin.ExperimentalUnsignedTypes') + } +} diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.gradle b/tests/standalone/nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.gradle index 434f28835b..438b138cc0 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.gradle +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.gradle @@ -8,3 +8,10 @@ // Resolve beside this script so custom Nitrogen output directories work too. def nitrogenDirectory = buildscript.sourceFile.parentFile android.sourceSets.main.java.srcDirs += [new File(nitrogenDirectory, 'kotlin')] + +// UInt64 arrays are Kotlin ULongArrays, which still require an opt-in. +plugins.withId('org.jetbrains.kotlin.android') { + kotlin.sourceSets.configureEach { + languageSettings.optIn('kotlin.ExperimentalUnsignedTypes') + } +} diff --git a/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt b/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt index c14da2721d..d7ca858023 100644 --- a/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt +++ b/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt @@ -201,6 +201,31 @@ class HybridTestObjectKotlin : HybridTestObjectSwiftKotlinSpec() { return callback.callSync(value) } + override fun bounceUnsignedArray(array: ULongArray): ULongArray { + return array + } + + override fun bounceNestedUnsignedArray(array: Array): Array { + return array + } + + override fun bounceOptionalUnsignedArray(array: ULongArray?): ULongArray? { + return array + } + + override fun bounceUnsignedArrayAsync(array: ULongArray): Promise { + return Promise.async { + return@async array + } + } + + override fun callUnsignedArrayCallback( + array: ULongArray, + callback: Callback<(array: ULongArray) -> ULongArray>, + ): ULongArray { + return callback.callSync(array) + } + override fun bounceHybridObjects(array: Array): Array { return array } diff --git a/tests/standalone/nitro-test/apple/HybridTestObjectSwift.swift b/tests/standalone/nitro-test/apple/HybridTestObjectSwift.swift index 8b25bbd578..03abaaaef2 100644 --- a/tests/standalone/nitro-test/apple/HybridTestObjectSwift.swift +++ b/tests/standalone/nitro-test/apple/HybridTestObjectSwift.swift @@ -363,6 +363,30 @@ class HybridTestObjectSwift: HybridTestObjectSwiftKotlinSpec { return try callback.callSync(value) } + func bounceUnsignedArray(array: [UInt64]) throws -> [UInt64] { + return array + } + + func bounceNestedUnsignedArray(array: [[UInt64]]) throws -> [[UInt64]] { + return array + } + + func bounceOptionalUnsignedArray(array: [UInt64]?) throws -> [UInt64]? { + return array + } + + func bounceUnsignedArrayAsync(array: [UInt64]) throws -> any Promise<[UInt64]> { + return .async { + return array + } + } + + func callUnsignedArrayCallback( + array: [UInt64], callback: any Callback<[UInt64], [UInt64]> + ) throws -> [UInt64] { + return try callback.callSync(array) + } + func bounceHybridObjects(array: [(any HybridChildSpec)]) throws -> [(any HybridChildSpec)] { return array } diff --git a/tests/standalone/nitro-test/cpp/HybridTestObjectCpp.cpp b/tests/standalone/nitro-test/cpp/HybridTestObjectCpp.cpp index 3bdb06f9da..26e26e1938 100644 --- a/tests/standalone/nitro-test/cpp/HybridTestObjectCpp.cpp +++ b/tests/standalone/nitro-test/cpp/HybridTestObjectCpp.cpp @@ -360,6 +360,28 @@ std::vector>> HybridTestObjectCpp::callNestedS return callback.callSync(value); } +std::vector HybridTestObjectCpp::bounceUnsignedArray(const std::vector& array) { + return array; +} + +std::vector> HybridTestObjectCpp::bounceNestedUnsignedArray(const std::vector>& array) { + return array; +} + +std::optional> HybridTestObjectCpp::bounceOptionalUnsignedArray(const std::optional>& array) { + return array; +} + +Promise> HybridTestObjectCpp::bounceUnsignedArrayAsync(const std::vector& array) { + return Promise>::async([=]() { return array; }); +} + +std::vector +HybridTestObjectCpp::callUnsignedArrayCallback(const std::vector& array, + const Callback(const std::vector&)>& callback) { + return callback.callSync(array); +} + std::vector HybridTestObjectCpp::bounceHybridObjects(const std::vector& array) { return array; } diff --git a/tests/standalone/nitro-test/cpp/HybridTestObjectCpp.hpp b/tests/standalone/nitro-test/cpp/HybridTestObjectCpp.hpp index a38579b28e..c4816cf6fd 100644 --- a/tests/standalone/nitro-test/cpp/HybridTestObjectCpp.hpp +++ b/tests/standalone/nitro-test/cpp/HybridTestObjectCpp.hpp @@ -179,6 +179,12 @@ class HybridTestObjectCpp : public HybridTestObjectCppSpec { const std::vector>>& value, const Callback>>(const std::vector>>&)>& callback) override; + std::vector bounceUnsignedArray(const std::vector& array) override; + std::vector> bounceNestedUnsignedArray(const std::vector>& array) override; + std::optional> bounceOptionalUnsignedArray(const std::optional>& array) override; + Promise> bounceUnsignedArrayAsync(const std::vector& array) override; + std::vector callUnsignedArrayCallback(const std::vector& array, + const Callback(const std::vector&)>& callback) override; std::vector bounceHybridObjects(const std::vector& array) override; std::vector> bounceFunctions(const std::vector>& functions) override; diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/NitroTest+autolinking.cmake b/tests/standalone/nitro-test/nitrogen/generated/android/NitroTest+autolinking.cmake index 6ddb1a4602..322a4ed0b7 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/NitroTest+autolinking.cmake +++ b/tests/standalone/nitro-test/nitrogen/generated/android/NitroTest+autolinking.cmake @@ -41,6 +41,7 @@ target_sources(NitroTest PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JCallback_std__string.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JCallback_std__vector_Powertrain__std__vector_Powertrain_.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JCallback_std__vector_std__vector_std__optional_Person____std__vector_std__vector_std__optional_Person___.cpp" + "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JCallback_std__vector_uint64_t__std__vector_uint64_t_.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JCallback_uint64_t_uint64_t.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JCallback_void.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JCallback_void_double.cpp" diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/NitroTest+autolinking.gradle b/tests/standalone/nitro-test/nitrogen/generated/android/NitroTest+autolinking.gradle index d79490161a..72f716e055 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/NitroTest+autolinking.gradle +++ b/tests/standalone/nitro-test/nitrogen/generated/android/NitroTest+autolinking.gradle @@ -8,3 +8,10 @@ // Resolve beside this script so custom Nitrogen output directories work too. def nitrogenDirectory = buildscript.sourceFile.parentFile android.sourceSets.main.java.srcDirs += [new File(nitrogenDirectory, 'kotlin')] + +// UInt64 arrays are Kotlin ULongArrays, which still require an opt-in. +plugins.withId('org.jetbrains.kotlin.android') { + kotlin.sourceSets.configureEach { + languageSettings.optIn('kotlin.ExperimentalUnsignedTypes') + } +} diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/NitroTestOnLoad.cpp b/tests/standalone/nitro-test/nitrogen/generated/android/NitroTestOnLoad.cpp index cf7ff5f9bc..4964f2fbb3 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/NitroTestOnLoad.cpp +++ b/tests/standalone/nitro-test/nitrogen/generated/android/NitroTestOnLoad.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ namespace margelo::nitro::test { margelo::nitro::test::JCallback_void_std__vector_Powertrain_::registerNatives(); margelo::nitro::test::JCallback_Promise_std__vector_Powertrain__::registerNatives(); margelo::nitro::test::JCallback_std__vector_std__vector_std__optional_Person____std__vector_std__vector_std__optional_Person___::registerNatives(); + margelo::nitro::test::JCallback_std__vector_uint64_t__std__vector_uint64_t_::registerNatives(); margelo::nitro::test::JCallback_double_double::registerNatives(); margelo::nitro::test::JCallback_Promise_void_::registerNatives(); margelo::nitro::test::JCallback_void_std__optional_double_::registerNatives(); diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/c++/HybridTestObjectCppSpecClass.cpp b/tests/standalone/nitro-test/nitrogen/generated/android/c++/HybridTestObjectCppSpecClass.cpp index 0d66ef5e70..240c373dea 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/c++/HybridTestObjectCppSpecClass.cpp +++ b/tests/standalone/nitro-test/nitrogen/generated/android/c++/HybridTestObjectCppSpecClass.cpp @@ -147,6 +147,11 @@ namespace margelo::nitro::test { clazz.registerHybridMethod("callEnumArrayPromiseCallback", &HybridTestObjectCppSpec::callEnumArrayPromiseCallback); clazz.registerHybridMethod("awaitEnumArrayPromise", &HybridTestObjectCppSpec::awaitEnumArrayPromise); clazz.registerHybridMethod("callNestedStructCallback", &HybridTestObjectCppSpec::callNestedStructCallback); + clazz.registerHybridMethod("bounceUnsignedArray", &HybridTestObjectCppSpec::bounceUnsignedArray); + clazz.registerHybridMethod("bounceNestedUnsignedArray", &HybridTestObjectCppSpec::bounceNestedUnsignedArray); + clazz.registerHybridMethod("bounceOptionalUnsignedArray", &HybridTestObjectCppSpec::bounceOptionalUnsignedArray); + clazz.registerHybridMethod("bounceUnsignedArrayAsync", &HybridTestObjectCppSpec::bounceUnsignedArrayAsync); + clazz.registerHybridMethod("callUnsignedArrayCallback", &HybridTestObjectCppSpec::callUnsignedArrayCallback); clazz.registerHybridMethod("bounceHybridObjects", &HybridTestObjectCppSpec::bounceHybridObjects); clazz.registerHybridMethod("bounceFunctions", &HybridTestObjectCppSpec::bounceFunctions); clazz.registerHybridMethod("bounceMaps", &HybridTestObjectCppSpec::bounceMaps); diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/c++/JCallback_std__vector_uint64_t__std__vector_uint64_t_.cpp b/tests/standalone/nitro-test/nitrogen/generated/android/c++/JCallback_std__vector_uint64_t__std__vector_uint64_t_.cpp new file mode 100644 index 0000000000..a1de52f781 --- /dev/null +++ b/tests/standalone/nitro-test/nitrogen/generated/android/c++/JCallback_std__vector_uint64_t__std__vector_uint64_t_.cpp @@ -0,0 +1,60 @@ +/// +/// JCallback_std__vector_uint64_t__std__vector_uint64_t_.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/margelo/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include +#include +#include +#include +#include +#include +#include + +namespace margelo::nitro::test { + + JNIRetainedValue>::Type JCallback_std__vector_uint64_t__std__vector_uint64_t_::JFunction_cxx::invoke(JNIRetainedValue>::Type array) const { + static const auto __method = javaClassStatic()->getMethod(jni::alias_ref)>("call"); + auto result = __method(self(), JNIRetainedValue>::borrow(array)); + return JNIRetainedValue>::retain(result); + } + + jni::local_ref JCallback_std__vector_uint64_t__std__vector_uint64_t_::create(CallbackType callback) { + return newObjectCxxArgs(std::move(callback)); + } + + jni::local_ref JCallback_std__vector_uint64_t__std__vector_uint64_t_::callSync_cxx(jni::alias_ref array) { + return callSync(array); + } + + jni::local_ref>> JCallback_std__vector_uint64_t__std__vector_uint64_t_::callAsync_cxx(jni::alias_ref array) { + return callAsync>>(array); + } + + void JCallback_std__vector_uint64_t__std__vector_uint64_t_::callAndForget_cxx(jni::alias_ref array) { + callAndForget(array); + } + + jni::local_ref JCallback_std__vector_uint64_t__std__vector_uint64_t_::fromCxx_cxx(jni::alias_ref, jni::alias_ref callback) { + return create(getCallback(callback)); + } + + jni::local_ref JCallback_std__vector_uint64_t__std__vector_uint64_t_::fromFunction_cxx(jni::alias_ref, jni::alias_ref function) { + return create(CallbackType::make(JNICallable(jni::make_global(function)))); + } + + void JCallback_std__vector_uint64_t__std__vector_uint64_t_::registerNatives() { + registerHybrid({ + makeNativeMethod("callSync_cxx", JCallback_std__vector_uint64_t__std__vector_uint64_t_::callSync_cxx), + makeNativeMethod("callAsync_cxx", JCallback_std__vector_uint64_t__std__vector_uint64_t_::callAsync_cxx), + makeNativeMethod("callAndForget_cxx", JCallback_std__vector_uint64_t__std__vector_uint64_t_::callAndForget_cxx), + makeNativeMethod("fromCxx_cxx", JCallback_std__vector_uint64_t__std__vector_uint64_t_::fromCxx_cxx), + makeNativeMethod("fromFunction_cxx", JCallback_std__vector_uint64_t__std__vector_uint64_t_::fromFunction_cxx), + }); + } + + JCallback_std__vector_uint64_t__std__vector_uint64_t_::JCallback_std__vector_uint64_t__std__vector_uint64_t_(CallbackType callback) : HybridBase(std::move(callback)) {} + +} // namespace margelo::nitro::test diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp b/tests/standalone/nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp index 9bb092c2e5..45022a90e3 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp +++ b/tests/standalone/nitro-test/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -192,6 +193,11 @@ namespace margelo::nitro::test { clazz.registerHybridMethod("callEnumArrayPromiseCallback", &JHybridTestObjectSwiftKotlinSpec::callEnumArrayPromiseCallback); clazz.registerHybridMethod("awaitEnumArrayPromise", &JHybridTestObjectSwiftKotlinSpec::awaitEnumArrayPromise); clazz.registerHybridMethod("callNestedStructCallback", &JHybridTestObjectSwiftKotlinSpec::callNestedStructCallback); + clazz.registerHybridMethod("bounceUnsignedArray", &JHybridTestObjectSwiftKotlinSpec::bounceUnsignedArray); + clazz.registerHybridMethod("bounceNestedUnsignedArray", &JHybridTestObjectSwiftKotlinSpec::bounceNestedUnsignedArray); + clazz.registerHybridMethod("bounceOptionalUnsignedArray", &JHybridTestObjectSwiftKotlinSpec::bounceOptionalUnsignedArray); + clazz.registerHybridMethod("bounceUnsignedArrayAsync", &JHybridTestObjectSwiftKotlinSpec::bounceUnsignedArrayAsync); + clazz.registerHybridMethod("callUnsignedArrayCallback", &JHybridTestObjectSwiftKotlinSpec::callUnsignedArrayCallback); clazz.registerHybridMethod("bounceHybridObjects", &JHybridTestObjectSwiftKotlinSpec::bounceHybridObjects); clazz.registerHybridMethod("bounceFunctions", &JHybridTestObjectSwiftKotlinSpec::bounceFunctions); clazz.registerHybridMethod("bounceMaps", &JHybridTestObjectSwiftKotlinSpec::bounceMaps); @@ -648,6 +654,31 @@ namespace margelo::nitro::test { auto __result = __method(_javaPart, CxxPart::getClass(), value, callback); return __result; } + jni::local_ref JHybridTestObjectSwiftKotlinSpec::bounceUnsignedArray(const jni::local_ref& array) { + static const auto __method = CxxPart::getClass()->getNonvirtualMethod(jni::alias_ref /* array */)>("bounceUnsignedArray_cxx"); + auto __result = __method(_javaPart, CxxPart::getClass(), array); + return __result; + } + jni::local_ref> JHybridTestObjectSwiftKotlinSpec::bounceNestedUnsignedArray(const jni::local_ref>& array) { + static const auto __method = CxxPart::getClass()->getNonvirtualMethod>(jni::alias_ref> /* array */)>("bounceNestedUnsignedArray_cxx"); + auto __result = __method(_javaPart, CxxPart::getClass(), array); + return __result; + } + jni::local_ref> JHybridTestObjectSwiftKotlinSpec::bounceOptionalUnsignedArray(const jni::local_ref>& array) { + static const auto __method = CxxPart::getClass()->getNonvirtualMethod>(jni::alias_ref> /* array */)>("bounceOptionalUnsignedArray_cxx"); + auto __result = __method(_javaPart, CxxPart::getClass(), array); + return __result; + } + jni::local_ref>> JHybridTestObjectSwiftKotlinSpec::bounceUnsignedArrayAsync(const jni::local_ref& array) { + static const auto __method = CxxPart::getClass()->getNonvirtualMethod>>(jni::alias_ref /* array */)>("bounceUnsignedArrayAsync_cxx"); + auto __result = __method(_javaPart, CxxPart::getClass(), array); + return __result; + } + jni::local_ref JHybridTestObjectSwiftKotlinSpec::callUnsignedArrayCallback(const jni::local_ref& array, const jni::local_ref& callback) { + static const auto __method = CxxPart::getClass()->getNonvirtualMethod(jni::alias_ref /* array */, jni::alias_ref /* callback */)>("callUnsignedArrayCallback_cxx"); + auto __result = __method(_javaPart, CxxPart::getClass(), array, callback); + return __result; + } jni::local_ref> JHybridTestObjectSwiftKotlinSpec::bounceHybridObjects(const jni::local_ref>& array) { static const auto __method = CxxPart::getClass()->getNonvirtualMethod>(jni::alias_ref> /* array */)>("bounceHybridObjects"); auto __result = __method(_javaPart, CxxPart::getClass(), array); diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JCallback_std__vector_uint64_t__std__vector_uint64_t_.hpp b/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JCallback_std__vector_uint64_t__std__vector_uint64_t_.hpp new file mode 100644 index 0000000000..74e3cce6ab --- /dev/null +++ b/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JCallback_std__vector_uint64_t__std__vector_uint64_t_.hpp @@ -0,0 +1,55 @@ +/// +/// JCallback_std__vector_uint64_t__std__vector_uint64_t_.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/margelo/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace margelo::nitro::test { + + namespace jni = facebook::jni; + + /** + * The C++ part of the Kotlin `Callback_std__vector_uint64_t__std__vector_uint64_t_`, which holds a `Callback<...>` in `JNICallback`. + */ + class JCallback_std__vector_uint64_t__std__vector_uint64_t_ final : public jni::HybridClass(jni::local_ref)>> { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/test/Callback_std__vector_uint64_t__std__vector_uint64_t_;"; + + /** + * The Kotlin `Callback_std__vector_uint64_t__std__vector_uint64_t_.Function_cxx`, which calls a Kotlin callback. + */ + struct JFunction_cxx : jni::JavaClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/test/Callback_std__vector_uint64_t__std__vector_uint64_t_$Function_cxx;"; + JNIRetainedValue>::Type invoke(JNIRetainedValue>::Type array) const; + }; + + public: + static jni::local_ref create(CallbackType callback); + static void registerNatives(); + + private: + jni::local_ref callSync_cxx(jni::alias_ref array); + jni::local_ref>> callAsync_cxx(jni::alias_ref array); + void callAndForget_cxx(jni::alias_ref array); + static jni::local_ref fromCxx_cxx(jni::alias_ref, jni::alias_ref callback); + static jni::local_ref fromFunction_cxx(jni::alias_ref, jni::alias_ref function); + + private: + friend HybridBase; + explicit JCallback_std__vector_uint64_t__std__vector_uint64_t_(CallbackType callback); + }; + +} // namespace margelo::nitro::test diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JHybridTestObjectSwiftKotlinSpec.hpp b/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JHybridTestObjectSwiftKotlinSpec.hpp index 207a25607f..5b052a1e1a 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JHybridTestObjectSwiftKotlinSpec.hpp +++ b/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JHybridTestObjectSwiftKotlinSpec.hpp @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include @@ -211,6 +212,11 @@ namespace margelo::nitro::test { jni::local_ref>>> callEnumArrayPromiseCallback(const jni::local_ref& callback); jni::local_ref>>> awaitEnumArrayPromise(const jni::local_ref>>>& promise); jni::local_ref>>> callNestedStructCallback(const jni::local_ref>>>& value, const jni::local_ref& callback); + jni::local_ref bounceUnsignedArray(const jni::local_ref& array); + jni::local_ref> bounceNestedUnsignedArray(const jni::local_ref>& array); + jni::local_ref> bounceOptionalUnsignedArray(const jni::local_ref>& array); + jni::local_ref>> bounceUnsignedArrayAsync(const jni::local_ref& array); + jni::local_ref callUnsignedArrayCallback(const jni::local_ref& array, const jni::local_ref& callback); jni::local_ref> bounceHybridObjects(const jni::local_ref>& array); jni::local_ref> bounceFunctions(const jni::local_ref>& functions); jni::local_ref> bounceMaps(const jni::local_ref>& maps); diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JUnsignedValues.hpp b/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JUnsignedValues.hpp index 8dc1b465f0..c8b32f0f3e 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JUnsignedValues.hpp +++ b/tests/standalone/nitro-test/nitrogen/generated/android/c++/include/NitroTest/private/JUnsignedValues.hpp @@ -49,8 +49,8 @@ namespace margelo::nitro::test { } jni::local_ref getValues() const { - static const auto method = javaClassStatic()->getMethod("getValues_cxx"); - return method(this->self()); + static const auto field = javaClassStatic()->getField("values"); + return getFieldValue(field); } jni::local_ref> getNested() const { diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Callback_std__vector_uint64_t__std__vector_uint64_t_.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Callback_std__vector_uint64_t__std__vector_uint64_t_.kt new file mode 100644 index 0000000000..a3e9a6c0df --- /dev/null +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/Callback_std__vector_uint64_t__std__vector_uint64_t_.kt @@ -0,0 +1,97 @@ +/// +/// Callback_std__vector_uint64_t__std__vector_uint64_t_.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/margelo/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.test + +import androidx.annotation.Keep +import com.facebook.jni.HybridData +import com.facebook.proguard.annotations.DoNotStrip +import com.margelo.nitro.core.Callback +import com.margelo.nitro.core.Promise +import com.margelo.nitro.core.CxxCallback +import com.margelo.nitro.core.callSync + +/** + * The JNI representation of `Callback<(array: ULongArray) -> ULongArray>`, for the JavaScript callback `(array: array) => std::vector`. + * It holds a C++ `Callback<...>`, which calls either a JS function or a native function. + * Use `Callback<(array: ULongArray) -> ULongArray>` instead of this class in your code. + */ +@DoNotStrip +@Keep +@Suppress( + "KotlinJniMissingFunction", "unused", + "RedundantSuppression", "RedundantUnitReturnType", "FunctionName", + "ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName", + "PARAMETER_NAME_CHANGED_ON_OVERRIDE", +) +class Callback_std__vector_uint64_t__std__vector_uint64_t_ @DoNotStrip @Keep private constructor(hybridData: HybridData): CxxCallback(hybridData), Callback.Arity1 { + override fun callSync(array: ULongArray): ULongArray { + val __result = callSync_cxx(array.asLongArray()) + return __result.asULongArray() + } + + override fun callAsync(array: ULongArray): Promise { + val __result = callAsync_cxx(array.asLongArray()) + return __result.let { __source -> Promise().also { __promise -> __source.then { __result -> __promise.resolve(__result.asULongArray()) }.catch { __promise.reject(it) } } } + } + + override fun callAndForget(array: ULongArray): Unit { + callAndForget_cxx(array.asLongArray()) + } + + /** + * Lets C++ call a Kotlin callback with JNI types, e.g. `Long` instead of `ULong`. + */ + @DoNotStrip + @Keep + private class Function_cxx(private val callback: Callback<(array: ULongArray) -> ULongArray>) { + @DoNotStrip + @Keep + fun call(array: LongArray): LongArray { + val __result = this.callback.callSync(array.asULongArray()) + return __result.asLongArray() + } + } + + @DoNotStrip + @Keep + private external fun callSync_cxx(array: LongArray): LongArray + + @DoNotStrip + @Keep + private external fun callAsync_cxx(array: LongArray): Promise + + @DoNotStrip + @Keep + private external fun callAndForget_cxx(array: LongArray): Unit + + companion object { + /** + * Returns the given [callback] as its JNI representation. + * A callback from another module keeps its C++ `Callback<...>`, and + * a callback created in Kotlin is wrapped in a C++ `Callback<...>` that calls it. + */ + @JvmStatic + fun fromKotlin(callback: Callback<(array: ULongArray) -> ULongArray>): Callback_std__vector_uint64_t__std__vector_uint64_t_ { + return when (callback) { + is Callback_std__vector_uint64_t__std__vector_uint64_t_ -> callback + is CxxCallback -> fromCxx_cxx(callback) + else -> fromFunction_cxx(Function_cxx(callback)) + } + } + + @JvmStatic + @DoNotStrip + @Keep + private external fun fromCxx_cxx(callback: CxxCallback): Callback_std__vector_uint64_t__std__vector_uint64_t_ + + @JvmStatic + @DoNotStrip + @Keep + private external fun fromFunction_cxx(function: Function_cxx): Callback_std__vector_uint64_t__std__vector_uint64_t_ + } +} diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt index 45bc1f1047..639d7b7350 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt @@ -15,7 +15,6 @@ import com.margelo.nitro.core.NullType import com.margelo.nitro.core.Callback import com.margelo.nitro.core.Promise import com.margelo.nitro.utils.mapToArray -import com.margelo.nitro.utils.mapToLongArray import com.margelo.nitro.core.AnyJSON import com.margelo.nitro.core.ArrayBuffer import com.margelo.nitro.test.external.HybridSomeExternalObjectSpec @@ -287,6 +286,51 @@ abstract class HybridTestObjectSwiftKotlinSpec: HybridObject() { return __result } + abstract fun bounceUnsignedArray(array: ULongArray): ULongArray + + @DoNotStrip + @Keep + private fun bounceUnsignedArray_cxx(array: LongArray): LongArray { + val __result = bounceUnsignedArray(array.asULongArray()) + return __result.asLongArray() + } + + abstract fun bounceNestedUnsignedArray(array: Array): Array + + @DoNotStrip + @Keep + private fun bounceNestedUnsignedArray_cxx(array: Array): Array { + val __result = bounceNestedUnsignedArray(array.mapToArray { __item -> __item.asULongArray() }) + return __result.mapToArray { __item -> __item.asLongArray() } + } + + abstract fun bounceOptionalUnsignedArray(array: ULongArray?): ULongArray? + + @DoNotStrip + @Keep + private fun bounceOptionalUnsignedArray_cxx(array: LongArray?): LongArray? { + val __result = bounceOptionalUnsignedArray(array?.let { it.asULongArray() }) + return __result?.let { it.asLongArray() } + } + + abstract fun bounceUnsignedArrayAsync(array: ULongArray): Promise + + @DoNotStrip + @Keep + private fun bounceUnsignedArrayAsync_cxx(array: LongArray): Promise { + val __result = bounceUnsignedArrayAsync(array.asULongArray()) + return __result.let { __source -> Promise().also { __promise -> __source.then { __result -> __promise.resolve(__result.asLongArray()) }.catch { __promise.reject(it) } } } + } + + abstract fun callUnsignedArrayCallback(array: ULongArray, callback: Callback<(array: ULongArray) -> ULongArray>): ULongArray + + @DoNotStrip + @Keep + private fun callUnsignedArrayCallback_cxx(array: LongArray, callback: Callback_std__vector_uint64_t__std__vector_uint64_t_): LongArray { + val __result = callUnsignedArrayCallback(array.asULongArray(), callback) + return __result.asLongArray() + } + @DoNotStrip @Keep abstract fun bounceHybridObjects(array: Array): Array diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/UnsignedValues.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/UnsignedValues.kt index a59ebfb2bb..dee6d5a359 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/UnsignedValues.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/UnsignedValues.kt @@ -12,7 +12,6 @@ import com.facebook.proguard.annotations.DoNotStrip import java.util.Objects import com.margelo.nitro.core.Callback import com.margelo.nitro.utils.mapToArray -import com.margelo.nitro.utils.mapToLongArray /** * Represents the JavaScript object/struct "UnsignedValues". @@ -28,10 +27,10 @@ data class UnsignedValues( val optionalUnsigned: ULong?, @DoNotStrip @Keep - val values: Array, + val values: ULongArray, @DoNotStrip @Keep - val nested: Array>, + val nested: Array, @DoNotStrip @Keep val record: Map, @@ -46,18 +45,11 @@ data class UnsignedValues( return optionalUnsigned?.let { it.toLong() } } - @DoNotStrip - @Keep - @Suppress("unused", "FunctionName") - private fun getValues_cxx(): LongArray { - return values.mapToLongArray { __item -> __item.toLong() } - } - @DoNotStrip @Keep @Suppress("unused", "FunctionName") private fun getNested_cxx(): Array { - return nested.mapToArray, LongArray> { __item -> __item.mapToLongArray { __item -> __item.toLong() } } + return nested.mapToArray { __item -> __item.asLongArray() } } @DoNotStrip @@ -79,8 +71,8 @@ data class UnsignedValues( if (other !is UnsignedValues) return false return Objects.deepEquals(this.unsignedValue, other.unsignedValue) && Objects.deepEquals(this.optionalUnsigned, other.optionalUnsigned) - && Objects.deepEquals(this.values, other.values) - && Objects.deepEquals(this.nested, other.nested) + && Objects.deepEquals(this.values.asLongArray(), other.values.asLongArray()) + && Objects.deepEquals(this.nested.mapToArray { __item -> __item.asLongArray() }, other.nested.mapToArray { __item -> __item.asLongArray() }) && Objects.deepEquals(this.record, other.record) && Objects.deepEquals(this.callbacks, other.callbacks) } @@ -89,8 +81,8 @@ data class UnsignedValues( return arrayOf( unsignedValue, optionalUnsigned, - values, - nested, + values.asLongArray(), + nested.mapToArray { __item -> __item.asLongArray() }, record, callbacks ).contentDeepHashCode() @@ -105,7 +97,7 @@ data class UnsignedValues( @Suppress("unused") @JvmStatic private fun fromCpp(unsignedValue: Long, optionalUnsigned: Long?, values: LongArray, nested: Array, record: Map, callbacks: Array): UnsignedValues { - return UnsignedValues(unsignedValue.toULong(), optionalUnsigned?.let { it.toULong() }, values.mapToArray { __item -> __item.toULong() }, nested.mapToArray> { __item -> __item.mapToArray { __item -> __item.toULong() } }, record.mapValues { (_, __value) -> __value?.let { it.toULong() } }, callbacks.mapToArray ULong>> { __item -> __item }) + return UnsignedValues(unsignedValue.toULong(), optionalUnsigned?.let { it.toULong() }, values.asULongArray(), nested.mapToArray { __item -> __item.asULongArray() }, record.mapValues { (_, __value) -> __value?.let { it.toULong() } }, callbacks.mapToArray ULong>> { __item -> __item }) } } } diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTest-Swift-Cxx-Bridge.cpp b/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTest-Swift-Cxx-Bridge.cpp index feff7dce5e..26faaa3021 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTest-Swift-Cxx-Bridge.cpp +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTest-Swift-Cxx-Bridge.cpp @@ -216,6 +216,24 @@ namespace margelo::nitro::test::swift_bridge { }); } + Promise_swift__Array_uint64_t_ create_Promise_swift__Array_uint64_t_() { return Promise_swift__Array_uint64_t_::pending(); } + + void reject_Promise_swift__Array_uint64_t_(const Promise_swift__Array_uint64_t_& promise, std::exception_ptr error) { promise.reject(std::move(error)); } + + void listenRejected_Promise_swift__Array_uint64_t_(const Promise_swift__Array_uint64_t_& promise, std::function listener) { promise.addOnRejectedListener(std::move(listener)); } + + void resolve_Promise_swift__Array_uint64_t_(const Promise_swift__Array_uint64_t_& promise, const void* NON_NULL value) { + promise.resolve(NitroModules::copySwiftValue>(value)); + } + + void listen_Promise_swift__Array_uint64_t_(const Promise_swift__Array_uint64_t_& promise, std::function listener) { + promise.addOnResolvedListener([listener = std::move(listener)](const swift::Array& value) { + NitroModules::withSwiftValue(value, [&](const void* pointer) { + listener(pointer); + }); + }); + } + Result callSync_Callback_void(const Callback_void& callback) noexcept { try { callback.callSync(); @@ -445,6 +463,37 @@ namespace margelo::nitro::test::swift_bridge { }); } + Result callSync_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(const Callback_swift__Array_uint64_t__swift__Array_uint64_t_& callback, const void* NON_NULL param0, void* NON_NULL __outResult) noexcept { + try { + NitroModules::initializeSwiftValue(__outResult, callback.callSync(NitroModules::copySwiftValue>(param0))); + return Result::withValue(); + } catch (...) { + return Result::withError(std::current_exception()); + } + } + + Promise> callAsync_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(const Callback_swift__Array_uint64_t__swift__Array_uint64_t_& callback, const void* NON_NULL param0) { + return callback.callAsync(NitroModules::copySwiftValue>(param0)); + } + + void callAndForget_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(const Callback_swift__Array_uint64_t__swift__Array_uint64_t_& callback, const void* NON_NULL param0) { + callback.callAndForget(NitroModules::copySwiftValue>(param0)); + } + + Callback_swift__Array_uint64_t__swift__Array_uint64_t_ create_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(std::function(const void* NON_NULL param0, void* NON_NULL __outResult)> closure) { + return Callback_swift__Array_uint64_t__swift__Array_uint64_t_::make([closure = std::move(closure)](const swift::Array& param0) -> swift::Array { + auto __result = borrowSwiftValue(param0, [&](const void* param0) { + return withSwiftResult>([&](void* __outResult) { + return closure(param0, __outResult); + }); + }); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + return std::move(__result.value()); + }); + } + Callback_void InlineCallback_void::escape() const { return get().escape(); } diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTestAppleCxx/include/NitroTestAppleCxx/NitroTestAppleCxx.h b/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTestAppleCxx/include/NitroTestAppleCxx/NitroTestAppleCxx.h index 1cac9f9546..2d04008326 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTestAppleCxx/include/NitroTestAppleCxx/NitroTestAppleCxx.h +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTestAppleCxx/include/NitroTestAppleCxx/NitroTestAppleCxx.h @@ -226,6 +226,12 @@ namespace margelo::nitro::test::swift_bridge { Promise<::NitroTest::SwiftContainer_swift__Array___NitroTest__Powertrain_> callAsync_Callback___NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain____NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain_(const Callback___NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain____NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain_& callback, const void* NON_NULL param0); void callAndForget_Callback___NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain____NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain_(const Callback___NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain____NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain_& callback, const void* NON_NULL param0); Callback___NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain____NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain_ create_Callback___NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain____NitroTest__SwiftContainer_swift__Array___NitroTest__Powertrain_(std::function(const void* NON_NULL param0, void* NON_NULL __outResult)> closure); + using Promise_swift__Array_uint64_t_ = Promise>; + Promise_swift__Array_uint64_t_ create_Promise_swift__Array_uint64_t_(); + void reject_Promise_swift__Array_uint64_t_(const Promise_swift__Array_uint64_t_& promise, std::exception_ptr error); + void listenRejected_Promise_swift__Array_uint64_t_(const Promise_swift__Array_uint64_t_& promise, std::function listener); + void resolve_Promise_swift__Array_uint64_t_(const Promise_swift__Array_uint64_t_& promise, const void* NON_NULL value); + void listen_Promise_swift__Array_uint64_t_(const Promise_swift__Array_uint64_t_& promise, std::function listener); using Callback_void = Callback; Result callSync_Callback_void(const Callback_void& callback) noexcept; Callback_void create_Callback_void(std::function()> closure); @@ -287,6 +293,11 @@ namespace margelo::nitro::test::swift_bridge { Promise<::NitroTest::SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___> callAsync_Callback___NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person______NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___(const Callback___NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person______NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___& callback, const void* NON_NULL param0); void callAndForget_Callback___NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person______NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___(const Callback___NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person______NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___& callback, const void* NON_NULL param0); Callback___NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person______NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___ create_Callback___NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person______NitroTest__SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___(std::function(const void* NON_NULL param0, void* NON_NULL __outResult)> closure); + using Callback_swift__Array_uint64_t__swift__Array_uint64_t_ = Callback(const swift::Array&)>; + Result callSync_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(const Callback_swift__Array_uint64_t__swift__Array_uint64_t_& callback, const void* NON_NULL param0, void* NON_NULL __outResult) noexcept; + Promise> callAsync_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(const Callback_swift__Array_uint64_t__swift__Array_uint64_t_& callback, const void* NON_NULL param0); + void callAndForget_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(const Callback_swift__Array_uint64_t__swift__Array_uint64_t_& callback, const void* NON_NULL param0); + Callback_swift__Array_uint64_t__swift__Array_uint64_t_ create_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(std::function(const void* NON_NULL param0, void* NON_NULL __outResult)> closure); // TODO: Replace this borrowing facade with a typealias once our minimum Xcode includes // https://github.com/swiftlang/swift/pull/93321, which fixes https://github.com/swiftlang/swift/issues/93318. // Exporting the same imported InlineCallback specialization from two Swift headers duplicates its traits. diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/c++/HybridTestObjectCppSpecClass.cpp b/tests/standalone/nitro-test/nitrogen/generated/apple/c++/HybridTestObjectCppSpecClass.cpp index 0d66ef5e70..240c373dea 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/c++/HybridTestObjectCppSpecClass.cpp +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/c++/HybridTestObjectCppSpecClass.cpp @@ -147,6 +147,11 @@ namespace margelo::nitro::test { clazz.registerHybridMethod("callEnumArrayPromiseCallback", &HybridTestObjectCppSpec::callEnumArrayPromiseCallback); clazz.registerHybridMethod("awaitEnumArrayPromise", &HybridTestObjectCppSpec::awaitEnumArrayPromise); clazz.registerHybridMethod("callNestedStructCallback", &HybridTestObjectCppSpec::callNestedStructCallback); + clazz.registerHybridMethod("bounceUnsignedArray", &HybridTestObjectCppSpec::bounceUnsignedArray); + clazz.registerHybridMethod("bounceNestedUnsignedArray", &HybridTestObjectCppSpec::bounceNestedUnsignedArray); + clazz.registerHybridMethod("bounceOptionalUnsignedArray", &HybridTestObjectCppSpec::bounceOptionalUnsignedArray); + clazz.registerHybridMethod("bounceUnsignedArrayAsync", &HybridTestObjectCppSpec::bounceUnsignedArrayAsync); + clazz.registerHybridMethod("callUnsignedArrayCallback", &HybridTestObjectCppSpec::callUnsignedArrayCallback); clazz.registerHybridMethod("bounceHybridObjects", &HybridTestObjectCppSpec::bounceHybridObjects); clazz.registerHybridMethod("bounceFunctions", &HybridTestObjectCppSpec::bounceFunctions); clazz.registerHybridMethod("bounceMaps", &HybridTestObjectCppSpec::bounceMaps); diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/c++/HybridTestObjectSwiftKotlinSpecSwift.cpp b/tests/standalone/nitro-test/nitrogen/generated/apple/c++/HybridTestObjectSwiftKotlinSpecSwift.cpp index d453f2e164..3fa47dd5f2 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/c++/HybridTestObjectSwiftKotlinSpecSwift.cpp +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/c++/HybridTestObjectSwiftKotlinSpecSwift.cpp @@ -377,6 +377,58 @@ namespace margelo::nitro::test { return std::move(__result.value()); } + swift::Array HybridTestObjectSwiftKotlinSpecSwift::bounceUnsignedArray(const swift::Array& array) { + auto __result = withSwiftResult>([&](void* __outResult) { + return _swiftPart.bounceUnsignedArray(array, __outResult); + }); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + return std::move(__result.value()); + } + + swift::Array> HybridTestObjectSwiftKotlinSpecSwift::bounceNestedUnsignedArray(const swift::Array>& array) { + auto __result = withSwiftResult>>([&](void* __outResult) { + return _swiftPart.bounceNestedUnsignedArray(array, __outResult); + }); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + return std::move(__result.value()); + } + + swift::Optional> HybridTestObjectSwiftKotlinSpecSwift::bounceOptionalUnsignedArray(const swift::Optional>& array) { + auto __result = withSwiftResult>>([&](void* __outResult) { + return _swiftPart.bounceOptionalUnsignedArray(array, __outResult); + }); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + return std::move(__result.value()); + } + + Promise> HybridTestObjectSwiftKotlinSpecSwift::bounceUnsignedArrayAsync(const swift::Array& array) { + auto __result = withCxxResult>>([&](void* __outResult) { + return _swiftPart.bounceUnsignedArrayAsync(array, __outResult); + }); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + return std::move(__result.value()); + } + + swift::Array HybridTestObjectSwiftKotlinSpecSwift::callUnsignedArrayCallback(const swift::Array& array, const Callback(const swift::Array&)>& callback) { + auto __result = ([&](const void* callback) { + return withSwiftResult>([&](void* __outResult) { + return _swiftPart.callUnsignedArrayCallback(array, callback, __outResult); + }); + })(std::addressof(callback)); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + return std::move(__result.value()); + } + swift::Array<::NitroTest::HybridChildSpec_cxx> HybridTestObjectSwiftKotlinSpecSwift::bounceHybridObjects(const swift::Array<::NitroTest::HybridChildSpec_cxx>& array) { auto __result = withSwiftResult>([&](void* __outResult) { return _swiftPart.bounceHybridObjects(array, __outResult); @@ -1619,6 +1671,11 @@ namespace margelo::nitro::test { clazz.registerHybridMethod("callEnumArrayPromiseCallback", &HybridTestObjectSwiftKotlinSpecSwift::callEnumArrayPromiseCallback); clazz.registerHybridMethod("awaitEnumArrayPromise", &HybridTestObjectSwiftKotlinSpecSwift::awaitEnumArrayPromise); clazz.registerHybridMethod("callNestedStructCallback", &HybridTestObjectSwiftKotlinSpecSwift::callNestedStructCallback); + clazz.registerHybridMethod("bounceUnsignedArray", &HybridTestObjectSwiftKotlinSpecSwift::bounceUnsignedArray); + clazz.registerHybridMethod("bounceNestedUnsignedArray", &HybridTestObjectSwiftKotlinSpecSwift::bounceNestedUnsignedArray); + clazz.registerHybridMethod("bounceOptionalUnsignedArray", &HybridTestObjectSwiftKotlinSpecSwift::bounceOptionalUnsignedArray); + clazz.registerHybridMethod("bounceUnsignedArrayAsync", &HybridTestObjectSwiftKotlinSpecSwift::bounceUnsignedArrayAsync); + clazz.registerHybridMethod("callUnsignedArrayCallback", &HybridTestObjectSwiftKotlinSpecSwift::callUnsignedArrayCallback); clazz.registerHybridMethod("bounceHybridObjects", &HybridTestObjectSwiftKotlinSpecSwift::bounceHybridObjects); clazz.registerHybridMethod("bounceFunctions", &HybridTestObjectSwiftKotlinSpecSwift::bounceFunctions); clazz.registerHybridMethod("bounceMaps", &HybridTestObjectSwiftKotlinSpecSwift::bounceMaps); diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/c++/include/NitroTest/private/HybridTestObjectSwiftKotlinSpecSwift.hpp b/tests/standalone/nitro-test/nitrogen/generated/apple/c++/include/NitroTest/private/HybridTestObjectSwiftKotlinSpecSwift.hpp index 6a9b6330e7..705a322fe0 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/c++/include/NitroTest/private/HybridTestObjectSwiftKotlinSpecSwift.hpp +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/c++/include/NitroTest/private/HybridTestObjectSwiftKotlinSpecSwift.hpp @@ -120,6 +120,11 @@ namespace margelo::nitro::test { Promise<::NitroTest::SwiftContainer_swift__Array___NitroTest__Powertrain_> callEnumArrayPromiseCallback(const Callback()>& callback); Promise<::NitroTest::SwiftContainer_swift__Array___NitroTest__Powertrain_> awaitEnumArrayPromise(const Promise<::NitroTest::SwiftContainer_swift__Array___NitroTest__Powertrain_>& promise); swift::Array>> callNestedStructCallback(const swift::Array>>& value, const Callback<::NitroTest::SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___(const ::NitroTest::SwiftContainer_swift__Array_swift__Array_swift__Optional___NitroTest__Person___&)>& callback); + swift::Array bounceUnsignedArray(const swift::Array& array); + swift::Array> bounceNestedUnsignedArray(const swift::Array>& array); + swift::Optional> bounceOptionalUnsignedArray(const swift::Optional>& array); + Promise> bounceUnsignedArrayAsync(const swift::Array& array); + swift::Array callUnsignedArrayCallback(const swift::Array& array, const Callback(const swift::Array&)>& callback); swift::Array<::NitroTest::HybridChildSpec_cxx> bounceHybridObjects(const swift::Array<::NitroTest::HybridChildSpec_cxx>& array); swift::Array> bounceFunctions(const swift::Array>& functions); swift::Array bounceMaps(const swift::Array& maps); diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/swift/Callback_swift__Array_uint64_t__swift__Array_uint64_t_.swift b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/Callback_swift__Array_uint64_t__swift__Array_uint64_t_.swift new file mode 100644 index 0000000000..14d5d06924 --- /dev/null +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/Callback_swift__Array_uint64_t__swift__Array_uint64_t_.swift @@ -0,0 +1,71 @@ +/// +/// Callback_swift__Array_uint64_t__swift__Array_uint64_t_.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/margelo/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +public import NitroModules +internal import CxxStdlib +internal import NitroTestAppleCxx + +public typealias Callback_swift__Array_uint64_t__swift__Array_uint64_t_ = margelo.nitro.test.swift_bridge.Callback_swift__Array_uint64_t__swift__Array_uint64_t_ + +extension Callback_swift__Array_uint64_t__swift__Array_uint64_t_ { + public typealias Arguments = ([UInt64]) + public typealias Return = [UInt64] + public typealias AsyncResult = margelo.nitro.test.swift_bridge.Promise_swift__Array_uint64_t_ + private typealias bridge = margelo.nitro.test.swift_bridge + + public func __nitroCallSync(_ arguments: Arguments) throws -> Return { + return try withUnsafePointer(to: arguments) { (param0: UnsafePointer<[UInt64]>) -> Return in + return try withUnsafeTemporaryAllocation(of: [UInt64].self, capacity: 1) { (result: UnsafeMutableBufferPointer<[UInt64]>) -> Return in + let __result = bridge.callSync_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(self, param0, result.baseAddress!) + if __result.hasError() { + throw RuntimeError.from(cppError: __result.error()) + } + let value = result.baseAddress!.move() + return value + } + } + } + public func __nitroCallAsync(_ arguments: Arguments) -> AsyncResult { + return withUnsafePointer(to: arguments) { (param0: UnsafePointer<[UInt64]>) -> AsyncResult in + return bridge.callAsync_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(self, param0) + } + } + public func __nitroCallAndForget(_ arguments: Arguments) { + return withUnsafePointer(to: arguments) { (param0: UnsafePointer<[UInt64]>) -> Void in + bridge.callAndForget_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(self, param0) + } + } + public init(_ closure: @escaping @Sendable ([UInt64]) throws -> Return) { + self = bridge.create_Callback_swift__Array_uint64_t__swift__Array_uint64_t_(.init { (param0: UnsafeRawPointer!, __outResult: UnsafeMutableRawPointer!) -> bridge.Result_void in + do { + let value = try closure(param0.load(as: [UInt64].self)) + __outResult.assumingMemoryBound(to: [UInt64].self).initialize(to: value) + return bridge.Result_void.withValue() + } catch { + return bridge.Result_void.withError(error.toCpp()) + } + }) + } +} + +extension Callback<([UInt64]), [UInt64]> where Self == Callback_swift__Array_uint64_t__swift__Array_uint64_t_ { + /// Creates a native callback from an escaping Swift closure. + public static func native(_ closure: @escaping @Sendable ([UInt64]) throws -> [UInt64]) -> Self { + return Self(closure) + } +} + +extension Callback<([UInt64]), [UInt64]> { + func toCpp() -> Callback_swift__Array_uint64_t__swift__Array_uint64_t_ { + if let value = self as? Callback_swift__Array_uint64_t__swift__Array_uint64_t_ { + return value + } + return Callback_swift__Array_uint64_t__swift__Array_uint64_t_ { (param0: [UInt64]) -> [UInt64] in + try self.callSync((param0)) + } + } +} diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/swift/HybridTestObjectSwiftKotlinSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/HybridTestObjectSwiftKotlinSpec.swift index 1c338bdae2..a8aeb43243 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/swift/HybridTestObjectSwiftKotlinSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/HybridTestObjectSwiftKotlinSpec.swift @@ -58,6 +58,11 @@ public protocol HybridTestObjectSwiftKotlinSpec_protocol: HybridTestObjectSwiftK func callEnumArrayPromiseCallback(callback: any Callback<(), any Promise<[Powertrain]>>) throws -> any Promise<[Powertrain]> func awaitEnumArrayPromise(promise: any Promise<[Powertrain]>) throws -> any Promise<[Powertrain]> func callNestedStructCallback(value: [[Person?]], callback: any Callback<(/* value */ [[Person?]]), [[Person?]]>) throws -> [[Person?]] + func bounceUnsignedArray(array: [UInt64]) throws -> [UInt64] + func bounceNestedUnsignedArray(array: [[UInt64]]) throws -> [[UInt64]] + func bounceOptionalUnsignedArray(array: [UInt64]?) throws -> [UInt64]? + func bounceUnsignedArrayAsync(array: [UInt64]) throws -> any Promise<[UInt64]> + func callUnsignedArrayCallback(array: [UInt64], callback: any Callback<(/* array */ [UInt64]), [UInt64]>) throws -> [UInt64] func bounceHybridObjects(array: [(any HybridChildSpec)]) throws -> [(any HybridChildSpec)] func bounceFunctions(functions: [any Callback<(), Void>]) throws -> [any Callback<(), Void>] func bounceMaps(maps: [AnyJSON]) throws -> [AnyJSON] diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift index db8c617b9c..e4cc9de133 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift @@ -509,6 +509,56 @@ public final class HybridTestObjectSwiftKotlinSpec_cxx { } } + public final func bounceUnsignedArray(array: [UInt64], __outResult: UnsafeMutableRawPointer) -> bridge.Result_void { + do { + let value = try __implementation.bounceUnsignedArray(array: array) + __outResult.assumingMemoryBound(to: [UInt64].self).initialize(to: value) + return bridge.Result_void.withValue() + } catch { + return bridge.Result_void.withError(error.toCpp()) + } + } + + public final func bounceNestedUnsignedArray(array: [[UInt64]], __outResult: UnsafeMutableRawPointer) -> bridge.Result_void { + do { + let value = try __implementation.bounceNestedUnsignedArray(array: array) + __outResult.assumingMemoryBound(to: [[UInt64]].self).initialize(to: value) + return bridge.Result_void.withValue() + } catch { + return bridge.Result_void.withError(error.toCpp()) + } + } + + public final func bounceOptionalUnsignedArray(array: [UInt64]?, __outResult: UnsafeMutableRawPointer) -> bridge.Result_void { + do { + let value = try __implementation.bounceOptionalUnsignedArray(array: array) + __outResult.assumingMemoryBound(to: [UInt64]?.self).initialize(to: value) + return bridge.Result_void.withValue() + } catch { + return bridge.Result_void.withError(error.toCpp()) + } + } + + public final func bounceUnsignedArrayAsync(array: [UInt64], __outResult: UnsafeMutableRawPointer) -> bridge.Result_void { + do { + let value = try __implementation.bounceUnsignedArrayAsync(array: array) + __outResult.initializeMemory(as: margelo.nitro.test.swift_bridge.Promise_swift__Array_uint64_t_.self, repeating: value.toCpp(), count: 1) + return bridge.Result_void.withValue() + } catch { + return bridge.Result_void.withError(error.toCpp()) + } + } + + public final func callUnsignedArrayCallback(array: [UInt64], callback: UnsafeRawPointer, __outResult: UnsafeMutableRawPointer) -> bridge.Result_void { + do { + let value = try __implementation.callUnsignedArrayCallback(array: array, callback: callback.load(as: margelo.nitro.test.swift_bridge.Callback_swift__Array_uint64_t__swift__Array_uint64_t_.self)) + __outResult.assumingMemoryBound(to: [UInt64].self).initialize(to: value) + return bridge.Result_void.withValue() + } catch { + return bridge.Result_void.withError(error.toCpp()) + } + } + public final func bounceHybridObjects(array: [HybridChildSpec_cxx], __outResult: UnsafeMutableRawPointer) -> bridge.Result_void { do { let value = try __implementation.bounceHybridObjects(array: array.map { $0.getHybridChildSpec() }) diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/swift/Promise_swift__Array_uint64_t_.swift b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/Promise_swift__Array_uint64_t_.swift new file mode 100644 index 0000000000..3abd82c274 --- /dev/null +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/Promise_swift__Array_uint64_t_.swift @@ -0,0 +1,102 @@ +/// +/// Promise_swift__Array_uint64_t_.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/margelo/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +public import NitroModules +internal import CxxStdlib +public import Dispatch +internal import NitroTestAppleCxx + +public typealias Promise_swift__Array_uint64_t_ = margelo.nitro.test.swift_bridge.Promise_swift__Array_uint64_t_ + +extension Promise_swift__Array_uint64_t_ { + public typealias T = [UInt64] + private typealias bridge = margelo.nitro.test.swift_bridge + + public func __nitroResolve(result: [UInt64]) { + withUnsafePointer(to: result) { (pointer: UnsafePointer<[UInt64]>) -> Void in + bridge.resolve_Promise_swift__Array_uint64_t_(self, pointer) + } + } + public func __nitroReject(error: any Error) { + bridge.reject_Promise_swift__Array_uint64_t_(self, error.toCpp()) + } + + public func __nitroAddOnResolvedListener(_ listener: @escaping @Sendable ([UInt64]) -> Void) { + bridge.listen_Promise_swift__Array_uint64_t_(self, .init { (value: UnsafeRawPointer!) -> Void in + listener(value.load(as: [UInt64].self)) + }) + } + public func __nitroAddOnRejectedListener(_ listener: @escaping @Sendable (any Error) -> Void) { + bridge.listenRejected_Promise_swift__Array_uint64_t_(self, .init { (exceptionPtr: std.exception_ptr) -> Void in + listener(RuntimeError.from(cppError: exceptionPtr)) + }) + } +} + +extension Promise<[UInt64]> where Self == Promise_swift__Array_uint64_t_ { + public static func pending() -> Self { + return margelo.nitro.test.swift_bridge.create_Promise_swift__Array_uint64_t_() + } + + public static func resolved(with result: [UInt64]) -> Self { + let promise = Promise_swift__Array_uint64_t_.pending() + promise.resolve(result: result) + return promise + } + public static func rejected(with error: any Error) -> Self { + let promise = Promise_swift__Array_uint64_t_.pending() + promise.reject(error: error) + return promise + } + + public static func `async`( + _ priority: TaskPriority? = nil, + _ run: sending @escaping @isolated(any) () async throws -> sending [UInt64] + ) -> Self { + let promise = Promise_swift__Array_uint64_t_.pending() + Task(priority: priority) { () async -> Void in + do { + promise.resolve(result: try await run()) + } catch { + promise.reject(error: error) + } + } + return promise + } + + public static func parallel( + _ queue: DispatchQueue = .global(), + _ run: @escaping @Sendable () throws -> [UInt64] + ) -> Self { + let promise = Promise_swift__Array_uint64_t_.pending() + queue.async { () -> Void in + do { + promise.resolve(result: try run()) + } catch { + promise.reject(error: error) + } + } + return promise + } +} + +extension Promise<[UInt64]> { + func toCpp() -> Promise_swift__Array_uint64_t_ { + if let self = self as? Promise_swift__Array_uint64_t_ { + return self + } else { + let promise = Promise_swift__Array_uint64_t_.pending() + self.addOnResolvedListener { (result: [UInt64]) -> Void in + promise.resolve(result: result) + } + self.addOnRejectedListener { (error: any Error) -> Void in + promise.reject(error: error) + } + return promise + } + } +} diff --git a/tests/standalone/nitro-test/nitrogen/generated/shared/c++/include/NitroTest/HybridTestObjectCppSpec.hpp b/tests/standalone/nitro-test/nitrogen/generated/shared/c++/include/NitroTest/HybridTestObjectCppSpec.hpp index 487f3cae88..e709415a47 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/shared/c++/include/NitroTest/HybridTestObjectCppSpec.hpp +++ b/tests/standalone/nitro-test/nitrogen/generated/shared/c++/include/NitroTest/HybridTestObjectCppSpec.hpp @@ -166,6 +166,11 @@ namespace margelo::nitro::test { virtual Promise> callEnumArrayPromiseCallback(const Callback>()>& callback) = 0; virtual Promise> awaitEnumArrayPromise(const Promise>& promise) = 0; virtual std::vector>> callNestedStructCallback(const std::vector>>& value, const Callback>>(const std::vector>>& /* value */)>& callback) = 0; + virtual std::vector bounceUnsignedArray(const std::vector& array) = 0; + virtual std::vector> bounceNestedUnsignedArray(const std::vector>& array) = 0; + virtual std::optional> bounceOptionalUnsignedArray(const std::optional>& array) = 0; + virtual Promise> bounceUnsignedArrayAsync(const std::vector& array) = 0; + virtual std::vector callUnsignedArrayCallback(const std::vector& array, const Callback(const std::vector& /* array */)>& callback) = 0; virtual std::vector bounceHybridObjects(const std::vector& array) = 0; virtual std::vector> bounceFunctions(const std::vector>& functions) = 0; virtual std::vector bounceMaps(const std::vector& maps) = 0; diff --git a/tests/standalone/nitro-test/specs/TestObject.nitro.ts b/tests/standalone/nitro-test/specs/TestObject.nitro.ts index 99994b94c5..97483d0d9b 100644 --- a/tests/standalone/nitro-test/specs/TestObject.nitro.ts +++ b/tests/standalone/nitro-test/specs/TestObject.nitro.ts @@ -231,6 +231,13 @@ export declare class TestObjectCpp extends HybridObject { callback: (value: (Person | undefined)[][]) => (Person | undefined)[][] ): (Person | undefined)[][] + // Unsigned containers + bounceUnsignedArray(array: UInt64[]): UInt64[] + bounceNestedUnsignedArray(array: UInt64[][]): UInt64[][] + bounceOptionalUnsignedArray(array?: UInt64[]): UInt64[] | undefined + bounceUnsignedArrayAsync(array: UInt64[]): Promise + callUnsignedArrayCallback(array: UInt64[], callback: (array: UInt64[]) => UInt64[]): UInt64[] + // Arrays (complex) bounceHybridObjects(array: Child[]): Child[] bounceFunctions(functions: (() => void)[]): (() => void)[] @@ -515,6 +522,13 @@ export declare class TestObjectSwiftKotlin extends HybridObject { callback: (value: (Person | undefined)[][]) => (Person | undefined)[][] ): (Person | undefined)[][] + // Unsigned containers + bounceUnsignedArray(array: UInt64[]): UInt64[] + bounceNestedUnsignedArray(array: UInt64[][]): UInt64[][] + bounceOptionalUnsignedArray(array?: UInt64[]): UInt64[] | undefined + bounceUnsignedArrayAsync(array: UInt64[]): Promise + callUnsignedArrayCallback(array: UInt64[], callback: (array: UInt64[]) => UInt64[]): UInt64[] + // Arrays (complex) bounceHybridObjects(array: Child[]): Child[] bounceFunctions(functions: (() => void)[]): (() => void)[] diff --git a/tests/standalone/test-runner/js/data.test.ts b/tests/standalone/test-runner/js/data.test.ts index d14b72614b..e8ae786cd1 100644 --- a/tests/standalone/test-runner/js/data.test.ts +++ b/tests/standalone/test-runner/js/data.test.ts @@ -154,6 +154,37 @@ export const cases = { } }, }), + ...casesForTestObjects('Unsigned containers', { + 'bounceUnsignedArray(...) preserves all 64 bits': (testObject) => { + expect(testObject.bounceUnsignedArray(UNSIGNED_BOUNDARIES)).to.deep.equal(UNSIGNED_BOUNDARIES) + expect(testObject.bounceUnsignedArray([])).to.deep.equal([]) + }, + + 'bounceNestedUnsignedArray(...) preserves every level': (testObject) => { + const nested = [[], UNSIGNED_BOUNDARIES, [18446744073709551615n]] + expect(testObject.bounceNestedUnsignedArray(nested)).to.deep.equal(nested) + }, + + 'bounceOptionalUnsignedArray(...) preserves a missing and a present array': (testObject) => { + expect(testObject.bounceOptionalUnsignedArray(undefined)).to.equal(undefined) + expect(testObject.bounceOptionalUnsignedArray(UNSIGNED_BOUNDARIES)).to.deep.equal(UNSIGNED_BOUNDARIES) + }, + + 'bounceUnsignedArrayAsync(...) resolves all 64 bits': async (testObject) => { + const result = await withTimeout(testObject.bounceUnsignedArrayAsync(UNSIGNED_BOUNDARIES)) + expect(result).to.deep.equal(UNSIGNED_BOUNDARIES) + }, + + 'callUnsignedArrayCallback(...) passes all 64 bits to JS and back': (testObject) => { + const received: bigint[][] = [] + const result = testObject.callUnsignedArrayCallback(UNSIGNED_BOUNDARIES, (array) => { + received.push(array) + return [...array].reverse() + }) + expect(received).to.deep.equal([UNSIGNED_BOUNDARIES]) + expect(result).to.deep.equal([...UNSIGNED_BOUNDARIES].reverse()) + }, + }), ...casesForTestObjects('Struct roundtrips', { 'bouncePartialStruct(...) keeps an empty struct': (testObject) => { expect(testObject.bouncePartialStruct({ name: undefined, age: undefined })).to.deep.equal({ name: undefined, age: undefined })