hermes-transform 0.28.0 → 0.29.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 (51) hide show
  1. package/dist/detachedNode.js +1 -0
  2. package/dist/detachedNode.js.flow +1 -0
  3. package/dist/generated/node-types.js +1 -12
  4. package/dist/generated/node-types.js.flow +2 -19
  5. package/dist/generated/special-case-node-types/misc.js +11 -0
  6. package/dist/generated/special-case-node-types/misc.js.flow +18 -0
  7. package/dist/src/detachedNode.js +178 -0
  8. package/dist/src/generated/node-types.js +2212 -0
  9. package/dist/src/generated/special-case-node-types/Comment.js +36 -0
  10. package/dist/src/generated/special-case-node-types/DeclareExportDeclaration.js +58 -0
  11. package/dist/src/generated/special-case-node-types/DeclareHook.js +33 -0
  12. package/dist/src/generated/special-case-node-types/ExportNamedDeclaration.js +44 -0
  13. package/dist/src/generated/special-case-node-types/Literal.js +97 -0
  14. package/dist/src/generated/special-case-node-types/ObjectTypeProperty.js +74 -0
  15. package/dist/src/generated/special-case-node-types/Property.js +136 -0
  16. package/dist/src/generated/special-case-node-types/misc.js +158 -0
  17. package/dist/src/generated/special-case-node-types.js +69 -0
  18. package/dist/src/index.js +53 -0
  19. package/dist/src/transform/Errors.js +43 -0
  20. package/dist/src/transform/MutationContext.js +81 -0
  21. package/dist/src/transform/TransformContext.js +213 -0
  22. package/dist/src/transform/comments/comments.js +308 -0
  23. package/dist/src/transform/comments/prettier/common/util.js +364 -0
  24. package/dist/src/transform/comments/prettier/language-js/comments.js +788 -0
  25. package/dist/src/transform/comments/prettier/language-js/loc.js +42 -0
  26. package/dist/src/transform/comments/prettier/language-js/printer-estree.js +32 -0
  27. package/dist/src/transform/comments/prettier/language-js/utils.js +119 -0
  28. package/dist/src/transform/comments/prettier/main/comments.js +440 -0
  29. package/dist/src/transform/comments/prettier/utils/get-last.js +13 -0
  30. package/dist/src/transform/mutations/AddComments.js +43 -0
  31. package/dist/src/transform/mutations/CloneCommentsTo.js +31 -0
  32. package/dist/src/transform/mutations/InsertStatement.js +91 -0
  33. package/dist/src/transform/mutations/ModifyNodeInPlace.js +59 -0
  34. package/dist/src/transform/mutations/RemoveComment.js +78 -0
  35. package/dist/src/transform/mutations/RemoveNode.js +205 -0
  36. package/dist/src/transform/mutations/RemoveStatement.js +59 -0
  37. package/dist/src/transform/mutations/ReplaceNode.js +92 -0
  38. package/dist/src/transform/mutations/ReplaceStatementWithMany.js +79 -0
  39. package/dist/src/transform/mutations/utils/getStatementParent.js +143 -0
  40. package/dist/src/transform/mutations/utils/isValidModuleDeclarationParent.js +43 -0
  41. package/dist/src/transform/parse.js +56 -0
  42. package/dist/src/transform/print.js +134 -0
  43. package/dist/src/transform/transform.js +36 -0
  44. package/dist/src/transform/transformAST.js +134 -0
  45. package/dist/src/traverse/NodeEventGenerator.js +353 -0
  46. package/dist/src/traverse/SafeEmitter.js +52 -0
  47. package/dist/src/traverse/esquery.js +37 -0
  48. package/dist/src/traverse/traverse.js +150 -0
  49. package/dist/transform/comments/prettier/language-js/comments.js +29 -1
  50. package/dist/transform/mutations/utils/getStatementParent.js.flow +7 -5
  51. package/package.json +5 -5
