Skip to content

Commit 639d890

Browse files
alanleedevfacebook-github-bot
authored andcommitted
add missing struct member initialization in Props.h (facebook#44294)
Summary: Pull Request resolved: facebook#44294 **Problem:** It was discovered while testing 3 party library, generated member variables in a C++ `struct` in `Props.h` is not initialized. Also `WithDefault` would not work as well. (For the problematic case it was a `boolean` but would also apply to other primitive types.) If there is no default initialization and the component prop is optional and the user of the native component does not set the prop then the variable is never initialized and this is problematic for primitive types in C++ where no initialization results in an undefined behavior. **Proposed solution:** (Following C++Core Guideline of [always initialize](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-always).) Reusing `generatePropsString()` used by `ClassTemplate` to generate props for `StructTemplate` as well. updated relevant test snapshots. This change is only concerning the `Props.h` file. **Changelog:** [General][Fixed] - fixed `Props.h` created from codegen missing default initializers in C++ `struct` Reviewed By: cipolleschi Differential Revision: D56659457 fbshipit-source-id: 0d21ad20c0491a7e8bb718cd3156da65def72f23
1 parent 61f584c commit 639d890

File tree

6 files changed

+137
-52
lines changed

6 files changed

+137
-52
lines changed

packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap

+13-13
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static inline std::string toString(const ArrayPropsNativeComponentViewSizesMaskW
8686
return result;
8787
}
8888
struct ArrayPropsNativeComponentViewObjectStruct {
89-
std::string prop;
89+
std::string prop{};
9090
};
9191
9292
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentViewObjectStruct &result) {
@@ -113,8 +113,8 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
113113
114114
115115
struct ArrayPropsNativeComponentViewArrayOfObjectsStruct {
116-
Float prop1;
117-
int prop2;
116+
Float prop1{0.0};
117+
int prop2{0};
118118
};
119119
120120
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentViewArrayOfObjectsStruct &result) {
@@ -760,12 +760,12 @@ static inline std::string toString(const ObjectPropsNativeComponentIntEnumProp &
760760
}
761761
}
762762
struct ObjectPropsNativeComponentObjectPropStruct {
763-
std::string stringProp;
764-
bool booleanProp;
765-
Float floatProp;
766-
int intProp;
767-
ObjectPropsNativeComponentStringEnumProp stringEnumProp;
768-
ObjectPropsNativeComponentIntEnumProp intEnumProp;
763+
std::string stringProp{\\"\\"};
764+
bool booleanProp{false};
765+
Float floatProp{0.0};
766+
int intProp{0};
767+
ObjectPropsNativeComponentStringEnumProp stringEnumProp{ObjectPropsNativeComponentStringEnumProp::Small};
768+
ObjectPropsNativeComponentIntEnumProp intEnumProp{ObjectPropsNativeComponentIntEnumProp::IntEnumProp0};
769769
};
770770
771771
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsNativeComponentObjectPropStruct &result) {
@@ -802,7 +802,7 @@ static inline std::string toString(const ObjectPropsNativeComponentObjectPropStr
802802
}
803803
804804
struct ObjectPropsNativeComponentObjectArrayPropStruct {
805-
std::vector<std::string> array;
805+
std::vector<std::string> array{};
806806
};
807807
808808
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsNativeComponentObjectArrayPropStruct &result) {
@@ -819,9 +819,9 @@ static inline std::string toString(const ObjectPropsNativeComponentObjectArrayPr
819819
}
820820
821821
struct ObjectPropsNativeComponentObjectPrimitiveRequiredPropStruct {
822-
ImageSource image;
823-
SharedColor color;
824-
Point point;
822+
ImageSource image{};
823+
SharedColor color{};
824+
Point point{};
825825
};
826826
827827
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsNativeComponentObjectPrimitiveRequiredPropStruct &result) {

packages/react-native-codegen/src/generators/components/CppHelpers.js

+9
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ function getEnumMaskName(enumName: string): string {
166166
return `${enumName}Mask`;
167167
}
168168

169+
function getDefaultInitializerString(
170+
componentName: string,
171+
prop: NamedShape<PropTypeAnnotation>,
172+
): string {
173+
const defaultValue = convertDefaultTypeToString(componentName, prop);
174+
return `{${defaultValue}}`;
175+
}
176+
169177
function convertDefaultTypeToString(
170178
componentName: string,
171179
prop: NamedShape<PropTypeAnnotation>,
@@ -305,6 +313,7 @@ const IncludeTemplate = ({
305313
};
306314

307315
module.exports = {
316+
getDefaultInitializerString,
308317
convertDefaultTypeToString,
309318
getCppArrayTypeForAnnotation,
310319
getCppTypeForAnnotation,

packages/react-native-codegen/src/generators/components/GeneratePropsH.js

+18-14
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ const {
2323
getNativeTypeFromAnnotation,
2424
} = require('./ComponentsGeneratorUtils.js');
2525
const {
26-
convertDefaultTypeToString,
2726
generateStructName,
27+
getDefaultInitializerString,
2828
getEnumMaskName,
2929
toIntEnumValueName,
3030
} = require('./CppHelpers.js');
@@ -460,13 +460,21 @@ function generateEnumString(
460460
function generatePropsString(
461461
componentName: string,
462462
props: $ReadOnlyArray<NamedShape<PropTypeAnnotation>>,
463+
nameParts: $ReadOnlyArray<string>,
463464
) {
464465
return props
465466
.map(prop => {
466-
const nativeType = getNativeTypeFromAnnotation(componentName, prop, []);
467-
const defaultValue = convertDefaultTypeToString(componentName, prop);
467+
const nativeType = getNativeTypeFromAnnotation(
468+
componentName,
469+
prop,
470+
nameParts,
471+
);
472+
const defaultInitializer = getDefaultInitializerString(
473+
componentName,
474+
prop,
475+
);
468476

469-
return `${nativeType} ${prop.name}{${defaultValue}};`;
477+
return `${nativeType} ${prop.name}${defaultInitializer};`;
470478
})
471479
.join('\n' + ' ');
472480
}
@@ -633,16 +641,11 @@ function generateStruct(
633641
): void {
634642
const structNameParts = nameParts;
635643
const structName = generateStructName(componentName, structNameParts);
636-
637-
const fields = properties
638-
.map(property => {
639-
return `${getNativeTypeFromAnnotation(
640-
componentName,
641-
property,
642-
structNameParts,
643-
)} ${property.name};`;
644-
})
645-
.join('\n' + ' ');
644+
const fields = generatePropsString(
645+
componentName,
646+
properties,
647+
structNameParts,
648+
);
646649

647650
properties.forEach((property: NamedShape<PropTypeAnnotation>) => {
648651
const name = property.name;
@@ -742,6 +745,7 @@ module.exports = {
742745
const propsString = generatePropsString(
743746
componentName,
744747
component.props,
748+
[],
745749
);
746750
const extendString = getClassExtendString(component);
747751
const extendsImports = getExtendsImports(component.extendsProps);

packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js

+32
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,38 @@ const OBJECT_PROPS: SchemaType = {
871871
default: 0,
872872
},
873873
},
874+
{
875+
name: 'stringUserDefaultProp',
876+
optional: true,
877+
typeAnnotation: {
878+
type: 'StringTypeAnnotation',
879+
default: 'user_default',
880+
},
881+
},
882+
{
883+
name: 'booleanUserDefaultProp',
884+
optional: true,
885+
typeAnnotation: {
886+
type: 'BooleanTypeAnnotation',
887+
default: true,
888+
},
889+
},
890+
{
891+
name: 'floatUserDefaultProp',
892+
optional: true,
893+
typeAnnotation: {
894+
type: 'FloatTypeAnnotation',
895+
default: 3.14,
896+
},
897+
},
898+
{
899+
name: 'intUserDefaultProp',
900+
optional: true,
901+
typeAnnotation: {
902+
type: 'Int32TypeAnnotation',
903+
default: 9999,
904+
},
905+
},
874906
{
875907
name: 'stringEnumProp',
876908
optional: true,

packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap

+45-25
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static inline std::string toString(const ArrayPropsNativeComponentSizesMaskWrapp
8585
return result;
8686
}
8787
struct ArrayPropsNativeComponentObjectStruct {
88-
std::string stringProp;
88+
std::string stringProp{\\"\\"};
8989
};
9090
9191
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentObjectStruct &result) {
@@ -112,7 +112,7 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
112112
113113
114114
struct ArrayPropsNativeComponentArrayObjectStruct {
115-
std::string stringProp;
115+
std::string stringProp{\\"\\"};
116116
};
117117
118118
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentArrayObjectStruct &result) {
@@ -139,7 +139,7 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
139139
140140
141141
struct ArrayPropsNativeComponentArrayStruct {
142-
std::vector<ArrayPropsNativeComponentArrayObjectStruct> object;
142+
std::vector<ArrayPropsNativeComponentArrayObjectStruct> object{};
143143
};
144144
145145
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentArrayStruct &result) {
@@ -166,7 +166,7 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
166166
167167
168168
struct ArrayPropsNativeComponentArrayOfArrayOfObjectStruct {
169-
std::string stringProp;
169+
std::string stringProp{\\"\\"};
170170
};
171171
172172
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentArrayOfArrayOfObjectStruct &result) {
@@ -246,9 +246,9 @@ Map {
246246
namespace facebook::react {
247247
248248
struct ArrayPropsNativeComponentNativePrimitivesStruct {
249-
std::vector<SharedColor> colors;
250-
std::vector<ImageSource> srcs;
251-
std::vector<Point> points;
249+
std::vector<SharedColor> colors{};
250+
std::vector<ImageSource> srcs{};
251+
std::vector<Point> points{};
252252
};
253253
254254
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentNativePrimitivesStruct &result) {
@@ -1104,7 +1104,7 @@ static inline std::string toString(const ObjectPropsIntEnumProp &value) {
11041104
}
11051105
}
11061106
struct ObjectPropsObjectPropObjectArrayPropStruct {
1107-
std::vector<std::string> array;
1107+
std::vector<std::string> array{};
11081108
};
11091109
11101110
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsObjectPropObjectArrayPropStruct &result) {
@@ -1121,9 +1121,9 @@ static inline std::string toString(const ObjectPropsObjectPropObjectArrayPropStr
11211121
}
11221122
11231123
struct ObjectPropsObjectPropObjectPrimitiveRequiredPropStruct {
1124-
ImageSource image;
1125-
SharedColor color;
1126-
Point point;
1124+
ImageSource image{};
1125+
SharedColor color{};
1126+
Point point{};
11271127
};
11281128
11291129
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsObjectPropObjectPrimitiveRequiredPropStruct &result) {
@@ -1148,7 +1148,7 @@ static inline std::string toString(const ObjectPropsObjectPropObjectPrimitiveReq
11481148
}
11491149
11501150
struct ObjectPropsObjectPropNestedPropANestedPropBStruct {
1151-
std::string nestedPropC;
1151+
std::string nestedPropC{\\"\\"};
11521152
};
11531153
11541154
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsObjectPropNestedPropANestedPropBStruct &result) {
@@ -1165,7 +1165,7 @@ static inline std::string toString(const ObjectPropsObjectPropNestedPropANestedP
11651165
}
11661166
11671167
struct ObjectPropsObjectPropNestedPropAStruct {
1168-
ObjectPropsObjectPropNestedPropANestedPropBStruct nestedPropB;
1168+
ObjectPropsObjectPropNestedPropANestedPropBStruct nestedPropB{};
11691169
};
11701170
11711171
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsObjectPropNestedPropAStruct &result) {
@@ -1182,7 +1182,7 @@ static inline std::string toString(const ObjectPropsObjectPropNestedPropAStruct
11821182
}
11831183
11841184
struct ObjectPropsObjectPropNestedArrayAsPropertyArrayPropStruct {
1185-
std::string stringProp;
1185+
std::string stringProp{\\"\\"};
11861186
};
11871187
11881188
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsObjectPropNestedArrayAsPropertyArrayPropStruct &result) {
@@ -1209,7 +1209,7 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
12091209
12101210
12111211
struct ObjectPropsObjectPropNestedArrayAsPropertyStruct {
1212-
std::vector<ObjectPropsObjectPropNestedArrayAsPropertyArrayPropStruct> arrayProp;
1212+
std::vector<ObjectPropsObjectPropNestedArrayAsPropertyArrayPropStruct> arrayProp{};
12131213
};
12141214
12151215
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsObjectPropNestedArrayAsPropertyStruct &result) {
@@ -1226,16 +1226,20 @@ static inline std::string toString(const ObjectPropsObjectPropNestedArrayAsPrope
12261226
}
12271227
12281228
struct ObjectPropsObjectPropStruct {
1229-
std::string stringProp;
1230-
bool booleanProp;
1231-
Float floatProp;
1232-
int intProp;
1233-
ObjectPropsStringEnumProp stringEnumProp;
1234-
ObjectPropsIntEnumProp intEnumProp;
1235-
ObjectPropsObjectPropObjectArrayPropStruct objectArrayProp;
1236-
ObjectPropsObjectPropObjectPrimitiveRequiredPropStruct objectPrimitiveRequiredProp;
1237-
ObjectPropsObjectPropNestedPropAStruct nestedPropA;
1238-
ObjectPropsObjectPropNestedArrayAsPropertyStruct nestedArrayAsProperty;
1229+
std::string stringProp{\\"\\"};
1230+
bool booleanProp{false};
1231+
Float floatProp{0.0};
1232+
int intProp{0};
1233+
std::string stringUserDefaultProp{\\"user_default\\"};
1234+
bool booleanUserDefaultProp{true};
1235+
Float floatUserDefaultProp{3.14};
1236+
int intUserDefaultProp{9999};
1237+
ObjectPropsStringEnumProp stringEnumProp{ObjectPropsStringEnumProp::Option1};
1238+
ObjectPropsIntEnumProp intEnumProp{ObjectPropsIntEnumProp::IntEnumProp0};
1239+
ObjectPropsObjectPropObjectArrayPropStruct objectArrayProp{};
1240+
ObjectPropsObjectPropObjectPrimitiveRequiredPropStruct objectPrimitiveRequiredProp{};
1241+
ObjectPropsObjectPropNestedPropAStruct nestedPropA{};
1242+
ObjectPropsObjectPropNestedArrayAsPropertyStruct nestedArrayAsProperty{};
12391243
};
12401244
12411245
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ObjectPropsObjectPropStruct &result) {
@@ -1257,6 +1261,22 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
12571261
if (tmp_intProp != map.end()) {
12581262
fromRawValue(context, tmp_intProp->second, result.intProp);
12591263
}
1264+
auto tmp_stringUserDefaultProp = map.find(\\"stringUserDefaultProp\\");
1265+
if (tmp_stringUserDefaultProp != map.end()) {
1266+
fromRawValue(context, tmp_stringUserDefaultProp->second, result.stringUserDefaultProp);
1267+
}
1268+
auto tmp_booleanUserDefaultProp = map.find(\\"booleanUserDefaultProp\\");
1269+
if (tmp_booleanUserDefaultProp != map.end()) {
1270+
fromRawValue(context, tmp_booleanUserDefaultProp->second, result.booleanUserDefaultProp);
1271+
}
1272+
auto tmp_floatUserDefaultProp = map.find(\\"floatUserDefaultProp\\");
1273+
if (tmp_floatUserDefaultProp != map.end()) {
1274+
fromRawValue(context, tmp_floatUserDefaultProp->second, result.floatUserDefaultProp);
1275+
}
1276+
auto tmp_intUserDefaultProp = map.find(\\"intUserDefaultProp\\");
1277+
if (tmp_intUserDefaultProp != map.end()) {
1278+
fromRawValue(context, tmp_intUserDefaultProp->second, result.intUserDefaultProp);
1279+
}
12601280
auto tmp_stringEnumProp = map.find(\\"stringEnumProp\\");
12611281
if (tmp_stringEnumProp != map.end()) {
12621282
fromRawValue(context, tmp_stringEnumProp->second, result.stringEnumProp);

packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaPojo-test.js.snap

+20
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,10 @@ public class ObjectPropsPropsObjectProp {
10241024
private boolean mBooleanProp;
10251025
private float mFloatProp;
10261026
private int mIntProp;
1027+
private @Nullable String mStringUserDefaultProp;
1028+
private boolean mBooleanUserDefaultProp;
1029+
private float mFloatUserDefaultProp;
1030+
private int mIntUserDefaultProp;
10271031
private @Nullable String mStringEnumProp;
10281032
private @Nullable Integer mIntEnumProp;
10291033
private ObjectPropsPropsObjectPropObjectArrayProp mObjectArrayProp;
@@ -1047,6 +1051,22 @@ public class ObjectPropsPropsObjectProp {
10471051
return mIntProp;
10481052
}
10491053
@DoNotStrip
1054+
public @Nullable String getStringUserDefaultProp() {
1055+
return mStringUserDefaultProp;
1056+
}
1057+
@DoNotStrip
1058+
public boolean getBooleanUserDefaultProp() {
1059+
return mBooleanUserDefaultProp;
1060+
}
1061+
@DoNotStrip
1062+
public float getFloatUserDefaultProp() {
1063+
return mFloatUserDefaultProp;
1064+
}
1065+
@DoNotStrip
1066+
public int getIntUserDefaultProp() {
1067+
return mIntUserDefaultProp;
1068+
}
1069+
@DoNotStrip
10501070
public @Nullable String getStringEnumProp() {
10511071
return mStringEnumProp;
10521072
}

0 commit comments

Comments
 (0)