Skip to content

Commit 99f3c24

Browse files
netmaxt3rfacebook-github-bot
authored andcommitted
fix array enum prop parsing for array enum types (#44123)
Summary: codegen generates type alias for array enum props with uint32_t which cause wrong overloaded fromRawValue to call at runtime eventually app to terminate more detailed info at issue #43821 ## Changelog: [Internal] [Fixed] - Codegen for array enum props Pull Request resolved: #44123 Test Plan: TODO Reviewed By: cipolleschi Differential Revision: D56414554 Pulled By: dmytrorykun fbshipit-source-id: 0ec1b65951bc16ff58dd2b119c97a4e3fac2b161
1 parent c1f5504 commit 99f3c24

File tree

7 files changed

+76
-19
lines changed

7 files changed

+76
-19
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ ArrayPropsNativeComponentViewProps::ArrayPropsNativeComponentViewProps(
3434
points(convertRawProp(context, rawProps, \\"points\\", sourceProps.points, {})),
3535
edgeInsets(convertRawProp(context, rawProps, \\"edgeInsets\\", sourceProps.edgeInsets, {})),
3636
dimensions(convertRawProp(context, rawProps, \\"dimensions\\", sourceProps.dimensions, {})),
37-
sizes(convertRawProp(context, rawProps, \\"sizes\\", sourceProps.sizes, {static_cast<ArrayPropsNativeComponentViewSizesMask>(ArrayPropsNativeComponentViewSizes::Small)})),
37+
sizes(convertRawProp(context, rawProps, \\"sizes\\", ArrayPropsNativeComponentViewSizesMaskWrapped{ .value = sourceProps.sizes }, {static_cast<ArrayPropsNativeComponentViewSizesMask>(ArrayPropsNativeComponentViewSizes::Small)}).value),
3838
object(convertRawProp(context, rawProps, \\"object\\", sourceProps.object, {})),
3939
arrayOfObjects(convertRawProp(context, rawProps, \\"arrayOfObjects\\", sourceProps.arrayOfObjects, {}))
4040
{}

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ namespace facebook::react {
2828
2929
using ArrayPropsNativeComponentViewSizesMask = uint32_t;
3030
31+
struct ArrayPropsNativeComponentViewSizesMaskWrapped {
32+
ArrayPropsNativeComponentViewSizesMask value;
33+
};
34+
3135
enum class ArrayPropsNativeComponentViewSizes: ArrayPropsNativeComponentViewSizesMask {
3236
Small = 1 << 0,
3337
Large = 1 << 1
@@ -51,29 +55,29 @@ constexpr void operator|=(
5155
lhs = lhs | static_cast<ArrayPropsNativeComponentViewSizesMask>(rhs);
5256
}
5357
54-
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentViewSizesMask &result) {
58+
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentViewSizesMaskWrapped &wrapped) {
5559
auto items = std::vector<std::string>{value};
5660
for (const auto &item : items) {
5761
if (item == \\"small\\") {
58-
result |= ArrayPropsNativeComponentViewSizes::Small;
62+
wrapped.value |= ArrayPropsNativeComponentViewSizes::Small;
5963
continue;
6064
}
6165
if (item == \\"large\\") {
62-
result |= ArrayPropsNativeComponentViewSizes::Large;
66+
wrapped.value |= ArrayPropsNativeComponentViewSizes::Large;
6367
continue;
6468
}
6569
abort();
6670
}
6771
}
6872
69-
static inline std::string toString(const ArrayPropsNativeComponentViewSizesMask &value) {
73+
static inline std::string toString(const ArrayPropsNativeComponentViewSizesMaskWrapped &wrapped) {
7074
auto result = std::string{};
7175
auto separator = std::string{\\", \\"};
7276
73-
if (value & ArrayPropsNativeComponentViewSizes::Small) {
77+
if (wrapped.value & ArrayPropsNativeComponentViewSizes::Small) {
7478
result += \\"small\\" + separator;
7579
}
76-
if (value & ArrayPropsNativeComponentViewSizes::Large) {
80+
if (wrapped.value & ArrayPropsNativeComponentViewSizes::Large) {
7781
result += \\"large\\" + separator;
7882
}
7983
if (!result.empty()) {

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ function getEnumMaskName(enumName: string): string {
169169
function convertDefaultTypeToString(
170170
componentName: string,
171171
prop: NamedShape<PropTypeAnnotation>,
172+
fromBuilder: boolean = false,
172173
): string {
173174
const typeAnnotation = prop.typeAnnotation;
174175
switch (typeAnnotation.type) {
@@ -231,6 +232,9 @@ function convertDefaultTypeToString(
231232
const defaultValue = `${enumName}::${toSafeCppString(
232233
elementType.default,
233234
)}`;
235+
if (fromBuilder) {
236+
return `${enumMaskName}Wrapped{ .value = static_cast<${enumMaskName}>(${defaultValue})}`;
237+
}
234238
return `static_cast<${enumMaskName}>(${defaultValue})`;
235239
default:
236240
return '';
@@ -256,6 +260,37 @@ function convertDefaultTypeToString(
256260
}
257261
}
258262

263+
function getSourceProp(
264+
componentName: string,
265+
prop: NamedShape<PropTypeAnnotation>,
266+
): string {
267+
const typeAnnotation = prop.typeAnnotation;
268+
switch (typeAnnotation.type) {
269+
case 'ArrayTypeAnnotation':
270+
const elementType = typeAnnotation.elementType;
271+
switch (elementType.type) {
272+
case 'StringEnumTypeAnnotation':
273+
const enumName = getEnumName(componentName, prop.name);
274+
const enumMaskName = getEnumMaskName(enumName);
275+
return `${enumMaskName}Wrapped{ .value = sourceProps.${prop.name} }`;
276+
}
277+
}
278+
return `sourceProps.${prop.name}`;
279+
}
280+
281+
function isWrappedPropType(prop: NamedShape<PropTypeAnnotation>): boolean {
282+
const typeAnnotation = prop.typeAnnotation;
283+
switch (typeAnnotation.type) {
284+
case 'ArrayTypeAnnotation':
285+
const elementType = typeAnnotation.elementType;
286+
switch (elementType.type) {
287+
case 'StringEnumTypeAnnotation':
288+
return true;
289+
}
290+
}
291+
return false;
292+
}
293+
259294
const IncludeTemplate = ({
260295
headerPrefix,
261296
file,
@@ -279,4 +314,6 @@ module.exports = {
279314
generateStructName,
280315
generateEventStructName,
281316
IncludeTemplate,
317+
getSourceProp,
318+
isWrappedPropType,
282319
};

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ const {
1616
IncludeTemplate,
1717
convertDefaultTypeToString,
1818
getImports,
19+
getSourceProp,
20+
isWrappedPropType,
1921
} = require('./CppHelpers');
2022

2123
// File path -> contents
@@ -71,8 +73,14 @@ ${className}::${className}(
7173
function generatePropsString(componentName: string, component: ComponentShape) {
7274
return component.props
7375
.map(prop => {
76+
const sourceProp = getSourceProp(componentName, prop);
7477
const defaultValue = convertDefaultTypeToString(componentName, prop);
75-
return `${prop.name}(convertRawProp(context, rawProps, "${prop.name}", sourceProps.${prop.name}, {${defaultValue}}))`;
78+
const isWrappedProp = isWrappedPropType(prop);
79+
let convertRawProp = `convertRawProp(context, rawProps, "${prop.name}", ${sourceProp}, {${defaultValue}})`;
80+
if (isWrappedProp) {
81+
convertRawProp += '.value';
82+
}
83+
return `${prop.name}(${convertRawProp})`;
7684
})
7785
.join(',\n' + ' ');
7886
}

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ const ArrayEnumTemplate = ({
214214
`
215215
using ${enumMask} = uint32_t;
216216
217+
struct ${enumMask}Wrapped {
218+
${enumMask} value;
219+
};
220+
217221
enum class ${enumName}: ${enumMask} {
218222
${values}
219223
};
@@ -236,15 +240,15 @@ constexpr void operator|=(
236240
lhs = lhs | static_cast<${enumMask}>(rhs);
237241
}
238242
239-
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ${enumMask} &result) {
243+
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ${enumMask}Wrapped &wrapped) {
240244
auto items = std::vector<std::string>{value};
241245
for (const auto &item : items) {
242246
${fromCases}
243247
abort();
244248
}
245249
}
246250
247-
static inline std::string toString(const ${enumMask} &value) {
251+
static inline std::string toString(const ${enumMask}Wrapped &wrapped) {
248252
auto result = std::string{};
249253
auto separator = std::string{", "};
250254
@@ -302,7 +306,7 @@ function generateArrayEnumString(
302306
.map(
303307
option =>
304308
`if (item == "${option}") {
305-
result |= ${enumName}::${toSafeCppString(option)};
309+
wrapped.value |= ${enumName}::${toSafeCppString(option)};
306310
continue;
307311
}`,
308312
)
@@ -311,7 +315,7 @@ function generateArrayEnumString(
311315
const toCases = options
312316
.map(
313317
option =>
314-
`if (value & ${enumName}::${toSafeCppString(option)}) {
318+
`if (wrapped.value & ${enumName}::${toSafeCppString(option)}) {
315319
result += "${option}" + separator;
316320
}`,
317321
)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ ArrayPropsNativeComponentProps::ArrayPropsNativeComponentProps(
3333
srcs(convertRawProp(context, rawProps, \\"srcs\\", sourceProps.srcs, {})),
3434
points(convertRawProp(context, rawProps, \\"points\\", sourceProps.points, {})),
3535
dimensions(convertRawProp(context, rawProps, \\"dimensions\\", sourceProps.dimensions, {})),
36-
sizes(convertRawProp(context, rawProps, \\"sizes\\", sourceProps.sizes, {static_cast<ArrayPropsNativeComponentSizesMask>(ArrayPropsNativeComponentSizes::Small)})),
36+
sizes(convertRawProp(context, rawProps, \\"sizes\\", ArrayPropsNativeComponentSizesMaskWrapped{ .value = sourceProps.sizes }, {static_cast<ArrayPropsNativeComponentSizesMask>(ArrayPropsNativeComponentSizes::Small)}).value),
3737
object(convertRawProp(context, rawProps, \\"object\\", sourceProps.object, {})),
3838
array(convertRawProp(context, rawProps, \\"array\\", sourceProps.array, {})),
3939
arrayOfArrayOfObject(convertRawProp(context, rawProps, \\"arrayOfArrayOfObject\\", sourceProps.arrayOfArrayOfObject, {}))

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ namespace facebook::react {
2727
2828
using ArrayPropsNativeComponentSizesMask = uint32_t;
2929
30+
struct ArrayPropsNativeComponentSizesMaskWrapped {
31+
ArrayPropsNativeComponentSizesMask value;
32+
};
33+
3034
enum class ArrayPropsNativeComponentSizes: ArrayPropsNativeComponentSizesMask {
3135
Small = 1 << 0,
3236
Large = 1 << 1
@@ -50,29 +54,29 @@ constexpr void operator|=(
5054
lhs = lhs | static_cast<ArrayPropsNativeComponentSizesMask>(rhs);
5155
}
5256
53-
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentSizesMask &result) {
57+
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ArrayPropsNativeComponentSizesMaskWrapped &wrapped) {
5458
auto items = std::vector<std::string>{value};
5559
for (const auto &item : items) {
5660
if (item == \\"small\\") {
57-
result |= ArrayPropsNativeComponentSizes::Small;
61+
wrapped.value |= ArrayPropsNativeComponentSizes::Small;
5862
continue;
5963
}
6064
if (item == \\"large\\") {
61-
result |= ArrayPropsNativeComponentSizes::Large;
65+
wrapped.value |= ArrayPropsNativeComponentSizes::Large;
6266
continue;
6367
}
6468
abort();
6569
}
6670
}
6771
68-
static inline std::string toString(const ArrayPropsNativeComponentSizesMask &value) {
72+
static inline std::string toString(const ArrayPropsNativeComponentSizesMaskWrapped &wrapped) {
6973
auto result = std::string{};
7074
auto separator = std::string{\\", \\"};
7175
72-
if (value & ArrayPropsNativeComponentSizes::Small) {
76+
if (wrapped.value & ArrayPropsNativeComponentSizes::Small) {
7377
result += \\"small\\" + separator;
7478
}
75-
if (value & ArrayPropsNativeComponentSizes::Large) {
79+
if (wrapped.value & ArrayPropsNativeComponentSizes::Large) {
7680
result += \\"large\\" + separator;
7781
}
7882
if (!result.empty()) {

0 commit comments

Comments
 (0)