codegen: fix array of enums generation

Summary: While working on D16090949 I discovered that the code being generated for an array of enums was not correctly converted to mask. The type that holds the mask can't be enum class but other container type, I used `uint32_t`.

Reviewed By: shergin

Differential Revision: D16109338

fbshipit-source-id: 237077adaafe631eda973bc76cefa49035bbcd66
This commit is contained in:
Samuel Susla
2019-07-08 03:56:31 -07:00
committed by Facebook Github Bot
parent 59b8ee86c8
commit db17e969fa
2 changed files with 51 additions and 28 deletions
@@ -17,8 +17,6 @@ import type {PropTypeShape, SchemaType} from '../CodegenSchema';
// File path -> contents
type FilesOutput = Map<string, string>;
type TypeAnnotation = $PropertyType<PropTypeShape, 'typeAnnotation'>;
const template = `
/**
* Copyright (c) Facebook, Inc. and its affiliates.
@@ -70,23 +68,31 @@ static inline std::string toString(const ::_ENUM_NAME_:: &value) {
`.trim();
const arrayEnumTemplate = `
enum class ::_ENUM_NAME_::: uint32_t {
using ::_ENUM_MASK_:: = uint32_t;
enum class ::_ENUM_NAME_::: ::_ENUM_MASK_:: {
::_VALUES_::
};
constexpr bool operator&(
const enum ::_ENUM_NAME_:: lhs,
const enum ::_ENUM_NAME_:: rhs) {
return ((uint32_t)lhs & (uint32_t)rhs);
::_ENUM_MASK_:: const lhs,
enum ::_ENUM_NAME_:: const rhs) {
return lhs & static_cast<::_ENUM_MASK_::>(rhs);
}
constexpr bool operator|(
const enum ::_ENUM_NAME_:: lhs,
const enum ::_ENUM_NAME_:: rhs) {
return ((uint32_t)lhs | (uint32_t)rhs);
constexpr ::_ENUM_MASK_:: operator|(
::_ENUM_MASK_:: const lhs,
enum ::_ENUM_NAME_:: const rhs) {
return lhs | static_cast<::_ENUM_MASK_::>(rhs);
}
static inline void fromRawValue(const RawValue &value, ::_ENUM_NAME_:: &result) {
constexpr void operator|=(
::_ENUM_MASK_:: &lhs,
enum ::_ENUM_NAME_:: const rhs) {
lhs = lhs | static_cast<::_ENUM_MASK_::>(rhs);
}
static inline void fromRawValue(const RawValue &value, ::_ENUM_MASK_:: &result) {
auto items = std::vector<std::string>{value};
for (const auto &item : items) {
::_FROM_CASES_::
@@ -94,7 +100,7 @@ static inline void fromRawValue(const RawValue &value, ::_ENUM_NAME_:: &result)
}
}
static inline std::string toString(const ::_ENUM_NAME_:: &value) {
static inline std::string toString(const ::_ENUM_MASK_:: &value) {
auto result = std::string{};
auto separator = std::string{", "};
@@ -158,7 +164,8 @@ function getNativeTypeFromAnnotation(componentName: string, prop): string {
);
}
if (typeAnnotation.elementType.type === 'StringEnumTypeAnnotation') {
return getEnumName(componentName, prop.name);
const enumName = getEnumName(componentName, prop.name);
return getEnumMaskName(enumName);
}
const itemAnnotation = getNativeTypeFromAnnotation(componentName, {
typeAnnotation: typeAnnotation.elementType,
@@ -211,9 +218,12 @@ function convertDefaultTypeToString(componentName: string, prop): string {
'A default is required for array StringEnumTypeAnnotation',
);
}
return `${getEnumName(componentName, prop.name)}::${toSafeCppString(
const enumName = getEnumName(componentName, prop.name);
const enumMaskName = getEnumMaskName(enumName);
const defaultValue = `${enumName}::${toSafeCppString(
typeAnnotation.elementType.default || '',
)}`;
return `static_cast<${enumMaskName}>(${defaultValue})`;
default:
return '';
}
@@ -233,6 +243,10 @@ function getEnumName(componentName, propName): string {
return `${componentName}${uppercasedPropName}`;
}
function getEnumMaskName(enumName: string): string {
return `${enumName}Mask`;
}
function convertValueToEnumOption(value: string): string {
return toSafeCppString(value);
}
@@ -253,7 +267,7 @@ function generateArrayEnumString(
.map(
option =>
`if (item == "${option}") {
result = (${enumName})(result | ${enumName}::${toSafeCppString(option)});
result |= ${enumName}::${toSafeCppString(option)};
continue;
}`,
)
@@ -270,6 +284,7 @@ function generateArrayEnumString(
return arrayEnumTemplate
.replace(/::_ENUM_NAME_::/g, enumName)
.replace(/::_ENUM_MASK_::/g, getEnumMaskName(enumName))
.replace('::_VALUES_::', values)
.replace('::_FROM_CASES_::', fromCases)
.replace('::_TO_CASES_::', toCases);
@@ -21,39 +21,47 @@ Map {
namespace facebook {
namespace react {
enum class ArrayPropsNativeComponentSizes: uint32_t {
using ArrayPropsNativeComponentSizesMask = uint32_t;
enum class ArrayPropsNativeComponentSizes: ArrayPropsNativeComponentSizesMask {
Small = 1 << 0,
Large = 1 << 1
};
constexpr bool operator&(
const enum ArrayPropsNativeComponentSizes lhs,
const enum ArrayPropsNativeComponentSizes rhs) {
return ((uint32_t)lhs & (uint32_t)rhs);
ArrayPropsNativeComponentSizesMask const lhs,
enum ArrayPropsNativeComponentSizes const rhs) {
return lhs & static_cast<ArrayPropsNativeComponentSizesMask>(rhs);
}
constexpr bool operator|(
const enum ArrayPropsNativeComponentSizes lhs,
const enum ArrayPropsNativeComponentSizes rhs) {
return ((uint32_t)lhs | (uint32_t)rhs);
constexpr ArrayPropsNativeComponentSizesMask operator|(
ArrayPropsNativeComponentSizesMask const lhs,
enum ArrayPropsNativeComponentSizes const rhs) {
return lhs | static_cast<ArrayPropsNativeComponentSizesMask>(rhs);
}
static inline void fromRawValue(const RawValue &value, ArrayPropsNativeComponentSizes &result) {
constexpr void operator|=(
ArrayPropsNativeComponentSizesMask &lhs,
enum ArrayPropsNativeComponentSizes const rhs) {
lhs = lhs | static_cast<ArrayPropsNativeComponentSizesMask>(rhs);
}
static inline void fromRawValue(const RawValue &value, ArrayPropsNativeComponentSizesMask &result) {
auto items = std::vector<std::string>{value};
for (const auto &item : items) {
if (item == \\"small\\") {
result = (ArrayPropsNativeComponentSizes)(result | ArrayPropsNativeComponentSizes::Small);
result |= ArrayPropsNativeComponentSizes::Small;
continue;
}
if (item == \\"large\\") {
result = (ArrayPropsNativeComponentSizes)(result | ArrayPropsNativeComponentSizes::Large);
result |= ArrayPropsNativeComponentSizes::Large;
continue;
}
abort();
}
}
static inline std::string toString(const ArrayPropsNativeComponentSizes &value) {
static inline std::string toString(const ArrayPropsNativeComponentSizesMask &value) {
auto result = std::string{};
auto separator = std::string{\\", \\"};
@@ -83,7 +91,7 @@ class ArrayPropsNativeComponentProps final : public ViewProps {
const std::vector<SharedColor> colors{};
const std::vector<ImageSource> srcs{};
const std::vector<Point> points{};
const ArrayPropsNativeComponentSizes sizes{ArrayPropsNativeComponentSizes::Small};
const ArrayPropsNativeComponentSizesMask sizes{static_cast<ArrayPropsNativeComponentSizesMask>(ArrayPropsNativeComponentSizes::Small)};
};
} // namespace react