diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
| commit | efbc2ffe6a1ee5ec38a4396305561d6515d0943e (patch) | |
| tree | 2b4c94f18f2c792dfda813050755d5c0273fae22 /node_modules/babel-plugin-transform-remove-undefined/lib | |
| parent | 43acceb75957c880a5ba5a31aae221394a36d5f6 (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.js | 249 |
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 |
