hermes-transform 0.8.0 → 0.10.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 (65) hide show
  1. package/ESLINT_LICENCE +19 -0
  2. package/PRETTIER_LICENCE +7 -0
  3. package/dist/detachedNode.js +100 -42
  4. package/dist/detachedNode.js.flow +116 -41
  5. package/dist/generated/TransformCloneSignatures.js.flow +18 -0
  6. package/dist/generated/TransformModifySignatures.js.flow +1127 -0
  7. package/dist/generated/TransformReplaceSignatures.js.flow +15 -1
  8. package/dist/generated/node-types.js +852 -883
  9. package/dist/generated/node-types.js.flow +1187 -1217
  10. package/dist/generated/special-case-node-types/Comment.js +36 -0
  11. package/dist/generated/special-case-node-types/Comment.js.flow +36 -0
  12. package/dist/generated/special-case-node-types/DeclareExportDeclaration.js +55 -0
  13. package/dist/generated/special-case-node-types/DeclareExportDeclaration.js.flow +97 -0
  14. package/dist/generated/special-case-node-types/ExportNamedDeclaration.js +42 -0
  15. package/dist/generated/special-case-node-types/ExportNamedDeclaration.js.flow +75 -0
  16. package/dist/generated/special-case-node-types/Literal.js +97 -0
  17. package/dist/generated/special-case-node-types/Literal.js.flow +139 -0
  18. package/dist/generated/special-case-node-types/ObjectTypeProperty.js +73 -0
  19. package/dist/generated/special-case-node-types/ObjectTypeProperty.js.flow +107 -0
  20. package/dist/generated/special-case-node-types/Property.js +136 -0
  21. package/dist/generated/special-case-node-types/Property.js.flow +237 -0
  22. package/dist/generated/special-case-node-types/misc.js +119 -0
  23. package/dist/generated/special-case-node-types/misc.js.flow +205 -0
  24. package/dist/generated/special-case-node-types.js +42 -180
  25. package/dist/generated/special-case-node-types.js.flow +7 -258
  26. package/dist/index.js +19 -3
  27. package/dist/index.js.flow +6 -2
  28. package/dist/transform/TransformContext.js +34 -11
  29. package/dist/transform/TransformContext.js.flow +90 -33
  30. package/dist/transform/comments/comments.js +34 -5
  31. package/dist/transform/comments/comments.js.flow +39 -4
  32. package/dist/transform/comments/prettier/main/comments.js +1 -1
  33. package/dist/transform/comments/prettier/main/comments.js.flow +2 -1
  34. package/dist/transform/mutations/InsertStatement.js +4 -3
  35. package/dist/transform/mutations/InsertStatement.js.flow +4 -3
  36. package/dist/transform/mutations/RemoveComment.js +3 -3
  37. package/dist/transform/mutations/RemoveComment.js.flow +3 -5
  38. package/dist/transform/mutations/RemoveNode.js +2 -2
  39. package/dist/transform/mutations/RemoveNode.js.flow +2 -2
  40. package/dist/transform/mutations/RemoveStatement.js +2 -2
  41. package/dist/transform/mutations/RemoveStatement.js.flow +2 -2
  42. package/dist/transform/mutations/ReplaceNode.js +10 -7
  43. package/dist/transform/mutations/ReplaceNode.js.flow +7 -5
  44. package/dist/transform/mutations/ReplaceStatementWithMany.js +2 -2
  45. package/dist/transform/mutations/ReplaceStatementWithMany.js.flow +7 -4
  46. package/dist/transform/mutations/utils/getStatementParent.js +3 -2
  47. package/dist/transform/mutations/utils/getStatementParent.js.flow +5 -2
  48. package/dist/transform/parse.js +55 -0
  49. package/dist/transform/parse.js.flow +55 -0
  50. package/dist/transform/print.js +160 -0
  51. package/dist/transform/print.js.flow +176 -0
  52. package/dist/transform/transform.js +6 -67
  53. package/dist/transform/transform.js.flow +6 -69
  54. package/dist/transform/{getTransformedAST.js → transformAST.js} +7 -16
  55. package/dist/transform/{getTransformedAST.js.flow → transformAST.js.flow} +7 -14
  56. package/dist/traverse/NodeEventGenerator.js.flow +1 -1
  57. package/dist/traverse/traverse.js +36 -35
  58. package/dist/traverse/traverse.js.flow +46 -27
  59. package/package.json +10 -5
  60. package/dist/getVisitorKeys.js +0 -33
  61. package/dist/getVisitorKeys.js.flow +0 -31
  62. package/dist/transform/mutations/utils/arrayUtils.js +0 -43
  63. package/dist/transform/mutations/utils/arrayUtils.js.flow +0 -50
  64. package/dist/traverse/SimpleTraverser.js +0 -118
  65. package/dist/traverse/SimpleTraverser.js.flow +0 -112
