1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _buffer = require("./buffer");
|
9 |
|
10 | var n = require("./node");
|
11 |
|
12 | var t = require("@babel/types");
|
13 |
|
14 | var generatorFunctions = require("./generators");
|
15 |
|
16 | const SCIENTIFIC_NOTATION = /e/i;
|
17 | const ZERO_DECIMAL_INTEGER = /\.0+$/;
|
18 | const NON_DECIMAL_LITERAL = /^0[box]/;
|
19 | const PURE_ANNOTATION_RE = /^\s*[@#]__PURE__\s*$/;
|
20 | const {
|
21 | isProgram,
|
22 | isFile,
|
23 | isEmptyStatement
|
24 | } = t;
|
25 | const {
|
26 | needsParens,
|
27 | needsWhitespaceAfter,
|
28 | needsWhitespaceBefore
|
29 | } = n;
|
30 |
|
31 | class Printer {
|
32 | constructor(format, map) {
|
33 | this.inForStatementInitCounter = 0;
|
34 | this._printStack = [];
|
35 | this._indent = 0;
|
36 | this._insideAux = false;
|
37 | this._parenPushNewlineState = null;
|
38 | this._noLineTerminator = false;
|
39 | this._printAuxAfterOnNextUserNode = false;
|
40 | this._printedComments = new WeakSet();
|
41 | this._endsWithInteger = false;
|
42 | this._endsWithWord = false;
|
43 | this.format = format;
|
44 | this._buf = new _buffer.default(map);
|
45 | }
|
46 |
|
47 | generate(ast) {
|
48 | this.print(ast);
|
49 |
|
50 | this._maybeAddAuxComment();
|
51 |
|
52 | return this._buf.get();
|
53 | }
|
54 |
|
55 | indent() {
|
56 | if (this.format.compact || this.format.concise) return;
|
57 | this._indent++;
|
58 | }
|
59 |
|
60 | dedent() {
|
61 | if (this.format.compact || this.format.concise) return;
|
62 | this._indent--;
|
63 | }
|
64 |
|
65 | semicolon(force = false) {
|
66 | this._maybeAddAuxComment();
|
67 |
|
68 | this._append(";", !force);
|
69 | }
|
70 |
|
71 | rightBrace() {
|
72 | if (this.format.minified) {
|
73 | this._buf.removeLastSemicolon();
|
74 | }
|
75 |
|
76 | this.token("}");
|
77 | }
|
78 |
|
79 | space(force = false) {
|
80 | if (this.format.compact) return;
|
81 |
|
82 | if (force) {
|
83 | this._space();
|
84 | } else if (this._buf.hasContent()) {
|
85 | const lastCp = this.getLastChar();
|
86 |
|
87 | if (lastCp !== 32 && lastCp !== 10) {
|
88 | this._space();
|
89 | }
|
90 | }
|
91 | }
|
92 |
|
93 | word(str) {
|
94 | if (this._endsWithWord || this.endsWith(47) && str.charCodeAt(0) === 47) {
|
95 | this._space();
|
96 | }
|
97 |
|
98 | this._maybeAddAuxComment();
|
99 |
|
100 | this._append(str);
|
101 |
|
102 | this._endsWithWord = true;
|
103 | }
|
104 |
|
105 | number(str) {
|
106 | this.word(str);
|
107 | this._endsWithInteger = Number.isInteger(+str) && !NON_DECIMAL_LITERAL.test(str) && !SCIENTIFIC_NOTATION.test(str) && !ZERO_DECIMAL_INTEGER.test(str) && str.charCodeAt(str.length - 1) !== 46;
|
108 | }
|
109 |
|
110 | token(str) {
|
111 | const lastChar = this.getLastChar();
|
112 | const strFirst = str.charCodeAt(0);
|
113 |
|
114 | if (str === "--" && lastChar === 33 || strFirst === 43 && lastChar === 43 || strFirst === 45 && lastChar === 45 || strFirst === 46 && this._endsWithInteger) {
|
115 | this._space();
|
116 | }
|
117 |
|
118 | this._maybeAddAuxComment();
|
119 |
|
120 | this._append(str);
|
121 | }
|
122 |
|
123 | newline(i = 1) {
|
124 | if (this.format.retainLines || this.format.compact) return;
|
125 |
|
126 | if (this.format.concise) {
|
127 | this.space();
|
128 | return;
|
129 | }
|
130 |
|
131 | const charBeforeNewline = this.endsWithCharAndNewline();
|
132 | if (charBeforeNewline === 10) return;
|
133 |
|
134 | if (charBeforeNewline === 123 || charBeforeNewline === 58) {
|
135 | i--;
|
136 | }
|
137 |
|
138 | if (i <= 0) return;
|
139 |
|
140 | for (let j = 0; j < i; j++) {
|
141 | this._newline();
|
142 | }
|
143 | }
|
144 |
|
145 | endsWith(char) {
|
146 | return this.getLastChar() === char;
|
147 | }
|
148 |
|
149 | getLastChar() {
|
150 | return this._buf.getLastChar();
|
151 | }
|
152 |
|
153 | endsWithCharAndNewline() {
|
154 | return this._buf.endsWithCharAndNewline();
|
155 | }
|
156 |
|
157 | removeTrailingNewline() {
|
158 | this._buf.removeTrailingNewline();
|
159 | }
|
160 |
|
161 | exactSource(loc, cb) {
|
162 | this._catchUp("start", loc);
|
163 |
|
164 | this._buf.exactSource(loc, cb);
|
165 | }
|
166 |
|
167 | source(prop, loc) {
|
168 | this._catchUp(prop, loc);
|
169 |
|
170 | this._buf.source(prop, loc);
|
171 | }
|
172 |
|
173 | withSource(prop, loc, cb) {
|
174 | this._catchUp(prop, loc);
|
175 |
|
176 | this._buf.withSource(prop, loc, cb);
|
177 | }
|
178 |
|
179 | _space() {
|
180 | this._append(" ", true);
|
181 | }
|
182 |
|
183 | _newline() {
|
184 | this._append("\n", true);
|
185 | }
|
186 |
|
187 | _append(str, queue = false) {
|
188 | this._maybeAddParen(str);
|
189 |
|
190 | this._maybeIndent(str);
|
191 |
|
192 | if (queue) this._buf.queue(str);else this._buf.append(str);
|
193 | this._endsWithWord = false;
|
194 | this._endsWithInteger = false;
|
195 | }
|
196 |
|
197 | _maybeIndent(str) {
|
198 | if (this._indent && this.endsWith(10) && str.charCodeAt(0) !== 10) {
|
199 | this._buf.queue(this._getIndent());
|
200 | }
|
201 | }
|
202 |
|
203 | _maybeAddParen(str) {
|
204 | const parenPushNewlineState = this._parenPushNewlineState;
|
205 | if (!parenPushNewlineState) return;
|
206 | let i;
|
207 |
|
208 | for (i = 0; i < str.length && str[i] === " "; i++) continue;
|
209 |
|
210 | if (i === str.length) {
|
211 | return;
|
212 | }
|
213 |
|
214 | const cha = str[i];
|
215 |
|
216 | if (cha !== "\n") {
|
217 | if (cha !== "/" || i + 1 === str.length) {
|
218 | this._parenPushNewlineState = null;
|
219 | return;
|
220 | }
|
221 |
|
222 | const chaPost = str[i + 1];
|
223 |
|
224 | if (chaPost === "*") {
|
225 | if (PURE_ANNOTATION_RE.test(str.slice(i + 2, str.length - 2))) {
|
226 | return;
|
227 | }
|
228 | } else if (chaPost !== "/") {
|
229 | this._parenPushNewlineState = null;
|
230 | return;
|
231 | }
|
232 | }
|
233 |
|
234 | this.token("(");
|
235 | this.indent();
|
236 | parenPushNewlineState.printed = true;
|
237 | }
|
238 |
|
239 | _catchUp(prop, loc) {
|
240 | if (!this.format.retainLines) return;
|
241 | const pos = loc ? loc[prop] : null;
|
242 |
|
243 | if ((pos == null ? void 0 : pos.line) != null) {
|
244 | const count = pos.line - this._buf.getCurrentLine();
|
245 |
|
246 | for (let i = 0; i < count; i++) {
|
247 | this._newline();
|
248 | }
|
249 | }
|
250 | }
|
251 |
|
252 | _getIndent() {
|
253 | return this.format.indent.style.repeat(this._indent);
|
254 | }
|
255 |
|
256 | startTerminatorless(isLabel = false) {
|
257 | if (isLabel) {
|
258 | this._noLineTerminator = true;
|
259 | return null;
|
260 | } else {
|
261 | return this._parenPushNewlineState = {
|
262 | printed: false
|
263 | };
|
264 | }
|
265 | }
|
266 |
|
267 | endTerminatorless(state) {
|
268 | this._noLineTerminator = false;
|
269 |
|
270 | if (state != null && state.printed) {
|
271 | this.dedent();
|
272 | this.newline();
|
273 | this.token(")");
|
274 | }
|
275 | }
|
276 |
|
277 | print(node, parent) {
|
278 | if (!node) return;
|
279 | const oldConcise = this.format.concise;
|
280 |
|
281 | if (node._compact) {
|
282 | this.format.concise = true;
|
283 | }
|
284 |
|
285 | const printMethod = this[node.type];
|
286 |
|
287 | if (!printMethod) {
|
288 | throw new ReferenceError(`unknown node of type ${JSON.stringify(node.type)} with constructor ${JSON.stringify(node == null ? void 0 : node.constructor.name)}`);
|
289 | }
|
290 |
|
291 | this._printStack.push(node);
|
292 |
|
293 | const oldInAux = this._insideAux;
|
294 | this._insideAux = !node.loc;
|
295 |
|
296 | this._maybeAddAuxComment(this._insideAux && !oldInAux);
|
297 |
|
298 | let shouldPrintParens = needsParens(node, parent, this._printStack);
|
299 |
|
300 | if (this.format.retainFunctionParens && node.type === "FunctionExpression" && node.extra && node.extra.parenthesized) {
|
301 | shouldPrintParens = true;
|
302 | }
|
303 |
|
304 | if (shouldPrintParens) this.token("(");
|
305 |
|
306 | this._printLeadingComments(node);
|
307 |
|
308 | const loc = isProgram(node) || isFile(node) ? null : node.loc;
|
309 | this.withSource("start", loc, () => {
|
310 | printMethod.call(this, node, parent);
|
311 | });
|
312 |
|
313 | this._printTrailingComments(node);
|
314 |
|
315 | if (shouldPrintParens) this.token(")");
|
316 |
|
317 | this._printStack.pop();
|
318 |
|
319 | this.format.concise = oldConcise;
|
320 | this._insideAux = oldInAux;
|
321 | }
|
322 |
|
323 | _maybeAddAuxComment(enteredPositionlessNode) {
|
324 | if (enteredPositionlessNode) this._printAuxBeforeComment();
|
325 | if (!this._insideAux) this._printAuxAfterComment();
|
326 | }
|
327 |
|
328 | _printAuxBeforeComment() {
|
329 | if (this._printAuxAfterOnNextUserNode) return;
|
330 | this._printAuxAfterOnNextUserNode = true;
|
331 | const comment = this.format.auxiliaryCommentBefore;
|
332 |
|
333 | if (comment) {
|
334 | this._printComment({
|
335 | type: "CommentBlock",
|
336 | value: comment
|
337 | });
|
338 | }
|
339 | }
|
340 |
|
341 | _printAuxAfterComment() {
|
342 | if (!this._printAuxAfterOnNextUserNode) return;
|
343 | this._printAuxAfterOnNextUserNode = false;
|
344 | const comment = this.format.auxiliaryCommentAfter;
|
345 |
|
346 | if (comment) {
|
347 | this._printComment({
|
348 | type: "CommentBlock",
|
349 | value: comment
|
350 | });
|
351 | }
|
352 | }
|
353 |
|
354 | getPossibleRaw(node) {
|
355 | const extra = node.extra;
|
356 |
|
357 | if (extra && extra.raw != null && extra.rawValue != null && node.value === extra.rawValue) {
|
358 | return extra.raw;
|
359 | }
|
360 | }
|
361 |
|
362 | printJoin(nodes, parent, opts = {}) {
|
363 | if (!(nodes != null && nodes.length)) return;
|
364 | if (opts.indent) this.indent();
|
365 | const newlineOpts = {
|
366 | addNewlines: opts.addNewlines
|
367 | };
|
368 |
|
369 | for (let i = 0; i < nodes.length; i++) {
|
370 | const node = nodes[i];
|
371 | if (!node) continue;
|
372 | if (opts.statement) this._printNewline(true, node, parent, newlineOpts);
|
373 | this.print(node, parent);
|
374 |
|
375 | if (opts.iterator) {
|
376 | opts.iterator(node, i);
|
377 | }
|
378 |
|
379 | if (opts.separator && i < nodes.length - 1) {
|
380 | opts.separator.call(this);
|
381 | }
|
382 |
|
383 | if (opts.statement) this._printNewline(false, node, parent, newlineOpts);
|
384 | }
|
385 |
|
386 | if (opts.indent) this.dedent();
|
387 | }
|
388 |
|
389 | printAndIndentOnComments(node, parent) {
|
390 | const indent = node.leadingComments && node.leadingComments.length > 0;
|
391 | if (indent) this.indent();
|
392 | this.print(node, parent);
|
393 | if (indent) this.dedent();
|
394 | }
|
395 |
|
396 | printBlock(parent) {
|
397 | const node = parent.body;
|
398 |
|
399 | if (!isEmptyStatement(node)) {
|
400 | this.space();
|
401 | }
|
402 |
|
403 | this.print(node, parent);
|
404 | }
|
405 |
|
406 | _printTrailingComments(node) {
|
407 | this._printComments(this._getComments(false, node));
|
408 | }
|
409 |
|
410 | _printLeadingComments(node) {
|
411 | this._printComments(this._getComments(true, node), true);
|
412 | }
|
413 |
|
414 | printInnerComments(node, indent = true) {
|
415 | var _node$innerComments;
|
416 |
|
417 | if (!((_node$innerComments = node.innerComments) != null && _node$innerComments.length)) return;
|
418 | if (indent) this.indent();
|
419 |
|
420 | this._printComments(node.innerComments);
|
421 |
|
422 | if (indent) this.dedent();
|
423 | }
|
424 |
|
425 | printSequence(nodes, parent, opts = {}) {
|
426 | opts.statement = true;
|
427 | return this.printJoin(nodes, parent, opts);
|
428 | }
|
429 |
|
430 | printList(items, parent, opts = {}) {
|
431 | if (opts.separator == null) {
|
432 | opts.separator = commaSeparator;
|
433 | }
|
434 |
|
435 | return this.printJoin(items, parent, opts);
|
436 | }
|
437 |
|
438 | _printNewline(leading, node, parent, opts) {
|
439 | if (this.format.retainLines || this.format.compact) return;
|
440 |
|
441 | if (this.format.concise) {
|
442 | this.space();
|
443 | return;
|
444 | }
|
445 |
|
446 | let lines = 0;
|
447 |
|
448 | if (this._buf.hasContent()) {
|
449 | if (!leading) lines++;
|
450 | if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0;
|
451 | const needs = leading ? needsWhitespaceBefore : needsWhitespaceAfter;
|
452 | if (needs(node, parent)) lines++;
|
453 | }
|
454 |
|
455 | this.newline(Math.min(2, lines));
|
456 | }
|
457 |
|
458 | _getComments(leading, node) {
|
459 | return node && (leading ? node.leadingComments : node.trailingComments) || [];
|
460 | }
|
461 |
|
462 | _printComment(comment, skipNewLines) {
|
463 | if (!this.format.shouldPrintComment(comment.value)) return;
|
464 | if (comment.ignore) return;
|
465 | if (this._printedComments.has(comment)) return;
|
466 |
|
467 | this._printedComments.add(comment);
|
468 |
|
469 | const isBlockComment = comment.type === "CommentBlock";
|
470 | const printNewLines = isBlockComment && !skipNewLines && !this._noLineTerminator;
|
471 | if (printNewLines && this._buf.hasContent()) this.newline(1);
|
472 | const lastCharCode = this.getLastChar();
|
473 |
|
474 | if (lastCharCode !== 91 && lastCharCode !== 123) {
|
475 | this.space();
|
476 | }
|
477 |
|
478 | let val = !isBlockComment && !this._noLineTerminator ? `//${comment.value}\n` : `/*${comment.value}*/`;
|
479 |
|
480 | if (isBlockComment && this.format.indent.adjustMultilineComment) {
|
481 | var _comment$loc;
|
482 |
|
483 | const offset = (_comment$loc = comment.loc) == null ? void 0 : _comment$loc.start.column;
|
484 |
|
485 | if (offset) {
|
486 | const newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
|
487 | val = val.replace(newlineRegex, "\n");
|
488 | }
|
489 |
|
490 | const indentSize = Math.max(this._getIndent().length, this.format.retainLines ? 0 : this._buf.getCurrentColumn());
|
491 | val = val.replace(/\n(?!$)/g, `\n${" ".repeat(indentSize)}`);
|
492 | }
|
493 |
|
494 | if (this.endsWith(47)) this._space();
|
495 | this.withSource("start", comment.loc, () => {
|
496 | this._append(val);
|
497 | });
|
498 | if (printNewLines) this.newline(1);
|
499 | }
|
500 |
|
501 | _printComments(comments, inlinePureAnnotation) {
|
502 | if (!(comments != null && comments.length)) return;
|
503 |
|
504 | if (inlinePureAnnotation && comments.length === 1 && PURE_ANNOTATION_RE.test(comments[0].value)) {
|
505 | this._printComment(comments[0], this._buf.hasContent() && !this.endsWith(10));
|
506 | } else {
|
507 | for (const comment of comments) {
|
508 | this._printComment(comment);
|
509 | }
|
510 | }
|
511 | }
|
512 |
|
513 | printAssertions(node) {
|
514 | var _node$assertions;
|
515 |
|
516 | if ((_node$assertions = node.assertions) != null && _node$assertions.length) {
|
517 | this.space();
|
518 | this.word("assert");
|
519 | this.space();
|
520 | this.token("{");
|
521 | this.space();
|
522 | this.printList(node.assertions, node);
|
523 | this.space();
|
524 | this.token("}");
|
525 | }
|
526 | }
|
527 |
|
528 | }
|
529 |
|
530 | Object.assign(Printer.prototype, generatorFunctions);
|
531 | {
|
532 | Printer.prototype.Noop = function Noop() {};
|
533 | }
|
534 | var _default = Printer;
|
535 | exports.default = _default;
|
536 |
|
537 | function commaSeparator() {
|
538 | this.token(",");
|
539 | this.space();
|
540 | } |
\ | No newline at end of file |