diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-01-01 13:52:14 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-01 21:52:14 +0800 |
commit | 0417a69c3ef4922470b6891ad6039221059f5750 (patch) | |
tree | 5329008311c7303f54bc821aace798b7c47dd8e1 /lib/compress.js | |
parent | 2dbafbb4ee9c5cb82665299ee9343c80e96daad4 (diff) | |
download | tracifyjs-0417a69c3ef4922470b6891ad6039221059f5750.tar.gz tracifyjs-0417a69c3ef4922470b6891ad6039221059f5750.zip |
enhance `collapse_vars` & `dead_code` (#4491)
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/lib/compress.js b/lib/compress.js index bd98c306..0a560dda 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1204,10 +1204,8 @@ merge(Compressor.prototype, { }); AST_SymbolRef.DEFMETHOD("is_immutable", function() { - var def = this.definition(); - if (def.orig.length != 1) return false; - var sym = def.orig[0]; - return sym instanceof AST_SymbolLambda && def.scope.name === sym; + var def = this.redef || this.definition(); + return def.orig.length == 1 && def.orig[0] instanceof AST_SymbolLambda; }); AST_Node.DEFMETHOD("convert_symbol", noop); @@ -1296,8 +1294,9 @@ merge(Compressor.prototype, { function is_lhs_read_only(lhs, compressor) { if (lhs instanceof AST_This) return true; if (lhs instanceof AST_SymbolRef) { + if (lhs.is_immutable()) return true; var def = lhs.definition(); - return def.lambda || compressor.exposed(def) && identifier_atom[def.name]; + return compressor.exposed(def) && identifier_atom[def.name]; } if (lhs instanceof AST_PropAccess) { lhs = lhs.expression; @@ -1440,10 +1439,6 @@ merge(Compressor.prototype, { return node instanceof AST_SymbolRef && node.definition().undeclared; } - function get_rvalue(expr) { - return expr[expr instanceof AST_Assign ? "right" : "value"]; - } - var global_names = makePredicate("Array Boolean clearInterval clearTimeout console Date decodeURI decodeURIComponent encodeURI encodeURIComponent Error escape eval EvalError Function isFinite isNaN JSON Math Number parseFloat parseInt RangeError ReferenceError RegExp Object setInterval setTimeout String SyntaxError TypeError unescape URIError"); AST_SymbolRef.DEFMETHOD("is_declared", function(compressor) { return this.defined @@ -1580,6 +1575,15 @@ merge(Compressor.prototype, { line: node.start.line, col: node.start.col, }); + if (candidate.TYPE == "Binary") return make_node(AST_Assign, candidate, { + operator: "=", + left: candidate.right.left, + right: make_node(AST_Conditional, candidate, { + condition: candidate.operator == "&&" ? candidate.left : candidate.left.negate(compressor), + consequent: candidate.right.right, + alternative: node, + }), + }); if (candidate instanceof AST_UnaryPostfix) { if (lhs instanceof AST_SymbolRef) lhs.definition().fixed = false; return make_node(AST_UnaryPrefix, candidate, candidate); @@ -2004,10 +2008,12 @@ merge(Compressor.prototype, { } } - function extract_candidates(expr) { + function extract_candidates(expr, unused) { hit_stack.push(expr); if (expr instanceof AST_Array) { - expr.elements.forEach(extract_candidates); + expr.elements.forEach(function(node) { + extract_candidates(node, unused); + }); } else if (expr instanceof AST_Assign) { if (!(expr.left instanceof AST_Destructured)) candidates.push(hit_stack.slice()); extract_candidates(expr.left); @@ -2016,10 +2022,18 @@ merge(Compressor.prototype, { assignments[expr.left.name] = (assignments[expr.left.name] || 0) + 1; } } else if (expr instanceof AST_Await) { - extract_candidates(expr.expression); + extract_candidates(expr.expression, unused); } else if (expr instanceof AST_Binary) { - extract_candidates(expr.left); - extract_candidates(expr.right); + var lazy = lazy_op[expr.operator]; + if (unused + && lazy + && expr.right instanceof AST_Assign + && expr.right.operator == "=" + && !(expr.right.left instanceof AST_Destructured)) { + candidates.push(hit_stack.slice()); + } + extract_candidates(expr.left, !lazy && unused); + extract_candidates(expr.right, unused); } else if (expr instanceof AST_Call) { extract_candidates(expr.expression); expr.args.forEach(extract_candidates); @@ -2027,8 +2041,8 @@ merge(Compressor.prototype, { extract_candidates(expr.expression); } else if (expr instanceof AST_Conditional) { extract_candidates(expr.condition); - extract_candidates(expr.consequent); - extract_candidates(expr.alternative); + extract_candidates(expr.consequent, unused); + extract_candidates(expr.alternative, unused); } else if (expr instanceof AST_Definitions) { expr.definitions.forEach(extract_candidates); } else if (expr instanceof AST_Dot) { @@ -2041,9 +2055,9 @@ merge(Compressor.prototype, { } else if (expr instanceof AST_Exit) { if (expr.value) extract_candidates(expr.value); } else if (expr instanceof AST_For) { - if (expr.init) extract_candidates(expr.init); + if (expr.init) extract_candidates(expr.init, true); if (expr.condition) extract_candidates(expr.condition); - if (expr.step) extract_candidates(expr.step); + if (expr.step) extract_candidates(expr.step, true); if (!(expr.body instanceof AST_Block)) { extract_candidates(expr.body); } @@ -2064,13 +2078,16 @@ merge(Compressor.prototype, { expr.properties.forEach(function(prop) { hit_stack.push(prop); if (prop.key instanceof AST_Node) extract_candidates(prop.key); - if (prop instanceof AST_ObjectKeyVal) extract_candidates(prop.value); + if (prop instanceof AST_ObjectKeyVal) extract_candidates(prop.value, unused); hit_stack.pop(); }); } else if (expr instanceof AST_Sequence) { - expr.expressions.forEach(extract_candidates); + var end = expr.expressions.length - (unused ? 0 : 1); + expr.expressions.forEach(function(node, index) { + extract_candidates(node, index < end); + }); } else if (expr instanceof AST_SimpleStatement) { - extract_candidates(expr.body); + extract_candidates(expr.body, true); } else if (expr instanceof AST_Spread) { extract_candidates(expr.expression); } else if (expr instanceof AST_Sub) { @@ -2269,6 +2286,19 @@ merge(Compressor.prototype, { } function get_lhs(expr) { + if (expr instanceof AST_Assign) { + var def, lhs = expr.left; + if (expr.operator == "=" + && lhs instanceof AST_SymbolRef + && (def = lhs.definition()).references[0] === lhs + && !compressor.exposed(def)) { + var referenced = def.references.length - def.replaced; + if (referenced > 1) mangleable_var(expr.right); + } + return lhs; + } + if (expr instanceof AST_Binary) return expr.right.left; + if (expr instanceof AST_Unary) return expr.expression; if (expr instanceof AST_VarDef) { var def = expr.name.definition(); if (def.const_redefs) return; @@ -2282,19 +2312,18 @@ merge(Compressor.prototype, { if (mangleable_var(expr.value) || referenced == 1 && !compressor.exposed(def)) { return make_node(AST_SymbolRef, expr.name, expr.name); } - } else if (expr instanceof AST_Assign) { - var def, lhs = expr.left; - if (expr.operator == "=" - && lhs instanceof AST_SymbolRef - && (def = lhs.definition()).references[0] === lhs - && !compressor.exposed(def)) { - var referenced = def.references.length - def.replaced; - if (referenced > 1) mangleable_var(expr.right); - } - return lhs; - } else { - return expr.expression; + return; + } + } + + function get_rvalue(expr) { + if (expr instanceof AST_Assign) return expr.right; + if (expr instanceof AST_Binary) { + var node = expr.clone(); + node.right = expr.right.right; + return node; } + if (expr instanceof AST_VarDef) return expr.value; } function invariant(expr) { @@ -5890,6 +5919,10 @@ merge(Compressor.prototype, { }; } + function get_rvalue(expr) { + return expr[expr instanceof AST_Assign ? "right" : "value"]; + } + function insert_statements(body, orig, in_list) { switch (body.length) { case 0: @@ -9651,6 +9684,7 @@ merge(Compressor.prototype, { return strip_assignment(); } } while (parent instanceof AST_Binary && parent.right === node + || parent instanceof AST_Conditional && parent.condition !== node || parent instanceof AST_Sequence && parent.tail_node() === node || parent instanceof AST_UnaryPrefix); } |