@@ -18,8 +18,9 @@ import type {
18
18
  Statement,
19
19
  TypeAnnotationType,
20
20
  } from 'hermes-estree';
21
- import type {DetachedNode} from '../detachedNode';
21
+ import type {DetachedNode, MaybeDetachedNode} from '../detachedNode';
22
22
  import type {TransformCloneSignatures} from '../generated/TransformCloneSignatures';
23
+ import type {TransformModifySignatures} from '../generated/TransformModifySignatures';
23
24
  import type {TransformReplaceSignatures} from '../generated/TransformReplaceSignatures';
24
25
  import type {TraversalContext} from '../traverse/traverse';
25
26
  import type {AddCommentsMutation} from './mutations/AddComments';
@@ -29,9 +30,12 @@ import type {RemoveCommentMutation} from './mutations/RemoveComment';
29
30
  import type {RemoveNodeMutation} from './mutations/RemoveNode';
30
31
  import type {RemoveStatementMutation} from './mutations/RemoveStatement';
31
32
  import type {ReplaceNodeMutation} from './mutations/ReplaceNode';
32
- import type {ReplaceStatementWithManyMutation} from './mutations/ReplaceStatementWithMany';
33
+ import type {
34
+ ReplaceStatementWithManyMutation,
35
+ ReplaceStatementWithManyMutationNodes,
36
+ } from './mutations/ReplaceStatementWithMany';
33
37
 
