From 809aae7af8425f4306f820850b1306533a8e2a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 27 Oct 2026 15:05:35 +0100 Subject: [PATCH] test: cover callback struct fields across modules --- .../external/HybridSharedSpecializations.kt | 4 ++ .../apple/HybridSharedSpecializations.swift | 4 ++ .../cpp/HybridSharedSpecializationsCpp.cpp | 4 ++ .../cpp/HybridSharedSpecializationsCpp.hpp | 1 + .../NitroTestExternal+autolinking.cmake | 2 + ...ybridSharedSpecializationsCppSpecClass.cpp | 2 + .../c++/JHybridSharedSpecializationsSpec.cpp | 7 +++ .../android/c++/JSharedCallbackStruct.cpp | 37 +++++++++++ .../JHybridSharedSpecializationsSpec.hpp | 2 + .../private/JSharedCallbackStruct.hpp | 56 +++++++++++++++++ .../HybridSharedSpecializationsSpec.kt | 4 ++ .../test/external/SharedCallbackStruct.kt | 61 +++++++++++++++++++ .../NitroTestExternalAppleCxx.h | 2 + ...ybridSharedSpecializationsCppSpecClass.cpp | 2 + .../HybridSharedSpecializationsSpecSwift.cpp | 11 ++++ .../apple/c++/SharedCallbackStruct-Swift.cpp | 33 ++++++++++ .../HybridSharedSpecializationsSpecSwift.hpp | 1 + .../NitroTestExternal-Swift-Cxx-Umbrella.hpp | 1 + .../private/SharedCallbackStruct-Swift.hpp | 23 +++++++ .../HybridSharedSpecializationsSpec.swift | 1 + .../HybridSharedSpecializationsSpec_cxx.swift | 10 +++ .../apple/swift/SharedCallbackStruct.swift | 36 +++++++++++ .../shared/c++/SharedCallbackStruct.cpp | 44 +++++++++++++ .../HybridSharedSpecializationsCppSpec.hpp | 2 + .../SharedCallbackStruct.hpp | 45 ++++++++++++++ .../specs/SharedSpecializations.nitro.ts | 8 +++ .../standalone/test-runner/js/interop.test.ts | 15 +++++ 27 files changed, 418 insertions(+) create mode 100644 tests/standalone/nitro-test-external/nitrogen/generated/android/c++/JSharedCallbackStruct.cpp create mode 100644 tests/standalone/nitro-test-external/nitrogen/generated/android/c++/include/NitroTestExternal/private/JSharedCallbackStruct.hpp create mode 100644 tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/SharedCallbackStruct.kt create mode 100644 tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/SharedCallbackStruct-Swift.cpp create mode 100644 tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/SharedCallbackStruct-Swift.hpp create mode 100644 tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/SharedCallbackStruct.swift create mode 100644 tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/SharedCallbackStruct.cpp create mode 100644 tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/include/NitroTestExternal/SharedCallbackStruct.hpp diff --git a/tests/standalone/nitro-test-external/android/src/main/java/com/margelo/nitro/test/external/HybridSharedSpecializations.kt b/tests/standalone/nitro-test-external/android/src/main/java/com/margelo/nitro/test/external/HybridSharedSpecializations.kt index 9db2ab31d3..6c708867d2 100644 --- a/tests/standalone/nitro-test-external/android/src/main/java/com/margelo/nitro/test/external/HybridSharedSpecializations.kt +++ b/tests/standalone/nitro-test-external/android/src/main/java/com/margelo/nitro/test/external/HybridSharedSpecializations.kt @@ -74,6 +74,10 @@ class HybridSharedSpecializations : HybridSharedSpecializationsSpec() { return Callback.native { value -> callback(value) } } + override fun bounceCallbackStruct(value: SharedCallbackStruct): SharedCallbackStruct { + return value + } + override fun callVoidPromiseCallback(callback: Callback<() -> Promise>): Promise { return Promise.async { callback().await().await() diff --git a/tests/standalone/nitro-test-external/apple/HybridSharedSpecializations.swift b/tests/standalone/nitro-test-external/apple/HybridSharedSpecializations.swift index 077711a922..ec1ba2e6c7 100644 --- a/tests/standalone/nitro-test-external/apple/HybridSharedSpecializations.swift +++ b/tests/standalone/nitro-test-external/apple/HybridSharedSpecializations.swift @@ -62,6 +62,10 @@ class HybridSharedSpecializations: HybridSharedSpecializationsSpec { } } + func bounceCallbackStruct(value: SharedCallbackStruct) throws -> SharedCallbackStruct { + return value + } + func callVoidPromiseCallback(callback: any Callback<(), any Promise>) throws -> any Promise { return .async { let promise = try await callback() diff --git a/tests/standalone/nitro-test-external/cpp/HybridSharedSpecializationsCpp.cpp b/tests/standalone/nitro-test-external/cpp/HybridSharedSpecializationsCpp.cpp index 0847d0888f..0bdece8ccf 100644 --- a/tests/standalone/nitro-test-external/cpp/HybridSharedSpecializationsCpp.cpp +++ b/tests/standalone/nitro-test-external/cpp/HybridSharedSpecializationsCpp.cpp @@ -66,6 +66,10 @@ Callback HybridSharedSpecializationsCpp::wrapNumberCallback(const return Callback::make([=](double value) { callback(value); }); } +SharedCallbackStruct HybridSharedSpecializationsCpp::bounceCallbackStruct(const SharedCallbackStruct& value) { + return value; +} + Promise HybridSharedSpecializationsCpp::callVoidPromiseCallback(const Callback()>& callback) { return Promise::async([=]() { Promise> callPromise = callback(); diff --git a/tests/standalone/nitro-test-external/cpp/HybridSharedSpecializationsCpp.hpp b/tests/standalone/nitro-test-external/cpp/HybridSharedSpecializationsCpp.hpp index 6582283557..aef3946b3c 100644 --- a/tests/standalone/nitro-test-external/cpp/HybridSharedSpecializationsCpp.hpp +++ b/tests/standalone/nitro-test-external/cpp/HybridSharedSpecializationsCpp.hpp @@ -35,6 +35,7 @@ class HybridSharedSpecializationsCpp : public HybridSharedSpecializationsCppSpec void callWithString(const std::string& value, const Callback& callback) override; Promise mapNumber(double value, const Callback& callback) override; Callback wrapNumberCallback(const Callback& callback) override; + SharedCallbackStruct bounceCallbackStruct(const SharedCallbackStruct& value) override; Promise callVoidPromiseCallback(const Callback()>& callback) override; Promise callNumberPromiseCallback(const Callback()>& callback) override; void callInline(const InlineCallback& callback) override; diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.cmake b/tests/standalone/nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.cmake index 78b4c93fcd..6e26f219fc 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.cmake +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/NitroTestExternal+autolinking.cmake @@ -26,11 +26,13 @@ target_sources(NitroTestExternal PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JHybridSharedSpecializationsSpec.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JHybridSomeExternalObjectSpec.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JOptionalPrimitivesHolder.cpp" + "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JSharedCallbackStruct.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JSize.cpp" "${CMAKE_CURRENT_LIST_DIR}/../android/c++/JSizeUnit.cpp" "${CMAKE_CURRENT_LIST_DIR}/../shared/c++/CppOnlyValue.cpp" "${CMAKE_CURRENT_LIST_DIR}/../shared/c++/HybridCppValueSourceSpec.cpp" "${CMAKE_CURRENT_LIST_DIR}/../shared/c++/HybridSharedSpecializationsCppSpec.cpp" + "${CMAKE_CURRENT_LIST_DIR}/../shared/c++/SharedCallbackStruct.cpp" ) find_package(fbjni REQUIRED CONFIG) diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/HybridSharedSpecializationsCppSpecClass.cpp b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/HybridSharedSpecializationsCppSpecClass.cpp index e4ef6e30b6..fb8de08ea5 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/HybridSharedSpecializationsCppSpecClass.cpp +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/HybridSharedSpecializationsCppSpecClass.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include "HybridSharedSpecializationsCpp.hpp" @@ -43,6 +44,7 @@ namespace margelo::nitro::test::external { clazz.registerHybridMethod("wrapNumberCallback", &HybridSharedSpecializationsCppSpec::wrapNumberCallback); clazz.registerHybridMethod("callVoidPromiseCallback", &HybridSharedSpecializationsCppSpec::callVoidPromiseCallback); clazz.registerHybridMethod("callNumberPromiseCallback", &HybridSharedSpecializationsCppSpec::callNumberPromiseCallback); + clazz.registerHybridMethod("bounceCallbackStruct", &HybridSharedSpecializationsCppSpec::bounceCallbackStruct); clazz.registerHybridMethod("callInline", &HybridSharedSpecializationsCppSpec::callInline); clazz.registerHybridMethod("callInlineWithNumber", &HybridSharedSpecializationsCppSpec::callInlineWithNumber); clazz.registerHybridConstructor(&HybridSharedSpecializationsCppSpecBindings::constructor); diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/JHybridSharedSpecializationsSpec.cpp b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/JHybridSharedSpecializationsSpec.cpp index 8b107d5bf7..c5bc361550 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/JHybridSharedSpecializationsSpec.cpp +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/JHybridSharedSpecializationsSpec.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ namespace margelo::nitro::test::external { clazz.registerHybridMethod("wrapNumberCallback", &JHybridSharedSpecializationsSpec::wrapNumberCallback); clazz.registerHybridMethod("callVoidPromiseCallback", &JHybridSharedSpecializationsSpec::callVoidPromiseCallback); clazz.registerHybridMethod("callNumberPromiseCallback", &JHybridSharedSpecializationsSpec::callNumberPromiseCallback); + clazz.registerHybridMethod("bounceCallbackStruct", &JHybridSharedSpecializationsSpec::bounceCallbackStruct); clazz.registerHybridMethod("callInline", &JHybridSharedSpecializationsSpec::callInline); clazz.registerHybridMethod("callInlineWithNumber", &JHybridSharedSpecializationsSpec::callInlineWithNumber); clazz.registerHybridConstructor(&JHybridSharedSpecializationsSpec::constructor); @@ -156,6 +158,11 @@ namespace margelo::nitro::test::external { auto __result = __method(_javaPart, CxxPart::getClass(), callback); return __result; } + jni::local_ref JHybridSharedSpecializationsSpec::bounceCallbackStruct(const jni::local_ref& value) { + static const auto __method = CxxPart::getClass()->getNonvirtualMethod(jni::alias_ref /* value */)>("bounceCallbackStruct"); + auto __result = __method(_javaPart, CxxPart::getClass(), value); + return __result; + } void JHybridSharedSpecializationsSpec::callInline(const jni::local_ref& callback) { static const auto __method = CxxPart::getClass()->getNonvirtualMethod /* callback */)>("callInline_cxx"); __method(_javaPart, CxxPart::getClass(), callback); diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/JSharedCallbackStruct.cpp b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/JSharedCallbackStruct.cpp new file mode 100644 index 0000000000..b1277680b9 --- /dev/null +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/JSharedCallbackStruct.cpp @@ -0,0 +1,37 @@ +/// +/// JSharedCallbackStruct.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 { + + jni::local_ref JSIConverter>::fromJSI(jsi::Runtime& runtime, const jsi::Value& value) { + auto object = value.asObject(runtime); + return margelo::nitro::test::external::JSharedCallbackStruct::create(JSIConverter::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "value"))), JSIConverter>::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "onChanged")))); + } + + jsi::Value JSIConverter>::toJSI(jsi::Runtime& runtime, jni::alias_ref value) { + jsi::Object object(runtime); + object.setProperty(runtime, PropNameIDCache::get(runtime, "value"), JSIConverter::toJSI(runtime, value->getValue())); + object.setProperty(runtime, PropNameIDCache::get(runtime, "onChanged"), JSIConverter>::toJSI(runtime, value->getOnChanged())); + return object; + } + + bool JSIConverter>::canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) return false; + auto object = value.getObject(runtime); + if (!isPlainObject(runtime, object)) return false; + return JSIConverter::canConvert(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "value"))) && JSIConverter>::canConvert(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "onChanged"))); + } + +} // namespace margelo::nitro diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/include/NitroTestExternal/private/JHybridSharedSpecializationsSpec.hpp b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/include/NitroTestExternal/private/JHybridSharedSpecializationsSpec.hpp index 66004dee9f..74ebd47932 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/include/NitroTestExternal/private/JHybridSharedSpecializationsSpec.hpp +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/include/NitroTestExternal/private/JHybridSharedSpecializationsSpec.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,7 @@ namespace margelo::nitro::test::external { jni::local_ref wrapNumberCallback(const jni::local_ref& callback); jni::local_ref> callVoidPromiseCallback(const jni::local_ref& callback); jni::local_ref>> callNumberPromiseCallback(const jni::local_ref& callback); + jni::local_ref bounceCallbackStruct(const jni::local_ref& value); void callInline(const jni::local_ref& callback); jdouble callInlineWithNumber(jdouble value, const jni::local_ref& callback); diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/include/NitroTestExternal/private/JSharedCallbackStruct.hpp b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/include/NitroTestExternal/private/JSharedCallbackStruct.hpp new file mode 100644 index 0000000000..9df1c867ff --- /dev/null +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/c++/include/NitroTestExternal/private/JSharedCallbackStruct.hpp @@ -0,0 +1,56 @@ +/// +/// JSharedCallbackStruct.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 + +namespace margelo::nitro::test::external { + + namespace jni = facebook::jni; + + /** JNI access to the Kotlin data class SharedCallbackStruct. */ + struct JSharedCallbackStruct final : public jni::JavaClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/test/external/SharedCallbackStruct;"; + + static jni::local_ref create(jdouble value, jni::alias_ref onChanged) { + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod)>("fromCpp"); + return create(clazz, value, onChanged); + } + + jdouble getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + + jni::local_ref getOnChanged() const { + static const auto method = javaClassStatic()->getMethod("getOnChanged_cxx"); + return method(this->self()); + } + }; + +} // namespace margelo::nitro::test::external + +namespace margelo::nitro { + + namespace jni = facebook::jni; + namespace jsi = facebook::jsi; + + template <> + struct JSIConverter> { + static jni::local_ref fromJSI(jsi::Runtime& runtime, const jsi::Value& value); + static jsi::Value toJSI(jsi::Runtime& runtime, jni::alias_ref value); + static bool canConvert(jsi::Runtime& runtime, const jsi::Value& value); + }; + +} // namespace margelo::nitro diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSharedSpecializationsSpec.kt b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSharedSpecializationsSpec.kt index 08b88a5459..50119ef2a8 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSharedSpecializationsSpec.kt +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSharedSpecializationsSpec.kt @@ -124,6 +124,10 @@ abstract class HybridSharedSpecializationsSpec: HybridObject() { return __result } + @DoNotStrip + @Keep + abstract fun bounceCallbackStruct(value: SharedCallbackStruct): SharedCallbackStruct + abstract fun callInline(callback: Callback<() -> Unit>): Unit @DoNotStrip diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/SharedCallbackStruct.kt b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/SharedCallbackStruct.kt new file mode 100644 index 0000000000..c29b0a0edc --- /dev/null +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/SharedCallbackStruct.kt @@ -0,0 +1,61 @@ +/// +/// SharedCallbackStruct.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.external + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects +import com.margelo.nitro.core.Callback + +/** + * Represents the JavaScript object/struct "SharedCallbackStruct". + */ +@DoNotStrip +@Keep +data class SharedCallbackStruct( + @DoNotStrip + @Keep + val value: Double, + @DoNotStrip + @Keep + val onChanged: Callback<(value: Double) -> Unit> +) { + @DoNotStrip + @Keep + @Suppress("unused", "FunctionName") + private fun getOnChanged_cxx(): Callback_void_double { + return Callback_void_double.fromKotlin(onChanged) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is SharedCallbackStruct) return false + return Objects.deepEquals(this.value, other.value) + && Objects.deepEquals(this.onChanged, other.onChanged) + } + + override fun hashCode(): Int { + return arrayOf( + value, + onChanged + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(value: Double, onChanged: Callback_void_double): SharedCallbackStruct { + return SharedCallbackStruct(value, onChanged) + } + } +} diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/NitroTestExternalAppleCxx/include/NitroTestExternalAppleCxx/NitroTestExternalAppleCxx.h b/tests/standalone/nitro-test-external/nitrogen/generated/apple/NitroTestExternalAppleCxx/include/NitroTestExternalAppleCxx/NitroTestExternalAppleCxx.h index 1b4a25eb61..ae88052219 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/apple/NitroTestExternalAppleCxx/include/NitroTestExternalAppleCxx/NitroTestExternalAppleCxx.h +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/NitroTestExternalAppleCxx/include/NitroTestExternalAppleCxx/NitroTestExternalAppleCxx.h @@ -21,6 +21,8 @@ namespace NitroTestExternal { class Size; } // Forward declaration of `HybridSharedSpecializationsSpec_cxx` to properly resolve imports. namespace NitroTestExternal { class HybridSharedSpecializationsSpec_cxx; } namespace swift { class String; } +// Forward declaration of `SharedCallbackStruct` to properly resolve imports. +namespace NitroTestExternal { class SharedCallbackStruct; } #include #ifndef SWIFT_SWIFT_H namespace swift { template class Optional; } diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/HybridSharedSpecializationsCppSpecClass.cpp b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/HybridSharedSpecializationsCppSpecClass.cpp index e4ef6e30b6..fb8de08ea5 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/HybridSharedSpecializationsCppSpecClass.cpp +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/HybridSharedSpecializationsCppSpecClass.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include "HybridSharedSpecializationsCpp.hpp" @@ -43,6 +44,7 @@ namespace margelo::nitro::test::external { clazz.registerHybridMethod("wrapNumberCallback", &HybridSharedSpecializationsCppSpec::wrapNumberCallback); clazz.registerHybridMethod("callVoidPromiseCallback", &HybridSharedSpecializationsCppSpec::callVoidPromiseCallback); clazz.registerHybridMethod("callNumberPromiseCallback", &HybridSharedSpecializationsCppSpec::callNumberPromiseCallback); + clazz.registerHybridMethod("bounceCallbackStruct", &HybridSharedSpecializationsCppSpec::bounceCallbackStruct); clazz.registerHybridMethod("callInline", &HybridSharedSpecializationsCppSpec::callInline); clazz.registerHybridMethod("callInlineWithNumber", &HybridSharedSpecializationsCppSpec::callInlineWithNumber); clazz.registerHybridConstructor(&HybridSharedSpecializationsCppSpecBindings::constructor); diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/HybridSharedSpecializationsSpecSwift.cpp b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/HybridSharedSpecializationsSpecSwift.cpp index 59294dec79..f6afb2cc93 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/HybridSharedSpecializationsSpecSwift.cpp +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/HybridSharedSpecializationsSpecSwift.cpp @@ -161,6 +161,16 @@ namespace margelo::nitro::test::external { return std::move(__result.value()); } + ::NitroTestExternal::SharedCallbackStruct HybridSharedSpecializationsSpecSwift::bounceCallbackStruct(const ::NitroTestExternal::SharedCallbackStruct& value) { + auto __result = withSwiftResult<::NitroTestExternal::SharedCallbackStruct>([&](void* __outResult) { + return _swiftPart.bounceCallbackStruct(value, __outResult); + }); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + return std::move(__result.value()); + } + void HybridSharedSpecializationsSpecSwift::callInline(const InlineCallback& callback) { auto __result = _swiftPart.callInline(callback); if (__result.hasError()) [[unlikely]] { @@ -201,6 +211,7 @@ namespace margelo::nitro::test::external { clazz.registerHybridMethod("wrapNumberCallback", &HybridSharedSpecializationsSpecSwift::wrapNumberCallback); clazz.registerHybridMethod("callVoidPromiseCallback", &HybridSharedSpecializationsSpecSwift::callVoidPromiseCallback); clazz.registerHybridMethod("callNumberPromiseCallback", &HybridSharedSpecializationsSpecSwift::callNumberPromiseCallback); + clazz.registerHybridMethod("bounceCallbackStruct", &HybridSharedSpecializationsSpecSwift::bounceCallbackStruct); clazz.registerHybridMethod("callInline", &HybridSharedSpecializationsSpecSwift::callInline); clazz.registerHybridMethod("callInlineWithNumber", &HybridSharedSpecializationsSpecSwift::callInlineWithNumber); clazz.registerHybridConstructor(&HybridSharedSpecializationsSpecSwift::constructor); diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/SharedCallbackStruct-Swift.cpp b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/SharedCallbackStruct-Swift.cpp new file mode 100644 index 0000000000..4a3f458dad --- /dev/null +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/SharedCallbackStruct-Swift.cpp @@ -0,0 +1,33 @@ +/// +/// SharedCallbackStruct-Swift.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/margelo/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include +#include +#include + +namespace margelo::nitro { + + ::NitroTestExternal::SharedCallbackStruct JSIConverter<::NitroTestExternal::SharedCallbackStruct>::fromJSI(jsi::Runtime& runtime, const jsi::Value& value) { + auto object = value.asObject(runtime); + return ::NitroTestExternal::SharedCallbackStruct::init_cxx(JSIConverter::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "value"))), JSIConverter>::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "onChanged")))); + } + + jsi::Value JSIConverter<::NitroTestExternal::SharedCallbackStruct>::toJSI(jsi::Runtime& runtime, const ::NitroTestExternal::SharedCallbackStruct& value) { + jsi::Object object(runtime); + object.setProperty(runtime, PropNameIDCache::get(runtime, "value"), JSIConverter::toJSI(runtime, value.getValue_cxx())); + object.setProperty(runtime, PropNameIDCache::get(runtime, "onChanged"), JSIConverter>::toJSI(runtime, value.getOnChanged_cxx())); + return object; + } + + bool JSIConverter<::NitroTestExternal::SharedCallbackStruct>::canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) return false; + auto object = value.getObject(runtime); + if (!isPlainObject(runtime, object)) return false; + return JSIConverter::canConvert(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "value"))) && JSIConverter>::canConvert(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "onChanged"))); + } + +} // namespace margelo::nitro diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/HybridSharedSpecializationsSpecSwift.hpp b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/HybridSharedSpecializationsSpecSwift.hpp index caf75804c1..91262fb48d 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/HybridSharedSpecializationsSpecSwift.hpp +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/HybridSharedSpecializationsSpecSwift.hpp @@ -71,6 +71,7 @@ namespace margelo::nitro::test::external { Callback wrapNumberCallback(const Callback& callback); Promise callVoidPromiseCallback(const Callback()>& callback); Promise callNumberPromiseCallback(const Callback()>& callback); + ::NitroTestExternal::SharedCallbackStruct bounceCallbackStruct(const ::NitroTestExternal::SharedCallbackStruct& value); void callInline(const InlineCallback& callback); double callInlineWithNumber(double value, const InlineCallback& callback); // Constructor diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/NitroTestExternal-Swift-Cxx-Umbrella.hpp b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/NitroTestExternal-Swift-Cxx-Umbrella.hpp index 36c7e462f5..231b643370 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/NitroTestExternal-Swift-Cxx-Umbrella.hpp +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/NitroTestExternal-Swift-Cxx-Umbrella.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/SharedCallbackStruct-Swift.hpp b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/SharedCallbackStruct-Swift.hpp new file mode 100644 index 0000000000..30dab94241 --- /dev/null +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/c++/include/NitroTestExternal/private/SharedCallbackStruct-Swift.hpp @@ -0,0 +1,23 @@ +/// +/// SharedCallbackStruct-Swift.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/margelo/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +// Forward declaration of `SharedCallbackStruct` to properly resolve imports. +namespace NitroTestExternal { class SharedCallbackStruct; } + +namespace margelo::nitro { + + template <> + struct JSIConverter<::NitroTestExternal::SharedCallbackStruct> { + static ::NitroTestExternal::SharedCallbackStruct fromJSI(jsi::Runtime& runtime, const jsi::Value& value); + static jsi::Value toJSI(jsi::Runtime& runtime, const ::NitroTestExternal::SharedCallbackStruct& value); + static bool canConvert(jsi::Runtime& runtime, const jsi::Value& value); + }; + +} // namespace margelo::nitro diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/HybridSharedSpecializationsSpec.swift b/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/HybridSharedSpecializationsSpec.swift index 7835ce9481..c5ef1d5bd6 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/HybridSharedSpecializationsSpec.swift +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/HybridSharedSpecializationsSpec.swift @@ -28,6 +28,7 @@ public protocol HybridSharedSpecializationsSpec_protocol: HybridSharedSpecializa func wrapNumberCallback(callback: any Callback<(/* value */ Double), Void>) throws -> any Callback<(/* value */ Double), Void> func callVoidPromiseCallback(callback: any Callback<(), any Promise>) throws -> any Promise func callNumberPromiseCallback(callback: any Callback<(), any Promise>) throws -> any Promise + func bounceCallbackStruct(value: SharedCallbackStruct) throws -> SharedCallbackStruct func callInline(callback: borrowing some InlineCallback<(), Void> & ~Copyable & ~Escapable) throws -> Void func callInlineWithNumber(value: Double, callback: borrowing some InlineCallback<(/* value */ Double), Double> & ~Copyable & ~Escapable) throws -> Double diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/HybridSharedSpecializationsSpec_cxx.swift b/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/HybridSharedSpecializationsSpec_cxx.swift index 572873165b..e351b0adaa 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/HybridSharedSpecializationsSpec_cxx.swift +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/HybridSharedSpecializationsSpec_cxx.swift @@ -255,6 +255,16 @@ public final class HybridSharedSpecializationsSpec_cxx { } } + public final func bounceCallbackStruct(value: SharedCallbackStruct, __outResult: UnsafeMutableRawPointer) -> bridge.Result_void { + do { + let value = try __implementation.bounceCallbackStruct(value: value) + __outResult.assumingMemoryBound(to: SharedCallbackStruct.self).initialize(to: value) + return bridge.Result_void.withValue() + } catch { + return bridge.Result_void.withError(error.toCpp()) + } + } + public final func callInline(callback: borrowing margelo.nitro.test.external.swift_bridge.InlineCallback_void) -> bridge.Result_void { do { try __implementation.callInline(callback: callback) diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/SharedCallbackStruct.swift b/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/SharedCallbackStruct.swift new file mode 100644 index 0000000000..e3cd46ac8b --- /dev/null +++ b/tests/standalone/nitro-test-external/nitrogen/generated/apple/swift/SharedCallbackStruct.swift @@ -0,0 +1,36 @@ +/// +/// SharedCallbackStruct.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 NitroTestExternalAppleCxx +internal import CxxStdlib + +@_expose(Cxx) +public struct SharedCallbackStruct: Sendable { + public let value: Double + public let onChanged: any Callback<(/* value */ Double), Void> + + public init(value: Double, onChanged: any Callback<(/* value */ Double), Void>) { + self.value = value + self.onChanged = onChanged + } + + @_spi(NitroCxx) + public static func init_cxx(_ value: Double, _ onChanged: margelo.nitro.test.external.swift_bridge.Callback_void_double) -> Self { + return Self(value: value, onChanged: onChanged) + } + + @_spi(NitroCxx) + public borrowing func getValue_cxx() -> Double { + return self.value + } + + @_spi(NitroCxx) + public borrowing func getOnChanged_cxx() -> margelo.nitro.test.external.swift_bridge.Callback_void_double { + return self.onChanged.toCpp() + } +} diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/SharedCallbackStruct.cpp b/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/SharedCallbackStruct.cpp new file mode 100644 index 0000000000..19c0bc490d --- /dev/null +++ b/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/SharedCallbackStruct.cpp @@ -0,0 +1,44 @@ +/// +/// SharedCallbackStruct.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 + +namespace margelo::nitro { + + margelo::nitro::test::external::SharedCallbackStruct JSIConverter::fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::test::external::SharedCallbackStruct( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "value"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "onChanged"))) + ); + } + + jsi::Value JSIConverter::toJSI(jsi::Runtime& runtime, const margelo::nitro::test::external::SharedCallbackStruct& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "value"), JSIConverter::toJSI(runtime, arg.value)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "onChanged"), JSIConverter>::toJSI(runtime, arg.onChanged)); + return obj; + } + + bool JSIConverter::canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "value")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "onChanged")))) return false; + return true; + } + +} // namespace margelo::nitro diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/include/NitroTestExternal/HybridSharedSpecializationsCppSpec.hpp b/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/include/NitroTestExternal/HybridSharedSpecializationsCppSpec.hpp index 4daf49968c..54f1ef123b 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/include/NitroTestExternal/HybridSharedSpecializationsCppSpec.hpp +++ b/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/include/NitroTestExternal/HybridSharedSpecializationsCppSpec.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace margelo::nitro::test::external { @@ -65,6 +66,7 @@ namespace margelo::nitro::test::external { virtual Callback wrapNumberCallback(const Callback& callback) = 0; virtual Promise callVoidPromiseCallback(const Callback()>& callback) = 0; virtual Promise callNumberPromiseCallback(const Callback()>& callback) = 0; + virtual SharedCallbackStruct bounceCallbackStruct(const SharedCallbackStruct& value) = 0; virtual void callInline(const InlineCallback& callback) = 0; virtual double callInlineWithNumber(double value, const InlineCallback& callback) = 0; diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/include/NitroTestExternal/SharedCallbackStruct.hpp b/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/include/NitroTestExternal/SharedCallbackStruct.hpp new file mode 100644 index 0000000000..0c03ea6819 --- /dev/null +++ b/tests/standalone/nitro-test-external/nitrogen/generated/shared/c++/include/NitroTestExternal/SharedCallbackStruct.hpp @@ -0,0 +1,45 @@ +/// +/// SharedCallbackStruct.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 + +namespace margelo::nitro::test::external { + + /** + * A struct which can be represented as a JavaScript object (SharedCallbackStruct). + */ + struct SharedCallbackStruct final { + public: + double value SWIFT_PRIVATE; + Callback onChanged SWIFT_PRIVATE; + + public: + explicit SharedCallbackStruct(double value, Callback onChanged): value(value), onChanged(std::move(onChanged)) {} + + public: + // SharedCallbackStruct is not equatable because these properties are not equatable: onChanged + }; + +} // namespace margelo::nitro::test::external + +namespace margelo::nitro { + + // C++ SharedCallbackStruct <> JS SharedCallbackStruct (object) + template <> + struct JSIConverter final { + static margelo::nitro::test::external::SharedCallbackStruct fromJSI(jsi::Runtime& runtime, const jsi::Value& arg); + static jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::test::external::SharedCallbackStruct& arg); + static bool canConvert(jsi::Runtime& runtime, const jsi::Value& value); + }; + +} // namespace margelo::nitro diff --git a/tests/standalone/nitro-test-external/specs/SharedSpecializations.nitro.ts b/tests/standalone/nitro-test-external/specs/SharedSpecializations.nitro.ts index 32fb8e15f6..5595c1f98b 100644 --- a/tests/standalone/nitro-test-external/specs/SharedSpecializations.nitro.ts +++ b/tests/standalone/nitro-test-external/specs/SharedSpecializations.nitro.ts @@ -4,6 +4,12 @@ import type { HybridObject, Inline } from 'nitro-core' export * from '#nitro/SharedSpecializationsCpp' export * from '#nitro/SharedSpecializations' +// Matches nitro-test's JsStyleStruct callback signature in a separate Swift module. +export interface SharedCallbackStruct { + value: number + onChanged: (value: number) => void +} + /** * Uses the same Promise and Callback specializations as `nitro-test`, such as * `Promise` and `(value: number) => void`. Both generated modules then @@ -45,6 +51,7 @@ export declare class SharedSpecializationsCpp extends HybridObject { callVoidPromiseCallback(callback: () => Promise): Promise callNumberPromiseCallback(callback: () => Promise): Promise numberCallback: (value: number) => void + bounceCallbackStruct(value: SharedCallbackStruct): SharedCallbackStruct // Inline callbacks callInline(callback: Inline<() => void>): void @@ -78,6 +85,7 @@ export declare class SharedSpecializations extends HybridObject { callVoidPromiseCallback(callback: () => Promise): Promise callNumberPromiseCallback(callback: () => Promise): Promise numberCallback: (value: number) => void + bounceCallbackStruct(value: SharedCallbackStruct): SharedCallbackStruct // Inline callbacks callInline(callback: Inline<() => void>): void diff --git a/tests/standalone/test-runner/js/interop.test.ts b/tests/standalone/test-runner/js/interop.test.ts index 815e3742d8..c2ccb7dbda 100644 --- a/tests/standalone/test-runner/js/interop.test.ts +++ b/tests/standalone/test-runner/js/interop.test.ts @@ -668,6 +668,21 @@ export const cases = { await waitFor(() => expect(callback.calls).to.deep.equal([[5]]), CALLBACK_TIMEOUT) }, + 'callback fields roundtrip through both modules': async (external, local) => { + const callback = recordCallback<(value: number) => void>() + const returned = (() => { + const onChanged = external.wrapNumberCallback(callback) + const externalStruct = external.bounceCallbackStruct({ value: 55, onChanged: onChanged }) + const localStruct = local.bounceWrappedJsStyleStruct({ value: externalStruct, items: [] }) + return localStruct.value + })() + gc() + expect(returned.value).to.equal(55) + returned.onChanged(7) + local.jsStyleObjectAsParameters(returned) + await waitFor(() => expect(callback.calls).to.deep.equal([[7], [55]]), CALLBACK_TIMEOUT) + }, + 'both modules call inline callbacks': (external, local) => { let calls = 0 external.callInline(() => {