diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2026-05-18 23:10:59 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2026-05-18 23:41:44 +0800 |
| commit | fc87c009806dcc98867f6b58efe29b042aa01dee (patch) | |
| tree | 8f59b3f4a5b66e9dfef2d40c8d318e258a521228 /node_modules/babel-plugin-minify-dead-code-elimination | |
| parent | 3336b2356ee6152d9c6ae59bd9b87ccbc0958407 (diff) | |
node: updatemain
Diffstat (limited to 'node_modules/babel-plugin-minify-dead-code-elimination')
5 files changed, 0 insertions, 1561 deletions
diff --git a/node_modules/babel-plugin-minify-dead-code-elimination/LICENSE b/node_modules/babel-plugin-minify-dead-code-elimination/LICENSE deleted file mode 100644 index f9f0a7f3..00000000 --- a/node_modules/babel-plugin-minify-dead-code-elimination/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2015-2016 Amjad Masad <amjad.masad@gmail.com> - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/babel-plugin-minify-dead-code-elimination/README.md b/node_modules/babel-plugin-minify-dead-code-elimination/README.md deleted file mode 100644 index 61a61727..00000000 --- a/node_modules/babel-plugin-minify-dead-code-elimination/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# babel-plugin-minify-dead-code-elimination - -Inlines bindings when possible. Tries to evaluate expressions and prunes unreachable as a result. - -## Example - -**In** - -```javascript -function foo() {var x = 1;} -function bar() { var x = f(); } -function baz() { - var x = 1; - console.log(x); - function unused() { - return 5; - } -} -``` - -**Out** - -```javascript -function foo() {} -function bar() { f(); } -function baz() { - console.log(1); -} -``` - -## Installation - -```sh -npm install babel-plugin-minify-dead-code-elimination --save-dev -``` - -## Usage - -### Via `.babelrc` (Recommended) - -**.babelrc** - -```json -// without options -{ - "plugins": ["minify-dead-code-elimination"] -} - -// with options -{ - "plugins": ["minify-dead-code-elimination", { "optimizeRawSize": true }] -} -``` - -### Via CLI - -```sh -babel --plugins minify-dead-code-elimination script.js -``` - -### Via Node API - -```javascript -require("@babel/core").transform("code", { - plugins: ["minify-dead-code-elimination"] -}); -``` - -## Options - -+ `keepFnName` - prevent plugin from removing function name. Useful for code depending on `fn.name` -+ `keepFnArgs` - prevent plugin from removing function args. Useful for code depending on `fn.length` -+ `keepClassName` - prevent plugin from removing class name. Useful for code depending on `cls.name` -+ `tdz` - Account for TDZ (Temporal Dead Zone) diff --git a/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js b/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js deleted file mode 100644 index d49e362c..00000000 --- a/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js +++ /dev/null @@ -1,1396 +0,0 @@ -"use strict"; - -function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } - -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } - -const some = require("lodash/some"); - -const _require = require("babel-helper-mark-eval-scopes"), - markEvalScopes = _require.markEvalScopes, - hasEval = _require.hasEval; - -const removeUseStrict = require("./remove-use-strict"); - -const evaluate = require("babel-helper-evaluate-path"); - -function evaluateTruthy(path) { - const res = evaluate(path); - if (res.confident) return !!res.value; -} - -function prevSiblings(path) { - const parentPath = path.parentPath; - const siblings = []; - let key = parentPath.key; - - while ((path = parentPath.getSibling(--key)).type) { - siblings.push(path); - } - - return siblings; -} - -function forEachAncestor(path, callback) { - while (path = path.parentPath) { - callback(path); - } -} - -module.exports = ({ - types: t, - traverse -}) => { - const removeOrVoid = require("babel-helper-remove-or-void")(t); - - const 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 - - const markForRemoval = Symbol("markForRemoval"); - const main = { - // remove side effectless statement - ExpressionStatement(path) { - if (path.get("expression").isPure()) { - removeOrVoid(path); - } - }, - - Function: { - // Let's take all the vars in a function that are not in the top level scope and hoist them - // with the first var declaration in the top-level scope. This transform in itself may - // not yield much returns (or even can be marginally harmful to size). However it's great - // for taking away statements from blocks that can be only expressions which the `simplify` - // plugin can turn into other things (e.g. if => conditional). - exit(path) { - // This hurts gzip size. - if (!this.optimizeRawSize) { - return; - } - - const node = path.node, - scope = path.scope; - const seen = new Set(); - const declars = []; - const mutations = []; - - for (const name in scope.bindings) { - const binding = scope.bindings[name]; - - if (!binding.path.isVariableDeclarator()) { - continue; - } - - const declarPath = binding.path.parentPath; - - if (seen.has(declarPath)) { - continue; - } - - seen.add(declarPath); - - if (declarPath.parentPath.isForInStatement()) { - continue; - } - - if (declarPath.parentPath.parentPath.isFunction()) { - continue; - } - - if (!declarPath.node || !declarPath.node.declarations) { - continue; - } - - const assignmentSequence = []; - - var _iterator = _createForOfIteratorHelper(declarPath.node.declarations), - _step; - - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - const declar = _step.value; - declars.push(declar); - - if (declar.init) { - assignmentSequence.push(t.assignmentExpression("=", declar.id, declar.init)); - mutations.push(() => { - declar.init = null; - }); - } - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } - - if (assignmentSequence.length) { - mutations.push(() => declarPath.replaceWith(t.sequenceExpression(assignmentSequence))); - } else { - mutations.push(() => removeOrVoid(declarPath)); - } - } - - if (declars.length) { - mutations.forEach(f => f()); - - var _iterator2 = _createForOfIteratorHelper(node.body.body), - _step2; - - try { - for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { - const statement = _step2.value; - - if (t.isVariableDeclaration(statement)) { - statement.declarations.push(...declars); - return; - } - } - } catch (err) { - _iterator2.e(err); - } finally { - _iterator2.f(); - } - - const varDecl = t.variableDeclaration("var", declars); - node.body.body.unshift(varDecl); - } - } - - }, - // Remove bindings with no references. - Scope: { - exit(path) { - if (path.node[shouldRevisit]) { - delete path.node[shouldRevisit]; - path.visit(); - } - }, - - enter(path) { - if (path.isProgram()) { - return; - } - - if (hasEval(path.scope)) { - return; - } - - const scope = path.scope; // if the scope is created by a function, we obtain its - // parameter list - - const canRemoveParams = path.isFunction() && path.node.kind !== "set"; - const paramsList = canRemoveParams ? path.get("params") : []; - - for (let i = paramsList.length - 1; i >= 0; i--) { - const param = paramsList[i]; - - if (param.isIdentifier()) { - const binding = scope.bindings[param.node.name]; - if (!binding) continue; - - if (binding.referenced) { - // when the first binding is referenced (right to left) - // exit without marking anything after this - break; - } - - binding[markForRemoval] = true; - continue; - } else if (param.isAssignmentPattern()) { - const left = param.get("left"); - const right = param.get("right"); - - if (left.isIdentifier() && right.isPure()) { - const binding = scope.bindings[left.node.name]; - - if (binding.referenced) { - // when the first binding is referenced (right to left) - // exit without marking anything after this - break; - } - - binding[markForRemoval] = true; - continue; - } - } // other patterns - assignment, object have side-effects - // and cannot be safely removed - - - break; - } - - for (const name in scope.bindings) { - const binding = scope.bindings[name]; - - if (!binding.referenced && binding.kind !== "module") { - if (binding.kind === "param" && (this.keepFnArgs || !binding[markForRemoval])) { - continue; - } else if (binding.path.isVariableDeclarator()) { - const declaration = binding.path.parentPath; - const maybeBlockParent = declaration.parentPath; - - if (maybeBlockParent && maybeBlockParent.isForXStatement({ - left: declaration.node - })) { - // Can't remove if in a for-in/for-of/for-await statement `for (var x in wat)`. - continue; - } - } else if (!scope.isPure(binding.path.node)) { - // TODO: AssignmentPattern are marked as impure and unused ids aren't removed yet - continue; - } else if (binding.path.isFunctionExpression() || binding.path.isClassExpression()) { - // `bar(function foo() {})` foo is not referenced but it's used. - continue; - } else if ( // ClassDeclaration has binding in two scopes - // 1. The scope in which it is declared - // 2. The class's own scope - binding.path.isClassDeclaration() && binding.path === scope.path) { - continue; - } - - const mutations = []; - let bail = false; // Make sure none of the assignments value is used - - binding.constantViolations.forEach(p => { - if (bail || p === binding.path) { - return; - } - - if (!p.parentPath.isExpressionStatement()) { - bail = true; - } - - if (p.isAssignmentExpression()) { - if (t.isArrayPattern(p.node.left) || t.isObjectPattern(p.node.left)) { - bail = true; - } else if (p.get("right").isPure()) { - mutations.push(() => removeOrVoid(p)); - } else { - mutations.push(() => p.replaceWith(p.get("right"))); - } - } - }); - - if (bail) { - continue; - } - - if (binding.path.isVariableDeclarator()) { - if (!binding.path.get("id").isIdentifier()) { - // deopt for object and array pattern - continue; - } // 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) { - // binding path has more than one declarations - if (binding.path.parentPath.node.declarations.length !== 1) { - continue; - } - - binding.path.parentPath.replaceWith(binding.path.node.init); - } else { - updateReferences(binding.path, this); - removeOrVoid(binding.path); - } - } else { - updateReferences(binding.path, this); - removeOrVoid(binding.path); - } - - mutations.forEach(f => f()); - scope.removeBinding(name); - } else if (binding.constant) { - if (binding.path.isFunctionDeclaration() || binding.path.isVariableDeclarator() && binding.path.get("init").isFunction()) { - const fun = binding.path.isFunctionDeclaration() ? binding.path : binding.path.get("init"); - let allInside = true; - - var _iterator3 = _createForOfIteratorHelper(binding.referencePaths), - _step3; - - try { - for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { - const ref = _step3.value; - - if (!ref.find(p => p.node === fun.node)) { - allInside = false; - break; - } - } - } catch (err) { - _iterator3.e(err); - } finally { - _iterator3.f(); - } - - if (allInside) { - scope.removeBinding(name); - updateReferences(binding.path, this); - removeOrVoid(binding.path); - continue; - } - } - - if (binding.references === 1 && binding.kind !== "param" && binding.kind !== "module" && binding.constant) { - let replacement = binding.path.node; - let replacementPath = binding.path; - let isReferencedBefore = false; - const refPath = binding.referencePaths[0]; - - if (t.isVariableDeclarator(replacement)) { - const _prevSiblings = prevSiblings(replacementPath); // traverse ancestors of a reference checking if it's before declaration - - - forEachAncestor(refPath, ancestor => { - if (_prevSiblings.indexOf(ancestor) > -1) { - isReferencedBefore = true; - } - }); // 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) { - continue; - } // 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 - // TODO: maybe a more intelligent approach instead of simply bailing out - - if (!replacementPath.get("id").isIdentifier()) { - continue; - } - - replacementPath = replacementPath.get("init"); - } - - if (!replacement) { - continue; - } - - if (!scope.isPure(replacement, true) && !isReferencedBefore) { - continue; - } - - let bail = false; - - if (replacementPath.isIdentifier()) { - const binding = 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 = !(binding && refPath.scope.getBinding(replacement.name) === binding && binding.constantViolations.length === 0); - } else if (replacementPath.isThisExpression()) { - bail = true; - } else { - replacementPath.traverse({ - Function(path) { - path.skip(); - }, - - ThisExpression(path) { - bail = true; - path.stop(); - }, - - ReferencedIdentifier({ - node - }) { - const binding = scope.getBinding(node.name); - - if (binding && refPath.scope.getBinding(node.name) === binding) { - bail = binding.constantViolations.length > 0; - - if (bail) { - path.stop(); - } - } - } - - }); - } - - if (bail) { - continue; - } - - let 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 - // and not in an if statement or otherwise. - // 2. If the replacement is an object then we have to make sure we are not in a loop or a function - // because otherwise we'll be inlining and doing a lot more allocation than we have to - // which would also could affect correctness in that they are not the same reference. - - - let mayLoop = false; - const sharesRoot = refPath.find(({ - node - }) => { - if (!mayLoop) { - mayLoop = t.isWhileStatement(node) || t.isFor(node) || t.isFunction(node); - } - - return node === parent; - }); // Anything that inherits from Object. - - const isObj = n => t.isFunction(n) || t.isObjectExpression(n) || t.isArrayExpression(n) || t.isRegExpLiteral(n); - - const isReplacementObj = isObj(replacement) || some(replacement, isObj); - - if (!sharesRoot || isReplacementObj && mayLoop) { - continue; - } // check if it's safe to replace - // To solve https://github.com/babel/minify/issues/691 - // Here we bail for property checks using the "in" operator - // This is because - `in` is a side-effect-free operation but the property - // could be deleted between the replacementPath and referencePath - // It is expensive to compute the delete operation and we bail for - // all the binary "in" operations - - - let inExpression = replacementPath.isBinaryExpression({ - operator: "in" - }); - - if (!inExpression) { - replacementPath.traverse({ - Function(path) { - path.skip(); - }, - - BinaryExpression(path) { - if (path.node.operator === "in") { - inExpression = true; - path.stop(); - } - } - - }); - } - - if (inExpression) { - continue; - } - - const replaced = replace(binding.referencePaths[0], { - binding, - scope, - replacement, - replacementPath - }); - - if (replaced) { - scope.removeBinding(name); - - if (binding.path.node) { - removeOrVoid(binding.path); - } - } - } - } - } // end-for-of - - } - - }, - - // Remove unreachable code. - BlockStatement(path) { - const paths = path.get("body"); - let purge = false; - - for (let i = 0; i < paths.length; i++) { - const p = paths[i]; - - if (!purge && p.isCompletionStatement()) { - purge = true; - continue; - } - - if (purge && !canExistAfterCompletion(p)) { - removeOrVoid(p); - } - } - }, - - // Double check unreachable code and remove return statements that - // have no semantic meaning - ReturnStatement(path) { - const node = path.node; - - if (!path.inList) { - return; - } // Not last in its block? (See BlockStatement visitor) - - - if (path.container.length - 1 !== path.key && !canExistAfterCompletion(path.getSibling(path.key + 1)) && path.parentPath.isBlockStatement()) { - // This is probably a new oppurtinity by some other transform - // let's call the block visitor on this again before proceeding. - path.parentPath.pushContext(path.context); - path.parentPath.visit(); - path.parentPath.popContext(); - return; - } - - if (node.argument) { - return; - } - - let noNext = true; - let parentPath = path.parentPath; - - while (parentPath && !parentPath.isFunction() && noNext) { - // https://github.com/babel/minify/issues/265 - if (hasLoopParent(parentPath)) { - noNext = false; - break; - } - - const nextPath = parentPath.getSibling(parentPath.key + 1); - - if (nextPath.node) { - if (nextPath.isReturnStatement()) { - nextPath.pushContext(path.context); - nextPath.visit(); - nextPath.popContext(); - - if (parentPath.getSibling(parentPath.key + 1).node) { - noNext = false; - break; - } - } else { - noNext = false; - break; - } - } - - parentPath = parentPath.parentPath; - } - - if (noNext) { - removeOrVoid(path); - } - }, - - ConditionalExpression(path) { - const node = path.node; - const evaluateTest = evaluateTruthy(path.get("test")); - - if (evaluateTest === true) { - path.replaceWith(node.consequent); - } else if (evaluateTest === false) { - path.replaceWith(node.alternate); - } - }, - - SwitchStatement: { - exit(path) { - const discriminantPath = path.get("discriminant"); - const evaluated = evaluate(discriminantPath, { - tdz: this.tdz - }); - if (!evaluated.confident) return; // the simplify transformation might have brought in the previous - // expressions into the switch's test expression and instead of - // bailing out of impure path, we collect the impurities of it's - // a sequence expression and bail out if the primary test itself - // is impure - - let beforeTest = []; - - if (t.isSequenceExpression(discriminantPath.node)) { - const expressions = discriminantPath.get("expressions"); - const lastExpression = expressions[expressions.length - 1]; - - if (!lastExpression.isPure()) { - return; - } - - beforeTest = [t.expressionStatement(t.sequenceExpression(expressions.slice(0, expressions.length - 1).map(path => path.node)))]; - } else if (!discriminantPath.isPure()) { - return; - } - - const discriminant = evaluated.value; - const cases = path.get("cases"); - let matchingCaseIndex = -1; - let defaultCaseIndex = -1; - - for (let i = 0; i < cases.length; i++) { - const test = cases[i].get("test"); // handle default case - - if (test.node === null) { - defaultCaseIndex = i; - continue; - } - - const testResult = evaluate(test, { - tdz: this.tdz - }); // if we are not able to deternine a test during - // compile time, we terminate immediately - - if (!testResult.confident) return; - - if (testResult.value === discriminant) { - matchingCaseIndex = i; - break; - } - } - - let result; - - if (matchingCaseIndex === -1) { - if (defaultCaseIndex === -1) { - path.skip(); - path.replaceWithMultiple(extractVars(path)); - return; - } else { - result = getStatementsUntilBreak(defaultCaseIndex); - } - } else { - result = getStatementsUntilBreak(matchingCaseIndex); - } - - 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([...extractVars(path), ...beforeTest, ...result.statements]); - - function getStatementsUntilBreak(start) { - const result = { - bail: false, - statements: [] - }; - - for (let i = start; i < cases.length; i++) { - const consequent = cases[i].get("consequent"); - - for (let j = 0; j < consequent.length; j++) { - const _isBreaking = isBreaking(consequent[j], path); - - if (_isBreaking.bail) { - result.bail = true; - return result; - } - - if (_isBreaking.break) { - // compute no more - // exit out of the loop - return result; - } else { - result.statements.push(consequent[j].node); - } - } - } - - return result; - } - - function replaceSwitch(statements) { - let isBlockRequired = false; - - for (let i = 0; i < statements.length; i++) { - if (t.isVariableDeclaration(statements[i], { - kind: "let" - })) { - isBlockRequired = true; - break; - } - - if (t.isVariableDeclaration(statements[i], { - kind: "const" - })) { - isBlockRequired = true; - break; - } - } - - if (isBlockRequired) { - path.replaceWith(t.BlockStatement(statements)); - } else { - path.replaceWithMultiple(statements); - } - } - } - - }, - - WhileStatement(path) { - const test = path.get("test"); - const result = evaluate(test, { - tdz: this.tdz - }); - - if (result.confident && test.isPure() && !result.value) { - path.replaceWithMultiple(extractVars(path.get("body"))); - } - }, - - ForStatement(path) { - const test = path.get("test"); - if (!test.isPure()) return; - const result = evaluate(test, { - tdz: this.tdz - }); - - if (result.confident) { - if (result.value) { - test.remove(); - } else { - const init = path.get("init"); - - if (init.node && !init.isPure()) { - path.replaceWith(init); - } else { - path.remove(); - } - } - } - }, - - DoWhileStatement(path) { - const test = path.get("test"); - const result = evaluate(test, { - tdz: this.tdz - }); - - if (result.confident && test.isPure() && !result.value) { - const body = path.get("body"); - - if (body.isBlockStatement()) { - const stmts = body.get("body"); - - var _iterator4 = _createForOfIteratorHelper(stmts), - _step4; - - try { - for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { - const stmt = _step4.value; - - const _isBreaking = isBreaking(stmt, path); - - if (_isBreaking.bail || _isBreaking.break) return; - - const _isContinuing = isContinuing(stmt, path); - - if (_isContinuing.bail || isContinuing.continue) return; - } - } catch (err) { - _iterator4.e(err); - } finally { - _iterator4.f(); - } - - path.replaceWith(body.node); - } else if (body.isBreakStatement()) { - const _isBreaking = isBreaking(body, path); - - if (_isBreaking.bail) return; - if (_isBreaking.break) path.remove(); - } else if (body.isContinueStatement()) { - return; - } else { - path.replaceWith(body.node); - } - } - }, - - // Join assignment and definition when in sequence. - // var x; x = 1; -> var x = 1; - AssignmentExpression(path) { - if (!path.get("left").isIdentifier() || !path.parentPath.isExpressionStatement()) { - return; - } - - const prev = path.parentPath.getSibling(path.parentPath.key - 1); - - if (!(prev && prev.isVariableDeclaration())) { - return; - } - - const 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; - removeOrVoid(path); - }, - - // Remove named function expression name. While this is dangerous as it changes - // `function.name` all minifiers do it and hence became a standard. - FunctionExpression(path) { - if (!this.keepFnName) { - removeUnreferencedId(path); - } - }, - - // remove class names - ClassExpression(path) { - if (!this.keepClassName) { - removeUnreferencedId(path); - } - }, - - // Put the `var` in the left if feasible. - ForInStatement(path) { - const left = path.get("left"); - - if (!left.isIdentifier()) { - return; - } - - const binding = path.scope.getBinding(left.node.name); - - if (!binding) { - return; - } - - if (binding.scope.getFunctionParent() !== path.scope.getFunctionParent()) { - return; - } - - if (!binding.path.isVariableDeclarator()) { - return; - } - - if (binding.path.parentPath.parentPath.isForInStatement({ - left: binding.path.parent - })) { - return; - } // If it has company then it's probably more efficient to keep. - - - if (binding.path.parent.declarations.length > 1) { - return; - } // meh - - - if (binding.path.node.init) { - return; - } - - removeOrVoid(binding.path); - path.node.left = t.variableDeclaration("var", [t.variableDeclarator(left.node)]); - binding.path = path.get("left").get("declarations")[0]; - } - - }; - return { - name: "minify-dead-code-elimination", - visitor: { - Function: { - exit(path) { - /** - * Use exit handler to traverse in a dfs post-order fashion - * to remove use strict - */ - const body = path.get("body"); - - if (body.isBlockStatement()) { - removeUseStrict(body); - } - } - - }, - IfStatement: { - exit(path, { - opts: { - tdz = false - } = {} - }) { - const consequent = path.get("consequent"); - const alternate = path.get("alternate"); - const test = path.get("test"); - const evalResult = evaluate(test, { - tdz - }); - const isPure = test.isPure(); - const 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 - // the consequent and completely ignore the alternate - // - // if (true) { foo; } -> { foo; } - // if ("foo") { foo; } -> { foo; } - // - - - if (evalResult.confident && evalResult.value) { - path.replaceWithMultiple([...replacements, ...toStatements(consequent), ...extractVars(alternate)]); - return; - } // 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 - // - // if ("") { bar; } else { foo; } -> { foo; } - // if ("") { bar; } -> - // - - - if (evalResult.confident && !evalResult.value) { - if (alternate.node) { - path.replaceWithMultiple([...replacements, ...toStatements(alternate), ...extractVars(consequent)]); - return; - } else { - path.replaceWithMultiple([...replacements, ...extractVars(consequent)]); - } - } // 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 - - path.node.alternate = null; - } // if the consequent block is empty turn alternate blocks into a consequent - // and flip the test - // - // if (foo) {} else { bar; } -> if (!foo) { bar; } - // - - - 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 - - path.node.alternate = null; - test.replaceWith(t.unaryExpression("!", test.node, true)); - } - } - - }, - - EmptyStatement(path) { - if (path.parentPath.isBlockStatement() || path.parentPath.isProgram()) { - path.remove(); - } - }, - - Program: { - exit(path, { - opts: { - // set defaults - optimizeRawSize = false, - keepFnName = false, - keepClassName = false, - keepFnArgs = false, - tdz = false - } = {} - } = {}) { - (traverse.clearCache || traverse.cache.clear)(); - path.scope.crawl(); - markEvalScopes(path); // We need to run this plugin in isolation. - - path.traverse(main, { - functionToBindings: new Map(), - optimizeRawSize, - keepFnName, - keepClassName, - keepFnArgs, - tdz - }); - } - - } - } - }; - - function toStatements(path) { - const node = path.node; - - if (path.isBlockStatement()) { - let hasBlockScoped = false; - - for (let i = 0; i < node.body.length; i++) { - const bodyNode = node.body[i]; - - if (t.isBlockScoped(bodyNode)) { - hasBlockScoped = true; - } - } - - if (!hasBlockScoped) { - return node.body; - } - } - - return [node]; - } // Extracts vars from a path - // Useful for removing blocks or paths that can contain - // variable declarations inside them - // Note: - // drops are inits - // extractVars({ var x = 5, y = x }) => var x, y; - - - function extractVars(path) { - const declarators = []; - - if (path.isVariableDeclaration({ - kind: "var" - })) { - var _iterator5 = _createForOfIteratorHelper(path.node.declarations), - _step5; - - try { - for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { - const decl = _step5.value; - const bindingIds = Object.keys(t.getBindingIdentifiers(decl.id)); - declarators.push(...bindingIds.map(name => t.variableDeclarator(t.identifier(name)))); - } - } catch (err) { - _iterator5.e(err); - } finally { - _iterator5.f(); - } - } else { - path.traverse({ - VariableDeclaration(varPath) { - if (!varPath.isVariableDeclaration({ - kind: "var" - })) return; - if (!isSameFunctionScope(varPath, path)) return; - - var _iterator6 = _createForOfIteratorHelper(varPath.node.declarations), - _step6; - - try { - for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { - const decl = _step6.value; - const bindingIds = Object.keys(t.getBindingIdentifiers(decl.id)); - declarators.push(...bindingIds.map(name => t.variableDeclarator(t.identifier(name)))); - } - } catch (err) { - _iterator6.e(err); - } finally { - _iterator6.f(); - } - } - - }); - } - - if (declarators.length <= 0) return []; - return [t.variableDeclaration("var", declarators)]; - } - - function replace(path, options) { - const replacement = options.replacement, - replacementPath = options.replacementPath, - scope = options.scope, - binding = options.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: - // 1. Original bindings that is referenced could be shadowed - // 2. Moving defintions to potentially hot code is bad - - - if (scope !== path.scope) { - if (t.isClass(replacement) || t.isFunction(replacement)) { - return; - } - - let bail = false; - traverse(replacement, { - Function(path) { - if (bail) { - return; - } - - bail = true; - path.stop(); - } - - }, scope); - - if (bail) { - return; - } - } // Avoid recursion. - - - if (path.find(({ - node - }) => node === replacement)) { - return; - } // 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()) { - const fnName = replacementPath.get("id").node.name; - - for (let name in replacementPath.scope.bindings) { - if (name === fnName) { - return; - } - } - } // 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 - // check its references and remove unreferenced ones - // if (t.isFunction(replacement)) { - // replacement.id = null; - // } - - - path.replaceWith(replacement); - return true; - } - - function updateReferences(fnToDeletePath) { - if (!fnToDeletePath.isFunction()) { - return; - } - - fnToDeletePath.traverse({ - ReferencedIdentifier(path) { - const node = path.node, - scope = path.scope; - const binding = scope.getBinding(node.name); - - if (!binding || !binding.path.isFunction() || binding.scope === scope || !binding.constant) { - return; - } - - const index = binding.referencePaths.indexOf(path); - - if (index === -1) { - return; - } - - binding.references--; - binding.referencePaths.splice(index, 1); - - if (binding.references === 0) { - binding.referenced = false; - } - - if (binding.references <= 1 && binding.scope.path.node) { - binding.scope.path.node[shouldRevisit] = true; - } - } - - }); - } - - function removeUnreferencedId(path) { - const id = path.get("id").node; - - if (!id) { - return; - } - - const node = path.node, - scope = path.scope; - const 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 - - - function isAncestor(path1, path2) { - return !!path2.findParent(parent => parent === path1); - } - - function isSameFunctionScope(path1, path2) { - return path1.scope.getFunctionParent() === path2.scope.getFunctionParent(); - } - - function isBreaking(stmt, path) { - return isControlTransfer(stmt, path, "break"); - } - - function isContinuing(stmt, path) { - return isControlTransfer(stmt, path, "continue"); - } // tells if a "stmt" is a break/continue statement - - - function isControlTransfer(stmt, path, control = "break") { - const _break$continue = { - break: "BreakStatement", - continue: "ContinueStatement" - }, - type = _break$continue[control]; - - if (!type) { - throw new Error("Can only handle break and continue statements"); - } - - const checker = `is${type}`; - - if (stmt[checker]()) { - return _isControlTransfer(stmt, path); - } - - let isTransferred = false; - let result = { - [control]: false, - bail: false - }; - stmt.traverse({ - [type](cPath) { - // if we already detected a break/continue statement, - if (isTransferred) return; - result = _isControlTransfer(cPath, path); - - if (result.bail || result[control]) { - isTransferred = true; - } - } - - }); - return result; - - function _isControlTransfer(cPath, path) { - const label = cPath.get("label"); - - if (label.node !== null) { - // labels are fn scoped and not accessible by inner functions - // path is the switch statement - if (!isSameFunctionScope(path, cPath)) { - // we don't have to worry about this break statement - return { - break: false, - bail: false - }; - } // here we handle the break labels - // if they are outside switch, we bail out - // if they are within the case, we keep them - - - let labelPath; - - if (path.scope.getLabel) { - labelPath = getLabel(label.node.name, path); - } else { - labelPath = path.scope.getBinding(label.node.name).path; - } - - const _isAncestor = isAncestor(labelPath, path); - - return { - bail: _isAncestor, - [control]: _isAncestor - }; - } // set the flag that it is indeed breaking - - - let isCTransfer = true; // this flag is to capture - // switch(0) { case 0: while(1) if (x) break; } - - let possibleRunTimeControlTransfer = false; // and compute if it's breaking the correct thing - - let parent = cPath.parentPath; - - while (parent !== stmt.parentPath) { - // loops and nested switch cases - if (parent.isLoop() || parent.isSwitchCase()) { - // invalidate all the possible runtime breaks captured - // while (1) { if (x) break; } - possibleRunTimeControlTransfer = false; // and set that it's not breaking our switch statement - - isCTransfer = false; - break; - } // - // this is a special case and depends on - // the fact that SwitchStatement is handled in the - // exit hook of the traverse - // - // switch (0) { - // case 0: if (x) break; - // } - // - // here `x` is runtime only. - // in this case, we need to bail out. So we depend on exit hook - // of switch so that, it would have visited the IfStatement first - // before the SwitchStatement and would have removed the - // IfStatement if it was a compile time determined - // - - - if (parent.isIfStatement()) { - possibleRunTimeControlTransfer = true; - } - - parent = parent.parentPath; - } - - return { - [control]: possibleRunTimeControlTransfer || isCTransfer, - bail: possibleRunTimeControlTransfer - }; - } - } // things that are hoisted - - - function canExistAfterCompletion(path) { - return path.isFunctionDeclaration() || path.isVariableDeclaration({ - kind: "var" - }); - } - - function getLabel(name, _path) { - let label, - path = _path; - - do { - label = path.scope.getLabel(name); - - if (label) { - return label; - } - } while (path = path.parentPath); - - return null; - } - - function hasLoopParent(path) { - let parent = path; - - do { - if (parent.isLoop()) { - return true; - } - } while (parent = parent.parentPath); - - return false; - } - - function extractSequenceImpure(seq) { - const expressions = seq.get("expressions"); - const result = []; - - for (let i = 0; i < expressions.length; i++) { - if (!expressions[i].isPure()) { - result.push(expressions[i].node); - } - } - - return t.sequenceExpression(result); - } -};
\ No newline at end of file diff --git a/node_modules/babel-plugin-minify-dead-code-elimination/lib/remove-use-strict.js b/node_modules/babel-plugin-minify-dead-code-elimination/lib/remove-use-strict.js deleted file mode 100644 index eb4cbe3a..00000000 --- a/node_modules/babel-plugin-minify-dead-code-elimination/lib/remove-use-strict.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict"; - -module.exports = removeUseStrict; -const newIssueUrl = "https://github.com/babel/minify/issues/new"; -const useStrict = "use strict"; -/** - * Remove redundant use strict - * If the parent has a "use strict" directive, it is not required in - * the children - * - * @param {NodePath} block BlockStatement - */ - -function removeUseStrict(block) { - if (!block.isBlockStatement()) { - throw new Error(`Received ${block.type}. Expected BlockStatement. ` + `Please report at ${newIssueUrl}`); - } - - const useStricts = getUseStrictDirectives(block); // early exit - - if (useStricts.length < 1) return; // only keep the first use strict - - if (useStricts.length > 1) { - for (let i = 1; i < useStricts.length; i++) { - useStricts[i].remove(); - } - } // check if parent has an use strict - - - if (hasStrictParent(block)) { - useStricts[0].remove(); - } -} - -function hasStrictParent(path) { - return path.findParent(parent => parent.isBlockStatement() && isStrict(parent)); -} - -function isStrict(block) { - return getUseStrictDirectives(block).length > 0; -} - -function getUseStrictDirectives(block) { - var dir = block.get("directives"); - return Array.isArray(dir) ? dir.filter(function (directive) { - return directive.node.value.value === useStrict; - }) : []; -}
\ No newline at end of file diff --git a/node_modules/babel-plugin-minify-dead-code-elimination/package.json b/node_modules/babel-plugin-minify-dead-code-elimination/package.json deleted file mode 100644 index db27e8ea..00000000 --- a/node_modules/babel-plugin-minify-dead-code-elimination/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "babel-plugin-minify-dead-code-elimination", - "version": "0.5.2", - "description": "", - "keywords": [ - "babel-plugin" - ], - "homepage": "https://github.com/babel/minify#readme", - "bugs": "https://github.com/babel/minify/issues", - "license": "MIT", - "author": "amasad", - "main": "lib/index.js", - "repository": "https://github.com/babel/minify/tree/master/packages/babel-plugin-minify-dead-code-elimination", - "dependencies": { - "babel-helper-evaluate-path": "^0.5.0", - "babel-helper-mark-eval-scopes": "^0.4.3", - "babel-helper-remove-or-void": "^0.4.3", - "lodash": "^4.17.11" - }, - "gitHead": "8f9c7c0a32103653bd6793d0ce44730f937e1ddf" -} |
