|
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 //----------------------------------------------------------------------------- |
|
8 var BUGNUMBER = 634472; |
|
9 var summary = 'contextual restrictions for yield and arguments'; |
|
10 var actual = ''; |
|
11 var expect = ''; |
|
12 |
|
13 |
|
14 function error(str) { |
|
15 let base; |
|
16 try { |
|
17 // the following line must not be broken up into multiple lines |
|
18 base = (function(){try{eval('throw new Error()')}catch(e){return e.lineNumber}})(); eval(str); |
|
19 return null; |
|
20 } catch (e) { |
|
21 e.lineNumber = e.lineNumber - base + 1; |
|
22 return e; |
|
23 } |
|
24 } |
|
25 |
|
26 const JSMSG_GENEXP_YIELD = error("(function(){((yield) for (x in []))})").message; |
|
27 const JSMSG_TOP_YIELD = error("yield").message; |
|
28 const JSMSG_YIELD_PAREN = error("(function(){yield, 1})").message; |
|
29 const JSMSG_YIELD_FOR = error("(function(){yield for})").message; |
|
30 const JSMSG_BAD_GENERATOR_SYNTAX = error("(1, x for (x in []))").message; |
|
31 |
|
32 const cases = [ |
|
33 // yield expressions |
|
34 { expr: "yield", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "simple yield" }, |
|
35 { expr: "yield 1", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg" }, |
|
36 { expr: "1, yield", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "simple yield at end of list" }, |
|
37 { expr: "1, yield 2", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg at end of list" }, |
|
38 { expr: "yield, 1", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "simple yield in list" }, |
|
39 { expr: "yield 1, 2", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "yield w/ arg in list" }, |
|
40 { expr: "(yield)", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "simple yield, parenthesized" }, |
|
41 { expr: "(yield 1)", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg, parenthesized" }, |
|
42 { expr: "(1, yield)", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "simple yield at end of list, parenthesized" }, |
|
43 { expr: "(1, yield 2)", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg at end of list, parenthesized" }, |
|
44 { expr: "(yield, 1)", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "simple yield in list, parenthesized" }, |
|
45 { expr: "(yield 1, 2)", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "yield w/ arg in list, parenthesized" }, |
|
46 |
|
47 // deeply nested yield expressions |
|
48 { expr: "((((yield))))", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "deeply nested yield" }, |
|
49 { expr: "((((yield 1))))", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "deeply nested yield w/ arg" }, |
|
50 |
|
51 // arguments |
|
52 { expr: "arguments", top: null, fun: null, gen: null, desc: "arguments in list" }, |
|
53 { expr: "1, arguments", top: null, fun: null, gen: null, desc: "arguments in list" }, |
|
54 |
|
55 // yield in generator expressions |
|
56 { expr: "(yield for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_FOR, gen: JSMSG_YIELD_FOR, desc: "simple yield in genexp" }, |
|
57 { expr: "(yield 1 for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg in genexp" }, |
|
58 { expr: "(yield, 1 for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "simple yield in list in genexp" }, |
|
59 { expr: "(yield 1, 2 for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "yield w/ arg in list in genexp" }, |
|
60 { expr: "(1, yield for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_FOR, gen: JSMSG_YIELD_FOR, desc: "simple yield at end of list in genexp" }, |
|
61 { expr: "(1, yield 2 for (x in []))", top: JSMSG_TOP_YIELD, fun: { simple: JSMSG_GENEXP_YIELD, call: JSMSG_GENEXP_YIELD }, |
|
62 gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg at end of list in genexp" }, |
|
63 { expr: "((yield) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "simple yield, parenthesized in genexp" }, |
|
64 { expr: "((yield 1) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg, parenthesized in genexp" }, |
|
65 { expr: "(1, (yield) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "simple yield, parenthesized in list in genexp" }, |
|
66 { expr: "(1, (yield 2) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg, parenthesized in list in genexp" }, |
|
67 { expr: "((1, yield) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "simple yield at end of list, parenthesized in genexp" }, |
|
68 { expr: "((1, yield 2) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg at end of list, parenthesized in genexp" }, |
|
69 { expr: "(1, (2, yield) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "simple yield at end of list, parenthesized in list in genexp" }, |
|
70 { expr: "(1, (2, yield 3) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg at end of list, parenthesized in list in genexp" }, |
|
71 { expr: "((yield, 1) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "simple yield in list, parenthesized in genexp" }, |
|
72 { expr: "((yield 1, 2) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "yield w/ arg in list, parenthesized in genexp" }, |
|
73 { expr: "(1, (yield, 2) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "simple yield in list, parenthesized in list in genexp" }, |
|
74 { expr: "(1, (yield 2, 3) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "yield w/ arg in list, parenthesized in list in genexp" }, |
|
75 |
|
76 // deeply nested yield in generator expressions |
|
77 { expr: "((((1, yield 2))) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "deeply nested yield in genexp" }, |
|
78 { expr: "((((1, yield 2)) for (x in [])) for (y in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "deeply nested yield in multiple genexps" }, |
|
79 |
|
80 // arguments in generator expressions |
|
81 { expr: "(arguments for (x in []))", top: null, fun: null, gen: null, desc: "simple arguments in genexp" }, |
|
82 { expr: "(1, arguments for (x in []))", top: JSMSG_BAD_GENERATOR_SYNTAX, fun: JSMSG_BAD_GENERATOR_SYNTAX, gen: JSMSG_BAD_GENERATOR_SYNTAX, desc: "arguments in list in genexp" }, |
|
83 { expr: "((arguments) for (x in []))", top: null, fun: null, gen: null, desc: "arguments, parenthesized in genexp" }, |
|
84 { expr: "(1, (arguments) for (x in []))", top: JSMSG_BAD_GENERATOR_SYNTAX, fun: JSMSG_BAD_GENERATOR_SYNTAX, gen: JSMSG_BAD_GENERATOR_SYNTAX, desc: "arguments, parenthesized in list in genexp" }, |
|
85 { expr: "((1, arguments) for (x in []))", top: null, fun: null, gen: null, desc: "arguments in list, parenthesized in genexp" }, |
|
86 { expr: "(1, (2, arguments) for (x in []))", top: JSMSG_BAD_GENERATOR_SYNTAX, fun: JSMSG_BAD_GENERATOR_SYNTAX, gen: JSMSG_BAD_GENERATOR_SYNTAX, desc: "arguments in list, parenthesized in list in genexp" }, |
|
87 |
|
88 // deeply nested arguments in generator expressions |
|
89 { expr: "((((1, arguments))) for (x in []))", top: null, fun: null, gen: null, desc: "deeply nested arguments in genexp" }, |
|
90 { expr: "((((1, arguments)) for (x in [])) for (y in []))", top: null, fun: null, gen: null, desc: "deeply nested arguments in multiple genexps" }, |
|
91 |
|
92 // legal yield/arguments in nested function |
|
93 { expr: "((function() { yield }) for (x in []))", top: null, fun: null, gen: null, desc: "legal yield in nested function" }, |
|
94 { expr: "((function() { arguments }) for (x in []))", top: null, fun: null, gen: null, desc: "legal arguments in nested function" }, |
|
95 { expr: "((function() arguments) for (x in []))", top: null, fun: null, gen: null, desc: "legal arguments in nested expression-closure" } |
|
96 ]; |
|
97 |
|
98 //----------------------------------------------------------------------------- |
|
99 test(); |
|
100 //----------------------------------------------------------------------------- |
|
101 |
|
102 function splitKeyword(str) { |
|
103 return str. |
|
104 replace(/yield for/, '\nyield for\n'). |
|
105 replace(/yield ([0-9])/, '\nyield $1\n'). |
|
106 replace(/yield([^ ]|$)/, '\nyield\n$1'). |
|
107 replace(/arguments/, '\narguments\n'); |
|
108 } |
|
109 |
|
110 function expectError1(err, ctx, msg) { |
|
111 reportCompare('object', typeof err, 'exn for: ' + msg); |
|
112 reportCompare(ctx, err.message, 'exn message for: ' + msg); |
|
113 if (ctx !== JSMSG_BAD_GENERATOR_SYNTAX) |
|
114 reportCompare(2, err.lineNumber, 'exn token for: ' + msg); |
|
115 } |
|
116 |
|
117 function expectError(expr, call, wrapCtx, expect, msg) { |
|
118 let exps = (typeof expect === "string") |
|
119 ? { simple: expect, call: expect } |
|
120 : expect; |
|
121 expectError1(error(wrapCtx(expr)), exps.simple, msg); |
|
122 if (call) |
|
123 expectError1(error(wrapCtx(call)), exps.call, 'call argument in ' + msg); |
|
124 } |
|
125 |
|
126 function expectSuccess(err, msg) { |
|
127 reportCompare(null, err, 'parse: ' + msg); |
|
128 } |
|
129 |
|
130 function atTop(str) { return str } |
|
131 function inFun(str) { return '(function(){' + str + '})' } |
|
132 function inGen(str) { return '(y for (y in ' + str + '))' } |
|
133 |
|
134 function test() |
|
135 { |
|
136 enterFunc ('test'); |
|
137 printBugNumber(BUGNUMBER); |
|
138 printStatus (summary); |
|
139 |
|
140 for (let i = 0, len = cases.length; i < len; i++) { |
|
141 let {expr, top, fun, gen, desc} = cases[i]; |
|
142 |
|
143 let call = (expr[0] === "(") ? ("print" + expr) : null; |
|
144 |
|
145 expr = splitKeyword(expr); |
|
146 if (call) |
|
147 call = splitKeyword(call); |
|
148 |
|
149 if (top) |
|
150 expectError(expr, call, atTop, top, 'top-level context, ' + desc); |
|
151 else |
|
152 expectSuccess(error(expr), 'top-level context, ' + desc); |
|
153 |
|
154 if (fun) |
|
155 expectError(expr, call, inFun, fun, 'function context, ' + desc); |
|
156 else |
|
157 expectSuccess(error(inFun(expr)), 'function context, ' + desc); |
|
158 |
|
159 if (gen) |
|
160 expectError(expr, call, inGen, gen, 'genexp context, ' + desc); |
|
161 else |
|
162 expectSuccess(error(inGen(expr)), 'genexp context, ' + desc); |
|
163 } |
|
164 |
|
165 exitFunc ('test'); |
|
166 } |