regenerator-transform
Advanced tools
Comparing version 0.9.3 to 0.9.4
754
lib/emit.js
"use strict"; | ||
var _typeof2 = require("babel-runtime/helpers/typeof"); | ||
var _typeof3 = _interopRequireDefault(_typeof2); | ||
var _stringify = require("babel-runtime/core-js/json/stringify"); | ||
@@ -359,295 +363,301 @@ | ||
switch (stmt.type) { | ||
case "ExpressionStatement": | ||
self.explodeExpression(path.get("expression"), true); | ||
break; | ||
var _ret = function () { | ||
switch (stmt.type) { | ||
case "ExpressionStatement": | ||
self.explodeExpression(path.get("expression"), true); | ||
break; | ||
case "LabeledStatement": | ||
after = loc(); | ||
case "LabeledStatement": | ||
after = 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); | ||
}); | ||
// 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); | ||
self.mark(after); | ||
break; | ||
break; | ||
case "WhileStatement": | ||
before = loc(); | ||
after = loc(); | ||
case "WhileStatement": | ||
before = loc(); | ||
after = 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); | ||
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; | ||
break; | ||
case "DoWhileStatement": | ||
var first = loc(); | ||
var test = loc(); | ||
after = loc(); | ||
case "DoWhileStatement": | ||
var first = loc(); | ||
var test = loc(); | ||
after = 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); | ||
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; | ||
break; | ||
case "ForStatement": | ||
head = loc(); | ||
var update = loc(); | ||
after = loc(); | ||
case "ForStatement": | ||
head = loc(); | ||
var update = loc(); | ||
after = 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); | ||
} | ||
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); | ||
self.mark(head); | ||
if (stmt.test) { | ||
self.jumpIfNot(self.explodeExpression(path.get("test")), after); | ||
} else { | ||
// No test means continue unconditionally. | ||
} | ||
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.leapManager.withEntry(new leap.LoopEntry(after, update, labelId), function () { | ||
self.explodeStatement(path.get("body")); | ||
}); | ||
self.mark(update); | ||
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); | ||
} | ||
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.jump(head); | ||
self.mark(after); | ||
self.mark(after); | ||
break; | ||
break; | ||
case "TypeCastExpression": | ||
return self.explodeExpression(path.get("expression")); | ||
case "TypeCastExpression": | ||
return { | ||
v: self.explodeExpression(path.get("expression")) | ||
}; | ||
case "ForInStatement": | ||
head = loc(); | ||
after = loc(); | ||
case "ForInStatement": | ||
head = loc(); | ||
after = loc(); | ||
var keyIterNextFn = self.makeTempVar(); | ||
self.emitAssign(keyIterNextFn, t.callExpression(util.runtimeProperty("keys"), [self.explodeExpression(path.get("right"))])); | ||
var keyIterNextFn = self.makeTempVar(); | ||
self.emitAssign(keyIterNextFn, t.callExpression(util.runtimeProperty("keys"), [self.explodeExpression(path.get("right"))])); | ||
self.mark(head); | ||
self.mark(head); | ||
var keyInfoTmpVar = self.makeTempVar(); | ||
self.jumpIf(t.memberExpression(t.assignmentExpression("=", keyInfoTmpVar, t.callExpression(keyIterNextFn, [])), t.identifier("done"), false), after); | ||
var keyInfoTmpVar = self.makeTempVar(); | ||
self.jumpIf(t.memberExpression(t.assignmentExpression("=", keyInfoTmpVar, t.callExpression(keyIterNextFn, [])), t.identifier("done"), false), after); | ||
self.emitAssign(stmt.left, t.memberExpression(keyInfoTmpVar, t.identifier("value"), false)); | ||
self.emitAssign(stmt.left, t.memberExpression(keyInfoTmpVar, t.identifier("value"), false)); | ||
self.leapManager.withEntry(new leap.LoopEntry(after, head, labelId), function () { | ||
self.explodeStatement(path.get("body")); | ||
}); | ||
self.leapManager.withEntry(new leap.LoopEntry(after, head, labelId), function () { | ||
self.explodeStatement(path.get("body")); | ||
}); | ||
self.jump(head); | ||
self.jump(head); | ||
self.mark(after); | ||
self.mark(after); | ||
break; | ||
break; | ||
case "BreakStatement": | ||
self.emitAbruptCompletion({ | ||
type: "break", | ||
target: self.leapManager.getBreakLoc(stmt.label) | ||
}); | ||
case "BreakStatement": | ||
self.emitAbruptCompletion({ | ||
type: "break", | ||
target: self.leapManager.getBreakLoc(stmt.label) | ||
}); | ||
break; | ||
break; | ||
case "ContinueStatement": | ||
self.emitAbruptCompletion({ | ||
type: "continue", | ||
target: self.leapManager.getContinueLoc(stmt.label) | ||
}); | ||
case "ContinueStatement": | ||
self.emitAbruptCompletion({ | ||
type: "continue", | ||
target: self.leapManager.getContinueLoc(stmt.label) | ||
}); | ||
break; | ||
break; | ||
case "SwitchStatement": | ||
// Always save the discriminant into a temporary variable in case the | ||
// test expressions overwrite values like context.sent. | ||
var disc = self.emitAssign(self.makeTempVar(), self.explodeExpression(path.get("discriminant"))); | ||
case "SwitchStatement": | ||
// Always save the discriminant into a temporary variable in case the | ||
// test expressions overwrite values like context.sent. | ||
var disc = self.emitAssign(self.makeTempVar(), self.explodeExpression(path.get("discriminant"))); | ||
after = loc(); | ||
var defaultLoc = loc(); | ||
var condition = defaultLoc; | ||
var caseLocs = []; | ||
after = loc(); | ||
var defaultLoc = loc(); | ||
var condition = defaultLoc; | ||
var caseLocs = []; | ||
// If there are no cases, .cases might be undefined. | ||
var cases = stmt.cases || []; | ||
// If there are no cases, .cases might be undefined. | ||
var cases = stmt.cases || []; | ||
for (var i = cases.length - 1; i >= 0; --i) { | ||
var c = cases[i]; | ||
t.assertSwitchCase(c); | ||
for (var i = cases.length - 1; i >= 0; --i) { | ||
var c = cases[i]; | ||
t.assertSwitchCase(c); | ||
if (c.test) { | ||
condition = t.conditionalExpression(t.binaryExpression("===", disc, c.test), caseLocs[i] = loc(), condition); | ||
} else { | ||
caseLocs[i] = defaultLoc; | ||
if (c.test) { | ||
condition = t.conditionalExpression(t.binaryExpression("===", disc, c.test), caseLocs[i] = loc(), condition); | ||
} else { | ||
caseLocs[i] = defaultLoc; | ||
} | ||
} | ||
} | ||
var discriminant = path.get("discriminant"); | ||
discriminant.replaceWith(condition); | ||
self.jump(self.explodeExpression(discriminant)); | ||
var discriminant = path.get("discriminant"); | ||
discriminant.replaceWith(condition); | ||
self.jump(self.explodeExpression(discriminant)); | ||
self.leapManager.withEntry(new leap.SwitchEntry(after), function () { | ||
path.get("cases").forEach(function (casePath) { | ||
var i = casePath.key; | ||
self.mark(caseLocs[i]); | ||
self.leapManager.withEntry(new leap.SwitchEntry(after), function () { | ||
path.get("cases").forEach(function (casePath) { | ||
var i = casePath.key; | ||
self.mark(caseLocs[i]); | ||
casePath.get("consequent").forEach(function (path) { | ||
self.explodeStatement(path); | ||
casePath.get("consequent").forEach(function (path) { | ||
self.explodeStatement(path); | ||
}); | ||
}); | ||
}); | ||
}); | ||
self.mark(after); | ||
if (defaultLoc.value === -1) { | ||
self.mark(defaultLoc); | ||
_assert2.default.strictEqual(after.value, defaultLoc.value); | ||
} | ||
self.mark(after); | ||
if (defaultLoc.value === -1) { | ||
self.mark(defaultLoc); | ||
_assert2.default.strictEqual(after.value, defaultLoc.value); | ||
} | ||
break; | ||
break; | ||
case "IfStatement": | ||
var elseLoc = stmt.alternate && loc(); | ||
after = loc(); | ||
case "IfStatement": | ||
var elseLoc = stmt.alternate && loc(); | ||
after = loc(); | ||
self.jumpIfNot(self.explodeExpression(path.get("test")), elseLoc || after); | ||
self.jumpIfNot(self.explodeExpression(path.get("test")), elseLoc || after); | ||
self.explodeStatement(path.get("consequent")); | ||
self.explodeStatement(path.get("consequent")); | ||
if (elseLoc) { | ||
self.jump(after); | ||
self.mark(elseLoc); | ||
self.explodeStatement(path.get("alternate")); | ||
} | ||
if (elseLoc) { | ||
self.jump(after); | ||
self.mark(elseLoc); | ||
self.explodeStatement(path.get("alternate")); | ||
} | ||
self.mark(after); | ||
self.mark(after); | ||
break; | ||
break; | ||
case "ReturnStatement": | ||
self.emitAbruptCompletion({ | ||
type: "return", | ||
value: self.explodeExpression(path.get("argument")) | ||
}); | ||
case "ReturnStatement": | ||
self.emitAbruptCompletion({ | ||
type: "return", | ||
value: self.explodeExpression(path.get("argument")) | ||
}); | ||
break; | ||
break; | ||
case "WithStatement": | ||
throw new Error("WithStatement not supported in generator functions."); | ||
case "WithStatement": | ||
throw new Error("WithStatement not supported in generator functions."); | ||
case "TryStatement": | ||
after = loc(); | ||
case "TryStatement": | ||
after = loc(); | ||
var handler = stmt.handler; | ||
var handler = stmt.handler; | ||
var catchLoc = handler && loc(); | ||
var catchEntry = catchLoc && new leap.CatchEntry(catchLoc, handler.param); | ||
var catchLoc = handler && loc(); | ||
var catchEntry = catchLoc && new leap.CatchEntry(catchLoc, handler.param); | ||
var finallyLoc = stmt.finalizer && loc(); | ||
var finallyEntry = finallyLoc && new leap.FinallyEntry(finallyLoc, after); | ||
var finallyLoc = stmt.finalizer && loc(); | ||
var finallyEntry = finallyLoc && new leap.FinallyEntry(finallyLoc, after); | ||
var tryEntry = new leap.TryEntry(self.getUnmarkedCurrentLoc(), catchEntry, finallyEntry); | ||
var tryEntry = new leap.TryEntry(self.getUnmarkedCurrentLoc(), catchEntry, finallyEntry); | ||
self.tryEntries.push(tryEntry); | ||
self.updateContextPrevLoc(tryEntry.firstLoc); | ||
self.tryEntries.push(tryEntry); | ||
self.updateContextPrevLoc(tryEntry.firstLoc); | ||
self.leapManager.withEntry(tryEntry, function () { | ||
self.explodeStatement(path.get("block")); | ||
self.leapManager.withEntry(tryEntry, function () { | ||
self.explodeStatement(path.get("block")); | ||
if (catchLoc) { | ||
(function () { | ||
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); | ||
} | ||
if (catchLoc) { | ||
(function () { | ||
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)); | ||
self.updateContextPrevLoc(self.mark(catchLoc)); | ||
var bodyPath = path.get("handler.body"); | ||
var safeParam = self.makeTempVar(); | ||
self.clearPendingException(tryEntry.firstLoc, safeParam); | ||
var bodyPath = path.get("handler.body"); | ||
var safeParam = self.makeTempVar(); | ||
self.clearPendingException(tryEntry.firstLoc, safeParam); | ||
bodyPath.traverse(catchParamVisitor, { | ||
safeParam: safeParam, | ||
catchParamName: handler.param.name | ||
}); | ||
bodyPath.traverse(catchParamVisitor, { | ||
safeParam: safeParam, | ||
catchParamName: handler.param.name | ||
}); | ||
self.leapManager.withEntry(catchEntry, function () { | ||
self.explodeStatement(bodyPath); | ||
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")); | ||
}); | ||
})(); | ||
} | ||
if (finallyLoc) { | ||
self.updateContextPrevLoc(self.mark(finallyLoc)); | ||
self.emit(t.returnStatement(t.callExpression(self.contextProperty("finish"), [finallyEntry.firstLoc]))); | ||
} | ||
}); | ||
self.leapManager.withEntry(finallyEntry, function () { | ||
self.explodeStatement(path.get("finalizer")); | ||
}); | ||
self.mark(after); | ||
self.emit(t.returnStatement(t.callExpression(self.contextProperty("finish"), [finallyEntry.firstLoc]))); | ||
} | ||
}); | ||
break; | ||
self.mark(after); | ||
case "ThrowStatement": | ||
self.emit(t.throwStatement(self.explodeExpression(path.get("argument")))); | ||
break; | ||
break; | ||
case "ThrowStatement": | ||
self.emit(t.throwStatement(self.explodeExpression(path.get("argument")))); | ||
default: | ||
throw new Error("unknown Statement of type " + (0, _stringify2.default)(stmt.type)); | ||
} | ||
}(); | ||
break; | ||
default: | ||
throw new Error("unknown Statement of type " + (0, _stringify2.default)(stmt.type)); | ||
} | ||
if ((typeof _ret === "undefined" ? "undefined" : (0, _typeof3.default)(_ret)) === "object") return _ret.v; | ||
}; | ||
@@ -807,15 +817,15 @@ | ||
} 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 = self.emitAssign(tempVar || self.makeTempVar(), 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 = self.emitAssign(tempVar || self.makeTempVar(), result); | ||
} | ||
return result; | ||
@@ -828,174 +838,206 @@ } | ||
switch (expr.type) { | ||
case "MemberExpression": | ||
return finish(t.memberExpression(self.explodeExpression(path.get("object")), expr.computed ? explodeViaTempVar(null, path.get("property")) : expr.property, expr.computed)); | ||
var _ret3 = function () { | ||
switch (expr.type) { | ||
case "MemberExpression": | ||
return { | ||
v: finish(t.memberExpression(self.explodeExpression(path.get("object")), expr.computed ? explodeViaTempVar(null, path.get("property")) : expr.property, expr.computed)) | ||
}; | ||
case "CallExpression": | ||
var calleePath = path.get("callee"); | ||
var argsPath = path.get("arguments"); | ||
case "CallExpression": | ||
var calleePath = path.get("callee"); | ||
var argsPath = path.get("arguments"); | ||
var newCallee = void 0; | ||
var newArgs = []; | ||
var newCallee = void 0; | ||
var newArgs = []; | ||
var hasLeapingArgs = false; | ||
argsPath.forEach(function (argPath) { | ||
hasLeapingArgs = hasLeapingArgs || meta.containsLeap(argPath.node); | ||
}); | ||
var hasLeapingArgs = false; | ||
argsPath.forEach(function (argPath) { | ||
hasLeapingArgs = hasLeapingArgs || meta.containsLeap(argPath.node); | ||
}); | ||
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. | ||
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. | ||
var newObject = 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")); | ||
var newObject = 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")); | ||
var newProperty = calleePath.node.computed ? explodeViaTempVar(null, calleePath.get("property")) : calleePath.node.property; | ||
var newProperty = calleePath.node.computed ? explodeViaTempVar(null, calleePath.get("property")) : calleePath.node.property; | ||
newArgs.unshift(newObject); | ||
newArgs.unshift(newObject); | ||
newCallee = t.memberExpression(t.memberExpression(newObject, newProperty, calleePath.node.computed), t.identifier("call"), false); | ||
newCallee = t.memberExpression(t.memberExpression(newObject, newProperty, calleePath.node.computed), t.identifier("call"), false); | ||
} else { | ||
newCallee = self.explodeExpression(calleePath); | ||
} | ||
} else { | ||
newCallee = self.explodeExpression(calleePath); | ||
} | ||
} else { | ||
newCallee = self.explodeExpression(calleePath); | ||
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), newCallee]); | ||
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), newCallee]); | ||
} | ||
} | ||
} | ||
argsPath.forEach(function (argPath) { | ||
newArgs.push(explodeViaTempVar(null, argPath)); | ||
}); | ||
argsPath.forEach(function (argPath) { | ||
newArgs.push(explodeViaTempVar(null, argPath)); | ||
}); | ||
return finish(t.callExpression(newCallee, newArgs)); | ||
return { | ||
v: finish(t.callExpression(newCallee, newArgs)) | ||
}; | ||
case "NewExpression": | ||
return finish(t.newExpression(explodeViaTempVar(null, path.get("callee")), path.get("arguments").map(function (argPath) { | ||
return explodeViaTempVar(null, argPath); | ||
}))); | ||
case "NewExpression": | ||
return { | ||
v: finish(t.newExpression(explodeViaTempVar(null, path.get("callee")), path.get("arguments").map(function (argPath) { | ||
return explodeViaTempVar(null, argPath); | ||
}))) | ||
}; | ||
case "ObjectExpression": | ||
return finish(t.objectExpression(path.get("properties").map(function (propPath) { | ||
if (propPath.isObjectProperty()) { | ||
return t.objectProperty(propPath.node.key, explodeViaTempVar(null, propPath.get("value")), propPath.node.computed); | ||
} else { | ||
return propPath.node; | ||
} | ||
}))); | ||
case "ObjectExpression": | ||
return { | ||
v: finish(t.objectExpression(path.get("properties").map(function (propPath) { | ||
if (propPath.isObjectProperty()) { | ||
return t.objectProperty(propPath.node.key, explodeViaTempVar(null, propPath.get("value")), propPath.node.computed); | ||
} else { | ||
return propPath.node; | ||
} | ||
}))) | ||
}; | ||
case "ArrayExpression": | ||
return finish(t.arrayExpression(path.get("elements").map(function (elemPath) { | ||
return explodeViaTempVar(null, elemPath); | ||
}))); | ||
case "ArrayExpression": | ||
return { | ||
v: finish(t.arrayExpression(path.get("elements").map(function (elemPath) { | ||
return explodeViaTempVar(null, elemPath); | ||
}))) | ||
}; | ||
case "SequenceExpression": | ||
var lastIndex = expr.expressions.length - 1; | ||
case "SequenceExpression": | ||
var 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); | ||
path.get("expressions").forEach(function (exprPath) { | ||
if (exprPath.key === lastIndex) { | ||
result = self.explodeExpression(exprPath, ignoreResult); | ||
} else { | ||
self.explodeExpression(exprPath, true); | ||
} | ||
}); | ||
return { | ||
v: result | ||
}; | ||
case "LogicalExpression": | ||
after = loc(); | ||
if (!ignoreResult) { | ||
result = self.makeTempVar(); | ||
} | ||
}); | ||
return result; | ||
var left = explodeViaTempVar(result, path.get("left")); | ||
case "LogicalExpression": | ||
after = loc(); | ||
if (expr.operator === "&&") { | ||
self.jumpIfNot(left, after); | ||
} else { | ||
_assert2.default.strictEqual(expr.operator, "||"); | ||
self.jumpIf(left, after); | ||
} | ||
if (!ignoreResult) { | ||
result = self.makeTempVar(); | ||
} | ||
explodeViaTempVar(result, path.get("right"), ignoreResult); | ||
var left = explodeViaTempVar(result, path.get("left")); | ||
self.mark(after); | ||
if (expr.operator === "&&") { | ||
self.jumpIfNot(left, after); | ||
} else { | ||
_assert2.default.strictEqual(expr.operator, "||"); | ||
self.jumpIf(left, after); | ||
} | ||
return { | ||
v: result | ||
}; | ||
explodeViaTempVar(result, path.get("right"), ignoreResult); | ||
case "ConditionalExpression": | ||
var elseLoc = loc(); | ||
after = loc(); | ||
var test = self.explodeExpression(path.get("test")); | ||
self.mark(after); | ||
self.jumpIfNot(test, elseLoc); | ||
return result; | ||
if (!ignoreResult) { | ||
result = self.makeTempVar(); | ||
} | ||
case "ConditionalExpression": | ||
var elseLoc = loc(); | ||
after = loc(); | ||
var test = self.explodeExpression(path.get("test")); | ||
explodeViaTempVar(result, path.get("consequent"), ignoreResult); | ||
self.jump(after); | ||
self.jumpIfNot(test, elseLoc); | ||
self.mark(elseLoc); | ||
explodeViaTempVar(result, path.get("alternate"), ignoreResult); | ||
if (!ignoreResult) { | ||
result = self.makeTempVar(); | ||
} | ||
self.mark(after); | ||
explodeViaTempVar(result, path.get("consequent"), ignoreResult); | ||
self.jump(after); | ||
return { | ||
v: result | ||
}; | ||
self.mark(elseLoc); | ||
explodeViaTempVar(result, path.get("alternate"), ignoreResult); | ||
case "UnaryExpression": | ||
return { | ||
v: 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)) | ||
}; | ||
self.mark(after); | ||
case "BinaryExpression": | ||
return { | ||
v: finish(t.binaryExpression(expr.operator, explodeViaTempVar(null, path.get("left")), explodeViaTempVar(null, path.get("right")))) | ||
}; | ||
return result; | ||
case "AssignmentExpression": | ||
return { | ||
v: finish(t.assignmentExpression(expr.operator, self.explodeExpression(path.get("left")), self.explodeExpression(path.get("right")))) | ||
}; | ||
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 "UpdateExpression": | ||
return { | ||
v: finish(t.updateExpression(expr.operator, self.explodeExpression(path.get("argument")), expr.prefix)) | ||
}; | ||
case "BinaryExpression": | ||
return finish(t.binaryExpression(expr.operator, explodeViaTempVar(null, path.get("left")), explodeViaTempVar(null, path.get("right")))); | ||
case "YieldExpression": | ||
after = loc(); | ||
var arg = expr.argument && self.explodeExpression(path.get("argument")); | ||
case "AssignmentExpression": | ||
return finish(t.assignmentExpression(expr.operator, self.explodeExpression(path.get("left")), self.explodeExpression(path.get("right")))); | ||
if (arg && expr.delegate) { | ||
var _result = self.makeTempVar(); | ||
case "UpdateExpression": | ||
return finish(t.updateExpression(expr.operator, self.explodeExpression(path.get("argument")), expr.prefix)); | ||
self.emit(t.returnStatement(t.callExpression(self.contextProperty("delegateYield"), [arg, t.stringLiteral(_result.property.name), after]))); | ||
case "YieldExpression": | ||
after = loc(); | ||
var arg = expr.argument && self.explodeExpression(path.get("argument")); | ||
self.mark(after); | ||
if (arg && expr.delegate) { | ||
var _result = self.makeTempVar(); | ||
return { | ||
v: _result | ||
}; | ||
} | ||
self.emit(t.returnStatement(t.callExpression(self.contextProperty("delegateYield"), [arg, t.stringLiteral(_result.property.name), after]))); | ||
self.emitAssign(self.contextProperty("next"), after); | ||
self.emit(t.returnStatement(arg || null)); | ||
self.mark(after); | ||
return _result; | ||
} | ||
return { | ||
v: self.contextProperty("sent") | ||
}; | ||
self.emitAssign(self.contextProperty("next"), after); | ||
self.emit(t.returnStatement(arg || null)); | ||
self.mark(after); | ||
default: | ||
throw new Error("unknown Expression of type " + (0, _stringify2.default)(expr.type)); | ||
} | ||
}(); | ||
return self.contextProperty("sent"); | ||
default: | ||
throw new Error("unknown Expression of type " + (0, _stringify2.default)(expr.type)); | ||
} | ||
if ((typeof _ret3 === "undefined" ? "undefined" : (0, _typeof3.default)(_ret3)) === "object") return _ret3.v; | ||
}; |
@@ -42,3 +42,5 @@ "use strict"; | ||
vdec.declarations.forEach(function (dec) { | ||
vars[dec.id.name] = dec.id; | ||
// 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); | ||
@@ -45,0 +47,0 @@ if (dec.init) { |
@@ -169,4 +169,4 @@ "use strict"; | ||
} else { | ||
return loc; | ||
} | ||
return loc; | ||
} | ||
} | ||
@@ -173,0 +173,0 @@ } |
@@ -38,7 +38,7 @@ "use strict"; | ||
} else if (Array.isArray(child)) { | ||
child.some(check); | ||
} else if (t.isNode(child)) { | ||
_assert2.default.strictEqual(result, false); | ||
result = predicate(child); | ||
} | ||
child.some(check); | ||
} else if (t.isNode(child)) { | ||
_assert2.default.strictEqual(result, false); | ||
result = predicate(child); | ||
} | ||
return result; | ||
@@ -45,0 +45,0 @@ } |
@@ -5,3 +5,3 @@ { | ||
"description": "Explode async and generator functions into a state machine.", | ||
"version": "0.9.3", | ||
"version": "0.9.4", | ||
"main": "lib/index.js", | ||
@@ -30,12 +30,15 @@ "keywords": [ | ||
}, | ||
"dependencies": { | ||
"babel-cli": "^6.18.0", | ||
"babel-plugin-transform-runtime": "^6.15.0", | ||
"babel-preset-es2015": "^6.18.0", | ||
"babel-runtime": "^6.18.0", | ||
"babel-types": "^6.19.0", | ||
"private": "^0.1.6" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "~6.9.0", | ||
"babel-plugin-transform-runtime": "~6.9.0", | ||
"babel-preset-es2015": "~6.9.0" | ||
}, | ||
"dependencies": { | ||
"babel-runtime": "~6.9.2", | ||
"babel-types": "~6.9.1", | ||
"private": "~0.1.6" | ||
"babel-cli": "^6.9.0", | ||
"babel-plugin-transform-runtime": "^6.9.0", | ||
"babel-preset-es2015": "^6.9.0" | ||
} | ||
} |
@@ -29,3 +29,5 @@ /** | ||
vdec.declarations.forEach(function(dec) { | ||
vars[dec.id.name] = dec.id; | ||
// 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); | ||
@@ -32,0 +34,0 @@ if (dec.init) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
145501
18
2946
6
+ Addedbabel-cli@^6.18.0
+ Addedbabel-preset-es2015@^6.18.0
+ Addedanymatch@1.3.2(transitive)
+ Addedarr-diff@2.0.04.0.0(transitive)
+ Addedarr-flatten@1.1.0(transitive)
+ Addedarr-union@3.1.0(transitive)
+ Addedarray-unique@0.2.10.3.2(transitive)
+ Addedassign-symbols@1.0.0(transitive)
+ Addedasync-each@1.0.6(transitive)
+ Addedatob@2.1.2(transitive)
+ Addedbabel-cli@6.26.0(transitive)
+ Addedbabel-core@6.26.3(transitive)
+ Addedbabel-generator@6.26.1(transitive)
+ Addedbabel-helper-call-delegate@6.24.1(transitive)
+ Addedbabel-helper-define-map@6.26.0(transitive)
+ Addedbabel-helper-function-name@6.24.1(transitive)
+ Addedbabel-helper-get-function-arity@6.24.1(transitive)
+ Addedbabel-helper-hoist-variables@6.24.1(transitive)
+ Addedbabel-helper-optimise-call-expression@6.24.1(transitive)
+ Addedbabel-helper-regex@6.26.0(transitive)
+ Addedbabel-helper-replace-supers@6.24.1(transitive)
+ Addedbabel-helpers@6.24.1(transitive)
+ Addedbabel-plugin-check-es2015-constants@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-arrow-functions@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-block-scoped-functions@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-block-scoping@6.26.0(transitive)
+ Addedbabel-plugin-transform-es2015-classes@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-computed-properties@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-destructuring@6.23.0(transitive)
+ Addedbabel-plugin-transform-es2015-duplicate-keys@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-for-of@6.23.0(transitive)
+ Addedbabel-plugin-transform-es2015-function-name@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-literals@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-modules-amd@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-modules-commonjs@6.26.2(transitive)
+ Addedbabel-plugin-transform-es2015-modules-systemjs@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-modules-umd@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-object-super@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-parameters@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-shorthand-properties@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-spread@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-sticky-regex@6.24.1(transitive)
+ Addedbabel-plugin-transform-es2015-template-literals@6.22.0(transitive)
+ Addedbabel-plugin-transform-es2015-typeof-symbol@6.23.0(transitive)
+ Addedbabel-plugin-transform-es2015-unicode-regex@6.24.1(transitive)
+ Addedbabel-plugin-transform-regenerator@6.26.0(transitive)
+ Addedbabel-plugin-transform-runtime@6.23.0(transitive)
+ Addedbabel-plugin-transform-strict-mode@6.24.1(transitive)
+ Addedbabel-polyfill@6.26.0(transitive)
+ Addedbabel-preset-es2015@6.24.1(transitive)
+ Addedbabel-register@6.26.0(transitive)
+ Addedbabel-template@6.26.0(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbase@0.11.2(transitive)
+ Addedbinary-extensions@1.13.1(transitive)
+ Addedbindings@1.5.0(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedbraces@1.8.52.3.2(transitive)
+ Addedcache-base@1.0.1(transitive)
+ Addedchokidar@1.7.0(transitive)
+ Addedclass-utils@0.3.6(transitive)
+ Addedcollection-visit@1.0.0(transitive)
+ Addedcommander@2.20.3(transitive)
+ Addedcomponent-emitter@1.3.1(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedconvert-source-map@1.9.0(transitive)
+ Addedcopy-descriptor@0.1.1(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addeddecode-uri-component@0.2.2(transitive)
+ Addeddefine-property@0.2.51.0.02.0.2(transitive)
+ Addeddetect-indent@4.0.0(transitive)
+ Addedexpand-brackets@0.1.52.1.4(transitive)
+ Addedexpand-range@1.8.2(transitive)
+ Addedextend-shallow@2.0.13.0.2(transitive)
+ Addedextglob@0.3.22.0.4(transitive)
+ Addedfile-uri-to-path@1.0.0(transitive)
+ Addedfilename-regex@2.0.1(transitive)
+ Addedfill-range@2.2.44.0.0(transitive)
+ Addedfor-in@1.0.2(transitive)
+ Addedfor-own@0.1.5(transitive)
+ Addedfragment-cache@0.2.1(transitive)
+ Addedfs-readdir-recursive@1.1.0(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedfsevents@1.2.13(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-value@2.0.6(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedglob-base@0.3.0(transitive)
+ Addedglob-parent@2.0.0(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhas-value@0.3.11.0.0(transitive)
+ Addedhas-values@0.1.41.0.0(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedhome-or-tmp@2.0.0(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedis-accessor-descriptor@1.0.1(transitive)
+ Addedis-binary-path@1.0.1(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedis-data-descriptor@1.0.1(transitive)
+ Addedis-descriptor@0.1.71.0.3(transitive)
+ Addedis-dotfile@1.0.3(transitive)
+ Addedis-equal-shallow@0.1.3(transitive)
+ Addedis-extendable@0.1.11.0.1(transitive)
+ Addedis-extglob@1.0.0(transitive)
+ Addedis-finite@1.1.0(transitive)
+ Addedis-glob@2.0.1(transitive)
+ Addedis-number@2.1.03.0.04.0.0(transitive)
+ Addedis-plain-object@2.0.4(transitive)
+ Addedis-posix-bracket@0.1.1(transitive)
+ Addedis-primitive@2.0.0(transitive)
+ Addedis-windows@1.0.2(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisobject@2.1.03.0.1(transitive)
+ Addedjsesc@0.5.01.3.0(transitive)
+ Addedjson5@0.5.1(transitive)
+ Addedkind-of@3.2.24.0.06.0.3(transitive)
+ Addedmap-cache@0.2.2(transitive)
+ Addedmap-visit@1.0.0(transitive)
+ Addedmath-random@1.0.4(transitive)
+ Addedmicromatch@2.3.113.1.10(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmixin-deep@1.3.2(transitive)
+ Addedmkdirp@0.5.6(transitive)
+ Addednan@2.20.0(transitive)
+ Addednanomatch@1.2.13(transitive)
+ Addednormalize-path@2.1.1(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedobject-copy@0.1.0(transitive)
+ Addedobject-visit@1.0.1(transitive)
+ Addedobject.omit@2.0.1(transitive)
+ Addedobject.pick@1.3.0(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedos-homedir@1.0.2(transitive)
+ Addedos-tmpdir@1.0.2(transitive)
+ Addedoutput-file-sync@1.1.2(transitive)
+ Addedparse-glob@3.0.4(transitive)
+ Addedpascalcase@0.1.1(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedposix-character-classes@0.1.1(transitive)
+ Addedpreserve@0.2.0(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedrandomatic@3.1.1(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedreaddirp@2.2.1(transitive)
+ Addedregenerate@1.4.2(transitive)
+ Addedregenerator-runtime@0.10.5(transitive)
+ Addedregenerator-transform@0.10.1(transitive)
+ Addedregex-cache@0.4.4(transitive)
+ Addedregex-not@1.0.2(transitive)
+ Addedregexpu-core@2.0.0(transitive)
+ Addedregjsgen@0.2.0(transitive)
+ Addedregjsparser@0.1.5(transitive)
+ Addedremove-trailing-separator@1.1.0(transitive)
+ Addedrepeat-element@1.1.4(transitive)
+ Addedrepeat-string@1.6.1(transitive)
+ Addedrepeating@2.0.1(transitive)
+ Addedresolve-url@0.2.1(transitive)
+ Addedret@0.1.15(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
+ Addedsafe-regex@1.1.0(transitive)
+ Addedset-value@2.0.1(transitive)
+ Addedslash@1.0.0(transitive)
+ Addedsnapdragon@0.8.2(transitive)
+ Addedsnapdragon-node@2.1.1(transitive)
+ Addedsnapdragon-util@3.0.1(transitive)
+ Addedsource-map@0.5.7(transitive)
+ Addedsource-map-resolve@0.5.3(transitive)
+ Addedsource-map-support@0.4.18(transitive)
+ Addedsource-map-url@0.4.1(transitive)
+ Addedsplit-string@3.1.0(transitive)
+ Addedstatic-extend@0.1.2(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedto-object-path@0.3.0(transitive)
+ Addedto-regex@3.0.2(transitive)
+ Addedto-regex-range@2.1.1(transitive)
+ Addedtrim-right@1.0.1(transitive)
+ Addedunion-value@1.0.1(transitive)
+ Addedunset-value@1.0.0(transitive)
+ Addedurix@0.1.0(transitive)
+ Addeduse@3.1.1(transitive)
+ Addeduser-home@1.1.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedv8flags@2.1.1(transitive)
+ Addedwrappy@1.0.2(transitive)
- Removedbabel-runtime@6.9.2(transitive)
- Removedbabel-types@6.9.1(transitive)
- Removedregenerator-runtime@0.9.6(transitive)
Updatedbabel-runtime@^6.18.0
Updatedbabel-types@^6.19.0
Updatedprivate@^0.1.6