JavaScript · 27769 bytes Raw Blame History
1 "use strict";
2
3 Object.defineProperty(exports, "__esModule", {
4 value: true
5 });
6 exports.default = void 0;
7 var _buffer = require("./buffer.js");
8 var _index = require("./node/index.js");
9 var n = _index;
10 var _t = require("@babel/types");
11 var _tokenMap = require("./token-map.js");
12 var generatorFunctions = require("./generators/index.js");
13 var _deprecated = require("./generators/deprecated.js");
14 const {
15 isExpression,
16 isFunction,
17 isStatement,
18 isClassBody,
19 isTSInterfaceBody,
20 isTSEnumMember
21 } = _t;
22 const SCIENTIFIC_NOTATION = /e/i;
23 const ZERO_DECIMAL_INTEGER = /\.0+$/;
24 const HAS_NEWLINE = /[\n\r\u2028\u2029]/;
25 const HAS_NEWLINE_OR_BlOCK_COMMENT_END = /[\n\r\u2028\u2029]|\*\//;
26 function commentIsNewline(c) {
27 return c.type === "CommentLine" || HAS_NEWLINE.test(c.value);
28 }
29 const {
30 needsParens
31 } = n;
32 class Printer {
33 constructor(format, map, tokens = null, originalCode = null) {
34 this.tokenContext = _index.TokenContext.normal;
35 this._tokens = null;
36 this._originalCode = null;
37 this._currentNode = null;
38 this._indent = 0;
39 this._indentRepeat = 0;
40 this._insideAux = false;
41 this._noLineTerminator = false;
42 this._noLineTerminatorAfterNode = null;
43 this._printAuxAfterOnNextUserNode = false;
44 this._printedComments = new Set();
45 this._endsWithInteger = false;
46 this._endsWithWord = false;
47 this._endsWithDiv = false;
48 this._lastCommentLine = 0;
49 this._endsWithInnerRaw = false;
50 this._indentInnerComments = true;
51 this.tokenMap = null;
52 this._boundGetRawIdentifier = this._getRawIdentifier.bind(this);
53 this._printSemicolonBeforeNextNode = -1;
54 this._printSemicolonBeforeNextToken = -1;
55 this.format = format;
56 this._tokens = tokens;
57 this._originalCode = originalCode;
58 this._indentRepeat = format.indent.style.length;
59 this._inputMap = (map == null ? void 0 : map._inputMap) || null;
60 this._buf = new _buffer.default(map, format.indent.style[0]);
61 }
62 enterForStatementInit() {
63 this.tokenContext |= _index.TokenContext.forInitHead | _index.TokenContext.forInOrInitHeadAccumulate;
64 return () => this.tokenContext = _index.TokenContext.normal;
65 }
66 enterForXStatementInit(isForOf) {
67 if (isForOf) {
68 this.tokenContext |= _index.TokenContext.forOfHead;
69 return null;
70 } else {
71 this.tokenContext |= _index.TokenContext.forInHead | _index.TokenContext.forInOrInitHeadAccumulate;
72 return () => this.tokenContext = _index.TokenContext.normal;
73 }
74 }
75 enterDelimited() {
76 const oldTokenContext = this.tokenContext;
77 const oldNoLineTerminatorAfterNode = this._noLineTerminatorAfterNode;
78 if (!(oldTokenContext & _index.TokenContext.forInOrInitHeadAccumulate) && oldNoLineTerminatorAfterNode === null) {
79 return () => {};
80 }
81 this._noLineTerminatorAfterNode = null;
82 this.tokenContext = _index.TokenContext.normal;
83 return () => {
84 this._noLineTerminatorAfterNode = oldNoLineTerminatorAfterNode;
85 this.tokenContext = oldTokenContext;
86 };
87 }
88 generate(ast) {
89 if (this.format.preserveFormat) {
90 this.tokenMap = new _tokenMap.TokenMap(ast, this._tokens, this._originalCode);
91 }
92 this.print(ast);
93 this._maybeAddAuxComment();
94 return this._buf.get();
95 }
96 indent() {
97 const {
98 format
99 } = this;
100 if (format.preserveFormat || format.compact || format.concise) {
101 return;
102 }
103 this._indent++;
104 }
105 dedent() {
106 const {
107 format
108 } = this;
109 if (format.preserveFormat || format.compact || format.concise) {
110 return;
111 }
112 this._indent--;
113 }
114 semicolon(force = false) {
115 this._maybeAddAuxComment();
116 if (force) {
117 this._appendChar(59);
118 this._noLineTerminator = false;
119 return;
120 }
121 if (this.tokenMap) {
122 const node = this._currentNode;
123 if (node.start != null && node.end != null) {
124 if (!this.tokenMap.endMatches(node, ";")) {
125 this._printSemicolonBeforeNextNode = this._buf.getCurrentLine();
126 return;
127 }
128 const indexes = this.tokenMap.getIndexes(this._currentNode);
129 this._catchUpTo(this._tokens[indexes[indexes.length - 1]].loc.start);
130 }
131 }
132 this._queue(59);
133 this._noLineTerminator = false;
134 }
135 rightBrace(node) {
136 if (this.format.minified) {
137 this._buf.removeLastSemicolon();
138 }
139 this.sourceWithOffset("end", node.loc, -1);
140 this.tokenChar(125);
141 }
142 rightParens(node) {
143 this.sourceWithOffset("end", node.loc, -1);
144 this.tokenChar(41);
145 }
146 space(force = false) {
147 const {
148 format
149 } = this;
150 if (format.compact || format.preserveFormat) return;
151 if (force) {
152 this._space();
153 } else if (this._buf.hasContent()) {
154 const lastCp = this.getLastChar();
155 if (lastCp !== 32 && lastCp !== 10) {
156 this._space();
157 }
158 }
159 }
160 word(str, noLineTerminatorAfter = false) {
161 this.tokenContext &= _index.TokenContext.forInOrInitHeadAccumulatePassThroughMask;
162 this._maybePrintInnerComments(str);
163 this._maybeAddAuxComment();
164 if (this.tokenMap) this._catchUpToCurrentToken(str);
165 if (this._endsWithWord || this._endsWithDiv && str.charCodeAt(0) === 47) {
166 this._space();
167 }
168 this._append(str, false);
169 this._endsWithWord = true;
170 this._noLineTerminator = noLineTerminatorAfter;
171 }
172 number(str, number) {
173 function isNonDecimalLiteral(str) {
174 if (str.length > 2 && str.charCodeAt(0) === 48) {
175 const secondChar = str.charCodeAt(1);
176 return secondChar === 98 || secondChar === 111 || secondChar === 120;
177 }
178 return false;
179 }
180 this.word(str);
181 this._endsWithInteger = Number.isInteger(number) && !isNonDecimalLiteral(str) && !SCIENTIFIC_NOTATION.test(str) && !ZERO_DECIMAL_INTEGER.test(str) && str.charCodeAt(str.length - 1) !== 46;
182 }
183 token(str, maybeNewline = false, occurrenceCount = 0) {
184 this.tokenContext &= _index.TokenContext.forInOrInitHeadAccumulatePassThroughMask;
185 this._maybePrintInnerComments(str, occurrenceCount);
186 this._maybeAddAuxComment();
187 if (this.tokenMap) this._catchUpToCurrentToken(str, occurrenceCount);
188 const lastChar = this.getLastChar();
189 const strFirst = str.charCodeAt(0);
190 if (lastChar === 33 && (str === "--" || strFirst === 61) || strFirst === 43 && lastChar === 43 || strFirst === 45 && lastChar === 45 || strFirst === 46 && this._endsWithInteger) {
191 this._space();
192 }
193 this._append(str, maybeNewline);
194 this._noLineTerminator = false;
195 }
196 tokenChar(char) {
197 this.tokenContext &= _index.TokenContext.forInOrInitHeadAccumulatePassThroughMask;
198 const str = String.fromCharCode(char);
199 this._maybePrintInnerComments(str);
200 this._maybeAddAuxComment();
201 if (this.tokenMap) this._catchUpToCurrentToken(str);
202 const lastChar = this.getLastChar();
203 if (char === 43 && lastChar === 43 || char === 45 && lastChar === 45 || char === 46 && this._endsWithInteger) {
204 this._space();
205 }
206 this._appendChar(char);
207 this._noLineTerminator = false;
208 }
209 newline(i = 1, force) {
210 if (i <= 0) return;
211 if (!force) {
212 if (this.format.retainLines || this.format.compact) return;
213 if (this.format.concise) {
214 this.space();
215 return;
216 }
217 }
218 if (i > 2) i = 2;
219 i -= this._buf.getNewlineCount();
220 for (let j = 0; j < i; j++) {
221 this._newline();
222 }
223 return;
224 }
225 endsWith(char) {
226 return this.getLastChar() === char;
227 }
228 getLastChar() {
229 return this._buf.getLastChar();
230 }
231 endsWithCharAndNewline() {
232 return this._buf.endsWithCharAndNewline();
233 }
234 removeTrailingNewline() {
235 this._buf.removeTrailingNewline();
236 }
237 exactSource(loc, cb) {
238 if (!loc) {
239 cb();
240 return;
241 }
242 this._catchUp("start", loc);
243 this._buf.exactSource(loc, cb);
244 }
245 source(prop, loc) {
246 if (!loc) return;
247 this._catchUp(prop, loc);
248 this._buf.source(prop, loc);
249 }
250 sourceWithOffset(prop, loc, columnOffset) {
251 if (!loc || this.format.preserveFormat) return;
252 this._catchUp(prop, loc);
253 this._buf.sourceWithOffset(prop, loc, columnOffset);
254 }
255 sourceIdentifierName(identifierName, pos) {
256 if (!this._buf._canMarkIdName) return;
257 const sourcePosition = this._buf._sourcePosition;
258 sourcePosition.identifierNamePos = pos;
259 sourcePosition.identifierName = identifierName;
260 }
261 _space() {
262 this._queue(32);
263 }
264 _newline() {
265 this._queue(10);
266 }
267 _catchUpToCurrentToken(str, occurrenceCount = 0) {
268 const token = this.tokenMap.findMatching(this._currentNode, str, occurrenceCount);
269 if (token) this._catchUpTo(token.loc.start);
270 if (this._printSemicolonBeforeNextToken !== -1 && this._printSemicolonBeforeNextToken === this._buf.getCurrentLine()) {
271 this._buf.appendChar(59);
272 this._endsWithWord = false;
273 this._endsWithInteger = false;
274 this._endsWithDiv = false;
275 }
276 this._printSemicolonBeforeNextToken = -1;
277 this._printSemicolonBeforeNextNode = -1;
278 }
279 _append(str, maybeNewline) {
280 this._maybeIndent(str.charCodeAt(0));
281 this._buf.append(str, maybeNewline);
282 this._endsWithWord = false;
283 this._endsWithInteger = false;
284 this._endsWithDiv = false;
285 }
286 _appendChar(char) {
287 this._maybeIndent(char);
288 this._buf.appendChar(char);
289 this._endsWithWord = false;
290 this._endsWithInteger = false;
291 this._endsWithDiv = false;
292 }
293 _queue(char) {
294 this._maybeIndent(char);
295 this._buf.queue(char);
296 this._endsWithWord = false;
297 this._endsWithInteger = false;
298 }
299 _maybeIndent(firstChar) {
300 if (this._indent && firstChar !== 10 && this.endsWith(10)) {
301 this._buf.queueIndentation(this._getIndent());
302 }
303 }
304 _shouldIndent(firstChar) {
305 if (this._indent && firstChar !== 10 && this.endsWith(10)) {
306 return true;
307 }
308 }
309 catchUp(line) {
310 if (!this.format.retainLines) return;
311 const count = line - this._buf.getCurrentLine();
312 for (let i = 0; i < count; i++) {
313 this._newline();
314 }
315 }
316 _catchUp(prop, loc) {
317 const {
318 format
319 } = this;
320 if (!format.preserveFormat) {
321 if (format.retainLines && loc != null && loc[prop]) {
322 this.catchUp(loc[prop].line);
323 }
324 return;
325 }
326 const pos = loc == null ? void 0 : loc[prop];
327 if (pos != null) this._catchUpTo(pos);
328 }
329 _catchUpTo({
330 line,
331 column,
332 index
333 }) {
334 const count = line - this._buf.getCurrentLine();
335 if (count > 0 && this._noLineTerminator) {
336 return;
337 }
338 for (let i = 0; i < count; i++) {
339 this._newline();
340 }
341 const spacesCount = count > 0 ? column : column - this._buf.getCurrentColumn();
342 if (spacesCount > 0) {
343 const spaces = this._originalCode ? this._originalCode.slice(index - spacesCount, index).replace(/[^\t\x0B\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]/gu, " ") : " ".repeat(spacesCount);
344 this._append(spaces, false);
345 }
346 }
347 _getIndent() {
348 return this._indentRepeat * this._indent;
349 }
350 printTerminatorless(node) {
351 this._noLineTerminator = true;
352 this.print(node);
353 }
354 print(node, noLineTerminatorAfter = false, trailingCommentsLineOffset) {
355 var _node$extra, _node$leadingComments, _node$leadingComments2;
356 if (!node) return;
357 this._endsWithInnerRaw = false;
358 const nodeType = node.type;
359 const format = this.format;
360 const oldConcise = format.concise;
361 if (node._compact) {
362 format.concise = true;
363 }
364 const printMethod = this[nodeType];
365 if (printMethod === undefined) {
366 throw new ReferenceError(`unknown node of type ${JSON.stringify(nodeType)} with constructor ${JSON.stringify(node.constructor.name)}`);
367 }
368 const parent = this._currentNode;
369 this._currentNode = node;
370 if (this.tokenMap) {
371 this._printSemicolonBeforeNextToken = this._printSemicolonBeforeNextNode;
372 }
373 const oldInAux = this._insideAux;
374 this._insideAux = node.loc == null;
375 this._maybeAddAuxComment(this._insideAux && !oldInAux);
376 const parenthesized = (_node$extra = node.extra) == null ? void 0 : _node$extra.parenthesized;
377 let shouldPrintParens = parenthesized && format.preserveFormat || parenthesized && format.retainFunctionParens && nodeType === "FunctionExpression" || needsParens(node, parent, this.tokenContext, format.preserveFormat ? this._boundGetRawIdentifier : undefined);
378 if (!shouldPrintParens && parenthesized && (_node$leadingComments = node.leadingComments) != null && _node$leadingComments.length && node.leadingComments[0].type === "CommentBlock") {
379 const parentType = parent == null ? void 0 : parent.type;
380 switch (parentType) {
381 case "ExpressionStatement":
382 case "VariableDeclarator":
383 case "AssignmentExpression":
384 case "ReturnStatement":
385 break;
386 case "CallExpression":
387 case "OptionalCallExpression":
388 case "NewExpression":
389 if (parent.callee !== node) break;
390 default:
391 shouldPrintParens = true;
392 }
393 }
394 let indentParenthesized = false;
395 if (!shouldPrintParens && this._noLineTerminator && ((_node$leadingComments2 = node.leadingComments) != null && _node$leadingComments2.some(commentIsNewline) || this.format.retainLines && node.loc && node.loc.start.line > this._buf.getCurrentLine())) {
396 shouldPrintParens = true;
397 indentParenthesized = true;
398 }
399 let oldNoLineTerminatorAfterNode;
400 let oldTokenContext;
401 if (!shouldPrintParens) {
402 noLineTerminatorAfter || (noLineTerminatorAfter = !!parent && this._noLineTerminatorAfterNode === parent && n.isLastChild(parent, node));
403 if (noLineTerminatorAfter) {
404 var _node$trailingComment;
405 if ((_node$trailingComment = node.trailingComments) != null && _node$trailingComment.some(commentIsNewline)) {
406 if (isExpression(node)) shouldPrintParens = true;
407 } else {
408 oldNoLineTerminatorAfterNode = this._noLineTerminatorAfterNode;
409 this._noLineTerminatorAfterNode = node;
410 }
411 }
412 }
413 if (shouldPrintParens) {
414 this.tokenChar(40);
415 if (indentParenthesized) this.indent();
416 this._endsWithInnerRaw = false;
417 if (this.tokenContext & _index.TokenContext.forInOrInitHeadAccumulate) {
418 oldTokenContext = this.tokenContext;
419 this.tokenContext = _index.TokenContext.normal;
420 }
421 oldNoLineTerminatorAfterNode = this._noLineTerminatorAfterNode;
422 this._noLineTerminatorAfterNode = null;
423 }
424 this._lastCommentLine = 0;
425 this._printLeadingComments(node, parent);
426 const loc = nodeType === "Program" || nodeType === "File" ? null : node.loc;
427 this.exactSource(loc, printMethod.bind(this, node, parent));
428 if (shouldPrintParens) {
429 this._printTrailingComments(node, parent);
430 if (indentParenthesized) {
431 this.dedent();
432 this.newline();
433 }
434 this.tokenChar(41);
435 this._noLineTerminator = noLineTerminatorAfter;
436 if (oldTokenContext) this.tokenContext = oldTokenContext;
437 } else if (noLineTerminatorAfter && !this._noLineTerminator) {
438 this._noLineTerminator = true;
439 this._printTrailingComments(node, parent);
440 } else {
441 this._printTrailingComments(node, parent, trailingCommentsLineOffset);
442 }
443 this._currentNode = parent;
444 format.concise = oldConcise;
445 this._insideAux = oldInAux;
446 if (oldNoLineTerminatorAfterNode !== undefined) {
447 this._noLineTerminatorAfterNode = oldNoLineTerminatorAfterNode;
448 }
449 this._endsWithInnerRaw = false;
450 }
451 _maybeAddAuxComment(enteredPositionlessNode) {
452 if (enteredPositionlessNode) this._printAuxBeforeComment();
453 if (!this._insideAux) this._printAuxAfterComment();
454 }
455 _printAuxBeforeComment() {
456 if (this._printAuxAfterOnNextUserNode) return;
457 this._printAuxAfterOnNextUserNode = true;
458 const comment = this.format.auxiliaryCommentBefore;
459 if (comment) {
460 this._printComment({
461 type: "CommentBlock",
462 value: comment
463 }, 0);
464 }
465 }
466 _printAuxAfterComment() {
467 if (!this._printAuxAfterOnNextUserNode) return;
468 this._printAuxAfterOnNextUserNode = false;
469 const comment = this.format.auxiliaryCommentAfter;
470 if (comment) {
471 this._printComment({
472 type: "CommentBlock",
473 value: comment
474 }, 0);
475 }
476 }
477 getPossibleRaw(node) {
478 const extra = node.extra;
479 if ((extra == null ? void 0 : extra.raw) != null && extra.rawValue != null && node.value === extra.rawValue) {
480 return extra.raw;
481 }
482 }
483 printJoin(nodes, statement, indent, separator, printTrailingSeparator, iterator, trailingCommentsLineOffset) {
484 if (!(nodes != null && nodes.length)) return;
485 if (indent == null && this.format.retainLines) {
486 var _nodes$0$loc;
487 const startLine = (_nodes$0$loc = nodes[0].loc) == null ? void 0 : _nodes$0$loc.start.line;
488 if (startLine != null && startLine !== this._buf.getCurrentLine()) {
489 indent = true;
490 }
491 }
492 if (indent) this.indent();
493 const newlineOpts = {
494 nextNodeStartLine: 0
495 };
496 const boundSeparator = separator == null ? void 0 : separator.bind(this);
497 const len = nodes.length;
498 for (let i = 0; i < len; i++) {
499 const node = nodes[i];
500 if (!node) continue;
501 if (statement) this._printNewline(i === 0, newlineOpts);
502 this.print(node, undefined, trailingCommentsLineOffset || 0);
503 iterator == null || iterator(node, i);
504 if (boundSeparator != null) {
505 if (i < len - 1) boundSeparator(i, false);else if (printTrailingSeparator) boundSeparator(i, true);
506 }
507 if (statement) {
508 var _node$trailingComment2;
509 if (!((_node$trailingComment2 = node.trailingComments) != null && _node$trailingComment2.length)) {
510 this._lastCommentLine = 0;
511 }
512 if (i + 1 === len) {
513 this.newline(1);
514 } else {
515 var _nextNode$loc;
516 const nextNode = nodes[i + 1];
517 newlineOpts.nextNodeStartLine = ((_nextNode$loc = nextNode.loc) == null ? void 0 : _nextNode$loc.start.line) || 0;
518 this._printNewline(true, newlineOpts);
519 }
520 }
521 }
522 if (indent) this.dedent();
523 }
524 printAndIndentOnComments(node) {
525 const indent = node.leadingComments && node.leadingComments.length > 0;
526 if (indent) this.indent();
527 this.print(node);
528 if (indent) this.dedent();
529 }
530 printBlock(parent) {
531 const node = parent.body;
532 if (node.type !== "EmptyStatement") {
533 this.space();
534 }
535 this.print(node);
536 }
537 _printTrailingComments(node, parent, lineOffset) {
538 const {
539 innerComments,
540 trailingComments
541 } = node;
542 if (innerComments != null && innerComments.length) {
543 this._printComments(2, innerComments, node, parent, lineOffset);
544 }
545 if (trailingComments != null && trailingComments.length) {
546 this._printComments(2, trailingComments, node, parent, lineOffset);
547 }
548 }
549 _printLeadingComments(node, parent) {
550 const comments = node.leadingComments;
551 if (!(comments != null && comments.length)) return;
552 this._printComments(0, comments, node, parent);
553 }
554 _maybePrintInnerComments(nextTokenStr, nextTokenOccurrenceCount) {
555 if (this._endsWithInnerRaw) {
556 var _this$tokenMap;
557 this.printInnerComments((_this$tokenMap = this.tokenMap) == null ? void 0 : _this$tokenMap.findMatching(this._currentNode, nextTokenStr, nextTokenOccurrenceCount));
558 }
559 this._endsWithInnerRaw = true;
560 this._indentInnerComments = true;
561 }
562 printInnerComments(nextToken) {
563 const node = this._currentNode;
564 const comments = node.innerComments;
565 if (!(comments != null && comments.length)) return;
566 const hasSpace = this.endsWith(32);
567 const indent = this._indentInnerComments;
568 const printedCommentsCount = this._printedComments.size;
569 if (indent) this.indent();
570 this._printComments(1, comments, node, undefined, undefined, nextToken);
571 if (hasSpace && printedCommentsCount !== this._printedComments.size) {
572 this.space();
573 }
574 if (indent) this.dedent();
575 }
576 noIndentInnerCommentsHere() {
577 this._indentInnerComments = false;
578 }
579 printSequence(nodes, indent, trailingCommentsLineOffset) {
580 this.printJoin(nodes, true, indent != null ? indent : false, undefined, undefined, undefined, trailingCommentsLineOffset);
581 }
582 printList(items, printTrailingSeparator, statement, indent, separator, iterator) {
583 this.printJoin(items, statement, indent, separator != null ? separator : commaSeparator, printTrailingSeparator, iterator);
584 }
585 shouldPrintTrailingComma(listEnd) {
586 if (!this.tokenMap) return null;
587 const listEndIndex = this.tokenMap.findLastIndex(this._currentNode, token => this.tokenMap.matchesOriginal(token, listEnd));
588 if (listEndIndex <= 0) return null;
589 return this.tokenMap.matchesOriginal(this._tokens[listEndIndex - 1], ",");
590 }
591 _printNewline(newLine, opts) {
592 const format = this.format;
593 if (format.retainLines || format.compact) return;
594 if (format.concise) {
595 this.space();
596 return;
597 }
598 if (!newLine) {
599 return;
600 }
601 const startLine = opts.nextNodeStartLine;
602 const lastCommentLine = this._lastCommentLine;
603 if (startLine > 0 && lastCommentLine > 0) {
604 const offset = startLine - lastCommentLine;
605 if (offset >= 0) {
606 this.newline(offset || 1);
607 return;
608 }
609 }
610 if (this._buf.hasContent()) {
611 this.newline(1);
612 }
613 }
614 _shouldPrintComment(comment, nextToken) {
615 if (comment.ignore) return 0;
616 if (this._printedComments.has(comment)) return 0;
617 if (this._noLineTerminator && HAS_NEWLINE_OR_BlOCK_COMMENT_END.test(comment.value)) {
618 return 2;
619 }
620 if (nextToken && this.tokenMap) {
621 const commentTok = this.tokenMap.find(this._currentNode, token => token.value === comment.value);
622 if (commentTok && commentTok.start > nextToken.start) {
623 return 2;
624 }
625 }
626 this._printedComments.add(comment);
627 if (!this.format.shouldPrintComment(comment.value)) {
628 return 0;
629 }
630 return 1;
631 }
632 _printComment(comment, skipNewLines) {
633 const noLineTerminator = this._noLineTerminator;
634 const isBlockComment = comment.type === "CommentBlock";
635 const printNewLines = isBlockComment && skipNewLines !== 1 && !this._noLineTerminator;
636 if (printNewLines && this._buf.hasContent() && skipNewLines !== 2) {
637 this.newline(1);
638 }
639 const lastCharCode = this.getLastChar();
640 if (lastCharCode !== 91 && lastCharCode !== 123 && lastCharCode !== 40) {
641 this.space();
642 }
643 let val;
644 if (isBlockComment) {
645 val = `/*${comment.value}*/`;
646 if (this.format.indent.adjustMultilineComment) {
647 var _comment$loc;
648 const offset = (_comment$loc = comment.loc) == null ? void 0 : _comment$loc.start.column;
649 if (offset) {
650 const newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
651 val = val.replace(newlineRegex, "\n");
652 }
653 if (this.format.concise) {
654 val = val.replace(/\n(?!$)/g, `\n`);
655 } else {
656 let indentSize = this.format.retainLines ? 0 : this._buf.getCurrentColumn();
657 if (this._shouldIndent(47) || this.format.retainLines) {
658 indentSize += this._getIndent();
659 }
660 val = val.replace(/\n(?!$)/g, `\n${" ".repeat(indentSize)}`);
661 }
662 }
663 } else if (!noLineTerminator) {
664 val = `//${comment.value}`;
665 } else {
666 val = `/*${comment.value}*/`;
667 }
668 if (this._endsWithDiv) this._space();
669 if (this.tokenMap) {
670 const {
671 _printSemicolonBeforeNextToken,
672 _printSemicolonBeforeNextNode
673 } = this;
674 this._printSemicolonBeforeNextToken = -1;
675 this._printSemicolonBeforeNextNode = -1;
676 this.source("start", comment.loc);
677 this._append(val, isBlockComment);
678 this._printSemicolonBeforeNextNode = _printSemicolonBeforeNextNode;
679 this._printSemicolonBeforeNextToken = _printSemicolonBeforeNextToken;
680 } else {
681 this.source("start", comment.loc);
682 this._append(val, isBlockComment);
683 }
684 if (!isBlockComment && !noLineTerminator) {
685 this.newline(1, true);
686 }
687 if (printNewLines && skipNewLines !== 3) {
688 this.newline(1);
689 }
690 }
691 _printComments(type, comments, node, parent, lineOffset = 0, nextToken) {
692 const nodeLoc = node.loc;
693 const len = comments.length;
694 let hasLoc = !!nodeLoc;
695 const nodeStartLine = hasLoc ? nodeLoc.start.line : 0;
696 const nodeEndLine = hasLoc ? nodeLoc.end.line : 0;
697 let lastLine = 0;
698 let leadingCommentNewline = 0;
699 const maybeNewline = this._noLineTerminator ? function () {} : this.newline.bind(this);
700 for (let i = 0; i < len; i++) {
701 const comment = comments[i];
702 const shouldPrint = this._shouldPrintComment(comment, nextToken);
703 if (shouldPrint === 2) {
704 hasLoc = false;
705 break;
706 }
707 if (hasLoc && comment.loc && shouldPrint === 1) {
708 const commentStartLine = comment.loc.start.line;
709 const commentEndLine = comment.loc.end.line;
710 if (type === 0) {
711 let offset = 0;
712 if (i === 0) {
713 if (this._buf.hasContent() && (comment.type === "CommentLine" || commentStartLine !== commentEndLine)) {
714 offset = leadingCommentNewline = 1;
715 }
716 } else {
717 offset = commentStartLine - lastLine;
718 }
719 lastLine = commentEndLine;
720 maybeNewline(offset);
721 this._printComment(comment, 1);
722 if (i + 1 === len) {
723 maybeNewline(Math.max(nodeStartLine - lastLine, leadingCommentNewline));
724 lastLine = nodeStartLine;
725 }
726 } else if (type === 1) {
727 const offset = commentStartLine - (i === 0 ? nodeStartLine : lastLine);
728 lastLine = commentEndLine;
729 maybeNewline(offset);
730 this._printComment(comment, 1);
731 if (i + 1 === len) {
732 maybeNewline(Math.min(1, nodeEndLine - lastLine));
733 lastLine = nodeEndLine;
734 }
735 } else {
736 const offset = commentStartLine - (i === 0 ? nodeEndLine - lineOffset : lastLine);
737 lastLine = commentEndLine;
738 maybeNewline(offset);
739 this._printComment(comment, 1);
740 }
741 } else {
742 hasLoc = false;
743 if (shouldPrint !== 1) {
744 continue;
745 }
746 if (len === 1) {
747 const singleLine = comment.loc ? comment.loc.start.line === comment.loc.end.line : !HAS_NEWLINE.test(comment.value);
748 const shouldSkipNewline = singleLine && !isStatement(node) && !isClassBody(parent) && !isTSInterfaceBody(parent) && !isTSEnumMember(node);
749 if (type === 0) {
750 this._printComment(comment, shouldSkipNewline && node.type !== "ObjectExpression" || singleLine && isFunction(parent, {
751 body: node
752 }) ? 1 : 0);
753 } else if (shouldSkipNewline && type === 2) {
754 this._printComment(comment, 1);
755 } else {
756 this._printComment(comment, 0);
757 }
758 } else if (type === 1 && !(node.type === "ObjectExpression" && node.properties.length > 1) && node.type !== "ClassBody" && node.type !== "TSInterfaceBody") {
759 this._printComment(comment, i === 0 ? 2 : i === len - 1 ? 3 : 0);
760 } else {
761 this._printComment(comment, 0);
762 }
763 }
764 }
765 if (type === 2 && hasLoc && lastLine) {
766 this._lastCommentLine = lastLine;
767 }
768 }
769 }
770 Object.assign(Printer.prototype, generatorFunctions);
771 {
772 (0, _deprecated.addDeprecatedGenerators)(Printer);
773 }
774 var _default = exports.default = Printer;
775 function commaSeparator(occurrenceCount, last) {
776 this.token(",", false, occurrenceCount);
777 if (!last) this.space();
778 }
779
780 //# sourceMappingURL=printer.js.map
781