@@ -487,7 +487,7 @@ Compressor.prototype.compress = function(node) {
487
487
return all(def.orig, function(sym) {
488
488
if (sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet) {
489
489
if (sym instanceof AST_SymbolImport) return true;
490
- return compressor && can_varify (compressor, sym);
490
+ return compressor && safe_from_tdz (compressor, sym);
491
491
}
492
492
return !(keep_lambda && sym instanceof AST_SymbolLambda);
493
493
});
@@ -525,10 +525,11 @@ Compressor.prototype.compress = function(node) {
525
525
function reset_def(tw, compressor, def) {
526
526
def.assignments = 0;
527
527
def.bool_return = 0;
528
- def.drop_return = 0;
529
528
def.cross_loop = false;
530
529
def.direct_access = false;
530
+ def.drop_return = 0;
531
531
def.escaped = [];
532
+ def.first_decl = null;
532
533
def.fixed = !def.const_redefs
533
534
&& !def.scope.pinned()
534
535
&& !compressor.exposed(def)
@@ -951,6 +952,7 @@ Compressor.prototype.compress = function(node) {
951
952
952
953
function visit(node, fixed) {
953
954
var d = node.definition();
955
+ if (!d.first_decl && d.references.length == 0) d.first_decl = node;
954
956
if (fixed && safe && d.fixed === undefined) {
955
957
mark(tw, d);
956
958
tw.loop_ids[d.id] = tw.in_loop;
@@ -1371,10 +1373,18 @@ Compressor.prototype.compress = function(node) {
1371
1373
return true;
1372
1374
});
1373
1375
def(AST_SymbolCatch, function() {
1374
- this.definition().fixed = false;
1376
+ var d = this.definition();
1377
+ if (!d.first_decl && d.references.length == 0) d.first_decl = this;
1378
+ d.fixed = false;
1379
+ });
1380
+ def(AST_SymbolDeclaration, function() {
1381
+ var d = this.definition();
1382
+ if (!d.first_decl && d.references.length == 0) d.first_decl = this;
1375
1383
});
1376
1384
def(AST_SymbolImport, function() {
1377
- this.definition().fixed = false;
1385
+ var d = this.definition();
1386
+ d.first_decl = this;
1387
+ d.fixed = false;
1378
1388
});
1379
1389
def(AST_SymbolRef, function(tw, descend, compressor) {
1380
1390
var ref = this;
@@ -1558,6 +1568,8 @@ Compressor.prototype.compress = function(node) {
1558
1568
walk_defn();
1559
1569
} else if (tw.parent() instanceof AST_Let) {
1560
1570
walk_defn();
1571
+ } else {
1572
+ node.name.walk(tw);
1561
1573
}
1562
1574
return true;
1563
1575
@@ -1566,6 +1578,7 @@ Compressor.prototype.compress = function(node) {
1566
1578
return node.value || make_node(AST_Undefined, node);
1567
1579
}, function(name, fixed) {
1568
1580
var d = name.definition();
1581
+ if (!d.first_decl && d.references.length == 0) d.first_decl = name;
1569
1582
if (fixed && safe_to_assign(tw, d, true)) {
1570
1583
mark(tw, d);
1571
1584
tw.loop_ids[d.id] = tw.in_loop;
@@ -4249,14 +4262,22 @@ Compressor.prototype.compress = function(node) {
4249
4262
}
4250
4263
4251
4264
function join_consecutive_vars(statements) {
4252
- var changed = false, defs;
4265
+ var changed = false, defs, prev_defs ;
4253
4266
for (var i = 0, j = -1; i < statements.length; i++) {
4254
4267
var stat = statements[i];
4255
4268
var prev = statements[j];
4256
4269
if (stat instanceof AST_Definitions) {
4257
4270
if (prev && prev.TYPE == stat.TYPE) {
4258
4271
prev.definitions = prev.definitions.concat(stat.definitions);
4259
4272
changed = true;
4273
+ } else if (stat && prev instanceof AST_Let && stat.can_letify(compressor)) {
4274
+ prev.definitions = prev.definitions.concat(to_let(stat).definitions);
4275
+ changed = true;
4276
+ } else if (prev && stat instanceof AST_Let && prev.can_letify(compressor)) {
4277
+ defs = prev_defs;
4278
+ statements[j] = prev = to_let(prev);
4279
+ prev.definitions = prev.definitions.concat(stat.definitions);
4280
+ changed = true;
4260
4281
} else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) {
4261
4282
defs.definitions = defs.definitions.concat(stat.definitions);
4262
4283
changed = true;
@@ -4271,6 +4292,7 @@ Compressor.prototype.compress = function(node) {
4271
4292
} else {
4272
4293
j++;
4273
4294
}
4295
+ prev_defs = defs;
4274
4296
statements[j] = defs = stat;
4275
4297
} else {
4276
4298
statements[++j] = stat;
@@ -4288,6 +4310,7 @@ Compressor.prototype.compress = function(node) {
4288
4310
prev.definitions = prev.definitions.concat(stat.init.definitions);
4289
4311
}
4290
4312
stat = stat.clone();
4313
+ prev_defs = defs;
4291
4314
defs = stat.init = prev;
4292
4315
statements[j] = merge_defns(stat);
4293
4316
changed = true;
@@ -4297,6 +4320,7 @@ Compressor.prototype.compress = function(node) {
4297
4320
stat.init = null;
4298
4321
changed = true;
4299
4322
} else if (stat.init instanceof AST_Var) {
4323
+ prev_defs = defs;
4300
4324
defs = stat.init;
4301
4325
exprs = merge_assigns(prev, stat.init);
4302
4326
if (exprs) {
@@ -9365,7 +9389,7 @@ Compressor.prototype.compress = function(node) {
9365
9389
}
9366
9390
}, true)) {
9367
9391
self.init = to_var(self.init, self.resolve());
9368
- } else if (can_letify( self.init, compressor, 1 )) {
9392
+ } else if (self.init.can_letify( compressor, true )) {
9369
9393
self.init = to_let(self.init);
9370
9394
}
9371
9395
}
@@ -10213,45 +10237,60 @@ Compressor.prototype.compress = function(node) {
10213
10237
});
10214
10238
}
10215
10239
10216
- function can_letify(stat, compressor, assigned) {
10217
- if (!(stat instanceof AST_Const)) return false;
10218
- if (!compressor.option("module") && all(stat.definitions, function(defn) {
10219
- return defn.name instanceof AST_SymbolConst;
10220
- })) return false;
10221
- return all(stat.definitions, function(defn) {
10222
- return !defn.name.match_symbol(function(node) {
10223
- if (node instanceof AST_SymbolDeclaration) return node.definition().assignments != assigned;
10224
- }, true);
10240
+ (function(def) {
10241
+ def(AST_Node, return_false);
10242
+ def(AST_Const, function(compressor, assigned) {
10243
+ assigned = assigned ? 1 : 0;
10244
+ var defns = this.definitions;
10245
+ if (!compressor.option("module") && all(defns, function(defn) {
10246
+ return defn.name instanceof AST_SymbolConst;
10247
+ })) return false;
10248
+ return all(defns, function(defn) {
10249
+ return !defn.name.match_symbol(function(node) {
10250
+ if (node instanceof AST_SymbolDeclaration) return node.definition().assignments != assigned;
10251
+ }, true);
10252
+ });
10225
10253
});
10226
- }
10254
+ def(AST_Var, function(compressor) {
10255
+ return all(this.definitions, function(defn) {
10256
+ return !defn.name.match_symbol(function(node) {
10257
+ if (!(node instanceof AST_SymbolDeclaration)) return false;
10258
+ if (node.definition().first_decl !== node) return true;
10259
+ return !safe_from_tdz(compressor, node);
10260
+ }, true);
10261
+ });
10262
+ });
10263
+ })(function(node, func) {
10264
+ node.DEFMETHOD("can_letify", func);
10265
+ });
10227
10266
10228
- function can_varify (compressor, sym) {
10267
+ function safe_from_tdz (compressor, sym) {
10229
10268
var def = sym.definition();
10230
10269
return (def.fixed || def.fixed === 0)
10231
10270
&& is_safe_lexical(def)
10232
10271
&& same_scope(def)
10233
10272
&& !may_overlap(compressor, def);
10234
10273
}
10235
10274
10236
- function varify(self, compressor) {
10237
- if ( all(self .definitions, function(defn) {
10275
+ AST_Definitions.DEFMETHOD("can_varify", function( compressor) {
10276
+ return all(this .definitions, function(defn) {
10238
10277
return !defn.name.match_symbol(function(node) {
10239
- if (node instanceof AST_SymbolDeclaration) return !can_varify (compressor, node);
10278
+ if (node instanceof AST_SymbolDeclaration) return !safe_from_tdz (compressor, node);
10240
10279
}, true);
10241
- })) return to_var(self, compressor.find_parent(AST_Scope)) ;
10242
- }
10280
+ });
10281
+ });
10243
10282
10244
10283
OPT(AST_Const, function(self, compressor) {
10245
10284
if (!compressor.option("varify")) return self;
10246
- var decl = varify(self, compressor);
10247
- if (decl) return decl;
10248
- if (can_letify(self, compressor, 0)) return to_let(self);
10285
+ if (self.can_varify(compressor)) return to_var(self, compressor.find_parent(AST_Scope));
10286
+ if (self.can_letify(compressor)) return to_let(self);
10249
10287
return self;
10250
10288
});
10251
10289
10252
10290
OPT(AST_Let, function(self, compressor) {
10253
10291
if (!compressor.option("varify")) return self;
10254
- return varify(self, compressor) || self;
10292
+ if (self.can_varify(compressor)) return to_var(self, compressor.find_parent(AST_Scope));
10293
+ return self;
10255
10294
});
10256
10295
10257
10296
function trim_optional_chain(node, compressor) {
0 commit comments