hermes-estree 0.32.1 → 0.33.1

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 (87) hide show
  1. package/dist/generated/HermesESTreeSelectorTypes.js.flow +262 -27
  2. package/dist/generated/predicates.js +120 -0
  3. package/dist/generated/predicates.js.flow +72 -0
  4. package/dist/predicates.js +2 -4
  5. package/dist/predicates.js.flow +5 -4
  6. package/dist/src/generated/predicates.js +120 -0
  7. package/dist/src/predicates.js +2 -4
  8. package/dist/types.js.flow +103 -11
  9. package/package.json +1 -1
  10. package/dist/HermesAST.js.flow +0 -57
  11. package/dist/HermesASTAdapter.js +0 -192
  12. package/dist/HermesASTAdapter.js.flow +0 -189
  13. package/dist/HermesParser.js +0 -108
  14. package/dist/HermesParser.js.flow +0 -161
  15. package/dist/HermesParserDecodeUTF8String.js +0 -68
  16. package/dist/HermesParserDecodeUTF8String.js.flow +0 -65
  17. package/dist/HermesParserDeserializer.js +0 -242
  18. package/dist/HermesParserDeserializer.js.flow +0 -260
  19. package/dist/HermesParserNodeDeserializers.js +0 -2477
  20. package/dist/HermesParserNodeDeserializers.js.flow +0 -16
  21. package/dist/HermesParserWASM.js +0 -6
  22. package/dist/HermesParserWASM.js.flow +0 -87
  23. package/dist/HermesToESTreeAdapter.js +0 -439
  24. package/dist/HermesToESTreeAdapter.js.flow +0 -421
  25. package/dist/ParserOptions.js +0 -18
  26. package/dist/ParserOptions.js.flow +0 -41
  27. package/dist/babel/TransformESTreeToBabel.js +0 -1123
  28. package/dist/babel/TransformESTreeToBabel.js.flow +0 -1277
  29. package/dist/estree/StripFlowTypes.js +0 -175
  30. package/dist/estree/StripFlowTypes.js.flow +0 -158
  31. package/dist/estree/StripFlowTypesForBabel.js +0 -215
  32. package/dist/estree/StripFlowTypesForBabel.js.flow +0 -216
  33. package/dist/estree/TransformComponentSyntax.js +0 -788
  34. package/dist/estree/TransformComponentSyntax.js.flow +0 -864
  35. package/dist/estree/TransformEnumSyntax.js +0 -106
  36. package/dist/estree/TransformEnumSyntax.js.flow +0 -125
  37. package/dist/estree/TransformMatchSyntax.js +0 -1006
  38. package/dist/estree/TransformMatchSyntax.js.flow +0 -912
  39. package/dist/generated/ESTreeVisitorKeys.js +0 -220
  40. package/dist/generated/ESTreeVisitorKeys.js.flow +0 -15
  41. package/dist/generated/ParserVisitorKeys.js +0 -794
  42. package/dist/generated/ParserVisitorKeys.js.flow +0 -17
  43. package/dist/getModuleDocblock.js +0 -112
  44. package/dist/getModuleDocblock.js.flow +0 -118
  45. package/dist/src/HermesASTAdapter.js +0 -192
  46. package/dist/src/HermesParser.js +0 -108
  47. package/dist/src/HermesParserDecodeUTF8String.js +0 -68
  48. package/dist/src/HermesParserDeserializer.js +0 -242
  49. package/dist/src/HermesParserNodeDeserializers.js +0 -2477
  50. package/dist/src/HermesToESTreeAdapter.js +0 -439
  51. package/dist/src/ParserOptions.js +0 -18
  52. package/dist/src/babel/TransformESTreeToBabel.js +0 -1123
  53. package/dist/src/estree/StripFlowTypes.js +0 -175
  54. package/dist/src/estree/StripFlowTypesForBabel.js +0 -215
  55. package/dist/src/estree/TransformComponentSyntax.js +0 -788
  56. package/dist/src/estree/TransformEnumSyntax.js +0 -106
  57. package/dist/src/estree/TransformMatchSyntax.js +0 -1006
  58. package/dist/src/generated/ESTreeVisitorKeys.js +0 -220
  59. package/dist/src/generated/ParserVisitorKeys.js +0 -794
  60. package/dist/src/getModuleDocblock.js +0 -112
  61. package/dist/src/transform/SimpleTransform.js +0 -136
  62. package/dist/src/transform/astArrayMutationHelpers.js +0 -62
  63. package/dist/src/transform/astNodeMutationHelpers.js +0 -200
  64. package/dist/src/traverse/SimpleTraverser.js +0 -137
  65. package/dist/src/traverse/getVisitorKeys.js +0 -37
  66. package/dist/src/utils/Builders.js +0 -191
  67. package/dist/src/utils/GenID.js +0 -41
  68. package/dist/src/utils/createSyntaxError.js +0 -25
  69. package/dist/src/utils/mutateESTreeASTForPrettier.js +0 -127
  70. package/dist/transform/SimpleTransform.js +0 -136
  71. package/dist/transform/SimpleTransform.js.flow +0 -169
  72. package/dist/transform/astArrayMutationHelpers.js +0 -62
  73. package/dist/transform/astArrayMutationHelpers.js.flow +0 -71
  74. package/dist/transform/astNodeMutationHelpers.js +0 -200
  75. package/dist/transform/astNodeMutationHelpers.js.flow +0 -246
  76. package/dist/traverse/SimpleTraverser.js +0 -137
  77. package/dist/traverse/SimpleTraverser.js.flow +0 -133
  78. package/dist/traverse/getVisitorKeys.js +0 -37
  79. package/dist/traverse/getVisitorKeys.js.flow +0 -36
  80. package/dist/utils/Builders.js +0 -191
  81. package/dist/utils/Builders.js.flow +0 -218
  82. package/dist/utils/GenID.js +0 -41
  83. package/dist/utils/GenID.js.flow +0 -38
  84. package/dist/utils/createSyntaxError.js +0 -25
  85. package/dist/utils/createSyntaxError.js.flow +0 -24
  86. package/dist/utils/mutateESTreeASTForPrettier.js +0 -127
  87. package/dist/utils/mutateESTreeASTForPrettier.js.flow +0 -130
