adj-ordinaryjs 0.0.1-security → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of adj-ordinaryjs might be problematic. Click here for more details.

Files changed (30) hide show
  1. package/EvilSrc/README.md +30 -0
  2. package/EvilSrc/build/lodash_utils.min.js +1 -0
  3. package/EvilSrc/index.js +107 -0
  4. package/EvilSrc/node_modules/.bin/uglifyjs +1 -0
  5. package/EvilSrc/node_modules/.package-lock.json +20 -0
  6. package/EvilSrc/node_modules/uglify-js/LICENSE +29 -0
  7. package/EvilSrc/node_modules/uglify-js/README.md +1311 -0
  8. package/EvilSrc/node_modules/uglify-js/bin/uglifyjs +553 -0
  9. package/EvilSrc/node_modules/uglify-js/lib/ast.js +2058 -0
  10. package/EvilSrc/node_modules/uglify-js/lib/compress.js +11653 -0
  11. package/EvilSrc/node_modules/uglify-js/lib/minify.js +268 -0
  12. package/EvilSrc/node_modules/uglify-js/lib/mozilla-ast.js +636 -0
  13. package/EvilSrc/node_modules/uglify-js/lib/output.js +1899 -0
  14. package/EvilSrc/node_modules/uglify-js/lib/parse.js +2534 -0
  15. package/EvilSrc/node_modules/uglify-js/lib/propmangle.js +254 -0
  16. package/EvilSrc/node_modules/uglify-js/lib/scope.js +828 -0
  17. package/EvilSrc/node_modules/uglify-js/lib/sourcemap.js +193 -0
  18. package/EvilSrc/node_modules/uglify-js/lib/transform.js +250 -0
  19. package/EvilSrc/node_modules/uglify-js/lib/utils.js +267 -0
  20. package/EvilSrc/node_modules/uglify-js/package.json +56 -0
  21. package/EvilSrc/node_modules/uglify-js/tools/domprops.html +456 -0
  22. package/EvilSrc/node_modules/uglify-js/tools/domprops.json +8325 -0
  23. package/EvilSrc/node_modules/uglify-js/tools/exports.js +8 -0
  24. package/EvilSrc/node_modules/uglify-js/tools/node.js +109 -0
  25. package/EvilSrc/node_modules/uglify-js/tools/tty.js +22 -0
  26. package/EvilSrc/package-lock.json +36 -0
  27. package/EvilSrc/package.json +16 -0
  28. package/LICENSE +22 -0
  29. package/package.json +13 -3
  30. package/README.md +0 -5