34
- import {deepCloneNode, shallowCloneNode} from '../detachedNode';
38
+ import {asDetachedNode, deepCloneNode, shallowCloneNode} from '../detachedNode';
35
39
  import {
36
40
  CommentPlacement,
37
41
  getCommentsForNode,
@@ -103,6 +107,8 @@ type TransformCloneAPIs = $ReadOnly<{
103
107
  shallowCloneArray: {
104
108
  <T: ESNode>(node: $ReadOnlyArray<T>): $ReadOnlyArray<DetachedNode<T>>,
105
109
  <T: ESNode>(node: ?$ReadOnlyArray<T>): ?$ReadOnlyArray<DetachedNode<T>>,
110
+ <T: ESNode>(node: $ReadOnlyArray<?T>): $ReadOnlyArray<DetachedNode<?T>>,
111
+ <T: ESNode>(node: ?$ReadOnlyArray<?T>): ?$ReadOnlyArray<DetachedNode<?T>>,
106
112
  },
107
113
 
108
114
  /**
@@ -148,14 +154,14 @@ type TransformCommentAPIs = $ReadOnly<{
148
154
  */
149
155
  cloneCommentsTo: (
150
156
  target: ESNode,
151
- destination: ESNode | DetachedNode<ESNode>,
157
+ destination: MaybeDetachedNode<ESNode>,
152
158
  ) => void,
153
159
 
154
160
  /**
155
161
  * Add comments on the line before a specified node.
156
162
  */
157
163
  addLeadingComments: (
158
- node: ESNode | DetachedNode<ESNode>,
164
+ node: MaybeDetachedNode<ESNode>,
159
165
  comments: SingleOrArray<Comment>,
160
166
  ) => void,
161
167
 
@@ -163,7 +169,7 @@ type TransformCommentAPIs = $ReadOnly<{
163
169
  * Add comments inline before a specified node.
164
170
  */
165
171
  addLeadingInlineComments: (
166
- node: ESNode | DetachedNode<ESNode>,
172
+ node: MaybeDetachedNode<ESNode>,
167
173
  comments: SingleOrArray<Comment>,
168
174
  ) => void,
169
175
 
@@ -171,7 +177,7 @@ type TransformCommentAPIs = $ReadOnly<{
171
177
  * Add comments on the line after a specified node.
172
178
  */
173
179
  addTrailingComments: (
174
- node: ESNode | DetachedNode<ESNode>,
180
+ node: MaybeDetachedNode<ESNode>,
175
181
  comments: SingleOrArray<Comment>,
176
182
  ) => void,
177
183
 
@@ -179,7 +185,7 @@ type TransformCommentAPIs = $ReadOnly<{
179
185
  * Add comments inline after a specified node.
180
186
  */
181
187
  addTrailingInlineComments: (
182
- node: ESNode | DetachedNode<ESNode>,
188
+ node: MaybeDetachedNode<ESNode>,
183
189
  comments: SingleOrArray<Comment>,
184
190
  ) => void,
185
191
 
@@ -197,7 +203,7 @@ type TransformInsertAPIs = $ReadOnly<{
197
203
  insertAfterStatement: (
198
204
  target: InsertStatementMutation['target'],
199
205
  nodeToInsert: SingleOrArray<
200
- DetachedNode<InsertStatementMutation['target']>,
206
+ MaybeDetachedNode<InsertStatementMutation['target']>,
201
207
  >,
202
208
  ) => void,
203
209
 
@@ -208,11 +214,19 @@ type TransformInsertAPIs = $ReadOnly<{
208
214
  insertBeforeStatement: (
209
215
  target: InsertStatementMutation['target'],
210
216
  nodeToInsert: SingleOrArray<
211
- DetachedNode<InsertStatementMutation['target']>,
217
+ MaybeDetachedNode<InsertStatementMutation['target']>,
212
218
  >,
213
219
  ) => void,
214
220
  }>;
215
221
 
222
+ type TransformModifyAPIs = $ReadOnly<{
223
+ /**
224
+ * Modifies a given node in place.
225
+ * This is equivalent to doing a replace with a shallow clone with overrides.
226
+ */
227
+ modifyNodeInPlace: TransformModifySignatures,
228
+ }>;
229
+
216
230
  type TransformRemoveAPIs = $ReadOnly<{
217
231
  /**
218
232
  * Removes a given node from the AST.
@@ -236,37 +250,37 @@ type TransformReplaceAPIs = $ReadOnly<{
236
250
  // Expressions may be replaced with other expressions
237
251
  (
238
252
  target: Expression,
239
- nodeToReplaceWith: DetachedNode<Expression>,
253
+ nodeToReplaceWith: MaybeDetachedNode<Expression>,
240
254
  options?: ReplaceNodeOptions,
241
255
  ): void,
242
256
  // Module declarations may be replaced with statements or other module declarations
243
257
  (
244
258
  target: ModuleDeclaration,
245
- nodeToReplaceWith: DetachedNode<ModuleDeclaration | Statement>,
259
+ nodeToReplaceWith: MaybeDetachedNode<ModuleDeclaration | Statement>,
246
260
  options?: ReplaceNodeOptions,
247
261
  ): void,
248
262
  // Statement maybe be replaced with statements or module declarations
249
263
  (
250
264
  target: Statement,
251
- nodeToReplaceWith: DetachedNode<ModuleDeclaration | Statement>,
265
+ nodeToReplaceWith: MaybeDetachedNode<ModuleDeclaration | Statement>,
252
266
  options?: ReplaceNodeOptions,
253
267
  ): void,
254
268
  // Types maybe be replaced with other types
255
269
  (
256
270
  target: TypeAnnotationType,
257
- nodeToReplaceWith: DetachedNode<TypeAnnotationType>,
271
+ nodeToReplaceWith: MaybeDetachedNode<TypeAnnotationType>,
258
272
  options?: ReplaceNodeOptions,
259
273
  ): void,
260
274
  // Class members may be replaced with other class members
261
275
  (
262
276
  target: ClassMember,
263
- nodeToReplaceWith: DetachedNode<ClassMember>,
277
+ nodeToReplaceWith: MaybeDetachedNode<ClassMember>,
264
278
  options?: ReplaceNodeOptions,
265
279
  ): void,
266
280
  // Function params amy be replace with other function params
267
281
  (
268
282
  target: FunctionParameter,
269
- nodeToReplaceWith: DetachedNode<FunctionParameter>,
283
+ nodeToReplaceWith: MaybeDetachedNode<FunctionParameter>,
270
284
  options?: ReplaceNodeOptions,
271
285
  ): void,
272
286
  } & TransformReplaceSignatures, // allow like-for-like replacements as well
@@ -277,7 +291,9 @@ type TransformReplaceAPIs = $ReadOnly<{
277
291
  */
278
292
  replaceStatementWithMany: (
279
293
  target: ReplaceStatementWithManyMutation['target'],
280
- nodesToReplaceWith: ReplaceStatementWithManyMutation['nodesToReplaceWith'],
294
+ nodesToReplaceWith: $ReadOnlyArray<
295
+ MaybeDetachedNode<ReplaceStatementWithManyMutationNodes>,
296
+ >,
281
297
  options?: {
282
298
  /**
283
299
  * Moves the comments from the target node to the first node in the array.
@@ -296,6 +312,7 @@ export type TransformContextAdditions = $ReadOnly<{
296
312
  ...TransformCommentAPIs,
297
313
  ...TransformCloneAPIs,
298
314
  ...TransformInsertAPIs,
315
+ ...TransformModifyAPIs,
299
316
  ...TransformRemoveAPIs,
300
317
  ...TransformReplaceAPIs,
301
318
  }>;
@@ -321,14 +338,15 @@ export function getTransformContext(): TransformContextAdditions {
321
338
  return null;
322
339
  }
323
340
 
324
- return shallowCloneNode(node);
341
+ return shallowCloneNode(node, {});
325
342
  }: TransformCloneAPIs['shallowCloneNode']),
326
343
 
327
- // $FlowExpectedError[incompatible-exact]
328
344
  shallowCloneNodeWithOverrides: ((
329
345
  node: ?ESNode,
330
- newProps?: $ReadOnly<{...}>,
331
- ): ?DetachedNode<ESNode> => {
346
+ newProps?: $ReadOnly<{...}> = {},
347
+ ): // $FlowExpectedError[incompatible-cast]
348
+ // $FlowExpectedError[prop-missing]
349
+ ?DetachedNode<ESNode> => {
332
350
  if (node == null) {
333
351
  return null;
334
352
  }
@@ -337,14 +355,20 @@ export function getTransformContext(): TransformContextAdditions {
337
355
  }: TransformCloneAPIs['shallowCloneNodeWithOverrides']),
338
356
 
339
357
  shallowCloneArray: (<T: ESNode>(
340
- nodes: ?$ReadOnlyArray<T>,
358
+ nodes: ?$ReadOnlyArray<?T>,
341
359
  ): // $FlowExpectedError[incompatible-cast]
342
- ?$ReadOnlyArray<DetachedNode<ESNode>> => {
360
+ ?$ReadOnlyArray<DetachedNode<?ESNode>> => {
343
361
  if (nodes == null) {
344
362
  return null;
345
363
  }
346
364
 
347
- return nodes.map(node => shallowCloneNode<T>(node));
365
+ return nodes.map((node): DetachedNode<?ESNode> => {
366
+ if (node == null) {
367
+ // $FlowExpectedError[incompatible-return]
368
+ return node;
369
+ }
370
+ return shallowCloneNode<T>(node, {});
371
+ });
348
372
  }: TransformCloneAPIs['shallowCloneArray']),
349
373
 
350
374
  deepCloneNode: ((
@@ -355,14 +379,15 @@ export function getTransformContext(): TransformContextAdditions {
355
379
  return null;
356
380
  }
357
381
 
358
- return deepCloneNode(node);
382
+ return deepCloneNode(node, {});
359
383
  }: TransformCloneAPIs['deepCloneNode']),
360
384
 
361
- // $FlowExpectedError[incompatible-exact]
362
385
  deepCloneNodeWithOverrides: ((
363
386
  node: ?ESNode,
364
- newProps?: $ReadOnly<{...}>,
365
- ): ?DetachedNode<ESNode> => {
387
+ newProps?: $ReadOnly<{...}> = {},
388
+ ): // $FlowExpectedError[incompatible-cast]
389
+ // $FlowExpectedError[prop-missing]
390
+ ?DetachedNode<ESNode> => {
366
391
  if (node == null) {
367
392
  return null;
368
393
  }
@@ -444,13 +469,25 @@ export function getTransformContext(): TransformContextAdditions {
444
469
  const insertAPIs: TransformInsertAPIs = {
445
470
  insertAfterStatement: ((target, nodesToInsert): void => {
446
471
  pushMutation(
447
- createInsertStatementMutation('after', target, toArray(nodesToInsert)),
472
+ createInsertStatementMutation(
473
+ 'after',
474
+ target,
475
+ toArray(nodesToInsert).map(n =>
476
+ asDetachedNode(n, {useDeepClone: true}),
477
+ ),
478
+ ),
448
479
  );
449
480
  }: TransformInsertAPIs['insertBeforeStatement']),
450
481
 
451
482
  insertBeforeStatement: ((target, nodesToInsert): void => {
452
483
  pushMutation(
453
- createInsertStatementMutation('before', target, toArray(nodesToInsert)),
484
+ createInsertStatementMutation(
485
+ 'before',
486
+ target,
487
+ toArray(nodesToInsert).map(n =>
488
+ asDetachedNode(n, {useDeepClone: true}),
489
+ ),
490
+ ),
454
491
  );
455
492
  }: TransformInsertAPIs['insertBeforeStatement']),
456
493
  };
@@ -466,11 +503,15 @@ export function getTransformContext(): TransformContextAdditions {
466
503
  const replaceAPIs: TransformReplaceAPIs = {
467
504
  replaceNode: ((
468
505
  target: ESNode,
469
- nodeToReplaceWith: DetachedNode<ESNode>,
506
+ nodeToReplaceWith: MaybeDetachedNode<ESNode>,
470
507
  options?: ReplaceNodeOptions,
471
508
  ): void => {
472
509
  pushMutation(
473
- createReplaceNodeMutation(target, nodeToReplaceWith, options),
510
+ createReplaceNodeMutation(
511
+ target,
512
+ asDetachedNode(nodeToReplaceWith),
513
+ options,
514
+ ),
474
515
  );
475
516
  }: TransformReplaceAPIs['replaceNode']),
476
517
 
@@ -482,12 +523,27 @@ export function getTransformContext(): TransformContextAdditions {
482
523
  pushMutation(
483
524
  createReplaceStatementWithManyMutation(
484
525
  target,
485
- nodesToReplaceWith,
526
+ nodesToReplaceWith.map(n => asDetachedNode(n)),
486
527
  options,
487
528
  ),
488
529
  );
489
530
  }: TransformReplaceAPIs['replaceStatementWithMany']),
490
531
  };
532
+ const modifyAPIs: TransformModifyAPIs = {
533
+ modifyNodeInPlace: ((
534
+ node: ?ESNode,
535
+ newProps?: $ReadOnly<{...}> = {},
536
+ options?: ReplaceNodeOptions,
537
+ ): void => {
538
+ if (node == null) {
539
+ return;
540
+ }
541
+
542
+ const cloned = shallowCloneNode(node, newProps, {preserveLocation: true});
543
+ // $FlowExpectedError[incompatible-call]
544
+ replaceAPIs.replaceNode(node, cloned, options);
545
+ }: TransformModifyAPIs['modifyNodeInPlace']),
546
+ };
491
547
 
492
548
  return {
493
549
  mutations,
@@ -500,6 +556,7 @@ export function getTransformContext(): TransformContextAdditions {
500
556
  ...cloneAPIs,
501
557
  ...commentAPIs,
502
558
  ...insertAPIs,
559
+ ...modifyAPIs,
503
560
  ...removeAPIs,
504
561
  ...replaceAPIs,
505
562
  };
@@ -10,7 +10,10 @@ exports.appendCommentToSource = appendCommentToSource;
10
10
  exports.attachComments = attachComments;
11
11
  exports.cloneComment = cloneComment;
12
12
  exports.cloneCommentWithMarkers = cloneCommentWithMarkers;
13
+ exports.cloneJSDocCommentsToNewNode = cloneJSDocCommentsToNewNode;
13
14
  exports.getCommentsForNode = getCommentsForNode;
15
+ exports.getLeadingCommentsForNode = getLeadingCommentsForNode;
16
+ exports.getTrailingCommentsForNode = getTrailingCommentsForNode;
14
17
  exports.isLeadingComment = isLeadingComment;
15
18
  exports.isTrailingComment = isTrailingComment;
16
19
  exports.moveCommentsToNewNode = moveCommentsToNewNode;
@@ -24,6 +27,8 @@ var _printerEstree = _interopRequireDefault(require("./prettier/language-js/prin
24
27
 
25
28
  var _util = require("./prettier/common/util");
26
29
 
30
+ var _hermesEstree = require("hermes-estree");
31
+
27
32
  var _os = require("os");
28
33
 
29
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -57,18 +62,34 @@ function moveCommentsToNewNode(oldNode, newNode) {
57
62
  setCommentsOnNode(oldNode, []);
58
63
  }
59
64
 
65
+ function cloneJSDocCommentsToNewNode(oldNode, newNode) {
66
+ const comments = getCommentsForNode(oldNode).filter(comment => {
67
+ return (0, _hermesEstree.isBlockComment)(comment) && // JSDoc comments always start with an extra asterisk
68
+ comment.value.startsWith('*');
69
+ });
70
+ setCommentsOnNode(newNode, comments.map(cloneCommentWithMarkers));
71
+ }
72
+
60
73
  function setCommentsOnNode(node, comments) {
61
74
  // $FlowExpectedError - this property is secretly added by prettier.
62
75
  node.comments = comments;
63
76
  }
64
77
 
65
- function addCommentsToNode(node, comments) {
78
+ function addCommentsToNode(node, comments, side = 'trailing') {
66
79
  var _node$comments;
67
80
 
68
- // $FlowExpectedError - this property is secretly added by prettier.
69
- node.comments = (_node$comments = node.comments) != null ? _node$comments : []; // $FlowExpectedError
70
-
71
- node.comments.push(...comments);
81
+ // $FlowExpectedError[prop-missing] - this property is secretly added by prettier.
82
+ // $FlowExpectedError[cannot-write]
83
+ // $FlowExpectedError[incompatible-use]
84
+ node.comments = (_node$comments = node.comments) != null ? _node$comments : [];
85
+
86
+ if (side === 'leading') {
87
+ // $FlowExpectedError[incompatible-cast]
88
+ node.comments.unshift(...comments);
89
+ } else {
90
+ // $FlowExpectedError[incompatible-cast]
91
+ node.comments.push(...comments);
92
+ }
72
93
  }
73
94
 
74
95
  function getCommentsForNode(node) {
@@ -88,6 +109,14 @@ function isTrailingComment(comment) {
88
109
  return comment.trailing === true;
89
110
  }
90
111
 
112
+ function getLeadingCommentsForNode(node) {
113
+ return getCommentsForNode(node).filter(isLeadingComment);
114
+ }
115
+
116
+ function getTrailingCommentsForNode(node) {
117
+ return getCommentsForNode(node).filter(isTrailingComment);
118
+ }
119
+
91
120
  function addComment(node, comment, placement) {
92
121
  switch (placement) {
93
122
  case CommentPlacement.LEADING_OWN_LINE:
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import type {Comment, ESNode, Program} from 'hermes-estree';
12
- import type {DetachedNode} from '../../detachedNode';
12
+ import type {DetachedNode, MaybeDetachedNode} from '../../detachedNode';
13
13
 
14
14
  // $FlowExpectedError[untyped-import]
15
15
  import {attach as untypedAttach} from './prettier/main/comments';
@@ -23,6 +23,7 @@ import {
23
23
  // $FlowExpectedError[untyped-import]
24
24
  addTrailingComment as untypedAddTrailingComment,
25
25
  } from './prettier/common/util';
26
+ import {isBlockComment} from 'hermes-estree';
26
27
  import {EOL} from 'os';
27
28
 
28
29
  export type Options = $ReadOnly<{}>;
@@ -54,6 +55,20 @@ export function moveCommentsToNewNode(
54
55
  setCommentsOnNode(oldNode, []);
55
56
  }
56
57
 
58
+ export function cloneJSDocCommentsToNewNode(
59
+ oldNode: ESNode,
60
+ newNode: MaybeDetachedNode<ESNode>,
61
+ ): void {
62
+ const comments = getCommentsForNode(oldNode).filter(comment => {
63
+ return (
64
+ isBlockComment(comment) &&
65
+ // JSDoc comments always start with an extra asterisk
66
+ comment.value.startsWith('*')
67
+ );
68
+ });
69
+ setCommentsOnNode(newNode, comments.map(cloneCommentWithMarkers));
70
+ }
71
+
57
72
  export function setCommentsOnNode(
58
73
  node: ESNode | DetachedNode<ESNode>,
59
74
  comments: $ReadOnlyArray<Comment>,
@@ -65,11 +80,19 @@ export function setCommentsOnNode(
65
80
  export function addCommentsToNode(
66
81
  node: ESNode | DetachedNode<ESNode>,
67
82
  comments: $ReadOnlyArray<Comment>,
83
+ side?: 'leading' | 'trailing' = 'trailing',
68
84
  ): void {
69
- // $FlowExpectedError - this property is secretly added by prettier.
85
+ // $FlowExpectedError[prop-missing] - this property is secretly added by prettier.
86
+ // $FlowExpectedError[cannot-write]
87
+ // $FlowExpectedError[incompatible-use]
70
88
  node.comments = node.comments ?? [];
71
- // $FlowExpectedError
72
- (node.comments: Array<Comment>).push(...comments);
89
+ if (side === 'leading') {
90
+ // $FlowExpectedError[incompatible-cast]
91
+ (node.comments: Array<Comment>).unshift(...comments);
92
+ } else {
93
+ // $FlowExpectedError[incompatible-cast]
94
+ (node.comments: Array<Comment>).push(...comments);
95
+ }
73
96
  }
74
97
 
75
98
  export function getCommentsForNode(
@@ -88,6 +111,18 @@ export function isTrailingComment(comment: Comment): boolean {
88
111
  return comment.trailing === true;
89
112
  }
90
113
 
114
+ export function getLeadingCommentsForNode(
115
+ node: ESNode | DetachedNode<ESNode>,
116
+ ): $ReadOnlyArray<Comment> {
117
+ return getCommentsForNode(node).filter(isLeadingComment);
118
+ }
119
+
120
+ export function getTrailingCommentsForNode(
121
+ node: ESNode | DetachedNode<ESNode>,
122
+ ): $ReadOnlyArray<Comment> {
123
+ return getCommentsForNode(node).filter(isTrailingComment);
124
+ }
125
+
91
126
  export function addComment(
92
127
  node: ESNode | DetachedNode<ESNode>,
93
128
  comment: Comment,
@@ -50,7 +50,7 @@ function getSortedChildNodes(node, options, resultArray) {
50
50
  return childNodesCache.get(node);
51
51
  }
52
52
 
53
- const childNodes = printer.getCommentChildNodes && printer.getCommentChildNodes(node, options) || typeof node === 'object' && Object.entries(node).filter(([key]) => key !== 'enclosingNode' && key !== 'precedingNode' && key !== 'followingNode' && key !== 'tokens' && key !== 'comments').map(([, value]) => value);
53
+ const childNodes = printer.getCommentChildNodes && printer.getCommentChildNodes(node, options) || typeof node === 'object' && Object.entries(node).filter(([key]) => key !== 'enclosingNode' && key !== 'precedingNode' && key !== 'followingNode' && key !== 'tokens' && key !== 'comments' && key !== 'parent').map(([, value]) => value);
54
54
 
55
55
  if (!childNodes) {
56
56
  return;
@@ -57,7 +57,8 @@ function getSortedChildNodes(node, options, resultArray) {
57
57
  key !== 'precedingNode' &&
58
58
  key !== 'followingNode' &&
59
59
  key !== 'tokens' &&
60
- key !== 'comments',
60
+ key !== 'comments' &&
61
+ key !== 'parent',
61
62
  )
62
63
  .map(([, value]) => value));
63
64
 
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createInsertStatementMutation = createInsertStatementMutation;
7
7
  exports.performInsertStatementMutation = performInsertStatementMutation;
8
8
 
9
- var _arrayUtils = require("./utils/arrayUtils");
9
+ var _hermesParser = require("hermes-parser");
10
10
 
11
11
  var _getStatementParent = require("./utils/getStatementParent");
12
12
 
@@ -58,13 +58,13 @@ function performInsertStatementMutation(mutationContext, mutation) {
58
58
  switch (mutation.side) {
59
59
  case 'before':
60
60
  {
61
- parent[insertionParent.key] = (0, _arrayUtils.insertInArray)(parent[insertionParent.key], insertionParent.targetIndex, mutation.nodesToInsert);
61
+ parent[insertionParent.key] = _hermesParser.astArrayMutationHelpers.insertInArray(parent[insertionParent.key], insertionParent.targetIndex, mutation.nodesToInsert);
62
62
  break;
63
63
  }
64
64
 
65
65
  case 'after':
66
66
  {
67
- parent[insertionParent.key] = (0, _arrayUtils.insertInArray)(parent[insertionParent.key], insertionParent.targetIndex + 1, mutation.nodesToInsert);
67
+ parent[insertionParent.key] = _hermesParser.astArrayMutationHelpers.insertInArray(parent[insertionParent.key], insertionParent.targetIndex + 1, mutation.nodesToInsert);
68
68
  break;
69
69
  }
70
70
  }
@@ -86,5 +86,6 @@ function performInsertStatementMutation(mutationContext, mutation) {
86
86
  parent: insertionParent.parent
87
87
  });
88
88
  insertionParent.parent[insertionParent.key] = blockStatement;
89
+ statementToWrap.parent = blockStatement;
89
90
  return insertionParent.parent;
90
91
  }
@@ -12,7 +12,7 @@ import type {ESNode, ModuleDeclaration, Statement} from 'hermes-estree';
12
12
  import type {MutationContext} from '../MutationContext';
13
13
  import type {DetachedNode} from '../../detachedNode';
14
14
 
15
- import {insertInArray} from './utils/arrayUtils';
15
+ import {astArrayMutationHelpers} from 'hermes-parser';
16
16
  import {getStatementParent} from './utils/getStatementParent';
17
17
  import {isValidModuleDeclarationParent} from './utils/isValidModuleDeclarationParent';
18
18
  import {InvalidInsertionError} from '../Errors';
@@ -73,7 +73,7 @@ export function performInsertStatementMutation(
73
73
  } = insertionParent.parent;
74
74
  switch (mutation.side) {
75
75
  case 'before': {
76
- parent[insertionParent.key] = insertInArray(
76
+ parent[insertionParent.key] = astArrayMutationHelpers.insertInArray(
77
77
  parent[insertionParent.key],
78
78
  insertionParent.targetIndex,
79
79
  mutation.nodesToInsert,
@@ -82,7 +82,7 @@ export function performInsertStatementMutation(
82
82
  }
83
83
 
84
84
  case 'after': {
85
- parent[insertionParent.key] = insertInArray(
85
+ parent[insertionParent.key] = astArrayMutationHelpers.insertInArray(
86
86
  parent[insertionParent.key],
87
87
  insertionParent.targetIndex + 1,
88
88
  mutation.nodesToInsert,
@@ -113,6 +113,7 @@ export function performInsertStatementMutation(
113
113
 
114
114
  (insertionParent.parent: interface {[string]: mixed})[insertionParent.key] =
115
115
  blockStatement;
116
+ statementToWrap.parent = blockStatement;
116
117
 
117
118
  return insertionParent.parent;
118
119
  }
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createRemoveCommentMutation = createRemoveCommentMutation;
7
7
  exports.performRemoveCommentMutations = performRemoveCommentMutations;
8
8
 
9
- var _SimpleTraverser = require("../../traverse/SimpleTraverser");
9
+ var _hermesParser = require("hermes-parser");
10
10
 
11
11
  var _comments = require("../comments/comments");
12
12
 
@@ -33,7 +33,7 @@ function performRemoveCommentMutations(ast, mutations) {
33
33
 
34
34
  const commentsToRemove = new Set(mutations.map(m => m.comment));
35
35
 
36
- _SimpleTraverser.SimpleTraverser.traverse(ast, {
36
+ _hermesParser.SimpleTraverser.traverse(ast, {
37
37
  enter(node) {
38
38
  if (node === ast) {
39
39
  return;
@@ -56,7 +56,7 @@ function performRemoveCommentMutations(ast, mutations) {
56
56
 
57
57
  if (commentsToRemove.size === 0) {
58
58
  // no more comments to process - so we can exit traversal
59
- throw _SimpleTraverser.SimpleTraverserBreak;
59
+ throw _hermesParser.SimpleTraverserBreak;
60
60
  }
61
61
  },
62
62
 
@@ -9,10 +9,8 @@
9
9
  */
10
10
 
11
11
  import type {Comment, Program} from 'hermes-estree';
12
- import {
13
- SimpleTraverser,
14
- SimpleTraverserBreak,
15
- } from '../../traverse/SimpleTraverser';
12
+
13
+ import {SimpleTraverser, SimpleTraverserBreak} from 'hermes-parser';
16
14
  import {getCommentsForNode, setCommentsOnNode} from '../comments/comments';
17
15
 
18
16
  export type RemoveCommentMutation = $ReadOnly<{
@@ -70,7 +68,7 @@ function intersectSets<T>(
70
68
  first: $ReadOnlySet<T>,
71
69
  other: $ReadOnlySet<T>,
72
70
  ): Set<T> {
73
- const ret = new Set();
71
+ const ret = new Set<T>();
74
72
  for (const value of first) {
75
73
  if (other.has(value)) {
76
74
  ret.add(value);
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createRemoveNodeMutation = createRemoveNodeMutation;
7
7
  exports.performRemoveNodeMutation = performRemoveNodeMutation;
8
8
 
9
- var _arrayUtils = require("./utils/arrayUtils");
9
+ var _hermesParser = require("hermes-parser");
10
10
 
11
11
  var _Errors = require("../Errors");
12
12
 
@@ -187,6 +187,6 @@ function performRemoveNodeMutation(mutationContext, mutation) {
187
187
  mutationContext.markDeletion(mutation.node);
188
188
  mutationContext.markMutation(removalParent.parent, removalParent.key);
189
189
  const parent = removalParent.parent;
190
- parent[removalParent.key] = (0, _arrayUtils.removeFromArray)(parent[removalParent.key], removalParent.targetIndex);
190
+ parent[removalParent.key] = _hermesParser.astArrayMutationHelpers.removeFromArray(parent[removalParent.key], removalParent.targetIndex);
191
191
  return removalParent.parent;
192
192
  }
@@ -30,7 +30,7 @@ import type {
30
30
  import type {MutationContext} from '../MutationContext';
31
31
  import type {DetachedNode} from '../../detachedNode';
32
32
 
33
- import {removeFromArray} from './utils/arrayUtils';
33
+ import {astArrayMutationHelpers} from 'hermes-parser';
34
34
  import {InvalidRemovalError} from '../Errors';
35
35
 
36
36
  export type RemoveNodeMutation = $ReadOnly<{
@@ -281,7 +281,7 @@ export function performRemoveNodeMutation(
281
281
  const parent: interface {
282
282
  [string]: $ReadOnlyArray<DetachedNode<RemoveNodeMutation['node']>>,
283
283
  } = removalParent.parent;
284
- parent[removalParent.key] = removeFromArray(
284
+ parent[removalParent.key] = astArrayMutationHelpers.removeFromArray(
285
285
  parent[removalParent.key],
286
286
  removalParent.targetIndex,
287
287
  );
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createRemoveStatementMutation = createRemoveStatementMutation;
7
7
  exports.performRemoveStatementMutation = performRemoveStatementMutation;
8
8
 
9
- var _arrayUtils = require("./utils/arrayUtils");
9
+ var _hermesParser = require("hermes-parser");
10
10
 
11
11
  var _getStatementParent = require("./utils/getStatementParent");
12
12
 
@@ -39,7 +39,7 @@ function performRemoveStatementMutation(mutationContext, mutation) {
39
39
 
40
40
  if (removalParent.type === 'array') {
41
41
  const parent = removalParent.parent;
42
- parent[removalParent.key] = (0, _arrayUtils.removeFromArray)(parent[removalParent.key], removalParent.targetIndex);
42
+ parent[removalParent.key] = _hermesParser.astArrayMutationHelpers.removeFromArray(parent[removalParent.key], removalParent.targetIndex);
43
43
  } else {
44
44
  // The parent has a 1:1 relationship on this key, so we can't just
45
45
  // remove the node. Instead we replace it with an empty block statement.