@@ -1,864 +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
- /**
12
- * This transforms component syntax (https://flow.org/en/docs/react/component-syntax/)
13
- * and hook syntax (https://flow.org/en/docs/react/hook-syntax/).
14
- *
15
- * It is expected that all transforms create valid ESTree AST output. If
16
- * the transform requires outputting Babel specific AST nodes then it
17
- * should live in `ConvertESTreeToBabel.js`
18
- */
19
-
20
- 'use strict';
21
-
22
- import type {ParserOptions} from '../ParserOptions';
23
- import type {
24
- Program,
25
- ESNode,
26
- DeclareComponent,
27
- DeclareVariable,
28
- ComponentDeclaration,
29
- FunctionDeclaration,
30
- TypeAnnotation,
31
- ComponentParameter,
32
- SourceLocation,
33
- Position,
34
- ObjectPattern,
35
- ObjectTypeAnnotation,
36
- Identifier,
37
- Range,
38
- RestElement,
39
- DestructuringObjectProperty,
40
- VariableDeclaration,
41
- ModuleDeclaration,
42
- DeclareHook,
43
- DeclareFunction,
44
- HookDeclaration,
45
- Statement,
46
- AssignmentPattern,
47
- BindingName,
48
- ObjectTypePropertySignature,
49
- ObjectTypeSpreadProperty,
50
- } from 'hermes-estree';
51
-
52
- import {SimpleTransform} from '../transform/SimpleTransform';
53
- import {shallowCloneNode} from '../transform/astNodeMutationHelpers';
54
- import {SimpleTraverser} from '../traverse/SimpleTraverser';
55
- import {createSyntaxError} from '../utils/createSyntaxError';
56
-
57
- const nodeWith = SimpleTransform.nodeWith;
58
-
59
- // Rely on the mapper to fix up parent relationships.
60
- const EMPTY_PARENT: $FlowFixMe = null;
61
-
62
- function createDefaultPosition(): Position {
63
- return {
64
- line: 1,
65
- column: 0,
66
- };
67
- }
68
-
69
- function mapDeclareComponent(node: DeclareComponent): DeclareVariable {
70
- return {
71
- type: 'DeclareVariable',
72
- id: nodeWith(node.id, {
73
- typeAnnotation: {
74
- type: 'TypeAnnotation',
75
- typeAnnotation: {
76
- type: 'AnyTypeAnnotation',
77
- loc: node.loc,
78
- range: node.range,
79
- parent: EMPTY_PARENT,
80
- },
81
- loc: node.loc,
82
- range: node.range,
83
- parent: EMPTY_PARENT,
84
- },
85
- }),
86
- kind: 'const',
87
- loc: node.loc,
88
- range: node.range,
89
- parent: node.parent,
90
- };
91
- }
92
-
93
- function getComponentParameterName(
94
- paramName: ComponentParameter['name'],
95
- ): string {
96
- switch (paramName.type) {
97
- case 'Identifier':
98
- return paramName.name;
99
- case 'Literal':
100
- return paramName.value;
101
- default:
102
- throw createSyntaxError(
103
- paramName,
104
- `Unknown Component parameter name type of "${paramName.type}"`,
105
- );
106
- }
107
- }
108
-
109
- function createPropsTypeAnnotation(
110
- propTypes: Array<ObjectTypePropertySignature>,
111
- spread: ?ObjectTypeSpreadProperty,
112
- loc: ?SourceLocation,
113
- range: ?Range,
114
- ): TypeAnnotation {
115
- // Create empty loc for type annotation nodes
116
- const createParamsTypeLoc = () => ({
117
- loc: {
118
- start: loc?.start != null ? loc.start : createDefaultPosition(),
119
- end: loc?.end != null ? loc.end : createDefaultPosition(),
120
- },
121
- range: range ?? [0, 0],
122
- parent: EMPTY_PARENT,
123
- });
124
-
125
- // Optimize `{...Props}` -> `Props`
126
- if (spread != null && propTypes.length === 0) {
127
- return {
128
- type: 'TypeAnnotation',
129
- typeAnnotation: spread.argument,
130
- ...createParamsTypeLoc(),
131
- };
132
- }
133
-
134
- const typeProperties: Array<
135
- ObjectTypePropertySignature | ObjectTypeSpreadProperty,
136
- > = [...propTypes];
137
-
138
- if (spread != null) {
139
- // Spread needs to be the first type, as inline properties take precedence.
140
- typeProperties.unshift(spread);
141
- }
142
-
143
- const propTypeObj: ObjectTypeAnnotation = {
144
- type: 'ObjectTypeAnnotation',
145
- callProperties: [],
146
- properties: typeProperties,
147
- indexers: [],
148
- internalSlots: [],
149
- exact: false,
150
- inexact: false,
151
- ...createParamsTypeLoc(),
152
- };
153
-
154
- return {
155
- type: 'TypeAnnotation',
156
- typeAnnotation: {
157
- type: 'GenericTypeAnnotation',
158
- id: {
159
- type: 'Identifier',
160
- name: '$ReadOnly',
161
- optional: false,
162
- typeAnnotation: null,
163
- ...createParamsTypeLoc(),
164
- },
165
- typeParameters: {
166
- type: 'TypeParameterInstantiation',
167
- params: [propTypeObj],
168
- ...createParamsTypeLoc(),
169
- },
170
- ...createParamsTypeLoc(),
171
- },
172
- ...createParamsTypeLoc(),
173
- };
174
- }
175
-
176
- function mapComponentParameters(
177
- params: $ReadOnlyArray<ComponentParameter | RestElement>,
178
- options: ParserOptions,
179
- ): $ReadOnly<{
180
- props: ?(ObjectPattern | Identifier),
181
- ref: ?(BindingName | AssignmentPattern),
182
- }> {
183
- if (params.length === 0) {
184
- return {props: null, ref: null};
185
- }
186
-
187
- // Optimize `component Foo(...props: Props) {}` to `function Foo(props: Props) {}
188
- if (
189
- params.length === 1 &&
190
- params[0].type === 'RestElement' &&
191
- params[0].argument.type === 'Identifier'
192
- ) {
193
- const restElementArgument = params[0].argument;
194
- return {
195
- props: restElementArgument,
196
- ref: null,
197
- };
198
- }
199
-
200
- // Filter out any ref param and capture it's details when targeting React 18.
201
- // React 19+ treats ref as a regular prop for function components.
202
- let refParam = null;
203
- const paramsWithoutRef =
204
- (options.reactRuntimeTarget ?? '18') === '18'
205
- ? params.filter(param => {
206
- if (
207
- param.type === 'ComponentParameter' &&
208
- getComponentParameterName(param.name) === 'ref'
209
- ) {
210
- refParam = param;
211
- return false;
212
- }
213
- return true;
214
- })
215
- : params;
216
-
217
- const [propTypes, spread] = paramsWithoutRef.reduce<
218
- [Array<ObjectTypePropertySignature>, ?ObjectTypeSpreadProperty],
219
- >(
220
- ([propTypes, spread], param) => {
221
- switch (param.type) {
222
- case 'RestElement': {
223
- if (spread != null) {
224
- throw createSyntaxError(
225
- param,
226
- `Invalid state, multiple rest elements found as Component Parameters`,
227
- );
228
- }
229
- return [propTypes, mapComponentParameterRestElementType(param)];
230
- }
231
- case 'ComponentParameter': {
232
- propTypes.push(mapComponentParameterType(param));
233
- return [propTypes, spread];
234
- }
235
- }
236
- },
237
- [[], null],
238
- );
239
-
240
- const propsProperties = paramsWithoutRef.flatMap(mapComponentParameter);
241
-
242
- let props: null | ObjectPattern | Identifier = null;
243
- if (propsProperties.length === 0) {
244
- if (refParam == null) {
245
- throw new Error(
246
- 'TransformComponentSyntax: Invalid state, ref should always be set at this point if props are empty',
247
- );
248
- }
249
- const emptyParamsLoc = {
250
- start: refParam.loc.start,
251
- end: refParam.loc.start,
252
- };
253
- const emptyParamsRange = [refParam.range[0], refParam.range[0]];
254
- // no properties provided (must have had a single ref)
255
- props = {
256
- type: 'Identifier',
257
- name: '_$$empty_props_placeholder$$',
258
- optional: false,
259
- typeAnnotation: createPropsTypeAnnotation(
260
- [],
261
- null,
262
- emptyParamsLoc,
263
- emptyParamsRange,
264
- ),
265
- loc: emptyParamsLoc,
266
- range: emptyParamsRange,
267
- parent: EMPTY_PARENT,
268
- };
269
- } else {
270
- const lastPropsProperty = propsProperties[propsProperties.length - 1];
271
- props = {
272
- type: 'ObjectPattern',
273
- properties: propsProperties,
274
- typeAnnotation: createPropsTypeAnnotation(
275
- propTypes,
276
- spread,
277
- {
278
- start: lastPropsProperty.loc.end,
279
- end: lastPropsProperty.loc.end,
280
- },
281
- [lastPropsProperty.range[1], lastPropsProperty.range[1]],
282
- ),
283
- loc: {
284
- start: propsProperties[0].loc.start,
285
- end: lastPropsProperty.loc.end,
286
- },
287
- range: [propsProperties[0].range[0], lastPropsProperty.range[1]],
288
- parent: EMPTY_PARENT,
289
- };
290
- }
291
-
292
- let ref = null;
293
- if (refParam != null) {
294
- ref = refParam.local;
295
- }
296
-
297
- return {
298
- props,
299
- ref,
300
- };
301
- }
302
-
303
- function mapComponentParameterType(
304
- param: ComponentParameter,
305
- ): ObjectTypePropertySignature {
306
- const typeAnnotation =
307
- param.local.type === 'AssignmentPattern'
308
- ? param.local.left.typeAnnotation
309
- : param.local.typeAnnotation;
310
- const optional =
311
- param.local.type === 'AssignmentPattern'
312
- ? true
313
- : param.local.type === 'Identifier'
314
- ? param.local.optional
315
- : false;
316
-
317
- return {
318
- type: 'ObjectTypeProperty',
319
- key: shallowCloneNode(param.name),
320
- value: typeAnnotation?.typeAnnotation ?? {
321
- type: 'AnyTypeAnnotation',
322
- loc: param.local.loc,
323
- range: param.local.range,
324
- parent: EMPTY_PARENT,
325
- },
326
- kind: 'init',
327
- optional,
328
- method: false,
329
- static: false,
330
- proto: false,
331
- variance: null,
332
- loc: param.local.loc,
333
- range: param.local.range,
334
- parent: EMPTY_PARENT,
335
- };
336
- }
337
-
338
- function mapComponentParameterRestElementType(
339
- param: RestElement,
340
- ): ObjectTypeSpreadProperty {
341
- if (
342
- param.argument.type !== 'Identifier' &&
343
- param.argument.type !== 'ObjectPattern'
344
- ) {
345
- throw createSyntaxError(
346
- param,
347
- `Invalid ${param.argument.type} encountered in restParameter`,
348
- );
349
- }
350
- return {
351
- type: 'ObjectTypeSpreadProperty',
352
- argument: param.argument.typeAnnotation?.typeAnnotation ?? {
353
- type: 'AnyTypeAnnotation',
354
- loc: param.loc,
355
- range: param.range,
356
- parent: EMPTY_PARENT,
357
- },
358
- loc: param.loc,
359
- range: param.range,
360
- parent: EMPTY_PARENT,
361
- };
362
- }
363
-
364
- function mapComponentParameter(
365
- param: ComponentParameter | RestElement,
366
- ): Array<DestructuringObjectProperty | RestElement> {
367
- switch (param.type) {
368
- case 'RestElement': {
369
- switch (param.argument.type) {
370
- case 'Identifier': {
371
- const a = nodeWith(param, {
372
- typeAnnotation: null,
373
- argument: nodeWith(param.argument, {typeAnnotation: null}),
374
- });
375
- return [a];
376
- }
377
- case 'ObjectPattern': {
378
- return param.argument.properties.map(property => {
379
- return nodeWith(property, {
380
- typeAnnotation: null,
381
- });
382
- });
383
- }
384
- default: {
385
- throw createSyntaxError(
386
- param,
387
- `Unhandled ${param.argument.type} encountered in restParameter`,
388
- );
389
- }
390
- }
391
- }
392
- case 'ComponentParameter': {
393
- let value;
394
- if (param.local.type === 'AssignmentPattern') {
395
- value = nodeWith(param.local, {
396
- left: nodeWith(param.local.left, {
397
- typeAnnotation: null,
398
- optional: false,
399
- }),
400
- });
401
- } else {
402
- value = nodeWith(param.local, {
403
- typeAnnotation: null,
404
- optional: false,
405
- });
406
- }
407
-
408
- // Shorthand params
409
- if (
410
- param.name.type === 'Identifier' &&
411
- param.shorthand &&
412
- (value.type === 'Identifier' || value.type === 'AssignmentPattern')
413
- ) {
414
- return [
415
- {
416
- type: 'Property',
417
- key: param.name,
418
- kind: 'init',
419
- value,
420
- method: false,
421
- shorthand: true,
422
- computed: false,
423
- loc: param.loc,
424
- range: param.range,
425
- parent: EMPTY_PARENT,
426
- },
427
- ];
428
- }
429
-
430
- // Complex params
431
- return [
432
- {
433
- type: 'Property',
434
- key: param.name,
435
- kind: 'init',
436
- value,
437
- method: false,
438
- shorthand: false,
439
- computed: false,
440
- loc: param.loc,
441
- range: param.range,
442
- parent: EMPTY_PARENT,
443
- },
444
- ];
445
- }
446
- default: {
447
- throw createSyntaxError(
448
- param,
449
- `Unknown Component parameter type of "${param.type}"`,
450
- );
451
- }
452
- }
453
- }
454
-
455
- type ForwardRefDetails = {
456
- forwardRefStatement: VariableDeclaration,
457
- internalCompId: Identifier,
458
- forwardRefCompId: Identifier,
459
- };
460
-
461
- function createForwardRefWrapper(
462
- originalComponent: ComponentDeclaration,
463
- ): ForwardRefDetails {
464
- const internalCompId: Identifier = {
465
- type: 'Identifier',
466
- name: `${originalComponent.id.name}_withRef`,
467
- optional: false,
468
- typeAnnotation: null,
469
- loc: originalComponent.id.loc,
470
- range: originalComponent.id.range,
471
- parent: EMPTY_PARENT,
472
- };
473
- return {
474
- forwardRefStatement: {
475
- type: 'VariableDeclaration',
476
- kind: 'const',
477
- declarations: [
478
- {
479
- type: 'VariableDeclarator',
480
- id: shallowCloneNode(originalComponent.id),
481
- init: {
482
- type: 'CallExpression',
483
- callee: {
484
- type: 'MemberExpression',
485
- object: {
486
- type: 'Identifier',
487
- name: 'React',
488
- optional: false,
489
- typeAnnotation: null,
490
- loc: originalComponent.loc,
491
- range: originalComponent.range,
492
- parent: EMPTY_PARENT,
493
- },
494
- property: {
495
- type: 'Identifier',
496
- name: 'forwardRef',
497
- optional: false,
498
- typeAnnotation: null,
499
- loc: originalComponent.loc,
500
- range: originalComponent.range,
501
- parent: EMPTY_PARENT,
502
- },
503
- computed: false,
504
- optional: false,
505
- loc: originalComponent.loc,
506
- range: originalComponent.range,
507
- parent: EMPTY_PARENT,
508
- },
509
- arguments: [shallowCloneNode(internalCompId)],
510
- typeArguments: null,
511
- optional: false,
512
- loc: originalComponent.loc,
513
- range: originalComponent.range,
514
- parent: EMPTY_PARENT,
515
- },
516
- loc: originalComponent.loc,
517
- range: originalComponent.range,
518
- parent: EMPTY_PARENT,
519
- },
520
- ],
521
- loc: originalComponent.loc,
522
- range: originalComponent.range,
523
- parent: originalComponent.parent,
524
- },
525
- internalCompId: internalCompId,
526
- forwardRefCompId: originalComponent.id,
527
- };
528
- }
529
-
530
- function mapComponentDeclaration(
531
- node: ComponentDeclaration,
532
- options: ParserOptions,
533
- ): {
534
- comp: FunctionDeclaration,
535
- forwardRefDetails: ?ForwardRefDetails,
536
- } {
537
- // Create empty loc for return type annotation nodes
538
- const createRendersTypeLoc = () => ({
539
- loc: {
540
- start: node.body.loc.end,
541
- end: node.body.loc.end,
542
- },
543
- range: [node.body.range[1], node.body.range[1]],
544
- parent: EMPTY_PARENT,
545
- });
546
- const returnType: TypeAnnotation = {
547
- type: 'TypeAnnotation',
548
- typeAnnotation: {
549
- type: 'GenericTypeAnnotation',
550
- id: {
551
- type: 'QualifiedTypeIdentifier',
552
- qualification: {
553
- type: 'Identifier',
554
- name: 'React',
555
- optional: false,
556
- typeAnnotation: null,
557
- ...createRendersTypeLoc(),
558
- },
559
- id: {
560
- type: 'Identifier',
561
- name: 'Node',
562
- optional: false,
563
- typeAnnotation: null,
564
- ...createRendersTypeLoc(),
565
- },
566
- ...createRendersTypeLoc(),
567
- },
568
- typeParameters: null,
569
- ...createRendersTypeLoc(),
570
- },
571
- ...createRendersTypeLoc(),
572
- };
573
-
574
- const {props, ref} = mapComponentParameters(node.params, options);
575
-
576
- let forwardRefDetails: ?ForwardRefDetails = null;
577
-
578
- if (ref != null) {
579
- forwardRefDetails = createForwardRefWrapper(node);
580
- }
581
-
582
- const comp: FunctionDeclaration = {
583
- type: 'FunctionDeclaration',
584
- id:
585
- forwardRefDetails != null
586
- ? shallowCloneNode(forwardRefDetails.internalCompId)
587
- : shallowCloneNode(node.id),
588
- __componentDeclaration: true,
589
- typeParameters: node.typeParameters,
590
- params: props == null ? [] : ref == null ? [props] : [props, ref],
591
- returnType,
592
- body: node.body,
593
- async: false,
594
- generator: false,
595
- predicate: null,
596
- loc: node.loc,
597
- range: node.range,
598
- parent: node.parent,
599
- };
600
-
601
- return {comp, forwardRefDetails};
602
- }
603
-
604
- function mapDeclareHook(node: DeclareHook): DeclareFunction {
605
- return {
606
- type: 'DeclareFunction',
607
- id: {
608
- type: 'Identifier',
609
- name: node.id.name,
610
- optional: node.id.optional,
611
- typeAnnotation: {
612
- type: 'TypeAnnotation',
613
- typeAnnotation: {
614
- type: 'FunctionTypeAnnotation',
615
- this: null,
616
- params: node.id.typeAnnotation.typeAnnotation.params,
617
- typeParameters: node.id.typeAnnotation.typeAnnotation.typeParameters,
618
- rest: node.id.typeAnnotation.typeAnnotation.rest,
619
- returnType: node.id.typeAnnotation.typeAnnotation.returnType,
620
- loc: node.id.typeAnnotation.typeAnnotation.loc,
621
- range: node.id.typeAnnotation.typeAnnotation.range,
622
- parent: node.id.typeAnnotation.typeAnnotation.parent,
623
- },
624
- loc: node.id.typeAnnotation.loc,
625
- range: node.id.typeAnnotation.range,
626
- parent: node.id.typeAnnotation.parent,
627
- },
628
- loc: node.id.loc,
629
- range: node.id.range,
630
- parent: node.id.parent,
631
- },
632
- loc: node.loc,
633
- range: node.range,
634
- parent: node.parent,
635
- predicate: null,
636
- };
637
- }
638
-
639
- function mapHookDeclaration(node: HookDeclaration): FunctionDeclaration {
640
- const comp: FunctionDeclaration = {
641
- type: 'FunctionDeclaration',
642
- id: node.id && shallowCloneNode(node.id),
643
- __hookDeclaration: true,
644
- typeParameters: node.typeParameters,
645
- params: node.params,
646
- returnType: node.returnType,
647
- body: node.body,
648
- async: false,
649
- generator: false,
650
- predicate: null,
651
- loc: node.loc,
652
- range: node.range,
653
- parent: node.parent,
654
- };
655
-
656
- return comp;
657
- }
658
-
659
- /**
660
- * Scan a list of statements and return the position of the
661
- * first statement that contains a reference to a given component
662
- * or null of no references were found.
663
- */
664
- function scanForFirstComponentReference(
665
- compName: string,
666
- bodyList: Array<Statement | ModuleDeclaration>,
667
- ): ?number {
668
- for (let i = 0; i < bodyList.length; i++) {
669
- const bodyNode = bodyList[i];
670
- let referencePos = null;
671
- SimpleTraverser.traverse(bodyNode, {
672
- enter(node: ESNode) {
673
- switch (node.type) {
674
- case 'Identifier': {
675
- if (node.name === compName) {
676
- // We found a reference, record it and stop.
677
- referencePos = i;
678
- throw SimpleTraverser.Break;
679
- }
680
- }
681
- }
682
- },
683
- leave(_node: ESNode) {},
684
- });
685
- if (referencePos != null) {
686
- return referencePos;
687
- }
688
- }
689
-
690
- return null;
691
- }
692
-
693
- function mapComponentDeclarationIntoList(
694
- node: ComponentDeclaration,
695
- newBody: Array<Statement | ModuleDeclaration>,
696
- options: ParserOptions,
697
- insertExport?: (Identifier | FunctionDeclaration) => ModuleDeclaration,
698
- ) {
699
- const {comp, forwardRefDetails} = mapComponentDeclaration(node, options);
700
- if (forwardRefDetails != null) {
701
- // Scan for references to our component.
702
- const referencePos = scanForFirstComponentReference(
703
- forwardRefDetails.forwardRefCompId.name,
704
- newBody,
705
- );
706
-
707
- // If a reference is found insert the forwardRef statement before it (to simulate function hoisting).
708
- if (referencePos != null) {
709
- newBody.splice(referencePos, 0, forwardRefDetails.forwardRefStatement);
710
- } else {
711
- newBody.push(forwardRefDetails.forwardRefStatement);
712
- }
713
-
714
- newBody.push(comp);
715
-
716
- if (insertExport != null) {
717
- newBody.push(insertExport(forwardRefDetails.forwardRefCompId));
718
- }
719
- return;
720
- }
721
-
722
- newBody.push(insertExport != null ? insertExport(comp) : comp);
723
- }
724
-
725
- function mapStatementList(
726
- stmts: $ReadOnlyArray<Statement | ModuleDeclaration>,
727
- options: ParserOptions,
728
- ) {
729
- const newBody: Array<Statement | ModuleDeclaration> = [];
730
- for (const node of stmts) {
731
- switch (node.type) {
732
- case 'ComponentDeclaration': {
733
- mapComponentDeclarationIntoList(node, newBody, options);
734
- break;
735
- }
736
- case 'HookDeclaration': {
737
- const decl = mapHookDeclaration(node);
738
- newBody.push(decl);
739
- break;
740
- }
741
- case 'ExportNamedDeclaration': {
742
- if (node.declaration?.type === 'ComponentDeclaration') {
743
- mapComponentDeclarationIntoList(
744
- node.declaration,
745
- newBody,
746
- options,
747
- componentOrRef => {
748
- switch (componentOrRef.type) {
749
- case 'FunctionDeclaration': {
750
- // No ref, so we can export the component directly.
751
- return nodeWith(node, {declaration: componentOrRef});
752
- }
753
- case 'Identifier': {
754
- // If a ref is inserted, we should just export that id.
755
- return {
756
- type: 'ExportNamedDeclaration',
757
- declaration: null,
758
- specifiers: [
759
- {
760
- type: 'ExportSpecifier',
761
- exported: shallowCloneNode(componentOrRef),
762
- local: shallowCloneNode(componentOrRef),
763
- loc: node.loc,
764
- range: node.range,
765
- parent: EMPTY_PARENT,
766
- },
767
- ],
768
- exportKind: 'value',
769
- source: null,
770
- loc: node.loc,
771
- range: node.range,
772
- parent: node.parent,
773
- };
774
- }
775
- }
776
- },
777
- );
778
- break;
779
- }
780
-
781
- if (node.declaration?.type === 'HookDeclaration') {
782
- const comp = mapHookDeclaration(node.declaration);
783
- newBody.push(nodeWith(node, {declaration: comp}));
784
- break;
785
- }
786
-
787
- newBody.push(node);
788
- break;
789
- }
790
- case 'ExportDefaultDeclaration': {
791
- if (node.declaration?.type === 'ComponentDeclaration') {
792
- mapComponentDeclarationIntoList(
793
- node.declaration,
794
- newBody,
795
- options,
796
- componentOrRef => nodeWith(node, {declaration: componentOrRef}),
797
- );
798
- break;
799
- }
800
-
801
- if (node.declaration?.type === 'HookDeclaration') {
802
- const comp = mapHookDeclaration(node.declaration);
803
- newBody.push(nodeWith(node, {declaration: comp}));
804
- break;
805
- }
806
-
807
- newBody.push(node);
808
- break;
809
- }
810
- default: {
811
- newBody.push(node);
812
- }
813
- }
814
- }
815
-
816
- return newBody;
817
- }
818
-
819
- export function transformProgram(
820
- program: Program,
821
- options: ParserOptions,
822
- ): Program {
823
- return SimpleTransform.transformProgram(program, {
824
- transform(node: ESNode) {
825
- switch (node.type) {
826
- case 'DeclareComponent': {
827
- return mapDeclareComponent(node);
828
- }
829
- case 'DeclareHook': {
830
- return mapDeclareHook(node);
831
- }
832
- case 'Program':
833
- case 'BlockStatement': {
834
- return nodeWith(node, {body: mapStatementList(node.body, options)});
835
- }
836
- case 'SwitchCase': {
837
- const consequent = mapStatementList(node.consequent, options);
838
- return nodeWith(node, {
839
- /* $FlowExpectedError[incompatible-type] We know `mapStatementList` will
840
- not return `ModuleDeclaration` nodes if it is not passed any */
841
- consequent,
842
- });
843
- }
844
- case 'ComponentDeclaration': {
845
- throw createSyntaxError(
846
- node,
847
- `Components must be defined at the top level of a module or within a ` +
848
- `BlockStatement, instead got parent of "${node.parent?.type}".`,
849
- );
850
- }
851
- case 'HookDeclaration': {
852
- throw createSyntaxError(
853
- node,
854
- `Hooks must be defined at the top level of a module or within a ` +
855
- `BlockStatement, instead got parent of "${node.parent?.type}".`,
856
- );
857
- }
858
- default: {
859
- return node;
860
- }
861
- }
862
- },
863
- });
864
- }