| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 | 
							- "use strict";
 
- Object.defineProperty(exports, "__esModule", {
 
-   value: true
 
- });
 
- exports.getLoopBodyBindings = getLoopBodyBindings;
 
- exports.getUsageInBody = getUsageInBody;
 
- exports.isVarInLoopHead = isVarInLoopHead;
 
- exports.wrapLoopBody = wrapLoopBody;
 
- var _core = require("@babel/core");
 
- const collectLoopBodyBindingsVisitor = {
 
-   "Expression|Declaration|Loop"(path) {
 
-     path.skip();
 
-   },
 
-   Scope(path, state) {
 
-     if (path.isFunctionParent()) path.skip();
 
-     const {
 
-       bindings
 
-     } = path.scope;
 
-     for (const name of Object.keys(bindings)) {
 
-       const binding = bindings[name];
 
-       if (binding.kind === "let" || binding.kind === "const" || binding.kind === "hoisted") {
 
-         state.blockScoped.push(binding);
 
-       }
 
-     }
 
-   }
 
- };
 
- function getLoopBodyBindings(loopPath) {
 
-   const state = {
 
-     blockScoped: []
 
-   };
 
-   loopPath.traverse(collectLoopBodyBindingsVisitor, state);
 
-   return state.blockScoped;
 
- }
 
- function getUsageInBody(binding, loopPath) {
 
-   const seen = new WeakSet();
 
-   let capturedInClosure = false;
 
-   const constantViolations = filterMap(binding.constantViolations, path => {
 
-     const {
 
-       inBody,
 
-       inClosure
 
-     } = relativeLoopLocation(path, loopPath);
 
-     if (!inBody) return null;
 
-     capturedInClosure || (capturedInClosure = inClosure);
 
-     const id = path.isUpdateExpression() ? path.get("argument") : path.isAssignmentExpression() ? path.get("left") : null;
 
-     if (id) seen.add(id.node);
 
-     return id;
 
-   });
 
-   const references = filterMap(binding.referencePaths, path => {
 
-     if (seen.has(path.node)) return null;
 
-     const {
 
-       inBody,
 
-       inClosure
 
-     } = relativeLoopLocation(path, loopPath);
 
-     if (!inBody) return null;
 
-     capturedInClosure || (capturedInClosure = inClosure);
 
-     return path;
 
-   });
 
-   return {
 
-     capturedInClosure,
 
-     hasConstantViolations: constantViolations.length > 0,
 
-     usages: references.concat(constantViolations)
 
-   };
 
- }
 
- function relativeLoopLocation(path, loopPath) {
 
-   const bodyPath = loopPath.get("body");
 
-   let inClosure = false;
 
-   for (let currPath = path; currPath; currPath = currPath.parentPath) {
 
-     if (currPath.isFunction() || currPath.isClass() || currPath.isMethod()) {
 
-       inClosure = true;
 
-     }
 
-     if (currPath === bodyPath) {
 
-       return {
 
-         inBody: true,
 
-         inClosure
 
-       };
 
-     } else if (currPath === loopPath) {
 
-       return {
 
-         inBody: false,
 
-         inClosure
 
-       };
 
-     }
 
-   }
 
-   throw new Error("Internal Babel error: path is not in loop. Please report this as a bug.");
 
- }
 
