yank out more transformers and put them into plugins
This commit is contained in:
parent
939c00d33c
commit
3247851019
11
package.json
11
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",
|
||||
|
||||
@ -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"),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1,10 +0,0 @@
|
||||
export var metadata = {
|
||||
optional: true,
|
||||
group: "builtin-pre"
|
||||
};
|
||||
|
||||
export var visitor = {
|
||||
DebuggerStatement() {
|
||||
this.dangerouslyRemove();
|
||||
}
|
||||
};
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user