1
0
mirror of https://github.com/S2-/minifyfromhtml.git synced 2025-08-03 20:30:04 +02:00
Files
minifyfromhtml/node_modules/babel-plugin-minify-simplify/lib/assignment-expression.js
2018-05-05 13:54:07 +02:00

96 lines
2.5 KiB
JavaScript

"use strict";
const operators = new Set(["+", "-", "*", "%", "<<", ">>", ">>>", "&", "|", "^", "/", "**"]);
const updateOperators = new Set(["+", "-"]);
module.exports = t => {
function simplify(path) {
const rightExpr = path.get("right");
const leftExpr = path.get("left");
if (path.node.operator !== "=") {
return;
}
const canBeUpdateExpression = rightExpr.get("right").isNumericLiteral() && rightExpr.get("right").node.value === 1 && updateOperators.has(rightExpr.node.operator);
if (leftExpr.isMemberExpression()) {
const leftPropNames = getPropNames(leftExpr);
const rightPropNames = getPropNames(rightExpr.get("left"));
if (!leftPropNames || leftPropNames.indexOf(undefined) > -1 || !rightPropNames || rightPropNames.indexOf(undefined) > -1 || !operators.has(rightExpr.node.operator) || !areArraysEqual(leftPropNames, rightPropNames)) {
return;
}
} else {
if (!rightExpr.isBinaryExpression() || !operators.has(rightExpr.node.operator) || leftExpr.node.name !== rightExpr.node.left.name) {
return;
}
}
let newExpression; // special case x=x+1 --> ++x
if (canBeUpdateExpression) {
newExpression = t.updateExpression(rightExpr.node.operator + rightExpr.node.operator, t.clone(leftExpr.node), true
/* prefix */
);
} else {
newExpression = t.assignmentExpression(rightExpr.node.operator + "=", t.clone(leftExpr.node), t.clone(rightExpr.node.right));
}
path.replaceWith(newExpression);
}
return {
simplify
};
};
function areArraysEqual(arr1, arr2) {
return arr1.every((value, index) => {
return String(value) === String(arr2[index]);
});
}
function getPropNames(path) {
if (!path.isMemberExpression()) {
return;
}
let obj = path.get("object");
const prop = path.get("property");
const propNames = [getName(prop.node)];
while (obj.type === "MemberExpression") {
const node = obj.get("property").node;
if (node) {
propNames.push(getName(node));
}
obj = obj.get("object");
}
propNames.push(getName(obj.node));
return propNames;
}
function getName(node) {
if (node.type === "ThisExpression") {
return "this";
}
if (node.type === "Super") {
return "super";
}
if (node.type === "NullLiteral") {
return "null";
} // augment identifiers so that they don't match
// string/number literals
// but still match against each other
return node.name ? node.name + "_" : node.value
/* Literal */
;
}