- const collectCompletionsAndVarsVisitor = {
 
-   Function(path) {
 
-     path.skip();
 
-   },
 
-   LabeledStatement: {
 
-     enter({
 
-       node
 
-     }, state) {
 
-       state.labelsStack.push(node.label.name);
 
-     },
 
-     exit({
 
-       node
 
-     }, state) {
 
-       const popped = state.labelsStack.pop();
 
-       if (popped !== node.label.name) {
 
-         throw new Error("Assertion failure. Please report this bug to Babel.");
 
-       }
 
-     }
 
-   },
 
-   Loop: {
 
-     enter(_, state) {
 
-       state.labellessContinueTargets++;
 
-       state.labellessBreakTargets++;
 
-     },
 
-     exit(_, state) {
 
-       state.labellessContinueTargets--;
 
-       state.labellessBreakTargets--;
 
-     }
 
-   },
 
-   SwitchStatement: {
 
-     enter(_, state) {
 
-       state.labellessBreakTargets++;
 
-     },
 
-     exit(_, state) {
 
-       state.labellessBreakTargets--;
 
-     }
 
-   },
 
-   "BreakStatement|ContinueStatement"(path, state) {
 
-     const {
 
-       label
 
-     } = path.node;
 
-     if (label) {
 
-       if (state.labelsStack.includes(label.name)) return;
 
-     } else if (path.isBreakStatement() ? state.labellessBreakTargets > 0 : state.labellessContinueTargets > 0) {
 
-       return;
 
-     }
 
-     state.breaksContinues.push(path);
 
-   },
 
-   ReturnStatement(path, state) {
 
-     state.returns.push(path);
 
-   },
 
-   VariableDeclaration(path, state) {
 
-     if (path.parent === state.loopNode && isVarInLoopHead(path)) return;
 
-     if (path.node.kind === "var") state.vars.push(path);
 
-   }
 
- };
 
- function wrapLoopBody(loopPath, captured, updatedBindingsUsages) {
 
-   const loopNode = loopPath.node;
 
-   const state = {
 
-     breaksContinues: [],
 
-     returns: [],
 
-     labelsStack: [],
 
-     labellessBreakTargets: 0,
 
-     labellessContinueTargets: 0,
 
-     vars: [],
 
-     loopNode
 
-   };
 
-   loopPath.traverse(collectCompletionsAndVarsVisitor, state);
 
-   const callArgs = [];
 
-   const closureParams = [];
 
-   const updater = [];
 
-   for (const [name, updatedUsage] of updatedBindingsUsages) {
 
-     callArgs.push(_core.types.identifier(name));
 
-     const innerName = loopPath.scope.generateUid(name);
 
-     closureParams.push(_core.types.identifier(innerName));
 
-     updater.push(_core.types.assignmentExpression("=", _core.types.identifier(name), _core.types.identifier(innerName)));
 
-     for (const path of updatedUsage) path.replaceWith(_core.types.identifier(innerName));
 
-   }
 
-   for (const name of captured) {
 
-     if (updatedBindingsUsages.has(name)) continue;
 
-     callArgs.push(_core.types.identifier(name));
 
-     closureParams.push(_core.types.identifier(name));
 
-   }
 
-   const id = loopPath.scope.generateUid("loop");
 
-   const fn = _core.types.functionExpression(null, closureParams, _core.types.toBlock(loopNode.body));
 
-   let call = _core.types.callExpression(_core.types.identifier(id), callArgs);
 
-   const fnParent = loopPath.findParent(p => p.isFunction());
 
-   if (fnParent) {
 
-     const {
 
-       async,
 
-       generator
 
-     } = fnParent.node;
 
-     fn.async = async;
 
-     fn.generator = generator;
 
-     if (generator) call = _core.types.yieldExpression(call, true);else if (async) call = _core.types.awaitExpression(call);
 
-   }
 
-   const updaterNode = updater.length > 0 ? _core.types.expressionStatement(_core.types.sequenceExpression(updater)) : null;
 
-   if (updaterNode) fn.body.body.push(updaterNode);
 
-   const [varPath] = loopPath.insertBefore(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(_core.types.identifier(id), fn)]));
 
-   const bodyStmts = [];
 
-   const varNames = [];
 
-   for (const varPath of state.vars) {
 
-     const assign = [];
 
-     for (const decl of varPath.node.declarations) {
 
-       varNames.push(...Object.keys(_core.types.getBindingIdentifiers(decl.id)));
 
-       if (decl.init) {
 
-         assign.push(_core.types.assignmentExpression("=", decl.id, decl.init));
 
-       } else if (_core.types.isForXStatement(varPath.parent, {
 
-         left: varPath.node
 
-       })) {
 
-         assign.push(decl.id);
 
-       }
 
-     }
 
-     if (assign.length > 0) {
 
-       const replacement = assign.length === 1 ? assign[0] : _core.types.sequenceExpression(assign);
 
-       varPath.replaceWith(replacement);
 
-     } else {
 
-       varPath.remove();
 
-     }
 
-   }
 
