summaryrefslogtreecommitdiff
path: root/node_modules/babel-plugin-transform-inline-consecutive-adds/lib
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2024-08-30 17:21:18 +0800
committerlittleblack111 <littleblack11111@gmail.com>2024-08-30 17:21:18 +0800
commitefbc2ffe6a1ee5ec38a4396305561d6515d0943e (patch)
tree2b4c94f18f2c792dfda813050755d5c0273fae22 /node_modules/babel-plugin-transform-inline-consecutive-adds/lib
parent43acceb75957c880a5ba5a31aae221394a36d5f6 (diff)
node fixes, updates
Diffstat (limited to 'node_modules/babel-plugin-transform-inline-consecutive-adds/lib')
-rw-r--r--node_modules/babel-plugin-transform-inline-consecutive-adds/lib/array-collapser.js52
-rw-r--r--node_modules/babel-plugin-transform-inline-consecutive-adds/lib/array-property-collapser.js99
-rw-r--r--node_modules/babel-plugin-transform-inline-consecutive-adds/lib/collapser.js32
-rw-r--r--node_modules/babel-plugin-transform-inline-consecutive-adds/lib/index.js228
-rw-r--r--node_modules/babel-plugin-transform-inline-consecutive-adds/lib/object-collapser.js60
-rw-r--r--node_modules/babel-plugin-transform-inline-consecutive-adds/lib/set-collapser.js61
6 files changed, 532 insertions, 0 deletions
diff --git a/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/array-collapser.js b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/array-collapser.js
new file mode 100644
index 00000000..540c92aa
--- /dev/null
+++ b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/array-collapser.js
@@ -0,0 +1,52 @@
+"use strict";
+
+const Collapser = require("./collapser");
+
+class ArrayCollapser extends Collapser {
+ isInitTypeValid(init) {
+ return init.isArrayExpression();
+ }
+
+ isExpressionTypeValid(expr) {
+ return expr.isCallExpression();
+ }
+
+ getExpressionChecker(objName, checkReference) {
+ return expr => {
+ // checks expr is of form:
+ // foo.push(rval1, ...nrvals)
+ const callee = expr.get("callee");
+
+ if (!callee.isMemberExpression()) {
+ return false;
+ }
+
+ const obj = callee.get("object"),
+ prop = callee.get("property");
+
+ if (!obj.isIdentifier() || obj.node.name !== objName || !prop.isIdentifier() || prop.node.name !== "push") {
+ return false;
+ }
+
+ const args = expr.get("arguments");
+
+ if (args.some(checkReference)) {
+ return false;
+ }
+
+ return true;
+ };
+ }
+
+ extractAssignment(expr) {
+ return expr.node.arguments;
+ }
+
+ addSuccessfully(t, args, init) {
+ args.map(a => init.elements.push(a));
+ return true;
+ }
+
+}
+
+module.exports = ArrayCollapser; \ No newline at end of file
diff --git a/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/array-property-collapser.js b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/array-property-collapser.js
new file mode 100644
index 00000000..9e83b38f
--- /dev/null
+++ b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/array-property-collapser.js
@@ -0,0 +1,99 @@
+"use strict";
+
+const Collapser = require("./collapser");
+
+class ArrayPropertyCollapser extends Collapser {
+ isInitTypeValid(init) {
+ return init.isArrayExpression();
+ }
+
+ isExpressionTypeValid(expr) {
+ return expr.isAssignmentExpression();
+ }
+
+ getExpressionChecker(objName, checkReference) {
+ return expr => {
+ // checks expr is of form:
+ // foo[num] = rval
+ const left = expr.get("left");
+
+ if (!left.isMemberExpression()) {
+ return false;
+ }
+
+ const obj = left.get("object"),
+ prop = left.get("property");
+
+ if (!obj.isIdentifier() || obj.node.name !== objName) {
+ return false;
+ }
+
+ const checkIndex = num => Number.isInteger(num) && num >= 0;
+
+ if (!(prop.isNumericLiteral() || prop.isStringLiteral()) || !checkIndex(Number(prop.node.value))) {
+ return false;
+ }
+
+ const right = expr.get("right");
+
+ if (checkReference(right)) {
+ return false;
+ }
+
+ return true;
+ };
+ }
+
+ extractAssignment(expr) {
+ return [expr.node.left.property.value, expr.get("right")];
+ }
+
+ addSuccessfully(t, [index, rval], init) {
+ const elements = init.elements;
+
+ for (let i = elements.length; i <= index; i++) {
+ elements.push(null);
+ }
+
+ if (elements[index] !== null) {
+ return false;
+ }
+
+ elements[index] = rval.node;
+ return true;
+ }
+
+ isSizeSmaller({
+ newInit,
+ oldInit,
+ varDecl,
+ assignments,
+ statements
+ }) {
+ const anyUndefined = args => args.some(a => a === undefined); // We make an inexact calculation of how much space we save.
+ // It's inexact because we don't know how whitespaces will get minimized,
+ // and other factors.
+
+
+ if (anyUndefined([statements[statements.length - 1].node.end, varDecl.node.end])) {
+ return false;
+ }
+
+ const statementsLength = statements[statements.length - 1].node.end - varDecl.node.end; // Approx. formula of the change in `init`'s length =
+ // (# commas added) + (size of all the new rvals added), where
+ // # commas added = (difference between the lengths of the old and new arrays)
+
+ const numCommaAdded = newInit.elements.length - oldInit.elements.length;
+
+ if (anyUndefined(assignments.map(([, rval]) => rval.node.end)) || anyUndefined(assignments.map(([, rval]) => rval.node.start))) {
+ return false;
+ }
+
+ const sizeOfRvals = assignments.map(([, rval]) => rval.node.end - rval.node.start + 1).reduce((a, b) => a + b, 0); // add 1 for space in front // sum
+
+ return numCommaAdded + sizeOfRvals < statementsLength;
+ }
+
+}
+
+module.exports = ArrayPropertyCollapser; \ No newline at end of file
diff --git a/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/collapser.js b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/collapser.js
new file mode 100644
index 00000000..5d1f2c01
--- /dev/null
+++ b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/collapser.js
@@ -0,0 +1,32 @@
+"use strict";
+
+const NotImplementedError = Error("NotImplementedError");
+
+class Collapser {
+ isInitTypeValid() {
+ throw NotImplementedError;
+ }
+
+ isExpressionTypeValid() {
+ throw NotImplementedError;
+ }
+
+ getExpressionChecker() {
+ throw NotImplementedError;
+ }
+
+ extractAssignment() {
+ throw NotImplementedError;
+ }
+
+ addSuccessfully() {
+ throw NotImplementedError;
+ }
+
+ isSizeSmaller() {
+ return true;
+ }
+
+}
+
+module.exports = Collapser; \ No newline at end of file
diff --git a/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/index.js b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/index.js
new file mode 100644
index 00000000..80811010
--- /dev/null
+++ b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/index.js
@@ -0,0 +1,228 @@
+"use strict";
+
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
+
+function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
+
+function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
+
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
+
+const COLLAPSERS = [require("./object-collapser"), require("./array-collapser"), require("./array-property-collapser"), require("./set-collapser")].map(Collapser => {
+ return new Collapser();
+});
+
+function getFunctionParent(path, scopeParent) {
+ const parent = path.findParent(p => p.isFunction()); // don"t traverse higher than the function the var is defined in.
+
+ return parent === scopeParent ? null : parent;
+}
+
+function getFunctionReferences(path, scopeParent, references = new Set()) {
+ for (let func = getFunctionParent(path, scopeParent); func; func = getFunctionParent(func, scopeParent)) {
+ const id = func.node.id;
+ const binding = id && func.scope.getBinding(id.name);
+
+ if (!binding) {
+ continue;
+ }
+
+ binding.referencePaths.forEach(path => {
+ if (!references.has(path)) {
+ references.add(path);
+ getFunctionReferences(path, scopeParent, references);
+ }
+ });
+ }
+
+ return references;
+}
+
+function getIdAndFunctionReferences(name, parent) {
+ // Returns false if there's an error. Otherwise returns a list of references.
+ const binding = parent.scope.getBinding(name);
+
+ if (!binding) {
+ return false;
+ }
+
+ const references = binding.referencePaths.reduce((references, ref) => {
+ references.add(ref);
+ getFunctionReferences(ref, parent, references);
+ return references;
+ }, new Set());
+ return Array.from(references);
+}
+
+function validateTopLevel(path) {
+ // Ensures the structure is of the form (roughly):
+ // {
+ // ...
+ // var foo = expr;
+ // ...
+ // }
+ // returns null if not of this form
+ // otherwise returns [foo as string, ?rval, index of the variable declaration]
+ const declarations = path.get("declarations");
+
+ if (declarations.length !== 1) {
+ return;
+ }
+
+ const declaration = declarations[0];
+ const id = declaration.get("id"),
+ init = declaration.get("init");
+
+ if (!id.isIdentifier()) {
+ return;
+ }
+
+ const parent = path.parentPath;
+
+ if (!parent.isBlockParent() || !parent.isScopable()) {
+ return;
+ }
+
+ const body = parent.get("body");
+
+ if (!Array.isArray(body)) {
+ return;
+ }
+
+ const startIndex = body.indexOf(path);
+
+ if (startIndex === -1) {
+ return;
+ }
+
+ return [id.node.name, init, startIndex];
+}
+
+function collectExpressions(path, isExprTypeValid) {
+ // input: ExprStatement => 'a | SequenceExpression
+ // SequenceExpression => 'a list
+ // Validates 'a is of the right type
+ // returns null if found inconsistency, else returns Array<"a>
+ if (path.isExpressionStatement()) {
+ const exprs = collectExpressions(path.get("expression"), isExprTypeValid);
+ return exprs !== null ? exprs : null;
+ }
+
+ if (path.isSequenceExpression()) {
+ const exprs = path.get("expressions").map(p => collectExpressions(p, isExprTypeValid));
+
+ if (exprs.some(e => e === null)) {
+ return null;
+ } else {
+ return exprs.reduce((s, n) => s.concat(n), []); // === Array.flatten
+ }
+ }
+
+ if (isExprTypeValid(path)) {
+ return [path];
+ }
+
+ return null;
+}
+
+function getContiguousStatementsAndExpressions(body, start, end, isExprTypeValid, checkExpr) {
+ const statements = [];
+ let allExprs = [];
+
+ for (let i = start; i < end; i++) {
+ const exprs = collectExpressions(body[i], isExprTypeValid);
+
+ if (exprs === null || !exprs.every(e => checkExpr(e))) {
+ break;
+ }
+
+ statements.push(body[i]);
+ allExprs = allExprs.concat(exprs);
+ }
+
+ return [statements, allExprs];
+}
+
+function getReferenceChecker(references) {
+ // returns a function s.t. given an expr, returns true iff expr is an ancestor of a reference
+ return expr => references.some(r => r === expr || r.isDescendant(expr));
+}
+
+function tryUseCollapser(t, collapser, varDecl, topLevel, checkReference) {
+ // Returns true iff successfully used the collapser. Otherwise returns undefined.
+ const _topLevel = _slicedToArray(topLevel, 3),
+ name = _topLevel[0],
+ init = _topLevel[1],
+ startIndex = _topLevel[2];
+
+ if (!collapser.isInitTypeValid(init)) {
+ return;
+ }
+
+ const body = varDecl.parentPath.get("body");
+
+ const _getContiguousStateme = getContiguousStatementsAndExpressions(body, startIndex + 1, body.length, collapser.isExpressionTypeValid, collapser.getExpressionChecker(name, checkReference)),
+ _getContiguousStateme2 = _slicedToArray(_getContiguousStateme, 2),
+ statements = _getContiguousStateme2[0],
+ exprs = _getContiguousStateme2[1];
+
+ if (statements.length === 0) {
+ return;
+ }
+
+ const assignments = exprs.map(e => collapser.extractAssignment(e));
+ const oldInit = init.node;
+ const newInit = t.cloneDeep(oldInit);
+
+ if (!assignments.every(assignment => collapser.addSuccessfully(t, assignment, newInit))) {
+ return;
+ } // some collapses may increase the size
+
+
+ if (!collapser.isSizeSmaller({
+ newInit,
+ oldInit,
+ varDecl,
+ assignments,
+ statements
+ })) {
+ return;
+ }
+
+ init.replaceWith(newInit);
+ statements.forEach(s => s.remove());
+ return true;
+}
+
+module.exports = function ({
+ types: t
+}) {
+ return {
+ name: "transform-inline-consecutive-adds",
+ visitor: {
+ VariableDeclaration(varDecl) {
+ const topLevel = validateTopLevel(varDecl);
+
+ if (!topLevel) {
+ return;
+ }
+
+ const _topLevel2 = _slicedToArray(topLevel, 1),
+ name = _topLevel2[0];
+
+ const references = getIdAndFunctionReferences(name, varDecl.parentPath);
+
+ if (references === false) {
+ return;
+ }
+
+ const checkReference = getReferenceChecker(references);
+
+ if (COLLAPSERS.some(c => tryUseCollapser(t, c, varDecl, topLevel, checkReference))) {
+ return;
+ }
+ }
+
+ }
+ };
+}; \ No newline at end of file
diff --git a/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/object-collapser.js b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/object-collapser.js
new file mode 100644
index 00000000..c8fe59ad
--- /dev/null
+++ b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/object-collapser.js
@@ -0,0 +1,60 @@
+"use strict";
+
+const Collapser = require("./collapser");
+
+class ObjectCollapser extends Collapser {
+ isInitTypeValid(init) {
+ return init.isObjectExpression();
+ }
+
+ isExpressionTypeValid(expr) {
+ return expr.isAssignmentExpression();
+ }
+
+ getExpressionChecker(objName, checkReference) {
+ return expr => {
+ // checks expr is of form:
+ // foo.a = rval | foo[a] = rval
+ const left = expr.get("left");
+
+ if (!left.isMemberExpression()) {
+ return false;
+ }
+
+ const obj = left.get("object"),
+ prop = left.get("property");
+
+ if (!obj.isIdentifier() || obj.node.name !== objName) {
+ return false;
+ }
+
+ if (!prop.isIdentifier() && checkReference(prop)) {
+ return false;
+ }
+
+ if (left.node.computed && !(prop.isStringLiteral() || prop.isNumericLiteral())) {
+ return false;
+ }
+
+ const right = expr.get("right");
+
+ if (checkReference(right)) {
+ return false;
+ }
+
+ return true;
+ };
+ }
+
+ extractAssignment(expr) {
+ return [expr.node.left.property, expr.node.right];
+ }
+
+ addSuccessfully(t, [left, right], init) {
+ init.properties.push(t.objectProperty(left, right));
+ return true;
+ }
+
+}
+
+module.exports = ObjectCollapser; \ No newline at end of file
diff --git a/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/set-collapser.js b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/set-collapser.js
new file mode 100644
index 00000000..e4b37b31
--- /dev/null
+++ b/node_modules/babel-plugin-transform-inline-consecutive-adds/lib/set-collapser.js
@@ -0,0 +1,61 @@
+"use strict";
+
+const Collapser = require("./collapser");
+
+class SetCollapser extends Collapser {
+ isInitTypeValid(init) {
+ return init.isNewExpression() && init.get("callee").isIdentifier() && init.node.callee.name === "Set" && ( // other iterables might not be append-able
+ init.node.arguments.length === 0 || init.node.arguments.length === 1 && init.get("arguments")[0].isArrayExpression());
+ }
+
+ isExpressionTypeValid(expr) {
+ return expr.isCallExpression();
+ }
+
+ getExpressionChecker(objName, checkReference) {
+ return expr => {
+ // checks expr is of form:
+ // foo.add(rval)
+ const callee = expr.get("callee");
+
+ if (!callee.isMemberExpression()) {
+ return false;
+ }
+
+ const obj = callee.get("object"),
+ prop = callee.get("property");
+
+ if (!obj.isIdentifier() || obj.node.name !== objName || !prop.isIdentifier() || prop.node.name !== "add") {
+ return false;
+ }
+
+ const args = expr.get("arguments");
+
+ if (args.length !== 1) {
+ return false;
+ }
+
+ if (checkReference(args[0])) {
+ return false;
+ }
+
+ return true;
+ };
+ }
+
+ extractAssignment(expr) {
+ return expr.node.arguments[0];
+ }
+
+ addSuccessfully(t, arg, init) {
+ if (init.arguments.length === 0) {
+ init.arguments.push(t.arrayExpression());
+ }
+
+ init.arguments[0].elements.push(arg);
+ return true;
+ }
+
+}
+
+module.exports = SetCollapser; \ No newline at end of file