mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-21 15:25:09 +00:00
131 lines
No EOL
3.7 KiB
JavaScript
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);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}; |