OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Flags: --allow-natives-syntax --harmony-explicit-tailcalls | |
6 // Flags: --harmony-do-expressions | |
7 | |
8 var SyntaxErrorTests = [ | |
9 { msg: "Unexpected expression inside tail call", | |
10 tests: [ | |
11 { src: `()=>{ return continue foo ; }`, | |
12 err: ` ^^^`, | |
13 }, | |
14 { src: `()=>{ return continue 42 ; }`, | |
15 err: ` ^^`, | |
16 }, | |
17 { src: `()=>{ return continue new foo () ; }`, | |
18 err: ` ^^^^^^^^^^`, | |
19 }, | |
20 { src: `()=>{ loop: return continue loop ; }`, | |
21 err: ` ^^^^`, | |
22 }, | |
23 { src: `class A { foo() { return continue super.x ; } }`, | |
24 err: ` ^^^^^^^`, | |
25 }, | |
26 { src: `()=>{ return continue this ; }`, | |
27 err: ` ^^^^`, | |
28 }, | |
29 { src: `()=>{ return continue class A {} ; }`, | |
30 err: ` ^^^^^^^^^^`, | |
31 }, | |
32 { src: `()=>{ return continue class A extends B {} ; }`, | |
33 err: ` ^^^^^^^^^^^^^^^^^^^^`, | |
34 }, | |
35 { src: `()=>{ return continue function A() { } ; }`, | |
36 err: ` ^^^^^^^^^^^^^^^^`, | |
37 }, | |
38 { src: `()=>{ return continue { a: b, c: d} ; }`, | |
39 err: ` ^^^^^^^^^^^^^`, | |
40 }, | |
41 { src: `()=>{ return continue function* Gen() { yield 1; } ; }`, | |
42 err: ` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^`, | |
43 }, | |
44 { src: `function A() { return continue new.target ; }`, | |
45 err: ` ^^^^^^^^^^`, | |
46 }, | |
47 { src: `()=>{ return continue () ; }`, | |
48 err: ` ^^`, | |
49 }, | |
50 { src: `()=>{ return continue ( 42 ) ; }`, | |
51 err: ` ^^^^^^`, | |
52 }, | |
53 { src: "()=>{ return continue `123 ${foo} 34lk` ; }", | |
54 err: ` ^^^^^^^^^^^^^^^^^`, | |
55 }, | |
56 { src: `()=>{ return continue do { x ? foo() : bar() ; } }`, | |
57 err: ` ^^^^^^^^^^^^^^^^^^^^^^^^^^`, | |
58 }, | |
59 ], | |
60 }, | |
61 { msg: "Tail call expression is not allowed here", | |
62 tests: [ | |
63 { src: `()=>{ return continue continue continue b() ; }`, | |
64 err: ` ^^^^^^^^^^^^`, | |
65 }, | |
66 { src: `()=>{ return continue ( continue b() ) ; }`, | |
67 err: ` ^^^^^^^^^^^^`, | |
68 }, | |
69 { src: `()=>{ return continue f() - a ; }`, | |
70 err: ` ^^^^^^^^^^^^^`, | |
71 }, | |
72 { src: `()=>{ return b + continue f() ; }`, | |
73 err: ` ^^^^^^^^^^^^^^`, | |
74 }, | |
75 { src: `()=>{ return 1, 2, 3, continue f() , 4 ; }`, | |
76 err: ` ^^^^^^^^^^^^^`, | |
77 }, | |
78 { src: `()=>{ var x = continue f ( ) ; }`, | |
79 err: ` ^^^^^^^^^^^^^^^`, | |
80 }, | |
81 { src: `()=>{ return continue f () ? 1 : 2 ; }`, | |
82 err: ` ^^^^^^^^^^^^^`, | |
83 }, | |
84 { src: `()=>{ return (1, 2, 3, continue f()), 4; }`, | |
85 err: ` ^^^^^^^^^^^^`, | |
86 }, | |
87 { src: `()=>{ return [1, 2, continue f() ] ; }`, | |
88 err: ` ^^^^^^^^^^^^`, | |
89 }, | |
90 { src: `()=>{ return [1, 2, ... continue f() ] ; }`, | |
91 err: ` ^^^^^^^^^^^^`, | |
92 }, | |
93 { src: `()=>{ return [1, 2, continue f(), 3 ] ; }`, | |
94 err: ` ^^^^^^^^^^^^`, | |
95 }, | |
96 { src: "()=>{ return `123 ${a} ${ continue foo ( ) } 34lk` ; }", | |
97 err: ` ^^^^^^^^^^^^^^^^`, | |
98 }, | |
99 { src: `()=>{ return g( 1, 2, continue f() ); }`, | |
100 err: ` ^^^^^^^^^^^^`, | |
101 }, | |
102 { src: `()=>{ return continue f() || a; }`, | |
103 err: ` ^^^^^^^^^^^^`, | |
104 }, | |
105 { src: `()=>{ return continue foo() instanceof bar ; }`, | |
106 err: ` ^^^^^^^^^^^^^^`, | |
107 }, | |
108 { src: `()=>{ return bar instanceof continue foo() ; }`, | |
109 err: ` ^^^^^^^^^^^^^^`, | |
110 }, | |
111 { src: `()=>{ return continue foo() in bar ; }`, | |
112 err: ` ^^^^^^^^^^^^^^`, | |
113 }, | |
114 { src: `()=>{ return bar in continue foo() ; }`, | |
115 err: ` ^^^^^^^^^^^^^^`, | |
116 }, | |
117 { src: `()=>{ function* G() { yield continue foo(); } }`, | |
118 err: ` ^^^^^^^^^^^^^^`, | |
119 }, | |
120 { src: `()=>{ (1, 2, 3, continue f() ) => {} }`, | |
121 err: ` ^^^^^^^^^^^^`, | |
122 }, | |
123 { src: `()=>{ (... continue f()) => {} }`, | |
124 err: ` ^^^^^^^^^^^^`, | |
125 }, | |
126 { src: `()=>{ (a, b, c, ... continue f() ) => {} }`, | |
127 err: ` ^^^^^^^^^^^^`, | |
128 }, | |
129 { src: `()=>{ return a <= continue f(); }`, | |
130 err: ` ^^^^^^^^^^^^`, | |
131 }, | |
132 { src: `()=>{ return b > continue f(); }`, | |
133 err: ` ^^^^^^^^^^^^`, | |
134 }, | |
135 { src: `()=>{ return a << continue f(); }`, | |
136 err: ` ^^^^^^^^^^^^`, | |
137 }, | |
138 { src: `()=>{ return b >> continue f(); }`, | |
139 err: ` ^^^^^^^^^^^^`, | |
140 }, | |
141 { src: `()=>{ return c >>> continue f(); }`, | |
142 err: ` ^^^^^^^^^^^^`, | |
143 }, | |
144 { src: `()=>{ return continue f() = a ; }`, | |
145 err: ` ^^^^^^^^^^^^`, | |
146 }, | |
147 { src: `()=>{ return a = continue f() ; }`, | |
148 err: ` ^^^^^^^^^^^^`, | |
149 }, | |
150 { src: `()=>{ return a += continue f(); }`, | |
151 err: ` ^^^^^^^^^^^^`, | |
152 }, | |
153 { src: `()=>{ return a ** continue f() ; }`, | |
154 err: ` ^^^^^^^^^^^^`, | |
155 }, | |
156 { src: `()=>{ return delete continue foo() ; }`, | |
157 err: ` ^^^^^^^^^^^^^^`, | |
158 }, | |
159 { src: `()=>{ typeof continue foo() ; }`, | |
160 err: ` ^^^^^^^^^^^^^^`, | |
161 }, | |
162 { src: `()=>{ return ~ continue foo() ; }`, | |
163 err: ` ^^^^^^^^^^^^^^`, | |
164 }, | |
165 { src: `()=>{ return void continue foo() ; }`, | |
166 err: ` ^^^^^^^^^^^^^^`, | |
167 }, | |
168 { src: `()=>{ return !continue foo() ; }`, | |
169 err: ` ^^^^^^^^^^^^^^`, | |
170 }, | |
171 { src: `()=>{ return -continue foo() ; }`, | |
172 err: ` ^^^^^^^^^^^^^^`, | |
173 }, | |
174 { src: `()=>{ return +continue foo() ; }`, | |
175 err: ` ^^^^^^^^^^^^^^`, | |
176 }, | |
177 { src: `()=>{ return ++ continue f( ) ; }`, | |
178 err: ` ^^^^^^^^^^^^^`, | |
179 }, | |
180 { src: `()=>{ return continue f() ++; }`, | |
181 err: ` ^^^^^^^^^^^^`, | |
182 }, | |
183 { src: `()=>{ return continue f() --; }`, | |
184 err: ` ^^^^^^^^^^^^`, | |
185 }, | |
186 { src: `()=>{ return (continue foo()) () ; }`, | |
187 err: ` ^^^^^^^^^^^^^^`, | |
188 }, | |
189 { src: `()=>{ for (var i = continue foo(); i < 10; i++) bar(); }`, | |
190 err: ` ^^^^^^^^^^^^^^`, | |
191 }, | |
192 { src: `()=>{ for (var i = 0; i < continue foo(); i++) bar(); }`, | |
193 err: ` ^^^^^^^^^^^^^^`, | |
194 }, | |
195 { src: `()=>{ for (var i = 0; i < 10; continue foo()) bar(); }`, | |
196 err: ` ^^^^^^^^^^^^^^`, | |
197 }, | |
198 { src: `()=>{ if (continue foo()) bar(); }`, | |
199 err: ` ^^^^^^^^^^^^^^`, | |
200 }, | |
201 { src: `()=>{ while (continue foo()) bar(); }`, | |
202 err: ` ^^^^^^^^^^^^^^`, | |
203 }, | |
204 { src: `()=>{ do { smth; } while (continue foo()) ; }`, | |
205 err: ` ^^^^^^^^^^^^^^`, | |
206 }, | |
207 { src: `()=>{ throw continue foo() ; }`, | |
208 err: ` ^^^^^^^^^^^^^^`, | |
209 }, | |
210 { src: `()=>{ switch (continue foo()) { case 1: break; } ; }`, | |
211 err: ` ^^^^^^^^^^^^^^`, | |
212 }, | |
213 { src: `()=>{ with (continue foo()) { smth; } }`, | |
214 err: ` ^^^^^^^^^^^^^^`, | |
215 }, | |
216 { src: `()=>{ let x = continue foo() }`, | |
217 err: ` ^^^^^^^^^^^^^^`, | |
218 }, | |
219 { src: `()=>{ const c = continue foo() }`, | |
220 err: ` ^^^^^^^^^^^^^^^`, | |
221 }, | |
222 { src: `class A {}; class B extends A { constructor() { return continue su per () ; } }`, | |
223 err: ` ^^^^^^^^^^^ ^^^^^^`, | |
224 }, | |
225 { src: `class A extends continue f () {}; }`, | |
226 err: ` ^^^^^^^^^^^^^`, | |
227 }, | |
228 ], | |
229 }, | |
230 { msg: "Tail call expression in try block", | |
231 tests: [ | |
232 { src: `()=>{ try { return continue f ( ) ; } catch(e) {} }`, | |
233 err: ` ^^^^^^^^^^^^^^^^`, | |
234 }, | |
235 { src: `()=>{ try { try { smth; } catch(e) { return continue f( ) ; } }` , | |
236 err: ` ^^^^^^^^^^^^^^`, | |
237 }, | |
238 { src: `()=>{ try { try { smth; } catch(e) { return continue f( ) ; } } finally { bla; } }`, | |
239 err: ` ^^^^^^^^^^^^^^`, | |
240 }, | |
241 ], | |
242 }, | |
243 { msg: "Tail call expression in catch block when finally block is also present ", | |
244 tests: [ | |
245 { src: `()=>{ try { smth; } catch(e) { return continue f ( ) ; } finall y { blah; } }`, | |
246 err: ` ^^^^^^^^^^^^^^^^`, | |
247 }, | |
248 { src: `()=>{ try { smth; } catch(e) { try { smth; } catch (e) { return c ontinue f ( ) ; } } finally { blah; } }`, | |
249 err: ` ^ ^^^^^^^^^^^^^^^`, | |
250 }, | |
251 ], | |
252 }, | |
253 { msg: "Tail call expression in for-in/of body", | |
254 tests: [ | |
255 { src: `()=>{ for (var v in {a:0}) { return continue foo () ; } }`, | |
256 err: ` ^^^^^^^^^^^^^^^^`, | |
257 }, | |
258 { src: `()=>{ for (var v of [1, 2, 3]) { return continue foo () ; } }`, | |
259 err: ` ^^^^^^^^^^^^^^^^`, | |
260 }, | |
261 ], | |
262 }, | |
263 { msg: "Undefined label 'foo'", | |
264 tests: [ | |
265 { src: `()=>{ continue foo () ; }`, | |
266 err: ` ^^^`, | |
267 }, | |
268 ], | |
269 }, | |
270 ]; | |
271 | |
272 | |
273 // Should parse successfully. | |
274 var NoErrorTests = [ | |
275 `()=>{ return continue a.b.c.foo () ; }`, | |
276 `()=>{ return continue a().b.c().d.foo () ; }`, | |
277 `()=>{ return continue foo (1)(2)(3, 4) ; }`, | |
278 `()=>{ return ( continue b() ) ; }`, | |
279 "()=>{ return continue bar`ab cd ef` ; }", | |
280 "()=>{ return continue bar`ab ${cd} ef` ; }", | |
281 `()=>{ return a || continue f() ; }`, | |
282 `()=>{ return a && continue f() ; }`, | |
283 `()=>{ return a , continue f() ; }`, | |
284 `()=>{ function* G() { return continue foo(); } }`, | |
285 `()=>{ class A { foo() { return continue super.f() ; } } }`, | |
286 `()=>{ function B() { return continue new.target() ; } }`, | |
287 `()=>{ return continue do { x ? foo() : bar() ; }() }`, | |
rossberg
2016/05/04 10:45:30
Wait, why is this legal? A do expression shouldn't
Igor Sheludko
2016/05/04 11:50:14
Because it's actually a
return continue (do {...
| |
288 `()=>{ return do { 1, continue foo() } }`, | |
289 `()=>{ return do { x ? continue foo() : y } }`, | |
290 `()=> continue (foo ()) ;`, | |
291 `()=> a || continue foo () ;`, | |
292 `()=> a && continue foo () ;`, | |
293 `()=> a ? continue foo () : b;`, | |
294 ]; | |
295 | |
296 | |
297 (function() { | |
298 for (test_set of SyntaxErrorTests) { | |
299 var expected_message = "SyntaxError: " + test_set.msg; | |
300 for (test of test_set.tests) { | |
301 var passed = true; | |
302 var e = null; | |
303 try { | |
304 Realm.eval(0, test.src); | |
305 } catch (ee) { | |
306 e = ee; | |
307 } | |
308 print("======================================="); | |
309 print("Expected | " + expected_message); | |
310 print("Source | " + test.src); | |
311 print(" | " + test.err); | |
312 | |
313 if (e === null) { | |
314 print("FAILED"); | |
315 throw new Error("SyntaxError was not thrown"); | |
316 } | |
317 | |
318 var details = %GetMessageFromException(e); | |
319 if (details.start_pos == undefined || | |
320 details.end_pos == undefined) { | |
321 throw new Error("Bad message object returned"); | |
322 } | |
323 var underline = " ".repeat(details.start_pos) + | |
324 "^".repeat(details.end_pos - details.start_pos); | |
325 var passed = expected_message === e.toString() && | |
326 test.err === underline; | |
327 | |
328 if (passed) { | |
329 print("PASSED"); | |
330 print(); | |
331 } else { | |
332 print("---------------------------------------"); | |
333 print("Actual | " + e); | |
334 print("Source | " + test.src); | |
335 print(" | " + underline); | |
336 print("FAILED"); | |
337 throw new Error("Test failed"); | |
338 } | |
339 } | |
340 } | |
341 })(); | |
342 | |
343 | |
344 (function() { | |
345 for (src of NoErrorTests) { | |
346 print("======================================="); | |
347 print("Source | " + src); | |
348 Realm.eval(0, src); | |
349 print("PASSED"); | |
350 print(); | |
351 } | |
352 })(); | |
OLD | NEW |