Skip to content

Commit 67b9628

Browse files
rubennortefacebook-github-bot
authored andcommitted
Modify native module codegen to throw JS errors when passing null values for non-nullable arguments
Summary: Changelog: [General][Breaking] Native modules using the codegen now throw an error when called with `null` for optional but not nullable arguments. ## Context Right now, if you have a native module using the codegen with a method like this: ``` someMethod(value?: number): void; ``` And you call it like this: ``` NativeModule.someMethod(null); ``` The app doesn't throw an error, but it should because this method shouldn't accept `null` according to its type definition. ## Changes This modifies the codegen to only check for `undefined` in those cases, otherwise trying to cast the value to the expected type and failing if it's `null`. NOTE: this is technically a breaking change, but if people are using Flow or TypeScript in their projects they're very unlikely to hit this case, because they would've complained if you tried to pass `null` in these cases. Reviewed By: cipolleschi Differential Revision: D54206289 fbshipit-source-id: 58f2f2f3009d203b96189d3c66d1ae98a9e4fb36
1 parent 2117122 commit 67b9628

3 files changed

Lines changed: 37 additions & 31 deletions

File tree

packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleCpp-test.js.snap

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalCxxSp
643643
static jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalCxxSpecJSI_getObjectShape(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
644644
return static_cast<NativeSampleTurboModuleNullableAndOptionalCxxSpecJSI *>(&turboModule)->getObjectShape(
645645
rt,
646-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
646+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
647647
);
648648
}
649649
static jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalCxxSpecJSI_getAlias(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
@@ -714,70 +714,70 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_voidF
714714
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getBool(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
715715
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getBool(
716716
rt,
717-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
717+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
718718
);
719719
}
720720
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getNumber(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
721721
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getNumber(
722722
rt,
723-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber())
723+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber())
724724
);
725725
}
726726
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getString(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
727727
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getString(
728728
rt,
729-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asString(rt))
729+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asString(rt))
730730
);
731731
}
732732
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getArray(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
733733
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getArray(
734734
rt,
735-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt).asArray(rt))
735+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt).asArray(rt))
736736
);
737737
}
738738
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getObject(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
739739
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getObject(
740740
rt,
741-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
741+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
742742
);
743743
}
744744
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getObjectShape(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
745745
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getObjectShape(
746746
rt,
747-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
747+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
748748
);
749749
}
750750
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getAlias(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
751751
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getAlias(
752752
rt,
753-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
753+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
754754
);
755755
}
756756
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getRootTag(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
757757
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getRootTag(
758758
rt,
759-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber())
759+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber())
760760
);
761761
}
762762
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getValue(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
763763
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getValue(
764764
rt,
765-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber()),
766-
count <= 1 || args[1].isNull() || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asString(rt)),
767-
count <= 2 || args[2].isNull() || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt))
765+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber()),
766+
count <= 1 || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asString(rt)),
767+
count <= 2 || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt))
768768
);
769769
}
770770
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getValueWithCallback(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
771771
static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getValueWithCallback(
772772
rt,
773-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt).asFunction(rt))
773+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt).asFunction(rt))
774774
);
775775
return jsi::Value::undefined();
776776
}
777777
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getValueWithPromise(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
778778
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getValueWithPromise(
779779
rt,
780-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
780+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
781781
);
782782
}
783783
@@ -1464,7 +1464,7 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalCxxSp
14641464
static jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalCxxSpecJSI_getObjectShape(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
14651465
return static_cast<NativeSampleTurboModuleNullableAndOptionalCxxSpecJSI *>(&turboModule)->getObjectShape(
14661466
rt,
1467-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
1467+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
14681468
);
14691469
}
14701470
static jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalCxxSpecJSI_getAlias(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
@@ -1535,70 +1535,70 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_voidF
15351535
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getBool(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15361536
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getBool(
15371537
rt,
1538-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
1538+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
15391539
);
15401540
}
15411541
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getNumber(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15421542
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getNumber(
15431543
rt,
1544-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber())
1544+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber())
15451545
);
15461546
}
15471547
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getString(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15481548
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getString(
15491549
rt,
1550-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asString(rt))
1550+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asString(rt))
15511551
);
15521552
}
15531553
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getArray(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15541554
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getArray(
15551555
rt,
1556-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt).asArray(rt))
1556+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt).asArray(rt))
15571557
);
15581558
}
15591559
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getObject(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15601560
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getObject(
15611561
rt,
1562-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
1562+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
15631563
);
15641564
}
15651565
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getObjectShape(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15661566
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getObjectShape(
15671567
rt,
1568-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
1568+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
15691569
);
15701570
}
15711571
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getAlias(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15721572
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getAlias(
15731573
rt,
1574-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
1574+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
15751575
);
15761576
}
15771577
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getRootTag(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15781578
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getRootTag(
15791579
rt,
1580-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber())
1580+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber())
15811581
);
15821582
}
15831583
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getValue(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15841584
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getValue(
15851585
rt,
1586-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber()),
1587-
count <= 1 || args[1].isNull() || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asString(rt)),
1588-
count <= 2 || args[2].isNull() || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt))
1586+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asNumber()),
1587+
count <= 1 || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asString(rt)),
1588+
count <= 2 || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt))
15891589
);
15901590
}
15911591
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getValueWithCallback(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15921592
static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getValueWithCallback(
15931593
rt,
1594-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt).asFunction(rt))
1594+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt).asFunction(rt))
15951595
);
15961596
return jsi::Value::undefined();
15971597
}
15981598
static jsi::Value __hostFunction_NativeSampleTurboModuleOptionalCxxSpecJSI_getValueWithPromise(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
15991599
return static_cast<NativeSampleTurboModuleOptionalCxxSpecJSI *>(&turboModule)->getValueWithPromise(
16001600
rt,
1601-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
1601+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
16021602
);
16031603
}
16041604

packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ function serializeArg(
132132
const val = `args[${index}]`;
133133
const expression = callback(val);
134134

135+
// param?: T
136+
if (optional && !nullable) {
137+
// throw new Error('are we hitting this case? ' + moduleName);
138+
return `count <= ${index} || ${val}.isUndefined() ? std::nullopt : std::make_optional(${expression})`;
139+
}
140+
135141
// param: ?T
136142
// param?: ?T
137143
if (nullable || optional) {

packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionalMetho
6161
rt,
6262
count <= 0 ? throw jsi::JSError(rt, \\"Expected argument in position 0 to be passed\\") : args[0].asObject(rt),
6363
count <= 1 ? throw jsi::JSError(rt, \\"Expected argument in position 1 to be passed\\") : args[1].asObject(rt).asFunction(rt),
64-
count <= 2 || args[2].isNull() || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt).asArray(rt))
64+
count <= 2 || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt).asArray(rt))
6565
);
6666
return jsi::Value::undefined();
6767
}
@@ -243,7 +243,7 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithP
243243
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getWithWithOptionalArgs(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
244244
auto result = static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getWithWithOptionalArgs(
245245
rt,
246-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
246+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asBool())
247247
);
248248
return result ? jsi::Value(std::move(*result)) : jsi::Value::null();
249249
}
@@ -591,7 +591,7 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithP
591591
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithOptionalArg(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
592592
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getValueWithOptionalArg(
593593
rt,
594-
count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
594+
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt))
595595
);
596596
}
597597
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnums(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {

0 commit comments

Comments
 (0)