hermes-parser 0.15.1 → 0.17.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.
@@ -1,793 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow strict
8
- * @format
9
- */
10
-
11
- import type {
12
- HermesNode,
13
- HermesSourceLocation,
14
- HermesPosition,
15
- } from './HermesAST';
16
-
17
- import HermesASTAdapter from './HermesASTAdapter';
18
-
19
- declare var BigInt: ?(value: $FlowFixMe) => mixed;
20
-
21
- function createDefaultPosition(): HermesPosition {
22
- return {
23
- line: 1,
24
- column: 0,
25
- };
26
- }
27
-
28
- function createSyntaxError(node: HermesNode, err: string): SyntaxError {
29
- const syntaxError = new SyntaxError(err);
30
- // $FlowExpectedError[prop-missing]
31
- syntaxError.loc = {
32
- line: node.loc.start.line,
33
- column: node.loc.start.column,
34
- };
35
-
36
- return syntaxError;
37
- }
38
-
39
- export default class HermesToBabelAdapter extends HermesASTAdapter {
40
- fixSourceLocation(node: HermesNode): void {
41
- const loc = node.loc;
42
- if (loc == null) {
43
- return;
44
- }
45
-
46
- node.loc = {
47
- source: this.sourceFilename ?? null,
48
- start: loc.start,
49
- end: loc.end,
50
- };
51
-
52
- if (node.start == null) {
53
- node.start = loc.rangeStart;
54
- }
55
- if (node.end == null) {
56
- node.end = loc.rangeEnd;
57
- }
58
- }
59
-
60
- mapNode(node: HermesNode): HermesNode {
61
- this.fixSourceLocation(node);
62
- switch (node.type) {
63
- case 'Program':
64
- return this.mapProgram(node);
65
- case 'BlockStatement':
66
- return this.mapNodeWithDirectives(node);
67
- case 'Empty':
68
- return this.mapEmpty(node);
69
- case 'Identifier':
70
- return this.mapIdentifier(node);
71
- case 'TemplateElement':
72
- return this.mapTemplateElement(node);
73
- case 'GenericTypeAnnotation':
74
- return this.mapGenericTypeAnnotation(node);
75
- case 'SymbolTypeAnnotation':
76
- return this.mapSymbolTypeAnnotation(node);
77
- case 'Property':
78
- return this.mapProperty(node);
79
- case 'MethodDefinition':
80
- return this.mapMethodDefinition(node);
81
- case 'ImportDeclaration':
82
- return this.mapImportDeclaration(node);
83
- case 'ImportSpecifier':
84
- return this.mapImportSpecifier(node);
85
- case 'ExportDefaultDeclaration':
86
- return this.mapExportDefaultDeclaration(node);
87
- case 'ExportNamedDeclaration':
88
- return this.mapExportNamedDeclaration(node);
89
- case 'ExportNamespaceSpecifier':
90
- return this.mapExportNamespaceSpecifier(node);
91
- case 'ExportAllDeclaration':
92
- return this.mapExportAllDeclaration(node);
93
- case 'RestElement':
94
- return this.mapRestElement(node);
95
- case 'ImportExpression':
96
- return this.mapImportExpression(node);
97
- case 'JSXStringLiteral':
98
- return this.mapJSXStringLiteral(node);
99
- case 'PrivateName':
100
- return this.mapPrivateName(node);
101
- case 'ClassPrivateProperty':
102
- return this.mapPrivateProperty(node);
103
- case 'FunctionDeclaration':
104
- case 'FunctionExpression':
105
- return this.mapFunction(node);
106
- case 'IndexedAccessType':
107
- case 'OptionalIndexedAccessType':
108
- case 'KeyofTypeAnnotation':
109
- case 'ConditionalTypeAnnotation':
110
- case 'InferTypeAnnotation':
111
- case 'TupleTypeLabeledElement':
112
- case 'TupleTypeSpreadElement':
113
- case 'ObjectTypeMappedTypeProperty':
114
- case 'ComponentTypeAnnotation':
115
- case 'TypePredicate':
116
- return this.mapUnsupportedTypeAnnotation(node);
117
- case 'BigIntLiteral':
118
- return this.mapBigIntLiteral(node);
119
- case 'BigIntLiteralTypeAnnotation':
120
- return this.mapBigIntLiteralTypeAnnotation(node);
121
- case 'BigIntTypeAnnotation':
122
- return this.mapBigIntTypeAnnotation(node);
123
- case 'TypeofTypeAnnotation':
124
- return this.mapTypeofTypeAnnotation(node);
125
- case 'QualifiedTypeofIdentifier':
126
- return this.mapQualifiedTypeofIdentifier(node);
127
- case 'DeclareVariable':
128
- return this.mapDeclareVariable(node);
129
- case 'DeclareEnum':
130
- return this.mapDeclareEnum(node);
131
- case 'DeclareComponent':
132
- return this.mapDeclareComponent(node);
133
- case 'JSXElement':
134
- return this.mapJSXElement(node);
135
- case 'ComponentDeclaration':
136
- return this.mapComponentDeclaration(node);
137
- default:
138
- return this.mapNodeDefault(node);
139
- }
140
- }
141
-
142
- mapProgram(node: HermesNode): HermesNode {
143
- // Visit child nodes and convert to directives
144
- const {comments, ...program} = this.mapNodeWithDirectives(node);
145
-
146
- program.sourceType = this.getSourceType();
147
-
148
- // Adjust start loc to beginning of file
149
- program.loc.start = {line: 1, column: 0};
150
- program.start = 0;
151
-
152
- // Adjust end loc to include last comment if program ends with a comment
153
- if (comments.length > 0) {
154
- const lastComment = comments[comments.length - 1];
155
- if (lastComment.end > program.end) {
156
- program.loc.end = lastComment.loc.end;
157
- program.end = lastComment.end;
158
- }
159
- }
160
-
161
- // Rename root node to File node and move Program node under program property
162
- return {
163
- type: 'File',
164
- loc: program.loc,
165
- start: program.start,
166
- end: program.end,
167
- program,
168
- comments,
169
- };
170
- }
171
-
172
- mapNodeWithDirectives(node: HermesNode): HermesNode {
173
- const directives = [];
174
- for (const child of node.body) {
175
- if (child.type === 'ExpressionStatement' && child.directive != null) {
176
- // Visit directive children
177
- const directiveChild = this.mapNode(child);
178
-
179
- // Modify string literal node to be DirectiveLiteral node
180
- directiveChild.expression.type = 'DirectiveLiteral';
181
-
182
- // Construct Directive node with DirectiveLiteral value
183
- directives.push({
184
- type: 'Directive',
185
- loc: directiveChild.loc,
186
- start: directiveChild.start,
187
- end: directiveChild.end,
188
- value: directiveChild.expression,
189
- });
190
- } else {
191
- // Once we have found the first non-directive node we know there cannot be any more directives
192
- break;
193
- }
194
- }
195
-
196
- // Move directives from body to new directives array
197
- node.directives = directives;
198
- if (directives.length !== 0) {
199
- node.body = node.body.slice(directives.length);
200
- }
201
-
202
- // Visit expression statement children
203
- const body = node.body;
204
- for (let i = 0; i < body.length; i++) {
205
- const child = body[i];
206
- if (child != null) {
207
- body[i] = this.mapNode(child);
208
- }
209
- }
210
-
211
- return node;
212
- }
213
-
214
- mapIdentifier(node: HermesNode): HermesNode {
215
- node.loc.identifierName = node.name;
216
- return this.mapNodeDefault(node);
217
- }
218
-
219
- mapTemplateElement(node: HermesNode): HermesNode {
220
- // Adjust start loc to exclude "`" at beginning of template literal if this is the first quasi,
221
- // otherwise exclude "}" from previous expression.
222
- const startCharsToExclude = 1;
223
-
224
- // Adjust end loc to exclude "`" at end of template literal if this is the last quasi,
225
- // otherwise exclude "${" from next expression.
226
- const endCharsToExclude = node.tail ? 1 : 2;
227
-
228
- return {
229
- type: 'TemplateElement',
230
- loc: {
231
- start: {
232
- line: node.loc.start.line,
233
- column: node.loc.start.column + startCharsToExclude,
234
- },
235
- end: {
236
- line: node.loc.end.line,
237
- column: node.loc.end.column - endCharsToExclude,
238
- },
239
- },
240
- start: node.start + startCharsToExclude,
241
- end: node.end - endCharsToExclude,
242
- tail: node.tail,
243
- value: {
244
- cooked: node.cooked,
245
- raw: node.raw,
246
- },
247
- };
248
- }
249
-
250
- mapGenericTypeAnnotation(node: HermesNode): HermesNode {
251
- // Convert simple `this` generic type to ThisTypeAnnotation
252
- if (
253
- node.typeParameters == null &&
254
- node.id.type === 'Identifier' &&
255
- node.id.name === 'this'
256
- ) {
257
- return {
258
- type: 'ThisTypeAnnotation',
259
- loc: node.loc,
260
- start: node.start,
261
- end: node.end,
262
- };
263
- }
264
-
265
- return this.mapNodeDefault(node);
266
- }
267
-
268
- mapSymbolTypeAnnotation(node: HermesNode): HermesNode {
269
- return {
270
- type: 'GenericTypeAnnotation',
271
- loc: node.loc,
272
- start: node.start,
273
- end: node.end,
274
- id: {
275
- type: 'Identifier',
276
- loc: node.loc,
277
- start: node.start,
278
- end: node.end,
279
- name: 'symbol',
280
- },
281
- typeParameters: null,
282
- };
283
- }
284
-
285
- mapProperty(node: HermesNode): HermesNode {
286
- const key = this.mapNode(node.key);
287
- const value = this.mapNode(node.value);
288
-
289
- // Convert methods, getters, and setters to ObjectMethod nodes
290
- if (node.method || node.kind !== 'init') {
291
- // Properties under the FunctionExpression value that should be moved
292
- // to the ObjectMethod node itself.
293
- const {
294
- id,
295
- params,
296
- body,
297
- async,
298
- generator,
299
- returnType,
300
- typeParameters,
301
- predicate,
302
- } = value;
303
-
304
- const newNode: HermesNode = {
305
- type: 'ObjectMethod',
306
- loc: node.loc,
307
- start: node.start,
308
- end: node.end,
309
- // Non getter or setter methods have `kind = method`
310
- kind: node.kind === 'init' ? 'method' : node.kind,
311
- method: node.kind === 'init' ? true : false,
312
- computed: node.computed,
313
- key,
314
- id,
315
- params,
316
- body,
317
- async,
318
- generator,
319
- returnType,
320
- typeParameters,
321
- predicate,
322
- };
323
- if (node.kind !== 'init') {
324
- // babel emits an empty variance property on accessors for some reason
325
- newNode.variance = null;
326
- }
327
- return newNode;
328
- } else {
329
- // Non-method property nodes should be renamed to ObjectProperty
330
- node.type = 'ObjectProperty';
331
- return node;
332
- }
333
- }
334
-
335
- mapMethodDefinition(node: HermesNode): HermesNode {
336
- const key = this.mapNode(node.key);
337
- const value = this.mapNode(node.value);
338
-
339
- // Properties under the FunctionExpression value that should be moved
340
- // to the ClassMethod node itself.
341
- const {
342
- id,
343
- params,
344
- body,
345
- async,
346
- generator,
347
- returnType,
348
- typeParameters,
349
- predicate,
350
- } = value;
351
-
352
- return {
353
- type: key.type === 'PrivateName' ? 'ClassPrivateMethod' : 'ClassMethod',
354
- loc: node.loc,
355
- start: node.start,
356
- end: node.end,
357
- kind: node.kind,
358
- computed: node.computed,
359
- static: node.static,
360
- key,
361
- id,
362
- params,
363
- body,
364
- async,
365
- generator,
366
- returnType,
367
- typeParameters,
368
- predicate,
369
- };
370
- }
371
-
372
- mapRestElement(node: HermesNode): HermesNode {
373
- const restElement = this.mapNodeDefault(node);
374
-
375
- // Hermes puts type annotations on rest elements on the argument node,
376
- // but Babel expects type annotations on the rest element node itself.
377
- const annotation = restElement.argument.typeAnnotation;
378
- if (annotation != null) {
379
- restElement.typeAnnotation = annotation;
380
- restElement.argument.typeAnnotation = null;
381
- // Unfortunately there's no way for us to recover the end location of
382
- // the argument for the general case
383
- if (restElement.argument.type === 'Identifier') {
384
- restElement.argument.end =
385
- restElement.argument.start + restElement.argument.name.length;
386
- restElement.argument.loc.end = {
387
- ...restElement.argument.loc.start,
388
- column:
389
- restElement.argument.loc.start.column +
390
- restElement.argument.name.length,
391
- };
392
- }
393
- }
394
-
395
- return restElement;
396
- }
397
-
398
- mapImportExpression(node: HermesNode): HermesNode {
399
- // Babel expects ImportExpression to be structued as a regular
400
- // CallExpression where the callee is an Import node.
401
- return {
402
- type: 'CallExpression',
403
- loc: node.loc,
404
- start: node.start,
405
- end: node.end,
406
- callee: {
407
- type: 'Import',
408
- loc: {
409
- ...node.loc,
410
- end: {
411
- ...node.loc.start,
412
- column: node.loc.start.column + 'import'.length,
413
- },
414
- },
415
- start: node.start,
416
- end: node.start + 'import'.length,
417
- },
418
- arguments: [this.mapNode(node.source)],
419
- };
420
- }
421
-
422
- mapJSXStringLiteral(node: HermesNode): HermesNode {
423
- // Babel expects StringLiterals in JSX,
424
- // but Hermes uses JSXStringLiteral to attach the raw value without
425
- // having to internally attach it to every single string literal.
426
- return {
427
- type: 'StringLiteral',
428
- loc: node.loc,
429
- start: node.start,
430
- end: node.end,
431
- value: node.value,
432
- };
433
- }
434
-
435
- mapFunction(node: HermesNode): HermesNode {
436
- // Remove the first parameter if it is a this-type annotation,
437
- // which is not recognized by Babel.
438
- if (node.params.length !== 0 && node.params[0].name === 'this') {
439
- node.params.shift();
440
- }
441
-
442
- return this.mapNodeDefault(node);
443
- }
444
-
445
- /**
446
- * If Babel (the version we target) does not support a type annotation we
447
- * parse, we need to return some other valid type annotation in its place.
448
- */
449
- mapUnsupportedTypeAnnotation(node: HermesNode): HermesNode {
450
- return {
451
- type: 'AnyTypeAnnotation',
452
- loc: node.loc,
453
- start: node.start,
454
- end: node.end,
455
- };
456
- }
457
-
458
- mapBigIntLiteral(node: HermesNode): HermesNode {
459
- node.value = this.getBigIntLiteralValue(node.bigint).value;
460
- return node;
461
- }
462
- mapBigIntLiteralTypeAnnotation(node: HermesNode): HermesNode {
463
- node.value = this.getBigIntLiteralValue(node.raw).value;
464
- return node;
465
- }
466
- /**
467
- * Babel does not parse the bigint keyword type as the keyword node.
468
- * So we need to down-level the AST to a plain GenericTypeAnnotation
469
- */
470
- mapBigIntTypeAnnotation(node: HermesNode): HermesNode {
471
- return {
472
- type: 'GenericTypeAnnotation',
473
- id: {
474
- type: 'Identifier',
475
- name: 'bigint',
476
- loc: node.loc,
477
- start: node.start,
478
- end: node.end,
479
- },
480
- typeParameters: null,
481
- loc: node.loc,
482
- start: node.start,
483
- end: node.end,
484
- };
485
- }
486
-
487
- mapPrivateProperty(nodeUnprocessed: HermesNode): HermesNode {
488
- const node = this.mapNodeDefault(nodeUnprocessed);
489
- node.key = {
490
- type: 'PrivateName',
491
- id: {
492
- ...node.key,
493
- // babel doesn't include the hash in the identifier
494
- start: node.key.start + 1,
495
- loc: {
496
- ...node.key.loc,
497
- start: {
498
- ...node.key.loc.start,
499
- column: node.key.loc.start.column + 1,
500
- },
501
- },
502
- },
503
- start: node.key.start,
504
- end: node.key.end,
505
- loc: node.key.loc,
506
- };
507
-
508
- return node;
509
- }
510
-
511
- mapPrivateName(node: HermesNode): HermesNode {
512
- // babel doesn't include the hash in the identifier
513
- node.id.start += 1;
514
- node.id.loc.start.column += 1;
515
- return node;
516
- }
517
-
518
- mapExportNamespaceSpecifier(nodeUnprocessed: HermesNode): HermesNode {
519
- const node = this.mapNodeDefault(nodeUnprocessed);
520
-
521
- // the hermes AST emits the location as the location of the entire export
522
- // but babel emits the location as *just* the "* as id" bit
523
-
524
- // the end will always align with the end of the identifier (ezpz)
525
- // but the start will align with the "*" token - which we can't recover from just the AST
526
- // so we just fudge the start location a bit to get it "good enough"
527
- // it will be wrong if the AST is anything like "export * as x from 'y'"... but oh well
528
- node.start = node.start + 'export '.length;
529
- node.loc.start.column = node.loc.start.column + 'export '.length;
530
- node.end = node.exported.end;
531
- node.loc.end = {
532
- column: node.exported.loc.end.column,
533
- line: node.exported.loc.end.line,
534
- };
535
-
536
- return node;
537
- }
538
-
539
- mapTypeofTypeAnnotation(nodeUnprocessed: HermesNode): HermesNode {
540
- nodeUnprocessed.argument = {
541
- type: 'GenericTypeAnnotation',
542
- id: nodeUnprocessed.argument,
543
- typeParameters: null,
544
- loc: nodeUnprocessed.argument.loc,
545
- };
546
-
547
- return this.mapNodeDefault(nodeUnprocessed);
548
- }
549
-
550
- mapQualifiedTypeofIdentifier(nodeUnprocessed: HermesNode): HermesNode {
551
- nodeUnprocessed.type = 'QualifiedTypeIdentifier';
552
-
553
- return this.mapNodeDefault(nodeUnprocessed);
554
- }
555
-
556
- mapDeclareVariable(nodeUnprocessed: HermesNode): HermesNode {
557
- delete nodeUnprocessed.kind;
558
-
559
- return this.mapNodeDefault(nodeUnprocessed);
560
- }
561
-
562
- mapDeclareEnum(nodeUnprocessed: HermesNode): HermesNode {
563
- nodeUnprocessed.id.typeAnnotation = this.mapUnsupportedTypeAnnotation(
564
- nodeUnprocessed.body,
565
- );
566
-
567
- delete nodeUnprocessed.body;
568
-
569
- nodeUnprocessed.type = 'DeclareVariable';
570
-
571
- return this.mapDeclareVariable(nodeUnprocessed);
572
- }
573
-
574
- mapDeclareComponent(nodeUnprocessed: HermesNode): HermesNode {
575
- nodeUnprocessed.id.typeAnnotation =
576
- this.mapUnsupportedTypeAnnotation(nodeUnprocessed);
577
-
578
- delete nodeUnprocessed.params;
579
- delete nodeUnprocessed.rest;
580
- delete nodeUnprocessed.typeParameters;
581
- delete nodeUnprocessed.rendersType;
582
-
583
- nodeUnprocessed.type = 'DeclareVariable';
584
-
585
- return this.mapDeclareVariable(nodeUnprocessed);
586
- }
587
-
588
- mapJSXElement(nodeUnprocessed: HermesNode): HermesNode {
589
- delete nodeUnprocessed.openingElement.typeArguments;
590
- return this.mapNodeDefault(nodeUnprocessed);
591
- }
592
-
593
- mapComponentDeclaration(nodeUnprocessed: HermesNode): HermesNode {
594
- let rendersType = nodeUnprocessed.rendersType;
595
- if (rendersType == null) {
596
- // Create empty loc for return type annotation nodes
597
- const createRendersTypeLoc = () => ({
598
- loc: {
599
- start: {...nodeUnprocessed.body.loc.end},
600
- end: {...nodeUnprocessed.body.loc.end},
601
- rangeStart: nodeUnprocessed.body.loc.rangeStart,
602
- rangeEnd: nodeUnprocessed.body.loc.rangeEnd,
603
- },
604
- });
605
-
606
- rendersType = {
607
- type: 'TypeAnnotation',
608
- typeAnnotation: {
609
- type: 'GenericTypeAnnotation',
610
- id: {
611
- type: 'QualifiedTypeIdentifier',
612
- qualification: {
613
- type: 'Identifier',
614
- name: 'React',
615
- ...createRendersTypeLoc(),
616
- },
617
- id: {
618
- type: 'Identifier',
619
- name: 'Node',
620
- ...createRendersTypeLoc(),
621
- },
622
- ...createRendersTypeLoc(),
623
- },
624
- typeParameters: null,
625
- ...createRendersTypeLoc(),
626
- },
627
- ...createRendersTypeLoc(),
628
- };
629
- }
630
-
631
- function getParamName(paramName: HermesNode): string {
632
- switch (paramName.type) {
633
- case 'Identifier':
634
- return paramName.name;
635
- case 'StringLiteral':
636
- return paramName.value;
637
- default:
638
- throw createSyntaxError(
639
- paramName,
640
- `Unknown Component parameter name type of "${paramName.type}"`,
641
- );
642
- }
643
- }
644
-
645
- function createPropsTypeAnnotation(loc: HermesSourceLocation) {
646
- // Create empty loc for type annotation nodes
647
- const createParamsTypeLoc = () => ({
648
- loc: {
649
- start: loc.start != null ? {...loc.start} : createDefaultPosition(),
650
- end: loc.end != null ? {...loc.end} : createDefaultPosition(),
651
- rangeStart: loc.rangeStart,
652
- rangeEnd: loc.rangeEnd,
653
- },
654
- });
655
-
656
- return {
657
- type: 'TypeAnnotation',
658
- typeAnnotation: {
659
- type: 'GenericTypeAnnotation',
660
- id: {
661
- type: 'Identifier',
662
- name: '$ReadOnly',
663
- ...createParamsTypeLoc(),
664
- },
665
- typeParameters: {
666
- type: 'TypeParameterInstantiation',
667
- params: [
668
- {
669
- type: 'ObjectTypeAnnotation',
670
- callProperties: [],
671
- properties: [],
672
- indexers: [],
673
- internalSlots: [],
674
- exact: false,
675
- inexact: true,
676
- ...createParamsTypeLoc(),
677
- },
678
- ],
679
- ...createParamsTypeLoc(),
680
- },
681
- ...createParamsTypeLoc(),
682
- },
683
- ...createParamsTypeLoc(),
684
- };
685
- }
686
-
687
- const params = (() => {
688
- if (nodeUnprocessed.params.length === 0) {
689
- return [];
690
- }
691
-
692
- // Optimize `component Foo(...props: Props) {}` to `function Foo(props: Props) {}
693
- if (
694
- nodeUnprocessed.params.length === 1 &&
695
- nodeUnprocessed.params[0].type === 'RestElement'
696
- ) {
697
- const restElement = nodeUnprocessed.params[0];
698
- return [
699
- {
700
- ...restElement.argument,
701
- typeAnnotation: createPropsTypeAnnotation(
702
- restElement.argument.typeAnnotation.loc,
703
- ),
704
- },
705
- ];
706
- }
707
-
708
- const properties = nodeUnprocessed.params.map(param => {
709
- switch (param.type) {
710
- case 'RestElement': {
711
- delete param.typeAnnotation;
712
- return param;
713
- }
714
- case 'ComponentParameter': {
715
- if (getParamName(param.name) === 'ref') {
716
- throw createSyntaxError(
717
- param,
718
- 'Component parameters named "ref" are currently not supported',
719
- );
720
- }
721
-
722
- if (param.name.type === 'Identifier') {
723
- delete param.name.typeAnnotation;
724
- }
725
- if (param.local.type === 'AssignmentPattern') {
726
- delete param.local.left.typeAnnotation;
727
- delete param.local.left.optional;
728
- } else {
729
- delete param.local.typeAnnotation;
730
- delete param.local.optional;
731
- }
732
-
733
- return {
734
- type: 'ObjectProperty',
735
- key: param.name,
736
- value: param.local,
737
- method: false,
738
- shorthand: param.shorthand,
739
- computed: false,
740
- loc: param.loc,
741
- start: param.start,
742
- end: param.end,
743
- };
744
- }
745
- default: {
746
- throw createSyntaxError(
747
- param,
748
- `Unknown Component parameter type of "${param.type}"`,
749
- );
750
- }
751
- }
752
- });
753
-
754
- const paramsLoc = {
755
- start: properties[0].loc.start,
756
- end: properties[properties.length - 1].loc.end,
757
- rangeStart: properties[0].loc.rangeStart,
758
- rangeEnd: properties[properties.length - 1].loc.rangeEnd,
759
- };
760
-
761
- return [
762
- {
763
- type: 'ObjectPattern',
764
- properties,
765
- typeAnnotation: createPropsTypeAnnotation({
766
- ...paramsLoc,
767
- start: paramsLoc.end,
768
- rangeStart: paramsLoc.rangeEnd,
769
- }),
770
- loc: paramsLoc,
771
- },
772
- ];
773
- })();
774
-
775
- const functionComponent = {
776
- type: 'FunctionDeclaration',
777
- __componentDeclaration: true,
778
- id: nodeUnprocessed.id,
779
- typeParameters: nodeUnprocessed.typeParameters,
780
- params,
781
- returnType: rendersType,
782
- body: nodeUnprocessed.body,
783
- async: false,
784
- generator: false,
785
- predicate: null,
786
- loc: nodeUnprocessed.loc,
787
- start: nodeUnprocessed.start,
788
- end: nodeUnprocessed.end,
789
- };
790
-
791
- return this.mapNodeDefault(functionComponent);
792
- }
793
- }