regenerator spring cleaning
This commit is contained in:
@@ -8,57 +8,50 @@
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var b = types.builders;
|
||||
var n = types.namedTypes;
|
||||
var leap = require("./leap");
|
||||
var meta = require("./meta");
|
||||
exports.Emitter = Emitter;
|
||||
|
||||
var runtimeProperty = require("./util").runtimeProperty;
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var leap = require("./leap");
|
||||
var meta = require("./meta");
|
||||
var _ = require("lodash");
|
||||
|
||||
var runtimeKeysMethod = runtimeProperty("keys");
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var b = types.builders;
|
||||
var n = types.namedTypes;
|
||||
|
||||
function Emitter(contextId) {
|
||||
assert.ok(this instanceof Emitter);
|
||||
n.Identifier.assert(contextId);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
// 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".
|
||||
contextId: { value: contextId },
|
||||
// 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.
|
||||
listing: { value: [] },
|
||||
// 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.
|
||||
marked: { value: [true] },
|
||||
// A sparse array whose keys correspond to locations in this.listing
|
||||
// that have been marked as branch/jump targets.
|
||||
this.marked = [true];
|
||||
|
||||
// The last location will be marked when this.getDispatchLoop is
|
||||
// called.
|
||||
finalLoc: { value: loc() },
|
||||
// The last location will be marked when this.getDispatchLoop is
|
||||
// called.
|
||||
this.finalLoc = loc();
|
||||
|
||||
// A list of all leap.TryEntry statements emitted.
|
||||
tryEntries: { value: [] }
|
||||
});
|
||||
// A list of all leap.TryEntry statements emitted.
|
||||
this.tryEntries = [];
|
||||
|
||||
// The .leapManager property needs to be defined by a separate
|
||||
// defineProperties call so that .finalLoc will be visible to the
|
||||
// leap.LeapManager constructor.
|
||||
Object.defineProperties(this, {
|
||||
// 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.
|
||||
leapManager: { value: new leap.LeapManager(this) }
|
||||
});
|
||||
// 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);
|
||||
}
|
||||
|
||||
var 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
|
||||
@@ -70,7 +63,7 @@ function loc() {
|
||||
|
||||
// Sets the exact value of the given location to the offset of the next
|
||||
// Statement emitted.
|
||||
Ep.mark = function(loc) {
|
||||
Emitter.prototype.mark = function(loc) {
|
||||
n.Literal.assert(loc);
|
||||
var index = this.listing.length;
|
||||
if (loc.value === -1) {
|
||||
@@ -84,29 +77,28 @@ Ep.mark = function(loc) {
|
||||
return loc;
|
||||
};
|
||||
|
||||
Ep.emit = function(node) {
|
||||
if (n.Expression.check(node))
|
||||
node = b.expressionStatement(node);
|
||||
Emitter.prototype.emit = function(node) {
|
||||
if (n.Expression.check(node)) node = b.expressionStatement(node);
|
||||
n.Statement.assert(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) {
|
||||
Emitter.prototype.emitAssign = function(lhs, rhs) {
|
||||
this.emit(this.assign(lhs, rhs));
|
||||
return lhs;
|
||||
};
|
||||
|
||||
// Shorthand for an assignment statement.
|
||||
Ep.assign = function(lhs, rhs) {
|
||||
Emitter.prototype.assign = function(lhs, rhs) {
|
||||
return b.expressionStatement(
|
||||
b.assignmentExpression("=", lhs, rhs));
|
||||
};
|
||||
|
||||
// Convenience function for generating expressions like context.next,
|
||||
// context.sent, and context.rval.
|
||||
Ep.contextProperty = function(name, computed) {
|
||||
Emitter.prototype.contextProperty = function(name, computed) {
|
||||
return b.memberExpression(
|
||||
this.contextId,
|
||||
computed ? b.literal(name) : b.identifier(name),
|
||||
@@ -124,7 +116,7 @@ var volatileContextPropertyNames = {
|
||||
// A "volatile" context property is a MemberExpression like context.sent
|
||||
// that should probably be stored in a temporary variable when there's a
|
||||
// possibility the property will get overwritten.
|
||||
Ep.isVolatileContextProperty = function(expr) {
|
||||
Emitter.prototype.isVolatileContextProperty = function(expr) {
|
||||
if (n.MemberExpression.check(expr)) {
|
||||
if (expr.computed) {
|
||||
// If it's a computed property such as context[couldBeAnything],
|
||||
@@ -135,8 +127,7 @@ Ep.isVolatileContextProperty = function(expr) {
|
||||
if (n.Identifier.check(expr.object) &&
|
||||
n.Identifier.check(expr.property) &&
|
||||
expr.object.name === this.contextId.name &&
|
||||
hasOwn.call(volatileContextPropertyNames,
|
||||
expr.property.name)) {
|
||||
_.has(volatileContextPropertyNames, expr.property.name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -145,7 +136,7 @@ Ep.isVolatileContextProperty = function(expr) {
|
||||
};
|
||||
|
||||
// Shorthand for setting context.rval and jumping to `context.stop()`.
|
||||
Ep.stop = function(rval) {
|
||||
Emitter.prototype.stop = function(rval) {
|
||||
if (rval) {
|
||||
this.setReturnValue(rval);
|
||||
}
|
||||
@@ -153,7 +144,7 @@ Ep.stop = function(rval) {
|
||||
this.jump(this.finalLoc);
|
||||
};
|
||||
|
||||
Ep.setReturnValue = function(valuePath) {
|
||||
Emitter.prototype.setReturnValue = function(valuePath) {
|
||||
n.Expression.assert(valuePath.value);
|
||||
|
||||
this.emitAssign(
|
||||
@@ -162,7 +153,7 @@ Ep.setReturnValue = function(valuePath) {
|
||||
);
|
||||
};
|
||||
|
||||
Ep.clearPendingException = function(tryLoc, assignee) {
|
||||
Emitter.prototype.clearPendingException = function(tryLoc, assignee) {
|
||||
n.Literal.assert(tryLoc);
|
||||
|
||||
var catchCall = b.callExpression(
|
||||
@@ -179,13 +170,13 @@ Ep.clearPendingException = function(tryLoc, assignee) {
|
||||
|
||||
// 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) {
|
||||
Emitter.prototype.jump = function(toLoc) {
|
||||
this.emitAssign(this.contextProperty("next"), toLoc);
|
||||
this.emit(b.breakStatement());
|
||||
};
|
||||
|
||||
// Conditional jump.
|
||||
Ep.jumpIf = function(test, toLoc) {
|
||||
Emitter.prototype.jumpIf = function(test, toLoc) {
|
||||
n.Expression.assert(test);
|
||||
n.Literal.assert(toLoc);
|
||||
|
||||
@@ -199,13 +190,12 @@ Ep.jumpIf = function(test, toLoc) {
|
||||
};
|
||||
|
||||
// Conditional jump, with the condition negated.
|
||||
Ep.jumpIfNot = function(test, toLoc) {
|
||||
Emitter.prototype.jumpIfNot = function(test, toLoc) {
|
||||
n.Expression.assert(test);
|
||||
n.Literal.assert(toLoc);
|
||||
|
||||
var negatedTest;
|
||||
if (n.UnaryExpression.check(test) &&
|
||||
test.operator === "!") {
|
||||
if (n.UnaryExpression.check(test) && test.operator === "!") {
|
||||
// Avoid double negation.
|
||||
negatedTest = test.argument;
|
||||
} else {
|
||||
@@ -227,13 +217,13 @@ Ep.jumpIfNot = function(test, toLoc) {
|
||||
// other local variables, and since we just increment `nextTempId`
|
||||
// monotonically, uniqueness is assured.
|
||||
var nextTempId = 0;
|
||||
Ep.makeTempVar = function() {
|
||||
Emitter.prototype.makeTempVar = function() {
|
||||
return this.contextProperty("t" + nextTempId++);
|
||||
};
|
||||
|
||||
Ep.getContextFunction = function(id) {
|
||||
Emitter.prototype.getContextFunction = function(id) {
|
||||
var node = b.functionExpression(
|
||||
id || null/*Anonymous*/,
|
||||
id || null,
|
||||
[this.contextId],
|
||||
b.blockStatement([this.getDispatchLoop()]),
|
||||
false, // Not a generator anymore!
|
||||
@@ -254,7 +244,7 @@ Ep.getContextFunction = function(id) {
|
||||
//
|
||||
// Each marked location in this.listing will correspond to one generated
|
||||
// case statement.
|
||||
Ep.getDispatchLoop = function() {
|
||||
Emitter.prototype.getDispatchLoop = function() {
|
||||
var self = this;
|
||||
var cases = [];
|
||||
var current;
|
||||
@@ -265,9 +255,7 @@ Ep.getDispatchLoop = function() {
|
||||
|
||||
self.listing.forEach(function(stmt, i) {
|
||||
if (self.marked.hasOwnProperty(i)) {
|
||||
cases.push(b.switchCase(
|
||||
b.literal(i),
|
||||
current = []));
|
||||
cases.push(b.switchCase(b.literal(i), current = []));
|
||||
alreadyEnded = false;
|
||||
}
|
||||
|
||||
@@ -318,7 +306,7 @@ function isSwitchCaseEnder(stmt) {
|
||||
n.ThrowStatement.check(stmt);
|
||||
}
|
||||
|
||||
Ep.getTryEntryList = function() {
|
||||
Emitter.prototype.getTryEntryList = 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.
|
||||
@@ -358,7 +346,7 @@ Ep.getTryEntryList = function() {
|
||||
|
||||
// No destructive modification of AST nodes.
|
||||
|
||||
Ep.explode = function(path, ignoreResult) {
|
||||
Emitter.prototype.explode = function(path, ignoreResult) {
|
||||
assert.ok(path instanceof types.NodePath);
|
||||
|
||||
var node = path.value;
|
||||
@@ -377,10 +365,7 @@ Ep.explode = function(path, ignoreResult) {
|
||||
|
||||
switch (node.type) {
|
||||
case "Program":
|
||||
return path.get("body").map(
|
||||
self.explodeStatement,
|
||||
self
|
||||
);
|
||||
return path.get("body").map(self.explodeStatement, self);
|
||||
|
||||
case "VariableDeclarator":
|
||||
throw getDeclError(node);
|
||||
@@ -390,13 +375,10 @@ Ep.explode = function(path, ignoreResult) {
|
||||
case "Property":
|
||||
case "SwitchCase":
|
||||
case "CatchClause":
|
||||
throw new Error(
|
||||
node.type + " nodes should be handled by their parents");
|
||||
throw new Error(node.type + " nodes should be handled by their parents");
|
||||
|
||||
default:
|
||||
throw new Error(
|
||||
"unknown Node of type " +
|
||||
JSON.stringify(node.type));
|
||||
throw new Error("unknown Node of type " + JSON.stringify(node.type));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -407,7 +389,7 @@ function getDeclError(node) {
|
||||
JSON.stringify(node));
|
||||
}
|
||||
|
||||
Ep.explodeStatement = function(path, labelId) {
|
||||
Emitter.prototype.explodeStatement = function(path, labelId) {
|
||||
assert.ok(path instanceof types.NodePath);
|
||||
|
||||
var stmt = path.value;
|
||||
@@ -768,18 +750,15 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(
|
||||
"unknown Statement of type " +
|
||||
JSON.stringify(stmt.type));
|
||||
throw new Error("unknown Statement of type " + JSON.stringify(stmt.type));
|
||||
}
|
||||
};
|
||||
|
||||
Ep.emitAbruptCompletion = function(record) {
|
||||
Emitter.prototype.emitAbruptCompletion = function(record) {
|
||||
if (!isValidCompletion(record)) {
|
||||
assert.ok(
|
||||
false,
|
||||
"invalid completion record: " +
|
||||
JSON.stringify(record)
|
||||
"invalid completion record: " + JSON.stringify(record)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -790,12 +769,10 @@ Ep.emitAbruptCompletion = function(record) {
|
||||
|
||||
var abruptArgs = [b.literal(record.type)];
|
||||
|
||||
if (record.type === "break" ||
|
||||
record.type === "continue") {
|
||||
if (record.type === "break" || record.type === "continue") {
|
||||
n.Literal.assert(record.target);
|
||||
abruptArgs[1] = record.target;
|
||||
} else if (record.type === "return" ||
|
||||
record.type === "throw") {
|
||||
} else if (record.type === "return" || record.type === "throw") {
|
||||
if (record.value) {
|
||||
n.Expression.assert(record.value);
|
||||
abruptArgs[1] = record.value;
|
||||
@@ -816,15 +793,15 @@ function isValidCompletion(record) {
|
||||
var type = record.type;
|
||||
|
||||
if (type === "normal") {
|
||||
return !hasOwn.call(record, "target");
|
||||
return !_.has(record, "target");
|
||||
}
|
||||
|
||||
if (type === "break" || type === "continue") {
|
||||
return !hasOwn.call(record, "value") && n.Literal.check(record.target);
|
||||
return !_.has(record, "value") && n.Literal.check(record.target);
|
||||
}
|
||||
|
||||
if (type === "return" || type === "throw") {
|
||||
return hasOwn.call(record, "value") && !hasOwn.call(record, "target");
|
||||
return _.has(record, "value") && !_.has(record, "target");
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -840,7 +817,7 @@ function isValidCompletion(record) {
|
||||
// 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() {
|
||||
Emitter.prototype.getUnmarkedCurrentLoc = function() {
|
||||
return b.literal(this.listing.length);
|
||||
};
|
||||
|
||||
@@ -854,7 +831,7 @@ Ep.getUnmarkedCurrentLoc = function() {
|
||||
// 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) {
|
||||
Emitter.prototype.updateContextPrevLoc = function(loc) {
|
||||
if (loc) {
|
||||
n.Literal.assert(loc);
|
||||
|
||||
@@ -877,7 +854,7 @@ Ep.updateContextPrevLoc = function(loc) {
|
||||
this.emitAssign(this.contextProperty("prev"), loc);
|
||||
};
|
||||
|
||||
Ep.explodeExpression = function(path, ignoreResult) {
|
||||
Emitter.prototype.explodeExpression = function(path, ignoreResult) {
|
||||
assert.ok(path instanceof types.NodePath);
|
||||
|
||||
var expr = path.value;
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
*/
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var types = require("ast-types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var n = types.namedTypes;
|
||||
var b = types.builders;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
// The hoist function takes a FunctionExpression or FunctionDeclaration
|
||||
// and replaces any Declaration nodes in its body with assignments, then
|
||||
@@ -139,7 +140,7 @@ exports.hoist = function(funPath) {
|
||||
var declarations = [];
|
||||
|
||||
Object.keys(vars).forEach(function(name) {
|
||||
if (!hasOwn.call(paramNames, name)) {
|
||||
if (!_.has(paramNames, name)) {
|
||||
declarations.push(b.variableDeclarator(vars[name], null));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,10 +8,20 @@
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
exports.FunctionEntry = FunctionEntry;
|
||||
exports.FinallyEntry = FinallyEntry;
|
||||
exports.SwitchEntry = SwitchEntry;
|
||||
exports.LeapManager = LeapManager;
|
||||
exports.CatchEntry = CatchEntry;
|
||||
exports.LoopEntry = LoopEntry;
|
||||
exports.TryEntry = TryEntry;
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var n = types.namedTypes;
|
||||
var inherits = require("util").inherits;
|
||||
var types = require("ast-types");
|
||||
var util = require("util");
|
||||
|
||||
var inherits = util.inherits;
|
||||
var n = types.namedTypes;
|
||||
|
||||
function Entry() {
|
||||
assert.ok(this instanceof Entry);
|
||||
@@ -22,13 +32,10 @@ function FunctionEntry(returnLoc) {
|
||||
|
||||
n.Literal.assert(returnLoc);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
returnLoc: { value: returnLoc }
|
||||
});
|
||||
this.returnLoc = returnLoc;
|
||||
}
|
||||
|
||||
inherits(FunctionEntry, Entry);
|
||||
exports.FunctionEntry = FunctionEntry;
|
||||
|
||||
function LoopEntry(breakLoc, continueLoc, label) {
|
||||
Entry.call(this);
|
||||
@@ -42,28 +49,22 @@ function LoopEntry(breakLoc, continueLoc, label) {
|
||||
label = null;
|
||||
}
|
||||
|
||||
Object.defineProperties(this, {
|
||||
breakLoc: { value: breakLoc },
|
||||
continueLoc: { value: continueLoc },
|
||||
label: { value: label }
|
||||
});
|
||||
this.breakLoc = breakLoc;
|
||||
this.continueLoc = continueLoc;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
inherits(LoopEntry, Entry);
|
||||
exports.LoopEntry = LoopEntry;
|
||||
|
||||
function SwitchEntry(breakLoc) {
|
||||
Entry.call(this);
|
||||
|
||||
n.Literal.assert(breakLoc);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
breakLoc: { value: breakLoc }
|
||||
});
|
||||
this.breakLoc = breakLoc;
|
||||
}
|
||||
|
||||
inherits(SwitchEntry, Entry);
|
||||
exports.SwitchEntry = SwitchEntry;
|
||||
|
||||
function TryEntry(firstLoc, catchEntry, finallyEntry) {
|
||||
Entry.call(this);
|
||||
@@ -85,15 +86,12 @@ function TryEntry(firstLoc, catchEntry, finallyEntry) {
|
||||
// Have to have one or the other (or both).
|
||||
assert.ok(catchEntry || finallyEntry);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
firstLoc: { value: firstLoc },
|
||||
catchEntry: { value: catchEntry },
|
||||
finallyEntry: { value: finallyEntry }
|
||||
});
|
||||
this.firstLoc = firstLoc;
|
||||
this.catchEntry = catchEntry;
|
||||
this.finallyEntry = finallyEntry;
|
||||
}
|
||||
|
||||
inherits(TryEntry, Entry);
|
||||
exports.TryEntry = TryEntry;
|
||||
|
||||
function CatchEntry(firstLoc, paramId) {
|
||||
Entry.call(this);
|
||||
@@ -101,27 +99,21 @@ function CatchEntry(firstLoc, paramId) {
|
||||
n.Literal.assert(firstLoc);
|
||||
n.Identifier.assert(paramId);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
firstLoc: { value: firstLoc },
|
||||
paramId: { value: paramId }
|
||||
});
|
||||
this.firstLoc = firstLoc;
|
||||
this.paramId = paramId;
|
||||
}
|
||||
|
||||
inherits(CatchEntry, Entry);
|
||||
exports.CatchEntry = CatchEntry;
|
||||
|
||||
function FinallyEntry(firstLoc) {
|
||||
Entry.call(this);
|
||||
|
||||
n.Literal.assert(firstLoc);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
firstLoc: { value: firstLoc }
|
||||
});
|
||||
this.firstLoc = firstLoc;
|
||||
}
|
||||
|
||||
inherits(FinallyEntry, Entry);
|
||||
exports.FinallyEntry = FinallyEntry;
|
||||
|
||||
function LeapManager(emitter) {
|
||||
assert.ok(this instanceof LeapManager);
|
||||
@@ -129,18 +121,11 @@ function LeapManager(emitter) {
|
||||
var Emitter = require("./emit").Emitter;
|
||||
assert.ok(emitter instanceof Emitter);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
emitter: { value: emitter },
|
||||
entryStack: {
|
||||
value: [new FunctionEntry(emitter.finalLoc)]
|
||||
}
|
||||
});
|
||||
this.emitter = emitter;
|
||||
this.entryStack = [new FunctionEntry(emitter.finalLoc)];
|
||||
}
|
||||
|
||||
var LMp = LeapManager.prototype;
|
||||
exports.LeapManager = LeapManager;
|
||||
|
||||
LMp.withEntry = function(entry, callback) {
|
||||
LeapManager.prototype.withEntry = function(entry, callback) {
|
||||
assert.ok(entry instanceof Entry);
|
||||
this.entryStack.push(entry);
|
||||
try {
|
||||
@@ -151,7 +136,7 @@ LMp.withEntry = function(entry, callback) {
|
||||
}
|
||||
};
|
||||
|
||||
LMp._findLeapLocation = function(property, label) {
|
||||
LeapManager.prototype._findLeapLocation = function(property, label) {
|
||||
for (var i = this.entryStack.length - 1; i >= 0; --i) {
|
||||
var entry = this.entryStack[i];
|
||||
var loc = entry[property];
|
||||
@@ -170,10 +155,10 @@ LMp._findLeapLocation = function(property, label) {
|
||||
return null;
|
||||
};
|
||||
|
||||
LMp.getBreakLoc = function(label) {
|
||||
LeapManager.prototype.getBreakLoc = function(label) {
|
||||
return this._findLeapLocation("breakLoc", label);
|
||||
};
|
||||
|
||||
LMp.getContinueLoc = function(label) {
|
||||
LeapManager.prototype.getContinueLoc = function(label) {
|
||||
return this._findLeapLocation("continueLoc", label);
|
||||
};
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
*/
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var m = require("private").makeAccessor();
|
||||
var types = require("ast-types");
|
||||
var m = require("private").makeAccessor();
|
||||
var _ = require("lodash");
|
||||
|
||||
var isArray = types.builtInTypes.array;
|
||||
var n = types.namedTypes;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var n = types.namedTypes;
|
||||
|
||||
function makePredicate(propertyName, knownTypes) {
|
||||
function onlyChildren(node) {
|
||||
@@ -45,16 +46,13 @@ function makePredicate(propertyName, knownTypes) {
|
||||
n.Node.assert(node);
|
||||
|
||||
var meta = m(node);
|
||||
if (hasOwn.call(meta, propertyName))
|
||||
return meta[propertyName];
|
||||
if (_.has(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 (_.has(opaqueTypes, node.type)) return meta[propertyName] = false;
|
||||
|
||||
if (hasOwn.call(knownTypes, node.type))
|
||||
return meta[propertyName] = true;
|
||||
if (_.has(knownTypes, node.type)) return meta[propertyName] = true;
|
||||
|
||||
return meta[propertyName] = onlyChildren(node);
|
||||
}
|
||||
@@ -91,7 +89,7 @@ var leapTypes = {
|
||||
|
||||
// All leap types are also side effect types.
|
||||
for (var type in leapTypes) {
|
||||
if (hasOwn.call(leapTypes, type)) {
|
||||
if (_.has(leapTypes, type)) {
|
||||
sideEffectTypes[type] = leapTypes[type];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ if (typeof global.regeneratorRuntime === "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var iteratorSymbol = typeof Symbol === "function" && Symbol.iterator || "@@iterator";
|
||||
var runtime = global.regeneratorRuntime = exports;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
var wrap = runtime.wrap = function wrap(innerFn, outerFn, self, tryList) {
|
||||
return new Generator(innerFn, outerFn, self || null, tryList || []);
|
||||
@@ -412,8 +412,7 @@ Context.prototype = {
|
||||
throw record.arg;
|
||||
}
|
||||
|
||||
if (record.type === "break" ||
|
||||
record.type === "continue") {
|
||||
if (record.type === "break" || record.type === "continue") {
|
||||
this.next = record.arg;
|
||||
} else if (record.type === "return") {
|
||||
this.rval = record.arg;
|
||||
|
||||
@@ -8,30 +8,11 @@
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
var b = require("ast-types").builders;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.defaults = function(obj) {
|
||||
var len = arguments.length;
|
||||
var extension;
|
||||
|
||||
for (var i = 1; i < len; ++i) {
|
||||
if ((extension = arguments[i])) {
|
||||
for (var key in extension) {
|
||||
if (hasOwn.call(extension, key) && !hasOwn.call(obj, key)) {
|
||||
obj[key] = extension[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
exports.runtimeProperty = function(name) {
|
||||
return b.memberExpression(
|
||||
b.identifier("regeneratorRuntime"),
|
||||
b.identifier(name),
|
||||
false
|
||||
exports.runtimeProperty = function (name) {
|
||||
return t.memberExpression(
|
||||
t.identifier("regeneratorRuntime"),
|
||||
t.identifier(name)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -200,8 +200,7 @@ function shouldNotHoistAbove(stmtPath) {
|
||||
for (var i = 0; i < value.declarations.length; ++i) {
|
||||
var decl = value.declarations[i];
|
||||
if (n.CallExpression.check(decl.init) &&
|
||||
types.astNodesAreEquivalent(decl.init.callee,
|
||||
runtimeMarkMethod)) {
|
||||
types.astNodesAreEquivalent(decl.init.callee, runtimeMarkMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user