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