github.com/evanw/esbuild@v0.21.4/internal/bundler_tests/bundler_lower_test.go (about) 1 package bundler_tests 2 3 // This file contains tests for "lowering" syntax, which means converting it to 4 // older JavaScript. For example, "a ** b" becomes a call to "Math.pow(a, b)" 5 // when lowered. Which syntax is lowered is determined by the language target. 6 7 import ( 8 "testing" 9 10 "github.com/evanw/esbuild/internal/compat" 11 "github.com/evanw/esbuild/internal/config" 12 ) 13 14 var lower_suite = suite{ 15 name: "lower", 16 } 17 18 func TestLowerOptionalCatchNameCollisionNoBundle(t *testing.T) { 19 lower_suite.expectBundled(t, bundled{ 20 files: map[string]string{ 21 "/entry.js": ` 22 try {} 23 catch { var e, e2 } 24 var e3 25 `, 26 }, 27 entryPaths: []string{"/entry.js"}, 28 options: config.Options{ 29 UnsupportedJSFeatures: es(2018), 30 AbsOutputFile: "/out.js", 31 }, 32 }) 33 } 34 35 func TestLowerObjectSpreadNoBundle(t *testing.T) { 36 lower_suite.expectBundled(t, bundled{ 37 files: map[string]string{ 38 "/entry.jsx": ` 39 let tests = [ 40 {...a, ...b}, 41 {a, b, ...c}, 42 {...a, b, c}, 43 {a, ...b, c}, 44 {a, b, ...c, ...d, e, f, ...g, ...h, i, j}, 45 ] 46 let jsx = [ 47 <div {...a} {...b}/>, 48 <div a b {...c}/>, 49 <div {...a} b c/>, 50 <div a {...b} c/>, 51 <div a b {...c} {...d} e f {...g} {...h} i j/>, 52 ] 53 `, 54 }, 55 entryPaths: []string{"/entry.jsx"}, 56 options: config.Options{ 57 UnsupportedJSFeatures: es(2017), 58 AbsOutputFile: "/out.js", 59 }, 60 }) 61 } 62 63 func TestLowerExponentiationOperatorNoBundle(t *testing.T) { 64 lower_suite.expectBundled(t, bundled{ 65 files: map[string]string{ 66 "/entry.js": ` 67 let tests = { 68 // Exponentiation operator 69 0: a ** b ** c, 70 1: (a ** b) ** c, 71 72 // Exponentiation assignment operator 73 2: a **= b, 74 3: a.b **= c, 75 4: a[b] **= c, 76 5: a().b **= c, 77 6: a()[b] **= c, 78 7: a[b()] **= c, 79 8: a()[b()] **= c, 80 81 // These all should not need capturing (no object identity) 82 9: a[0] **= b, 83 10: a[false] **= b, 84 11: a[null] **= b, 85 12: a[void 0] **= b, 86 13: a[123n] **= b, 87 14: a[this] **= b, 88 89 // These should need capturing (have object identitiy) 90 15: a[/x/] **= b, 91 16: a[{}] **= b, 92 17: a[[]] **= b, 93 18: a[() => {}] **= b, 94 19: a[function() {}] **= b, 95 } 96 `, 97 }, 98 entryPaths: []string{"/entry.js"}, 99 options: config.Options{ 100 UnsupportedJSFeatures: es(2015), 101 AbsOutputFile: "/out.js", 102 }, 103 expectedScanLog: `entry.js: ERROR: Big integer literals are not available in the configured target environment 104 `, 105 }) 106 } 107 108 func TestLowerPrivateFieldAssignments2015NoBundle(t *testing.T) { 109 lower_suite.expectBundled(t, bundled{ 110 files: map[string]string{ 111 "/entry.js": ` 112 class Foo { 113 #x 114 unary() { 115 this.#x++ 116 this.#x-- 117 ++this.#x 118 --this.#x 119 } 120 binary() { 121 this.#x = 1 122 this.#x += 1 123 this.#x -= 1 124 this.#x *= 1 125 this.#x /= 1 126 this.#x %= 1 127 this.#x **= 1 128 this.#x <<= 1 129 this.#x >>= 1 130 this.#x >>>= 1 131 this.#x &= 1 132 this.#x |= 1 133 this.#x ^= 1 134 this.#x &&= 1 135 this.#x ||= 1 136 this.#x ??= 1 137 } 138 } 139 `, 140 }, 141 entryPaths: []string{"/entry.js"}, 142 options: config.Options{ 143 UnsupportedJSFeatures: es(2015), 144 AbsOutputFile: "/out.js", 145 }, 146 }) 147 } 148 149 func TestLowerPrivateFieldAssignments2019NoBundle(t *testing.T) { 150 lower_suite.expectBundled(t, bundled{ 151 files: map[string]string{ 152 "/entry.js": ` 153 class Foo { 154 #x 155 unary() { 156 this.#x++ 157 this.#x-- 158 ++this.#x 159 --this.#x 160 } 161 binary() { 162 this.#x = 1 163 this.#x += 1 164 this.#x -= 1 165 this.#x *= 1 166 this.#x /= 1 167 this.#x %= 1 168 this.#x **= 1 169 this.#x <<= 1 170 this.#x >>= 1 171 this.#x >>>= 1 172 this.#x &= 1 173 this.#x |= 1 174 this.#x ^= 1 175 this.#x &&= 1 176 this.#x ||= 1 177 this.#x ??= 1 178 } 179 } 180 `, 181 }, 182 entryPaths: []string{"/entry.js"}, 183 options: config.Options{ 184 UnsupportedJSFeatures: es(2019), 185 AbsOutputFile: "/out.js", 186 }, 187 }) 188 } 189 190 func TestLowerPrivateFieldAssignments2020NoBundle(t *testing.T) { 191 lower_suite.expectBundled(t, bundled{ 192 files: map[string]string{ 193 "/entry.js": ` 194 class Foo { 195 #x 196 unary() { 197 this.#x++ 198 this.#x-- 199 ++this.#x 200 --this.#x 201 } 202 binary() { 203 this.#x = 1 204 this.#x += 1 205 this.#x -= 1 206 this.#x *= 1 207 this.#x /= 1 208 this.#x %= 1 209 this.#x **= 1 210 this.#x <<= 1 211 this.#x >>= 1 212 this.#x >>>= 1 213 this.#x &= 1 214 this.#x |= 1 215 this.#x ^= 1 216 this.#x &&= 1 217 this.#x ||= 1 218 this.#x ??= 1 219 } 220 } 221 `, 222 }, 223 entryPaths: []string{"/entry.js"}, 224 options: config.Options{ 225 UnsupportedJSFeatures: es(2020), 226 AbsOutputFile: "/out.js", 227 }, 228 }) 229 } 230 231 func TestLowerPrivateFieldAssignmentsNextNoBundle(t *testing.T) { 232 lower_suite.expectBundled(t, bundled{ 233 files: map[string]string{ 234 "/entry.js": ` 235 class Foo { 236 #x 237 unary() { 238 this.#x++ 239 this.#x-- 240 ++this.#x 241 --this.#x 242 } 243 binary() { 244 this.#x = 1 245 this.#x += 1 246 this.#x -= 1 247 this.#x *= 1 248 this.#x /= 1 249 this.#x %= 1 250 this.#x **= 1 251 this.#x <<= 1 252 this.#x >>= 1 253 this.#x >>>= 1 254 this.#x &= 1 255 this.#x |= 1 256 this.#x ^= 1 257 this.#x &&= 1 258 this.#x ||= 1 259 this.#x ??= 1 260 } 261 } 262 `, 263 }, 264 entryPaths: []string{"/entry.js"}, 265 options: config.Options{ 266 AbsOutputFile: "/out.js", 267 }, 268 }) 269 } 270 271 func TestLowerPrivateFieldOptionalChain2019NoBundle(t *testing.T) { 272 lower_suite.expectBundled(t, bundled{ 273 files: map[string]string{ 274 "/entry.js": ` 275 class Foo { 276 #x 277 foo() { 278 this?.#x.y 279 this?.y.#x 280 this.#x?.y 281 } 282 } 283 `, 284 }, 285 entryPaths: []string{"/entry.js"}, 286 options: config.Options{ 287 UnsupportedJSFeatures: es(2019), 288 AbsOutputFile: "/out.js", 289 }, 290 }) 291 } 292 293 func TestLowerPrivateFieldOptionalChain2020NoBundle(t *testing.T) { 294 lower_suite.expectBundled(t, bundled{ 295 files: map[string]string{ 296 "/entry.js": ` 297 class Foo { 298 #x 299 foo() { 300 this?.#x.y 301 this?.y.#x 302 this.#x?.y 303 } 304 } 305 `, 306 }, 307 entryPaths: []string{"/entry.js"}, 308 options: config.Options{ 309 UnsupportedJSFeatures: es(2020), 310 AbsOutputFile: "/out.js", 311 }, 312 }) 313 } 314 315 func TestLowerPrivateFieldOptionalChainNextNoBundle(t *testing.T) { 316 lower_suite.expectBundled(t, bundled{ 317 files: map[string]string{ 318 "/entry.js": ` 319 class Foo { 320 #x 321 foo() { 322 this?.#x.y 323 this?.y.#x 324 this.#x?.y 325 } 326 } 327 `, 328 }, 329 entryPaths: []string{"/entry.js"}, 330 options: config.Options{ 331 AbsOutputFile: "/out.js", 332 }, 333 }) 334 } 335 336 func TestTSLowerPrivateFieldOptionalChain2015NoBundle(t *testing.T) { 337 lower_suite.expectBundled(t, bundled{ 338 files: map[string]string{ 339 "/entry.ts": ` 340 class Foo { 341 #x 342 foo() { 343 this?.#x.y 344 this?.y.#x 345 this.#x?.y 346 } 347 } 348 `, 349 }, 350 entryPaths: []string{"/entry.ts"}, 351 options: config.Options{ 352 UnsupportedJSFeatures: es(2015), 353 AbsOutputFile: "/out.js", 354 }, 355 }) 356 } 357 358 func TestTSLowerPrivateStaticMembers2015NoBundle(t *testing.T) { 359 lower_suite.expectBundled(t, bundled{ 360 files: map[string]string{ 361 "/entry.ts": ` 362 class Foo { 363 static #x 364 static get #y() {} 365 static set #y(x) {} 366 static #z() {} 367 foo() { 368 Foo.#x += 1 369 Foo.#y += 1 370 Foo.#z() 371 } 372 } 373 `, 374 }, 375 entryPaths: []string{"/entry.ts"}, 376 options: config.Options{ 377 UnsupportedJSFeatures: es(2015), 378 AbsOutputFile: "/out.js", 379 }, 380 }) 381 } 382 383 func TestTSLowerPrivateFieldAndMethodAvoidNameCollision2015(t *testing.T) { 384 lower_suite.expectBundled(t, bundled{ 385 files: map[string]string{ 386 "/entry.ts": ` 387 export class WeakMap { 388 #x 389 } 390 export class WeakSet { 391 #y() {} 392 } 393 `, 394 }, 395 entryPaths: []string{"/entry.ts"}, 396 options: config.Options{ 397 Mode: config.ModeBundle, 398 UnsupportedJSFeatures: es(2015), 399 AbsOutputFile: "/out.js", 400 }, 401 }) 402 } 403 404 func TestLowerPrivateGetterSetter2015(t *testing.T) { 405 lower_suite.expectBundled(t, bundled{ 406 files: map[string]string{ 407 "/entry.js": ` 408 export class Foo { 409 get #foo() { return this.foo } 410 set #bar(val) { this.bar = val } 411 get #prop() { return this.prop } 412 set #prop(val) { this.prop = val } 413 foo(fn) { 414 fn().#foo 415 fn().#bar = 1 416 fn().#prop 417 fn().#prop = 2 418 } 419 unary(fn) { 420 fn().#prop++; 421 fn().#prop--; 422 ++fn().#prop; 423 --fn().#prop; 424 } 425 binary(fn) { 426 fn().#prop = 1; 427 fn().#prop += 1; 428 fn().#prop -= 1; 429 fn().#prop *= 1; 430 fn().#prop /= 1; 431 fn().#prop %= 1; 432 fn().#prop **= 1; 433 fn().#prop <<= 1; 434 fn().#prop >>= 1; 435 fn().#prop >>>= 1; 436 fn().#prop &= 1; 437 fn().#prop |= 1; 438 fn().#prop ^= 1; 439 fn().#prop &&= 1; 440 fn().#prop ||= 1; 441 fn().#prop ??= 1; 442 } 443 } 444 `, 445 }, 446 entryPaths: []string{"/entry.js"}, 447 options: config.Options{ 448 Mode: config.ModeBundle, 449 UnsupportedJSFeatures: es(2015), 450 AbsOutputFile: "/out.js", 451 }, 452 }) 453 } 454 455 func TestLowerPrivateGetterSetter2019(t *testing.T) { 456 lower_suite.expectBundled(t, bundled{ 457 files: map[string]string{ 458 "/entry.js": ` 459 export class Foo { 460 get #foo() { return this.foo } 461 set #bar(val) { this.bar = val } 462 get #prop() { return this.prop } 463 set #prop(val) { this.prop = val } 464 foo(fn) { 465 fn().#foo 466 fn().#bar = 1 467 fn().#prop 468 fn().#prop = 2 469 } 470 unary(fn) { 471 fn().#prop++; 472 fn().#prop--; 473 ++fn().#prop; 474 --fn().#prop; 475 } 476 binary(fn) { 477 fn().#prop = 1; 478 fn().#prop += 1; 479 fn().#prop -= 1; 480 fn().#prop *= 1; 481 fn().#prop /= 1; 482 fn().#prop %= 1; 483 fn().#prop **= 1; 484 fn().#prop <<= 1; 485 fn().#prop >>= 1; 486 fn().#prop >>>= 1; 487 fn().#prop &= 1; 488 fn().#prop |= 1; 489 fn().#prop ^= 1; 490 fn().#prop &&= 1; 491 fn().#prop ||= 1; 492 fn().#prop ??= 1; 493 } 494 } 495 `, 496 }, 497 entryPaths: []string{"/entry.js"}, 498 options: config.Options{ 499 Mode: config.ModeBundle, 500 UnsupportedJSFeatures: es(2019), 501 AbsOutputFile: "/out.js", 502 }, 503 }) 504 } 505 506 func TestLowerPrivateGetterSetter2020(t *testing.T) { 507 lower_suite.expectBundled(t, bundled{ 508 files: map[string]string{ 509 "/entry.js": ` 510 export class Foo { 511 get #foo() { return this.foo } 512 set #bar(val) { this.bar = val } 513 get #prop() { return this.prop } 514 set #prop(val) { this.prop = val } 515 foo(fn) { 516 fn().#foo 517 fn().#bar = 1 518 fn().#prop 519 fn().#prop = 2 520 } 521 unary(fn) { 522 fn().#prop++; 523 fn().#prop--; 524 ++fn().#prop; 525 --fn().#prop; 526 } 527 binary(fn) { 528 fn().#prop = 1; 529 fn().#prop += 1; 530 fn().#prop -= 1; 531 fn().#prop *= 1; 532 fn().#prop /= 1; 533 fn().#prop %= 1; 534 fn().#prop **= 1; 535 fn().#prop <<= 1; 536 fn().#prop >>= 1; 537 fn().#prop >>>= 1; 538 fn().#prop &= 1; 539 fn().#prop |= 1; 540 fn().#prop ^= 1; 541 fn().#prop &&= 1; 542 fn().#prop ||= 1; 543 fn().#prop ??= 1; 544 } 545 } 546 `, 547 }, 548 entryPaths: []string{"/entry.js"}, 549 options: config.Options{ 550 Mode: config.ModeBundle, 551 UnsupportedJSFeatures: es(2020), 552 AbsOutputFile: "/out.js", 553 }, 554 }) 555 } 556 557 func TestLowerPrivateGetterSetterNext(t *testing.T) { 558 lower_suite.expectBundled(t, bundled{ 559 files: map[string]string{ 560 "/entry.js": ` 561 export class Foo { 562 get #foo() { return this.foo } 563 set #bar(val) { this.bar = val } 564 get #prop() { return this.prop } 565 set #prop(val) { this.prop = val } 566 foo(fn) { 567 fn().#foo 568 fn().#bar = 1 569 fn().#prop 570 fn().#prop = 2 571 } 572 unary(fn) { 573 fn().#prop++; 574 fn().#prop--; 575 ++fn().#prop; 576 --fn().#prop; 577 } 578 binary(fn) { 579 fn().#prop = 1; 580 fn().#prop += 1; 581 fn().#prop -= 1; 582 fn().#prop *= 1; 583 fn().#prop /= 1; 584 fn().#prop %= 1; 585 fn().#prop **= 1; 586 fn().#prop <<= 1; 587 fn().#prop >>= 1; 588 fn().#prop >>>= 1; 589 fn().#prop &= 1; 590 fn().#prop |= 1; 591 fn().#prop ^= 1; 592 fn().#prop &&= 1; 593 fn().#prop ||= 1; 594 fn().#prop ??= 1; 595 } 596 } 597 `, 598 }, 599 entryPaths: []string{"/entry.js"}, 600 options: config.Options{ 601 Mode: config.ModeBundle, 602 AbsOutputFile: "/out.js", 603 }, 604 }) 605 } 606 607 func TestLowerPrivateMethod2019(t *testing.T) { 608 lower_suite.expectBundled(t, bundled{ 609 files: map[string]string{ 610 "/entry.js": ` 611 export class Foo { 612 #field 613 #method() {} 614 baseline() { 615 a().foo 616 b().foo(x) 617 c()?.foo(x) 618 d().foo?.(x) 619 e()?.foo?.(x) 620 } 621 privateField() { 622 a().#field 623 b().#field(x) 624 c()?.#field(x) 625 d().#field?.(x) 626 e()?.#field?.(x) 627 f()?.foo.#field(x).bar() 628 } 629 privateMethod() { 630 a().#method 631 b().#method(x) 632 c()?.#method(x) 633 d().#method?.(x) 634 e()?.#method?.(x) 635 f()?.foo.#method(x).bar() 636 } 637 } 638 `, 639 }, 640 entryPaths: []string{"/entry.js"}, 641 options: config.Options{ 642 Mode: config.ModeBundle, 643 UnsupportedJSFeatures: es(2019), 644 AbsOutputFile: "/out.js", 645 }, 646 }) 647 } 648 649 func TestLowerPrivateMethod2020(t *testing.T) { 650 lower_suite.expectBundled(t, bundled{ 651 files: map[string]string{ 652 "/entry.js": ` 653 export class Foo { 654 #field 655 #method() {} 656 baseline() { 657 a().foo 658 b().foo(x) 659 c()?.foo(x) 660 d().foo?.(x) 661 e()?.foo?.(x) 662 } 663 privateField() { 664 a().#field 665 b().#field(x) 666 c()?.#field(x) 667 d().#field?.(x) 668 e()?.#field?.(x) 669 f()?.foo.#field(x).bar() 670 } 671 privateMethod() { 672 a().#method 673 b().#method(x) 674 c()?.#method(x) 675 d().#method?.(x) 676 e()?.#method?.(x) 677 f()?.foo.#method(x).bar() 678 } 679 } 680 `, 681 }, 682 entryPaths: []string{"/entry.js"}, 683 options: config.Options{ 684 Mode: config.ModeBundle, 685 UnsupportedJSFeatures: es(2020), 686 AbsOutputFile: "/out.js", 687 }, 688 }) 689 } 690 691 func TestLowerPrivateMethodNext(t *testing.T) { 692 lower_suite.expectBundled(t, bundled{ 693 files: map[string]string{ 694 "/entry.js": ` 695 export class Foo { 696 #field 697 #method() {} 698 baseline() { 699 a().foo 700 b().foo(x) 701 c()?.foo(x) 702 d().foo?.(x) 703 e()?.foo?.(x) 704 } 705 privateField() { 706 a().#field 707 b().#field(x) 708 c()?.#field(x) 709 d().#field?.(x) 710 e()?.#field?.(x) 711 f()?.foo.#field(x).bar() 712 } 713 privateMethod() { 714 a().#method 715 b().#method(x) 716 c()?.#method(x) 717 d().#method?.(x) 718 e()?.#method?.(x) 719 f()?.foo.#method(x).bar() 720 } 721 } 722 `, 723 }, 724 entryPaths: []string{"/entry.js"}, 725 options: config.Options{ 726 Mode: config.ModeBundle, 727 AbsOutputFile: "/out.js", 728 }, 729 }) 730 } 731 732 func TestLowerPrivateClassExpr2020NoBundle(t *testing.T) { 733 lower_suite.expectBundled(t, bundled{ 734 files: map[string]string{ 735 "/entry.js": ` 736 export let Foo = class { 737 #field 738 #method() {} 739 static #staticField 740 static #staticMethod() {} 741 foo() { 742 this.#field = this.#method() 743 Foo.#staticField = Foo.#staticMethod() 744 } 745 } 746 `, 747 }, 748 entryPaths: []string{"/entry.js"}, 749 options: config.Options{ 750 UnsupportedJSFeatures: es(2020), 751 AbsOutputFile: "/out.js", 752 }, 753 }) 754 } 755 756 func TestLowerPrivateMethodWithModifiers2020(t *testing.T) { 757 lower_suite.expectBundled(t, bundled{ 758 files: map[string]string{ 759 "/entry.js": ` 760 export class Foo { 761 *#g() {} 762 async #a() {} 763 async *#ag() {} 764 765 static *#sg() {} 766 static async #sa() {} 767 static async *#sag() {} 768 } 769 `, 770 }, 771 entryPaths: []string{"/entry.js"}, 772 options: config.Options{ 773 Mode: config.ModeBundle, 774 UnsupportedJSFeatures: es(2020), 775 AbsOutputFile: "/out.js", 776 }, 777 }) 778 } 779 780 func TestLowerAsync2016NoBundle(t *testing.T) { 781 lower_suite.expectBundled(t, bundled{ 782 files: map[string]string{ 783 "/entry.js": ` 784 async function foo(bar) { 785 await bar 786 return [this, arguments] 787 } 788 class Foo {async foo() {}} 789 export default [ 790 foo, 791 Foo, 792 async function() {}, 793 async () => {}, 794 {async foo() {}}, 795 class {async foo() {}}, 796 function() { 797 return async (bar) => { 798 await bar 799 return [this, arguments] 800 } 801 }, 802 ] 803 `, 804 }, 805 entryPaths: []string{"/entry.js"}, 806 options: config.Options{ 807 UnsupportedJSFeatures: es(2016), 808 AbsOutputFile: "/out.js", 809 }, 810 }) 811 } 812 813 func TestLowerAsync2017NoBundle(t *testing.T) { 814 lower_suite.expectBundled(t, bundled{ 815 files: map[string]string{ 816 "/entry.js": ` 817 async function foo(bar) { 818 await bar 819 return arguments 820 } 821 class Foo {async foo() {}} 822 export default [ 823 foo, 824 Foo, 825 async function() {}, 826 async () => {}, 827 {async foo() {}}, 828 class {async foo() {}}, 829 function() { 830 return async (bar) => { 831 await bar 832 return [this, arguments] 833 } 834 }, 835 ] 836 `, 837 }, 838 entryPaths: []string{"/entry.js"}, 839 options: config.Options{ 840 UnsupportedJSFeatures: es(2017), 841 AbsOutputFile: "/out.js", 842 }, 843 }) 844 } 845 846 func TestLowerAsyncThis2016CommonJS(t *testing.T) { 847 lower_suite.expectBundled(t, bundled{ 848 files: map[string]string{ 849 "/entry.js": ` 850 exports.foo = async () => this 851 `, 852 }, 853 entryPaths: []string{"/entry.js"}, 854 options: config.Options{ 855 Mode: config.ModeBundle, 856 UnsupportedJSFeatures: es(2016), 857 AbsOutputFile: "/out.js", 858 }, 859 }) 860 } 861 862 func TestLowerAsyncThis2016ES6(t *testing.T) { 863 lower_suite.expectBundled(t, bundled{ 864 files: map[string]string{ 865 "/entry.js": ` 866 export {bar} from "./other" 867 export let foo = async () => this 868 `, 869 "/other.js": ` 870 export let bar = async () => {} 871 `, 872 }, 873 entryPaths: []string{"/entry.js"}, 874 options: config.Options{ 875 Mode: config.ModeBundle, 876 UnsupportedJSFeatures: es(2016), 877 AbsOutputFile: "/out.js", 878 }, 879 debugLogs: true, 880 expectedScanLog: `entry.js: DEBUG: Top-level "this" will be replaced with undefined since this file is an ECMAScript module 881 entry.js: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here: 882 `, 883 }) 884 } 885 886 func TestLowerAsyncES5(t *testing.T) { 887 lower_suite.expectBundled(t, bundled{ 888 files: map[string]string{ 889 "/entry.js": ` 890 import './fn-stmt' 891 import './fn-expr' 892 import './arrow-1' 893 import './arrow-2' 894 import './export-def-1' 895 import './export-def-2' 896 import './obj-method' 897 `, 898 "/fn-stmt.js": `async function foo() {}`, 899 "/fn-expr.js": `(async function() {})`, 900 "/arrow-1.js": `(async () => {})`, 901 "/arrow-2.js": `(async x => {})`, 902 "/export-def-1.js": `export default async function foo() {}`, 903 "/export-def-2.js": `export default async function() {}`, 904 "/obj-method.js": `({async foo() {}})`, 905 }, 906 entryPaths: []string{"/entry.js"}, 907 options: config.Options{ 908 Mode: config.ModeBundle, 909 UnsupportedJSFeatures: es(5), 910 AbsOutputFile: "/out.js", 911 }, 912 expectedScanLog: `arrow-1.js: ERROR: Transforming async functions to the configured target environment is not supported yet 913 arrow-2.js: ERROR: Transforming async functions to the configured target environment is not supported yet 914 export-def-1.js: ERROR: Transforming async functions to the configured target environment is not supported yet 915 export-def-2.js: ERROR: Transforming async functions to the configured target environment is not supported yet 916 fn-expr.js: ERROR: Transforming async functions to the configured target environment is not supported yet 917 fn-stmt.js: ERROR: Transforming async functions to the configured target environment is not supported yet 918 obj-method.js: ERROR: Transforming async functions to the configured target environment is not supported yet 919 `, 920 }) 921 } 922 923 func TestLowerAsyncSuperES2017NoBundle(t *testing.T) { 924 lower_suite.expectBundled(t, bundled{ 925 files: map[string]string{ 926 "/entry.js": ` 927 class Derived extends Base { 928 async test(key) { 929 return [ 930 await super.foo, 931 await super[key], 932 await ([super.foo] = [0]), 933 await ([super[key]] = [0]), 934 935 await (super.foo = 1), 936 await (super[key] = 1), 937 await (super.foo += 2), 938 await (super[key] += 2), 939 940 await ++super.foo, 941 await ++super[key], 942 await super.foo++, 943 await super[key]++, 944 945 await super.foo.name, 946 await super[key].name, 947 await super.foo?.name, 948 await super[key]?.name, 949 950 await super.foo(1, 2), 951 await super[key](1, 2), 952 await super.foo?.(1, 2), 953 await super[key]?.(1, 2), 954 955 await (() => super.foo)(), 956 await (() => super[key])(), 957 await (() => super.foo())(), 958 await (() => super[key]())(), 959 960 await super.foo` + "``" + `, 961 await super[key]` + "``" + `, 962 ] 963 } 964 } 965 966 // This covers a bug that caused a compiler crash 967 let fn = async () => class extends Base { 968 a = super.a 969 b = () => super.b 970 c() { return super.c } 971 d() { return () => super.d } 972 } 973 974 // This covers a bug that generated bad code 975 class Derived2 extends Base { 976 async a() { return class { [super.foo] = 123 } } 977 b = async () => class { [super.foo] = 123 } 978 } 979 980 // This covers putting the generated temporary variable inside the loop 981 for (let i = 0; i < 3; i++) { 982 objs.push({ 983 __proto__: { 984 foo() { return i }, 985 }, 986 async bar() { return super.foo() }, 987 }) 988 } 989 `, 990 }, 991 entryPaths: []string{"/entry.js"}, 992 options: config.Options{ 993 UnsupportedJSFeatures: es(2017), 994 AbsOutputFile: "/out.js", 995 }, 996 }) 997 } 998 999 func TestLowerAsyncSuperES2016NoBundle(t *testing.T) { 1000 lower_suite.expectBundled(t, bundled{ 1001 files: map[string]string{ 1002 "/entry.js": ` 1003 class Derived extends Base { 1004 async test(key) { 1005 return [ 1006 await super.foo, 1007 await super[key], 1008 await ([super.foo] = [0]), 1009 await ([super[key]] = [0]), 1010 1011 await (super.foo = 1), 1012 await (super[key] = 1), 1013 await (super.foo += 2), 1014 await (super[key] += 2), 1015 1016 await ++super.foo, 1017 await ++super[key], 1018 await super.foo++, 1019 await super[key]++, 1020 1021 await super.foo.name, 1022 await super[key].name, 1023 await super.foo?.name, 1024 await super[key]?.name, 1025 1026 await super.foo(1, 2), 1027 await super[key](1, 2), 1028 await super.foo?.(1, 2), 1029 await super[key]?.(1, 2), 1030 1031 await (() => super.foo)(), 1032 await (() => super[key])(), 1033 await (() => super.foo())(), 1034 await (() => super[key]())(), 1035 1036 await super.foo` + "``" + `, 1037 await super[key]` + "``" + `, 1038 ] 1039 } 1040 } 1041 1042 // This covers a bug that caused a compiler crash 1043 let fn = async () => class extends Base { 1044 a = super.a 1045 b = () => super.b 1046 c() { return super.c } 1047 d() { return () => super.d } 1048 } 1049 1050 // This covers a bug that generated bad code 1051 class Derived2 extends Base { 1052 async a() { return class { [super.foo] = 123 } } 1053 b = async () => class { [super.foo] = 123 } 1054 } 1055 1056 // This covers putting the generated temporary variable inside the loop 1057 for (let i = 0; i < 3; i++) { 1058 objs.push({ 1059 __proto__: { 1060 foo() { return i }, 1061 }, 1062 async bar() { return super.foo() }, 1063 }) 1064 } 1065 `, 1066 }, 1067 entryPaths: []string{"/entry.js"}, 1068 options: config.Options{ 1069 UnsupportedJSFeatures: es(2016), 1070 AbsOutputFile: "/out.js", 1071 }, 1072 }) 1073 } 1074 1075 func TestLowerStaticAsyncSuperES2021NoBundle(t *testing.T) { 1076 lower_suite.expectBundled(t, bundled{ 1077 files: map[string]string{ 1078 "/entry.js": ` 1079 class Derived extends Base { 1080 static test = async (key) => { 1081 return [ 1082 await super.foo, 1083 await super[key], 1084 await ([super.foo] = [0]), 1085 await ([super[key]] = [0]), 1086 1087 await (super.foo = 1), 1088 await (super[key] = 1), 1089 await (super.foo += 2), 1090 await (super[key] += 2), 1091 1092 await ++super.foo, 1093 await ++super[key], 1094 await super.foo++, 1095 await super[key]++, 1096 1097 await super.foo.name, 1098 await super[key].name, 1099 await super.foo?.name, 1100 await super[key]?.name, 1101 1102 await super.foo(1, 2), 1103 await super[key](1, 2), 1104 await super.foo?.(1, 2), 1105 await super[key]?.(1, 2), 1106 1107 await (() => super.foo)(), 1108 await (() => super[key])(), 1109 await (() => super.foo())(), 1110 await (() => super[key]())(), 1111 1112 await super.foo` + "``" + `, 1113 await super[key]` + "``" + `, 1114 ] 1115 } 1116 } 1117 1118 // This covers a bug that caused a compiler crash 1119 let fn = async () => class extends Base { 1120 static a = super.a 1121 static b = () => super.b 1122 static c() { return super.c } 1123 static d() { return () => super.d } 1124 } 1125 1126 // This covers a bug that generated bad code 1127 class Derived2 extends Base { 1128 static async a() { return class { [super.foo] = 123 } } 1129 static b = async () => class { [super.foo] = 123 } 1130 } 1131 `, 1132 }, 1133 entryPaths: []string{"/entry.js"}, 1134 options: config.Options{ 1135 UnsupportedJSFeatures: es(2021), 1136 AbsOutputFile: "/out.js", 1137 }, 1138 }) 1139 } 1140 1141 func TestLowerStaticAsyncSuperES2016NoBundle(t *testing.T) { 1142 lower_suite.expectBundled(t, bundled{ 1143 files: map[string]string{ 1144 "/entry.js": ` 1145 class Derived extends Base { 1146 static test = async (key) => { 1147 return [ 1148 await super.foo, 1149 await super[key], 1150 await ([super.foo] = [0]), 1151 await ([super[key]] = [0]), 1152 1153 await (super.foo = 1), 1154 await (super[key] = 1), 1155 await (super.foo += 2), 1156 await (super[key] += 2), 1157 1158 await ++super.foo, 1159 await ++super[key], 1160 await super.foo++, 1161 await super[key]++, 1162 1163 await super.foo.name, 1164 await super[key].name, 1165 await super.foo?.name, 1166 await super[key]?.name, 1167 1168 await super.foo(1, 2), 1169 await super[key](1, 2), 1170 await super.foo?.(1, 2), 1171 await super[key]?.(1, 2), 1172 1173 await (() => super.foo)(), 1174 await (() => super[key])(), 1175 await (() => super.foo())(), 1176 await (() => super[key]())(), 1177 1178 await super.foo` + "``" + `, 1179 await super[key]` + "``" + `, 1180 ] 1181 } 1182 } 1183 1184 // This covers a bug that caused a compiler crash 1185 let fn = async () => class extends Base { 1186 static a = super.a 1187 static b = () => super.b 1188 static c() { return super.c } 1189 static d() { return () => super.d } 1190 } 1191 1192 // This covers a bug that generated bad code 1193 class Derived2 extends Base { 1194 static async a() { return class { [super.foo] = 123 } } 1195 static b = async () => class { [super.foo] = 123 } 1196 } 1197 `, 1198 }, 1199 entryPaths: []string{"/entry.js"}, 1200 options: config.Options{ 1201 UnsupportedJSFeatures: es(2016), 1202 AbsOutputFile: "/out.js", 1203 }, 1204 }) 1205 } 1206 1207 func TestLowerStaticSuperES2021NoBundle(t *testing.T) { 1208 lower_suite.expectBundled(t, bundled{ 1209 files: map[string]string{ 1210 "/entry.js": ` 1211 class Derived extends Base { 1212 static test = key => { 1213 return [ 1214 super.foo, 1215 super[key], 1216 ([super.foo] = [0]), 1217 ([super[key]] = [0]), 1218 1219 (super.foo = 1), 1220 (super[key] = 1), 1221 (super.foo += 2), 1222 (super[key] += 2), 1223 1224 ++super.foo, 1225 ++super[key], 1226 super.foo++, 1227 super[key]++, 1228 1229 super.foo.name, 1230 super[key].name, 1231 super.foo?.name, 1232 super[key]?.name, 1233 1234 super.foo(1, 2), 1235 super[key](1, 2), 1236 super.foo?.(1, 2), 1237 super[key]?.(1, 2), 1238 1239 (() => super.foo)(), 1240 (() => super[key])(), 1241 (() => super.foo())(), 1242 (() => super[key]())(), 1243 1244 super.foo` + "``" + `, 1245 super[key]` + "``" + `, 1246 ] 1247 } 1248 } 1249 `, 1250 }, 1251 entryPaths: []string{"/entry.js"}, 1252 options: config.Options{ 1253 UnsupportedJSFeatures: es(2021), 1254 AbsOutputFile: "/out.js", 1255 }, 1256 }) 1257 } 1258 1259 func TestLowerStaticSuperES2016NoBundle(t *testing.T) { 1260 lower_suite.expectBundled(t, bundled{ 1261 files: map[string]string{ 1262 "/entry.js": ` 1263 class Derived extends Base { 1264 static test = key => { 1265 return [ 1266 super.foo, 1267 super[key], 1268 ([super.foo] = [0]), 1269 ([super[key]] = [0]), 1270 1271 (super.foo = 1), 1272 (super[key] = 1), 1273 (super.foo += 2), 1274 (super[key] += 2), 1275 1276 ++super.foo, 1277 ++super[key], 1278 super.foo++, 1279 super[key]++, 1280 1281 super.foo.name, 1282 super[key].name, 1283 super.foo?.name, 1284 super[key]?.name, 1285 1286 super.foo(1, 2), 1287 super[key](1, 2), 1288 super.foo?.(1, 2), 1289 super[key]?.(1, 2), 1290 1291 (() => super.foo)(), 1292 (() => super[key])(), 1293 (() => super.foo())(), 1294 (() => super[key]())(), 1295 1296 super.foo` + "``" + `, 1297 super[key]` + "``" + `, 1298 ] 1299 } 1300 } 1301 `, 1302 }, 1303 entryPaths: []string{"/entry.js"}, 1304 options: config.Options{ 1305 UnsupportedJSFeatures: es(2016), 1306 AbsOutputFile: "/out.js", 1307 }, 1308 }) 1309 } 1310 1311 func TestLowerAsyncArrowSuperES2016(t *testing.T) { 1312 lower_suite.expectBundled(t, bundled{ 1313 files: map[string]string{ 1314 "/entry.js": ` 1315 export { default as foo1 } from "./foo1" 1316 export { default as foo2 } from "./foo2" 1317 export { default as foo3 } from "./foo3" 1318 export { default as foo4 } from "./foo4" 1319 export { default as bar1 } from "./bar1" 1320 export { default as bar2 } from "./bar2" 1321 export { default as bar3 } from "./bar3" 1322 export { default as bar4 } from "./bar4" 1323 export { default as baz1 } from "./baz1" 1324 export { default as baz2 } from "./baz2" 1325 import "./outer" 1326 `, 1327 "/foo1.js": `export default class extends x { foo1() { return async () => super.foo('foo1') } }`, 1328 "/foo2.js": `export default class extends x { foo2() { return async () => () => super.foo('foo2') } }`, 1329 "/foo3.js": `export default class extends x { foo3() { return () => async () => super.foo('foo3') } }`, 1330 "/foo4.js": `export default class extends x { foo4() { return async () => async () => super.foo('foo4') } }`, 1331 "/bar1.js": `export default class extends x { bar1 = async () => super.foo('bar1') }`, 1332 "/bar2.js": `export default class extends x { bar2 = async () => () => super.foo('bar2') }`, 1333 "/bar3.js": `export default class extends x { bar3 = () => async () => super.foo('bar3') }`, 1334 "/bar4.js": `export default class extends x { bar4 = async () => async () => super.foo('bar4') }`, 1335 "/baz1.js": `export default class extends x { async baz1() { return () => super.foo('baz1') } }`, 1336 "/baz2.js": `export default class extends x { async baz2() { return () => () => super.foo('baz2') } }`, 1337 "/outer.js": ` 1338 // Helper functions for "super" shouldn't be inserted into this outer function 1339 export default (async function () { 1340 class y extends z { 1341 foo = async () => super.foo() 1342 } 1343 await new y().foo()() 1344 })() 1345 `, 1346 }, 1347 entryPaths: []string{"/entry.js"}, 1348 options: config.Options{ 1349 Mode: config.ModeBundle, 1350 UnsupportedJSFeatures: es(2016), 1351 AbsOutputFile: "/out.js", 1352 }, 1353 }) 1354 } 1355 1356 func TestLowerAsyncArrowSuperSetterES2016(t *testing.T) { 1357 lower_suite.expectBundled(t, bundled{ 1358 files: map[string]string{ 1359 "/entry.js": ` 1360 export { default as foo1 } from "./foo1" 1361 export { default as foo2 } from "./foo2" 1362 export { default as foo3 } from "./foo3" 1363 export { default as foo4 } from "./foo4" 1364 export { default as bar1 } from "./bar1" 1365 export { default as bar2 } from "./bar2" 1366 export { default as bar3 } from "./bar3" 1367 export { default as bar4 } from "./bar4" 1368 export { default as baz1 } from "./baz1" 1369 export { default as baz2 } from "./baz2" 1370 import "./outer" 1371 `, 1372 "/foo1.js": `export default class extends x { foo1() { return async () => super.foo = 'foo1' } }`, 1373 "/foo2.js": `export default class extends x { foo2() { return async () => () => super.foo = 'foo2' } }`, 1374 "/foo3.js": `export default class extends x { foo3() { return () => async () => super.foo = 'foo3' } }`, 1375 "/foo4.js": `export default class extends x { foo4() { return async () => async () => super.foo = 'foo4' } }`, 1376 "/bar1.js": `export default class extends x { bar1 = async () => super.foo = 'bar1' }`, 1377 "/bar2.js": `export default class extends x { bar2 = async () => () => super.foo = 'bar2' }`, 1378 "/bar3.js": `export default class extends x { bar3 = () => async () => super.foo = 'bar3' }`, 1379 "/bar4.js": `export default class extends x { bar4 = async () => async () => super.foo = 'bar4' }`, 1380 "/baz1.js": `export default class extends x { async baz1() { return () => super.foo = 'baz1' } }`, 1381 "/baz2.js": `export default class extends x { async baz2() { return () => () => super.foo = 'baz2' } }`, 1382 "/outer.js": ` 1383 // Helper functions for "super" shouldn't be inserted into this outer function 1384 export default (async function () { 1385 class y extends z { 1386 foo = async () => super.foo = 'foo' 1387 } 1388 await new y().foo()() 1389 })() 1390 `, 1391 }, 1392 entryPaths: []string{"/entry.js"}, 1393 options: config.Options{ 1394 Mode: config.ModeBundle, 1395 UnsupportedJSFeatures: es(2016), 1396 AbsOutputFile: "/out.js", 1397 }, 1398 }) 1399 } 1400 1401 func TestLowerStaticAsyncArrowSuperES2016(t *testing.T) { 1402 lower_suite.expectBundled(t, bundled{ 1403 files: map[string]string{ 1404 "/entry.js": ` 1405 export { default as foo1 } from "./foo1" 1406 export { default as foo2 } from "./foo2" 1407 export { default as foo3 } from "./foo3" 1408 export { default as foo4 } from "./foo4" 1409 export { default as bar1 } from "./bar1" 1410 export { default as bar2 } from "./bar2" 1411 export { default as bar3 } from "./bar3" 1412 export { default as bar4 } from "./bar4" 1413 export { default as baz1 } from "./baz1" 1414 export { default as baz2 } from "./baz2" 1415 import "./outer" 1416 `, 1417 "/foo1.js": `export default class extends x { static foo1() { return async () => super.foo('foo1') } }`, 1418 "/foo2.js": `export default class extends x { static foo2() { return async () => () => super.foo('foo2') } }`, 1419 "/foo3.js": `export default class extends x { static foo3() { return () => async () => super.foo('foo3') } }`, 1420 "/foo4.js": `export default class extends x { static foo4() { return async () => async () => super.foo('foo4') } }`, 1421 "/bar1.js": `export default class extends x { static bar1 = async () => super.foo('bar1') }`, 1422 "/bar2.js": `export default class extends x { static bar2 = async () => () => super.foo('bar2') }`, 1423 "/bar3.js": `export default class extends x { static bar3 = () => async () => super.foo('bar3') }`, 1424 "/bar4.js": `export default class extends x { static bar4 = async () => async () => super.foo('bar4') }`, 1425 "/baz1.js": `export default class extends x { static async baz1() { return () => super.foo('baz1') } }`, 1426 "/baz2.js": `export default class extends x { static async baz2() { return () => () => super.foo('baz2') } }`, 1427 "/outer.js": ` 1428 // Helper functions for "super" shouldn't be inserted into this outer function 1429 export default (async function () { 1430 class y extends z { 1431 static foo = async () => super.foo() 1432 } 1433 await y.foo()() 1434 })() 1435 `, 1436 }, 1437 entryPaths: []string{"/entry.js"}, 1438 options: config.Options{ 1439 Mode: config.ModeBundle, 1440 UnsupportedJSFeatures: es(2016), 1441 AbsOutputFile: "/out.js", 1442 }, 1443 }) 1444 } 1445 1446 func TestLowerStaticAsyncArrowSuperSetterES2016(t *testing.T) { 1447 lower_suite.expectBundled(t, bundled{ 1448 files: map[string]string{ 1449 "/entry.js": ` 1450 export { default as foo1 } from "./foo1" 1451 export { default as foo2 } from "./foo2" 1452 export { default as foo3 } from "./foo3" 1453 export { default as foo4 } from "./foo4" 1454 export { default as bar1 } from "./bar1" 1455 export { default as bar2 } from "./bar2" 1456 export { default as bar3 } from "./bar3" 1457 export { default as bar4 } from "./bar4" 1458 export { default as baz1 } from "./baz1" 1459 export { default as baz2 } from "./baz2" 1460 import "./outer" 1461 `, 1462 "/foo1.js": `export default class extends x { static foo1() { return async () => super.foo = 'foo1' } }`, 1463 "/foo2.js": `export default class extends x { static foo2() { return async () => () => super.foo = 'foo2' } }`, 1464 "/foo3.js": `export default class extends x { static foo3() { return () => async () => super.foo = 'foo3' } }`, 1465 "/foo4.js": `export default class extends x { static foo4() { return async () => async () => super.foo = 'foo4' } }`, 1466 "/bar1.js": `export default class extends x { static bar1 = async () => super.foo = 'bar1' }`, 1467 "/bar2.js": `export default class extends x { static bar2 = async () => () => super.foo = 'bar2' }`, 1468 "/bar3.js": `export default class extends x { static bar3 = () => async () => super.foo = 'bar3' }`, 1469 "/bar4.js": `export default class extends x { static bar4 = async () => async () => super.foo = 'bar4' }`, 1470 "/baz1.js": `export default class extends x { static async baz1() { return () => super.foo = 'baz1' } }`, 1471 "/baz2.js": `export default class extends x { static async baz2() { return () => () => super.foo = 'baz2' } }`, 1472 "/outer.js": ` 1473 // Helper functions for "super" shouldn't be inserted into this outer function 1474 export default (async function () { 1475 class y extends z { 1476 static foo = async () => super.foo = 'foo' 1477 } 1478 await y.foo()() 1479 })() 1480 `, 1481 }, 1482 entryPaths: []string{"/entry.js"}, 1483 options: config.Options{ 1484 Mode: config.ModeBundle, 1485 UnsupportedJSFeatures: es(2016), 1486 AbsOutputFile: "/out.js", 1487 }, 1488 }) 1489 } 1490 1491 func TestLowerPrivateSuperES2022(t *testing.T) { 1492 lower_suite.expectBundled(t, bundled{ 1493 files: map[string]string{ 1494 "/entry.js": ` 1495 export { default as foo1 } from "./foo1" 1496 export { default as foo2 } from "./foo2" 1497 export { default as foo3 } from "./foo3" 1498 export { default as foo4 } from "./foo4" 1499 export { default as foo5 } from "./foo5" 1500 export { default as foo6 } from "./foo6" 1501 export { default as foo7 } from "./foo7" 1502 export { default as foo8 } from "./foo8" 1503 `, 1504 "/foo1.js": `export default class extends x { #foo() { super.foo() } }`, 1505 "/foo2.js": `export default class extends x { #foo() { super.foo++ } }`, 1506 "/foo3.js": `export default class extends x { static #foo() { super.foo() } }`, 1507 "/foo4.js": `export default class extends x { static #foo() { super.foo++ } }`, 1508 "/foo5.js": `export default class extends x { #foo = () => { super.foo() } }`, 1509 "/foo6.js": `export default class extends x { #foo = () => { super.foo++ } }`, 1510 "/foo7.js": `export default class extends x { static #foo = () => { super.foo() } }`, 1511 "/foo8.js": `export default class extends x { static #foo = () => { super.foo++ } }`, 1512 }, 1513 entryPaths: []string{"/entry.js"}, 1514 options: config.Options{ 1515 Mode: config.ModeBundle, 1516 UnsupportedJSFeatures: es(2022), 1517 AbsOutputFile: "/out.js", 1518 }, 1519 }) 1520 } 1521 1522 func TestLowerPrivateSuperES2021(t *testing.T) { 1523 lower_suite.expectBundled(t, bundled{ 1524 files: map[string]string{ 1525 "/entry.js": ` 1526 export { default as foo1 } from "./foo1" 1527 export { default as foo2 } from "./foo2" 1528 export { default as foo3 } from "./foo3" 1529 export { default as foo4 } from "./foo4" 1530 export { default as foo5 } from "./foo5" 1531 export { default as foo6 } from "./foo6" 1532 export { default as foo7 } from "./foo7" 1533 export { default as foo8 } from "./foo8" 1534 `, 1535 "/foo1.js": `export default class extends x { #foo() { super.foo() } }`, 1536 "/foo2.js": `export default class extends x { #foo() { super.foo++ } }`, 1537 "/foo3.js": `export default class extends x { static #foo() { super.foo() } }`, 1538 "/foo4.js": `export default class extends x { static #foo() { super.foo++ } }`, 1539 "/foo5.js": `export default class extends x { #foo = () => { super.foo() } }`, 1540 "/foo6.js": `export default class extends x { #foo = () => { super.foo++ } }`, 1541 "/foo7.js": `export default class extends x { static #foo = () => { super.foo() } }`, 1542 "/foo8.js": `export default class extends x { static #foo = () => { super.foo++ } }`, 1543 }, 1544 entryPaths: []string{"/entry.js"}, 1545 options: config.Options{ 1546 Mode: config.ModeBundle, 1547 UnsupportedJSFeatures: es(2021), 1548 AbsOutputFile: "/out.js", 1549 }, 1550 }) 1551 } 1552 1553 // https://github.com/evanw/esbuild/issues/2158 1554 func TestLowerPrivateSuperStaticBundleIssue2158(t *testing.T) { 1555 lower_suite.expectBundled(t, bundled{ 1556 files: map[string]string{ 1557 "/entry.js": ` 1558 export class Foo extends Object { 1559 static FOO; 1560 constructor() { 1561 super(); 1562 } 1563 #foo; 1564 } 1565 `, 1566 }, 1567 entryPaths: []string{"/entry.js"}, 1568 options: config.Options{ 1569 Mode: config.ModeBundle, 1570 AbsOutputFile: "/out.js", 1571 }, 1572 }) 1573 } 1574 1575 func TestLowerClassField2020NoBundle(t *testing.T) { 1576 lower_suite.expectBundled(t, bundled{ 1577 files: map[string]string{ 1578 "/entry.js": ` 1579 class Foo { 1580 #foo = 123 1581 #bar 1582 foo = 123 1583 bar 1584 static #s_foo = 123 1585 static #s_bar 1586 static s_foo = 123 1587 static s_bar 1588 } 1589 `, 1590 }, 1591 entryPaths: []string{"/entry.js"}, 1592 options: config.Options{ 1593 UnsupportedJSFeatures: es(2020), 1594 AbsOutputFile: "/out.js", 1595 }, 1596 }) 1597 } 1598 1599 func TestLowerClassFieldNextNoBundle(t *testing.T) { 1600 lower_suite.expectBundled(t, bundled{ 1601 files: map[string]string{ 1602 "/entry.js": ` 1603 class Foo { 1604 #foo = 123 1605 #bar 1606 foo = 123 1607 bar 1608 static #s_foo = 123 1609 static #s_bar 1610 static s_foo = 123 1611 static s_bar 1612 } 1613 `, 1614 }, 1615 entryPaths: []string{"/entry.js"}, 1616 options: config.Options{ 1617 AbsOutputFile: "/out.js", 1618 }, 1619 }) 1620 } 1621 1622 func TestTSLowerClassField2020NoBundle(t *testing.T) { 1623 lower_suite.expectBundled(t, bundled{ 1624 files: map[string]string{ 1625 "/entry.ts": ` 1626 class Foo { 1627 #foo = 123 1628 #bar 1629 foo = 123 1630 bar 1631 static #s_foo = 123 1632 static #s_bar 1633 static s_foo = 123 1634 static s_bar 1635 } 1636 `, 1637 "/tsconfig.json": `{ 1638 "compilerOptions": { 1639 "useDefineForClassFields": false 1640 } 1641 }`, 1642 }, 1643 entryPaths: []string{"/entry.ts"}, 1644 options: config.Options{ 1645 UnsupportedJSFeatures: es(2020), 1646 AbsOutputFile: "/out.js", 1647 }, 1648 }) 1649 } 1650 1651 func TestTSLowerClassPrivateFieldNextNoBundle(t *testing.T) { 1652 lower_suite.expectBundled(t, bundled{ 1653 files: map[string]string{ 1654 "/entry.ts": ` 1655 class Foo { 1656 #foo = 123 1657 #bar 1658 foo = 123 1659 bar 1660 static #s_foo = 123 1661 static #s_bar 1662 static s_foo = 123 1663 static s_bar 1664 } 1665 `, 1666 "/tsconfig.json": `{ 1667 "compilerOptions": { 1668 "useDefineForClassFields": false 1669 } 1670 }`, 1671 }, 1672 entryPaths: []string{"/entry.ts"}, 1673 options: config.Options{ 1674 AbsOutputFile: "/out.js", 1675 }, 1676 }) 1677 } 1678 1679 func TestLowerClassFieldStrictTsconfigJson2020(t *testing.T) { 1680 lower_suite.expectBundled(t, bundled{ 1681 files: map[string]string{ 1682 "/entry.js": ` 1683 import loose from './loose' 1684 import strict from './strict' 1685 console.log(loose, strict) 1686 `, 1687 "/loose/index.js": ` 1688 export default class { 1689 foo 1690 } 1691 `, 1692 "/loose/tsconfig.json": ` 1693 { 1694 "compilerOptions": { 1695 "useDefineForClassFields": false 1696 } 1697 } 1698 `, 1699 "/strict/index.js": ` 1700 export default class { 1701 foo 1702 } 1703 `, 1704 "/strict/tsconfig.json": ` 1705 { 1706 "compilerOptions": { 1707 "useDefineForClassFields": true 1708 } 1709 } 1710 `, 1711 }, 1712 entryPaths: []string{"/entry.js"}, 1713 options: config.Options{ 1714 Mode: config.ModeBundle, 1715 UnsupportedJSFeatures: es(2020), 1716 AbsOutputFile: "/out.js", 1717 }, 1718 }) 1719 } 1720 1721 func TestTSLowerClassFieldStrictTsconfigJson2020(t *testing.T) { 1722 lower_suite.expectBundled(t, bundled{ 1723 files: map[string]string{ 1724 "/entry.js": ` 1725 import loose from './loose' 1726 import strict from './strict' 1727 console.log(loose, strict) 1728 `, 1729 "/loose/index.ts": ` 1730 export default class { 1731 foo 1732 } 1733 `, 1734 "/loose/tsconfig.json": ` 1735 { 1736 "compilerOptions": { 1737 "useDefineForClassFields": false 1738 } 1739 } 1740 `, 1741 "/strict/index.ts": ` 1742 export default class { 1743 foo 1744 } 1745 `, 1746 "/strict/tsconfig.json": ` 1747 { 1748 "compilerOptions": { 1749 "useDefineForClassFields": true 1750 } 1751 } 1752 `, 1753 }, 1754 entryPaths: []string{"/entry.js"}, 1755 options: config.Options{ 1756 Mode: config.ModeBundle, 1757 UnsupportedJSFeatures: es(2020), 1758 AbsOutputFile: "/out.js", 1759 }, 1760 }) 1761 } 1762 1763 func TestTSLowerObjectRest2017NoBundle(t *testing.T) { 1764 lower_suite.expectBundled(t, bundled{ 1765 files: map[string]string{ 1766 "/entry.ts": ` 1767 const { ...local_const } = {}; 1768 let { ...local_let } = {}; 1769 var { ...local_var } = {}; 1770 let arrow_fn = ({ ...x }) => { }; 1771 let fn_expr = function ({ ...x } = default_value) {}; 1772 let class_expr = class { method(x, ...[y, { ...z }]) {} }; 1773 1774 function fn_stmt({ a = b(), ...x }, { c = d(), ...y }) {} 1775 class class_stmt { method({ ...x }) {} } 1776 namespace ns { export let { ...x } = {} } 1777 try { } catch ({ ...catch_clause }) {} 1778 1779 for (const { ...for_in_const } in { abc }) {} 1780 for (let { ...for_in_let } in { abc }) {} 1781 for (var { ...for_in_var } in { abc }) ; 1782 for (const { ...for_of_const } of [{}]) ; 1783 for (let { ...for_of_let } of [{}]) x() 1784 for (var { ...for_of_var } of [{}]) x() 1785 for (const { ...for_const } = {}; x; x = null) {} 1786 for (let { ...for_let } = {}; x; x = null) {} 1787 for (var { ...for_var } = {}; x; x = null) {} 1788 for ({ ...x } in { abc }) {} 1789 for ({ ...x } of [{}]) {} 1790 for ({ ...x } = {}; x; x = null) {} 1791 1792 ({ ...assign } = {}); 1793 ({ obj_method({ ...x }) {} }); 1794 1795 // Check for used return values 1796 ({ ...x } = x); 1797 for ({ ...x } = x; 0; ) ; 1798 console.log({ ...x } = x); 1799 console.log({ x, ...xx } = { x }); 1800 console.log({ x: { ...xx } } = { x }); 1801 `, 1802 }, 1803 entryPaths: []string{"/entry.ts"}, 1804 options: config.Options{ 1805 UnsupportedJSFeatures: es(2017), 1806 AbsOutputFile: "/out.js", 1807 }, 1808 }) 1809 } 1810 1811 func TestTSLowerObjectRest2018NoBundle(t *testing.T) { 1812 lower_suite.expectBundled(t, bundled{ 1813 files: map[string]string{ 1814 "/entry.ts": ` 1815 const { ...local_const } = {}; 1816 let { ...local_let } = {}; 1817 var { ...local_var } = {}; 1818 let arrow_fn = ({ ...x }) => { }; 1819 let fn_expr = function ({ ...x } = default_value) {}; 1820 let class_expr = class { method(x, ...[y, { ...z }]) {} }; 1821 1822 function fn_stmt({ a = b(), ...x }, { c = d(), ...y }) {} 1823 class class_stmt { method({ ...x }) {} } 1824 namespace ns { export let { ...x } = {} } 1825 try { } catch ({ ...catch_clause }) {} 1826 1827 for (const { ...for_in_const } in { abc }) {} 1828 for (let { ...for_in_let } in { abc }) {} 1829 for (var { ...for_in_var } in { abc }) ; 1830 for (const { ...for_of_const } of [{}]) ; 1831 for (let { ...for_of_let } of [{}]) x() 1832 for (var { ...for_of_var } of [{}]) x() 1833 for (const { ...for_const } = {}; x; x = null) {} 1834 for (let { ...for_let } = {}; x; x = null) {} 1835 for (var { ...for_var } = {}; x; x = null) {} 1836 for ({ ...x } in { abc }) {} 1837 for ({ ...x } of [{}]) {} 1838 for ({ ...x } = {}; x; x = null) {} 1839 1840 ({ ...assign } = {}); 1841 ({ obj_method({ ...x }) {} }); 1842 1843 // Check for used return values 1844 ({ ...x } = x); 1845 for ({ ...x } = x; 0; ) ; 1846 console.log({ ...x } = x); 1847 console.log({ x, ...xx } = { x }); 1848 console.log({ x: { ...xx } } = { x }); 1849 `, 1850 }, 1851 entryPaths: []string{"/entry.ts"}, 1852 options: config.Options{ 1853 UnsupportedJSFeatures: es(2018), 1854 AbsOutputFile: "/out.js", 1855 }, 1856 }) 1857 } 1858 1859 func TestClassSuperThisIssue242NoBundle(t *testing.T) { 1860 lower_suite.expectBundled(t, bundled{ 1861 files: map[string]string{ 1862 "/entry.ts": ` 1863 export class A {} 1864 1865 export class B extends A { 1866 #e: string 1867 constructor(c: { d: any }) { 1868 super() 1869 this.#e = c.d ?? 'test' 1870 } 1871 f() { 1872 return this.#e 1873 } 1874 } 1875 `, 1876 }, 1877 entryPaths: []string{"/entry.ts"}, 1878 options: config.Options{ 1879 UnsupportedJSFeatures: es(2019), 1880 AbsOutputFile: "/out.js", 1881 }, 1882 }) 1883 } 1884 1885 func TestLowerExportStarAsNameCollisionNoBundle(t *testing.T) { 1886 lower_suite.expectBundled(t, bundled{ 1887 files: map[string]string{ 1888 "/entry.js": ` 1889 export * as ns from 'path' 1890 let ns = 123 1891 export {ns as sn} 1892 `, 1893 }, 1894 entryPaths: []string{"/entry.js"}, 1895 options: config.Options{ 1896 UnsupportedJSFeatures: es(2019), 1897 AbsOutputFile: "/out.js", 1898 }, 1899 }) 1900 } 1901 1902 func TestLowerExportStarAsNameCollision(t *testing.T) { 1903 lower_suite.expectBundled(t, bundled{ 1904 files: map[string]string{ 1905 "/entry.js": ` 1906 import * as test from './nested' 1907 console.log(test.foo, test.oof) 1908 export * as ns from 'path1' 1909 let ns = 123 1910 export {ns as sn} 1911 `, 1912 "/nested.js": ` 1913 export * as foo from 'path2' 1914 let foo = 123 1915 export {foo as oof} 1916 `, 1917 }, 1918 entryPaths: []string{"/entry.js"}, 1919 options: config.Options{ 1920 Mode: config.ModeBundle, 1921 UnsupportedJSFeatures: es(2019), 1922 AbsOutputFile: "/out.js", 1923 ExternalSettings: config.ExternalSettings{ 1924 PreResolve: config.ExternalMatchers{Exact: map[string]bool{ 1925 "path1": true, 1926 "path2": true, 1927 }}, 1928 }, 1929 }, 1930 }) 1931 } 1932 1933 func TestLowerStrictModeSyntax(t *testing.T) { 1934 lower_suite.expectBundled(t, bundled{ 1935 files: map[string]string{ 1936 "/entry.js": ` 1937 import './for-in' 1938 `, 1939 "/for-in.js": ` 1940 if (test) 1941 for (var a = b in {}) ; 1942 for (var x = y in {}) ; 1943 `, 1944 }, 1945 entryPaths: []string{"/entry.js"}, 1946 options: config.Options{ 1947 Mode: config.ModeBundle, 1948 OutputFormat: config.FormatESModule, 1949 AbsOutputFile: "/out.js", 1950 }, 1951 }) 1952 } 1953 1954 func TestLowerForbidStrictModeSyntax(t *testing.T) { 1955 lower_suite.expectBundled(t, bundled{ 1956 files: map[string]string{ 1957 "/entry.js": ` 1958 import './with' 1959 import './delete-1' 1960 import './delete-2' 1961 import './delete-3' 1962 `, 1963 "/with.js": ` 1964 with (x) y 1965 `, 1966 "/delete-1.js": ` 1967 delete x 1968 `, 1969 "/delete-2.js": ` 1970 delete (y) 1971 `, 1972 "/delete-3.js": ` 1973 delete (1 ? z : z) 1974 `, 1975 }, 1976 entryPaths: []string{"/entry.js"}, 1977 options: config.Options{ 1978 Mode: config.ModeBundle, 1979 OutputFormat: config.FormatESModule, 1980 AbsOutputFile: "/out.js", 1981 }, 1982 expectedScanLog: `delete-1.js: ERROR: Delete of a bare identifier cannot be used with the "esm" output format due to strict mode 1983 delete-2.js: ERROR: Delete of a bare identifier cannot be used with the "esm" output format due to strict mode 1984 with.js: ERROR: With statements cannot be used with the "esm" output format due to strict mode 1985 `, 1986 }) 1987 } 1988 1989 func TestLowerPrivateClassFieldOrder(t *testing.T) { 1990 lower_suite.expectBundled(t, bundled{ 1991 files: map[string]string{ 1992 "/entry.js": ` 1993 class Foo { 1994 #foo = 123 // This must be set before "bar" is initialized 1995 bar = this.#foo 1996 } 1997 console.log(new Foo().bar === 123) 1998 `, 1999 }, 2000 entryPaths: []string{"/entry.js"}, 2001 options: config.Options{ 2002 Mode: config.ModePassThrough, 2003 AbsOutputFile: "/out.js", 2004 UnsupportedJSFeatures: compat.ClassPrivateField, 2005 }, 2006 }) 2007 } 2008 2009 func TestLowerPrivateClassMethodOrder(t *testing.T) { 2010 lower_suite.expectBundled(t, bundled{ 2011 files: map[string]string{ 2012 "/entry.js": ` 2013 class Foo { 2014 bar = this.#foo() 2015 #foo() { return 123 } // This must be set before "bar" is initialized 2016 } 2017 console.log(new Foo().bar === 123) 2018 `, 2019 }, 2020 entryPaths: []string{"/entry.js"}, 2021 options: config.Options{ 2022 Mode: config.ModePassThrough, 2023 AbsOutputFile: "/out.js", 2024 UnsupportedJSFeatures: compat.ClassPrivateMethod, 2025 }, 2026 }) 2027 } 2028 2029 func TestLowerPrivateClassAccessorOrder(t *testing.T) { 2030 lower_suite.expectBundled(t, bundled{ 2031 files: map[string]string{ 2032 "/entry.js": ` 2033 class Foo { 2034 bar = this.#foo 2035 get #foo() { return 123 } // This must be set before "bar" is initialized 2036 } 2037 console.log(new Foo().bar === 123) 2038 `, 2039 }, 2040 entryPaths: []string{"/entry.js"}, 2041 options: config.Options{ 2042 Mode: config.ModePassThrough, 2043 AbsOutputFile: "/out.js", 2044 UnsupportedJSFeatures: compat.ClassPrivateAccessor, 2045 }, 2046 }) 2047 } 2048 2049 func TestLowerPrivateClassStaticFieldOrder(t *testing.T) { 2050 lower_suite.expectBundled(t, bundled{ 2051 files: map[string]string{ 2052 "/entry.js": ` 2053 class Foo { 2054 static #foo = 123 // This must be set before "bar" is initialized 2055 static bar = Foo.#foo 2056 } 2057 console.log(Foo.bar === 123) 2058 2059 class FooThis { 2060 static #foo = 123 // This must be set before "bar" is initialized 2061 static bar = this.#foo 2062 } 2063 console.log(FooThis.bar === 123) 2064 `, 2065 }, 2066 entryPaths: []string{"/entry.js"}, 2067 options: config.Options{ 2068 Mode: config.ModePassThrough, 2069 AbsOutputFile: "/out.js", 2070 UnsupportedJSFeatures: compat.ClassPrivateStaticField, 2071 }, 2072 }) 2073 } 2074 2075 func TestLowerPrivateClassStaticMethodOrder(t *testing.T) { 2076 lower_suite.expectBundled(t, bundled{ 2077 files: map[string]string{ 2078 "/entry.js": ` 2079 class Foo { 2080 static bar = Foo.#foo() 2081 static #foo() { return 123 } // This must be set before "bar" is initialized 2082 } 2083 console.log(Foo.bar === 123) 2084 2085 class FooThis { 2086 static bar = this.#foo() 2087 static #foo() { return 123 } // This must be set before "bar" is initialized 2088 } 2089 console.log(FooThis.bar === 123) 2090 `, 2091 }, 2092 entryPaths: []string{"/entry.js"}, 2093 options: config.Options{ 2094 Mode: config.ModePassThrough, 2095 AbsOutputFile: "/out.js", 2096 UnsupportedJSFeatures: compat.ClassPrivateStaticMethod, 2097 }, 2098 }) 2099 } 2100 2101 func TestLowerPrivateClassStaticAccessorOrder(t *testing.T) { 2102 lower_suite.expectBundled(t, bundled{ 2103 files: map[string]string{ 2104 "/entry.js": ` 2105 class Foo { 2106 static bar = Foo.#foo 2107 static get #foo() { return 123 } // This must be set before "bar" is initialized 2108 } 2109 console.log(Foo.bar === 123) 2110 2111 class FooThis { 2112 static bar = this.#foo 2113 static get #foo() { return 123 } // This must be set before "bar" is initialized 2114 } 2115 console.log(FooThis.bar === 123) 2116 `, 2117 }, 2118 entryPaths: []string{"/entry.js"}, 2119 options: config.Options{ 2120 Mode: config.ModePassThrough, 2121 AbsOutputFile: "/out.js", 2122 UnsupportedJSFeatures: compat.ClassPrivateStaticAccessor, 2123 }, 2124 }) 2125 } 2126 2127 func TestLowerPrivateClassBrandCheckUnsupported(t *testing.T) { 2128 lower_suite.expectBundled(t, bundled{ 2129 files: map[string]string{ 2130 "/entry.js": ` 2131 class Foo { 2132 #foo 2133 #bar 2134 baz() { 2135 return [ 2136 this.#foo, 2137 this.#bar, 2138 #foo in this, 2139 ] 2140 } 2141 } 2142 `, 2143 }, 2144 entryPaths: []string{"/entry.js"}, 2145 options: config.Options{ 2146 Mode: config.ModePassThrough, 2147 AbsOutputFile: "/out.js", 2148 UnsupportedJSFeatures: compat.ClassPrivateBrandCheck, 2149 }, 2150 }) 2151 } 2152 2153 func TestLowerPrivateClassBrandCheckSupported(t *testing.T) { 2154 lower_suite.expectBundled(t, bundled{ 2155 files: map[string]string{ 2156 "/entry.js": ` 2157 class Foo { 2158 #foo 2159 #bar 2160 baz() { 2161 return [ 2162 this.#foo, 2163 this.#bar, 2164 #foo in this, 2165 ] 2166 } 2167 } 2168 `, 2169 }, 2170 entryPaths: []string{"/entry.js"}, 2171 options: config.Options{ 2172 Mode: config.ModePassThrough, 2173 AbsOutputFile: "/out.js", 2174 }, 2175 }) 2176 } 2177 2178 func TestLowerTemplateObject(t *testing.T) { 2179 lower_suite.expectBundled(t, bundled{ 2180 files: map[string]string{ 2181 "/entry.js": ` 2182 x = () => [ 2183 tag` + "`x`" + `, 2184 tag` + "`\\xFF`" + `, 2185 tag` + "`\\x`" + `, 2186 tag` + "`\\u`" + `, 2187 ] 2188 y = () => [ 2189 tag` + "`x${y}z`" + `, 2190 tag` + "`\\xFF${y}z`" + `, 2191 tag` + "`x${y}\\z`" + `, 2192 tag` + "`x${y}\\u`" + `, 2193 ] 2194 `, 2195 }, 2196 entryPaths: []string{"/entry.js"}, 2197 options: config.Options{ 2198 Mode: config.ModePassThrough, 2199 AbsOutputFile: "/out.js", 2200 UnsupportedJSFeatures: compat.TemplateLiteral, 2201 }, 2202 }) 2203 } 2204 2205 // See https://github.com/evanw/esbuild/issues/1424 for more information 2206 func TestLowerPrivateClassFieldStaticIssue1424(t *testing.T) { 2207 lower_suite.expectBundled(t, bundled{ 2208 files: map[string]string{ 2209 "/entry.js": ` 2210 class T { 2211 #a() { return 'a'; } 2212 #b() { return 'b'; } 2213 static c; 2214 d() { console.log(this.#a()); } 2215 } 2216 new T().d(); 2217 `, 2218 }, 2219 entryPaths: []string{"/entry.js"}, 2220 options: config.Options{ 2221 Mode: config.ModeBundle, 2222 AbsOutputFile: "/out.js", 2223 UnsupportedJSFeatures: compat.ClassPrivateMethod, 2224 }, 2225 }) 2226 } 2227 2228 // See https://github.com/evanw/esbuild/issues/1493 for more information 2229 func TestLowerNullishCoalescingAssignmentIssue1493(t *testing.T) { 2230 lower_suite.expectBundled(t, bundled{ 2231 files: map[string]string{ 2232 "/entry.js": ` 2233 export class A { 2234 #a; 2235 f() { 2236 this.#a ??= 1; 2237 } 2238 } 2239 `, 2240 }, 2241 entryPaths: []string{"/entry.js"}, 2242 options: config.Options{ 2243 Mode: config.ModeBundle, 2244 AbsOutputFile: "/out.js", 2245 UnsupportedJSFeatures: compat.LogicalAssignment, 2246 }, 2247 }) 2248 } 2249 2250 func TestStaticClassBlockESNext(t *testing.T) { 2251 lower_suite.expectBundled(t, bundled{ 2252 files: map[string]string{ 2253 "/entry.js": ` 2254 class A { 2255 static {} 2256 static { 2257 this.thisField++ 2258 A.classField++ 2259 super.superField = super.superField + 1 2260 super.superField++ 2261 } 2262 } 2263 let B = class { 2264 static {} 2265 static { 2266 this.thisField++ 2267 super.superField = super.superField + 1 2268 super.superField++ 2269 } 2270 } 2271 `, 2272 }, 2273 entryPaths: []string{"/entry.js"}, 2274 options: config.Options{ 2275 Mode: config.ModeBundle, 2276 AbsOutputFile: "/out.js", 2277 }, 2278 }) 2279 } 2280 2281 func TestStaticClassBlockES2021(t *testing.T) { 2282 lower_suite.expectBundled(t, bundled{ 2283 files: map[string]string{ 2284 "/entry.js": ` 2285 class A { 2286 static {} 2287 static { 2288 this.thisField++ 2289 A.classField++ 2290 super.superField = super.superField + 1 2291 super.superField++ 2292 } 2293 } 2294 let B = class { 2295 static {} 2296 static { 2297 this.thisField++ 2298 super.superField = super.superField + 1 2299 super.superField++ 2300 } 2301 } 2302 `, 2303 }, 2304 entryPaths: []string{"/entry.js"}, 2305 options: config.Options{ 2306 Mode: config.ModeBundle, 2307 AbsOutputFile: "/out.js", 2308 UnsupportedJSFeatures: es(2021), 2309 }, 2310 }) 2311 } 2312 2313 func TestLowerRegExpNameCollision(t *testing.T) { 2314 lower_suite.expectBundled(t, bundled{ 2315 files: map[string]string{ 2316 "/entry.js": ` 2317 export function foo(RegExp) { 2318 return new RegExp(/./d, 'd') 2319 } 2320 `, 2321 }, 2322 entryPaths: []string{"/entry.js"}, 2323 options: config.Options{ 2324 Mode: config.ModeBundle, 2325 AbsOutputFile: "/out.js", 2326 UnsupportedJSFeatures: es(2021), 2327 }, 2328 }) 2329 } 2330 2331 func TestLowerForAwait2017(t *testing.T) { 2332 lower_suite.expectBundled(t, bundled{ 2333 files: map[string]string{ 2334 "/entry.js": ` 2335 export default [ 2336 async () => { for await (x of y) z(x) }, 2337 async () => { for await (x.y of y) z(x) }, 2338 async () => { for await (let x of y) z(x) }, 2339 async () => { for await (const x of y) z(x) }, 2340 async () => { label: for await (const x of y) break label }, 2341 async () => { label: for await (const x of y) continue label }, 2342 ] 2343 `, 2344 }, 2345 entryPaths: []string{"/entry.js"}, 2346 options: config.Options{ 2347 Mode: config.ModePassThrough, 2348 AbsOutputFile: "/out.js", 2349 UnsupportedJSFeatures: es(2017), 2350 }, 2351 }) 2352 } 2353 2354 func TestLowerForAwait2015(t *testing.T) { 2355 lower_suite.expectBundled(t, bundled{ 2356 files: map[string]string{ 2357 "/entry.js": ` 2358 export default [ 2359 async () => { for await (x of y) z(x) }, 2360 async () => { for await (x.y of y) z(x) }, 2361 async () => { for await (let x of y) z(x) }, 2362 async () => { for await (const x of y) z(x) }, 2363 async () => { label: for await (const x of y) break label }, 2364 async () => { label: for await (const x of y) continue label }, 2365 ] 2366 `, 2367 }, 2368 entryPaths: []string{"/entry.js"}, 2369 options: config.Options{ 2370 Mode: config.ModePassThrough, 2371 AbsOutputFile: "/out.js", 2372 UnsupportedJSFeatures: es(2015), 2373 }, 2374 }) 2375 } 2376 2377 func TestLowerNestedFunctionDirectEval(t *testing.T) { 2378 lower_suite.expectBundled(t, bundled{ 2379 files: map[string]string{ 2380 "/1.js": "if (foo) { function x() {} }", 2381 "/2.js": "if (foo) { function x() {} eval('') }", 2382 "/3.js": "if (foo) { function x() {} if (bar) { eval('') } }", 2383 "/4.js": "if (foo) { eval(''); function x() {} }", 2384 "/5.js": "'use strict'; if (foo) { function x() {} }", 2385 "/6.js": "'use strict'; if (foo) { function x() {} eval('') }", 2386 "/7.js": "'use strict'; if (foo) { function x() {} if (bar) { eval('') } }", 2387 "/8.js": "'use strict'; if (foo) { eval(''); function x() {} }", 2388 }, 2389 entryPaths: []string{ 2390 "/1.js", 2391 "/2.js", 2392 "/3.js", 2393 "/4.js", 2394 "/5.js", 2395 "/6.js", 2396 "/7.js", 2397 "/8.js", 2398 }, 2399 options: config.Options{ 2400 Mode: config.ModePassThrough, 2401 AbsOutputDir: "/out", 2402 }, 2403 }) 2404 } 2405 2406 func TestJavaScriptDecoratorsESNext(t *testing.T) { 2407 lower_suite.expectBundled(t, bundled{ 2408 files: map[string]string{ 2409 "/entry.js": ` 2410 @x.y() 2411 @(new y.x) 2412 export default class Foo { 2413 @x @y mUndef 2414 @x @y mDef = 1 2415 @x @y method() { return new Foo } 2416 @x @y static sUndef 2417 @x @y static sDef = new Foo 2418 @x @y static sMethod() { return new Foo } 2419 } 2420 `, 2421 }, 2422 entryPaths: []string{"/entry.js"}, 2423 options: config.Options{ 2424 Mode: config.ModePassThrough, 2425 AbsOutputFile: "/out.js", 2426 }, 2427 }) 2428 } 2429 2430 func TestJavaScriptAutoAccessorESNext(t *testing.T) { 2431 lower_suite.expectBundled(t, bundled{ 2432 files: map[string]string{ 2433 "/js-define.js": ` 2434 class Foo { 2435 accessor one = 1 2436 accessor #two = 2 2437 accessor [three()] = 3 2438 2439 static accessor four = 4 2440 static accessor #five = 5 2441 static accessor [six()] = 6 2442 } 2443 `, 2444 "/ts-define/ts-define.ts": ` 2445 class Foo { 2446 accessor one = 1 2447 accessor #two = 2 2448 accessor [three()] = 3 2449 2450 static accessor four = 4 2451 static accessor #five = 5 2452 static accessor [six()] = 6 2453 } 2454 class Normal { accessor a = b; c = d } 2455 class Private { accessor #a = b; c = d } 2456 class StaticNormal { static accessor a = b; static c = d } 2457 class StaticPrivate { static accessor #a = b; static c = d } 2458 `, 2459 "/ts-define/tsconfig.json": `{ 2460 "compilerOptions": { 2461 "useDefineForClassFields": true, 2462 }, 2463 }`, 2464 "/ts-assign/ts-assign.ts": ` 2465 class Foo { 2466 accessor one = 1 2467 accessor #two = 2 2468 accessor [three()] = 3 2469 2470 static accessor four = 4 2471 static accessor #five = 5 2472 static accessor [six()] = 6 2473 } 2474 class Normal { accessor a = b; c = d } 2475 class Private { accessor #a = b; c = d } 2476 class StaticNormal { static accessor a = b; static c = d } 2477 class StaticPrivate { static accessor #a = b; static c = d } 2478 `, 2479 "/ts-assign/tsconfig.json": `{ 2480 "compilerOptions": { 2481 "useDefineForClassFields": false, 2482 }, 2483 }`, 2484 }, 2485 entryPaths: []string{ 2486 "/js-define.js", 2487 "/ts-define/ts-define.ts", 2488 "/ts-assign/ts-assign.ts", 2489 }, 2490 options: config.Options{ 2491 Mode: config.ModePassThrough, 2492 AbsOutputDir: "/out", 2493 }, 2494 }) 2495 } 2496 2497 func TestJavaScriptAutoAccessorES2022(t *testing.T) { 2498 lower_suite.expectBundled(t, bundled{ 2499 files: map[string]string{ 2500 "/js-define.js": ` 2501 class Foo { 2502 accessor one = 1 2503 accessor #two = 2 2504 accessor [three()] = 3 2505 2506 static accessor four = 4 2507 static accessor #five = 5 2508 static accessor [six()] = 6 2509 } 2510 `, 2511 "/ts-define/ts-define.ts": ` 2512 class Foo { 2513 accessor one = 1 2514 accessor #two = 2 2515 accessor [three()] = 3 2516 2517 static accessor four = 4 2518 static accessor #five = 5 2519 static accessor [six()] = 6 2520 } 2521 class Normal { accessor a = b; c = d } 2522 class Private { accessor #a = b; c = d } 2523 class StaticNormal { static accessor a = b; static c = d } 2524 class StaticPrivate { static accessor #a = b; static c = d } 2525 `, 2526 "/ts-define/tsconfig.json": `{ 2527 "compilerOptions": { 2528 "useDefineForClassFields": true, 2529 }, 2530 }`, 2531 "/ts-assign/ts-assign.ts": ` 2532 class Foo { 2533 accessor one = 1 2534 accessor #two = 2 2535 accessor [three()] = 3 2536 2537 static accessor four = 4 2538 static accessor #five = 5 2539 static accessor [six()] = 6 2540 } 2541 class Normal { accessor a = b; c = d } 2542 class Private { accessor #a = b; c = d } 2543 class StaticNormal { static accessor a = b; static c = d } 2544 class StaticPrivate { static accessor #a = b; static c = d } 2545 `, 2546 "/ts-assign/tsconfig.json": `{ 2547 "compilerOptions": { 2548 "useDefineForClassFields": false, 2549 }, 2550 }`, 2551 }, 2552 entryPaths: []string{ 2553 "/js-define.js", 2554 "/ts-define/ts-define.ts", 2555 "/ts-assign/ts-assign.ts", 2556 }, 2557 options: config.Options{ 2558 Mode: config.ModePassThrough, 2559 AbsOutputDir: "/out", 2560 UnsupportedJSFeatures: es(2022), 2561 }, 2562 }) 2563 } 2564 2565 func TestJavaScriptAutoAccessorES2021(t *testing.T) { 2566 lower_suite.expectBundled(t, bundled{ 2567 files: map[string]string{ 2568 "/js-define.js": ` 2569 class Foo { 2570 accessor one = 1 2571 accessor #two = 2 2572 accessor [three()] = 3 2573 2574 static accessor four = 4 2575 static accessor #five = 5 2576 static accessor [six()] = 6 2577 } 2578 `, 2579 "/ts-define/ts-define.ts": ` 2580 class Foo { 2581 accessor one = 1 2582 accessor #two = 2 2583 accessor [three()] = 3 2584 2585 static accessor four = 4 2586 static accessor #five = 5 2587 static accessor [six()] = 6 2588 } 2589 class Normal { accessor a = b; c = d } 2590 class Private { accessor #a = b; c = d } 2591 class StaticNormal { static accessor a = b; static c = d } 2592 class StaticPrivate { static accessor #a = b; static c = d } 2593 `, 2594 "/ts-define/tsconfig.json": `{ 2595 "compilerOptions": { 2596 "useDefineForClassFields": true, 2597 }, 2598 }`, 2599 "/ts-assign/ts-assign.ts": ` 2600 class Foo { 2601 accessor one = 1 2602 accessor #two = 2 2603 accessor [three()] = 3 2604 2605 static accessor four = 4 2606 static accessor #five = 5 2607 static accessor [six()] = 6 2608 } 2609 class Normal { accessor a = b; c = d } 2610 class Private { accessor #a = b; c = d } 2611 class StaticNormal { static accessor a = b; static c = d } 2612 class StaticPrivate { static accessor #a = b; static c = d } 2613 `, 2614 "/ts-assign/tsconfig.json": `{ 2615 "compilerOptions": { 2616 "useDefineForClassFields": false, 2617 }, 2618 }`, 2619 }, 2620 entryPaths: []string{ 2621 "/js-define.js", 2622 "/ts-define/ts-define.ts", 2623 "/ts-assign/ts-assign.ts", 2624 }, 2625 options: config.Options{ 2626 Mode: config.ModePassThrough, 2627 AbsOutputDir: "/out", 2628 UnsupportedJSFeatures: es(2021), 2629 }, 2630 }) 2631 } 2632 2633 func TestLowerUsing(t *testing.T) { 2634 lower_suite.expectBundled(t, bundled{ 2635 files: map[string]string{ 2636 "/entry.js": ` 2637 using a = b 2638 await using c = d 2639 if (nested) { 2640 using x = 1 2641 await using y = 2 2642 } 2643 2644 function foo() { 2645 using a = b 2646 if (nested) { 2647 using x = 1 2648 } 2649 } 2650 2651 async function bar() { 2652 using a = b 2653 await using c = d 2654 if (nested) { 2655 using x = 1 2656 await using y = 2 2657 } 2658 } 2659 `, 2660 "/loops.js": ` 2661 for (using a of b) c(() => a) 2662 for (await using d of e) f(() => d) 2663 for await (using g of h) i(() => g) 2664 for await (await using j of k) l(() => j) 2665 2666 if (nested) { 2667 for (using a of b) c(() => a) 2668 for (await using d of e) f(() => d) 2669 for await (using g of h) i(() => g) 2670 for await (await using j of k) l(() => j) 2671 } 2672 2673 function foo() { 2674 for (using a of b) c(() => a) 2675 } 2676 2677 async function bar() { 2678 for (using a of b) c(() => a) 2679 for (await using d of e) f(() => d) 2680 for await (using g of h) i(() => g) 2681 for await (await using j of k) l(() => j) 2682 } 2683 `, 2684 "/switch.js": ` 2685 using x = y 2686 switch (foo) { 2687 case 0: using c = d 2688 default: using e = f 2689 } 2690 switch (foo) { 2691 case 0: await using c = d 2692 default: using e = f 2693 } 2694 2695 async function foo() { 2696 using x = y 2697 switch (foo) { 2698 case 0: using c = d 2699 default: using e = f 2700 } 2701 switch (foo) { 2702 case 0: await using c = d 2703 default: using e = f 2704 } 2705 } 2706 `, 2707 }, 2708 entryPaths: []string{ 2709 "/entry.js", 2710 "/loops.js", 2711 "/switch.js", 2712 }, 2713 options: config.Options{ 2714 Mode: config.ModePassThrough, 2715 AbsOutputDir: "/out", 2716 UnsupportedJSFeatures: compat.Using, 2717 }, 2718 }) 2719 } 2720 2721 func TestLowerUsingUnsupportedAsync(t *testing.T) { 2722 lower_suite.expectBundled(t, bundled{ 2723 files: map[string]string{ 2724 "/entry.js": ` 2725 function foo() { 2726 using a = b 2727 if (nested) { 2728 using x = 1 2729 } 2730 } 2731 2732 async function bar() { 2733 using a = b 2734 await using c = d 2735 if (nested) { 2736 using x = 1 2737 await using y = 2 2738 } 2739 } 2740 `, 2741 "/loops.js": ` 2742 for (using a of b) c(() => a) 2743 2744 if (nested) { 2745 for (using a of b) c(() => a) 2746 } 2747 2748 function foo() { 2749 for (using a of b) c(() => a) 2750 } 2751 2752 async function bar() { 2753 for (using a of b) c(() => a) 2754 for (await using d of e) f(() => d) 2755 } 2756 `, 2757 "/switch.js": ` 2758 using x = y 2759 switch (foo) { 2760 case 0: using c = d 2761 default: using e = f 2762 } 2763 2764 async function foo() { 2765 using x = y 2766 switch (foo) { 2767 case 0: using c = d 2768 default: using e = f 2769 } 2770 switch (foo) { 2771 case 0: await using c = d 2772 default: using e = f 2773 } 2774 } 2775 `, 2776 }, 2777 entryPaths: []string{ 2778 "/entry.js", 2779 "/loops.js", 2780 "/switch.js", 2781 }, 2782 options: config.Options{ 2783 Mode: config.ModePassThrough, 2784 AbsOutputDir: "/out", 2785 UnsupportedJSFeatures: compat.AsyncAwait | compat.TopLevelAwait, 2786 }, 2787 }) 2788 } 2789 2790 func TestLowerUsingUnsupportedUsingAndAsync(t *testing.T) { 2791 lower_suite.expectBundled(t, bundled{ 2792 files: map[string]string{ 2793 "/entry.js": ` 2794 function foo() { 2795 using a = b 2796 if (nested) { 2797 using x = 1 2798 } 2799 } 2800 2801 async function bar() { 2802 using a = b 2803 await using c = d 2804 if (nested) { 2805 using x = 1 2806 await using y = 2 2807 } 2808 } 2809 `, 2810 "/loops.js": ` 2811 for (using a of b) c(() => a) 2812 2813 if (nested) { 2814 for (using a of b) c(() => a) 2815 } 2816 2817 function foo() { 2818 for (using a of b) c(() => a) 2819 } 2820 2821 async function bar() { 2822 for (using a of b) c(() => a) 2823 for (await using d of e) f(() => d) 2824 } 2825 `, 2826 "/switch.js": ` 2827 using x = y 2828 switch (foo) { 2829 case 0: using c = d 2830 default: using e = f 2831 } 2832 2833 async function foo() { 2834 using x = y 2835 switch (foo) { 2836 case 0: using c = d 2837 default: using e = f 2838 } 2839 switch (foo) { 2840 case 0: await using c = d 2841 default: using e = f 2842 } 2843 } 2844 `, 2845 }, 2846 entryPaths: []string{ 2847 "/entry.js", 2848 "/loops.js", 2849 "/switch.js", 2850 }, 2851 options: config.Options{ 2852 Mode: config.ModePassThrough, 2853 AbsOutputDir: "/out", 2854 UnsupportedJSFeatures: compat.Using | compat.AsyncAwait | compat.TopLevelAwait, 2855 }, 2856 }) 2857 } 2858 2859 func TestLowerUsingHoisting(t *testing.T) { 2860 lower_suite.expectBundled(t, bundled{ 2861 files: map[string]string{ 2862 "/hoist-use-strict.js": ` 2863 "use strict" 2864 using a = b 2865 function foo() { 2866 "use strict" 2867 using a = b 2868 } 2869 `, 2870 "/hoist-directive.js": ` 2871 "use wtf" 2872 using a = b 2873 function foo() { 2874 "use wtf" 2875 using a = b 2876 } 2877 `, 2878 "/hoist-import.js": ` 2879 using a = b 2880 import "./foo" 2881 using c = d 2882 `, 2883 "/hoist-export-star.js": ` 2884 using a = b 2885 export * from './foo' 2886 using c = d 2887 `, 2888 "/hoist-export-from.js": ` 2889 using a = b 2890 export {x, y} from './foo' 2891 using c = d 2892 `, 2893 "/hoist-export-clause.js": ` 2894 using a = b 2895 export {a, c as 'c!'} 2896 using c = d 2897 `, 2898 "/hoist-export-local-direct.js": ` 2899 using a = b 2900 export var ac1 = [a, c], { x: [x1] } = foo 2901 export let a1 = a, { y: [y1] } = foo 2902 export const c1 = c, { z: [z1] } = foo 2903 var ac2 = [a, c], { x: [x2] } = foo 2904 let a2 = a, { y: [y2] } = foo 2905 const c2 = c, { z: [z2] } = foo 2906 using c = d 2907 `, 2908 "/hoist-export-local-indirect.js": ` 2909 using a = b 2910 var ac1 = [a, c], { x: [x1] } = foo 2911 let a1 = a, { y: [y1] } = foo 2912 const c1 = c, { z: [z1] } = foo 2913 var ac2 = [a, c], { x: [x2] } = foo 2914 let a2 = a, { y: [y2] } = foo 2915 const c2 = c, { z: [z2] } = foo 2916 using c = d 2917 export {x1, y1, z1} 2918 `, 2919 "/hoist-export-class-direct.js": ` 2920 using a = b 2921 export class Foo1 { ac = [a, c] } 2922 export class Bar1 { ac = [a, c, Bar1] } 2923 class Foo2 { ac = [a, c] } 2924 class Bar2 { ac = [a, c, Bar2] } 2925 using c = d 2926 `, 2927 "/hoist-export-class-indirect.js": ` 2928 using a = b 2929 class Foo1 { ac = [a, c] } 2930 class Bar1 { ac = [a, c, Bar1] } 2931 class Foo2 { ac = [a, c] } 2932 class Bar2 { ac = [a, c, Bar2] } 2933 using c = d 2934 export {Foo1, Bar1} 2935 `, 2936 "/hoist-export-function-direct.js": ` 2937 using a = b 2938 export function foo1() { return [a, c] } 2939 export function bar1() { return [a, c, bar1] } 2940 function foo2() { return [a, c] } 2941 function bar2() { return [a, c, bar2] } 2942 using c = d 2943 `, 2944 "/hoist-export-function-indirect.js": ` 2945 using a = b 2946 function foo1() { return [a, c] } 2947 function bar1() { return [a, c, bar1] } 2948 function foo2() { return [a, c] } 2949 function bar2() { return [a, c, bar2] } 2950 using c = d 2951 export {foo1, bar1} 2952 `, 2953 "/hoist-export-default-class-name-unused.js": ` 2954 using a = b 2955 export default class Foo { 2956 ac = [a, c] 2957 } 2958 using c = d 2959 `, 2960 "/hoist-export-default-class-name-used.js": ` 2961 using a = b 2962 export default class Foo { 2963 ac = [a, c, Foo] 2964 } 2965 using c = d 2966 `, 2967 "/hoist-export-default-class-anonymous.js": ` 2968 using a = b 2969 export default class { 2970 ac = [a, c] 2971 } 2972 using c = d 2973 `, 2974 "/hoist-export-default-function-name-unused.js": ` 2975 using a = b 2976 export default function foo() { 2977 return [a, c] 2978 } 2979 using c = d 2980 `, 2981 "/hoist-export-default-function-name-used.js": ` 2982 using a = b 2983 export default function foo() { 2984 return [a, c, foo] 2985 } 2986 using c = d 2987 `, 2988 "/hoist-export-default-function-anonymous.js": ` 2989 using a = b 2990 export default function() { 2991 return [a, c] 2992 } 2993 using c = d 2994 `, 2995 "/hoist-export-default-expr.js": ` 2996 using a = b 2997 export default [a, c] 2998 using c = d 2999 `, 3000 }, 3001 entryPaths: []string{ 3002 "/hoist-use-strict.js", 3003 "/hoist-directive.js", 3004 "/hoist-import.js", 3005 "/hoist-export-star.js", 3006 "/hoist-export-from.js", 3007 "/hoist-export-clause.js", 3008 "/hoist-export-local-direct.js", 3009 "/hoist-export-local-indirect.js", 3010 "/hoist-export-class-direct.js", 3011 "/hoist-export-class-indirect.js", 3012 "/hoist-export-function-direct.js", 3013 "/hoist-export-function-indirect.js", 3014 "/hoist-export-default-class-name-unused.js", 3015 "/hoist-export-default-class-name-used.js", 3016 "/hoist-export-default-class-anonymous.js", 3017 "/hoist-export-default-function-name-unused.js", 3018 "/hoist-export-default-function-name-used.js", 3019 "/hoist-export-default-function-anonymous.js", 3020 "/hoist-export-default-expr.js", 3021 }, 3022 options: config.Options{ 3023 Mode: config.ModePassThrough, 3024 AbsOutputDir: "/out", 3025 UnsupportedJSFeatures: compat.Using, 3026 }, 3027 }) 3028 } 3029 3030 func TestLowerUsingInsideTSNamespace(t *testing.T) { 3031 lower_suite.expectBundled(t, bundled{ 3032 files: map[string]string{ 3033 "/entry.ts": ` 3034 namespace ns { 3035 export let a = b 3036 using c = d 3037 export let e = f 3038 } 3039 `, 3040 }, 3041 entryPaths: []string{"/entry.ts"}, 3042 options: config.Options{ 3043 Mode: config.ModePassThrough, 3044 AbsOutputDir: "/out", 3045 UnsupportedJSFeatures: compat.Using, 3046 }, 3047 }) 3048 } 3049 3050 func TestLowerAsyncGenerator(t *testing.T) { 3051 lower_suite.expectBundled(t, bundled{ 3052 files: map[string]string{ 3053 "/entry.ts": ` 3054 async function* foo() { 3055 yield 3056 yield x 3057 yield *x 3058 await using x = await y 3059 for await (let x of y) {} 3060 for await (await using x of y) {} 3061 } 3062 foo = async function* () { 3063 yield 3064 yield x 3065 yield *x 3066 await using x = await y 3067 for await (let x of y) {} 3068 for await (await using x of y) {} 3069 } 3070 foo = { async *bar () { 3071 yield 3072 yield x 3073 yield *x 3074 await using x = await y 3075 for await (let x of y) {} 3076 for await (await using x of y) {} 3077 } } 3078 class Foo { async *bar () { 3079 yield 3080 yield x 3081 yield *x 3082 await using x = await y 3083 for await (let x of y) {} 3084 for await (await using x of y) {} 3085 } } 3086 Foo = class { async *bar () { 3087 yield 3088 yield x 3089 yield *x 3090 await using x = await y 3091 for await (let x of y) {} 3092 for await (await using x of y) {} 3093 } } 3094 async function bar() { 3095 await using x = await y 3096 for await (let x of y) {} 3097 for await (await using x of y) {} 3098 } 3099 `, 3100 }, 3101 entryPaths: []string{"/entry.ts"}, 3102 options: config.Options{ 3103 Mode: config.ModePassThrough, 3104 AbsOutputDir: "/out", 3105 UnsupportedJSFeatures: compat.AsyncGenerator, 3106 }, 3107 }) 3108 } 3109 3110 func TestLowerAsyncGeneratorNoAwait(t *testing.T) { 3111 lower_suite.expectBundled(t, bundled{ 3112 files: map[string]string{ 3113 "/entry.ts": ` 3114 async function* foo() { 3115 yield 3116 yield x 3117 yield *x 3118 await using x = await y 3119 for await (let x of y) {} 3120 for await (await using x of y) {} 3121 } 3122 foo = async function* () { 3123 yield 3124 yield x 3125 yield *x 3126 await using x = await y 3127 for await (let x of y) {} 3128 for await (await using x of y) {} 3129 } 3130 foo = { async *bar () { 3131 yield 3132 yield x 3133 yield *x 3134 await using x = await y 3135 for await (let x of y) {} 3136 for await (await using x of y) {} 3137 } } 3138 class Foo { async *bar () { 3139 yield 3140 yield x 3141 yield *x 3142 await using x = await y 3143 for await (let x of y) {} 3144 for await (await using x of y) {} 3145 } } 3146 Foo = class { async *bar () { 3147 yield 3148 yield x 3149 yield *x 3150 await using x = await y 3151 for await (let x of y) {} 3152 for await (await using x of y) {} 3153 } } 3154 async function bar() { 3155 await using x = await y 3156 for await (let x of y) {} 3157 for await (await using x of y) {} 3158 } 3159 `, 3160 }, 3161 entryPaths: []string{"/entry.ts"}, 3162 options: config.Options{ 3163 Mode: config.ModePassThrough, 3164 AbsOutputDir: "/out", 3165 UnsupportedJSFeatures: compat.AsyncGenerator | compat.AsyncAwait, 3166 }, 3167 }) 3168 } 3169 3170 func TestJavaScriptDecoratorsBundleIssue3768(t *testing.T) { 3171 lower_suite.expectBundled(t, bundled{ 3172 files: map[string]string{ 3173 "/base-instance-method.js": `class Foo { @dec foo() { return Foo } }`, 3174 "/base-instance-field.js": `class Foo { @dec foo = Foo }`, 3175 "/base-instance-accessor.js": `class Foo { @dec accessor foo = Foo }`, 3176 3177 "/base-static-method.js": `class Foo { @dec static foo() { return Foo } }`, 3178 "/base-static-field.js": `class Foo { @dec static foo = Foo }`, 3179 "/base-static-accessor.js": `class Foo { @dec static accessor foo = Foo }`, 3180 3181 "/derived-instance-method.js": `class Foo extends Bar { @dec foo() { return Foo } }`, 3182 "/derived-instance-field.js": `class Foo extends Bar { @dec foo = Foo }`, 3183 "/derived-instance-accessor.js": `class Foo extends Bar { @dec accessor foo = Foo }`, 3184 3185 "/derived-static-method.js": `class Foo extends Bar { @dec static foo() { return Foo } }`, 3186 "/derived-static-field.js": `class Foo extends Bar { @dec static foo = Foo }`, 3187 "/derived-static-accessor.js": `class Foo extends Bar { @dec static accessor foo = Foo }`, 3188 }, 3189 entryPaths: []string{"/*"}, 3190 options: config.Options{ 3191 Mode: config.ModeBundle, 3192 AbsOutputDir: "/out", 3193 UnsupportedJSFeatures: compat.Decorators, 3194 }, 3195 }) 3196 }