Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support wrapGenerator.isGeneratorFunction #55

Merged
merged 3 commits into from
Nov 2, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion lib/visit.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function visitNode(node) {
// TODO Ensure these identifiers are named uniquely.
var contextId = b.identifier("$ctx");
var argsId = b.identifier("$args");
var wrapGeneratorId = b.identifier("wrapGenerator");
var shouldAliasArguments = renameArguments(node, argsId);
var vars = hoist(node);

Expand All @@ -59,13 +60,39 @@ function visitNode(node) {
}

outerBody.push(b.returnStatement(
b.callExpression(b.identifier("wrapGenerator"), [
b.callExpression(wrapGeneratorId, [
emitter.getContextFunction(),
b.thisExpression()
])
));

node.body = b.blockStatement(outerBody);

var markMethod = b.memberExpression(
wrapGeneratorId,
b.identifier("mark"),
false
);

if (n.FunctionDeclaration.check(node)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: this case really deserves some comments.

var path = this.parent;

while (path && !n.BlockStatement.check(path.value)) {
path = path.parent;
}

if (path) {
var firstStmtPath = path.get("body", 0);
firstStmtPath.replace(
b.expressionStatement(b.callExpression(markMethod, [node.id])),
firstStmtPath.value
);
}

} else {
n.FunctionExpression.assert(node);
this.replace(b.callExpression(markMethod, [node]));
}
}

function renameArguments(func, argsId) {
Expand Down
14 changes: 14 additions & 0 deletions runtime/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@
// breaking out of the dispatch switch statement.
var ContinueSentinel = {};

// Dummy constructor that we use as the .constructor property for
// functions that return Generator objects.
function GeneratorFunction() {}

wrapGenerator.mark = function(genFun) {
genFun.constructor = GeneratorFunction;
return genFun;
};

wrapGenerator.isGeneratorFunction = function(genFun) {
var ctor = genFun && genFun.constructor;
return ctor ? "GeneratorFunction" === ctor.name : false;
};

function Generator(innerFn, self) {
var generator = this;
var context = new Context();
Expand Down
2 changes: 1 addition & 1 deletion runtime/min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions test/tests.es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -963,3 +963,43 @@ describe("yield* expression results", function () {
assert.strictEqual(pumpNumber(foo()), 10);
});
});

describe("isGeneratorFunction", function() {
it("should work for function declarations", function() {
// Do the assertions up here to make sure the generator function is
// marked at the beginning of the block the function is declared in.
assert.strictEqual(
wrapGenerator.isGeneratorFunction(genFun),
true
);

assert.strictEqual(
wrapGenerator.isGeneratorFunction(normalFun),
false
);

function normalFun() {
return 0;
}

function *genFun() {
yield 0;
}
});

it("should work for function expressions", function() {
assert.strictEqual(
wrapGenerator.isGeneratorFunction(function *genFun() {
yield 0;
}),
true
);

assert.strictEqual(
wrapGenerator.isGeneratorFunction(function normalFun() {
return 0;
}),
false
);
});
});