Codegen: Generate ObjC structs for type aliases

Summary:
**Motivation:**

Match the old codegen's behavior when generating structs for type alias derived objects.

**Problem description:**

Take, for example, the following spec:

```
export type MyTypeAlias = { /* ... */ }
export interface Spec extends TurboModule {
  // ...
  +myMethod: (paramName: MyTypeAlias) => void;
  // ...
}
```

The codegen needs to generate a struct to expose the properties of the type alias object. The codegen was producing the following output:

```
- (void)myMethod:(JS::MyModule::SpecMyMethodParamName &)paramName;
```

...which does not match the output from the original codegen:

```
- (void)myMethod:(JS::MyModule::MyTypeAlias &)paramName;
```

The original codegen generates a struct using the type alias name, while the new codegen was generating a struct that uses a combination of the property and parameter names.

Now that type alias names are exposed in the schema, the new codegen can match the original codegen's behavior.

**De-duplication of structs:**

Prior to these changes, type aliases were expanded into regular object types. This meant that any spec that used a type alias more than once would lead to redundant structs getting created. With these changes, we only generate the one struct per type alias, matching the old codegen.

**Expansion of type aliases:**

A new type was introduced in D22200700 (https://github.com/facebook/react-native/commit/e261f022fe6a7653b79330f878fed143725f5324), TypeAliasTypeAnnotation:

```
export type TypeAliasTypeAnnotation = $ReadOnly<{|
  type: 'TypeAliasTypeAnnotation',
  name: string,
|}>;
```

This type may now appear in several locations where a `{| type: 'ObjectTypeAnnotation', properties: [] |}` otherwise would have been used. A `getTypeAliasTypeAnnotation` function is introduced which, given an alias name and an array of aliases provided by the module, will produce the actual object type annotation for the given property parameter.

Changelog: [Internal]

Reviewed By: RSNara

Differential Revision: D22244323

fbshipit-source-id: 125fbf0d6d887bd05a99bf8b81b30bdda4f1682b
This commit is contained in:
Héctor Ramos
2020-07-01 23:39:44 -07:00
committed by Facebook GitHub Bot
parent e255748d12
commit 7e7706cb7d
14 changed files with 2504 additions and 190 deletions
@@ -11,7 +11,7 @@
'use strict';
import type {SchemaType} from '../../CodegenSchema';
const {getTypeAliasTypeAnnotation} = require('./ObjCppUtils/Utils');
type FilesOutput = Map<string, string>;
const propertyHeaderTemplate =
@@ -62,20 +62,25 @@ namespace react {
} // namespace facebook
`;
function traverseArg(arg, index): string {
function traverseArg(arg, index, aliases): string {
function wrap(suffix) {
return `args[${index}]${suffix}`;
}
const {typeAnnotation} = arg;
switch (typeAnnotation.type) {
const realTypeAnnotation =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases)
: typeAnnotation;
switch (realTypeAnnotation.type) {
case 'ReservedFunctionValueTypeAnnotation':
switch (typeAnnotation.name) {
switch (realTypeAnnotation.name) {
case 'RootTag':
return wrap('.getNumber()');
default:
(typeAnnotation.name: empty);
(realTypeAnnotation.name: empty);
throw new Error(
`Unknown prop type for "${arg.name}", found: "${typeAnnotation.name}"`,
`Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.name}"`,
);
}
case 'StringTypeAnnotation':
@@ -91,27 +96,26 @@ function traverseArg(arg, index): string {
case 'FunctionTypeAnnotation':
return `std::move(${wrap('.getObject(rt).getFunction(rt)')})`;
case 'GenericObjectTypeAnnotation':
case 'TypeAliasTypeAnnotation': // TODO: Handle aliases
case 'ObjectTypeAnnotation':
return wrap('.getObject(rt)');
case 'AnyTypeAnnotation':
throw new Error(`Any type is not allowed in params for "${arg.name}"`);
default:
// TODO (T65847278): Figure out why this does not work.
// (typeAnnotation.type: empty);
// (type: empty);
throw new Error(
`Unknown prop type for "${arg.name}", found: "${typeAnnotation.type}"`,
`Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.type}"`,
);
}
}
function traverseProperty(property): string {
function traverseProperty(property, aliases): string {
const propertyTemplate =
property.typeAnnotation.returnTypeAnnotation.type === 'VoidTypeAnnotation'
? voidPropertyTemplate
: nonvoidPropertyTemplate;
const traversedArgs = property.typeAnnotation.params
.map(traverseArg)
.map((p, i) => traverseArg(p, i, aliases))
.join(', ');
return propertyTemplate
.replace(/::_PROPERTY_NAME_::/g, property.name)
@@ -138,9 +142,9 @@ module.exports = {
const modules = Object.keys(nativeModules)
.map(name => {
const {properties} = nativeModules[name];
const {aliases, properties} = nativeModules[name];
const traversedProperties = properties
.map(property => traverseProperty(property))
.map(property => traverseProperty(property, aliases))
.join('\n');
return moduleTemplate
.replace(/::_MODULE_PROPERTIES_::/g, traversedProperties)
@@ -14,8 +14,12 @@ import type {
SchemaType,
FunctionTypeAnnotationParamTypeAnnotation,
FunctionTypeAnnotationReturn,
TypeAliasTypeAnnotation,
ObjectTypeAliasTypeShape,
} from '../../CodegenSchema';
const {getTypeAliasTypeAnnotation} = require('./ObjCppUtils/Utils');
type FilesOutput = Map<string, string>;
const moduleTemplate = `
@@ -51,17 +55,23 @@ namespace react {
function translatePrimitiveJSTypeToCpp(
typeAnnotation:
| FunctionTypeAnnotationParamTypeAnnotation
| FunctionTypeAnnotationReturn,
| FunctionTypeAnnotationReturn
| TypeAliasTypeAnnotation,
createErrorMessage: (typeName: string) => string,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
) {
switch (typeAnnotation.type) {
const realTypeAnnotation =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases)
: typeAnnotation;
switch (realTypeAnnotation.type) {
case 'ReservedFunctionValueTypeAnnotation':
switch (typeAnnotation.name) {
switch (realTypeAnnotation.name) {
case 'RootTag':
return 'double';
default:
(typeAnnotation.name: empty);
throw new Error(createErrorMessage(typeAnnotation.name));
(realTypeAnnotation.name: empty);
throw new Error(createErrorMessage(realTypeAnnotation.name));
}
case 'VoidTypeAnnotation':
return 'void';
@@ -74,7 +84,6 @@ function translatePrimitiveJSTypeToCpp(
return 'int';
case 'BooleanTypeAnnotation':
return 'bool';
// case 'TypeAliasTypeAnnotation': // TODO: Handle aliases
case 'GenericObjectTypeAnnotation':
case 'ObjectTypeAnnotation':
return 'jsi::Object';
@@ -86,8 +95,8 @@ function translatePrimitiveJSTypeToCpp(
return 'jsi::Value';
default:
// TODO (T65847278): Figure out why this does not work.
// (typeAnnotation.type: empty);
throw new Error(createErrorMessage(typeAnnotation.type));
// (type: empty);
throw new Error(createErrorMessage(realTypeAnnotation.type));
}
}
@@ -114,7 +123,7 @@ module.exports = {
const modules = Object.keys(nativeModules)
.map(name => {
const {properties} = nativeModules[name];
const {aliases, properties} = nativeModules[name];
const traversedProperties = properties
.map(prop => {
const traversedArgs = prop.typeAnnotation.params
@@ -123,6 +132,7 @@ module.exports = {
param.typeAnnotation,
typeName =>
`Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`,
aliases,
);
const isObject = translatedParam.startsWith('jsi::');
return (
@@ -140,6 +150,7 @@ module.exports = {
prop.typeAnnotation.returnTypeAnnotation,
typeName =>
`Unsupported return type for ${prop.name}. Found: ${typeName}`,
aliases,
),
)
.replace(
@@ -15,13 +15,17 @@ import type {
FunctionTypeAnnotationParam,
FunctionTypeAnnotationReturn,
ObjectParamTypeAnnotation,
ObjectTypeAliasTypeShape,
} from '../../CodegenSchema';
const {
translateObjectsForStructs,
capitalizeFirstLetter,
getNamespacedStructName,
} = require('./ObjCppUtils/GenerateStructs');
const {getTypeAliasTypeAnnotation} = require('./ObjCppUtils/Utils');
type FilesOutput = Map<string, string>;
const moduleTemplate = ` /**
@@ -101,20 +105,26 @@ const constants = `- (facebook::react::ModuleConstants<JS::Native::_MODULE_NAME_
function translatePrimitiveJSTypeToObjCType(
param: FunctionTypeAnnotationParam,
createErrorMessage: (typeName: string) => string,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
) {
const {nullable, typeAnnotation} = param;
function wrapIntoNullableIfNeeded(generatedType: string) {
return nullable ? `${generatedType} _Nullable` : generatedType;
}
switch (typeAnnotation.type) {
const realTypeAnnotation =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases)
: typeAnnotation;
switch (realTypeAnnotation.type) {
case 'ReservedFunctionValueTypeAnnotation':
switch (typeAnnotation.name) {
switch (realTypeAnnotation.name) {
case 'RootTag':
return nullable ? 'NSNumber *' : 'double';
default:
(typeAnnotation.name: empty);
throw new Error(createErrorMessage(typeAnnotation.name));
(realTypeAnnotation.name: empty);
throw new Error(createErrorMessage(realTypeAnnotation.name));
}
case 'StringTypeAnnotation':
return wrapIntoNullableIfNeeded('NSString *');
@@ -124,19 +134,21 @@ function translatePrimitiveJSTypeToObjCType(
return nullable ? 'NSNumber *' : 'double';
case 'BooleanTypeAnnotation':
return nullable ? 'NSNumber * _Nullable' : 'BOOL';
case 'TypeAliasTypeAnnotation': // TODO: Handle aliases
case 'ObjectTypeAnnotation':
if (typeAnnotation.type === 'TypeAliasTypeAnnotation') {
return getNamespacedStructName(typeAnnotation.name) + ' &';
}
return wrapIntoNullableIfNeeded('NSDictionary *');
case 'GenericObjectTypeAnnotation':
return wrapIntoNullableIfNeeded('NSDictionary *');
case 'ArrayTypeAnnotation':
return wrapIntoNullableIfNeeded('NSArray *');
case 'FunctionTypeAnnotation':
return 'RCTResponseSenderBlock';
case 'ObjectTypeAnnotation':
return wrapIntoNullableIfNeeded('NSDictionary *');
default:
// TODO (T65847278): Figure out why this does not work.
// (typeAnnotation.type: empty);
throw new Error(createErrorMessage(typeAnnotation.type));
// (type: empty);
throw new Error(createErrorMessage(realTypeAnnotation.type));
}
}
@@ -184,23 +196,26 @@ function translatePrimitiveJSTypeToObjCTypeForReturn(
function handleArrayOfObjects(
objectForGeneratingStructs: Array<ObjectForGeneratingStructs>,
param: FunctionTypeAnnotationParam,
propOrParam: FunctionTypeAnnotationParam,
name: string,
) {
if (
param.typeAnnotation.type === 'ArrayTypeAnnotation' &&
param.typeAnnotation.elementType &&
param.typeAnnotation.elementType.type === 'ObjectTypeAnnotation' &&
param.typeAnnotation.elementType.properties
propOrParam.typeAnnotation.type === 'ArrayTypeAnnotation' &&
propOrParam.typeAnnotation.elementType
) {
const {elementType} = param.typeAnnotation;
const {properties} = elementType;
if (properties && properties.length > 0) {
const typeAnnotation = propOrParam.typeAnnotation.elementType;
const type = typeAnnotation.type;
if (
type === 'ObjectTypeAnnotation' &&
typeAnnotation.properties &&
typeAnnotation.properties.length > 0
) {
objectForGeneratingStructs.push({
name,
object: {
type: 'ObjectTypeAnnotation',
properties,
properties: typeAnnotation.properties,
},
});
}
@@ -237,7 +252,7 @@ module.exports = {
.sort()
.map(name => {
const objectForGeneratingStructs: Array<ObjectForGeneratingStructs> = [];
const {properties} = nativeModules[name];
const {aliases, properties} = nativeModules[name];
const implementations = properties
.map(prop => {
const nativeArgs = prop.typeAnnotation.params
@@ -250,36 +265,55 @@ module.exports = {
const variableName =
capitalizeFirstLetter(prop.name) +
capitalizeFirstLetter(param.name);
const structName = 'Spec' + variableName;
objectForGeneratingStructs.push({
name: variableName,
name: structName,
object: {
type: 'ObjectTypeAnnotation',
properties: param.typeAnnotation.properties,
},
});
paramObjCType = `JS::Native::_MODULE_NAME_::::Spec${variableName}&`;
paramObjCType = getNamespacedStructName(structName) + ' &';
param.typeAnnotation.properties.map(aProp =>
handleArrayOfObjects(
param.typeAnnotation.properties.map(aProp => {
return handleArrayOfObjects(
objectForGeneratingStructs,
aProp,
capitalizeFirstLetter(prop.name) +
'Spec' +
capitalizeFirstLetter(prop.name) +
capitalizeFirstLetter(param.name) +
capitalizeFirstLetter(aProp.name) +
'Element',
),
);
});
} else if (
param.typeAnnotation.type === 'TypeAliasTypeAnnotation'
) {
const typeAnnotation = getTypeAliasTypeAnnotation(
param.typeAnnotation.name,
aliases,
);
if (typeAnnotation.type === 'ObjectTypeAnnotation') {
paramObjCType =
getNamespacedStructName(param.typeAnnotation.name) + ' &';
} else {
throw Error(
`Unsupported type for "${param.typeAnnotation.name}". Found: ${typeAnnotation.type}`,
);
}
} else {
paramObjCType = translatePrimitiveJSTypeToObjCType(
param,
typeName =>
`Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`,
aliases,
);
handleArrayOfObjects(
objectForGeneratingStructs,
param,
capitalizeFirstLetter(prop.name) +
'Spec' +
capitalizeFirstLetter(prop.name) +
capitalizeFirstLetter(param.name) +
'Element',
);
@@ -296,8 +330,7 @@ module.exports = {
returnTypeAnnotation.properties
) {
objectForGeneratingStructs.push({
name: capitalizeFirstLetter(prop.name) + 'ReturnType',
name: 'Spec' + capitalizeFirstLetter(prop.name) + 'ReturnType',
object: {
type: 'ObjectTypeAnnotation',
properties: returnTypeAnnotation.properties,
@@ -327,10 +360,44 @@ module.exports = {
return implementation;
})
.join('\n');
Object.keys(aliases)
.reverse()
.map((aliasName, i) => {
const alias = aliases[aliasName];
let paramObjCType = '';
switch (alias.type) {
case 'ObjectTypeAnnotation':
if (alias.properties) {
objectForGeneratingStructs.push({
name: aliasName,
object: {
type: 'ObjectTypeAnnotation',
properties: alias.properties,
},
});
paramObjCType = getNamespacedStructName(alias.name) + ' &';
}
break;
default:
throw Error(
`Unsupported type for "${aliasName}". Found: ${alias.type}`,
);
}
return `${i === 0 ? '' : aliasName}:(${paramObjCType})${aliasName}`;
})
.join('\n');
return protocolTemplate
.replace(
/::_STRUCTS_::/g,
translateObjectsForStructs(objectForGeneratingStructs, name),
translateObjectsForStructs(
objectForGeneratingStructs,
name,
aliases,
),
)
.replace(/::_MODULE_PROPERTIES_::/g, implementations)
.replace(/::_MODULE_NAME_::/g, name)
@@ -13,7 +13,10 @@
import type {SchemaType, NativeModuleShape} from '../../CodegenSchema';
const {capitalizeFirstLetter} = require('./ObjCppUtils/GenerateStructs');
const {flatObjects} = require('./ObjCppUtils/Utils');
const {
flatObjects,
getTypeAliasTypeAnnotation,
} = require('./ObjCppUtils/Utils');
type FilesOutput = Map<string, string>;
@@ -40,16 +43,16 @@ const moduleTemplate = `
}`.trim();
const getterTemplate = `
@implementation RCTCxxConvert (Native::_MODULE_NAME_::_Spec::_GETTER_NAME_::)
+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_Spec::_GETTER_NAME_:::(id)json
@implementation RCTCxxConvert (Native::_MODULE_NAME_::_::_GETTER_NAME_::)
+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_::_GETTER_NAME_:::(id)json
{
return facebook::react::managedPointer<JS::Native::_MODULE_NAME_::::Spec::_GETTER_NAME_::>(json);
return facebook::react::managedPointer<JS::Native::_MODULE_NAME_::::::_GETTER_NAME_::>(json);
}
@end
`;
const argConvertionTemplate =
'\n setMethodArgConversionSelector(@"::_ARG_NAME_::", ::_ARG_NUMBER_::, @"JS_Native::_MODULE_NAME_::_Spec::_SELECTOR_NAME_:::");';
'\n setMethodArgConversionSelector(@"::_ARG_NAME_::", ::_ARG_NUMBER_::, @"JS_Native::_MODULE_NAME_::_::_SELECTOR_NAME_:::");';
const template = `
/**
@@ -171,46 +174,65 @@ module.exports = {
const module: NativeModuleShape = nativeModules[moduleName];
return acc.concat(
flatObjects(
module.properties.reduce((moduleAcc, property) => {
const {returnTypeAnnotation} = property.typeAnnotation;
if (returnTypeAnnotation.type === 'ObjectTypeAnnotation') {
const {properties} = returnTypeAnnotation;
if (properties) {
moduleAcc.push({
name: capitalizeFirstLetter(property.name) + 'ReturnType',
object: {
type: 'ObjectTypeAnnotation',
properties: properties,
},
});
module.properties
.reduce((moduleAcc, property) => {
const {returnTypeAnnotation} = property.typeAnnotation;
if (returnTypeAnnotation.type === 'ObjectTypeAnnotation') {
const {properties} = returnTypeAnnotation;
if (properties) {
moduleAcc.push({
name:
'Spec' +
capitalizeFirstLetter(property.name) +
'ReturnType',
object: {
type: 'ObjectTypeAnnotation',
properties: properties,
},
});
}
}
}
if (property.typeAnnotation.params) {
return moduleAcc.concat(
property.typeAnnotation.params
.map(param => {
if (
param.typeAnnotation.type === 'ObjectTypeAnnotation'
) {
const {properties} = param.typeAnnotation;
if (properties) {
return {
name:
capitalizeFirstLetter(property.name) +
capitalizeFirstLetter(param.name),
object: {
type: 'ObjectTypeAnnotation',
properties: properties,
},
};
if (property.typeAnnotation.params) {
return moduleAcc.concat(
property.typeAnnotation.params
.map(param => {
if (
param.typeAnnotation.type === 'ObjectTypeAnnotation'
) {
const {properties} = param.typeAnnotation;
if (properties) {
return {
name:
'Spec' +
capitalizeFirstLetter(property.name) +
capitalizeFirstLetter(param.name),
object: {
type: 'ObjectTypeAnnotation',
properties: properties,
},
};
}
}
}
})
.filter(Boolean),
);
}
return moduleAcc;
}, []),
})
.filter(Boolean),
);
}
return moduleAcc;
}, [])
.concat(
Object.keys(module.aliases).map(aliasName => {
const alias = getTypeAliasTypeAnnotation(
aliasName,
module.aliases,
);
return {
name: aliasName,
object: {type: alias.type, properties: alias.properties},
};
}),
),
false,
module.aliases,
)
.map(object =>
getterTemplate
@@ -224,7 +246,7 @@ module.exports = {
const modules = Object.keys(nativeModules)
.map(name => {
const {properties} = nativeModules[name];
const {aliases, properties} = nativeModules[name];
const translatedMethods = properties
.map(property => translateMethodForImplementation(property))
.join('\n');
@@ -254,19 +276,33 @@ module.exports = {
properties
.map(({name: propertyName, typeAnnotation: {params}}) =>
params
.map((param, index) =>
param.typeAnnotation.type === 'ObjectTypeAnnotation' &&
param.typeAnnotation.properties
? argConvertionTemplate
.replace(
'::_SELECTOR_NAME_::',
capitalizeFirstLetter(propertyName) +
capitalizeFirstLetter(param.name),
.map((param, index) => {
const typeAnnotation =
param.typeAnnotation.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(
param.typeAnnotation.name,
aliases,
)
.replace('::_ARG_NUMBER_::', index.toString())
.replace('::_ARG_NAME_::', propertyName)
: '',
)
: param.typeAnnotation;
const selectorName =
param.typeAnnotation.type === 'TypeAliasTypeAnnotation'
? param.typeAnnotation.name
: 'Spec' +
capitalizeFirstLetter(propertyName) +
capitalizeFirstLetter(param.name);
if (
typeAnnotation.type === 'ObjectTypeAnnotation' &&
typeAnnotation.properties
) {
return argConvertionTemplate
.replace('::_SELECTOR_NAME_::', selectorName)
.replace('::_ARG_NUMBER_::', index.toString())
.replace('::_ARG_NAME_::', propertyName);
}
return '';
})
.join(''),
)
.join(''),
@@ -10,11 +10,15 @@
'use strict';
import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema';
import type {
ObjectParamTypeAnnotation,
ObjectTypeAliasTypeShape,
} from '../../../CodegenSchema';
const {
flatObjects,
capitalizeFirstLetter,
getSafePropertyName,
getTypeAliasTypeAnnotation,
} = require('./Utils');
const {generateStructsForConstants} = require('./GenerateStructsForConstants');
@@ -25,42 +29,38 @@ const template = `
const structTemplate = `
namespace JS {
namespace Native::_MODULE_NAME_:: {
struct Spec::_STRUCT_NAME_:: {
struct ::_STRUCT_NAME_:: {
::_STRUCT_PROPERTIES_::
Spec::_STRUCT_NAME_::(NSDictionary *const v) : _v(v) {}
::_STRUCT_NAME_::(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (Native::_MODULE_NAME_::_Spec::_STRUCT_NAME_::)
+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_Spec::_STRUCT_NAME_:::(id)json;
@interface RCTCxxConvert (Native::_MODULE_NAME_::_::_STRUCT_NAME_::)
+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_::_STRUCT_NAME_:::(id)json;
@end
`;
const inlineTemplate = `
inline ::_RETURN_TYPE_::JS::Native::_MODULE_NAME_::::Spec::_STRUCT_NAME_::::::_PROPERTY_NAME_::() const
inline ::_RETURN_TYPE_::JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::::_PROPERTY_NAME_::() const
{
id const p = _v[@"::_PROPERTY_NAME_::"];
return ::_RETURN_VALUE_::;
}
`;
function getNamespacedStructName(
structName: string,
property: ObjectParamTypeAnnotation,
) {
return `JS::Native::_MODULE_NAME_::::Spec${structName}${capitalizeFirstLetter(
getSafePropertyName(property),
)}`;
function getNamespacedStructName(structName: string): string {
return `JS::Native::_MODULE_NAME_::::${structName}`;
}
function getElementTypeForArray(
property: ObjectParamTypeAnnotation,
name: string,
moduleName: string,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): string {
const {typeAnnotation} = property;
@@ -81,7 +81,11 @@ function getElementTypeForArray(
return 'id<NSObject>';
}
const {type} = typeAnnotation.elementType;
const type =
typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.elementType.name, aliases)
.type
: typeAnnotation.elementType.type;
switch (type) {
case 'StringTypeAnnotation':
return 'NSString *';
@@ -91,8 +95,11 @@ function getElementTypeForArray(
case 'Int32TypeAnnotation':
return 'double';
case 'ObjectTypeAnnotation':
return getNamespacedStructName(name, property) + 'Element';
case 'TypeAliasTypeAnnotation': // TODO: Handle aliases
const structName =
typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation'
? typeAnnotation.elementType.name
: `${property.name}Element`;
return getNamespacedStructName(structName);
case 'GenericObjectTypeAnnotation':
// TODO(T67565166): Generic objects are not type safe and should be disallowed in the schema. This case should throw an error once it is disallowed in schema.
console.error(
@@ -118,6 +125,7 @@ function getInlineMethodSignature(
property: ObjectParamTypeAnnotation,
name: string,
moduleName: string,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): string {
const {typeAnnotation} = property;
function markOptionalTypeIfNecessary(type: string) {
@@ -135,14 +143,28 @@ function getInlineMethodSignature(
return `id<NSObject> ${getSafePropertyName(property)}() const;`;
}
switch (typeAnnotation.type) {
const realTypeAnnotation =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases)
: typeAnnotation;
const variableName =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? `${capitalizeFirstLetter(typeAnnotation.name)}`
: `${capitalizeFirstLetter(name)}${capitalizeFirstLetter(
getSafePropertyName(property),
)}`;
switch (realTypeAnnotation.type) {
case 'ReservedFunctionValueTypeAnnotation':
switch (typeAnnotation.name) {
switch (realTypeAnnotation.name) {
case 'RootTag':
return `double ${getSafePropertyName(property)}() const;`;
default:
(typeAnnotation.name: empty);
throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`);
(realTypeAnnotation.name: empty);
throw new Error(
`Unknown prop type, found: ${realTypeAnnotation.name}"`,
);
}
case 'StringTypeAnnotation':
return `NSString *${getSafePropertyName(property)}() const;`;
@@ -157,10 +179,9 @@ function getInlineMethodSignature(
property,
)}() const;`;
case 'ObjectTypeAnnotation':
return (
markOptionalTypeIfNecessary(getNamespacedStructName(name, property)) +
` ${getSafePropertyName(property)}() const;`
);
return `${markOptionalTypeIfNecessary(
getNamespacedStructName(variableName),
)} ${getSafePropertyName(property)}() const;`;
case 'GenericObjectTypeAnnotation':
case 'AnyTypeAnnotation':
return `id<NSObject> ${
@@ -172,11 +193,12 @@ function getInlineMethodSignature(
property,
name,
moduleName,
aliases,
)}>`,
)} ${getSafePropertyName(property)}() const;`;
case 'FunctionTypeAnnotation':
default:
throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`);
throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`);
}
}
@@ -184,6 +206,7 @@ function getInlineMethodImplementation(
property: ObjectParamTypeAnnotation,
name: string,
moduleName: string,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): string {
const {typeAnnotation} = property;
function markOptionalTypeIfNecessary(type: string): string {
@@ -216,7 +239,12 @@ function getInlineMethodImplementation(
throw new Error(`Cannot get array element type for ${name}`);
}
const {type} = typeAnnotation.elementType;
const type =
typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.elementType.name, aliases)
.type
: typeAnnotation.elementType.type;
switch (type) {
case 'StringTypeAnnotation':
return `RCTBridgingToString(${element})`;
@@ -228,8 +256,11 @@ function getInlineMethodImplementation(
case 'BooleanTypeAnnotation':
return `RCTBridgingToBool(${element})`;
case 'ObjectTypeAnnotation':
return `${getNamespacedStructName(name, property)}Element(${element})`;
case 'TypeAliasTypeAnnotation': // TODO: Handle aliases
const structName =
typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation'
? `${typeAnnotation.elementType.name}(${element})`
: `${getSafePropertyName(property)}Element(${element})`;
return getNamespacedStructName(structName);
case 'GenericObjectTypeAnnotation':
return element;
case 'AnyObjectTypeAnnotation':
@@ -260,16 +291,23 @@ function getInlineMethodImplementation(
.replace(/::_RETURN_VALUE_::/, 'p');
}
switch (typeAnnotation.type) {
const realTypeAnnotation =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases)
: typeAnnotation;
switch (realTypeAnnotation.type) {
case 'ReservedFunctionValueTypeAnnotation':
switch (typeAnnotation.name) {
switch (realTypeAnnotation.name) {
case 'RootTag':
return inlineTemplate
.replace(/::_RETURN_TYPE_::/, 'double ')
.replace(/::_RETURN_VALUE_::/, 'RCTBridgingToDouble(p)');
default:
(typeAnnotation.name: empty);
throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`);
(realTypeAnnotation.name: empty);
throw new Error(
`Unknown prop type, found: ${realTypeAnnotation.name}"`,
);
}
case 'StringTypeAnnotation':
return inlineTemplate
@@ -300,19 +338,21 @@ function getInlineMethodImplementation(
)
.replace(/::_RETURN_VALUE_::/, 'p');
case 'ObjectTypeAnnotation':
const structName =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? `${capitalizeFirstLetter(typeAnnotation.name)}`
: `${name}${capitalizeFirstLetter(getSafePropertyName(property))}`;
const namespacedStructName = getNamespacedStructName(structName);
return inlineTemplate
.replace(
/::_RETURN_TYPE_::/,
markOptionalTypeIfNecessary(getNamespacedStructName(name, property)),
markOptionalTypeIfNecessary(namespacedStructName),
)
.replace(
/::_RETURN_VALUE_::/,
property.optional
? `(p == nil ? folly::none : folly::make_optional(${getNamespacedStructName(
name,
property,
)}(p)))`
: `${getNamespacedStructName(name, property)}(p)`,
? `(p == nil ? folly::none : folly::make_optional(${namespacedStructName}(p)))`
: `${namespacedStructName}(p)`,
);
case 'ArrayTypeAnnotation':
return inlineTemplate
@@ -323,6 +363,7 @@ function getInlineMethodImplementation(
property,
name,
moduleName,
aliases,
)}>`,
),
)
@@ -332,13 +373,14 @@ function getInlineMethodImplementation(
property,
name,
moduleName,
aliases,
)}(id itemValue_0) { return ${bridgeArrayElementValueIfNecessary(
'itemValue_0',
)}; })`,
);
case 'FunctionTypeAnnotation':
default:
throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`);
throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`);
}
}
@@ -353,15 +395,21 @@ function translateObjectsForStructs(
|}>,
>,
moduleName: string,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): string {
const flattenObjects = flatObjects(annotations);
const flattenObjects = flatObjects(annotations, false, aliases);
const translatedInlineMethods = flattenObjects
.reduce(
(acc, object) =>
acc.concat(
object.properties.map(property =>
getInlineMethodImplementation(property, object.name, moduleName)
getInlineMethodImplementation(
property,
object.name,
moduleName,
aliases,
)
.replace(/::_PROPERTY_NAME_::/g, getSafePropertyName(property))
.replace(/::_STRUCT_NAME_::/g, object.name),
),
@@ -371,22 +419,26 @@ function translateObjectsForStructs(
.join('\n');
const translatedStructs = flattenObjects
.map(object =>
structTemplate
.map(object => {
return structTemplate
.replace(
/::_STRUCT_PROPERTIES_::/g,
object.properties
.map(property =>
getInlineMethodSignature(property, object.name, moduleName),
getInlineMethodSignature(
property,
object.name,
moduleName,
aliases,
),
)
.join('\n '),
)
.replace(/::_STRUCT_NAME_::/g, object.name),
)
.replace(/::_STRUCT_NAME_::/g, object.name);
})
.reverse()
.join('\n');
const translatedConstants = generateStructsForConstants(annotations);
const translatedConstants = generateStructsForConstants(annotations, aliases);
return template
.replace(/::_STRUCTS_::/, translatedStructs)
@@ -396,4 +448,5 @@ function translateObjectsForStructs(
module.exports = {
translateObjectsForStructs,
capitalizeFirstLetter,
getNamespacedStructName,
};
@@ -10,8 +10,15 @@
'use strict';
import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema';
const {flatObjects, capitalizeFirstLetter} = require('./Utils');
import type {
ObjectParamTypeAnnotation,
ObjectTypeAliasTypeShape,
} from '../../../CodegenSchema';
const {
flatObjects,
capitalizeFirstLetter,
getTypeAliasTypeAnnotation,
} = require('./Utils');
const structTemplate = `
namespace JS {
@@ -54,6 +61,7 @@ inline JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::Builder::Builder(::_STRUC
function getBuilderInputFieldDeclaration(
property: ObjectParamTypeAnnotation,
name: string,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): string {
function markRequiredIfNecessary(annotation) {
if (!property.optional) {
@@ -70,14 +78,26 @@ function getBuilderInputFieldDeclaration(
);
}
switch (typeAnnotation.type) {
const realTypeAnnotation =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases)
: typeAnnotation;
const variableName =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? typeAnnotation.name
: `${name}${capitalizeFirstLetter(property.name)}`;
switch (realTypeAnnotation.type) {
case 'ReservedFunctionValueTypeAnnotation':
switch (typeAnnotation.name) {
switch (realTypeAnnotation.name) {
case 'RootTag':
return markRequiredIfNecessary('double');
default:
(typeAnnotation.name: empty);
throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`);
(realTypeAnnotation.name: empty);
throw new Error(
`Unknown prop type, found: ${realTypeAnnotation.name}"`,
);
}
case 'StringTypeAnnotation':
if (property.optional) {
@@ -92,11 +112,8 @@ function getBuilderInputFieldDeclaration(
return markRequiredIfNecessary('bool');
case 'ObjectTypeAnnotation':
return markRequiredIfNecessary(
`JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter(
property.name,
)}::Builder`,
`JS::Native::_MODULE_NAME_::::${variableName}::Builder`,
);
case 'TypeAliasTypeAnnotation': // TODO: Handle aliases
case 'GenericObjectTypeAnnotation':
case 'AnyTypeAnnotation':
if (property.optional) {
@@ -107,7 +124,7 @@ function getBuilderInputFieldDeclaration(
return markRequiredIfNecessary('std::vector<id<NSObject>>');
case 'FunctionTypeAnnotation':
default:
throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`);
throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`);
}
}
@@ -160,7 +177,10 @@ function unsafeGetter(name: string, optional: boolean) {
`.trim();
}
function getObjectProperty(property: ObjectParamTypeAnnotation): string {
function getObjectProperty(
property: ObjectParamTypeAnnotation,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): string {
const {typeAnnotation} = property;
// TODO(T67898313): Workaround for NativeLinking's use of union type. This check may be removed once typeAnnotation is non-optional.
@@ -170,13 +190,22 @@ function getObjectProperty(property: ObjectParamTypeAnnotation): string {
);
}
switch (typeAnnotation.type) {
const type =
typeAnnotation.type === 'TypeAliasTypeAnnotation'
? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases).type
: typeAnnotation.type;
switch (type) {
case 'ReservedFunctionValueTypeAnnotation':
if (typeAnnotation.name == null) {
throw new Error(`Prop type ${type} has no name.`);
}
switch (typeAnnotation.name) {
case 'RootTag':
return numberGetter(property.name, property.optional);
default:
(typeAnnotation.name: empty);
// TODO (T65847278): Figure out why this does not work.
// (typeAnnotation.name: empty);
throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`);
}
case 'NumberTypeAnnotation':
@@ -186,7 +215,6 @@ function getObjectProperty(property: ObjectParamTypeAnnotation): string {
case 'BooleanTypeAnnotation':
return boolGetter(property.name, property.optional);
case 'StringTypeAnnotation':
case 'TypeAliasTypeAnnotation': // TODO: Handle aliases
case 'GenericObjectTypeAnnotation':
case 'AnyTypeAnnotation':
return safeGetter(property.name, property.optional);
@@ -196,7 +224,7 @@ function getObjectProperty(property: ObjectParamTypeAnnotation): string {
return arrayGetter(property.name, property.optional);
case 'FunctionTypeAnnotation':
default:
throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`);
throw new Error(`Unknown prop type, found: ${type}"`);
}
}
@@ -210,8 +238,9 @@ function generateStructsForConstants(
|}>,
|}>,
>,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): string {
return flatObjects(annotations, true)
return flatObjects(annotations, true, aliases)
.reduce(
(acc, object) =>
acc.concat(
@@ -220,14 +249,18 @@ function generateStructsForConstants(
/::_INPUT_::/g,
object.properties
.map(property =>
getBuilderInputFieldDeclaration(property, object.name),
getBuilderInputFieldDeclaration(
property,
object.name,
aliases,
),
)
.join('\n '),
)
.replace(
/::_PROPERTIES_::/g,
object.properties
.map(property => getObjectProperty(property))
.map(property => getObjectProperty(property, aliases))
.join('\n'),
)
.replace(/::_STRUCT_NAME_::/g, object.name),
@@ -10,7 +10,10 @@
'use strict';
import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema';
import type {
ObjectParamTypeAnnotation,
ObjectTypeAliasTypeShape,
} from '../../../CodegenSchema';
function capitalizeFirstLetter(string: string): string {
return string.charAt(0).toUpperCase() + string.slice(1);
@@ -27,6 +30,7 @@ function flatObjects(
|}>,
>,
forConstants: boolean = false,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): $ReadOnlyArray<
$ReadOnly<{|
name: string,
@@ -37,17 +41,23 @@ function flatObjects(
properties: $ReadOnlyArray<ObjectParamTypeAnnotation>,
name: string,
|}> = annotations
.map(annotation => ({
name: annotation.name,
properties: annotation.object.properties,
}))
.map(annotation => {
if (annotation.object.type === 'TypeAliasTypeAnnotation') {
const alias = getTypeAliasTypeAnnotation(annotation.name, aliases);
return {name: annotation.name, properties: alias.properties};
}
return {
name: annotation.name,
properties: annotation.object.properties,
};
})
.filter(
annotation =>
(annotation.name === 'GetConstantsReturnType') === forConstants,
(annotation.name === 'SpecGetConstantsReturnType') === forConstants,
)
.filter(
annotation =>
annotation.name !== 'GetConstantsReturnType' ||
annotation.name !== 'SpecGetConstantsReturnType' ||
annotation.properties.length > 0,
);
@@ -94,8 +104,35 @@ function getSafePropertyName(property: ObjectParamTypeAnnotation): string {
return property.name;
}
function getTypeAliasTypeAnnotation(
name: string,
aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): $ReadOnly<ObjectTypeAliasTypeShape> {
const typeAnnotation = aliases[name];
if (!typeAnnotation) {
throw Error(`No type annotation found for "${name}" in schema`);
}
if (typeAnnotation.type === 'ObjectTypeAnnotation') {
if (typeAnnotation.properties) {
return typeAnnotation;
}
throw new Error(
`Unsupported type for "${name}". Please provide properties.`,
);
}
if (typeAnnotation.type === 'TypeAliasTypeAnnotation') {
return getTypeAliasTypeAnnotation(typeAnnotation.name, aliases);
}
throw Error(
`Unsupported type annotation in alias "${name}", found: ${typeAnnotation.type}`,
);
}
module.exports = {
flatObjects,
capitalizeFirstLetter,
getSafePropertyName,
getTypeAliasTypeAnnotation,
};
@@ -707,10 +707,806 @@ const COMPLEX_OBJECTS: SchemaType = {
},
},
};
const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = {
modules: {
AliasTurboModule: {
nativeModules: {
AliasTurboModule: {
aliases: {
Options: {
properties: [
{
optional: false,
name: 'offset',
typeAnnotation: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'x',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'y',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
],
},
},
{
optional: false,
name: 'size',
typeAnnotation: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'width',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'height',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
],
},
},
{
optional: true,
name: 'displaySize',
typeAnnotation: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'width',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'height',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
],
},
},
{
optional: true,
name: 'resizeMode',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: true,
name: 'allowExternalStorage',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
],
type: 'ObjectTypeAnnotation',
},
},
properties: [
{
name: 'getConstants',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'ObjectTypeAnnotation',
properties: [],
},
params: [],
optional: false,
},
},
{
name: 'cropImage',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'VoidTypeAnnotation',
},
params: [
{
nullable: false,
name: 'cropData',
typeAnnotation: {
type: 'TypeAliasTypeAnnotation',
name: 'Options',
},
},
],
optional: false,
},
},
],
},
},
},
},
};
const REAL_MODULE_EXAMPLE: SchemaType = {
modules: {
NativeCameraRollManager: {
nativeModules: {
CameraRollManager: {
aliases: {
PhotoIdentifierImage: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'uri',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: false,
name: 'playableDuration',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'width',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'height',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: true,
name: 'isStored',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
{
optional: false,
name: 'filename',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
],
},
PhotoIdentifier: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'node',
typeAnnotation: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'image',
typeAnnotation: {
type: 'TypeAliasTypeAnnotation',
name: 'PhotoIdentifierImage',
},
},
{
optional: false,
name: 'type',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: false,
name: 'group_name',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: false,
name: 'timestamp',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'location',
typeAnnotation: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'longitude',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'latitude',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: true,
name: 'altitude',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: true,
name: 'heading',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: true,
name: 'speed',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
],
},
},
],
},
},
],
},
PhotoIdentifiersPage: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'edges',
typeAnnotation: {
type: 'ArrayTypeAnnotation',
elementType: {
type: 'TypeAliasTypeAnnotation',
name: 'PhotoIdentifier',
},
},
},
{
optional: false,
name: 'page_info',
typeAnnotation: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'has_next_page',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
{
optional: true,
name: 'start_cursor',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: true,
name: 'end_cursor',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
],
},
},
],
},
GetPhotosParams: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'first',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: true,
name: 'after',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: true,
name: 'groupName',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: true,
name: 'groupTypes',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: true,
name: 'assetType',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: true,
name: 'maxSize',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: true,
name: 'mimeTypes',
typeAnnotation: {
type: 'ArrayTypeAnnotation',
elementType: {
type: 'StringTypeAnnotation',
},
},
},
],
},
},
properties: [
{
name: 'getConstants',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'ObjectTypeAnnotation',
properties: [],
},
params: [],
optional: false,
},
},
{
name: 'getPhotos',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
type: 'GenericPromiseTypeAnnotation',
nullable: false,
},
params: [
{
nullable: false,
name: 'params',
typeAnnotation: {
type: 'TypeAliasTypeAnnotation',
name: 'GetPhotosParams',
},
},
],
optional: false,
},
},
{
name: 'saveToCameraRoll',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
type: 'GenericPromiseTypeAnnotation',
nullable: false,
},
params: [
{
nullable: false,
name: 'uri',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
nullable: false,
name: 'type',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
],
optional: false,
},
},
{
name: 'deletePhotos',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
type: 'GenericPromiseTypeAnnotation',
nullable: false,
},
params: [
{
name: 'assets',
nullable: false,
typeAnnotation: {
type: 'ArrayTypeAnnotation',
elementType: {
type: 'StringTypeAnnotation',
},
},
},
],
optional: false,
},
},
],
},
},
},
NativeImagePickerIOS: {
nativeModules: {
ImagePickerIOS: {
aliases: {},
properties: [
{
name: 'openCameraDialog',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'VoidTypeAnnotation',
},
params: [
{
nullable: false,
name: 'config',
typeAnnotation: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'unmirrorFrontFacingCamera',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
{
optional: false,
name: 'videoMode',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
],
},
},
{
name: 'successCallback',
nullable: false,
typeAnnotation: {
type: 'FunctionTypeAnnotation',
},
},
{
name: 'cancelCallback',
nullable: false,
typeAnnotation: {
type: 'FunctionTypeAnnotation',
},
},
],
optional: false,
},
},
],
},
},
},
NativeExceptionsManager: {
nativeModules: {
ExceptionsManager: {
aliases: {
StackFrame: {
properties: [
{
optional: true,
name: 'column',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'file',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: true,
name: 'lineNumber',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'methodName',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: true,
name: 'collapse',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
],
type: 'ObjectTypeAnnotation',
},
ExceptionData: {
properties: [
{
optional: false,
name: 'message',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: false,
name: 'originalMessage',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: false,
name: 'name',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: false,
name: 'componentStack',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
optional: false,
name: 'stack',
typeAnnotation: {
type: 'ArrayTypeAnnotation',
elementType: {
type: 'TypeAliasTypeAnnotation',
name: 'StackFrame',
},
},
},
{
optional: false,
name: 'id',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'isFatal',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
{
optional: true,
name: 'extraData',
typeAnnotation: {
type: 'GenericObjectTypeAnnotation',
},
},
],
type: 'ObjectTypeAnnotation',
},
},
properties: [
{
name: 'reportFatalException',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'VoidTypeAnnotation',
},
params: [
{
nullable: false,
name: 'message',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
name: 'stack',
nullable: false,
typeAnnotation: {
type: 'ArrayTypeAnnotation',
elementType: {
type: 'TypeAliasTypeAnnotation',
name: 'StackFrame',
},
},
},
{
nullable: false,
name: 'exceptionId',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
],
optional: false,
},
},
{
name: 'reportSoftException',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'VoidTypeAnnotation',
},
params: [
{
nullable: false,
name: 'message',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
name: 'stack',
nullable: false,
typeAnnotation: {
type: 'ArrayTypeAnnotation',
elementType: {
type: 'TypeAliasTypeAnnotation',
name: 'StackFrame',
},
},
},
{
nullable: false,
name: 'exceptionId',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
],
optional: false,
},
},
{
name: 'reportException',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'VoidTypeAnnotation',
},
params: [
{
nullable: false,
name: 'data',
typeAnnotation: {
type: 'TypeAliasTypeAnnotation',
name: 'ExceptionData',
},
},
],
optional: true,
},
},
{
name: 'updateExceptionMessage',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'VoidTypeAnnotation',
},
params: [
{
nullable: false,
name: 'message',
typeAnnotation: {
type: 'StringTypeAnnotation',
},
},
{
name: 'stack',
nullable: false,
typeAnnotation: {
type: 'ArrayTypeAnnotation',
elementType: {
type: 'TypeAliasTypeAnnotation',
name: 'StackFrame',
},
},
},
{
nullable: false,
name: 'exceptionId',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
],
optional: false,
},
},
{
name: 'dismissRedbox',
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
nullable: false,
type: 'VoidTypeAnnotation',
},
params: [],
optional: true,
},
},
],
},
},
},
},
};
module.exports = {
COMPLEX_OBJECTS,
TWO_MODULES_SAME_FILE,
TWO_MODULES_DIFFERENT_FILES,
EMPTY_NATIVE_MODULES,
SIMPLE_NATIVE_MODULES,
NATIVE_MODULES_WITH_TYPE_ALIASES,
REAL_MODULE_EXAMPLE,
};
@@ -21,7 +21,7 @@ const SIMPLE_STRUCT: $ReadOnlyArray<
|}>,
> = [
{
name: 'SampleFuncReturnType',
name: 'SpecSampleFuncReturnType',
object: {
type: 'ObjectTypeAnnotation',
properties: [
@@ -122,7 +122,7 @@ const SIMPLE_CONSTANTS: $ReadOnlyArray<
|}>,
> = [
{
name: 'GetConstantsReturnType',
name: 'SpecGetConstantsReturnType',
object: {
type: 'ObjectTypeAnnotation',
properties: [
@@ -23,7 +23,7 @@ describe('GenerateStructs', () => {
it(`can generate fixture ${fixtureName}`, () => {
expect(
generator
.translateObjectsForStructs(fixture, fixtureName)
.translateObjectsForStructs(fixture, fixtureName, {})
.replace(/::_MODULE_NAME_::/g, 'SampleTurboModule'),
).toMatchSnapshot();
});
@@ -72,6 +72,130 @@ NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared
}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateModuleCpp can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = `
Map {
"NativeModules.cpp" => "
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <react/modules/NATIVE_MODULES_WITH_TYPE_ALIASES/NativeModules.h>
namespace facebook {
namespace react {
static jsi::Value __hostFunction_NativeAliasTurboModuleCxxSpecJSI_getConstants(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeAliasTurboModuleCxxSpecJSI *>(&turboModule)->getConstants(rt);
}
static jsi::Value __hostFunction_NativeAliasTurboModuleCxxSpecJSI_cropImage(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeAliasTurboModuleCxxSpecJSI *>(&turboModule)->cropImage(rt, args[0].getObject(rt));
return jsi::Value::undefined();
}
NativeAliasTurboModuleCxxSpecJSI::NativeAliasTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"AliasTurboModule\\", jsInvoker) {
methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeAliasTurboModuleCxxSpecJSI_getConstants};
methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleCxxSpecJSI_cropImage};
}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateModuleCpp can generate fixture REAL_MODULE_EXAMPLE 1`] = `
Map {
"NativeModules.cpp" => "
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <react/modules/REAL_MODULE_EXAMPLE/NativeModules.h>
namespace facebook {
namespace react {
static jsi::Value __hostFunction_NativeCameraRollManagerCxxSpecJSI_getConstants(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraRollManagerCxxSpecJSI *>(&turboModule)->getConstants(rt);
}
static jsi::Value __hostFunction_NativeCameraRollManagerCxxSpecJSI_getPhotos(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraRollManagerCxxSpecJSI *>(&turboModule)->getPhotos(rt, args[0].getObject(rt));
}
static jsi::Value __hostFunction_NativeCameraRollManagerCxxSpecJSI_saveToCameraRoll(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraRollManagerCxxSpecJSI *>(&turboModule)->saveToCameraRoll(rt, args[0].getString(rt), args[1].getString(rt));
}
static jsi::Value __hostFunction_NativeCameraRollManagerCxxSpecJSI_deletePhotos(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraRollManagerCxxSpecJSI *>(&turboModule)->deletePhotos(rt, args[0].getObject(rt).getArray(rt));
}
NativeCameraRollManagerCxxSpecJSI::NativeCameraRollManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"CameraRollManager\\", jsInvoker) {
methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeCameraRollManagerCxxSpecJSI_getConstants};
methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerCxxSpecJSI_getPhotos};
methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerCxxSpecJSI_saveToCameraRoll};
methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerCxxSpecJSI_deletePhotos};
}
static jsi::Value __hostFunction_NativeImagePickerIOSCxxSpecJSI_openCameraDialog(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeImagePickerIOSCxxSpecJSI *>(&turboModule)->openCameraDialog(rt, args[0].getObject(rt), std::move(args[1].getObject(rt).getFunction(rt)), std::move(args[2].getObject(rt).getFunction(rt)));
return jsi::Value::undefined();
}
NativeImagePickerIOSCxxSpecJSI::NativeImagePickerIOSCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"ImagePickerIOS\\", jsInvoker) {
methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSCxxSpecJSI_openCameraDialog};
}
static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportFatalException(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeExceptionsManagerCxxSpecJSI *>(&turboModule)->reportFatalException(rt, args[0].getString(rt), args[1].getObject(rt).getArray(rt), args[2].getNumber());
return jsi::Value::undefined();
}
static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportSoftException(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeExceptionsManagerCxxSpecJSI *>(&turboModule)->reportSoftException(rt, args[0].getString(rt), args[1].getObject(rt).getArray(rt), args[2].getNumber());
return jsi::Value::undefined();
}
static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportException(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeExceptionsManagerCxxSpecJSI *>(&turboModule)->reportException(rt, args[0].getObject(rt));
return jsi::Value::undefined();
}
static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_updateExceptionMessage(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeExceptionsManagerCxxSpecJSI *>(&turboModule)->updateExceptionMessage(rt, args[0].getString(rt), args[1].getObject(rt).getArray(rt), args[2].getNumber());
return jsi::Value::undefined();
}
static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_dismissRedbox(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeExceptionsManagerCxxSpecJSI *>(&turboModule)->dismissRedbox(rt);
return jsi::Value::undefined();
}
NativeExceptionsManagerCxxSpecJSI::NativeExceptionsManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"ExceptionsManager\\", jsInvoker) {
methodMap_[\\"reportFatalException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportFatalException};
methodMap_[\\"reportSoftException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportSoftException};
methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportException};
methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerCxxSpecJSI_updateExceptionMessage};
methodMap_[\\"dismissRedbox\\"] = MethodMetadata {0, __hostFunction_NativeExceptionsManagerCxxSpecJSI_dismissRedbox};
}
} // namespace react
} // namespace facebook
",
@@ -59,6 +59,96 @@ protected:
public:
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateModuleCpp can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = `
Map {
"NativeModules.h" => "
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <ReactCommon/TurboModule.h>
namespace facebook {
namespace react {
class JSI_EXPORT NativeAliasTurboModuleCxxSpecJSI : public TurboModule {
protected:
NativeAliasTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
public:
virtual jsi::Object getConstants(jsi::Runtime &rt) = 0;
virtual void cropImage(jsi::Runtime &rt, const jsi::Object &cropData) = 0;
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateModuleCpp can generate fixture REAL_MODULE_EXAMPLE 1`] = `
Map {
"NativeModules.h" => "
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <ReactCommon/TurboModule.h>
namespace facebook {
namespace react {
class JSI_EXPORT NativeCameraRollManagerCxxSpecJSI : public TurboModule {
protected:
NativeCameraRollManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
public:
virtual jsi::Object getConstants(jsi::Runtime &rt) = 0;
virtual jsi::Value getPhotos(jsi::Runtime &rt, const jsi::Object &params) = 0;
virtual jsi::Value saveToCameraRoll(jsi::Runtime &rt, const jsi::String &uri, const jsi::String &type) = 0;
virtual jsi::Value deletePhotos(jsi::Runtime &rt, const jsi::Array &assets) = 0;
};
class JSI_EXPORT NativeImagePickerIOSCxxSpecJSI : public TurboModule {
protected:
NativeImagePickerIOSCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
public:
virtual void openCameraDialog(jsi::Runtime &rt, const jsi::Object &config, const jsi::Function &successCallback, const jsi::Function &cancelCallback) = 0;
};
class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule {
protected:
NativeExceptionsManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
public:
virtual void reportFatalException(jsi::Runtime &rt, const jsi::String &message, const jsi::Array &stack, double exceptionId) = 0;
virtual void reportSoftException(jsi::Runtime &rt, const jsi::String &message, const jsi::Array &stack, double exceptionId) = 0;
virtual void reportException(jsi::Runtime &rt, const jsi::Object &data) = 0;
virtual void updateExceptionMessage(jsi::Runtime &rt, const jsi::String &message, const jsi::Array &stack, double exceptionId) = 0;
virtual void dismissRedbox(jsi::Runtime &rt) = 0;
};
} // namespace react
@@ -96,7 +96,7 @@ namespace JS {
folly::Optional<facebook::react::LazyVector<double>> optionalArrayOfNumbers() const;
facebook::react::LazyVector<NSString *> arrayOfStrings() const;
folly::Optional<facebook::react::LazyVector<NSString *>> optionalArrayOfStrings() const;
facebook::react::LazyVector<JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement> arrayOfObjects() const;
facebook::react::LazyVector<JS::NativeSampleTurboModule::arrayOfObjectsElement> arrayOfObjects() const;
SpecGetArraysOptions(NSDictionary *const v) : _v(v) {}
private:
@@ -305,10 +305,10 @@ inline folly::Optional<facebook::react::LazyVector<NSString *>> JS::NativeSample
}
inline facebook::react::LazyVector<JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement> JS::NativeSampleTurboModule::SpecGetArraysOptions::arrayOfObjects() const
inline facebook::react::LazyVector<JS::NativeSampleTurboModule::arrayOfObjectsElement> JS::NativeSampleTurboModule::SpecGetArraysOptions::arrayOfObjects() const
{
id const p = _v[@\\"arrayOfObjects\\"];
return RCTBridgingToVec(p, ^JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement(id itemValue_0) { return JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement(itemValue_0); });
return RCTBridgingToVec(p, ^JS::NativeSampleTurboModule::arrayOfObjectsElement(id itemValue_0) { return JS::NativeSampleTurboModule::arrayOfObjectsElement(itemValue_0); });
}
@@ -363,12 +363,12 @@ inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty:
@protocol NativeSampleTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
- (NSDictionary *) difficult:(JS::NativeSampleTurboModule::SpecDifficultA&)A;
- (void) optionals:(JS::NativeSampleTurboModule::SpecOptionalsA&)A;
- (NSDictionary *) difficult:(JS::NativeSampleTurboModule::SpecDifficultA &)A;
- (void) optionals:(JS::NativeSampleTurboModule::SpecOptionalsA &)A;
- (void) optionalMethod:(NSDictionary *)options
callback:(RCTResponseSenderBlock)callback
extras:(NSArray * _Nullable)extras;
- (void) getArrays:(JS::NativeSampleTurboModule::SpecGetArraysOptions&)options;
- (void) getArrays:(JS::NativeSampleTurboModule::SpecGetArraysOptions &)options;
@end
@@ -443,6 +443,827 @@ namespace facebook {
}
`;
exports[`GenerateModuleHObjCpp can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = `
Map {
"SampleSpec.h" => "
/**
* Copyright (c) Facebook, Inc. and its 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: GenerateModuleHObjCpp.js
*/
#ifndef __cplusplus
#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm.
#endif
#import <vector>
#import <Foundation/Foundation.h>
#import <folly/Optional.h>
#import <RCTRequired/RCTRequired.h>
#import <RCTTypeSafety/RCTConvertHelpers.h>
#import <RCTTypeSafety/RCTTypedModuleConstants.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTCxxConvert.h>
#import <React/RCTManagedPointer.h>
#import <ReactCommon/RCTTurboModule.h>
namespace JS {
namespace NativeAliasTurboModule {
struct OptionsDisplaySize {
double width() const;
double height() const;
OptionsDisplaySize(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeAliasTurboModule_OptionsDisplaySize)
+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsDisplaySize:(id)json;
@end
namespace JS {
namespace NativeAliasTurboModule {
struct OptionsSize {
double width() const;
double height() const;
OptionsSize(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeAliasTurboModule_OptionsSize)
+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsSize:(id)json;
@end
namespace JS {
namespace NativeAliasTurboModule {
struct OptionsOffset {
double x() const;
double y() const;
OptionsOffset(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeAliasTurboModule_OptionsOffset)
+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json;
@end
namespace JS {
namespace NativeAliasTurboModule {
struct Options {
JS::NativeAliasTurboModule::OptionsOffset offset() const;
JS::NativeAliasTurboModule::OptionsSize size() const;
folly::Optional<JS::NativeAliasTurboModule::OptionsDisplaySize> displaySize() const;
NSString *resizeMode() const;
folly::Optional<bool> allowExternalStorage() const;
Options(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeAliasTurboModule_Options)
+ (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json;
@end
inline JS::NativeAliasTurboModule::OptionsOffset JS::NativeAliasTurboModule::Options::offset() const
{
id const p = _v[@\\"offset\\"];
return JS::NativeAliasTurboModule::OptionsOffset(p);
}
inline JS::NativeAliasTurboModule::OptionsSize JS::NativeAliasTurboModule::Options::size() const
{
id const p = _v[@\\"size\\"];
return JS::NativeAliasTurboModule::OptionsSize(p);
}
inline folly::Optional<JS::NativeAliasTurboModule::OptionsDisplaySize> JS::NativeAliasTurboModule::Options::displaySize() const
{
id const p = _v[@\\"displaySize\\"];
return (p == nil ? folly::none : folly::make_optional(JS::NativeAliasTurboModule::OptionsDisplaySize(p)));
}
inline NSString *JS::NativeAliasTurboModule::Options::resizeMode() const
{
id const p = _v[@\\"resizeMode\\"];
return RCTBridgingToString(p);
}
inline folly::Optional<bool> JS::NativeAliasTurboModule::Options::allowExternalStorage() const
{
id const p = _v[@\\"allowExternalStorage\\"];
return RCTBridgingToOptionalBool(p);
}
inline double JS::NativeAliasTurboModule::OptionsOffset::x() const
{
id const p = _v[@\\"x\\"];
return RCTBridgingToDouble(p);
}
inline double JS::NativeAliasTurboModule::OptionsOffset::y() const
{
id const p = _v[@\\"y\\"];
return RCTBridgingToDouble(p);
}
inline double JS::NativeAliasTurboModule::OptionsSize::width() const
{
id const p = _v[@\\"width\\"];
return RCTBridgingToDouble(p);
}
inline double JS::NativeAliasTurboModule::OptionsSize::height() const
{
id const p = _v[@\\"height\\"];
return RCTBridgingToDouble(p);
}
inline double JS::NativeAliasTurboModule::OptionsDisplaySize::width() const
{
id const p = _v[@\\"width\\"];
return RCTBridgingToDouble(p);
}
inline double JS::NativeAliasTurboModule::OptionsDisplaySize::height() const
{
id const p = _v[@\\"height\\"];
return RCTBridgingToDouble(p);
}
@protocol NativeAliasTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
- (void) cropImage:(JS::NativeAliasTurboModule::Options &)cropData;
@end
namespace facebook {
namespace react {
/**
* ObjC++ class for module 'AliasTurboModule'
*/
class JSI_EXPORT NativeAliasTurboModuleSpecJSI : public ObjCTurboModule {
public:
NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams &params);
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateModuleHObjCpp can generate fixture REAL_MODULE_EXAMPLE 1`] = `
Map {
"SampleSpec.h" => "
/**
* Copyright (c) Facebook, Inc. and its 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: GenerateModuleHObjCpp.js
*/
#ifndef __cplusplus
#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm.
#endif
#import <vector>
#import <Foundation/Foundation.h>
#import <folly/Optional.h>
#import <RCTRequired/RCTRequired.h>
#import <RCTTypeSafety/RCTConvertHelpers.h>
#import <RCTTypeSafety/RCTTypedModuleConstants.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTCxxConvert.h>
#import <React/RCTManagedPointer.h>
#import <ReactCommon/RCTTurboModule.h>
namespace JS {
namespace NativeCameraRollManager {
struct PhotoIdentifierNodeLocation {
double longitude() const;
double latitude() const;
folly::Optional<double> altitude() const;
folly::Optional<double> heading() const;
folly::Optional<double> speed() const;
PhotoIdentifierNodeLocation(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNodeLocation)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNodeLocation:(id)json;
@end
namespace JS {
namespace NativeCameraRollManager {
struct PhotoIdentifierNode {
JS::NativeCameraRollManager::PhotoIdentifierImage image() const;
NSString *type() const;
NSString *group_name() const;
double timestamp() const;
JS::NativeCameraRollManager::PhotoIdentifierNodeLocation location() const;
PhotoIdentifierNode(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNode)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNode:(id)json;
@end
namespace JS {
namespace NativeCameraRollManager {
struct PhotoIdentifiersPagePage_info {
bool has_next_page() const;
NSString *start_cursor() const;
NSString *end_cursor() const;
PhotoIdentifiersPagePage_info(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPagePage_info)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPagePage_info:(id)json;
@end
namespace JS {
namespace NativeCameraRollManager {
struct PhotoIdentifierImage {
NSString *uri() const;
double playableDuration() const;
double width() const;
double height() const;
folly::Optional<bool> isStored() const;
NSString *filename() const;
PhotoIdentifierImage(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierImage)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierImage:(id)json;
@end
namespace JS {
namespace NativeCameraRollManager {
struct PhotoIdentifier {
JS::NativeCameraRollManager::PhotoIdentifierNode node() const;
PhotoIdentifier(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifier)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifier:(id)json;
@end
namespace JS {
namespace NativeCameraRollManager {
struct PhotoIdentifiersPage {
facebook::react::LazyVector<JS::NativeCameraRollManager::PhotoIdentifier> edges() const;
JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info page_info() const;
PhotoIdentifiersPage(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPage)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json;
@end
namespace JS {
namespace NativeCameraRollManager {
struct GetPhotosParams {
double first() const;
NSString *after() const;
NSString *groupName() const;
NSString *groupTypes() const;
NSString *assetType() const;
folly::Optional<double> maxSize() const;
folly::Optional<facebook::react::LazyVector<NSString *>> mimeTypes() const;
GetPhotosParams(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeCameraRollManager_GetPhotosParams)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json;
@end
inline double JS::NativeCameraRollManager::GetPhotosParams::first() const
{
id const p = _v[@\\"first\\"];
return RCTBridgingToDouble(p);
}
inline NSString *JS::NativeCameraRollManager::GetPhotosParams::after() const
{
id const p = _v[@\\"after\\"];
return RCTBridgingToString(p);
}
inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupName() const
{
id const p = _v[@\\"groupName\\"];
return RCTBridgingToString(p);
}
inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupTypes() const
{
id const p = _v[@\\"groupTypes\\"];
return RCTBridgingToString(p);
}
inline NSString *JS::NativeCameraRollManager::GetPhotosParams::assetType() const
{
id const p = _v[@\\"assetType\\"];
return RCTBridgingToString(p);
}
inline folly::Optional<double> JS::NativeCameraRollManager::GetPhotosParams::maxSize() const
{
id const p = _v[@\\"maxSize\\"];
return RCTBridgingToOptionalDouble(p);
}
inline folly::Optional<facebook::react::LazyVector<NSString *>> JS::NativeCameraRollManager::GetPhotosParams::mimeTypes() const
{
id const p = _v[@\\"mimeTypes\\"];
return RCTBridgingToOptionalVec(p, ^NSString *(id itemValue_0) { return RCTBridgingToString(itemValue_0); });
}
inline facebook::react::LazyVector<JS::NativeCameraRollManager::PhotoIdentifier> JS::NativeCameraRollManager::PhotoIdentifiersPage::edges() const
{
id const p = _v[@\\"edges\\"];
return RCTBridgingToVec(p, ^JS::NativeCameraRollManager::PhotoIdentifier(id itemValue_0) { return JS::NativeCameraRollManager::PhotoIdentifier(itemValue_0); });
}
inline JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info JS::NativeCameraRollManager::PhotoIdentifiersPage::page_info() const
{
id const p = _v[@\\"page_info\\"];
return JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info(p);
}
inline JS::NativeCameraRollManager::PhotoIdentifierNode JS::NativeCameraRollManager::PhotoIdentifier::node() const
{
id const p = _v[@\\"node\\"];
return JS::NativeCameraRollManager::PhotoIdentifierNode(p);
}
inline NSString *JS::NativeCameraRollManager::PhotoIdentifierImage::uri() const
{
id const p = _v[@\\"uri\\"];
return RCTBridgingToString(p);
}
inline double JS::NativeCameraRollManager::PhotoIdentifierImage::playableDuration() const
{
id const p = _v[@\\"playableDuration\\"];
return RCTBridgingToDouble(p);
}
inline double JS::NativeCameraRollManager::PhotoIdentifierImage::width() const
{
id const p = _v[@\\"width\\"];
return RCTBridgingToDouble(p);
}
inline double JS::NativeCameraRollManager::PhotoIdentifierImage::height() const
{
id const p = _v[@\\"height\\"];
return RCTBridgingToDouble(p);
}
inline folly::Optional<bool> JS::NativeCameraRollManager::PhotoIdentifierImage::isStored() const
{
id const p = _v[@\\"isStored\\"];
return RCTBridgingToOptionalBool(p);
}
inline NSString *JS::NativeCameraRollManager::PhotoIdentifierImage::filename() const
{
id const p = _v[@\\"filename\\"];
return RCTBridgingToString(p);
}
inline bool JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::has_next_page() const
{
id const p = _v[@\\"has_next_page\\"];
return RCTBridgingToBool(p);
}
inline NSString *JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::start_cursor() const
{
id const p = _v[@\\"start_cursor\\"];
return RCTBridgingToString(p);
}
inline NSString *JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::end_cursor() const
{
id const p = _v[@\\"end_cursor\\"];
return RCTBridgingToString(p);
}
inline JS::NativeCameraRollManager::PhotoIdentifierImage JS::NativeCameraRollManager::PhotoIdentifierNode::image() const
{
id const p = _v[@\\"image\\"];
return JS::NativeCameraRollManager::PhotoIdentifierImage(p);
}
inline NSString *JS::NativeCameraRollManager::PhotoIdentifierNode::type() const
{
id const p = _v[@\\"type\\"];
return RCTBridgingToString(p);
}
inline NSString *JS::NativeCameraRollManager::PhotoIdentifierNode::group_name() const
{
id const p = _v[@\\"group_name\\"];
return RCTBridgingToString(p);
}
inline double JS::NativeCameraRollManager::PhotoIdentifierNode::timestamp() const
{
id const p = _v[@\\"timestamp\\"];
return RCTBridgingToDouble(p);
}
inline JS::NativeCameraRollManager::PhotoIdentifierNodeLocation JS::NativeCameraRollManager::PhotoIdentifierNode::location() const
{
id const p = _v[@\\"location\\"];
return JS::NativeCameraRollManager::PhotoIdentifierNodeLocation(p);
}
inline double JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::longitude() const
{
id const p = _v[@\\"longitude\\"];
return RCTBridgingToDouble(p);
}
inline double JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::latitude() const
{
id const p = _v[@\\"latitude\\"];
return RCTBridgingToDouble(p);
}
inline folly::Optional<double> JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::altitude() const
{
id const p = _v[@\\"altitude\\"];
return RCTBridgingToOptionalDouble(p);
}
inline folly::Optional<double> JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::heading() const
{
id const p = _v[@\\"heading\\"];
return RCTBridgingToOptionalDouble(p);
}
inline folly::Optional<double> JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::speed() const
{
id const p = _v[@\\"speed\\"];
return RCTBridgingToOptionalDouble(p);
}
@protocol NativeCameraRollManagerSpec <RCTBridgeModule, RCTTurboModule>
- (void) getPhotos:(JS::NativeCameraRollManager::GetPhotosParams &)params
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
- (void) saveToCameraRoll:(NSString *)uri
type:(NSString *)type
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
- (void) deletePhotos:(NSArray *)assets
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
@end
namespace JS {
namespace NativeExceptionsManager {
struct StackFrame {
folly::Optional<double> column() const;
NSString *file() const;
folly::Optional<double> lineNumber() const;
NSString *methodName() const;
folly::Optional<bool> collapse() const;
StackFrame(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeExceptionsManager_StackFrame)
+ (RCTManagedPointer *)JS_NativeExceptionsManager_StackFrame:(id)json;
@end
namespace JS {
namespace NativeExceptionsManager {
struct ExceptionData {
NSString *message() const;
NSString *originalMessage() const;
NSString *name() const;
NSString *componentStack() const;
facebook::react::LazyVector<JS::NativeExceptionsManager::StackFrame> stack() const;
double id_() const;
bool isFatal() const;
id<NSObject> _Nullable extraData() const;
ExceptionData(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeExceptionsManager_ExceptionData)
+ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json;
@end
inline NSString *JS::NativeExceptionsManager::ExceptionData::message() const
{
id const p = _v[@\\"message\\"];
return RCTBridgingToString(p);
}
inline NSString *JS::NativeExceptionsManager::ExceptionData::originalMessage() const
{
id const p = _v[@\\"originalMessage\\"];
return RCTBridgingToString(p);
}
inline NSString *JS::NativeExceptionsManager::ExceptionData::name() const
{
id const p = _v[@\\"name\\"];
return RCTBridgingToString(p);
}
inline NSString *JS::NativeExceptionsManager::ExceptionData::componentStack() const
{
id const p = _v[@\\"componentStack\\"];
return RCTBridgingToString(p);
}
inline facebook::react::LazyVector<JS::NativeExceptionsManager::StackFrame> JS::NativeExceptionsManager::ExceptionData::stack() const
{
id const p = _v[@\\"stack\\"];
return RCTBridgingToVec(p, ^JS::NativeExceptionsManager::StackFrame(id itemValue_0) { return JS::NativeExceptionsManager::StackFrame(itemValue_0); });
}
inline double JS::NativeExceptionsManager::ExceptionData::id_() const
{
id const p = _v[@\\"id_\\"];
return RCTBridgingToDouble(p);
}
inline bool JS::NativeExceptionsManager::ExceptionData::isFatal() const
{
id const p = _v[@\\"isFatal\\"];
return RCTBridgingToBool(p);
}
inline id<NSObject> _Nullable JS::NativeExceptionsManager::ExceptionData::extraData() const
{
id const p = _v[@\\"extraData\\"];
return p;
}
inline folly::Optional<double> JS::NativeExceptionsManager::StackFrame::column() const
{
id const p = _v[@\\"column\\"];
return RCTBridgingToOptionalDouble(p);
}
inline NSString *JS::NativeExceptionsManager::StackFrame::file() const
{
id const p = _v[@\\"file\\"];
return RCTBridgingToString(p);
}
inline folly::Optional<double> JS::NativeExceptionsManager::StackFrame::lineNumber() const
{
id const p = _v[@\\"lineNumber\\"];
return RCTBridgingToOptionalDouble(p);
}
inline NSString *JS::NativeExceptionsManager::StackFrame::methodName() const
{
id const p = _v[@\\"methodName\\"];
return RCTBridgingToString(p);
}
inline folly::Optional<bool> JS::NativeExceptionsManager::StackFrame::collapse() const
{
id const p = _v[@\\"collapse\\"];
return RCTBridgingToOptionalBool(p);
}
@protocol NativeExceptionsManagerSpec <RCTBridgeModule, RCTTurboModule>
- (void) reportFatalException:(NSString *)message
stack:(NSArray *)stack
exceptionId:(double)exceptionId;
- (void) reportSoftException:(NSString *)message
stack:(NSArray *)stack
exceptionId:(double)exceptionId;
- (void) reportException:(JS::NativeExceptionsManager::ExceptionData &)data;
- (void) updateExceptionMessage:(NSString *)message
stack:(NSArray *)stack
exceptionId:(double)exceptionId;
- (void) dismissRedbox;
@end
namespace JS {
namespace NativeImagePickerIOS {
struct SpecOpenCameraDialogConfig {
bool unmirrorFrontFacingCamera() const;
bool videoMode() const;
SpecOpenCameraDialogConfig(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig)
+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json;
@end
inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::unmirrorFrontFacingCamera() const
{
id const p = _v[@\\"unmirrorFrontFacingCamera\\"];
return RCTBridgingToBool(p);
}
inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::videoMode() const
{
id const p = _v[@\\"videoMode\\"];
return RCTBridgingToBool(p);
}
@protocol NativeImagePickerIOSSpec <RCTBridgeModule, RCTTurboModule>
- (void) openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config
successCallback:(RCTResponseSenderBlock)successCallback
cancelCallback:(RCTResponseSenderBlock)cancelCallback;
@end
namespace facebook {
namespace react {
/**
* ObjC++ class for module 'CameraRollManager'
*/
class JSI_EXPORT NativeCameraRollManagerSpecJSI : public ObjCTurboModule {
public:
NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams &params);
};
/**
* ObjC++ class for module 'ExceptionsManager'
*/
class JSI_EXPORT NativeExceptionsManagerSpecJSI : public ObjCTurboModule {
public:
NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams &params);
};
/**
* ObjC++ class for module 'ImagePickerIOS'
*/
class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule {
public:
NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams &params);
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateModuleHObjCpp can generate fixture SIMPLE_NATIVE_MODULES 1`] = `
Map {
"SampleSpec.h" => "
@@ -132,6 +132,248 @@ namespace facebook {
}
`;
exports[`GenerateModuleHObjCpp can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = `
Map {
"SampleSpec-generated.mm" => "
/**
* Copyright (c) Facebook, Inc. and its 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: GenerateModuleMm.js
*/
#include <SampleSpec/SampleSpec.h>
#import <folly/Optional.h>
@implementation RCTCxxConvert (NativeAliasTurboModule_Options)
+ (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json
{
return facebook::react::managedPointer<JS::NativeAliasTurboModule::Options>(json);
}
@end
@implementation RCTCxxConvert (NativeAliasTurboModule_OptionsOffset)
+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json
{
return facebook::react::managedPointer<JS::NativeAliasTurboModule::OptionsOffset>(json);
}
@end
@implementation RCTCxxConvert (NativeAliasTurboModule_OptionsSize)
+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsSize:(id)json
{
return facebook::react::managedPointer<JS::NativeAliasTurboModule::OptionsSize>(json);
}
@end
@implementation RCTCxxConvert (NativeAliasTurboModule_OptionsDisplaySize)
+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsDisplaySize:(id)json
{
return facebook::react::managedPointer<JS::NativeAliasTurboModule::OptionsDisplaySize>(json);
}
@end
namespace facebook {
namespace react {
static facebook::jsi::Value __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, VoidKind, \\"cropImage\\", @selector(cropImage:), args, count);
}
NativeAliasTurboModuleSpecJSI::NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams &params)
: ObjCTurboModule(params) {
methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage};
setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_Options:\\");
}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateModuleHObjCpp can generate fixture REAL_MODULE_EXAMPLE 1`] = `
Map {
"SampleSpec-generated.mm" => "
/**
* Copyright (c) Facebook, Inc. and its 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: GenerateModuleMm.js
*/
#include <SampleSpec/SampleSpec.h>
#import <folly/Optional.h>
@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierImage)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierImage:(id)json
{
return facebook::react::managedPointer<JS::NativeCameraRollManager::PhotoIdentifierImage>(json);
}
@end
@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifier)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifier:(id)json
{
return facebook::react::managedPointer<JS::NativeCameraRollManager::PhotoIdentifier>(json);
}
@end
@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPage)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json
{
return facebook::react::managedPointer<JS::NativeCameraRollManager::PhotoIdentifiersPage>(json);
}
@end
@implementation RCTCxxConvert (NativeCameraRollManager_GetPhotosParams)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json
{
return facebook::react::managedPointer<JS::NativeCameraRollManager::GetPhotosParams>(json);
}
@end
@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNode)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNode:(id)json
{
return facebook::react::managedPointer<JS::NativeCameraRollManager::PhotoIdentifierNode>(json);
}
@end
@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPagePage_info)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPagePage_info:(id)json
{
return facebook::react::managedPointer<JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info>(json);
}
@end
@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNodeLocation)
+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNodeLocation:(id)json
{
return facebook::react::managedPointer<JS::NativeCameraRollManager::PhotoIdentifierNodeLocation>(json);
}
@end
@implementation RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig)
+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json
{
return facebook::react::managedPointer<JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig>(json);
}
@end
@implementation RCTCxxConvert (NativeExceptionsManager_StackFrame)
+ (RCTManagedPointer *)JS_NativeExceptionsManager_StackFrame:(id)json
{
return facebook::react::managedPointer<JS::NativeExceptionsManager::StackFrame>(json);
}
@end
@implementation RCTCxxConvert (NativeExceptionsManager_ExceptionData)
+ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json
{
return facebook::react::managedPointer<JS::NativeExceptionsManager::ExceptionData>(json);
}
@end
namespace facebook {
namespace react {
static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, PromiseKind, \\"getPhotos\\", @selector(getPhotos:resolve:reject:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, PromiseKind, \\"saveToCameraRoll\\", @selector(saveToCameraRoll:type:resolve:reject:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, PromiseKind, \\"deletePhotos\\", @selector(deletePhotos:resolve:reject:), args, count);
}
NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams &params)
: ObjCTurboModule(params) {
methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos};
methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll};
methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos};
setMethodArgConversionSelector(@\\"getPhotos\\", 0, @\\"JS_NativeCameraRollManager_GetPhotosParams:\\");
}
static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count);
}
NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams &params)
: ObjCTurboModule(params) {
methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog};
setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\");
}
static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, VoidKind, \\"reportFatalException\\", @selector(reportFatalException:stack:exceptionId:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, VoidKind, \\"reportSoftException\\", @selector(reportSoftException:stack:exceptionId:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, VoidKind, \\"reportException\\", @selector(reportException:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, VoidKind, \\"updateExceptionMessage\\", @selector(updateExceptionMessage:stack:exceptionId:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule &>(turboModule)
.invokeObjCMethod(rt, VoidKind, \\"dismissRedbox\\", @selector(dismissRedbox), args, count);
}
NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams &params)
: ObjCTurboModule(params) {
methodMap_[\\"reportFatalException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException};
methodMap_[\\"reportSoftException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException};
methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportException};
methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage};
methodMap_[\\"dismissRedbox\\"] = MethodMetadata {0, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox};
setMethodArgConversionSelector(@\\"reportException\\", 0, @\\"JS_NativeExceptionsManager_ExceptionData:\\");
}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateModuleHObjCpp can generate fixture SIMPLE_NATIVE_MODULES 1`] = `
Map {
"SampleSpec-generated.mm" => "