terser 5.16.2 → 5.16.3
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 +4 -0
- package/dist/bundle.min.js +150 -125
- package/lib/compress/inline.js +119 -114
- package/lib/compress/reduce-vars.js +30 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/bundle.min.js
CHANGED
@@ -15352,15 +15352,17 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15352
15352
|
|
15353
15353
|
***********************************************************************/
|
15354
15354
|
|
15355
|
-
|
15356
|
-
|
15357
|
-
|
15355
|
+
/**
|
15356
|
+
* Define the method AST_Node#reduce_vars, which goes through the AST in
|
15357
|
+
* execution order to perform basic flow analysis
|
15358
|
+
*/
|
15358
15359
|
function def_reduce_vars(node, func) {
|
15359
15360
|
node.DEFMETHOD("reduce_vars", func);
|
15360
15361
|
}
|
15361
15362
|
|
15362
15363
|
def_reduce_vars(AST_Node, noop);
|
15363
15364
|
|
15365
|
+
/** Clear definition properties */
|
15364
15366
|
function reset_def(compressor, def) {
|
15365
15367
|
def.assignments = 0;
|
15366
15368
|
def.chained = false;
|
@@ -15369,7 +15371,10 @@ function reset_def(compressor, def) {
|
|
15369
15371
|
def.recursive_refs = 0;
|
15370
15372
|
def.references = [];
|
15371
15373
|
def.single_use = undefined;
|
15372
|
-
if (
|
15374
|
+
if (
|
15375
|
+
def.scope.pinned()
|
15376
|
+
|| (def.orig[0] instanceof AST_SymbolFunarg && def.scope.uses_arguments)
|
15377
|
+
) {
|
15373
15378
|
def.fixed = false;
|
15374
15379
|
} else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) {
|
15375
15380
|
def.fixed = def.init;
|
@@ -15691,15 +15696,23 @@ def_reduce_vars(AST_Default, function(tw, descend) {
|
|
15691
15696
|
|
15692
15697
|
function mark_lambda(tw, descend, compressor) {
|
15693
15698
|
clear_flag(this, INLINED);
|
15694
|
-
|
15695
|
-
|
15696
|
-
|
15697
|
-
|
15698
|
-
|
15699
|
-
|
15699
|
+
|
15700
|
+
// Sometimes we detach the lambda for safety, and instead of push()
|
15701
|
+
// we go to an entirely fresh lineage of safe_ids.
|
15702
|
+
let previous_safe_ids;
|
15703
|
+
if (this instanceof AST_Defun || this.uses_arguments || this.pinned()) {
|
15704
|
+
previous_safe_ids = tw.safe_ids;
|
15705
|
+
tw.safe_ids = Object.create(null);
|
15706
|
+
} else {
|
15707
|
+
push(tw);
|
15700
15708
|
}
|
15709
|
+
|
15710
|
+
reset_variables(tw, compressor, this);
|
15711
|
+
|
15701
15712
|
var iife;
|
15702
15713
|
if (!this.name
|
15714
|
+
&& !this.uses_arguments
|
15715
|
+
&& !this.pinned()
|
15703
15716
|
&& (iife = tw.parent()) instanceof AST_Call
|
15704
15717
|
&& iife.expression === this
|
15705
15718
|
&& !iife.args.some(arg => arg instanceof AST_Expansion)
|
@@ -15725,7 +15738,13 @@ function mark_lambda(tw, descend, compressor) {
|
|
15725
15738
|
});
|
15726
15739
|
}
|
15727
15740
|
descend();
|
15728
|
-
|
15741
|
+
|
15742
|
+
if (previous_safe_ids) {
|
15743
|
+
tw.safe_ids = previous_safe_ids;
|
15744
|
+
} else {
|
15745
|
+
pop(tw);
|
15746
|
+
}
|
15747
|
+
|
15729
15748
|
return true;
|
15730
15749
|
}
|
15731
15750
|
|
@@ -17334,6 +17353,13 @@ function tighten_body(statements, compressor) {
|
|
17334
17353
|
|
17335
17354
|
***********************************************************************/
|
17336
17355
|
|
17356
|
+
/**
|
17357
|
+
* Module that contains the inlining logic.
|
17358
|
+
*
|
17359
|
+
* @module
|
17360
|
+
*
|
17361
|
+
* The stars of the show are `inline_into_symbolref` and `inline_into_call`.
|
17362
|
+
*/
|
17337
17363
|
|
17338
17364
|
function within_array_or_object_literal(compressor) {
|
17339
17365
|
var node, level = 0;
|
@@ -17364,136 +17390,135 @@ function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
|
|
17364
17390
|
|
17365
17391
|
function inline_into_symbolref(self, compressor) {
|
17366
17392
|
const parent = compressor.parent();
|
17367
|
-
|
17368
|
-
|
17369
|
-
|
17370
|
-
|
17371
|
-
|
17372
|
-
|
17373
|
-
|
17393
|
+
|
17394
|
+
const def = self.definition();
|
17395
|
+
const nearest_scope = compressor.find_scope();
|
17396
|
+
if (compressor.top_retain && def.global && compressor.top_retain(def)) {
|
17397
|
+
def.fixed = false;
|
17398
|
+
def.single_use = false;
|
17399
|
+
return self;
|
17400
|
+
}
|
17401
|
+
|
17402
|
+
let fixed = self.fixed_value();
|
17403
|
+
let single_use = def.single_use
|
17404
|
+
&& !(parent instanceof AST_Call
|
17405
|
+
&& (parent.is_callee_pure(compressor))
|
17406
|
+
|| has_annotation(parent, _NOINLINE))
|
17407
|
+
&& !(parent instanceof AST_Export
|
17408
|
+
&& fixed instanceof AST_Lambda
|
17409
|
+
&& fixed.name);
|
17410
|
+
|
17411
|
+
if (single_use && fixed instanceof AST_Node) {
|
17412
|
+
single_use =
|
17413
|
+
!fixed.has_side_effects(compressor)
|
17414
|
+
&& !fixed.may_throw(compressor);
|
17415
|
+
}
|
17416
|
+
|
17417
|
+
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
17418
|
+
if (retain_top_func(fixed, compressor)) {
|
17419
|
+
single_use = false;
|
17420
|
+
} else if (def.scope !== self.scope
|
17421
|
+
&& (def.escaped == 1
|
17422
|
+
|| has_flag(fixed, INLINED)
|
17423
|
+
|| within_array_or_object_literal(compressor)
|
17424
|
+
|| !compressor.option("reduce_funcs"))) {
|
17425
|
+
single_use = false;
|
17426
|
+
} else if (is_recursive_ref(compressor, def)) {
|
17427
|
+
single_use = false;
|
17428
|
+
} else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
|
17429
|
+
single_use = fixed.is_constant_expression(self.scope);
|
17430
|
+
if (single_use == "f") {
|
17431
|
+
var scope = self.scope;
|
17432
|
+
do {
|
17433
|
+
if (scope instanceof AST_Defun || is_func_expr(scope)) {
|
17434
|
+
set_flag(scope, INLINED);
|
17435
|
+
}
|
17436
|
+
} while (scope = scope.parent_scope);
|
17437
|
+
}
|
17374
17438
|
}
|
17439
|
+
}
|
17375
17440
|
|
17376
|
-
|
17377
|
-
|
17378
|
-
|
17379
|
-
&& (
|
17380
|
-
|
17381
|
-
|
17382
|
-
&& fixed
|
17383
|
-
&& fixed.name);
|
17384
|
-
|
17385
|
-
|
17386
|
-
|
17387
|
-
|
17388
|
-
|
17389
|
-
|
17390
|
-
|
17391
|
-
if (
|
17392
|
-
|
17393
|
-
|
17394
|
-
|
17395
|
-
|
17396
|
-
|
17397
|
-
|
17398
|
-
|
17399
|
-
|
17400
|
-
|
17401
|
-
|
17402
|
-
|
17403
|
-
|
17404
|
-
|
17405
|
-
|
17406
|
-
|
17407
|
-
|
17408
|
-
|
17409
|
-
}
|
17410
|
-
} while (scope = scope.parent_scope);
|
17441
|
+
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
17442
|
+
single_use =
|
17443
|
+
def.scope === self.scope
|
17444
|
+
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
17445
|
+
|| parent instanceof AST_Call
|
17446
|
+
&& parent.expression === self
|
17447
|
+
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
17448
|
+
&& !(fixed.name && fixed.name.definition().recursive_refs > 0);
|
17449
|
+
}
|
17450
|
+
|
17451
|
+
if (single_use && fixed) {
|
17452
|
+
if (fixed instanceof AST_DefClass) {
|
17453
|
+
set_flag(fixed, SQUEEZED);
|
17454
|
+
fixed = make_node(AST_ClassExpression, fixed, fixed);
|
17455
|
+
}
|
17456
|
+
if (fixed instanceof AST_Defun) {
|
17457
|
+
set_flag(fixed, SQUEEZED);
|
17458
|
+
fixed = make_node(AST_Function, fixed, fixed);
|
17459
|
+
}
|
17460
|
+
if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
|
17461
|
+
const defun_def = fixed.name.definition();
|
17462
|
+
let lambda_def = fixed.variables.get(fixed.name.name);
|
17463
|
+
let name = lambda_def && lambda_def.orig[0];
|
17464
|
+
if (!(name instanceof AST_SymbolLambda)) {
|
17465
|
+
name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
17466
|
+
name.scope = fixed;
|
17467
|
+
fixed.name = name;
|
17468
|
+
lambda_def = fixed.def_function(name);
|
17469
|
+
}
|
17470
|
+
walk(fixed, node => {
|
17471
|
+
if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
|
17472
|
+
node.thedef = lambda_def;
|
17473
|
+
lambda_def.references.push(node);
|
17411
17474
|
}
|
17412
|
-
}
|
17475
|
+
});
|
17413
17476
|
}
|
17477
|
+
if (
|
17478
|
+
(fixed instanceof AST_Lambda || fixed instanceof AST_Class)
|
17479
|
+
&& fixed.parent_scope !== nearest_scope
|
17480
|
+
) {
|
17481
|
+
fixed = fixed.clone(true, compressor.get_toplevel());
|
17414
17482
|
|
17415
|
-
|
17416
|
-
single_use =
|
17417
|
-
def.scope === self.scope
|
17418
|
-
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
17419
|
-
|| parent instanceof AST_Call
|
17420
|
-
&& parent.expression === self
|
17421
|
-
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
17422
|
-
&& !(fixed.name && fixed.name.definition().recursive_refs > 0);
|
17483
|
+
nearest_scope.add_child_scope(fixed);
|
17423
17484
|
}
|
17485
|
+
return fixed.optimize(compressor);
|
17486
|
+
}
|
17424
17487
|
|
17425
|
-
|
17426
|
-
|
17427
|
-
|
17428
|
-
|
17429
|
-
|
17430
|
-
if (
|
17431
|
-
|
17432
|
-
|
17433
|
-
|
17434
|
-
|
17435
|
-
const defun_def = fixed.name.definition();
|
17436
|
-
let lambda_def = fixed.variables.get(fixed.name.name);
|
17437
|
-
let name = lambda_def && lambda_def.orig[0];
|
17438
|
-
if (!(name instanceof AST_SymbolLambda)) {
|
17439
|
-
name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
17440
|
-
name.scope = fixed;
|
17441
|
-
fixed.name = name;
|
17442
|
-
lambda_def = fixed.def_function(name);
|
17443
|
-
}
|
17444
|
-
walk(fixed, node => {
|
17445
|
-
if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
|
17446
|
-
node.thedef = lambda_def;
|
17447
|
-
lambda_def.references.push(node);
|
17448
|
-
}
|
17449
|
-
});
|
17488
|
+
// multiple uses
|
17489
|
+
if (fixed) {
|
17490
|
+
let replace;
|
17491
|
+
|
17492
|
+
if (fixed instanceof AST_This) {
|
17493
|
+
if (!(def.orig[0] instanceof AST_SymbolFunarg)
|
17494
|
+
&& def.references.every((ref) =>
|
17495
|
+
def.scope === ref.scope
|
17496
|
+
)) {
|
17497
|
+
replace = fixed;
|
17450
17498
|
}
|
17499
|
+
} else {
|
17500
|
+
var ev = fixed.evaluate(compressor);
|
17451
17501
|
if (
|
17452
|
-
|
17453
|
-
&&
|
17502
|
+
ev !== fixed
|
17503
|
+
&& (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
|
17454
17504
|
) {
|
17455
|
-
|
17456
|
-
|
17457
|
-
nearest_scope.add_child_scope(fixed);
|
17505
|
+
replace = make_node_from_constant(ev, fixed);
|
17458
17506
|
}
|
17459
|
-
return fixed.optimize(compressor);
|
17460
17507
|
}
|
17461
17508
|
|
17462
|
-
|
17463
|
-
|
17464
|
-
|
17509
|
+
if (replace) {
|
17510
|
+
const name_length = self.size(compressor);
|
17511
|
+
const replace_size = replace.size(compressor);
|
17465
17512
|
|
17466
|
-
|
17467
|
-
|
17468
|
-
|
17469
|
-
|
17470
|
-
)
|
17471
|
-
replace = fixed;
|
17472
|
-
}
|
17473
|
-
} else {
|
17474
|
-
var ev = fixed.evaluate(compressor);
|
17475
|
-
if (
|
17476
|
-
ev !== fixed
|
17477
|
-
&& (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
|
17478
|
-
) {
|
17479
|
-
replace = make_node_from_constant(ev, fixed);
|
17480
|
-
}
|
17513
|
+
let overhead = 0;
|
17514
|
+
if (compressor.option("unused") && !compressor.exposed(def)) {
|
17515
|
+
overhead =
|
17516
|
+
(name_length + 2 + replace_size) /
|
17517
|
+
(def.references.length - def.assignments);
|
17481
17518
|
}
|
17482
17519
|
|
17483
|
-
if (
|
17484
|
-
|
17485
|
-
const replace_size = replace.size(compressor);
|
17486
|
-
|
17487
|
-
let overhead = 0;
|
17488
|
-
if (compressor.option("unused") && !compressor.exposed(def)) {
|
17489
|
-
overhead =
|
17490
|
-
(name_length + 2 + replace_size) /
|
17491
|
-
(def.references.length - def.assignments);
|
17492
|
-
}
|
17493
|
-
|
17494
|
-
if (replace_size <= name_length + overhead) {
|
17495
|
-
return replace;
|
17496
|
-
}
|
17520
|
+
if (replace_size <= name_length + overhead) {
|
17521
|
+
return replace;
|
17497
17522
|
}
|
17498
17523
|
}
|
17499
17524
|
}
|
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
|
|