• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
8var 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: `class A {}; class B extends A { constructor() { return continue foo () ; } }`,
64        err: `                                                       ^^^^^^^^^^^^^^^`,
65      },
66      { src: `class A extends continue f () {}; }`,
67        err: `                ^^^^^^^^^^^^^`,
68      },
69    ],
70  },
71  { msg: "Tail call expressions are not allowed in non-strict mode",
72    tests: [
73      { src: `()=>{ return  continue continue continue b()  ; }`,
74        err: `                                ^^^^^^^^^^^^`,
75      },
76      { src: `()=>{ return  continue ( continue b() ) ; }`,
77        err: `                         ^^^^^^^^^^^^`,
78      },
79      { src: `()=>{ return   continue  f()   - a ; }`,
80        err: `               ^^^^^^^^^^^^^`,
81      },
82      { src: `()=>{ return b + continue   f()  ; }`,
83        err: `                 ^^^^^^^^^^^^^^`,
84      },
85      { src: `()=>{ return 1, 2, 3,   continue  f() , 4  ; }`,
86        err: `                        ^^^^^^^^^^^^^`,
87      },
88      { src: `()=>{ var x =  continue  f ( ) ; }`,
89        err: `               ^^^^^^^^^^^^^^^`,
90      },
91      { src: `()=>{ return   continue f () ? 1 : 2 ; }`,
92        err: `               ^^^^^^^^^^^^^`,
93      },
94      { src: `()=>{ return (1, 2, 3, continue f()), 4; }`,
95        err: `                       ^^^^^^^^^^^^`,
96      },
97      { src: `()=>{ return [1, 2, continue f() ] ;  }`,
98        err: `                    ^^^^^^^^^^^^`,
99      },
100      { src: `()=>{ return [1, 2, ... continue f() ] ;  }`,
101        err: `                        ^^^^^^^^^^^^`,
102      },
103      { src: `()=>{ return [1, 2, continue f(), 3 ] ;  }`,
104        err: `                    ^^^^^^^^^^^^`,
105      },
106      { src: "()=>{ return `123 ${a} ${ continue foo ( ) } 34lk` ;  }",
107        err: `                          ^^^^^^^^^^^^^^^^`,
108      },
109      { src: `()=>{ return g( 1, 2, continue f() ); }`,
110        err: `                      ^^^^^^^^^^^^`,
111      },
112      { src: `()=>{ return continue f() || a; }`,
113        err: `             ^^^^^^^^^^^^`,
114      },
115      { src: `()=>{ return a || b || c || continue f() || d; }`,
116        err: `                            ^^^^^^^^^^^^`,
117      },
118      { src: `()=>{ return a && b && c && continue f() && d; }`,
119        err: `                            ^^^^^^^^^^^^`,
120      },
121      { src: `()=>{ return a && b || c && continue f() ? d : e; }`,
122        err: `                            ^^^^^^^^^^^^`,
123      },
124      { src: `()=>{ return a ? b : c && continue f() && d || e; }`,
125        err: `                          ^^^^^^^^^^^^`,
126      },
127      { src: `()=>{ return continue foo() instanceof bar ; }`,
128        err: `             ^^^^^^^^^^^^^^`,
129      },
130      { src: `()=>{ return bar instanceof continue foo() ; }`,
131        err: `                            ^^^^^^^^^^^^^^`,
132      },
133      { src: `()=>{ return continue foo() in bar ; }`,
134        err: `             ^^^^^^^^^^^^^^`,
135      },
136      { src: `()=>{ return bar in continue foo() ; }`,
137        err: `                    ^^^^^^^^^^^^^^`,
138      },
139      { src: `()=>{ function* G() { yield continue foo(); } }`,
140        err: `                            ^^^^^^^^^^^^^^`,
141      },
142      { src: `()=>{ (1, 2, 3, continue f() ) => {} }`,
143        err: `                ^^^^^^^^^^^^`,
144      },
145      { src: `()=>{ (... continue f()) => {}  }`,
146        err: `           ^^^^^^^^^^^^`,
147      },
148      { src: `()=>{ (a, b, c, ... continue f() ) => {}  }`,
149        err: `                    ^^^^^^^^^^^^`,
150      },
151      { src: `()=>{ return a <= continue f(); }`,
152        err: `                  ^^^^^^^^^^^^`,
153      },
154      { src: `()=>{ return b > continue f(); }`,
155        err: `                 ^^^^^^^^^^^^`,
156      },
157      { src: `()=>{ return a << continue f(); }`,
158        err: `                  ^^^^^^^^^^^^`,
159      },
160      { src: `()=>{ return b >> continue f(); }`,
161        err: `                  ^^^^^^^^^^^^`,
162      },
163      { src: `()=>{ return c >>> continue f(); }`,
164        err: `                   ^^^^^^^^^^^^`,
165      },
166      { src: `()=>{ return continue f() = a ; }`,
167        err: `             ^^^^^^^^^^^^`,
168      },
169      { src: `()=>{ return a = continue f() ; }`,
170        err: `                 ^^^^^^^^^^^^`,
171      },
172      { src: `()=>{ return a += continue f(); }`,
173        err: `                  ^^^^^^^^^^^^`,
174      },
175      { src: `()=>{ return a ** continue f() ; }`,
176        err: `                  ^^^^^^^^^^^^`,
177      },
178      { src: `()=>{ return delete continue foo() ; }`,
179        err: `                    ^^^^^^^^^^^^^^`,
180      },
181      { src: `()=>{ typeof continue foo()  ; }`,
182        err: `             ^^^^^^^^^^^^^^`,
183      },
184      { src: `()=>{ return ~ continue foo() ; }`,
185        err: `               ^^^^^^^^^^^^^^`,
186      },
187      { src: `()=>{ return void  continue foo() ; }`,
188        err: `                   ^^^^^^^^^^^^^^`,
189      },
190      { src: `()=>{ return !continue foo() ; }`,
191        err: `              ^^^^^^^^^^^^^^`,
192      },
193      { src: `()=>{ return -continue foo() ; }`,
194        err: `              ^^^^^^^^^^^^^^`,
195      },
196      { src: `()=>{ return +continue foo() ; }`,
197        err: `              ^^^^^^^^^^^^^^`,
198      },
199      { src: `()=>{ return ++ continue f( ) ; }`,
200        err: `                ^^^^^^^^^^^^^`,
201      },
202      { src: `()=>{ return continue f()  ++; }`,
203        err: `             ^^^^^^^^^^^^`,
204      },
205      { src: `()=>{ return continue f() --; }`,
206        err: `             ^^^^^^^^^^^^`,
207      },
208      { src: `()=>{ return (continue foo()) () ;  }`,
209        err: `              ^^^^^^^^^^^^^^`,
210      },
211      { src: `()=>{ for (var i = continue foo(); i < 10; i++) bar(); }`,
212        err: `                   ^^^^^^^^^^^^^^`,
213      },
214      { src: `()=>{ for (var i = 0; i < continue foo(); i++) bar(); }`,
215        err: `                          ^^^^^^^^^^^^^^`,
216      },
217      { src: `()=>{ for (var i = 0; i < 10; continue foo()) bar(); }`,
218        err: `                              ^^^^^^^^^^^^^^`,
219      },
220      { src: `()=>{ if (continue foo()) bar(); }`,
221        err: `          ^^^^^^^^^^^^^^`,
222      },
223      { src: `()=>{ while (continue foo()) bar(); }`,
224        err: `             ^^^^^^^^^^^^^^`,
225      },
226      { src: `()=>{ do { smth; } while (continue foo()) ; }`,
227        err: `                          ^^^^^^^^^^^^^^`,
228      },
229      { src: `()=>{ throw continue foo() ; }`,
230        err: `            ^^^^^^^^^^^^^^`,
231      },
232      { src: `()=>{ switch (continue foo()) { case 1: break; } ; }`,
233        err: `              ^^^^^^^^^^^^^^`,
234      },
235      { src: `()=>{ with (continue foo()) { smth; } }`,
236        err: `            ^^^^^^^^^^^^^^`,
237      },
238      { src: `()=>{ let x = continue foo() }`,
239        err: `              ^^^^^^^^^^^^^^`,
240      },
241      { src: `()=>{ const c = continue  foo() }`,
242        err: `                ^^^^^^^^^^^^^^^`,
243      },
244      { src: `()=>{ try { return  continue   f ( ) ; } catch(e) {} }`,
245        err: `                    ^^^^^^^^^^^^^^^^`,
246      },
247      { src: `()=>{ try { try { smth; } catch(e) { return  continue  f( ) ; } }`,
248        err: `                                             ^^^^^^^^^^^^^^`,
249      },
250      { src: `()=>{ try { try { smth; } catch(e) { return  continue  f( ) ; } } finally { bla; } }`,
251        err: `                                             ^^^^^^^^^^^^^^`,
252      },
253      { src: `()=>{ try { smth; } catch(e) { return  continue   f ( ) ; } finally { blah; } }`,
254        err: `                                       ^^^^^^^^^^^^^^^^`,
255      },
256      { src: `()=>{ try { smth; } catch(e) { try { smth; } catch (e) { return  continue   f ( ) ; } } finally { blah; } }`,
257        err: `                                                                 ^^^^^^^^^^^^^^^^`,
258      },
259      { src: `()=>{ for (var v in {a:0}) { return continue  foo () ; } }`,
260        err: `                                    ^^^^^^^^^^^^^^^^`,
261      },
262      { src: `()=>{ for (var v of [1, 2, 3]) { return continue  foo () ; } }`,
263        err: `                                        ^^^^^^^^^^^^^^^^`,
264      },
265      { src: `()=>{ return continue  a.b.c.foo () ; }`,
266        err: `             ^^^^^^^^^^^^^^^^^^^^^^`,
267      },
268      { src: `()=>{ return continue  a().b.c().d.foo () ; }`,
269        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^`,
270      },
271      { src: `()=>{ return continue  foo (1)(2)(3, 4) ; }`,
272        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^^`,
273      },
274      { src: `()=>{ return ( continue b() ) ; }`,
275        err: `               ^^^^^^^^^^^^`,
276      },
277      { src: "()=>{ return continue bar`ab cd ef` ; }",
278        err: `             ^^^^^^^^^^^^^^^^^^^^^^`,
279      },
280      { src: "()=>{ return continue bar`ab ${cd} ef` ; }",
281        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^`,
282      },
283      { src: `()=>{ return a || continue f() ; }`,
284        err: `                  ^^^^^^^^^^^^`,
285      },
286      { src: `()=>{ return a && continue f() ; }`,
287        err: `                  ^^^^^^^^^^^^`,
288      },
289      { src: `()=>{ return a , continue f() ; }`,
290        err: `                 ^^^^^^^^^^^^`,
291      },
292      { src: `()=>{ function* G() { return continue foo(); } }`,
293        err: `                             ^^^^^^^^^^^^^^`,
294      },
295      { src: `()=>{ function B() { return continue new.target() ; } }`,
296        err: `                            ^^^^^^^^^^^^^^^^^^^^^`,
297      },
298      { src: `()=>{ return continue do { x ? foo() : bar() ; }() }`,
299        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^`,
300      },
301      { src: `()=>{ return continue (do { x ? foo() : bar() ; })() }`,
302        err: `             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^`,
303      },
304      { src: `()=>{ return do { 1, continue foo() } }`,
305        err: `                     ^^^^^^^^^^^^^^`,
306      },
307      { src: `()=>{ return do { x ? continue foo() : y } }`,
308        err: `                      ^^^^^^^^^^^^^^`,
309      },
310      { src: `()=>{ return a || (b && continue c()); }`,
311        err: `                        ^^^^^^^^^^^^`,
312      },
313      { src: `()=>{ return a && (b || continue c()); }`,
314        err: `                        ^^^^^^^^^^^^`,
315      },
316      { src: `()=>{ return a || (b ? c : continue d()); }`,
317        err: `                           ^^^^^^^^^^^^`,
318      },
319      { src: `()=>{ return 1, 2, 3, a || (b ? c : continue d()); }`,
320        err: `                                    ^^^^^^^^^^^^`,
321      },
322      { src: `()=> continue  (foo ()) ;`,
323        err: `     ^^^^^^^^^^^^^^^^^^`,
324      },
325      { src: `()=> a || continue  foo () ;`,
326        err: `          ^^^^^^^^^^^^^^^^`,
327      },
328      { src: `()=> a && continue  foo () ;`,
329        err: `          ^^^^^^^^^^^^^^^^`,
330      },
331      { src: `()=> a ? continue  foo () : b;`,
332        err: `         ^^^^^^^^^^^^^^^^`,
333      },
334    ],
335  },
336  { msg: "Undefined label 'foo'",
337    tests: [
338      { src: `()=>{ continue  foo () ; }`,
339        err: `                ^^^`,
340      },
341    ],
342  },
343];
344
345
346// Should parse successfully.
347var NoErrorTests = [
348  `()=>{ class A { foo() { return continue super.f() ; } } }`,
349  `()=>{ class A { foo() { return continue f() ; } } }`,
350  `()=>{ class A { foo() { return a || continue f() ; } } }`,
351  `()=>{ class A { foo() { return b && continue f() ; } } }`,
352];
353
354
355(function() {
356  for (var test_set of SyntaxErrorTests) {
357    var expected_message = "SyntaxError: " + test_set.msg;
358    for (var test of test_set.tests) {
359      var passed = true;
360      var e = null;
361      try {
362        Realm.eval(0, test.src);
363      } catch (ee) {
364        e = ee;
365      }
366      print("=======================================");
367      print("Expected | " + expected_message);
368      print("Source   | " + test.src);
369      print("         | " + test.err);
370
371      if (e === null) {
372        print("FAILED");
373        throw new Error("SyntaxError was not thrown");
374      }
375
376      var details = %GetExceptionDetails(e);
377      if (details.start_pos == undefined ||
378          details.end_pos == undefined) {
379        throw new Error("Bad message object returned");
380      }
381      var underline = " ".repeat(details.start_pos) +
382                      "^".repeat(details.end_pos - details.start_pos);
383      var passed = expected_message === e.toString() &&
384                   test.err === underline;
385
386      if (passed) {
387        print("PASSED");
388        print();
389      } else {
390        print("---------------------------------------");
391        print("Actual   | " + e);
392        print("Source   | " + test.src);
393        print("         | " + underline);
394        print("FAILED");
395        throw new Error("Test failed");
396      }
397    }
398  }
399})();
400
401
402(function() {
403  for (var src of NoErrorTests) {
404    print("=======================================");
405    print("Source   | " + src);
406    Realm.eval(0, src);
407    print("PASSED");
408    print();
409  }
410})();
411