support let (#4227)

This commit is contained in:
Alex Lam S.L
2020-10-19 01:32:39 +01:00
committed by GitHub
parent 6c7226c10e
commit 96bf7fceab
10 changed files with 1186 additions and 152 deletions

View File

@@ -97,6 +97,7 @@ function Compressor(options, false_by_default) {
unsafe_regexp : false,
unsafe_undefined: false,
unused : !false_by_default,
varify : !false_by_default,
}, true);
var evaluate = this.options["evaluate"];
this.eval_threshold = /eager/.test(evaluate) ? 1 / 0 : +evaluate;
@@ -488,7 +489,9 @@ merge(Compressor.prototype, {
if (!(declare || all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolConst);
}))) return false;
if (def.fixed === undefined) return true;
if (def.fixed === undefined) return declare || all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolLet);
});
if (def.fixed === null && def.safe_ids) {
def.safe_ids[def.id] = false;
delete def.safe_ids;
@@ -1616,7 +1619,7 @@ merge(Compressor.prototype, {
if (side_effects && may_modify(node)) return true;
var def = node.definition();
return (in_try || def.scope.resolve() !== scope) && !all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolConst);
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet);
});
}
if (node instanceof AST_This) return symbol_in_lvalues(node, parent);
@@ -2177,7 +2180,7 @@ merge(Compressor.prototype, {
var stat = statements[i];
if (stat instanceof AST_BlockStatement) {
if (all(stat.body, function(stat) {
return !(stat instanceof AST_Const);
return !(stat instanceof AST_Const || stat instanceof AST_Let);
})) {
CHANGED = true;
eliminate_spurious_blocks(stat.body);
@@ -2513,7 +2516,7 @@ merge(Compressor.prototype, {
var line = block.body[i];
if (line instanceof AST_Var && declarations_only(line)) {
decls.push(line);
} else if (stat || line instanceof AST_Const) {
} else if (stat || line instanceof AST_Const || line instanceof AST_Let) {
return false;
} else {
stat = line;
@@ -2829,7 +2832,7 @@ merge(Compressor.prototype, {
function push(node) {
if (block) {
block.push(node);
if (node instanceof AST_Const) block.required = true;
if (node instanceof AST_Const || node instanceof AST_Let) block.required = true;
} else {
target.push(node);
}
@@ -4106,7 +4109,7 @@ merge(Compressor.prototype, {
def(AST_SymbolDeclaration, return_false);
def(AST_SymbolRef, function(compressor) {
return !(this.is_declared(compressor) && all(this.definition().orig, function(sym) {
return !(sym instanceof AST_SymbolConst);
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet);
}));
});
def(AST_This, return_false);
@@ -4360,7 +4363,7 @@ merge(Compressor.prototype, {
return make_node(AST_EmptyStatement, node);
case 1:
var stat = node.body[0];
if (!(stat instanceof AST_Const)) return stat;
if (!(stat instanceof AST_Const || stat instanceof AST_Let)) return stat;
}
return node;
}
@@ -4460,10 +4463,7 @@ merge(Compressor.prototype, {
}
if (node instanceof AST_Const) {
node.definitions.forEach(function(defn) {
var def = defn.name.definition();
references[def.id] = false;
def = def.redefined();
if (def) references[def.id] = false;
references[defn.name.definition().id] = false;
defn.value.walk(tw);
});
return true;
@@ -4516,6 +4516,13 @@ merge(Compressor.prototype, {
pop();
return true;
}
if (node instanceof AST_Let) {
node.definitions.forEach(function(defn) {
references[defn.name.definition().id] = false;
if (defn.value) defn.value.walk(tw);
});
return true;
}
if (node instanceof AST_Scope) {
push();
segment.block = node;
@@ -4618,7 +4625,10 @@ merge(Compressor.prototype, {
if (!tail_refs) continue;
if (head_refs.start.block !== tail_refs.start.block
|| !mergeable(head_refs, tail_refs)
|| head_refs.start.loop && !mergeable(tail_refs, head_refs)) {
|| head_refs.start.loop && !mergeable(tail_refs, head_refs)
|| !all(tail_refs, function(sym) {
return sym.scope.find_variable(def.name) === def;
})) {
skipped.unshift(tail);
continue;
}
@@ -4715,7 +4725,7 @@ merge(Compressor.prototype, {
if (!(sym instanceof AST_SymbolRef)) return;
if (compressor.exposed(sym.definition())) return;
if (!all(sym.definition().orig, function(sym) {
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLambda);
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLambda || sym instanceof AST_SymbolLet);
})) return;
return sym;
};
@@ -4956,7 +4966,7 @@ merge(Compressor.prototype, {
}
} else if (compressor.option("functions")
&& !compressor.option("ie8")
&& !(node instanceof AST_Const)
&& !(node instanceof AST_Const || node instanceof AST_Let)
&& var_defs.length == 1
&& sym.assignments == 0
&& def.value instanceof AST_Function
@@ -5100,7 +5110,7 @@ merge(Compressor.prototype, {
return in_list ? List.skip : make_node(AST_EmptyStatement, node);
case 1:
var stat = node.body[0];
if (!(stat instanceof AST_Const)) return stat;
if (!(stat instanceof AST_Const || stat instanceof AST_Let)) return stat;
} else if (node instanceof AST_For) {
// Certain combination of unused name + side effect leads to invalid AST:
// https://github.com/mishoo/UglifyJS/issues/44
@@ -5665,7 +5675,7 @@ merge(Compressor.prototype, {
return ref.fixed_value() === right;
})
&& all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolConst);
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet);
});
}
});
@@ -5883,7 +5893,7 @@ merge(Compressor.prototype, {
});
function drop_symbol(ref) {
return all(ref.definition().orig, function(sym) {
return !(sym instanceof AST_SymbolConst);
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet);
});
}
def(AST_SymbolRef, function(compressor) {
@@ -6623,6 +6633,12 @@ merge(Compressor.prototype, {
});
});
AST_Let.DEFMETHOD("remove_initializers", function() {
this.definitions.forEach(function(def) {
def.value = null;
});
});
AST_Var.DEFMETHOD("remove_initializers", function() {
this.definitions.forEach(function(def) {
def.value = null;
@@ -6650,20 +6666,17 @@ merge(Compressor.prototype, {
return make_sequence(this, assignments);
});
OPT(AST_Const, function(self, compressor) {
return all(self.definitions, function(defn) {
function varify(self, compressor) {
return compressor.option("varify") && all(self.definitions, function(defn) {
var node = defn.name;
if (!node.fixed_value()) return false;
var def = node.definition();
if (compressor.exposed(def)) return false;
var scope = def.scope.resolve();
if (def.scope === scope) return true;
if (scope instanceof AST_Toplevel) return !scope.variables.has(node.name) && !scope.globals.has(node.name);
var s = def.scope;
do {
for (var s = def.scope; s !== scope;) {
s = s.parent_scope;
if (s.var_names()[node.name]) return false;
} while (s !== scope);
}
return true;
}) ? make_node(AST_Var, self, {
definitions: self.definitions.map(function(defn) {
@@ -6678,7 +6691,10 @@ merge(Compressor.prototype, {
});
})
}) : self;
});
}
OPT(AST_Const, varify);
OPT(AST_Let, varify);
function lift_sequence_in_expression(node, compressor) {
var exp = node.expression;