Skip to content

Commit 21aff99

Browse files
authored
enhance varify (#5737)
1 parent 1d400f1 commit 21aff99

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

lib/compress.js

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ function Compressor(options, false_by_default) {
9898
switches : !false_by_default,
9999
templates : !false_by_default,
100100
top_retain : null,
101-
toplevel : !!(options && (options["module"] || options["top_retain"])),
101+
toplevel : !!(options && !options["expression"] && (options["module"] || options["top_retain"])),
102102
typeofs : !false_by_default,
103103
unsafe : false,
104104
unsafe_comps : false,
@@ -9357,14 +9357,16 @@ Compressor.prototype.compress = function(node) {
93579357
OPT(AST_ForEnumeration, function(self, compressor) {
93589358
if (compressor.option("varify") && is_lexical_definition(self.init)) {
93599359
var name = self.init.definitions[0].name;
9360-
if ((name instanceof AST_Destructured || name instanceof AST_SymbolLet)
9360+
if ((compressor.option("module") || name instanceof AST_Destructured || name instanceof AST_SymbolLet)
93619361
&& !name.match_symbol(function(node) {
93629362
if (node instanceof AST_SymbolDeclaration) {
93639363
var def = node.definition();
93649364
return !same_scope(def) || may_overlap(compressor, def);
93659365
}
93669366
}, true)) {
93679367
self.init = to_var(self.init, self.resolve());
9368+
} else if (can_letify(self.init, compressor, 1)) {
9369+
self.init = to_let(self.init);
93689370
}
93699371
}
93709372
return self;
@@ -10178,6 +10180,20 @@ Compressor.prototype.compress = function(node) {
1017810180
}
1017910181
}
1018010182

10183+
function to_let(stat) {
10184+
return make_node(AST_Let, stat, {
10185+
definitions: stat.definitions.map(function(defn) {
10186+
return make_node(AST_VarDef, defn, {
10187+
name: defn.name.convert_symbol(AST_SymbolLet, function(name, node) {
10188+
var def = name.definition();
10189+
def.orig[def.orig.indexOf(node)] = name;
10190+
}),
10191+
value: defn.value,
10192+
});
10193+
}),
10194+
});
10195+
}
10196+
1018110197
function to_var(stat, scope) {
1018210198
return make_node(AST_Var, stat, {
1018310199
definitions: stat.definitions.map(function(defn) {
@@ -10197,6 +10213,18 @@ Compressor.prototype.compress = function(node) {
1019710213
});
1019810214
}
1019910215

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);
10225+
});
10226+
}
10227+
1020010228
function can_varify(compressor, sym) {
1020110229
var def = sym.definition();
1020210230
return (def.fixed || def.fixed === 0)
@@ -10206,15 +10234,23 @@ Compressor.prototype.compress = function(node) {
1020610234
}
1020710235

1020810236
function varify(self, compressor) {
10209-
return compressor.option("varify") && all(self.definitions, function(defn) {
10237+
return all(self.definitions, function(defn) {
1021010238
return !defn.name.match_symbol(function(node) {
1021110239
if (node instanceof AST_SymbolDeclaration) return !can_varify(compressor, node);
1021210240
}, true);
1021310241
}) ? to_var(self, compressor.find_parent(AST_Scope)) : self;
1021410242
}
1021510243

10216-
OPT(AST_Const, varify);
10217-
OPT(AST_Let, varify);
10244+
OPT(AST_Const, function(self, compressor) {
10245+
if (!compressor.option("varify")) return self;
10246+
if (can_letify(self, compressor, 0)) return to_let(self);
10247+
return varify(self, compressor);
10248+
});
10249+
10250+
OPT(AST_Let, function(self, compressor) {
10251+
if (!compressor.option("varify")) return self;
10252+
return varify(self, compressor);
10253+
});
1021810254

1021910255
function trim_optional_chain(node, compressor) {
1022010256
if (!compressor.option("optional_chains")) return;

lib/minify.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ function minify(files, options) {
8989
rename: undefined,
9090
sourceMap: false,
9191
timings: false,
92-
toplevel: !!(options && options["module"]),
92+
toplevel: !!(options && !options["expression"] && options["module"]),
9393
v8: false,
9494
validate: false,
9595
warnings: false,

test/compress/varify.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,42 @@ forin_const_2: {
329329
node_version: ">=6"
330330
}
331331

332+
forin_const_3: {
333+
options = {
334+
module: true,
335+
reduce_vars: true,
336+
toplevel: true,
337+
varify: true,
338+
}
339+
input: {
340+
"use strict";
341+
const o = {
342+
p: 42,
343+
q: "PASS",
344+
};
345+
for (const k in o)
346+
(function f() {
347+
console.log(k, o[k]);
348+
})();
349+
}
350+
expect: {
351+
"use strict";
352+
let o = {
353+
p: 42,
354+
q: "PASS",
355+
};
356+
for (let k in o)
357+
(function f() {
358+
console.log(k, o[k]);
359+
})();
360+
}
361+
expect_stdout: [
362+
"p 42",
363+
"q PASS",
364+
]
365+
node_version: ">=4"
366+
}
367+
332368
forin_let_1: {
333369
options = {
334370
join_vars: true,

0 commit comments

Comments
 (0)