diff --git a/package.json b/package.json index b2d143d73a..29338bac42 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,16 @@ "dependencies": { "acorn-jsx": "^1.0.0", "ast-types": "~0.7.0", - "babel-plugin-undefined-to-void": "^1.1.0", + "babel-plugin-constant-folding": "^1.0.1", + "babel-plugin-dead-code-elimination": "^1.0.1", + "babel-plugin-eval": "^1.0.1", + "babel-plugin-inline-environment-variables": "^1.0.1", + "babel-plugin-member-expression-literals": "^1.0.1", + "babel-plugin-property-literals": "^1.0.1", + "babel-plugin-proto-to-assign": "^1.0.3", + "babel-plugin-remove-console": "^1.0.1", + "babel-plugin-remove-debugger": "^1.0.1", + "babel-plugin-undefined-to-void": "^1.1.6", "bluebird": "^2.9.25", "chalk": "^1.0.0", "convert-source-map": "^1.1.0", diff --git a/src/babel/transformation/transformers/index.js b/src/babel/transformation/transformers/index.js index 6c7fa65ae4..d1fba5652d 100644 --- a/src/babel/transformation/transformers/index.js +++ b/src/babel/transformation/transformers/index.js @@ -1,17 +1,17 @@ export default { //- builtin-prepass - "minification.constantFolding": require("./minification/constant-folding"), + "minification.constantFolding": require("babel-plugin-constant-folding"), //- builtin-pre strict: require("./other/strict"), - eval: require("./other/eval"), + eval: require("babel-plugin-eval"), _explode: require("./internal/explode"), _validation: require("./internal/validation"), _hoistDirectives: require("./internal/hoist-directives"), - "minification.removeDebugger": require("./minification/remove-debugger"), - "minification.removeConsole": require("./minification/remove-console"), - "utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"), - "minification.deadCodeElimination": require("./minification/dead-code-elimination"), + "minification.removeDebugger": require("babel-plugin-remove-debugger"), + "minification.removeConsole": require("babel-plugin-remove-console"), + "utility.inlineEnvironmentVariables": require("babel-plugin-inline-environment-variables"), + "minification.deadCodeElimination": require("babel-plugin-dead-code-elimination"), _modules: require("./internal/modules"), "spec.functionName": require("./spec/function-name"), "es6.spec.templateLiterals": require("./es6/spec.template-literals"), @@ -49,7 +49,7 @@ export default { "es6.spread": require("./es6/spread"), "es6.parameters.default": require("./es6/parameters.default"), "es7.exportExtensions": require("./es7/export-extensions"), - "spec.protoToAssign": require("./spec/proto-to-assign"), + "spec.protoToAssign": require("babel-plugin-proto-to-assign"), "es7.doExpressions": require("./es7/do-expressions"), "es6.spec.symbols": require("./es6/spec.symbols"), "es7.functionBind": require("./es7/function-bind"), @@ -79,8 +79,8 @@ export default { _shadowFunctions: require("./internal/shadow-functions"), "es3.propertyLiterals": require("./es3/property-literals"), "es3.memberExpressionLiterals": require("./es3/member-expression-literals"), - "minification.memberExpressionLiterals": require("./minification/member-expression-literals"), - "minification.propertyLiterals": require("./minification/property-literals"), + "minification.memberExpressionLiterals": require("babel-plugin-member-expression-literals"), + "minification.propertyLiterals": require("babel-plugin-property-literals"), _blockHoist: require("./internal/block-hoist"), jscript: require("./other/jscript"), flow: require("./other/flow"), diff --git a/src/babel/transformation/transformers/minification/constant-folding.js b/src/babel/transformation/transformers/minification/constant-folding.js deleted file mode 100644 index c3d383529b..0000000000 --- a/src/babel/transformation/transformers/minification/constant-folding.js +++ /dev/null @@ -1,73 +0,0 @@ -import * as t from "../../../types"; - -export var metadata = { - optional: true, - group: "builtin-prepass", - experimental: true -}; - -export var visitor = { - AssignmentExpression() { - var left = this.get("left"); - if (!left.isIdentifier()) return; - - var binding = this.scope.getBinding(left.node.name); - if (!binding || binding.hasDeoptValue) return; - - var evaluated = this.get("right").evaluate(); - if (evaluated.confident) { - binding.setValue(evaluated.value); - } else { - binding.deoptValue(); - } - }, - - IfStatement() { - var evaluated = this.get("test").evaluate(); - if (!evaluated.confident) { - // todo: deopt binding values for constant violations inside - return this.skip(); - } - - if (evaluated.value) { - this.skipKey("alternate"); - } else { - this.skipKey("consequent"); - } - }, - - Scopable: { - enter() { - var funcScope = this.scope.getFunctionParent(); - - for (var name in this.scope.bindings) { - var binding = this.scope.bindings[name]; - var deopt = false; - - for (var path of (binding.constantViolations: Array)) { - var funcViolationScope = path.scope.getFunctionParent(); - if (funcViolationScope !== funcScope) { - deopt = true; - break; - } - } - - if (deopt) binding.deoptValue(); - } - }, - - exit() { - for (var name in this.scope.bindings) { - var binding = this.scope.bindings[name]; - binding.clearValue(); - } - } - }, - - Expression: { - exit() { - var res = this.evaluate(); - if (res.confident) return t.valueToNode(res.value); - } - } -}; diff --git a/src/babel/transformation/transformers/minification/dead-code-elimination.js b/src/babel/transformation/transformers/minification/dead-code-elimination.js deleted file mode 100644 index af23dba7e6..0000000000 --- a/src/babel/transformation/transformers/minification/dead-code-elimination.js +++ /dev/null @@ -1,154 +0,0 @@ -import * as t from "../../../types"; - -function toStatements(node) { - if (t.isBlockStatement(node)) { - var hasBlockScoped = false; - - for (var i = 0; i < node.body.length; i++) { - var bodyNode = node.body[i]; - if (t.isBlockScoped(bodyNode)) hasBlockScoped = true; - } - - if (!hasBlockScoped) { - return node.body; - } - } - - return node; -} - -export var metadata = { - optional: true, - group: "builtin-pre", - experimental: true -}; - -export var visitor = { - ReferencedIdentifier(node, parent, scope) { - var binding = scope.getBinding(node.name); - if (!binding || binding.references > 1 || !binding.constant) return; - if (binding.kind === "param" || binding.kind === "module") return; - - var replacement = binding.path.node; - if (t.isVariableDeclarator(replacement)) { - replacement = replacement.init; - } - if (!replacement) return; - - // ensure it's a "pure" type - if (!scope.isPure(replacement, true)) return; - - if (t.isClass(replacement) || t.isFunction(replacement)) { - // don't change this if it's in a different scope, this can be bad - // for performance since it may be inside a loop or deeply nested in - // hot code - if (binding.path.scope.parent !== scope) return; - } - - if (this.findParent((path) => path.node === replacement)) { - return; - } - - t.toExpression(replacement); - scope.removeBinding(node.name); - binding.path.dangerouslyRemove(); - return replacement; - }, - - "ClassDeclaration|FunctionDeclaration"(node, parent, scope) { - var binding = scope.getBinding(node.id.name); - if (binding && !binding.referenced) { - this.dangerouslyRemove(); - } - }, - - VariableDeclarator(node, parent, scope) { - if (!t.isIdentifier(node.id) || !scope.isPure(node.init, true)) return; - visitor["ClassDeclaration|FunctionDeclaration"].apply(this, arguments); - }, - - ConditionalExpression(node) { - var evaluateTest = this.get("test").evaluateTruthy(); - if (evaluateTest === true) { - return node.consequent; - } else if (evaluateTest === false) { - return node.alternate; - } - }, - - BlockStatement() { - var paths = this.get("body"); - - var purge = false; - - for (var i = 0; i < paths.length; i++) { - let path = paths[i]; - - if (!purge && path.isCompletionStatement()) { - purge = true; - continue; - } - - if (purge && !path.isFunctionDeclaration()) { - path.dangerouslyRemove(); - } - } - }, - - IfStatement: { - exit(node) { - var consequent = node.consequent; - var alternate = node.alternate; - var test = node.test; - - var evaluateTest = this.get("test").evaluateTruthy(); - - // 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 (evaluateTest === true) { - return toStatements(consequent); - } - - // 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 (evaluateTest === false) { - if (alternate) { - return toStatements(alternate); - } else { - return this.dangerouslyRemove(); - } - } - - // remove alternate blocks that are empty - // - // if (foo) { foo; } else {} -> if (foo) { foo; } - // - - if (t.isBlockStatement(alternate) && !alternate.body.length) { - alternate = 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 (t.isBlockStatement(consequent) && !consequent.body.length && t.isBlockStatement(alternate) && alternate.body.length) { - node.consequent = node.alternate; - node.alternate = null; - node.test = t.unaryExpression("!", test, true); - } - } - } -}; diff --git a/src/babel/transformation/transformers/minification/member-expression-literals.js b/src/babel/transformation/transformers/minification/member-expression-literals.js deleted file mode 100644 index 130875c894..0000000000 --- a/src/babel/transformation/transformers/minification/member-expression-literals.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as t from "../../../types"; - -export var metadata = { - optional: true, - group: "builtin-trailing" -}; - -export var visitor = { - MemberExpression: { - exit(node) { - var prop = node.property; - if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) { - // foo["bar"] => foo.bar - node.property = t.identifier(prop.value); - node.computed = false; - } - } - } -}; diff --git a/src/babel/transformation/transformers/minification/property-literals.js b/src/babel/transformation/transformers/minification/property-literals.js deleted file mode 100644 index 28abb18434..0000000000 --- a/src/babel/transformation/transformers/minification/property-literals.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as t from "../../../types"; - -export var metadata = { - optional: true, - group: "builtin-trailing" -}; - -export var visitor = { - Property: { - exit(node) { - var key = node.key; - if (t.isLiteral(key) && t.isValidIdentifier(key.value)) { - // "foo": "bar" -> foo: "bar" - node.key = t.identifier(key.value); - node.computed = false; - } - } - } -}; diff --git a/src/babel/transformation/transformers/minification/remove-console.js b/src/babel/transformation/transformers/minification/remove-console.js deleted file mode 100644 index 125ad4ba5c..0000000000 --- a/src/babel/transformation/transformers/minification/remove-console.js +++ /dev/null @@ -1,12 +0,0 @@ -export var metadata = { - optional: true, - group: "builtin-pre" -}; - -export var visitor = { - CallExpression() { - if (this.get("callee").matchesPattern("console", true)) { - this.dangerouslyRemove(); - } - } -}; diff --git a/src/babel/transformation/transformers/minification/remove-debugger.js b/src/babel/transformation/transformers/minification/remove-debugger.js deleted file mode 100644 index cde74857be..0000000000 --- a/src/babel/transformation/transformers/minification/remove-debugger.js +++ /dev/null @@ -1,10 +0,0 @@ -export var metadata = { - optional: true, - group: "builtin-pre" -}; - -export var visitor = { - DebuggerStatement() { - this.dangerouslyRemove(); - } -}; diff --git a/src/babel/transformation/transformers/other/eval.js b/src/babel/transformation/transformers/other/eval.js deleted file mode 100644 index c946cebafb..0000000000 --- a/src/babel/transformation/transformers/other/eval.js +++ /dev/null @@ -1,23 +0,0 @@ -import traverse from "../../../traversal"; -import parse from "../../../helpers/parse"; - -export var metadata = { - group: "builtin-pre", - optional: true -}; - -export var visitor = { - CallExpression(node) { - if (this.get("callee").isIdentifier({ name: "eval" }) && node.arguments.length === 1) { - var evaluate = this.get("arguments")[0].evaluate(); - if (!evaluate.confident) return; - - var code = evaluate.value; - if (typeof code !== "string") return; - - var ast = parse(code); - traverse.removeProperties(ast); - return ast.program; - } - } -}; diff --git a/src/babel/transformation/transformers/spec/proto-to-assign.js b/src/babel/transformation/transformers/spec/proto-to-assign.js deleted file mode 100644 index 5fc2e460b2..0000000000 --- a/src/babel/transformation/transformers/spec/proto-to-assign.js +++ /dev/null @@ -1,64 +0,0 @@ -import * as t from "../../../types"; -import pull from "lodash/array/pull"; - -function isProtoKey(node) { - return t.isLiteral(t.toComputedKey(node, node.key), { value: "__proto__" }); -} - -function isProtoAssignmentExpression(node) { - var left = node.left; - return t.isMemberExpression(left) && t.isLiteral(t.toComputedKey(left, left.property), { value: "__proto__" }); -} - -function buildDefaultsCallExpression(expr, ref, file) { - return t.expressionStatement(t.callExpression(file.addHelper("defaults"), [ref, expr.right])); -} - -export var metadata = { - secondPass: true, - optional: true -}; - -export var visitor = { - AssignmentExpression(node, parent, scope, file) { - if (!isProtoAssignmentExpression(node)) return; - - var nodes = []; - var left = node.left.object; - var temp = scope.maybeGenerateMemoised(left); - - nodes.push(t.expressionStatement(t.assignmentExpression("=", temp, left))); - nodes.push(buildDefaultsCallExpression(node, temp, file)); - if (temp) nodes.push(temp); - - return nodes; - }, - - ExpressionStatement(node, parent, scope, file) { - var expr = node.expression; - if (!t.isAssignmentExpression(expr, { operator: "=" })) return; - - if (isProtoAssignmentExpression(expr)) { - return buildDefaultsCallExpression(expr, expr.left.object, file); - } - }, - - ObjectExpression(node, parent, scope, file) { - var proto; - - for (var i = 0; i < node.properties.length; i++) { - var prop = node.properties[i]; - - if (isProtoKey(prop)) { - proto = prop.value; - pull(node.properties, prop); - } - } - - if (proto) { - var args = [t.objectExpression([]), proto]; - if (node.properties.length) args.push(node); - return t.callExpression(file.addHelper("extends"), args); - } - } -}; diff --git a/src/babel/transformation/transformers/utility/inline-environment-variables.js b/src/babel/transformation/transformers/utility/inline-environment-variables.js deleted file mode 100644 index 3e0c0f1e6c..0000000000 --- a/src/babel/transformation/transformers/utility/inline-environment-variables.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as t from "../../../types"; - -export var metadata = { - optional: true, - group: "builtin-pre" -}; - -var match = t.buildMatchMemberExpression("process.env"); - -export var visitor = { - MemberExpression(node) { - if (match(node.object)) { - var key = this.toComputedKey(); - if (t.isLiteral(key)) { - return t.valueToNode(process.env[key.value]); - } - } - } -};