terser 5.3.7 → 5.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +9 -2
- package/dist/bundle.min.js +307 -136
- package/lib/ast.js +55 -6
- package/lib/compress/index.js +140 -34
- package/lib/mozilla-ast.js +24 -39
- package/lib/output.js +19 -7
- package/lib/parse.js +71 -51
- package/package.json +11 -12
- package/dist/bundle.min.js.map +0 -1
package/lib/ast.js
CHANGED
@@ -93,8 +93,54 @@ function DEFNODE(type, props, methods, base = AST_Node) {
|
|
93
93
|
return ctor;
|
94
94
|
}
|
95
95
|
|
96
|
-
|
97
|
-
|
96
|
+
const has_tok_flag = (tok, flag) => Boolean(tok.flags & flag);
|
97
|
+
const set_tok_flag = (tok, flag, truth) => {
|
98
|
+
if (truth) {
|
99
|
+
tok.flags |= flag;
|
100
|
+
} else {
|
101
|
+
tok.flags &= ~flag;
|
102
|
+
}
|
103
|
+
};
|
104
|
+
|
105
|
+
const TOK_FLAG_NLB = 0b0001;
|
106
|
+
const TOK_FLAG_QUOTE_SINGLE = 0b0010;
|
107
|
+
const TOK_FLAG_QUOTE_EXISTS = 0b0100;
|
108
|
+
|
109
|
+
class AST_Token {
|
110
|
+
constructor(type, value, line, col, pos, nlb, comments_before, comments_after, file) {
|
111
|
+
this.flags = (nlb ? 1 : 0);
|
112
|
+
|
113
|
+
this.type = type;
|
114
|
+
this.value = value;
|
115
|
+
this.line = line;
|
116
|
+
this.col = col;
|
117
|
+
this.pos = pos;
|
118
|
+
this.comments_before = comments_before;
|
119
|
+
this.comments_after = comments_after;
|
120
|
+
this.file = file;
|
121
|
+
|
122
|
+
Object.seal(this);
|
123
|
+
}
|
124
|
+
|
125
|
+
get nlb() {
|
126
|
+
return has_tok_flag(this, TOK_FLAG_NLB);
|
127
|
+
}
|
128
|
+
|
129
|
+
set nlb(new_nlb) {
|
130
|
+
set_tok_flag(this, TOK_FLAG_NLB, new_nlb);
|
131
|
+
}
|
132
|
+
|
133
|
+
get quote() {
|
134
|
+
return !has_tok_flag(this, TOK_FLAG_QUOTE_EXISTS)
|
135
|
+
? ""
|
136
|
+
: (has_tok_flag(this, TOK_FLAG_QUOTE_SINGLE) ? "'" : '"');
|
137
|
+
}
|
138
|
+
|
139
|
+
set quote(quote_type) {
|
140
|
+
set_tok_flag(this, TOK_FLAG_QUOTE_SINGLE, quote_type === "'");
|
141
|
+
set_tok_flag(this, TOK_FLAG_QUOTE_EXISTS, !!quote_type);
|
142
|
+
}
|
143
|
+
}
|
98
144
|
|
99
145
|
var AST_Node = DEFNODE("Node", "start end", {
|
100
146
|
_clone: function(deep) {
|
@@ -563,7 +609,7 @@ var AST_TemplateSegment = DEFNODE("TemplateSegment", "value raw", {
|
|
563
609
|
$documentation: "A segment of a template string literal",
|
564
610
|
$propdoc: {
|
565
611
|
value: "Content of the segment",
|
566
|
-
raw: "Raw
|
612
|
+
raw: "Raw source of the segment",
|
567
613
|
}
|
568
614
|
});
|
569
615
|
|
@@ -1075,8 +1121,11 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
|
1075
1121
|
},
|
1076
1122
|
});
|
1077
1123
|
|
1078
|
-
var AST_Assign = DEFNODE("Assign",
|
1124
|
+
var AST_Assign = DEFNODE("Assign", "logical", {
|
1079
1125
|
$documentation: "An assignment expression — `a = b + 5`",
|
1126
|
+
$propdoc: {
|
1127
|
+
logical: "Whether it's a logical assignment"
|
1128
|
+
}
|
1080
1129
|
}, AST_Binary);
|
1081
1130
|
|
1082
1131
|
var AST_DefaultAssign = DEFNODE("DefaultAssign", null, {
|
@@ -1367,11 +1416,11 @@ var AST_String = DEFNODE("String", "value quote", {
|
|
1367
1416
|
}
|
1368
1417
|
}, AST_Constant);
|
1369
1418
|
|
1370
|
-
var AST_Number = DEFNODE("Number", "value
|
1419
|
+
var AST_Number = DEFNODE("Number", "value raw", {
|
1371
1420
|
$documentation: "A number literal",
|
1372
1421
|
$propdoc: {
|
1373
1422
|
value: "[number] the numeric value",
|
1374
|
-
|
1423
|
+
raw: "[string] numeric value as string"
|
1375
1424
|
}
|
1376
1425
|
}, AST_Constant);
|
1377
1426
|
|
package/lib/compress/index.js
CHANGED
@@ -528,6 +528,7 @@ AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) {
|
|
528
528
|
function read_property(obj, key) {
|
529
529
|
key = get_value(key);
|
530
530
|
if (key instanceof AST_Node) return;
|
531
|
+
|
531
532
|
var value;
|
532
533
|
if (obj instanceof AST_Array) {
|
533
534
|
var elements = obj.elements;
|
@@ -542,6 +543,7 @@ function read_property(obj, key) {
|
|
542
543
|
if (!value && props[i].key === key) value = props[i].value;
|
543
544
|
}
|
544
545
|
}
|
546
|
+
|
545
547
|
return value instanceof AST_SymbolRef && value.fixed_value() || value;
|
546
548
|
}
|
547
549
|
|
@@ -674,38 +676,56 @@ function is_modified(compressor, tw, node, value, level, immutable) {
|
|
674
676
|
|| value instanceof AST_This;
|
675
677
|
}
|
676
678
|
|
677
|
-
|
679
|
+
// A definition "escapes" when its value can leave the point of use.
|
680
|
+
// Example: `a = b || c`
|
681
|
+
// In this example, "b" and "c" are escaping, because they're going into "a"
|
682
|
+
//
|
683
|
+
// def.escaped is != 0 when it escapes.
|
684
|
+
//
|
685
|
+
// When greater than 1, it means that N chained properties will be read off
|
686
|
+
// of that def before an escape occurs. This is useful for evaluating
|
687
|
+
// property accesses, where you need to know when to stop.
|
688
|
+
function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) {
|
678
689
|
var parent = tw.parent(level);
|
679
690
|
if (value) {
|
680
691
|
if (value.is_constant()) return;
|
681
692
|
if (value instanceof AST_ClassExpression) return;
|
682
693
|
}
|
683
|
-
|
694
|
+
|
695
|
+
if (
|
696
|
+
parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right
|
684
697
|
|| parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
|
685
698
|
|| parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
|
686
699
|
|| parent instanceof AST_VarDef && node === parent.value
|
687
|
-
|| parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope
|
700
|
+
|| parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope
|
701
|
+
) {
|
688
702
|
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
|
689
703
|
if (!d.escaped || d.escaped > depth) d.escaped = depth;
|
690
704
|
return;
|
691
|
-
} else if (
|
705
|
+
} else if (
|
706
|
+
parent instanceof AST_Array
|
692
707
|
|| parent instanceof AST_Await
|
693
708
|
|| parent instanceof AST_Binary && lazy_op.has(parent.operator)
|
694
709
|
|| parent instanceof AST_Conditional && node !== parent.condition
|
695
710
|
|| parent instanceof AST_Expansion
|
696
|
-
|| parent instanceof AST_Sequence && node === parent.tail_node()
|
711
|
+
|| parent instanceof AST_Sequence && node === parent.tail_node()
|
712
|
+
) {
|
697
713
|
mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
|
698
714
|
} else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
|
699
715
|
var obj = tw.parent(level + 1);
|
716
|
+
|
700
717
|
mark_escaped(tw, d, scope, obj, obj, level + 2, depth);
|
701
718
|
} else if (parent instanceof AST_PropAccess && node === parent.expression) {
|
702
719
|
value = read_property(value, parent.property);
|
720
|
+
|
703
721
|
mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1);
|
704
722
|
if (value) return;
|
705
723
|
}
|
724
|
+
|
706
725
|
if (level > 0) return;
|
707
726
|
if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
|
708
727
|
if (parent instanceof AST_SimpleStatement) return;
|
728
|
+
|
709
729
|
d.direct_access = true;
|
710
730
|
}
|
711
731
|
|
@@ -729,32 +749,64 @@ function is_modified(compressor, tw, node, value, level, immutable) {
|
|
729
749
|
suppress(node.left);
|
730
750
|
return;
|
731
751
|
}
|
752
|
+
|
753
|
+
const finish_walk = () => {
|
754
|
+
if (node.logical) {
|
755
|
+
node.left.walk(tw);
|
756
|
+
|
757
|
+
push(tw);
|
758
|
+
node.right.walk(tw);
|
759
|
+
pop(tw);
|
760
|
+
|
761
|
+
return true;
|
762
|
+
}
|
763
|
+
};
|
764
|
+
|
732
765
|
var sym = node.left;
|
733
|
-
if (!(sym instanceof AST_SymbolRef)) return;
|
766
|
+
if (!(sym instanceof AST_SymbolRef)) return finish_walk();
|
767
|
+
|
734
768
|
var def = sym.definition();
|
735
769
|
var safe = safe_to_assign(tw, def, sym.scope, node.right);
|
736
770
|
def.assignments++;
|
737
|
-
if (!safe) return;
|
771
|
+
if (!safe) return finish_walk();
|
772
|
+
|
738
773
|
var fixed = def.fixed;
|
739
|
-
if (!fixed && node.operator != "=") return;
|
774
|
+
if (!fixed && node.operator != "=" && !node.logical) return finish_walk();
|
775
|
+
|
740
776
|
var eq = node.operator == "=";
|
741
777
|
var value = eq ? node.right : node;
|
742
|
-
if (is_modified(compressor, tw, node, value, 0)) return;
|
778
|
+
if (is_modified(compressor, tw, node, value, 0)) return finish_walk();
|
779
|
+
|
743
780
|
def.references.push(sym);
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
781
|
+
|
782
|
+
if (!node.logical) {
|
783
|
+
if (!eq) def.chained = true;
|
784
|
+
|
785
|
+
def.fixed = eq ? function() {
|
786
|
+
return node.right;
|
787
|
+
} : function() {
|
788
|
+
return make_node(AST_Binary, node, {
|
789
|
+
operator: node.operator.slice(0, -1),
|
790
|
+
left: fixed instanceof AST_Node ? fixed : fixed(),
|
791
|
+
right: node.right
|
792
|
+
});
|
793
|
+
};
|
794
|
+
}
|
795
|
+
|
796
|
+
if (node.logical) {
|
797
|
+
mark(tw, def, false);
|
798
|
+
push(tw);
|
799
|
+
node.right.walk(tw);
|
800
|
+
pop(tw);
|
801
|
+
return true;
|
802
|
+
}
|
803
|
+
|
754
804
|
mark(tw, def, false);
|
755
805
|
node.right.walk(tw);
|
756
806
|
mark(tw, def, true);
|
807
|
+
|
757
808
|
mark_escaped(tw, def, sym.scope, node, value, 0, 1);
|
809
|
+
|
758
810
|
return true;
|
759
811
|
});
|
760
812
|
def_reduce_vars(AST_Binary, function(tw) {
|
@@ -1357,7 +1409,8 @@ function tighten_body(statements, compressor) {
|
|
1357
1409
|
}
|
1358
1410
|
// Stop immediately if these node types are encountered
|
1359
1411
|
var parent = scanner.parent();
|
1360
|
-
if (node instanceof AST_Assign
|
1412
|
+
if (node instanceof AST_Assign
|
1413
|
+
&& (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
|
1361
1414
|
|| node instanceof AST_Await
|
1362
1415
|
|| node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
|
1363
1416
|
|| node instanceof AST_Debugger
|
@@ -1425,6 +1478,7 @@ function tighten_body(statements, compressor) {
|
|
1425
1478
|
}
|
1426
1479
|
return make_node(AST_Assign, candidate, {
|
1427
1480
|
operator: "=",
|
1481
|
+
logical: false,
|
1428
1482
|
left: make_node(AST_SymbolRef, candidate.name, candidate.name),
|
1429
1483
|
right: value
|
1430
1484
|
});
|
@@ -1729,6 +1783,7 @@ function tighten_body(statements, compressor) {
|
|
1729
1783
|
var parent = scanner.parent(level);
|
1730
1784
|
if (parent instanceof AST_Assign) {
|
1731
1785
|
if (write_only
|
1786
|
+
&& !parent.logical
|
1732
1787
|
&& !(parent.left instanceof AST_PropAccess
|
1733
1788
|
|| lvalues.has(parent.left.name))) {
|
1734
1789
|
return find_stop(parent, level + 1, write_only);
|
@@ -1783,7 +1838,9 @@ function tighten_body(statements, compressor) {
|
|
1783
1838
|
}
|
1784
1839
|
|
1785
1840
|
function get_lhs(expr) {
|
1786
|
-
if (expr instanceof
|
1841
|
+
if (expr instanceof AST_Assign && expr.logical) {
|
1842
|
+
return false;
|
1843
|
+
} else if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) {
|
1787
1844
|
var def = expr.name.definition();
|
1788
1845
|
if (!member(expr.name, def.orig)) return;
|
1789
1846
|
var referenced = def.references.length - def.replaced;
|
@@ -1794,14 +1851,20 @@ function tighten_body(statements, compressor) {
|
|
1794
1851
|
return make_node(AST_SymbolRef, expr.name, expr.name);
|
1795
1852
|
}
|
1796
1853
|
} else {
|
1797
|
-
const lhs = expr
|
1854
|
+
const lhs = expr instanceof AST_Assign
|
1855
|
+
? expr.left
|
1856
|
+
: expr.expression;
|
1798
1857
|
return !is_ref_of(lhs, AST_SymbolConst)
|
1799
1858
|
&& !is_ref_of(lhs, AST_SymbolLet) && lhs;
|
1800
1859
|
}
|
1801
1860
|
}
|
1802
1861
|
|
1803
1862
|
function get_rvalue(expr) {
|
1804
|
-
|
1863
|
+
if (expr instanceof AST_Assign) {
|
1864
|
+
return expr.right;
|
1865
|
+
} else {
|
1866
|
+
return expr.value;
|
1867
|
+
}
|
1805
1868
|
}
|
1806
1869
|
|
1807
1870
|
function get_lvalues(expr) {
|
@@ -1860,7 +1923,9 @@ function tighten_body(statements, compressor) {
|
|
1860
1923
|
&& !(in_loop
|
1861
1924
|
&& (lvalues.has(lhs.name)
|
1862
1925
|
|| candidate instanceof AST_Unary
|
1863
|
-
|| candidate instanceof AST_Assign
|
1926
|
+
|| (candidate instanceof AST_Assign
|
1927
|
+
&& !candidate.logical
|
1928
|
+
&& candidate.operator != "=")));
|
1864
1929
|
}
|
1865
1930
|
|
1866
1931
|
function value_has_side_effects(expr) {
|
@@ -2287,7 +2352,7 @@ function tighten_body(statements, compressor) {
|
|
2287
2352
|
var def = defn.definitions[defn.definitions.length - 1];
|
2288
2353
|
if (!(def.value instanceof AST_Object)) return;
|
2289
2354
|
var exprs;
|
2290
|
-
if (body instanceof AST_Assign) {
|
2355
|
+
if (body instanceof AST_Assign && !body.logical) {
|
2291
2356
|
exprs = [ body ];
|
2292
2357
|
} else if (body instanceof AST_Sequence) {
|
2293
2358
|
exprs = body.expressions.slice();
|
@@ -2510,6 +2575,8 @@ function is_undefined(node, compressor) {
|
|
2510
2575
|
&& (this.left._dot_throw(compressor) || this.right._dot_throw(compressor));
|
2511
2576
|
});
|
2512
2577
|
def_may_throw_on_access(AST_Assign, function(compressor) {
|
2578
|
+
if (this.logical) return true;
|
2579
|
+
|
2513
2580
|
return this.operator == "="
|
2514
2581
|
&& this.right._dot_throw(compressor);
|
2515
2582
|
});
|
@@ -3734,6 +3801,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
3734
3801
|
var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars;
|
3735
3802
|
const assign_as_unused = r_keep_assign.test(compressor.option("unused")) ? return_false : function(node) {
|
3736
3803
|
if (node instanceof AST_Assign
|
3804
|
+
&& !node.logical
|
3737
3805
|
&& (has_flag(node, WRITE_ONLY) || node.operator == "=")
|
3738
3806
|
) {
|
3739
3807
|
return node.left;
|
@@ -3952,6 +4020,7 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
3952
4020
|
sym.references.push(ref);
|
3953
4021
|
var assign = make_node(AST_Assign, def, {
|
3954
4022
|
operator: "=",
|
4023
|
+
logical: false,
|
3955
4024
|
left: ref,
|
3956
4025
|
right: def.value
|
3957
4026
|
});
|
@@ -4387,6 +4456,8 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
|
4387
4456
|
}
|
4388
4457
|
});
|
4389
4458
|
def_drop_side_effect_free(AST_Assign, function(compressor) {
|
4459
|
+
if (this.logical) return this;
|
4460
|
+
|
4390
4461
|
var left = this.left;
|
4391
4462
|
if (left.has_side_effects(compressor)
|
4392
4463
|
|| compressor.has_directive("use strict")
|
@@ -4983,6 +5054,7 @@ AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
|
4983
5054
|
var name = make_node(AST_SymbolRef, def.name, def.name);
|
4984
5055
|
assignments.push(make_node(AST_Assign, def, {
|
4985
5056
|
operator : "=",
|
5057
|
+
logical: false,
|
4986
5058
|
left : name,
|
4987
5059
|
right : def.value
|
4988
5060
|
}));
|
@@ -5013,6 +5085,17 @@ def_optimize(AST_Definitions, function(self) {
|
|
5013
5085
|
return self;
|
5014
5086
|
});
|
5015
5087
|
|
5088
|
+
def_optimize(AST_VarDef, function(self) {
|
5089
|
+
if (
|
5090
|
+
self.name instanceof AST_SymbolLet
|
5091
|
+
&& self.value != null
|
5092
|
+
&& is_undefined(self.value)
|
5093
|
+
) {
|
5094
|
+
self.value = null;
|
5095
|
+
}
|
5096
|
+
return self;
|
5097
|
+
});
|
5098
|
+
|
5016
5099
|
def_optimize(AST_Import, function(self) {
|
5017
5100
|
return self;
|
5018
5101
|
});
|
@@ -5597,6 +5680,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
5597
5680
|
def.references.push(sym);
|
5598
5681
|
if (value) expressions.push(make_node(AST_Assign, self, {
|
5599
5682
|
operator: "=",
|
5683
|
+
logical: false,
|
5600
5684
|
left: sym,
|
5601
5685
|
right: value.clone()
|
5602
5686
|
}));
|
@@ -5640,6 +5724,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
5640
5724
|
def.references.push(sym);
|
5641
5725
|
expressions.splice(pos++, 0, make_node(AST_Assign, var_def, {
|
5642
5726
|
operator: "=",
|
5727
|
+
logical: false,
|
5643
5728
|
left: sym,
|
5644
5729
|
right: make_node(AST_Undefined, name)
|
5645
5730
|
}));
|
@@ -6160,7 +6245,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
6160
6245
|
var l = self.left;
|
6161
6246
|
var r = self.right.evaluate(compressor);
|
6162
6247
|
if (r != self.right) {
|
6163
|
-
l.segments[l.segments.length - 1].value += r
|
6248
|
+
l.segments[l.segments.length - 1].value += String(r);
|
6164
6249
|
return l;
|
6165
6250
|
}
|
6166
6251
|
}
|
@@ -6169,7 +6254,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
6169
6254
|
var r = self.right;
|
6170
6255
|
var l = self.left.evaluate(compressor);
|
6171
6256
|
if (l != self.left) {
|
6172
|
-
r.segments[0].value = l
|
6257
|
+
r.segments[0].value = String(l) + r.segments[0].value;
|
6173
6258
|
return r;
|
6174
6259
|
}
|
6175
6260
|
}
|
@@ -6597,6 +6682,10 @@ function is_reachable(self, defs) {
|
|
6597
6682
|
const ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &");
|
6598
6683
|
const ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &");
|
6599
6684
|
def_optimize(AST_Assign, function(self, compressor) {
|
6685
|
+
if (self.logical) {
|
6686
|
+
return self.lift_sequences(compressor);
|
6687
|
+
}
|
6688
|
+
|
6600
6689
|
var def;
|
6601
6690
|
if (compressor.option("dead_code")
|
6602
6691
|
&& self.left instanceof AST_SymbolRef
|
@@ -6814,16 +6903,20 @@ def_optimize(AST_Conditional, function(self, compressor) {
|
|
6814
6903
|
// |
|
6815
6904
|
// v
|
6816
6905
|
// exp = foo ? something : something_else;
|
6817
|
-
if (
|
6906
|
+
if (
|
6907
|
+
consequent instanceof AST_Assign
|
6818
6908
|
&& alternative instanceof AST_Assign
|
6819
|
-
&& consequent.operator
|
6909
|
+
&& consequent.operator === alternative.operator
|
6910
|
+
&& consequent.logical === alternative.logical
|
6820
6911
|
&& consequent.left.equivalent_to(alternative.left)
|
6821
6912
|
&& (!self.condition.has_side_effects(compressor)
|
6822
6913
|
|| consequent.operator == "="
|
6823
|
-
&& !consequent.left.has_side_effects(compressor))
|
6914
|
+
&& !consequent.left.has_side_effects(compressor))
|
6915
|
+
) {
|
6824
6916
|
return make_node(AST_Assign, self, {
|
6825
6917
|
operator: consequent.operator,
|
6826
6918
|
left: consequent.left,
|
6919
|
+
logical: consequent.logical,
|
6827
6920
|
right: make_node(AST_Conditional, self, {
|
6828
6921
|
condition: self.condition,
|
6829
6922
|
consequent: consequent.right,
|
@@ -7419,9 +7512,12 @@ def_optimize(AST_Yield, function(self, compressor) {
|
|
7419
7512
|
});
|
7420
7513
|
|
7421
7514
|
def_optimize(AST_TemplateString, function(self, compressor) {
|
7422
|
-
if (
|
7423
|
-
|
7515
|
+
if (
|
7516
|
+
!compressor.option("evaluate")
|
7517
|
+
|| compressor.parent() instanceof AST_PrefixedTemplateString
|
7518
|
+
) {
|
7424
7519
|
return self;
|
7520
|
+
}
|
7425
7521
|
|
7426
7522
|
var segments = [];
|
7427
7523
|
for (var i = 0; i < self.segments.length; i++) {
|
@@ -7457,7 +7553,17 @@ def_optimize(AST_TemplateString, function(self, compressor) {
|
|
7457
7553
|
if (segments.length == 1) {
|
7458
7554
|
return make_node(AST_String, self, segments[0]);
|
7459
7555
|
}
|
7460
|
-
|
7556
|
+
|
7557
|
+
if (
|
7558
|
+
segments.length === 3
|
7559
|
+
&& segments[1] instanceof AST_Node
|
7560
|
+
&& (
|
7561
|
+
segments[1].is_string(compressor)
|
7562
|
+
|| segments[1].is_number(compressor)
|
7563
|
+
|| is_nullish(segments[1])
|
7564
|
+
|| compressor.option("unsafe")
|
7565
|
+
)
|
7566
|
+
) {
|
7461
7567
|
// `foo${bar}` => "foo" + bar
|
7462
7568
|
if (segments[2].value === "") {
|
7463
7569
|
return make_node(AST_Binary, self, {
|
@@ -7468,7 +7574,7 @@ def_optimize(AST_TemplateString, function(self, compressor) {
|
|
7468
7574
|
right: segments[1],
|
7469
7575
|
});
|
7470
7576
|
}
|
7471
|
-
//
|
7577
|
+
// `${bar}baz` => bar + "baz"
|
7472
7578
|
if (segments[0].value === "") {
|
7473
7579
|
return make_node(AST_Binary, self, {
|
7474
7580
|
operator: "+",
|
package/lib/mozilla-ast.js
CHANGED
@@ -544,6 +544,7 @@ import {
|
|
544
544
|
return new AST_String(args);
|
545
545
|
case "number":
|
546
546
|
args.value = val;
|
547
|
+
args.raw = M.raw || val.toString();
|
547
548
|
return new AST_Number(args);
|
548
549
|
case "boolean":
|
549
550
|
return new (val ? AST_True : AST_False)(args);
|
@@ -1068,22 +1069,10 @@ import {
|
|
1068
1069
|
|
1069
1070
|
def_to_moz(AST_Constant, function To_Moz_Literal(M) {
|
1070
1071
|
var value = M.value;
|
1071
|
-
if (typeof value === "number" && (value < 0 || (value === 0 && 1 / value < 0))) {
|
1072
|
-
return {
|
1073
|
-
type: "UnaryExpression",
|
1074
|
-
operator: "-",
|
1075
|
-
prefix: true,
|
1076
|
-
argument: {
|
1077
|
-
type: "Literal",
|
1078
|
-
value: -value,
|
1079
|
-
raw: M.start.raw
|
1080
|
-
}
|
1081
|
-
};
|
1082
|
-
}
|
1083
1072
|
return {
|
1084
1073
|
type: "Literal",
|
1085
1074
|
value: value,
|
1086
|
-
raw: M.
|
1075
|
+
raw: M.raw || M.print_to_string()
|
1087
1076
|
};
|
1088
1077
|
});
|
1089
1078
|
|
@@ -1108,40 +1097,36 @@ import {
|
|
1108
1097
|
|
1109
1098
|
/* -----[ tools ]----- */
|
1110
1099
|
|
1111
|
-
function raw_token(moznode) {
|
1112
|
-
if (moznode.type == "Literal") {
|
1113
|
-
return moznode.raw != null ? moznode.raw : moznode.value + "";
|
1114
|
-
}
|
1115
|
-
}
|
1116
|
-
|
1117
1100
|
function my_start_token(moznode) {
|
1118
1101
|
var loc = moznode.loc, start = loc && loc.start;
|
1119
1102
|
var range = moznode.range;
|
1120
|
-
return new AST_Token(
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1103
|
+
return new AST_Token(
|
1104
|
+
"",
|
1105
|
+
"",
|
1106
|
+
start && start.line || 0,
|
1107
|
+
start && start.column || 0,
|
1108
|
+
range ? range [0] : moznode.start,
|
1109
|
+
false,
|
1110
|
+
[],
|
1111
|
+
[],
|
1112
|
+
loc && loc.source,
|
1113
|
+
);
|
1130
1114
|
}
|
1131
1115
|
|
1132
1116
|
function my_end_token(moznode) {
|
1133
1117
|
var loc = moznode.loc, end = loc && loc.end;
|
1134
1118
|
var range = moznode.range;
|
1135
|
-
return new AST_Token(
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1119
|
+
return new AST_Token(
|
1120
|
+
"",
|
1121
|
+
"",
|
1122
|
+
end && end.line || 0,
|
1123
|
+
end && end.column || 0,
|
1124
|
+
range ? range [0] : moznode.end,
|
1125
|
+
false,
|
1126
|
+
[],
|
1127
|
+
[],
|
1128
|
+
loc && loc.source,
|
1129
|
+
);
|
1145
1130
|
}
|
1146
1131
|
|
1147
1132
|
function map(moztype, mytype, propmap) {
|
package/lib/output.js
CHANGED
@@ -239,7 +239,7 @@ function OutputStream(options) {
|
|
239
239
|
let printed_comments = new Set();
|
240
240
|
|
241
241
|
var to_utf8 = options.ascii_only ? function(str, identifier) {
|
242
|
-
if (options.ecma >= 2015) {
|
242
|
+
if (options.ecma >= 2015 && !options.safari10) {
|
243
243
|
str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
|
244
244
|
var code = get_full_char_code(ch, 0).toString(16);
|
245
245
|
return "\\u{" + code + "}";
|
@@ -1335,6 +1335,9 @@ function OutputStream(options) {
|
|
1335
1335
|
}
|
1336
1336
|
output.print("`");
|
1337
1337
|
});
|
1338
|
+
DEFPRINT(AST_TemplateSegment, function(self, output) {
|
1339
|
+
output.print_template_string_chars(self.value);
|
1340
|
+
});
|
1338
1341
|
|
1339
1342
|
AST_Arrow.DEFMETHOD("_do_print", function(output) {
|
1340
1343
|
var self = this;
|
@@ -1776,7 +1779,10 @@ function OutputStream(options) {
|
|
1776
1779
|
var prop = self.property;
|
1777
1780
|
var print_computed = RESERVED_WORDS.has(prop)
|
1778
1781
|
? output.option("ie8")
|
1779
|
-
: !is_identifier_string(
|
1782
|
+
: !is_identifier_string(
|
1783
|
+
prop,
|
1784
|
+
output.option("ecma") >= 2015 || output.option("safari10")
|
1785
|
+
);
|
1780
1786
|
|
1781
1787
|
if (self.optional) output.print("?.");
|
1782
1788
|
|
@@ -1946,7 +1952,7 @@ function OutputStream(options) {
|
|
1946
1952
|
var print_string = RESERVED_WORDS.has(key)
|
1947
1953
|
? output.option("ie8")
|
1948
1954
|
: (
|
1949
|
-
output.option("ecma") < 2015
|
1955
|
+
output.option("ecma") < 2015 || output.option("safari10")
|
1950
1956
|
? !is_basic_identifier_string(key)
|
1951
1957
|
: !is_identifier_string(key, true)
|
1952
1958
|
);
|
@@ -1965,7 +1971,10 @@ function OutputStream(options) {
|
|
1965
1971
|
var allowShortHand = output.option("shorthand");
|
1966
1972
|
if (allowShortHand &&
|
1967
1973
|
self.value instanceof AST_Symbol &&
|
1968
|
-
is_identifier_string(
|
1974
|
+
is_identifier_string(
|
1975
|
+
self.key,
|
1976
|
+
output.option("ecma") >= 2015 || output.option("safari10")
|
1977
|
+
) &&
|
1969
1978
|
get_name(self.value) === self.key &&
|
1970
1979
|
!RESERVED_WORDS.has(self.key)
|
1971
1980
|
) {
|
@@ -1974,7 +1983,10 @@ function OutputStream(options) {
|
|
1974
1983
|
} else if (allowShortHand &&
|
1975
1984
|
self.value instanceof AST_DefaultAssign &&
|
1976
1985
|
self.value.left instanceof AST_Symbol &&
|
1977
|
-
is_identifier_string(
|
1986
|
+
is_identifier_string(
|
1987
|
+
self.key,
|
1988
|
+
output.option("ecma") >= 2015 || output.option("safari10")
|
1989
|
+
) &&
|
1978
1990
|
get_name(self.value.left) === self.key
|
1979
1991
|
) {
|
1980
1992
|
print_property_name(self.key, self.quote, output);
|
@@ -2072,8 +2084,8 @@ function OutputStream(options) {
|
|
2072
2084
|
output.print_string(self.getValue(), self.quote, output.in_directive);
|
2073
2085
|
});
|
2074
2086
|
DEFPRINT(AST_Number, function(self, output) {
|
2075
|
-
if ((output.option("keep_numbers") || output.use_asm) && self.
|
2076
|
-
output.print(self.
|
2087
|
+
if ((output.option("keep_numbers") || output.use_asm) && self.raw) {
|
2088
|
+
output.print(self.raw);
|
2077
2089
|
} else {
|
2078
2090
|
output.print(make_num(self.getValue()));
|
2079
2091
|
}
|