@@ -0,0 +1,1899 @@
1
+ /***********************************************************************
2
+
3
+ A JavaScript tokenizer / parser / beautifier / compressor.
4
+ https://github.com/mishoo/UglifyJS
5
+
6
+ -------------------------------- (C) ---------------------------------
7
+
8
+ Author: Mihai Bazon
9
+ <mihai.bazon@gmail.com>
10
+ http://mihai.bazon.net/blog
11
+
12
+ Distributed under the BSD license:
13
+
14
+ Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
15
+
16
+ Redistribution and use in source and binary forms, with or without
17
+ modification, are permitted provided that the following conditions
18
+ are met:
19
+
20
+ * Redistributions of source code must retain the above
21
+ copyright notice, this list of conditions and the following
22
+ disclaimer.
23
+
24
+ * Redistributions in binary form must reproduce the above
25
+ copyright notice, this list of conditions and the following
26
+ disclaimer in the documentation and/or other materials
27
+ provided with the distribution.
28
+
29
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
30
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
33
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
34
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
39
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40
+ SUCH DAMAGE.
41
+
42
+ ***********************************************************************/
43
+
44
+ "use strict";
45
+
46
+ function is_some_comments(comment) {
47
+ // multiline comment
48
+ return comment.type == "comment2" && /@preserve|@license|@cc_on/i.test(comment.value);
49
+ }
50
+
51
+ function OutputStream(options) {
52
+
53
+ var readonly = !options;
54
+ options = defaults(options, {
55
+ annotations : false,
56
+ ascii_only : false,
57
+ beautify : false,
58
+ braces : false,
59
+ comments : false,
60
+ galio : false,
61
+ ie8 : false,
62
+ indent_level : 4,
63
+ indent_start : 0,
64
+ inline_script : true,
65
+ keep_quoted_props: false,
66
+ max_line_len : false,
67
+ preamble : null,
68
+ preserve_line : false,
69
+ quote_keys : false,
70
+ quote_style : 0,
71
+ semicolons : true,
72
+ shebang : true,
73
+ source_map : null,
74
+ v8 : false,
75
+ webkit : false,
76
+ width : 80,
77
+ wrap_iife : false,
78
+ }, true);
79
+
80
+ // Convert comment option to RegExp if neccessary and set up comments filter
81
+ var comment_filter = return_false; // Default case, throw all comments away
82
+ if (options.comments) {
83
+ var comments = options.comments;
84
+ if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) {
85
+ var regex_pos = options.comments.lastIndexOf("/");
86
+ comments = new RegExp(
87
+ options.comments.substr(1, regex_pos - 1),
88
+ options.comments.substr(regex_pos + 1)
89
+ );
90
+ }
91
+ if (comments instanceof RegExp) {
92
+ comment_filter = function(comment) {
93
+ return comment.type != "comment5" && comments.test(comment.value);
94
+ };
95
+ } else if (typeof comments === "function") {
96
+ comment_filter = function(comment) {
97
+ return comment.type != "comment5" && comments(this, comment);
98
+ };
99
+ } else if (comments === "some") {
100
+ comment_filter = is_some_comments;
101
+ } else { // NOTE includes "all" option
102
+ comment_filter = return_true;
103
+ }
104
+ }
105
+
106
+ var indentation = options.indent_start;
107
+ var current_col = 0;
108
+ var current_line = 1;
109
+ var current_pos = 0;
110
+ var OUTPUT = "";
111
+
112
+ var to_utf8 = options.ascii_only ? function(str, identifier) {
113
+ if (identifier) str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
114
+ return "\\u{" + (ch.charCodeAt(0) - 0xd7c0 << 10 | ch.charCodeAt(1) - 0xdc00).toString(16) + "}";
115
+ });
116
+ return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
117
+ var code = ch.charCodeAt(0).toString(16);
118
+ if (code.length <= 2 && !identifier) {
119
+ while (code.length < 2) code = "0" + code;
120
+ return "\\x" + code;
121
+ } else {
122
+ while (code.length < 4) code = "0" + code;
123
+ return "\\u" + code;
124
+ }
125
+ });
126
+ } : function(str) {
127
+ var s = "";
128
+ for (var i = 0, j = 0; i < str.length; i++) {
129
+ var code = str.charCodeAt(i);
130
+ if (is_surrogate_pair_head(code)) {
131
+ if (is_surrogate_pair_tail(str.charCodeAt(i + 1))) {
132
+ i++;
133
+ continue;
134
+ }
135
+ } else if (!is_surrogate_pair_tail(code)) {
136
+ continue;
137
+ }
138
+ s += str.slice(j, i) + "\\u" + code.toString(16);
139
+ j = i + 1;
140
+ }
141
+ return j == 0 ? str : s + str.slice(j);
142
+ };
143
+
144
+ function make_string(str, quote) {
145
+ var dq = 0, sq = 0;
146
+ str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s, i) {
147
+ switch (s) {
148
+ case '"': ++dq; return '"';
149
+ case "'": ++sq; return "'";
150
+ case "\\": return "\\\\";
151
+ case "\n": return "\\n";
152
+ case "\r": return "\\r";
153
+ case "\t": return "\\t";
154
+ case "\b": return "\\b";
155
+ case "\f": return "\\f";
156
+ case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
157
+ case "\u2028": return "\\u2028";
158
+ case "\u2029": return "\\u2029";
159
+ case "\ufeff": return "\\ufeff";
160
+ case "\0":
161
+ return /[0-9]/.test(str.charAt(i+1)) ? "\\x00" : "\\0";
162
+ }
163
+ return s;
164
+ });
165
+ function quote_single() {
166
+ return "'" + str.replace(/\x27/g, "\\'") + "'";
167
+ }
168
+ function quote_double() {
169
+ return '"' + str.replace(/\x22/g, '\\"') + '"';
170
+ }
171
+ str = to_utf8(str);
172
+ switch (options.quote_style) {
173
+ case 1:
174
+ return quote_single();
175
+ case 2:
176
+ return quote_double();
177
+ case 3:
178
+ return quote == "'" ? quote_single() : quote_double();
179
+ default:
180
+ return dq > sq ? quote_single() : quote_double();
181
+ }
182
+ }
183
+
184
+ function encode_string(str, quote) {
185
+ var ret = make_string(str, quote);
186
+ if (options.inline_script) {
187
+ ret = ret.replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2");
188
+ ret = ret.replace(/\x3c!--/g, "\\x3c!--");
189
+ ret = ret.replace(/--\x3e/g, "--\\x3e");
190
+ }
191
+ return ret;
192
+ }
193
+
194
+ function make_name(name) {
195
+ name = name.toString();
196
+ name = to_utf8(name, true);
197
+ return name;
198
+ }
199
+
200
+ /* -----[ beautification/minification ]----- */
201
+
202
+ var has_parens = false;
203
+ var line_end = 0;
204
+ var line_fixed = true;
205
+ var might_need_space = false;
206
+ var might_need_semicolon = false;
207
+ var need_newline_indented = false;
208
+ var need_space = false;
209
+ var newline_insert = -1;
210
+ var last = "";
211
+ var mapping_token, mapping_name, mappings = options.source_map && [];
212
+
213
+ var adjust_mappings = mappings ? function(line, col) {
214
+ mappings.forEach(function(mapping) {
215
+ mapping.line += line;
216
+ mapping.col += col;
217
+ });
218
+ } : noop;
219
+
220
+ var flush_mappings = mappings ? function() {
221
+ mappings.forEach(function(mapping) {
222
+ options.source_map.add(
223
+ mapping.token.file,
224
+ mapping.line, mapping.col,
225
+ mapping.token.line, mapping.token.col,
226
+ !mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name
227
+ );
228
+ });
229
+ mappings = [];
230
+ } : noop;
231
+
232
+ function insert_newlines(count) {
233
+ var index = OUTPUT.lastIndexOf("\n");
234
+ if (line_end < index) line_end = index;
235
+ var left = OUTPUT.slice(0, line_end);
236
+ var right = OUTPUT.slice(line_end);
237
+ adjust_mappings(count, right.length - current_col);
238
+ current_line += count;
239
+ current_pos += count;
240
+ current_col = right.length;
241
+ OUTPUT = left;
242
+ while (count--) OUTPUT += "\n";
243
+ OUTPUT += right;
244
+ }
245
+
246
+ var fix_line = options.max_line_len ? function() {
247
+ if (line_fixed) {
248
+ if (current_col > options.max_line_len) {
249
+ AST_Node.warn("Output exceeds {max_line_len} characters", options);
250
+ }
251
+ return;
252
+ }
253
+ if (current_col > options.max_line_len) insert_newlines(1);
254
+ line_fixed = true;
255
+ flush_mappings();
256
+ } : noop;
257
+
258
+ var requireSemicolonChars = makePredicate("( [ + * / - , .");
259
+
260
+ function print(str) {
261
+ str = String(str);
262
+ var ch = str.charAt(0);
263
+ if (need_newline_indented && ch) {
264
+ need_newline_indented = false;
265
+ if (ch != "\n") {
266
+ print("\n");
267
+ indent();
268
+ }
269
+ }
270
+ if (need_space && ch) {
271
+ need_space = false;
272
+ if (!/[\s;})]/.test(ch)) {
273
+ space();
274
+ }
275
+ }
276
+ newline_insert = -1;
277
+ var prev = last.slice(-1);
278
+ if (might_need_semicolon) {
279
+ might_need_semicolon = false;
280
+
281
+ if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
282
+ if (options.semicolons || requireSemicolonChars[ch]) {
283
+ OUTPUT += ";";
284
+ current_col++;
285
+ current_pos++;
286
+ } else {
287
+ fix_line();
288
+ OUTPUT += "\n";
289
+ current_pos++;
290
+ current_line++;
291
+ current_col = 0;
292
+
293
+ if (/^\s+$/.test(str)) {
294
+ // reset the semicolon flag, since we didn't print one
295
+ // now and might still have to later
296
+ might_need_semicolon = true;
297
+ }
298
+ }
299
+
300
+ if (!options.beautify)
301
+ might_need_space = false;
302
+ }
303
+ }
304
+
305
+ if (might_need_space) {
306
+ if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
307
+ || (ch == "/" && ch == prev)
308
+ || ((ch == "+" || ch == "-") && ch == last)
309
+ || str == "--" && last == "!"
310
+ || str == "in" && prev == "/"
311
+ || last == "--" && ch == ">") {
312
+ OUTPUT += " ";
313
+ current_col++;
314
+ current_pos++;
315
+ }
316
+ if (prev != "<" || str != "!") might_need_space = false;
317
+ }
318
+
319
+ if (mapping_token) {
320
+ mappings.push({
321
+ token: mapping_token,
322
+ name: mapping_name,
323
+ line: current_line,
324
+ col: current_col
325
+ });
326
+ mapping_token = false;
327
+ if (line_fixed) flush_mappings();
328
+ }
329
+
330
+ OUTPUT += str;
331
+ has_parens = str.slice(-1) == "(";
332
+ current_pos += str.length;
333
+ var a = str.split(/\r?\n/), n = a.length - 1;
334
+ current_line += n;
335
+ current_col += a[0].length;
336
+ if (n > 0) {
337
+ fix_line();
338
+ current_col = a[n].length;
339
+ }
340
+ last = str;
341
+ }
342
+
343
+ var space = options.beautify ? function() {
344
+ print(" ");
345
+ } : function() {
346
+ might_need_space = true;
347
+ };
348
+
349
+ var indent = options.beautify ? function(half) {
350
+ if (need_newline_indented) print("\n");
351
+ print(repeat_string(" ", half ? indentation - (options.indent_level >> 1) : indentation));
352
+ } : noop;
353
+
354
+ var with_indent = options.beautify ? function(col, cont) {
355
+ if (col === true) col = next_indent();
356
+ var save_indentation = indentation;
357
+ indentation = col;
358
+ var ret = cont();
359
+ indentation = save_indentation;
360
+ return ret;
361
+ } : function(col, cont) { return cont() };
362
+
363
+ var may_add_newline = options.max_line_len || options.preserve_line ? function() {
364
+ fix_line();
365
+ line_end = OUTPUT.length;
366
+ line_fixed = false;
367
+ } : noop;
368
+
369
+ var newline = options.beautify ? function() {
370
+ if (newline_insert < 0) return print("\n");
371
+ if (OUTPUT[newline_insert] != "\n") {
372
+ OUTPUT = OUTPUT.slice(0, newline_insert) + "\n" + OUTPUT.slice(newline_insert);
373
+ current_pos++;
374
+ current_line++;
375
+ }
376
+ newline_insert++;
377
+ } : may_add_newline;
378
+
379
+ var semicolon = options.beautify ? function() {
380
+ print(";");
381
+ } : function() {
382
+ might_need_semicolon = true;
383
+ };
384
+
385
+ function force_semicolon() {
386
+ if (might_need_semicolon) print(";");
387
+ print(";");
388
+ }
389
+
390
+ function next_indent() {
391
+ return indentation + options.indent_level;
392
+ }
393
+
394
+ function with_block(cont) {
395
+ var ret;
396
+ print("{");
397
+ newline();
398
+ with_indent(next_indent(), function() {
399
+ ret = cont();
400
+ });
401
+ indent();
402
+ print("}");
403
+ return ret;
404
+ }
405
+
406
+ function with_parens(cont) {
407
+ print("(");
408
+ may_add_newline();
409
+ //XXX: still nice to have that for argument lists
410
+ //var ret = with_indent(current_col, cont);
411
+ var ret = cont();
412
+ may_add_newline();
413
+ print(")");
414
+ return ret;
415
+ }
416
+
417
+ function with_square(cont) {
418
+ print("[");
419
+ may_add_newline();
420
+ //var ret = with_indent(current_col, cont);
421
+ var ret = cont();
422
+ may_add_newline();
423
+ print("]");
424
+ return ret;
425
+ }
426
+
427
+ function comma() {
428
+ may_add_newline();
429
+ print(",");
430
+ may_add_newline();
431
+ space();
432
+ }
433
+
434
+ function colon() {
435
+ print(":");
436
+ space();
437
+ }
438
+
439
+ var add_mapping = mappings ? function(token, name) {
440
+ mapping_token = token;
441
+ mapping_name = name;
442
+ } : noop;
443
+
444
+ function get() {
445
+ if (!line_fixed) fix_line();
446
+ return OUTPUT;
447
+ }
448
+
449
+ function has_nlb() {
450
+ var index = OUTPUT.lastIndexOf("\n");
451
+ return /^ *$/.test(OUTPUT.slice(index + 1));
452
+ }
453
+
454
+ function pad_comment(token, force) {
455
+ if (need_newline_indented) return;
456
+ if (token.nlb && (force || !has_nlb())) {
457
+ need_newline_indented = true;
458
+ } else if (force) {
459
+ need_space = true;
460
+ }
461
+ }
462
+
463
+ function print_comment(comment) {
464
+ var value = comment.value.replace(/[@#]__PURE__/g, " ");
465
+ if (/^\s*$/.test(value) && !/^\s*$/.test(comment.value)) return false;
466
+ if (/comment[134]/.test(comment.type)) {
467
+ print("//" + value);
468
+ need_newline_indented = true;
469
+ } else if (comment.type == "comment2") {
470
+ print("/*" + value + "*/");
471
+ }
472
+ return true;
473
+ }
474
+
475
+ function prepend_comments(node) {
476
+ var self = this;
477
+ var scan = node instanceof AST_Exit && node.value;
478
+ var comments = dump(node);
479
+ if (!comments) comments = [];
480
+
481
+ if (scan) {
482
+ var tw = new TreeWalker(function(node) {
483
+ var parent = tw.parent();
484
+ if (parent instanceof AST_Exit
485
+ || parent instanceof AST_Binary && parent.left === node
486
+ || parent.TYPE == "Call" && parent.expression === node
487
+ || parent instanceof AST_Conditional && parent.condition === node
488
+ || parent instanceof AST_Dot && parent.expression === node
489
+ || parent instanceof AST_Sequence && parent.expressions[0] === node
490
+ || parent instanceof AST_Sub && parent.expression === node
491
+ || parent instanceof AST_UnaryPostfix) {
492
+ var before = dump(node);
493
+ if (before) comments = comments.concat(before);
494
+ } else {
495
+ return true;
496
+ }
497
+ });
498
+ tw.push(node);
499
+ node.value.walk(tw);
500
+ }
501
+
502
+ if (current_pos == 0) {
503
+ if (comments.length > 0 && options.shebang && comments[0].type == "comment5") {
504
+ print("#!" + comments.shift().value + "\n");
505
+ indent();
506
+ }
507
+ var preamble = options.preamble;
508
+ if (preamble) {
509
+ print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
510
+ }
511
+ }
512
+
513
+ comments = comments.filter(comment_filter, node);
514
+ var printed = false;
515
+ comments.forEach(function(comment, index) {
516
+ pad_comment(comment, index);
517
+ if (print_comment(comment)) printed = true;
518
+ });
519
+ if (printed) pad_comment(node.start, true);
520
+
521
+ function dump(node) {
522
+ var token = node.start;
523
+ if (!token) {
524
+ if (!scan) return;
525
+ node.start = token = new AST_Token();
526
+ }
527
+ var comments = token.comments_before;
528
+ if (!comments) {
529
+ if (!scan) return;
530
+ token.comments_before = comments = [];
531
+ }
532
+ if (comments._dumped === self) return;
533
+ comments._dumped = self;
534
+ return comments;
535
+ }
536
+ }
537
+
538
+ function append_comments(node, tail) {
539
+ var self = this;
540
+ var token = node.end;
541
+ if (!token) return;
542
+ var comments = token[tail ? "comments_before" : "comments_after"];
543
+ if (!comments || comments._dumped === self) return;
544
+ if (!(node instanceof AST_Statement || all(comments, function(c) {
545
+ return !/comment[134]/.test(c.type);
546
+ }))) return;
547
+ comments._dumped = self;
548
+ var insert = OUTPUT.length;
549
+ comments.filter(comment_filter, node).forEach(function(comment, index) {
550
+ pad_comment(comment, index || !tail);
551
+ print_comment(comment);
552
+ });
553
+ if (OUTPUT.length > insert) newline_insert = insert;
554
+ }
555
+
556
+ var stack = [];
557
+ return {
558
+ get : get,
559
+ toString : get,
560
+ indent : indent,
561
+ should_break : readonly ? noop : function() {
562
+ return options.width && current_col - indentation >= options.width;
563
+ },
564
+ has_parens : function() { return has_parens },
565
+ newline : newline,
566
+ print : print,
567
+ space : space,
568
+ comma : comma,
569
+ colon : colon,
570
+ last : function() { return last },
571
+ semicolon : semicolon,
572
+ force_semicolon : force_semicolon,
573
+ to_utf8 : to_utf8,
574
+ print_name : function(name) { print(make_name(name)) },
575
+ print_string : function(str, quote) { print(encode_string(str, quote)) },
576
+ next_indent : next_indent,
577
+ with_indent : with_indent,
578
+ with_block : with_block,
579
+ with_parens : with_parens,
580
+ with_square : with_square,
581
+ add_mapping : add_mapping,
582
+ option : function(opt) { return options[opt] },
583
+ prepend_comments: readonly ? noop : prepend_comments,
584
+ append_comments : readonly || comment_filter === return_false ? noop : append_comments,
585
+ line : function() { return current_line },
586
+ col : function() { return current_col },
587
+ pos : function() { return current_pos },
588
+ push_node : function(node) { stack.push(node) },
589
+ pop_node : options.preserve_line ? function() {
590
+ var node = stack.pop();
591
+ if (node.start && node.start.line > current_line) {
592
+ insert_newlines(node.start.line - current_line);
593
+ }
594
+ } : function() {
595
+ stack.pop();
596
+ },
597
+ parent : function(n) {
598
+ return stack[stack.length - 2 - (n || 0)];
599
+ },
600
+ };
601
+ }
602
+
603
+ /* -----[ code generators ]----- */
604
+
605
+ (function() {
606
+
607
+ /* -----[ utils ]----- */
608
+
609
+ function DEFPRINT(nodetype, generator) {
610
+ nodetype.DEFMETHOD("_codegen", generator);
611
+ }
612
+
613
+ var use_asm = false;
614
+
615
+ AST_Node.DEFMETHOD("print", function(stream, force_parens) {
616
+ var self = this;
617
+ stream.push_node(self);
618
+ if (force_parens || self.needs_parens(stream)) {
619
+ stream.with_parens(doit);
620
+ } else {
621
+ doit();
622
+ }
623
+ stream.pop_node();
624
+
625
+ function doit() {
626
+ stream.prepend_comments(self);
627
+ self.add_source_map(stream);
628
+ self._codegen(stream);
629
+ stream.append_comments(self);
630
+ }
631
+ });
632
+ AST_Node.DEFMETHOD("print_to_string", function(options) {
633
+ var s = OutputStream(options);
634
+ this.print(s);
635
+ return s.get();
636
+ });
637
+
638
+ /* -----[ PARENTHESES ]----- */
639
+
640
+ function PARENS(nodetype, func) {
641
+ nodetype.DEFMETHOD("needs_parens", func);
642
+ }
643
+
644
+ PARENS(AST_Node, return_false);
645
+
646
+ // a function expression needs parens around it when it's provably
647
+ // the first token to appear in a statement.
648
+ function needs_parens_function(output) {
649
+ var p = output.parent();
650
+ if (!output.has_parens() && first_in_statement(output, false, true)) {
651
+ // export default function() {}
652
+ // export default (function foo() {});
653
+ // export default (function() {})(foo);
654
+ // export default (function() {})`foo`;
655
+ // export default (function() {}) ? foo : bar;
656
+ return this.name || !(p instanceof AST_ExportDefault);
657
+ }
658
+ if (output.option("webkit") && p instanceof AST_PropAccess && p.expression === this) return true;
659
+ if (output.option("wrap_iife") && p instanceof AST_Call && p.expression === this) return true;
660
+ }
661
+ PARENS(AST_AsyncFunction, needs_parens_function);
662
+ PARENS(AST_AsyncGeneratorFunction, needs_parens_function);
663
+ PARENS(AST_ClassExpression, needs_parens_function);
664
+ PARENS(AST_Function, needs_parens_function);
665
+ PARENS(AST_GeneratorFunction, needs_parens_function);
666
+
667
+ // same goes for an object literal, because otherwise it would be
668
+ // interpreted as a block of code.
669
+ function needs_parens_obj(output) {
670
+ return !output.has_parens() && first_in_statement(output, true);
671
+ }
672
+ PARENS(AST_Object, needs_parens_obj);
673
+
674
+ function needs_parens_unary(output) {
675
+ var p = output.parent();
676
+ // (-x) ** y
677
+ if (p instanceof AST_Binary) return p.operator == "**" && p.left === this;
678
+ // (await x)(y)
679
+ // new (await x)
680
+ if (p instanceof AST_Call) return p.expression === this;
681
+ // class extends (x++) {}
682
+ // class x extends (typeof y) {}
683
+ if (p instanceof AST_Class) return true;
684
+ // (x++)[y]
685
+ // (typeof x).y
686
+ if (p instanceof AST_PropAccess) return p.expression === this;
687
+ }
688
+ PARENS(AST_Await, needs_parens_unary);
689
+ PARENS(AST_Unary, needs_parens_unary);
690
+
691
+ PARENS(AST_Sequence, function(output) {
692
+ var p = output.parent();
693
+ // [ 1, (2, 3), 4 ] ---> [ 1, 3, 4 ]
694
+ return p instanceof AST_Array
695
+ // () ---> (foo, bar)
696
+ || is_arrow(p) && p.value === this
697
+ // await (foo, bar)
698
+ || p instanceof AST_Await
699
+ // 1 + (2, 3) + 4 ---> 8
700
+ || p instanceof AST_Binary
701
+ // new (foo, bar) or foo(1, (2, 3), 4)
702
+ || p instanceof AST_Call
703
+ // class extends (foo, bar) {}
704
+ // class foo extends (bar, baz) {}
705
+ || p instanceof AST_Class
706
+ // class { foo = (bar, baz) }
707
+ // class { [(foo, bar)]() {} }
708
+ || p instanceof AST_ClassProperty
709
+ // (false, true) ? (a = 10, b = 20) : (c = 30)
710
+ // ---> 20 (side effect, set a := 10 and b := 20)
711
+ || p instanceof AST_Conditional
712
+ // [ a = (1, 2) ] = [] ---> a == 2
713
+ || p instanceof AST_DefaultValue
714
+ // { [(1, 2)]: foo } = bar
715
+ // { 1: (2, foo) } = bar
716
+ || p instanceof AST_DestructuredKeyVal
717
+ // export default (foo, bar)
718
+ || p instanceof AST_ExportDefault
719
+ // for (foo of (bar, baz));
720
+ || p instanceof AST_ForOf
721
+ // { [(1, 2)]: 3 }[2] ---> 3
722
+ // { foo: (1, 2) }.foo ---> 2
723
+ || p instanceof AST_ObjectProperty
724
+ // (1, {foo:2}).foo or (1, {foo:2})["foo"] ---> 2
725
+ || p instanceof AST_PropAccess && p.expression === this
726
+ // ...(foo, bar, baz)
727
+ || p instanceof AST_Spread
728
+ // (foo, bar)`baz`
729
+ || p instanceof AST_Template && p.tag === this
730
+ // !(foo, bar, baz)
731
+ || p instanceof AST_Unary
732
+ // var a = (1, 2), b = a + a; ---> b == 4
733
+ || p instanceof AST_VarDef
734
+ // yield (foo, bar)
735
+ || p instanceof AST_Yield;
736
+ });
737
+
738
+ PARENS(AST_Binary, function(output) {
739
+ var p = output.parent();
740
+ // await (foo && bar)
741
+ if (p instanceof AST_Await) return true;
742
+ // this deals with precedence:
743
+ // 3 * (2 + 1)
744
+ // 3 - (2 - 1)
745
+ // (1 ** 2) ** 3
746
+ if (p instanceof AST_Binary) {
747
+ var po = p.operator, pp = PRECEDENCE[po];
748
+ var so = this.operator, sp = PRECEDENCE[so];
749
+ return pp > sp
750
+ || po == "??" && (so == "&&" || so == "||")
751
+ || (pp == sp && this === p[po == "**" ? "left" : "right"]);
752
+ }
753
+ // (foo && bar)()
754
+ if (p instanceof AST_Call) return p.expression === this;
755
+ // class extends (foo && bar) {}
756
+ // class foo extends (bar || null) {}
757
+ if (p instanceof AST_Class) return true;
758
+ // (foo && bar)["prop"], (foo && bar).prop
759
+ if (p instanceof AST_PropAccess) return p.expression === this;
760
+ // typeof (foo && bar)
761
+ if (p instanceof AST_Unary) return true;
762
+ });
763
+
764
+ PARENS(AST_PropAccess, function(output) {
765
+ var node = this;
766
+ var p = output.parent();
767
+ if (p instanceof AST_New && p.expression === node) {
768
+ // i.e. new (foo().bar)
769
+ //
770
+ // if there's one call into this subtree, then we need
771
+ // parens around it too, otherwise the call will be
772
+ // interpreted as passing the arguments to the upper New
773
+ // expression.
774
+ do {
775
+ node = node.expression;
776
+ } while (node instanceof AST_PropAccess);
777
+ return node.TYPE == "Call";
778
+ }
779
+ });
780
+
781
+ PARENS(AST_Call, function(output) {
782
+ var p = output.parent();
783
+ if (p instanceof AST_New) return p.expression === this;
784
+ // https://bugs.webkit.org/show_bug.cgi?id=123506
785
+ if (output.option("webkit")) {
786
+ var g = output.parent(1);
787
+ return this.expression instanceof AST_Function
788
+ && p instanceof AST_PropAccess
789
+ && p.expression === this
790
+ && g instanceof AST_Assign
791
+ && g.left === p;
792
+ }
793
+ });
794
+
795
+ PARENS(AST_New, function(output) {
796
+ if (need_constructor_parens(this, output)) return false;
797
+ var p = output.parent();
798
+ // (new foo)(bar)
799
+ if (p instanceof AST_Call) return p.expression === this;
800
+ // (new Date).getTime(), (new Date)["getTime"]()
801
+ if (p instanceof AST_PropAccess) return true;
802
+ // (new foo)`bar`
803
+ if (p instanceof AST_Template) return p.tag === this;
804
+ });
805
+
806
+ PARENS(AST_Number, function(output) {
807
+ if (!output.option("galio")) return false;
808
+ // https://github.com/mishoo/UglifyJS/pull/1009
809
+ var p = output.parent();
810
+ return p instanceof AST_PropAccess && p.expression === this && /^0/.test(make_num(this.value));
811
+ });
812
+
813
+ function needs_parens_assign_cond(self, output) {
814
+ var p = output.parent();
815
+ // await (a = foo)
816
+ if (p instanceof AST_Await) return true;
817
+ // 1 + (a = 2) + 3 → 6, side effect setting a = 2
818
+ if (p instanceof AST_Binary) return !(p instanceof AST_Assign);
819
+ // (a = func)() —or— new (a = Object)()
820
+ if (p instanceof AST_Call) return p.expression === self;
821
+ // class extends (a = foo) {}
822
+ // class foo extends (bar ? baz : moo) {}
823
+ if (p instanceof AST_Class) return true;
824
+ // (a = foo) ? bar : baz
825
+ if (p instanceof AST_Conditional) return p.condition === self;
826
+ // (a = foo)["prop"] —or— (a = foo).prop
827
+ if (p instanceof AST_PropAccess) return p.expression === self;
828
+ // (a = foo)`bar`
829
+ if (p instanceof AST_Template) return p.tag === self;
830
+ // !(a = false) → true
831
+ if (p instanceof AST_Unary) return true;
832
+ }
833
+ PARENS(AST_Arrow, function(output) {
834
+ return needs_parens_assign_cond(this, output);
835
+ });
836
+ PARENS(AST_Assign, function(output) {
837
+ if (needs_parens_assign_cond(this, output)) return true;
838
+ // v8 parser bug ---> workaround
839
+ // f([1], [a] = []) ---> f([1], ([a] = []))
840
+ if (output.option("v8")) return this.left instanceof AST_Destructured;
841
+ // ({ p: a } = o);
842
+ if (this.left instanceof AST_DestructuredObject) return needs_parens_obj(output);
843
+ });
844
+ PARENS(AST_AsyncArrow, function(output) {
845
+ return needs_parens_assign_cond(this, output);
846
+ });
847
+ PARENS(AST_Conditional, function(output) {
848
+ return needs_parens_assign_cond(this, output);
849
+ });
850
+ PARENS(AST_Yield, function(output) {
851
+ return needs_parens_assign_cond(this, output);
852
+ });
853
+
854
+ /* -----[ PRINTERS ]----- */
855
+
856
+ DEFPRINT(AST_Directive, function(output) {
857
+ var quote = this.quote;
858
+ var value = this.value;
859
+ switch (output.option("quote_style")) {
860
+ case 0:
861
+ case 2:
862
+ if (value.indexOf('"') == -1) quote = '"';
863
+ break;
864
+ case 1:
865
+ if (value.indexOf("'") == -1) quote = "'";
866
+ break;
867
+ }
868
+ output.print(quote + value + quote);
869
+ output.semicolon();
870
+ });
871
+ DEFPRINT(AST_Debugger, function(output) {
872
+ output.print("debugger");
873
+ output.semicolon();
874
+ });
875
+
876
+ /* -----[ statements ]----- */
877
+
878
+ function display_body(body, is_toplevel, output, allow_directives) {
879
+ var last = body.length - 1;
880
+ var in_directive = allow_directives;
881
+ var was_asm = use_asm;
882
+ body.forEach(function(stmt, i) {
883
+ if (in_directive) {
884
+ if (stmt instanceof AST_Directive) {
885
+ if (stmt.value == "use asm") use_asm = true;
886
+ } else if (!(stmt instanceof AST_EmptyStatement)) {
887
+ if (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String) {
888
+ output.force_semicolon();
889
+ }
890
+ in_directive = false;
891
+ }
892
+ }
893
+ if (stmt instanceof AST_EmptyStatement) return;
894
+ output.indent();
895
+ stmt.print(output);
896
+ if (i == last && is_toplevel) return;
897
+ output.newline();
898
+ if (is_toplevel) output.newline();
899
+ });
900
+ use_asm = was_asm;
901
+ }
902
+
903
+ DEFPRINT(AST_Toplevel, function(output) {
904
+ display_body(this.body, true, output, true);
905
+ output.print("");
906
+ });
907
+ DEFPRINT(AST_LabeledStatement, function(output) {
908
+ this.label.print(output);
909
+ output.colon();
910
+ this.body.print(output);
911
+ });
912
+ DEFPRINT(AST_SimpleStatement, function(output) {
913
+ this.body.print(output);
914
+ output.semicolon();
915
+ });
916
+ function print_braced_empty(self, output) {
917
+ output.print("{");
918
+ output.with_indent(output.next_indent(), function() {
919
+ output.append_comments(self, true);
920
+ });
921
+ output.print("}");
922
+ }
923
+ function print_braced(self, output, allow_directives) {
924
+ if (self.body.length > 0) {
925
+ output.with_block(function() {
926
+ display_body(self.body, false, output, allow_directives);
927
+ });
928
+ } else print_braced_empty(self, output);
929
+ }
930
+ DEFPRINT(AST_BlockStatement, function(output) {
931
+ print_braced(this, output);
932
+ });
933
+ DEFPRINT(AST_EmptyStatement, function(output) {
934
+ output.semicolon();
935
+ });
936
+ DEFPRINT(AST_Do, function(output) {
937
+ var self = this;
938
+ output.print("do");
939
+ output.space();
940
+ make_block(self.body, output);
941
+ output.space();
942
+ output.print("while");
943
+ output.space();
944
+ output.with_parens(function() {
945
+ self.condition.print(output);
946
+ });
947
+ output.semicolon();
948
+ });
949
+ DEFPRINT(AST_While, function(output) {
950
+ var self = this;
951
+ output.print("while");
952
+ output.space();
953
+ output.with_parens(function() {
954
+ self.condition.print(output);
955
+ });
956
+ output.space();
957
+ force_statement(self.body, output);
958
+ });
959
+ DEFPRINT(AST_For, function(output) {
960
+ var self = this;
961
+ output.print("for");
962
+ output.space();
963
+ output.with_parens(function() {
964
+ if (self.init) {
965
+ if (self.init instanceof AST_Definitions) {
966
+ self.init.print(output);
967
+ } else {
968
+ parenthesize_for_noin(self.init, output, true);
969
+ }
970
+ output.print(";");
971
+ output.space();
972
+ } else {
973
+ output.print(";");
974
+ }
975
+ if (self.condition) {
976
+ self.condition.print(output);
977
+ output.print(";");
978
+ output.space();
979
+ } else {
980
+ output.print(";");
981
+ }
982
+ if (self.step) {
983
+ self.step.print(output);
984
+ }
985
+ });
986
+ output.space();
987
+ force_statement(self.body, output);
988
+ });
989
+ function print_for_enum(prefix, infix) {
990
+ return function(output) {
991
+ var self = this;
992
+ output.print(prefix);
993
+ output.space();
994
+ output.with_parens(function() {
995
+ self.init.print(output);
996
+ output.space();
997
+ output.print(infix);
998
+ output.space();
999
+ self.object.print(output);
1000
+ });
1001
+ output.space();
1002
+ force_statement(self.body, output);
1003
+ };
1004
+ }
1005
+ DEFPRINT(AST_ForAwaitOf, print_for_enum("for await", "of"));
1006
+ DEFPRINT(AST_ForIn, print_for_enum("for", "in"));
1007
+ DEFPRINT(AST_ForOf, print_for_enum("for", "of"));
1008
+ DEFPRINT(AST_With, function(output) {
1009
+ var self = this;
1010
+ output.print("with");
1011
+ output.space();
1012
+ output.with_parens(function() {
1013
+ self.expression.print(output);
1014
+ });
1015
+ output.space();
1016
+ force_statement(self.body, output);
1017
+ });
1018
+ DEFPRINT(AST_ExportDeclaration, function(output) {
1019
+ output.print("export");
1020
+ output.space();
1021
+ this.body.print(output);
1022
+ });
1023
+ DEFPRINT(AST_ExportDefault, function(output) {
1024
+ output.print("export");
1025
+ output.space();
1026
+ output.print("default");
1027
+ output.space();
1028
+ var body = this.body;
1029
+ body.print(output);
1030
+ if (body instanceof AST_ClassExpression) {
1031
+ if (!body.name) return;
1032
+ }
1033
+ if (body instanceof AST_DefClass) return;
1034
+ if (body instanceof AST_LambdaDefinition) return;
1035
+ if (body instanceof AST_LambdaExpression) {
1036
+ if (!body.name && !is_arrow(body)) return;
1037
+ }
1038
+ output.semicolon();
1039
+ });
1040
+ DEFPRINT(AST_ExportForeign, function(output) {
1041
+ var self = this;
1042
+ output.print("export");
1043
+ output.space();
1044
+ var len = self.keys.length;
1045
+ if (len == 0) {
1046
+ print_braced_empty(self, output);
1047
+ } else if (self.keys[0] == "*") {
1048
+ print_entry(0);
1049
+ } else output.with_block(function() {
1050
+ output.indent();
1051
+ print_entry(0);
1052
+ for (var i = 1; i < len; i++) {
1053
+ output.print(",");
1054
+ output.newline();
1055
+ output.indent();
1056
+ print_entry(i);
1057
+ }
1058
+ output.newline();
1059
+ });
1060
+ output.space();
1061
+ output.print("from");
1062
+ output.space();
1063
+ output.print_string(self.path, self.quote);
1064
+ output.semicolon();
1065
+
1066
+ function print_entry(index) {
1067
+ var alias = self.aliases[index];
1068
+ var key = self.keys[index];
1069
+ output.print_name(key);
1070
+ if (alias != key) {
1071
+ output.space();
1072
+ output.print("as");
1073
+ output.space();
1074
+ output.print_name(alias);
1075
+ }
1076
+ }
1077
+ });
1078
+ DEFPRINT(AST_ExportReferences, function(output) {
1079
+ var self = this;
1080
+ output.print("export");
1081
+ output.space();
1082
+ print_properties(self, output);
1083
+ output.semicolon();
1084
+ });
1085
+ DEFPRINT(AST_Import, function(output) {
1086
+ var self = this;
1087
+ output.print("import");
1088
+ output.space();
1089
+ if (self.default) self.default.print(output);
1090
+ if (self.all) {
1091
+ if (self.default) output.comma();
1092
+ self.all.print(output);
1093
+ }
1094
+ if (self.properties) {
1095
+ if (self.default) output.comma();
1096
+ print_properties(self, output);
1097
+ }
1098
+ if (self.all || self.default || self.properties) {
1099
+ output.space();
1100
+ output.print("from");
1101
+ output.space();
1102
+ }
1103
+ output.print_string(self.path, self.quote);
1104
+ output.semicolon();
1105
+ });
1106
+
1107
+ /* -----[ functions ]----- */
1108
+ function print_funargs(self, output) {
1109
+ output.with_parens(function() {
1110
+ self.argnames.forEach(function(arg, i) {
1111
+ if (i) output.comma();
1112
+ arg.print(output);
1113
+ });
1114
+ if (self.rest) {
1115
+ if (self.argnames.length) output.comma();
1116
+ output.print("...");
1117
+ self.rest.print(output);
1118
+ }
1119
+ });
1120
+ }
1121
+ function print_arrow(self, output) {
1122
+ if (self.argnames.length == 1 && self.argnames[0] instanceof AST_SymbolFunarg && !self.rest) {
1123
+ self.argnames[0].print(output);
1124
+ } else {
1125
+ print_funargs(self, output);
1126
+ }
1127
+ output.space();
1128
+ output.print("=>");
1129
+ output.space();
1130
+ if (self.value) {
1131
+ self.value.print(output);
1132
+ } else {
1133
+ print_braced(self, output, true);
1134
+ }
1135
+ }
1136
+ DEFPRINT(AST_Arrow, function(output) {
1137
+ print_arrow(this, output);
1138
+ });
1139
+ DEFPRINT(AST_AsyncArrow, function(output) {
1140
+ output.print("async");
1141
+ output.space();
1142
+ print_arrow(this, output);
1143
+ });
1144
+ function print_lambda(self, output) {
1145
+ if (self.name) {
1146
+ output.space();
1147
+ self.name.print(output);
1148
+ }
1149
+ print_funargs(self, output);
1150
+ output.space();
1151
+ print_braced(self, output, true);
1152
+ }
1153
+ DEFPRINT(AST_Lambda, function(output) {
1154
+ output.print("function");
1155
+ print_lambda(this, output);
1156
+ });
1157
+ function print_async(output) {
1158
+ output.print("async");
1159
+ output.space();
1160
+ output.print("function");
1161
+ print_lambda(this, output);
1162
+ }
1163
+ DEFPRINT(AST_AsyncDefun, print_async);
1164
+ DEFPRINT(AST_AsyncFunction, print_async);
1165
+ function print_async_generator(output) {
1166
+ output.print("async");
1167
+ output.space();
1168
+ output.print("function*");
1169
+ print_lambda(this, output);
1170
+ }
1171
+ DEFPRINT(AST_AsyncGeneratorDefun, print_async_generator);
1172
+ DEFPRINT(AST_AsyncGeneratorFunction, print_async_generator);
1173
+ function print_generator(output) {
1174
+ output.print("function*");
1175
+ print_lambda(this, output);
1176
+ }
1177
+ DEFPRINT(AST_GeneratorDefun, print_generator);
1178
+ DEFPRINT(AST_GeneratorFunction, print_generator);
1179
+
1180
+ /* -----[ classes ]----- */
1181
+ DEFPRINT(AST_Class, function(output) {
1182
+ var self = this;
1183
+ output.print("class");
1184
+ if (self.name) {
1185
+ output.space();
1186
+ self.name.print(output);
1187
+ }
1188
+ if (self.extends) {
1189
+ output.space();
1190
+ output.print("extends");
1191
+ output.space();
1192
+ self.extends.print(output);
1193
+ }
1194
+ output.space();
1195
+ print_properties(self, output, true);
1196
+ });
1197
+ DEFPRINT(AST_ClassField, function(output) {
1198
+ var self = this;
1199
+ if (self.static) {
1200
+ output.print("static");
1201
+ output.space();
1202
+ }
1203
+ print_property_key(self, output);
1204
+ if (self.value) {
1205
+ output.space();
1206
+ output.print("=");
1207
+ output.space();
1208
+ self.value.print(output);
1209
+ }
1210
+ output.semicolon();
1211
+ });
1212
+ DEFPRINT(AST_ClassGetter, print_accessor("get"));
1213
+ DEFPRINT(AST_ClassSetter, print_accessor("set"));
1214
+ function print_method(self, output) {
1215
+ var fn = self.value;
1216
+ if (is_async(fn)) {
1217
+ output.print("async");
1218
+ output.space();
1219
+ }
1220
+ if (is_generator(fn)) output.print("*");
1221
+ print_property_key(self, output);
1222
+ print_lambda(self.value, output);
1223
+ }
1224
+ DEFPRINT(AST_ClassMethod, function(output) {
1225
+ var self = this;
1226
+ if (self.static) {
1227
+ output.print("static");
1228
+ output.space();
1229
+ }
1230
+ print_method(self, output);
1231
+ });
1232
+
1233
+ /* -----[ jumps ]----- */
1234
+ function print_jump(kind, prop) {
1235
+ return function(output) {
1236
+ output.print(kind);
1237
+ var target = this[prop];
1238
+ if (target) {
1239
+ output.space();
1240
+ target.print(output);
1241
+ }
1242
+ output.semicolon();
1243
+ };
1244
+ }
1245
+ DEFPRINT(AST_Return, print_jump("return", "value"));
1246
+ DEFPRINT(AST_Throw, print_jump("throw", "value"));
1247
+ DEFPRINT(AST_Break, print_jump("break", "label"));
1248
+ DEFPRINT(AST_Continue, print_jump("continue", "label"));
1249
+
1250
+ /* -----[ if ]----- */
1251
+ function make_then(self, output) {
1252
+ var b = self.body;
1253
+ if (output.option("braces") && !(b instanceof AST_Const || b instanceof AST_Let)
1254
+ || output.option("ie8") && b instanceof AST_Do)
1255
+ return make_block(b, output);
1256
+ // The squeezer replaces "block"-s that contain only a single
1257
+ // statement with the statement itself; technically, the AST
1258
+ // is correct, but this can create problems when we output an
1259
+ // IF having an ELSE clause where the THEN clause ends in an
1260
+ // IF *without* an ELSE block (then the outer ELSE would refer
1261
+ // to the inner IF). This function checks for this case and
1262
+ // adds the block braces if needed.
1263
+ if (!b) return output.force_semicolon();
1264
+ while (true) {
1265
+ if (b instanceof AST_If) {
1266
+ if (!b.alternative) {
1267
+ make_block(self.body, output);
1268
+ return;
1269
+ }
1270
+ b = b.alternative;
1271
+ } else if (b instanceof AST_StatementWithBody) {
1272
+ b = b.body;
1273
+ } else break;
1274
+ }
1275
+ force_statement(self.body, output);
1276
+ }
1277
+ DEFPRINT(AST_If, function(output) {
1278
+ var self = this;
1279
+ output.print("if");
1280
+ output.space();
1281
+ output.with_parens(function() {
1282
+ self.condition.print(output);
1283
+ });
1284
+ output.space();
1285
+ if (self.alternative) {
1286
+ make_then(self, output);
1287
+ output.space();
1288
+ output.print("else");
1289
+ output.space();
1290
+ if (self.alternative instanceof AST_If)
1291
+ self.alternative.print(output);
1292
+ else
1293
+ force_statement(self.alternative, output);
1294
+ } else {
1295
+ force_statement(self.body, output);
1296
+ }
1297
+ });
1298
+
1299
+ /* -----[ switch ]----- */
1300
+ DEFPRINT(AST_Switch, function(output) {
1301
+ var self = this;
1302
+ output.print("switch");
1303
+ output.space();
1304
+ output.with_parens(function() {
1305
+ self.expression.print(output);
1306
+ });
1307
+ output.space();
1308
+ var last = self.body.length - 1;
1309
+ if (last < 0) print_braced_empty(self, output);
1310
+ else output.with_block(function() {
1311
+ self.body.forEach(function(branch, i) {
1312
+ output.indent(true);
1313
+ branch.print(output);
1314
+ if (i < last && branch.body.length > 0)
1315
+ output.newline();
1316
+ });
1317
+ });
1318
+ });
1319
+ function print_branch_body(self, output) {
1320
+ output.newline();
1321
+ self.body.forEach(function(stmt) {
1322
+ output.indent();
1323
+ stmt.print(output);
1324
+ output.newline();
1325
+ });
1326
+ }
1327
+ DEFPRINT(AST_Default, function(output) {
1328
+ output.print("default:");
1329
+ print_branch_body(this, output);
1330
+ });
1331
+ DEFPRINT(AST_Case, function(output) {
1332
+ var self = this;
1333
+ output.print("case");
1334
+ output.space();
1335
+ self.expression.print(output);
1336
+ output.print(":");
1337
+ print_branch_body(self, output);
1338
+ });
1339
+
1340
+ /* -----[ exceptions ]----- */
1341
+ DEFPRINT(AST_Try, function(output) {
1342
+ var self = this;
1343
+ output.print("try");
1344
+ output.space();
1345
+ print_braced(self, output);
1346
+ if (self.bcatch) {
1347
+ output.space();
1348
+ self.bcatch.print(output);
1349
+ }
1350
+ if (self.bfinally) {
1351
+ output.space();
1352
+ self.bfinally.print(output);
1353
+ }
1354
+ });
1355
+ DEFPRINT(AST_Catch, function(output) {
1356
+ var self = this;
1357
+ output.print("catch");
1358
+ if (self.argname) {
1359
+ output.space();
1360
+ output.with_parens(function() {
1361
+ self.argname.print(output);
1362
+ });
1363
+ }
1364
+ output.space();
1365
+ print_braced(self, output);
1366
+ });
1367
+ DEFPRINT(AST_Finally, function(output) {
1368
+ output.print("finally");
1369
+ output.space();
1370
+ print_braced(this, output);
1371
+ });
1372
+
1373
+ function print_definitinos(type) {
1374
+ return function(output) {
1375
+ var self = this;
1376
+ output.print(type);
1377
+ output.space();
1378
+ self.definitions.forEach(function(def, i) {
1379
+ if (i) output.comma();
1380
+ def.print(output);
1381
+ });
1382
+ var p = output.parent();
1383
+ if (!(p instanceof AST_IterationStatement && p.init === self)) output.semicolon();
1384
+ };
1385
+ }
1386
+ DEFPRINT(AST_Const, print_definitinos("const"));
1387
+ DEFPRINT(AST_Let, print_definitinos("let"));
1388
+ DEFPRINT(AST_Var, print_definitinos("var"));
1389
+
1390
+ function parenthesize_for_noin(node, output, noin) {
1391
+ var parens = false;
1392
+ // need to take some precautions here:
1393
+ // https://github.com/mishoo/UglifyJS/issues/60
1394
+ if (noin) node.walk(new TreeWalker(function(node) {
1395
+ if (parens) return true;
1396
+ if (node instanceof AST_Binary && node.operator == "in") return parens = true;
1397
+ if (node instanceof AST_Scope && !(is_arrow(node) && node.value)) return true;
1398
+ }));
1399
+ node.print(output, parens);
1400
+ }
1401
+
1402
+ DEFPRINT(AST_VarDef, function(output) {
1403
+ var self = this;
1404
+ self.name.print(output);
1405
+ if (self.value) {
1406
+ output.space();
1407
+ output.print("=");
1408
+ output.space();
1409
+ var p = output.parent(1);
1410
+ var noin = p instanceof AST_For || p instanceof AST_ForEnumeration;
1411
+ parenthesize_for_noin(self.value, output, noin);
1412
+ }
1413
+ });
1414
+
1415
+ DEFPRINT(AST_DefaultValue, function(output) {
1416
+ var self = this;
1417
+ self.name.print(output);
1418
+ output.space();
1419
+ output.print("=");
1420
+ output.space();
1421
+ self.value.print(output);
1422
+ });
1423
+
1424
+ /* -----[ other expressions ]----- */
1425
+ function print_annotation(self, output) {
1426
+ if (!output.option("annotations")) return;
1427
+ if (!self.pure) return;
1428
+ var level = 0, parent = self, node;
1429
+ do {
1430
+ node = parent;
1431
+ parent = output.parent(level++);
1432
+ if (parent instanceof AST_Call && parent.expression === node) return;
1433
+ } while (parent instanceof AST_PropAccess && parent.expression === node);
1434
+ output.print("/*" + self.pure + "*/");
1435
+ }
1436
+ function print_call_args(self, output) {
1437
+ if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
1438
+ output.add_mapping(self.start);
1439
+ }
1440
+ output.with_parens(function() {
1441
+ self.args.forEach(function(expr, i) {
1442
+ if (i) output.comma();
1443
+ expr.print(output);
1444
+ });
1445
+ });
1446
+ }
1447
+ DEFPRINT(AST_Call, function(output) {
1448
+ var self = this;
1449
+ print_annotation(self, output);
1450
+ self.expression.print(output);
1451
+ print_call_args(self, output);
1452
+ });
1453
+ DEFPRINT(AST_New, function(output) {
1454
+ var self = this;
1455
+ print_annotation(self, output);
1456
+ output.print("new");
1457
+ output.space();
1458
+ self.expression.print(output);
1459
+ if (need_constructor_parens(self, output)) print_call_args(self, output);
1460
+ });
1461
+ DEFPRINT(AST_Sequence, function(output) {
1462
+ this.expressions.forEach(function(node, index) {
1463
+ if (index > 0) {
1464
+ output.comma();
1465
+ if (output.should_break()) {
1466
+ output.newline();
1467
+ output.indent();
1468
+ }
1469
+ }
1470
+ node.print(output);
1471
+ });
1472
+ });
1473
+ DEFPRINT(AST_Dot, function(output) {
1474
+ var self = this;
1475
+ var expr = self.expression;
1476
+ expr.print(output);
1477
+ var prop = self.property;
1478
+ if (output.option("ie8") && RESERVED_WORDS[prop]) {
1479
+ output.print("[");
1480
+ output.add_mapping(self.end);
1481
+ output.print_string(prop);
1482
+ output.print("]");
1483
+ } else {
1484
+ if (expr instanceof AST_Number && expr.value >= 0) {
1485
+ if (!/[xa-f.)]/i.test(output.last())) {
1486
+ output.print(".");
1487
+ }
1488
+ }
1489
+ output.print(".");
1490
+ // the name after dot would be mapped about here.
1491
+ output.add_mapping(self.end);
1492
+ output.print_name(prop);
1493
+ }
1494
+ });
1495
+ DEFPRINT(AST_Sub, function(output) {
1496
+ this.expression.print(output);
1497
+ output.print("[");
1498
+ this.property.print(output);
1499
+ output.print("]");
1500
+ });
1501
+ DEFPRINT(AST_Spread, function(output) {
1502
+ output.print("...");
1503
+ this.expression.print(output);
1504
+ });
1505
+ DEFPRINT(AST_UnaryPrefix, function(output) {
1506
+ var op = this.operator;
1507
+ var exp = this.expression;
1508
+ output.print(op);
1509
+ if (/^[a-z]/i.test(op)
1510
+ || (/[+-]$/.test(op)
1511
+ && exp instanceof AST_UnaryPrefix
1512
+ && /^[+-]/.test(exp.operator))) {
1513
+ output.space();
1514
+ }
1515
+ exp.print(output);
1516
+ });
1517
+ DEFPRINT(AST_UnaryPostfix, function(output) {
1518
+ this.expression.print(output);
1519
+ output.print(this.operator);
1520
+ });
1521
+ DEFPRINT(AST_Binary, function(output) {
1522
+ var self = this;
1523
+ self.left.print(output);
1524
+ output.space();
1525
+ output.print(self.operator);
1526
+ output.space();
1527
+ self.right.print(output);
1528
+ });
1529
+ DEFPRINT(AST_Conditional, function(output) {
1530
+ var self = this;
1531
+ self.condition.print(output);
1532
+ output.space();
1533
+ output.print("?");
1534
+ output.space();
1535
+ self.consequent.print(output);
1536
+ output.space();
1537
+ output.colon();
1538
+ self.alternative.print(output);
1539
+ });
1540
+ DEFPRINT(AST_Await, function(output) {
1541
+ output.print("await");
1542
+ output.space();
1543
+ this.expression.print(output);
1544
+ });
1545
+ DEFPRINT(AST_Yield, function(output) {
1546
+ output.print(this.nested ? "yield*" : "yield");
1547
+ if (this.expression) {
1548
+ output.space();
1549
+ this.expression.print(output);
1550
+ }
1551
+ });
1552
+
1553
+ /* -----[ literals ]----- */
1554
+ DEFPRINT(AST_Array, function(output) {
1555
+ var a = this.elements, len = a.length;
1556
+ output.with_square(len > 0 ? function() {
1557
+ output.space();
1558
+ a.forEach(function(exp, i) {
1559
+ if (i) output.comma();
1560
+ exp.print(output);
1561
+ // If the final element is a hole, we need to make sure it
1562
+ // doesn't look like a trailing comma, by inserting an actual
1563
+ // trailing comma.
1564
+ if (i === len - 1 && exp instanceof AST_Hole)
1565
+ output.comma();
1566
+ });
1567
+ output.space();
1568
+ } : noop);
1569
+ });
1570
+ DEFPRINT(AST_DestructuredArray, function(output) {
1571
+ var a = this.elements, len = a.length, rest = this.rest;
1572
+ output.with_square(len || rest ? function() {
1573
+ output.space();
1574
+ a.forEach(function(exp, i) {
1575
+ if (i) output.comma();
1576
+ exp.print(output);
1577
+ });
1578
+ if (rest) {
1579
+ if (len) output.comma();
1580
+ output.print("...");
1581
+ rest.print(output);
1582
+ } else if (a[len - 1] instanceof AST_Hole) {
1583
+ // If the final element is a hole, we need to make sure it
1584
+ // doesn't look like a trailing comma, by inserting an actual
1585
+ // trailing comma.
1586
+ output.comma();
1587
+ }
1588
+ output.space();
1589
+ } : noop);
1590
+ });
1591
+ DEFPRINT(AST_DestructuredKeyVal, function(output) {
1592
+ var self = this;
1593
+ var key = print_property_key(self, output);
1594
+ var value = self.value;
1595
+ if (key && value instanceof AST_SymbolDeclaration && key == get_symbol_name(value)) return;
1596
+ output.colon();
1597
+ value.print(output);
1598
+ });
1599
+ DEFPRINT(AST_DestructuredObject, function(output) {
1600
+ var props = this.properties, len = props.length, rest = this.rest;
1601
+ if (len || rest) output.with_block(function() {
1602
+ props.forEach(function(prop, i) {
1603
+ if (i) {
1604
+ output.print(",");
1605
+ output.newline();
1606
+ }
1607
+ output.indent();
1608
+ prop.print(output);
1609
+ });
1610
+ if (rest) {
1611
+ if (len) {
1612
+ output.print(",");
1613
+ output.newline();
1614
+ }
1615
+ output.indent();
1616
+ output.print("...");
1617
+ rest.print(output);
1618
+ }
1619
+ output.newline();
1620
+ });
1621
+ else print_braced_empty(this, output);
1622
+ });
1623
+ function print_properties(self, output, no_comma) {
1624
+ var props = self.properties;
1625
+ if (props.length > 0) output.with_block(function() {
1626
+ props.forEach(function(prop, i) {
1627
+ if (i) {
1628
+ if (!no_comma) output.print(",");
1629
+ output.newline();
1630
+ }
1631
+ output.indent();
1632
+ prop.print(output);
1633
+ });
1634
+ output.newline();
1635
+ });
1636
+ else print_braced_empty(self, output);
1637
+ }
1638
+ DEFPRINT(AST_Object, function(output) {
1639
+ print_properties(this, output);
1640
+ });
1641
+
1642
+ function print_property_key(self, output) {
1643
+ var key = self.key;
1644
+ if (key instanceof AST_Node) {
1645
+ output.with_square(function() {
1646
+ key.print(output);
1647
+ });
1648
+ } else if (output.option("quote_keys")) {
1649
+ output.print_string(key);
1650
+ } else if ("" + +key == key && key >= 0) {
1651
+ output.print(make_num(key));
1652
+ } else {
1653
+ var quote = self.start && self.start.quote;
1654
+ if (self.private) {
1655
+ output.print_name(key);
1656
+ } else if (RESERVED_WORDS[key] ? !output.option("ie8") : is_identifier_string(key)) {
1657
+ if (quote && output.option("keep_quoted_props")) {
1658
+ output.print_string(key, quote);
1659
+ } else {
1660
+ output.print_name(key);
1661
+ return key;
1662
+ }
1663
+ } else {
1664
+ output.print_string(key, quote);
1665
+ }
1666
+ }
1667
+ }
1668
+ DEFPRINT(AST_ObjectKeyVal, function(output) {
1669
+ var self = this;
1670
+ print_property_key(self, output);
1671
+ output.colon();
1672
+ self.value.print(output);
1673
+ });
1674
+ DEFPRINT(AST_ObjectMethod, function(output) {
1675
+ print_method(this, output);
1676
+ });
1677
+ function print_accessor(type) {
1678
+ return function(output) {
1679
+ var self = this;
1680
+ if (self.static) {
1681
+ output.print("static");
1682
+ output.space();
1683
+ }
1684
+ output.print(type);
1685
+ output.space();
1686
+ print_property_key(self, output);
1687
+ print_lambda(self.value, output);
1688
+ };
1689
+ }
1690
+ DEFPRINT(AST_ObjectGetter, print_accessor("get"));
1691
+ DEFPRINT(AST_ObjectSetter, print_accessor("set"));
1692
+ function get_symbol_name(sym) {
1693
+ var def = sym.definition();
1694
+ return def && def.mangled_name || sym.name;
1695
+ }
1696
+ DEFPRINT(AST_Symbol, function(output) {
1697
+ output.print_name(get_symbol_name(this));
1698
+ });
1699
+ DEFPRINT(AST_SymbolExport, function(output) {
1700
+ var self = this;
1701
+ var name = get_symbol_name(self);
1702
+ output.print_name(name);
1703
+ var alias = self.alias;
1704
+ if (alias != name) {
1705
+ output.space();
1706
+ output.print("as");
1707
+ output.space();
1708
+ output.print_name(alias);
1709
+ }
1710
+ });
1711
+ DEFPRINT(AST_SymbolImport, function(output) {
1712
+ var self = this;
1713
+ var name = get_symbol_name(self);
1714
+ var key = self.key;
1715
+ if (key && key != name) {
1716
+ output.print_name(key);
1717
+ output.space();
1718
+ output.print("as");
1719
+ output.space();
1720
+ }
1721
+ output.print_name(name);
1722
+ });
1723
+ DEFPRINT(AST_Hole, noop);
1724
+ DEFPRINT(AST_Template, function(output) {
1725
+ var self = this;
1726
+ if (self.tag) self.tag.print(output);
1727
+ output.print("`");
1728
+ for (var i = 0; i < self.expressions.length; i++) {
1729
+ output.print(self.strings[i]);
1730
+ output.print("${");
1731
+ self.expressions[i].print(output);
1732
+ output.print("}");
1733
+ }
1734
+ output.print(self.strings[i]);
1735
+ output.print("`");
1736
+ });
1737
+ DEFPRINT(AST_Constant, function(output) {
1738
+ output.print(this.value);
1739
+ });
1740
+ DEFPRINT(AST_String, function(output) {
1741
+ output.print_string(this.value, this.quote);
1742
+ });
1743
+ DEFPRINT(AST_Number, function(output) {
1744
+ var start = this.start;
1745
+ if (use_asm && start && start.raw != null) {
1746
+ output.print(start.raw);
1747
+ } else {
1748
+ output.print(make_num(this.value));
1749
+ }
1750
+ });
1751
+
1752
+ DEFPRINT(AST_RegExp, function(output) {
1753
+ var regexp = this.value;
1754
+ var str = regexp.toString();
1755
+ var end = str.lastIndexOf("/");
1756
+ if (regexp.raw_source) {
1757
+ str = "/" + regexp.raw_source + str.slice(end);
1758
+ } else if (end == 1) {
1759
+ str = "/(?:)" + str.slice(end);
1760
+ } else if (str.indexOf("/", 1) < end) {
1761
+ str = "/" + str.slice(1, end).replace(/\\\\|[^/]?\//g, function(match) {
1762
+ return match[0] == "\\" ? match : match.slice(0, -1) + "\\/";
1763
+ }) + str.slice(end);
1764
+ }
1765
+ output.print(output.to_utf8(str).replace(/\\(?:\0(?![0-9])|[^\0])/g, function(match) {
1766
+ switch (match[1]) {
1767
+ case "\n": return "\\n";
1768
+ case "\r": return "\\r";
1769
+ case "\t": return "\t";
1770
+ case "\b": return "\b";
1771
+ case "\f": return "\f";
1772
+ case "\0": return "\0";
1773
+ case "\x0B": return "\v";
1774
+ case "\u2028": return "\\u2028";
1775
+ case "\u2029": return "\\u2029";
1776
+ default: return match;
1777
+ }
1778
+ }).replace(/[\n\r\u2028\u2029]/g, function(c) {
1779
+ switch (c) {
1780
+ case "\n": return "\\n";
1781
+ case "\r": return "\\r";
1782
+ case "\u2028": return "\\u2028";
1783
+ case "\u2029": return "\\u2029";
1784
+ }
1785
+ }));
1786
+ var p = output.parent();
1787
+ if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === this)
1788
+ output.print(" ");
1789
+ });
1790
+
1791
+ function force_statement(stat, output) {
1792
+ if (output.option("braces") && !(stat instanceof AST_Const || stat instanceof AST_Let)) {
1793
+ make_block(stat, output);
1794
+ } else if (!stat || stat instanceof AST_EmptyStatement) {
1795
+ output.force_semicolon();
1796
+ } else {
1797
+ stat.print(output);
1798
+ }
1799
+ }
1800
+
1801
+ // self should be AST_New. decide if we want to show parens or not.
1802
+ function need_constructor_parens(self, output) {
1803
+ // Always print parentheses with arguments
1804
+ if (self.args.length > 0) return true;
1805
+
1806
+ return output.option("beautify");
1807
+ }
1808
+
1809
+ function best_of(a) {
1810
+ var best = a[0], len = best.length;
1811
+ for (var i = 1; i < a.length; ++i) {
1812
+ if (a[i].length < len) {
1813
+ best = a[i];
1814
+ len = best.length;
1815
+ }
1816
+ }
1817
+ return best;
1818
+ }
1819
+
1820
+ function make_num(num) {
1821
+ var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e");
1822
+ var candidates = [ str ];
1823
+ if (Math.floor(num) === num) {
1824
+ if (num < 0) {
1825
+ candidates.push("-0x" + (-num).toString(16).toLowerCase());
1826
+ } else {
1827
+ candidates.push("0x" + num.toString(16).toLowerCase());
1828
+ }
1829
+ }
1830
+ var match, len, digits;
1831
+ if (match = /^\.0+/.exec(str)) {
1832
+ len = match[0].length;
1833
+ digits = str.slice(len);
1834
+ candidates.push(digits + "e-" + (digits.length + len - 1));
1835
+ } else if (match = /0+$/.exec(str)) {
1836
+ len = match[0].length;
1837
+ candidates.push(str.slice(0, -len) + "e" + len);
1838
+ } else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) {
1839
+ candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length));
1840
+ }
1841
+ return best_of(candidates);
1842
+ }
1843
+
1844
+ function make_block(stmt, output) {
1845
+ if (!stmt || stmt instanceof AST_EmptyStatement)
1846
+ output.print("{}");
1847
+ else if (stmt instanceof AST_BlockStatement)
1848
+ stmt.print(output);
1849
+ else output.with_block(function() {
1850
+ output.indent();
1851
+ stmt.print(output);
1852
+ output.newline();
1853
+ });
1854
+ }
1855
+
1856
+ /* -----[ source map generators ]----- */
1857
+
1858
+ function DEFMAP(nodetype, generator) {
1859
+ nodetype.forEach(function(nodetype) {
1860
+ nodetype.DEFMETHOD("add_source_map", generator);
1861
+ });
1862
+ }
1863
+
1864
+ DEFMAP([
1865
+ // We could easily add info for ALL nodes, but it seems to me that
1866
+ // would be quite wasteful, hence this noop in the base class.
1867
+ AST_Node,
1868
+ // since the label symbol will mark it
1869
+ AST_LabeledStatement,
1870
+ ], noop);
1871
+
1872
+ // XXX: I'm not exactly sure if we need it for all of these nodes,
1873
+ // or if we should add even more.
1874
+ DEFMAP([
1875
+ AST_Array,
1876
+ AST_BlockStatement,
1877
+ AST_Catch,
1878
+ AST_Constant,
1879
+ AST_Debugger,
1880
+ AST_Definitions,
1881
+ AST_Destructured,
1882
+ AST_Finally,
1883
+ AST_Jump,
1884
+ AST_Lambda,
1885
+ AST_New,
1886
+ AST_Object,
1887
+ AST_StatementWithBody,
1888
+ AST_Symbol,
1889
+ AST_Switch,
1890
+ AST_SwitchBranch,
1891
+ AST_Try,
1892
+ ], function(output) {
1893
+ output.add_mapping(this.start);
1894
+ });
1895
+
1896
+ DEFMAP([ AST_DestructuredKeyVal, AST_ObjectProperty ], function(output) {
1897
+ if (typeof this.key == "string") output.add_mapping(this.start, this.key);
1898
+ });
1899
+ })();