react-native-codegen
Version:
⚛️ Code generation tools for React Native
263 lines (245 loc) • 7.18 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @format
*/
;
const _require = require('../../Utils'),
capitalize = _require.capitalize;
function toJavaType(typeAnnotation, addImport) {
const importNullable = () => addImport('androidx.annotation.Nullable');
const importReadableMap = () =>
addImport('com.facebook.react.bridge.ReadableMap');
const importArrayList = () => addImport('java.util.ArrayList');
switch (typeAnnotation.type) {
/**
* Primitives
*/
case 'BooleanTypeAnnotation': {
if (typeAnnotation.default === null) {
importNullable();
return '@Nullable Boolean';
} else {
return 'boolean';
}
}
case 'StringTypeAnnotation': {
importNullable();
return '@Nullable String';
}
case 'DoubleTypeAnnotation': {
return 'double';
}
case 'FloatTypeAnnotation': {
if (typeAnnotation.default === null) {
importNullable();
return '@Nullable Float';
} else {
return 'float';
}
}
case 'Int32TypeAnnotation': {
return 'int';
}
/**
* Enums
*/
// TODO: Make StringEnumTypeAnnotation type-safe?
case 'StringEnumTypeAnnotation':
importNullable();
return '@Nullable String';
// TODO: Make Int32EnumTypeAnnotation type-safe?
case 'Int32EnumTypeAnnotation':
importNullable();
return '@Nullable Integer';
/**
* Reserved types
*/
case 'ReservedPropTypeAnnotation': {
switch (typeAnnotation.name) {
case 'ColorPrimitive':
importNullable();
return '@Nullable Integer';
// TODO: Make ImageSourcePrimitive type-safe
case 'ImageSourcePrimitive':
importNullable();
importReadableMap();
return '@Nullable ReadableMap';
// TODO: Make PointPrimitive type-safe
case 'PointPrimitive':
importNullable();
importReadableMap();
return '@Nullable ReadableMap';
// TODO: Make EdgeInsetsPrimitive type-safe
case 'EdgeInsetsPrimitive':
importNullable();
importReadableMap();
return '@Nullable ReadableMap';
default:
typeAnnotation.name;
throw new Error(
`Received unknown ReservedPropTypeAnnotation ${typeAnnotation.name}`,
);
}
}
/**
* Other Pojo objects
*/
case 'PojoTypeAliasTypeAnnotation': {
return typeAnnotation.name;
}
/**
* Arrays
*/
case 'ArrayTypeAnnotation': {
const elementType = typeAnnotation.elementType;
const elementTypeString = (() => {
switch (elementType.type) {
/**
* Primitives
*/
case 'BooleanTypeAnnotation': {
return 'Boolean';
}
case 'StringTypeAnnotation': {
return 'String';
}
case 'DoubleTypeAnnotation': {
return 'Double';
}
case 'FloatTypeAnnotation': {
return 'Float';
}
case 'Int32TypeAnnotation': {
return 'Integer';
}
/**
* Enums
*/
// TODO: Make StringEnums type-safe in Pojos
case 'StringEnumTypeAnnotation': {
return 'String';
}
/**
* Other Pojo objects
*/
case 'PojoTypeAliasTypeAnnotation': {
return elementType.name;
}
/**
* Reserved types
*/
case 'ReservedPropTypeAnnotation': {
switch (elementType.name) {
case 'ColorPrimitive':
return 'Integer';
// TODO: Make ImageSourcePrimitive type-safe
case 'ImageSourcePrimitive':
importReadableMap();
return 'ReadableMap';
// TODO: Make PointPrimitive type-safe
case 'PointPrimitive':
importReadableMap();
return 'ReadableMap';
// TODO: Make EdgeInsetsPrimitive type-safe
case 'EdgeInsetsPrimitive':
importReadableMap();
return 'ReadableMap';
default:
elementType.name;
throw new Error(
`Received unknown ReservedPropTypeAnnotation ${elementType.name}`,
);
}
}
// Arrays
case 'ArrayTypeAnnotation': {
const pojoTypeAliasTypeAnnotation = elementType.elementType;
importArrayList();
return `ArrayList<${pojoTypeAliasTypeAnnotation.name}>`;
}
default: {
elementType.type;
throw new Error(
`Unrecognized PojoTypeAnnotation Array element type annotation '${typeAnnotation.type}'`,
);
}
}
})();
importArrayList();
return `ArrayList<${elementTypeString}>`;
}
default: {
typeAnnotation.type;
throw new Error(
`Unrecognized PojoTypeAnnotation '${typeAnnotation.type}'`,
);
}
}
}
function toJavaMemberName(property) {
return `m${capitalize(property.name)}`;
}
function toJavaMemberDeclaration(property, addImport) {
const type = toJavaType(property.typeAnnotation, addImport);
const memberName = toJavaMemberName(property);
return `private ${type} ${memberName};`;
}
function toJavaGetter(property, addImport) {
const type = toJavaType(property.typeAnnotation, addImport);
const getterName = `get${capitalize(property.name)}`;
const memberName = toJavaMemberName(property);
addImport('com.facebook.proguard.annotations.DoNotStrip');
return `@DoNotStrip
public ${type} ${getterName}() {
return ${memberName};
}`;
}
function serializePojo(pojo, basePackageName) {
const importSet = new Set();
const addImport = $import => {
importSet.add($import);
};
addImport('com.facebook.proguard.annotations.DoNotStrip');
const indent = ' '.repeat(2);
const members = pojo.properties
.map(property => toJavaMemberDeclaration(property, addImport))
.map(member => `${indent}${member}`)
.join('\n');
const getters = pojo.properties
.map(property => toJavaGetter(property, addImport))
.map(getter =>
getter
.split('\n')
.map(line => `${indent}${line}`)
.join('\n'),
)
.join('\n');
const imports = [...importSet]
.map($import => `import ${$import};`)
.sort()
.join('\n');
return `/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* ${'@'}generated by codegen project: GeneratePropsJavaPojo.js
*/
package ${basePackageName}.${pojo.namespace};
${imports === '' ? '' : `\n${imports}\n`}
@DoNotStrip
public class ${pojo.name} {
${members}
${getters}
}
`;
}
module.exports = {
serializePojo,
};