summaryrefslogtreecommitdiff
path: root/node_modules/babel-plugin-transform-remove-undefined/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-remove-undefined/lib
parent43acceb75957c880a5ba5a31aae221394a36d5f6 (diff)
node fixes, updates
Diffstat (limited to 'node_modules/babel-plugin-transform-remove-undefined/lib')
-rw-r--r--node_modules/babel-plugin-transform-remove-undefined/lib/index.js249
1 files changed, 249 insertions, 0 deletions
diff --git a/node_modules/babel-plugin-transform-remove-undefined/lib/index.js b/node_modules/babel-plugin-transform-remove-undefined/lib/index.js
new file mode 100644
index 00000000..0b09c1d7
--- /dev/null
+++ b/node_modules/babel-plugin-transform-remove-undefined/lib/index.js
@@ -0,0 +1,249 @@
+"use strict";
+
+const evaluate = require("babel-helper-evaluate-path");
+
+function isPureAndUndefined(rval, {
+ tdz,
+ scope = {
+ hasBinding: () => false
+ }
+} = {}) {
+ if (rval.isIdentifier() && rval.node.name === "undefined") {
+ // deopt right away if undefined is a local binding
+ if (scope.hasBinding(rval.node.name, true
+ /* no globals */
+ )) {
+ return false;
+ }
+
+ return true;
+ }
+
+ if (!rval.isPure()) {
+ return false;
+ }
+
+ const evaluation = evaluate(rval, {
+ tdz
+ });
+ return evaluation.confident === true && evaluation.value === undefined;
+}
+
+function getLoopParent(path, scopeParent) {
+ const parent = path.findParent(p => p.isLoop() || p === scopeParent); // don't traverse higher than the function the var is defined in.
+
+ return parent === scopeParent ? null : parent;
+}
+
+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 hasViolation(declarator, scope, start) {
+ const binding = scope.getBinding(declarator.node.id.name);
+
+ if (!binding) {
+ return true;
+ }
+
+ const scopeParent = declarator.getFunctionParent();
+ const violation = binding.constantViolations.some(v => {
+ // https://github.com/babel/minify/issues/630
+ if (!v.node) {
+ return false;
+ } // return 'true' if we cannot guarantee the violation references
+ // the initialized identifier after
+
+
+ const violationStart = v.node.start;
+
+ if (violationStart === undefined || violationStart < start) {
+ return true;
+ }
+
+ const references = getFunctionReferences(v, scopeParent);
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = references[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ const ref = _step.value;
+
+ if (ref.node.start === undefined || ref.node.start < start) {
+ return true;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
+ _iterator.return();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ for (let loop = getLoopParent(declarator, scopeParent); loop; loop = getLoopParent(loop, scopeParent)) {
+ if (loop.node.end === undefined || loop.node.end > violationStart) {
+ return true;
+ }
+ }
+ });
+ return violation;
+}
+
+module.exports = function () {
+ return {
+ name: "transform-remove-undefined",
+ visitor: {
+ SequenceExpression(path, {
+ opts: {
+ tdz
+ } = {}
+ }) {
+ const expressions = path.get("expressions");
+
+ for (let i = 0; i < expressions.length; i++) {
+ const expr = expressions[i];
+ if (!isPureAndUndefined(expr, {
+ tdz,
+ scope: path.scope
+ })) continue; // last value
+
+ if (i === expressions.length - 1) {
+ if (path.parentPath.isExpressionStatement()) {
+ expr.remove();
+ }
+ } else {
+ expr.remove();
+ }
+ }
+ },
+
+ ReturnStatement(path, {
+ opts: {
+ tdz
+ } = {}
+ }) {
+ if (path.node.argument !== null) {
+ if (isPureAndUndefined(path.get("argument"), {
+ tdz,
+ scope: path.scope
+ })) {
+ path.node.argument = null;
+ }
+ }
+ },
+
+ VariableDeclaration(path, {
+ opts: {
+ tdz
+ } = {}
+ }) {
+ switch (path.node.kind) {
+ case "const":
+ break;
+
+ case "let":
+ var _iteratorNormalCompletion2 = true;
+ var _didIteratorError2 = false;
+ var _iteratorError2 = undefined;
+
+ try {
+ for (var _iterator2 = path.get("declarations")[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+ const declarator = _step2.value;
+
+ if (isPureAndUndefined(declarator.get("init"), {
+ tdz
+ })) {
+ declarator.node.init = null;
+ }
+ }
+ } catch (err) {
+ _didIteratorError2 = true;
+ _iteratorError2 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
+ _iterator2.return();
+ }
+ } finally {
+ if (_didIteratorError2) {
+ throw _iteratorError2;
+ }
+ }
+ }
+
+ break;
+
+ case "var":
+ const start = path.node.start;
+
+ if (start === undefined) {
+ // This is common for plugin-generated nodes
+ break;
+ }
+
+ const scope = path.scope;
+ var _iteratorNormalCompletion3 = true;
+ var _didIteratorError3 = false;
+ var _iteratorError3 = undefined;
+
+ try {
+ for (var _iterator3 = path.get("declarations")[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ const declarator = _step3.value;
+
+ if (isPureAndUndefined(declarator.get("init")) && !hasViolation(declarator, scope, start)) {
+ declarator.node.init = null;
+ }
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
+ _iterator3.return();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+
+ }
+ };
+}; \ No newline at end of file