babel-plugin-minify-dead-code-elimination
Advanced tools
Comparing version 0.4.0-alpha.6546ad11 to 0.4.0-alpha.f95869d4
451
lib/index.js
"use strict"; | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
@@ -12,2 +12,3 @@ var some = require("lodash.some"); | ||
var removeUseStrict = require("./remove-use-strict"); | ||
var evaluate = require("babel-helper-evaluate-path"); | ||
@@ -18,3 +19,2 @@ | ||
var siblings = []; | ||
var key = parentPath.key; | ||
@@ -25,2 +25,3 @@ | ||
} | ||
return siblings; | ||
@@ -40,9 +41,8 @@ } | ||
var removeOrVoid = require("babel-helper-remove-or-void")(t); | ||
var shouldRevisit = Symbol("shouldRevisit"); | ||
// this is used for tracking fn params that can be removed | ||
var shouldRevisit = Symbol("shouldRevisit"); // this is used for tracking fn params that can be removed | ||
// as traversal takes place from left and | ||
// unused params can be removed only on the right | ||
var markForRemoval = Symbol("markForRemoval"); | ||
var main = { | ||
@@ -70,3 +70,2 @@ // remove side effectless statement | ||
scope = path.scope; | ||
var seen = new Set(); | ||
@@ -78,2 +77,3 @@ var declars = []; | ||
var binding = scope.bindings[name]; | ||
if (!binding.path.isVariableDeclarator()) { | ||
@@ -84,5 +84,7 @@ return "continue"; | ||
var declarPath = binding.path.parentPath; | ||
if (seen.has(declarPath)) { | ||
return "continue"; | ||
} | ||
seen.add(declarPath); | ||
@@ -106,2 +108,3 @@ | ||
declars.push(declar); | ||
if (declar.init) { | ||
@@ -130,3 +133,3 @@ assignmentSequence.push(t.assignmentExpression("=", declar.id, declar.init)); | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return) { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return != null) { | ||
_iterator2.return(); | ||
@@ -168,8 +171,9 @@ } | ||
for (var _iterator = node.body.body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var statement = _step.value; | ||
var _statement = _step.value; | ||
if (t.isVariableDeclaration(statement)) { | ||
if (t.isVariableDeclaration(_statement)) { | ||
var _statement$declaratio; | ||
(_statement$declaratio = statement.declarations).push.apply(_statement$declaratio, declars); | ||
(_statement$declaratio = _statement.declarations).push.apply(_statement$declaratio, declars); | ||
return; | ||
@@ -183,3 +187,3 @@ } | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
if (!_iteratorNormalCompletion && _iterator.return != null) { | ||
_iterator.return(); | ||
@@ -198,4 +202,4 @@ } | ||
} | ||
}, | ||
// Remove bindings with no references. | ||
@@ -221,5 +225,3 @@ Scope: { | ||
var scope = path.scope; | ||
// if the scope is created by a function, we obtain its | ||
var scope = path.scope; // if the scope is created by a function, we obtain its | ||
// parameter list | ||
@@ -251,2 +253,3 @@ | ||
var _binding = scope.bindings[left.node.name]; | ||
if (_binding.referenced) { | ||
@@ -261,6 +264,6 @@ // when the first binding is referenced (right to left) | ||
} | ||
} | ||
} // other patterns - assignment, object have side-effects | ||
// and cannot be safely removed | ||
// other patterns - assignment, object have side-effects | ||
// and cannot be safely removed | ||
break; | ||
@@ -278,2 +281,3 @@ } | ||
var maybeBlockParent = declaration.parentPath; | ||
if (maybeBlockParent && maybeBlockParent.isForXStatement({ | ||
@@ -291,4 +295,3 @@ left: declaration.node | ||
return "continue"; | ||
} else if ( | ||
// ClassDeclaration has binding in two scopes | ||
} else if ( // ClassDeclaration has binding in two scopes | ||
// 1. The scope in which it is declared | ||
@@ -301,4 +304,4 @@ // 2. The class's own scope | ||
var mutations = []; | ||
var bail = false; | ||
// Make sure none of the assignments value is used | ||
var bail = false; // Make sure none of the assignments value is used | ||
binding.constantViolations.forEach(function (p) { | ||
@@ -332,7 +335,7 @@ if (bail || p === binding.path) { | ||
return "continue"; | ||
} | ||
// if declarator has some impure init expression | ||
} // if declarator has some impure init expression | ||
// var x = foo(); | ||
// => foo(); | ||
if (binding.path.node.init && !scope.isPure(binding.path.node.init) && binding.path.parentPath.node.declarations) { | ||
@@ -343,2 +346,3 @@ // binding path has more than one declarations | ||
} | ||
binding.path.parentPath.replaceWith(binding.path.node.init); | ||
@@ -360,3 +364,3 @@ } else { | ||
if (binding.path.isFunctionDeclaration() || binding.path.isVariableDeclarator() && binding.path.get("init").isFunction()) { | ||
var _ret4 = function () { | ||
var _ret3 = function () { | ||
var fun = binding.path.isFunctionDeclaration() ? binding.path : binding.path.get("init"); | ||
@@ -370,5 +374,5 @@ var allInside = true; | ||
for (var _iterator3 = binding.referencePaths[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | ||
var ref = _step3.value; | ||
var _ref2 = _step3.value; | ||
if (!ref.find(function (p) { | ||
if (!_ref2.find(function (p) { | ||
return p.node === fun.node; | ||
@@ -385,3 +389,3 @@ })) { | ||
try { | ||
if (!_iteratorNormalCompletion3 && _iterator3.return) { | ||
if (!_iteratorNormalCompletion3 && _iterator3.return != null) { | ||
_iterator3.return(); | ||
@@ -406,3 +410,3 @@ } | ||
if (typeof _ret4 === "object") return _ret4.v; | ||
if (typeof _ret3 === "object") return _ret3.v; | ||
} | ||
@@ -414,8 +418,8 @@ | ||
var isReferencedBefore = false; | ||
var refPath = binding.referencePaths[0]; | ||
if (t.isVariableDeclarator(replacement)) { | ||
var _prevSiblings = prevSiblings(replacementPath); | ||
// traverse ancestors of a reference checking if it's before declaration | ||
var _prevSiblings = prevSiblings(replacementPath); // traverse ancestors of a reference checking if it's before declaration | ||
forEachAncestor(refPath, function (ancestor) { | ||
@@ -425,20 +429,19 @@ if (_prevSiblings.indexOf(ancestor) > -1) { | ||
} | ||
}); | ||
// deopt if reference is in different scope than binding | ||
}); // deopt if reference is in different scope than binding | ||
// since we don't know if it's sync or async execution | ||
// (i.e. whether value has been assigned to a reference or not) | ||
if (isReferencedBefore && refPath.scope !== binding.scope) { | ||
return "continue"; | ||
} | ||
// simulate hoisting by replacing value | ||
} // simulate hoisting by replacing value | ||
// with undefined if declaration is after reference | ||
replacement = isReferencedBefore ? t.unaryExpression("void", t.numericLiteral(0), true) : replacement.init; | ||
// Bail out for ArrayPattern and ObjectPattern | ||
replacement = isReferencedBefore ? t.unaryExpression("void", t.numericLiteral(0), true) : replacement.init; // Bail out for ArrayPattern and ObjectPattern | ||
// TODO: maybe a more intelligent approach instead of simply bailing out | ||
if (!replacementPath.get("id").isIdentifier()) { | ||
return "continue"; | ||
} | ||
replacementPath = replacementPath.get("init"); | ||
@@ -458,7 +461,8 @@ } | ||
if (replacementPath.isIdentifier()) { | ||
var _binding2 = scope.getBinding(replacement.name); | ||
// the reference should be in the same scope | ||
var _binding2 = scope.getBinding(replacement.name); // the reference should be in the same scope | ||
// and the replacement should be a constant - this is to | ||
// ensure that the duplication of replacement is not affected | ||
// https://github.com/babel/minify/issues/685 | ||
_bail = !(_binding2 && refPath.scope.getBinding(replacement.name) === _binding2 && _binding2.constantViolations.length === 0); | ||
@@ -471,4 +475,4 @@ } else { | ||
ReferencedIdentifier(_ref2) { | ||
var node = _ref2.node; | ||
ReferencedIdentifier(_ref3) { | ||
var node = _ref3.node; | ||
@@ -478,3 +482,5 @@ if (_bail) { | ||
} | ||
var binding = scope.getBinding(node.name); | ||
if (binding && refPath.scope.getBinding(node.name) === binding) { | ||
@@ -484,2 +490,3 @@ _bail = binding.constantViolations.length > 0; | ||
} | ||
}); | ||
@@ -493,7 +500,6 @@ } | ||
var parent = binding.path.parent; | ||
if (t.isVariableDeclaration(parent)) { | ||
parent = binding.path.parentPath.parent; | ||
} | ||
// 1. Make sure we share the parent with the node. In other words it's lexically defined | ||
} // 1. Make sure we share the parent with the node. In other words it's lexically defined | ||
// and not in an if statement or otherwise. | ||
@@ -503,5 +509,7 @@ // 2. If the replacement is an object then we have to make sure we are not in a loop or a function | ||
// which would also could affect correctness in that they are not the same reference. | ||
var mayLoop = false; | ||
var sharesRoot = refPath.find(function (_ref3) { | ||
var node = _ref3.node; | ||
var sharesRoot = refPath.find(function (_ref4) { | ||
var node = _ref4.node; | ||
@@ -511,6 +519,6 @@ if (!mayLoop) { | ||
} | ||
return node === parent; | ||
}); | ||
}); // Anything that inherits from Object. | ||
// Anything that inherits from Object. | ||
var isObj = function isObj(n) { | ||
@@ -524,5 +532,3 @@ return t.isFunction(n) || t.isObjectExpression(n) || t.isArrayExpression(n); | ||
return "continue"; | ||
} | ||
// check if it's safe to replace | ||
} // check if it's safe to replace | ||
// To solve https://github.com/babel/minify/issues/691 | ||
@@ -534,2 +540,4 @@ // Here we bail for property checks using the "in" operator | ||
// all the binary "in" operations | ||
var inExpression = replacementPath.isBinaryExpression({ | ||
@@ -544,2 +552,3 @@ operator: "in" | ||
}, | ||
BinaryExpression(path) { | ||
@@ -551,2 +560,3 @@ if (path.node.operator === "in") { | ||
} | ||
}); | ||
@@ -568,2 +578,3 @@ } | ||
scope.removeBinding(name); | ||
if (binding.path.node) { | ||
@@ -578,7 +589,9 @@ removeOrVoid(binding.path); | ||
for (var name in scope.bindings) { | ||
var _ret3 = _loop3(name); | ||
var _ret2 = _loop3(name); | ||
if (_ret3 === "continue") continue; | ||
if (_ret2 === "continue") continue; | ||
} // end-for-of | ||
} | ||
}, | ||
@@ -589,3 +602,2 @@ | ||
var paths = path.get("body"); | ||
var purge = false; | ||
@@ -614,5 +626,5 @@ | ||
return; | ||
} | ||
} // Not last in its block? (See BlockStatement visitor) | ||
// Not last in its block? (See BlockStatement visitor) | ||
if (path.container.length - 1 !== path.key && !canExistAfterCompletion(path.getSibling(path.key + 1)) && path.parentPath.isBlockStatement()) { | ||
@@ -624,3 +636,2 @@ // This is probably a new oppurtinity by some other transform | ||
path.parentPath.popContext(); | ||
return; | ||
@@ -635,2 +646,3 @@ } | ||
var parentPath = path.parentPath; | ||
while (parentPath && !parentPath.isFunction() && noNext) { | ||
@@ -644,2 +656,3 @@ // https://github.com/babel/minify/issues/265 | ||
var nextPath = parentPath.getSibling(parentPath.key + 1); | ||
if (nextPath.node) { | ||
@@ -650,2 +663,3 @@ if (nextPath.isReturnStatement()) { | ||
nextPath.popContext(); | ||
if (parentPath.getSibling(parentPath.key + 1).node) { | ||
@@ -671,4 +685,4 @@ noNext = false; | ||
var node = path.node; | ||
var evaluateTest = path.get("test").evaluateTruthy(); | ||
var evaluateTest = path.get("test").evaluateTruthy(); | ||
if (evaluateTest === true) { | ||
@@ -683,9 +697,8 @@ path.replaceWith(node.consequent); | ||
exit(path) { | ||
var evaluated = evaluate(path.get("discriminant"), { tdz: this.tdz }); | ||
var evaluated = evaluate(path.get("discriminant"), { | ||
tdz: this.tdz | ||
}); | ||
if (!evaluated.confident) return; | ||
var discriminant = evaluated.value; | ||
var cases = path.get("cases"); | ||
var matchingCaseIndex = -1; | ||
@@ -695,5 +708,4 @@ var defaultCaseIndex = -1; | ||
for (var i = 0; i < cases.length; i++) { | ||
var test = cases[i].get("test"); | ||
var test = cases[i].get("test"); // handle default case | ||
// handle default case | ||
if (test.node === null) { | ||
@@ -704,6 +716,7 @@ defaultCaseIndex = i; | ||
var testResult = evaluate(test, { tdz: this.tdz }); | ||
var testResult = evaluate(test, { | ||
tdz: this.tdz | ||
}); // if we are not able to deternine a test during | ||
// compile time, we terminate immediately | ||
// if we are not able to deternine a test during | ||
// compile time, we terminate immediately | ||
if (!testResult.confident) return; | ||
@@ -717,3 +730,3 @@ | ||
var result = void 0; | ||
var result; | ||
@@ -732,9 +745,8 @@ if (matchingCaseIndex === -1) { | ||
if (result.bail) return; | ||
// we extract vars from the entire switch statement | ||
if (result.bail) return; // we extract vars from the entire switch statement | ||
// and there will be duplicates which | ||
// will be again removed by DCE | ||
replaceSwitch([].concat(_toConsumableArray(extractVars(path)), _toConsumableArray(result.statements))); | ||
replaceSwitch(_toConsumableArray(extractVars(path)).concat(_toConsumableArray(result.statements))); | ||
function getStatementsUntilBreak(start) { | ||
@@ -751,2 +763,3 @@ var result = { | ||
var _isBreaking = isBreaking(consequent[j], path); | ||
if (_isBreaking.bail) { | ||
@@ -756,2 +769,3 @@ result.bail = true; | ||
} | ||
if (_isBreaking.break) { | ||
@@ -774,7 +788,12 @@ // compute no more | ||
for (var _i2 = 0; _i2 < statements.length; _i2++) { | ||
if (t.isVariableDeclaration(statements[_i2], { kind: "let" })) { | ||
if (t.isVariableDeclaration(statements[_i2], { | ||
kind: "let" | ||
})) { | ||
isBlockRequired = true; | ||
break; | ||
} | ||
if (t.isVariableDeclaration(statements[_i2], { kind: "const" })) { | ||
if (t.isVariableDeclaration(statements[_i2], { | ||
kind: "const" | ||
})) { | ||
isBlockRequired = true; | ||
@@ -792,2 +811,3 @@ break; | ||
} | ||
}, | ||
@@ -797,3 +817,6 @@ | ||
var test = path.get("test"); | ||
var result = evaluate(test, { tdz: this.tdz }); | ||
var result = evaluate(test, { | ||
tdz: this.tdz | ||
}); | ||
if (result.confident && test.isPure() && !result.value) { | ||
@@ -807,4 +830,6 @@ path.remove(); | ||
if (!test.isPure()) return; | ||
var result = evaluate(test, { | ||
tdz: this.tdz | ||
}); | ||
var result = evaluate(test, { tdz: this.tdz }); | ||
if (result.confident) { | ||
@@ -821,3 +846,6 @@ if (result.value) { | ||
var test = path.get("test"); | ||
var result = evaluate(test, { tdz: this.tdz }); | ||
var result = evaluate(test, { | ||
tdz: this.tdz | ||
}); | ||
if (result.confident && test.isPure() && !result.value) { | ||
@@ -834,7 +862,10 @@ var body = path.get("body"); | ||
for (var _iterator4 = stmts[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { | ||
var stmt = _step4.value; | ||
var _stmt = _step4.value; | ||
var _isBreaking = isBreaking(stmt, path); | ||
var _isBreaking = isBreaking(_stmt, path); | ||
if (_isBreaking.bail || _isBreaking.break) return; | ||
var _isContinuing = isContinuing(stmt, path); | ||
var _isContinuing = isContinuing(_stmt, path); | ||
if (_isContinuing.bail || isContinuing.continue) return; | ||
@@ -847,3 +878,3 @@ } | ||
try { | ||
if (!_iteratorNormalCompletion4 && _iterator4.return) { | ||
if (!_iteratorNormalCompletion4 && _iterator4.return != null) { | ||
_iterator4.return(); | ||
@@ -861,2 +892,3 @@ } | ||
var _isBreaking2 = isBreaking(body, path); | ||
if (_isBreaking2.bail) return; | ||
@@ -880,2 +912,3 @@ if (_isBreaking2.break) path.remove(); | ||
var prev = path.parentPath.getSibling(path.parentPath.key - 1); | ||
if (!(prev && prev.isVariableDeclaration())) { | ||
@@ -886,5 +919,7 @@ return; | ||
var declars = prev.node.declarations; | ||
if (declars.length !== 1 || declars[0].init || declars[0].id.name !== path.get("left").node.name) { | ||
return; | ||
} | ||
declars[0].init = path.node.right; | ||
@@ -912,2 +947,3 @@ removeOrVoid(path); | ||
var left = path.get("left"); | ||
if (!left.isIdentifier()) { | ||
@@ -918,2 +954,3 @@ return; | ||
var binding = path.scope.getBinding(left.node.name); | ||
if (!binding) { | ||
@@ -935,10 +972,10 @@ return; | ||
return; | ||
} | ||
} // If it has company then it's probably more efficient to keep. | ||
// If it has company then it's probably more efficient to keep. | ||
if (binding.path.parent.declarations.length > 1) { | ||
return; | ||
} | ||
} // meh | ||
// meh | ||
if (binding.path.node.init) { | ||
@@ -952,4 +989,4 @@ return; | ||
} | ||
}; | ||
return { | ||
@@ -965,2 +1002,3 @@ name: "minify-dead-code-elimination", | ||
var body = path.get("body"); | ||
if (body.isBlockStatement()) { | ||
@@ -970,23 +1008,22 @@ removeUseStrict(body); | ||
} | ||
}, | ||
IfStatement: { | ||
exit(path, _ref4) { | ||
var _ref4$opts = _ref4.opts; | ||
_ref4$opts = _ref4$opts === undefined ? {} : _ref4$opts; | ||
var _ref4$opts$tdz = _ref4$opts.tdz, | ||
tdz = _ref4$opts$tdz === undefined ? false : _ref4$opts$tdz; | ||
exit(path, _ref5) { | ||
var _ref5$opts = _ref5.opts; | ||
_ref5$opts = _ref5$opts === void 0 ? {} : _ref5$opts; | ||
var _ref5$opts$tdz = _ref5$opts.tdz, | ||
tdz = _ref5$opts$tdz === void 0 ? false : _ref5$opts$tdz; | ||
var consequent = path.get("consequent"); | ||
var alternate = path.get("alternate"); | ||
var test = path.get("test"); | ||
var evalResult = evaluate(test, { tdz }); | ||
var evalResult = evaluate(test, { | ||
tdz | ||
}); | ||
var isPure = test.isPure(); | ||
var replacements = []; | ||
var replacements = []; | ||
if (evalResult.confident && !isPure && test.isSequenceExpression()) { | ||
replacements.push(t.expressionStatement(extractSequenceImpure(test))); | ||
} | ||
// we can check if a test will be truthy 100% and if so then we can inline | ||
} // we can check if a test will be truthy 100% and if so then we can inline | ||
// the consequent and completely ignore the alternate | ||
@@ -997,8 +1034,8 @@ // | ||
// | ||
if (evalResult.confident && evalResult.value) { | ||
path.replaceWithMultiple([].concat(replacements, _toConsumableArray(toStatements(consequent)), _toConsumableArray(extractVars(alternate)))); | ||
path.replaceWithMultiple(replacements.concat(_toConsumableArray(toStatements(consequent)), _toConsumableArray(extractVars(alternate)))); | ||
return; | ||
} | ||
// we can check if a test will be falsy 100% and if so we can inline the | ||
} // we can check if a test will be falsy 100% and if so we can inline the | ||
// alternate if there is one and completely remove the consequent | ||
@@ -1009,22 +1046,22 @@ // | ||
// | ||
if (evalResult.confident && !evalResult.value) { | ||
if (alternate.node) { | ||
path.replaceWithMultiple([].concat(replacements, _toConsumableArray(toStatements(alternate)), _toConsumableArray(extractVars(consequent)))); | ||
path.replaceWithMultiple(replacements.concat(_toConsumableArray(toStatements(alternate)), _toConsumableArray(extractVars(consequent)))); | ||
return; | ||
} else { | ||
path.replaceWithMultiple([].concat(replacements, _toConsumableArray(extractVars(consequent)))); | ||
path.replaceWithMultiple(replacements.concat(_toConsumableArray(extractVars(consequent)))); | ||
} | ||
} | ||
// remove alternate blocks that are empty | ||
} // remove alternate blocks that are empty | ||
// | ||
// if (foo) { foo; } else {} -> if (foo) { foo; } | ||
// | ||
if (alternate.isBlockStatement() && !alternate.node.body.length) { | ||
alternate.remove(); | ||
// For if-statements babel-traverse replaces with an empty block | ||
alternate.remove(); // For if-statements babel-traverse replaces with an empty block | ||
path.node.alternate = null; | ||
} | ||
// if the consequent block is empty turn alternate blocks into a consequent | ||
} // if the consequent block is empty turn alternate blocks into a consequent | ||
// and flip the test | ||
@@ -1034,6 +1071,8 @@ // | ||
// | ||
if (consequent.isBlockStatement() && !consequent.node.body.length && alternate.isBlockStatement() && alternate.node.body.length) { | ||
consequent.replaceWith(alternate.node); | ||
alternate.remove(); | ||
// For if-statements babel-traverse replaces with an empty block | ||
alternate.remove(); // For if-statements babel-traverse replaces with an empty block | ||
path.node.alternate = null; | ||
@@ -1043,2 +1082,3 @@ test.replaceWith(t.unaryExpression("!", test.node, true)); | ||
} | ||
}, | ||
@@ -1054,23 +1094,20 @@ | ||
exit(path) { | ||
var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, | ||
_ref5$opts = _ref5.opts; | ||
var _ref6 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, | ||
_ref6$opts = _ref6.opts; | ||
_ref5$opts = _ref5$opts === undefined ? {} : _ref5$opts; | ||
var _ref5$opts$optimizeRa = _ref5$opts.optimizeRawSize, | ||
optimizeRawSize = _ref5$opts$optimizeRa === undefined ? false : _ref5$opts$optimizeRa, | ||
_ref5$opts$keepFnName = _ref5$opts.keepFnName, | ||
keepFnName = _ref5$opts$keepFnName === undefined ? false : _ref5$opts$keepFnName, | ||
_ref5$opts$keepClassN = _ref5$opts.keepClassName, | ||
keepClassName = _ref5$opts$keepClassN === undefined ? false : _ref5$opts$keepClassN, | ||
_ref5$opts$keepFnArgs = _ref5$opts.keepFnArgs, | ||
keepFnArgs = _ref5$opts$keepFnArgs === undefined ? false : _ref5$opts$keepFnArgs, | ||
_ref5$opts$tdz = _ref5$opts.tdz, | ||
tdz = _ref5$opts$tdz === undefined ? false : _ref5$opts$tdz; | ||
_ref6$opts = _ref6$opts === void 0 ? {} : _ref6$opts; | ||
var _ref6$opts$optimizeRa = _ref6$opts.optimizeRawSize, | ||
optimizeRawSize = _ref6$opts$optimizeRa === void 0 ? false : _ref6$opts$optimizeRa, | ||
_ref6$opts$keepFnName = _ref6$opts.keepFnName, | ||
keepFnName = _ref6$opts$keepFnName === void 0 ? false : _ref6$opts$keepFnName, | ||
_ref6$opts$keepClassN = _ref6$opts.keepClassName, | ||
keepClassName = _ref6$opts$keepClassN === void 0 ? false : _ref6$opts$keepClassN, | ||
_ref6$opts$keepFnArgs = _ref6$opts.keepFnArgs, | ||
keepFnArgs = _ref6$opts$keepFnArgs === void 0 ? false : _ref6$opts$keepFnArgs, | ||
_ref6$opts$tdz = _ref6$opts.tdz, | ||
tdz = _ref6$opts$tdz === void 0 ? false : _ref6$opts$tdz; | ||
(traverse.clearCache || traverse.cache.clear)(); | ||
path.scope.crawl(); | ||
markEvalScopes(path); // We need to run this plugin in isolation. | ||
markEvalScopes(path); | ||
// We need to run this plugin in isolation. | ||
path.traverse(main, { | ||
@@ -1085,2 +1122,3 @@ functionToBindings: new Map(), | ||
} | ||
} | ||
@@ -1098,2 +1136,3 @@ } | ||
var bodyNode = node.body[i]; | ||
if (t.isBlockScoped(bodyNode)) { | ||
@@ -1108,6 +1147,5 @@ hasBlockScoped = true; | ||
} | ||
return [node]; | ||
} | ||
// Extracts vars from a path | ||
} // Extracts vars from a path | ||
// Useful for removing blocks or paths that can contain | ||
@@ -1118,6 +1156,10 @@ // variable declarations inside them | ||
// extractVars({ var x = 5, y = x }) => var x, y; | ||
function extractVars(path) { | ||
var declarators = []; | ||
if (path.isVariableDeclaration({ kind: "var" })) { | ||
if (path.isVariableDeclaration({ | ||
kind: "var" | ||
})) { | ||
var _iteratorNormalCompletion5 = true; | ||
@@ -1129,6 +1171,4 @@ var _didIteratorError5 = false; | ||
for (var _iterator5 = path.node.declarations[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { | ||
var decl = _step5.value; | ||
var bindingIds = Object.keys(t.getBindingIdentifiers(decl.id)); | ||
var _decl = _step5.value; | ||
var bindingIds = Object.keys(t.getBindingIdentifiers(_decl.id)); | ||
declarators.push.apply(declarators, _toConsumableArray(bindingIds.map(function (name) { | ||
@@ -1143,3 +1183,3 @@ return t.variableDeclarator(t.identifier(name)); | ||
try { | ||
if (!_iteratorNormalCompletion5 && _iterator5.return) { | ||
if (!_iteratorNormalCompletion5 && _iterator5.return != null) { | ||
_iterator5.return(); | ||
@@ -1156,5 +1196,6 @@ } | ||
VariableDeclaration(varPath) { | ||
if (!varPath.isVariableDeclaration({ kind: "var" })) return; | ||
if (!varPath.isVariableDeclaration({ | ||
kind: "var" | ||
})) return; | ||
if (!isSameFunctionScope(varPath, path)) return; | ||
var _iteratorNormalCompletion6 = true; | ||
@@ -1166,6 +1207,7 @@ var _didIteratorError6 = false; | ||
for (var _iterator6 = varPath.node.declarations[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { | ||
var _decl = _step6.value; | ||
var _decl3 = _step6.value; | ||
var _bindingIds = Object.keys(t.getBindingIdentifiers(_decl.id)); | ||
declarators.push.apply(declarators, _toConsumableArray(_bindingIds.map(function (name) { | ||
var _bindingIds2 = Object.keys(t.getBindingIdentifiers(_decl3.id)); | ||
declarators.push.apply(declarators, _toConsumableArray(_bindingIds2.map(function (name) { | ||
return t.variableDeclarator(t.identifier(name)); | ||
@@ -1179,3 +1221,3 @@ }))); | ||
try { | ||
if (!_iteratorNormalCompletion6 && _iterator6.return) { | ||
if (!_iteratorNormalCompletion6 && _iterator6.return != null) { | ||
_iterator6.return(); | ||
@@ -1190,2 +1232,3 @@ } | ||
} | ||
}); | ||
@@ -1195,3 +1238,2 @@ } | ||
if (declarators.length <= 0) return []; | ||
return [t.variableDeclaration("var", declarators)]; | ||
@@ -1204,13 +1246,11 @@ } | ||
scope = options.scope, | ||
binding = options.binding; | ||
binding = options.binding; // Same name, different binding. | ||
// Same name, different binding. | ||
if (scope.getBinding(path.node.name) !== binding) { | ||
return; | ||
} | ||
// We don't want to move code around to different scopes because: | ||
} // We don't want to move code around to different scopes because: | ||
// 1. Original bindings that is referenced could be shadowed | ||
// 2. Moving defintions to potentially hot code is bad | ||
if (scope !== path.scope) { | ||
@@ -1227,5 +1267,7 @@ if (t.isClass(replacement) || t.isFunction(replacement)) { | ||
} | ||
bail = true; | ||
path.stop(); | ||
} | ||
}, scope); | ||
@@ -1236,17 +1278,18 @@ | ||
} | ||
} | ||
} // Avoid recursion. | ||
// Avoid recursion. | ||
if (path.find(function (_ref6) { | ||
var node = _ref6.node; | ||
if (path.find(function (_ref7) { | ||
var node = _ref7.node; | ||
return node === replacement; | ||
})) { | ||
return; | ||
} | ||
// https://github.com/babel/minify/issues/611 | ||
} // https://github.com/babel/minify/issues/611 | ||
// this is valid only for FunctionDeclaration where we convert | ||
// function declaration to expression in the next step | ||
if (replacementPath.isFunctionDeclaration()) { | ||
var fnName = replacementPath.get("id").node.name; | ||
for (var name in replacementPath.scope.bindings) { | ||
@@ -1257,10 +1300,8 @@ if (name === fnName) { | ||
} | ||
} | ||
} // https://github.com/babel/minify/issues/130 | ||
// https://github.com/babel/minify/issues/130 | ||
if (!t.isExpression(replacement)) { | ||
t.toExpression(replacement); | ||
} | ||
// We don't remove fn name here, we let the FnExpr & ClassExpr visitors | ||
} // We don't remove fn name here, we let the FnExpr & ClassExpr visitors | ||
// check its references and remove unreferenced ones | ||
@@ -1271,2 +1312,3 @@ // if (t.isFunction(replacement)) { | ||
path.replaceWith(replacement); | ||
@@ -1285,3 +1327,2 @@ return true; | ||
scope = path.scope; | ||
var binding = scope.getBinding(node.name); | ||
@@ -1294,7 +1335,10 @@ | ||
var index = binding.referencePaths.indexOf(path); | ||
if (index === -1) { | ||
return; | ||
} | ||
binding.references--; | ||
binding.referencePaths.splice(index, 1); | ||
if (binding.references === 0) { | ||
@@ -1308,2 +1352,3 @@ binding.referenced = false; | ||
} | ||
}); | ||
@@ -1314,2 +1359,3 @@ } | ||
var id = path.get("id").node; | ||
if (!id) { | ||
@@ -1321,13 +1367,11 @@ return; | ||
scope = path.scope; | ||
var binding = scope.getBinding(id.name); // Check if shadowed or is not referenced. | ||
var binding = scope.getBinding(id.name); | ||
// Check if shadowed or is not referenced. | ||
if (binding && (binding.path.node !== node || !binding.referenced)) { | ||
node.id = null; | ||
} | ||
} | ||
} // path1 -> path2 | ||
// is path1 an ancestor of path2 | ||
// path1 -> path2 | ||
// is path1 an ancestor of path2 | ||
function isAncestor(path1, path2) { | ||
@@ -1349,5 +1393,5 @@ return !!path2.findParent(function (parent) { | ||
return isControlTransfer(stmt, path, "continue"); | ||
} | ||
} // tells if a "stmt" is a break/continue statement | ||
// tells if a "stmt" is a break/continue statement | ||
function isControlTransfer(stmt, path) { | ||
@@ -1364,2 +1408,3 @@ var control = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "break"; | ||
} | ||
var checker = `is${type}`; | ||
@@ -1376,3 +1421,2 @@ | ||
}; | ||
stmt.traverse({ | ||
@@ -1382,3 +1426,2 @@ [type](cPath) { | ||
if (isTransferred) return; | ||
result = _isControlTransfer(cPath, path); | ||
@@ -1390,4 +1433,4 @@ | ||
} | ||
}); | ||
return result; | ||
@@ -1407,8 +1450,9 @@ | ||
}; | ||
} | ||
// here we handle the break labels | ||
} // here we handle the break labels | ||
// if they are outside switch, we bail out | ||
// if they are within the case, we keep them | ||
var labelPath = void 0; | ||
var labelPath; | ||
if (path.scope.getLabel) { | ||
@@ -1419,2 +1463,3 @@ labelPath = getLabel(label.node.name, path); | ||
} | ||
var _isAncestor = isAncestor(labelPath, path); | ||
@@ -1426,12 +1471,10 @@ | ||
}; | ||
} | ||
} // set the flag that it is indeed breaking | ||
// set the flag that it is indeed breaking | ||
var isCTransfer = true; | ||
// this flag is to capture | ||
var isCTransfer = true; // this flag is to capture | ||
// switch(0) { case 0: while(1) if (x) break; } | ||
var possibleRunTimeControlTransfer = false; | ||
// and compute if it's breaking the correct thing | ||
var possibleRunTimeControlTransfer = false; // and compute if it's breaking the correct thing | ||
var parent = cPath.parentPath; | ||
@@ -1444,9 +1487,7 @@ | ||
// while (1) { if (x) break; } | ||
possibleRunTimeControlTransfer = false; | ||
possibleRunTimeControlTransfer = false; // and set that it's not breaking our switch statement | ||
// and set that it's not breaking our switch statement | ||
isCTransfer = false; | ||
break; | ||
} | ||
// | ||
} // | ||
// this is a special case and depends on | ||
@@ -1466,5 +1507,8 @@ // the fact that SwitchStatement is handled in the | ||
// | ||
if (parent.isIfStatement()) { | ||
possibleRunTimeControlTransfer = true; | ||
} | ||
parent = parent.parentPath; | ||
@@ -1478,14 +1522,18 @@ } | ||
} | ||
} | ||
} // things that are hoisted | ||
// things that are hoisted | ||
function canExistAfterCompletion(path) { | ||
return path.isFunctionDeclaration() || path.isVariableDeclaration({ kind: "var" }); | ||
return path.isFunctionDeclaration() || path.isVariableDeclaration({ | ||
kind: "var" | ||
}); | ||
} | ||
function getLabel(name, _path) { | ||
var label = void 0, | ||
var label, | ||
path = _path; | ||
do { | ||
label = path.scope.getLabel(name); | ||
if (label) { | ||
@@ -1495,2 +1543,3 @@ return label; | ||
} while (path = path.parentPath); | ||
return null; | ||
@@ -1501,2 +1550,3 @@ } | ||
var parent = path; | ||
do { | ||
@@ -1507,2 +1557,3 @@ if (parent.isLoop()) { | ||
} while (parent = parent.parentPath); | ||
return false; | ||
@@ -1514,2 +1565,3 @@ } | ||
var result = []; | ||
for (var i = 0; i < expressions.length; i++) { | ||
@@ -1520,4 +1572,5 @@ if (!expressions[i].isPure()) { | ||
} | ||
return t.sequenceExpression(result); | ||
} | ||
}; |
"use strict"; | ||
module.exports = removeUseStrict; | ||
var newIssueUrl = "https://github.com/babel/minify/issues/new"; | ||
var useStrict = "use strict"; | ||
/** | ||
@@ -16,2 +13,3 @@ * Remove redundant use strict | ||
*/ | ||
function removeUseStrict(block) { | ||
@@ -22,8 +20,6 @@ if (!block.isBlockStatement()) { | ||
var useStricts = getUseStrictDirectives(block); | ||
var useStricts = getUseStrictDirectives(block); // early exit | ||
// early exit | ||
if (useStricts.length < 1) return; | ||
if (useStricts.length < 1) return; // only keep the first use strict | ||
// only keep the first use strict | ||
if (useStricts.length > 1) { | ||
@@ -33,5 +29,5 @@ for (var i = 1; i < useStricts.length; i++) { | ||
} | ||
} | ||
} // check if parent has an use strict | ||
// check if parent has an use strict | ||
if (hasStrictParent(block)) { | ||
@@ -38,0 +34,0 @@ useStricts[0].remove(); |
{ | ||
"name": "babel-plugin-minify-dead-code-elimination", | ||
"version": "0.4.0-alpha.6546ad11", | ||
"version": "0.4.0-alpha.f95869d4", | ||
"description": "", | ||
@@ -15,7 +15,7 @@ "keywords": [ | ||
"dependencies": { | ||
"babel-helper-evaluate-path": "^0.4.0-alpha.6546ad11", | ||
"babel-helper-mark-eval-scopes": "^0.4.0-alpha.6546ad11", | ||
"babel-helper-remove-or-void": "^0.4.0-alpha.6546ad11", | ||
"babel-helper-evaluate-path": "^0.4.0-alpha.f95869d4", | ||
"babel-helper-mark-eval-scopes": "^0.4.0-alpha.f95869d4", | ||
"babel-helper-remove-or-void": "^0.4.0-alpha.f95869d4", | ||
"lodash.some": "^4.6.0" | ||
} | ||
} |
@@ -64,3 +64,3 @@ # babel-plugin-minify-dead-code-elimination | ||
```javascript | ||
require("babel-core").transform("code", { | ||
require("@babel/core").transform("code", { | ||
plugins: ["minify-dead-code-elimination"] | ||
@@ -67,0 +67,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
48117
1210