@react-native-windows/codegen 0.76.0-preview.1 → 0.76.0-preview.3
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.
- package/CHANGELOG.md +22 -5
- package/lib-commonjs/Cli.js +1 -1
- package/lib-commonjs/Cli.js.map +1 -1
- package/lib-commonjs/generators/AliasGen.js +5 -2
- package/lib-commonjs/generators/AliasGen.js.map +1 -1
- package/lib-commonjs/generators/GenerateComponentWindows.js +107 -44
- package/lib-commonjs/generators/GenerateComponentWindows.js.map +1 -1
- package/lib-commonjs/generators/GenerateNM2.js +3 -1
- package/lib-commonjs/generators/GenerateNM2.js.map +1 -1
- package/lib-commonjs/generators/GenerateTypeScript.js.map +1 -1
- package/lib-commonjs/generators/ObjectTypes.js.map +1 -1
- package/lib-commonjs/generators/ParamTypes.js.map +1 -1
- package/lib-commonjs/generators/ValidateMethods.js +9 -2
- package/lib-commonjs/generators/ValidateMethods.js.map +1 -1
- package/lib-commonjs/index.js.map +1 -1
- package/package.json +4 -4
- package/src/Cli.ts +3 -2
- package/src/generators/AliasGen.ts +27 -18
- package/src/generators/GenerateComponentWindows.ts +241 -101
- package/src/generators/GenerateNM2.ts +7 -2
- package/src/generators/GenerateTypeScript.ts +7 -5
- package/src/generators/ObjectTypes.ts +7 -5
- package/src/generators/ParamTypes.ts +21 -11
- package/src/generators/ValidateMethods.ts +29 -19
- package/src/index.ts +13 -14
|
@@ -6,9 +6,19 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
SchemaType,
|
|
11
|
+
EventTypeAnnotation,
|
|
12
|
+
PropTypeAnnotation,
|
|
13
|
+
ObjectTypeAnnotation,
|
|
14
|
+
CommandParamTypeAnnotation,
|
|
15
|
+
} from '@react-native/codegen/lib/CodegenSchema';
|
|
10
16
|
import {getAliasCppName, setPreferredModuleName} from './AliasManaging';
|
|
11
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
translateComponentPropsFieldType,
|
|
19
|
+
translateComponentEventType,
|
|
20
|
+
translateCommandParamType,
|
|
21
|
+
} from './PropObjectTypes';
|
|
12
22
|
import type {CppStringTypes} from './ObjectTypes';
|
|
13
23
|
import type {AliasMap} from './AliasManaging';
|
|
14
24
|
|
|
@@ -21,11 +31,14 @@ const headerTemplate = `/*
|
|
|
21
31
|
*/
|
|
22
32
|
#pragma once
|
|
23
33
|
|
|
24
|
-
#include <JSValueComposition.h>
|
|
25
34
|
#include <NativeModules.h>
|
|
26
|
-
#include <winrt/Microsoft.ReactNative.Composition.h>
|
|
27
|
-
#include <winrt/Microsoft.UI.Composition.h>`
|
|
28
35
|
|
|
36
|
+
#ifdef RNW_NEW_ARCH
|
|
37
|
+
#include <JSValueComposition.h>
|
|
38
|
+
|
|
39
|
+
#include <winrt/Microsoft.ReactNative.Composition.h>
|
|
40
|
+
#include <winrt/Microsoft.UI.Composition.h>
|
|
41
|
+
#endif // #ifdef RNW_NEW_ARCH`;
|
|
29
42
|
|
|
30
43
|
const propsTemplate = `REACT_STRUCT(::_PROPS_NAME_::)
|
|
31
44
|
struct ::_PROPS_NAME_:: : winrt::implements<::_PROPS_NAME_::, winrt::Microsoft::ReactNative::IComponentProps> {
|
|
@@ -37,16 +50,16 @@ struct ::_PROPS_NAME_:: : winrt::implements<::_PROPS_NAME_::, winrt::Microsoft::
|
|
|
37
50
|
|
|
38
51
|
::_PROPS_FIELDS_::
|
|
39
52
|
const winrt::Microsoft::ReactNative::ViewProps ViewProps;
|
|
40
|
-
}
|
|
53
|
+
};`;
|
|
41
54
|
|
|
42
55
|
const propsObjectTemplate = `REACT_STRUCT(::_OBJECT_NAME_::)
|
|
43
56
|
struct ::_OBJECT_NAME_:: {
|
|
44
57
|
::_OBJECT_FIELDS_::};
|
|
45
|
-
|
|
58
|
+
`;
|
|
46
59
|
const eventsObjectTemplate = `REACT_STRUCT(::_OBJECT_NAME_::)
|
|
47
60
|
struct ::_OBJECT_NAME_:: {
|
|
48
61
|
::_OBJECT_FIELDS_::};
|
|
49
|
-
|
|
62
|
+
`;
|
|
50
63
|
|
|
51
64
|
const eventEmitterMethodTemplate = ` void ::_EVENT_NAME_::(::_EVENT_OBJECT_TYPE_:: &value) const {
|
|
52
65
|
m_eventEmitter.DispatchEvent(L"::_EVENT_NAME_NO_ON_::", [value](const winrt::Microsoft::ReactNative::IJSValueWriter writer) {
|
|
@@ -54,7 +67,6 @@ const eventEmitterMethodTemplate = ` void ::_EVENT_NAME_::(::_EVENT_OBJECT_TYPE
|
|
|
54
67
|
});
|
|
55
68
|
}`;
|
|
56
69
|
|
|
57
|
-
|
|
58
70
|
const eventEmitterTemplate = `::_COMPONENT_EVENT_OBJECT_TYPES_::
|
|
59
71
|
|
|
60
72
|
struct ::_EVENT_EMITTER_NAME_:: {
|
|
@@ -67,7 +79,7 @@ struct ::_EVENT_EMITTER_NAME_:: {
|
|
|
67
79
|
|
|
68
80
|
private:
|
|
69
81
|
winrt::Microsoft::ReactNative::EventEmitter m_eventEmitter{nullptr};
|
|
70
|
-
}
|
|
82
|
+
};`;
|
|
71
83
|
|
|
72
84
|
const baseStructTemplate = `
|
|
73
85
|
template<typename TUserData>
|
|
@@ -212,6 +224,8 @@ void Register::_COMPONENT_NAME_::NativeComponent(
|
|
|
212
224
|
const fileTemplate = `
|
|
213
225
|
${headerTemplate}
|
|
214
226
|
|
|
227
|
+
#ifdef RNW_NEW_ARCH
|
|
228
|
+
|
|
215
229
|
namespace ::_NAMESPACE_:: {
|
|
216
230
|
|
|
217
231
|
::_COMPONENT_PROP_OBJECT_TYPES_::
|
|
@@ -223,11 +237,13 @@ namespace ::_NAMESPACE_:: {
|
|
|
223
237
|
|
|
224
238
|
::_COMPONENT_REGISTRATION_::
|
|
225
239
|
} // namespace ::_NAMESPACE_::
|
|
240
|
+
|
|
241
|
+
#endif // #ifdef RNW_NEW_ARCH
|
|
226
242
|
`;
|
|
227
243
|
|
|
228
244
|
function capitalizeFirstLetter(s: string) {
|
|
229
245
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
230
|
-
|
|
246
|
+
}
|
|
231
247
|
|
|
232
248
|
export function createComponentGenerator({
|
|
233
249
|
namespace,
|
|
@@ -255,114 +271,241 @@ export function createComponentGenerator({
|
|
|
255
271
|
const componentShape = component.components[componentName];
|
|
256
272
|
|
|
257
273
|
componentShape.extendsProps.forEach(propsBaseType => {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
274
|
+
if (
|
|
275
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
276
|
+
propsBaseType.type !== 'ReactNativeBuiltInType' ||
|
|
277
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
278
|
+
propsBaseType.knownTypeName !== 'ReactNativeCoreViewProps'
|
|
279
|
+
) {
|
|
280
|
+
throw new Error(
|
|
281
|
+
'Currently only supports props extending from ViewProps',
|
|
282
|
+
);
|
|
261
283
|
}
|
|
262
284
|
});
|
|
263
285
|
|
|
264
286
|
// Props
|
|
265
|
-
const propObjectAliases: AliasMap<
|
|
287
|
+
const propObjectAliases: AliasMap<
|
|
288
|
+
ObjectTypeAnnotation<PropTypeAnnotation>
|
|
289
|
+
> = {types: {}, jobs: []};
|
|
266
290
|
const propsName = `${componentName}Props`;
|
|
267
|
-
const propsFields = componentShape.props
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
291
|
+
const propsFields = componentShape.props
|
|
292
|
+
.map(prop => {
|
|
293
|
+
const propType = translateComponentPropsFieldType(
|
|
294
|
+
prop.typeAnnotation,
|
|
295
|
+
propObjectAliases,
|
|
296
|
+
`${propsName}_${prop.name}`,
|
|
297
|
+
cppCodegenOptions,
|
|
298
|
+
);
|
|
299
|
+
return ` REACT_FIELD(${prop.name})\n ${
|
|
300
|
+
prop.optional && !propType.alreadySupportsOptionalOrHasDefault
|
|
301
|
+
? `std::optional<${propType.type}>`
|
|
302
|
+
: propType.type
|
|
303
|
+
} ${prop.name}${propType.initializer};\n`;
|
|
304
|
+
})
|
|
305
|
+
.join('\n');
|
|
306
|
+
|
|
307
|
+
const propObjectTypes = propObjectAliases.jobs
|
|
308
|
+
.map(propObjectTypeName => {
|
|
309
|
+
const propObjectType = propObjectAliases.types[propObjectTypeName]!;
|
|
310
|
+
const propsObjectFields = propObjectType.properties
|
|
311
|
+
.map(property => {
|
|
312
|
+
const propType = translateComponentPropsFieldType(
|
|
313
|
+
property.typeAnnotation,
|
|
314
|
+
propObjectAliases,
|
|
315
|
+
`${propsName}_${property.name}`,
|
|
316
|
+
cppCodegenOptions,
|
|
317
|
+
);
|
|
318
|
+
return ` REACT_FIELD(${property.name})\n ${
|
|
319
|
+
property.optional &&
|
|
320
|
+
!propType.alreadySupportsOptionalOrHasDefault
|
|
321
|
+
? `std::optional<${propType.type}>`
|
|
322
|
+
: propType.type
|
|
323
|
+
} ${property.name}${propType.initializer};\n`;
|
|
324
|
+
})
|
|
325
|
+
.join('\n');
|
|
326
|
+
|
|
327
|
+
return propsObjectTemplate
|
|
328
|
+
.replace(
|
|
329
|
+
/::_OBJECT_NAME_::/g,
|
|
330
|
+
getAliasCppName(propObjectTypeName),
|
|
331
|
+
)
|
|
332
|
+
.replace(/::_OBJECT_FIELDS_::/g, propsObjectFields);
|
|
333
|
+
})
|
|
334
|
+
.join('\n');
|
|
282
335
|
|
|
283
336
|
// Events
|
|
284
|
-
const eventObjectAliases: AliasMap<
|
|
337
|
+
const eventObjectAliases: AliasMap<
|
|
338
|
+
ObjectTypeAnnotation<EventTypeAnnotation>
|
|
339
|
+
> = {types: {}, jobs: []};
|
|
285
340
|
const eventEmitterName = `${componentName}EventEmitter`;
|
|
286
|
-
const eventEmitterMethods = componentShape.events
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
341
|
+
const eventEmitterMethods = componentShape.events
|
|
342
|
+
.filter(event => event.typeAnnotation.argument)
|
|
343
|
+
.map(event => {
|
|
344
|
+
if (event.typeAnnotation.argument?.baseTypes) {
|
|
345
|
+
throw new Error(
|
|
346
|
+
'Events with base type arguments not currently supported',
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Called to collect the eventObjectAliases
|
|
351
|
+
translateComponentEventType(
|
|
352
|
+
event.typeAnnotation.argument!,
|
|
353
|
+
eventObjectAliases,
|
|
354
|
+
`${event.name}`,
|
|
355
|
+
cppCodegenOptions,
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
// onSomething -> something
|
|
359
|
+
let eventNameLower = event.name.replace('on', '');
|
|
360
|
+
eventNameLower =
|
|
361
|
+
eventNameLower[0].toLowerCase() + eventNameLower.slice(1);
|
|
362
|
+
|
|
363
|
+
return eventEmitterMethodTemplate
|
|
364
|
+
.replace(/::_EVENT_NAME_::/g, event.name)
|
|
365
|
+
.replace(/::_EVENT_NAME_NO_ON_::/g, eventNameLower)
|
|
366
|
+
.replace(
|
|
367
|
+
/::_EVENT_OBJECT_TYPE_::/g,
|
|
368
|
+
event.name.replace('on', 'On'),
|
|
369
|
+
);
|
|
370
|
+
})
|
|
371
|
+
.join('\n\n');
|
|
372
|
+
|
|
373
|
+
const eventObjects = eventObjectAliases.jobs
|
|
374
|
+
.map(eventObjectTypeName => {
|
|
375
|
+
const eventObjectType =
|
|
376
|
+
eventObjectAliases.types[eventObjectTypeName]!;
|
|
377
|
+
const eventObjectFields = eventObjectType.properties
|
|
378
|
+
.map(property => {
|
|
379
|
+
const eventPropType = translateComponentEventType(
|
|
380
|
+
property.typeAnnotation,
|
|
381
|
+
eventObjectAliases,
|
|
382
|
+
eventObjectTypeName,
|
|
383
|
+
cppCodegenOptions,
|
|
384
|
+
);
|
|
385
|
+
return ` REACT_FIELD(${property.name})\n ${
|
|
386
|
+
property.optional &&
|
|
387
|
+
!eventPropType.alreadySupportsOptionalOrHasDefault
|
|
388
|
+
? `std::optional<${eventPropType.type}>`
|
|
389
|
+
: eventPropType.type
|
|
390
|
+
} ${property.name}${eventPropType.initializer};\n`;
|
|
391
|
+
})
|
|
392
|
+
.join('\n');
|
|
393
|
+
return eventsObjectTemplate
|
|
394
|
+
.replace(
|
|
395
|
+
/::_OBJECT_NAME_::/g,
|
|
396
|
+
`${componentName}_${eventObjectTypeName.replace('on', 'On')}`,
|
|
397
|
+
)
|
|
398
|
+
.replace(/::_OBJECT_FIELDS_::/g, eventObjectFields);
|
|
399
|
+
})
|
|
400
|
+
.join('\n');
|
|
401
|
+
|
|
402
|
+
const eventObjectUsings = eventObjectAliases.jobs
|
|
403
|
+
.map(eventObjectTypeName => {
|
|
404
|
+
return ` using ${eventObjectTypeName.replace(
|
|
405
|
+
'on',
|
|
406
|
+
'On',
|
|
407
|
+
)} = ${componentName}_${eventObjectTypeName.replace('on', 'On')};`;
|
|
408
|
+
})
|
|
409
|
+
.join('\n');
|
|
290
410
|
|
|
291
|
-
// Called to collect the eventObjectAliases
|
|
292
|
-
translateComponentEventType(event.typeAnnotation.argument!, eventObjectAliases, `${event.name}`, cppCodegenOptions);
|
|
293
|
-
|
|
294
|
-
// onSomething -> something
|
|
295
|
-
let eventNameLower = event.name.replace('on', '');
|
|
296
|
-
eventNameLower = eventNameLower[0].toLowerCase() + eventNameLower.slice(1);
|
|
297
|
-
|
|
298
|
-
return eventEmitterMethodTemplate
|
|
299
|
-
.replace(/::_EVENT_NAME_::/g,event.name)
|
|
300
|
-
.replace(/::_EVENT_NAME_NO_ON_::/g,eventNameLower)
|
|
301
|
-
.replace(/::_EVENT_OBJECT_TYPE_::/g, event.name.replace('on', 'On'));
|
|
302
|
-
}).join('\n\n');
|
|
303
|
-
|
|
304
|
-
const eventObjects = eventObjectAliases.jobs.map(eventObjectTypeName => {
|
|
305
|
-
const eventObjectType = eventObjectAliases.types[eventObjectTypeName]!;
|
|
306
|
-
const eventObjectFields = eventObjectType.properties.map(property => {
|
|
307
|
-
const eventPropType = translateComponentEventType(property.typeAnnotation, eventObjectAliases, eventObjectTypeName, cppCodegenOptions);
|
|
308
|
-
return ` REACT_FIELD(${property.name})\n ${(property.optional && !eventPropType.alreadySupportsOptionalOrHasDefault) ? `std::optional<${eventPropType.type}>` : eventPropType.type} ${property.name}${eventPropType.initializer};\n`;
|
|
309
|
-
}).join('\n');
|
|
310
|
-
return eventsObjectTemplate.replace(/::_OBJECT_NAME_::/g, `${componentName}_${eventObjectTypeName.replace('on', 'On')}`).replace(/::_OBJECT_FIELDS_::/g, eventObjectFields);
|
|
311
|
-
}).join('\n');
|
|
312
|
-
|
|
313
|
-
const eventObjectUsings = eventObjectAliases.jobs.map(eventObjectTypeName => {
|
|
314
|
-
return ` using ${eventObjectTypeName.replace('on', 'On')} = ${componentName}_${eventObjectTypeName.replace('on', 'On')};`
|
|
315
|
-
}).join('\n');
|
|
316
|
-
|
|
317
411
|
const eventEmitter = eventEmitterTemplate
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
412
|
+
.replace(/::_COMPONENT_EVENT_OBJECT_TYPES_::/g, eventObjects)
|
|
413
|
+
.replace(/::_EVENT_EMITTER_METHODS_::/g, eventEmitterMethods)
|
|
414
|
+
.replace(/::_EVENT_EMITTER_USINGS_::/g, eventObjectUsings);
|
|
322
415
|
|
|
323
416
|
// Commands
|
|
324
|
-
const commandAliases: AliasMap<
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
417
|
+
const commandAliases: AliasMap<
|
|
418
|
+
ObjectTypeAnnotation<CommandParamTypeAnnotation>
|
|
419
|
+
> = {types: {}, jobs: []};
|
|
420
|
+
const hasAnyCommands = componentShape.commands.length !== 0;
|
|
421
|
+
const commandHandlers = hasAnyCommands
|
|
422
|
+
? componentShape.commands
|
|
423
|
+
.map(command => {
|
|
424
|
+
const commandArgs = command.typeAnnotation.params
|
|
425
|
+
.map(param => {
|
|
426
|
+
const commandArgType = translateCommandParamType(
|
|
427
|
+
param.typeAnnotation,
|
|
428
|
+
commandAliases,
|
|
429
|
+
`${componentName}_${command.name}`,
|
|
430
|
+
cppCodegenOptions,
|
|
431
|
+
);
|
|
432
|
+
return `${
|
|
433
|
+
param.optional &&
|
|
434
|
+
!commandArgType.alreadySupportsOptionalOrHasDefault
|
|
435
|
+
? `std::optional<${commandArgType.type}>`
|
|
436
|
+
: commandArgType.type
|
|
437
|
+
} ${param.name}`;
|
|
438
|
+
})
|
|
439
|
+
.join(', ');
|
|
440
|
+
|
|
441
|
+
return ` // You must provide an implementation of this method to handle the "${
|
|
442
|
+
command.name
|
|
443
|
+
}" command
|
|
444
|
+
virtual void Handle${capitalizeFirstLetter(
|
|
445
|
+
command.name,
|
|
446
|
+
)}Command(${commandArgs}) noexcept = 0;`;
|
|
447
|
+
})
|
|
448
|
+
.join('\n\n')
|
|
449
|
+
: '';
|
|
450
|
+
|
|
451
|
+
const commandHandler = hasAnyCommands
|
|
452
|
+
? `void HandleCommand(const winrt::Microsoft::ReactNative::ComponentView &view, const winrt::Microsoft::ReactNative::HandleCommandArgs& args) noexcept {
|
|
338
453
|
auto userData = view.UserData().as<TUserData>();
|
|
339
454
|
auto commandName = args.CommandName();
|
|
340
|
-
${componentShape.commands
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
455
|
+
${componentShape.commands
|
|
456
|
+
.map(command => {
|
|
457
|
+
const commaSeparatedCommandArgs = command.typeAnnotation.params
|
|
458
|
+
.map(param => param.name)
|
|
459
|
+
.join(', ');
|
|
460
|
+
return ` if (commandName == L"${command.name}") {
|
|
461
|
+
${
|
|
462
|
+
command.typeAnnotation.params.length !== 0
|
|
463
|
+
? ` ${command.typeAnnotation.params
|
|
464
|
+
.map(param => {
|
|
465
|
+
const commandArgType = translateCommandParamType(
|
|
466
|
+
param.typeAnnotation,
|
|
467
|
+
commandAliases,
|
|
468
|
+
`${componentName}_${command.name}`,
|
|
469
|
+
cppCodegenOptions,
|
|
470
|
+
);
|
|
471
|
+
return `${
|
|
472
|
+
param.optional &&
|
|
473
|
+
!commandArgType.alreadySupportsOptionalOrHasDefault
|
|
474
|
+
? `std::optional<${commandArgType.type}>`
|
|
475
|
+
: commandArgType.type
|
|
476
|
+
} ${param.name};`;
|
|
477
|
+
})
|
|
478
|
+
.join('\n')}
|
|
479
|
+
winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), ${commaSeparatedCommandArgs});`
|
|
480
|
+
: ''
|
|
481
|
+
}
|
|
482
|
+
userData->Handle${capitalizeFirstLetter(
|
|
483
|
+
command.name,
|
|
484
|
+
)}Command(${commaSeparatedCommandArgs});
|
|
349
485
|
return;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
486
|
+
}`;
|
|
487
|
+
})
|
|
488
|
+
.join('\n\n')}
|
|
489
|
+
}`
|
|
490
|
+
: '';
|
|
491
|
+
|
|
492
|
+
const registerCommandHandler = hasAnyCommands
|
|
493
|
+
? ` builder.SetCustomCommandHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
|
|
355
494
|
const winrt::Microsoft::ReactNative::HandleCommandArgs& args) noexcept {
|
|
356
495
|
auto userData = view.UserData().as<TUserData>();
|
|
357
496
|
userData->HandleCommand(view, args);
|
|
358
|
-
});`
|
|
497
|
+
});`
|
|
498
|
+
: '';
|
|
359
499
|
|
|
360
500
|
const baseType = baseStructTemplate
|
|
361
|
-
|
|
362
|
-
|
|
501
|
+
.replace(/::_COMPONENT_VIEW_COMMAND_HANDLERS_::/g, commandHandlers)
|
|
502
|
+
.replace(/::_COMPONENT_VIEW_COMMAND_HANDLER_::/g, commandHandler);
|
|
363
503
|
|
|
364
504
|
// Registration
|
|
365
|
-
const componentRegistration = registerTemplate.replace(
|
|
505
|
+
const componentRegistration = registerTemplate.replace(
|
|
506
|
+
/::_REGISTER_CUSTOM_COMMAND_HANDLER_::/g,
|
|
507
|
+
registerCommandHandler,
|
|
508
|
+
);
|
|
366
509
|
|
|
367
510
|
// Final output
|
|
368
511
|
const replaceContent = function (template: string): string {
|
|
@@ -380,10 +523,7 @@ ${command.typeAnnotation.params.length !== 0 ? ` ${command.typeAnnotation.p
|
|
|
380
523
|
.replace(/\n\n\n+/g, '\n\n');
|
|
381
524
|
};
|
|
382
525
|
|
|
383
|
-
files.set(
|
|
384
|
-
`${componentName}.g.h`,
|
|
385
|
-
replaceContent(fileTemplate),
|
|
386
|
-
);
|
|
526
|
+
files.set(`${componentName}.g.h`, replaceContent(fileTemplate));
|
|
387
527
|
}
|
|
388
528
|
}
|
|
389
529
|
|
|
@@ -118,11 +118,16 @@ export function createNM2Generator({
|
|
|
118
118
|
});
|
|
119
119
|
let tuples = `
|
|
120
120
|
static constexpr auto methods = std::tuple{
|
|
121
|
-
${methods.traversedPropertyTuples}${
|
|
121
|
+
${methods.traversedPropertyTuples}${
|
|
122
|
+
methods.traversedEventEmitterTuples ? '\n' : ''
|
|
123
|
+
}${methods.traversedEventEmitterTuples}
|
|
122
124
|
};`;
|
|
123
125
|
let checks = `
|
|
124
126
|
constexpr auto methodCheckResults = CheckMethods<TModule, ::_MODULE_NAME_::Spec>();`;
|
|
125
|
-
let errors =
|
|
127
|
+
let errors =
|
|
128
|
+
methods.traversedProperties +
|
|
129
|
+
(methods.traversedEventEmitters ? '\n' : '') +
|
|
130
|
+
methods.traversedEventEmitters;
|
|
126
131
|
|
|
127
132
|
// prepare constants
|
|
128
133
|
const constants = generateValidateConstants(nativeModule, aliases);
|
|
@@ -62,11 +62,13 @@ function optionalSign<T>(obj: NamedShape<T>): string {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
function translateType(
|
|
65
|
-
type:
|
|
66
|
-
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
type:
|
|
66
|
+
| Nullable<
|
|
67
|
+
| NativeModuleBaseTypeAnnotation
|
|
68
|
+
| NativeModuleParamTypeAnnotation
|
|
69
|
+
| NativeModuleReturnTypeAnnotation
|
|
70
|
+
>
|
|
71
|
+
| UnsafeAnyTypeAnnotation,
|
|
70
72
|
): string {
|
|
71
73
|
// avoid: Property 'type' does not exist on type 'never'
|
|
72
74
|
const returnType = type.type;
|
|
@@ -47,11 +47,13 @@ function translateUnionReturnType(
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export function translateFieldOrReturnType(
|
|
50
|
-
type:
|
|
51
|
-
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
type:
|
|
51
|
+
| Nullable<
|
|
52
|
+
| NativeModuleBaseTypeAnnotation
|
|
53
|
+
| NativeModuleStringTypeAnnotation
|
|
54
|
+
| NativeModuleFunctionTypeAnnotation
|
|
55
|
+
>
|
|
56
|
+
| UnsafeAnyTypeAnnotation,
|
|
55
57
|
aliases: AliasMap,
|
|
56
58
|
baseAliasName: string,
|
|
57
59
|
callerName: 'translateField' | 'translateReturnType',
|
|
@@ -149,7 +149,9 @@ function translateArray(
|
|
|
149
149
|
function translateEventEmitterArray(
|
|
150
150
|
param: {
|
|
151
151
|
readonly type: 'ArrayTypeAnnotation';
|
|
152
|
-
readonly elementType:
|
|
152
|
+
readonly elementType:
|
|
153
|
+
| NativeModuleEventEmitterBaseTypeAnnotation
|
|
154
|
+
| {type: string};
|
|
153
155
|
},
|
|
154
156
|
aliases: AliasMap,
|
|
155
157
|
baseAliasName: string,
|
|
@@ -254,7 +256,13 @@ function translateEventEmitterParam(
|
|
|
254
256
|
case 'BooleanTypeAnnotation':
|
|
255
257
|
return 'bool';
|
|
256
258
|
case 'ArrayTypeAnnotation':
|
|
257
|
-
return translateEventEmitterArray(
|
|
259
|
+
return translateEventEmitterArray(
|
|
260
|
+
param,
|
|
261
|
+
aliases,
|
|
262
|
+
baseAliasName,
|
|
263
|
+
target,
|
|
264
|
+
options,
|
|
265
|
+
);
|
|
258
266
|
case 'TypeAliasTypeAnnotation':
|
|
259
267
|
return decorateType(getAliasCppName(param.name), target);
|
|
260
268
|
case 'VoidTypeAnnotation':
|
|
@@ -265,7 +273,9 @@ function translateEventEmitterParam(
|
|
|
265
273
|
}
|
|
266
274
|
|
|
267
275
|
function translateNullableParamType(
|
|
268
|
-
paramType:
|
|
276
|
+
paramType:
|
|
277
|
+
| Nullable<NativeModuleParamTypeAnnotation>
|
|
278
|
+
| UnsafeAnyTypeAnnotation,
|
|
269
279
|
aliases: AliasMap,
|
|
270
280
|
baseAliasName: string,
|
|
271
281
|
nullableTarget: ParamTarget,
|
|
@@ -357,14 +367,14 @@ export function translateEventEmitterArgs(
|
|
|
357
367
|
baseAliasName: string,
|
|
358
368
|
options: CppCodegenOptions,
|
|
359
369
|
) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
370
|
+
const translatedParam = translateEventEmitterParam(
|
|
371
|
+
params,
|
|
372
|
+
aliases,
|
|
373
|
+
baseAliasName,
|
|
374
|
+
'spec',
|
|
375
|
+
options,
|
|
376
|
+
);
|
|
377
|
+
return `${translatedParam}`;
|
|
368
378
|
}
|
|
369
379
|
|
|
370
380
|
export function translateArgs(
|
|
@@ -14,7 +14,11 @@ import type {
|
|
|
14
14
|
} from '@react-native/codegen/lib/CodegenSchema';
|
|
15
15
|
import {AliasMap} from './AliasManaging';
|
|
16
16
|
import type {CppCodegenOptions} from './ObjectTypes';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
translateArgs,
|
|
19
|
+
translateSpecArgs,
|
|
20
|
+
translateEventEmitterArgs,
|
|
21
|
+
} from './ParamTypes';
|
|
18
22
|
import {translateImplReturnType, translateSpecReturnType} from './ReturnTypes';
|
|
19
23
|
|
|
20
24
|
function isMethodSync(funcType: NativeModuleFunctionTypeAnnotation) {
|
|
@@ -92,7 +96,7 @@ function renderProperties(
|
|
|
92
96
|
aliases: AliasMap,
|
|
93
97
|
tuple: boolean,
|
|
94
98
|
options: CppCodegenOptions,
|
|
95
|
-
): {
|
|
99
|
+
): {code: string; numberOfProperties: number} {
|
|
96
100
|
// TODO: generate code for constants
|
|
97
101
|
const properties = methods
|
|
98
102
|
.filter(prop => prop.name !== 'getConstants')
|
|
@@ -154,32 +158,31 @@ function renderProperties(
|
|
|
154
158
|
}
|
|
155
159
|
});
|
|
156
160
|
|
|
157
|
-
|
|
161
|
+
return {code: properties.join('\n'), numberOfProperties: properties.length};
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
function getPossibleEventEmitterSignatures(
|
|
161
165
|
eventEmitter: NativeModuleEventEmitterShape,
|
|
162
166
|
aliases: AliasMap,
|
|
163
|
-
options: CppCodegenOptions
|
|
164
|
-
|
|
167
|
+
options: CppCodegenOptions,
|
|
168
|
+
): string[] {
|
|
165
169
|
const traversedArgs = translateEventEmitterArgs(
|
|
166
170
|
eventEmitter.typeAnnotation.typeAnnotation,
|
|
167
171
|
aliases,
|
|
168
172
|
eventEmitter.name,
|
|
169
173
|
options,
|
|
170
174
|
);
|
|
171
|
-
return [
|
|
175
|
+
return [
|
|
176
|
+
`REACT_EVENT(${eventEmitter.name}) std::function<void(${traversedArgs})> ${eventEmitter.name};`,
|
|
177
|
+
];
|
|
172
178
|
}
|
|
173
179
|
|
|
174
180
|
function translatePossibleEventSignatures(
|
|
175
181
|
eventEmitter: NativeModuleEventEmitterShape,
|
|
176
182
|
aliases: AliasMap,
|
|
177
|
-
options: CppCodegenOptions
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
aliases,
|
|
181
|
-
options
|
|
182
|
-
)
|
|
183
|
+
options: CppCodegenOptions,
|
|
184
|
+
): string {
|
|
185
|
+
return getPossibleEventEmitterSignatures(eventEmitter, aliases, options)
|
|
183
186
|
.map(sig => `" ${sig}\\n"`)
|
|
184
187
|
.join('\n ');
|
|
185
188
|
}
|
|
@@ -201,7 +204,9 @@ function renderEventEmitters(
|
|
|
201
204
|
);
|
|
202
205
|
|
|
203
206
|
if (tuple) {
|
|
204
|
-
return ` EventEmitter<void(${traversedArgs})>{${
|
|
207
|
+
return ` EventEmitter<void(${traversedArgs})>{${
|
|
208
|
+
index + indexOffset
|
|
209
|
+
}, L"${eventEmitter.name}"},`;
|
|
205
210
|
} else {
|
|
206
211
|
return ` REACT_SHOW_EVENTEMITTER_SPEC_ERRORS(
|
|
207
212
|
${index + indexOffset},
|
|
@@ -210,7 +215,7 @@ function renderEventEmitters(
|
|
|
210
215
|
eventEmitter,
|
|
211
216
|
aliases,
|
|
212
217
|
options,
|
|
213
|
-
|
|
218
|
+
)});`;
|
|
214
219
|
}
|
|
215
220
|
})
|
|
216
221
|
.join('\n');
|
|
@@ -221,10 +226,10 @@ export function generateValidateMethods(
|
|
|
221
226
|
aliases: AliasMap,
|
|
222
227
|
options: CppCodegenOptions,
|
|
223
228
|
): {
|
|
224
|
-
traversedProperties: string
|
|
225
|
-
traversedEventEmitters: string
|
|
226
|
-
traversedPropertyTuples: string
|
|
227
|
-
traversedEventEmitterTuples: string
|
|
229
|
+
traversedProperties: string;
|
|
230
|
+
traversedEventEmitters: string;
|
|
231
|
+
traversedPropertyTuples: string;
|
|
232
|
+
traversedEventEmitterTuples: string;
|
|
228
233
|
} {
|
|
229
234
|
const methods = nativeModule.spec.methods;
|
|
230
235
|
const eventEmitters = nativeModule.spec.eventEmitters;
|
|
@@ -254,5 +259,10 @@ export function generateValidateMethods(
|
|
|
254
259
|
true,
|
|
255
260
|
options,
|
|
256
261
|
);
|
|
257
|
-
return {
|
|
262
|
+
return {
|
|
263
|
+
traversedPropertyTuples: traversedPropertyTuples.code,
|
|
264
|
+
traversedEventEmitterTuples,
|
|
265
|
+
traversedProperties: traversedProperties.code,
|
|
266
|
+
traversedEventEmitters,
|
|
267
|
+
};
|
|
258
268
|
}
|