diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2026-05-18 23:10:59 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2026-05-18 23:41:44 +0800 |
| commit | fc87c009806dcc98867f6b58efe29b042aa01dee (patch) | |
| tree | 8f59b3f4a5b66e9dfef2d40c8d318e258a521228 /node_modules/regenerator-transform/src | |
| parent | 3336b2356ee6152d9c6ae59bd9b87ccbc0958407 (diff) | |
node: updatemain
Diffstat (limited to 'node_modules/regenerator-transform/src')
| -rw-r--r-- | node_modules/regenerator-transform/src/emit.js | 1308 | ||||
| -rw-r--r-- | node_modules/regenerator-transform/src/hoist.js | 161 | ||||
| -rw-r--r-- | node_modules/regenerator-transform/src/index.js | 27 | ||||
| -rw-r--r-- | node_modules/regenerator-transform/src/leap.js | 179 | ||||
| -rw-r--r-- | node_modules/regenerator-transform/src/meta.js | 110 | ||||
| -rw-r--r-- | node_modules/regenerator-transform/src/replaceShorthandObjectMethod.js | 82 | ||||
| -rw-r--r-- | node_modules/regenerator-transform/src/util.js | 45 | ||||
| -rw-r--r-- | node_modules/regenerator-transform/src/visit.js | 369 |
8 files changed, 0 insertions, 2281 deletions
diff --git a/node_modules/regenerator-transform/src/emit.js b/node_modules/regenerator-transform/src/emit.js deleted file mode 100644 index 7b551cdd..00000000 --- a/node_modules/regenerator-transform/src/emit.js +++ /dev/null @@ -1,1308 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import assert from "assert"; -import * as leap from "./leap"; -import * as meta from "./meta"; -import * as util from "./util"; - -let hasOwn = Object.prototype.hasOwnProperty; - -function Emitter(contextId) { - assert.ok(this instanceof Emitter); - - util.getTypes().assertIdentifier(contextId); - - // Used to generate unique temporary names. - this.nextTempId = 0; - - // In order to make sure the context object does not collide with - // anything in the local scope, we might have to rename it, so we - // refer to it symbolically instead of just assuming that it will be - // called "context". - this.contextId = contextId; - - // An append-only list of Statements that grows each time this.emit is - // called. - this.listing = []; - - // A sparse array whose keys correspond to locations in this.listing - // that have been marked as branch/jump targets. - this.marked = [true]; - - this.insertedLocs = new Set(); - - // The last location will be marked when this.getDispatchLoop is - // called. - this.finalLoc = this.loc(); - - // A list of all leap.TryEntry statements emitted. - this.tryEntries = []; - - // Each time we evaluate the body of a loop, we tell this.leapManager - // to enter a nested loop context that determines the meaning of break - // and continue statements therein. - this.leapManager = new leap.LeapManager(this); -} - -let Ep = Emitter.prototype; -exports.Emitter = Emitter; - -// Offsets into this.listing that could be used as targets for branches or -// jumps are represented as numeric Literal nodes. This representation has -// the amazingly convenient benefit of allowing the exact value of the -// location to be determined at any time, even after generating code that -// refers to the location. -// We use 'Number.MAX_VALUE' to mark uninitialized location. We can safely do -// so because no code can realistically have about 1.8e+308 locations before -// hitting memory limit of the machine it's running on. For comparison, the -// estimated number of atoms in the observable universe is around 1e+80. -const PENDING_LOCATION = Number.MAX_VALUE; -Ep.loc = function() { - const l = util.getTypes().numericLiteral(PENDING_LOCATION) - this.insertedLocs.add(l); - return l; -} - -Ep.getInsertedLocs = function() { - return this.insertedLocs; -} - -Ep.getContextId = function() { - return util.getTypes().clone(this.contextId); -} - -// Sets the exact value of the given location to the offset of the next -// Statement emitted. -Ep.mark = function(loc) { - util.getTypes().assertLiteral(loc); - let index = this.listing.length; - if (loc.value === PENDING_LOCATION) { - loc.value = index; - } else { - // Locations can be marked redundantly, but their values cannot change - // once set the first time. - assert.strictEqual(loc.value, index); - } - this.marked[index] = true; - return loc; -}; - -Ep.emit = function(node) { - const t = util.getTypes(); - - if (t.isExpression(node)) { - node = t.expressionStatement(node); - } - - t.assertStatement(node); - this.listing.push(node); -}; - -// Shorthand for emitting assignment statements. This will come in handy -// for assignments to temporary variables. -Ep.emitAssign = function(lhs, rhs) { - this.emit(this.assign(lhs, rhs)); - return lhs; -}; - -// Shorthand for an assignment statement. -Ep.assign = function(lhs, rhs) { - const t = util.getTypes(); - return t.expressionStatement( - t.assignmentExpression("=", t.cloneDeep(lhs), rhs)); -}; - -// Convenience function for generating expressions like context.next, -// context.sent, and context.rval. -Ep.contextProperty = function(name, computed) { - const t = util.getTypes(); - return t.memberExpression( - this.getContextId(), - computed ? t.stringLiteral(name) : t.identifier(name), - !!computed - ); -}; - -// Shorthand for setting context.rval and jumping to `context.stop()`. -Ep.stop = function(rval) { - if (rval) { - this.setReturnValue(rval); - } - - this.jump(this.finalLoc); -}; - -Ep.setReturnValue = function(valuePath) { - util.getTypes().assertExpression(valuePath.value); - - this.emitAssign( - this.contextProperty("rval"), - this.explodeExpression(valuePath) - ); -}; - -Ep.clearPendingException = function(tryLoc, assignee) { - const t = util.getTypes(); - - t.assertLiteral(tryLoc); - - let catchCall = t.callExpression( - this.contextProperty("catch", true), - [t.clone(tryLoc)] - ); - - if (assignee) { - this.emitAssign(assignee, catchCall); - } else { - this.emit(catchCall); - } -}; - -// Emits code for an unconditional jump to the given location, even if the -// exact value of the location is not yet known. -Ep.jump = function(toLoc) { - this.emitAssign(this.contextProperty("next"), toLoc); - this.emit(util.getTypes().breakStatement()); -}; - -// Conditional jump. -Ep.jumpIf = function(test, toLoc) { - const t = util.getTypes(); - - t.assertExpression(test); - t.assertLiteral(toLoc); - - this.emit(t.ifStatement( - test, - t.blockStatement([ - this.assign(this.contextProperty("next"), toLoc), - t.breakStatement() - ]) - )); -}; - -// Conditional jump, with the condition negated. -Ep.jumpIfNot = function(test, toLoc) { - const t = util.getTypes(); - - t.assertExpression(test); - t.assertLiteral(toLoc); - - let negatedTest; - if (t.isUnaryExpression(test) && - test.operator === "!") { - // Avoid double negation. - negatedTest = test.argument; - } else { - negatedTest = t.unaryExpression("!", test); - } - - this.emit(t.ifStatement( - negatedTest, - t.blockStatement([ - this.assign(this.contextProperty("next"), toLoc), - t.breakStatement() - ]) - )); -}; - -// Returns a unique MemberExpression that can be used to store and -// retrieve temporary values. Since the object of the member expression is -// the context object, which is presumed to coexist peacefully with all -// other local variables, and since we just increment `nextTempId` -// monotonically, uniqueness is assured. -Ep.makeTempVar = function() { - return this.contextProperty("t" + this.nextTempId++); -}; - -Ep.getContextFunction = function(id) { - const t = util.getTypes(); - - return t.functionExpression( - id || null/*Anonymous*/, - [this.getContextId()], - t.blockStatement([this.getDispatchLoop()]), - false, // Not a generator anymore! - false // Nor an expression. - ); -}; - -// Turns this.listing into a loop of the form -// -// while (1) switch (context.next) { -// case 0: -// ... -// case n: -// return context.stop(); -// } -// -// Each marked location in this.listing will correspond to one generated -// case statement. -Ep.getDispatchLoop = function() { - const self = this; - const t = util.getTypes(); - let cases = []; - let current; - - // If we encounter a break, continue, or return statement in a switch - // case, we can skip the rest of the statements until the next case. - let alreadyEnded = false; - - self.listing.forEach(function(stmt, i) { - if (self.marked.hasOwnProperty(i)) { - cases.push(t.switchCase( - t.numericLiteral(i), - current = [])); - alreadyEnded = false; - } - - if (!alreadyEnded) { - current.push(stmt); - if (t.isCompletionStatement(stmt)) - alreadyEnded = true; - } - }); - - // Now that we know how many statements there will be in this.listing, - // we can finally resolve this.finalLoc.value. - this.finalLoc.value = this.listing.length; - - cases.push( - t.switchCase(this.finalLoc, [ - // Intentionally fall through to the "end" case... - ]), - - // So that the runtime can jump to the final location without having - // to know its offset, we provide the "end" case as a synonym. - t.switchCase(t.stringLiteral("end"), [ - // This will check/clear both context.thrown and context.rval. - t.returnStatement( - t.callExpression(this.contextProperty("stop"), []) - ) - ]) - ); - - return t.whileStatement( - t.numericLiteral(1), - t.switchStatement( - t.assignmentExpression( - "=", - this.contextProperty("prev"), - this.contextProperty("next") - ), - cases - ) - ); -}; - -Ep.getTryLocsList = function() { - if (this.tryEntries.length === 0) { - // To avoid adding a needless [] to the majority of runtime.wrap - // argument lists, force the caller to handle this case specially. - return null; - } - - const t = util.getTypes(); - let lastLocValue = 0; - - return t.arrayExpression( - this.tryEntries.map(function(tryEntry) { - let thisLocValue = tryEntry.firstLoc.value; - assert.ok(thisLocValue >= lastLocValue, "try entries out of order"); - lastLocValue = thisLocValue; - - let ce = tryEntry.catchEntry; - let fe = tryEntry.finallyEntry; - - let locs = [ - tryEntry.firstLoc, - // The null here makes a hole in the array. - ce ? ce.firstLoc : null - ]; - - if (fe) { - locs[2] = fe.firstLoc; - locs[3] = fe.afterLoc; - } - - return t.arrayExpression(locs.map(loc => loc && t.clone(loc))); - }) - ); -}; - -// All side effects must be realized in order. - -// If any subexpression harbors a leap, all subexpressions must be -// neutered of side effects. - -// No destructive modification of AST nodes. - -Ep.explode = function(path, ignoreResult) { - const t = util.getTypes(); - let node = path.node; - let self = this; - - t.assertNode(node); - - if (t.isDeclaration(node)) - throw getDeclError(node); - - if (t.isStatement(node)) - return self.explodeStatement(path); - - if (t.isExpression(node)) - return self.explodeExpression(path, ignoreResult); - - switch (node.type) { - case "Program": - return path.get("body").map( - self.explodeStatement, - self - ); - - case "VariableDeclarator": - throw getDeclError(node); - - // These node types should be handled by their parent nodes - // (ObjectExpression, SwitchStatement, and TryStatement, respectively). - case "Property": - case "SwitchCase": - case "CatchClause": - throw new Error( - node.type + " nodes should be handled by their parents"); - - default: - throw new Error( - "unknown Node of type " + - JSON.stringify(node.type)); - } -}; - -function getDeclError(node) { - return new Error( - "all declarations should have been transformed into " + - "assignments before the Exploder began its work: " + - JSON.stringify(node)); -} - -Ep.explodeStatement = function(path, labelId) { - const t = util.getTypes(); - let stmt = path.node; - let self = this; - let before, after, head; - - t.assertStatement(stmt); - - if (labelId) { - t.assertIdentifier(labelId); - } else { - labelId = null; - } - - // Explode BlockStatement nodes even if they do not contain a yield, - // because we don't want or need the curly braces. - if (t.isBlockStatement(stmt)) { - path.get("body").forEach(function (path) { - self.explodeStatement(path); - }); - return; - } - - if (!meta.containsLeap(stmt)) { - // Technically we should be able to avoid emitting the statement - // altogether if !meta.hasSideEffects(stmt), but that leads to - // confusing generated code (for instance, `while (true) {}` just - // disappears) and is probably a more appropriate job for a dedicated - // dead code elimination pass. - self.emit(stmt); - return; - } - - switch (stmt.type) { - case "ExpressionStatement": - self.explodeExpression(path.get("expression"), true); - break; - - case "LabeledStatement": - after = this.loc(); - - // Did you know you can break from any labeled block statement or - // control structure? Well, you can! Note: when a labeled loop is - // encountered, the leap.LabeledEntry created here will immediately - // enclose a leap.LoopEntry on the leap manager's stack, and both - // entries will have the same label. Though this works just fine, it - // may seem a bit redundant. In theory, we could check here to - // determine if stmt knows how to handle its own label; for example, - // stmt happens to be a WhileStatement and so we know it's going to - // establish its own LoopEntry when we explode it (below). Then this - // LabeledEntry would be unnecessary. Alternatively, we might be - // tempted not to pass stmt.label down into self.explodeStatement, - // because we've handled the label here, but that's a mistake because - // labeled loops may contain labeled continue statements, which is not - // something we can handle in this generic case. All in all, I think a - // little redundancy greatly simplifies the logic of this case, since - // it's clear that we handle all possible LabeledStatements correctly - // here, regardless of whether they interact with the leap manager - // themselves. Also remember that labels and break/continue-to-label - // statements are rare, and all of this logic happens at transform - // time, so it has no additional runtime cost. - self.leapManager.withEntry( - new leap.LabeledEntry(after, stmt.label), - function() { - self.explodeStatement(path.get("body"), stmt.label); - } - ); - - self.mark(after); - - break; - - case "WhileStatement": - before = this.loc(); - after = this.loc(); - - self.mark(before); - self.jumpIfNot(self.explodeExpression(path.get("test")), after); - self.leapManager.withEntry( - new leap.LoopEntry(after, before, labelId), - function() { self.explodeStatement(path.get("body")); } - ); - self.jump(before); - self.mark(after); - - break; - - case "DoWhileStatement": - let first = this.loc(); - let test = this.loc(); - after = this.loc(); - - self.mark(first); - self.leapManager.withEntry( - new leap.LoopEntry(after, test, labelId), - function() { self.explode(path.get("body")); } - ); - self.mark(test); - self.jumpIf(self.explodeExpression(path.get("test")), first); - self.mark(after); - - break; - - case "ForStatement": - head = this.loc(); - let update = this.loc(); - after = this.loc(); - - if (stmt.init) { - // We pass true here to indicate that if stmt.init is an expression - // then we do not care about its result. - self.explode(path.get("init"), true); - } - - self.mark(head); - - if (stmt.test) { - self.jumpIfNot(self.explodeExpression(path.get("test")), after); - } else { - // No test means continue unconditionally. - } - - self.leapManager.withEntry( - new leap.LoopEntry(after, update, labelId), - function() { self.explodeStatement(path.get("body")); } - ); - - self.mark(update); - - if (stmt.update) { - // We pass true here to indicate that if stmt.update is an - // expression then we do not care about its result. - self.explode(path.get("update"), true); - } - - self.jump(head); - - self.mark(after); - - break; - - case "TypeCastExpression": - return self.explodeExpression(path.get("expression")); - - case "ForInStatement": - head = this.loc(); - after = this.loc(); - - let keyIterNextFn = self.makeTempVar(); - self.emitAssign( - keyIterNextFn, - t.callExpression( - util.runtimeProperty("keys"), - [self.explodeExpression(path.get("right"))] - ) - ); - - self.mark(head); - - let keyInfoTmpVar = self.makeTempVar(); - self.jumpIf( - t.memberExpression( - t.assignmentExpression( - "=", - keyInfoTmpVar, - t.callExpression(t.cloneDeep(keyIterNextFn), []) - ), - t.identifier("done"), - false - ), - after - ); - - self.emitAssign( - stmt.left, - t.memberExpression( - t.cloneDeep(keyInfoTmpVar), - t.identifier("value"), - false - ) - ); - - self.leapManager.withEntry( - new leap.LoopEntry(after, head, labelId), - function() { self.explodeStatement(path.get("body")); } - ); - - self.jump(head); - - self.mark(after); - - break; - - case "BreakStatement": - self.emitAbruptCompletion({ - type: "break", - target: self.leapManager.getBreakLoc(stmt.label) - }); - - break; - - case "ContinueStatement": - self.emitAbruptCompletion({ - type: "continue", - target: self.leapManager.getContinueLoc(stmt.label) - }); - - break; - - case "SwitchStatement": - // Always save the discriminant into a temporary variable in case the - // test expressions overwrite values like context.sent. - let disc = self.emitAssign( - self.makeTempVar(), - self.explodeExpression(path.get("discriminant")) - ); - - after = this.loc(); - let defaultLoc = this.loc(); - let condition = defaultLoc; - let caseLocs = []; - - // If there are no cases, .cases might be undefined. - let cases = stmt.cases || []; - - for (let i = cases.length - 1; i >= 0; --i) { - let c = cases[i]; - t.assertSwitchCase(c); - - if (c.test) { - condition = t.conditionalExpression( - t.binaryExpression("===", t.cloneDeep(disc), c.test), - caseLocs[i] = this.loc(), - condition - ); - } else { - caseLocs[i] = defaultLoc; - } - } - - let discriminant = path.get("discriminant"); - util.replaceWithOrRemove(discriminant, condition); - self.jump(self.explodeExpression(discriminant)); - - self.leapManager.withEntry( - new leap.SwitchEntry(after), - function() { - path.get("cases").forEach(function(casePath) { - let i = casePath.key; - self.mark(caseLocs[i]); - - casePath.get("consequent").forEach(function (path) { - self.explodeStatement(path); - }); - }); - } - ); - - self.mark(after); - if (defaultLoc.value === PENDING_LOCATION) { - self.mark(defaultLoc); - assert.strictEqual(after.value, defaultLoc.value); - } - - break; - - case "IfStatement": - let elseLoc = stmt.alternate && this.loc(); - after = this.loc(); - - self.jumpIfNot( - self.explodeExpression(path.get("test")), - elseLoc || after - ); - - self.explodeStatement(path.get("consequent")); - - if (elseLoc) { - self.jump(after); - self.mark(elseLoc); - self.explodeStatement(path.get("alternate")); - } - - self.mark(after); - - break; - - case "ReturnStatement": - self.emitAbruptCompletion({ - type: "return", - value: self.explodeExpression(path.get("argument")) - }); - - break; - - case "WithStatement": - throw new Error("WithStatement not supported in generator functions."); - - case "TryStatement": - after = this.loc(); - - let handler = stmt.handler; - - let catchLoc = handler && this.loc(); - let catchEntry = catchLoc && new leap.CatchEntry( - catchLoc, - handler.param - ); - - let finallyLoc = stmt.finalizer && this.loc(); - let finallyEntry = finallyLoc && - new leap.FinallyEntry(finallyLoc, after); - - let tryEntry = new leap.TryEntry( - self.getUnmarkedCurrentLoc(), - catchEntry, - finallyEntry - ); - - self.tryEntries.push(tryEntry); - self.updateContextPrevLoc(tryEntry.firstLoc); - - self.leapManager.withEntry(tryEntry, function() { - self.explodeStatement(path.get("block")); - - if (catchLoc) { - if (finallyLoc) { - // If we have both a catch block and a finally block, then - // because we emit the catch block first, we need to jump over - // it to the finally block. - self.jump(finallyLoc); - - } else { - // If there is no finally block, then we need to jump over the - // catch block to the fall-through location. - self.jump(after); - } - - self.updateContextPrevLoc(self.mark(catchLoc)); - - let bodyPath = path.get("handler.body"); - let safeParam = self.makeTempVar(); - self.clearPendingException(tryEntry.firstLoc, safeParam); - - bodyPath.traverse(catchParamVisitor, { - getSafeParam: () => t.cloneDeep(safeParam), - catchParamName: handler.param.name - }); - - self.leapManager.withEntry(catchEntry, function() { - self.explodeStatement(bodyPath); - }); - } - - if (finallyLoc) { - self.updateContextPrevLoc(self.mark(finallyLoc)); - - self.leapManager.withEntry(finallyEntry, function() { - self.explodeStatement(path.get("finalizer")); - }); - - self.emit(t.returnStatement(t.callExpression( - self.contextProperty("finish"), - [finallyEntry.firstLoc] - ))); - } - }); - - self.mark(after); - - break; - - case "ThrowStatement": - self.emit(t.throwStatement( - self.explodeExpression(path.get("argument")) - )); - - break; - - case "ClassDeclaration": - self.emit(self.explodeClass(path)); - break; - - default: - throw new Error( - "unknown Statement of type " + - JSON.stringify(stmt.type)); - } -}; - -let catchParamVisitor = { - Identifier: function(path, state) { - if (path.node.name === state.catchParamName && util.isReference(path)) { - util.replaceWithOrRemove(path, state.getSafeParam()); - } - }, - - Scope: function(path, state) { - if (path.scope.hasOwnBinding(state.catchParamName)) { - // Don't descend into nested scopes that shadow the catch - // parameter with their own declarations. - path.skip(); - } - } -}; - -Ep.emitAbruptCompletion = function(record) { - if (!isValidCompletion(record)) { - assert.ok( - false, - "invalid completion record: " + - JSON.stringify(record) - ); - } - - assert.notStrictEqual( - record.type, "normal", - "normal completions are not abrupt" - ); - - const t = util.getTypes(); - let abruptArgs = [t.stringLiteral(record.type)]; - - if (record.type === "break" || - record.type === "continue") { - t.assertLiteral(record.target); - abruptArgs[1] = this.insertedLocs.has(record.target) - ? record.target - : t.cloneDeep(record.target); - } else if (record.type === "return" || - record.type === "throw") { - if (record.value) { - t.assertExpression(record.value); - abruptArgs[1] = this.insertedLocs.has(record.value) - ? record.value - : t.cloneDeep(record.value); - } - } - - this.emit( - t.returnStatement( - t.callExpression( - this.contextProperty("abrupt"), - abruptArgs - ) - ) - ); -}; - -function isValidCompletion(record) { - let type = record.type; - - if (type === "normal") { - return !hasOwn.call(record, "target"); - } - - if (type === "break" || - type === "continue") { - return !hasOwn.call(record, "value") - && util.getTypes().isLiteral(record.target); - } - - if (type === "return" || - type === "throw") { - return hasOwn.call(record, "value") - && !hasOwn.call(record, "target"); - } - - return false; -} - - -// Not all offsets into emitter.listing are potential jump targets. For -// example, execution typically falls into the beginning of a try block -// without jumping directly there. This method returns the current offset -// without marking it, so that a switch case will not necessarily be -// generated for this offset (I say "not necessarily" because the same -// location might end up being marked in the process of emitting other -// statements). There's no logical harm in marking such locations as jump -// targets, but minimizing the number of switch cases keeps the generated -// code shorter. -Ep.getUnmarkedCurrentLoc = function() { - return util.getTypes().numericLiteral(this.listing.length); -}; - -// The context.prev property takes the value of context.next whenever we -// evaluate the switch statement discriminant, which is generally good -// enough for tracking the last location we jumped to, but sometimes -// context.prev needs to be more precise, such as when we fall -// successfully out of a try block and into a finally block without -// jumping. This method exists to update context.prev to the freshest -// available location. If we were implementing a full interpreter, we -// would know the location of the current instruction with complete -// precision at all times, but we don't have that luxury here, as it would -// be costly and verbose to set context.prev before every statement. -Ep.updateContextPrevLoc = function(loc) { - const t = util.getTypes(); - if (loc) { - t.assertLiteral(loc); - - if (loc.value === PENDING_LOCATION) { - // If an uninitialized location literal was passed in, set its value - // to the current this.listing.length. - loc.value = this.listing.length; - } else { - // Otherwise assert that the location matches the current offset. - assert.strictEqual(loc.value, this.listing.length); - } - - } else { - loc = this.getUnmarkedCurrentLoc(); - } - - // Make sure context.prev is up to date in case we fell into this try - // statement without jumping to it. TODO Consider avoiding this - // assignment when we know control must have jumped here. - this.emitAssign(this.contextProperty("prev"), loc); -}; - - -// In order to save the rest of explodeExpression from a combinatorial -// trainwreck of special cases, explodeViaTempVar is responsible for -// deciding when a subexpression needs to be "exploded," which is my -// very technical term for emitting the subexpression as an assignment -// to a temporary variable and the substituting the temporary variable -// for the original subexpression. Think of exploded view diagrams, not -// Michael Bay movies. The point of exploding subexpressions is to -// control the precise order in which the generated code realizes the -// side effects of those subexpressions. -Ep.explodeViaTempVar = function(tempVar, childPath, hasLeapingChildren, ignoreChildResult) { - assert.ok( - !ignoreChildResult || !tempVar, - "Ignoring the result of a child expression but forcing it to " + - "be assigned to a temporary variable?" - ); - const t = util.getTypes(); - - let result = this.explodeExpression(childPath, ignoreChildResult); - - if (ignoreChildResult) { - // Side effects already emitted above. - - } else if (tempVar || (hasLeapingChildren && - !t.isLiteral(result))) { - // If tempVar was provided, then the result will always be assigned - // to it, even if the result does not otherwise need to be assigned - // to a temporary variable. When no tempVar is provided, we have - // the flexibility to decide whether a temporary variable is really - // necessary. Unfortunately, in general, a temporary variable is - // required whenever any child contains a yield expression, since it - // is difficult to prove (at all, let alone efficiently) whether - // this result would evaluate to the same value before and after the - // yield (see #206). One narrow case where we can prove it doesn't - // matter (and thus we do not need a temporary variable) is when the - // result in question is a Literal value. - result = this.emitAssign( - tempVar || this.makeTempVar(), - result - ); - } - return result; -}; - -Ep.explodeExpression = function(path, ignoreResult) { - const t = util.getTypes(); - let expr = path.node; - if (expr) { - t.assertExpression(expr); - } else { - return expr; - } - - let self = this; - let result; // Used optionally by several cases below. - let after; - - function finish(expr) { - t.assertExpression(expr); - if (ignoreResult) { - self.emit(expr); - } - return expr; - } - - // If the expression does not contain a leap, then we either emit the - // expression as a standalone statement or return it whole. - if (!meta.containsLeap(expr)) { - return finish(expr); - } - - // If any child contains a leap (such as a yield or labeled continue or - // break statement), then any sibling subexpressions will almost - // certainly have to be exploded in order to maintain the order of their - // side effects relative to the leaping child(ren). - let hasLeapingChildren = meta.containsLeap.onlyChildren(expr); - - // If ignoreResult is true, then we must take full responsibility for - // emitting the expression with all its side effects, and we should not - // return a result. - - switch (expr.type) { - case "MemberExpression": - return finish(t.memberExpression( - self.explodeExpression(path.get("object")), - expr.computed - ? self.explodeViaTempVar(null, path.get("property"), hasLeapingChildren) - : expr.property, - expr.computed - )); - - case "CallExpression": - let calleePath = path.get("callee"); - let argsPath = path.get("arguments"); - - let newCallee; - let newArgs; - - let hasLeapingArgs = argsPath.some( - argPath => meta.containsLeap(argPath.node) - ); - - let injectFirstArg = null; - - if (t.isMemberExpression(calleePath.node)) { - if (hasLeapingArgs) { - // If the arguments of the CallExpression contained any yield - // expressions, then we need to be sure to evaluate the callee - // before evaluating the arguments, but if the callee was a member - // expression, then we must be careful that the object of the - // member expression still gets bound to `this` for the call. - - let newObject = self.explodeViaTempVar( - // Assign the exploded callee.object expression to a temporary - // variable so that we can use it twice without reevaluating it. - self.makeTempVar(), - calleePath.get("object"), - hasLeapingChildren - ); - - let newProperty = calleePath.node.computed - ? self.explodeViaTempVar(null, calleePath.get("property"), hasLeapingChildren) - : calleePath.node.property; - - injectFirstArg = newObject; - - newCallee = t.memberExpression( - t.memberExpression( - t.cloneDeep(newObject), - newProperty, - calleePath.node.computed - ), - t.identifier("call"), - false - ); - - } else { - newCallee = self.explodeExpression(calleePath); - } - - } else { - newCallee = self.explodeViaTempVar(null, calleePath, hasLeapingChildren); - - if (t.isMemberExpression(newCallee)) { - // If the callee was not previously a MemberExpression, then the - // CallExpression was "unqualified," meaning its `this` object - // should be the global object. If the exploded expression has - // become a MemberExpression (e.g. a context property, probably a - // temporary variable), then we need to force it to be unqualified - // by using the (0, object.property)(...) trick; otherwise, it - // will receive the object of the MemberExpression as its `this` - // object. - newCallee = t.sequenceExpression([ - t.numericLiteral(0), - t.cloneDeep(newCallee) - ]); - } - } - - if (hasLeapingArgs) { - newArgs = argsPath.map(argPath => self.explodeViaTempVar(null, argPath, hasLeapingChildren)); - if (injectFirstArg) newArgs.unshift(injectFirstArg); - - newArgs = newArgs.map(arg => t.cloneDeep(arg)); - } else { - newArgs = path.node.arguments; - } - - return finish(t.callExpression(newCallee, newArgs)); - - case "NewExpression": - return finish(t.newExpression( - self.explodeViaTempVar(null, path.get("callee"), hasLeapingChildren), - path.get("arguments").map(function(argPath) { - return self.explodeViaTempVar(null, argPath, hasLeapingChildren); - }) - )); - - case "ObjectExpression": - return finish(t.objectExpression( - path.get("properties").map(function(propPath) { - if (propPath.isObjectProperty()) { - return t.objectProperty( - propPath.node.key, - self.explodeViaTempVar(null, propPath.get("value"), hasLeapingChildren), - propPath.node.computed - ); - } else { - return propPath.node; - } - }) - )); - - case "ArrayExpression": - return finish(t.arrayExpression( - path.get("elements").map(function(elemPath) { - if (!elemPath.node) { - return null; - } if (elemPath.isSpreadElement()) { - return t.spreadElement( - self.explodeViaTempVar(null, elemPath.get("argument"), hasLeapingChildren) - ); - } else { - return self.explodeViaTempVar(null, elemPath, hasLeapingChildren); - } - }) - )); - - case "SequenceExpression": - let lastIndex = expr.expressions.length - 1; - - path.get("expressions").forEach(function(exprPath) { - if (exprPath.key === lastIndex) { - result = self.explodeExpression(exprPath, ignoreResult); - } else { - self.explodeExpression(exprPath, true); - } - }); - - return result; - - case "LogicalExpression": - after = this.loc(); - - if (!ignoreResult) { - result = self.makeTempVar(); - } - - let left = self.explodeViaTempVar(result, path.get("left"), hasLeapingChildren); - - if (expr.operator === "&&") { - self.jumpIfNot(left, after); - } else { - assert.strictEqual(expr.operator, "||"); - self.jumpIf(left, after); - } - - self.explodeViaTempVar(result, path.get("right"), hasLeapingChildren, ignoreResult); - - self.mark(after); - - return result; - - case "ConditionalExpression": - let elseLoc = this.loc(); - after = this.loc(); - let test = self.explodeExpression(path.get("test")); - - self.jumpIfNot(test, elseLoc); - - if (!ignoreResult) { - result = self.makeTempVar(); - } - - self.explodeViaTempVar(result, path.get("consequent"), hasLeapingChildren, ignoreResult); - self.jump(after); - - self.mark(elseLoc); - self.explodeViaTempVar(result, path.get("alternate"), hasLeapingChildren, ignoreResult); - - self.mark(after); - - return result; - - case "UnaryExpression": - return finish(t.unaryExpression( - expr.operator, - // Can't (and don't need to) break up the syntax of the argument. - // Think about delete a[b]. - self.explodeExpression(path.get("argument")), - !!expr.prefix - )); - - case "BinaryExpression": - return finish(t.binaryExpression( - expr.operator, - self.explodeViaTempVar(null, path.get("left"), hasLeapingChildren), - self.explodeViaTempVar(null, path.get("right"), hasLeapingChildren) - )); - - case "AssignmentExpression": - if (expr.operator === "=") { - // If this is a simple assignment, the left hand side does not need - // to be read before the right hand side is evaluated, so we can - // avoid the more complicated logic below. - return finish(t.assignmentExpression( - expr.operator, - self.explodeExpression(path.get("left")), - self.explodeExpression(path.get("right")) - )); - } - - const lhs = self.explodeExpression(path.get("left")); - const temp = self.emitAssign(self.makeTempVar(), lhs); - - // For example, - // - // x += yield y - // - // becomes - // - // context.t0 = x - // x = context.t0 += yield y - // - // so that the left-hand side expression is read before the yield. - // Fixes https://github.com/facebook/regenerator/issues/345. - - return finish(t.assignmentExpression( - "=", - t.cloneDeep(lhs), - t.assignmentExpression( - expr.operator, - t.cloneDeep(temp), - self.explodeExpression(path.get("right")) - ) - )); - - case "UpdateExpression": - return finish(t.updateExpression( - expr.operator, - self.explodeExpression(path.get("argument")), - expr.prefix - )); - - case "YieldExpression": - after = this.loc(); - let arg = expr.argument && self.explodeExpression(path.get("argument")); - - if (arg && expr.delegate) { - let result = self.makeTempVar(); - - let ret = t.returnStatement(t.callExpression( - self.contextProperty("delegateYield"), - [ - arg, - t.stringLiteral(result.property.name), - after - ] - )); - ret.loc = expr.loc; - - self.emit(ret); - self.mark(after); - - return result; - } - - self.emitAssign(self.contextProperty("next"), after); - - let ret = t.returnStatement(t.cloneDeep(arg) || null); - // Preserve the `yield` location so that source mappings for the statements - // link back to the yield properly. - ret.loc = expr.loc; - self.emit(ret); - self.mark(after); - - return self.contextProperty("sent"); - - case "ClassExpression": - return finish(self.explodeClass(path)); - - default: - throw new Error( - "unknown Expression of type " + - JSON.stringify(expr.type)); - } -}; - -Ep.explodeClass = function(path) { - const explodingChildren = []; - - if (path.node.superClass) { - explodingChildren.push(path.get("superClass")); - } - - path.get("body.body").forEach(member => { - if (member.node.computed) { - explodingChildren.push(member.get("key")); - } - }); - - const hasLeapingChildren = explodingChildren.some( - child => meta.containsLeap(child)); - - for (let i = 0; i < explodingChildren.length; i++) { - const child = explodingChildren[i]; - const isLast = i === explodingChildren.length - 1; - - if (isLast) { - child.replaceWith(this.explodeExpression(child)); - } else { - child.replaceWith(this.explodeViaTempVar(null, child, hasLeapingChildren)); - } - } - - return path.node; -}; diff --git a/node_modules/regenerator-transform/src/hoist.js b/node_modules/regenerator-transform/src/hoist.js deleted file mode 100644 index 6fbad6de..00000000 --- a/node_modules/regenerator-transform/src/hoist.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import * as util from "./util"; -let hasOwn = Object.prototype.hasOwnProperty; - -// The hoist function takes a FunctionExpression or FunctionDeclaration -// and replaces any Declaration nodes in its body with assignments, then -// returns a VariableDeclaration containing just the names of the removed -// declarations. -exports.hoist = function(funPath) { - const t = util.getTypes(); - t.assertFunction(funPath.node); - - let vars = {}; - - function varDeclToExpr({ node: vdec, scope }, includeIdentifiers) { - t.assertVariableDeclaration(vdec); - // TODO assert.equal(vdec.kind, "var"); - let exprs = []; - - vdec.declarations.forEach(function(dec) { - // Note: We duplicate 'dec.id' here to ensure that the variable declaration IDs don't - // have the same 'loc' value, since that can make sourcemaps and retainLines behave poorly. - vars[dec.id.name] = t.identifier(dec.id.name); - - // Remove the binding, to avoid "duplicate declaration" errors when it will - // be injected again. - scope.removeBinding(dec.id.name); - - if (dec.init) { - exprs.push(t.assignmentExpression( - "=", dec.id, dec.init - )); - } else if (includeIdentifiers) { - exprs.push(dec.id); - } - }); - - if (exprs.length === 0) - return null; - - if (exprs.length === 1) - return exprs[0]; - - return t.sequenceExpression(exprs); - } - - funPath.get("body").traverse({ - VariableDeclaration: { - exit: function(path) { - let expr = varDeclToExpr(path, false); - if (expr === null) { - path.remove(); - } else { - // We don't need to traverse this expression any further because - // there can't be any new declarations inside an expression. - util.replaceWithOrRemove(path, t.expressionStatement(expr)); - } - - // Since the original node has been either removed or replaced, - // avoid traversing it any further. - path.skip(); - } - }, - - ForStatement: function(path) { - let init = path.get("init"); - if (init.isVariableDeclaration()) { - util.replaceWithOrRemove(init, varDeclToExpr(init, false)); - } - }, - - ForXStatement: function(path) { - let left = path.get("left"); - if (left.isVariableDeclaration()) { - util.replaceWithOrRemove(left, varDeclToExpr(left, true)); - } - }, - - FunctionDeclaration: function(path) { - let node = path.node; - vars[node.id.name] = node.id; - - let assignment = t.expressionStatement( - t.assignmentExpression( - "=", - t.clone(node.id), - t.functionExpression( - path.scope.generateUidIdentifierBasedOnNode(node), - node.params, - node.body, - node.generator, - node.expression - ) - ) - ); - - if (path.parentPath.isBlockStatement()) { - // Insert the assignment form before the first statement in the - // enclosing block. - path.parentPath.unshiftContainer("body", assignment); - - // Remove the function declaration now that we've inserted the - // equivalent assignment form at the beginning of the block. - path.remove(); - } else { - // If the parent node is not a block statement, then we can just - // replace the declaration with the equivalent assignment form - // without worrying about hoisting it. - util.replaceWithOrRemove(path, assignment); - } - - // Remove the binding, to avoid "duplicate declaration" errors when it will - // be injected again. - path.scope.removeBinding(node.id.name); - - // Don't hoist variables out of inner functions. - path.skip(); - }, - - FunctionExpression: function(path) { - // Don't descend into nested function expressions. - path.skip(); - }, - - ArrowFunctionExpression: function(path) { - // Don't descend into nested function expressions. - path.skip(); - } - }); - - let paramNames = {}; - funPath.get("params").forEach(function(paramPath) { - let param = paramPath.node; - if (t.isIdentifier(param)) { - paramNames[param.name] = param; - } else { - // Variables declared by destructuring parameter patterns will be - // harmlessly re-declared. - } - }); - - let declarations = []; - - Object.keys(vars).forEach(function(name) { - if (!hasOwn.call(paramNames, name)) { - declarations.push(t.variableDeclarator(vars[name], null)); - } - }); - - if (declarations.length === 0) { - return null; // Be sure to handle this case! - } - - return t.variableDeclaration("var", declarations); -}; diff --git a/node_modules/regenerator-transform/src/index.js b/node_modules/regenerator-transform/src/index.js deleted file mode 100644 index 2a18dffe..00000000 --- a/node_modules/regenerator-transform/src/index.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { getVisitor } from "./visit"; - -export default function (context) { - const plugin = { - visitor: getVisitor(context), - }; - - // Some presets manually call child presets, but fail to pass along the - // context object. Out of an abundance of caution, we verify that it - // exists first to avoid causing unnecessary breaking changes. - const version = context && context.version; - - // The "name" property is not allowed in older versions of Babel (6.x) - // and will cause the plugin validator to throw an exception. - if (version && parseInt(version, 10) >= 7) { - plugin.name = "regenerator-transform"; - } - - return plugin; -} diff --git a/node_modules/regenerator-transform/src/leap.js b/node_modules/regenerator-transform/src/leap.js deleted file mode 100644 index afbcda04..00000000 --- a/node_modules/regenerator-transform/src/leap.js +++ /dev/null @@ -1,179 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import assert from "assert"; -import { Emitter } from "./emit"; -import { inherits } from "util"; -import { getTypes } from "./util"; - -function Entry() { - assert.ok(this instanceof Entry); -} - -function FunctionEntry(returnLoc) { - Entry.call(this); - getTypes().assertLiteral(returnLoc); - this.returnLoc = returnLoc; -} - -inherits(FunctionEntry, Entry); -exports.FunctionEntry = FunctionEntry; - -function LoopEntry(breakLoc, continueLoc, label) { - Entry.call(this); - - const t = getTypes(); - - t.assertLiteral(breakLoc); - t.assertLiteral(continueLoc); - - if (label) { - t.assertIdentifier(label); - } else { - label = null; - } - - this.breakLoc = breakLoc; - this.continueLoc = continueLoc; - this.label = label; -} - -inherits(LoopEntry, Entry); -exports.LoopEntry = LoopEntry; - -function SwitchEntry(breakLoc) { - Entry.call(this); - getTypes().assertLiteral(breakLoc); - this.breakLoc = breakLoc; -} - -inherits(SwitchEntry, Entry); -exports.SwitchEntry = SwitchEntry; - -function TryEntry(firstLoc, catchEntry, finallyEntry) { - Entry.call(this); - - const t = getTypes(); - t.assertLiteral(firstLoc); - - if (catchEntry) { - assert.ok(catchEntry instanceof CatchEntry); - } else { - catchEntry = null; - } - - if (finallyEntry) { - assert.ok(finallyEntry instanceof FinallyEntry); - } else { - finallyEntry = null; - } - - // Have to have one or the other (or both). - assert.ok(catchEntry || finallyEntry); - - this.firstLoc = firstLoc; - this.catchEntry = catchEntry; - this.finallyEntry = finallyEntry; -} - -inherits(TryEntry, Entry); -exports.TryEntry = TryEntry; - -function CatchEntry(firstLoc, paramId) { - Entry.call(this); - - const t = getTypes(); - - t.assertLiteral(firstLoc); - t.assertIdentifier(paramId); - - this.firstLoc = firstLoc; - this.paramId = paramId; -} - -inherits(CatchEntry, Entry); -exports.CatchEntry = CatchEntry; - -function FinallyEntry(firstLoc, afterLoc) { - Entry.call(this); - const t = getTypes(); - t.assertLiteral(firstLoc); - t.assertLiteral(afterLoc); - this.firstLoc = firstLoc; - this.afterLoc = afterLoc; -} - -inherits(FinallyEntry, Entry); -exports.FinallyEntry = FinallyEntry; - -function LabeledEntry(breakLoc, label) { - Entry.call(this); - - const t = getTypes(); - - t.assertLiteral(breakLoc); - t.assertIdentifier(label); - - this.breakLoc = breakLoc; - this.label = label; -} - -inherits(LabeledEntry, Entry); -exports.LabeledEntry = LabeledEntry; - -function LeapManager(emitter) { - assert.ok(this instanceof LeapManager); - - assert.ok(emitter instanceof Emitter); - - this.emitter = emitter; - this.entryStack = [new FunctionEntry(emitter.finalLoc)]; -} - -let LMp = LeapManager.prototype; -exports.LeapManager = LeapManager; - -LMp.withEntry = function(entry, callback) { - assert.ok(entry instanceof Entry); - this.entryStack.push(entry); - try { - callback.call(this.emitter); - } finally { - let popped = this.entryStack.pop(); - assert.strictEqual(popped, entry); - } -}; - -LMp._findLeapLocation = function(property, label) { - for (let i = this.entryStack.length - 1; i >= 0; --i) { - let entry = this.entryStack[i]; - let loc = entry[property]; - if (loc) { - if (label) { - if (entry.label && - entry.label.name === label.name) { - return loc; - } - } else if (entry instanceof LabeledEntry) { - // Ignore LabeledEntry entries unless we are actually breaking to - // a label. - } else { - return loc; - } - } - } - - return null; -}; - -LMp.getBreakLoc = function(label) { - return this._findLeapLocation("breakLoc", label); -}; - -LMp.getContinueLoc = function(label) { - return this._findLeapLocation("continueLoc", label); -}; diff --git a/node_modules/regenerator-transform/src/meta.js b/node_modules/regenerator-transform/src/meta.js deleted file mode 100644 index dea4c6be..00000000 --- a/node_modules/regenerator-transform/src/meta.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import assert from "assert"; -import { getTypes } from "./util.js"; - -const mMap = new WeakMap(); -function m(node) { - if (!mMap.has(node)) { - mMap.set(node, {}); - } - return mMap.get(node); -} - -const hasOwn = Object.prototype.hasOwnProperty; - -function makePredicate(propertyName, knownTypes) { - function onlyChildren(node) { - const t = getTypes(); - t.assertNode(node); - - // Assume no side effects until we find out otherwise. - let result = false; - - function check(child) { - if (result) { - // Do nothing. - } else if (Array.isArray(child)) { - child.some(check); - } else if (t.isNode(child)) { - assert.strictEqual(result, false); - result = predicate(child); - } - return result; - } - - let keys = t.VISITOR_KEYS[node.type]; - if (keys) { - for (let i = 0; i < keys.length; i++) { - let key = keys[i]; - let child = node[key]; - check(child); - } - } - - return result; - } - - function predicate(node) { - getTypes().assertNode(node); - - let meta = m(node); - if (hasOwn.call(meta, propertyName)) - return meta[propertyName]; - - // Certain types are "opaque," which means they have no side - // effects or leaps and we don't care about their subexpressions. - if (hasOwn.call(opaqueTypes, node.type)) - return meta[propertyName] = false; - - if (hasOwn.call(knownTypes, node.type)) - return meta[propertyName] = true; - - return meta[propertyName] = onlyChildren(node); - } - - predicate.onlyChildren = onlyChildren; - - return predicate; -} - -let opaqueTypes = { - FunctionExpression: true, - ArrowFunctionExpression: true -}; - -// These types potentially have side effects regardless of what side -// effects their subexpressions have. -let sideEffectTypes = { - CallExpression: true, // Anything could happen! - ForInStatement: true, // Modifies the key variable. - UnaryExpression: true, // Think delete. - BinaryExpression: true, // Might invoke .toString() or .valueOf(). - AssignmentExpression: true, // Side-effecting by definition. - UpdateExpression: true, // Updates are essentially assignments. - NewExpression: true // Similar to CallExpression. -}; - -// These types are the direct cause of all leaps in control flow. -let leapTypes = { - YieldExpression: true, - BreakStatement: true, - ContinueStatement: true, - ReturnStatement: true, - ThrowStatement: true -}; - -// All leap types are also side effect types. -for (let type in leapTypes) { - if (hasOwn.call(leapTypes, type)) { - sideEffectTypes[type] = leapTypes[type]; - } -} - -exports.hasSideEffects = makePredicate("hasSideEffects", sideEffectTypes); -exports.containsLeap = makePredicate("containsLeap", leapTypes); diff --git a/node_modules/regenerator-transform/src/replaceShorthandObjectMethod.js b/node_modules/regenerator-transform/src/replaceShorthandObjectMethod.js deleted file mode 100644 index c406c63a..00000000 --- a/node_modules/regenerator-transform/src/replaceShorthandObjectMethod.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import * as util from "./util"; - -// this function converts a shorthand object generator method into a normal -// (non-shorthand) object property which is a generator function expression. for -// example, this: -// -// var foo = { -// *bar(baz) { return 5; } -// } -// -// should be replaced with: -// -// var foo = { -// bar: function*(baz) { return 5; } -// } -// -// to do this, it clones the parameter array and the body of the object generator -// method into a new FunctionExpression. -// -// this method can be passed any Function AST node path, and it will return -// either: -// a) the path that was passed in (iff the path did not need to be replaced) or -// b) the path of the new FunctionExpression that was created as a replacement -// (iff the path did need to be replaced) -// -// In either case, though, the caller can count on the fact that the return value -// is a Function AST node path. -// -// If this function is called with an AST node path that is not a Function (or with an -// argument that isn't an AST node path), it will throw an error. -export default function replaceShorthandObjectMethod(path) { - const t = util.getTypes(); - - if (!path.node || !t.isFunction(path.node)) { - throw new Error("replaceShorthandObjectMethod can only be called on Function AST node paths."); - } - - // this function only replaces shorthand object methods (called ObjectMethod - // in Babel-speak). - if (!t.isObjectMethod(path.node)) { - return path; - } - - // this function only replaces generators. - if (!path.node.generator) { - return path; - } - - const parameters = path.node.params.map(function (param) { - return t.cloneDeep(param); - }) - - const functionExpression = t.functionExpression( - null, // id - parameters, // params - t.cloneDeep(path.node.body), // body - path.node.generator, - path.node.async - ); - - util.replaceWithOrRemove(path, - t.objectProperty( - t.cloneDeep(path.node.key), // key - functionExpression, //value - path.node.computed, // computed - false // shorthand - ) - ); - - // path now refers to the ObjectProperty AST node path, but we want to return a - // Function AST node path for the function expression we created. we know that - // the FunctionExpression we just created is the value of the ObjectProperty, - // so return the "value" path off of this path. - return path.get("value"); -} diff --git a/node_modules/regenerator-transform/src/util.js b/node_modules/regenerator-transform/src/util.js deleted file mode 100644 index 80eea017..00000000 --- a/node_modules/regenerator-transform/src/util.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -let currentTypes = null; - -export function wrapWithTypes(types, fn) { - return function (...args) { - const oldTypes = currentTypes; - currentTypes = types; - try { - return fn.apply(this, args); - } finally { - currentTypes = oldTypes; - } - }; -} - -export function getTypes() { - return currentTypes; -} - -export function runtimeProperty(name) { - const t = getTypes(); - return t.memberExpression( - t.identifier("regeneratorRuntime"), - t.identifier(name), - false - ); -} - -export function isReference(path) { - return path.isReferenced() || path.parentPath.isAssignmentExpression({ left: path.node }); -} - -export function replaceWithOrRemove(path, replacement) { - if (replacement) { - path.replaceWith(replacement) - } else { - path.remove(); - } -} diff --git a/node_modules/regenerator-transform/src/visit.js b/node_modules/regenerator-transform/src/visit.js deleted file mode 100644 index a2744b38..00000000 --- a/node_modules/regenerator-transform/src/visit.js +++ /dev/null @@ -1,369 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -"use strict"; - -import assert from "assert"; -import { hoist } from "./hoist"; -import { Emitter } from "./emit"; -import replaceShorthandObjectMethod from "./replaceShorthandObjectMethod"; -import * as util from "./util"; - -exports.getVisitor = ({ types: t }) => ({ - Method(path, state) { - let node = path.node; - - if (!shouldRegenerate(node, state)) return; - - const container = t.functionExpression( - null, - [], - t.cloneNode(node.body, false), - node.generator, - node.async, - ); - - path.get("body").set("body", [ - t.returnStatement( - t.callExpression(container, []), - ), - ]); - - // Regardless of whether or not the wrapped function is a an async method - // or generator the outer function should not be - node.async = false; - node.generator = false; - - // Unwrap the wrapper IIFE's environment so super and this and such still work. - path - .get("body.body.0.argument.callee") - .unwrapFunctionEnvironment(); - }, - Function: { - exit: util.wrapWithTypes(t, function(path, state) { - let node = path.node; - - if (!shouldRegenerate(node, state)) return; - - // if this is an ObjectMethod, we need to convert it to an ObjectProperty - path = replaceShorthandObjectMethod(path); - node = path.node; - - let contextId = path.scope.generateUidIdentifier("context"); - let argsId = path.scope.generateUidIdentifier("args"); - - path.ensureBlock(); - let bodyBlockPath = path.get("body"); - - if (node.async) { - bodyBlockPath.traverse(awaitVisitor); - } - - bodyBlockPath.traverse(functionSentVisitor, { - context: contextId - }); - - let outerBody = []; - let innerBody = []; - - bodyBlockPath.get("body").forEach(function(childPath) { - let node = childPath.node; - if (t.isExpressionStatement(node) && - t.isStringLiteral(node.expression)) { - // Babylon represents directives like "use strict" as elements - // of a bodyBlockPath.node.directives array, but they could just - // as easily be represented (by other parsers) as traditional - // string-literal-valued expression statements, so we need to - // handle that here. (#248) - outerBody.push(node); - } else if (node && node._blockHoist != null) { - outerBody.push(node); - } else { - innerBody.push(node); - } - }); - - if (outerBody.length > 0) { - // Only replace the inner body if we actually hoisted any statements - // to the outer body. - bodyBlockPath.node.body = innerBody; - } - - let outerFnExpr = getOuterFnExpr(path); - // Note that getOuterFnExpr has the side-effect of ensuring that the - // function has a name (so node.id will always be an Identifier), even - // if a temporary name has to be synthesized. - t.assertIdentifier(node.id); - let innerFnId = t.identifier(node.id.name + "$"); - - // Turn all declarations into vars, and replace the original - // declarations with equivalent assignment expressions. - let vars = hoist(path); - - let context = { - usesThis: false, - usesArguments: false, - getArgsId: () => t.clone(argsId), - }; - path.traverse(argumentsThisVisitor, context); - - if (context.usesArguments) { - vars = vars || t.variableDeclaration("var", []); - vars.declarations.push(t.variableDeclarator( - t.clone(argsId), - t.identifier("arguments"), - )); - } - - let emitter = new Emitter(contextId); - emitter.explode(path.get("body")); - - if (vars && vars.declarations.length > 0) { - outerBody.push(vars); - } - - let wrapArgs = [emitter.getContextFunction(innerFnId)]; - let tryLocsList = emitter.getTryLocsList(); - - if (node.generator) { - wrapArgs.push(outerFnExpr); - } else if (context.usesThis || tryLocsList || node.async) { - // Async functions that are not generators don't care about the - // outer function because they don't need it to be marked and don't - // inherit from its .prototype. - wrapArgs.push(t.nullLiteral()); - } - if (context.usesThis) { - wrapArgs.push(t.thisExpression()); - } else if (tryLocsList || node.async) { - wrapArgs.push(t.nullLiteral()); - } - if (tryLocsList) { - wrapArgs.push(tryLocsList); - } else if (node.async) { - wrapArgs.push(t.nullLiteral()); - } - - if (node.async) { - // Rename any locally declared "Promise" variable, - // to use the global one. - let currentScope = path.scope; - do { - if (currentScope.hasOwnBinding("Promise")) currentScope.rename("Promise"); - } while (currentScope = currentScope.parent); - - wrapArgs.push(t.identifier("Promise")); - } - - let wrapCall = t.callExpression( - util.runtimeProperty(node.async ? "async" : "wrap"), - wrapArgs - ); - - outerBody.push(t.returnStatement(wrapCall)); - node.body = t.blockStatement(outerBody); - // We injected a few new variable declarations (for every hoisted var), - // so we need to add them to the scope. - path.get("body.body").forEach(p => p.scope.registerDeclaration(p)); - - const oldDirectives = bodyBlockPath.node.directives; - if (oldDirectives) { - // Babylon represents directives like "use strict" as elements of - // a bodyBlockPath.node.directives array. (#248) - node.body.directives = oldDirectives; - } - - let wasGeneratorFunction = node.generator; - if (wasGeneratorFunction) { - node.generator = false; - } - - if (node.async) { - node.async = false; - } - - if (wasGeneratorFunction && t.isExpression(node)) { - util.replaceWithOrRemove(path, t.callExpression(util.runtimeProperty("mark"), [node])) - path.addComment("leading", "#__PURE__"); - } - - const insertedLocs = emitter.getInsertedLocs(); - - path.traverse({ - NumericLiteral(path) { - if (!insertedLocs.has(path.node)) { - return; - } - - path.replaceWith(t.numericLiteral(path.node.value)); - }, - }) - - // Generators are processed in 'exit' handlers so that regenerator only has to run on - // an ES5 AST, but that means traversal will not pick up newly inserted references - // to things like 'regeneratorRuntime'. To avoid this, we explicitly requeue. - path.requeue(); - }) - } -}); - -// Check if a node should be transformed by regenerator -function shouldRegenerate(node, state) { - if (node.generator) { - if (node.async) { - // Async generator - return state.opts.asyncGenerators !== false; - } else { - // Plain generator - return state.opts.generators !== false; - } - } else if (node.async) { - // Async function - return state.opts.async !== false; - } else { - // Not a generator or async function. - return false; - } -} - -// Given a NodePath for a Function, return an Expression node that can be -// used to refer reliably to the function object from inside the function. -// This expression is essentially a replacement for arguments.callee, with -// the key advantage that it works in strict mode. -function getOuterFnExpr(funPath) { - const t = util.getTypes(); - let node = funPath.node; - t.assertFunction(node); - - if (!node.id) { - // Default-exported function declarations, and function expressions may not - // have a name to reference, so we explicitly add one. - node.id = funPath.scope.parent.generateUidIdentifier("callee"); - } - - if (node.generator && // Non-generator functions don't need to be marked. - t.isFunctionDeclaration(node)) { - // Return the identifier returned by runtime.mark(<node.id>). - return getMarkedFunctionId(funPath); - } - - return t.clone(node.id); -} - -const markInfo = new WeakMap(); - -function getMarkInfo(node) { - if (!markInfo.has(node)) { - markInfo.set(node, {}); - } - return markInfo.get(node); -} - -function getMarkedFunctionId(funPath) { - const t = util.getTypes(); - const node = funPath.node; - t.assertIdentifier(node.id); - - const blockPath = funPath.findParent(function (path) { - return path.isProgram() || path.isBlockStatement(); - }); - - if (!blockPath) { - return node.id; - } - - const block = blockPath.node; - assert.ok(Array.isArray(block.body)); - - const info = getMarkInfo(block); - if (!info.decl) { - info.decl = t.variableDeclaration("var", []); - blockPath.unshiftContainer("body", info.decl); - info.declPath = blockPath.get("body.0"); - } - - assert.strictEqual(info.declPath.node, info.decl); - - // Get a new unique identifier for our marked variable. - const markedId = blockPath.scope.generateUidIdentifier("marked"); - const markCallExp = t.callExpression( - util.runtimeProperty("mark"), - [t.clone(node.id)] - ); - - const index = info.decl.declarations.push( - t.variableDeclarator(markedId, markCallExp) - ) - 1; - - const markCallExpPath = - info.declPath.get("declarations." + index + ".init"); - - assert.strictEqual(markCallExpPath.node, markCallExp); - - markCallExpPath.addComment("leading", "#__PURE__"); - - return t.clone(markedId); -} - -let argumentsThisVisitor = { - "FunctionExpression|FunctionDeclaration|Method": function(path) { - path.skip(); - }, - - Identifier: function(path, state) { - if (path.node.name === "arguments" && util.isReference(path)) { - util.replaceWithOrRemove(path, state.getArgsId()); - state.usesArguments = true; - } - }, - - ThisExpression: function(path, state) { - state.usesThis = true; - } -}; - -let functionSentVisitor = { - MetaProperty(path) { - let { node } = path; - - if (node.meta.name === "function" && - node.property.name === "sent") { - const t = util.getTypes(); - util.replaceWithOrRemove( - path, - t.memberExpression( - t.clone(this.context), - t.identifier("_sent") - ) - ); - } - } -}; - -let awaitVisitor = { - Function: function(path) { - path.skip(); // Don't descend into nested function scopes. - }, - - AwaitExpression: function(path) { - const t = util.getTypes(); - - // Convert await expressions to yield expressions. - let argument = path.node.argument; - - // Transforming `await x` to `yield regeneratorRuntime.awrap(x)` - // causes the argument to be wrapped in such a way that the runtime - // can distinguish between awaited and merely yielded values. - util.replaceWithOrRemove(path, t.yieldExpression( - t.callExpression( - util.runtimeProperty("awrap"), - [argument] - ), - false - )); - } -}; |
