1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

yield now behaves as expected around 'this' - fixes https://github.com/jashkenas/coffeescript/issues/3882

This commit is contained in:
Andreas Lubbe 2015-02-26 13:01:12 +01:00
parent 06b74591e7
commit 84c125a71b
3 changed files with 50 additions and 3 deletions

View file

@ -87,7 +87,7 @@
};
Base.prototype.compileClosure = function(o) {
var args, argumentsNode, func, jumpNode, meth, parts;
var args, argumentsNode, func, jumpNode, meth, parts, ref3;
if (jumpNode = this.jumps()) {
jumpNode.error('cannot use a pure statement in an expression');
}
@ -105,7 +105,7 @@
func = new Value(func, [new Access(new Literal(meth))]);
}
parts = (new Call(func, args)).compileNode(o);
if (func.isGenerator) {
if (func.isGenerator || ((ref3 = func.base) != null ? ref3.isGenerator : void 0)) {
parts.unshift(this.makeCode("(yield* "));
parts.push(this.makeCode(")"));
}

View file

@ -90,7 +90,7 @@ exports.Base = class Base
meth = 'call'
func = new Value func, [new Access new Literal meth]
parts = (new Call func, args).compileNode o
if func.isGenerator
if func.isGenerator or func.base?.isGenerator
parts.unshift @makeCode "(yield* "
parts.push @makeCode ")"
parts

View file

@ -218,3 +218,50 @@ test "symbolic operators has precedence over the `yield`", ->
mapped = CoffeeScript.eval "(arr) -> (#{expression} for i in arr)"
arrayEq mapped(values), collect yielded values
test "yield handles 'this' correctly", ->
x = ->
yield switch
when true then yield => this
yield for item in [1]
yield => this
yield if true then yield => this
yield try throw yield => this
throw yield => this
y = x.call [1, 2, 3]
z = y.next()
arrayEq z.value(), [1, 2, 3]
ok z.done is false
z = y.next 123
ok z.value is 123 and z.done is false
z = y.next()
arrayEq z.value(), [1, 2, 3]
ok z.done is false
z = y.next 42
arrayEq z.value, [42]
ok z.done is false
z = y.next()
arrayEq z.value(), [1, 2, 3]
ok z.done is false
z = y.next 456
ok z.value is 456 and z.done is false
z = y.next()
arrayEq z.value(), [1, 2, 3]
ok z.done is false
z = y.next new Error "ignore me"
ok z.value is undefined and z.done is false
z = y.next()
arrayEq z.value(), [1, 2, 3]
ok z.done is false
throws -> y.next new Error "boom"