github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/parser/parser_test.go (about) 1 package parser 2 3 import ( 4 "errors" 5 "regexp" 6 "strings" 7 "testing" 8 9 "github.com/nuvolaris/goja/ast" 10 "github.com/nuvolaris/goja/file" 11 "github.com/nuvolaris/goja/token" 12 "github.com/nuvolaris/goja/unistring" 13 ) 14 15 func firstErr(err error) error { 16 switch err := err.(type) { 17 case ErrorList: 18 return err[0] 19 } 20 return err 21 } 22 23 var matchBeforeAfterSeparator = regexp.MustCompile(`(?m)^[ \t]*---$`) 24 25 func testParse(src string) (parser *_parser, program *ast.Program, err error) { 26 defer func() { 27 if tmp := recover(); tmp != nil { 28 switch tmp := tmp.(type) { 29 case string: 30 if strings.HasPrefix(tmp, "SyntaxError:") { 31 parser = nil 32 program = nil 33 err = errors.New(tmp) 34 return 35 } 36 } 37 panic(tmp) 38 } 39 }() 40 parser = newParser("", src) 41 program, err = parser.parse() 42 return 43 } 44 45 func TestParseFile(t *testing.T) { 46 tt(t, func() { 47 _, err := ParseFile(nil, "", `/abc/`, 0) 48 is(err, nil) 49 50 _, err = ParseFile(nil, "", `/(?!def)abc/`, IgnoreRegExpErrors) 51 is(err, nil) 52 53 _, err = ParseFile(nil, "", `/(?!def)abc/; return`, IgnoreRegExpErrors) 54 is(err, "(anonymous): Line 1:15 Illegal return statement") 55 }) 56 } 57 58 func TestParseFunction(t *testing.T) { 59 tt(t, func() { 60 test := func(prm, bdy string, expect interface{}) *ast.FunctionLiteral { 61 function, err := ParseFunction(prm, bdy) 62 is(firstErr(err), expect) 63 return function 64 } 65 66 test("a, b,c,d", "", nil) 67 68 test("a, b;,c,d", "", "(anonymous): Line 1:15 Unexpected token ;") 69 70 test("this", "", "(anonymous): Line 1:11 Unexpected token this") 71 72 test("a, b, c, null", "", "(anonymous): Line 1:20 Unexpected token null") 73 74 test("a, b,c,d", "return;", nil) 75 76 test("a, b,c,d", "break;", "(anonymous): Line 2:1 Illegal break statement") 77 78 test("a, b,c,d", "{}", nil) 79 }) 80 } 81 82 func TestParserErr(t *testing.T) { 83 tt(t, func() { 84 test := func(input string, expect interface{}) (*ast.Program, *_parser) { 85 parser := newParser("", input) 86 program, err := parser.parse() 87 is(firstErr(err), expect) 88 return program, parser 89 } 90 91 test("", nil) 92 93 program, parser := test(` 94 var abc; 95 break; do { 96 } while(true); 97 `, "(anonymous): Line 3:9 Illegal break statement") 98 { 99 stmt := program.Body[1].(*ast.BadStatement) 100 is(parser.position(stmt.From).Column, 9) 101 is(parser.position(stmt.To).Column, 16) 102 is(parser.slice(stmt.From, stmt.To), "break; ") 103 } 104 105 s := string([]byte{0x22, 0x25, 0x21, 0x63, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x25, 0x63, 0x25, 0x9c, 0x29, 0x25, 0x21, 0x5c, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x5c, 0xe2, 0x80, 0xa9, 0x29, 0x78, 0x39, 0x63, 0x22}) 106 test(s, `(anonymous): Line 1:16 Invalid UTF-8 character`) 107 108 test("{", "(anonymous): Line 1:2 Unexpected end of input") 109 110 test("}", "(anonymous): Line 1:1 Unexpected token }") 111 112 test("3ea", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 113 114 test("3in", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 115 116 test("3in []", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 117 118 test("3e", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 119 120 test("3e+", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 121 122 test("3e-", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 123 124 test("3x", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 125 126 test("3x0", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 127 128 test("0x", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 129 130 test("09", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 131 132 test("018", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 133 134 test("01.0", "(anonymous): Line 1:3 Unexpected number") 135 136 test(".0.9", "(anonymous): Line 1:3 Unexpected number") 137 138 test("0o3e1", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 139 140 test("01a", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 141 142 test("0x3in[]", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 143 144 test("\"Hello\nWorld\"", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 145 146 test("\u203f = 10", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 147 148 test("x\\", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 149 150 test("x\\\\", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 151 152 test("x\\u005c", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 153 154 test("x\\u002a", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 155 156 test("x\\\\u002a", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 157 158 test("/\n", "(anonymous): Line 1:1 Invalid regular expression: missing /") 159 160 test("0 = 1", "(anonymous): Line 1:1 Invalid left-hand side in assignment") 161 162 test("func() = 1", "(anonymous): Line 1:1 Invalid left-hand side in assignment") 163 164 test("(1 + 1) = 2", "(anonymous): Line 1:2 Invalid left-hand side in assignment") 165 166 test("1++", "(anonymous): Line 1:2 Invalid left-hand side in assignment") 167 168 test("1--", "(anonymous): Line 1:2 Invalid left-hand side in assignment") 169 170 test("--1", "(anonymous): Line 1:1 Invalid left-hand side in assignment") 171 172 test("for((1 + 1) in abc) def();", "(anonymous): Line 1:1 Invalid left-hand side in for-in or for-of") 173 174 test("[", "(anonymous): Line 1:2 Unexpected end of input") 175 176 test("[,", "(anonymous): Line 1:3 Unexpected end of input") 177 178 test("1 + {", "(anonymous): Line 1:6 Unexpected end of input") 179 180 test("1 + { abc:abc", "(anonymous): Line 1:14 Unexpected end of input") 181 182 test("1 + { abc:abc,", "(anonymous): Line 1:15 Unexpected end of input") 183 184 test("var abc = /\n/", "(anonymous): Line 1:11 Invalid regular expression: missing /") 185 186 test("var abc = \"\n", "(anonymous): Line 1:11 Unexpected token ILLEGAL") 187 188 test("var if = 0", "(anonymous): Line 1:5 Unexpected token if") 189 190 test("abc + 0 = 1", "(anonymous): Line 1:1 Invalid left-hand side in assignment") 191 192 test("+abc = 1", "(anonymous): Line 1:1 Invalid left-hand side in assignment") 193 194 test("1 + (", "(anonymous): Line 1:6 Unexpected end of input") 195 196 test("\n\n\n{", "(anonymous): Line 4:2 Unexpected end of input") 197 198 test("\n/* Some multiline\ncomment */\n)", "(anonymous): Line 4:1 Unexpected token )") 199 200 test("+1 ** 2", "(anonymous): Line 1:4 Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence") 201 test("typeof 1 ** 2", "(anonymous): Line 1:10 Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence") 202 203 // TODO 204 //{ set 1 } 205 //{ get 2 } 206 //({ set: s(if) { } }) 207 //({ set s(.) { } }) 208 //({ set: s() { } }) 209 //({ set: s(a, b) { } }) 210 //({ get: g(d) { } }) 211 //({ get i() { }, i: 42 }) 212 //({ i: 42, get i() { } }) 213 //({ set i(x) { }, i: 42 }) 214 //({ i: 42, set i(x) { } }) 215 //({ get i() { }, get i() { } }) 216 //({ set i(x) { }, set i(x) { } }) 217 218 test("function abc(if) {}", "(anonymous): Line 1:14 Unexpected token if") 219 220 test("function abc(true) {}", "(anonymous): Line 1:14 Unexpected token true") 221 222 test("function abc(false) {}", "(anonymous): Line 1:14 Unexpected token false") 223 224 test("function abc(null) {}", "(anonymous): Line 1:14 Unexpected token null") 225 226 test("function null() {}", "(anonymous): Line 1:10 Unexpected token null") 227 228 test("function true() {}", "(anonymous): Line 1:10 Unexpected token true") 229 230 test("function false() {}", "(anonymous): Line 1:10 Unexpected token false") 231 232 test("function if() {}", "(anonymous): Line 1:10 Unexpected token if") 233 234 test("a b;", "(anonymous): Line 1:3 Unexpected identifier") 235 236 test("if.a", "(anonymous): Line 1:3 Unexpected token .") 237 238 test("a if", "(anonymous): Line 1:3 Unexpected token if") 239 240 test("a class", "(anonymous): Line 1:3 Unexpected token class") 241 242 test("break\n", "(anonymous): Line 1:1 Illegal break statement") 243 244 test("break 1;", "(anonymous): Line 1:7 Unexpected number") 245 246 test("for (;;) { break 1; }", "(anonymous): Line 1:18 Unexpected number") 247 248 test("continue\n", "(anonymous): Line 1:1 Illegal continue statement") 249 250 test("continue 1;", "(anonymous): Line 1:10 Unexpected number") 251 252 test("for (;;) { continue 1; }", "(anonymous): Line 1:21 Unexpected number") 253 254 test("throw", "(anonymous): Line 1:1 Unexpected end of input") 255 256 test("throw;", "(anonymous): Line 1:6 Unexpected token ;") 257 258 test("throw \n", "(anonymous): Line 1:1 Unexpected end of input") 259 260 test("for (var abc, def in {});", "(anonymous): Line 1:19 Unexpected token in") 261 262 test("for ((abc in {});;);", nil) 263 264 test("for ((abc in {}));", "(anonymous): Line 1:17 Unexpected token )") 265 266 test("for (+abc in {});", "(anonymous): Line 1:1 Invalid left-hand side in for-in or for-of") 267 268 test("if (false)", "(anonymous): Line 1:11 Unexpected end of input") 269 270 test("if (false) abc(); else", "(anonymous): Line 1:23 Unexpected end of input") 271 272 test("do", "(anonymous): Line 1:3 Unexpected end of input") 273 274 test("while (false)", "(anonymous): Line 1:14 Unexpected end of input") 275 276 test("for (;;)", "(anonymous): Line 1:9 Unexpected end of input") 277 278 test("with (abc)", "(anonymous): Line 1:11 Unexpected end of input") 279 280 test("try {}", "(anonymous): Line 1:1 Missing catch or finally after try") 281 282 test("try {} catch () {}", "(anonymous): Line 1:15 Unexpected token )") 283 284 test("\u203f = 1", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 285 286 // TODO 287 // const x = 12, y; 288 // const x, y = 12; 289 // const x; 290 // if(true) let a = 1; 291 // if(true) const a = 1; 292 293 test(`new abc()."def"`, "(anonymous): Line 1:11 Unexpected string") 294 295 test("/*", "(anonymous): Line 1:3 Unexpected end of input") 296 297 test("/**", "(anonymous): Line 1:4 Unexpected end of input") 298 299 test("/*\n\n\n", "(anonymous): Line 4:1 Unexpected end of input") 300 301 test("/*\n\n\n*", "(anonymous): Line 4:2 Unexpected end of input") 302 303 test("/*abc", "(anonymous): Line 1:6 Unexpected end of input") 304 305 test("/*abc *", "(anonymous): Line 1:9 Unexpected end of input") 306 307 test("\n]", "(anonymous): Line 2:1 Unexpected token ]") 308 309 test("\r\n]", "(anonymous): Line 2:1 Unexpected token ]") 310 311 test("\n\r]", "(anonymous): Line 3:1 Unexpected token ]") 312 313 test("//\r\n]", "(anonymous): Line 2:1 Unexpected token ]") 314 315 test("//\n\r]", "(anonymous): Line 3:1 Unexpected token ]") 316 317 test("/abc\\\n/", "(anonymous): Line 1:1 Invalid regular expression: missing /") 318 319 test("//\r \n]", "(anonymous): Line 3:1 Unexpected token ]") 320 321 test("/*\r\n*/]", "(anonymous): Line 2:3 Unexpected token ]") 322 323 test("/*\r \n*/]", "(anonymous): Line 3:3 Unexpected token ]") 324 325 test("\\\\", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 326 327 test("\\u005c", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 328 329 test("\\abc", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 330 331 test("\\u0000", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 332 333 test("\\u200c = []", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 334 335 test("\\u200D = []", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 336 337 test(`"\`, "(anonymous): Line 1:1 Unexpected token ILLEGAL") 338 339 test(`"\u`, "(anonymous): Line 1:1 Unexpected token ILLEGAL") 340 341 test("return", "(anonymous): Line 1:1 Illegal return statement") 342 343 test("continue", "(anonymous): Line 1:1 Illegal continue statement") 344 345 test("break", "(anonymous): Line 1:1 Illegal break statement") 346 347 test("switch (abc) { default: continue; }", "(anonymous): Line 1:25 Illegal continue statement") 348 349 test("do { abc } *", "(anonymous): Line 1:12 Unexpected token *") 350 351 test("while (true) { break abc; }", "(anonymous): Line 1:16 Undefined label 'abc'") 352 353 test("while (true) { continue abc; }", "(anonymous): Line 1:16 Undefined label 'abc'") 354 355 test("abc: while (true) { (function(){ break abc; }); }", "(anonymous): Line 1:34 Undefined label 'abc'") 356 357 test("abc: while (true) { (function(){ abc: break abc; }); }", nil) 358 359 test("abc: while (true) { (function(){ continue abc; }); }", "(anonymous): Line 1:34 Undefined label 'abc'") 360 361 test(`abc: if (0) break abc; else {}`, nil) 362 363 test(`abc: if (0) { break abc; } else {}`, nil) 364 365 test(`abc: if (0) { break abc } else {}`, nil) 366 367 test("abc: while (true) { abc: while (true) {} }", "(anonymous): Line 1:21 Label 'abc' already exists") 368 369 test(`if(0) { do { } while(0) } else { do { } while(0) }`, nil) 370 371 test(`if(0) do { } while(0); else do { } while(0)`, nil) 372 373 test("_: _: while (true) {]", "(anonymous): Line 1:4 Label '_' already exists") 374 375 test("_:\n_:\nwhile (true) {]", "(anonymous): Line 2:1 Label '_' already exists") 376 377 test("_:\n _:\nwhile (true) {]", "(anonymous): Line 2:4 Label '_' already exists") 378 379 test("function(){}", "(anonymous): Line 1:9 Unexpected token (") 380 381 test("\n/*/", "(anonymous): Line 2:4 Unexpected end of input") 382 383 test("/*/.source", "(anonymous): Line 1:11 Unexpected end of input") 384 385 test("var class", "(anonymous): Line 1:5 Unexpected token class") 386 387 test("var if", "(anonymous): Line 1:5 Unexpected token if") 388 389 test("object Object", "(anonymous): Line 1:8 Unexpected identifier") 390 391 test("[object Object]", "(anonymous): Line 1:9 Unexpected identifier") 392 393 test("\\u0xyz", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 394 395 test(`for (var abc, def in {}) {}`, "(anonymous): Line 1:19 Unexpected token in") 396 397 test(`for (abc, def in {}) {}`, "(anonymous): Line 1:1 Invalid left-hand side in for-in or for-of") 398 399 test(`for (var abc=def, ghi=("abc" in {}); true;) {}`, nil) 400 401 { 402 // Semicolon insertion 403 404 test("this\nif (1);", nil) 405 406 test("while (1) { break\nif (1); }", nil) 407 408 test("throw\nif (1);", "(anonymous): Line 1:1 Illegal newline after throw") 409 410 test("(function(){ return\nif (1); })", nil) 411 412 test("while (1) { continue\nif (1); }", nil) 413 414 test("debugger\nif (1);", nil) 415 } 416 417 { // Reserved words 418 419 test("class", "(anonymous): Line 1:6 Unexpected end of input") 420 test("abc.class = 1", nil) 421 test("var class;", "(anonymous): Line 1:5 Unexpected token class") 422 423 test("const", "(anonymous): Line 1:6 Unexpected end of input") 424 test("abc.const = 1", nil) 425 test("var const;", "(anonymous): Line 1:5 Unexpected token const") 426 427 test("enum", "(anonymous): Line 1:1 Unexpected reserved word") 428 test("abc.enum = 1", nil) 429 test("var enum;", "(anonymous): Line 1:5 Unexpected reserved word") 430 431 test("export", "(anonymous): Line 1:1 Unexpected reserved word") 432 test("abc.export = 1", nil) 433 test("var export;", "(anonymous): Line 1:5 Unexpected reserved word") 434 435 test("extends", "(anonymous): Line 1:1 Unexpected token extends") 436 test("abc.extends = 1", nil) 437 test("var extends;", "(anonymous): Line 1:5 Unexpected token extends") 438 439 test("import", "(anonymous): Line 1:1 Unexpected reserved word") 440 test("abc.import = 1", nil) 441 test("var import;", "(anonymous): Line 1:5 Unexpected reserved word") 442 443 test("super", "(anonymous): Line 1:1 'super' keyword unexpected here") 444 test("abc.super = 1", nil) 445 test("var super;", "(anonymous): Line 1:5 Unexpected token super") 446 test(` 447 obj = { 448 aaa: 1 449 bbb: "string" 450 };`, "(anonymous): Line 4:6 Unexpected identifier") 451 test("{}", nil) 452 test("{a: 1}", nil) 453 test("{a: 1,}", "(anonymous): Line 1:7 Unexpected token }") 454 test("{a: 1, b: 2}", "(anonymous): Line 1:9 Unexpected token :") 455 test("{a: 1, b: 2,}", "(anonymous): Line 1:9 Unexpected token :") 456 test(`let f = () => new import('');`, "(anonymous): Line 1:19 Unexpected reserved word") 457 458 } 459 460 { // Reserved words (strict) 461 462 test(`implements`, nil) 463 test(`abc.implements = 1`, nil) 464 test(`var implements;`, nil) 465 466 test(`interface`, nil) 467 test(`abc.interface = 1`, nil) 468 test(`var interface;`, nil) 469 470 test(`let`, nil) 471 test(`abc.let = 1`, nil) 472 test(`var let;`, nil) 473 474 test(`package`, nil) 475 test(`abc.package = 1`, nil) 476 test(`var package;`, nil) 477 478 test(`private`, nil) 479 test(`abc.private = 1`, nil) 480 test(`var private;`, nil) 481 482 test(`protected`, nil) 483 test(`abc.protected = 1`, nil) 484 test(`var protected;`, nil) 485 486 test(`public`, nil) 487 test(`abc.public = 1`, nil) 488 test(`var public;`, nil) 489 490 test(`static`, nil) 491 test(`abc.static = 1`, nil) 492 test(`var static;`, nil) 493 494 test(`yield`, nil) 495 test(`abc.yield = 1`, nil) 496 test(`var yield;`, nil) 497 } 498 test(`0, { get a(param = null) {} };`, "(anonymous): Line 1:11 Getter must not have any formal parameters.") 499 test(`let{f(`, "(anonymous): Line 1:7 Unexpected end of input") 500 test("`", "(anonymous): Line 1:2 Unexpected end of input") 501 test(" `", "(anonymous): Line 1:3 Unexpected end of input") 502 test("` ", "(anonymous): Line 1:3 Unexpected end of input") 503 test(`var{..(`, "(anonymous): Line 1:7 Unexpected token ILLEGAL") 504 test(`var{get..(`, "(anonymous): Line 1:10 Unexpected token ILLEGAL") 505 test(`var{set..(`, "(anonymous): Line 1:10 Unexpected token ILLEGAL") 506 test(`(0 ?? 0 || true)`, "(anonymous): Line 1:9 Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses") 507 test(`(a || b ?? c)`, "(anonymous): Line 1:9 Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses") 508 test(`2 ?? 2 && 3 + 3`, "(anonymous): Line 1:3 Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses") 509 test(` 510 class C { 511 st\u0061tic m() {} 512 } 513 `, "(anonymous): Line 3:25 Unexpected identifier") 514 }) 515 } 516 517 func TestParser(t *testing.T) { 518 tt(t, func() { 519 test := func(source string, chk interface{}) *ast.Program { 520 _, program, err := testParse(source) 521 is(firstErr(err), chk) 522 return program 523 } 524 test(`new (() => {});`, nil) 525 526 test(` 527 abc 528 -- 529 [] 530 `, "(anonymous): Line 3:13 Invalid left-hand side in assignment") 531 532 test(` 533 abc-- 534 [] 535 `, nil) 536 537 test("1\n[]\n", "(anonymous): Line 2:2 Unexpected token ]") 538 539 test(` 540 function abc() { 541 } 542 abc() 543 `, nil) 544 545 test("", nil) 546 547 test("//", nil) 548 549 test("/* */", nil) 550 551 test("/** **/", nil) 552 553 test("/*****/", nil) 554 555 test("/*", "(anonymous): Line 1:3 Unexpected end of input") 556 557 test("#", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 558 559 test("/**/#", "(anonymous): Line 1:5 Unexpected token ILLEGAL") 560 561 test("new +", "(anonymous): Line 1:5 Unexpected token +") 562 563 program := test(";", nil) 564 is(len(program.Body), 1) 565 is(program.Body[0].(*ast.EmptyStatement).Semicolon, file.Idx(1)) 566 567 program = test(";;", nil) 568 is(len(program.Body), 2) 569 is(program.Body[0].(*ast.EmptyStatement).Semicolon, file.Idx(1)) 570 is(program.Body[1].(*ast.EmptyStatement).Semicolon, file.Idx(2)) 571 572 program = test("1.2", nil) 573 is(len(program.Body), 1) 574 is(program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.NumberLiteral).Literal, "1.2") 575 576 program = test("/* */1.2", nil) 577 is(len(program.Body), 1) 578 is(program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.NumberLiteral).Literal, "1.2") 579 580 program = test("\n", nil) 581 is(len(program.Body), 0) 582 583 test(` 584 if (0) { 585 abc = 0 586 } 587 else abc = 0 588 `, nil) 589 590 test("if (0) abc = 0 else abc = 0", "(anonymous): Line 1:16 Unexpected token else") 591 592 test(` 593 if (0) { 594 abc = 0 595 } else abc = 0 596 `, nil) 597 598 test(` 599 if (0) { 600 abc = 1 601 } else { 602 } 603 `, nil) 604 605 test(` 606 do { 607 } while (true) 608 `, nil) 609 610 test(` 611 try { 612 } finally { 613 } 614 `, nil) 615 616 test(` 617 try { 618 } catch (abc) { 619 } finally { 620 } 621 `, nil) 622 623 test(` 624 try { 625 } 626 catch (abc) { 627 } 628 finally { 629 } 630 `, nil) 631 632 test(`try {} catch (abc) {} finally {}`, nil) 633 634 test("try {} catch {}", nil) 635 636 test(` 637 do { 638 do { 639 } while (0) 640 } while (0) 641 `, nil) 642 643 test(` 644 (function(){ 645 try { 646 if ( 647 1 648 ) { 649 return 1 650 } 651 return 0 652 } finally { 653 } 654 })() 655 `, nil) 656 657 test("abc = ''\ndef", nil) 658 659 test("abc = 1\ndef", nil) 660 661 test("abc = Math\ndef", nil) 662 663 test(`"\'"`, nil) 664 665 test(` 666 abc = function(){ 667 } 668 abc = 0 669 `, nil) 670 671 test("abc.null = 0", nil) 672 673 test("0x41", nil) 674 675 test(`"\d"`, nil) 676 677 test(`(function(){return this})`, nil) 678 679 test(` 680 Object.defineProperty(Array.prototype, "0", { 681 value: 100, 682 writable: false, 683 configurable: true 684 }); 685 abc = [101]; 686 abc.hasOwnProperty("0") && abc[0] === 101; 687 `, nil) 688 689 test(`new abc()`, nil) 690 test(`new {}`, nil) 691 692 test(` 693 limit = 4 694 result = 0 695 while (limit) { 696 limit = limit - 1 697 if (limit) { 698 } 699 else { 700 break 701 } 702 result = result + 1 703 } 704 `, nil) 705 706 test(` 707 while (0) { 708 if (0) { 709 continue 710 } 711 } 712 `, nil) 713 714 test("var \u0061\u0062\u0063 = 0", nil) 715 716 // 7_3_1 717 test("var test7_3_1\nabc = 66;", nil) 718 test("var test7_3_1\u2028abc = 66;", nil) 719 720 // 7_3_3 721 test("//\u2028 =;", "(anonymous): Line 2:2 Unexpected token =") 722 723 // 7_3_10 724 test("var abc = \u2029;", "(anonymous): Line 2:1 Unexpected token ;") 725 test("var abc = \\u2029;", "(anonymous): Line 1:11 Unexpected token ILLEGAL") 726 test("var \\u0061\\u0062\\u0063 = 0;", nil) 727 728 test("'", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 729 730 test("'\nstr\ning\n'", "(anonymous): Line 1:1 Unexpected token ILLEGAL") 731 732 // S7.6_A4.3_T1 733 test(`var $\u0030 = 0;`, nil) 734 735 // S7.6.1.1_A1.1 736 test(`switch = 1`, "(anonymous): Line 1:8 Unexpected token =") 737 738 // S7.8.3_A2.1_T1 739 test(`.0 === 0.0`, nil) 740 741 // 7.8.5-1 742 test("var regExp = /\\\rn/;", "(anonymous): Line 1:14 Invalid regular expression: missing /") 743 744 // S7.8.5_A1.1_T2 745 test("var regExp = /=/;", nil) 746 747 // S7.8.5_A1.2_T1 748 test("/*/", "(anonymous): Line 1:4 Unexpected end of input") 749 750 // Sbp_7.9_A9_T3 751 test(` 752 do { 753 ; 754 } while (false) true 755 `, nil) 756 757 // S7.9_A10_T10 758 test(` 759 {a:1 760 } 3 761 `, nil) 762 763 test(` 764 abc 765 ++def 766 `, nil) 767 768 // S7.9_A5.2_T1 769 test(` 770 for(false;false 771 ) { 772 break; 773 } 774 `, "(anonymous): Line 3:13 Unexpected token )") 775 776 // S7.9_A9_T8 777 test(` 778 do {}; 779 while (false) 780 `, "(anonymous): Line 2:18 Unexpected token ;") 781 782 // S8.4_A5 783 test(` 784 "x\0y" 785 `, nil) 786 787 // S9.3.1_A6_T1 788 test(` 789 10e10000 790 `, nil) 791 792 // 10.4.2-1-5 793 test(` 794 "abc\ 795 def" 796 `, nil) 797 798 test("'\\\n'", nil) 799 800 test("'\\\r\n'", nil) 801 802 //// 11.13.1-1-1 803 test("42 = 42;", "(anonymous): Line 1:1 Invalid left-hand side in assignment") 804 test("s &^= 42;", "(anonymous): Line 1:4 Unexpected token ^=") 805 806 // S11.13.2_A4.2_T1.3 807 test(` 808 abc /= "1" 809 `, nil) 810 811 // 12.1-1 812 test(` 813 try{};catch(){} 814 `, "(anonymous): Line 2:13 Missing catch or finally after try") 815 816 // 12.1-3 817 test(` 818 try{};finally{} 819 `, "(anonymous): Line 2:13 Missing catch or finally after try") 820 821 // S12.6.3_A11.1_T3 822 test(` 823 while (true) { 824 break abc; 825 } 826 `, "(anonymous): Line 3:17 Undefined label 'abc'") 827 828 // S15.3_A2_T1 829 test(`var x / = 1;`, "(anonymous): Line 1:7 Unexpected token /") 830 831 test(` 832 function abc() { 833 if (0) 834 return; 835 else { 836 } 837 } 838 `, nil) 839 840 test("//\u2028 var =;", "(anonymous): Line 2:6 Unexpected token =") 841 842 test(` 843 throw 844 {} 845 `, "(anonymous): Line 2:13 Illegal newline after throw") 846 847 // S7.6.1.1_A1.11 848 test(` 849 function = 1 850 `, "(anonymous): Line 2:22 Unexpected token =") 851 852 // S7.8.3_A1.2_T1 853 test(`0e1`, nil) 854 855 test("abc = 1; abc\n++", "(anonymous): Line 2:3 Unexpected end of input") 856 857 // --- 858 859 test("({ get abc() {} })", nil) 860 861 test(`for (abc.def in {}) {}`, nil) 862 863 test(`while (true) { break }`, nil) 864 865 test(`while (true) { continue }`, nil) 866 867 test(`abc=/^(?:(\w+:)\/{2}(\w+(?:\.\w+)*\/?)|(.{0,2}\/{1}))?([/.]*?(?:[^?]+)?\/)?((?:[^/?]+)\.(\w+))(?:\?(\S+)?)?$/,def=/^(?:(\w+:)\/{2})|(.{0,2}\/{1})?([/.]*?(?:[^?]+)?\/?)?$/`, nil) 868 869 test(`(function() { try {} catch (err) {} finally {} return })`, nil) 870 871 test(`0xde0b6b3a7640080.toFixed(0)`, nil) 872 873 test(`/[^-._0-9A-Za-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u37f-\u1fff\u200c-\u200d\u203f\u2040\u2070-\u218f]/`, nil) 874 875 test(`/[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/`, nil) 876 877 test("var abc = 1;\ufeff", nil) 878 879 test("\ufeff/* var abc = 1; */", nil) 880 881 test(`if (-0x8000000000000000<=abc&&abc<=0x8000000000000000) {}`, nil) 882 883 test(`(function(){debugger;return this;})`, nil) 884 885 test(` 886 887 `, nil) 888 889 test(` 890 var abc = "" 891 debugger 892 `, nil) 893 894 test(` 895 var abc = /\[\]$/ 896 debugger 897 `, nil) 898 899 test(` 900 var abc = 1 / 901 2 902 debugger 903 `, nil) 904 905 test("'ё\\\u2029'", nil) 906 907 test(`[a, b] = [1, 2]`, nil) 908 test(`({"a b": {}} = {})`, nil) 909 910 test(`ref = (a, b = 39,) => { 911 };`, nil) 912 test(`(a,) => {}`, nil) 913 914 test(`2 ?? (2 && 3) + 3`, nil) 915 test(`(2 ?? 2) && 3 + 3`, nil) 916 program = test(`a ?? b ?? c`, nil) 917 is(len(program.Body), 1) 918 is(program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.BinaryExpression).Right.(*ast.Identifier).Name, "c") 919 920 program = test(` 921 class C { 922 a 923 b 924 #c 925 m() { 926 return this.#c; 927 } 928 } 929 `, nil) 930 is(len(program.Body), 1) 931 932 { 933 program := test(`(-2)**53`, nil) 934 st := program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.BinaryExpression) 935 is(st.Operator, token.EXPONENT) 936 left := st.Left.(*ast.UnaryExpression) 937 is(left.Operator, token.MINUS) 938 op1 := left.Operand.(*ast.NumberLiteral) 939 is(op1.Literal, "2") 940 941 right := st.Right.(*ast.NumberLiteral) 942 is(right.Literal, "53") 943 } 944 945 }) 946 } 947 948 func TestParseDestruct(t *testing.T) { 949 parser := newParser("", `({a: (a.b), ...spread,} = {})`) 950 prg, err := parser.parse() 951 if err != nil { 952 t.Fatal(err) 953 } 954 _ = prg 955 } 956 957 func Test_parseStringLiteral(t *testing.T) { 958 tt(t, func() { 959 test := func(have string, want unistring.String) { 960 parser := newParser("", have) 961 parser.read() 962 parser.read() 963 _, res, err := parser.scanString(0, true) 964 is(err, "") 965 is(res, want) 966 } 967 968 test(`""`, "") 969 test(`/=/`, "=") 970 971 test("'1(\\\\d+)'", "1(\\d+)") 972 973 test("'\\u2029'", "\u2029") 974 975 test("'abc\\uFFFFabc'", "abc\uFFFFabc") 976 977 test("'[First line \\\nSecond line \\\n Third line\\\n. ]'", 978 "[First line Second line Third line. ]") 979 980 test("'\\u007a\\x79\\u000a\\x78'", "zy\nx") 981 982 // S7.8.4_A4.2_T3 983 test("'\\a'", "a") 984 test("'\u0410'", "\u0410") 985 986 // S7.8.4_A5.1_T1 987 test("'\\0'", "\u0000") 988 989 // S8.4_A5 990 test("'\u0000'", "\u0000") 991 992 // 15.5.4.20 993 test("\"'abc'\\\n'def'\"", "'abc''def'") 994 995 // 15.5.4.20-4-1 996 test("\"'abc'\\\r\n'def'\"", "'abc''def'") 997 998 // Octal 999 test("'\\0'", "\000") 1000 test("'\\00'", "\000") 1001 test("'\\000'", "\000") 1002 test("'\\09'", "\0009") 1003 test("'\\009'", "\0009") 1004 test("'\\0009'", "\0009") 1005 test("'\\1'", "\001") 1006 test("'\\01'", "\001") 1007 test("'\\001'", "\001") 1008 test("'\\0011'", "\0011") 1009 test("'\\1abc'", "\001abc") 1010 1011 test("'\\\u4e16'", "\u4e16") 1012 1013 // err 1014 test = func(have string, want unistring.String) { 1015 parser := newParser("", have) 1016 parser.read() 1017 parser.read() 1018 _, res, err := parser.scanString(0, true) 1019 is(err, want) 1020 is(res, "") 1021 } 1022 1023 test(`"\u"`, `invalid escape: \u: len("") != 4`) 1024 test(`"\u0"`, `invalid escape: \u: len("0") != 4`) 1025 test(`"\u00"`, `invalid escape: \u: len("00") != 4`) 1026 test(`"\u000"`, `invalid escape: \u: len("000") != 4`) 1027 1028 test(`"\x"`, `invalid escape: \x: len("") != 2`) 1029 test(`"\x0"`, `invalid escape: \x: len("0") != 2`) 1030 }) 1031 } 1032 1033 func Test_parseNumberLiteral(t *testing.T) { 1034 tt(t, func() { 1035 test := func(input string, expect interface{}) { 1036 result, err := parseNumberLiteral(input) 1037 is(err, nil) 1038 is(result, expect) 1039 } 1040 1041 test("0", 0) 1042 1043 test("0x8000000000000000", float64(9.223372036854776e+18)) 1044 }) 1045 } 1046 1047 func TestPosition(t *testing.T) { 1048 tt(t, func() { 1049 parser := newParser("", "// Lorem ipsum") 1050 1051 // Out of range, idx0 (error condition) 1052 is(parser.slice(0, 1), "") 1053 is(parser.slice(0, 10), "") 1054 1055 // Out of range, idx1 (error condition) 1056 is(parser.slice(1, 128), "") 1057 1058 is(parser.str[0:0], "") 1059 is(parser.slice(1, 1), "") 1060 1061 is(parser.str[0:1], "/") 1062 is(parser.slice(1, 2), "/") 1063 1064 is(parser.str[0:14], "// Lorem ipsum") 1065 is(parser.slice(1, 15), "// Lorem ipsum") 1066 1067 parser = newParser("", "(function(){ return 0; })") 1068 program, err := parser.parse() 1069 is(err, nil) 1070 1071 var node ast.Node 1072 node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.FunctionLiteral) 1073 is(node.Idx0(), file.Idx(2)) 1074 is(node.Idx1(), file.Idx(25)) 1075 is(parser.slice(node.Idx0(), node.Idx1()), "function(){ return 0; }") 1076 is(parser.slice(node.Idx0(), node.Idx1()+1), "function(){ return 0; })") 1077 is(parser.slice(node.Idx0(), node.Idx1()+2), "") 1078 is(node.(*ast.FunctionLiteral).Source, "function(){ return 0; }") 1079 1080 node = program 1081 is(node.Idx0(), file.Idx(2)) 1082 is(node.Idx1(), file.Idx(25)) 1083 is(parser.slice(node.Idx0(), node.Idx1()), "function(){ return 0; }") 1084 1085 parser = newParser("", "(function(){ return abc; })") 1086 program, err = parser.parse() 1087 is(err, nil) 1088 node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.FunctionLiteral) 1089 is(node.(*ast.FunctionLiteral).Source, "function(){ return abc; }") 1090 }) 1091 } 1092 1093 func TestExtractSourceMapLine(t *testing.T) { 1094 tt(t, func() { 1095 is(extractSourceMapLine(""), "") 1096 is(extractSourceMapLine("\n"), "") 1097 is(extractSourceMapLine(" "), "") 1098 is(extractSourceMapLine("1\n2\n3\n4\n"), "") 1099 1100 src := `"use strict"; 1101 var x = {}; 1102 //# sourceMappingURL=delme.js.map` 1103 modSrc := `(function(exports, require, module) {` + src + ` 1104 })` 1105 is(extractSourceMapLine(modSrc), "//# sourceMappingURL=delme.js.map") 1106 is(extractSourceMapLine(modSrc+"\n\n\n\n"), "//# sourceMappingURL=delme.js.map") 1107 }) 1108 } 1109 1110 func TestSourceMapOptions(t *testing.T) { 1111 tt(t, func() { 1112 count := 0 1113 requestedPath := "" 1114 loader := func(p string) ([]byte, error) { 1115 count++ 1116 requestedPath = p 1117 return nil, nil 1118 } 1119 src := `"use strict"; 1120 var x = {}; 1121 //# sourceMappingURL=delme.js.map` 1122 _, err := ParseFile(nil, "delme.js", src, 0, WithSourceMapLoader(loader)) 1123 is(err, nil) 1124 is(count, 1) 1125 is(requestedPath, "delme.js.map") 1126 1127 count = 0 1128 _, err = ParseFile(nil, "", src, 0, WithSourceMapLoader(loader)) 1129 is(err, nil) 1130 is(count, 1) 1131 is(requestedPath, "delme.js.map") 1132 1133 count = 0 1134 _, err = ParseFile(nil, "delme.js", src, 0, WithDisableSourceMaps) 1135 is(err, nil) 1136 is(count, 0) 1137 1138 _, err = ParseFile(nil, "/home/user/src/delme.js", src, 0, WithSourceMapLoader(loader)) 1139 is(err, nil) 1140 is(count, 1) 1141 is(requestedPath, "/home/user/src/delme.js.map") 1142 1143 count = 0 1144 _, err = ParseFile(nil, "https://site.com/delme.js", src, 0, WithSourceMapLoader(loader)) 1145 is(err, nil) 1146 is(count, 1) 1147 is(requestedPath, "https://site.com/delme.js.map") 1148 }) 1149 } 1150 1151 func TestParseTemplateCharacters(t *testing.T) { 1152 parser := newParser("", "`test\\\r\\\n${a}`") 1153 parser.next() 1154 if parser.token != token.BACKTICK { 1155 t.Fatalf("Token: %s", parser.token) 1156 } 1157 checkParseTemplateChars := func(expectedLiteral string, expectedParsed unistring.String, expectedFinished, expectParseErr, expectErr bool) { 1158 literal, parsed, finished, parseErr, err := parser.parseTemplateCharacters() 1159 if err != "" != expectErr { 1160 t.Fatal(err) 1161 } 1162 if literal != expectedLiteral { 1163 t.Fatalf("Literal: %q", literal) 1164 } 1165 if parsed != expectedParsed { 1166 t.Fatalf("Parsed: %q", parsed) 1167 } 1168 if finished != expectedFinished { 1169 t.Fatal(finished) 1170 } 1171 if parseErr != "" != expectParseErr { 1172 t.Fatalf("parseErr: %v", parseErr) 1173 } 1174 } 1175 checkParseTemplateChars("test\\\n\\\n", "test", false, false, false) 1176 parser.next() 1177 parser.expect(token.IDENTIFIER) 1178 if len(parser.errors) > 0 { 1179 t.Fatal(parser.errors) 1180 } 1181 if parser.token != token.RIGHT_BRACE { 1182 t.Fatal("Expected }") 1183 } 1184 if len(parser.errors) > 0 { 1185 t.Fatal(parser.errors) 1186 } 1187 checkParseTemplateChars("", "", true, false, false) 1188 if parser.chr != -1 { 1189 t.Fatal("Expected EOF") 1190 } 1191 } 1192 1193 func TestParseTemplateLiteral(t *testing.T) { 1194 parser := newParser("", "f()\n`test${a}`") 1195 prg, err := parser.parse() 1196 if err != nil { 1197 t.Fatal(err) 1198 } 1199 if st, ok := prg.Body[0].(*ast.ExpressionStatement); ok { 1200 if expr, ok := st.Expression.(*ast.TemplateLiteral); ok { 1201 if expr.Tag == nil { 1202 t.Fatal("tag is nil") 1203 } 1204 if idx0 := expr.Tag.Idx0(); idx0 != 1 { 1205 t.Fatalf("Tag.Idx0(): %d", idx0) 1206 } 1207 if expr.OpenQuote != 5 { 1208 t.Fatalf("OpenQuote: %d", expr.OpenQuote) 1209 } 1210 if expr.CloseQuote != 14 { 1211 t.Fatalf("CloseQuote: %d", expr.CloseQuote) 1212 } 1213 if l := len(expr.Elements); l != 2 { 1214 t.Fatalf("len elements: %d", l) 1215 } 1216 if l := len(expr.Expressions); l != 1 { 1217 t.Fatalf("len expressions: %d", l) 1218 } 1219 } else { 1220 t.Fatal(st) 1221 } 1222 } else { 1223 t.Fatal(prg.Body[0]) 1224 } 1225 } 1226 1227 func TestParseTemplateLiteralWithTail(t *testing.T) { 1228 parser := newParser("", "f()\n`test${a}tail` ") 1229 prg, err := parser.parse() 1230 if err != nil { 1231 t.Fatal(err) 1232 } 1233 if st, ok := prg.Body[0].(*ast.ExpressionStatement); ok { 1234 if expr, ok := st.Expression.(*ast.TemplateLiteral); ok { 1235 if expr.CloseQuote != 18 { 1236 t.Fatalf("CloseQuote: %d", expr.CloseQuote) 1237 } 1238 } else { 1239 t.Fatal(st) 1240 } 1241 } else { 1242 t.Fatal(prg.Body[0]) 1243 } 1244 }