diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-10-19 01:32:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-19 08:32:39 +0800 |
commit | 96bf7fceabf1670ca07c08a04a3130e742775c8f (patch) | |
tree | 71a28df4db6ce0ec1a5e0423dad6b74ab00fa065 /lib/compress.js | |
parent | 6c7226c10ef1328c726ce7c5d364efed8ed0d374 (diff) | |
download | tracifyjs-96bf7fceabf1670ca07c08a04a3130e742775c8f.tar.gz tracifyjs-96bf7fceabf1670ca07c08a04a3130e742775c8f.zip |
support `let` (#4227)
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/lib/compress.js b/lib/compress.js index 015ee306..d4be93ee 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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; |