diff --git a/packages/react-native-codegen/src/CodegenSchema.d.ts b/packages/react-native-codegen/src/CodegenSchema.d.ts index 045a5b4ccaf..d16379472fa 100644 --- a/packages/react-native-codegen/src/CodegenSchema.d.ts +++ b/packages/react-native-codegen/src/CodegenSchema.d.ts @@ -295,6 +295,11 @@ export interface NativeModuleStringLiteralTypeAnnotation { readonly value: string; } +export interface NativeModuleStringLiteralUnionTypeAnnotation { + readonly type: 'StringLiteralUnionTypeAnnotation'; + readonly types: NativeModuleStringLiteralTypeAnnotation[]; +} + export interface NativeModuleNumberTypeAnnotation { readonly type: 'NumberTypeAnnotation'; } @@ -377,6 +382,7 @@ export type NativeModuleEventEmitterBaseTypeAnnotation = | NativeModuleNumberTypeAnnotation | NativeModuleStringTypeAnnotation | NativeModuleStringLiteralTypeAnnotation + | NativeModuleStringLiteralUnionTypeAnnotation | NativeModuleTypeAliasTypeAnnotation | NativeModuleGenericObjectTypeAnnotation | VoidTypeAnnotation; @@ -391,6 +397,7 @@ export type NativeModuleEventEmitterTypeAnnotation = export type NativeModuleBaseTypeAnnotation = | NativeModuleStringTypeAnnotation | NativeModuleStringLiteralTypeAnnotation + | NativeModuleStringLiteralUnionTypeAnnotation | NativeModuleNumberTypeAnnotation | NativeModuleInt32TypeAnnotation | NativeModuleDoubleTypeAnnotation diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 089a83098f9..4398919e775 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -46,6 +46,11 @@ export type StringLiteralTypeAnnotation = $ReadOnly<{ value: string, }>; +export type StringLiteralUnionTypeAnnotation = $ReadOnly<{ + type: 'StringLiteralUnionTypeAnnotation', + types: $ReadOnlyArray, +}>; + export type StringEnumTypeAnnotation = $ReadOnly<{ type: 'StringEnumTypeAnnotation', options: $ReadOnlyArray, @@ -363,6 +368,7 @@ type NativeModuleEventEmitterBaseTypeAnnotation = | NativeModuleNumberTypeAnnotation | StringTypeAnnotation | StringLiteralTypeAnnotation + | StringLiteralUnionTypeAnnotation | NativeModuleTypeAliasTypeAnnotation | NativeModuleGenericObjectTypeAnnotation | VoidTypeAnnotation; @@ -377,6 +383,7 @@ export type NativeModuleEventEmitterTypeAnnotation = export type NativeModuleBaseTypeAnnotation = | StringTypeAnnotation | StringLiteralTypeAnnotation + | StringLiteralUnionTypeAnnotation | NativeModuleNumberTypeAnnotation | Int32TypeAnnotation | DoubleTypeAnnotation diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js index 6a30a71fd9f..1aa3c73dbbb 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js @@ -163,6 +163,8 @@ function serializeArg( return wrap(val => `${val}.asString(rt)`); case 'StringLiteralTypeAnnotation': return wrap(val => `${val}.asString(rt)`); + case 'StringLiteralUnionTypeAnnotation': + return wrap(val => `${val}.asString(rt)`); case 'BooleanTypeAnnotation': return wrap(val => `${val}.asBool()`); case 'EnumDeclaration': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index 2a76a9054d8..f7c4d674881 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -175,6 +175,8 @@ function translatePrimitiveJSTypeToCpp( return wrapOptional('jsi::String', isRequired); case 'StringLiteralTypeAnnotation': return wrapOptional('jsi::String', isRequired); + case 'StringLiteralUnionTypeAnnotation': + return wrapOptional('jsi::String', isRequired); case 'NumberTypeAnnotation': return wrapOptional('double', isRequired); case 'DoubleTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js index 0d130bc0777..779b9ac3f5f 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js @@ -133,6 +133,8 @@ function translateEventEmitterTypeToJavaType( return 'String'; case 'StringLiteralTypeAnnotation': return 'String'; + case 'StringLiteralUnionTypeAnnotation': + return 'String'; case 'NumberTypeAnnotation': case 'FloatTypeAnnotation': case 'DoubleTypeAnnotation': @@ -197,6 +199,8 @@ function translateFunctionParamToJavaType( return wrapOptional('String', isRequired); case 'StringLiteralTypeAnnotation': return wrapOptional('String', isRequired); + case 'StringLiteralUnionTypeAnnotation': + return wrapOptional('String', isRequired); case 'NumberTypeAnnotation': return wrapOptional('double', isRequired); case 'FloatTypeAnnotation': @@ -289,6 +293,8 @@ function translateFunctionReturnTypeToJavaType( return wrapOptional('String', isRequired); case 'StringLiteralTypeAnnotation': return wrapOptional('String', isRequired); + case 'StringLiteralUnionTypeAnnotation': + return wrapOptional('String', isRequired); case 'NumberTypeAnnotation': return wrapOptional('double', isRequired); case 'FloatTypeAnnotation': @@ -401,6 +407,8 @@ function getFalsyReturnStatementFromReturnType( return nullable ? 'return null;' : 'return "";'; case 'StringLiteralTypeAnnotation': return nullable ? 'return null;' : 'return "";'; + case 'StringLiteralUnionTypeAnnotation': + return nullable ? 'return null;' : 'return "";'; case 'ObjectTypeAnnotation': return 'return null;'; case 'GenericObjectTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js index 8b9228c15f4..3beb1c3fa1e 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js @@ -167,6 +167,8 @@ function translateReturnTypeToKind( return 'StringKind'; case 'StringLiteralTypeAnnotation': return 'StringKind'; + case 'StringLiteralUnionTypeAnnotation': + return 'StringKind'; case 'BooleanTypeAnnotation': return 'BooleanKind'; case 'EnumDeclaration': @@ -248,6 +250,8 @@ function translateParamTypeToJniType( return 'Ljava/lang/String;'; case 'StringLiteralTypeAnnotation': return 'Ljava/lang/String;'; + case 'StringLiteralUnionTypeAnnotation': + return 'Ljava/lang/String;'; case 'BooleanTypeAnnotation': return !isRequired ? 'Ljava/lang/Boolean;' : 'Z'; case 'EnumDeclaration': @@ -326,6 +330,8 @@ function translateReturnTypeToJniType( return 'Ljava/lang/String;'; case 'StringLiteralTypeAnnotation': return 'Ljava/lang/String;'; + case 'StringLiteralUnionTypeAnnotation': + return 'Ljava/lang/String;'; case 'BooleanTypeAnnotation': return nullable ? 'Ljava/lang/Boolean;' : 'Z'; case 'EnumDeclaration': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js index 0609689fe28..2792697aec1 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js @@ -23,6 +23,7 @@ import type { NativeModuleObjectTypeAnnotation, StringTypeAnnotation, StringLiteralTypeAnnotation, + StringLiteralUnionTypeAnnotation, NativeModuleTypeAliasTypeAnnotation, Nullable, ReservedTypeAnnotation, @@ -60,6 +61,7 @@ export type StructProperty = $ReadOnly<{ export type StructTypeAnnotation = | StringTypeAnnotation | StringLiteralTypeAnnotation + | StringLiteralUnionTypeAnnotation | NativeModuleNumberTypeAnnotation | Int32TypeAnnotation | DoubleTypeAnnotation diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js index 8ceb6447277..9fe6e73fc70 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js @@ -96,6 +96,8 @@ function toObjCType( return 'NSString *'; case 'StringLiteralTypeAnnotation': return 'NSString *'; + case 'StringLiteralUnionTypeAnnotation': + return 'NSString *'; case 'NumberTypeAnnotation': return wrapCxxOptional('double', isRequired); case 'FloatTypeAnnotation': @@ -177,6 +179,8 @@ function toObjCValue( return value; case 'StringLiteralTypeAnnotation': return value; + case 'StringLiteralUnionTypeAnnotation': + return value; case 'NumberTypeAnnotation': return wrapPrimitive('double'); case 'FloatTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js index e68693af6b8..dbf0fbefb50 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js @@ -87,6 +87,8 @@ function toObjCType( return 'NSString *'; case 'StringLiteralTypeAnnotation': return 'NSString *'; + case 'StringLiteralUnionTypeAnnotation': + return 'NSString *'; case 'NumberTypeAnnotation': return wrapCxxOptional('double', isRequired); case 'FloatTypeAnnotation': @@ -167,6 +169,8 @@ function toObjCValue( return RCTBridgingTo('String'); case 'StringLiteralTypeAnnotation': return RCTBridgingTo('String'); + case 'StringLiteralUnionTypeAnnotation': + return RCTBridgingTo('String'); case 'NumberTypeAnnotation': return RCTBridgingTo('Double'); case 'FloatTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeEventEmitter.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeEventEmitter.js index 9f1d5b077fa..ae3ff4e198e 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeEventEmitter.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeEventEmitter.js @@ -22,6 +22,8 @@ function getEventEmitterTypeObjCType( return 'NSString *_Nonnull'; case 'StringLiteralTypeAnnotation': return 'NSString *_Nonnull'; + case 'StringLiteralUnionTypeAnnotation': + return 'NSString *_Nonnull'; case 'NumberTypeAnnotation': return 'NSNumber *_Nonnull'; case 'BooleanTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js index c5ea2b66840..3c024a65e44 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js @@ -259,6 +259,8 @@ function getParamObjCType( return notStruct(wrapOptional('NSString *', !nullable)); case 'StringLiteralTypeAnnotation': return notStruct(wrapOptional('NSString *', !nullable)); + case 'StringLiteralUnionTypeAnnotation': + return notStruct(wrapOptional('NSString *', !nullable)); case 'NumberTypeAnnotation': return notStruct(isRequired ? 'double' : 'NSNumber *'); case 'FloatTypeAnnotation': @@ -336,6 +338,10 @@ function getReturnObjCType( // TODO: Can NSString * returns not be _Nullable? // In the legacy codegen, we don't surround NSSTring * with _Nullable return wrapOptional('NSString *', isRequired); + case 'StringLiteralUnionTypeAnnotation': + // TODO: Can NSString * returns not be _Nullable? + // In the legacy codegen, we don't surround NSSTring * with _Nullable + return wrapOptional('NSString *', isRequired); case 'NumberTypeAnnotation': return wrapOptional('NSNumber *', isRequired); case 'FloatTypeAnnotation': @@ -404,6 +410,8 @@ function getReturnJSType( return 'StringKind'; case 'StringLiteralTypeAnnotation': return 'StringKind'; + case 'StringLiteralUnionTypeAnnotation': + return 'StringKind'; case 'NumberTypeAnnotation': return 'NumberKind'; case 'FloatTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index 058ad1e7146..6e34e330eff 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -2316,6 +2316,23 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = { memberType: 'StringTypeAnnotation', }, }, + { + name: 'y-literal', + optional: false, + typeAnnotation: { + type: 'StringLiteralUnionTypeAnnotation', + types: [ + { + type: 'StringLiteralTypeAnnotation', + value: 'foo', + }, + { + type: 'StringLiteralTypeAnnotation', + value: 'bar', + }, + ], + }, + }, { name: 'z', optional: false, @@ -2626,6 +2643,23 @@ const UNION_MODULE: SchemaType = { memberType: 'StringTypeAnnotation', }, }, + { + name: 'chooseStringLiteral', + optional: false, + typeAnnotation: { + type: 'StringLiteralUnionTypeAnnotation', + types: [ + { + type: 'StringLiteralTypeAnnotation', + value: 'foo', + }, + { + type: 'StringLiteralTypeAnnotation', + value: 'bar', + }, + ], + }, + }, ], }, }, diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap index 4fca1c7436f..ebdad85f6ed 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap @@ -216,7 +216,8 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getUnion(jsi: rt, count <= 0 ? throw jsi::JSError(rt, \\"Expected argument in position 0 to be passed\\") : args[0].asNumber(), count <= 1 ? throw jsi::JSError(rt, \\"Expected argument in position 1 to be passed\\") : args[1].asString(rt), - count <= 2 ? throw jsi::JSError(rt, \\"Expected argument in position 2 to be passed\\") : args[2].asObject(rt) + count <= 2 ? throw jsi::JSError(rt, \\"Expected argument in position 2 to be passed\\") : args[2].asString(rt), + count <= 3 ? throw jsi::JSError(rt, \\"Expected argument in position 3 to be passed\\") : args[3].asObject(rt) ); } static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValue(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { @@ -309,7 +310,7 @@ NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getObject}; methodMap_[\\"getSet\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getSet}; methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getString}; - methodMap_[\\"getUnion\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getUnion}; + methodMap_[\\"getUnion\\"] = MethodMetadata {4, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getUnion}; methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValue}; methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithCallback}; methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithPromise}; @@ -764,13 +765,14 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getUnion(jsi: count <= 0 ? throw jsi::JSError(rt, \\"Expected argument in position 0 to be passed\\") : args[0].asNumber(), count <= 1 ? throw jsi::JSError(rt, \\"Expected argument in position 1 to be passed\\") : args[1].asNumber(), count <= 2 ? throw jsi::JSError(rt, \\"Expected argument in position 2 to be passed\\") : args[2].asObject(rt), - count <= 3 ? throw jsi::JSError(rt, \\"Expected argument in position 3 to be passed\\") : args[3].asString(rt) + count <= 3 ? throw jsi::JSError(rt, \\"Expected argument in position 3 to be passed\\") : args[3].asString(rt), + count <= 4 ? throw jsi::JSError(rt, \\"Expected argument in position 4 to be passed\\") : args[4].asString(rt) ); } NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker) : TurboModule(\\"SampleTurboModule\\", jsInvoker) { - methodMap_[\\"getUnion\\"] = MethodMetadata {4, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getUnion}; + methodMap_[\\"getUnion\\"] = MethodMetadata {5, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getUnion}; } diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap index ede5b6c5771..4f64f741130 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap @@ -693,7 +693,7 @@ public: virtual jsi::Object getObject(jsi::Runtime &rt, jsi::Object arg) = 0; virtual jsi::Array getSet(jsi::Runtime &rt, jsi::Array arg) = 0; virtual jsi::String getString(jsi::Runtime &rt, jsi::String arg) = 0; - virtual jsi::String getUnion(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) = 0; + virtual jsi::String getUnion(jsi::Runtime &rt, double x, jsi::String y, jsi::String y-literal, jsi::Object z) = 0; virtual jsi::Object getValue(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) = 0; virtual void getValueWithCallback(jsi::Runtime &rt, jsi::Function callback) = 0; virtual jsi::Value getValueWithPromise(jsi::Runtime &rt, bool error) = 0; @@ -855,13 +855,13 @@ private: return bridging::callFromJs( rt, &T::getString, jsInvoker_, instance_, std::move(arg)); } - jsi::String getUnion(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) override { + jsi::String getUnion(jsi::Runtime &rt, double x, jsi::String y, jsi::String y-literal, jsi::Object z) override { static_assert( - bridging::getParameterCount(&T::getUnion) == 4, - \\"Expected getUnion(...) to have 4 parameters\\"); + bridging::getParameterCount(&T::getUnion) == 5, + \\"Expected getUnion(...) to have 5 parameters\\"); return bridging::callFromJs( - rt, &T::getUnion, jsInvoker_, instance_, std::move(x), std::move(y), std::move(z)); + rt, &T::getUnion, jsInvoker_, instance_, std::move(x), std::move(y), std::move(y-literal), std::move(z)); } jsi::Object getValue(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) override { static_assert( @@ -2520,7 +2520,7 @@ protected: NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); public: - virtual jsi::Object getUnion(jsi::Runtime &rt, double chooseInt, double chooseFloat, jsi::Object chooseObject, jsi::String chooseString) = 0; + virtual jsi::Object getUnion(jsi::Runtime &rt, double chooseInt, double chooseFloat, jsi::Object chooseObject, jsi::String chooseString, jsi::String chooseStringLiteral) = 0; }; @@ -2551,13 +2551,13 @@ private: } - jsi::Object getUnion(jsi::Runtime &rt, double chooseInt, double chooseFloat, jsi::Object chooseObject, jsi::String chooseString) override { + jsi::Object getUnion(jsi::Runtime &rt, double chooseInt, double chooseFloat, jsi::Object chooseObject, jsi::String chooseString, jsi::String chooseStringLiteral) override { static_assert( - bridging::getParameterCount(&T::getUnion) == 5, - \\"Expected getUnion(...) to have 5 parameters\\"); + bridging::getParameterCount(&T::getUnion) == 6, + \\"Expected getUnion(...) to have 6 parameters\\"); return bridging::callFromJs( - rt, &T::getUnion, jsInvoker_, instance_, std::move(chooseInt), std::move(chooseFloat), std::move(chooseObject), std::move(chooseString)); + rt, &T::getUnion, jsInvoker_, instance_, std::move(chooseInt), std::move(chooseFloat), std::move(chooseObject), std::move(chooseString), std::move(chooseStringLiteral)); } private: diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap index c7047527e6f..3cb576c6ad3 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap @@ -1292,7 +1292,8 @@ Map { - (NSDictionary *)getUnion:(double)chooseInt chooseFloat:(double)chooseFloat chooseObject:(NSDictionary *)chooseObject - chooseString:(NSString *)chooseString; + chooseString:(NSString *)chooseString + chooseStringLiteral:(NSString *)chooseStringLiteral; @end diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap index c26611b1afb..689f389a8bb 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap @@ -678,7 +678,7 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo @ReactMethod(isBlockingSynchronousMethod = true) @DoNotStrip - public abstract WritableMap getUnion(double chooseInt, double chooseFloat, ReadableMap chooseObject, String chooseString); + public abstract WritableMap getUnion(double chooseInt, double chooseFloat, ReadableMap chooseObject, String chooseString, String chooseStringLiteral); } ", } diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniCpp-test.js.snap index 917d063a1ae..a9be8dc3fed 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniCpp-test.js.snap @@ -571,12 +571,12 @@ namespace facebook::react { static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getUnion(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { static jmethodID cachedMethodId = nullptr; - return static_cast(turboModule).invokeJavaMethod(rt, ObjectKind, \\"getUnion\\", \\"(DDLcom/facebook/react/bridge/ReadableMap;Ljava/lang/String;)Lcom/facebook/react/bridge/WritableMap;\\", args, count, cachedMethodId); + return static_cast(turboModule).invokeJavaMethod(rt, ObjectKind, \\"getUnion\\", \\"(DDLcom/facebook/react/bridge/ReadableMap;Ljava/lang/String;Ljava/lang/String;)Lcom/facebook/react/bridge/WritableMap;\\", args, count, cachedMethodId); } NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const JavaTurboModule::InitParams ¶ms) : JavaTurboModule(params) { - methodMap_[\\"getUnion\\"] = MethodMetadata {4, __hostFunction_NativeSampleTurboModuleSpecJSI_getUnion}; + methodMap_[\\"getUnion\\"] = MethodMetadata {5, __hostFunction_NativeSampleTurboModuleSpecJSI_getUnion}; } std::shared_ptr union_module_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) { diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap index 7bbb6f8ee77..8d20280fc7f 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap @@ -784,13 +784,13 @@ Map { namespace facebook::react { static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getUnion(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getUnion\\", @selector(getUnion:chooseFloat:chooseObject:chooseString:), args, count); + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getUnion\\", @selector(getUnion:chooseFloat:chooseObject:chooseString:chooseStringLiteral:), args, count); } NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"getUnion\\"] = MethodMetadata {4, __hostFunction_NativeSampleTurboModuleSpecJSI_getUnion}; + methodMap_[\\"getUnion\\"] = MethodMetadata {5, __hostFunction_NativeSampleTurboModuleSpecJSI_getUnion}; } } // namespace facebook::react diff --git a/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js b/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js index 02aa6b3a535..a95af6cbdf4 100644 --- a/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js +++ b/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js @@ -862,8 +862,8 @@ describe('emitUnion', () => { const typeAnnotation = { type: 'UnionTypeAnnotation', types: [ - {type: 'StringLiteralTypeAnnotation'}, - {type: 'StringLiteralTypeAnnotation'}, + {type: 'StringLiteralTypeAnnotation', value: 'foo'}, + {type: 'StringLiteralTypeAnnotation', value: 'bar'}, ], }; describe('when nullable is true', () => { @@ -878,8 +878,17 @@ describe('emitUnion', () => { const expected = { type: 'NullableTypeAnnotation', typeAnnotation: { - type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation', + type: 'StringLiteralUnionTypeAnnotation', + types: [ + { + type: 'StringLiteralTypeAnnotation', + value: 'foo', + }, + { + type: 'StringLiteralTypeAnnotation', + value: 'bar', + }, + ], }, }; @@ -897,8 +906,17 @@ describe('emitUnion', () => { ); const expected = { - type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation', + type: 'StringLiteralUnionTypeAnnotation', + types: [ + { + type: 'StringLiteralTypeAnnotation', + value: 'foo', + }, + { + type: 'StringLiteralTypeAnnotation', + value: 'bar', + }, + ], }; expect(result).toEqual(expected); @@ -955,8 +973,8 @@ describe('emitUnion', () => { const typeAnnotation = { type: 'UnionTypeAnnotation', types: [ - {type: 'NumberLiteralTypeAnnotation'}, - {type: 'StringLiteralTypeAnnotation'}, + {type: 'NumberLiteralTypeAnnotation', value: 'foo'}, + {type: 'StringLiteralTypeAnnotation', value: 'bar'}, {type: 'ObjectTypeAnnotation'}, ], }; @@ -1002,11 +1020,11 @@ describe('emitUnion', () => { types: [ { type: 'TSLiteralType', - literal: {type: 'NumericLiteral'}, + literal: {type: 'NumericLiteral', value: 4}, }, { type: 'TSLiteralType', - literal: {type: 'NumericLiteral'}, + literal: {type: 'NumericLiteral', value: 5}, }, ], }; @@ -1056,11 +1074,11 @@ describe('emitUnion', () => { types: [ { type: 'TSLiteralType', - literal: {type: 'StringLiteral'}, + literal: {type: 'StringLiteral', value: 'foo'}, }, { type: 'TSLiteralType', - literal: {type: 'StringLiteral'}, + literal: {type: 'StringLiteral', value: 'bar'}, }, ], }; @@ -1076,8 +1094,17 @@ describe('emitUnion', () => { const expected = { type: 'NullableTypeAnnotation', typeAnnotation: { - type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation', + type: 'StringLiteralUnionTypeAnnotation', + types: [ + { + type: 'StringLiteralTypeAnnotation', + value: 'foo', + }, + { + type: 'StringLiteralTypeAnnotation', + value: 'bar', + }, + ], }, }; @@ -1095,8 +1122,17 @@ describe('emitUnion', () => { ); const expected = { - type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation', + type: 'StringLiteralUnionTypeAnnotation', + types: [ + { + type: 'StringLiteralTypeAnnotation', + value: 'foo', + }, + { + type: 'StringLiteralTypeAnnotation', + value: 'bar', + }, + ], }; expect(result).toEqual(expected); @@ -1162,11 +1198,11 @@ describe('emitUnion', () => { types: [ { type: 'TSLiteralType', - literal: {type: 'NumericLiteral'}, + literal: {type: 'NumericLiteral', value: 4}, }, { type: 'TSLiteralType', - literal: {type: 'StringLiteral'}, + literal: {type: 'StringLiteral', value: 'foo'}, }, { type: 'TSLiteralType', diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 9937ce800ff..60340fc027f 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -396,8 +396,21 @@ exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`] 'name': 'chooseString', 'optional': false, 'typeAnnotation': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'One' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Two' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Three' + } + ] } } ] @@ -2286,8 +2299,21 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_UNION 1` 'name': 'chooseString', 'optional': false, 'typeAnnotation': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'One' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Two' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Three' + } + ] } } ] @@ -2317,8 +2343,17 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_UNION_RE 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'light' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'dark' + } + ] }, 'params': [] } @@ -2336,8 +2371,17 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_UNION_RE 'name': 'strings', 'optional': false, 'typeAnnotation': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'light' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'dark' + } + ] } } ] @@ -2602,8 +2646,25 @@ exports[`RN Codegen Flow Parser can generate fixture PROMISE_WITH_COMMONLY_USED_ 'returnTypeAnnotation': { 'type': 'PromiseTypeAnnotation', 'elementType': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Spring' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Summer' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Autumn' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Winter' + } + ] } }, 'params': [] diff --git a/packages/react-native-codegen/src/parsers/flow/parser.js b/packages/react-native-codegen/src/parsers/flow/parser.js index 91cac322b93..3a435e47ba4 100644 --- a/packages/react-native-codegen/src/parsers/flow/parser.js +++ b/packages/react-native-codegen/src/parsers/flow/parser.js @@ -117,6 +117,12 @@ class FlowParser implements Parser { return [...new Set(membersTypes.map(remapLiteral))]; } + getStringLiteralUnionTypeAnnotationStringLiterals( + membersTypes: $FlowFixMe[], + ): string[] { + return membersTypes.map((item: $FlowFixMe) => item.value); + } + parseFile(filename: string): SchemaType { const contents = fs.readFileSync(filename, 'utf8'); diff --git a/packages/react-native-codegen/src/parsers/parser.js b/packages/react-native-codegen/src/parsers/parser.js index 4c0d0257ed5..bfb160bc77f 100644 --- a/packages/react-native-codegen/src/parsers/parser.js +++ b/packages/react-native-codegen/src/parsers/parser.js @@ -146,6 +146,14 @@ export interface Parser { remapUnionTypeAnnotationMemberNames( types: $FlowFixMe, ): UnionTypeAnnotationMemberType[]; + /** + * Given a union annotation members types, it returns an array of string literals. + * @parameter membersTypes: union annotation members types + * @returns: an array of string literals. + */ + getStringLiteralUnionTypeAnnotationStringLiterals( + types: $FlowFixMe, + ): string[]; /** * Given the name of a file, it returns a Schema. * @parameter filename: the name of the file. diff --git a/packages/react-native-codegen/src/parsers/parserMock.js b/packages/react-native-codegen/src/parsers/parserMock.js index 7b0cc7ed53f..1045acfea12 100644 --- a/packages/react-native-codegen/src/parsers/parserMock.js +++ b/packages/react-native-codegen/src/parsers/parserMock.js @@ -109,6 +109,12 @@ export class MockedParser implements Parser { return []; } + getStringLiteralUnionTypeAnnotationStringLiterals( + membersTypes: $FlowFixMe[], + ): string[] { + return []; + } + parseFile(filename: string): SchemaType { return schemaMock; } diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index 91dd4532dc0..1a6957e0ae1 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -35,6 +35,7 @@ import type { ReservedTypeAnnotation, StringTypeAnnotation, StringLiteralTypeAnnotation, + StringLiteralUnionTypeAnnotation, VoidTypeAnnotation, } from '../CodegenSchema'; import type {Parser} from './parser'; @@ -409,7 +410,14 @@ function emitUnion( hasteModuleName: string, typeAnnotation: $FlowFixMe, parser: Parser, -): Nullable { +): Nullable< + NativeModuleUnionTypeAnnotation | StringLiteralUnionTypeAnnotation, +> { + // Get all the literals by type + // Verify they are all the same + // If string, persist as StringLiteralUnionType + // If number, persist as NumberTypeAnnotation (TODO: Number literal) + const unionTypes = parser.remapUnionTypeAnnotationMemberNames( typeAnnotation.types, ); @@ -423,12 +431,42 @@ function emitUnion( ); } + if (unionTypes[0] === 'StringTypeAnnotation') { + // Reprocess as a string literal union + return emitStringLiteralUnion( + nullable, + hasteModuleName, + typeAnnotation, + parser, + ); + } + return wrapNullable(nullable, { type: 'UnionTypeAnnotation', memberType: unionTypes[0], }); } +function emitStringLiteralUnion( + nullable: boolean, + hasteModuleName: string, + typeAnnotation: $FlowFixMe, + parser: Parser, +): Nullable { + const stringLiterals = + parser.getStringLiteralUnionTypeAnnotationStringLiterals( + typeAnnotation.types, + ); + + return wrapNullable(nullable, { + type: 'StringLiteralUnionTypeAnnotation', + types: stringLiterals.map(stringLiteral => ({ + type: 'StringLiteralTypeAnnotation', + value: stringLiteral, + })), + }); +} + function translateArrayTypeAnnotation( hasteModuleName: string, types: TypeDeclarationMap, diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap index 2e2917b7457..185b5adb7c2 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap @@ -387,8 +387,21 @@ exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODUL 'name': 'chooseString', 'optional': false, 'typeAnnotation': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'One' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Two' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Three' + } + ] } } ] @@ -2764,8 +2777,21 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_UN 'name': 'chooseString', 'optional': false, 'typeAnnotation': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'One' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Two' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'Three' + } + ] } } ] @@ -2795,8 +2821,17 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_UN 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'light' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'dark' + } + ] }, 'params': [] } @@ -2814,8 +2849,17 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_UN 'name': 'strings', 'optional': false, 'typeAnnotation': { - 'type': 'UnionTypeAnnotation', - 'memberType': 'StringTypeAnnotation' + 'type': 'StringLiteralUnionTypeAnnotation', + 'types': [ + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'light' + }, + { + 'type': 'StringLiteralTypeAnnotation', + 'value': 'dark' + } + ] } } ] diff --git a/packages/react-native-codegen/src/parsers/typescript/parser.js b/packages/react-native-codegen/src/parsers/typescript/parser.js index 04f8c1d69e6..592929dbd43 100644 --- a/packages/react-native-codegen/src/parsers/typescript/parser.js +++ b/packages/react-native-codegen/src/parsers/typescript/parser.js @@ -117,6 +117,12 @@ class TypeScriptParser implements Parser { return [...new Set(membersTypes.map(remapLiteral))]; } + getStringLiteralUnionTypeAnnotationStringLiterals( + membersTypes: $FlowFixMe[], + ): string[] { + return membersTypes.map((item: $FlowFixMe) => item.literal.value); + } + parseFile(filename: string): SchemaType { const contents = fs.readFileSync(filename, 'utf8');