hermes-transform 0.28.1 → 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.
- package/dist/detachedNode.js +1 -0
- package/dist/detachedNode.js.flow +1 -0
- package/dist/generated/node-types.js +1 -12
- package/dist/generated/node-types.js.flow +2 -19
- package/dist/generated/special-case-node-types/misc.js +11 -0
- package/dist/generated/special-case-node-types/misc.js.flow +18 -0
- package/dist/src/detachedNode.js +178 -0
- package/dist/src/generated/node-types.js +2212 -0
- package/dist/src/generated/special-case-node-types/Comment.js +36 -0
- package/dist/src/generated/special-case-node-types/DeclareExportDeclaration.js +58 -0
- package/dist/src/generated/special-case-node-types/DeclareHook.js +33 -0
- package/dist/src/generated/special-case-node-types/ExportNamedDeclaration.js +44 -0
- package/dist/src/generated/special-case-node-types/Literal.js +97 -0
- package/dist/src/generated/special-case-node-types/ObjectTypeProperty.js +74 -0
- package/dist/src/generated/special-case-node-types/Property.js +136 -0
- package/dist/src/generated/special-case-node-types/misc.js +158 -0
- package/dist/src/generated/special-case-node-types.js +69 -0
- package/dist/src/index.js +53 -0
- package/dist/src/transform/Errors.js +43 -0
- package/dist/src/transform/MutationContext.js +81 -0
- package/dist/src/transform/TransformContext.js +213 -0
- package/dist/src/transform/comments/comments.js +308 -0
- package/dist/src/transform/comments/prettier/common/util.js +364 -0
- package/dist/src/transform/comments/prettier/language-js/comments.js +788 -0
- package/dist/src/transform/comments/prettier/language-js/loc.js +42 -0
- package/dist/src/transform/comments/prettier/language-js/printer-estree.js +32 -0
- package/dist/src/transform/comments/prettier/language-js/utils.js +119 -0
- package/dist/src/transform/comments/prettier/main/comments.js +440 -0
- package/dist/src/transform/comments/prettier/utils/get-last.js +13 -0
- package/dist/src/transform/mutations/AddComments.js +43 -0
- package/dist/src/transform/mutations/CloneCommentsTo.js +31 -0
- package/dist/src/transform/mutations/InsertStatement.js +91 -0
- package/dist/src/transform/mutations/ModifyNodeInPlace.js +59 -0
- package/dist/src/transform/mutations/RemoveComment.js +78 -0
- package/dist/src/transform/mutations/RemoveNode.js +205 -0
- package/dist/src/transform/mutations/RemoveStatement.js +59 -0
- package/dist/src/transform/mutations/ReplaceNode.js +92 -0
- package/dist/src/transform/mutations/ReplaceStatementWithMany.js +79 -0
- package/dist/src/transform/mutations/utils/getStatementParent.js +143 -0
- package/dist/src/transform/mutations/utils/isValidModuleDeclarationParent.js +43 -0
- package/dist/src/transform/parse.js +56 -0
- package/dist/src/transform/print.js +134 -0
- package/dist/src/transform/transform.js +36 -0
- package/dist/src/transform/transformAST.js +134 -0
- package/dist/src/traverse/NodeEventGenerator.js +353 -0
- package/dist/src/traverse/SafeEmitter.js +52 -0
- package/dist/src/traverse/esquery.js +37 -0
- package/dist/src/traverse/traverse.js +150 -0
- package/dist/transform/comments/prettier/language-js/comments.js +29 -1
- package/dist/transform/mutations/utils/getStatementParent.js.flow +7 -5
- 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
|
+
};
|