Home | History | Annotate | Download | only in harmony
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 // Flags: --harmony-generators
     29 
     30 // Test basic generator syntax.
     31 
     32 // Yield statements.
     33 function* g() { yield 3; yield 4; }
     34 
     35 // Yield expressions.
     36 function* g() { (yield 3) + (yield 4); }
     37 
     38 // You can have a generator in strict mode.
     39 function* g() { "use strict"; yield 3; yield 4; }
     40 
     41 // Generators can have return statements also, which internally parse to a kind
     42 // of yield expression.
     43 function* g() { yield 1; return; }
     44 function* g() { yield 1; return 2; }
     45 function* g() { yield 1; return 2; yield "dead"; }
     46 
     47 // Generator expression.
     48 (function* () { yield 3; });
     49 
     50 // Named generator expression.
     51 (function* g() { yield 3; });
     52 
     53 // A generator without a yield is specified as causing an early error.  This
     54 // behavior is currently unimplemented.  See
     55 // https://bugs.ecmascript.org/show_bug.cgi?id=1283.
     56 function* g() { }
     57 
     58 // A YieldExpression in the RHS of a YieldExpression is currently specified as
     59 // causing an early error.  This behavior is currently unimplemented.  See
     60 // https://bugs.ecmascript.org/show_bug.cgi?id=1283.
     61 function* g() { yield yield 1; }
     62 function* g() { yield 3 + (yield 4); }
     63 
     64 // Generator definitions with a name of "yield" are not specifically ruled out
     65 // by the spec, as the `yield' name is outside the generator itself.  However,
     66 // in strict-mode, "yield" is an invalid identifier.
     67 function* yield() { (yield 3) + (yield 4); }
     68 assertThrows("function* yield() { \"use strict\"; (yield 3) + (yield 4); }",
     69              SyntaxError);
     70 
     71 // In classic mode, yield is a normal identifier, outside of generators.
     72 function yield(yield) { yield: yield (yield + yield (0)); }
     73 
     74 // Yield is always valid as a key in an object literal.
     75 ({ yield: 1 });
     76 function* g() { yield ({ yield: 1 }) }
     77 function* g() { yield ({ get yield() { return 1; }}) }
     78 
     79 // Checks that yield is a valid label in classic mode, but not valid in a strict
     80 // mode or in generators.
     81 function f() { yield: 1 }
     82 assertThrows("function f() { \"use strict\"; yield: 1 }", SyntaxError)
     83 assertThrows("function* g() { yield: 1 }", SyntaxError)
     84 
     85 // Yield is only a keyword in the body of the generator, not in nested
     86 // functions.
     87 function* g() { function f() { yield (yield + yield (0)); } }
     88 
     89 // Yield needs a RHS.
     90 assertThrows("function* g() { yield; }", SyntaxError);
     91 
     92 // Yield in a generator is not an identifier.
     93 assertThrows("function* g() { yield = 10; }", SyntaxError);
     94 
     95 // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which is
     96 // invalid.
     97 assertThrows("function* g() { yield 3 + yield 4; }", SyntaxError);
     98 
     99 // Yield is still a future-reserved-word in strict mode
    100 assertThrows("function f() { \"use strict\"; var yield = 13; }", SyntaxError);
    101 
    102 // The name of the NFE is let-bound in G, so is invalid.
    103 assertThrows("function* g() { yield (function yield() {}); }", SyntaxError);
    104 
    105 // In generators, yield is invalid as a formal argument name.
    106 assertThrows("function* g(yield) { yield (10); }", SyntaxError);
    107