Skip to content

Commit

Permalink
Fix nested array object structs
Browse files Browse the repository at this point in the history
Summary: Fixes some issues with generating deeply nested objects and arrays

Reviewed By: TheSavior

Differential Revision: D16858639

fbshipit-source-id: f9ca90da4fcef7f4fe795b38888c66ffef45c06b
  • Loading branch information
rickhanlonii authored and facebook-github-bot committed Aug 19, 2019
1 parent 8c995a2 commit 3050ac2
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 17 deletions.
Expand Up @@ -220,7 +220,7 @@ function getNativeTypeFromAnnotation(
typeAnnotation: typeAnnotation.elementType,
name: componentName,
},
nameParts,
nameParts.concat([prop.name]),
);
return `std::vector<${itemAnnotation}>`;
}
Expand Down Expand Up @@ -527,37 +527,71 @@ function getLocalImports(
return imports;
}

function generateStructs(componentName: string, component): string {
function generateStructsForComponent(componentName: string, component): string {
const structs = generateStructs(componentName, component.props, []);
const structArray = Array.from(structs.values());
if (structArray.length < 1) {
return '';
}
return structArray.join('\n\n');
}
function generateStructs(
componentName: string,
properties,
nameParts,
): StructsMap {
const structs: StructsMap = new Map();
component.props.forEach(prop => {
if (prop.typeAnnotation.type === 'ObjectTypeAnnotation') {
properties.forEach(prop => {
const typeAnnotation = prop.typeAnnotation;
if (typeAnnotation.type === 'ObjectTypeAnnotation') {
generateStruct(
structs,
componentName,
[prop.name],
prop.typeAnnotation.properties,
nameParts.concat([prop.name]),
typeAnnotation.properties,
);
} else if (
}
if (
prop.typeAnnotation.type === 'ArrayTypeAnnotation' &&
prop.typeAnnotation.elementType.type === 'ObjectTypeAnnotation'
) {
const properties = prop.typeAnnotation.elementType.properties;
generateStruct(structs, componentName, [prop.name], properties);
// 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.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}ArrayStruct`,
`${[componentName, ...nameParts.concat([prop.name])].join(
'',
)}ArrayStruct`,
arrayConversionFunction.replace(
/::_STRUCT_NAME_::/g,
generateStructName(componentName, [prop.name]),
generateStructName(componentName, nameParts.concat([prop.name])),
),
);
}
});
const structArray = Array.from(structs.values());
if (structArray.length < 1) {
return '';
}
return structArray.join('\n\n');
return structs;
}
function generateStruct(
Expand Down Expand Up @@ -661,7 +695,10 @@ module.exports = {
const component = components[componentName];
const newName = `${componentName}Props`;
const structString = generateStructs(componentName, component);
const structString = generateStructsForComponent(
componentName,
component,
);
const enumString = generateEnumString(componentName, component);
const propsString = generatePropsString(
componentName,
Expand Down
Expand Up @@ -93,6 +93,60 @@ static inline std::string toString(const ArrayPropsNativeComponentObjectStruct &
return \\"[Object ArrayPropsNativeComponentObjectStruct]\\";
}
static inline void fromRawValue(const RawValue &value, std::vector<ArrayPropsNativeComponentObjectStruct> &result) {
auto items = (std::vector<RawValue>)value;
for (const auto &item : items) {
ArrayPropsNativeComponentObjectStruct newItem;
fromRawValue(item, newItem);
result.emplace_back(newItem);
}
}
struct ArrayPropsNativeComponentArrayObjectStruct {
std::string stringProp;
};
static inline void fromRawValue(const RawValue &value, ArrayPropsNativeComponentArrayObjectStruct &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 ArrayPropsNativeComponentArrayObjectStruct &value) {
return \\"[Object ArrayPropsNativeComponentArrayObjectStruct]\\";
}
static inline void fromRawValue(const RawValue &value, std::vector<ArrayPropsNativeComponentArrayObjectStruct> &result) {
auto items = (std::vector<RawValue>)value;
for (const auto &item : items) {
ArrayPropsNativeComponentArrayObjectStruct newItem;
fromRawValue(item, newItem);
result.emplace_back(newItem);
}
}
struct ArrayPropsNativeComponentArrayStruct {
std::vector<ArrayPropsNativeComponentArrayObjectStruct> object;
};
static inline void fromRawValue(const RawValue &value, ArrayPropsNativeComponentArrayStruct &result) {
auto map = (better::map<std::string, RawValue>)value;
auto object = map.find(\\"object\\");
if (object != map.end()) {
fromRawValue(object->second, result.object);
}
}
static inline std::string toString(const ArrayPropsNativeComponentArrayStruct &value) {
return \\"[Object ArrayPropsNativeComponentArrayStruct]\\";
}
static inline void fromRawValue(const RawValue &value, std::vector<ArrayPropsNativeComponentArrayStruct> &result) {
auto items = (std::vector<RawValue>)value;
for (const auto &item : items) {
Expand Down

0 comments on commit 3050ac2

Please sign in to comment.