frappe_docker/frappe-bench/node_modules/babel-plugin-minify-constant-folding/lib/index.js
2017-07-31 15:51:51 +05:30

131 lines
No EOL
3.7 KiB
JavaScript

"use strict";
var evaluate = require("babel-helper-evaluate-path");
var jsesc = require("jsesc");
module.exports = function (_ref) {
var t = _ref.types,
traverse = _ref.traverse;
var seen = Symbol("seen");
return {
name: "minify-constant-folding",
visitor: {
// Evaluate string expressions that are next to each other
// but are not actually a binary expression.
// "a" + b + "c" + "d" -> "a" + b + "cd"
BinaryExpression(path) {
var literal = void 0,
bin = void 0;
if (path.get("right").isStringLiteral()) {
literal = path.get("right");
if (path.get("left").isBinaryExpression({ operator: "+" })) {
bin = path.get("left");
} else {
return;
}
} else if (path.get("left").isStringLiteral()) {
literal = path.get("left");
if (path.get("right").isBinaryExpression({ operator: "+" })) {
bin = path.get("right");
} else {
return;
}
} else {
return;
}
var relevant = getLeaf(bin, literal.key);
if (!relevant) {
return;
}
var value = literal.key === "right" ? relevant.node.value + literal.node.value : literal.node.value + relevant.node.value;
relevant.replaceWith(t.stringLiteral(value));
path.replaceWith(bin.node);
function getLeaf(path, direction) {
if (path.isStringLiteral()) {
return path;
} else if (path.isBinaryExpression({ operator: "+" })) {
return getLeaf(path.get(direction), direction);
}
}
},
// TODO: look into evaluating binding too (could result in more code, but gzip?)
Expression(path) {
var node = path.node;
if (node[seen]) {
return;
}
if (path.isLiteral()) {
return;
}
if (!path.isPure()) {
return;
}
if (traverse.hasType(node, path.scope, "Identifier", t.FUNCTION_TYPES)) {
return;
}
// -0 maybe compared via dividing and then checking against -Infinity
// Also -X will always be -X.
if (t.isUnaryExpression(node, { operator: "-" }) && t.isNumericLiteral(node.argument)) {
return;
}
// We have a transform that converts true/false to !0/!1
if (t.isUnaryExpression(node, { operator: "!" }) && t.isNumericLiteral(node.argument)) {
if (node.argument.value === 0 || node.argument.value === 1) {
return;
}
}
// void 0 is used for undefined.
if (t.isUnaryExpression(node, { operator: "void" }) && t.isNumericLiteral(node.argument, { value: 0 })) {
return;
}
var res = evaluate(path);
if (res.confident) {
// Avoid fractions because they can be longer than the original expression.
// There is also issues with number percision?
if (typeof res.value === "number" && !Number.isInteger(res.value)) {
return;
}
// Preserve -0
if (typeof res.value === "number" && res.value === 0) {
if (1 / res.value === -Infinity) {
var _node2 = t.unaryExpression("-", t.numericLiteral(0), true);
_node2[seen] = true;
path.replaceWith(_node2);
return;
}
}
// https://github.com/babel/babili/issues/382
if (typeof res.value === "string") {
res.value = jsesc(res.value, {
isScriptContext: true
});
}
var _node = t.valueToNode(res.value);
_node[seen] = true;
path.replaceWith(_node);
}
}
}
};
};