| "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()) 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)); | 
|       } | 
|     } | 
|     if (assign.length > 0) { | 
|       let replacement = assign.length === 1 ? assign[0] : _core.types.sequenceExpression(assign); | 
|       if (!_core.types.isForStatement(varPath.parent, { | 
|         init: varPath.node | 
|       }) && !_core.types.isForXStatement(varPath.parent, { | 
|         left: varPath.node | 
|       })) { | 
|         replacement = _core.types.expressionStatement(replacement); | 
|       } | 
|       varPath.replaceWith(replacement); | 
|     } else { | 
|       varPath.remove(); | 
|     } | 
|   } | 
|   if (varNames.length) { | 
|     bodyStmts.push(_core.types.variableDeclaration("var", varNames.map(name => _core.types.variableDeclarator(_core.types.identifier(name))))); | 
|   } | 
|   if (state.breaksContinues.length === 0 && state.returns.length === 0) { | 
|     bodyStmts.push(_core.types.expressionStatement(call)); | 
|   } else { | 
|     const completionId = loopPath.scope.generateUid("ret"); | 
|     bodyStmts.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(_core.types.identifier(completionId), call)])); | 
|     const injected = new Set(); | 
|     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.returnStatement(_core.types.stringLiteral(name))); | 
|       if (updaterNode) path.insertBefore(_core.types.cloneNode(updaterNode)); | 
|       if (injected.has(name)) continue; | 
|       injected.add(name); | 
|       bodyStmts.push(_core.template.statement.ast` | 
|         if ( | 
|           ${_core.types.identifier(completionId)} === ${_core.types.stringLiteral(name)} | 
|         ) ${node} | 
|       `); | 
|     } | 
|     if (state.returns.length) { | 
|       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 (typeof ${_core.types.identifier(completionId)} === "object") | 
|           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 |