@react-native-windows/codegen 0.0.0-canary.9 → 0.0.1-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +726 -15
  2. package/README.md +1 -1
  3. package/bin.js +0 -0
  4. package/lib-commonjs/Cli.d.ts +7 -0
  5. package/lib-commonjs/Cli.js +92 -0
  6. package/lib-commonjs/Cli.js.map +1 -0
  7. package/lib-commonjs/generators/AliasGen.d.ts +12 -0
  8. package/lib-commonjs/generators/AliasGen.js +88 -0
  9. package/lib-commonjs/generators/AliasGen.js.map +1 -0
  10. package/lib-commonjs/generators/AliasManaging.d.ts +15 -0
  11. package/lib-commonjs/generators/AliasManaging.js +49 -0
  12. package/lib-commonjs/generators/AliasManaging.js.map +1 -0
  13. package/lib-commonjs/generators/GenerateNM2.d.ts +15 -0
  14. package/lib-commonjs/generators/GenerateNM2.js +142 -0
  15. package/lib-commonjs/generators/GenerateNM2.js.map +1 -0
  16. package/lib-commonjs/generators/GenerateTypeScript.d.ts +11 -0
  17. package/lib-commonjs/generators/GenerateTypeScript.js +166 -0
  18. package/lib-commonjs/generators/GenerateTypeScript.js.map +1 -0
  19. package/lib-commonjs/generators/ObjectTypes.d.ts +13 -0
  20. package/lib-commonjs/generators/ObjectTypes.js +75 -0
  21. package/lib-commonjs/generators/ObjectTypes.js.map +1 -0
  22. package/lib-commonjs/generators/ParamTypes.d.ts +12 -0
  23. package/lib-commonjs/generators/ParamTypes.js +137 -0
  24. package/lib-commonjs/generators/ParamTypes.js.map +1 -0
  25. package/lib-commonjs/generators/ReturnTypes.d.ts +10 -0
  26. package/lib-commonjs/generators/ReturnTypes.js +29 -0
  27. package/lib-commonjs/generators/ReturnTypes.js.map +1 -0
  28. package/lib-commonjs/generators/ValidateConstants.d.ts +8 -0
  29. package/lib-commonjs/generators/ValidateConstants.js +38 -0
  30. package/lib-commonjs/generators/ValidateConstants.js.map +1 -0
  31. package/lib-commonjs/generators/ValidateMethods.d.ts +9 -0
  32. package/lib-commonjs/generators/ValidateMethods.js +75 -0
  33. package/lib-commonjs/generators/ValidateMethods.js.map +1 -0
  34. package/lib-commonjs/index.d.ts +37 -0
  35. package/lib-commonjs/index.js +224 -0
  36. package/lib-commonjs/index.js.map +1 -0
  37. package/package.json +37 -20
  38. package/src/Cli.ts +57 -190
  39. package/src/generators/AliasGen.ts +149 -0
  40. package/src/generators/AliasManaging.ts +75 -0
  41. package/src/generators/GenerateNM2.ts +138 -295
  42. package/src/generators/GenerateTypeScript.ts +247 -0
  43. package/src/generators/ObjectTypes.ts +130 -0
  44. package/src/generators/ParamTypes.ts +298 -0
  45. package/src/generators/ReturnTypes.ts +70 -0
  46. package/src/generators/ValidateConstants.ts +50 -0
  47. package/src/generators/ValidateMethods.ts +177 -0
  48. package/src/index.ts +393 -0
  49. package/.eslintrc.js +0 -4
  50. package/.vscode/launch.json +0 -23
  51. package/CHANGELOG.json +0 -583
  52. package/jest.config.js +0 -1
  53. package/tsconfig.json +0 -5
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ * Licensed under the MIT License.
4
+ * @format
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ import type {
10
+ NamedShape,
11
+ NativeModuleBaseTypeAnnotation,
12
+ NativeModuleFunctionTypeAnnotation,
13
+ NativeModuleObjectTypeAnnotation,
14
+ NativeModuleParamTypeAnnotation,
15
+ NativeModuleReturnTypeAnnotation,
16
+ NativeModuleSchema,
17
+ Nullable,
18
+ SchemaType,
19
+ } from '@react-native/codegen/lib/CodegenSchema';
20
+
21
+ interface CodegenNativeModuleSchema extends NativeModuleSchema {
22
+ optionalTurboModule?: boolean;
23
+ }
24
+
25
+ export function setOptionalTurboModule(
26
+ schema: NativeModuleSchema,
27
+ optional: boolean,
28
+ ): void {
29
+ const cs = <CodegenNativeModuleSchema>schema;
30
+ cs.optionalTurboModule = optional;
31
+ }
32
+
33
+ export function getOptionalTurboModule(schema: NativeModuleSchema): boolean {
34
+ return (<CodegenNativeModuleSchema>schema).optionalTurboModule ?? false;
35
+ }
36
+
37
+ type ObjectProp = NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>;
38
+ type FunctionParam = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
39
+ type FunctionDecl = NamedShape<Nullable<NativeModuleFunctionTypeAnnotation>>;
40
+ type FilesOutput = Map<string, string>;
41
+
42
+ const moduleTemplate = `
43
+ /*
44
+ * This file is auto-generated from a NativeModule spec file in js.
45
+ *
46
+ * This is a TypeScript turbo module definition file.
47
+ */
48
+
49
+ import {TurboModule, TurboModuleRegistry} from 'react-native';
50
+ 'use strict';
51
+ ::_MODULE_ALIASED_STRUCTS_::
52
+ export interface Spec extends TurboModule {
53
+ ::_MODULE_MEMBERS_::
54
+ }
55
+
56
+ export default TurboModuleRegistry.::_MODULE_GETTER_::<Spec>('::_MODULE_NAME_::');
57
+ `;
58
+
59
+ function optionalSign<T>(obj: NamedShape<T>): string {
60
+ return obj.optional ? '?' : '';
61
+ }
62
+
63
+ function translateType(
64
+ type: Nullable<
65
+ | NativeModuleBaseTypeAnnotation
66
+ | NativeModuleParamTypeAnnotation
67
+ | NativeModuleReturnTypeAnnotation
68
+ >,
69
+ ): string {
70
+ // avoid: Property 'type' does not exist on type 'never'
71
+ const returnType = type.type;
72
+ switch (type.type) {
73
+ case 'StringTypeAnnotation':
74
+ return 'string';
75
+ case 'NumberTypeAnnotation':
76
+ case 'FloatTypeAnnotation':
77
+ case 'DoubleTypeAnnotation':
78
+ case 'Int32TypeAnnotation':
79
+ return 'number';
80
+ case 'BooleanTypeAnnotation':
81
+ return 'boolean';
82
+ case 'ArrayTypeAnnotation':
83
+ if (type.elementType) {
84
+ return `${translateType(type.elementType)}[]`;
85
+ } else {
86
+ return `Array`;
87
+ }
88
+ case 'GenericObjectTypeAnnotation':
89
+ return 'object';
90
+ case 'ObjectTypeAnnotation':
91
+ return `{${type.properties
92
+ .map((prop: ObjectProp) => {
93
+ return `${prop.name}${optionalSign(prop)}: ${translateType(
94
+ prop.typeAnnotation,
95
+ )}`;
96
+ })
97
+ .join(', ')}}`;
98
+ case 'ReservedTypeAnnotation': {
99
+ // avoid: Property 'name' does not exist on type 'never'
100
+ const name = type.name;
101
+ // (#6597)
102
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
103
+ if (name !== 'RootTag')
104
+ throw new Error(
105
+ `Unknown reserved function: ${name} in translateReturnType`,
106
+ );
107
+ return 'number';
108
+ }
109
+ case 'TypeAliasTypeAnnotation':
110
+ return type.name;
111
+ case 'NullableTypeAnnotation':
112
+ return `(${translateType(type.typeAnnotation)} | null | undefined)`;
113
+ case 'VoidTypeAnnotation':
114
+ return `void`;
115
+ case 'PromiseTypeAnnotation':
116
+ return `Promise`;
117
+ case `FunctionTypeAnnotation`:
118
+ return `((${type.params
119
+ .map((param: FunctionParam) => {
120
+ return `${param.name}${optionalSign(param)}: ${translateType(
121
+ param.typeAnnotation,
122
+ )}`;
123
+ })
124
+ .join(', ')}) => ${translateType(type.returnTypeAnnotation)})`;
125
+ default:
126
+ throw new Error(`Unhandled type in translateReturnType: ${returnType}`);
127
+ }
128
+ }
129
+
130
+ function translateAlias(
131
+ name: string,
132
+ type: NativeModuleObjectTypeAnnotation,
133
+ ): string {
134
+ return `
135
+ export interface ${name} {
136
+ ${type.properties
137
+ .map((prop: ObjectProp) => {
138
+ return ` ${prop.name}${optionalSign(prop)}: ${translateType(
139
+ prop.typeAnnotation,
140
+ )};`;
141
+ })
142
+ .join('\n')}
143
+ }
144
+ `;
145
+ }
146
+
147
+ function tryGetConstantType(
148
+ nativeModule: NativeModuleSchema,
149
+ ): NativeModuleObjectTypeAnnotation | undefined {
150
+ const candidates = nativeModule.spec.properties.filter(
151
+ prop => prop.name === 'getConstants',
152
+ );
153
+ if (candidates.length === 0) {
154
+ return undefined;
155
+ }
156
+
157
+ const getConstant = candidates[0];
158
+ const funcType =
159
+ getConstant.typeAnnotation.type === 'NullableTypeAnnotation'
160
+ ? getConstant.typeAnnotation.typeAnnotation
161
+ : getConstant.typeAnnotation;
162
+ if (
163
+ funcType.params.length > 0 ||
164
+ funcType.returnTypeAnnotation.type !== 'ObjectTypeAnnotation'
165
+ ) {
166
+ return undefined;
167
+ }
168
+
169
+ const constantType = funcType.returnTypeAnnotation;
170
+ if (constantType.properties.length === 0) {
171
+ return undefined;
172
+ }
173
+
174
+ return constantType;
175
+ }
176
+
177
+ function translateMethod(func: FunctionDecl): string {
178
+ const funcType =
179
+ func.typeAnnotation.type === 'NullableTypeAnnotation'
180
+ ? func.typeAnnotation.typeAnnotation
181
+ : func.typeAnnotation;
182
+
183
+ return `
184
+ ${func.name}(${funcType.params
185
+ .map((param: FunctionParam) => {
186
+ return `${param.name}${optionalSign(param)}: ${translateType(
187
+ param.typeAnnotation,
188
+ )}`;
189
+ })
190
+ .join(', ')})${optionalSign(func)}: ${translateType(
191
+ funcType.returnTypeAnnotation,
192
+ )}${
193
+ funcType.returnTypeAnnotation.type === 'ObjectTypeAnnotation' ? '' : ';'
194
+ }`;
195
+ }
196
+
197
+ export function generateTypeScript(
198
+ _libraryName: string,
199
+ schema: SchemaType,
200
+ _moduleSpecName: string,
201
+ ): FilesOutput {
202
+ const files = new Map<string, string>();
203
+
204
+ for (const moduleName of Object.keys(schema.modules)) {
205
+ const nativeModule = schema.modules[moduleName];
206
+ // from 0.65 facebook's react-native-codegen
207
+ // the module name has the Native prefix comparing to 0.63
208
+ // when reading files we provided
209
+ const nativePrefix = 'Native';
210
+ const preferredModuleName = moduleName.startsWith(nativePrefix)
211
+ ? moduleName.substr(nativePrefix.length)
212
+ : moduleName;
213
+
214
+ if (nativeModule.type === 'NativeModule') {
215
+ console.log(`Generating ${preferredModuleName}Spec.g.ts`);
216
+
217
+ const aliasCode = Object.keys(nativeModule.aliasMap)
218
+ .map(name => translateAlias(name, nativeModule.aliasMap[name]))
219
+ .join('');
220
+
221
+ const constantType = tryGetConstantType(nativeModule);
222
+ const constantCode =
223
+ constantType === undefined
224
+ ? ''
225
+ : ` getConstants(): ${translateType(constantType)}`;
226
+
227
+ const methods = nativeModule.spec.properties.filter(
228
+ prop => prop.name !== 'getConstants',
229
+ );
230
+ const membersCode = methods.map(translateMethod).join('');
231
+
232
+ files.set(
233
+ `${preferredModuleName}Spec.g.ts`,
234
+ moduleTemplate
235
+ .replace(/::_MODULE_ALIASED_STRUCTS_::/g, aliasCode)
236
+ .replace(/::_MODULE_MEMBERS_::/g, constantCode + membersCode)
237
+ .replace(/::_MODULE_NAME_::/g, preferredModuleName)
238
+ .replace(
239
+ /::_MODULE_GETTER_::/g,
240
+ getOptionalTurboModule(nativeModule) ? 'get' : 'getEnforcing',
241
+ ),
242
+ );
243
+ }
244
+ }
245
+
246
+ return files;
247
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ * Licensed under the MIT License.
4
+ * @format
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ import type {
10
+ NativeModuleEnumDeclaration,
11
+ NativeModuleBaseTypeAnnotation,
12
+ NativeModuleUnionTypeAnnotation,
13
+ NativeModuleStringTypeAnnotation,
14
+ NativeModuleFunctionTypeAnnotation,
15
+ Nullable,
16
+ } from '@react-native/codegen/lib/CodegenSchema';
17
+ import {
18
+ AliasMap,
19
+ getAliasCppName,
20
+ getAnonymousAliasCppName,
21
+ } from './AliasManaging';
22
+
23
+ export type CppStringTypes = 'std::string' | 'std::wstring';
24
+
25
+ export interface CppCodegenOptions {
26
+ cppStringType: CppStringTypes;
27
+ }
28
+
29
+ function translateUnionReturnType(
30
+ type: NativeModuleEnumDeclaration | NativeModuleUnionTypeAnnotation,
31
+ options: CppCodegenOptions,
32
+ ): string {
33
+ const memberType = type.memberType;
34
+ switch (type.memberType) {
35
+ case 'StringTypeAnnotation':
36
+ return options.cppStringType;
37
+ case 'NumberTypeAnnotation':
38
+ return 'double';
39
+ case 'ObjectTypeAnnotation':
40
+ return '::React::JSValue';
41
+ default:
42
+ throw new Error(
43
+ `Unknown enum/union member type in translateReturnType: ${memberType}`,
44
+ );
45
+ }
46
+ }
47
+
48
+ export function translateFieldOrReturnType(
49
+ type: Nullable<
50
+ | NativeModuleBaseTypeAnnotation
51
+ | NativeModuleStringTypeAnnotation
52
+ | NativeModuleFunctionTypeAnnotation
53
+ >,
54
+ aliases: AliasMap,
55
+ baseAliasName: string,
56
+ callerName: 'translateField' | 'translateReturnType',
57
+ options: CppCodegenOptions,
58
+ ): string {
59
+ // avoid: Property 'type' does not exist on type 'never'
60
+ const returnType = type.type;
61
+ switch (type.type) {
62
+ case 'StringTypeAnnotation':
63
+ return options.cppStringType;
64
+ case 'NumberTypeAnnotation':
65
+ case 'FloatTypeAnnotation':
66
+ case 'DoubleTypeAnnotation':
67
+ return 'double';
68
+ case 'Int32TypeAnnotation':
69
+ return 'int';
70
+ case 'BooleanTypeAnnotation':
71
+ return 'bool';
72
+ case 'ArrayTypeAnnotation':
73
+ if (type.elementType) {
74
+ return `std::vector<${translateFieldOrReturnType(
75
+ type.elementType,
76
+ aliases,
77
+ `${baseAliasName}_element`,
78
+ callerName,
79
+ options,
80
+ )}>`;
81
+ } else {
82
+ return `::React::JSValueArray`;
83
+ }
84
+ case 'GenericObjectTypeAnnotation':
85
+ return '::React::JSValue';
86
+ case 'ObjectTypeAnnotation':
87
+ return getAnonymousAliasCppName(aliases, baseAliasName, type);
88
+ case 'ReservedTypeAnnotation': {
89
+ // avoid: Property 'name' does not exist on type 'never'
90
+ const name = type.name;
91
+ // (#6597)
92
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
93
+ if (name !== 'RootTag')
94
+ throw new Error(`Unknown reserved function: ${name} in ${callerName}`);
95
+ return 'double';
96
+ }
97
+ case 'TypeAliasTypeAnnotation':
98
+ return getAliasCppName(type.name);
99
+ case 'NullableTypeAnnotation':
100
+ return `std::optional<${translateFieldOrReturnType(
101
+ type.typeAnnotation,
102
+ aliases,
103
+ baseAliasName,
104
+ callerName,
105
+ options,
106
+ )}>`;
107
+ case 'MixedTypeAnnotation':
108
+ return '';
109
+ case 'EnumDeclaration':
110
+ case 'UnionTypeAnnotation':
111
+ return translateUnionReturnType(type, options);
112
+ default:
113
+ throw new Error(`Unhandled type in ${callerName}: ${returnType}`);
114
+ }
115
+ }
116
+
117
+ export function translateField(
118
+ type: Nullable<NativeModuleBaseTypeAnnotation>,
119
+ aliases: AliasMap,
120
+ baseAliasName: string,
121
+ options: CppCodegenOptions,
122
+ ): string {
123
+ return translateFieldOrReturnType(
124
+ type,
125
+ aliases,
126
+ baseAliasName,
127
+ 'translateField',
128
+ options,
129
+ );
130
+ }
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ * Licensed under the MIT License.
4
+ * @format
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ import type {
10
+ NamedShape,
11
+ NativeModuleArrayTypeAnnotation,
12
+ NativeModuleBaseTypeAnnotation,
13
+ NativeModuleEnumDeclaration,
14
+ NativeModuleFunctionTypeAnnotation,
15
+ NativeModuleParamTypeAnnotation,
16
+ NativeModuleUnionTypeAnnotation,
17
+ Nullable,
18
+ } from '@react-native/codegen/lib/CodegenSchema';
19
+ import {
20
+ AliasMap,
21
+ getAliasCppName,
22
+ getAnonymousAliasCppName,
23
+ } from './AliasManaging';
24
+ import type {CppCodegenOptions} from './ObjectTypes';
25
+
26
+ type NativeModuleParamShape = NamedShape<
27
+ Nullable<NativeModuleParamTypeAnnotation>
28
+ >;
29
+
30
+ type ParamTarget = 'spec' | 'template' | 'callback-arg' | 'method-arg';
31
+
32
+ function decorateType(type: string, target: ParamTarget): string {
33
+ switch (target) {
34
+ case 'method-arg':
35
+ return `${type} &&`;
36
+ case 'callback-arg':
37
+ return `${type} const &`;
38
+ default:
39
+ return type;
40
+ }
41
+ }
42
+
43
+ function translateUnionReturnType(
44
+ type: NativeModuleEnumDeclaration | NativeModuleUnionTypeAnnotation,
45
+ target: ParamTarget,
46
+ options: CppCodegenOptions,
47
+ ): string {
48
+ const memberType = type.memberType;
49
+ switch (type.memberType) {
50
+ case 'StringTypeAnnotation':
51
+ return options.cppStringType;
52
+ case 'NumberTypeAnnotation':
53
+ return 'double';
54
+ case 'ObjectTypeAnnotation':
55
+ return decorateType('::React::JSValue', target);
56
+ default:
57
+ throw new Error(
58
+ `Unknown enum/union member type in translateReturnType: ${memberType}`,
59
+ );
60
+ }
61
+ }
62
+
63
+ function translateFunction(
64
+ param: NativeModuleFunctionTypeAnnotation,
65
+ aliases: AliasMap,
66
+ baseAliasName: string,
67
+ target: ParamTarget,
68
+ options: CppCodegenOptions,
69
+ ): string {
70
+ // TODO: type.returnTypeAnnotation
71
+ switch (target) {
72
+ case 'spec':
73
+ return `Callback<${param.params
74
+ .map((p: NativeModuleParamShape) =>
75
+ translateSpecFunctionParam(
76
+ p,
77
+ aliases,
78
+ `${baseAliasName}_${p.name}`,
79
+ options,
80
+ ),
81
+ )
82
+ .join(', ')}>`;
83
+ case 'template':
84
+ return `std::function<void(${param.params
85
+ .map((p: NativeModuleParamShape) =>
86
+ translateCallbackParam(
87
+ p,
88
+ aliases,
89
+ `${baseAliasName}_${p.name}`,
90
+ options,
91
+ ),
92
+ )
93
+ .join(', ')})>`;
94
+ default:
95
+ return `std::function<void(${param.params
96
+ .map((p: NativeModuleParamShape) =>
97
+ translateCallbackParam(
98
+ p,
99
+ aliases,
100
+ `${baseAliasName}_${p.name}`,
101
+ options,
102
+ ),
103
+ )
104
+ .join(', ')})> const &`;
105
+ }
106
+ }
107
+
108
+ function translateArray(
109
+ param: NativeModuleArrayTypeAnnotation<
110
+ Nullable<NativeModuleBaseTypeAnnotation>
111
+ >,
112
+ aliases: AliasMap,
113
+ baseAliasName: string,
114
+ target: ParamTarget,
115
+ options: CppCodegenOptions,
116
+ ): string {
117
+ if (param.elementType) {
118
+ switch (target) {
119
+ case 'spec':
120
+ case 'template':
121
+ return `std::vector<${translateNullableParamType(
122
+ param.elementType,
123
+ aliases,
124
+ `${baseAliasName}_element`,
125
+ 'template',
126
+ 'template',
127
+ options,
128
+ )}>`;
129
+ default:
130
+ return `std::vector<${translateNullableParamType(
131
+ param.elementType,
132
+ aliases,
133
+ `${baseAliasName}_element`,
134
+ 'template',
135
+ 'template',
136
+ options,
137
+ )}> const &`;
138
+ }
139
+ } else {
140
+ return decorateType('::React::JSValueArray', target);
141
+ }
142
+ }
143
+
144
+ function translateParam(
145
+ param: NativeModuleParamTypeAnnotation,
146
+ aliases: AliasMap,
147
+ baseAliasName: string,
148
+ target: ParamTarget,
149
+ options: CppCodegenOptions,
150
+ ): string {
151
+ // avoid: Property 'type' does not exist on type 'never'
152
+ const paramType = param.type;
153
+ switch (param.type) {
154
+ case 'StringTypeAnnotation':
155
+ return options.cppStringType;
156
+ case 'NumberTypeAnnotation':
157
+ case 'FloatTypeAnnotation':
158
+ case 'DoubleTypeAnnotation':
159
+ return 'double';
160
+ case 'Int32TypeAnnotation':
161
+ return 'int';
162
+ case 'BooleanTypeAnnotation':
163
+ return 'bool';
164
+ case 'FunctionTypeAnnotation':
165
+ return translateFunction(param, aliases, baseAliasName, target, options);
166
+ case 'ArrayTypeAnnotation':
167
+ return translateArray(param, aliases, baseAliasName, target, options);
168
+ case 'GenericObjectTypeAnnotation':
169
+ return decorateType('::React::JSValue', target);
170
+ case 'ObjectTypeAnnotation':
171
+ return decorateType(
172
+ getAnonymousAliasCppName(aliases, baseAliasName, param),
173
+ target,
174
+ );
175
+ case 'ReservedTypeAnnotation': {
176
+ // avoid: Property 'name' does not exist on type 'never'
177
+ const name = param.name;
178
+ // (#6597)
179
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
180
+ if (name !== 'RootTag')
181
+ throw new Error(`Unknown reserved function: ${name} in translateParam`);
182
+ return 'double';
183
+ }
184
+ case 'TypeAliasTypeAnnotation':
185
+ return decorateType(getAliasCppName(param.name), target);
186
+ case 'MixedTypeAnnotation':
187
+ return '';
188
+ case 'EnumDeclaration':
189
+ case 'UnionTypeAnnotation':
190
+ return translateUnionReturnType(param, target, options);
191
+ default:
192
+ throw new Error(`Unhandled type in translateParam: ${paramType}`);
193
+ }
194
+ }
195
+
196
+ function translateNullableParamType(
197
+ paramType: Nullable<NativeModuleParamTypeAnnotation>,
198
+ aliases: AliasMap,
199
+ baseAliasName: string,
200
+ nullableTarget: ParamTarget,
201
+ target: ParamTarget,
202
+ options: CppCodegenOptions,
203
+ ): string {
204
+ switch (paramType.type) {
205
+ case 'NullableTypeAnnotation':
206
+ return `std::optional<${translateParam(
207
+ paramType.typeAnnotation,
208
+ aliases,
209
+ baseAliasName,
210
+ nullableTarget,
211
+ options,
212
+ )}>`;
213
+ default:
214
+ return translateParam(paramType, aliases, baseAliasName, target, options);
215
+ }
216
+ }
217
+
218
+ function translateSpecFunctionParam(
219
+ param: NativeModuleParamShape,
220
+ aliases: AliasMap,
221
+ baseAliasName: string,
222
+ options: CppCodegenOptions,
223
+ ): string {
224
+ return translateNullableParamType(
225
+ param.typeAnnotation,
226
+ aliases,
227
+ baseAliasName,
228
+ 'spec',
229
+ 'spec',
230
+ options,
231
+ );
232
+ }
233
+
234
+ function translateCallbackParam(
235
+ param: NativeModuleParamShape,
236
+ aliases: AliasMap,
237
+ baseAliasName: string,
238
+ options: CppCodegenOptions,
239
+ ): string {
240
+ return translateNullableParamType(
241
+ param.typeAnnotation,
242
+ aliases,
243
+ baseAliasName,
244
+ 'template',
245
+ 'callback-arg',
246
+ options,
247
+ );
248
+ }
249
+
250
+ function translateFunctionParam(
251
+ param: NativeModuleParamShape,
252
+ aliases: AliasMap,
253
+ baseAliasName: string,
254
+ options: CppCodegenOptions,
255
+ ): string {
256
+ return translateNullableParamType(
257
+ param.typeAnnotation,
258
+ aliases,
259
+ baseAliasName,
260
+ 'template',
261
+ 'method-arg',
262
+ options,
263
+ );
264
+ }
265
+
266
+ export function translateSpecArgs(
267
+ params: ReadonlyArray<NativeModuleParamShape>,
268
+ aliases: AliasMap,
269
+ baseAliasName: string,
270
+ options: CppCodegenOptions,
271
+ ) {
272
+ return params.map(param => {
273
+ const translatedParam = translateSpecFunctionParam(
274
+ param,
275
+ aliases,
276
+ `${baseAliasName}_${param.name}`,
277
+ options,
278
+ );
279
+ return `${translatedParam}`;
280
+ });
281
+ }
282
+
283
+ export function translateArgs(
284
+ params: ReadonlyArray<NativeModuleParamShape>,
285
+ aliases: AliasMap,
286
+ baseAliasName: string,
287
+ options: CppCodegenOptions,
288
+ ) {
289
+ return params.map(param => {
290
+ const translatedParam = translateFunctionParam(
291
+ param,
292
+ aliases,
293
+ `${baseAliasName}_${param.name}`,
294
+ options,
295
+ );
296
+ return `${translatedParam} ${param.name}`;
297
+ });
298
+ }