@@ -0,0 +1,788 @@
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
+ * @format
8
+ */
9
+ 'use strict';
10
+
11
+ const {
12
+ getLast,
13
+ hasNewline,
14
+ addLeadingComment,
15
+ getNextNonSpaceNonCommentCharacterIndexWithStartIndex,
16
+ getNextNonSpaceNonCommentCharacterIndex,
17
+ hasNewlineInRange,
18
+ addTrailingComment,
19
+ addDanglingComment,
20
+ getNextNonSpaceNonCommentCharacter,
21
+ isNonEmptyArray
22
+ } = require('../common/util.js');
23
+
24
+ const {
25
+ isBlockComment,
26
+ getFunctionParameters,
27
+ isPrettierIgnoreComment,
28
+ isCallLikeExpression,
29
+ getCallArguments,
30
+ isCallExpression,
31
+ isMemberExpression,
32
+ isObjectProperty
33
+ } = require('./utils.js');
34
+
35
+ const {
36
+ locStart,
37
+ locEnd
38
+ } = require('./loc.js');
39
+ /**
40
+ * @typedef {import("./types/estree").Node} Node
41
+ * @typedef {import("./types/estree").Comment} Comment
42
+ * @typedef {import("../common/ast-path")} AstPath
43
+ *
44
+ * @typedef {Object} CommentContext
45
+ * @property {Comment} comment
46
+ * @property {Node} precedingNode
47
+ * @property {Node} enclosingNode
48
+ * @property {Node} followingNode
49
+ * @property {string} text
50
+ * @property {any} options
51
+ * @property {Node} ast
52
+ * @property {boolean} isLastComment
53
+ */
54
+
55
+ /**
56
+ * @param {CommentContext} context
57
+ * @returns {boolean}
58
+ */
59
+
60
+
61
+ function handleOwnLineComment(context) {
62
+ return [handleIgnoreComments, handleLastFunctionArgComments, handleMemberExpressionComments, handleIfStatementComments, handleWhileComments, handleTryStatementComments, handleClassComments, handleImportSpecifierComments, handleForComments, handleUnionTypeComments, handleMatchOrPatternComments, handleOnlyComments, handleImportDeclarationComments, handleAssignmentPatternComments, handleMethodNameComments, handleLabeledStatementComments].some(fn => fn(context));
63
+ }
64
+ /**
65
+ * @param {CommentContext} context
66
+ * @returns {boolean}
67
+ */
68
+
69
+
70
+ function handleEndOfLineComment(context) {
71
+ return [handleClosureTypeCastComments, handleLastFunctionArgComments, handleConditionalExpressionComments, handleImportSpecifierComments, handleIfStatementComments, handleWhileComments, handleTryStatementComments, handleClassComments, handleLabeledStatementComments, handleCallExpressionComments, handlePropertyComments, handleOnlyComments, handleTypeAliasComments, handleVariableDeclaratorComments].some(fn => fn(context));
72
+ }
73
+ /**
74
+ * @param {CommentContext} context
75
+ * @returns {boolean}
76
+ */
77
+
78
+
79
+ function handleRemainingComment(context) {
80
+ return [handleIgnoreComments, handleIfStatementComments, handleWhileComments, handleObjectPropertyAssignment, handleCommentInEmptyParens, handleMethodNameComments, handleOnlyComments, handleCommentAfterArrowParams, handleFunctionNameComments, handleTSMappedTypeComments, handleBreakAndContinueStatementComments, handleTSFunctionTrailingComments].some(fn => fn(context));
81
+ }
82
+ /**
83
+ * @param {Node} node
84
+ * @returns {void}
85
+ */
86
+
87
+
88
+ function addBlockStatementFirstComment(node, comment) {
89
+ // @ts-expect-error
90
+ const firstNonEmptyNode = (node.body || node.properties).find(({
91
+ type
92
+ }) => type !== 'EmptyStatement');
93
+
94
+ if (firstNonEmptyNode) {
95
+ addLeadingComment(firstNonEmptyNode, comment);
96
+ } else {
97
+ addDanglingComment(node, comment);
98
+ }
99
+ }
100
+ /**
101
+ * @param {Node} node
102
+ * @returns {void}
103
+ */
104
+
105
+
106
+ function addBlockOrNotComment(node, comment) {
107
+ if (node.type === 'BlockStatement') {
108
+ addBlockStatementFirstComment(node, comment);
109
+ } else {
110
+ addLeadingComment(node, comment);
111
+ }
112
+ }
113
+
114
+ function handleClosureTypeCastComments({
115
+ comment,
116
+ followingNode
117
+ }) {
118
+ if (followingNode && isTypeCastComment(comment)) {
119
+ addLeadingComment(followingNode, comment);
120
+ return true;
121
+ }
122
+
123
+ return false;
124
+ } // There are often comments before the else clause of if statements like
125
+ //
126
+ // if (1) { ... }
127
+ // // comment
128
+ // else { ... }
129
+ //
130
+ // They are being attached as leading comments of the BlockExpression which
131
+ // is not well printed. What we want is to instead move the comment inside
132
+ // of the block and make it leadingComment of the first element of the block
133
+ // or dangling comment of the block if there is nothing inside
134
+ //
135
+ // if (1) { ... }
136
+ // else {
137
+ // // comment
138
+ // ...
139
+ // }
140
+
141
+
142
+ function handleIfStatementComments({
143
+ comment,
144
+ precedingNode,
145
+ enclosingNode,
146
+ followingNode,
147
+ text
148
+ }) {
149
+ if (!enclosingNode || enclosingNode.type !== 'IfStatement' || !followingNode) {
150
+ return false;
151
+ } // We unfortunately have no way using the AST or location of nodes to know
152
+ // if the comment is positioned before the condition parenthesis:
153
+ // if (a /* comment */) {}
154
+ // The only workaround I found is to look at the next character to see if
155
+ // it is a ).
156
+
157
+
158
+ const nextCharacter = getNextNonSpaceNonCommentCharacter(text, comment, locEnd);
159
+
160
+ if (nextCharacter === ')') {
161
+ addTrailingComment(precedingNode, comment);
162
+ return true;
163
+ } // Comments before `else`:
164
+ // - treat as trailing comments of the consequent, if it's a BlockStatement
165
+ // - treat as a dangling comment otherwise
166
+
167
+
168
+ if (precedingNode === enclosingNode.consequent && followingNode === enclosingNode.alternate) {
169
+ if (precedingNode.type === 'BlockStatement') {
170
+ addTrailingComment(precedingNode, comment);
171
+ } else {
172
+ addDanglingComment(enclosingNode, comment);
173
+ }
174
+
175
+ return true;
176
+ }
177
+
178
+ if (followingNode.type === 'BlockStatement') {
179
+ addBlockStatementFirstComment(followingNode, comment);
180
+ return true;
181
+ }
182
+
183
+ if (followingNode.type === 'IfStatement') {
184
+ addBlockOrNotComment(followingNode.consequent, comment);
185
+ return true;
186
+ } // For comments positioned after the condition parenthesis in an if statement
187
+ // before the consequent without brackets on, such as
188
+ // if (a) /* comment */ true,
189
+ // we look at the next character to see if the following node
190
+ // is the consequent for the if statement
191
+
192
+
193
+ if (enclosingNode.consequent === followingNode) {
194
+ addLeadingComment(followingNode, comment);
195
+ return true;
196
+ }
197
+
198
+ return false;
199
+ }
200
+
201
+ function handleWhileComments({
202
+ comment,
203
+ precedingNode,
204
+ enclosingNode,
205
+ followingNode,
206
+ text
207
+ }) {
208
+ if (!enclosingNode || enclosingNode.type !== 'WhileStatement' || !followingNode) {
209
+ return false;
210
+ } // We unfortunately have no way using the AST or location of nodes to know
211
+ // if the comment is positioned before the condition parenthesis:
212
+ // while (a /* comment */) {}
213
+ // The only workaround I found is to look at the next character to see if
214
+ // it is a ).
215
+
216
+
217
+ const nextCharacter = getNextNonSpaceNonCommentCharacter(text, comment, locEnd);
218
+
219
+ if (nextCharacter === ')') {
220
+ addTrailingComment(precedingNode, comment);
221
+ return true;
222
+ }
223
+
224
+ if (followingNode.type === 'BlockStatement') {
225
+ addBlockStatementFirstComment(followingNode, comment);
226
+ return true;
227
+ }
228
+
229
+ if (enclosingNode.body === followingNode) {
230
+ addLeadingComment(followingNode, comment);
231
+ return true;
232
+ }
233
+
234
+ return false;
235
+ } // Same as IfStatement but for TryStatement
236
+
237
+
238
+ function handleTryStatementComments({
239
+ comment,
240
+ precedingNode,
241
+ enclosingNode,
242
+ followingNode
243
+ }) {
244
+ if (!enclosingNode || enclosingNode.type !== 'TryStatement' && enclosingNode.type !== 'CatchClause' || !followingNode) {
245
+ return false;
246
+ }
247
+
248
+ if (enclosingNode.type === 'CatchClause' && precedingNode) {
249
+ addTrailingComment(precedingNode, comment);
250
+ return true;
251
+ }
252
+
253
+ if (followingNode.type === 'BlockStatement') {
254
+ addBlockStatementFirstComment(followingNode, comment);
255
+ return true;
256
+ }
257
+
258
+ if (followingNode.type === 'TryStatement') {
259
+ addBlockOrNotComment(followingNode.finalizer, comment);
260
+ return true;
261
+ }
262
+
263
+ if (followingNode.type === 'CatchClause') {
264
+ addBlockOrNotComment(followingNode.body, comment);
265
+ return true;
266
+ }
267
+
268
+ return false;
269
+ }
270
+
271
+ function handleMemberExpressionComments({
272
+ comment,
273
+ enclosingNode,
274
+ followingNode
275
+ }) {
276
+ if (isMemberExpression(enclosingNode) && followingNode && followingNode.type === 'Identifier') {
277
+ addLeadingComment(enclosingNode, comment);
278
+ return true;
279
+ }
280
+
281
+ return false;
282
+ }
283
+
284
+ function handleConditionalExpressionComments({
285
+ comment,
286
+ precedingNode,
287
+ enclosingNode,
288
+ followingNode,
289
+ text
290
+ }) {
291
+ const isSameLineAsPrecedingNode = precedingNode && !hasNewlineInRange(text, locEnd(precedingNode), locStart(comment));
292
+
293
+ if ((!precedingNode || !isSameLineAsPrecedingNode) && enclosingNode && (enclosingNode.type === 'ConditionalExpression' || enclosingNode.type === 'TSConditionalType') && followingNode) {
294
+ addLeadingComment(followingNode, comment);
295
+ return true;
296
+ }
297
+
298
+ return false;
299
+ }
300
+
301
+ function handleObjectPropertyAssignment({
302
+ comment,
303
+ precedingNode,
304
+ enclosingNode
305
+ }) {
306
+ if (isObjectProperty(enclosingNode) && enclosingNode.shorthand && enclosingNode.key === precedingNode && enclosingNode.value.type === 'AssignmentPattern') {
307
+ addTrailingComment(enclosingNode.value.left, comment);
308
+ return true;
309
+ }
310
+
311
+ return false;
312
+ }
313
+
314
+ function handleClassComments({
315
+ comment,
316
+ precedingNode,
317
+ enclosingNode,
318
+ followingNode
319
+ }) {
320
+ if (enclosingNode && (enclosingNode.type === 'ClassDeclaration' || enclosingNode.type === 'ClassExpression' || enclosingNode.type === 'DeclareClass' || enclosingNode.type === 'DeclareInterface' || enclosingNode.type === 'InterfaceDeclaration' || enclosingNode.type === 'TSInterfaceDeclaration')) {
321
+ if (isNonEmptyArray(enclosingNode.decorators) && !(followingNode && followingNode.type === 'Decorator')) {
322
+ addTrailingComment(getLast(enclosingNode.decorators), comment);
323
+ return true;
324
+ }
325
+
326
+ if (enclosingNode.body && followingNode === enclosingNode.body) {
327
+ addBlockStatementFirstComment(enclosingNode.body, comment);
328
+ return true;
329
+ } // Don't add leading comments to `implements`, `extends`, `mixins` to
330
+ // avoid printing the comment after the keyword.
331
+
332
+
333
+ if (followingNode) {
334
+ for (const prop of ['implements', 'extends', 'mixins']) {
335
+ if (enclosingNode[prop] && followingNode === enclosingNode[prop][0]) {
336
+ if (precedingNode && (precedingNode === enclosingNode.id || precedingNode === enclosingNode.typeParameters || precedingNode === enclosingNode.superClass)) {
337
+ addTrailingComment(precedingNode, comment);
338
+ } else {
339
+ addDanglingComment(enclosingNode, comment, prop);
340
+ }
341
+
342
+ return true;
343
+ }
344
+ }
345
+ }
346
+ }
347
+
348
+ return false;
349
+ }
350
+
351
+ function handleMethodNameComments({
352
+ comment,
353
+ precedingNode,
354
+ enclosingNode,
355
+ text
356
+ }) {
357
+ // This is only needed for estree parsers (flow, typescript) to attach
358
+ // after a method name:
359
+ // obj = { fn /*comment*/() {} };
360
+ if (enclosingNode && precedingNode && ( // "MethodDefinition" is handled in getCommentChildNodes
361
+ enclosingNode.type === 'Property' || enclosingNode.type === 'TSDeclareMethod' || enclosingNode.type === 'TSAbstractMethodDefinition') && precedingNode.type === 'Identifier' && enclosingNode.key === precedingNode && // special Property case: { key: /*comment*/(value) };
362
+ // comment should be attached to value instead of key
363
+ getNextNonSpaceNonCommentCharacter(text, precedingNode, locEnd) !== ':') {
364
+ addTrailingComment(precedingNode, comment);
365
+ return true;
366
+ } // Print comments between decorators and class methods as a trailing comment
367
+ // on the decorator node instead of the method node
368
+
369
+
370
+ if (precedingNode && enclosingNode && precedingNode.type === 'Decorator' && (enclosingNode.type === 'ClassMethod' || enclosingNode.type === 'ClassProperty' || enclosingNode.type === 'PropertyDefinition' || enclosingNode.type === 'TSAbstractPropertyDefinition' || enclosingNode.type === 'TSAbstractMethodDefinition' || enclosingNode.type === 'TSDeclareMethod' || enclosingNode.type === 'MethodDefinition')) {
371
+ addTrailingComment(precedingNode, comment);
372
+ return true;
373
+ }
374
+
375
+ return false;
376
+ }
377
+
378
+ function handleFunctionNameComments({
379
+ comment,
380
+ precedingNode,
381
+ enclosingNode,
382
+ text
383
+ }) {
384
+ if (getNextNonSpaceNonCommentCharacter(text, comment, locEnd) !== '(') {
385
+ return false;
386
+ }
387
+
388
+ if (precedingNode && enclosingNode && (enclosingNode.type === 'FunctionDeclaration' || enclosingNode.type === 'FunctionExpression' || enclosingNode.type === 'ClassMethod' || enclosingNode.type === 'MethodDefinition' || enclosingNode.type === 'ObjectMethod')) {
389
+ addTrailingComment(precedingNode, comment);
390
+ return true;
391
+ }
392
+
393
+ return false;
394
+ }
395
+
396
+ function handleCommentAfterArrowParams({
397
+ comment,
398
+ enclosingNode,
399
+ text
400
+ }) {
401
+ if (!(enclosingNode && enclosingNode.type === 'ArrowFunctionExpression')) {
402
+ return false;
403
+ }
404
+
405
+ const index = getNextNonSpaceNonCommentCharacterIndex(text, comment, locEnd);
406
+
407
+ if (index !== false && text.slice(index, index + 2) === '=>') {
408
+ addDanglingComment(enclosingNode, comment);
409
+ return true;
410
+ }
411
+
412
+ return false;
413
+ }
414
+
415
+ function handleCommentInEmptyParens({
416
+ comment,
417
+ enclosingNode,
418
+ text
419
+ }) {
420
+ if (getNextNonSpaceNonCommentCharacter(text, comment, locEnd) !== ')') {
421
+ return false;
422
+ } // Only add dangling comments to fix the case when no params are present,
423
+ // i.e. a function without any argument.
424
+
425
+
426
+ if (enclosingNode && (isRealFunctionLikeNode(enclosingNode) && getFunctionParameters(enclosingNode).length === 0 || isCallLikeExpression(enclosingNode) && getCallArguments(enclosingNode).length === 0)) {
427
+ addDanglingComment(enclosingNode, comment);
428
+ return true;
429
+ }
430
+
431
+ if (enclosingNode && (enclosingNode.type === 'MethodDefinition' || enclosingNode.type === 'TSAbstractMethodDefinition') && getFunctionParameters(enclosingNode.value).length === 0) {
432
+ addDanglingComment(enclosingNode.value, comment);
433
+ return true;
434
+ }
435
+
436
+ return false;
437
+ }
438
+
439
+ function handleLastFunctionArgComments({
440
+ comment,
441
+ precedingNode,
442
+ enclosingNode,
443
+ followingNode,
444
+ text
445
+ }) {
446
+ // Flow function type definitions
447
+ if (precedingNode && precedingNode.type === 'FunctionTypeParam' && enclosingNode && enclosingNode.type === 'FunctionTypeAnnotation' && followingNode && followingNode.type !== 'FunctionTypeParam') {
448
+ addTrailingComment(precedingNode, comment);
449
+ return true;
450
+ } // Real functions and TypeScript function type definitions
451
+
452
+
453
+ if (precedingNode && (precedingNode.type === 'Identifier' || precedingNode.type === 'AssignmentPattern') && enclosingNode && isRealFunctionLikeNode(enclosingNode) && getNextNonSpaceNonCommentCharacter(text, comment, locEnd) === ')') {
454
+ addTrailingComment(precedingNode, comment);
455
+ return true;
456
+ }
457
+
458
+ if (enclosingNode && enclosingNode.type === 'FunctionDeclaration' && followingNode && followingNode.type === 'BlockStatement') {
459
+ const functionParamRightParenIndex = (() => {
460
+ const parameters = getFunctionParameters(enclosingNode);
461
+
462
+ if (parameters.length > 0) {
463
+ return getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, locEnd(getLast(parameters)));
464
+ }
465
+
466
+ const functionParamLeftParenIndex = getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, locEnd(enclosingNode.id));
467
+ return functionParamLeftParenIndex !== false && getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, functionParamLeftParenIndex + 1);
468
+ })();
469
+
470
+ if (locStart(comment) > functionParamRightParenIndex) {
471
+ addBlockStatementFirstComment(followingNode, comment);
472
+ return true;
473
+ }
474
+ }
475
+
476
+ return false;
477
+ }
478
+
479
+ function handleImportSpecifierComments({
480
+ comment,
481
+ enclosingNode
482
+ }) {
483
+ if (enclosingNode && enclosingNode.type === 'ImportSpecifier') {
484
+ addLeadingComment(enclosingNode, comment);
485
+ return true;
486
+ }
487
+
488
+ return false;
489
+ }
490
+
491
+ function handleLabeledStatementComments({
492
+ comment,
493
+ enclosingNode
494
+ }) {
495
+ if (enclosingNode && enclosingNode.type === 'LabeledStatement') {
496
+ addLeadingComment(enclosingNode, comment);
497
+ return true;
498
+ }
499
+
500
+ return false;
501
+ }
502
+
503
+ function handleBreakAndContinueStatementComments({
504
+ comment,
505
+ enclosingNode
506
+ }) {
507
+ if (enclosingNode && (enclosingNode.type === 'ContinueStatement' || enclosingNode.type === 'BreakStatement') && !enclosingNode.label) {
508
+ addTrailingComment(enclosingNode, comment);
509
+ return true;
510
+ }
511
+
512
+ return false;
513
+ }
514
+
515
+ function handleCallExpressionComments({
516
+ comment,
517
+ precedingNode,
518
+ enclosingNode
519
+ }) {
520
+ if (isCallExpression(enclosingNode) && precedingNode && enclosingNode.callee === precedingNode && enclosingNode.arguments.length > 0) {
521
+ addLeadingComment(enclosingNode.arguments[0], comment);
522
+ return true;
523
+ }
524
+
525
+ return false;
526
+ }
527
+
528
+ function handleUnionTypeComments({
529
+ comment,
530
+ precedingNode,
531
+ enclosingNode,
532
+ followingNode
533
+ }) {
534
+ if (enclosingNode && (enclosingNode.type === 'UnionTypeAnnotation' || enclosingNode.type === 'TSUnionType')) {
535
+ if (isPrettierIgnoreComment(comment)) {
536
+ followingNode.prettierIgnore = true;
537
+ comment.unignore = true;
538
+ }
539
+
540
+ if (precedingNode) {
541
+ addTrailingComment(precedingNode, comment);
542
+ return true;
543
+ }
544
+
545
+ return false;
546
+ }
547
+
548
+ if (followingNode && (followingNode.type === 'UnionTypeAnnotation' || followingNode.type === 'TSUnionType') && isPrettierIgnoreComment(comment)) {
549
+ followingNode.types[0].prettierIgnore = true;
550
+ comment.unignore = true;
551
+ }
552
+
553
+ return false;
554
+ }
555
+
556
+ function handleMatchOrPatternComments({
557
+ comment,
558
+ precedingNode,
559
+ enclosingNode,
560
+ followingNode
561
+ }) {
562
+ if (enclosingNode && enclosingNode.type === 'MatchOrPattern') {
563
+ if (isPrettierIgnoreComment(comment)) {
564
+ followingNode.prettierIgnore = true;
565
+ comment.unignore = true;
566
+ }
567
+
568
+ if (precedingNode) {
569
+ addTrailingComment(precedingNode, comment);
570
+ return true;
571
+ }
572
+
573
+ return false;
574
+ }
575
+
576
+ if (followingNode && followingNode.type === 'MatchOrPattern' && isPrettierIgnoreComment(comment)) {
577
+ followingNode.types[0].prettierIgnore = true;
578
+ comment.unignore = true;
579
+ }
580
+
581
+ return false;
582
+ }
583
+
584
+ function handlePropertyComments({
585
+ comment,
586
+ enclosingNode
587
+ }) {
588
+ if (isObjectProperty(enclosingNode)) {
589
+ addLeadingComment(enclosingNode, comment);
590
+ return true;
591
+ }
592
+
593
+ return false;
594
+ }
595
+
596
+ function handleOnlyComments({
597
+ comment,
598
+ enclosingNode,
599
+ followingNode,
600
+ ast,
601
+ isLastComment
602
+ }) {
603
+ // With Flow the enclosingNode is undefined so use the AST instead.
604
+ if (ast && ast.body && ast.body.length === 0) {
605
+ if (isLastComment) {
606
+ addDanglingComment(ast, comment);
607
+ } else {
608
+ addLeadingComment(ast, comment);
609
+ }
610
+
611
+ return true;
612
+ }
613
+
614
+ if (enclosingNode && enclosingNode.type === 'Program' && enclosingNode.body.length === 0 && !isNonEmptyArray(enclosingNode.directives)) {
615
+ if (isLastComment) {
616
+ addDanglingComment(enclosingNode, comment);
617
+ } else {
618
+ addLeadingComment(enclosingNode, comment);
619
+ }
620
+
621
+ return true;
622
+ }
623
+
624
+ if (followingNode && followingNode.type === 'Program' && followingNode.body.length === 0 && enclosingNode && enclosingNode.type === 'ModuleExpression') {
625
+ addDanglingComment(followingNode, comment);
626
+ return true;
627
+ }
628
+
629
+ return false;
630
+ }
631
+
632
+ function handleForComments({
633
+ comment,
634
+ enclosingNode
635
+ }) {
636
+ if (enclosingNode && (enclosingNode.type === 'ForInStatement' || enclosingNode.type === 'ForOfStatement')) {
637
+ addLeadingComment(enclosingNode, comment);
638
+ return true;
639
+ }
640
+
641
+ return false;
642
+ }
643
+
644
+ function handleImportDeclarationComments({
645
+ comment,
646
+ precedingNode,
647
+ enclosingNode,
648
+ text
649
+ }) {
650
+ if (precedingNode && precedingNode.type === 'ImportSpecifier' && enclosingNode && enclosingNode.type === 'ImportDeclaration' && hasNewline(text, locEnd(comment))) {
651
+ addTrailingComment(precedingNode, comment);
652
+ return true;
653
+ }
654
+
655
+ return false;
656
+ }
657
+
658
+ function handleAssignmentPatternComments({
659
+ comment,
660
+ enclosingNode
661
+ }) {
662
+ if (enclosingNode && enclosingNode.type === 'AssignmentPattern') {
663
+ addLeadingComment(enclosingNode, comment);
664
+ return true;
665
+ }
666
+
667
+ return false;
668
+ }
669
+
670
+ function handleTypeAliasComments({
671
+ comment,
672
+ enclosingNode
673
+ }) {
674
+ if (enclosingNode && enclosingNode.type === 'TypeAlias') {
675
+ addLeadingComment(enclosingNode, comment);
676
+ return true;
677
+ }
678
+
679
+ return false;
680
+ }
681
+
682
+ function handleVariableDeclaratorComments({
683
+ comment,
684
+ enclosingNode,
685
+ followingNode
686
+ }) {
687
+ if (enclosingNode && (enclosingNode.type === 'VariableDeclarator' || enclosingNode.type === 'AssignmentExpression') && followingNode && (followingNode.type === 'ObjectExpression' || followingNode.type === 'ArrayExpression' || followingNode.type === 'TemplateLiteral' || followingNode.type === 'TaggedTemplateExpression' || isBlockComment(comment))) {
688
+ addLeadingComment(followingNode, comment);
689
+ return true;
690
+ }
691
+
692
+ return false;
693
+ }
694
+
695
+ function handleTSFunctionTrailingComments({
696
+ comment,
697
+ enclosingNode,
698
+ followingNode,
699
+ text
700
+ }) {
701
+ if (!followingNode && enclosingNode && (enclosingNode.type === 'TSMethodSignature' || enclosingNode.type === 'TSDeclareFunction' || enclosingNode.type === 'TSAbstractMethodDefinition') && getNextNonSpaceNonCommentCharacter(text, comment, locEnd) === ';') {
702
+ addTrailingComment(enclosingNode, comment);
703
+ return true;
704
+ }
705
+
706
+ return false;
707
+ }
708
+
709
+ function handleIgnoreComments({
710
+ comment,
711
+ enclosingNode,
712
+ followingNode
713
+ }) {
714
+ if (isPrettierIgnoreComment(comment) && enclosingNode && enclosingNode.type === 'TSMappedType' && followingNode && followingNode.type === 'TSTypeParameter' && followingNode.constraint) {
715
+ enclosingNode.prettierIgnore = true;
716
+ comment.unignore = true;
717
+ return true;
718
+ }
719
+ }
720
+
721
+ function handleTSMappedTypeComments({
722
+ comment,
723
+ precedingNode,
724
+ enclosingNode,
725
+ followingNode
726
+ }) {
727
+ if (!enclosingNode || enclosingNode.type !== 'TSMappedType') {
728
+ return false;
729
+ }
730
+
731
+ if (followingNode && followingNode.type === 'TSTypeParameter' && followingNode.name) {
732
+ addLeadingComment(followingNode.name, comment);
733
+ return true;
734
+ }
735
+
736
+ if (precedingNode && precedingNode.type === 'TSTypeParameter' && precedingNode.constraint) {
737
+ addTrailingComment(precedingNode.constraint, comment);
738
+ return true;
739
+ }
740
+
741
+ return false;
742
+ }
743
+ /**
744
+ * @param {Node} node
745
+ * @returns {boolean}
746
+ */
747
+
748
+
749
+ function isRealFunctionLikeNode(node) {
750
+ return node.type === 'ArrowFunctionExpression' || node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ObjectMethod' || node.type === 'ClassMethod' || node.type === 'TSDeclareFunction' || node.type === 'TSCallSignatureDeclaration' || node.type === 'TSConstructSignatureDeclaration' || node.type === 'TSMethodSignature' || node.type === 'TSConstructorType' || node.type === 'TSFunctionType' || node.type === 'TSDeclareMethod';
751
+ }
752
+ /**
753
+ * @param {any} node
754
+ * @returns {Node[] | void}
755
+ */
756
+
757
+
758
+ function getCommentChildNodes(node, options) {
759
+ // Prevent attaching comments to FunctionExpression in this case:
760
+ // class Foo {
761
+ // bar() // comment
762
+ // {
763
+ // baz();
764
+ // }
765
+ // }
766
+ if ((options.parser === 'typescript' || options.parser === 'flow' || options.parser === 'espree' || options.parser === 'meriyah' || options.parser === '__babel_estree') && node.type === 'MethodDefinition' && node.value && node.value.type === 'FunctionExpression' && getFunctionParameters(node.value).length === 0 && !node.value.returnType && !isNonEmptyArray(node.value.typeParameters) && node.value.body) {
767
+ return [...(node.decorators || []), node.key, node.value.body];
768
+ }
769
+ }
770
+ /**
771
+ * @param {Comment} comment
772
+ * @returns {boolean}
773
+ */
774
+
775
+
776
+ function isTypeCastComment(comment) {
777
+ return isBlockComment(comment) && comment.value[0] === '*' && // TypeScript expects the type to be enclosed in curly brackets, however
778
+ // Closure Compiler accepts types in parens and even without any delimiters at all.
779
+ // That's why we just search for "@type".
780
+ /@type\b/.test(comment.value);
781
+ }
782
+
783
+ module.exports = {
784
+ handleOwnLineComment,
785
+ handleEndOfLineComment,
786
+ handleRemainingComment,
787
+ getCommentChildNodes
788
+ };