split up es3.xLiterals transformers - fixes #1415
This commit is contained in:
@@ -2,11 +2,7 @@ import * as t from "../../../types";
|
||||
|
||||
export function MemberExpression(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;
|
||||
} else if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
|
||||
if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
|
||||
// foo.default -> foo["default"]
|
||||
node.property = t.literal(prop.name);
|
||||
node.computed = true;
|
||||
|
||||
@@ -2,11 +2,7 @@ import * as t from "../../../types";
|
||||
|
||||
export function Property(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;
|
||||
} else if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
|
||||
if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
|
||||
// default: "bar" -> "default": "bar"
|
||||
node.key = t.literal(key.name);
|
||||
}
|
||||
|
||||
@@ -16,27 +16,13 @@ function loose(node, body, objId) {
|
||||
|
||||
function spec(node, body, objId, initProps, file) {
|
||||
var props = node.properties;
|
||||
var prop, key;
|
||||
|
||||
// normalize key
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
if (prop.kind !== "init") continue;
|
||||
|
||||
key = prop.key;
|
||||
|
||||
if (!prop.computed && t.isIdentifier(key)) {
|
||||
prop.key = t.literal(key.name);
|
||||
}
|
||||
}
|
||||
|
||||
// add all non-computed properties and `__proto__` properties to the initializer
|
||||
|
||||
var broken = false;
|
||||
|
||||
for (i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
let prop = props[i];
|
||||
|
||||
if (prop.computed) {
|
||||
broken = true;
|
||||
@@ -51,24 +37,17 @@ function spec(node, body, objId, initProps, file) {
|
||||
// add a simple assignment for all Symbol member expressions due to symbol polyfill limitations
|
||||
// otherwise use Object.defineProperty
|
||||
|
||||
for (i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
let prop = props[i];
|
||||
if (!prop) continue;
|
||||
|
||||
key = prop.key;
|
||||
var bodyNode;
|
||||
|
||||
if (prop.computed && t.isMemberExpression(key) && t.isIdentifier(key.object, { name: "Symbol" })) {
|
||||
// { [Symbol.iterator]: "foo" }
|
||||
bodyNode = t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(objId, key, true),
|
||||
prop.value
|
||||
);
|
||||
} else {
|
||||
bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
|
||||
let key = prop.key;
|
||||
if (t.isIdentifier(key) && !prop.computed) {
|
||||
key = t.literal(key.name);
|
||||
}
|
||||
|
||||
var bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
|
||||
|
||||
body.push(t.expressionStatement(bodyNode));
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,10 @@ export default {
|
||||
|
||||
"utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"),
|
||||
"utility.inlineExpressions": require("./utility/inline-expressions"),
|
||||
"utility.deadCodeElimination": require("./utility/dead-code-elimination"),
|
||||
|
||||
"minification.deadCodeElimination": require("./minification/dead-code-elimination"),
|
||||
"minification.memberExpressionLiterals": require("./minification/member-expression-literals"),
|
||||
"minification.propertyLiterals": require("./minification/property-literals"),
|
||||
|
||||
jscript: require("./other/jscript"),
|
||||
flow: require("./other/flow")
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
};
|
||||
|
||||
export function MemberExpression(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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
};
|
||||
|
||||
export function Property(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,120 +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
|
||||
};
|
||||
|
||||
export function Identifier(node, parent, scope) {
|
||||
if (!this.isReferenced()) return;
|
||||
|
||||
var binding = scope.getBinding(node.name);
|
||||
if (!binding || binding.references > 1 || !binding.constant) return;
|
||||
|
||||
var replacement = binding.path.node;
|
||||
if (t.isVariableDeclarator(replacement)) {
|
||||
replacement = replacement.init;
|
||||
}
|
||||
t.toExpression(replacement);
|
||||
|
||||
scope.removeBinding(node.name);
|
||||
|
||||
binding.path.remove();
|
||||
return replacement;
|
||||
}
|
||||
|
||||
export function FunctionDeclaration(node, parent, scope) {
|
||||
var bindingInfo = scope.getBinding(node.id.name);
|
||||
if (bindingInfo && !bindingInfo.referenced) {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
|
||||
export { FunctionDeclaration as ClassDeclaration };
|
||||
|
||||
export function VariableDeclarator(node, parent, scope) {
|
||||
if (!t.isIdentifier(node.id) || !scope.isPure(node.init)) return;
|
||||
FunctionDeclaration.apply(this, arguments);
|
||||
}
|
||||
|
||||
export function ConditionalExpression(node, parent, scope) {
|
||||
var evaluateTest = this.get("test").evaluateTruthy();
|
||||
if (evaluateTest === true) {
|
||||
return node.consequent;
|
||||
} else if (evaluateTest === false) {
|
||||
return node.alternate;
|
||||
}
|
||||
}
|
||||
|
||||
export var IfStatement = {
|
||||
exit(node, parent, scope) {
|
||||
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.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user