Skip to content

Commit

Permalink
Add generator for array<array<object>>
Browse files Browse the repository at this point in the history
Summary: This diff adds support for generating native code for arrays of arrays of objects

Reviewed By: JoshuaGross, mdvacca

Differential Revision: D16936272

fbshipit-source-id: 1543f8c1d5d9d4db28e4c7841ff7184ca0e417b3
  • Loading branch information
rickhanlonii authored and facebook-github-bot committed Sep 6, 2019
1 parent 588ece2 commit a7a1c8c
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
import type {PropTypeShape} from '../../CodegenSchema';

function upperCaseFirst(inString: string): string {
if (inString.length === 0) {
return inString;
}

return inString[0].toUpperCase() + inString.slice(1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,20 @@ const arrayConversionFunction = `static inline void fromRawValue(const RawValue
}
`;

const doubleArrayConversionFunction = `static inline void fromRawValue(const RawValue &value, std::vector<std::vector<::_STRUCT_NAME_::>> &result) {
auto items = (std::vector<std::vector<RawValue>>)value;
for (const std::vector<RawValue> &item : items) {
auto nestedArray = std::vector<::_STRUCT_NAME_::>{};
for (const RawValue &nestedItem : item) {
::_STRUCT_NAME_:: newItem;
fromRawValue(nestedItem, newItem);
nestedArray.emplace_back(newItem);
}
result.emplace_back(nestedArray);
}
}
`;

const arrayEnumTemplate = `
using ::_ENUM_MASK_:: = uint32_t;
Expand Down Expand Up @@ -220,18 +234,22 @@ function getNativeTypeFromAnnotation(
throw new Error('Received unknown NativePrimitiveTypeAnnotation');
}
case 'ArrayTypeAnnotation': {
if (typeAnnotation.elementType.type === 'ArrayTypeAnnotation') {
// TODO: Implement correctly in the next diff, this is to pass tests
return 'std::vector<int>';
const arrayType = typeAnnotation.elementType.type;
if (arrayType === 'ArrayTypeAnnotation') {
return `std::vector<${getNativeTypeFromAnnotation(
componentName,
{typeAnnotation: typeAnnotation.elementType, name: ''},
nameParts.concat([prop.name]),
)}>`;
}
if (typeAnnotation.elementType.type === 'ObjectTypeAnnotation') {
if (arrayType === 'ObjectTypeAnnotation') {
const structName = generateStructName(
componentName,
nameParts.concat([prop.name]),
);
return `std::vector<${structName}>`;
}
if (typeAnnotation.elementType.type === 'StringEnumTypeAnnotation') {
if (arrayType === 'StringEnumTypeAnnotation') {
const enumName = getEnumName(componentName, prop.name);
return getEnumMaskName(enumName);
}
Expand Down Expand Up @@ -606,6 +624,45 @@ function generateStructs(
),
);
}
if (
prop.typeAnnotation.type === 'ArrayTypeAnnotation' &&
prop.typeAnnotation.elementType.type === 'ArrayTypeAnnotation' &&
prop.typeAnnotation.elementType.elementType.type ===
'ObjectTypeAnnotation'
) {
// Recursively visit all of the object properties.
// Note: this is depth first so that the nested structs are ordered first.
const elementProperties =
prop.typeAnnotation.elementType.elementType.properties;
const nestedStructs = generateStructs(
componentName,
elementProperties,
nameParts.concat([prop.name]),
);
nestedStructs.forEach(function(value, key) {
structs.set(key, value);
});
// Generate this struct and its conversion function.
generateStruct(
structs,
componentName,
nameParts.concat([prop.name]),
elementProperties,
);
// Generate the conversion function for std:vector<Object>.
// Note: This needs to be at the end since it references the struct above.
structs.set(
`${[componentName, ...nameParts.concat([prop.name])].join(
'',
)}ArrayArrayStruct`,
doubleArrayConversionFunction.replace(
/::_STRUCT_NAME_::/g,
generateStructName(componentName, nameParts.concat([prop.name])),
),
);
}
});
return structs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,37 @@ static inline void fromRawValue(const RawValue &value, std::vector<ArrayPropsNat
}
}
struct ArrayPropsNativeComponentArrayOfArrayOfObjectStruct {
std::string stringProp;
};
static inline void fromRawValue(const RawValue &value, ArrayPropsNativeComponentArrayOfArrayOfObjectStruct &result) {
auto map = (better::map<std::string, RawValue>)value;
auto stringProp = map.find(\\"stringProp\\");
if (stringProp != map.end()) {
fromRawValue(stringProp->second, result.stringProp);
}
}
static inline std::string toString(const ArrayPropsNativeComponentArrayOfArrayOfObjectStruct &value) {
return \\"[Object ArrayPropsNativeComponentArrayOfArrayOfObjectStruct]\\";
}
static inline void fromRawValue(const RawValue &value, std::vector<std::vector<ArrayPropsNativeComponentArrayOfArrayOfObjectStruct>> &result) {
auto items = (std::vector<std::vector<RawValue>>)value;
for (const std::vector<RawValue> &item : items) {
auto nestedArray = std::vector<ArrayPropsNativeComponentArrayOfArrayOfObjectStruct>{};
for (const RawValue &nestedItem : item) {
ArrayPropsNativeComponentArrayOfArrayOfObjectStruct newItem;
fromRawValue(nestedItem, newItem);
nestedArray.emplace_back(newItem);
}
result.emplace_back(nestedArray);
}
}
class ArrayPropsNativeComponentProps final : public ViewProps {
public:
ArrayPropsNativeComponentProps() = default;
Expand All @@ -173,7 +204,7 @@ class ArrayPropsNativeComponentProps final : public ViewProps {
const ArrayPropsNativeComponentSizesMask sizes{static_cast<ArrayPropsNativeComponentSizesMask>(ArrayPropsNativeComponentSizes::Small)};
const std::vector<ArrayPropsNativeComponentObjectStruct> object{};
const std::vector<ArrayPropsNativeComponentArrayStruct> array{};
const std::vector<int> arrayOfArrayOfObject{};
const std::vector<std::vector<ArrayPropsNativeComponentArrayOfArrayOfObjectStruct>> arrayOfArrayOfObject{};
};
} // namespace react
Expand Down

0 comments on commit a7a1c8c

Please sign in to comment.