|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 |
|
7 // This file tests contextual restrictions for yield and arguments, and is |
|
8 // derived from js1_8/genexps/regress-634472.js. |
|
9 |
|
10 function error(str) { |
|
11 var base; |
|
12 try { |
|
13 // the following line must not be broken up into multiple lines |
|
14 base = (function(){try{eval('throw new Error()')}catch(e){return e.lineNumber}})(); eval(str); |
|
15 return null; |
|
16 } catch (e) { |
|
17 e.lineNumber = e.lineNumber - base + 1; |
|
18 return e; |
|
19 } |
|
20 } |
|
21 |
|
22 const YIELD_PAREN = error("(function*(){(for (y of (yield 1, 2)) y)})").message; |
|
23 const GENEXP_YIELD = error("(function*(){(for (x of yield 1) x)})").message; |
|
24 const TOP_YIELD = error("yield").message; |
|
25 const GENERIC = error("(for)").message; |
|
26 const BAD_GENERATOR_SYNTAX = error("(for (x of []) x, 1)").message; |
|
27 const MISSING_SEMI = error("yield 1").message; |
|
28 const MISSING_PAREN = error("(yield 1)").message; |
|
29 const PAREN_PAREN = error("(foo").message; |
|
30 const FOR_OF_PAREN = error("(for (x of y, z) w)").message; |
|
31 |
|
32 const cases = [ |
|
33 // Expressions involving yield without a value, not currently implemented. Many |
|
34 // of these errors would need to be updated. |
|
35 //{ expr: "yield", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "simple yield" }, |
|
36 //{ expr: "1, yield", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "simple yield at end of list" }, |
|
37 //{ expr: "yield, 1", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list" }, |
|
38 //{ expr: "(yield)", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "simple yield, parenthesized" }, |
|
39 //{ expr: "(1, yield)", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "simple yield at end of list, parenthesized" }, |
|
40 //{ expr: "(yield, 1)", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list, parenthesized" }, |
|
41 //{ expr: "((((yield))))", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "deeply nested yield" }, |
|
42 //{ expr: "(for (x of []) yield)", top: TOP_YIELD, fun: GENERIC, gen: GENERIC, desc: "simple yield in genexp" }, |
|
43 //{ expr: "(for (x of []) yield, 1)", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list in genexp" }, |
|
44 //{ expr: "(for (x of []) 1, yield)", top: TOP_YIELD, fun: GENERIC, gen: GENERIC, desc: "simple yield at end of list in genexp" }, |
|
45 //{ expr: "(for (x of []) (yield))", top: TOP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, desc: "simple yield, parenthesized in genexp" }, |
|
46 //{ expr: "(for (x of []) 1, (yield))", top: TOP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, desc: "simple yield, parenthesized in list in genexp" }, |
|
47 //{ expr: "(for (x of []) (1, yield))", top: TOP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, desc: "simple yield at end of list, parenthesized in genexp" }, |
|
48 //{ expr: "(for (x of []) 1, (2, yield))", top: TOP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, desc: "simple yield at end of list, parenthesized in list in genexp" }, |
|
49 //{ expr: "(for (x of []) (yield, 1))", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list, parenthesized in genexp" }, |
|
50 //{ expr: "(for (x of []) 1, (yield, 2))", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list, parenthesized in list in genexp" }, |
|
51 //{ expr: "(for (x of []) (function*() { yield }))", top: null, fun: null, gen: null, desc: "legal yield in nested function" }, |
|
52 |
|
53 // yield expressions |
|
54 { expr: "yield 1", top: MISSING_SEMI, fun: MISSING_SEMI, gen: null, genexp: GENEXP_YIELD, desc: "yield w/ arg" }, |
|
55 { expr: "1, yield 2", top: MISSING_SEMI, fun: MISSING_SEMI, gen: null, genexp: FOR_OF_PAREN, desc: "yield w/ arg at end of list" }, |
|
56 { expr: "yield 1, 2", top: MISSING_SEMI, fun: MISSING_SEMI, gen: null, genexp: FOR_OF_PAREN, desc: "yield w/ arg in list" }, |
|
57 { expr: "(yield 1)", top: MISSING_PAREN, fun: MISSING_PAREN, gen: null, genexp: GENEXP_YIELD, desc: "yield w/ arg, parenthesized" }, |
|
58 { expr: "(1, yield 2)", top: MISSING_PAREN, fun: MISSING_PAREN, gen: null, genexp: GENEXP_YIELD, desc: "yield w/ arg at end of list, parenthesized" }, |
|
59 { expr: "(yield 1, 2)", top: MISSING_PAREN, fun: MISSING_PAREN, gen: null, genexp: YIELD_PAREN, desc: "yield w/ arg in list, parenthesized" }, |
|
60 |
|
61 // deeply nested yield expressions |
|
62 { expr: "((((yield 1))))", top: MISSING_PAREN, fun: MISSING_PAREN, gen: null, genexp: GENEXP_YIELD, desc: "deeply nested yield w/ arg" }, |
|
63 |
|
64 // arguments |
|
65 { expr: "arguments", top: null, fun: null, gen: null, genexp: null, desc: "arguments in list" }, |
|
66 { expr: "1, arguments", top: null, fun: null, gen: null, genexp: FOR_OF_PAREN, desc: "arguments in list" }, |
|
67 |
|
68 // yield in generator expressions |
|
69 { expr: "(for (x of []) yield 1)", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "yield w/ arg in genexp" }, |
|
70 { expr: "(for (x of []) yield 1, 2)", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "yield w/ arg in list in genexp" }, |
|
71 { expr: "(for (x of []) 1, yield 2)", top: PAREN_PAREN, fun: PAREN_PAREN, gen: PAREN_PAREN, genexp: PAREN_PAREN, desc: "yield w/ arg at end of list in genexp" }, |
|
72 { expr: "(for (x of []) (yield 1))", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "yield w/ arg, parenthesized in genexp" }, |
|
73 { expr: "(for (x of []) 1, (yield 2))", top: PAREN_PAREN, fun: PAREN_PAREN, gen: PAREN_PAREN, genexp: PAREN_PAREN, desc: "yield w/ arg, parenthesized in list in genexp" }, |
|
74 { expr: "(for (x of []) (1, yield 2))", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "yield w/ arg at end of list, parenthesized in genexp" }, |
|
75 { expr: "(for (x of []) 1, (2, yield 3))", top: PAREN_PAREN, fun: PAREN_PAREN, gen: PAREN_PAREN, genexp: PAREN_PAREN, desc: "yield w/ arg at end of list, parenthesized in list in genexp" }, |
|
76 { expr: "(for (x of []) (yield 1, 2))", top: YIELD_PAREN, fun: YIELD_PAREN, gen: YIELD_PAREN, genexp: YIELD_PAREN, desc: "yield w/ arg in list, parenthesized in genexp" }, |
|
77 { expr: "(for (x of []) 1, (yield 2, 3))", top: PAREN_PAREN, fun: PAREN_PAREN, gen: PAREN_PAREN, genexp: PAREN_PAREN, desc: "yield w/ arg in list, parenthesized in list in genexp" }, |
|
78 |
|
79 // deeply nested yield in generator expressions |
|
80 { expr: "(for (x of []) (((1, yield 2))))", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "deeply nested yield in genexp" }, |
|
81 { expr: "(for (y of []) (for (x of []) ((1, yield 2))))", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "deeply nested yield in multiple genexps" }, |
|
82 |
|
83 // arguments in generator expressions |
|
84 { expr: "(for (x of []) arguments)", top: null, fun: null, gen: null, genexp: null, desc: "simple arguments in genexp" }, |
|
85 { expr: "(for (x of []) 1, arguments)", top: BAD_GENERATOR_SYNTAX, fun: BAD_GENERATOR_SYNTAX, gen: BAD_GENERATOR_SYNTAX, genexp: BAD_GENERATOR_SYNTAX, desc: "arguments in list in genexp" }, |
|
86 { expr: "(for (x of []) (arguments))", top: null, fun: null, gen: null, genexp: null, desc: "arguments, parenthesized in genexp" }, |
|
87 { expr: "(for (x of []) 1, (arguments))", top: BAD_GENERATOR_SYNTAX, fun: BAD_GENERATOR_SYNTAX, gen: BAD_GENERATOR_SYNTAX, genexp: BAD_GENERATOR_SYNTAX, desc: "arguments, parenthesized in list in genexp" }, |
|
88 { expr: "(for (x of []) (1, arguments))", top: null, fun: null, gen: null, genexp: null, desc: "arguments in list, parenthesized in genexp" }, |
|
89 { expr: "(for (x of []) 1, (2, arguments))", top: BAD_GENERATOR_SYNTAX, fun: BAD_GENERATOR_SYNTAX, gen: BAD_GENERATOR_SYNTAX, genexp: BAD_GENERATOR_SYNTAX, desc: "arguments in list, parenthesized in list in genexp" }, |
|
90 |
|
91 // deeply nested arguments in generator expressions |
|
92 { expr: "(for (x of []) (((1, arguments))))", top: null, fun: null, gen: null, genexp: null, desc: "deeply nested arguments in genexp" }, |
|
93 { expr: "(for (y of []) (for (x of []) ((1, arguments))))", top: null, fun: null, gen: null, genexp: null, desc: "deeply nested arguments in multiple genexps" }, |
|
94 |
|
95 // legal yield/arguments in nested function |
|
96 { expr: "(for (x of []) (function*() { yield 1 }))", top: null, fun: null, gen: null, genexp: null, desc: "legal yield in nested function" }, |
|
97 { expr: "(for (x of []) (function() { arguments }))", top: null, fun: null, gen: null, genexp: null, desc: "legal arguments in nested function" }, |
|
98 { expr: "(for (x of []) (function() arguments))", top: null, fun: null, gen: null, genexp: null, desc: "legal arguments in nested expression-closure" } |
|
99 ]; |
|
100 |
|
101 //----------------------------------------------------------------------------- |
|
102 test(); |
|
103 //----------------------------------------------------------------------------- |
|
104 |
|
105 function splitKeyword(str) { |
|
106 return str. |
|
107 // replace(/[)] yield/, ')\nyield\n'). |
|
108 replace(/yield ([0-9])/, '\nyield $1\n'). |
|
109 replace(/yield([^ ]|$)/, '\nyield\n$1'). |
|
110 replace(/arguments/, '\narguments\n'); |
|
111 } |
|
112 |
|
113 function expectError1(err, ctx, msg) { |
|
114 reportCompare('object', typeof err, 'exn for: ' + msg); |
|
115 reportCompare(ctx, err.message, 'exn message for: ' + msg); |
|
116 if (ctx !== BAD_GENERATOR_SYNTAX && ctx != PAREN_PAREN && ctx != FOR_OF_PAREN) |
|
117 reportCompare(2, err.lineNumber, 'exn token for: ' + msg); |
|
118 } |
|
119 |
|
120 function expectError(expr, wrapCtx, expect, msg) { |
|
121 expectError1(error(wrapCtx(expr)), expect, msg); |
|
122 } |
|
123 |
|
124 function expectSuccess(err, msg) { |
|
125 reportCompare(null, err, 'parse: ' + msg); |
|
126 } |
|
127 |
|
128 function atTop(str) { return str } |
|
129 function inFun(str) { return '(function(){' + str + '})' } |
|
130 function inGen(str) { return '(function*(){' + str + '})' } |
|
131 function inGenExp(str) { return '(for (y of ' + str + ') y)' } |
|
132 |
|
133 function test() |
|
134 { |
|
135 enterFunc ('test'); |
|
136 printBugNumber(BUGNUMBER); |
|
137 printStatus (summary); |
|
138 |
|
139 for (var i = 0, len = cases.length; i < len; i++) { |
|
140 var expr, top, fun, gen, genexp, desc; |
|
141 expr = cases[i].expr; |
|
142 top = cases[i].top; |
|
143 fun = cases[i].fun; |
|
144 gen = cases[i].gen; |
|
145 genexp = cases[i].genexp; |
|
146 desc = cases[i].desc; |
|
147 |
|
148 expr = splitKeyword(expr); |
|
149 |
|
150 if (top) |
|
151 expectError(expr, atTop, top, 'top-level context, ' + desc); |
|
152 else |
|
153 expectSuccess(error(expr), 'top-level context, ' + desc); |
|
154 |
|
155 if (fun) |
|
156 expectError(expr, inFun, fun, 'function context, ' + desc); |
|
157 else |
|
158 expectSuccess(error(inFun(expr)), 'function context, ' + desc); |
|
159 |
|
160 if (gen) |
|
161 expectError(expr, inGen, gen, 'generator context, ' + desc); |
|
162 else |
|
163 expectSuccess(error(inGen(expr)), 'generator context, ' + desc); |
|
164 |
|
165 if (genexp) |
|
166 expectError(expr, inGenExp, genexp, 'genexp context, ' + desc); |
|
167 else |
|
168 expectSuccess(error(inGenExp(expr)), 'genexp context, ' + desc); |
|
169 } |
|
170 |
|
171 exitFunc ('test'); |
|
172 } |