terser 5.16.2 → 5.16.4
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 +13 -0
- package/dist/bundle.min.js +286 -223
- package/lib/ast.js +27 -6
- package/lib/compress/index.js +21 -10
- package/lib/compress/inference.js +2 -2
- package/lib/compress/inline.js +119 -114
- package/lib/compress/reduce-vars.js +31 -12
- package/lib/compress/tighten-body.js +11 -7
- package/lib/equivalent-to.js +1 -1
- package/lib/mozilla-ast.js +3 -2
- package/lib/output.js +5 -1
- package/lib/parse.js +20 -1
- package/lib/scope.js +2 -8
- package/lib/size.js +1 -3
- package/lib/transform.js +4 -10
- package/lib/utils/index.js +31 -35
- package/package.json +1 -1
package/lib/ast.js
CHANGED
@@ -111,6 +111,14 @@ class AST_Token {
|
|
111
111
|
Object.seal(this);
|
112
112
|
}
|
113
113
|
|
114
|
+
// Return a string summary of the token for node.js console.log
|
115
|
+
[Symbol.for("nodejs.util.inspect.custom")](_depth, options) {
|
116
|
+
const special = str => options.stylize(str, "special");
|
117
|
+
const quote = typeof this.value === "string" && this.value.includes("`") ? "'" : "`";
|
118
|
+
const value = `${quote}${this.value}${quote}`;
|
119
|
+
return `${special("[AST_Token")} ${value} at ${this.line}:${this.col}${special("]")}`;
|
120
|
+
}
|
121
|
+
|
114
122
|
get nlb() {
|
115
123
|
return has_tok_flag(this, TOK_FLAG_NLB);
|
116
124
|
}
|
@@ -1257,12 +1265,11 @@ var AST_Case = DEFNODE("Case", "expression", function AST_Case(props) {
|
|
1257
1265
|
|
1258
1266
|
/* -----[ EXCEPTIONS ]----- */
|
1259
1267
|
|
1260
|
-
var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
|
1268
|
+
var AST_Try = DEFNODE("Try", "body bcatch bfinally", function AST_Try(props) {
|
1261
1269
|
if (props) {
|
1270
|
+
this.body = props.body;
|
1262
1271
|
this.bcatch = props.bcatch;
|
1263
1272
|
this.bfinally = props.bfinally;
|
1264
|
-
this.body = props.body;
|
1265
|
-
this.block_scope = props.block_scope;
|
1266
1273
|
this.start = props.start;
|
1267
1274
|
this.end = props.end;
|
1268
1275
|
}
|
@@ -1271,12 +1278,13 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
|
|
1271
1278
|
}, {
|
1272
1279
|
$documentation: "A `try` statement",
|
1273
1280
|
$propdoc: {
|
1281
|
+
body: "[AST_TryBlock] the try block",
|
1274
1282
|
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
1275
1283
|
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
1276
1284
|
},
|
1277
1285
|
_walk: function(visitor) {
|
1278
1286
|
return visitor._visit(this, function() {
|
1279
|
-
|
1287
|
+
this.body._walk(visitor);
|
1280
1288
|
if (this.bcatch) this.bcatch._walk(visitor);
|
1281
1289
|
if (this.bfinally) this.bfinally._walk(visitor);
|
1282
1290
|
});
|
@@ -1284,9 +1292,21 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", function AST_Try(props) {
|
|
1284
1292
|
_children_backwards(push) {
|
1285
1293
|
if (this.bfinally) push(this.bfinally);
|
1286
1294
|
if (this.bcatch) push(this.bcatch);
|
1287
|
-
|
1288
|
-
while (i--) push(this.body[i]);
|
1295
|
+
push(this.body);
|
1289
1296
|
},
|
1297
|
+
}, AST_Statement);
|
1298
|
+
|
1299
|
+
var AST_TryBlock = DEFNODE("TryBlock", null, function AST_TryBlock(props) {
|
1300
|
+
if (props) {
|
1301
|
+
this.body = props.body;
|
1302
|
+
this.block_scope = props.block_scope;
|
1303
|
+
this.start = props.start;
|
1304
|
+
this.end = props.end;
|
1305
|
+
}
|
1306
|
+
|
1307
|
+
this.flags = 0;
|
1308
|
+
}, {
|
1309
|
+
$documentation: "The `try` block of a try statement"
|
1290
1310
|
}, AST_Block);
|
1291
1311
|
|
1292
1312
|
var AST_Catch = DEFNODE("Catch", "argname", function AST_Catch(props) {
|
@@ -3235,6 +3255,7 @@ export {
|
|
3235
3255
|
AST_Toplevel,
|
3236
3256
|
AST_True,
|
3237
3257
|
AST_Try,
|
3258
|
+
AST_TryBlock,
|
3238
3259
|
AST_Unary,
|
3239
3260
|
AST_UnaryPostfix,
|
3240
3261
|
AST_UnaryPrefix,
|
package/lib/compress/index.js
CHANGED
@@ -1529,9 +1529,9 @@ def_optimize(AST_Switch, function(self, compressor) {
|
|
1529
1529
|
});
|
1530
1530
|
|
1531
1531
|
def_optimize(AST_Try, function(self, compressor) {
|
1532
|
-
tighten_body(self.body, compressor);
|
1533
1532
|
if (self.bcatch && self.bfinally && self.bfinally.body.every(is_empty)) self.bfinally = null;
|
1534
|
-
|
1533
|
+
|
1534
|
+
if (compressor.option("dead_code") && self.body.body.every(is_empty)) {
|
1535
1535
|
var body = [];
|
1536
1536
|
if (self.bcatch) {
|
1537
1537
|
trim_unreachable_code(compressor, self.bcatch, body);
|
@@ -2737,16 +2737,21 @@ def_optimize(AST_Assign, function(self, compressor) {
|
|
2737
2737
|
return self;
|
2738
2738
|
|
2739
2739
|
function in_try(level, node) {
|
2740
|
-
|
2741
|
-
|
2742
|
-
|
2743
|
-
|
2744
|
-
|
2740
|
+
function may_assignment_throw() {
|
2741
|
+
const right = self.right;
|
2742
|
+
self.right = make_node(AST_Null, right);
|
2743
|
+
const may_throw = node.may_throw(compressor);
|
2744
|
+
self.right = right;
|
2745
|
+
|
2746
|
+
return may_throw;
|
2747
|
+
}
|
2748
|
+
|
2749
|
+
var stop_at = self.left.definition().scope.get_defun_scope();
|
2745
2750
|
var parent;
|
2746
|
-
while ((parent = compressor.parent(level++)) !==
|
2751
|
+
while ((parent = compressor.parent(level++)) !== stop_at) {
|
2747
2752
|
if (parent instanceof AST_Try) {
|
2748
2753
|
if (parent.bfinally) return true;
|
2749
|
-
if (
|
2754
|
+
if (parent.bcatch && may_assignment_throw()) return true;
|
2750
2755
|
}
|
2751
2756
|
}
|
2752
2757
|
}
|
@@ -2759,7 +2764,13 @@ def_optimize(AST_DefaultAssign, function(self, compressor) {
|
|
2759
2764
|
var evaluateRight = self.right.evaluate(compressor);
|
2760
2765
|
|
2761
2766
|
// `[x = undefined] = foo` ---> `[x] = foo`
|
2762
|
-
|
2767
|
+
// `(arg = undefined) => ...` ---> `(arg) => ...` (unless `keep_fargs`)
|
2768
|
+
if (
|
2769
|
+
evaluateRight === undefined &&
|
2770
|
+
(compressor.parent() instanceof AST_Lambda
|
2771
|
+
? compressor.option("keep_fargs") === false
|
2772
|
+
: true)
|
2773
|
+
) {
|
2763
2774
|
self = self.left;
|
2764
2775
|
} else if (evaluateRight !== self.right) {
|
2765
2776
|
evaluateRight = make_node_from_constant(evaluateRight, self.right);
|
@@ -300,7 +300,7 @@ export function is_nullish(node, compressor) {
|
|
300
300
|
|| any(this.body, compressor);
|
301
301
|
});
|
302
302
|
def_has_side_effects(AST_Try, function(compressor) {
|
303
|
-
return
|
303
|
+
return this.body.has_side_effects(compressor)
|
304
304
|
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|
305
305
|
|| this.bfinally && this.bfinally.has_side_effects(compressor);
|
306
306
|
});
|
@@ -529,7 +529,7 @@ export function is_nullish(node, compressor) {
|
|
529
529
|
});
|
530
530
|
def_may_throw(AST_SymbolClassProperty, return_false);
|
531
531
|
def_may_throw(AST_Try, function(compressor) {
|
532
|
-
return this.bcatch ? this.bcatch.may_throw(compressor) :
|
532
|
+
return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor)
|
533
533
|
|| this.bfinally && this.bfinally.may_throw(compressor);
|
534
534
|
});
|
535
535
|
def_may_throw(AST_Unary, function(compressor) {
|
package/lib/compress/inline.js
CHANGED
@@ -92,7 +92,6 @@ import "../size.js";
|
|
92
92
|
import "./evaluate.js";
|
93
93
|
import "./drop-side-effect-free.js";
|
94
94
|
import "./reduce-vars.js";
|
95
|
-
import { is_lhs } from "./inference.js";
|
96
95
|
import {
|
97
96
|
SQUEEZED,
|
98
97
|
INLINED,
|
@@ -114,6 +113,13 @@ import {
|
|
114
113
|
retain_top_func,
|
115
114
|
} from "./common.js";
|
116
115
|
|
116
|
+
/**
|
117
|
+
* Module that contains the inlining logic.
|
118
|
+
*
|
119
|
+
* @module
|
120
|
+
*
|
121
|
+
* The stars of the show are `inline_into_symbolref` and `inline_into_call`.
|
122
|
+
*/
|
117
123
|
|
118
124
|
function within_array_or_object_literal(compressor) {
|
119
125
|
var node, level = 0;
|
@@ -144,136 +150,135 @@ function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
|
|
144
150
|
|
145
151
|
export function inline_into_symbolref(self, compressor) {
|
146
152
|
const parent = compressor.parent();
|
147
|
-
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
|
148
|
-
const def = self.definition();
|
149
|
-
const nearest_scope = compressor.find_scope();
|
150
|
-
if (compressor.top_retain && def.global && compressor.top_retain(def)) {
|
151
|
-
def.fixed = false;
|
152
|
-
def.single_use = false;
|
153
|
-
return self;
|
154
|
-
}
|
155
153
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
&& fixed.name);
|
164
|
-
|
165
|
-
if (single_use && fixed instanceof AST_Node) {
|
166
|
-
single_use =
|
167
|
-
!fixed.has_side_effects(compressor)
|
168
|
-
&& !fixed.may_throw(compressor);
|
169
|
-
}
|
154
|
+
const def = self.definition();
|
155
|
+
const nearest_scope = compressor.find_scope();
|
156
|
+
if (compressor.top_retain && def.global && compressor.top_retain(def)) {
|
157
|
+
def.fixed = false;
|
158
|
+
def.single_use = false;
|
159
|
+
return self;
|
160
|
+
}
|
170
161
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
162
|
+
let fixed = self.fixed_value();
|
163
|
+
let single_use = def.single_use
|
164
|
+
&& !(parent instanceof AST_Call
|
165
|
+
&& (parent.is_callee_pure(compressor))
|
166
|
+
|| has_annotation(parent, _NOINLINE))
|
167
|
+
&& !(parent instanceof AST_Export
|
168
|
+
&& fixed instanceof AST_Lambda
|
169
|
+
&& fixed.name);
|
170
|
+
|
171
|
+
if (single_use && fixed instanceof AST_Node) {
|
172
|
+
single_use =
|
173
|
+
!fixed.has_side_effects(compressor)
|
174
|
+
&& !fixed.may_throw(compressor);
|
175
|
+
}
|
176
|
+
|
177
|
+
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
178
|
+
if (retain_top_func(fixed, compressor)) {
|
179
|
+
single_use = false;
|
180
|
+
} else if (def.scope !== self.scope
|
181
|
+
&& (def.escaped == 1
|
182
|
+
|| has_flag(fixed, INLINED)
|
183
|
+
|| within_array_or_object_literal(compressor)
|
184
|
+
|| !compressor.option("reduce_funcs"))) {
|
185
|
+
single_use = false;
|
186
|
+
} else if (is_recursive_ref(compressor, def)) {
|
187
|
+
single_use = false;
|
188
|
+
} else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
|
189
|
+
single_use = fixed.is_constant_expression(self.scope);
|
190
|
+
if (single_use == "f") {
|
191
|
+
var scope = self.scope;
|
192
|
+
do {
|
193
|
+
if (scope instanceof AST_Defun || is_func_expr(scope)) {
|
194
|
+
set_flag(scope, INLINED);
|
195
|
+
}
|
196
|
+
} while (scope = scope.parent_scope);
|
192
197
|
}
|
193
198
|
}
|
199
|
+
}
|
194
200
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
201
|
+
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
202
|
+
single_use =
|
203
|
+
def.scope === self.scope
|
204
|
+
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
205
|
+
|| parent instanceof AST_Call
|
206
|
+
&& parent.expression === self
|
207
|
+
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
208
|
+
&& !(fixed.name && fixed.name.definition().recursive_refs > 0);
|
209
|
+
}
|
204
210
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
211
|
+
if (single_use && fixed) {
|
212
|
+
if (fixed instanceof AST_DefClass) {
|
213
|
+
set_flag(fixed, SQUEEZED);
|
214
|
+
fixed = make_node(AST_ClassExpression, fixed, fixed);
|
215
|
+
}
|
216
|
+
if (fixed instanceof AST_Defun) {
|
217
|
+
set_flag(fixed, SQUEEZED);
|
218
|
+
fixed = make_node(AST_Function, fixed, fixed);
|
219
|
+
}
|
220
|
+
if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
|
221
|
+
const defun_def = fixed.name.definition();
|
222
|
+
let lambda_def = fixed.variables.get(fixed.name.name);
|
223
|
+
let name = lambda_def && lambda_def.orig[0];
|
224
|
+
if (!(name instanceof AST_SymbolLambda)) {
|
225
|
+
name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
226
|
+
name.scope = fixed;
|
227
|
+
fixed.name = name;
|
228
|
+
lambda_def = fixed.def_function(name);
|
213
229
|
}
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
if (!(name instanceof AST_SymbolLambda)) {
|
219
|
-
name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
220
|
-
name.scope = fixed;
|
221
|
-
fixed.name = name;
|
222
|
-
lambda_def = fixed.def_function(name);
|
230
|
+
walk(fixed, node => {
|
231
|
+
if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
|
232
|
+
node.thedef = lambda_def;
|
233
|
+
lambda_def.references.push(node);
|
223
234
|
}
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
235
|
+
});
|
236
|
+
}
|
237
|
+
if (
|
238
|
+
(fixed instanceof AST_Lambda || fixed instanceof AST_Class)
|
239
|
+
&& fixed.parent_scope !== nearest_scope
|
240
|
+
) {
|
241
|
+
fixed = fixed.clone(true, compressor.get_toplevel());
|
242
|
+
|
243
|
+
nearest_scope.add_child_scope(fixed);
|
244
|
+
}
|
245
|
+
return fixed.optimize(compressor);
|
246
|
+
}
|
247
|
+
|
248
|
+
// multiple uses
|
249
|
+
if (fixed) {
|
250
|
+
let replace;
|
251
|
+
|
252
|
+
if (fixed instanceof AST_This) {
|
253
|
+
if (!(def.orig[0] instanceof AST_SymbolFunarg)
|
254
|
+
&& def.references.every((ref) =>
|
255
|
+
def.scope === ref.scope
|
256
|
+
)) {
|
257
|
+
replace = fixed;
|
230
258
|
}
|
259
|
+
} else {
|
260
|
+
var ev = fixed.evaluate(compressor);
|
231
261
|
if (
|
232
|
-
|
233
|
-
&&
|
262
|
+
ev !== fixed
|
263
|
+
&& (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
|
234
264
|
) {
|
235
|
-
|
236
|
-
|
237
|
-
nearest_scope.add_child_scope(fixed);
|
265
|
+
replace = make_node_from_constant(ev, fixed);
|
238
266
|
}
|
239
|
-
return fixed.optimize(compressor);
|
240
267
|
}
|
241
268
|
|
242
|
-
|
243
|
-
|
244
|
-
|
269
|
+
if (replace) {
|
270
|
+
const name_length = self.size(compressor);
|
271
|
+
const replace_size = replace.size(compressor);
|
245
272
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
)
|
251
|
-
replace = fixed;
|
252
|
-
}
|
253
|
-
} else {
|
254
|
-
var ev = fixed.evaluate(compressor);
|
255
|
-
if (
|
256
|
-
ev !== fixed
|
257
|
-
&& (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
|
258
|
-
) {
|
259
|
-
replace = make_node_from_constant(ev, fixed);
|
260
|
-
}
|
273
|
+
let overhead = 0;
|
274
|
+
if (compressor.option("unused") && !compressor.exposed(def)) {
|
275
|
+
overhead =
|
276
|
+
(name_length + 2 + replace_size) /
|
277
|
+
(def.references.length - def.assignments);
|
261
278
|
}
|
262
279
|
|
263
|
-
if (
|
264
|
-
|
265
|
-
const replace_size = replace.size(compressor);
|
266
|
-
|
267
|
-
let overhead = 0;
|
268
|
-
if (compressor.option("unused") && !compressor.exposed(def)) {
|
269
|
-
overhead =
|
270
|
-
(name_length + 2 + replace_size) /
|
271
|
-
(def.references.length - def.assignments);
|
272
|
-
}
|
273
|
-
|
274
|
-
if (replace_size <= name_length + overhead) {
|
275
|
-
return replace;
|
276
|
-
}
|
280
|
+
if (replace_size <= name_length + overhead) {
|
281
|
+
return replace;
|
277
282
|
}
|
278
283
|
}
|
279
284
|
}
|
@@ -103,15 +103,17 @@ import { lazy_op, is_modified } from "./inference.js";
|
|
103
103
|
import { INLINED, clear_flag } from "./compressor-flags.js";
|
104
104
|
import { read_property, has_break_or_continue, is_recursive_ref } from "./common.js";
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
/**
|
107
|
+
* Define the method AST_Node#reduce_vars, which goes through the AST in
|
108
|
+
* execution order to perform basic flow analysis
|
109
|
+
*/
|
109
110
|
function def_reduce_vars(node, func) {
|
110
111
|
node.DEFMETHOD("reduce_vars", func);
|
111
112
|
}
|
112
113
|
|
113
114
|
def_reduce_vars(AST_Node, noop);
|
114
115
|
|
116
|
+
/** Clear definition properties */
|
115
117
|
function reset_def(compressor, def) {
|
116
118
|
def.assignments = 0;
|
117
119
|
def.chained = false;
|
@@ -120,7 +122,10 @@ function reset_def(compressor, def) {
|
|
120
122
|
def.recursive_refs = 0;
|
121
123
|
def.references = [];
|
122
124
|
def.single_use = undefined;
|
123
|
-
if (
|
125
|
+
if (
|
126
|
+
def.scope.pinned()
|
127
|
+
|| (def.orig[0] instanceof AST_SymbolFunarg && def.scope.uses_arguments)
|
128
|
+
) {
|
124
129
|
def.fixed = false;
|
125
130
|
} else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) {
|
126
131
|
def.fixed = def.init;
|
@@ -442,15 +447,23 @@ def_reduce_vars(AST_Default, function(tw, descend) {
|
|
442
447
|
|
443
448
|
function mark_lambda(tw, descend, compressor) {
|
444
449
|
clear_flag(this, INLINED);
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
450
|
+
|
451
|
+
// Sometimes we detach the lambda for safety, and instead of push()
|
452
|
+
// we go to an entirely fresh lineage of safe_ids.
|
453
|
+
let previous_safe_ids;
|
454
|
+
if (this instanceof AST_Defun || this.uses_arguments || this.pinned()) {
|
455
|
+
previous_safe_ids = tw.safe_ids;
|
456
|
+
tw.safe_ids = Object.create(null);
|
457
|
+
} else {
|
458
|
+
push(tw);
|
451
459
|
}
|
460
|
+
|
461
|
+
reset_variables(tw, compressor, this);
|
462
|
+
|
452
463
|
var iife;
|
453
464
|
if (!this.name
|
465
|
+
&& !this.uses_arguments
|
466
|
+
&& !this.pinned()
|
454
467
|
&& (iife = tw.parent()) instanceof AST_Call
|
455
468
|
&& iife.expression === this
|
456
469
|
&& !iife.args.some(arg => arg instanceof AST_Expansion)
|
@@ -476,7 +489,13 @@ function mark_lambda(tw, descend, compressor) {
|
|
476
489
|
});
|
477
490
|
}
|
478
491
|
descend();
|
479
|
-
|
492
|
+
|
493
|
+
if (previous_safe_ids) {
|
494
|
+
tw.safe_ids = previous_safe_ids;
|
495
|
+
} else {
|
496
|
+
pop(tw);
|
497
|
+
}
|
498
|
+
|
480
499
|
return true;
|
481
500
|
}
|
482
501
|
|
@@ -605,7 +624,7 @@ def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) {
|
|
605
624
|
def_reduce_vars(AST_Try, function(tw, descend, compressor) {
|
606
625
|
reset_block_variables(compressor, this);
|
607
626
|
push(tw);
|
608
|
-
|
627
|
+
this.body.walk(tw);
|
609
628
|
pop(tw);
|
610
629
|
if (this.bcatch) {
|
611
630
|
push(tw);
|
@@ -52,7 +52,6 @@ import {
|
|
52
52
|
AST_Break,
|
53
53
|
AST_Call,
|
54
54
|
AST_Case,
|
55
|
-
AST_Catch,
|
56
55
|
AST_Chain,
|
57
56
|
AST_Class,
|
58
57
|
AST_Conditional,
|
@@ -71,7 +70,6 @@ import {
|
|
71
70
|
AST_Exit,
|
72
71
|
AST_Expansion,
|
73
72
|
AST_Export,
|
74
|
-
AST_Finally,
|
75
73
|
AST_For,
|
76
74
|
AST_ForIn,
|
77
75
|
AST_If,
|
@@ -103,6 +101,7 @@ import {
|
|
103
101
|
AST_SymbolVar,
|
104
102
|
AST_This,
|
105
103
|
AST_Try,
|
104
|
+
AST_TryBlock,
|
106
105
|
AST_Unary,
|
107
106
|
AST_UnaryPostfix,
|
108
107
|
AST_UnaryPrefix,
|
@@ -234,13 +233,11 @@ export function tighten_body(statements, compressor) {
|
|
234
233
|
function find_loop_scope_try() {
|
235
234
|
var node = compressor.self(), level = 0, in_loop = false, in_try = false;
|
236
235
|
do {
|
237
|
-
if (node instanceof
|
238
|
-
level++;
|
239
|
-
} else if (node instanceof AST_IterationStatement) {
|
236
|
+
if (node instanceof AST_IterationStatement) {
|
240
237
|
in_loop = true;
|
241
238
|
} else if (node instanceof AST_Scope) {
|
242
239
|
break;
|
243
|
-
} else if (node instanceof
|
240
|
+
} else if (node instanceof AST_TryBlock) {
|
244
241
|
in_try = true;
|
245
242
|
}
|
246
243
|
} while (node = compressor.parent(level++));
|
@@ -284,6 +281,9 @@ export function tighten_body(statements, compressor) {
|
|
284
281
|
&& (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
|
285
282
|
|| node instanceof AST_Await
|
286
283
|
|| node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
|
284
|
+
||
|
285
|
+
(node instanceof AST_Call || node instanceof AST_PropAccess)
|
286
|
+
&& node.optional
|
287
287
|
|| node instanceof AST_Debugger
|
288
288
|
|| node instanceof AST_Destructuring
|
289
289
|
|| node instanceof AST_Expansion
|
@@ -457,7 +457,11 @@ export function tighten_body(statements, compressor) {
|
|
457
457
|
var hit = funarg;
|
458
458
|
var abort = false, replaced = 0, can_replace = !args || !hit;
|
459
459
|
if (!can_replace) {
|
460
|
-
for (
|
460
|
+
for (
|
461
|
+
let j = compressor.self().argnames.lastIndexOf(candidate.name) + 1;
|
462
|
+
!abort && j < args.length;
|
463
|
+
j++
|
464
|
+
) {
|
461
465
|
args[j].transform(scanner);
|
462
466
|
}
|
463
467
|
can_replace = true;
|
package/lib/equivalent-to.js
CHANGED
@@ -172,7 +172,7 @@ AST_Switch.prototype.shallow_cmp = pass_through;
|
|
172
172
|
AST_SwitchBranch.prototype.shallow_cmp = pass_through;
|
173
173
|
|
174
174
|
AST_Try.prototype.shallow_cmp = function(other) {
|
175
|
-
return (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
|
175
|
+
return (this.body === other.body) && (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
|
176
176
|
};
|
177
177
|
|
178
178
|
AST_Catch.prototype.shallow_cmp = function(other) {
|
package/lib/mozilla-ast.js
CHANGED
@@ -151,6 +151,7 @@ import {
|
|
151
151
|
AST_Toplevel,
|
152
152
|
AST_True,
|
153
153
|
AST_Try,
|
154
|
+
AST_TryBlock,
|
154
155
|
AST_Unary,
|
155
156
|
AST_UnaryPostfix,
|
156
157
|
AST_UnaryPrefix,
|
@@ -344,7 +345,7 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
344
345
|
return new AST_Try({
|
345
346
|
start : my_start_token(M),
|
346
347
|
end : my_end_token(M),
|
347
|
-
body : from_moz(M.block)
|
348
|
+
body : new AST_TryBlock(from_moz(M.block)),
|
348
349
|
bcatch : from_moz(handlers[0]),
|
349
350
|
bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
|
350
351
|
});
|
@@ -1315,7 +1316,7 @@ import { is_basic_identifier_string } from "./parse.js";
|
|
1315
1316
|
def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
|
1316
1317
|
return {
|
1317
1318
|
type: "TryStatement",
|
1318
|
-
block: to_moz_block(M),
|
1319
|
+
block: to_moz_block(M.body),
|
1319
1320
|
handler: to_moz(M.bcatch),
|
1320
1321
|
guardedHandlers: [],
|
1321
1322
|
finalizer: to_moz(M.bfinally)
|
package/lib/output.js
CHANGED
@@ -143,6 +143,7 @@ import {
|
|
143
143
|
AST_Throw,
|
144
144
|
AST_Toplevel,
|
145
145
|
AST_Try,
|
146
|
+
AST_TryBlock,
|
146
147
|
AST_Unary,
|
147
148
|
AST_UnaryPostfix,
|
148
149
|
AST_UnaryPrefix,
|
@@ -1620,7 +1621,7 @@ function OutputStream(options) {
|
|
1620
1621
|
DEFPRINT(AST_Try, function(self, output) {
|
1621
1622
|
output.print("try");
|
1622
1623
|
output.space();
|
1623
|
-
|
1624
|
+
self.body.print(output);
|
1624
1625
|
if (self.bcatch) {
|
1625
1626
|
output.space();
|
1626
1627
|
self.bcatch.print(output);
|
@@ -1630,6 +1631,9 @@ function OutputStream(options) {
|
|
1630
1631
|
self.bfinally.print(output);
|
1631
1632
|
}
|
1632
1633
|
});
|
1634
|
+
DEFPRINT(AST_TryBlock, function(self, output) {
|
1635
|
+
print_braced(self, output);
|
1636
|
+
});
|
1633
1637
|
DEFPRINT(AST_Catch, function(self, output) {
|
1634
1638
|
output.print("catch");
|
1635
1639
|
if (self.argname) {
|