js/src/tests/js1_8/genexps/regress-380237-04.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:36b4b5fd7e08
1 // |reftest| skip -- obsolete test, need to remove minor failures to reenable.
2 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 //-----------------------------------------------------------------------------
8 var BUGNUMBER = 380237;
9 var summary = 'Generator expressions parenthesization test';
10 var actual = '';
11 var expect = '';
12
13
14 /*
15
16 Given that parentheization seems so fragile *and* the rules for where
17 genexps are allowed keep changing, I thought it would be good to have
18 a way to test that:
19
20 1) unparenthesized genexps are allowed in some places and the
21 decompilation is sane and not over-parenthesized
22
23 2) unparenthesized genexps are disallowed in many places and when
24 there are parens, the decompilation is sane and not over-parenthesized
25
26 */
27
28 // |genexp| must have the exact same whitespace the decompiler uses
29 genexp = "x * x for (x in [])";
30 genexpParened = "(" + genexp + ")";
31 genexpParenedTwice = "(" + genexpParened + ")";
32
33 // Warning: be careful not to put [] around stuff, because that would
34 // cause it to be treated as an array comprehension instead of a
35 // generator expression!
36
37 // Statements
38 doesNotNeedParens(1, "if (xx) { }");
39 needParens(2, "if (1, xx) { }");
40 needParens(3, "if (xx, 1) { }");
41 doesNotNeedParens(4, "do { } while (xx);");
42 doesNotNeedParens(5, "while (xx) { }");
43 doesNotNeedParens(6, "switch (xx) { }");
44 doesNotNeedParens(7, "with (xx) { }");
45 needParens(8, "switch (x) { case xx: }");
46 needParens(9, "return xx;");
47 needParens(10, "yield xx;");
48 needParens(11, "for (xx;;) { }");
49 needParens(12, "for (;xx;) { }", "function anonymous() {\n for (;;) {\n }\n}");
50 needParens(13, "for (;;xx) { }");
51 needParens(14, "for (i in xx) { }");
52 needParens(15, "throw xx");
53 needParens(16, "try { } catch (e if xx) { }");
54 needParens(17, "let (x=3) xx");
55 needParens(18, "let (x=xx) 3");
56
57 // Function calls
58 doesNotNeedParens(19, "f(xx);");
59 needParens(20, "f(xx, 1);");
60 needParens(21, "f(1, xx);");
61 doesNotNeedParens(22, "/x/(xx);");
62 needParens(23, "/x/(xx, 1);");
63 needParens(24, "/x/(1, xx);");
64
65 // eval is special and often confuses the decompiler.
66 doesNotNeedParens(25, "eval(xx);");
67 needParens(26, "eval(xx, 1);");
68 needParens(27, "eval(1, xx);");
69
70 // Expressions
71 needParens(28, "xx;"); // ???
72 needParens(29, "var g = xx;"); // ???
73 needParens(30, "g += xx;");
74 needParens(31, "xx();");
75 needParens(32, "xx() = 3;");
76 needParens(33, "a ? xx : c");
77 needParens(34, "xx ? b : c");
78 needParens(35, "a ? b : xx");
79 needParens(36, "1 ? xx : c");
80 needParens(37, "0 ? b : xx");
81 needParens(38, "1 + xx");
82 needParens(39, "xx + 1");
83 needParens(40, "1, xx");
84 doesNotNeedParens(41, "+(xx)");
85 doesNotNeedParens(42, "!(xx)");
86 needParens(43, "xx, 1");
87 needParens(44, "[1, xx]");
88 needParens(45, "[xx, 1]");
89 needParens(46, "[xx,3]");
90 needParens(47, "[xx,null]");
91 needParens(48, "xx.p");
92 needParens(49, "xx.@p");
93 needParens(50, "typeof xx;");
94 needParens(51, "void xx;");
95 needParens(52, "({ a: xx })");
96 needParens(53, "({ a: 1, b: xx })");
97 needParens(54, "({ a: xx, b: 1 })");
98 needParens(55, "({ a getter: xx })");
99 needParens(56, "<x a={xx}/>");
100 doesNotNeedParens(57, "new (xx);");
101 doesNotNeedParens(58, "new a(xx);");
102
103
104 // Generator expressions cannot be used as LHS, even though they're syntactic
105 // sugar for something that looks a lot like an "lvalue return": (f() = 3).
106
107 rejectLHS(59, "++ (xx);");
108 rejectLHS(60, "delete xx;");
109 rejectLHS(61, "delete (xx);");
110 rejectLHS(62, "for (xx in []) { }");
111 rejectLHS(63, "for ((xx) in []) { }");
112 rejectLHS(64, "try { } catch(xx) { }");
113 rejectLHS(65, "try { } catch([(xx)]) { }");
114 rejectLHS(66, "xx += 3;");
115 rejectLHS(67, "(xx) += 3;");
116 rejectLHS(68, "xx = 3;");
117
118 // Assignment
119 rejectLHS(69, " (xx) = 3;");
120 rejectLHS(70, "var (xx) = 3;");
121 rejectLHS(71, "const (xx) = 3;");
122 rejectLHS(72, "let (xx) = 3;");
123
124 // Destructuring assignment
125 rejectLHS(73, " [(xx)] = 3;");
126 rejectLHS(74, "var [(xx)] = 3;");
127 rejectLHS(75, "const [(xx)] = 3;");
128 rejectLHS(76, "let [(xx)] = 3;");
129
130 // Group assignment (Spidermonkey optimization for certain
131 // destructuring assignments)
132 rejectLHS(77, " [(xx)] = [3];");
133 rejectLHS(78, "var [(xx)] = [3];");
134 rejectLHS(79, "const [(xx)] = [3];");
135 rejectLHS(80, "let [(xx)] = [3];");
136
137 // Destructuring & group assignment for array comprehensions, just for kicks.
138 rejectLHS(81, " [xx] = [3];");
139 rejectLHS(82, "var [xx] = [3];");
140 rejectLHS(83, "const [xx] = [3];");
141 rejectLHS(84, "let [xx] = 3;");
142 rejectLHS(85, " [xx] = 3;");
143 rejectLHS(86, "var [xx] = 3;");
144 rejectLHS(87, "const [xx] = 3;");
145 rejectLHS(88, "let [xx] = 3;");
146
147 // This is crazy, ambiguous, and/or buggy.
148 // See https://bugzilla.mozilla.org/show_bug.cgi?id=380237#c23 et seq.
149 //doesNotNeedParens("(yield xx);");
150
151 print("Done!");
152
153 function doesNotNeedParens(section, pat)
154 {
155 print("Testing section " + section + " pattern " + pat);
156
157 var f, ft;
158 sanityCheck(section, pat);
159
160 expect = 'No Error';
161 actual = '';
162 ft = pat.replace(/xx/, genexp);
163 try {
164 f = new Function(ft);
165 actual = 'No Error';
166 } catch(e) {
167 print("Unparenthesized genexp SHOULD have been accepted here!");
168 actual = e + '';
169 }
170 reportCompare(expect, actual, summary + ': doesNotNeedParens section ' + section + ' pattern ' + pat);
171
172 roundTripTest(section, f);
173
174 // Make sure the decompilation is not over-parenthesized.
175 var uf = "" + f;
176 if (pat.indexOf("(xx)") != -1)
177 overParenTest(section, f);
178 // else
179 // print("Skipping the over-parenthesization test, because I don't know how to test for over-parenthesization when the pattern doesn't have parens snugly around it.")
180 }
181
182 function needParens(section, pat, exp)
183 {
184 print("Testing section " + section + " pattern " + pat);
185
186 var f, ft;
187 sanityCheck(section, pat);
188
189 expect = 'SyntaxError';
190 actual = '';
191 ft = pat.replace(/xx/, genexp);
192 try {
193 f = new Function(ft);
194 print("Unparenthesized genexp should NOT have been accepted here!");
195 } catch(e) {
196 /* expected to throw */
197 actual = e.name;
198 }
199 reportCompare(expect, actual, summary + ': needParens section ' + section + ' pattern ' + pat);
200
201 expect = 'No Error';
202 actual = '';
203 ft = pat.replace(/xx/, genexpParened);
204 try {
205 f = new Function(ft);
206 actual = 'No Error';
207 } catch(e) {
208 print("Yikes!");
209 actual = e + '';
210 }
211 reportCompare(expect, actual, summary + ': needParens section ' + section + ' ft ' + ft);
212
213 roundTripTest(section, f, exp);
214 overParenTest(section, f, exp);
215 }
216
217 function rejectLHS(section, pat)
218 {
219 print("Testing section " + section + " pattern " + pat);
220
221 // sanityCheck(pat); // because 'z' should be accepted as an LHS or binding
222
223 var ft;
224
225 expect = 'SyntaxError';
226 actual = '';
227 ft = pat.replace(/xx/, genexp)
228 try {
229 new Function(ft);
230 print("That should have been a syntax error!");
231 actual = 'No Error';
232 } catch(e) {
233 actual = e.name;
234 }
235 reportCompare(expect, actual, summary + ': rejectLHS section ' + section);
236 }
237
238
239 function overParenTest(section, f, exp)
240 {
241 var uf = "" + f;
242 if (uf == exp)
243 return;
244
245 reportCompare(false, uf.indexOf(genexpParened) == -1, summary +
246 ': overParenTest genexp snugly in parentheses: section ' + section + ' uf ' + uf);
247
248 if (uf.indexOf(genexpParened) != -1) {
249 reportCompare(true, uf.indexOf(genexpParenedTwice) == -1, summary +
250 ': overParensTest decompilation should not be over-parenthesized: section ' + ' uf ' + uf);
251 }
252 }
253
254 function sanityCheck(section, pat)
255 {
256 expect = '';
257 actual = '';
258
259 if (pat.indexOf("xx") == -1)
260 {
261 actual += "No 'xx' in this pattern? ";
262 }
263
264 var f, ft;
265 ft = pat.replace(/xx/, "z");
266 try {
267 f = new Function(ft);
268 } catch(e) {
269 actual += "Yowzers! Probably a bogus test!";
270 }
271 reportCompare(expect, actual, summary + ': sanityCheck section ' + section + ' pattern ' + pat);
272 }
273
274 function roundTripTest(section, f, exp)
275 {
276 // Decompile
277 var uf = "" + f;
278
279 // Recompile
280 expect = 'No Error';
281 actual = '';
282 var euf;
283 try {
284 euf = eval("(" + uf + ")");
285 actual = 'No Error';
286 reportCompare(expect, actual, summary + ': roundTripTest: section ' + section + ' uf ' + uf);
287 } catch(e) {
288 actual = e + '';
289 reportCompare(expect, actual, summary + ': roundTripTest: section ' + section + ' uf ' + uf);
290 return;
291 }
292
293 // Decompile again and make sure the decompilations match exactly.
294 expect = exp || uf;
295 actual = "" + euf;
296 reportCompare(expect, actual, summary + ': roundTripTest no round-trip change: section ' + section);
297 }

mercurial