| // This file was written by Andy Wingo <wingo@igalia.com> and originally |
| // contributed to V8 as generators-parsing.js, available here: |
| // |
| // http://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/harmony/generators-parsing.js |
| |
| function assertSyntaxError(str) { |
| var msg; |
| var evil = eval; |
| try { |
| // Non-direct eval. |
| evil(str); |
| } catch (exc) { |
| if (exc instanceof SyntaxError) |
| return; |
| msg = "Assertion failed: expected SyntaxError, got " + exc; |
| } |
| if (msg === undefined) |
| msg = "Assertion failed: expected SyntaxError, but no exception thrown"; |
| throw new Error(msg + " - " + str); |
| } |
| |
| // Yield statements. |
| function* g() { yield 3; yield 4; } |
| |
| // Yield expressions. |
| function* g() { (yield 3) + (yield 4); } |
| |
| // Yield without a RHS. |
| function* g() { yield; } |
| function* g() { yield } |
| function* g() { |
| yield |
| } |
| function* g() { (yield) } |
| function* g() { [yield] } |
| function* g() { {yield} } |
| function* g() { (yield), (yield) } |
| function* g() { yield; yield } |
| function* g() { (yield) ? yield : yield } |
| function* g() { |
| (yield) |
| ? yield |
| : yield |
| } |
| |
| // If yield has a RHS, it needs to start on the same line. The * in a |
| // yield* counts as starting the RHS. |
| function* g() { |
| yield * |
| foo |
| } |
| assertThrows("function* g() { yield\n* foo }", SyntaxError); |
| assertIteratorNext(function*(){ |
| yield |
| 3 |
| }(), undefined) |
| |
| // A YieldExpression is not a LogicalORExpression. |
| assertThrows("function* g() { yield ? yield : yield }", SyntaxError); |
| |
| // You can have a generator in strict mode. |
| function* g() { "use strict"; yield 3; yield 4; } |
| |
| // Generators can have return statements also, which internally parse to a kind |
| // of yield expression. |
| function* g() { yield 1; return; } |
| function* g() { yield 1; return 2; } |
| function* g() { yield 1; return 2; yield "dead"; } |
| |
| // Generator expression. |
| (function* () { yield 3; }); |
| |
| // Named generator expression. |
| (function* g() { yield 3; }); |
| |
| // Generators do not have to contain yield expressions. |
| function* g() { } |
| |
| // YieldExpressions can occur in the RHS of a YieldExpression. |
| function* g() { yield yield 1; } |
| function* g() { yield 3 + (yield 4); } |
| |
| // Generator definitions with a name of "yield" are not specifically ruled out |
| // by the spec, as the `yield' name is outside the generator itself. However, |
| // in strict-mode, "yield" is an invalid identifier. |
| function* yield() { (yield 3) + (yield 4); } |
| assertSyntaxError("function* yield() { 'use strict'; (yield 3) + (yield 4); }"); |
| |
| // In classic mode, yield is a normal identifier, outside of generators. |
| function yield(yield) { yield: yield (yield + yield (0)); } |
| |
| // Yield is always valid as a key in an object literal. |
| ({ yield: 1 }); |
| function* g() { yield ({ yield: 1 }) } |
| function* g() { yield ({ get yield() { return 1; }}) } |
| |
| // Yield is a valid property name. |
| function* g(obj) { yield obj.yield; } |
| |
| // Checks that yield is a valid label in classic mode, but not valid in a strict |
| // mode or in generators. |
| function f() { yield: 1 } |
| assertSyntaxError("function f() { 'use strict'; yield: 1 }") |
| assertSyntaxError("function* g() { yield: 1 }") |
| |
| // Yield is only a keyword in the body of the generator, not in nested |
| // functions. |
| function* g() { function f(yield) { yield (yield + yield (0)); } } |
| |
| // Yield in a generator is not an identifier. |
| assertSyntaxError("function* g() { yield = 10; }"); |
| |
| // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which is |
| // invalid. |
| assertSyntaxError("function* g() { yield 3 + yield 4; }"); |
| |
| // Yield is still a future-reserved-word in strict mode |
| assertSyntaxError("function f() { 'use strict'; var yield = 13; }"); |
| |
| // The name of the NFE is let-bound in G, so is invalid. |
| assertSyntaxError("function* g() { yield (function yield() {}); }"); |
| |
| // In generators, yield is invalid as a formal argument name. |
| assertSyntaxError("function* g(yield) { yield (10); }"); |
| |
| if (typeof reportCompare == "function") |
| reportCompare(true, true); |