-   if (varNames.length) {
 
-     varPath.pushContainer("declarations", varNames.map(name => _core.types.variableDeclarator(_core.types.identifier(name))));
 
-   }
 
-   const labelNum = state.breaksContinues.length;
 
-   const returnNum = state.returns.length;
 
-   if (labelNum + returnNum === 0) {
 
-     bodyStmts.push(_core.types.expressionStatement(call));
 
-   } else if (labelNum === 1 && returnNum === 0) {
 
-     for (const path of state.breaksContinues) {
 
-       const {
 
-         node
 
-       } = path;
 
-       const {
 
-         type,
 
-         label
 
-       } = node;
 
-       let name = type === "BreakStatement" ? "break" : "continue";
 
-       if (label) name += " " + label.name;
 
-       path.replaceWith(_core.types.addComment(_core.types.returnStatement(_core.types.numericLiteral(1)), "trailing", " " + name, true));
 
-       if (updaterNode) path.insertBefore(_core.types.cloneNode(updaterNode));
 
-       bodyStmts.push(_core.template.statement.ast`
 
-         if (${call}) ${node}
 
-       `);
 
-     }
 
-   } else {
 
-     const completionId = loopPath.scope.generateUid("ret");
 
-     if (varPath.isVariableDeclaration()) {
 
-       varPath.pushContainer("declarations", [_core.types.variableDeclarator(_core.types.identifier(completionId))]);
 
-       bodyStmts.push(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.identifier(completionId), call)));
 
-     } else {
 
-       bodyStmts.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(_core.types.identifier(completionId), call)]));
 
-     }
 
-     const injected = [];
 
-     for (const path of state.breaksContinues) {
 
-       const {
 
-         node
 
-       } = path;
 
-       const {
 
-         type,
 
-         label
 
-       } = node;
 
-       let name = type === "BreakStatement" ? "break" : "continue";
 
-       if (label) name += " " + label.name;
 
-       let i = injected.indexOf(name);
 
-       const hasInjected = i !== -1;
 
-       if (!hasInjected) {
 
-         injected.push(name);
 
-         i = injected.length - 1;
 
-       }
 
-       path.replaceWith(_core.types.addComment(_core.types.returnStatement(_core.types.numericLiteral(i)), "trailing", " " + name, true));
 
-       if (updaterNode) path.insertBefore(_core.types.cloneNode(updaterNode));
 
-       if (hasInjected) continue;
 
-       bodyStmts.push(_core.template.statement.ast`
 
-         if (${_core.types.identifier(completionId)} === ${_core.types.numericLiteral(i)}) ${node}
 
-       `);
 
-     }
 
-     if (returnNum) {
 
-       for (const path of state.returns) {
 
-         const arg = path.node.argument || path.scope.buildUndefinedNode();
 
-         path.replaceWith(_core.template.statement.ast`
 
-           return { v: ${arg} };
 
-         `);
 
-       }
 
-       bodyStmts.push(_core.template.statement.ast`
 
-           if (${_core.types.identifier(completionId)}) return ${_core.types.identifier(completionId)}.v;
 
-         `);
 
-     }
 
-   }
 
-   loopNode.body = _core.types.blockStatement(bodyStmts);
 
-   return varPath;
 
- }
 
- function isVarInLoopHead(path) {
 
-   if (_core.types.isForStatement(path.parent)) return path.key === "init";
 
-   if (_core.types.isForXStatement(path.parent)) return path.key === "left";
 
-   return false;
 
- }
 
- function filterMap(list, fn) {
 
-   const result = [];
 
-   for (const item of list) {
 
-     const mapped = fn(item);
 
-     if (mapped) result.push(mapped);
 
-   }
 
-   return result;
 
- }
 
- //# sourceMappingURL=loop.js.map
 
 
  |