diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 58ba6815c..70e306b21 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -29,7 +29,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - NitroModules (0.8.0): + - NitroModules (0.9.1): - DoubleConversion - glog - hermes-engine @@ -1828,7 +1828,7 @@ SPEC CHECKSUMS: glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f hermes-engine: 3b6e0717ca847e2fc90a201e59db36caf04dee88 NitroImage: 0cffeee137c14b8c8df97649626646528cb89b28 - NitroModules: 7184d6a9527f2d015c7e4865ee6615b3e26d9cfb + NitroModules: a3e3619f2c74dd9a706d3597d7c359d56e94ef22 RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47 RCTDeprecation: 34cbf122b623037ea9facad2e92e53434c5c7422 RCTRequired: 24c446d7bcd0f517d516b6265d8df04dc3eb1219 diff --git a/example/src/getTests.ts b/example/src/getTests.ts index 3ced7c15e..8e5c59724 100644 --- a/example/src/getTests.ts +++ b/example/src/getTests.ts @@ -307,6 +307,16 @@ export function getTests( .didNotThrow() .equals('passed') ), + createTest('tryOptionalEnum(...)', () => + it(() => testObject.tryOptionalEnum('gas')) + .didNotThrow() + .equals('gas') + ), + createTest('tryOptionalEnum(...)', () => + it(() => testObject.tryOptionalEnum(undefined)) + .didNotThrow() + .equals(undefined) + ), // Variants tests ...('someVariant' in testObject diff --git a/packages/nitrogen/src/syntax/createType.ts b/packages/nitrogen/src/syntax/createType.ts index c8ee25b55..e41c69257 100644 --- a/packages/nitrogen/src/syntax/createType.ts +++ b/packages/nitrogen/src/syntax/createType.ts @@ -265,7 +265,9 @@ export function createType(type: TSMorphType, isOptional: boolean): Type { `Anonymous objects cannot be represented in C++! Extract "${type.getText()}" to a separate interface/type declaration.` ) } else if (type.isStringLiteral()) { - return new StringType() + throw new Error( + `String literal ${type.getText()} cannot be represented in C++ because it is ambiguous between a string and a discriminating union enum.` + ) } else { throw new Error( `The TypeScript type "${type.getText()}" cannot be represented in C++!` diff --git a/packages/nitrogen/src/syntax/swift/SwiftCxxBridgedType.ts b/packages/nitrogen/src/syntax/swift/SwiftCxxBridgedType.ts index 35766a5e7..7449a68d0 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftCxxBridgedType.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftCxxBridgedType.ts @@ -52,6 +52,10 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> { case 'enum': // Enums cannot be referenced from C++ <-> Swift bi-directionally, // so we just pass the underlying raw value (int32), and cast from Int <-> Enum. + if (this.isBridgingToDirectCppTarget) { + // ...unless we bridge directly to a C++ target. Then we don't need special conversion. + return false + } return true case 'hybrid-object': // Swift HybridObjects need to be wrapped in our own *Cxx Swift classes. @@ -83,6 +87,9 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> { return true case 'array-buffer': // ArrayBufferHolder <> std::shared_ptr + if (this.isBridgingToDirectCppTarget) { + return false + } return true case 'promise': // PromiseHolder <> std::shared_ptr> @@ -348,9 +355,12 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> { } case 'optional': { const optional = getTypeAs(this.type, OptionalType) - const wrapping = new SwiftCxxBridgedType(optional.wrappingType) + const wrapping = new SwiftCxxBridgedType(optional.wrappingType, true) switch (language) { case 'swift': + if (!wrapping.needsSpecialHandling) { + return `${cppParameterName}.value` + } return ` { () -> ${optional.getCode('swift')} in if let actualValue = ${cppParameterName}.value { @@ -525,7 +535,7 @@ case ${i}: } case 'optional': { const optional = getTypeAs(this.type, OptionalType) - const wrapping = new SwiftCxxBridgedType(optional.wrappingType) + const wrapping = new SwiftCxxBridgedType(optional.wrappingType, true) const bridge = this.getBridgeOrThrow() const makeFunc = `bridge.${bridge.funcName}` switch (language) { diff --git a/packages/react-native-nitro-image/android/src/main/java/com/margelo/nitro/image/HybridTestObjectKotlin.kt b/packages/react-native-nitro-image/android/src/main/java/com/margelo/nitro/image/HybridTestObjectKotlin.kt index 230db4272..530aea225 100644 --- a/packages/react-native-nitro-image/android/src/main/java/com/margelo/nitro/image/HybridTestObjectKotlin.kt +++ b/packages/react-native-nitro-image/android/src/main/java/com/margelo/nitro/image/HybridTestObjectKotlin.kt @@ -71,6 +71,11 @@ class HybridTestObjectKotlin: HybridTestObjectSwiftKotlinSpec() { return str } + + override fun tryOptionalEnum(value: Powertrain?): Powertrain? { + return value + } + override fun calculateFibonacciSync(value: Double): Long { val n = value.toInt() if (n == 0) return 0L diff --git a/packages/react-native-nitro-image/cpp/HybridTestObjectCpp.cpp b/packages/react-native-nitro-image/cpp/HybridTestObjectCpp.cpp index f4edad826..16228e419 100644 --- a/packages/react-native-nitro-image/cpp/HybridTestObjectCpp.cpp +++ b/packages/react-native-nitro-image/cpp/HybridTestObjectCpp.cpp @@ -145,6 +145,10 @@ std::string HybridTestObjectCpp::tryMiddleParam(double num, std::optional return str; } +std::optional HybridTestObjectCpp::tryOptionalEnum(std::optional value) { + return value; +} + std::variant HybridTestObjectCpp::passVariant(const std::variant, std::vector>& either) { if (std::holds_alternative(either)) { diff --git a/packages/react-native-nitro-image/cpp/HybridTestObjectCpp.hpp b/packages/react-native-nitro-image/cpp/HybridTestObjectCpp.hpp index 4ef9f7ef7..ef8a3cf97 100644 --- a/packages/react-native-nitro-image/cpp/HybridTestObjectCpp.hpp +++ b/packages/react-native-nitro-image/cpp/HybridTestObjectCpp.hpp @@ -70,6 +70,7 @@ class HybridTestObjectCpp : public HybridTestObjectCppSpec { double funcThatThrows() override; std::string tryOptionalParams(double num, bool boo, const std::optional& str) override; std::string tryMiddleParam(double num, std::optional boo, const std::string& str) override; + std::optional tryOptionalEnum(std::optional value) override; std::variant passVariant(const std::variant, std::vector>& either) override; diff --git a/packages/react-native-nitro-image/ios/HybridTestObjectSwiftKotlin.swift b/packages/react-native-nitro-image/ios/HybridTestObjectSwift.swift similarity index 97% rename from packages/react-native-nitro-image/ios/HybridTestObjectSwiftKotlin.swift rename to packages/react-native-nitro-image/ios/HybridTestObjectSwift.swift index a227864fc..19791bc61 100644 --- a/packages/react-native-nitro-image/ios/HybridTestObjectSwiftKotlin.swift +++ b/packages/react-native-nitro-image/ios/HybridTestObjectSwift.swift @@ -100,6 +100,10 @@ class HybridTestObjectSwift : HybridTestObjectSwiftKotlinSpec { return str } + func tryOptionalEnum(value: Powertrain?) throws -> Powertrain? { + return value + } + func calculateFibonacciSync(value: Double) throws -> Int64 { let n = Int64(value) if n <= 1 { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp index c7f2a3444..e8954c659 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp @@ -11,10 +11,10 @@ namespace margelo::nitro::image { class HybridTestObjectSwiftKotlinSpec; } // Forward declaration of `AnyMap` to properly resolve imports. namespace NitroModules { class AnyMap; } -// Forward declaration of `Car` to properly resolve imports. -namespace margelo::nitro::image { struct Car; } // Forward declaration of `Powertrain` to properly resolve imports. namespace margelo::nitro::image { enum class Powertrain; } +// Forward declaration of `Car` to properly resolve imports. +namespace margelo::nitro::image { struct Car; } // Forward declaration of `Person` to properly resolve imports. namespace margelo::nitro::image { struct Person; } // Forward declaration of `ArrayBuffer` to properly resolve imports. @@ -28,12 +28,12 @@ namespace NitroModules { class ArrayBuffer; } #include #include #include +#include "Powertrain.hpp" +#include "JPowertrain.hpp" #include #include #include "Car.hpp" #include "JCar.hpp" -#include "Powertrain.hpp" -#include "JPowertrain.hpp" #include "Person.hpp" #include "JPerson.hpp" #include @@ -172,6 +172,11 @@ namespace margelo::nitro::image { auto result = method(_javaPart, num, boo.has_value() ? jni::JBoolean::valueOf(boo.value()) : nullptr, jni::make_jstring(str)); return result->toStdString(); } + std::optional JHybridTestObjectSwiftKotlinSpec::tryOptionalEnum(std::optional value) { + static const auto method = _javaPart->getClass()->getMethod(jni::alias_ref /* value */)>("tryOptionalEnum"); + auto result = method(_javaPart, value.has_value() ? JPowertrain::fromCpp(value.value()) : nullptr); + return result != nullptr ? std::make_optional(result->toCpp()) : std::nullopt; + } int64_t JHybridTestObjectSwiftKotlinSpec::calculateFibonacciSync(double value) { static const auto method = _javaPart->getClass()->getMethod("calculateFibonacciSync"); auto result = method(_javaPart, value); diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp index 6d1ff47f5..bb6a7744c 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp @@ -65,6 +65,7 @@ namespace margelo::nitro::image { double funcThatThrows() override; std::string tryOptionalParams(double num, bool boo, const std::optional& str) override; std::string tryMiddleParam(double num, std::optional boo, const std::string& str) override; + std::optional tryOptionalEnum(std::optional value) override; int64_t calculateFibonacciSync(double value) override; std::future calculateFibonacciAsync(double value) override; std::future wait(double seconds) override; diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt index de68a3a28..5e5e4f3cc 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt @@ -116,6 +116,10 @@ abstract class HybridTestObjectSwiftKotlinSpec: HybridObject() { @Keep abstract fun tryMiddleParam(num: Double, boo: Boolean?, str: String): String + @DoNotStrip + @Keep + abstract fun tryOptionalEnum(value: Powertrain?): Powertrain? + @DoNotStrip @Keep abstract fun calculateFibonacciSync(value: Double): Long diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.hpp b/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.hpp index 663d80c85..7c1aacd80 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.hpp @@ -143,6 +143,14 @@ namespace margelo::nitro::image::bridge::swift { return std::optional(value); } + /** + * Specialized version of `std::optional`. + */ + using std__optional_Powertrain_ = std::optional; + inline std::optional create_std__optional_Powertrain_(const Powertrain& value) { + return std::optional(value); + } + /** * Specialized version of `std::vector`. */ diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/c++/HybridTestObjectSwiftKotlinSpecSwift.hpp b/packages/react-native-nitro-image/nitrogen/generated/ios/c++/HybridTestObjectSwiftKotlinSpecSwift.hpp index 417e2c34d..d4b5c07da 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/c++/HybridTestObjectSwiftKotlinSpecSwift.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/c++/HybridTestObjectSwiftKotlinSpecSwift.hpp @@ -18,10 +18,10 @@ namespace margelo::nitro::image { class HybridTestObjectSwiftKotlinSpec; } namespace margelo::nitro::image { class HybridTestObjectSwiftKotlinSpecSwift; } // Forward declaration of `AnyMap` to properly resolve imports. namespace NitroModules { class AnyMap; } -// Forward declaration of `Car` to properly resolve imports. -namespace margelo::nitro::image { struct Car; } // Forward declaration of `Powertrain` to properly resolve imports. namespace margelo::nitro::image { enum class Powertrain; } +// Forward declaration of `Car` to properly resolve imports. +namespace margelo::nitro::image { struct Car; } // Forward declaration of `Person` to properly resolve imports. namespace margelo::nitro::image { struct Person; } // Forward declaration of `ArrayBuffer` to properly resolve imports. @@ -35,11 +35,11 @@ namespace NitroModules { class ArrayBufferHolder; } #include "HybridTestObjectSwiftKotlinSpec.hpp" #include "HybridTestObjectSwiftKotlinSpecSwift.hpp" #include +#include "Powertrain.hpp" #include #include #include #include "Car.hpp" -#include "Powertrain.hpp" #include "Person.hpp" #include #include @@ -170,6 +170,10 @@ namespace margelo::nitro::image { auto __result = _swiftPart.tryMiddleParam(std::forward(num), boo, str); return __result; } + inline std::optional tryOptionalEnum(std::optional value) override { + auto __result = _swiftPart.tryOptionalEnum(value); + return __result; + } inline int64_t calculateFibonacciSync(double value) override { auto __result = _swiftPart.calculateFibonacciSync(std::forward(value)); return __result; diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift index ce200b782..8ef74098c 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift @@ -48,6 +48,7 @@ public protocol HybridTestObjectSwiftKotlinSpec: HybridObjectSpec { func funcThatThrows() throws -> Double func tryOptionalParams(num: Double, boo: Bool, str: String?) throws -> String func tryMiddleParam(num: Double, boo: Bool?, str: String) throws -> String + func tryOptionalEnum(value: Powertrain?) throws -> Powertrain? func calculateFibonacciSync(value: Double) throws -> Int64 func calculateFibonacciAsync(value: Double) throws -> Promise func wait(seconds: Double) throws -> Promise diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpecCxx.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpecCxx.swift index eeec6238f..c5ad1503c 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpecCxx.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpecCxx.swift @@ -277,14 +277,25 @@ public final class HybridTestObjectSwiftKotlinSpecCxx { @inline(__always) public func tryMiddleParam(num: Double, boo: bridge.std__optional_bool_, str: std.string) -> std.string { do { - let result = try self.implementation.tryMiddleParam(num: num, boo: { () -> Bool? in - if let actualValue = boo.value { - return actualValue + let result = try self.implementation.tryMiddleParam(num: num, boo: boo.value, str: String(str)) + return std.string(result) + } catch { + let message = "\(error.localizedDescription)" + fatalError("Swift errors can currently not be propagated to C++! See https://github.com/swiftlang/swift/issues/75290 (Error: \(message))") + } + } + + @inline(__always) + public func tryOptionalEnum(value: bridge.std__optional_Powertrain_) -> bridge.std__optional_Powertrain_ { + do { + let result = try self.implementation.tryOptionalEnum(value: value.value) + return { () -> bridge.std__optional_Powertrain_ in + if let actualValue = result { + return bridge.create_std__optional_Powertrain_(actualValue) } else { - return nil + return .init() } - }(), str: String(str)) - return std.string(result) + }() } catch { let message = "\(error.localizedDescription)" fatalError("Swift errors can currently not be propagated to C++! See https://github.com/swiftlang/swift/issues/75290 (Error: \(message))") diff --git a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.cpp index a5207256b..6ab9a64c1 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.cpp @@ -42,6 +42,7 @@ namespace margelo::nitro::image { prototype.registerHybridMethod("funcThatThrows", &HybridTestObjectCppSpec::funcThatThrows); prototype.registerHybridMethod("tryOptionalParams", &HybridTestObjectCppSpec::tryOptionalParams); prototype.registerHybridMethod("tryMiddleParam", &HybridTestObjectCppSpec::tryMiddleParam); + prototype.registerHybridMethod("tryOptionalEnum", &HybridTestObjectCppSpec::tryOptionalEnum); prototype.registerHybridMethod("passVariant", &HybridTestObjectCppSpec::passVariant); prototype.registerHybridMethod("getVariantEnum", &HybridTestObjectCppSpec::getVariantEnum); prototype.registerHybridMethod("getVariantObjects", &HybridTestObjectCppSpec::getVariantObjects); diff --git a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.hpp index 9064c9b07..c3f7b9608 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectCppSpec.hpp @@ -17,6 +17,8 @@ namespace margelo::nitro::image { class HybridTestObjectCppSpec; } // Forward declaration of `AnyMap` to properly resolve imports. namespace NitroModules { class AnyMap; } +// Forward declaration of `Powertrain` to properly resolve imports. +namespace margelo::nitro::image { enum class Powertrain; } // Forward declaration of `OldEnum` to properly resolve imports. namespace margelo::nitro::image { enum class OldEnum; } // Forward declaration of `Person` to properly resolve imports. @@ -33,6 +35,7 @@ namespace NitroModules { class ArrayBuffer; } #include #include "HybridTestObjectCppSpec.hpp" #include +#include "Powertrain.hpp" #include #include "OldEnum.hpp" #include "Person.hpp" @@ -96,6 +99,7 @@ namespace margelo::nitro::image { virtual double funcThatThrows() = 0; virtual std::string tryOptionalParams(double num, bool boo, const std::optional& str) = 0; virtual std::string tryMiddleParam(double num, std::optional boo, const std::string& str) = 0; + virtual std::optional tryOptionalEnum(std::optional value) = 0; virtual std::variant passVariant(const std::variant, std::vector>& either) = 0; virtual std::variant getVariantEnum(const std::variant& variant) = 0; virtual std::variant getVariantObjects(const std::variant& variant) = 0; diff --git a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.cpp index 2e13653b4..ea402ef8f 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.cpp @@ -38,6 +38,7 @@ namespace margelo::nitro::image { prototype.registerHybridMethod("funcThatThrows", &HybridTestObjectSwiftKotlinSpec::funcThatThrows); prototype.registerHybridMethod("tryOptionalParams", &HybridTestObjectSwiftKotlinSpec::tryOptionalParams); prototype.registerHybridMethod("tryMiddleParam", &HybridTestObjectSwiftKotlinSpec::tryMiddleParam); + prototype.registerHybridMethod("tryOptionalEnum", &HybridTestObjectSwiftKotlinSpec::tryOptionalEnum); prototype.registerHybridMethod("calculateFibonacciSync", &HybridTestObjectSwiftKotlinSpec::calculateFibonacciSync); prototype.registerHybridMethod("calculateFibonacciAsync", &HybridTestObjectSwiftKotlinSpec::calculateFibonacciAsync); prototype.registerHybridMethod("wait", &HybridTestObjectSwiftKotlinSpec::wait); diff --git a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.hpp index b85ade6b0..4be42221f 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/shared/c++/HybridTestObjectSwiftKotlinSpec.hpp @@ -17,6 +17,8 @@ namespace margelo::nitro::image { class HybridTestObjectSwiftKotlinSpec; } // Forward declaration of `AnyMap` to properly resolve imports. namespace NitroModules { class AnyMap; } +// Forward declaration of `Powertrain` to properly resolve imports. +namespace margelo::nitro::image { enum class Powertrain; } // Forward declaration of `Car` to properly resolve imports. namespace margelo::nitro::image { struct Car; } // Forward declaration of `Person` to properly resolve imports. @@ -29,6 +31,7 @@ namespace NitroModules { class ArrayBuffer; } #include #include "HybridTestObjectSwiftKotlinSpec.hpp" #include +#include "Powertrain.hpp" #include #include #include "Car.hpp" @@ -86,6 +89,7 @@ namespace margelo::nitro::image { virtual double funcThatThrows() = 0; virtual std::string tryOptionalParams(double num, bool boo, const std::optional& str) = 0; virtual std::string tryMiddleParam(double num, std::optional boo, const std::string& str) = 0; + virtual std::optional tryOptionalEnum(std::optional value) = 0; virtual int64_t calculateFibonacciSync(double value) = 0; virtual std::future calculateFibonacciAsync(double value) = 0; virtual std::future wait(double seconds) = 0; diff --git a/packages/react-native-nitro-image/src/specs/TestObject.nitro.ts b/packages/react-native-nitro-image/src/specs/TestObject.nitro.ts index faf108924..323584953 100644 --- a/packages/react-native-nitro-image/src/specs/TestObject.nitro.ts +++ b/packages/react-native-nitro-image/src/specs/TestObject.nitro.ts @@ -52,6 +52,7 @@ export interface TestObjectCpp extends HybridObject<{ ios: 'c++' }> { // Optional parameters tryOptionalParams(num: number, boo: boolean, str?: string): string tryMiddleParam(num: number, boo: boolean | undefined, str: string): string + tryOptionalEnum(value?: Powertrain): Powertrain | undefined // Variants someVariant: number | string @@ -127,6 +128,7 @@ export interface TestObjectSwiftKotlin // Optional parameters tryOptionalParams(num: number, boo: boolean, str?: string): string tryMiddleParam(num: number, boo: boolean | undefined, str: string): string + tryOptionalEnum(value?: Powertrain): Powertrain | undefined // TODO: Variants are not yet supported in Swift/Kotlin! // Variants diff --git a/packages/react-native-nitro-modules/cpp/registry/HybridObjectRegistry.cpp b/packages/react-native-nitro-modules/cpp/registry/HybridObjectRegistry.cpp index a6728f957..6dba26153 100644 --- a/packages/react-native-nitro-modules/cpp/registry/HybridObjectRegistry.cpp +++ b/packages/react-native-nitro-modules/cpp/registry/HybridObjectRegistry.cpp @@ -58,22 +58,27 @@ std::shared_ptr HybridObjectRegistry::createHybridObject(const std auto fn = map.find(hybridObjectName); if (fn == map.end()) [[unlikely]] { auto message = "Cannot create an instance of HybridObject \"" + std::string(hybridObjectName) + - "\" - " - "It has not yet been registered in the Nitro Modules HybridObjectRegistry!"; + "\" - It has not yet been registered in the Nitro Modules HybridObjectRegistry! Suggestions:\n" + "- If you use Nitrogen, make sure your `nitro.json` contains `" + + std::string(hybridObjectName) + + "` on this platform.\n" + "- If you use Nitrogen, make sure your library (*Package.java)/app (MainApplication.java) calls " + "`System.loadLibrary(\"<>\")` somewhere on app-startup.\n" + "- If you use Nitrogen, make sure your cpp-adapter.cpp calls `margelo::nitro::<>::initialize(vm)`.\n" + "- If you use Nitrogen, inspect the generated `<>OnLoad.cpp` file.\n" + "- If you don't use Nitrogen, make sure you called `HybridObjectRegistry.registerHybridObject(...)`."; throw std::runtime_error(message); } std::shared_ptr instance = fn->second(); #ifdef NITRO_DEBUG if (instance == nullptr) [[unlikely]] { - throw std::runtime_error("Failed to create HybridObject \"" + hybridObjectName + - "\" - " - "The constructor returned a nullptr!"); + throw std::runtime_error("Failed to create HybridObject \"" + hybridObjectName + "\" - The constructor returned a nullptr!"); } if (instance->getName() != hybridObjectName) [[unlikely]] { throw std::runtime_error("HybridObject's name (\"" + instance->getName() + - "\") does not match" - "the name it was registered with (\"" + + "\") " + "does not match the name it was registered with (\"" + hybridObjectName + "\")!"); } #endif diff --git a/packages/react-native-nitro-modules/src/NativeNitroModules.web.ts b/packages/react-native-nitro-modules/src/NativeNitroModules.web.ts deleted file mode 100644 index c772cb0cf..000000000 --- a/packages/react-native-nitro-modules/src/NativeNitroModules.web.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { TurboModule } from 'react-native' - -export interface Spec extends TurboModule {} - -export function getNativeNitroModules(): Spec { - throw new Error( - `Native NitroModules are not available on web! Make sure you're not calling getNativeNitroModules() in a web (.web.ts) environment.` - ) -} diff --git a/packages/react-native-nitro-modules/src/NitroModules.ts b/packages/react-native-nitro-modules/src/NitroModules.ts index 325efab86..ebae9264f 100644 --- a/packages/react-native-nitro-modules/src/NitroModules.ts +++ b/packages/react-native-nitro-modules/src/NitroModules.ts @@ -1,4 +1,4 @@ -import { getNativeNitroModules } from './NativeNitroModules' +import { getNativeNitroModules } from './NitroModulesTurboModule' import type { HybridObject } from './HybridObject' // TODO: Do we wanna support such constructors? diff --git a/packages/react-native-nitro-modules/src/NativeNitroModules.ts b/packages/react-native-nitro-modules/src/NitroModulesTurboModule.ts similarity index 70% rename from packages/react-native-nitro-modules/src/NativeNitroModules.ts rename to packages/react-native-nitro-modules/src/NitroModulesTurboModule.ts index 6fefcea99..b8a0e4f69 100644 --- a/packages/react-native-nitro-modules/src/NativeNitroModules.ts +++ b/packages/react-native-nitro-modules/src/NitroModulesTurboModule.ts @@ -3,7 +3,10 @@ import { TurboModuleRegistry } from 'react-native' import type { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes' import { ModuleNotFoundError } from './ModuleNotFoundError' -export interface Spec extends TurboModule { +// This TurboModule is *not* codegen'd. +// It's handwritten, because otherwise the app's CMakeLists wants to build it. +// Instead, we want to build it ourselves and have full control over the CMakeLists. +export interface NativeNitroSpec extends TurboModule { // Set up install(): void // Hybrid Objects stuff @@ -16,12 +19,13 @@ export interface Spec extends TurboModule { buildType: 'debug' | 'release' } -let turboModule: Spec | undefined -export function getNativeNitroModules(): Spec { +let turboModule: NativeNitroSpec | undefined +export function getNativeNitroModules(): NativeNitroSpec { if (turboModule == null) { try { // 1. Get (and initialize) the C++ TurboModule - turboModule = TurboModuleRegistry.getEnforcing('NitroModulesCxx') + turboModule = + TurboModuleRegistry.getEnforcing('NitroModulesCxx') // 2. Install Dispatcher and required bindings into the Runtime turboModule.install() diff --git a/packages/react-native-nitro-modules/src/NitroModulesTurboModule.web.ts b/packages/react-native-nitro-modules/src/NitroModulesTurboModule.web.ts new file mode 100644 index 000000000..86ca85ea1 --- /dev/null +++ b/packages/react-native-nitro-modules/src/NitroModulesTurboModule.web.ts @@ -0,0 +1,7 @@ +import { Platform } from 'react-native' + +export function getNativeNitroModules(): never { + throw new Error( + `Native NitroModules are not available on ${Platform.OS}! Make sure you're not calling getNativeNitroModules() in a ${Platform.OS} (.${Platform.OS}.ts) environment.` + ) +}