fixed yield return producing incorrect output when used outside of the last line
This commit is contained in:
parent
fea058c53a
commit
feee6954a6
|
@ -652,13 +652,18 @@
|
|||
};
|
||||
|
||||
Return.prototype.compileNode = function(o) {
|
||||
var answer;
|
||||
var answer, exprIsYieldReturn, ref3;
|
||||
answer = [];
|
||||
answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : ""))));
|
||||
exprIsYieldReturn = (ref3 = this.expression) != null ? typeof ref3.isYieldReturn === "function" ? ref3.isYieldReturn() : void 0 : void 0;
|
||||
if (!exprIsYieldReturn) {
|
||||
answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : ""))));
|
||||
}
|
||||
if (this.expression) {
|
||||
answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN));
|
||||
}
|
||||
answer.push(this.makeCode(";"));
|
||||
if (!exprIsYieldReturn) {
|
||||
answer.push(this.makeCode(";"));
|
||||
}
|
||||
return answer;
|
||||
};
|
||||
|
||||
|
@ -2361,6 +2366,10 @@
|
|||
return (ref3 = this.operator) === 'yield' || ref3 === 'yield*';
|
||||
};
|
||||
|
||||
Op.prototype.isYieldReturn = function() {
|
||||
return this.isYield() && this.first instanceof Return;
|
||||
};
|
||||
|
||||
Op.prototype.isUnary = function() {
|
||||
return !this.second;
|
||||
};
|
||||
|
@ -2531,7 +2540,9 @@
|
|||
this.error('yield statements must occur within a function generator.');
|
||||
}
|
||||
if (indexOf.call(Object.keys(this.first), 'expression') >= 0 && !(this.first instanceof Throw)) {
|
||||
if (this.first.expression != null) {
|
||||
if (this.isYieldReturn()) {
|
||||
parts.push(this.first.compileToFragments(o, LEVEL_TOP));
|
||||
} else if (this.first.expression != null) {
|
||||
parts.push(this.first.expression.compileToFragments(o, LEVEL_OP));
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -453,11 +453,13 @@ exports.Return = class Return extends Base
|
|||
|
||||
compileNode: (o) ->
|
||||
answer = []
|
||||
exprIsYieldReturn = @expression?.isYieldReturn?()
|
||||
# TODO: If we call expression.compile() here twice, we'll sometimes get back different results!
|
||||
answer.push @makeCode @tab + "return#{if @expression then " " else ""}"
|
||||
unless exprIsYieldReturn
|
||||
answer.push @makeCode @tab + "return#{if @expression then " " else ""}"
|
||||
if @expression
|
||||
answer = answer.concat @expression.compileToFragments o, LEVEL_PAREN
|
||||
answer.push @makeCode ";"
|
||||
answer.push @makeCode ";" unless exprIsYieldReturn
|
||||
return answer
|
||||
|
||||
#### Value
|
||||
|
@ -1674,6 +1676,9 @@ exports.Op = class Op extends Base
|
|||
isYield: ->
|
||||
@operator in ['yield', 'yield*']
|
||||
|
||||
isYieldReturn: ->
|
||||
@isYield() and @first instanceof Return
|
||||
|
||||
isUnary: ->
|
||||
not @second
|
||||
|
||||
|
@ -1802,7 +1807,10 @@ exports.Op = class Op extends Base
|
|||
if not o.scope.parent?
|
||||
@error 'yield statements must occur within a function generator.'
|
||||
if 'expression' in Object.keys(@first) and not (@first instanceof Throw)
|
||||
parts.push @first.expression.compileToFragments o, LEVEL_OP if @first.expression?
|
||||
if @isYieldReturn()
|
||||
parts.push @first.compileToFragments o, LEVEL_TOP
|
||||
else if @first.expression?
|
||||
parts.push @first.expression.compileToFragments o, LEVEL_OP
|
||||
else
|
||||
parts.push [@makeCode "(#{op} "]
|
||||
parts.push @first.compileToFragments o, LEVEL_OP
|
||||
|
|
|
@ -38,6 +38,15 @@ test "last line yields are returned", ->
|
|||
y = x.next 42
|
||||
ok y.value is 42 and y.done is true
|
||||
|
||||
test "yield return can be used anywhere in the function body", ->
|
||||
x = do ->
|
||||
if true
|
||||
yield return true
|
||||
return false
|
||||
|
||||
y = x.next()
|
||||
ok y.value is true and y.done is true
|
||||
|
||||
test "bound generator", ->
|
||||
obj =
|
||||
bound: ->
|
||||
|
|
Loading…
Reference in New Issue