github.com/evanw/esbuild@v0.21.4/internal/js_parser/js_parser_test.go (about)

     1  package js_parser
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/evanw/esbuild/internal/ast"
     9  	"github.com/evanw/esbuild/internal/compat"
    10  	"github.com/evanw/esbuild/internal/config"
    11  	"github.com/evanw/esbuild/internal/helpers"
    12  	"github.com/evanw/esbuild/internal/js_ast"
    13  	"github.com/evanw/esbuild/internal/js_printer"
    14  	"github.com/evanw/esbuild/internal/logger"
    15  	"github.com/evanw/esbuild/internal/renamer"
    16  	"github.com/evanw/esbuild/internal/test"
    17  )
    18  
    19  func expectParseErrorCommon(t *testing.T, contents string, expected string, options config.Options) {
    20  	t.Helper()
    21  	t.Run(contents, func(t *testing.T) {
    22  		t.Helper()
    23  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
    24  		Parse(log, test.SourceForTest(contents), OptionsFromConfig(&options))
    25  		msgs := log.Done()
    26  		text := ""
    27  		for _, msg := range msgs {
    28  			text += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})
    29  		}
    30  		test.AssertEqualWithDiff(t, text, expected)
    31  	})
    32  }
    33  
    34  func expectParseError(t *testing.T, contents string, expected string) {
    35  	t.Helper()
    36  	expectParseErrorCommon(t, contents, expected, config.Options{})
    37  }
    38  
    39  func expectParseErrorTarget(t *testing.T, esVersion int, contents string, expected string) {
    40  	t.Helper()
    41  	expectParseErrorCommon(t, contents, expected, config.Options{
    42  		UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{
    43  			compat.ES: {Parts: []int{esVersion}},
    44  		}),
    45  	})
    46  }
    47  
    48  func expectPrintedWithUnsupportedFeatures(t *testing.T, unsupportedJSFeatures compat.JSFeature, contents string, expected string) {
    49  	t.Helper()
    50  	expectPrintedCommon(t, contents, expected, config.Options{
    51  		UnsupportedJSFeatures: unsupportedJSFeatures,
    52  	})
    53  }
    54  
    55  func expectParseErrorWithUnsupportedFeatures(t *testing.T, unsupportedJSFeatures compat.JSFeature, contents string, expected string) {
    56  	t.Helper()
    57  	expectParseErrorCommon(t, contents, expected, config.Options{
    58  		UnsupportedJSFeatures: unsupportedJSFeatures,
    59  	})
    60  }
    61  
    62  func expectPrintedCommon(t *testing.T, contents string, expected string, options config.Options) {
    63  	t.Helper()
    64  	t.Run(contents, func(t *testing.T) {
    65  		t.Helper()
    66  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
    67  		options.OmitRuntimeForTests = true
    68  		tree, ok := Parse(log, test.SourceForTest(contents), OptionsFromConfig(&options))
    69  		msgs := log.Done()
    70  		text := ""
    71  		for _, msg := range msgs {
    72  			if msg.Kind != logger.Warning {
    73  				text += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})
    74  			}
    75  		}
    76  		test.AssertEqualWithDiff(t, text, "")
    77  		if !ok {
    78  			t.Fatal("Parse error")
    79  		}
    80  		symbols := ast.NewSymbolMap(1)
    81  		symbols.SymbolsForSource[0] = tree.Symbols
    82  		r := renamer.NewNoOpRenamer(symbols)
    83  		js := js_printer.Print(tree, symbols, r, js_printer.Options{
    84  			UnsupportedFeatures: options.UnsupportedJSFeatures,
    85  			ASCIIOnly:           options.ASCIIOnly,
    86  		}).JS
    87  		test.AssertEqualWithDiff(t, string(js), expected)
    88  	})
    89  }
    90  
    91  func expectPrinted(t *testing.T, contents string, expected string) {
    92  	t.Helper()
    93  	expectPrintedCommon(t, contents, expected, config.Options{})
    94  }
    95  
    96  func expectPrintedMangle(t *testing.T, contents string, expected string) {
    97  	t.Helper()
    98  	expectPrintedCommon(t, contents, expected, config.Options{
    99  		MinifySyntax: true,
   100  	})
   101  }
   102  
   103  func expectPrintedNormalAndMangle(t *testing.T, contents string, normal string, mangle string) {
   104  	expectPrinted(t, contents, normal)
   105  	expectPrintedMangle(t, contents, mangle)
   106  }
   107  
   108  func expectPrintedTarget(t *testing.T, esVersion int, contents string, expected string) {
   109  	t.Helper()
   110  	expectPrintedCommon(t, contents, expected, config.Options{
   111  		UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{
   112  			compat.ES: {Parts: []int{esVersion}},
   113  		}),
   114  	})
   115  }
   116  
   117  func expectPrintedMangleTarget(t *testing.T, esVersion int, contents string, expected string) {
   118  	t.Helper()
   119  	expectPrintedCommon(t, contents, expected, config.Options{
   120  		UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{
   121  			compat.ES: {Parts: []int{esVersion}},
   122  		}),
   123  		MinifySyntax: true,
   124  	})
   125  }
   126  
   127  func expectPrintedASCII(t *testing.T, contents string, expected string) {
   128  	t.Helper()
   129  	expectPrintedCommon(t, contents, expected, config.Options{
   130  		ASCIIOnly: true,
   131  	})
   132  }
   133  
   134  func expectPrintedTargetASCII(t *testing.T, esVersion int, contents string, expected string) {
   135  	t.Helper()
   136  	expectPrintedCommon(t, contents, expected, config.Options{
   137  		UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{
   138  			compat.ES: {Parts: []int{esVersion}},
   139  		}),
   140  		ASCIIOnly: true,
   141  	})
   142  }
   143  
   144  func expectParseErrorTargetASCII(t *testing.T, esVersion int, contents string, expected string) {
   145  	t.Helper()
   146  	expectParseErrorCommon(t, contents, expected, config.Options{
   147  		UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{
   148  			compat.ES: {Parts: []int{esVersion}},
   149  		}),
   150  		ASCIIOnly: true,
   151  	})
   152  }
   153  
   154  func expectParseErrorJSX(t *testing.T, contents string, expected string) {
   155  	t.Helper()
   156  	expectParseErrorCommon(t, contents, expected, config.Options{
   157  		JSX: config.JSXOptions{
   158  			Parse: true,
   159  		},
   160  	})
   161  }
   162  
   163  func expectPrintedJSX(t *testing.T, contents string, expected string) {
   164  	t.Helper()
   165  	expectPrintedCommon(t, contents, expected, config.Options{
   166  		JSX: config.JSXOptions{
   167  			Parse: true,
   168  		},
   169  	})
   170  }
   171  
   172  func expectPrintedJSXSideEffects(t *testing.T, contents string, expected string) {
   173  	t.Helper()
   174  	expectPrintedCommon(t, contents, expected, config.Options{
   175  		JSX: config.JSXOptions{
   176  			Parse:       true,
   177  			SideEffects: true,
   178  		},
   179  	})
   180  }
   181  
   182  func expectPrintedMangleJSX(t *testing.T, contents string, expected string) {
   183  	t.Helper()
   184  	expectPrintedCommon(t, contents, expected, config.Options{
   185  		MinifySyntax: true,
   186  		JSX: config.JSXOptions{
   187  			Parse: true,
   188  		},
   189  	})
   190  }
   191  
   192  type JSXAutomaticTestOptions struct {
   193  	Development            bool
   194  	ImportSource           string
   195  	OmitJSXRuntimeForTests bool
   196  	SideEffects            bool
   197  }
   198  
   199  func expectParseErrorJSXAutomatic(t *testing.T, options JSXAutomaticTestOptions, contents string, expected string) {
   200  	t.Helper()
   201  	expectParseErrorCommon(t, contents, expected, config.Options{
   202  		OmitJSXRuntimeForTests: options.OmitJSXRuntimeForTests,
   203  		JSX: config.JSXOptions{
   204  			AutomaticRuntime: true,
   205  			Parse:            true,
   206  			Development:      options.Development,
   207  			ImportSource:     options.ImportSource,
   208  			SideEffects:      options.SideEffects,
   209  		},
   210  	})
   211  }
   212  
   213  func expectPrintedJSXAutomatic(t *testing.T, options JSXAutomaticTestOptions, contents string, expected string) {
   214  	t.Helper()
   215  	expectPrintedCommon(t, contents, expected, config.Options{
   216  		OmitJSXRuntimeForTests: options.OmitJSXRuntimeForTests,
   217  		JSX: config.JSXOptions{
   218  			AutomaticRuntime: true,
   219  			Parse:            true,
   220  			Development:      options.Development,
   221  			ImportSource:     options.ImportSource,
   222  			SideEffects:      options.SideEffects,
   223  		},
   224  	})
   225  }
   226  
   227  func TestBinOp(t *testing.T) {
   228  	for code, entry := range js_ast.OpTable {
   229  		opCode := js_ast.OpCode(code)
   230  
   231  		if opCode.IsLeftAssociative() {
   232  			op := entry.Text
   233  			expectPrinted(t, "a "+op+" b "+op+" c", "a "+op+" b "+op+" c;\n")
   234  			expectPrinted(t, "(a "+op+" b) "+op+" c", "a "+op+" b "+op+" c;\n")
   235  			expectPrinted(t, "a "+op+" (b "+op+" c)", "a "+op+" (b "+op+" c);\n")
   236  		}
   237  
   238  		if opCode.IsRightAssociative() {
   239  			op := entry.Text
   240  			expectPrinted(t, "a "+op+" b "+op+" c", "a "+op+" b "+op+" c;\n")
   241  
   242  			// Avoid errors about invalid assignment targets
   243  			if opCode.BinaryAssignTarget() == js_ast.AssignTargetNone {
   244  				expectPrinted(t, "(a "+op+" b) "+op+" c", "(a "+op+" b) "+op+" c;\n")
   245  			}
   246  
   247  			expectPrinted(t, "a "+op+" (b "+op+" c)", "a "+op+" b "+op+" c;\n")
   248  		}
   249  	}
   250  }
   251  
   252  func TestComments(t *testing.T) {
   253  	expectParseError(t, "throw //\n x", "<stdin>: ERROR: Unexpected newline after \"throw\"\n")
   254  	expectParseError(t, "throw /**/\n x", "<stdin>: ERROR: Unexpected newline after \"throw\"\n")
   255  	expectParseError(t, "throw <!--\n x",
   256  		`<stdin>: ERROR: Unexpected newline after "throw"
   257  <stdin>: WARNING: Treating "<!--" as the start of a legacy HTML single-line comment
   258  `)
   259  	expectParseError(t, "throw -->\n x", "<stdin>: ERROR: Unexpected \">\"\n")
   260  
   261  	expectParseError(t, "export {}\n<!--", `<stdin>: ERROR: Legacy HTML single-line comments are not allowed in ECMAScript modules
   262  <stdin>: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here:
   263  <stdin>: WARNING: Treating "<!--" as the start of a legacy HTML single-line comment
   264  `)
   265  
   266  	expectParseError(t, "export {}\n-->", `<stdin>: ERROR: Legacy HTML single-line comments are not allowed in ECMAScript modules
   267  <stdin>: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here:
   268  <stdin>: WARNING: Treating "-->" as the start of a legacy HTML single-line comment
   269  `)
   270  
   271  	expectPrinted(t, "return //\n x", "return;\nx;\n")
   272  	expectPrinted(t, "return /**/\n x", "return;\nx;\n")
   273  	expectPrinted(t, "return <!--\n x", "return;\nx;\n")
   274  	expectPrinted(t, "-->\nx", "x;\n")
   275  	expectPrinted(t, "x\n-->\ny", "x;\ny;\n")
   276  	expectPrinted(t, "x\n -->\ny", "x;\ny;\n")
   277  	expectPrinted(t, "x\n/**/-->\ny", "x;\ny;\n")
   278  	expectPrinted(t, "x/*\n*/-->\ny", "x;\ny;\n")
   279  	expectPrinted(t, "x\n/**/ /**/-->\ny", "x;\ny;\n")
   280  	expectPrinted(t, "if(x-->y)z", "if (x-- > y) z;\n")
   281  }
   282  
   283  func TestStrictMode(t *testing.T) {
   284  	useStrict := "<stdin>: NOTE: Strict mode is triggered by the \"use strict\" directive here:\n"
   285  
   286  	expectPrinted(t, "'use strict'", "\"use strict\";\n")
   287  	expectPrinted(t, "`use strict`", "`use strict`;\n")
   288  	expectPrinted(t, "//! @legal comment\n 'use strict'", "\"use strict\";\n//! @legal comment\n")
   289  	expectPrinted(t, "/*! @legal comment */ 'use strict'", "\"use strict\";\n/*! @legal comment */\n")
   290  	expectPrinted(t, "function f() { //! @legal comment\n 'use strict' }", "function f() {\n  //! @legal comment\n  \"use strict\";\n}\n")
   291  	expectPrinted(t, "function f() { /*! @legal comment */ 'use strict' }", "function f() {\n  /*! @legal comment */\n  \"use strict\";\n}\n")
   292  	expectParseError(t, "//! @legal comment\n 'use strict'", "")
   293  	expectParseError(t, "/*! @legal comment */ 'use strict'", "")
   294  	expectParseError(t, "function f() { //! @legal comment\n 'use strict' }", "")
   295  	expectParseError(t, "function f() { /*! @legal comment */ 'use strict' }", "")
   296  
   297  	nonSimple := "<stdin>: ERROR: Cannot use a \"use strict\" directive in a function with a non-simple parameter list\n"
   298  	expectParseError(t, "function f() { 'use strict' }", "")
   299  	expectParseError(t, "function f(x) { 'use strict' }", "")
   300  	expectParseError(t, "function f([x]) { 'use strict' }", nonSimple)
   301  	expectParseError(t, "function f({x}) { 'use strict' }", nonSimple)
   302  	expectParseError(t, "function f(x = 1) { 'use strict' }", nonSimple)
   303  	expectParseError(t, "function f(x, ...y) { 'use strict' }", nonSimple)
   304  	expectParseError(t, "(function() { 'use strict' })", "")
   305  	expectParseError(t, "(function(x) { 'use strict' })", "")
   306  	expectParseError(t, "(function([x]) { 'use strict' })", nonSimple)
   307  	expectParseError(t, "(function({x}) { 'use strict' })", nonSimple)
   308  	expectParseError(t, "(function(x = 1) { 'use strict' })", nonSimple)
   309  	expectParseError(t, "(function(x, ...y) { 'use strict' })", nonSimple)
   310  	expectParseError(t, "() => { 'use strict' }", "")
   311  	expectParseError(t, "(x) => { 'use strict' }", "")
   312  	expectParseError(t, "([x]) => { 'use strict' }", nonSimple)
   313  	expectParseError(t, "({x}) => { 'use strict' }", nonSimple)
   314  	expectParseError(t, "(x = 1) => { 'use strict' }", nonSimple)
   315  	expectParseError(t, "(x, ...y) => { 'use strict' }", nonSimple)
   316  	expectParseError(t, "(x, ...y) => { //! @license comment\n 'use strict' }", nonSimple)
   317  
   318  	why := "<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n"
   319  
   320  	expectPrinted(t, "let x = '\\0'", "let x = \"\\0\";\n")
   321  	expectPrinted(t, "let x = '\\00'", "let x = \"\\0\";\n")
   322  	expectPrinted(t, "'use strict'; let x = '\\0'", "\"use strict\";\nlet x = \"\\0\";\n")
   323  	expectPrinted(t, "let x = '\\0'; export {}", "let x = \"\\0\";\nexport {};\n")
   324  	expectParseError(t, "'use strict'; let x = '\\00'", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   325  	expectParseError(t, "'use strict'; let x = '\\08'", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   326  	expectParseError(t, "'use strict'; let x = '\\008'", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   327  	expectParseError(t, "let x = '\\00'; export {}", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\n"+why)
   328  	expectParseError(t, "let x = '\\09'; export {}", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\n"+why)
   329  	expectParseError(t, "let x = '\\009'; export {}", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\n"+why)
   330  
   331  	expectPrinted(t, "'\\0'", "\"\\0\";\n")
   332  	expectPrinted(t, "'\\00'", "\"\\0\";\n")
   333  	expectPrinted(t, "'use strict'; '\\0'", "\"use strict\";\n\"\\0\";\n")
   334  	expectParseError(t, "'use strict'; '\\00'", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   335  	expectParseError(t, "'use strict'; '\\08'", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   336  	expectParseError(t, "'use strict'; '\\008'", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   337  	expectParseError(t, "'\\00'; 'use strict';", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   338  	expectParseError(t, "'\\08'; 'use strict';", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   339  	expectParseError(t, "'\\008'; 'use strict';", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\n"+useStrict)
   340  	expectParseError(t, "'\\00'; export {}", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\n"+why)
   341  	expectParseError(t, "'\\09'; export {}", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\n"+why)
   342  	expectParseError(t, "'\\009'; export {}", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\n"+why)
   343  
   344  	expectPrinted(t, "with (x) y", "with (x) y;\n")
   345  	expectParseError(t, "'use strict'; with (x) y", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+useStrict)
   346  	expectParseError(t, "with (x) y; export {}", "<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n"+why)
   347  
   348  	expectPrinted(t, "delete x", "delete x;\n")
   349  	expectParseError(t, "'use strict'; delete x", "<stdin>: ERROR: Delete of a bare identifier cannot be used in strict mode\n"+useStrict)
   350  	expectParseError(t, "delete x; export {}", "<stdin>: ERROR: Delete of a bare identifier cannot be used in an ECMAScript module\n"+why)
   351  
   352  	expectPrinted(t, "for (var x = y in z) ;", "x = y;\nfor (var x in z) ;\n")
   353  	expectParseError(t, "'use strict'; for (var x = y in z) ;",
   354  		"<stdin>: ERROR: Variable initializers inside for-in loops cannot be used in strict mode\n"+useStrict)
   355  	expectParseError(t, "for (var x = y in z) ; export {}",
   356  		"<stdin>: ERROR: Variable initializers inside for-in loops cannot be used in an ECMAScript module\n"+why)
   357  
   358  	expectPrinted(t, "function f(a, a) {}", "function f(a, a) {\n}\n")
   359  	expectPrinted(t, "(function(a, a) {})", "(function(a, a) {\n});\n")
   360  	expectPrinted(t, "({ f: function(a, a) {} })", "({ f: function(a, a) {\n} });\n")
   361  	expectPrinted(t, "({ f: function*(a, a) {} })", "({ f: function* (a, a) {\n} });\n")
   362  	expectPrinted(t, "({ f: async function(a, a) {} })", "({ f: async function(a, a) {\n} });\n")
   363  
   364  	bindingError := "<stdin>: ERROR: \"a\" cannot be bound multiple times in the same parameter list\n" +
   365  		"<stdin>: NOTE: The name \"a\" was originally bound here:\n"
   366  
   367  	expectParseError(t, "function f(a, a) { 'use strict' }", bindingError)
   368  	expectParseError(t, "function *f(a, a) { 'use strict' }", bindingError)
   369  	expectParseError(t, "async function f(a, a) { 'use strict' }", bindingError)
   370  	expectParseError(t, "(function(a, a) { 'use strict' })", bindingError)
   371  	expectParseError(t, "(function*(a, a) { 'use strict' })", bindingError)
   372  	expectParseError(t, "(async function(a, a) { 'use strict' })", bindingError)
   373  	expectParseError(t, "function f(a, [a]) {}", bindingError)
   374  	expectParseError(t, "function f([a], a) {}", bindingError)
   375  	expectParseError(t, "'use strict'; function f(a, a) {}", bindingError)
   376  	expectParseError(t, "'use strict'; (function(a, a) {})", bindingError)
   377  	expectParseError(t, "'use strict'; ((a, a) => {})", bindingError)
   378  	expectParseError(t, "function f(a, a) {}; export {}", bindingError)
   379  	expectParseError(t, "(function(a, a) {}); export {}", bindingError)
   380  	expectParseError(t, "(function(a, [a]) {})", bindingError)
   381  	expectParseError(t, "({ f(a, a) {} })", bindingError)
   382  	expectParseError(t, "({ *f(a, a) {} })", bindingError)
   383  	expectParseError(t, "({ async f(a, a) {} })", bindingError)
   384  	expectParseError(t, "(a, a) => {}", bindingError)
   385  
   386  	expectParseError(t, "'use strict'; if (0) function f() {}",
   387  		"<stdin>: ERROR: Function declarations inside if statements cannot be used in strict mode\n"+useStrict)
   388  	expectParseError(t, "'use strict'; if (0) ; else function f() {}",
   389  		"<stdin>: ERROR: Function declarations inside if statements cannot be used in strict mode\n"+useStrict)
   390  	expectParseError(t, "'use strict'; x: function f() {}",
   391  		"<stdin>: ERROR: Function declarations inside labels cannot be used in strict mode\n"+useStrict)
   392  
   393  	expectParseError(t, "if (0) function f() {} export {}",
   394  		"<stdin>: ERROR: Function declarations inside if statements cannot be used in an ECMAScript module\n"+why)
   395  	expectParseError(t, "if (0) ; else function f() {} export {}",
   396  		"<stdin>: ERROR: Function declarations inside if statements cannot be used in an ECMAScript module\n"+why)
   397  	expectParseError(t, "x: function f() {} export {}",
   398  		"<stdin>: ERROR: Function declarations inside labels cannot be used in an ECMAScript module\n"+why)
   399  
   400  	expectPrinted(t, "eval++", "eval++;\n")
   401  	expectPrinted(t, "eval = 0", "eval = 0;\n")
   402  	expectPrinted(t, "eval += 0", "eval += 0;\n")
   403  	expectPrinted(t, "[eval] = 0", "[eval] = 0;\n")
   404  	expectPrinted(t, "arguments++", "arguments++;\n")
   405  	expectPrinted(t, "arguments = 0", "arguments = 0;\n")
   406  	expectPrinted(t, "arguments += 0", "arguments += 0;\n")
   407  	expectPrinted(t, "[arguments] = 0", "[arguments] = 0;\n")
   408  	expectParseError(t, "'use strict'; eval++", "<stdin>: ERROR: Invalid assignment target\n")
   409  	expectParseError(t, "'use strict'; eval = 0", "<stdin>: ERROR: Invalid assignment target\n")
   410  	expectParseError(t, "'use strict'; eval += 0", "<stdin>: ERROR: Invalid assignment target\n")
   411  	expectParseError(t, "'use strict'; [eval] = 0", "<stdin>: ERROR: Invalid assignment target\n")
   412  	expectParseError(t, "'use strict'; arguments++", "<stdin>: ERROR: Invalid assignment target\n")
   413  	expectParseError(t, "'use strict'; arguments = 0", "<stdin>: ERROR: Invalid assignment target\n")
   414  	expectParseError(t, "'use strict'; arguments += 0", "<stdin>: ERROR: Invalid assignment target\n")
   415  	expectParseError(t, "'use strict'; [arguments] = 0", "<stdin>: ERROR: Invalid assignment target\n")
   416  
   417  	evalDecl := "<stdin>: ERROR: Declarations with the name \"eval\" cannot be used in strict mode\n" + useStrict
   418  	argsDecl := "<stdin>: ERROR: Declarations with the name \"arguments\" cannot be used in strict mode\n" + useStrict
   419  	expectPrinted(t, "function eval() {}", "function eval() {\n}\n")
   420  	expectPrinted(t, "function arguments() {}", "function arguments() {\n}\n")
   421  	expectPrinted(t, "function f(eval) {}", "function f(eval) {\n}\n")
   422  	expectPrinted(t, "function f(arguments) {}", "function f(arguments) {\n}\n")
   423  	expectPrinted(t, "({ f(eval) {} })", "({ f(eval) {\n} });\n")
   424  	expectPrinted(t, "({ f(arguments) {} })", "({ f(arguments) {\n} });\n")
   425  	expectParseError(t, "'use strict'; function eval() {}", evalDecl)
   426  	expectParseError(t, "'use strict'; function arguments() {}", argsDecl)
   427  	expectParseError(t, "'use strict'; function f(eval) {}", evalDecl)
   428  	expectParseError(t, "'use strict'; function f(arguments) {}", argsDecl)
   429  	expectParseError(t, "function eval() { 'use strict' }", evalDecl)
   430  	expectParseError(t, "function arguments() { 'use strict' }", argsDecl)
   431  	expectParseError(t, "function f(eval) { 'use strict' }", evalDecl)
   432  	expectParseError(t, "function f(arguments) { 'use strict' }", argsDecl)
   433  	expectParseError(t, "({ f(eval) { 'use strict' } })", evalDecl)
   434  	expectParseError(t, "({ f(arguments) { 'use strict' } })", argsDecl)
   435  	expectParseError(t, "'use strict'; class eval {}", evalDecl)
   436  	expectParseError(t, "'use strict'; class arguments {}", argsDecl)
   437  
   438  	expectPrinted(t, "let protected", "let protected;\n")
   439  	expectPrinted(t, "let protecte\\u0064", "let protected;\n")
   440  	expectPrinted(t, "let x = protected", "let x = protected;\n")
   441  	expectPrinted(t, "let x = protecte\\u0064", "let x = protected;\n")
   442  	expectParseError(t, "'use strict'; let protected",
   443  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   444  	expectParseError(t, "'use strict'; let protecte\\u0064",
   445  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   446  	expectParseError(t, "'use strict'; let x = protected",
   447  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   448  	expectParseError(t, "'use strict'; let x = protecte\\u0064",
   449  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   450  	expectParseError(t, "'use strict'; protected: 0",
   451  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   452  	expectParseError(t, "'use strict'; protecte\\u0064: 0",
   453  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   454  	expectParseError(t, "'use strict'; function protected() {}",
   455  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   456  	expectParseError(t, "'use strict'; function protecte\\u0064() {}",
   457  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   458  	expectParseError(t, "'use strict'; (function protected() {})",
   459  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   460  	expectParseError(t, "'use strict'; (function protecte\\u0064() {})",
   461  		"<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+useStrict)
   462  
   463  	expectPrinted(t, "0123", "83;\n")
   464  	expectPrinted(t, "({0123: 4})", "({ 83: 4 });\n")
   465  	expectPrinted(t, "let {0123: x} = y", "let { 83: x } = y;\n")
   466  	expectParseError(t, "'use strict'; 0123",
   467  		"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\n"+useStrict)
   468  	expectParseError(t, "'use strict'; ({0123: 4})",
   469  		"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\n"+useStrict)
   470  	expectParseError(t, "'use strict'; let {0123: x} = y",
   471  		"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\n"+useStrict)
   472  	expectParseError(t, "'use strict'; 08",
   473  		"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\n"+useStrict)
   474  	expectParseError(t, "'use strict'; ({08: 4})",
   475  		"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\n"+useStrict)
   476  	expectParseError(t, "'use strict'; let {08: x} = y",
   477  		"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\n"+useStrict)
   478  
   479  	classNote := "<stdin>: NOTE: All code inside a class is implicitly in strict mode\n"
   480  
   481  	expectPrinted(t, "function f() { 'use strict' } with (x) y", "function f() {\n  \"use strict\";\n}\nwith (x) y;\n")
   482  	expectPrinted(t, "with (x) y; function f() { 'use strict' }", "with (x) y;\nfunction f() {\n  \"use strict\";\n}\n")
   483  	expectPrinted(t, "class f {} with (x) y", "class f {\n}\nwith (x) y;\n")
   484  	expectPrinted(t, "with (x) y; class f {}", "with (x) y;\nclass f {\n}\n")
   485  	expectPrinted(t, "`use strict`; with (x) y", "`use strict`;\nwith (x) y;\n")
   486  	expectPrinted(t, "{ 'use strict'; with (x) y }", "{\n  \"use strict\";\n  with (x) y;\n}\n")
   487  	expectPrinted(t, "if (0) { 'use strict'; with (x) y }", "if (0) {\n  \"use strict\";\n  with (x) y;\n}\n")
   488  	expectPrinted(t, "while (0) { 'use strict'; with (x) y }", "while (0) {\n  \"use strict\";\n  with (x) y;\n}\n")
   489  	expectPrinted(t, "try { 'use strict'; with (x) y } catch {}", "try {\n  \"use strict\";\n  with (x) y;\n} catch {\n}\n")
   490  	expectPrinted(t, "try {} catch { 'use strict'; with (x) y }", "try {\n} catch {\n  \"use strict\";\n  with (x) y;\n}\n")
   491  	expectPrinted(t, "try {} finally { 'use strict'; with (x) y }", "try {\n} finally {\n  \"use strict\";\n  with (x) y;\n}\n")
   492  	expectParseError(t, "\"use strict\"; with (x) y", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+useStrict)
   493  	expectParseError(t, "function f() { 'use strict'; with (x) y }", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+useStrict)
   494  	expectParseError(t, "function f() { 'use strict'; function y() { with (x) y } }", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+useStrict)
   495  	expectParseError(t, "class f { x() { with (x) y } }", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+classNote)
   496  	expectParseError(t, "class f { x() { function y() { with (x) y } } }", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+classNote)
   497  	expectParseError(t, "class f { x() { function protected() {} } }", "<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in strict mode\n"+classNote)
   498  
   499  	reservedWordExport := "<stdin>: ERROR: \"protected\" is a reserved word and cannot be used in an ECMAScript module\n" +
   500  		why
   501  
   502  	expectParseError(t, "var protected; export {}", reservedWordExport)
   503  	expectParseError(t, "class protected {} export {}", reservedWordExport)
   504  	expectParseError(t, "(class protected {}); export {}", reservedWordExport)
   505  	expectParseError(t, "function protected() {} export {}", reservedWordExport)
   506  	expectParseError(t, "(function protected() {}); export {}", reservedWordExport)
   507  
   508  	importMeta := "<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n" +
   509  		"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the use of \"import.meta\" here:\n"
   510  	importStatement := "<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n" +
   511  		"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \"import\" keyword here:\n"
   512  	exportKeyword := "<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n" +
   513  		"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n"
   514  	tlaKeyword := "<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n" +
   515  		"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n"
   516  
   517  	expectPrinted(t, "import(x); with (y) z", "import(x);\nwith (y) z;\n")
   518  	expectPrinted(t, "import('x'); with (y) z", "import(\"x\");\nwith (y) z;\n")
   519  	expectPrinted(t, "with (y) z; import(x)", "with (y) z;\nimport(x);\n")
   520  	expectPrinted(t, "with (y) z; import('x')", "with (y) z;\nimport(\"x\");\n")
   521  	expectPrinted(t, "(import(x)); with (y) z", "import(x);\nwith (y) z;\n")
   522  	expectPrinted(t, "(import('x')); with (y) z", "import(\"x\");\nwith (y) z;\n")
   523  	expectPrinted(t, "with (y) z; (import(x))", "with (y) z;\nimport(x);\n")
   524  	expectPrinted(t, "with (y) z; (import('x'))", "with (y) z;\nimport(\"x\");\n")
   525  
   526  	expectParseError(t, "import.meta; with (y) z", importMeta)
   527  	expectParseError(t, "with (y) z; import.meta", importMeta)
   528  	expectParseError(t, "(import.meta); with (y) z", importMeta)
   529  	expectParseError(t, "with (y) z; (import.meta)", importMeta)
   530  	expectParseError(t, "import 'x'; with (y) z", importStatement)
   531  	expectParseError(t, "import * as x from 'x'; with (y) z", importStatement)
   532  	expectParseError(t, "import x from 'x'; with (y) z", importStatement)
   533  	expectParseError(t, "import {x} from 'x'; with (y) z", importStatement)
   534  
   535  	expectParseError(t, "export {}; with (y) z", exportKeyword)
   536  	expectParseError(t, "export let x; with (y) z", exportKeyword)
   537  	expectParseError(t, "export function x() {} with (y) z", exportKeyword)
   538  	expectParseError(t, "export class x {} with (y) z", exportKeyword)
   539  
   540  	expectParseError(t, "await 0; with (y) z", tlaKeyword)
   541  	expectParseError(t, "with (y) z; await 0", tlaKeyword)
   542  	expectParseError(t, "for await (x of y); with (y) z", tlaKeyword)
   543  	expectParseError(t, "with (y) z; for await (x of y);", tlaKeyword)
   544  	expectParseError(t, "await using x = _; with (y) z", tlaKeyword)
   545  	expectParseError(t, "with (y) z; await using x = _", tlaKeyword)
   546  	expectParseError(t, "for (await using x of _) ; with (y) z", tlaKeyword)
   547  	expectParseError(t, "with (y) z; for (await using x of _) ;", tlaKeyword)
   548  
   549  	fAlreadyDeclaredError := "<stdin>: ERROR: The symbol \"f\" has already been declared\n" +
   550  		"<stdin>: NOTE: The symbol \"f\" was originally declared here:\n"
   551  	nestedNote := "<stdin>: NOTE: Duplicate function declarations are not allowed in nested blocks"
   552  	moduleNote := "<stdin>: NOTE: Duplicate top-level function declarations are not allowed in an ECMAScript module. " +
   553  		"This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n"
   554  
   555  	cases := []string{
   556  		"function f() {} function f() {}",
   557  		"function f() {} function *f() {}",
   558  		"function *f() {} function f() {}",
   559  		"function f() {} async function f() {}",
   560  		"async function f() {} function f() {}",
   561  		"function f() {} async function *f() {}",
   562  		"async function *f() {} function f() {}",
   563  	}
   564  
   565  	for _, c := range cases {
   566  		expectParseError(t, c, "")
   567  		expectParseError(t, "'use strict'; "+c, "")
   568  		expectParseError(t, "function foo() { 'use strict'; "+c+" }", "")
   569  	}
   570  
   571  	expectParseError(t, "function f() {} function f() {} export {}", fAlreadyDeclaredError+moduleNote)
   572  	expectParseError(t, "function f() {} function *f() {} export {}", fAlreadyDeclaredError+moduleNote)
   573  	expectParseError(t, "function f() {} async function f() {} export {}", fAlreadyDeclaredError+moduleNote)
   574  	expectParseError(t, "function *f() {} function f() {} export {}", fAlreadyDeclaredError+moduleNote)
   575  	expectParseError(t, "async function f() {} function f() {} export {}", fAlreadyDeclaredError+moduleNote)
   576  
   577  	expectParseError(t, "'use strict'; { function f() {} function f() {} }",
   578  		fAlreadyDeclaredError+nestedNote+" in strict mode. Strict mode is triggered by the \"use strict\" directive here:\n")
   579  	expectParseError(t, "'use strict'; switch (0) { case 1: function f() {} default: function f() {} }",
   580  		fAlreadyDeclaredError+nestedNote+" in strict mode. Strict mode is triggered by the \"use strict\" directive here:\n")
   581  
   582  	expectParseError(t, "function foo() { 'use strict'; { function f() {} function f() {} } }",
   583  		fAlreadyDeclaredError+nestedNote+" in strict mode. Strict mode is triggered by the \"use strict\" directive here:\n")
   584  	expectParseError(t, "function foo() { 'use strict'; switch (0) { case 1: function f() {} default: function f() {} } }",
   585  		fAlreadyDeclaredError+nestedNote+" in strict mode. Strict mode is triggered by the \"use strict\" directive here:\n")
   586  
   587  	expectParseError(t, "{ function f() {} function f() {} } export {}",
   588  		fAlreadyDeclaredError+nestedNote+" in an ECMAScript module. This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n")
   589  	expectParseError(t, "switch (0) { case 1: function f() {} default: function f() {} } export {}",
   590  		fAlreadyDeclaredError+nestedNote+" in an ECMAScript module. This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n")
   591  
   592  	expectParseError(t, "var x; var x", "")
   593  	expectParseError(t, "'use strict'; var x; var x", "")
   594  	expectParseError(t, "var x; var x; export {}", "")
   595  }
   596  
   597  func TestExponentiation(t *testing.T) {
   598  	expectPrinted(t, "--x ** 2", "--x ** 2;\n")
   599  	expectPrinted(t, "++x ** 2", "++x ** 2;\n")
   600  	expectPrinted(t, "x-- ** 2", "x-- ** 2;\n")
   601  	expectPrinted(t, "x++ ** 2", "x++ ** 2;\n")
   602  
   603  	expectPrinted(t, "(-x) ** 2", "(-x) ** 2;\n")
   604  	expectPrinted(t, "(+x) ** 2", "(+x) ** 2;\n")
   605  	expectPrinted(t, "(~x) ** 2", "(~x) ** 2;\n")
   606  	expectPrinted(t, "(!x) ** 2", "(!x) ** 2;\n")
   607  	expectPrinted(t, "(-1) ** 2", "(-1) ** 2;\n")
   608  	expectPrinted(t, "(+1) ** 2", "1 ** 2;\n")
   609  	expectPrinted(t, "(~1) ** 2", "(~1) ** 2;\n")
   610  	expectPrinted(t, "(!1) ** 2", "false ** 2;\n")
   611  	expectPrinted(t, "(void x) ** 2", "(void x) ** 2;\n")
   612  	expectPrinted(t, "(delete x) ** 2", "(delete x) ** 2;\n")
   613  	expectPrinted(t, "(typeof x) ** 2", "(typeof x) ** 2;\n")
   614  	expectPrinted(t, "undefined ** 2", "(void 0) ** 2;\n")
   615  
   616  	expectParseError(t, "-x ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   617  	expectParseError(t, "+x ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   618  	expectParseError(t, "~x ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   619  	expectParseError(t, "!x ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   620  	expectParseError(t, "void x ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   621  	expectParseError(t, "delete x ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   622  	expectParseError(t, "typeof x ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   623  
   624  	expectParseError(t, "-x.y() ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   625  	expectParseError(t, "+x.y() ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   626  	expectParseError(t, "~x.y() ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   627  	expectParseError(t, "!x.y() ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   628  	expectParseError(t, "void x.y() ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   629  	expectParseError(t, "delete x.y() ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   630  	expectParseError(t, "typeof x.y() ** 2", "<stdin>: ERROR: Unexpected \"**\"\n")
   631  
   632  	// https://github.com/tc39/ecma262/issues/2197
   633  	expectParseError(t, "delete x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   634  	expectParseError(t, "delete x.prop ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   635  	expectParseError(t, "delete x[0] ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   636  	expectParseError(t, "delete x?.prop ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   637  	expectParseError(t, "void x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   638  	expectParseError(t, "typeof x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   639  	expectParseError(t, "+x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   640  	expectParseError(t, "-x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   641  	expectParseError(t, "~x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   642  	expectParseError(t, "!x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   643  	expectParseError(t, "await x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   644  	expectParseError(t, "await -x ** 0", "<stdin>: ERROR: Unexpected \"**\"\n")
   645  	expectPrinted(t, "(delete x) ** 0", "(delete x) ** 0;\n")
   646  	expectPrinted(t, "(delete x.prop) ** 0", "(delete x.prop) ** 0;\n")
   647  	expectPrinted(t, "(delete x[0]) ** 0", "(delete x[0]) ** 0;\n")
   648  	expectPrinted(t, "(delete x?.prop) ** 0", "(delete x?.prop) ** 0;\n")
   649  	expectPrinted(t, "(void x) ** 0", "(void x) ** 0;\n")
   650  	expectPrinted(t, "(typeof x) ** 0", "(typeof x) ** 0;\n")
   651  	expectPrinted(t, "(+x) ** 0", "(+x) ** 0;\n")
   652  	expectPrinted(t, "(-x) ** 0", "(-x) ** 0;\n")
   653  	expectPrinted(t, "(~x) ** 0", "(~x) ** 0;\n")
   654  	expectPrinted(t, "(!x) ** 0", "(!x) ** 0;\n")
   655  	expectPrinted(t, "(await x) ** 0", "(await x) ** 0;\n")
   656  	expectPrinted(t, "(await -x) ** 0", "(await -x) ** 0;\n")
   657  }
   658  
   659  func TestAwait(t *testing.T) {
   660  	expectPrinted(t, "await x", "await x;\n")
   661  	expectPrinted(t, "await +x", "await +x;\n")
   662  	expectPrinted(t, "await -x", "await -x;\n")
   663  	expectPrinted(t, "await ~x", "await ~x;\n")
   664  	expectPrinted(t, "await !x", "await !x;\n")
   665  	expectPrinted(t, "await --x", "await --x;\n")
   666  	expectPrinted(t, "await ++x", "await ++x;\n")
   667  	expectPrinted(t, "await x--", "await x--;\n")
   668  	expectPrinted(t, "await x++", "await x++;\n")
   669  	expectPrinted(t, "await void x", "await void x;\n")
   670  	expectPrinted(t, "await typeof x", "await typeof x;\n")
   671  	expectPrinted(t, "await (x * y)", "await (x * y);\n")
   672  	expectPrinted(t, "await (x ** y)", "await (x ** y);\n")
   673  
   674  	expectParseError(t, "var { await } = {}", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   675  	expectParseError(t, "async function f() { var { await } = {} }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   676  	expectParseError(t, "async function* f() { var { await } = {} }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   677  	expectParseError(t, "class C { async f() { var { await } = {} } }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   678  	expectParseError(t, "class C { async* f() { var { await } = {} } }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   679  	expectParseError(t, "class C { static { var { await } = {} } }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   680  
   681  	expectParseError(t, "var {} = { await }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   682  	expectParseError(t, "async function f() { var {} = { await } }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   683  	expectParseError(t, "async function* f() { var {} = { await } }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   684  	expectParseError(t, "class C { async f() { var {} = { await } } }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   685  	expectParseError(t, "class C { async* f() { var {} = { await } } }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   686  	expectParseError(t, "class C { static { var {} = { await } } }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
   687  
   688  	expectParseError(t, "await delete x",
   689  		`<stdin>: ERROR: Delete of a bare identifier cannot be used in an ECMAScript module
   690  <stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level "await" keyword here:
   691  `)
   692  	expectPrinted(t, "async function f() { await delete x }", "async function f() {\n  await delete x;\n}\n")
   693  
   694  	// Can't use await at the top-level without top-level await
   695  	err := "<stdin>: ERROR: Top-level await is not available in the configured target environment\n"
   696  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "await x;", err)
   697  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) await x;", err)
   698  	expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) await x;", "if (false) x;\n")
   699  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "with (x) y; if (false) await x;",
   700  		"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n"+
   701  			"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n")
   702  }
   703  
   704  func TestRegExp(t *testing.T) {
   705  	expectPrinted(t, "/x/d", "/x/d;\n")
   706  	expectPrinted(t, "/x/g", "/x/g;\n")
   707  	expectPrinted(t, "/x/i", "/x/i;\n")
   708  	expectPrinted(t, "/x/m", "/x/m;\n")
   709  	expectPrinted(t, "/x/s", "/x/s;\n")
   710  	expectPrinted(t, "/x/u", "/x/u;\n")
   711  	expectPrinted(t, "/x/y", "/x/y;\n")
   712  
   713  	expectParseError(t, "/)/", "<stdin>: ERROR: Unexpected \")\" in regular expression\n")
   714  	expectPrinted(t, "/[\\])]/", "/[\\])]/;\n")
   715  
   716  	expectParseError(t, "/x/msuygig",
   717  		`<stdin>: ERROR: Duplicate flag "g" in regular expression
   718  <stdin>: NOTE: The first "g" was here:
   719  `)
   720  }
   721  
   722  func TestUnicodeIdentifierNames(t *testing.T) {
   723  	// There are two code points that are valid in identifiers in ES5 but not in ES6+:
   724  	//
   725  	//   U+30FB KATAKANA MIDDLE DOT
   726  	//   U+FF65 HALFWIDTH KATAKANA MIDDLE DOT
   727  	//
   728  	expectPrinted(t, "x = {x惻: 0}", "x = { \"x惻\": 0 };\n")
   729  	expectPrinted(t, "x = {xd: 0}", "x = { \"xd\": 0 };\n")
   730  	expectPrinted(t, "x = {xπ: 0}", "x = { xπ: 0 };\n")
   731  	expectPrinted(t, "x = y.x惻", "x = y[\"x惻\"];\n")
   732  	expectPrinted(t, "x = y.xd", "x = y[\"xd\"];\n")
   733  	expectPrinted(t, "x = y.xπ", "x = y.xπ;\n")
   734  }
   735  
   736  func TestIdentifierEscapes(t *testing.T) {
   737  	expectPrinted(t, "var _\\u0076\\u0061\\u0072", "var _var;\n")
   738  	expectParseError(t, "var \\u0076\\u0061\\u0072", "<stdin>: ERROR: Expected identifier but found \"\\\\u0076\\\\u0061\\\\u0072\"\n")
   739  	expectParseError(t, "\\u0076\\u0061\\u0072 foo", "<stdin>: ERROR: Unexpected \"\\\\u0076\\\\u0061\\\\u0072\"\n")
   740  
   741  	expectPrinted(t, "foo._\\u0076\\u0061\\u0072", "foo._var;\n")
   742  	expectPrinted(t, "foo.\\u0076\\u0061\\u0072", "foo.var;\n")
   743  
   744  	expectParseError(t, "\u200Ca", "<stdin>: ERROR: Unexpected \"\\u200c\"\n")
   745  	expectParseError(t, "\u200Da", "<stdin>: ERROR: Unexpected \"\\u200d\"\n")
   746  }
   747  
   748  func TestSpecialIdentifiers(t *testing.T) {
   749  	expectPrinted(t, "exports", "exports;\n")
   750  	expectPrinted(t, "require", "require;\n")
   751  	expectPrinted(t, "module", "module;\n")
   752  }
   753  
   754  func TestDecls(t *testing.T) {
   755  	expectParseError(t, "var x = 0", "")
   756  	expectParseError(t, "let x = 0", "")
   757  	expectParseError(t, "const x = 0", "")
   758  	expectParseError(t, "for (var x = 0;;) ;", "")
   759  	expectParseError(t, "for (let x = 0;;) ;", "")
   760  	expectParseError(t, "for (const x = 0;;) ;", "")
   761  
   762  	expectParseError(t, "for (var x in y) ;", "")
   763  	expectParseError(t, "for (let x in y) ;", "")
   764  	expectParseError(t, "for (const x in y) ;", "")
   765  	expectParseError(t, "for (var x of y) ;", "")
   766  	expectParseError(t, "for (let x of y) ;", "")
   767  	expectParseError(t, "for (const x of y) ;", "")
   768  
   769  	expectParseError(t, "var x", "")
   770  	expectParseError(t, "let x", "")
   771  	expectParseError(t, "const x", "<stdin>: ERROR: The constant \"x\" must be initialized\n")
   772  	expectParseError(t, "const {}", "<stdin>: ERROR: This constant must be initialized\n")
   773  	expectParseError(t, "const []", "<stdin>: ERROR: This constant must be initialized\n")
   774  	expectParseError(t, "for (var x;;) ;", "")
   775  	expectParseError(t, "for (let x;;) ;", "")
   776  	expectParseError(t, "for (const x;;) ;", "<stdin>: ERROR: The constant \"x\" must be initialized\n")
   777  	expectParseError(t, "for (const {};;) ;", "<stdin>: ERROR: This constant must be initialized\n")
   778  	expectParseError(t, "for (const [];;) ;", "<stdin>: ERROR: This constant must be initialized\n")
   779  
   780  	// Make sure bindings are visited during parsing
   781  	expectPrinted(t, "var {[x]: y} = {}", "var { [x]: y } = {};\n")
   782  	expectPrinted(t, "var {...x} = {}", "var { ...x } = {};\n")
   783  
   784  	// Test destructuring patterns
   785  	expectPrinted(t, "var [...x] = []", "var [...x] = [];\n")
   786  	expectPrinted(t, "var {...x} = {}", "var { ...x } = {};\n")
   787  	expectPrinted(t, "([...x] = []) => {}", "([...x] = []) => {\n};\n")
   788  	expectPrinted(t, "({...x} = {}) => {}", "({ ...x } = {}) => {\n};\n")
   789  
   790  	expectParseError(t, "var [...x,] = []", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   791  	expectParseError(t, "var {...x,} = {}", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   792  	expectParseError(t, "([...x,] = []) => {}", "<stdin>: ERROR: Invalid binding pattern\n")
   793  	expectParseError(t, "({...x,} = {}) => {}", "<stdin>: ERROR: Invalid binding pattern\n")
   794  
   795  	expectPrinted(t, "[b, ...c] = d", "[b, ...c] = d;\n")
   796  	expectPrinted(t, "([b, ...c] = d)", "[b, ...c] = d;\n")
   797  	expectPrinted(t, "({b, ...c} = d)", "({ b, ...c } = d);\n")
   798  	expectPrinted(t, "({a = b} = c)", "({ a = b } = c);\n")
   799  	expectPrinted(t, "({a: b = c} = d)", "({ a: b = c } = d);\n")
   800  	expectPrinted(t, "({a: b.c} = d)", "({ a: b.c } = d);\n")
   801  	expectPrinted(t, "[a = {}] = b", "[a = {}] = b;\n")
   802  	expectPrinted(t, "[[...a, b].x] = c", "[[...a, b].x] = c;\n")
   803  	expectPrinted(t, "[{...a, b}.x] = c", "[{ ...a, b }.x] = c;\n")
   804  	expectPrinted(t, "({x: [...a, b].x} = c)", "({ x: [...a, b].x } = c);\n")
   805  	expectPrinted(t, "({x: {...a, b}.x} = c)", "({ x: { ...a, b }.x } = c);\n")
   806  	expectPrinted(t, "[x = [...a, b]] = c", "[x = [...a, b]] = c;\n")
   807  	expectPrinted(t, "[x = {...a, b}] = c", "[x = { ...a, b }] = c;\n")
   808  	expectPrinted(t, "({x = [...a, b]} = c)", "({ x = [...a, b] } = c);\n")
   809  	expectPrinted(t, "({x = {...a, b}} = c)", "({ x = { ...a, b } } = c);\n")
   810  
   811  	expectPrinted(t, "(x = y)", "x = y;\n")
   812  	expectPrinted(t, "([] = [])", "[] = [];\n")
   813  	expectPrinted(t, "({} = {})", "({} = {});\n")
   814  	expectPrinted(t, "([[]] = [[]])", "[[]] = [[]];\n")
   815  	expectPrinted(t, "({x: {}} = {x: {}})", "({ x: {} } = { x: {} });\n")
   816  	expectPrinted(t, "(x) = y", "x = y;\n")
   817  	expectParseError(t, "([]) = []", "<stdin>: ERROR: Invalid assignment target\n")
   818  	expectParseError(t, "({}) = {}", "<stdin>: ERROR: Invalid assignment target\n")
   819  	expectParseError(t, "[([])] = [[]]", "<stdin>: ERROR: Invalid assignment target\n")
   820  	expectParseError(t, "({x: ({})} = {x: {}})", "<stdin>: ERROR: Invalid assignment target\n")
   821  	expectParseError(t, "(([]) = []) => {}", "<stdin>: ERROR: Invalid binding pattern\n")
   822  	expectParseError(t, "(({}) = {}) => {}", "<stdin>: ERROR: Invalid binding pattern\n")
   823  	expectParseError(t, "function f(([]) = []) {}", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
   824  	expectParseError(t, "function f(({}) = {}) {}", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
   825  
   826  	expectPrinted(t, "for (x in y) ;", "for (x in y) ;\n")
   827  	expectPrinted(t, "for ([] in y) ;", "for ([] in y) ;\n")
   828  	expectPrinted(t, "for ({} in y) ;", "for ({} in y) ;\n")
   829  	expectPrinted(t, "for ((x) in y) ;", "for (x in y) ;\n")
   830  	expectParseError(t, "for (([]) in y) ;", "<stdin>: ERROR: Invalid assignment target\n")
   831  	expectParseError(t, "for (({}) in y) ;", "<stdin>: ERROR: Invalid assignment target\n")
   832  
   833  	expectPrinted(t, "for (x of y) ;", "for (x of y) ;\n")
   834  	expectPrinted(t, "for ([] of y) ;", "for ([] of y) ;\n")
   835  	expectPrinted(t, "for ({} of y) ;", "for ({} of y) ;\n")
   836  	expectPrinted(t, "for ((x) of y) ;", "for (x of y) ;\n")
   837  	expectParseError(t, "for (([]) of y) ;", "<stdin>: ERROR: Invalid assignment target\n")
   838  	expectParseError(t, "for (({}) of y) ;", "<stdin>: ERROR: Invalid assignment target\n")
   839  
   840  	expectParseError(t, "[[...a, b]] = c", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   841  	expectParseError(t, "[{...a, b}] = c", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   842  	expectParseError(t, "({x: [...a, b]} = c)", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   843  	expectParseError(t, "({x: {...a, b}} = c)", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   844  	expectParseError(t, "[b, ...c,] = d", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   845  	expectParseError(t, "([b, ...c,] = d)", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   846  	expectParseError(t, "({b, ...c,} = d)", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   847  	expectParseError(t, "({a = b})", "<stdin>: ERROR: Unexpected \"=\"\n")
   848  	expectParseError(t, "({x = {a = b}} = c)", "<stdin>: ERROR: Unexpected \"=\"\n")
   849  	expectParseError(t, "[a = {b = c}] = d", "<stdin>: ERROR: Unexpected \"=\"\n")
   850  
   851  	expectPrinted(t, "for ([{a = {}}] in b) {}", "for ([{ a = {} }] in b) {\n}\n")
   852  	expectPrinted(t, "for ([{a = {}}] of b) {}", "for ([{ a = {} }] of b) {\n}\n")
   853  	expectPrinted(t, "for ({a = {}} in b) {}", "for ({ a = {} } in b) {\n}\n")
   854  	expectPrinted(t, "for ({a = {}} of b) {}", "for ({ a = {} } of b) {\n}\n")
   855  
   856  	expectParseError(t, "({a = {}} in b)", "<stdin>: ERROR: Unexpected \"=\"\n")
   857  	expectParseError(t, "[{a = {}}]\nof()", "<stdin>: ERROR: Unexpected \"=\"\n")
   858  	expectParseError(t, "for ([...a, b] in c) {}", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   859  	expectParseError(t, "for ([...a, b] of c) {}", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
   860  }
   861  
   862  func TestBreakAndContinue(t *testing.T) {
   863  	expectParseError(t, "break", "<stdin>: ERROR: Cannot use \"break\" here:\n")
   864  	expectParseError(t, "continue", "<stdin>: ERROR: Cannot use \"continue\" here:\n")
   865  
   866  	expectParseError(t, "x: { break }", "<stdin>: ERROR: Cannot use \"break\" here:\n")
   867  	expectParseError(t, "x: { break x }", "")
   868  	expectParseError(t, "x: { continue }", "<stdin>: ERROR: Cannot use \"continue\" here:\n")
   869  	expectParseError(t, "x: { continue x }", "<stdin>: ERROR: Cannot continue to label \"x\"\n")
   870  
   871  	expectParseError(t, "while (1) break", "")
   872  	expectParseError(t, "while (1) continue", "")
   873  	expectParseError(t, "while (1) { function foo() { break } }", "<stdin>: ERROR: Cannot use \"break\" here:\n")
   874  	expectParseError(t, "while (1) { function foo() { continue } }", "<stdin>: ERROR: Cannot use \"continue\" here:\n")
   875  	expectParseError(t, "x: while (1) break x", "")
   876  	expectParseError(t, "x: while (1) continue x", "")
   877  	expectParseError(t, "x: while (1) y: { break x }", "")
   878  	expectParseError(t, "x: while (1) y: { continue x }", "")
   879  	expectParseError(t, "x: while (1) y: { break y }", "")
   880  	expectParseError(t, "x: while (1) y: { continue y }", "<stdin>: ERROR: Cannot continue to label \"y\"\n")
   881  	expectParseError(t, "x: while (1) { function foo() { break x } }", "<stdin>: ERROR: There is no containing label named \"x\"\n")
   882  	expectParseError(t, "x: while (1) { function foo() { continue x } }", "<stdin>: ERROR: There is no containing label named \"x\"\n")
   883  
   884  	expectParseError(t, "switch (1) { case 1: break }", "")
   885  	expectParseError(t, "switch (1) { case 1: continue }", "<stdin>: ERROR: Cannot use \"continue\" here:\n")
   886  	expectParseError(t, "x: switch (1) { case 1: break x }", "")
   887  	expectParseError(t, "x: switch (1) { case 1: continue x }", "<stdin>: ERROR: Cannot continue to label \"x\"\n")
   888  }
   889  
   890  func TestFor(t *testing.T) {
   891  	expectParseError(t, "for (; in x) ;", "<stdin>: ERROR: Unexpected \"in\"\n")
   892  	expectParseError(t, "for (; of x) ;", "<stdin>: ERROR: Expected \";\" but found \"x\"\n")
   893  	expectParseError(t, "for (; in; ) ;", "<stdin>: ERROR: Unexpected \"in\"\n")
   894  	expectPrinted(t, "for (; of; ) ;", "for (; of; ) ;\n")
   895  
   896  	expectPrinted(t, "for (a in b) ;", "for (a in b) ;\n")
   897  	expectPrinted(t, "for (var a in b) ;", "for (var a in b) ;\n")
   898  	expectPrinted(t, "for (let a in b) ;", "for (let a in b) ;\n")
   899  	expectPrinted(t, "for (const a in b) ;", "for (const a in b) ;\n")
   900  	expectPrinted(t, "for (a in b, c) ;", "for (a in b, c) ;\n")
   901  	expectPrinted(t, "for (a in b = c) ;", "for (a in b = c) ;\n")
   902  	expectPrinted(t, "for (var a in b, c) ;", "for (var a in b, c) ;\n")
   903  	expectPrinted(t, "for (var a in b = c) ;", "for (var a in b = c) ;\n")
   904  	expectParseError(t, "for (var a, b in b) ;", "<stdin>: ERROR: for-in loops must have a single declaration\n")
   905  	expectParseError(t, "for (let a, b in b) ;", "<stdin>: ERROR: for-in loops must have a single declaration\n")
   906  	expectParseError(t, "for (const a, b in b) ;", "<stdin>: ERROR: for-in loops must have a single declaration\n")
   907  
   908  	expectPrinted(t, "for (a of b) ;", "for (a of b) ;\n")
   909  	expectPrinted(t, "for (var a of b) ;", "for (var a of b) ;\n")
   910  	expectPrinted(t, "for (let a of b) ;", "for (let a of b) ;\n")
   911  	expectPrinted(t, "for (const a of b) ;", "for (const a of b) ;\n")
   912  	expectPrinted(t, "for (a of b = c) ;", "for (a of b = c) ;\n")
   913  	expectPrinted(t, "for (var a of b = c) ;", "for (var a of b = c) ;\n")
   914  	expectParseError(t, "for (a of b, c) ;", "<stdin>: ERROR: Expected \")\" but found \",\"\n")
   915  	expectParseError(t, "for (var a of b, c) ;", "<stdin>: ERROR: Expected \")\" but found \",\"\n")
   916  	expectParseError(t, "for (var a, b of b) ;", "<stdin>: ERROR: for-of loops must have a single declaration\n")
   917  	expectParseError(t, "for (let a, b of b) ;", "<stdin>: ERROR: for-of loops must have a single declaration\n")
   918  	expectParseError(t, "for (const a, b of b) ;", "<stdin>: ERROR: for-of loops must have a single declaration\n")
   919  
   920  	// Avoid the initializer starting with "let" token
   921  	expectPrinted(t, "for ((let) of bar);", "for ((let) of bar) ;\n")
   922  	expectPrinted(t, "for ((let).foo of bar);", "for ((let).foo of bar) ;\n")
   923  	expectPrinted(t, "for ((let.foo) of bar);", "for ((let).foo of bar) ;\n")
   924  	expectPrinted(t, "for ((let``.foo) of bar);", "for ((let)``.foo of bar) ;\n")
   925  	expectParseError(t, "for (let.foo of bar);", "<stdin>: ERROR: \"let\" must be wrapped in parentheses to be used as an expression here:\n")
   926  	expectParseError(t, "for (let().foo of bar);", "<stdin>: ERROR: \"let\" must be wrapped in parentheses to be used as an expression here:\n")
   927  	expectParseError(t, "for (let``.foo of bar);", "<stdin>: ERROR: \"let\" must be wrapped in parentheses to be used as an expression here:\n")
   928  
   929  	expectPrinted(t, "for (var x = 0 in y) ;", "x = 0;\nfor (var x in y) ;\n") // This is a weird special-case
   930  	expectParseError(t, "for (let x = 0 in y) ;", "<stdin>: ERROR: for-in loop variables cannot have an initializer\n")
   931  	expectParseError(t, "for (const x = 0 in y) ;", "<stdin>: ERROR: for-in loop variables cannot have an initializer\n")
   932  	expectParseError(t, "for (var x = 0 of y) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   933  	expectParseError(t, "for (let x = 0 of y) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   934  	expectParseError(t, "for (const x = 0 of y) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   935  
   936  	expectParseError(t, "for (var [x] = y in z) ;", "<stdin>: ERROR: for-in loop variables cannot have an initializer\n")
   937  	expectParseError(t, "for (let [x] = y in z) ;", "<stdin>: ERROR: for-in loop variables cannot have an initializer\n")
   938  	expectParseError(t, "for (const [x] = y in z) ;", "<stdin>: ERROR: for-in loop variables cannot have an initializer\n")
   939  	expectParseError(t, "for (var [x] = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   940  	expectParseError(t, "for (let [x] = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   941  	expectParseError(t, "for (const [x] = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   942  
   943  	expectParseError(t, "for (var {x} = y in z) ;", "<stdin>: ERROR: for-in loop variables cannot have an initializer\n")
   944  	expectParseError(t, "for (let {x} = y in z) ;", "<stdin>: ERROR: for-in loop variables cannot have an initializer\n")
   945  	expectParseError(t, "for (const {x} = y in z) ;", "<stdin>: ERROR: for-in loop variables cannot have an initializer\n")
   946  	expectParseError(t, "for (var {x} = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   947  	expectParseError(t, "for (let {x} = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   948  	expectParseError(t, "for (const {x} = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
   949  
   950  	// Make sure "in" rules are enabled
   951  	expectPrinted(t, "for (var x = () => a in b);", "x = () => a;\nfor (var x in b) ;\n")
   952  	expectPrinted(t, "for (var x = a + b in c);", "x = a + b;\nfor (var x in c) ;\n")
   953  
   954  	// Make sure "in" rules are disabled
   955  	expectPrinted(t, "for (var x = `${y in z}`;;);", "for (var x = `${y in z}`; ; ) ;\n")
   956  	expectPrinted(t, "for (var {[x in y]: z} = {};;);", "for (var { [x in y]: z } = {}; ; ) ;\n")
   957  	expectPrinted(t, "for (var {x = y in z} = {};;);", "for (var { x = y in z } = {}; ; ) ;\n")
   958  	expectPrinted(t, "for (var [x = y in z] = {};;);", "for (var [x = y in z] = {}; ; ) ;\n")
   959  	expectPrinted(t, "for (var {x: y = z in w} = {};;);", "for (var { x: y = z in w } = {}; ; ) ;\n")
   960  	expectPrinted(t, "for (var x = (a in b);;);", "for (var x = (a in b); ; ) ;\n")
   961  	expectPrinted(t, "for (var x = [a in b];;);", "for (var x = [a in b]; ; ) ;\n")
   962  	expectPrinted(t, "for (var x = y(a in b);;);", "for (var x = y(a in b); ; ) ;\n")
   963  	expectPrinted(t, "for (var x = {y: a in b};;);", "for (var x = { y: a in b }; ; ) ;\n")
   964  	expectPrinted(t, "for (a ? b in c : d;;);", "for (a ? b in c : d; ; ) ;\n")
   965  	expectPrinted(t, "for (var x = () => { a in b };;);", "for (var x = () => {\n  a in b;\n}; ; ) ;\n")
   966  	expectPrinted(t, "for (var x = async () => { a in b };;);", "for (var x = async () => {\n  a in b;\n}; ; ) ;\n")
   967  	expectPrinted(t, "for (var x = function() { a in b };;);", "for (var x = function() {\n  a in b;\n}; ; ) ;\n")
   968  	expectPrinted(t, "for (var x = async function() { a in b };;);", "for (var x = async function() {\n  a in b;\n}; ; ) ;\n")
   969  	expectPrinted(t, "for (var x = class { [a in b]() {} };;);", "for (var x = class {\n  [a in b]() {\n  }\n}; ; ) ;\n")
   970  	expectParseError(t, "for (var x = class extends a in b {};;);", "<stdin>: ERROR: Expected \"{\" but found \"in\"\n")
   971  
   972  	errorText := `<stdin>: WARNING: This assignment will throw because "x" is a constant
   973  <stdin>: NOTE: The symbol "x" was declared a constant here:
   974  `
   975  	expectParseError(t, "for (var x = 0; ; x = 1) ;", "")
   976  	expectParseError(t, "for (let x = 0; ; x = 1) ;", "")
   977  	expectParseError(t, "for (const x = 0; ; x = 1) ;", errorText)
   978  	expectParseError(t, "for (var x = 0; ; x++) ;", "")
   979  	expectParseError(t, "for (let x = 0; ; x++) ;", "")
   980  	expectParseError(t, "for (const x = 0; ; x++) ;", errorText)
   981  
   982  	expectParseError(t, "for (var x in y) x = 1", "")
   983  	expectParseError(t, "for (let x in y) x = 1", "")
   984  	expectParseError(t, "for (const x in y) x = 1", errorText)
   985  	expectParseError(t, "for (var x in y) x++", "")
   986  	expectParseError(t, "for (let x in y) x++", "")
   987  	expectParseError(t, "for (const x in y) x++", errorText)
   988  
   989  	expectParseError(t, "for (var x of y) x = 1", "")
   990  	expectParseError(t, "for (let x of y) x = 1", "")
   991  	expectParseError(t, "for (const x of y) x = 1", errorText)
   992  	expectParseError(t, "for (var x of y) x++", "")
   993  	expectParseError(t, "for (let x of y) x++", "")
   994  	expectParseError(t, "for (const x of y) x++", errorText)
   995  
   996  	expectPrinted(t, "async of => {}", "async (of) => {\n};\n")
   997  	expectPrinted(t, "for ((async) of []) ;", "for ((async) of []) ;\n")
   998  	expectPrinted(t, "for (async.x of []) ;", "for (async.x of []) ;\n")
   999  	expectPrinted(t, "for (async of => {};;) ;", "for (async (of) => {\n}; ; ) ;\n")
  1000  	expectPrinted(t, "for (\\u0061sync of []) ;", "for ((async) of []) ;\n")
  1001  	expectPrinted(t, "for await (async of []) ;", "for await (async of []) ;\n")
  1002  	expectParseError(t, "for (async of []) ;", "<stdin>: ERROR: For loop initializers cannot start with \"async of\"\n")
  1003  	expectParseError(t, "for (async o\\u0066 []) ;", "<stdin>: ERROR: Expected \";\" but found \"o\\\\u0066\"\n")
  1004  	expectParseError(t, "for await (async of => {}) ;", "<stdin>: ERROR: Expected \"of\" but found \")\"\n")
  1005  	expectParseError(t, "for await (async of => {} of []) ;", "<stdin>: ERROR: Invalid assignment target\n")
  1006  	expectParseError(t, "for await (async o\\u0066 []) ;", "<stdin>: ERROR: Expected \"of\" but found \"o\\\\u0066\"\n")
  1007  
  1008  	// Can't use await at the top-level without top-level await
  1009  	err := "<stdin>: ERROR: Top-level await is not available in the configured target environment\n"
  1010  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "for await (x of y);", err)
  1011  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) for await (x of y);", err)
  1012  	expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) for await (x of y);", "if (false) for (x of y) ;\n")
  1013  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "with (x) y; if (false) for await (x of y);",
  1014  		"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n"+
  1015  			"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n")
  1016  }
  1017  
  1018  func TestScope(t *testing.T) {
  1019  	errorText := `<stdin>: ERROR: The symbol "x" has already been declared
  1020  <stdin>: NOTE: The symbol "x" was originally declared here:
  1021  `
  1022  
  1023  	expectParseError(t, "var x; var y", "")
  1024  	expectParseError(t, "var x; let y", "")
  1025  	expectParseError(t, "let x; var y", "")
  1026  	expectParseError(t, "let x; let y", "")
  1027  
  1028  	expectParseError(t, "var x; var x", "")
  1029  	expectParseError(t, "var x; let x", errorText)
  1030  	expectParseError(t, "let x; var x", errorText)
  1031  	expectParseError(t, "let x; let x", errorText)
  1032  	expectParseError(t, "function x() {} let x", errorText)
  1033  	expectParseError(t, "let x; function x() {}", errorText)
  1034  
  1035  	expectParseError(t, "var x; {var x}", "")
  1036  	expectParseError(t, "var x; {let x}", "")
  1037  	expectParseError(t, "let x; {var x}", errorText)
  1038  	expectParseError(t, "let x; {let x}", "")
  1039  	expectParseError(t, "let x; {function x() {}}", "")
  1040  
  1041  	expectParseError(t, "{var x} var x", "")
  1042  	expectParseError(t, "{var x} let x", errorText)
  1043  	expectParseError(t, "{let x} var x", "")
  1044  	expectParseError(t, "{let x} let x", "")
  1045  	expectParseError(t, "{function x() {}} let x", "")
  1046  
  1047  	expectParseError(t, "{var x; {var x}}", "")
  1048  	expectParseError(t, "{var x; {let x}}", "")
  1049  	expectParseError(t, "{let x; {var x}}", errorText)
  1050  	expectParseError(t, "{let x; {let x}}", "")
  1051  	expectParseError(t, "{let x; {function x() {}}}", "")
  1052  
  1053  	expectParseError(t, "{{var x} var x}", "")
  1054  	expectParseError(t, "{{var x} let x}", errorText)
  1055  	expectParseError(t, "{{let x} var x}", "")
  1056  	expectParseError(t, "{{let x} let x}", "")
  1057  	expectParseError(t, "{{function x() {}} let x}", "")
  1058  
  1059  	expectParseError(t, "{var x} {var x}", "")
  1060  	expectParseError(t, "{var x} {let x}", "")
  1061  	expectParseError(t, "{let x} {var x}", "")
  1062  	expectParseError(t, "{let x} {let x}", "")
  1063  	expectParseError(t, "{let x} {function x() {}}", "")
  1064  	expectParseError(t, "{function x() {}} {let x}", "")
  1065  
  1066  	expectParseError(t, "function x() {} {var x}", "")
  1067  	expectParseError(t, "function *x() {} {var x}", "")
  1068  	expectParseError(t, "async function x() {} {var x}", "")
  1069  	expectParseError(t, "async function *x() {} {var x}", "")
  1070  
  1071  	expectParseError(t, "{var x} function x() {}", "")
  1072  	expectParseError(t, "{var x} function *x() {}", "")
  1073  	expectParseError(t, "{var x} async function x() {}", "")
  1074  	expectParseError(t, "{var x} async function *x() {}", "")
  1075  
  1076  	expectParseError(t, "{ function x() {} {var x} }", errorText)
  1077  	expectParseError(t, "{ function *x() {} {var x} }", errorText)
  1078  	expectParseError(t, "{ async function x() {} {var x} }", errorText)
  1079  	expectParseError(t, "{ async function *x() {} {var x} }", errorText)
  1080  
  1081  	expectParseError(t, "{ {var x} function x() {} }", errorText)
  1082  	expectParseError(t, "{ {var x} function *x() {} }", errorText)
  1083  	expectParseError(t, "{ {var x} async function x() {} }", errorText)
  1084  	expectParseError(t, "{ {var x} async function *x() {} }", errorText)
  1085  
  1086  	expectParseError(t, "function f() { function x() {} {var x} }", "")
  1087  	expectParseError(t, "function f() { function *x() {} {var x} }", "")
  1088  	expectParseError(t, "function f() { async function x() {} {var x} }", "")
  1089  	expectParseError(t, "function f() { async function *x() {} {var x} }", "")
  1090  
  1091  	expectParseError(t, "function f() { {var x} function x() {} }", "")
  1092  	expectParseError(t, "function f() { {var x} function *x() {} }", "")
  1093  	expectParseError(t, "function f() { {var x} async function x() {} }", "")
  1094  	expectParseError(t, "function f() { {var x} async function *x() {} }", "")
  1095  
  1096  	expectParseError(t, "function f() { { function x() {} {var x} } }", errorText)
  1097  	expectParseError(t, "function f() { { function *x() {} {var x} } }", errorText)
  1098  	expectParseError(t, "function f() { { async function x() {} {var x} } }", errorText)
  1099  	expectParseError(t, "function f() { { async function *x() {} {var x} } }", errorText)
  1100  
  1101  	expectParseError(t, "function f() { { {var x} function x() {} } }", errorText)
  1102  	expectParseError(t, "function f() { { {var x} function *x() {} } }", errorText)
  1103  	expectParseError(t, "function f() { { {var x} async function x() {} } }", errorText)
  1104  	expectParseError(t, "function f() { { {var x} async function *x() {} } }", errorText)
  1105  
  1106  	expectParseError(t, "var x=1, x=2", "")
  1107  	expectParseError(t, "let x=1, x=2", errorText)
  1108  	expectParseError(t, "const x=1, x=2", errorText)
  1109  
  1110  	expectParseError(t, "function foo(x) { var x }", "")
  1111  	expectParseError(t, "function foo(x) { let x }", errorText)
  1112  	expectParseError(t, "function foo(x) { const x = 0 }", errorText)
  1113  	expectParseError(t, "function foo() { var foo }", "")
  1114  	expectParseError(t, "function foo() { let foo }", "")
  1115  	expectParseError(t, "function foo() { const foo = 0 }", "")
  1116  
  1117  	expectParseError(t, "(function foo(x) { var x })", "")
  1118  	expectParseError(t, "(function foo(x) { let x })", errorText)
  1119  	expectParseError(t, "(function foo(x) { const x = 0 })", errorText)
  1120  	expectParseError(t, "(function foo() { var foo })", "")
  1121  	expectParseError(t, "(function foo() { let foo })", "")
  1122  	expectParseError(t, "(function foo() { const foo = 0 })", "")
  1123  
  1124  	expectParseError(t, "var x; function x() {}", "")
  1125  	expectParseError(t, "var x; function *x() {}", "")
  1126  	expectParseError(t, "var x; async function x() {}", "")
  1127  	expectParseError(t, "let x; function x() {}", errorText)
  1128  	expectParseError(t, "function x() {} var x", "")
  1129  	expectParseError(t, "function* x() {} var x", "")
  1130  	expectParseError(t, "async function x() {} var x", "")
  1131  	expectParseError(t, "function x() {} let x", errorText)
  1132  	expectParseError(t, "function x() {} function x() {}", "")
  1133  
  1134  	expectParseError(t, "var x; class x {}", errorText)
  1135  	expectParseError(t, "let x; class x {}", errorText)
  1136  	expectParseError(t, "class x {} var x", errorText)
  1137  	expectParseError(t, "class x {} let x", errorText)
  1138  	expectParseError(t, "class x {} class x {}", errorText)
  1139  
  1140  	expectParseError(t, "function x() {} function x() {}", "")
  1141  	expectParseError(t, "function x() {} function *x() {}", "")
  1142  	expectParseError(t, "function x() {} async function x() {}", "")
  1143  	expectParseError(t, "function *x() {} function x() {}", "")
  1144  	expectParseError(t, "function *x() {} function *x() {}", "")
  1145  	expectParseError(t, "async function x() {} function x() {}", "")
  1146  	expectParseError(t, "async function x() {} async function x() {}", "")
  1147  
  1148  	expectParseError(t, "function f() { function x() {} function x() {} }", "")
  1149  	expectParseError(t, "function f() { function x() {} function *x() {} }", "")
  1150  	expectParseError(t, "function f() { function x() {} async function x() {} }", "")
  1151  	expectParseError(t, "function f() { function *x() {} function x() {} }", "")
  1152  	expectParseError(t, "function f() { function *x() {} function *x() {} }", "")
  1153  	expectParseError(t, "function f() { async function x() {} function x() {} }", "")
  1154  	expectParseError(t, "function f() { async function x() {} async function x() {} }", "")
  1155  
  1156  	text := "<stdin>: ERROR: The symbol \"x\" has already been declared\n<stdin>: NOTE: The symbol \"x\" was originally declared here:\n"
  1157  	for _, scope := range []string{"", "with (x)", "while (x)", "if (x)"} {
  1158  		expectParseError(t, scope+"{ function x() {} function x() {} }", "")
  1159  		expectParseError(t, scope+"{ function x() {} function *x() {} }", text)
  1160  		expectParseError(t, scope+"{ function x() {} async function x() {} }", text)
  1161  		expectParseError(t, scope+"{ function *x() {} function x() {} }", text)
  1162  		expectParseError(t, scope+"{ function *x() {} function *x() {} }", text)
  1163  		expectParseError(t, scope+"{ async function x() {} function x() {} }", text)
  1164  		expectParseError(t, scope+"{ async function x() {} async function x() {} }", text)
  1165  	}
  1166  }
  1167  
  1168  func TestASI(t *testing.T) {
  1169  	expectParseError(t, "throw\n0", "<stdin>: ERROR: Unexpected newline after \"throw\"\n")
  1170  	expectParseError(t, "return\n0", "<stdin>: WARNING: The following expression is not returned because of an automatically-inserted semicolon\n")
  1171  	expectPrinted(t, "return\n0", "return;\n0;\n")
  1172  	expectPrinted(t, "0\n[1]", "0[1];\n")
  1173  	expectPrinted(t, "0\n(1)", "0(1);\n")
  1174  	expectPrinted(t, "new x\n(1)", "new x(1);\n")
  1175  	expectPrinted(t, "while (true) break\nx", "while (true) break;\nx;\n")
  1176  	expectPrinted(t, "x\n!y", "x;\n!y;\n")
  1177  	expectPrinted(t, "x\n++y", "x;\n++y;\n")
  1178  	expectPrinted(t, "x\n--y", "x;\n--y;\n")
  1179  
  1180  	expectPrinted(t, "function* foo(){yield\na}", "function* foo() {\n  yield;\n  a;\n}\n")
  1181  	expectParseError(t, "function* foo(){yield\n*a}", "<stdin>: ERROR: Unexpected \"*\"\n")
  1182  	expectPrinted(t, "function* foo(){yield*\na}", "function* foo() {\n  yield* a;\n}\n")
  1183  
  1184  	expectPrinted(t, "async\nx => {}", "async;\n(x) => {\n};\n")
  1185  	expectPrinted(t, "async\nfunction foo() {}", "async;\nfunction foo() {\n}\n")
  1186  	expectPrinted(t, "export default async\nx => {}", "export default async;\n(x) => {\n};\n")
  1187  	expectPrinted(t, "export default async\nfunction foo() {}", "export default async;\nfunction foo() {\n}\n")
  1188  	expectParseError(t, "async\n() => {}", "<stdin>: ERROR: Expected \";\" but found \"=>\"\n")
  1189  	expectParseError(t, "export async\nfunction foo() {}", "<stdin>: ERROR: Unexpected newline after \"async\"\n")
  1190  	expectParseError(t, "export default async\n() => {}", "<stdin>: ERROR: Expected \";\" but found \"=>\"\n")
  1191  	expectParseError(t, "(async\nx => {})", "<stdin>: ERROR: Expected \")\" but found \"x\"\n")
  1192  	expectParseError(t, "(async\n() => {})", "<stdin>: ERROR: Expected \")\" but found \"=>\"\n")
  1193  	expectParseError(t, "(async\nfunction foo() {})", "<stdin>: ERROR: Expected \")\" but found \"function\"\n")
  1194  
  1195  	expectPrinted(t, "if (0) let\nx = 0", "if (0) let;\nx = 0;\n")
  1196  	expectPrinted(t, "if (0) let\n{x}", "if (0) let;\n{\n  x;\n}\n")
  1197  	expectParseError(t, "if (0) let\n{x} = 0", "<stdin>: ERROR: Unexpected \"=\"\n")
  1198  	expectParseError(t, "if (0) let\n[x] = 0", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1199  	expectPrinted(t, "function *foo() { if (0) let\nyield 0 }", "function* foo() {\n  if (0) let;\n  yield 0;\n}\n")
  1200  	expectPrinted(t, "async function foo() { if (0) let\nawait 0 }", "async function foo() {\n  if (0) let;\n  await 0;\n}\n")
  1201  
  1202  	expectPrinted(t, "let\nx = 0", "let x = 0;\n")
  1203  	expectPrinted(t, "let\n{x} = 0", "let { x } = 0;\n")
  1204  	expectPrinted(t, "let\n[x] = 0", "let [x] = 0;\n")
  1205  	expectParseError(t, "function *foo() { let\nyield 0 }",
  1206  		"<stdin>: ERROR: Cannot use \"yield\" as an identifier here:\n<stdin>: ERROR: Expected \";\" but found \"0\"\n")
  1207  	expectParseError(t, "async function foo() { let\nawait 0 }",
  1208  		"<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n<stdin>: ERROR: Expected \";\" but found \"0\"\n")
  1209  
  1210  	// This is a weird corner case where ASI applies without a newline
  1211  	expectPrinted(t, "do x;while(y)z", "do\n  x;\nwhile (y);\nz;\n")
  1212  	expectPrinted(t, "do x;while(y);z", "do\n  x;\nwhile (y);\nz;\n")
  1213  	expectPrinted(t, "{do x;while(y)}", "{\n  do\n    x;\n  while (y);\n}\n")
  1214  }
  1215  
  1216  func TestLocal(t *testing.T) {
  1217  	expectPrinted(t, "var let = 0", "var let = 0;\n")
  1218  	expectParseError(t, "let let = 0", "<stdin>: ERROR: Cannot use \"let\" as an identifier here:\n")
  1219  	expectParseError(t, "const let = 0", "<stdin>: ERROR: Cannot use \"let\" as an identifier here:\n")
  1220  
  1221  	expectPrinted(t, "var\nlet = 0", "var let = 0;\n")
  1222  	expectParseError(t, "let\nlet = 0", "<stdin>: ERROR: Cannot use \"let\" as an identifier here:\n")
  1223  	expectParseError(t, "const\nlet = 0", "<stdin>: ERROR: Cannot use \"let\" as an identifier here:\n")
  1224  
  1225  	expectPrinted(t, "for (var let in x) ;", "for (var let in x) ;\n")
  1226  	expectParseError(t, "for (let let in x) ;", "<stdin>: ERROR: Cannot use \"let\" as an identifier here:\n")
  1227  	expectParseError(t, "for (const let in x) ;", "<stdin>: ERROR: Cannot use \"let\" as an identifier here:\n")
  1228  
  1229  	expectPrinted(t, "for (var let of x) ;", "for (var let of x) ;\n")
  1230  	expectParseError(t, "for (let let of x) ;", "<stdin>: ERROR: Cannot use \"let\" as an identifier here:\n")
  1231  	expectParseError(t, "for (const let of x) ;", "<stdin>: ERROR: Cannot use \"let\" as an identifier here:\n")
  1232  
  1233  	errorText := `<stdin>: WARNING: This assignment will throw because "x" is a constant
  1234  <stdin>: NOTE: The symbol "x" was declared a constant here:
  1235  `
  1236  	expectParseError(t, "var x = 0; x = 1", "")
  1237  	expectParseError(t, "let x = 0; x = 1", "")
  1238  	expectParseError(t, "const x = 0; x = 1", errorText)
  1239  	expectParseError(t, "var x = 0; x++", "")
  1240  	expectParseError(t, "let x = 0; x++", "")
  1241  	expectParseError(t, "const x = 0; x++", errorText)
  1242  }
  1243  
  1244  func TestArrays(t *testing.T) {
  1245  	expectPrinted(t, "[]", "[];\n")
  1246  	expectPrinted(t, "[,]", "[,];\n")
  1247  	expectPrinted(t, "[1]", "[1];\n")
  1248  	expectPrinted(t, "[1,]", "[1];\n")
  1249  	expectPrinted(t, "[,1]", "[, 1];\n")
  1250  	expectPrinted(t, "[1,2]", "[1, 2];\n")
  1251  	expectPrinted(t, "[,1,2]", "[, 1, 2];\n")
  1252  	expectPrinted(t, "[1,,2]", "[1, , 2];\n")
  1253  	expectPrinted(t, "[1,2,]", "[1, 2];\n")
  1254  	expectPrinted(t, "[1,2,,]", "[1, 2, ,];\n")
  1255  }
  1256  
  1257  func TestPattern(t *testing.T) {
  1258  	expectPrinted(t, "let {if: x} = y", "let { if: x } = y;\n")
  1259  	expectParseError(t, "let {x: if} = y", "<stdin>: ERROR: Expected identifier but found \"if\"\n")
  1260  
  1261  	expectPrinted(t, "let {1_2_3n: x} = y", "let { 123n: x } = y;\n")
  1262  	expectPrinted(t, "let {0x1_2_3n: x} = y", "let { 0x123n: x } = y;\n")
  1263  
  1264  	expectParseError(t, "var [ (x) ] = 0", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  1265  	expectParseError(t, "var [ ...(x) ] = 0", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  1266  	expectParseError(t, "var { (x) } = 0", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  1267  	expectParseError(t, "var { x: (y) } = 0", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  1268  	expectParseError(t, "var { ...(x) } = 0", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  1269  }
  1270  
  1271  func TestAssignTarget(t *testing.T) {
  1272  	expectParseError(t, "x = 0", "")
  1273  	expectParseError(t, "x.y = 0", "")
  1274  	expectParseError(t, "x[y] = 0", "")
  1275  	expectParseError(t, "[,] = 0", "")
  1276  	expectParseError(t, "[x] = 0", "")
  1277  	expectParseError(t, "[x = y] = 0", "")
  1278  	expectParseError(t, "[...x] = 0", "")
  1279  	expectParseError(t, "({...x} = 0)", "")
  1280  	expectParseError(t, "({x = 0} = 0)", "")
  1281  	expectParseError(t, "({x: y = 0} = 0)", "")
  1282  
  1283  	expectParseError(t, "[ (y) ] = 0", "")
  1284  	expectParseError(t, "[ ...(y) ] = 0", "")
  1285  	expectParseError(t, "({ (y) } = 0)", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  1286  	expectParseError(t, "({ y: (z) } = 0)", "")
  1287  	expectParseError(t, "({ ...(y) } = 0)", "")
  1288  
  1289  	expectParseError(t, "[...x = y] = 0", "<stdin>: ERROR: Invalid assignment target\n")
  1290  	expectParseError(t, "x() = 0", "<stdin>: ERROR: Invalid assignment target\n")
  1291  	expectParseError(t, "x?.y = 0", "<stdin>: ERROR: Invalid assignment target\n")
  1292  	expectParseError(t, "x?.[y] = 0", "<stdin>: ERROR: Invalid assignment target\n")
  1293  	expectParseError(t, "({x: 0} = 0)", "<stdin>: ERROR: Invalid assignment target\n")
  1294  	expectParseError(t, "({x() {}} = 0)", "<stdin>: ERROR: Invalid assignment target\n")
  1295  	expectParseError(t, "({x: 0 = y} = 0)", "<stdin>: ERROR: Invalid assignment target\n")
  1296  }
  1297  
  1298  func TestObject(t *testing.T) {
  1299  	expectPrinted(t, "({foo})", "({ foo });\n")
  1300  	expectPrinted(t, "({foo:0})", "({ foo: 0 });\n")
  1301  	expectPrinted(t, "({1e9:0})", "({ 1e9: 0 });\n")
  1302  	expectPrinted(t, "({1_2_3n:0})", "({ 123n: 0 });\n")
  1303  	expectPrinted(t, "({0x1_2_3n:0})", "({ 0x123n: 0 });\n")
  1304  	expectPrinted(t, "({foo() {}})", "({ foo() {\n} });\n")
  1305  	expectPrinted(t, "({*foo() {}})", "({ *foo() {\n} });\n")
  1306  	expectPrinted(t, "({get foo() {}})", "({ get foo() {\n} });\n")
  1307  	expectPrinted(t, "({set foo(x) {}})", "({ set foo(x) {\n} });\n")
  1308  
  1309  	expectPrinted(t, "({if:0})", "({ if: 0 });\n")
  1310  	expectPrinted(t, "({if() {}})", "({ if() {\n} });\n")
  1311  	expectPrinted(t, "({*if() {}})", "({ *if() {\n} });\n")
  1312  	expectPrinted(t, "({get if() {}})", "({ get if() {\n} });\n")
  1313  	expectPrinted(t, "({set if(x) {}})", "({ set if(x) {\n} });\n")
  1314  
  1315  	expectParseError(t, "({static foo() {}})", "<stdin>: ERROR: Expected \"}\" but found \"foo\"\n")
  1316  	expectParseError(t, "({`a`})", "<stdin>: ERROR: Expected identifier but found \"`a`\"\n")
  1317  	expectParseError(t, "({if})", "<stdin>: ERROR: Expected \":\" but found \"}\"\n")
  1318  
  1319  	protoError := "<stdin>: ERROR: Cannot specify the \"__proto__\" property more than once per object\n" +
  1320  		"<stdin>: NOTE: The earlier \"__proto__\" property is here:\n"
  1321  
  1322  	expectParseError(t, "({__proto__: 1, __proto__: 2})", protoError)
  1323  	expectParseError(t, "({__proto__: 1, '__proto__': 2})", protoError)
  1324  	expectParseError(t, "({__proto__: 1, __proto__() {}})", "")
  1325  	expectParseError(t, "({__proto__: 1, get __proto__() {}})", "")
  1326  	expectParseError(t, "({__proto__: 1, set __proto__(x) {}})", "")
  1327  	expectParseError(t, "({__proto__: 1, ['__proto__']: 2})", "")
  1328  	expectParseError(t, "({__proto__, __proto__: 2})", "")
  1329  	expectParseError(t, "({__proto__: x, __proto__: y} = z)", "")
  1330  
  1331  	expectPrintedMangle(t, "x = {['_proto_']: x}", "x = { _proto_: x };\n")
  1332  	expectPrintedMangle(t, "x = {['__proto__']: x}", "x = { [\"__proto__\"]: x };\n")
  1333  
  1334  	expectParseError(t, "({set foo() {}})", "<stdin>: ERROR: Setter \"foo\" must have exactly one argument\n")
  1335  	expectParseError(t, "({get foo(x) {}})", "<stdin>: ERROR: Getter \"foo\" must have zero arguments\n")
  1336  	expectParseError(t, "({set foo(x, y) {}})", "<stdin>: ERROR: Setter \"foo\" must have exactly one argument\n")
  1337  
  1338  	expectParseError(t, "(class {set #foo() {}})", "<stdin>: ERROR: Setter \"#foo\" must have exactly one argument\n")
  1339  	expectParseError(t, "(class {get #foo(x) {}})", "<stdin>: ERROR: Getter \"#foo\" must have zero arguments\n")
  1340  	expectParseError(t, "(class {set #foo(x, y) {}})", "<stdin>: ERROR: Setter \"#foo\" must have exactly one argument\n")
  1341  
  1342  	expectParseError(t, "({set [foo]() {}})", "<stdin>: ERROR: Setter property must have exactly one argument\n")
  1343  	expectParseError(t, "({get [foo](x) {}})", "<stdin>: ERROR: Getter property must have zero arguments\n")
  1344  	expectParseError(t, "({set [foo](x, y) {}})", "<stdin>: ERROR: Setter property must have exactly one argument\n")
  1345  
  1346  	duplicateWarning := "<stdin>: WARNING: Duplicate key \"x\" in object literal\n" +
  1347  		"<stdin>: NOTE: The original key \"x\" is here:\n"
  1348  	expectParseError(t, "({x, x})", duplicateWarning)
  1349  	expectParseError(t, "({x() {}, x() {}})", duplicateWarning)
  1350  	expectParseError(t, "({get x() {}, get x() {}})", duplicateWarning)
  1351  	expectParseError(t, "({get x() {}, set x(y) {}, get x() {}})", duplicateWarning)
  1352  	expectParseError(t, "({get x() {}, set x(y) {}, set x(y) {}})", duplicateWarning)
  1353  	expectParseError(t, "({get x() {}, set x(y) {}})", "")
  1354  	expectParseError(t, "({set x(y) {}, get x() {}})", "")
  1355  
  1356  	// Check the string-to-int optimization
  1357  	expectPrintedMangle(t, "x = { '0': y }", "x = { 0: y };\n")
  1358  	expectPrintedMangle(t, "x = { '123': y }", "x = { 123: y };\n")
  1359  	expectPrintedMangle(t, "x = { '-123': y }", "x = { \"-123\": y };\n")
  1360  	expectPrintedMangle(t, "x = { '-0': y }", "x = { \"-0\": y };\n")
  1361  	expectPrintedMangle(t, "x = { '01': y }", "x = { \"01\": y };\n")
  1362  	expectPrintedMangle(t, "x = { '-01': y }", "x = { \"-01\": y };\n")
  1363  	expectPrintedMangle(t, "x = { '0x1': y }", "x = { \"0x1\": y };\n")
  1364  	expectPrintedMangle(t, "x = { '-0x1': y }", "x = { \"-0x1\": y };\n")
  1365  	expectPrintedMangle(t, "x = { '2147483647': y }", "x = { 2147483647: y };\n")
  1366  	expectPrintedMangle(t, "x = { '2147483648': y }", "x = { \"2147483648\": y };\n")
  1367  	expectPrintedMangle(t, "x = { '-2147483648': y }", "x = { \"-2147483648\": y };\n")
  1368  	expectPrintedMangle(t, "x = { '-2147483649': y }", "x = { \"-2147483649\": y };\n")
  1369  }
  1370  
  1371  func TestComputedProperty(t *testing.T) {
  1372  	expectPrinted(t, "({[a]: foo})", "({ [a]: foo });\n")
  1373  	expectPrinted(t, "({[(a, b)]: foo})", "({ [(a, b)]: foo });\n")
  1374  	expectParseError(t, "({[a, b]: foo})", "<stdin>: ERROR: Expected \"]\" but found \",\"\n")
  1375  
  1376  	expectPrinted(t, "({[a]: foo}) => {}", "({ [a]: foo }) => {\n};\n")
  1377  	expectPrinted(t, "({[(a, b)]: foo}) => {}", "({ [(a, b)]: foo }) => {\n};\n")
  1378  	expectParseError(t, "({[a, b]: foo}) => {}", "<stdin>: ERROR: Expected \"]\" but found \",\"\n")
  1379  
  1380  	expectPrinted(t, "var {[a]: foo} = bar", "var { [a]: foo } = bar;\n")
  1381  	expectPrinted(t, "var {[(a, b)]: foo} = bar", "var { [(a, b)]: foo } = bar;\n")
  1382  	expectParseError(t, "var {[a, b]: foo} = bar", "<stdin>: ERROR: Expected \"]\" but found \",\"\n")
  1383  
  1384  	expectPrinted(t, "class Foo {[a] = foo}", "class Foo {\n  [a] = foo;\n}\n")
  1385  	expectPrinted(t, "class Foo {[(a, b)] = foo}", "class Foo {\n  [(a, b)] = foo;\n}\n")
  1386  	expectParseError(t, "class Foo {[a, b] = foo}", "<stdin>: ERROR: Expected \"]\" but found \",\"\n")
  1387  }
  1388  
  1389  func TestQuotedProperty(t *testing.T) {
  1390  	expectPrinted(t, "x.x; y['y']", "x.x;\ny[\"y\"];\n")
  1391  	expectPrinted(t, "({y: y, 'z': z} = x)", "({ y, \"z\": z } = x);\n")
  1392  	expectPrinted(t, "var {y: y, 'z': z} = x", "var { y, \"z\": z } = x;\n")
  1393  	expectPrinted(t, "x = {y: 1, 'z': 2}", "x = { y: 1, \"z\": 2 };\n")
  1394  	expectPrinted(t, "x = {y() {}, 'z'() {}}", "x = { y() {\n}, \"z\"() {\n} };\n")
  1395  	expectPrinted(t, "x = {get y() {}, set 'z'(z) {}}", "x = { get y() {\n}, set \"z\"(z) {\n} };\n")
  1396  	expectPrinted(t, "x = class {y = 1; 'z' = 2}", "x = class {\n  y = 1;\n  \"z\" = 2;\n};\n")
  1397  	expectPrinted(t, "x = class {y() {}; 'z'() {}}", "x = class {\n  y() {\n  }\n  \"z\"() {\n  }\n};\n")
  1398  	expectPrinted(t, "x = class {get y() {}; set 'z'(z) {}}", "x = class {\n  get y() {\n  }\n  set \"z\"(z) {\n  }\n};\n")
  1399  
  1400  	expectPrintedMangle(t, "x.x; y['y']", "x.x, y.y;\n")
  1401  	expectPrintedMangle(t, "({y: y, 'z': z} = x)", "({ y, z } = x);\n")
  1402  	expectPrintedMangle(t, "var {y: y, 'z': z} = x", "var { y, z } = x;\n")
  1403  	expectPrintedMangle(t, "x = {y: 1, 'z': 2}", "x = { y: 1, z: 2 };\n")
  1404  	expectPrintedMangle(t, "x = {y() {}, 'z'() {}}", "x = { y() {\n}, z() {\n} };\n")
  1405  	expectPrintedMangle(t, "x = {get y() {}, set 'z'(z) {}}", "x = { get y() {\n}, set z(z) {\n} };\n")
  1406  	expectPrintedMangle(t, "x = class {y = 1; 'z' = 2}", "x = class {\n  y = 1;\n  z = 2;\n};\n")
  1407  	expectPrintedMangle(t, "x = class {y() {}; 'z'() {}}", "x = class {\n  y() {\n  }\n  z() {\n  }\n};\n")
  1408  	expectPrintedMangle(t, "x = class {get y() {}; set 'z'(z) {}}", "x = class {\n  get y() {\n  }\n  set z(z) {\n  }\n};\n")
  1409  }
  1410  
  1411  func TestLexicalDecl(t *testing.T) {
  1412  	expectPrinted(t, "if (1) var x", "if (1) var x;\n")
  1413  	expectPrinted(t, "if (1) function x() {}", "if (1) {\n  let x = function() {\n  };\n  var x = x;\n}\n")
  1414  	expectPrinted(t, "if (1) {} else function x() {}", "if (1) {\n} else {\n  let x = function() {\n  };\n  var x = x;\n}\n")
  1415  	expectPrinted(t, "switch (1) { case 1: const x = 1 }", "switch (1) {\n  case 1:\n    const x = 1;\n}\n")
  1416  	expectPrinted(t, "switch (1) { default: const x = 1 }", "switch (1) {\n  default:\n    const x = 1;\n}\n")
  1417  
  1418  	singleStmtContext := []string{
  1419  		"label: %s",
  1420  		"for (;;) %s",
  1421  		"if (1) %s",
  1422  		"while (1) %s",
  1423  		"with ({}) %s",
  1424  		"if (1) {} else %s",
  1425  		"do %s \n while(0)",
  1426  
  1427  		"for (;;) label: %s",
  1428  		"if (1) label: %s",
  1429  		"while (1) label: %s",
  1430  		"with ({}) label: %s",
  1431  		"if (1) {} else label: %s",
  1432  		"do label: %s \n while(0)",
  1433  
  1434  		"for (;;) label: label2: %s",
  1435  		"if (1) label: label2: %s",
  1436  		"while (1) label: label2: %s",
  1437  		"with ({}) label: label2: %s",
  1438  		"if (1) {} else label: label2: %s",
  1439  		"do label: label2: %s \n while(0)",
  1440  	}
  1441  
  1442  	for _, context := range singleStmtContext {
  1443  		expectParseError(t, fmt.Sprintf(context, "const x = 0"), "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1444  		expectParseError(t, fmt.Sprintf(context, "let x"), "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1445  		expectParseError(t, fmt.Sprintf(context, "class X {}"), "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1446  		expectParseError(t, fmt.Sprintf(context, "function* x() {}"), "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1447  		expectParseError(t, fmt.Sprintf(context, "async function x() {}"), "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1448  		expectParseError(t, fmt.Sprintf(context, "async function* x() {}"), "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1449  	}
  1450  
  1451  	expectPrinted(t, "function f() {}", "function f() {\n}\n")
  1452  	expectPrinted(t, "{function f() {}} let f", "{\n  let f = function() {\n  };\n}\nlet f;\n")
  1453  	expectPrinted(t, "if (1) function f() {} let f", "if (1) {\n  let f = function() {\n  };\n}\nlet f;\n")
  1454  	expectPrinted(t, "if (0) ; else function f() {} let f", "if (0) ;\nelse {\n  let f = function() {\n  };\n}\nlet f;\n")
  1455  	expectPrinted(t, "x: function f() {}", "x: {\n  let f = function() {\n  };\n  var f = f;\n}\n")
  1456  	expectPrinted(t, "{function* f() {}} let f", "{\n  function* f() {\n  }\n}\nlet f;\n")
  1457  	expectPrinted(t, "{async function f() {}} let f", "{\n  async function f() {\n  }\n}\nlet f;\n")
  1458  
  1459  	expectParseError(t, "if (1) label: function f() {} let f", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1460  	expectParseError(t, "if (1) label: label2: function f() {} let f", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1461  	expectParseError(t, "if (0) ; else label: function f() {} let f", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1462  	expectParseError(t, "if (0) ; else label: label2: function f() {} let f", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1463  
  1464  	expectParseError(t, "for (;;) function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1465  	expectParseError(t, "for (x in y) function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1466  	expectParseError(t, "for (x of y) function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1467  	expectParseError(t, "for await (x of y) function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1468  	expectParseError(t, "with (1) function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1469  	expectParseError(t, "while (1) function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1470  	expectParseError(t, "do function f() {} while (0)", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1471  
  1472  	fnLabelAwait := "<stdin>: ERROR: Function declarations inside labels cannot be used in an ECMAScript module\n" +
  1473  		"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n"
  1474  
  1475  	expectParseError(t, "for (;;) label: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1476  	expectParseError(t, "for (x in y) label: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1477  	expectParseError(t, "for (x of y) label: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1478  	expectParseError(t, "for await (x of y) label: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n"+fnLabelAwait)
  1479  	expectParseError(t, "with (1) label: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1480  	expectParseError(t, "while (1) label: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1481  	expectParseError(t, "do label: function f() {} while (0)", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1482  
  1483  	expectParseError(t, "for (;;) label: label2: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1484  	expectParseError(t, "for (x in y) label: label2: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1485  	expectParseError(t, "for (x of y) label: label2: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1486  	expectParseError(t, "for await (x of y) label: label2: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n"+fnLabelAwait)
  1487  	expectParseError(t, "with (1) label: label2: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1488  	expectParseError(t, "while (1) label: label2: function f() {}", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1489  	expectParseError(t, "do label: label2: function f() {} while (0)", "<stdin>: ERROR: Cannot use a declaration in a single-statement context\n")
  1490  
  1491  	// Test direct "eval"
  1492  	expectPrinted(t, "if (foo) { function x() {} }", "if (foo) {\n  let x = function() {\n  };\n  var x = x;\n}\n")
  1493  	expectPrinted(t, "if (foo) { function x() {} eval('') }", "if (foo) {\n  function x() {\n  }\n  eval(\"\");\n}\n")
  1494  	expectPrinted(t, "if (foo) { function x() {} if (bar) { eval('') } }", "if (foo) {\n  function x() {\n  }\n  if (bar) {\n    eval(\"\");\n  }\n}\n")
  1495  	expectPrinted(t, "if (foo) { eval(''); function x() {} }", "if (foo) {\n  function x() {\n  }\n  eval(\"\");\n}\n")
  1496  	expectPrinted(t, "'use strict'; if (foo) { function x() {} }", "\"use strict\";\nif (foo) {\n  let x = function() {\n  };\n}\n")
  1497  	expectPrinted(t, "'use strict'; if (foo) { function x() {} eval('') }", "\"use strict\";\nif (foo) {\n  function x() {\n  }\n  eval(\"\");\n}\n")
  1498  	expectPrinted(t, "'use strict'; if (foo) { function x() {} if (bar) { eval('') } }", "\"use strict\";\nif (foo) {\n  function x() {\n  }\n  if (bar) {\n    eval(\"\");\n  }\n}\n")
  1499  	expectPrinted(t, "'use strict'; if (foo) { eval(''); function x() {} }", "\"use strict\";\nif (foo) {\n  function x() {\n  }\n  eval(\"\");\n}\n")
  1500  }
  1501  
  1502  func TestFunction(t *testing.T) {
  1503  	expectPrinted(t, "function f() {} function f() {}", "function f() {\n}\nfunction f() {\n}\n")
  1504  	expectPrinted(t, "function f() {} function* f() {}", "function f() {\n}\nfunction* f() {\n}\n")
  1505  	expectPrinted(t, "function* f() {} function* f() {}", "function* f() {\n}\nfunction* f() {\n}\n")
  1506  	expectPrinted(t, "function f() {} async function f() {}", "function f() {\n}\nasync function f() {\n}\n")
  1507  	expectPrinted(t, "async function f() {} async function f() {}", "async function f() {\n}\nasync function f() {\n}\n")
  1508  
  1509  	expectPrinted(t, "function arguments() {}", "function arguments() {\n}\n")
  1510  	expectPrinted(t, "(function arguments() {})", "(function arguments() {\n});\n")
  1511  	expectPrinted(t, "function foo(arguments) {}", "function foo(arguments) {\n}\n")
  1512  	expectPrinted(t, "(function foo(arguments) {})", "(function foo(arguments) {\n});\n")
  1513  
  1514  	expectPrinted(t, "(function foo() { var arguments })", "(function foo() {\n  var arguments;\n});\n")
  1515  	expectPrinted(t, "(function foo() { { var arguments } })", "(function foo() {\n  {\n    var arguments;\n  }\n});\n")
  1516  
  1517  	expectPrintedMangle(t, "function foo() { return undefined }", "function foo() {\n}\n")
  1518  	expectPrintedMangle(t, "function* foo() { return undefined }", "function* foo() {\n}\n")
  1519  	expectPrintedMangle(t, "async function foo() { return undefined }", "async function foo() {\n}\n")
  1520  	expectPrintedMangle(t, "async function* foo() { return undefined }", "async function* foo() {\n  return void 0;\n}\n")
  1521  
  1522  	// Strip overwritten function declarations
  1523  	expectPrintedMangle(t, "function f() { x() } function f() { y() }", "function f() {\n  y();\n}\n")
  1524  	expectPrintedMangle(t, "function f() { x() } function *f() { y() }", "function* f() {\n  y();\n}\n")
  1525  	expectPrintedMangle(t, "function *f() { x() } function f() { y() }", "function f() {\n  y();\n}\n")
  1526  	expectPrintedMangle(t, "function *f() { x() } function *f() { y() }", "function* f() {\n  y();\n}\n")
  1527  	expectPrintedMangle(t, "function f() { x() } async function f() { y() }", "async function f() {\n  y();\n}\n")
  1528  	expectPrintedMangle(t, "async function f() { x() } function f() { y() }", "function f() {\n  y();\n}\n")
  1529  	expectPrintedMangle(t, "async function f() { x() } async function f() { y() }", "async function f() {\n  y();\n}\n")
  1530  	expectPrintedMangle(t, "var f; function f() {}", "var f;\nfunction f() {\n}\n")
  1531  	expectPrintedMangle(t, "function f() {} var f", "function f() {\n}\nvar f;\n")
  1532  	expectPrintedMangle(t, "var f; function f() { x() } function f() { y() }", "var f;\nfunction f() {\n  y();\n}\n")
  1533  	expectPrintedMangle(t, "function f() { x() } function f() { y() } var f", "function f() {\n  y();\n}\nvar f;\n")
  1534  	expectPrintedMangle(t, "function f() { x() } var f; function f() { y() }", "function f() {\n  x();\n}\nvar f;\nfunction f() {\n  y();\n}\n")
  1535  
  1536  	redeclaredError := "<stdin>: ERROR: The symbol \"f\" has already been declared\n" +
  1537  		"<stdin>: NOTE: The symbol \"f\" was originally declared here:\n"
  1538  
  1539  	expectParseError(t, "function *f() {} function *f() {}", "")
  1540  	expectParseError(t, "function f() {} let f", redeclaredError)
  1541  	expectParseError(t, "function f() {} var f", "")
  1542  	expectParseError(t, "function *f() {} var f", "")
  1543  	expectParseError(t, "let f; function f() {}", redeclaredError)
  1544  	expectParseError(t, "var f; function f() {}", "")
  1545  	expectParseError(t, "var f; function *f() {}", "")
  1546  
  1547  	expectParseError(t, "{ function *f() {} function *f() {} }", redeclaredError)
  1548  	expectParseError(t, "{ function f() {} let f }", redeclaredError)
  1549  	expectParseError(t, "{ function f() {} var f }", redeclaredError)
  1550  	expectParseError(t, "{ function *f() {} var f }", redeclaredError)
  1551  	expectParseError(t, "{ let f; function f() {} }", redeclaredError)
  1552  	expectParseError(t, "{ var f; function f() {} }", redeclaredError)
  1553  	expectParseError(t, "{ var f; function *f() {} }", redeclaredError)
  1554  
  1555  	expectParseError(t, "switch (0) { case 1: function *f() {} default: function *f() {} }", redeclaredError)
  1556  	expectParseError(t, "switch (0) { case 1: function f() {} default: let f }", redeclaredError)
  1557  	expectParseError(t, "switch (0) { case 1: function f() {} default: var f }", redeclaredError)
  1558  	expectParseError(t, "switch (0) { case 1: function *f() {} default: var f }", redeclaredError)
  1559  	expectParseError(t, "switch (0) { case 1: let f; default: function f() {} }", redeclaredError)
  1560  	expectParseError(t, "switch (0) { case 1: var f; default: function f() {} }", redeclaredError)
  1561  	expectParseError(t, "switch (0) { case 1: var f; default: function *f() {} }", redeclaredError)
  1562  }
  1563  
  1564  func TestClass(t *testing.T) {
  1565  	expectPrinted(t, "class Foo { foo() {} }", "class Foo {\n  foo() {\n  }\n}\n")
  1566  	expectPrinted(t, "class Foo { *foo() {} }", "class Foo {\n  *foo() {\n  }\n}\n")
  1567  	expectPrinted(t, "class Foo { get foo() {} }", "class Foo {\n  get foo() {\n  }\n}\n")
  1568  	expectPrinted(t, "class Foo { set foo(x) {} }", "class Foo {\n  set foo(x) {\n  }\n}\n")
  1569  	expectPrinted(t, "class Foo { async foo() {} }", "class Foo {\n  async foo() {\n  }\n}\n")
  1570  	expectPrinted(t, "class Foo { async *foo() {} }", "class Foo {\n  async *foo() {\n  }\n}\n")
  1571  	expectPrinted(t, "class Foo { static foo() {} }", "class Foo {\n  static foo() {\n  }\n}\n")
  1572  	expectPrinted(t, "class Foo { static *foo() {} }", "class Foo {\n  static *foo() {\n  }\n}\n")
  1573  	expectPrinted(t, "class Foo { static get foo() {} }", "class Foo {\n  static get foo() {\n  }\n}\n")
  1574  	expectPrinted(t, "class Foo { static set foo(x) {} }", "class Foo {\n  static set foo(x) {\n  }\n}\n")
  1575  	expectPrinted(t, "class Foo { static async foo() {} }", "class Foo {\n  static async foo() {\n  }\n}\n")
  1576  	expectPrinted(t, "class Foo { static async *foo() {} }", "class Foo {\n  static async *foo() {\n  }\n}\n")
  1577  	expectParseError(t, "class Foo { async static foo() {} }", "<stdin>: ERROR: Expected \"(\" but found \"foo\"\n")
  1578  	expectParseError(t, "class Foo { * static foo() {} }", "<stdin>: ERROR: Expected \"(\" but found \"foo\"\n")
  1579  	expectParseError(t, "class Foo { * *foo() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1580  	expectParseError(t, "class Foo { async * *foo() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1581  	expectParseError(t, "class Foo { * async foo() {} }", "<stdin>: ERROR: Expected \"(\" but found \"foo\"\n")
  1582  	expectParseError(t, "class Foo { * async * foo() {} }", "<stdin>: ERROR: Expected \"(\" but found \"*\"\n")
  1583  	expectParseError(t, "class Foo { static * *foo() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1584  	expectParseError(t, "class Foo { static async * *foo() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1585  	expectParseError(t, "class Foo { static * async foo() {} }", "<stdin>: ERROR: Expected \"(\" but found \"foo\"\n")
  1586  	expectParseError(t, "class Foo { static * async * foo() {} }", "<stdin>: ERROR: Expected \"(\" but found \"*\"\n")
  1587  
  1588  	expectPrinted(t, "class Foo { if() {} }", "class Foo {\n  if() {\n  }\n}\n")
  1589  	expectPrinted(t, "class Foo { *if() {} }", "class Foo {\n  *if() {\n  }\n}\n")
  1590  	expectPrinted(t, "class Foo { get if() {} }", "class Foo {\n  get if() {\n  }\n}\n")
  1591  	expectPrinted(t, "class Foo { set if(x) {} }", "class Foo {\n  set if(x) {\n  }\n}\n")
  1592  	expectPrinted(t, "class Foo { async if() {} }", "class Foo {\n  async if() {\n  }\n}\n")
  1593  	expectPrinted(t, "class Foo { async *if() {} }", "class Foo {\n  async *if() {\n  }\n}\n")
  1594  	expectPrinted(t, "class Foo { static if() {} }", "class Foo {\n  static if() {\n  }\n}\n")
  1595  	expectPrinted(t, "class Foo { static *if() {} }", "class Foo {\n  static *if() {\n  }\n}\n")
  1596  	expectPrinted(t, "class Foo { static get if() {} }", "class Foo {\n  static get if() {\n  }\n}\n")
  1597  	expectPrinted(t, "class Foo { static set if(x) {} }", "class Foo {\n  static set if(x) {\n  }\n}\n")
  1598  	expectPrinted(t, "class Foo { static async if() {} }", "class Foo {\n  static async if() {\n  }\n}\n")
  1599  	expectPrinted(t, "class Foo { static async *if() {} }", "class Foo {\n  static async *if() {\n  }\n}\n")
  1600  	expectParseError(t, "class Foo { async static if() {} }", "<stdin>: ERROR: Expected \"(\" but found \"if\"\n")
  1601  	expectParseError(t, "class Foo { * static if() {} }", "<stdin>: ERROR: Expected \"(\" but found \"if\"\n")
  1602  	expectParseError(t, "class Foo { * *if() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1603  	expectParseError(t, "class Foo { async * *if() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1604  	expectParseError(t, "class Foo { * async if() {} }", "<stdin>: ERROR: Expected \"(\" but found \"if\"\n")
  1605  	expectParseError(t, "class Foo { * async * if() {} }", "<stdin>: ERROR: Expected \"(\" but found \"*\"\n")
  1606  	expectParseError(t, "class Foo { static * *if() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1607  	expectParseError(t, "class Foo { static async * *if() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1608  	expectParseError(t, "class Foo { static * async if() {} }", "<stdin>: ERROR: Expected \"(\" but found \"if\"\n")
  1609  	expectParseError(t, "class Foo { static * async * if() {} }", "<stdin>: ERROR: Expected \"(\" but found \"*\"\n")
  1610  
  1611  	expectPrinted(t, "class Foo { a() {} b() {} }", "class Foo {\n  a() {\n  }\n  b() {\n  }\n}\n")
  1612  	expectPrinted(t, "class Foo { a() {} get b() {} }", "class Foo {\n  a() {\n  }\n  get b() {\n  }\n}\n")
  1613  	expectPrinted(t, "class Foo { a() {} set b(x) {} }", "class Foo {\n  a() {\n  }\n  set b(x) {\n  }\n}\n")
  1614  	expectPrinted(t, "class Foo { a() {} async b() {} }", "class Foo {\n  a() {\n  }\n  async b() {\n  }\n}\n")
  1615  	expectPrinted(t, "class Foo { a() {} async *b() {} }", "class Foo {\n  a() {\n  }\n  async *b() {\n  }\n}\n")
  1616  	expectPrinted(t, "class Foo { a() {} static b() {} }", "class Foo {\n  a() {\n  }\n  static b() {\n  }\n}\n")
  1617  	expectPrinted(t, "class Foo { a() {} static *b() {} }", "class Foo {\n  a() {\n  }\n  static *b() {\n  }\n}\n")
  1618  	expectPrinted(t, "class Foo { a() {} static get b() {} }", "class Foo {\n  a() {\n  }\n  static get b() {\n  }\n}\n")
  1619  	expectPrinted(t, "class Foo { a() {} static set b(x) {} }", "class Foo {\n  a() {\n  }\n  static set b(x) {\n  }\n}\n")
  1620  	expectPrinted(t, "class Foo { a() {} static async b() {} }", "class Foo {\n  a() {\n  }\n  static async b() {\n  }\n}\n")
  1621  	expectPrinted(t, "class Foo { a() {} static async *b() {} }", "class Foo {\n  a() {\n  }\n  static async *b() {\n  }\n}\n")
  1622  	expectParseError(t, "class Foo { a() {} async static b() {} }", "<stdin>: ERROR: Expected \"(\" but found \"b\"\n")
  1623  	expectParseError(t, "class Foo { a() {} * static b() {} }", "<stdin>: ERROR: Expected \"(\" but found \"b\"\n")
  1624  	expectParseError(t, "class Foo { a() {} * *b() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1625  	expectParseError(t, "class Foo { a() {} async * *b() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1626  	expectParseError(t, "class Foo { a() {} * async b() {} }", "<stdin>: ERROR: Expected \"(\" but found \"b\"\n")
  1627  	expectParseError(t, "class Foo { a() {} * async * b() {} }", "<stdin>: ERROR: Expected \"(\" but found \"*\"\n")
  1628  	expectParseError(t, "class Foo { a() {} static * *b() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1629  	expectParseError(t, "class Foo { a() {} static async * *b() {} }", "<stdin>: ERROR: Unexpected \"*\"\n")
  1630  	expectParseError(t, "class Foo { a() {} static * async b() {} }", "<stdin>: ERROR: Expected \"(\" but found \"b\"\n")
  1631  	expectParseError(t, "class Foo { a() {} static * async * b() {} }", "<stdin>: ERROR: Expected \"(\" but found \"*\"\n")
  1632  
  1633  	expectParseError(t, "class Foo { `a`() {} }", "<stdin>: ERROR: Expected identifier but found \"`a`\"\n")
  1634  
  1635  	// Strict mode reserved words cannot be used as class names
  1636  	expectParseError(t, "class static {}",
  1637  		"<stdin>: ERROR: \"static\" is a reserved word and cannot be used in strict mode\n"+
  1638  			"<stdin>: NOTE: All code inside a class is implicitly in strict mode\n")
  1639  	expectParseError(t, "(class static {})",
  1640  		"<stdin>: ERROR: \"static\" is a reserved word and cannot be used in strict mode\n"+
  1641  			"<stdin>: NOTE: All code inside a class is implicitly in strict mode\n")
  1642  	expectParseError(t, "class implements {}",
  1643  		"<stdin>: ERROR: \"implements\" is a reserved word and cannot be used in strict mode\n"+
  1644  			"<stdin>: NOTE: All code inside a class is implicitly in strict mode\n")
  1645  	expectParseError(t, "(class implements {})",
  1646  		"<stdin>: ERROR: \"implements\" is a reserved word and cannot be used in strict mode\n"+
  1647  			"<stdin>: NOTE: All code inside a class is implicitly in strict mode\n")
  1648  
  1649  	// The name "arguments" is forbidden in class bodies outside of computed properties
  1650  	expectPrinted(t, "class Foo { [arguments] }", "class Foo {\n  [arguments];\n}\n")
  1651  	expectPrinted(t, "class Foo { [arguments] = 1 }", "class Foo {\n  [arguments] = 1;\n}\n")
  1652  	expectPrinted(t, "class Foo { arguments = 1 }", "class Foo {\n  arguments = 1;\n}\n")
  1653  	expectPrinted(t, "class Foo { x = class { arguments = 1 } }", "class Foo {\n  x = class {\n    arguments = 1;\n  };\n}\n")
  1654  	expectPrinted(t, "class Foo { x = function() { arguments } }", "class Foo {\n  x = function() {\n    arguments;\n  };\n}\n")
  1655  	expectParseError(t, "class Foo { x = arguments }", "<stdin>: ERROR: Cannot access \"arguments\" here:\n")
  1656  	expectParseError(t, "class Foo { x = () => arguments }", "<stdin>: ERROR: Cannot access \"arguments\" here:\n")
  1657  	expectParseError(t, "class Foo { x = typeof arguments }", "<stdin>: ERROR: Cannot access \"arguments\" here:\n")
  1658  	expectParseError(t, "class Foo { x = 1 ? 2 : arguments }", "<stdin>: ERROR: Cannot access \"arguments\" here:\n")
  1659  	expectParseError(t, "class Foo { x = class { [arguments] } }", "<stdin>: ERROR: Cannot access \"arguments\" here:\n")
  1660  	expectParseError(t, "class Foo { x = class { [arguments] = 1 } }", "<stdin>: ERROR: Cannot access \"arguments\" here:\n")
  1661  	expectParseError(t, "class Foo { static { arguments } }", "<stdin>: ERROR: Cannot access \"arguments\" here:\n")
  1662  	expectParseError(t, "class Foo { static { class Bar { [arguments] } } }", "<stdin>: ERROR: Cannot access \"arguments\" here:\n")
  1663  
  1664  	// The name "constructor" is sometimes forbidden
  1665  	expectPrinted(t, "class Foo { get ['constructor']() {} }", "class Foo {\n  get [\"constructor\"]() {\n  }\n}\n")
  1666  	expectPrinted(t, "class Foo { set ['constructor'](x) {} }", "class Foo {\n  set [\"constructor\"](x) {\n  }\n}\n")
  1667  	expectPrinted(t, "class Foo { *['constructor']() {} }", "class Foo {\n  *[\"constructor\"]() {\n  }\n}\n")
  1668  	expectPrinted(t, "class Foo { async ['constructor']() {} }", "class Foo {\n  async [\"constructor\"]() {\n  }\n}\n")
  1669  	expectPrinted(t, "class Foo { async *['constructor']() {} }", "class Foo {\n  async *[\"constructor\"]() {\n  }\n}\n")
  1670  	expectParseError(t, "class Foo { get constructor() {} }", "<stdin>: ERROR: Class constructor cannot be a getter\n")
  1671  	expectParseError(t, "class Foo { get 'constructor'() {} }", "<stdin>: ERROR: Class constructor cannot be a getter\n")
  1672  	expectParseError(t, "class Foo { set constructor(x) {} }", "<stdin>: ERROR: Class constructor cannot be a setter\n")
  1673  	expectParseError(t, "class Foo { set 'constructor'(x) {} }", "<stdin>: ERROR: Class constructor cannot be a setter\n")
  1674  	expectParseError(t, "class Foo { *constructor() {} }", "<stdin>: ERROR: Class constructor cannot be a generator\n")
  1675  	expectParseError(t, "class Foo { *'constructor'() {} }", "<stdin>: ERROR: Class constructor cannot be a generator\n")
  1676  	expectParseError(t, "class Foo { async constructor() {} }", "<stdin>: ERROR: Class constructor cannot be an async function\n")
  1677  	expectParseError(t, "class Foo { async 'constructor'() {} }", "<stdin>: ERROR: Class constructor cannot be an async function\n")
  1678  	expectParseError(t, "class Foo { async *constructor() {} }", "<stdin>: ERROR: Class constructor cannot be an async function\n")
  1679  	expectParseError(t, "class Foo { async *'constructor'() {} }", "<stdin>: ERROR: Class constructor cannot be an async function\n")
  1680  	expectPrinted(t, "class Foo { static get constructor() {} }", "class Foo {\n  static get constructor() {\n  }\n}\n")
  1681  	expectPrinted(t, "class Foo { static get 'constructor'() {} }", "class Foo {\n  static get \"constructor\"() {\n  }\n}\n")
  1682  	expectPrinted(t, "class Foo { static set constructor(x) {} }", "class Foo {\n  static set constructor(x) {\n  }\n}\n")
  1683  	expectPrinted(t, "class Foo { static set 'constructor'(x) {} }", "class Foo {\n  static set \"constructor\"(x) {\n  }\n}\n")
  1684  	expectPrinted(t, "class Foo { static *constructor() {} }", "class Foo {\n  static *constructor() {\n  }\n}\n")
  1685  	expectPrinted(t, "class Foo { static *'constructor'() {} }", "class Foo {\n  static *\"constructor\"() {\n  }\n}\n")
  1686  	expectPrinted(t, "class Foo { static async constructor() {} }", "class Foo {\n  static async constructor() {\n  }\n}\n")
  1687  	expectPrinted(t, "class Foo { static async 'constructor'() {} }", "class Foo {\n  static async \"constructor\"() {\n  }\n}\n")
  1688  	expectPrinted(t, "class Foo { static async *constructor() {} }", "class Foo {\n  static async *constructor() {\n  }\n}\n")
  1689  	expectPrinted(t, "class Foo { static async *'constructor'() {} }", "class Foo {\n  static async *\"constructor\"() {\n  }\n}\n")
  1690  	expectPrinted(t, "({ constructor: 1 })", "({ constructor: 1 });\n")
  1691  	expectPrinted(t, "({ get constructor() {} })", "({ get constructor() {\n} });\n")
  1692  	expectPrinted(t, "({ set constructor(x) {} })", "({ set constructor(x) {\n} });\n")
  1693  	expectPrinted(t, "({ *constructor() {} })", "({ *constructor() {\n} });\n")
  1694  	expectPrinted(t, "({ async constructor() {} })", "({ async constructor() {\n} });\n")
  1695  	expectPrinted(t, "({ async* constructor() {} })", "({ async *constructor() {\n} });\n")
  1696  
  1697  	// The name "prototype" is sometimes forbidden
  1698  	expectPrinted(t, "class Foo { get prototype() {} }", "class Foo {\n  get prototype() {\n  }\n}\n")
  1699  	expectPrinted(t, "class Foo { get 'prototype'() {} }", "class Foo {\n  get \"prototype\"() {\n  }\n}\n")
  1700  	expectPrinted(t, "class Foo { set prototype(x) {} }", "class Foo {\n  set prototype(x) {\n  }\n}\n")
  1701  	expectPrinted(t, "class Foo { set 'prototype'(x) {} }", "class Foo {\n  set \"prototype\"(x) {\n  }\n}\n")
  1702  	expectPrinted(t, "class Foo { *prototype() {} }", "class Foo {\n  *prototype() {\n  }\n}\n")
  1703  	expectPrinted(t, "class Foo { *'prototype'() {} }", "class Foo {\n  *\"prototype\"() {\n  }\n}\n")
  1704  	expectPrinted(t, "class Foo { async prototype() {} }", "class Foo {\n  async prototype() {\n  }\n}\n")
  1705  	expectPrinted(t, "class Foo { async 'prototype'() {} }", "class Foo {\n  async \"prototype\"() {\n  }\n}\n")
  1706  	expectPrinted(t, "class Foo { async *prototype() {} }", "class Foo {\n  async *prototype() {\n  }\n}\n")
  1707  	expectPrinted(t, "class Foo { async *'prototype'() {} }", "class Foo {\n  async *\"prototype\"() {\n  }\n}\n")
  1708  	expectParseError(t, "class Foo { static get prototype() {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1709  	expectParseError(t, "class Foo { static get 'prototype'() {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1710  	expectParseError(t, "class Foo { static set prototype(x) {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1711  	expectParseError(t, "class Foo { static set 'prototype'(x) {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1712  	expectParseError(t, "class Foo { static *prototype() {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1713  	expectParseError(t, "class Foo { static *'prototype'() {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1714  	expectParseError(t, "class Foo { static async prototype() {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1715  	expectParseError(t, "class Foo { static async 'prototype'() {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1716  	expectParseError(t, "class Foo { static async *prototype() {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1717  	expectParseError(t, "class Foo { static async *'prototype'() {} }", "<stdin>: ERROR: Invalid static method name \"prototype\"\n")
  1718  	expectPrinted(t, "class Foo { static get ['prototype']() {} }", "class Foo {\n  static get [\"prototype\"]() {\n  }\n}\n")
  1719  	expectPrinted(t, "class Foo { static set ['prototype'](x) {} }", "class Foo {\n  static set [\"prototype\"](x) {\n  }\n}\n")
  1720  	expectPrinted(t, "class Foo { static *['prototype']() {} }", "class Foo {\n  static *[\"prototype\"]() {\n  }\n}\n")
  1721  	expectPrinted(t, "class Foo { static async ['prototype']() {} }", "class Foo {\n  static async [\"prototype\"]() {\n  }\n}\n")
  1722  	expectPrinted(t, "class Foo { static async *['prototype']() {} }", "class Foo {\n  static async *[\"prototype\"]() {\n  }\n}\n")
  1723  	expectPrinted(t, "({ prototype: 1 })", "({ prototype: 1 });\n")
  1724  	expectPrinted(t, "({ get prototype() {} })", "({ get prototype() {\n} });\n")
  1725  	expectPrinted(t, "({ set prototype(x) {} })", "({ set prototype(x) {\n} });\n")
  1726  	expectPrinted(t, "({ *prototype() {} })", "({ *prototype() {\n} });\n")
  1727  	expectPrinted(t, "({ async prototype() {} })", "({ async prototype() {\n} });\n")
  1728  	expectPrinted(t, "({ async* prototype() {} })", "({ async *prototype() {\n} });\n")
  1729  
  1730  	expectPrintedMangle(t, "class Foo { ['constructor'] = 0 }", "class Foo {\n  [\"constructor\"] = 0;\n}\n")
  1731  	expectPrintedMangle(t, "class Foo { ['constructor']() {} }", "class Foo {\n  [\"constructor\"]() {\n  }\n}\n")
  1732  	expectPrintedMangle(t, "class Foo { *['constructor']() {} }", "class Foo {\n  *[\"constructor\"]() {\n  }\n}\n")
  1733  	expectPrintedMangle(t, "class Foo { get ['constructor']() {} }", "class Foo {\n  get [\"constructor\"]() {\n  }\n}\n")
  1734  	expectPrintedMangle(t, "class Foo { set ['constructor'](x) {} }", "class Foo {\n  set [\"constructor\"](x) {\n  }\n}\n")
  1735  	expectPrintedMangle(t, "class Foo { async ['constructor']() {} }", "class Foo {\n  async [\"constructor\"]() {\n  }\n}\n")
  1736  
  1737  	expectPrintedMangle(t, "class Foo { static ['constructor'] = 0 }", "class Foo {\n  static [\"constructor\"] = 0;\n}\n")
  1738  	expectPrintedMangle(t, "class Foo { static ['constructor']() {} }", "class Foo {\n  static constructor() {\n  }\n}\n")
  1739  	expectPrintedMangle(t, "class Foo { static *['constructor']() {} }", "class Foo {\n  static *constructor() {\n  }\n}\n")
  1740  	expectPrintedMangle(t, "class Foo { static get ['constructor']() {} }", "class Foo {\n  static get constructor() {\n  }\n}\n")
  1741  	expectPrintedMangle(t, "class Foo { static set ['constructor'](x) {} }", "class Foo {\n  static set constructor(x) {\n  }\n}\n")
  1742  	expectPrintedMangle(t, "class Foo { static async ['constructor']() {} }", "class Foo {\n  static async constructor() {\n  }\n}\n")
  1743  
  1744  	expectPrintedMangle(t, "class Foo { ['prototype'] = 0 }", "class Foo {\n  prototype = 0;\n}\n")
  1745  	expectPrintedMangle(t, "class Foo { ['prototype']() {} }", "class Foo {\n  prototype() {\n  }\n}\n")
  1746  	expectPrintedMangle(t, "class Foo { *['prototype']() {} }", "class Foo {\n  *prototype() {\n  }\n}\n")
  1747  	expectPrintedMangle(t, "class Foo { get ['prototype']() {} }", "class Foo {\n  get prototype() {\n  }\n}\n")
  1748  	expectPrintedMangle(t, "class Foo { set ['prototype'](x) {} }", "class Foo {\n  set prototype(x) {\n  }\n}\n")
  1749  	expectPrintedMangle(t, "class Foo { async ['prototype']() {} }", "class Foo {\n  async prototype() {\n  }\n}\n")
  1750  
  1751  	expectPrintedMangle(t, "class Foo { static ['prototype'] = 0 }", "class Foo {\n  static [\"prototype\"] = 0;\n}\n")
  1752  	expectPrintedMangle(t, "class Foo { static ['prototype']() {} }", "class Foo {\n  static [\"prototype\"]() {\n  }\n}\n")
  1753  	expectPrintedMangle(t, "class Foo { static *['prototype']() {} }", "class Foo {\n  static *[\"prototype\"]() {\n  }\n}\n")
  1754  	expectPrintedMangle(t, "class Foo { static get ['prototype']() {} }", "class Foo {\n  static get [\"prototype\"]() {\n  }\n}\n")
  1755  	expectPrintedMangle(t, "class Foo { static set ['prototype'](x) {} }", "class Foo {\n  static set [\"prototype\"](x) {\n  }\n}\n")
  1756  	expectPrintedMangle(t, "class Foo { static async ['prototype']() {} }", "class Foo {\n  static async [\"prototype\"]() {\n  }\n}\n")
  1757  
  1758  	dupCtor := "<stdin>: ERROR: Classes cannot contain more than one constructor\n"
  1759  
  1760  	expectParseError(t, "class Foo { constructor() {} constructor() {} }", dupCtor)
  1761  	expectParseError(t, "class Foo { constructor() {} 'constructor'() {} }", dupCtor)
  1762  	expectParseError(t, "class Foo { constructor() {} ['constructor']() {} }", "")
  1763  	expectParseError(t, "class Foo { 'constructor'() {} constructor() {} }", dupCtor)
  1764  	expectParseError(t, "class Foo { ['constructor']() {} constructor() {} }", "")
  1765  	expectParseError(t, "class Foo { constructor() {} static constructor() {} }", "")
  1766  	expectParseError(t, "class Foo { static constructor() {} constructor() {} }", "")
  1767  	expectParseError(t, "class Foo { static constructor() {} static constructor() {} }", "")
  1768  	expectParseError(t, "class Foo { constructor = () => {}; constructor = () => {} }",
  1769  		"<stdin>: ERROR: Invalid field name \"constructor\"\n<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1770  	expectParseError(t, "({ constructor() {}, constructor() {} })",
  1771  		"<stdin>: WARNING: Duplicate key \"constructor\" in object literal\n<stdin>: NOTE: The original key \"constructor\" is here:\n")
  1772  	expectParseError(t, "(class { constructor() {} constructor() {} })", dupCtor)
  1773  	expectPrintedMangle(t, "class Foo { constructor() {} ['constructor']() {} }",
  1774  		"class Foo {\n  constructor() {\n  }\n  [\"constructor\"]() {\n  }\n}\n")
  1775  	expectPrintedMangle(t, "class Foo { static constructor() {} static ['constructor']() {} }",
  1776  		"class Foo {\n  static constructor() {\n  }\n  static constructor() {\n  }\n}\n")
  1777  
  1778  	// Check the string-to-int optimization
  1779  	expectPrintedMangle(t, "class x { '0' = y }", "class x {\n  0 = y;\n}\n")
  1780  	expectPrintedMangle(t, "class x { '123' = y }", "class x {\n  123 = y;\n}\n")
  1781  	expectPrintedMangle(t, "class x { ['-123'] = y }", "class x {\n  \"-123\" = y;\n}\n")
  1782  	expectPrintedMangle(t, "class x { '-0' = y }", "class x {\n  \"-0\" = y;\n}\n")
  1783  	expectPrintedMangle(t, "class x { '01' = y }", "class x {\n  \"01\" = y;\n}\n")
  1784  	expectPrintedMangle(t, "class x { '-01' = y }", "class x {\n  \"-01\" = y;\n}\n")
  1785  	expectPrintedMangle(t, "class x { '0x1' = y }", "class x {\n  \"0x1\" = y;\n}\n")
  1786  	expectPrintedMangle(t, "class x { '-0x1' = y }", "class x {\n  \"-0x1\" = y;\n}\n")
  1787  	expectPrintedMangle(t, "class x { '2147483647' = y }", "class x {\n  2147483647 = y;\n}\n")
  1788  	expectPrintedMangle(t, "class x { '2147483648' = y }", "class x {\n  \"2147483648\" = y;\n}\n")
  1789  	expectPrintedMangle(t, "class x { ['-2147483648'] = y }", "class x {\n  \"-2147483648\" = y;\n}\n")
  1790  	expectPrintedMangle(t, "class x { ['-2147483649'] = y }", "class x {\n  \"-2147483649\" = y;\n}\n")
  1791  
  1792  	// Make sure direct "eval" doesn't cause the class name to change
  1793  	expectPrinted(t, "class Foo { foo = [Foo, eval(bar)] }", "class Foo {\n  foo = [Foo, eval(bar)];\n}\n")
  1794  }
  1795  
  1796  func TestSuperCall(t *testing.T) {
  1797  	expectParseError(t, "super", "<stdin>: ERROR: Unexpected \"super\"\n")
  1798  	expectParseError(t, "super()", "<stdin>: ERROR: Unexpected \"super\"\n")
  1799  	expectParseError(t, "class Foo { foo = super() }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1800  	expectParseError(t, "class Foo { foo() { super() } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1801  	expectParseError(t, "class Foo extends Bar { foo = super() }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1802  	expectParseError(t, "class Foo extends Bar { foo() { super() } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1803  	expectParseError(t, "class Foo extends Bar { static constructor() { super() } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1804  	expectParseError(t, "class Foo extends Bar { constructor(x = function() { super() }) {} }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1805  	expectParseError(t, "class Foo extends Bar { constructor() { function foo() { super() } } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1806  	expectParseError(t, "class Foo extends Bar { constructor() { super } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1807  	expectPrinted(t, "class Foo extends Bar { constructor() { super() } }",
  1808  		"class Foo extends Bar {\n  constructor() {\n    super();\n  }\n}\n")
  1809  	expectPrinted(t, "class Foo extends Bar { constructor() { () => super() } }",
  1810  		"class Foo extends Bar {\n  constructor() {\n    () => super();\n  }\n}\n")
  1811  	expectPrinted(t, "class Foo extends Bar { constructor() { () => { super() } } }",
  1812  		"class Foo extends Bar {\n  constructor() {\n    () => {\n      super();\n    };\n  }\n}\n")
  1813  	expectPrinted(t, "class Foo extends Bar { constructor(x = super()) {} }",
  1814  		"class Foo extends Bar {\n  constructor(x = super()) {\n  }\n}\n")
  1815  	expectPrinted(t, "class Foo extends Bar { constructor(x = () => super()) {} }",
  1816  		"class Foo extends Bar {\n  constructor(x = () => super()) {\n  }\n}\n")
  1817  
  1818  	expectPrintedMangleTarget(t, 2015, "class A extends B { x; constructor() { super() } }",
  1819  		"class A extends B {\n  constructor() {\n    super();\n    __publicField(this, \"x\");\n  }\n}\n")
  1820  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super() } }",
  1821  		"class A extends B {\n  constructor() {\n    super();\n    __publicField(this, \"x\", 1);\n  }\n}\n")
  1822  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); c() } }",
  1823  		"class A extends B {\n  constructor() {\n    super();\n    __publicField(this, \"x\", 1);\n    c();\n  }\n}\n")
  1824  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { c(); super() } }",
  1825  		"class A extends B {\n  constructor() {\n    c();\n    super();\n    __publicField(this, \"x\", 1);\n  }\n}\n")
  1826  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); if (c) throw c } }",
  1827  		"class A extends B {\n  constructor() {\n    super();\n    __publicField(this, \"x\", 1);\n    if (c) throw c;\n  }\n}\n")
  1828  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); switch (c) { case 0: throw c } } }",
  1829  		"class A extends B {\n  constructor() {\n    super();\n    __publicField(this, \"x\", 1);\n    switch (c) {\n      case 0:\n        throw c;\n    }\n  }\n}\n")
  1830  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); while (!c) throw c } }",
  1831  		"class A extends B {\n  constructor() {\n    super();\n    __publicField(this, \"x\", 1);\n    for (; !c; ) throw c;\n  }\n}\n")
  1832  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); return c } }",
  1833  		"class A extends B {\n  constructor() {\n    super();\n    __publicField(this, \"x\", 1);\n    return c;\n  }\n}\n")
  1834  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { super(); throw c } }",
  1835  		"class A extends B {\n  constructor() {\n    super();\n    __publicField(this, \"x\", 1);\n    throw c;\n  }\n}\n")
  1836  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { if (true) super(1); else super(2); } }",
  1837  		"class A extends B {\n  constructor() {\n    super(1);\n    __publicField(this, \"x\", 1);\n  }\n}\n")
  1838  	expectPrintedMangleTarget(t, 2015, "class A extends B { x = 1; constructor() { if (foo) super(1); else super(2); } }",
  1839  		"class A extends B {\n  constructor() {\n    var __super = (...args) => (super(...args), __publicField(this, \"x\", 1), this);\n    foo ? __super(1) : __super(2);\n  }\n}\n")
  1840  }
  1841  
  1842  func TestSuperProp(t *testing.T) {
  1843  	expectParseError(t, "super.x", "<stdin>: ERROR: Unexpected \"super\"\n")
  1844  	expectParseError(t, "super[x]", "<stdin>: ERROR: Unexpected \"super\"\n")
  1845  
  1846  	expectPrinted(t, "class Foo { foo() { super.x } }", "class Foo {\n  foo() {\n    super.x;\n  }\n}\n")
  1847  	expectPrinted(t, "class Foo { foo() { super[x] } }", "class Foo {\n  foo() {\n    super[x];\n  }\n}\n")
  1848  	expectPrinted(t, "class Foo { foo(x = super.x) {} }", "class Foo {\n  foo(x = super.x) {\n  }\n}\n")
  1849  	expectPrinted(t, "class Foo { foo(x = super[x]) {} }", "class Foo {\n  foo(x = super[x]) {\n  }\n}\n")
  1850  	expectPrinted(t, "class Foo { static foo() { super.x } }", "class Foo {\n  static foo() {\n    super.x;\n  }\n}\n")
  1851  	expectPrinted(t, "class Foo { static foo() { super[x] } }", "class Foo {\n  static foo() {\n    super[x];\n  }\n}\n")
  1852  	expectPrinted(t, "class Foo { static foo(x = super.x) {} }", "class Foo {\n  static foo(x = super.x) {\n  }\n}\n")
  1853  	expectPrinted(t, "class Foo { static foo(x = super[x]) {} }", "class Foo {\n  static foo(x = super[x]) {\n  }\n}\n")
  1854  
  1855  	expectPrinted(t, "(class { foo() { super.x } })", "(class {\n  foo() {\n    super.x;\n  }\n});\n")
  1856  	expectPrinted(t, "(class { foo() { super[x] } })", "(class {\n  foo() {\n    super[x];\n  }\n});\n")
  1857  	expectPrinted(t, "(class { foo(x = super.x) {} })", "(class {\n  foo(x = super.x) {\n  }\n});\n")
  1858  	expectPrinted(t, "(class { foo(x = super[x]) {} })", "(class {\n  foo(x = super[x]) {\n  }\n});\n")
  1859  	expectPrinted(t, "(class { static foo() { super.x } })", "(class {\n  static foo() {\n    super.x;\n  }\n});\n")
  1860  	expectPrinted(t, "(class { static foo() { super[x] } })", "(class {\n  static foo() {\n    super[x];\n  }\n});\n")
  1861  	expectPrinted(t, "(class { static foo(x = super.x) {} })", "(class {\n  static foo(x = super.x) {\n  }\n});\n")
  1862  	expectPrinted(t, "(class { static foo(x = super[x]) {} })", "(class {\n  static foo(x = super[x]) {\n  }\n});\n")
  1863  
  1864  	expectPrinted(t, "class Foo { foo = super.x }", "class Foo {\n  foo = super.x;\n}\n")
  1865  	expectPrinted(t, "class Foo { foo = super[x] }", "class Foo {\n  foo = super[x];\n}\n")
  1866  	expectPrinted(t, "class Foo { foo = () => super.x }", "class Foo {\n  foo = () => super.x;\n}\n")
  1867  	expectPrinted(t, "class Foo { foo = () => super[x] }", "class Foo {\n  foo = () => super[x];\n}\n")
  1868  	expectParseError(t, "class Foo { foo = function () { super.x } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1869  	expectParseError(t, "class Foo { foo = function () { super[x] } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1870  
  1871  	expectPrinted(t, "class Foo { static foo = super.x }", "class Foo {\n  static foo = super.x;\n}\n")
  1872  	expectPrinted(t, "class Foo { static foo = super[x] }", "class Foo {\n  static foo = super[x];\n}\n")
  1873  	expectPrinted(t, "class Foo { static foo = () => super.x }", "class Foo {\n  static foo = () => super.x;\n}\n")
  1874  	expectPrinted(t, "class Foo { static foo = () => super[x] }", "class Foo {\n  static foo = () => super[x];\n}\n")
  1875  	expectParseError(t, "class Foo { static foo = function () { super.x } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1876  	expectParseError(t, "class Foo { static foo = function () { super[x] } }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1877  
  1878  	expectPrinted(t, "(class { foo = super.x })", "(class {\n  foo = super.x;\n});\n")
  1879  	expectPrinted(t, "(class { foo = super[x] })", "(class {\n  foo = super[x];\n});\n")
  1880  	expectPrinted(t, "(class { foo = () => super.x })", "(class {\n  foo = () => super.x;\n});\n")
  1881  	expectPrinted(t, "(class { foo = () => super[x] })", "(class {\n  foo = () => super[x];\n});\n")
  1882  	expectParseError(t, "(class { foo = function () { super.x } })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1883  	expectParseError(t, "(class { foo = function () { super[x] } })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1884  
  1885  	expectPrinted(t, "(class { static foo = super.x })", "(class {\n  static foo = super.x;\n});\n")
  1886  	expectPrinted(t, "(class { static foo = super[x] })", "(class {\n  static foo = super[x];\n});\n")
  1887  	expectPrinted(t, "(class { static foo = () => super.x })", "(class {\n  static foo = () => super.x;\n});\n")
  1888  	expectPrinted(t, "(class { static foo = () => super[x] })", "(class {\n  static foo = () => super[x];\n});\n")
  1889  	expectParseError(t, "(class { static foo = function () { super.x } })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1890  	expectParseError(t, "(class { static foo = function () { super[x] } })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1891  
  1892  	expectParseError(t, "({ foo: super.x })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1893  	expectParseError(t, "({ foo: super[x] })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1894  	expectParseError(t, "({ foo: () => super.x })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1895  	expectParseError(t, "({ foo: () => super[x] })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1896  	expectParseError(t, "({ foo: function () { super.x } })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1897  	expectParseError(t, "({ foo: function () { super[x] } })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1898  	expectPrinted(t, "({ foo() { super.x } })", "({ foo() {\n  super.x;\n} });\n")
  1899  	expectPrinted(t, "({ foo() { super[x] } })", "({ foo() {\n  super[x];\n} });\n")
  1900  	expectPrinted(t, "({ foo(x = super.x) {} })", "({ foo(x = super.x) {\n} });\n")
  1901  
  1902  	expectParseError(t, "class Foo { [super.x] }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1903  	expectParseError(t, "class Foo { [super[x]] }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1904  	expectParseError(t, "class Foo { static [super.x] }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1905  	expectParseError(t, "class Foo { static [super[x]] }", "<stdin>: ERROR: Unexpected \"super\"\n")
  1906  	expectParseError(t, "(class { [super.x] })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1907  	expectParseError(t, "(class { [super[x]] })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1908  	expectParseError(t, "(class { static [super.x] })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1909  	expectParseError(t, "(class { static [super[x]] })", "<stdin>: ERROR: Unexpected \"super\"\n")
  1910  }
  1911  
  1912  func TestClassFields(t *testing.T) {
  1913  	expectPrinted(t, "class Foo { a }", "class Foo {\n  a;\n}\n")
  1914  	expectPrinted(t, "class Foo { a = 1 }", "class Foo {\n  a = 1;\n}\n")
  1915  	expectPrinted(t, "class Foo { a = 1; b }", "class Foo {\n  a = 1;\n  b;\n}\n")
  1916  	expectParseError(t, "class Foo { a = 1 b }", "<stdin>: ERROR: Expected \";\" but found \"b\"\n")
  1917  
  1918  	expectPrinted(t, "class Foo { [a] }", "class Foo {\n  [a];\n}\n")
  1919  	expectPrinted(t, "class Foo { [a] = 1 }", "class Foo {\n  [a] = 1;\n}\n")
  1920  	expectPrinted(t, "class Foo { [a] = 1; [b] }", "class Foo {\n  [a] = 1;\n  [b];\n}\n")
  1921  	expectParseError(t, "class Foo { [a] = 1 b }", "<stdin>: ERROR: Expected \";\" but found \"b\"\n")
  1922  
  1923  	expectPrinted(t, "class Foo { static a }", "class Foo {\n  static a;\n}\n")
  1924  	expectPrinted(t, "class Foo { static a = 1 }", "class Foo {\n  static a = 1;\n}\n")
  1925  	expectPrinted(t, "class Foo { static a = 1; b }", "class Foo {\n  static a = 1;\n  b;\n}\n")
  1926  	expectParseError(t, "class Foo { static a = 1 b }", "<stdin>: ERROR: Expected \";\" but found \"b\"\n")
  1927  
  1928  	expectPrinted(t, "class Foo { static [a] }", "class Foo {\n  static [a];\n}\n")
  1929  	expectPrinted(t, "class Foo { static [a] = 1 }", "class Foo {\n  static [a] = 1;\n}\n")
  1930  	expectPrinted(t, "class Foo { static [a] = 1; [b] }", "class Foo {\n  static [a] = 1;\n  [b];\n}\n")
  1931  	expectParseError(t, "class Foo { static [a] = 1 b }", "<stdin>: ERROR: Expected \";\" but found \"b\"\n")
  1932  
  1933  	expectParseError(t, "class Foo { get a }", "<stdin>: ERROR: Expected \"(\" but found \"}\"\n")
  1934  	expectParseError(t, "class Foo { set a }", "<stdin>: ERROR: Expected \"(\" but found \"}\"\n")
  1935  	expectParseError(t, "class Foo { async a }", "<stdin>: ERROR: Expected \"(\" but found \"}\"\n")
  1936  
  1937  	expectParseError(t, "class Foo { get a = 1 }", "<stdin>: ERROR: Expected \"(\" but found \"=\"\n")
  1938  	expectParseError(t, "class Foo { set a = 1 }", "<stdin>: ERROR: Expected \"(\" but found \"=\"\n")
  1939  	expectParseError(t, "class Foo { async a = 1 }", "<stdin>: ERROR: Expected \"(\" but found \"=\"\n")
  1940  
  1941  	expectParseError(t, "class Foo { `a` = 0 }", "<stdin>: ERROR: Expected identifier but found \"`a`\"\n")
  1942  
  1943  	// The name "constructor" is forbidden
  1944  	expectParseError(t, "class Foo { constructor }", "<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1945  	expectParseError(t, "class Foo { 'constructor' }", "<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1946  	expectParseError(t, "class Foo { constructor = 1 }", "<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1947  	expectParseError(t, "class Foo { 'constructor' = 1 }", "<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1948  	expectParseError(t, "class Foo { static constructor }", "<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1949  	expectParseError(t, "class Foo { static 'constructor' }", "<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1950  	expectParseError(t, "class Foo { static constructor = 1 }", "<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1951  	expectParseError(t, "class Foo { static 'constructor' = 1 }", "<stdin>: ERROR: Invalid field name \"constructor\"\n")
  1952  
  1953  	expectPrinted(t, "class Foo { ['constructor'] }", "class Foo {\n  [\"constructor\"];\n}\n")
  1954  	expectPrinted(t, "class Foo { ['constructor'] = 1 }", "class Foo {\n  [\"constructor\"] = 1;\n}\n")
  1955  	expectPrinted(t, "class Foo { static ['constructor'] }", "class Foo {\n  static [\"constructor\"];\n}\n")
  1956  	expectPrinted(t, "class Foo { static ['constructor'] = 1 }", "class Foo {\n  static [\"constructor\"] = 1;\n}\n")
  1957  
  1958  	// The name "prototype" is sometimes forbidden
  1959  	expectPrinted(t, "class Foo { prototype }", "class Foo {\n  prototype;\n}\n")
  1960  	expectPrinted(t, "class Foo { 'prototype' }", "class Foo {\n  \"prototype\";\n}\n")
  1961  	expectPrinted(t, "class Foo { prototype = 1 }", "class Foo {\n  prototype = 1;\n}\n")
  1962  	expectPrinted(t, "class Foo { 'prototype' = 1 }", "class Foo {\n  \"prototype\" = 1;\n}\n")
  1963  	expectParseError(t, "class Foo { static prototype }", "<stdin>: ERROR: Invalid field name \"prototype\"\n")
  1964  	expectParseError(t, "class Foo { static 'prototype' }", "<stdin>: ERROR: Invalid field name \"prototype\"\n")
  1965  	expectParseError(t, "class Foo { static prototype = 1 }", "<stdin>: ERROR: Invalid field name \"prototype\"\n")
  1966  	expectParseError(t, "class Foo { static 'prototype' = 1 }", "<stdin>: ERROR: Invalid field name \"prototype\"\n")
  1967  	expectPrinted(t, "class Foo { static ['prototype'] }", "class Foo {\n  static [\"prototype\"];\n}\n")
  1968  	expectPrinted(t, "class Foo { static ['prototype'] = 1 }", "class Foo {\n  static [\"prototype\"] = 1;\n}\n")
  1969  }
  1970  
  1971  func TestClassStaticBlocks(t *testing.T) {
  1972  	expectPrinted(t, "class Foo { static {} }", "class Foo {\n  static {\n  }\n}\n")
  1973  	expectPrinted(t, "class Foo { static {} x = 1 }", "class Foo {\n  static {\n  }\n  x = 1;\n}\n")
  1974  	expectPrinted(t, "class Foo { static { this.foo() } }", "class Foo {\n  static {\n    this.foo();\n  }\n}\n")
  1975  
  1976  	expectParseError(t, "class Foo { static { yield } }",
  1977  		"<stdin>: ERROR: \"yield\" is a reserved word and cannot be used in strict mode\n"+
  1978  			"<stdin>: NOTE: All code inside a class is implicitly in strict mode\n")
  1979  	expectParseError(t, "class Foo { static { await } }", "<stdin>: ERROR: The keyword \"await\" cannot be used here:\n")
  1980  	expectParseError(t, "class Foo { static { return } }", "<stdin>: ERROR: A return statement cannot be used here:\n")
  1981  	expectParseError(t, "class Foo { static { break } }", "<stdin>: ERROR: Cannot use \"break\" here:\n")
  1982  	expectParseError(t, "class Foo { static { continue } }", "<stdin>: ERROR: Cannot use \"continue\" here:\n")
  1983  	expectParseError(t, "x: { class Foo { static { break x } } }", "<stdin>: ERROR: There is no containing label named \"x\"\n")
  1984  	expectParseError(t, "x: { class Foo { static { continue x } } }", "<stdin>: ERROR: There is no containing label named \"x\"\n")
  1985  
  1986  	expectPrintedMangle(t, "class Foo { static {} }", "class Foo {\n}\n")
  1987  	expectPrintedMangle(t, "class Foo { static { 123 } }", "class Foo {\n}\n")
  1988  	expectPrintedMangle(t, "class Foo { static { /* @__PURE__ */ foo() } }", "class Foo {\n}\n")
  1989  	expectPrintedMangle(t, "class Foo { static { foo() } }", "class Foo {\n  static {\n    foo();\n  }\n}\n")
  1990  }
  1991  
  1992  func TestAutoAccessors(t *testing.T) {
  1993  	expectPrinted(t, "class Foo { accessor }", "class Foo {\n  accessor;\n}\n")
  1994  	expectPrinted(t, "class Foo { accessor \n x }", "class Foo {\n  accessor;\n  x;\n}\n")
  1995  	expectPrinted(t, "class Foo { static accessor }", "class Foo {\n  static accessor;\n}\n")
  1996  	expectPrinted(t, "class Foo { static accessor \n x }", "class Foo {\n  static accessor;\n  x;\n}\n")
  1997  
  1998  	expectPrinted(t, "class Foo { accessor x }", "class Foo {\n  accessor x;\n}\n")
  1999  	expectPrinted(t, "class Foo { accessor x = y }", "class Foo {\n  accessor x = y;\n}\n")
  2000  	expectPrinted(t, "class Foo { accessor [x] }", "class Foo {\n  accessor [x];\n}\n")
  2001  	expectPrinted(t, "class Foo { accessor [x] = y }", "class Foo {\n  accessor [x] = y;\n}\n")
  2002  	expectPrinted(t, "class Foo { static accessor x }", "class Foo {\n  static accessor x;\n}\n")
  2003  	expectPrinted(t, "class Foo { static accessor [x] }", "class Foo {\n  static accessor [x];\n}\n")
  2004  	expectPrinted(t, "class Foo { static accessor x = y }", "class Foo {\n  static accessor x = y;\n}\n")
  2005  	expectPrinted(t, "class Foo { static accessor [x] = y }", "class Foo {\n  static accessor [x] = y;\n}\n")
  2006  
  2007  	expectPrinted(t, "Foo = class { accessor x }", "Foo = class {\n  accessor x;\n};\n")
  2008  	expectPrinted(t, "Foo = class { accessor [x] }", "Foo = class {\n  accessor [x];\n};\n")
  2009  	expectPrinted(t, "Foo = class { accessor x = y }", "Foo = class {\n  accessor x = y;\n};\n")
  2010  	expectPrinted(t, "Foo = class { accessor [x] = y }", "Foo = class {\n  accessor [x] = y;\n};\n")
  2011  	expectPrinted(t, "Foo = class { static accessor x }", "Foo = class {\n  static accessor x;\n};\n")
  2012  	expectPrinted(t, "Foo = class { static accessor [x] }", "Foo = class {\n  static accessor [x];\n};\n")
  2013  	expectPrinted(t, "Foo = class { static accessor x = y }", "Foo = class {\n  static accessor x = y;\n};\n")
  2014  
  2015  	expectPrinted(t, "class Foo { accessor get }", "class Foo {\n  accessor get;\n}\n")
  2016  	expectPrinted(t, "class Foo { get accessor() {} }", "class Foo {\n  get accessor() {\n  }\n}\n")
  2017  	expectParseError(t, "class Foo { accessor x() {} }", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2018  	expectParseError(t, "class Foo { accessor get x() {} }", "<stdin>: ERROR: Expected \";\" but found \"x\"\n")
  2019  	expectParseError(t, "class Foo { get accessor x() {} }", "<stdin>: ERROR: Expected \"(\" but found \"x\"\n")
  2020  
  2021  	expectPrinted(t, "Foo = { get accessor() {} }", "Foo = { get accessor() {\n} };\n")
  2022  	expectParseError(t, "Foo = { accessor x }", "<stdin>: ERROR: Expected \"}\" but found \"x\"\n")
  2023  	expectParseError(t, "Foo = { accessor x() {} }", "<stdin>: ERROR: Expected \"}\" but found \"x\"\n")
  2024  	expectParseError(t, "Foo = { get accessor x() {} }", "<stdin>: ERROR: Expected \"(\" but found \"x\"\n")
  2025  
  2026  	expectParseError(t, "class Foo { accessor x, y }", "<stdin>: ERROR: Expected \";\" but found \",\"\n")
  2027  	expectParseError(t, "class Foo { static accessor x, y }", "<stdin>: ERROR: Expected \";\" but found \",\"\n")
  2028  	expectParseError(t, "Foo = class { accessor x, y }", "<stdin>: ERROR: Expected \";\" but found \",\"\n")
  2029  	expectParseError(t, "Foo = class { static accessor x, y }", "<stdin>: ERROR: Expected \";\" but found \",\"\n")
  2030  }
  2031  
  2032  func TestDecorators(t *testing.T) {
  2033  	expectPrinted(t, "@x @y class Foo {}", "@x @y class Foo {\n}\n")
  2034  	expectPrinted(t, "@x @y export class Foo {}", "@x @y export class Foo {\n}\n")
  2035  	expectPrinted(t, "@x @y export default class Foo {}", "@x @y export default class Foo {\n}\n")
  2036  	expectPrinted(t, "_ = @x @y class {}", "_ = @x @y class {\n};\n")
  2037  
  2038  	expectPrinted(t, "class Foo { @x y }", "class Foo {\n  @x y;\n}\n")
  2039  	expectPrinted(t, "class Foo { @x y() {} }", "class Foo {\n  @x y() {\n  }\n}\n")
  2040  	expectPrinted(t, "class Foo { @x static y }", "class Foo {\n  @x static y;\n}\n")
  2041  	expectPrinted(t, "class Foo { @x static y() {} }", "class Foo {\n  @x static y() {\n  }\n}\n")
  2042  	expectPrinted(t, "class Foo { @x accessor y }", "class Foo {\n  @x accessor y;\n}\n")
  2043  
  2044  	expectPrinted(t, "class Foo { @x #y }", "class Foo {\n  @x #y;\n}\n")
  2045  	expectPrinted(t, "class Foo { @x #y() {} }", "class Foo {\n  @x #y() {\n  }\n}\n")
  2046  	expectPrinted(t, "class Foo { @x static #y }", "class Foo {\n  @x static #y;\n}\n")
  2047  	expectPrinted(t, "class Foo { @x static #y() {} }", "class Foo {\n  @x static #y() {\n  }\n}\n")
  2048  	expectPrinted(t, "class Foo { @x accessor #y }", "class Foo {\n  @x accessor #y;\n}\n")
  2049  
  2050  	expectParseError(t, "class Foo { x(@y z) {} }", "<stdin>: ERROR: Parameter decorators are not allowed in JavaScript\n")
  2051  	expectParseError(t, "class Foo { @x static {} }", "<stdin>: ERROR: Expected \";\" but found \"{\"\n")
  2052  
  2053  	expectPrinted(t, "@\na\n(\n)\n@\n(\nb\n)\nclass\nFoo\n{\n}\n", "@a()\n@b\nclass Foo {\n}\n")
  2054  	expectPrinted(t, "@(a, b) class Foo {}", "@(a, b) class Foo {\n}\n")
  2055  	expectPrinted(t, "@x() class Foo {}", "@x() class Foo {\n}\n")
  2056  	expectPrinted(t, "@x.y() class Foo {}", "@x.y() class Foo {\n}\n")
  2057  	expectPrinted(t, "@(() => {}) class Foo {}", "@(() => {\n}) class Foo {\n}\n")
  2058  	expectPrinted(t, "class Foo { #x = @y.#x.y.#x class {} }", "class Foo {\n  #x = @y.#x.y.#x class {\n  };\n}\n")
  2059  	expectParseError(t, "@123 class Foo {}", "<stdin>: ERROR: Expected identifier but found \"123\"\n")
  2060  	expectParseError(t, "@x[y] class Foo {}", "<stdin>: ERROR: Expected \";\" but found \"class\"\n")
  2061  	expectParseError(t, "@x?.() class Foo {}", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  2062  	expectParseError(t, "@x?.y() class Foo {}",
  2063  		"<stdin>: ERROR: JavaScript decorator syntax does not allow \"?.\" here\n"+
  2064  			"<stdin>: NOTE: Wrap this decorator in parentheses to allow arbitrary expressions:\n")
  2065  	expectParseError(t, "@x?.[y]() class Foo {}", "<stdin>: ERROR: Expected identifier but found \"[\"\n")
  2066  	expectParseError(t, "@new Function() class Foo {}", "<stdin>: ERROR: Expected identifier but found \"new\"\n")
  2067  	expectParseError(t, "@() => {} class Foo {}", "<stdin>: ERROR: Unexpected \")\"\n")
  2068  	expectParseError(t, "x = @y function() {}", "<stdin>: ERROR: Expected \"class\" but found \"function\"\n")
  2069  
  2070  	// See: https://github.com/microsoft/TypeScript/issues/55336
  2071  	expectParseError(t, "@x().y() class Foo {}",
  2072  		"<stdin>: ERROR: JavaScript decorator syntax does not allow \".\" after a call expression\n"+
  2073  			"<stdin>: NOTE: Wrap this decorator in parentheses to allow arbitrary expressions:\n")
  2074  
  2075  	expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "@dec class Foo {}",
  2076  		`var _Foo_decorators, _init;
  2077  _Foo_decorators = [dec];
  2078  class Foo {
  2079  }
  2080  _init = __decoratorStart(null);
  2081  Foo = __decorateElement(_init, 0, "Foo", _Foo_decorators, Foo);
  2082  __runInitializers(_init, 1, Foo);
  2083  `)
  2084  	expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec x }",
  2085  		`var _x_dec, _init;
  2086  _x_dec = [dec];
  2087  class Foo {
  2088    constructor() {
  2089      __publicField(this, "x", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
  2090    }
  2091  }
  2092  _init = __decoratorStart(null);
  2093  __decorateElement(_init, 5, "x", _x_dec, Foo);
  2094  `)
  2095  	expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec x() {} }",
  2096  		`var _x_dec, _init;
  2097  _x_dec = [dec];
  2098  class Foo {
  2099    constructor() {
  2100      __runInitializers(_init, 5, this);
  2101    }
  2102    x() {
  2103    }
  2104  }
  2105  _init = __decoratorStart(null);
  2106  __decorateElement(_init, 1, "x", _x_dec, Foo);
  2107  `)
  2108  	expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec accessor x }",
  2109  		`var _x_dec, _init, _x;
  2110  _x_dec = [dec];
  2111  class Foo {
  2112    constructor() {
  2113      __privateAdd(this, _x, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
  2114    }
  2115  }
  2116  _init = __decoratorStart(null);
  2117  _x = new WeakMap();
  2118  __decorateElement(_init, 4, "x", _x_dec, Foo, _x);
  2119  `)
  2120  	expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static x }",
  2121  		`var _x_dec, _init;
  2122  _x_dec = [dec];
  2123  class Foo {
  2124  }
  2125  _init = __decoratorStart(null);
  2126  __decorateElement(_init, 13, "x", _x_dec, Foo);
  2127  __publicField(Foo, "x", __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);
  2128  `)
  2129  	expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static x() {} }",
  2130  		`var _x_dec, _init;
  2131  _x_dec = [dec];
  2132  class Foo {
  2133    static x() {
  2134    }
  2135  }
  2136  _init = __decoratorStart(null);
  2137  __decorateElement(_init, 9, "x", _x_dec, Foo);
  2138  __runInitializers(_init, 3, Foo);
  2139  `)
  2140  	expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static accessor x }",
  2141  		`var _x_dec, _init, _x;
  2142  _x_dec = [dec];
  2143  class Foo {
  2144  }
  2145  _init = __decoratorStart(null);
  2146  _x = new WeakMap();
  2147  __decorateElement(_init, 12, "x", _x_dec, Foo, _x);
  2148  __privateAdd(Foo, _x, __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);
  2149  `)
  2150  
  2151  	// Check ASI for "abstract"
  2152  	expectParseError(t, "@x abstract class Foo {}", "<stdin>: ERROR: Expected \";\" but found \"class\"\n")
  2153  	expectParseError(t, "@x abstract\nclass Foo {}", "<stdin>: ERROR: Decorators are not valid here\n")
  2154  
  2155  	// Check decorator locations in relation to the "export" keyword
  2156  	expectPrinted(t, "@x export class Foo {}", "@x export class Foo {\n}\n")
  2157  	expectPrinted(t, "export @x class Foo {}", "@x export class Foo {\n}\n")
  2158  	expectPrinted(t, "@x export default class {}", "@x export default class {\n}\n")
  2159  	expectPrinted(t, "export default @x class {}", "@x export default class {\n}\n")
  2160  	expectPrinted(t, "@x export default class Foo {}", "@x export default class Foo {\n}\n")
  2161  	expectPrinted(t, "export default @x class Foo {}", "@x export default class Foo {\n}\n")
  2162  	expectPrinted(t, "export default (@x class {})", "export default (@x class {\n});\n")
  2163  	expectPrinted(t, "export default (@x class Foo {})", "export default (@x class Foo {\n});\n")
  2164  	expectParseError(t, "export @x default class {}", "<stdin>: ERROR: Unexpected \"default\"\n")
  2165  	expectParseError(t, "@x export @y class Foo {}", "<stdin>: ERROR: Decorators are not valid here\n")
  2166  	expectParseError(t, "@x export default abstract", "<stdin>: ERROR: Decorators are not valid here\n")
  2167  	expectParseError(t, "@x export @y default class {}", "<stdin>: ERROR: Decorators are not valid here\n<stdin>: ERROR: Unexpected \"default\"\n")
  2168  
  2169  	// Disallow TypeScript syntax in JavaScript
  2170  	expectParseError(t, "@x!.y!.z class Foo {}", "<stdin>: ERROR: Unexpected \"!\"\n")
  2171  }
  2172  
  2173  func TestGenerator(t *testing.T) {
  2174  	expectParseError(t, "(class { * foo })", "<stdin>: ERROR: Expected \"(\" but found \"}\"\n")
  2175  	expectParseError(t, "(class { * *foo() {} })", "<stdin>: ERROR: Unexpected \"*\"\n")
  2176  	expectParseError(t, "(class { get*foo() {} })", "<stdin>: ERROR: Unexpected \"*\"\n")
  2177  	expectParseError(t, "(class { set*foo() {} })", "<stdin>: ERROR: Unexpected \"*\"\n")
  2178  	expectParseError(t, "(class { *get foo() {} })", "<stdin>: ERROR: Expected \"(\" but found \"foo\"\n")
  2179  	expectParseError(t, "(class { *set foo() {} })", "<stdin>: ERROR: Expected \"(\" but found \"foo\"\n")
  2180  	expectParseError(t, "(class { *static foo() {} })", "<stdin>: ERROR: Expected \"(\" but found \"foo\"\n")
  2181  	expectParseError(t, "(class { *async foo() {} })", "<stdin>: ERROR: Expected \"(\" but found \"foo\"\n")
  2182  	expectParseError(t, "(class { async * *foo() {} })", "<stdin>: ERROR: Unexpected \"*\"\n")
  2183  
  2184  	expectParseError(t, "function* foo() { -yield 100 }", "<stdin>: ERROR: Cannot use a \"yield\" expression here without parentheses:\n")
  2185  	expectPrinted(t, "function* foo() { -(yield 100) }", "function* foo() {\n  -(yield 100);\n}\n")
  2186  }
  2187  
  2188  func TestYield(t *testing.T) {
  2189  	expectParseError(t, "yield 100", "<stdin>: ERROR: Cannot use \"yield\" outside a generator function\n")
  2190  	expectParseError(t, "-yield 100", "<stdin>: ERROR: Cannot use \"yield\" outside a generator function\n")
  2191  	expectPrinted(t, "yield\n100", "yield;\n100;\n")
  2192  
  2193  	noYield := "<stdin>: ERROR: The keyword \"yield\" cannot be used here:\n"
  2194  	expectParseError(t, "function* bar(x = yield y) {}", noYield+"<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2195  	expectParseError(t, "(function*(x = yield y) {})", noYield+"<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2196  	expectParseError(t, "({ *foo(x = yield y) {} })", noYield+"<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2197  	expectParseError(t, "class Foo { *foo(x = yield y) {} }", noYield+"<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2198  	expectParseError(t, "(class { *foo(x = yield y) {} })", noYield+"<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2199  
  2200  	expectParseError(t, "function *foo() { function bar(x = yield y) {} }", "<stdin>: ERROR: Cannot use \"yield\" outside a generator function\n")
  2201  	expectParseError(t, "function *foo() { (function(x = yield y) {}) }", "<stdin>: ERROR: Cannot use \"yield\" outside a generator function\n")
  2202  	expectParseError(t, "function *foo() { ({ foo(x = yield y) {} }) }", "<stdin>: ERROR: Cannot use \"yield\" outside a generator function\n")
  2203  	expectParseError(t, "function *foo() { class Foo { foo(x = yield y) {} } }", "<stdin>: ERROR: Cannot use \"yield\" outside a generator function\n")
  2204  	expectParseError(t, "function *foo() { (class { foo(x = yield y) {} }) }", "<stdin>: ERROR: Cannot use \"yield\" outside a generator function\n")
  2205  	expectParseError(t, "function *foo() { (x = yield y) => {} }", "<stdin>: ERROR: Cannot use a \"yield\" expression here:\n")
  2206  	expectPrinted(t, "function *foo() { x = yield }", "function* foo() {\n  x = yield;\n}\n")
  2207  	expectPrinted(t, "function *foo() { x = yield; }", "function* foo() {\n  x = yield;\n}\n")
  2208  	expectPrinted(t, "function *foo() { (x = yield) }", "function* foo() {\n  x = yield;\n}\n")
  2209  	expectPrinted(t, "function *foo() { [x = yield] }", "function* foo() {\n  [x = yield];\n}\n")
  2210  	expectPrinted(t, "function *foo() { x = (yield, yield) }", "function* foo() {\n  x = (yield, yield);\n}\n")
  2211  	expectPrinted(t, "function *foo() { x = y ? yield : yield }", "function* foo() {\n  x = y ? yield : yield;\n}\n")
  2212  	expectParseError(t, "function *foo() { x = yield ? y : z }", "<stdin>: ERROR: Unexpected \"?\"\n")
  2213  	expectParseError(t, "function *foo() { x = yield * }", "<stdin>: ERROR: Unexpected \"}\"\n")
  2214  	expectParseError(t, "function *foo() { (x = yield *) }", "<stdin>: ERROR: Unexpected \")\"\n")
  2215  	expectParseError(t, "function *foo() { [x = yield *] }", "<stdin>: ERROR: Unexpected \"]\"\n")
  2216  	expectPrinted(t, "function *foo() { x = yield y }", "function* foo() {\n  x = yield y;\n}\n")
  2217  	expectPrinted(t, "function *foo() { (x = yield y) }", "function* foo() {\n  x = yield y;\n}\n")
  2218  	expectPrinted(t, "function *foo() { x = yield \n y }", "function* foo() {\n  x = yield;\n  y;\n}\n")
  2219  	expectPrinted(t, "function *foo() { x = yield * y }", "function* foo() {\n  x = yield* y;\n}\n")
  2220  	expectPrinted(t, "function *foo() { (x = yield * y) }", "function* foo() {\n  x = yield* y;\n}\n")
  2221  	expectPrinted(t, "function *foo() { x = yield * \n y }", "function* foo() {\n  x = yield* y;\n}\n")
  2222  	expectParseError(t, "function *foo() { x = yield \n * y }", "<stdin>: ERROR: Unexpected \"*\"\n")
  2223  	expectParseError(t, "function foo() { (x = yield y) }", "<stdin>: ERROR: Cannot use \"yield\" outside a generator function\n")
  2224  	expectPrinted(t, "function foo() { x = yield * y }", "function foo() {\n  x = yield * y;\n}\n")
  2225  	expectPrinted(t, "function foo() { (x = yield * y) }", "function foo() {\n  x = yield * y;\n}\n")
  2226  	expectParseError(t, "function *foo() { (x = \\u0079ield) }", "<stdin>: ERROR: The keyword \"yield\" cannot be escaped\n")
  2227  	expectParseError(t, "function *foo() { (x = \\u0079ield* y) }", "<stdin>: ERROR: The keyword \"yield\" cannot be escaped\n")
  2228  
  2229  	// Yield as an identifier
  2230  	expectPrinted(t, "({yield} = x)", "({ yield } = x);\n")
  2231  	expectPrinted(t, "let x = {yield}", "let x = { yield };\n")
  2232  	expectPrinted(t, "function* yield() {}", "function* yield() {\n}\n")
  2233  	expectPrinted(t, "function foo() { ({yield} = x) }", "function foo() {\n  ({ yield } = x);\n}\n")
  2234  	expectPrinted(t, "function foo() { let x = {yield} }", "function foo() {\n  let x = { yield };\n}\n")
  2235  	expectParseError(t, "function *foo() { ({yield} = x) }", "<stdin>: ERROR: Cannot use \"yield\" as an identifier here:\n")
  2236  	expectParseError(t, "function *foo() { let x = {yield} }", "<stdin>: ERROR: Cannot use \"yield\" as an identifier here:\n")
  2237  
  2238  	// Yield as a declaration
  2239  	expectPrinted(t, "({ *yield() {} })", "({ *yield() {\n} });\n")
  2240  	expectPrinted(t, "(class { *yield() {} })", "(class {\n  *yield() {\n  }\n});\n")
  2241  	expectPrinted(t, "class Foo { *yield() {} }", "class Foo {\n  *yield() {\n  }\n}\n")
  2242  	expectPrinted(t, "function* yield() {}", "function* yield() {\n}\n")
  2243  	expectParseError(t, "(function* yield() {})", "<stdin>: ERROR: A generator function expression cannot be named \"yield\"\n")
  2244  
  2245  	// Yield as an async declaration
  2246  	expectPrinted(t, "({ async *yield() {} })", "({ async *yield() {\n} });\n")
  2247  	expectPrinted(t, "(class { async *yield() {} })", "(class {\n  async *yield() {\n  }\n});\n")
  2248  	expectPrinted(t, "class Foo { async *yield() {} }", "class Foo {\n  async *yield() {\n  }\n}\n")
  2249  	expectPrinted(t, "async function* yield() {}", "async function* yield() {\n}\n")
  2250  	expectParseError(t, "(async function* yield() {})", "<stdin>: ERROR: A generator function expression cannot be named \"yield\"\n")
  2251  }
  2252  
  2253  func TestAsync(t *testing.T) {
  2254  	expectPrinted(t, "function foo() { await }", "function foo() {\n  await;\n}\n")
  2255  	expectPrinted(t, "async function foo() { await 0 }", "async function foo() {\n  await 0;\n}\n")
  2256  	expectParseError(t, "async function() {}", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  2257  
  2258  	expectPrinted(t, "-async function foo() { await 0 }", "-async function foo() {\n  await 0;\n};\n")
  2259  	expectPrinted(t, "-async function() { await 0 }", "-async function() {\n  await 0;\n};\n")
  2260  	expectPrinted(t, "1 - async function foo() { await 0 }", "1 - async function foo() {\n  await 0;\n};\n")
  2261  	expectPrinted(t, "1 - async function() { await 0 }", "1 - async function() {\n  await 0;\n};\n")
  2262  	expectPrinted(t, "(async function foo() { await 0 })", "(async function foo() {\n  await 0;\n});\n")
  2263  	expectPrinted(t, "(async function() { await 0 })", "(async function() {\n  await 0;\n});\n")
  2264  	expectPrinted(t, "(x, async function foo() { await 0 })", "x, async function foo() {\n  await 0;\n};\n")
  2265  	expectPrinted(t, "(x, async function() { await 0 })", "x, async function() {\n  await 0;\n};\n")
  2266  	expectPrinted(t, "new async function() { await 0 }", "new async function() {\n  await 0;\n}();\n")
  2267  	expectPrinted(t, "new async function() { await 0 }.x", "new async function() {\n  await 0;\n}.x();\n")
  2268  
  2269  	friendlyAwaitError := "<stdin>: ERROR: \"await\" can only be used inside an \"async\" function\n"
  2270  	friendlyAwaitErrorWithNote := friendlyAwaitError + "<stdin>: NOTE: Consider adding the \"async\" keyword here:\n"
  2271  
  2272  	expectPrinted(t, "async", "async;\n")
  2273  	expectPrinted(t, "async + 1", "async + 1;\n")
  2274  	expectPrinted(t, "async => {}", "(async) => {\n};\n")
  2275  	expectPrinted(t, "(async, 1)", "async, 1;\n")
  2276  	expectPrinted(t, "(async, x) => {}", "(async, x) => {\n};\n")
  2277  	expectPrinted(t, "async ()", "async();\n")
  2278  	expectPrinted(t, "async (x)", "async(x);\n")
  2279  	expectPrinted(t, "async (...x)", "async(...x);\n")
  2280  	expectPrinted(t, "async (...x, ...y)", "async(...x, ...y);\n")
  2281  	expectPrinted(t, "async () => {}", "async () => {\n};\n")
  2282  	expectPrinted(t, "async x => {}", "async (x) => {\n};\n")
  2283  	expectPrinted(t, "async (x) => {}", "async (x) => {\n};\n")
  2284  	expectPrinted(t, "async (...x) => {}", "async (...x) => {\n};\n")
  2285  	expectPrinted(t, "async x => await 0", "async (x) => await 0;\n")
  2286  	expectPrinted(t, "async () => await 0", "async () => await 0;\n")
  2287  	expectPrinted(t, "new async()", "new async();\n")
  2288  	expectPrinted(t, "new async().x", "new async().x;\n")
  2289  	expectPrinted(t, "new (async())", "new (async())();\n")
  2290  	expectPrinted(t, "new (async().x)", "new (async()).x();\n")
  2291  	expectParseError(t, "async x;", "<stdin>: ERROR: Expected \"=>\" but found \";\"\n")
  2292  	expectParseError(t, "async (...x,) => {}", "<stdin>: ERROR: Unexpected \",\" after rest pattern\n")
  2293  	expectParseError(t, "async => await 0", friendlyAwaitErrorWithNote)
  2294  	expectParseError(t, "new async => {}", "<stdin>: ERROR: Expected \";\" but found \"=>\"\n")
  2295  	expectParseError(t, "new async () => {}", "<stdin>: ERROR: Expected \";\" but found \"=>\"\n")
  2296  
  2297  	expectPrinted(t, "(async x => y), z", "async (x) => y, z;\n")
  2298  	expectPrinted(t, "(async x => y, z)", "async (x) => y, z;\n")
  2299  	expectPrinted(t, "(async x => (y, z))", "async (x) => (y, z);\n")
  2300  	expectPrinted(t, "(async (x) => y), z", "async (x) => y, z;\n")
  2301  	expectPrinted(t, "(async (x) => y, z)", "async (x) => y, z;\n")
  2302  	expectPrinted(t, "(async (x) => (y, z))", "async (x) => (y, z);\n")
  2303  	expectPrinted(t, "async x => y, z", "async (x) => y, z;\n")
  2304  	expectPrinted(t, "async x => (y, z)", "async (x) => (y, z);\n")
  2305  	expectPrinted(t, "async (x) => y, z", "async (x) => y, z;\n")
  2306  	expectPrinted(t, "async (x) => (y, z)", "async (x) => (y, z);\n")
  2307  	expectPrinted(t, "export default async x => (y, z)", "export default async (x) => (y, z);\n")
  2308  	expectPrinted(t, "export default async (x) => (y, z)", "export default async (x) => (y, z);\n")
  2309  	expectParseError(t, "export default async x => y, z", "<stdin>: ERROR: Expected \";\" but found \",\"\n")
  2310  	expectParseError(t, "export default async (x) => y, z", "<stdin>: ERROR: Expected \";\" but found \",\"\n")
  2311  
  2312  	expectPrinted(t, "class Foo { async async() {} }", "class Foo {\n  async async() {\n  }\n}\n")
  2313  	expectPrinted(t, "(class { async async() {} })", "(class {\n  async async() {\n  }\n});\n")
  2314  	expectPrinted(t, "({ async async() {} })", "({ async async() {\n} });\n")
  2315  	expectParseError(t, "class Foo { async async }", "<stdin>: ERROR: Expected \"(\" but found \"}\"\n")
  2316  	expectParseError(t, "(class { async async })", "<stdin>: ERROR: Expected \"(\" but found \"}\"\n")
  2317  	expectParseError(t, "({ async async })", "<stdin>: ERROR: Expected \"(\" but found \"}\"\n")
  2318  
  2319  	noAwait := "<stdin>: ERROR: The keyword \"await\" cannot be used here:\n"
  2320  	expectParseError(t, "async function bar(x = await y) {}", noAwait+"<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2321  	expectParseError(t, "async (function(x = await y) {})", friendlyAwaitError)
  2322  	expectParseError(t, "async ({ foo(x = await y) {} })", friendlyAwaitError)
  2323  	expectParseError(t, "class Foo { async foo(x = await y) {} }", noAwait+"<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2324  	expectParseError(t, "(class { async foo(x = await y) {} })", noAwait+"<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2325  
  2326  	expectParseError(t, "async function foo() { function bar(x = await y) {} }", friendlyAwaitError)
  2327  	expectParseError(t, "async function foo() { (function(x = await y) {}) }", friendlyAwaitError)
  2328  	expectParseError(t, "async function foo() { ({ foo(x = await y) {} }) }", friendlyAwaitError)
  2329  	expectParseError(t, "async function foo() { class Foo { foo(x = await y) {} } }", friendlyAwaitError)
  2330  	expectParseError(t, "async function foo() { (class { foo(x = await y) {} }) }", friendlyAwaitError)
  2331  	expectParseError(t, "async function foo() { (x = await y) => {} }", "<stdin>: ERROR: Cannot use an \"await\" expression here:\n")
  2332  	expectParseError(t, "async function foo(x = await y) {}", "<stdin>: ERROR: The keyword \"await\" cannot be used here:\n<stdin>: ERROR: Expected \")\" but found \"y\"\n")
  2333  	expectParseError(t, "async function foo({ [await y]: x }) {}", "<stdin>: ERROR: The keyword \"await\" cannot be used here:\n<stdin>: ERROR: Expected \"]\" but found \"y\"\n")
  2334  	expectPrinted(t, "async function foo() { (x = await y) }", "async function foo() {\n  x = await y;\n}\n")
  2335  	expectParseError(t, "function foo() { (x = await y) }", friendlyAwaitErrorWithNote)
  2336  
  2337  	// Newlines
  2338  	expectPrinted(t, "(class { async \n foo() {} })", "(class {\n  async;\n  foo() {\n  }\n});\n")
  2339  	expectPrinted(t, "(class { async \n *foo() {} })", "(class {\n  async;\n  *foo() {\n  }\n});\n")
  2340  	expectParseError(t, "({ async \n foo() {} })", "<stdin>: ERROR: Expected \"}\" but found \"foo\"\n")
  2341  	expectParseError(t, "({ async \n *foo() {} })", "<stdin>: ERROR: Expected \"}\" but found \"*\"\n")
  2342  
  2343  	// Top-level await
  2344  	expectPrinted(t, "await foo;", "await foo;\n")
  2345  	expectPrinted(t, "for await(foo of bar);", "for await (foo of bar) ;\n")
  2346  	expectParseError(t, "function foo() { await foo }", friendlyAwaitErrorWithNote)
  2347  	expectParseError(t, "function foo() { for await(foo of bar); }", "<stdin>: ERROR: Cannot use \"await\" outside an async function\n")
  2348  	expectPrinted(t, "function foo(x = await) {}", "function foo(x = await) {\n}\n")
  2349  	expectParseError(t, "function foo(x = await y) {}", friendlyAwaitError)
  2350  	expectPrinted(t, "(function(x = await) {})", "(function(x = await) {\n});\n")
  2351  	expectParseError(t, "(function(x = await y) {})", friendlyAwaitError)
  2352  	expectPrinted(t, "({ foo(x = await) {} })", "({ foo(x = await) {\n} });\n")
  2353  	expectParseError(t, "({ foo(x = await y) {} })", friendlyAwaitError)
  2354  	expectPrinted(t, "class Foo { foo(x = await) {} }", "class Foo {\n  foo(x = await) {\n  }\n}\n")
  2355  	expectParseError(t, "class Foo { foo(x = await y) {} }", friendlyAwaitError)
  2356  	expectPrinted(t, "(class { foo(x = await) {} })", "(class {\n  foo(x = await) {\n  }\n});\n")
  2357  	expectParseError(t, "(class { foo(x = await y) {} })", friendlyAwaitError)
  2358  	expectParseError(t, "(x = await) => {}", "<stdin>: ERROR: Unexpected \")\"\n")
  2359  	expectParseError(t, "(x = await y) => {}", "<stdin>: ERROR: Cannot use an \"await\" expression here:\n")
  2360  	expectParseError(t, "(x = await)", "<stdin>: ERROR: Unexpected \")\"\n")
  2361  	expectPrinted(t, "(x = await y)", "x = await y;\n")
  2362  	expectParseError(t, "async (x = await) => {}", "<stdin>: ERROR: Unexpected \")\"\n")
  2363  	expectParseError(t, "async (x = await y) => {}", "<stdin>: ERROR: Cannot use an \"await\" expression here:\n")
  2364  	expectPrinted(t, "async(x = await y)", "async(x = await y);\n")
  2365  
  2366  	// Keywords with escapes
  2367  	expectPrinted(t, "\\u0061sync", "async;\n")
  2368  	expectPrinted(t, "(\\u0061sync)", "async;\n")
  2369  	expectPrinted(t, "function foo() { \\u0061wait }", "function foo() {\n  await;\n}\n")
  2370  	expectPrinted(t, "function foo() { var \\u0061wait }", "function foo() {\n  var await;\n}\n")
  2371  	expectParseError(t, "\\u0061wait", "<stdin>: ERROR: The keyword \"await\" cannot be escaped\n")
  2372  	expectParseError(t, "var \\u0061wait", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2373  	expectParseError(t, "async function foo() { \\u0061wait }", "<stdin>: ERROR: The keyword \"await\" cannot be escaped\n")
  2374  	expectParseError(t, "async function foo() { var \\u0061wait }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2375  	expectParseError(t, "\\u0061sync x => {}", "<stdin>: ERROR: Expected \";\" but found \"x\"\n")
  2376  	expectParseError(t, "\\u0061sync () => {}", "<stdin>: ERROR: Expected \";\" but found \"=>\"\n")
  2377  	expectParseError(t, "\\u0061sync function foo() {}", "<stdin>: ERROR: Expected \";\" but found \"function\"\n")
  2378  	expectParseError(t, "({ \\u0061sync foo() {} })", "<stdin>: ERROR: Expected \"}\" but found \"foo\"\n")
  2379  	expectParseError(t, "({ \\u0061sync *foo() {} })", "<stdin>: ERROR: Expected \"}\" but found \"*\"\n")
  2380  
  2381  	// For-await
  2382  	expectParseError(t, "for await(;;);", "<stdin>: ERROR: Unexpected \";\"\n")
  2383  	expectParseError(t, "for await(x in y);", "<stdin>: ERROR: Expected \"of\" but found \"in\"\n")
  2384  	expectParseError(t, "async function foo(){for await(;;);}", "<stdin>: ERROR: Unexpected \";\"\n")
  2385  	expectParseError(t, "async function foo(){for await(let x;;);}", "<stdin>: ERROR: Expected \"of\" but found \";\"\n")
  2386  	expectPrinted(t, "async function foo(){for await(x of y);}", "async function foo() {\n  for await (x of y) ;\n}\n")
  2387  	expectPrinted(t, "async function foo(){for await(let x of y);}", "async function foo() {\n  for await (let x of y) ;\n}\n")
  2388  
  2389  	// Await as an identifier
  2390  	expectPrinted(t, "(function await() {})", "(function await() {\n});\n")
  2391  	expectPrinted(t, "function foo() { ({await} = x) }", "function foo() {\n  ({ await } = x);\n}\n")
  2392  	expectPrinted(t, "function foo() { let x = {await} }", "function foo() {\n  let x = { await };\n}\n")
  2393  	expectParseError(t, "({await} = x)", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2394  	expectParseError(t, "let x = {await}", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2395  	expectParseError(t, "class await {}", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2396  	expectParseError(t, "(class await {})", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2397  	expectParseError(t, "function await() {}", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2398  	expectParseError(t, "async function foo() { ({await} = x) }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2399  	expectParseError(t, "async function foo() { let x = {await} }", "<stdin>: ERROR: Cannot use \"await\" as an identifier here:\n")
  2400  
  2401  	// Await as a declaration
  2402  	expectPrinted(t, "({ async await() {} })", "({ async await() {\n} });\n")
  2403  	expectPrinted(t, "(class { async await() {} })", "(class {\n  async await() {\n  }\n});\n")
  2404  	expectPrinted(t, "class Foo { async await() {} }", "class Foo {\n  async await() {\n  }\n}\n")
  2405  	expectParseError(t, "async function await() {}", "<stdin>: ERROR: An async function cannot be named \"await\"\n")
  2406  	expectParseError(t, "(async function await() {})", "<stdin>: ERROR: An async function cannot be named \"await\"\n")
  2407  
  2408  	// Await as a generator declaration
  2409  	expectPrinted(t, "({ async *await() {} })", "({ async *await() {\n} });\n")
  2410  	expectPrinted(t, "(class { async *await() {} })", "(class {\n  async *await() {\n  }\n});\n")
  2411  	expectPrinted(t, "class Foo { async *await() {} }", "class Foo {\n  async *await() {\n  }\n}\n")
  2412  	expectParseError(t, "async function* await() {}", "<stdin>: ERROR: An async function cannot be named \"await\"\n")
  2413  	expectParseError(t, "(async function* await() {})", "<stdin>: ERROR: An async function cannot be named \"await\"\n")
  2414  }
  2415  
  2416  func TestLabels(t *testing.T) {
  2417  	expectPrinted(t, "{a:b}", "{\n  a: b;\n}\n")
  2418  	expectPrinted(t, "({a:b})", "({ a: b });\n")
  2419  
  2420  	expectParseError(t, "while (1) break x", "<stdin>: ERROR: There is no containing label named \"x\"\n")
  2421  	expectParseError(t, "while (1) continue x", "<stdin>: ERROR: There is no containing label named \"x\"\n")
  2422  
  2423  	expectPrinted(t, "x: y: z: 1", "x: y: z: 1;\n")
  2424  	expectPrinted(t, "x: 1; y: 2; x: 3", "x: 1;\ny: 2;\nx: 3;\n")
  2425  	expectPrinted(t, "x: (() => { x: 1; })()", "x: (() => {\n  x: 1;\n})();\n")
  2426  	expectPrinted(t, "x: ({ f() { x: 1; } }).f()", "x: ({ f() {\n  x: 1;\n} }).f();\n")
  2427  	expectPrinted(t, "x: (function() { x: 1; })()", "x: (function() {\n  x: 1;\n})();\n")
  2428  	expectParseError(t, "x: y: x: 1", "<stdin>: ERROR: Duplicate label \"x\"\n<stdin>: NOTE: The original label \"x\" is here:\n")
  2429  
  2430  	expectPrinted(t, "x: break x", "x: break x;\n")
  2431  	expectPrinted(t, "x: { break x; foo() }", "x: {\n  break x;\n  foo();\n}\n")
  2432  	expectPrinted(t, "x: { y: { z: { foo(); break x; } } }", "x: {\n  y: {\n    z: {\n      foo();\n      break x;\n    }\n  }\n}\n")
  2433  	expectPrinted(t, "x: { class X { static { new X } } }", "x: {\n  class X {\n    static {\n      new X();\n    }\n  }\n}\n")
  2434  	expectPrintedMangle(t, "x: break x", "")
  2435  	expectPrintedMangle(t, "x: { break x; foo() }", "")
  2436  	expectPrintedMangle(t, "y: while (foo()) x: { break x; foo() }", "for (; foo(); ) ;\n")
  2437  	expectPrintedMangle(t, "y: while (foo()) x: { break y; foo() }", "y: for (; foo(); ) break y;\n")
  2438  	expectPrintedMangle(t, "x: { y: { z: { foo(); break x; } } }", "x: {\n  foo();\n  break x;\n}\n")
  2439  	expectPrintedMangle(t, "x: { class X { static { new X } } }", "{\n  class X {\n    static {\n      new X();\n    }\n  }\n}\n")
  2440  }
  2441  
  2442  func TestArrow(t *testing.T) {
  2443  	expectParseError(t, "({a: b, c() {}}) => {}", "<stdin>: ERROR: Invalid binding pattern\n")
  2444  	expectParseError(t, "({a: b, get c() {}}) => {}", "<stdin>: ERROR: Invalid binding pattern\n")
  2445  	expectParseError(t, "({a: b, set c(x) {}}) => {}", "<stdin>: ERROR: Invalid binding pattern\n")
  2446  
  2447  	expectParseError(t, "x = ([ (y) ]) => 0", "<stdin>: ERROR: Invalid binding pattern\n")
  2448  	expectParseError(t, "x = ([ ...(y) ]) => 0", "<stdin>: ERROR: Invalid binding pattern\n")
  2449  	expectParseError(t, "x = ({ (y) }) => 0", "<stdin>: ERROR: Expected identifier but found \"(\"\n")
  2450  	expectParseError(t, "x = ({ y: (z) }) => 0", "<stdin>: ERROR: Invalid binding pattern\n")
  2451  	expectParseError(t, "x = ({ ...(y) }) => 0", "<stdin>: ERROR: Invalid binding pattern\n")
  2452  
  2453  	expectPrinted(t, "x = ([ y = [ (z) ] ]) => 0", "x = ([y = [z]]) => 0;\n")
  2454  	expectPrinted(t, "x = ([ y = [ ...(z) ] ]) => 0", "x = ([y = [...z]]) => 0;\n")
  2455  	expectPrinted(t, "x = ({ y = { y: (z) } }) => 0", "x = ({ y = { y: z } }) => 0;\n")
  2456  	expectPrinted(t, "x = ({ y = { ...(y) } }) => 0", "x = ({ y = { ...y } }) => 0;\n")
  2457  
  2458  	expectPrinted(t, "x => function() {}", "(x) => function() {\n};\n")
  2459  	expectPrinted(t, "(x) => function() {}", "(x) => function() {\n};\n")
  2460  	expectPrinted(t, "(x => function() {})", "(x) => function() {\n};\n")
  2461  
  2462  	expectPrinted(t, "(x = () => {}) => {}", "(x = () => {\n}) => {\n};\n")
  2463  	expectPrinted(t, "async (x = () => {}) => {}", "async (x = () => {\n}) => {\n};\n")
  2464  
  2465  	expectParseError(t, "()\n=> {}", "<stdin>: ERROR: Unexpected newline before \"=>\"\n")
  2466  	expectParseError(t, "x\n=> {}", "<stdin>: ERROR: Unexpected newline before \"=>\"\n")
  2467  	expectParseError(t, "async x\n=> {}", "<stdin>: ERROR: Unexpected newline before \"=>\"\n")
  2468  	expectParseError(t, "async ()\n=> {}", "<stdin>: ERROR: Unexpected newline before \"=>\"\n")
  2469  	expectParseError(t, "(()\n=> {})", "<stdin>: ERROR: Unexpected newline before \"=>\"\n")
  2470  	expectParseError(t, "(x\n=> {})", "<stdin>: ERROR: Unexpected newline before \"=>\"\n")
  2471  	expectParseError(t, "(async x\n=> {})", "<stdin>: ERROR: Unexpected newline before \"=>\"\n")
  2472  	expectParseError(t, "(async ()\n=> {})", "<stdin>: ERROR: Unexpected newline before \"=>\"\n")
  2473  
  2474  	expectPrinted(t, "(() => {}) ? a : b", "(() => {\n}) ? a : b;\n")
  2475  	expectPrintedMangle(t, "(() => {}) ? a : b", "a;\n")
  2476  	expectParseError(t, "() => {} ? a : b", "<stdin>: ERROR: Expected \";\" but found \"?\"\n")
  2477  	expectPrinted(t, "1 < (() => {})", "1 < (() => {\n});\n")
  2478  	expectParseError(t, "1 < () => {}", "<stdin>: ERROR: Unexpected \")\"\n")
  2479  	expectParseError(t, "(...x = y) => {}", "<stdin>: ERROR: A rest argument cannot have a default initializer\n")
  2480  	expectParseError(t, "([...x = y]) => {}", "<stdin>: ERROR: A rest argument cannot have a default initializer\n")
  2481  
  2482  	// Can assign an arrow function
  2483  	expectPrinted(t, "y = x => {}", "y = (x) => {\n};\n")
  2484  	expectPrinted(t, "y = () => {}", "y = () => {\n};\n")
  2485  	expectPrinted(t, "y = (x) => {}", "y = (x) => {\n};\n")
  2486  	expectPrinted(t, "y = async x => {}", "y = async (x) => {\n};\n")
  2487  	expectPrinted(t, "y = async () => {}", "y = async () => {\n};\n")
  2488  	expectPrinted(t, "y = async (x) => {}", "y = async (x) => {\n};\n")
  2489  
  2490  	// Cannot add an arrow function
  2491  	expectPrinted(t, "1 + function () {}", "1 + function() {\n};\n")
  2492  	expectPrinted(t, "1 + async function () {}", "1 + async function() {\n};\n")
  2493  	expectParseError(t, "1 + x => {}", "<stdin>: ERROR: Expected \";\" but found \"=>\"\n")
  2494  	expectParseError(t, "1 + () => {}", "<stdin>: ERROR: Unexpected \")\"\n")
  2495  	expectParseError(t, "1 + (x) => {}", "<stdin>: ERROR: Expected \";\" but found \"=>\"\n")
  2496  	expectParseError(t, "1 + async x => {}", "<stdin>: ERROR: Expected \";\" but found \"x\"\n")
  2497  	expectParseError(t, "1 + async () => {}", "<stdin>: ERROR: Unexpected \"=>\"\n")
  2498  	expectParseError(t, "1 + async (x) => {}", "<stdin>: ERROR: Unexpected \"=>\"\n")
  2499  
  2500  	// Cannot extend an arrow function
  2501  	expectPrinted(t, "class Foo extends function () {} {}", "class Foo extends function() {\n} {\n}\n")
  2502  	expectPrinted(t, "class Foo extends async function () {} {}", "class Foo extends async function() {\n} {\n}\n")
  2503  	expectParseError(t, "class Foo extends x => {} {}", "<stdin>: ERROR: Expected \"{\" but found \"=>\"\n")
  2504  	expectParseError(t, "class Foo extends () => {} {}", "<stdin>: ERROR: Unexpected \")\"\n")
  2505  	expectParseError(t, "class Foo extends (x) => {} {}", "<stdin>: ERROR: Expected \"{\" but found \"=>\"\n")
  2506  	expectParseError(t, "class Foo extends async x => {} {}", "<stdin>: ERROR: Expected \"{\" but found \"x\"\n")
  2507  	expectParseError(t, "class Foo extends async () => {} {}", "<stdin>: ERROR: Unexpected \"=>\"\n")
  2508  	expectParseError(t, "class Foo extends async (x) => {} {}", "<stdin>: ERROR: Unexpected \"=>\"\n")
  2509  	expectParseError(t, "(class extends x => {} {})", "<stdin>: ERROR: Expected \"{\" but found \"=>\"\n")
  2510  	expectParseError(t, "(class extends () => {} {})", "<stdin>: ERROR: Unexpected \")\"\n")
  2511  	expectParseError(t, "(class extends (x) => {} {})", "<stdin>: ERROR: Expected \"{\" but found \"=>\"\n")
  2512  	expectParseError(t, "(class extends async x => {} {})", "<stdin>: ERROR: Expected \"{\" but found \"x\"\n")
  2513  	expectParseError(t, "(class extends async () => {} {})", "<stdin>: ERROR: Unexpected \"=>\"\n")
  2514  	expectParseError(t, "(class extends async (x) => {} {})", "<stdin>: ERROR: Unexpected \"=>\"\n")
  2515  
  2516  	expectParseError(t, "() => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2517  	expectParseError(t, "x => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2518  	expectParseError(t, "async () => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2519  	expectParseError(t, "async x => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2520  	expectParseError(t, "async (x) => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2521  	expectParseError(t, "0, async () => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2522  	expectParseError(t, "0, async x => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2523  	expectParseError(t, "0, async (x) => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2524  
  2525  	expectPrinted(t, "() => {}\n(0)", "() => {\n};\n0;\n")
  2526  	expectPrinted(t, "x => {}\n(0)", "(x) => {\n};\n0;\n")
  2527  	expectPrinted(t, "async () => {}\n(0)", "async () => {\n};\n0;\n")
  2528  	expectPrinted(t, "async x => {}\n(0)", "async (x) => {\n};\n0;\n")
  2529  	expectPrinted(t, "async (x) => {}\n(0)", "async (x) => {\n};\n0;\n")
  2530  
  2531  	expectPrinted(t, "() => {}\n,0", "() => {\n}, 0;\n")
  2532  	expectPrinted(t, "x => {}\n,0", "(x) => {\n}, 0;\n")
  2533  	expectPrinted(t, "async () => {}\n,0", "async () => {\n}, 0;\n")
  2534  	expectPrinted(t, "async x => {}\n,0", "async (x) => {\n}, 0;\n")
  2535  	expectPrinted(t, "async (x) => {}\n,0", "async (x) => {\n}, 0;\n")
  2536  
  2537  	expectPrinted(t, "(() => {})\n(0)", "/* @__PURE__ */ (() => {\n})(0);\n")
  2538  	expectPrinted(t, "(x => {})\n(0)", "/* @__PURE__ */ ((x) => {\n})(0);\n")
  2539  	expectPrinted(t, "(async () => {})\n(0)", "(async () => {\n})(0);\n")
  2540  	expectPrinted(t, "(async x => {})\n(0)", "(async (x) => {\n})(0);\n")
  2541  	expectPrinted(t, "(async (x) => {})\n(0)", "(async (x) => {\n})(0);\n")
  2542  
  2543  	expectParseError(t, "y = () => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2544  	expectParseError(t, "y = x => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2545  	expectParseError(t, "y = async () => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2546  	expectParseError(t, "y = async x => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2547  	expectParseError(t, "y = async (x) => {}(0)", "<stdin>: ERROR: Expected \";\" but found \"(\"\n")
  2548  
  2549  	expectPrinted(t, "y = () => {}\n(0)", "y = () => {\n};\n0;\n")
  2550  	expectPrinted(t, "y = x => {}\n(0)", "y = (x) => {\n};\n0;\n")
  2551  	expectPrinted(t, "y = async () => {}\n(0)", "y = async () => {\n};\n0;\n")
  2552  	expectPrinted(t, "y = async x => {}\n(0)", "y = async (x) => {\n};\n0;\n")
  2553  	expectPrinted(t, "y = async (x) => {}\n(0)", "y = async (x) => {\n};\n0;\n")
  2554  
  2555  	expectPrinted(t, "y = () => {}\n,0", "y = () => {\n}, 0;\n")
  2556  	expectPrinted(t, "y = x => {}\n,0", "y = (x) => {\n}, 0;\n")
  2557  	expectPrinted(t, "y = async () => {}\n,0", "y = async () => {\n}, 0;\n")
  2558  	expectPrinted(t, "y = async x => {}\n,0", "y = async (x) => {\n}, 0;\n")
  2559  	expectPrinted(t, "y = async (x) => {}\n,0", "y = async (x) => {\n}, 0;\n")
  2560  
  2561  	expectPrinted(t, "y = (() => {})\n(0)", "y = /* @__PURE__ */ (() => {\n})(0);\n")
  2562  	expectPrinted(t, "y = (x => {})\n(0)", "y = /* @__PURE__ */ ((x) => {\n})(0);\n")
  2563  	expectPrinted(t, "y = (async () => {})\n(0)", "y = (async () => {\n})(0);\n")
  2564  	expectPrinted(t, "y = (async x => {})\n(0)", "y = (async (x) => {\n})(0);\n")
  2565  	expectPrinted(t, "y = (async (x) => {})\n(0)", "y = (async (x) => {\n})(0);\n")
  2566  
  2567  	expectParseError(t, "(() => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2568  	expectParseError(t, "(x => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2569  	expectParseError(t, "(async () => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2570  	expectParseError(t, "(async x => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2571  	expectParseError(t, "(async (x) => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2572  
  2573  	expectParseError(t, "(() => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2574  	expectParseError(t, "(x => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2575  	expectParseError(t, "(async () => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2576  	expectParseError(t, "(async x => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2577  	expectParseError(t, "(async (x) => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2578  
  2579  	expectPrinted(t, "(() => {}\n,0)", "() => {\n}, 0;\n")
  2580  	expectPrinted(t, "(x => {}\n,0)", "(x) => {\n}, 0;\n")
  2581  	expectPrinted(t, "(async () => {}\n,0)", "async () => {\n}, 0;\n")
  2582  	expectPrinted(t, "(async x => {}\n,0)", "async (x) => {\n}, 0;\n")
  2583  	expectPrinted(t, "(async (x) => {}\n,0)", "async (x) => {\n}, 0;\n")
  2584  
  2585  	expectPrinted(t, "((() => {})\n(0))", "/* @__PURE__ */ (() => {\n})(0);\n")
  2586  	expectPrinted(t, "((x => {})\n(0))", "/* @__PURE__ */ ((x) => {\n})(0);\n")
  2587  	expectPrinted(t, "((async () => {})\n(0))", "(async () => {\n})(0);\n")
  2588  	expectPrinted(t, "((async x => {})\n(0))", "(async (x) => {\n})(0);\n")
  2589  	expectPrinted(t, "((async (x) => {})\n(0))", "(async (x) => {\n})(0);\n")
  2590  
  2591  	expectParseError(t, "y = (() => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2592  	expectParseError(t, "y = (x => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2593  	expectParseError(t, "y = (async () => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2594  	expectParseError(t, "y = (async x => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2595  	expectParseError(t, "y = (async (x) => {}(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2596  
  2597  	expectParseError(t, "y = (() => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2598  	expectParseError(t, "y = (x => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2599  	expectParseError(t, "y = (async () => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2600  	expectParseError(t, "y = (async x => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2601  	expectParseError(t, "y = (async (x) => {}\n(0))", "<stdin>: ERROR: Expected \")\" but found \"(\"\n")
  2602  
  2603  	expectPrinted(t, "y = (() => {}\n,0)", "y = (() => {\n}, 0);\n")
  2604  	expectPrinted(t, "y = (x => {}\n,0)", "y = ((x) => {\n}, 0);\n")
  2605  	expectPrinted(t, "y = (async () => {}\n,0)", "y = (async () => {\n}, 0);\n")
  2606  	expectPrinted(t, "y = (async x => {}\n,0)", "y = (async (x) => {\n}, 0);\n")
  2607  	expectPrinted(t, "y = (async (x) => {}\n,0)", "y = (async (x) => {\n}, 0);\n")
  2608  
  2609  	expectPrinted(t, "y = ((() => {})\n(0))", "y = /* @__PURE__ */ (() => {\n})(0);\n")
  2610  	expectPrinted(t, "y = ((x => {})\n(0))", "y = /* @__PURE__ */ ((x) => {\n})(0);\n")
  2611  	expectPrinted(t, "y = ((async () => {})\n(0))", "y = (async () => {\n})(0);\n")
  2612  	expectPrinted(t, "y = ((async x => {})\n(0))", "y = (async (x) => {\n})(0);\n")
  2613  	expectPrinted(t, "y = ((async (x) => {})\n(0))", "y = (async (x) => {\n})(0);\n")
  2614  }
  2615  
  2616  func TestTemplate(t *testing.T) {
  2617  	expectPrinted(t, "`\\0`", "`\\0`;\n")
  2618  	expectPrinted(t, "`${'\\00'}`", "`${\"\\0\"}`;\n")
  2619  
  2620  	expectParseError(t, "`\\7`", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\n")
  2621  	expectParseError(t, "`\\8`", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\n")
  2622  	expectParseError(t, "`\\9`", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\n")
  2623  	expectParseError(t, "`\\00`", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\n")
  2624  	expectParseError(t, "`\\00${x}`", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\n")
  2625  	expectParseError(t, "`${x}\\00`", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\n")
  2626  	expectParseError(t, "`${x}\\00${y}`", "<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\n")
  2627  	expectParseError(t, "`\\unicode`", "<stdin>: ERROR: Syntax error \"n\"\n")
  2628  	expectParseError(t, "`\\unicode${x}`", "<stdin>: ERROR: Syntax error \"n\"\n")
  2629  	expectParseError(t, "`${x}\\unicode`", "<stdin>: ERROR: Syntax error \"n\"\n")
  2630  	expectParseError(t, "`\\u{10FFFFF}`", "<stdin>: ERROR: Unicode escape sequence is out of range\n")
  2631  
  2632  	expectPrinted(t, "tag`\\7`", "tag`\\7`;\n")
  2633  	expectPrinted(t, "tag`\\8`", "tag`\\8`;\n")
  2634  	expectPrinted(t, "tag`\\9`", "tag`\\9`;\n")
  2635  	expectPrinted(t, "tag`\\00`", "tag`\\00`;\n")
  2636  	expectPrinted(t, "tag`\\00${x}`", "tag`\\00${x}`;\n")
  2637  	expectPrinted(t, "tag`${x}\\00`", "tag`${x}\\00`;\n")
  2638  	expectPrinted(t, "tag`${x}\\00${y}`", "tag`${x}\\00${y}`;\n")
  2639  	expectPrinted(t, "tag`\\unicode`", "tag`\\unicode`;\n")
  2640  	expectPrinted(t, "tag`\\unicode${x}`", "tag`\\unicode${x}`;\n")
  2641  	expectPrinted(t, "tag`${x}\\unicode`", "tag`${x}\\unicode`;\n")
  2642  	expectPrinted(t, "tag`\\u{10FFFFF}`", "tag`\\u{10FFFFF}`;\n")
  2643  
  2644  	expectPrinted(t, "tag``", "tag``;\n")
  2645  	expectPrinted(t, "(a?.b)``", "(a?.b)``;\n")
  2646  	expectPrinted(t, "(a?.(b))``", "(a?.(b))``;\n")
  2647  	expectPrinted(t, "(a?.[b])``", "(a?.[b])``;\n")
  2648  	expectPrinted(t, "(a?.b.c)``", "(a?.b.c)``;\n")
  2649  	expectPrinted(t, "(a?.(b).c)``", "(a?.(b).c)``;\n")
  2650  	expectPrinted(t, "(a?.[b].c)``", "(a?.[b].c)``;\n")
  2651  
  2652  	expectParseError(t, "a?.b``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2653  	expectParseError(t, "a?.(b)``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2654  	expectParseError(t, "a?.[b]``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2655  	expectParseError(t, "a?.b.c``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2656  	expectParseError(t, "a?.(b).c``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2657  	expectParseError(t, "a?.[b].c``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2658  
  2659  	expectParseError(t, "a?.b`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2660  	expectParseError(t, "a?.(b)`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2661  	expectParseError(t, "a?.[b]`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2662  	expectParseError(t, "a?.b.c`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2663  	expectParseError(t, "a?.(b).c`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2664  	expectParseError(t, "a?.[b].c`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2665  
  2666  	expectParseError(t, "a?.b\n``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2667  	expectParseError(t, "a?.(b)\n``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2668  	expectParseError(t, "a?.[b]\n``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2669  	expectParseError(t, "a?.b.c\n``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2670  	expectParseError(t, "a?.(b).c\n``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2671  	expectParseError(t, "a?.[b].c\n``", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2672  
  2673  	expectParseError(t, "a?.b\n`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2674  	expectParseError(t, "a?.(b)\n`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2675  	expectParseError(t, "a?.[b]\n`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2676  	expectParseError(t, "a?.b.c\n`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2677  	expectParseError(t, "a?.(b).c\n`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2678  	expectParseError(t, "a?.[b].c\n`${d}`", "<stdin>: ERROR: Template literals cannot have an optional chain as a tag\n")
  2679  
  2680  	expectPrinted(t, "`a${1 + `b${2}c` + 3}d`", "`a${`1b${2}c3`}d`;\n")
  2681  	expectPrintedMangle(t, "x = `a${1 + `b${2}c` + 3}d`", "x = `a1b2c3d`;\n")
  2682  
  2683  	expectPrinted(t, "`a\nb`", "`a\nb`;\n")
  2684  	expectPrinted(t, "`a\rb`", "`a\nb`;\n")
  2685  	expectPrinted(t, "`a\r\nb`", "`a\nb`;\n")
  2686  	expectPrinted(t, "`a\\nb`", "`a\nb`;\n")
  2687  	expectPrinted(t, "`a\\rb`", "`a\\rb`;\n")
  2688  	expectPrinted(t, "`a\\r\\nb`", "`a\\r\nb`;\n")
  2689  	expectPrinted(t, "`a\u2028b`", "`a\\u2028b`;\n")
  2690  	expectPrinted(t, "`a\u2029b`", "`a\\u2029b`;\n")
  2691  
  2692  	expectPrinted(t, "`a\n${b}`", "`a\n${b}`;\n")
  2693  	expectPrinted(t, "`a\r${b}`", "`a\n${b}`;\n")
  2694  	expectPrinted(t, "`a\r\n${b}`", "`a\n${b}`;\n")
  2695  	expectPrinted(t, "`a\\n${b}`", "`a\n${b}`;\n")
  2696  	expectPrinted(t, "`a\\r${b}`", "`a\\r${b}`;\n")
  2697  	expectPrinted(t, "`a\\r\\n${b}`", "`a\\r\n${b}`;\n")
  2698  	expectPrinted(t, "`a\u2028${b}`", "`a\\u2028${b}`;\n")
  2699  	expectPrinted(t, "`a\u2029${b}`", "`a\\u2029${b}`;\n")
  2700  
  2701  	expectPrinted(t, "`${a}\nb`", "`${a}\nb`;\n")
  2702  	expectPrinted(t, "`${a}\rb`", "`${a}\nb`;\n")
  2703  	expectPrinted(t, "`${a}\r\nb`", "`${a}\nb`;\n")
  2704  	expectPrinted(t, "`${a}\\nb`", "`${a}\nb`;\n")
  2705  	expectPrinted(t, "`${a}\\rb`", "`${a}\\rb`;\n")
  2706  	expectPrinted(t, "`${a}\\r\\nb`", "`${a}\\r\nb`;\n")
  2707  	expectPrinted(t, "`${a}\u2028b`", "`${a}\\u2028b`;\n")
  2708  	expectPrinted(t, "`${a}\u2029b`", "`${a}\\u2029b`;\n")
  2709  
  2710  	expectPrinted(t, "tag`a\nb`", "tag`a\nb`;\n")
  2711  	expectPrinted(t, "tag`a\rb`", "tag`a\nb`;\n")
  2712  	expectPrinted(t, "tag`a\r\nb`", "tag`a\nb`;\n")
  2713  	expectPrinted(t, "tag`a\\nb`", "tag`a\\nb`;\n")
  2714  	expectPrinted(t, "tag`a\\rb`", "tag`a\\rb`;\n")
  2715  	expectPrinted(t, "tag`a\\r\\nb`", "tag`a\\r\\nb`;\n")
  2716  	expectPrinted(t, "tag`a\u2028b`", "tag`a\u2028b`;\n")
  2717  	expectPrinted(t, "tag`a\u2029b`", "tag`a\u2029b`;\n")
  2718  
  2719  	expectPrinted(t, "tag`a\n${b}`", "tag`a\n${b}`;\n")
  2720  	expectPrinted(t, "tag`a\r${b}`", "tag`a\n${b}`;\n")
  2721  	expectPrinted(t, "tag`a\r\n${b}`", "tag`a\n${b}`;\n")
  2722  	expectPrinted(t, "tag`a\\n${b}`", "tag`a\\n${b}`;\n")
  2723  	expectPrinted(t, "tag`a\\r${b}`", "tag`a\\r${b}`;\n")
  2724  	expectPrinted(t, "tag`a\\r\\n${b}`", "tag`a\\r\\n${b}`;\n")
  2725  	expectPrinted(t, "tag`a\u2028${b}`", "tag`a\u2028${b}`;\n")
  2726  	expectPrinted(t, "tag`a\u2029${b}`", "tag`a\u2029${b}`;\n")
  2727  
  2728  	expectPrinted(t, "tag`${a}\nb`", "tag`${a}\nb`;\n")
  2729  	expectPrinted(t, "tag`${a}\rb`", "tag`${a}\nb`;\n")
  2730  	expectPrinted(t, "tag`${a}\r\nb`", "tag`${a}\nb`;\n")
  2731  	expectPrinted(t, "tag`${a}\\nb`", "tag`${a}\\nb`;\n")
  2732  	expectPrinted(t, "tag`${a}\\rb`", "tag`${a}\\rb`;\n")
  2733  	expectPrinted(t, "tag`${a}\\r\\nb`", "tag`${a}\\r\\nb`;\n")
  2734  	expectPrinted(t, "tag`${a}\u2028b`", "tag`${a}\u2028b`;\n")
  2735  	expectPrinted(t, "tag`${a}\u2029b`", "tag`${a}\u2029b`;\n")
  2736  }
  2737  
  2738  func TestSwitch(t *testing.T) {
  2739  	expectPrinted(t, "switch (x) { default: }", "switch (x) {\n  default:\n}\n")
  2740  	expectPrinted(t, "switch ((x => x + 1)(0)) { case 1: var y } y = 2", "switch (((x) => x + 1)(0)) {\n  case 1:\n    var y;\n}\ny = 2;\n")
  2741  	expectParseError(t, "switch (x) { default: default: }", "<stdin>: ERROR: Multiple default clauses are not allowed\n")
  2742  }
  2743  
  2744  func TestConstantFolding(t *testing.T) {
  2745  	expectPrinted(t, "x = !false", "x = true;\n")
  2746  	expectPrinted(t, "x = !true", "x = false;\n")
  2747  
  2748  	expectPrinted(t, "x = !!0", "x = false;\n")
  2749  	expectPrinted(t, "x = !!-0", "x = false;\n")
  2750  	expectPrinted(t, "x = !!1", "x = true;\n")
  2751  	expectPrinted(t, "x = !!NaN", "x = false;\n")
  2752  	expectPrinted(t, "x = !!Infinity", "x = true;\n")
  2753  	expectPrinted(t, "x = !!-Infinity", "x = true;\n")
  2754  	expectPrinted(t, "x = !!\"\"", "x = false;\n")
  2755  	expectPrinted(t, "x = !!\"x\"", "x = true;\n")
  2756  	expectPrinted(t, "x = !!function() {}", "x = true;\n")
  2757  	expectPrinted(t, "x = !!(() => {})", "x = true;\n")
  2758  	expectPrinted(t, "x = !!0n", "x = false;\n")
  2759  	expectPrinted(t, "x = !!1n", "x = true;\n")
  2760  	expectPrinted(t, "x = !!0b0n", "x = !!0b0n;\n")
  2761  	expectPrinted(t, "x = !!0b1n", "x = !!0b1n;\n")
  2762  	expectPrinted(t, "x = !!0o0n", "x = !!0o0n;\n")
  2763  	expectPrinted(t, "x = !!0o1n", "x = !!0o1n;\n")
  2764  	expectPrinted(t, "x = !!0x0n", "x = !!0x0n;\n")
  2765  	expectPrinted(t, "x = !!0x1n", "x = !!0x1n;\n")
  2766  
  2767  	expectPrinted(t, "x = 1 ? a : b", "x = 1 ? a : b;\n")
  2768  	expectPrinted(t, "x = 0 ? a : b", "x = 0 ? a : b;\n")
  2769  	expectPrintedMangle(t, "x = 1 ? a : b", "x = a;\n")
  2770  	expectPrintedMangle(t, "x = 0 ? a : b", "x = b;\n")
  2771  
  2772  	expectPrinted(t, "x = 1 && 2", "x = 2;\n")
  2773  	expectPrinted(t, "x = 1 || 2", "x = 1;\n")
  2774  	expectPrinted(t, "x = 0 && 1", "x = 0;\n")
  2775  	expectPrinted(t, "x = 0 || 1", "x = 1;\n")
  2776  
  2777  	expectPrinted(t, "x = null ?? 1", "x = 1;\n")
  2778  	expectPrinted(t, "x = undefined ?? 1", "x = 1;\n")
  2779  	expectPrinted(t, "x = 0 ?? 1", "x = 0;\n")
  2780  	expectPrinted(t, "x = false ?? 1", "x = false;\n")
  2781  	expectPrinted(t, "x = \"\" ?? 1", "x = \"\";\n")
  2782  
  2783  	expectPrinted(t, "x = typeof undefined", "x = \"undefined\";\n")
  2784  	expectPrinted(t, "x = typeof null", "x = \"object\";\n")
  2785  	expectPrinted(t, "x = typeof false", "x = \"boolean\";\n")
  2786  	expectPrinted(t, "x = typeof true", "x = \"boolean\";\n")
  2787  	expectPrinted(t, "x = typeof 123", "x = \"number\";\n")
  2788  	expectPrinted(t, "x = typeof 123n", "x = \"bigint\";\n")
  2789  	expectPrinted(t, "x = typeof 'abc'", "x = \"string\";\n")
  2790  	expectPrinted(t, "x = typeof function() {}", "x = \"function\";\n")
  2791  	expectPrinted(t, "x = typeof (() => {})", "x = \"function\";\n")
  2792  	expectPrinted(t, "x = typeof {}", "x = typeof {};\n")
  2793  	expectPrinted(t, "x = typeof []", "x = typeof [];\n")
  2794  
  2795  	expectPrinted(t, "x = undefined === undefined", "x = true;\n")
  2796  	expectPrinted(t, "x = undefined !== undefined", "x = false;\n")
  2797  	expectPrinted(t, "x = undefined == undefined", "x = true;\n")
  2798  	expectPrinted(t, "x = undefined != undefined", "x = false;\n")
  2799  
  2800  	expectPrinted(t, "x = null === null", "x = true;\n")
  2801  	expectPrinted(t, "x = null !== null", "x = false;\n")
  2802  	expectPrinted(t, "x = null == null", "x = true;\n")
  2803  	expectPrinted(t, "x = null != null", "x = false;\n")
  2804  
  2805  	expectPrinted(t, "x = null === undefined", "x = false;\n")
  2806  	expectPrinted(t, "x = null !== undefined", "x = true;\n")
  2807  	expectPrinted(t, "x = null == undefined", "x = true;\n")
  2808  	expectPrinted(t, "x = null != undefined", "x = false;\n")
  2809  
  2810  	expectPrinted(t, "x = undefined === null", "x = false;\n")
  2811  	expectPrinted(t, "x = undefined !== null", "x = true;\n")
  2812  	expectPrinted(t, "x = undefined == null", "x = true;\n")
  2813  	expectPrinted(t, "x = undefined != null", "x = false;\n")
  2814  
  2815  	expectPrinted(t, "x = true === true", "x = true;\n")
  2816  	expectPrinted(t, "x = true === false", "x = false;\n")
  2817  	expectPrinted(t, "x = true !== true", "x = false;\n")
  2818  	expectPrinted(t, "x = true !== false", "x = true;\n")
  2819  	expectPrinted(t, "x = true == true", "x = true;\n")
  2820  	expectPrinted(t, "x = true == false", "x = false;\n")
  2821  	expectPrinted(t, "x = true != true", "x = false;\n")
  2822  	expectPrinted(t, "x = true != false", "x = true;\n")
  2823  
  2824  	expectPrinted(t, "x = 1 === 1", "x = true;\n")
  2825  	expectPrinted(t, "x = 1 === 2", "x = false;\n")
  2826  	expectPrinted(t, "x = 1 === '1'", "x = 1 === \"1\";\n")
  2827  	expectPrinted(t, "x = 1 == 1", "x = true;\n")
  2828  	expectPrinted(t, "x = 1 == 2", "x = false;\n")
  2829  	expectPrinted(t, "x = 1 == '1'", "x = 1 == \"1\";\n")
  2830  
  2831  	expectPrinted(t, "x = 1 !== 1", "x = false;\n")
  2832  	expectPrinted(t, "x = 1 !== 2", "x = true;\n")
  2833  	expectPrinted(t, "x = 1 !== '1'", "x = 1 !== \"1\";\n")
  2834  	expectPrinted(t, "x = 1 != 1", "x = false;\n")
  2835  	expectPrinted(t, "x = 1 != 2", "x = true;\n")
  2836  	expectPrinted(t, "x = 1 != '1'", "x = 1 != \"1\";\n")
  2837  
  2838  	expectPrinted(t, "x = 'a' === '\\x61'", "x = true;\n")
  2839  	expectPrinted(t, "x = 'a' === '\\x62'", "x = false;\n")
  2840  	expectPrinted(t, "x = 'a' === 'abc'", "x = false;\n")
  2841  	expectPrinted(t, "x = 'a' !== '\\x61'", "x = false;\n")
  2842  	expectPrinted(t, "x = 'a' !== '\\x62'", "x = true;\n")
  2843  	expectPrinted(t, "x = 'a' !== 'abc'", "x = true;\n")
  2844  	expectPrinted(t, "x = 'a' == '\\x61'", "x = true;\n")
  2845  	expectPrinted(t, "x = 'a' == '\\x62'", "x = false;\n")
  2846  	expectPrinted(t, "x = 'a' == 'abc'", "x = false;\n")
  2847  	expectPrinted(t, "x = 'a' != '\\x61'", "x = false;\n")
  2848  	expectPrinted(t, "x = 'a' != '\\x62'", "x = true;\n")
  2849  	expectPrinted(t, "x = 'a' != 'abc'", "x = true;\n")
  2850  
  2851  	expectPrinted(t, "x = 'a' + 'b'", "x = \"ab\";\n")
  2852  	expectPrinted(t, "x = 'a' + 'bc'", "x = \"abc\";\n")
  2853  	expectPrinted(t, "x = 'ab' + 'c'", "x = \"abc\";\n")
  2854  	expectPrinted(t, "x = x + 'a' + 'b'", "x = x + \"ab\";\n")
  2855  	expectPrinted(t, "x = x + 'a' + 'bc'", "x = x + \"abc\";\n")
  2856  	expectPrinted(t, "x = x + 'ab' + 'c'", "x = x + \"abc\";\n")
  2857  	expectPrinted(t, "x = 'a' + 1", "x = \"a1\";\n")
  2858  	expectPrinted(t, "x = x * 'a' + 'b'", "x = x * \"a\" + \"b\";\n")
  2859  
  2860  	expectPrinted(t, "x = 'string' + `template`", "x = `stringtemplate`;\n")
  2861  	expectPrinted(t, "x = 'string' + `a${foo}b`", "x = `stringa${foo}b`;\n")
  2862  	expectPrinted(t, "x = 'string' + tag`template`", "x = \"string\" + tag`template`;\n")
  2863  	expectPrinted(t, "x = `template` + 'string'", "x = `templatestring`;\n")
  2864  	expectPrinted(t, "x = `a${foo}b` + 'string'", "x = `a${foo}bstring`;\n")
  2865  	expectPrinted(t, "x = tag`template` + 'string'", "x = tag`template` + \"string\";\n")
  2866  	expectPrinted(t, "x = `template` + `a${foo}b`", "x = `templatea${foo}b`;\n")
  2867  	expectPrinted(t, "x = `a${foo}b` + `template`", "x = `a${foo}btemplate`;\n")
  2868  	expectPrinted(t, "x = `a${foo}b` + `x${bar}y`", "x = `a${foo}bx${bar}y`;\n")
  2869  	expectPrinted(t, "x = `a${i}${j}bb` + `xxx${bar}yyyy`", "x = `a${i}${j}bbxxx${bar}yyyy`;\n")
  2870  	expectPrinted(t, "x = `a${foo}bb` + `xxx${i}${j}yyyy`", "x = `a${foo}bbxxx${i}${j}yyyy`;\n")
  2871  	expectPrinted(t, "x = `template` + tag`template2`", "x = `template` + tag`template2`;\n")
  2872  	expectPrinted(t, "x = tag`template` + `template2`", "x = tag`template` + `template2`;\n")
  2873  
  2874  	expectPrinted(t, "x = 123", "x = 123;\n")
  2875  	expectPrinted(t, "x = 123 .toString()", "x = 123 .toString();\n")
  2876  	expectPrinted(t, "x = -123", "x = -123;\n")
  2877  	expectPrinted(t, "x = (-123).toString()", "x = (-123).toString();\n")
  2878  	expectPrinted(t, "x = -0", "x = -0;\n")
  2879  	expectPrinted(t, "x = (-0).toString()", "x = (-0).toString();\n")
  2880  	expectPrinted(t, "x = -0 === 0", "x = true;\n")
  2881  
  2882  	expectPrinted(t, "x = NaN", "x = NaN;\n")
  2883  	expectPrinted(t, "x = NaN.toString()", "x = NaN.toString();\n")
  2884  	expectPrinted(t, "x = NaN === NaN", "x = false;\n")
  2885  
  2886  	expectPrinted(t, "x = Infinity", "x = Infinity;\n")
  2887  	expectPrinted(t, "x = Infinity.toString()", "x = Infinity.toString();\n")
  2888  	expectPrinted(t, "x = (-Infinity).toString()", "x = (-Infinity).toString();\n")
  2889  	expectPrinted(t, "x = Infinity === Infinity", "x = true;\n")
  2890  	expectPrinted(t, "x = Infinity === -Infinity", "x = false;\n")
  2891  
  2892  	expectPrinted(t, "x = 0n === 0n", "x = true;\n")
  2893  	expectPrinted(t, "x = 1n === 1n", "x = true;\n")
  2894  	expectPrinted(t, "x = 0n === 1n", "x = false;\n")
  2895  	expectPrinted(t, "x = 0n !== 1n", "x = true;\n")
  2896  	expectPrinted(t, "x = 0n !== 0n", "x = false;\n")
  2897  	expectPrinted(t, "x = 123n === 1_2_3n", "x = true;\n")
  2898  
  2899  	expectPrinted(t, "x = 0n === 0b0n", "x = 0n === 0b0n;\n")
  2900  	expectPrinted(t, "x = 0n === 0o0n", "x = 0n === 0o0n;\n")
  2901  	expectPrinted(t, "x = 0n === 0x0n", "x = 0n === 0x0n;\n")
  2902  	expectPrinted(t, "x = 0b0n === 0b0n", "x = true;\n")
  2903  	expectPrinted(t, "x = 0o0n === 0o0n", "x = true;\n")
  2904  	expectPrinted(t, "x = 0x0n === 0x0n", "x = true;\n")
  2905  
  2906  	// We support folding strings from sibling AST nodes since that ends up being
  2907  	// equivalent with string addition. For example, "(x + 'a') + 'b'" is the
  2908  	// same as "x + 'ab'". However, this is not true for numbers. We can't turn
  2909  	// "(x + 1) + '2'" into "x + '12'". These tests check for this edge case.
  2910  	expectPrinted(t, "x = 'a' + 'b' + y", "x = \"ab\" + y;\n")
  2911  	expectPrinted(t, "x = y + 'a' + 'b'", "x = y + \"ab\";\n")
  2912  	expectPrinted(t, "x = '3' + 4 + y", "x = \"34\" + y;\n")
  2913  	expectPrinted(t, "x = y + 4 + '5'", "x = y + 4 + \"5\";\n")
  2914  	expectPrinted(t, "x = '3' + 4 + 5", "x = \"345\";\n")
  2915  	expectPrinted(t, "x = 3 + 4 + '5'", "x = 3 + 4 + \"5\";\n")
  2916  
  2917  	expectPrinted(t, "x = null == 0", "x = false;\n")
  2918  	expectPrinted(t, "x = 0 == null", "x = false;\n")
  2919  	expectPrinted(t, "x = undefined == 0", "x = false;\n")
  2920  	expectPrinted(t, "x = 0 == undefined", "x = false;\n")
  2921  
  2922  	expectPrinted(t, "x = null == NaN", "x = false;\n")
  2923  	expectPrinted(t, "x = NaN == null", "x = false;\n")
  2924  	expectPrinted(t, "x = undefined == NaN", "x = false;\n")
  2925  	expectPrinted(t, "x = NaN == undefined", "x = false;\n")
  2926  
  2927  	expectPrinted(t, "x = null == ''", "x = false;\n")
  2928  	expectPrinted(t, "x = '' == null", "x = false;\n")
  2929  	expectPrinted(t, "x = undefined == ''", "x = false;\n")
  2930  	expectPrinted(t, "x = '' == undefined", "x = false;\n")
  2931  
  2932  	expectPrinted(t, "x = null == 'null'", "x = false;\n")
  2933  	expectPrinted(t, "x = 'null' == null", "x = false;\n")
  2934  	expectPrinted(t, "x = undefined == 'undefined'", "x = false;\n")
  2935  	expectPrinted(t, "x = 'undefined' == undefined", "x = false;\n")
  2936  
  2937  	expectPrinted(t, "x = false === 0", "x = false;\n")
  2938  	expectPrinted(t, "x = true === 1", "x = false;\n")
  2939  	expectPrinted(t, "x = false == 0", "x = true;\n")
  2940  	expectPrinted(t, "x = false == -0", "x = true;\n")
  2941  	expectPrinted(t, "x = true == 1", "x = true;\n")
  2942  	expectPrinted(t, "x = true == 2", "x = false;\n")
  2943  
  2944  	expectPrinted(t, "x = 0 === false", "x = false;\n")
  2945  	expectPrinted(t, "x = 1 === true", "x = false;\n")
  2946  	expectPrinted(t, "x = 0 == false", "x = true;\n")
  2947  	expectPrinted(t, "x = -0 == false", "x = true;\n")
  2948  	expectPrinted(t, "x = 1 == true", "x = true;\n")
  2949  	expectPrinted(t, "x = 2 == true", "x = false;\n")
  2950  }
  2951  
  2952  func TestConstantFoldingScopes(t *testing.T) {
  2953  	// Parsing will crash if somehow the scope traversal is misaligned between
  2954  	// the parsing and binding passes. This checks for those cases.
  2955  	expectPrintedMangle(t, "x; 1 ? 0 : ()=>{}; (()=>{})()", "x;\n")
  2956  	expectPrintedMangle(t, "x; 0 ? ()=>{} : 1; (()=>{})()", "x;\n")
  2957  	expectPrinted(t, "x; 0 && (()=>{}); (()=>{})()", "x;\n/* @__PURE__ */ (() => {\n})();\n")
  2958  	expectPrinted(t, "x; 1 || (()=>{}); (()=>{})()", "x;\n/* @__PURE__ */ (() => {\n})();\n")
  2959  	expectPrintedMangle(t, "if (1) 0; else ()=>{}; (()=>{})()", "")
  2960  	expectPrintedMangle(t, "if (0) ()=>{}; else 1; (()=>{})()", "")
  2961  }
  2962  
  2963  func TestImport(t *testing.T) {
  2964  	expectPrinted(t, "import \"foo\"", "import \"foo\";\n")
  2965  	expectPrinted(t, "import {} from \"foo\"", "import {} from \"foo\";\n")
  2966  	expectPrinted(t, "import {x} from \"foo\";x", "import { x } from \"foo\";\nx;\n")
  2967  	expectPrinted(t, "import {x as y} from \"foo\";y", "import { x as y } from \"foo\";\ny;\n")
  2968  	expectPrinted(t, "import {x as y, z} from \"foo\";y;z", "import { x as y, z } from \"foo\";\ny;\nz;\n")
  2969  	expectPrinted(t, "import {x as y, z,} from \"foo\";y;z", "import { x as y, z } from \"foo\";\ny;\nz;\n")
  2970  	expectPrinted(t, "import z, {x as y} from \"foo\";y;z", "import z, { x as y } from \"foo\";\ny;\nz;\n")
  2971  	expectPrinted(t, "import z from \"foo\";z", "import z from \"foo\";\nz;\n")
  2972  	expectPrinted(t, "import * as ns from \"foo\";ns;ns.x", "import * as ns from \"foo\";\nns;\nns.x;\n")
  2973  	expectPrinted(t, "import z, * as ns from \"foo\";z;ns;ns.x", "import z, * as ns from \"foo\";\nz;\nns;\nns.x;\n")
  2974  
  2975  	expectParseError(t, "import * from \"foo\"", "<stdin>: ERROR: Expected \"as\" but found \"from\"\n")
  2976  
  2977  	expectPrinted(t, "import('foo')", "import(\"foo\");\n")
  2978  	expectPrinted(t, "(import('foo'))", "import(\"foo\");\n")
  2979  	expectPrinted(t, "{import('foo')}", "{\n  import(\"foo\");\n}\n")
  2980  	expectPrinted(t, "import('foo').then(() => {})", "import(\"foo\").then(() => {\n});\n")
  2981  	expectPrinted(t, "new import.meta", "new import.meta();\n")
  2982  	expectPrinted(t, "new (import('foo'))", "new (import(\"foo\"))();\n")
  2983  	expectParseError(t, "import()", "<stdin>: ERROR: Unexpected \")\"\n")
  2984  	expectParseError(t, "import(...a)", "<stdin>: ERROR: Unexpected \"...\"\n")
  2985  	expectParseError(t, "new import('foo')", "<stdin>: ERROR: Cannot use an \"import\" expression here without parentheses:\n")
  2986  
  2987  	expectPrinted(t, "import.meta", "import.meta;\n")
  2988  	expectPrinted(t, "(import.meta)", "import.meta;\n")
  2989  	expectPrinted(t, "{import.meta}", "{\n  import.meta;\n}\n")
  2990  
  2991  	expectPrinted(t, "import x from \"foo\"; x = 1", "import x from \"foo\";\nx = 1;\n")
  2992  	expectPrinted(t, "import x from \"foo\"; x++", "import x from \"foo\";\nx++;\n")
  2993  	expectPrinted(t, "import x from \"foo\"; ([x] = 1)", "import x from \"foo\";\n[x] = 1;\n")
  2994  	expectPrinted(t, "import x from \"foo\"; ({x} = 1)", "import x from \"foo\";\n({ x } = 1);\n")
  2995  	expectPrinted(t, "import x from \"foo\"; ({y: x} = 1)", "import x from \"foo\";\n({ y: x } = 1);\n")
  2996  	expectPrinted(t, "import {x} from \"foo\"; x++", "import { x } from \"foo\";\nx++;\n")
  2997  	expectPrinted(t, "import * as x from \"foo\"; x++", "import * as x from \"foo\";\nx++;\n")
  2998  	expectPrinted(t, "import * as x from \"foo\"; x.y = 1", "import * as x from \"foo\";\nx.y = 1;\n")
  2999  	expectPrinted(t, "import * as x from \"foo\"; x[y] = 1", "import * as x from \"foo\";\nx[y] = 1;\n")
  3000  	expectPrinted(t, "import * as x from \"foo\"; x['y'] = 1", "import * as x from \"foo\";\nx[\"y\"] = 1;\n")
  3001  	expectPrinted(t, "import * as x from \"foo\"; x['y z'] = 1", "import * as x from \"foo\";\nx[\"y z\"] = 1;\n")
  3002  	expectPrinted(t, "import x from \"foo\"; ({y = x} = 1)", "import x from \"foo\";\n({ y = x } = 1);\n")
  3003  	expectPrinted(t, "import x from \"foo\"; ({[x]: y} = 1)", "import x from \"foo\";\n({ [x]: y } = 1);\n")
  3004  	expectPrinted(t, "import x from \"foo\"; x.y = 1", "import x from \"foo\";\nx.y = 1;\n")
  3005  	expectPrinted(t, "import x from \"foo\"; x[y] = 1", "import x from \"foo\";\nx[y] = 1;\n")
  3006  	expectPrinted(t, "import x from \"foo\"; x['y'] = 1", "import x from \"foo\";\nx[\"y\"] = 1;\n")
  3007  
  3008  	// "eval" and "arguments" are forbidden import names
  3009  	expectParseError(t, "import {eval} from 'foo'", "<stdin>: ERROR: Cannot use \"eval\" as an identifier here:\n")
  3010  	expectParseError(t, "import {ev\\u0061l} from 'foo'", "<stdin>: ERROR: Cannot use \"eval\" as an identifier here:\n")
  3011  	expectParseError(t, "import {x as eval} from 'foo'", "<stdin>: ERROR: Cannot use \"eval\" as an identifier here:\n")
  3012  	expectParseError(t, "import {x as ev\\u0061l} from 'foo'", "<stdin>: ERROR: Cannot use \"eval\" as an identifier here:\n")
  3013  	expectPrinted(t, "import {eval as x} from 'foo'", "import { eval as x } from \"foo\";\n")
  3014  	expectPrinted(t, "import {ev\\u0061l as x} from 'foo'", "import { eval as x } from \"foo\";\n")
  3015  	expectParseError(t, "import {arguments} from 'foo'", "<stdin>: ERROR: Cannot use \"arguments\" as an identifier here:\n")
  3016  	expectParseError(t, "import {\\u0061rguments} from 'foo'", "<stdin>: ERROR: Cannot use \"arguments\" as an identifier here:\n")
  3017  	expectParseError(t, "import {x as arguments} from 'foo'", "<stdin>: ERROR: Cannot use \"arguments\" as an identifier here:\n")
  3018  	expectParseError(t, "import {x as \\u0061rguments} from 'foo'", "<stdin>: ERROR: Cannot use \"arguments\" as an identifier here:\n")
  3019  	expectPrinted(t, "import {arguments as x} from 'foo'", "import { arguments as x } from \"foo\";\n")
  3020  	expectPrinted(t, "import {\\u0061rguments as x} from 'foo'", "import { arguments as x } from \"foo\";\n")
  3021  
  3022  	// String import alias with "import {} from"
  3023  	expectPrinted(t, "import {'' as x} from 'foo'", "import { \"\" as x } from \"foo\";\n")
  3024  	expectPrinted(t, "import {'šŸ•' as x} from 'foo'", "import { \"šŸ•\" as x } from \"foo\";\n")
  3025  	expectPrinted(t, "import {'a b' as x} from 'foo'", "import { \"a b\" as x } from \"foo\";\n")
  3026  	expectPrinted(t, "import {'\\uD800\\uDC00' as x} from 'foo'", "import { 𐀀 as x } from \"foo\";\n")
  3027  	expectParseError(t, "import {'x'} from 'foo'", "<stdin>: ERROR: Expected \"as\" but found \"}\"\n")
  3028  	expectParseError(t, "import {'\\uD800' as x} from 'foo'",
  3029  		"<stdin>: ERROR: This import alias is invalid because it contains the unpaired Unicode surrogate U+D800\n")
  3030  	expectParseError(t, "import {'\\uDC00' as x} from 'foo'",
  3031  		"<stdin>: ERROR: This import alias is invalid because it contains the unpaired Unicode surrogate U+DC00\n")
  3032  
  3033  	// String import alias with "import * as"
  3034  	expectParseError(t, "import * as '' from 'foo'", "<stdin>: ERROR: Expected identifier but found \"''\"\n")
  3035  }
  3036  
  3037  func TestExport(t *testing.T) {
  3038  	expectPrinted(t, "export default x", "export default x;\n")
  3039  	expectPrinted(t, "export class x {}", "export class x {\n}\n")
  3040  	expectPrinted(t, "export function x() {}", "export function x() {\n}\n")
  3041  	expectPrinted(t, "export async function x() {}", "export async function x() {\n}\n")
  3042  	expectPrinted(t, "export var x, y", "export var x, y;\n")
  3043  	expectPrinted(t, "export let x, y", "export let x, y;\n")
  3044  	expectPrinted(t, "export const x = 0, y = 1", "export const x = 0, y = 1;\n")
  3045  	expectPrinted(t, "export * from \"foo\"", "export * from \"foo\";\n")
  3046  	expectPrinted(t, "export * as ns from \"foo\"", "export * as ns from \"foo\";\n")
  3047  	expectPrinted(t, "export * as if from \"foo\"", "export * as if from \"foo\";\n")
  3048  	expectPrinted(t, "let x; export {x}", "let x;\nexport { x };\n")
  3049  	expectPrinted(t, "let x; export {x as y}", "let x;\nexport { x as y };\n")
  3050  	expectPrinted(t, "let x, z; export {x as y, z}", "let x, z;\nexport { x as y, z };\n")
  3051  	expectPrinted(t, "let x, z; export {x as y, z,}", "let x, z;\nexport { x as y, z };\n")
  3052  	expectPrinted(t, "let x; export {x} from \"foo\"", "let x;\nexport { x } from \"foo\";\n")
  3053  	expectPrinted(t, "let x; export {x as y} from \"foo\"", "let x;\nexport { x as y } from \"foo\";\n")
  3054  	expectPrinted(t, "let x, z; export {x as y, z} from \"foo\"", "let x, z;\nexport { x as y, z } from \"foo\";\n")
  3055  	expectPrinted(t, "let x, z; export {x as y, z,} from \"foo\"", "let x, z;\nexport { x as y, z } from \"foo\";\n")
  3056  
  3057  	expectParseError(t, "export x from \"foo\"", "<stdin>: ERROR: Unexpected \"x\"\n")
  3058  	expectParseError(t, "export async", "<stdin>: ERROR: Expected \"function\" but found end of file\n")
  3059  	expectParseError(t, "export async function", "<stdin>: ERROR: Expected identifier but found end of file\n")
  3060  	expectParseError(t, "export async () => {}", "<stdin>: ERROR: Expected \"function\" but found \"(\"\n")
  3061  	expectParseError(t, "export var", "<stdin>: ERROR: Expected identifier but found end of file\n")
  3062  	expectParseError(t, "export let", "<stdin>: ERROR: Expected identifier but found end of file\n")
  3063  	expectParseError(t, "export const", "<stdin>: ERROR: Expected identifier but found end of file\n")
  3064  
  3065  	// Do not parse TypeScript export syntax in JavaScript
  3066  	expectParseError(t, "export enum Foo {}", "<stdin>: ERROR: Unexpected \"enum\"\n")
  3067  	expectParseError(t, "export interface Foo {}", "<stdin>: ERROR: Unexpected \"interface\"\n")
  3068  	expectParseError(t, "export namespace Foo {}", "<stdin>: ERROR: Unexpected \"namespace\"\n")
  3069  	expectParseError(t, "export abstract class Foo {}", "<stdin>: ERROR: Unexpected \"abstract\"\n")
  3070  	expectParseError(t, "export declare class Foo {}", "<stdin>: ERROR: Unexpected \"declare\"\n")
  3071  	expectParseError(t, "export declare function foo() {}", "<stdin>: ERROR: Unexpected \"declare\"\n")
  3072  
  3073  	// String export alias with "export {}"
  3074  	expectPrinted(t, "let x; export {x as ''}", "let x;\nexport { x as \"\" };\n")
  3075  	expectPrinted(t, "let x; export {x as 'šŸ•'}", "let x;\nexport { x as \"šŸ•\" };\n")
  3076  	expectPrinted(t, "let x; export {x as 'a b'}", "let x;\nexport { x as \"a b\" };\n")
  3077  	expectPrinted(t, "let x; export {x as '\\uD800\\uDC00'}", "let x;\nexport { x as 𐀀 };\n")
  3078  	expectParseError(t, "let x; export {'x'}", "<stdin>: ERROR: Expected identifier but found \"'x'\"\n")
  3079  	expectParseError(t, "let x; export {'x' as 'y'}", "<stdin>: ERROR: Expected identifier but found \"'x'\"\n")
  3080  	expectParseError(t, "let x; export {x as '\\uD800'}",
  3081  		"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+D800\n")
  3082  	expectParseError(t, "let x; export {x as '\\uDC00'}",
  3083  		"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\n")
  3084  
  3085  	// String import alias with "export {} from"
  3086  	expectPrinted(t, "export {'' as x} from 'foo'", "export { \"\" as x } from \"foo\";\n")
  3087  	expectPrinted(t, "export {'šŸ•' as x} from 'foo'", "export { \"šŸ•\" as x } from \"foo\";\n")
  3088  	expectPrinted(t, "export {'a b' as x} from 'foo'", "export { \"a b\" as x } from \"foo\";\n")
  3089  	expectPrinted(t, "export {'\\uD800\\uDC00' as x} from 'foo'", "export { 𐀀 as x } from \"foo\";\n")
  3090  	expectParseError(t, "export {'\\uD800' as x} from 'foo'",
  3091  		"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+D800\n")
  3092  	expectParseError(t, "export {'\\uDC00' as x} from 'foo'",
  3093  		"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\n")
  3094  
  3095  	// String export alias with "export {} from"
  3096  	expectPrinted(t, "export {x as ''} from 'foo'", "export { x as \"\" } from \"foo\";\n")
  3097  	expectPrinted(t, "export {x as 'šŸ•'} from 'foo'", "export { x as \"šŸ•\" } from \"foo\";\n")
  3098  	expectPrinted(t, "export {x as 'a b'} from 'foo'", "export { x as \"a b\" } from \"foo\";\n")
  3099  	expectPrinted(t, "export {x as '\\uD800\\uDC00'} from 'foo'", "export { x as 𐀀 } from \"foo\";\n")
  3100  	expectParseError(t, "export {x as '\\uD800'} from 'foo'",
  3101  		"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+D800\n")
  3102  	expectParseError(t, "export {x as '\\uDC00'} from 'foo'",
  3103  		"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\n")
  3104  
  3105  	// String import and export alias with "export {} from"
  3106  	expectPrinted(t, "export {'x'} from 'foo'", "export { x } from \"foo\";\n")
  3107  	expectPrinted(t, "export {'a b'} from 'foo'", "export { \"a b\" } from \"foo\";\n")
  3108  	expectPrinted(t, "export {'x' as 'y'} from 'foo'", "export { x as y } from \"foo\";\n")
  3109  	expectPrinted(t, "export {'a b' as 'c d'} from 'foo'", "export { \"a b\" as \"c d\" } from \"foo\";\n")
  3110  
  3111  	// String export alias with "export * as"
  3112  	expectPrinted(t, "export * as '' from 'foo'", "export * as \"\" from \"foo\";\n")
  3113  	expectPrinted(t, "export * as 'šŸ•' from 'foo'", "export * as \"šŸ•\" from \"foo\";\n")
  3114  	expectPrinted(t, "export * as 'a b' from 'foo'", "export * as \"a b\" from \"foo\";\n")
  3115  	expectPrinted(t, "export * as '\\uD800\\uDC00' from 'foo'", "export * as 𐀀 from \"foo\";\n")
  3116  	expectParseError(t, "export * as '\\uD800' from 'foo'",
  3117  		"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+D800\n")
  3118  	expectParseError(t, "export * as '\\uDC00' from 'foo'",
  3119  		"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\n")
  3120  }
  3121  
  3122  func TestExportDuplicates(t *testing.T) {
  3123  	expectPrinted(t, "export {x};let x", "export { x };\nlet x;\n")
  3124  	expectPrinted(t, "export {x, x as y};let x", "export { x, x as y };\nlet x;\n")
  3125  	expectPrinted(t, "export {x};export {x as y} from 'foo';let x", "export { x };\nexport { x as y } from \"foo\";\nlet x;\n")
  3126  	expectPrinted(t, "export {x};export default function x() {}", "export { x };\nexport default function x() {\n}\n")
  3127  	expectPrinted(t, "export {x};export default class x {}", "export { x };\nexport default class x {\n}\n")
  3128  
  3129  	errorTextX := `<stdin>: ERROR: Multiple exports with the same name "x"
  3130  <stdin>: NOTE: The name "x" was originally exported here:
  3131  `
  3132  
  3133  	expectParseError(t, "export {x, x};let x", errorTextX)
  3134  	expectParseError(t, "export {x, y as x};let x, y", errorTextX)
  3135  	expectParseError(t, "export {x};export function x() {}", errorTextX)
  3136  	expectParseError(t, "export {x};export class x {}", errorTextX)
  3137  	expectParseError(t, "export {x};export const x = 0", errorTextX)
  3138  	expectParseError(t, "export {x};export let x", errorTextX)
  3139  	expectParseError(t, "export {x};export var x", errorTextX)
  3140  	expectParseError(t, "export {x};let x;export {x} from 'foo'", errorTextX)
  3141  	expectParseError(t, "export {x};let x;export {y as x} from 'foo'", errorTextX)
  3142  	expectParseError(t, "export {x};let x;export * as x from 'foo'", errorTextX)
  3143  
  3144  	errorTextDefault := `<stdin>: ERROR: Multiple exports with the same name "default"
  3145  <stdin>: NOTE: The name "default" was originally exported here:
  3146  `
  3147  
  3148  	expectParseError(t, "export {x as default};let x;export default 0", errorTextDefault)
  3149  	expectParseError(t, "export {x as default};let x;export default function() {}", errorTextDefault)
  3150  	expectParseError(t, "export {x as default};let x;export default class {}", errorTextDefault)
  3151  	expectParseError(t, "export {x as default};export default function x() {}", errorTextDefault)
  3152  	expectParseError(t, "export {x as default};export default class x {}", errorTextDefault)
  3153  }
  3154  
  3155  func TestExportDefault(t *testing.T) {
  3156  	expectParseError(t, "export default 1, 2", "<stdin>: ERROR: Expected \";\" but found \",\"\n")
  3157  	expectPrinted(t, "export default (1, 2)", "export default (1, 2);\n")
  3158  
  3159  	expectParseError(t, "export default async, 0", "<stdin>: ERROR: Expected \";\" but found \",\"\n")
  3160  	expectPrinted(t, "export default async", "export default async;\n")
  3161  	expectPrinted(t, "export default async()", "export default async();\n")
  3162  	expectPrinted(t, "export default async + 1", "export default async + 1;\n")
  3163  	expectPrinted(t, "export default async => {}", "export default (async) => {\n};\n")
  3164  	expectPrinted(t, "export default async x => {}", "export default async (x) => {\n};\n")
  3165  	expectPrinted(t, "export default async () => {}", "export default async () => {\n};\n")
  3166  
  3167  	// This is a corner case in the ES6 grammar. The "export default" statement
  3168  	// normally takes an expression except for the function and class keywords
  3169  	// which behave sort of like their respective declarations instead.
  3170  	expectPrinted(t, "export default function() {} - after", "export default function() {\n}\n-after;\n")
  3171  	expectPrinted(t, "export default function*() {} - after", "export default function* () {\n}\n-after;\n")
  3172  	expectPrinted(t, "export default function foo() {} - after", "export default function foo() {\n}\n-after;\n")
  3173  	expectPrinted(t, "export default function* foo() {} - after", "export default function* foo() {\n}\n-after;\n")
  3174  	expectPrinted(t, "export default async function() {} - after", "export default async function() {\n}\n-after;\n")
  3175  	expectPrinted(t, "export default async function*() {} - after", "export default async function* () {\n}\n-after;\n")
  3176  	expectPrinted(t, "export default async function foo() {} - after", "export default async function foo() {\n}\n-after;\n")
  3177  	expectPrinted(t, "export default async function* foo() {} - after", "export default async function* foo() {\n}\n-after;\n")
  3178  	expectPrinted(t, "export default class {} - after", "export default class {\n}\n-after;\n")
  3179  	expectPrinted(t, "export default class Foo {} - after", "export default class Foo {\n}\n-after;\n")
  3180  
  3181  	// Check ASI for "abstract"
  3182  	expectPrinted(t, "export default abstract\nclass Foo {}", "export default abstract;\nclass Foo {\n}\n")
  3183  	expectParseError(t, "export default abstract class {}", "<stdin>: ERROR: Expected \";\" but found \"class\"\n")
  3184  }
  3185  
  3186  func TestExportClause(t *testing.T) {
  3187  	expectPrinted(t, "export {x, y};let x, y", "export { x, y };\nlet x, y;\n")
  3188  	expectPrinted(t, "export {x, y as z,};let x, y", "export { x, y as z };\nlet x, y;\n")
  3189  	expectPrinted(t, "export {x, y} from 'path'", "export { x, y } from \"path\";\n")
  3190  	expectPrinted(t, "export {default, if} from 'path'", "export { default, if } from \"path\";\n")
  3191  	expectPrinted(t, "export {default as foo, if as bar} from 'path'", "export { default as foo, if as bar } from \"path\";\n")
  3192  	expectParseError(t, "export {default}", "<stdin>: ERROR: Expected identifier but found \"default\"\n")
  3193  	expectParseError(t, "export {default as foo}", "<stdin>: ERROR: Expected identifier but found \"default\"\n")
  3194  	expectParseError(t, "export {if}", "<stdin>: ERROR: Expected identifier but found \"if\"\n")
  3195  	expectParseError(t, "export {if as foo}", "<stdin>: ERROR: Expected identifier but found \"if\"\n")
  3196  }
  3197  
  3198  func TestCatch(t *testing.T) {
  3199  	expectPrinted(t, "try {} catch (e) {}", "try {\n} catch (e) {\n}\n")
  3200  	expectPrinted(t, "try {} catch (e) { var e }", "try {\n} catch (e) {\n  var e;\n}\n")
  3201  	expectPrinted(t, "var e; try {} catch (e) {}", "var e;\ntry {\n} catch (e) {\n}\n")
  3202  	expectPrinted(t, "let e; try {} catch (e) {}", "let e;\ntry {\n} catch (e) {\n}\n")
  3203  	expectPrinted(t, "try { var e } catch (e) {}", "try {\n  var e;\n} catch (e) {\n}\n")
  3204  	expectPrinted(t, "try { function e() {} } catch (e) {}", "try {\n  let e = function() {\n  };\n  var e = e;\n} catch (e) {\n}\n")
  3205  	expectPrinted(t, "try {} catch (e) { { function e() {} } }", "try {\n} catch (e) {\n  {\n    let e = function() {\n    };\n    var e = e;\n  }\n}\n")
  3206  	expectPrinted(t, "try {} catch (e) { if (1) function e() {} }", "try {\n} catch (e) {\n  if (1) {\n    let e = function() {\n    };\n    var e = e;\n  }\n}\n")
  3207  	expectPrinted(t, "try {} catch (e) { if (0) ; else function e() {} }", "try {\n} catch (e) {\n  if (0) ;\n  else {\n    let e = function() {\n    };\n    var e = e;\n  }\n}\n")
  3208  	expectPrinted(t, "try {} catch ({ e }) { { function e() {} } }", "try {\n} catch ({ e }) {\n  {\n    let e = function() {\n    };\n    var e = e;\n  }\n}\n")
  3209  
  3210  	errorText := `<stdin>: ERROR: The symbol "e" has already been declared
  3211  <stdin>: NOTE: The symbol "e" was originally declared here:
  3212  `
  3213  
  3214  	expectParseError(t, "try {} catch (e) { function e() {} }", errorText)
  3215  	expectParseError(t, "try {} catch ({ e }) { var e }", errorText)
  3216  	expectParseError(t, "try {} catch ({ e }) { { var e } }", errorText)
  3217  	expectParseError(t, "try {} catch ({ e }) { function e() {} }", errorText)
  3218  	expectParseError(t, "try {} catch (e) { let e }", errorText)
  3219  	expectParseError(t, "try {} catch (e) { const e = 0 }", errorText)
  3220  }
  3221  
  3222  func TestWarningEqualsNegativeZero(t *testing.T) {
  3223  	note := "NOTE: Floating-point equality is defined such that 0 and -0 are equal, so \"x === -0\" returns true for both 0 and -0. " +
  3224  		"You need to use \"Object.is(x, -0)\" instead to test for -0.\n"
  3225  
  3226  	expectParseError(t, "x === -0", "<stdin>: WARNING: Comparison with -0 using the \"===\" operator will also match 0\n"+note)
  3227  	expectParseError(t, "x == -0", "<stdin>: WARNING: Comparison with -0 using the \"==\" operator will also match 0\n"+note)
  3228  	expectParseError(t, "x !== -0", "<stdin>: WARNING: Comparison with -0 using the \"!==\" operator will also match 0\n"+note)
  3229  	expectParseError(t, "x != -0", "<stdin>: WARNING: Comparison with -0 using the \"!=\" operator will also match 0\n"+note)
  3230  	expectParseError(t, "switch (x) { case -0: }", "<stdin>: WARNING: Comparison with -0 using a case clause will also match 0\n"+note)
  3231  
  3232  	expectParseError(t, "-0 === x", "<stdin>: WARNING: Comparison with -0 using the \"===\" operator will also match 0\n"+note)
  3233  	expectParseError(t, "-0 == x", "<stdin>: WARNING: Comparison with -0 using the \"==\" operator will also match 0\n"+note)
  3234  	expectParseError(t, "-0 !== x", "<stdin>: WARNING: Comparison with -0 using the \"!==\" operator will also match 0\n"+note)
  3235  	expectParseError(t, "-0 != x", "<stdin>: WARNING: Comparison with -0 using the \"!=\" operator will also match 0\n"+note)
  3236  	expectParseError(t, "switch (-0) { case x: }", "") // Don't bother to handle this case
  3237  }
  3238  
  3239  func TestWarningEqualsNewObject(t *testing.T) {
  3240  	note := "NOTE: Equality with a new object is always false in JavaScript because the equality operator tests object identity. " +
  3241  		"You need to write code to compare the contents of the object instead. " +
  3242  		"For example, use \"Array.isArray(x) && x.length === 0\" instead of \"x === []\" to test for an empty array.\n"
  3243  
  3244  	expectParseError(t, "x === []", "<stdin>: WARNING: Comparison using the \"===\" operator here is always false\n"+note)
  3245  	expectParseError(t, "x !== []", "<stdin>: WARNING: Comparison using the \"!==\" operator here is always true\n"+note)
  3246  	expectParseError(t, "x == []", "")
  3247  	expectParseError(t, "x != []", "")
  3248  	expectParseError(t, "switch (x) { case []: }", "<stdin>: WARNING: This case clause will never be evaluated because the comparison is always false\n"+note)
  3249  
  3250  	expectParseError(t, "[] === x", "<stdin>: WARNING: Comparison using the \"===\" operator here is always false\n"+note)
  3251  	expectParseError(t, "[] !== x", "<stdin>: WARNING: Comparison using the \"!==\" operator here is always true\n"+note)
  3252  	expectParseError(t, "[] == x", "")
  3253  	expectParseError(t, "[] != x", "")
  3254  	expectParseError(t, "switch ([]) { case x: }", "") // Don't bother to handle this case
  3255  }
  3256  
  3257  func TestWarningEqualsNaN(t *testing.T) {
  3258  	note := "NOTE: Floating-point equality is defined such that NaN is never equal to anything, so \"x === NaN\" always returns false. " +
  3259  		"You need to use \"Number.isNaN(x)\" instead to test for NaN.\n"
  3260  
  3261  	expectParseError(t, "x === NaN", "<stdin>: WARNING: Comparison with NaN using the \"===\" operator here is always false\n"+note)
  3262  	expectParseError(t, "x !== NaN", "<stdin>: WARNING: Comparison with NaN using the \"!==\" operator here is always true\n"+note)
  3263  	expectParseError(t, "x == NaN", "<stdin>: WARNING: Comparison with NaN using the \"==\" operator here is always false\n"+note)
  3264  	expectParseError(t, "x != NaN", "<stdin>: WARNING: Comparison with NaN using the \"!=\" operator here is always true\n"+note)
  3265  	expectParseError(t, "switch (x) { case NaN: }", "<stdin>: WARNING: This case clause will never be evaluated because equality with NaN is always false\n"+note)
  3266  
  3267  	expectParseError(t, "NaN === x", "<stdin>: WARNING: Comparison with NaN using the \"===\" operator here is always false\n"+note)
  3268  	expectParseError(t, "NaN !== x", "<stdin>: WARNING: Comparison with NaN using the \"!==\" operator here is always true\n"+note)
  3269  	expectParseError(t, "NaN == x", "<stdin>: WARNING: Comparison with NaN using the \"==\" operator here is always false\n"+note)
  3270  	expectParseError(t, "NaN != x", "<stdin>: WARNING: Comparison with NaN using the \"!=\" operator here is always true\n"+note)
  3271  	expectParseError(t, "switch (NaN) { case x: }", "") // Don't bother to handle this case
  3272  }
  3273  
  3274  func TestWarningTypeofEquals(t *testing.T) {
  3275  	note := "NOTE: The expression \"typeof x\" actually evaluates to \"object\" in JavaScript, not \"null\". " +
  3276  		"You need to use \"x === null\" to test for null.\n"
  3277  
  3278  	expectParseError(t, "typeof x === 'null'", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3279  	expectParseError(t, "typeof x !== 'null'", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3280  	expectParseError(t, "typeof x == 'null'", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3281  	expectParseError(t, "typeof x != 'null'", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3282  	expectParseError(t, "switch (typeof x) { case 'null': }", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3283  
  3284  	expectParseError(t, "'null' === typeof x", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3285  	expectParseError(t, "'null' !== typeof x", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3286  	expectParseError(t, "'null' == typeof x", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3287  	expectParseError(t, "'null' != typeof x", "<stdin>: WARNING: The \"typeof\" operator will never evaluate to \"null\"\n"+note)
  3288  	expectParseError(t, "switch ('null') { case typeof x: }", "") // Don't bother to handle this case
  3289  }
  3290  
  3291  func TestWarningDeleteSuperProperty(t *testing.T) {
  3292  	text := "<stdin>: WARNING: Attempting to delete a property of \"super\" will throw a ReferenceError\n"
  3293  	expectParseError(t, "class Foo extends Bar { constructor() { delete super.foo } }", text)
  3294  	expectParseError(t, "class Foo extends Bar { constructor() { delete super['foo'] } }", text)
  3295  	expectParseError(t, "class Foo extends Bar { constructor() { delete (super.foo) } }", text)
  3296  	expectParseError(t, "class Foo extends Bar { constructor() { delete (super['foo']) } }", text)
  3297  
  3298  	expectParseError(t, "class Foo extends Bar { constructor() { delete super.foo.bar } }", "")
  3299  	expectParseError(t, "class Foo extends Bar { constructor() { delete super['foo']['bar'] } }", "")
  3300  }
  3301  
  3302  func TestWarningDuplicateCase(t *testing.T) {
  3303  	expectParseError(t, "switch (x) { case null: case undefined: }", "")
  3304  	expectParseError(t, "switch (x) { case false: case true: }", "")
  3305  	expectParseError(t, "switch (x) { case 0: case 1: }", "")
  3306  	expectParseError(t, "switch (x) { case 1: case 1n: }", "")
  3307  	expectParseError(t, "switch (x) { case 'a': case 'b': }", "")
  3308  	expectParseError(t, "switch (x) { case y: case z: }", "")
  3309  	expectParseError(t, "switch (x) { case y.a: case y.b: }", "")
  3310  	expectParseError(t, "switch (x) { case y.a: case z.a: }", "")
  3311  	expectParseError(t, "switch (x) { case y.a: case y?.a: }", "")
  3312  	expectParseError(t, "switch (x) { case y[a]: case y[b]: }", "")
  3313  	expectParseError(t, "switch (x) { case y[a]: case z[a]: }", "")
  3314  	expectParseError(t, "switch (x) { case y[a]: case y?.[a]: }", "")
  3315  
  3316  	alwaysWarning := "<stdin>: WARNING: This case clause will never be evaluated because it duplicates an earlier case clause\n" +
  3317  		"<stdin>: NOTE: The earlier case clause is here:\n"
  3318  	likelyWarning := "<stdin>: WARNING: This case clause may never be evaluated because it likely duplicates an earlier case clause\n" +
  3319  		"<stdin>: NOTE: The earlier case clause is here:\n"
  3320  
  3321  	expectParseError(t, "switch (x) { case null: case null: }", alwaysWarning)
  3322  	expectParseError(t, "switch (x) { case undefined: case undefined: }", alwaysWarning)
  3323  	expectParseError(t, "switch (x) { case true: case true: }", alwaysWarning)
  3324  	expectParseError(t, "switch (x) { case false: case false: }", alwaysWarning)
  3325  	expectParseError(t, "switch (x) { case 0xF: case 15: }", alwaysWarning)
  3326  	expectParseError(t, "switch (x) { case 'a': case `a`: }", alwaysWarning)
  3327  	expectParseError(t, "switch (x) { case 123n: case 1_2_3n: }", alwaysWarning)
  3328  	expectParseError(t, "switch (x) { case y: case y: }", alwaysWarning)
  3329  	expectParseError(t, "switch (x) { case y.a: case y.a: }", likelyWarning)
  3330  	expectParseError(t, "switch (x) { case y?.a: case y?.a: }", likelyWarning)
  3331  	expectParseError(t, "switch (x) { case y[a]: case y[a]: }", likelyWarning)
  3332  	expectParseError(t, "switch (x) { case y?.[a]: case y?.[a]: }", likelyWarning)
  3333  }
  3334  
  3335  func TestWarningDuplicateClassMember(t *testing.T) {
  3336  	duplicateWarning := "<stdin>: WARNING: Duplicate member \"x\" in class body\n" +
  3337  		"<stdin>: NOTE: The original member \"x\" is here:\n"
  3338  
  3339  	expectParseError(t, "class Foo { x; x }", duplicateWarning)
  3340  	expectParseError(t, "class Foo { x() {}; x() {} }", duplicateWarning)
  3341  	expectParseError(t, "class Foo { get x() {}; get x() {} }", duplicateWarning)
  3342  	expectParseError(t, "class Foo { get x() {}; set x(y) {}; get x() {} }", duplicateWarning)
  3343  	expectParseError(t, "class Foo { get x() {}; set x(y) {}; set x(y) {} }", duplicateWarning)
  3344  	expectParseError(t, "class Foo { get x() {}; set x(y) {} }", "")
  3345  	expectParseError(t, "class Foo { set x(y) {}; get x() {} }", "")
  3346  
  3347  	expectParseError(t, "class Foo { static x; static x }", duplicateWarning)
  3348  	expectParseError(t, "class Foo { static x() {}; static x() {} }", duplicateWarning)
  3349  	expectParseError(t, "class Foo { static get x() {}; static get x() {} }", duplicateWarning)
  3350  	expectParseError(t, "class Foo { static get x() {}; static set x(y) {}; static get x() {} }", duplicateWarning)
  3351  	expectParseError(t, "class Foo { static get x() {}; static set x(y) {}; static set x(y) {} }", duplicateWarning)
  3352  	expectParseError(t, "class Foo { static get x() {}; static set x(y) {} }", "")
  3353  	expectParseError(t, "class Foo { static set x(y) {}; static get x() {} }", "")
  3354  
  3355  	expectParseError(t, "class Foo { x; static x }", "")
  3356  	expectParseError(t, "class Foo { x; static x() {} }", "")
  3357  	expectParseError(t, "class Foo { x() {}; static x }", "")
  3358  	expectParseError(t, "class Foo { x() {}; static x() {} }", "")
  3359  	expectParseError(t, "class Foo { static x; x }", "")
  3360  	expectParseError(t, "class Foo { static x; x() {} }", "")
  3361  	expectParseError(t, "class Foo { static x() {}; x }", "")
  3362  	expectParseError(t, "class Foo { static x() {}; x() {} }", "")
  3363  	expectParseError(t, "class Foo { get x() {}; static get x() {} }", "")
  3364  	expectParseError(t, "class Foo { set x(y) {}; static set x(y) {} }", "")
  3365  }
  3366  
  3367  func TestWarningNullishCoalescing(t *testing.T) {
  3368  	expectParseError(t, "x = null ?? y", "")
  3369  	expectParseError(t, "x = undefined ?? y", "")
  3370  	expectParseError(t, "x = false ?? y", "")
  3371  	expectParseError(t, "x = true ?? y", "")
  3372  	expectParseError(t, "x = 0 ?? y", "")
  3373  	expectParseError(t, "x = 1 ?? y", "")
  3374  
  3375  	alwaysLeft := "<stdin>: WARNING: The \"??\" operator here will always return the left operand\n" +
  3376  		"<stdin>: NOTE: The left operand of the \"??\" operator here will never be null or undefined, so it will always be returned. This usually indicates a bug in your code:\n"
  3377  	alwaysRight := "<stdin>: WARNING: The \"??\" operator here will always return the right operand\n" +
  3378  		"<stdin>: NOTE: The left operand of the \"??\" operator here will always be null or undefined, so it will never be returned. This usually indicates a bug in your code:\n"
  3379  
  3380  	expectParseError(t, "x = a === b ?? y", alwaysLeft)
  3381  	expectParseError(t, "x = { ...a } ?? y", alwaysLeft)
  3382  	expectParseError(t, "x = (a => b) ?? y", alwaysLeft)
  3383  	expectParseError(t, "x = void a ?? y", alwaysRight)
  3384  }
  3385  
  3386  func TestWarningLogicalOperator(t *testing.T) {
  3387  	expectParseError(t, "x(a => b && a <= c)", "")
  3388  	expectParseError(t, "x(a => b || a <= c)", "")
  3389  	expectParseError(t, "x(a => (0 && a <= 1))", "")
  3390  	expectParseError(t, "x(a => (-1 && a <= 0))", "")
  3391  	expectParseError(t, "x(a => (0 || a <= -1))", "")
  3392  	expectParseError(t, "x(a => (1 || a <= 0))", "")
  3393  
  3394  	expectParseError(t, "x(a => 0 && a <= 1)", "<stdin>: WARNING: The \"&&\" operator here will always return the left operand\n"+
  3395  		"<stdin>: NOTE: The \"=>\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \">=\" here instead?\n")
  3396  	expectParseError(t, "x(a => -1 && a <= 0)", "<stdin>: WARNING: The \"&&\" operator here will always return the right operand\n"+
  3397  		"<stdin>: NOTE: The \"=>\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \">=\" here instead?\n")
  3398  	expectParseError(t, "x(a => 0 || a <= -1)", "<stdin>: WARNING: The \"||\" operator here will always return the right operand\n"+
  3399  		"<stdin>: NOTE: The \"=>\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \">=\" here instead?\n")
  3400  	expectParseError(t, "x(a => 1 || a <= 0)", "<stdin>: WARNING: The \"||\" operator here will always return the left operand\n"+
  3401  		"<stdin>: NOTE: The \"=>\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \">=\" here instead?\n")
  3402  }
  3403  
  3404  func TestMangleFor(t *testing.T) {
  3405  	expectPrintedMangle(t, "var a; while (1) ;", "for (var a; ; ) ;\n")
  3406  	expectPrintedMangle(t, "let a; while (1) ;", "let a;\nfor (; ; ) ;\n")
  3407  	expectPrintedMangle(t, "const a=0; while (1) ;", "const a = 0;\nfor (; ; ) ;\n")
  3408  
  3409  	expectPrintedMangle(t, "var a; for (var b;;) ;", "for (var a, b; ; ) ;\n")
  3410  	expectPrintedMangle(t, "let a; for (let b;;) ;", "let a;\nfor (let b; ; ) ;\n")
  3411  	expectPrintedMangle(t, "const a=0; for (const b = 1;;) ;", "const a = 0;\nfor (const b = 1; ; ) ;\n")
  3412  
  3413  	expectPrintedMangle(t, "export var a; while (1) ;", "export var a;\nfor (; ; ) ;\n")
  3414  	expectPrintedMangle(t, "export let a; while (1) ;", "export let a;\nfor (; ; ) ;\n")
  3415  	expectPrintedMangle(t, "export const a=0; while (1) ;", "export const a = 0;\nfor (; ; ) ;\n")
  3416  
  3417  	expectPrintedMangle(t, "export var a; for (var b;;) ;", "export var a;\nfor (var b; ; ) ;\n")
  3418  	expectPrintedMangle(t, "export let a; for (let b;;) ;", "export let a;\nfor (let b; ; ) ;\n")
  3419  	expectPrintedMangle(t, "export const a=0; for (const b = 1;;) ;", "export const a = 0;\nfor (const b = 1; ; ) ;\n")
  3420  
  3421  	expectPrintedMangle(t, "var a; for (let b;;) ;", "var a;\nfor (let b; ; ) ;\n")
  3422  	expectPrintedMangle(t, "let a; for (const b=0;;) ;", "let a;\nfor (const b = 0; ; ) ;\n")
  3423  	expectPrintedMangle(t, "const a=0; for (var b;;) ;", "const a = 0;\nfor (var b; ; ) ;\n")
  3424  
  3425  	expectPrintedMangle(t, "a(); while (1) ;", "for (a(); ; ) ;\n")
  3426  	expectPrintedMangle(t, "a(); for (b();;) ;", "for (a(), b(); ; ) ;\n")
  3427  
  3428  	expectPrintedMangle(t, "for (; ;) if (x) break;", "for (; !x; ) ;\n")
  3429  	expectPrintedMangle(t, "for (; ;) if (!x) break;", "for (; x; ) ;\n")
  3430  	expectPrintedMangle(t, "for (; a;) if (x) break;", "for (; a && !x; ) ;\n")
  3431  	expectPrintedMangle(t, "for (; a;) if (!x) break;", "for (; a && x; ) ;\n")
  3432  	expectPrintedMangle(t, "for (; ;) { if (x) break; y(); }", "for (; !x; )\n  y();\n")
  3433  	expectPrintedMangle(t, "for (; a;) { if (x) break; y(); }", "for (; a && !x; )\n  y();\n")
  3434  	expectPrintedMangle(t, "for (; ;) if (x) break; else y();", "for (; !x; ) y();\n")
  3435  	expectPrintedMangle(t, "for (; a;) if (x) break; else y();", "for (; a && !x; ) y();\n")
  3436  	expectPrintedMangle(t, "for (; ;) { if (x) break; else y(); z(); }", "for (; !x; )\n  y(), z();\n")
  3437  	expectPrintedMangle(t, "for (; a;) { if (x) break; else y(); z(); }", "for (; a && !x; )\n  y(), z();\n")
  3438  	expectPrintedMangle(t, "for (; ;) if (x) y(); else break;", "for (; x; ) y();\n")
  3439  	expectPrintedMangle(t, "for (; ;) if (!x) y(); else break;", "for (; !x; ) y();\n")
  3440  	expectPrintedMangle(t, "for (; a;) if (x) y(); else break;", "for (; a && x; ) y();\n")
  3441  	expectPrintedMangle(t, "for (; a;) if (!x) y(); else break;", "for (; a && !x; ) y();\n")
  3442  	expectPrintedMangle(t, "for (; ;) { if (x) y(); else break; z(); }", "for (; x; ) {\n  y();\n  z();\n}\n")
  3443  	expectPrintedMangle(t, "for (; a;) { if (x) y(); else break; z(); }", "for (; a && x; ) {\n  y();\n  z();\n}\n")
  3444  }
  3445  
  3446  func TestMangleLoopJump(t *testing.T) {
  3447  	// Trim after jump
  3448  	expectPrintedMangle(t, "while (x) { if (1) break; z(); }", "for (; x; )\n  break;\n")
  3449  	expectPrintedMangle(t, "while (x) { if (1) continue; z(); }", "for (; x; )\n  ;\n")
  3450  	expectPrintedMangle(t, "foo: while (a) while (x) { if (1) continue foo; z(); }", "foo: for (; a; ) for (; x; )\n  continue foo;\n")
  3451  	expectPrintedMangle(t, "while (x) { y(); if (1) break; z(); }", "for (; x; ) {\n  y();\n  break;\n}\n")
  3452  	expectPrintedMangle(t, "while (x) { y(); if (1) continue; z(); }", "for (; x; )\n  y();\n")
  3453  	expectPrintedMangle(t, "while (x) { y(); debugger; if (1) continue; z(); }", "for (; x; ) {\n  y();\n  debugger;\n}\n")
  3454  	expectPrintedMangle(t, "while (x) { let y = z(); if (1) continue; z(); }", "for (; x; ) {\n  let y = z();\n}\n")
  3455  	expectPrintedMangle(t, "while (x) { debugger; if (y) { if (1) break; z() } }", "for (; x; ) {\n  debugger;\n  if (y)\n    break;\n}\n")
  3456  	expectPrintedMangle(t, "while (x) { debugger; if (y) { if (1) continue; z() } }", "for (; x; ) {\n  debugger;\n  y;\n}\n")
  3457  	expectPrintedMangle(t, "while (x) { debugger; if (1) { if (1) break; z() } }", "for (; x; ) {\n  debugger;\n  break;\n}\n")
  3458  	expectPrintedMangle(t, "while (x) { debugger; if (1) { if (1) continue; z() } }", "for (; x; )\n  debugger;\n")
  3459  
  3460  	// Trim trailing continue
  3461  	expectPrintedMangle(t, "while (x()) continue", "for (; x(); ) ;\n")
  3462  	expectPrintedMangle(t, "while (x) { y(); continue }", "for (; x; )\n  y();\n")
  3463  	expectPrintedMangle(t, "while (x) { if (y) { z(); continue } }",
  3464  		"for (; x; )\n  if (y) {\n    z();\n    continue;\n  }\n")
  3465  	expectPrintedMangle(t, "label: while (x) while (y) { z(); continue label }",
  3466  		"label: for (; x; ) for (; y; ) {\n  z();\n  continue label;\n}\n")
  3467  
  3468  	// Optimize implicit continue
  3469  	expectPrintedMangle(t, "while (x) { if (y) continue; z(); }", "for (; x; )\n  y || z();\n")
  3470  	expectPrintedMangle(t, "while (x) { if (y) continue; else z(); w(); }", "for (; x; )\n  y || (z(), w());\n")
  3471  	expectPrintedMangle(t, "while (x) { t(); if (y) continue; z(); }", "for (; x; )\n  t(), !y && z();\n")
  3472  	expectPrintedMangle(t, "while (x) { t(); if (y) continue; else z(); w(); }", "for (; x; )\n  t(), !y && (z(), w());\n")
  3473  	expectPrintedMangle(t, "while (x) { debugger; if (y) continue; z(); }", "for (; x; ) {\n  debugger;\n  y || z();\n}\n")
  3474  	expectPrintedMangle(t, "while (x) { debugger; if (y) continue; else z(); w(); }", "for (; x; ) {\n  debugger;\n  y || (z(), w());\n}\n")
  3475  
  3476  	// Do not optimize implicit continue for statements that care about scope
  3477  	expectPrintedMangle(t, "while (x) { if (y) continue; function y() {} }", "for (; x; ) {\n  let y = function() {\n  };\n  var y = y;\n}\n")
  3478  	expectPrintedMangle(t, "while (x) { if (y) continue; let y }", "for (; x; ) {\n  if (y) continue;\n  let y;\n}\n")
  3479  	expectPrintedMangle(t, "while (x) { if (y) continue; var y }", "for (; x; )\n  if (!y)\n    var y;\n")
  3480  }
  3481  
  3482  func TestMangleUndefined(t *testing.T) {
  3483  	// These should be transformed
  3484  	expectPrintedNormalAndMangle(t, "console.log(undefined)", "console.log(void 0);\n", "console.log(void 0);\n")
  3485  	expectPrintedNormalAndMangle(t, "console.log(+undefined)", "console.log(NaN);\n", "console.log(NaN);\n")
  3486  	expectPrintedNormalAndMangle(t, "console.log(undefined + undefined)", "console.log(void 0 + void 0);\n", "console.log(void 0 + void 0);\n")
  3487  	expectPrintedNormalAndMangle(t, "const x = undefined", "const x = void 0;\n", "const x = void 0;\n")
  3488  	expectPrintedNormalAndMangle(t, "let x = undefined", "let x = void 0;\n", "let x;\n")
  3489  	expectPrintedNormalAndMangle(t, "var x = undefined", "var x = void 0;\n", "var x = void 0;\n")
  3490  	expectPrintedNormalAndMangle(t, "function foo(a) { if (!a) return undefined; a() }", "function foo(a) {\n  if (!a) return void 0;\n  a();\n}\n", "function foo(a) {\n  a && a();\n}\n")
  3491  
  3492  	// These should not be transformed
  3493  	expectPrintedNormalAndMangle(t, "delete undefined", "delete undefined;\n", "delete undefined;\n")
  3494  	expectPrintedNormalAndMangle(t, "undefined--", "undefined--;\n", "undefined--;\n")
  3495  	expectPrintedNormalAndMangle(t, "undefined++", "undefined++;\n", "undefined++;\n")
  3496  	expectPrintedNormalAndMangle(t, "--undefined", "--undefined;\n", "--undefined;\n")
  3497  	expectPrintedNormalAndMangle(t, "++undefined", "++undefined;\n", "++undefined;\n")
  3498  	expectPrintedNormalAndMangle(t, "undefined = 1", "undefined = 1;\n", "undefined = 1;\n")
  3499  	expectPrintedNormalAndMangle(t, "[undefined] = 1", "[undefined] = 1;\n", "[undefined] = 1;\n")
  3500  	expectPrintedNormalAndMangle(t, "({x: undefined} = 1)", "({ x: undefined } = 1);\n", "({ x: undefined } = 1);\n")
  3501  	expectPrintedNormalAndMangle(t, "with (x) y(undefined); z(undefined)", "with (x) y(undefined);\nz(void 0);\n", "with (x) y(undefined);\nz(void 0);\n")
  3502  	expectPrintedNormalAndMangle(t, "with (x) while (i) y(undefined); z(undefined)", "with (x) while (i) y(undefined);\nz(void 0);\n", "with (x) for (; i; ) y(undefined);\nz(void 0);\n")
  3503  }
  3504  
  3505  func TestMangleIndex(t *testing.T) {
  3506  	expectPrintedNormalAndMangle(t, "x['y']", "x[\"y\"];\n", "x.y;\n")
  3507  	expectPrintedNormalAndMangle(t, "x['y z']", "x[\"y z\"];\n", "x[\"y z\"];\n")
  3508  	expectPrintedNormalAndMangle(t, "x?.['y']", "x?.[\"y\"];\n", "x?.y;\n")
  3509  	expectPrintedNormalAndMangle(t, "x?.['y z']", "x?.[\"y z\"];\n", "x?.[\"y z\"];\n")
  3510  	expectPrintedNormalAndMangle(t, "x?.['y']()", "x?.[\"y\"]();\n", "x?.y();\n")
  3511  	expectPrintedNormalAndMangle(t, "x?.['y z']()", "x?.[\"y z\"]();\n", "x?.[\"y z\"]();\n")
  3512  
  3513  	expectPrintedNormalAndMangle(t, "x['y' + 'z']", "x[\"yz\"];\n", "x.yz;\n")
  3514  	expectPrintedNormalAndMangle(t, "x?.['y' + 'z']", "x?.[\"yz\"];\n", "x?.[\"yz\"];\n")
  3515  
  3516  	// Check the string-to-int optimization
  3517  	expectPrintedNormalAndMangle(t, "x['0']", "x[\"0\"];\n", "x[0];\n")
  3518  	expectPrintedNormalAndMangle(t, "x['123']", "x[\"123\"];\n", "x[123];\n")
  3519  	expectPrintedNormalAndMangle(t, "x['-123']", "x[\"-123\"];\n", "x[-123];\n")
  3520  	expectPrintedNormalAndMangle(t, "x['-0']", "x[\"-0\"];\n", "x[\"-0\"];\n")
  3521  	expectPrintedNormalAndMangle(t, "x['01']", "x[\"01\"];\n", "x[\"01\"];\n")
  3522  	expectPrintedNormalAndMangle(t, "x['-01']", "x[\"-01\"];\n", "x[\"-01\"];\n")
  3523  	expectPrintedNormalAndMangle(t, "x['0x1']", "x[\"0x1\"];\n", "x[\"0x1\"];\n")
  3524  	expectPrintedNormalAndMangle(t, "x['-0x1']", "x[\"-0x1\"];\n", "x[\"-0x1\"];\n")
  3525  	expectPrintedNormalAndMangle(t, "x['2147483647']", "x[\"2147483647\"];\n", "x[2147483647];\n")
  3526  	expectPrintedNormalAndMangle(t, "x['2147483648']", "x[\"2147483648\"];\n", "x[\"2147483648\"];\n")
  3527  	expectPrintedNormalAndMangle(t, "x['-2147483648']", "x[\"-2147483648\"];\n", "x[-2147483648];\n")
  3528  	expectPrintedNormalAndMangle(t, "x['-2147483649']", "x[\"-2147483649\"];\n", "x[\"-2147483649\"];\n")
  3529  }
  3530  
  3531  func TestMangleBlock(t *testing.T) {
  3532  	expectPrintedMangle(t, "while(1) { while (1) {} }", "for (; ; )\n  for (; ; )\n    ;\n")
  3533  	expectPrintedMangle(t, "while(1) { const x = y; }", "for (; ; ) {\n  const x = y;\n}\n")
  3534  	expectPrintedMangle(t, "while(1) { let x; }", "for (; ; ) {\n  let x;\n}\n")
  3535  	expectPrintedMangle(t, "while(1) { var x; }", "for (; ; )\n  var x;\n")
  3536  	expectPrintedMangle(t, "while(1) { class X {} }", "for (; ; ) {\n  class X {\n  }\n}\n")
  3537  	expectPrintedMangle(t, "while(1) { function x() {} }", "for (; ; )\n  var x = function() {\n  };\n")
  3538  	expectPrintedMangle(t, "while(1) { function* x() {} }", "for (; ; ) {\n  function* x() {\n  }\n}\n")
  3539  	expectPrintedMangle(t, "while(1) { async function x() {} }", "for (; ; ) {\n  async function x() {\n  }\n}\n")
  3540  	expectPrintedMangle(t, "while(1) { async function* x() {} }", "for (; ; ) {\n  async function* x() {\n  }\n}\n")
  3541  }
  3542  
  3543  func TestMangleSwitch(t *testing.T) {
  3544  	expectPrintedMangle(t, "x(); switch (y) { case z: return w; }", "switch (x(), y) {\n  case z:\n    return w;\n}\n")
  3545  	expectPrintedMangle(t, "if (t) { x(); switch (y) { case z: return w; } }", "if (t)\n  switch (x(), y) {\n    case z:\n      return w;\n  }\n")
  3546  }
  3547  
  3548  func TestMangleAddEmptyString(t *testing.T) {
  3549  	expectPrintedNormalAndMangle(t, "a = '' + 0", "a = \"0\";\n", "a = \"0\";\n")
  3550  	expectPrintedNormalAndMangle(t, "a = 0 + ''", "a = \"0\";\n", "a = \"0\";\n")
  3551  	expectPrintedNormalAndMangle(t, "a = '' + b", "a = \"\" + b;\n", "a = \"\" + b;\n")
  3552  	expectPrintedNormalAndMangle(t, "a = b + ''", "a = b + \"\";\n", "a = b + \"\";\n")
  3553  
  3554  	expectPrintedNormalAndMangle(t, "a = [] + 0", "a = \"0\";\n", "a = \"0\";\n")
  3555  	expectPrintedNormalAndMangle(t, "a = 0 + []", "a = \"0\";\n", "a = \"0\";\n")
  3556  	expectPrintedNormalAndMangle(t, "a = [] + b", "a = [] + b;\n", "a = [] + b;\n")
  3557  	expectPrintedNormalAndMangle(t, "a = b + []", "a = b + [];\n", "a = b + [];\n")
  3558  	expectPrintedNormalAndMangle(t, "a = [b] + 0", "a = [b] + 0;\n", "a = [b] + 0;\n")
  3559  	expectPrintedNormalAndMangle(t, "a = 0 + [b]", "a = 0 + [b];\n", "a = 0 + [b];\n")
  3560  
  3561  	expectPrintedNormalAndMangle(t, "a = [1, 2] + ''", "a = \"1,2\";\n", "a = \"1,2\";\n")
  3562  	expectPrintedNormalAndMangle(t, "a = [1, 0, 2] + ''", "a = \"1,0,2\";\n", "a = \"1,0,2\";\n")
  3563  	expectPrintedNormalAndMangle(t, "a = [1, null, 2] + ''", "a = \"1,,2\";\n", "a = \"1,,2\";\n")
  3564  	expectPrintedNormalAndMangle(t, "a = [1, undefined, 2] + ''", "a = \"1,,2\";\n", "a = \"1,,2\";\n")
  3565  	expectPrintedNormalAndMangle(t, "a = [1, true, 2] + ''", "a = \"1,true,2\";\n", "a = \"1,true,2\";\n")
  3566  	expectPrintedNormalAndMangle(t, "a = [1, false, 2] + ''", "a = \"1,false,2\";\n", "a = \"1,false,2\";\n")
  3567  	expectPrintedNormalAndMangle(t, "a = [1, , 2] + ''", "a = [1, , 2] + \"\";\n", "a = [1, , 2] + \"\";\n") // Note: Prototype hazards
  3568  	expectPrintedNormalAndMangle(t, "a = [1, , ,] + ''", "a = [1, , ,] + \"\";\n", "a = [1, , ,] + \"\";\n") // Note: Prototype hazards
  3569  
  3570  	expectPrintedNormalAndMangle(t, "a = {} + 0", "a = \"[object Object]0\";\n", "a = \"[object Object]0\";\n")
  3571  	expectPrintedNormalAndMangle(t, "a = 0 + {}", "a = \"0[object Object]\";\n", "a = \"0[object Object]\";\n")
  3572  	expectPrintedNormalAndMangle(t, "a = {} + b", "a = {} + b;\n", "a = {} + b;\n")
  3573  	expectPrintedNormalAndMangle(t, "a = b + {}", "a = b + {};\n", "a = b + {};\n")
  3574  	expectPrintedNormalAndMangle(t, "a = {toString:()=>1} + 0", "a = { toString: () => 1 } + 0;\n", "a = { toString: () => 1 } + 0;\n")
  3575  	expectPrintedNormalAndMangle(t, "a = 0 + {toString:()=>1}", "a = 0 + { toString: () => 1 };\n", "a = 0 + { toString: () => 1 };\n")
  3576  
  3577  	expectPrintedNormalAndMangle(t, "a = '' + `${b}`", "a = `${b}`;\n", "a = `${b}`;\n")
  3578  	expectPrintedNormalAndMangle(t, "a = `${b}` + ''", "a = `${b}`;\n", "a = `${b}`;\n")
  3579  	expectPrintedNormalAndMangle(t, "a = '' + typeof b", "a = typeof b;\n", "a = typeof b;\n")
  3580  	expectPrintedNormalAndMangle(t, "a = typeof b + ''", "a = typeof b;\n", "a = typeof b;\n")
  3581  
  3582  	expectPrintedNormalAndMangle(t, "a = [] + `${b}`", "a = `${b}`;\n", "a = `${b}`;\n")
  3583  	expectPrintedNormalAndMangle(t, "a = `${b}` + []", "a = `${b}`;\n", "a = `${b}`;\n")
  3584  	expectPrintedNormalAndMangle(t, "a = [] + typeof b", "a = typeof b;\n", "a = typeof b;\n")
  3585  	expectPrintedNormalAndMangle(t, "a = typeof b + []", "a = typeof b;\n", "a = typeof b;\n")
  3586  	expectPrintedNormalAndMangle(t, "a = [b] + `${b}`", "a = [b] + `${b}`;\n", "a = [b] + `${b}`;\n")
  3587  	expectPrintedNormalAndMangle(t, "a = `${b}` + [b]", "a = `${b}` + [b];\n", "a = `${b}` + [b];\n")
  3588  
  3589  	expectPrintedNormalAndMangle(t, "a = {} + `${b}`", "a = `[object Object]${b}`;\n", "a = `[object Object]${b}`;\n")
  3590  	expectPrintedNormalAndMangle(t, "a = `${b}` + {}", "a = `${b}[object Object]`;\n", "a = `${b}[object Object]`;\n")
  3591  	expectPrintedNormalAndMangle(t, "a = {} + typeof b", "a = {} + typeof b;\n", "a = {} + typeof b;\n")
  3592  	expectPrintedNormalAndMangle(t, "a = typeof b + {}", "a = typeof b + {};\n", "a = typeof b + {};\n")
  3593  	expectPrintedNormalAndMangle(t, "a = {toString:()=>1} + `${b}`", "a = { toString: () => 1 } + `${b}`;\n", "a = { toString: () => 1 } + `${b}`;\n")
  3594  	expectPrintedNormalAndMangle(t, "a = `${b}` + {toString:()=>1}", "a = `${b}` + { toString: () => 1 };\n", "a = `${b}` + { toString: () => 1 };\n")
  3595  
  3596  	expectPrintedNormalAndMangle(t, "a = '' + false", "a = \"false\";\n", "a = \"false\";\n")
  3597  	expectPrintedNormalAndMangle(t, "a = '' + true", "a = \"true\";\n", "a = \"true\";\n")
  3598  	expectPrintedNormalAndMangle(t, "a = false + ''", "a = \"false\";\n", "a = \"false\";\n")
  3599  	expectPrintedNormalAndMangle(t, "a = true + ''", "a = \"true\";\n", "a = \"true\";\n")
  3600  	expectPrintedNormalAndMangle(t, "a = 1 + false + ''", "a = 1 + false + \"\";\n", "a = 1 + false + \"\";\n")
  3601  	expectPrintedNormalAndMangle(t, "a = 0 + true + ''", "a = 0 + true + \"\";\n", "a = 0 + true + \"\";\n")
  3602  
  3603  	expectPrintedNormalAndMangle(t, "a = '' + null", "a = \"null\";\n", "a = \"null\";\n")
  3604  	expectPrintedNormalAndMangle(t, "a = null + ''", "a = \"null\";\n", "a = \"null\";\n")
  3605  	expectPrintedNormalAndMangle(t, "a = '' + undefined", "a = \"undefined\";\n", "a = \"undefined\";\n")
  3606  	expectPrintedNormalAndMangle(t, "a = undefined + ''", "a = \"undefined\";\n", "a = \"undefined\";\n")
  3607  
  3608  	expectPrintedNormalAndMangle(t, "a = '' + 0n", "a = \"0\";\n", "a = \"0\";\n")
  3609  	expectPrintedNormalAndMangle(t, "a = '' + 1n", "a = \"1\";\n", "a = \"1\";\n")
  3610  	expectPrintedNormalAndMangle(t, "a = '' + 123n", "a = \"123\";\n", "a = \"123\";\n")
  3611  	expectPrintedNormalAndMangle(t, "a = '' + 1_2_3n", "a = \"123\";\n", "a = \"123\";\n")
  3612  	expectPrintedNormalAndMangle(t, "a = '' + 0b0n", "a = \"\" + 0b0n;\n", "a = \"\" + 0b0n;\n")
  3613  	expectPrintedNormalAndMangle(t, "a = '' + 0o0n", "a = \"\" + 0o0n;\n", "a = \"\" + 0o0n;\n")
  3614  	expectPrintedNormalAndMangle(t, "a = '' + 0x0n", "a = \"\" + 0x0n;\n", "a = \"\" + 0x0n;\n")
  3615  
  3616  	expectPrintedNormalAndMangle(t, "a = '' + /a\\\\b/ig", "a = \"/a\\\\\\\\b/ig\";\n", "a = \"/a\\\\\\\\b/ig\";\n")
  3617  	expectPrintedNormalAndMangle(t, "a = /a\\\\b/ig + ''", "a = \"/a\\\\\\\\b/ig\";\n", "a = \"/a\\\\\\\\b/ig\";\n")
  3618  
  3619  	expectPrintedNormalAndMangle(t, "a = '' + ''.constructor", "a = \"function String() { [native code] }\";\n", "a = \"function String() { [native code] }\";\n")
  3620  	expectPrintedNormalAndMangle(t, "a = ''.constructor + ''", "a = \"function String() { [native code] }\";\n", "a = \"function String() { [native code] }\";\n")
  3621  	expectPrintedNormalAndMangle(t, "a = '' + /./.constructor", "a = \"function RegExp() { [native code] }\";\n", "a = \"function RegExp() { [native code] }\";\n")
  3622  	expectPrintedNormalAndMangle(t, "a = /./.constructor + ''", "a = \"function RegExp() { [native code] }\";\n", "a = \"function RegExp() { [native code] }\";\n")
  3623  }
  3624  
  3625  func TestMangleStringLength(t *testing.T) {
  3626  	expectPrinted(t, "a = ''.length", "a = \"\".length;\n")
  3627  	expectPrintedMangle(t, "''.length++", "\"\".length++;\n")
  3628  	expectPrintedMangle(t, "''.length = a", "\"\".length = a;\n")
  3629  
  3630  	expectPrintedMangle(t, "a = ''.len", "a = \"\".len;\n")
  3631  	expectPrintedMangle(t, "a = [].length", "a = [].length;\n")
  3632  	expectPrintedMangle(t, "a = ''.length", "a = 0;\n")
  3633  	expectPrintedMangle(t, "a = ``.length", "a = 0;\n")
  3634  	expectPrintedMangle(t, "a = b``.length", "a = b``.length;\n")
  3635  	expectPrintedMangle(t, "a = 'abc'.length", "a = 3;\n")
  3636  	expectPrintedMangle(t, "a = 'Č§įøƒÄ‹'.length", "a = 3;\n")
  3637  	expectPrintedMangle(t, "a = 'šŸ‘Æā€ā™‚ļø'.length", "a = 5;\n")
  3638  }
  3639  
  3640  func TestMangleStringIndex(t *testing.T) {
  3641  	expectPrinted(t, "a = 'abc'[0]", "a = \"abc\"[0];\n")
  3642  	expectPrintedMangle(t, "a = 'abc'[-1]", "a = \"abc\"[-1];\n")
  3643  	expectPrintedMangle(t, "a = 'abc'[-0]", "a = \"a\";\n")
  3644  	expectPrintedMangle(t, "a = 'abc'[0]", "a = \"a\";\n")
  3645  	expectPrintedMangle(t, "a = 'abc'[2]", "a = \"c\";\n")
  3646  	expectPrintedMangle(t, "a = 'abc'[3]", "a = \"abc\"[3];\n")
  3647  	expectPrintedMangle(t, "a = 'abc'[NaN]", "a = \"abc\"[NaN];\n")
  3648  	expectPrintedMangle(t, "a = 'abc'[-1e100]", "a = \"abc\"[-1e100];\n")
  3649  	expectPrintedMangle(t, "a = 'abc'[1e100]", "a = \"abc\"[1e100];\n")
  3650  	expectPrintedMangle(t, "a = 'abc'[-Infinity]", "a = \"abc\"[-Infinity];\n")
  3651  	expectPrintedMangle(t, "a = 'abc'[Infinity]", "a = \"abc\"[Infinity];\n")
  3652  }
  3653  
  3654  func TestMangleNot(t *testing.T) {
  3655  	// These can be mangled
  3656  	expectPrintedNormalAndMangle(t, "a = !(b == c)", "a = !(b == c);\n", "a = b != c;\n")
  3657  	expectPrintedNormalAndMangle(t, "a = !(b != c)", "a = !(b != c);\n", "a = b == c;\n")
  3658  	expectPrintedNormalAndMangle(t, "a = !(b === c)", "a = !(b === c);\n", "a = b !== c;\n")
  3659  	expectPrintedNormalAndMangle(t, "a = !(b !== c)", "a = !(b !== c);\n", "a = b === c;\n")
  3660  	expectPrintedNormalAndMangle(t, "if (!(a, b)) return c", "if (!(a, b)) return c;\n", "if (a, !b) return c;\n")
  3661  
  3662  	// These can't be mangled due to NaN and other special cases
  3663  	expectPrintedNormalAndMangle(t, "a = !(b < c)", "a = !(b < c);\n", "a = !(b < c);\n")
  3664  	expectPrintedNormalAndMangle(t, "a = !(b > c)", "a = !(b > c);\n", "a = !(b > c);\n")
  3665  	expectPrintedNormalAndMangle(t, "a = !(b <= c)", "a = !(b <= c);\n", "a = !(b <= c);\n")
  3666  	expectPrintedNormalAndMangle(t, "a = !(b >= c)", "a = !(b >= c);\n", "a = !(b >= c);\n")
  3667  }
  3668  
  3669  func TestMangleDoubleNot(t *testing.T) {
  3670  	expectPrintedNormalAndMangle(t, "a = !!b", "a = !!b;\n", "a = !!b;\n")
  3671  
  3672  	expectPrintedNormalAndMangle(t, "a = !!!b", "a = !!!b;\n", "a = !b;\n")
  3673  	expectPrintedNormalAndMangle(t, "a = !!-b", "a = !!-b;\n", "a = !!-b;\n")
  3674  	expectPrintedNormalAndMangle(t, "a = !!void b", "a = !!void b;\n", "a = !!void b;\n")
  3675  	expectPrintedNormalAndMangle(t, "a = !!delete b", "a = !!delete b;\n", "a = delete b;\n")
  3676  
  3677  	expectPrintedNormalAndMangle(t, "a = !!(b + c)", "a = !!(b + c);\n", "a = !!(b + c);\n")
  3678  	expectPrintedNormalAndMangle(t, "a = !!(b == c)", "a = !!(b == c);\n", "a = b == c;\n")
  3679  	expectPrintedNormalAndMangle(t, "a = !!(b != c)", "a = !!(b != c);\n", "a = b != c;\n")
  3680  	expectPrintedNormalAndMangle(t, "a = !!(b === c)", "a = !!(b === c);\n", "a = b === c;\n")
  3681  	expectPrintedNormalAndMangle(t, "a = !!(b !== c)", "a = !!(b !== c);\n", "a = b !== c;\n")
  3682  	expectPrintedNormalAndMangle(t, "a = !!(b < c)", "a = !!(b < c);\n", "a = b < c;\n")
  3683  	expectPrintedNormalAndMangle(t, "a = !!(b > c)", "a = !!(b > c);\n", "a = b > c;\n")
  3684  	expectPrintedNormalAndMangle(t, "a = !!(b <= c)", "a = !!(b <= c);\n", "a = b <= c;\n")
  3685  	expectPrintedNormalAndMangle(t, "a = !!(b >= c)", "a = !!(b >= c);\n", "a = b >= c;\n")
  3686  	expectPrintedNormalAndMangle(t, "a = !!(b in c)", "a = !!(b in c);\n", "a = b in c;\n")
  3687  	expectPrintedNormalAndMangle(t, "a = !!(b instanceof c)", "a = !!(b instanceof c);\n", "a = b instanceof c;\n")
  3688  
  3689  	expectPrintedNormalAndMangle(t, "a = !!(b && c)", "a = !!(b && c);\n", "a = !!(b && c);\n")
  3690  	expectPrintedNormalAndMangle(t, "a = !!(b || c)", "a = !!(b || c);\n", "a = !!(b || c);\n")
  3691  	expectPrintedNormalAndMangle(t, "a = !!(b ?? c)", "a = !!(b ?? c);\n", "a = !!(b ?? c);\n")
  3692  
  3693  	expectPrintedNormalAndMangle(t, "a = !!(!b && c)", "a = !!(!b && c);\n", "a = !!(!b && c);\n")
  3694  	expectPrintedNormalAndMangle(t, "a = !!(!b || c)", "a = !!(!b || c);\n", "a = !!(!b || c);\n")
  3695  	expectPrintedNormalAndMangle(t, "a = !!(!b ?? c)", "a = !!!b;\n", "a = !b;\n")
  3696  
  3697  	expectPrintedNormalAndMangle(t, "a = !!(b && !c)", "a = !!(b && !c);\n", "a = !!(b && !c);\n")
  3698  	expectPrintedNormalAndMangle(t, "a = !!(b || !c)", "a = !!(b || !c);\n", "a = !!(b || !c);\n")
  3699  	expectPrintedNormalAndMangle(t, "a = !!(b ?? !c)", "a = !!(b ?? !c);\n", "a = !!(b ?? !c);\n")
  3700  
  3701  	expectPrintedNormalAndMangle(t, "a = !!(!b && !c)", "a = !!(!b && !c);\n", "a = !b && !c;\n")
  3702  	expectPrintedNormalAndMangle(t, "a = !!(!b || !c)", "a = !!(!b || !c);\n", "a = !b || !c;\n")
  3703  	expectPrintedNormalAndMangle(t, "a = !!(!b ?? !c)", "a = !!!b;\n", "a = !b;\n")
  3704  
  3705  	expectPrintedNormalAndMangle(t, "a = !!(b, c)", "a = !!(b, c);\n", "a = (b, !!c);\n")
  3706  }
  3707  
  3708  func TestMangleBooleanConstructor(t *testing.T) {
  3709  	expectPrintedNormalAndMangle(t, "a = Boolean(b); var Boolean", "a = Boolean(b);\nvar Boolean;\n", "a = Boolean(b);\nvar Boolean;\n")
  3710  
  3711  	expectPrintedNormalAndMangle(t, "a = Boolean()", "a = Boolean();\n", "a = false;\n")
  3712  	expectPrintedNormalAndMangle(t, "a = Boolean(b)", "a = Boolean(b);\n", "a = !!b;\n")
  3713  	expectPrintedNormalAndMangle(t, "a = Boolean(!b)", "a = Boolean(!b);\n", "a = !b;\n")
  3714  	expectPrintedNormalAndMangle(t, "a = Boolean(!!b)", "a = Boolean(!!b);\n", "a = !!b;\n")
  3715  	expectPrintedNormalAndMangle(t, "a = Boolean(b ? true : false)", "a = Boolean(b ? true : false);\n", "a = !!b;\n")
  3716  	expectPrintedNormalAndMangle(t, "a = Boolean(b ? false : true)", "a = Boolean(b ? false : true);\n", "a = !b;\n")
  3717  	expectPrintedNormalAndMangle(t, "a = Boolean(b ? c > 0 : c < 0)", "a = Boolean(b ? c > 0 : c < 0);\n", "a = b ? c > 0 : c < 0;\n")
  3718  
  3719  	// Check for calling "SimplifyBooleanExpr" on the argument
  3720  	expectPrintedNormalAndMangle(t, "a = Boolean((b | c) !== 0)", "a = Boolean((b | c) !== 0);\n", "a = !!(b | c);\n")
  3721  	expectPrintedNormalAndMangle(t, "a = Boolean(b ? (c | d) !== 0 : (d | e) !== 0)", "a = Boolean(b ? (c | d) !== 0 : (d | e) !== 0);\n", "a = !!(b ? c | d : d | e);\n")
  3722  }
  3723  
  3724  func TestMangleNumberConstructor(t *testing.T) {
  3725  	expectPrintedNormalAndMangle(t, "a = Number(x)", "a = Number(x);\n", "a = Number(x);\n")
  3726  	expectPrintedNormalAndMangle(t, "a = Number(0n)", "a = Number(0n);\n", "a = Number(0n);\n")
  3727  	expectPrintedNormalAndMangle(t, "a = Number(false); var Number", "a = Number(false);\nvar Number;\n", "a = Number(false);\nvar Number;\n")
  3728  	expectPrintedNormalAndMangle(t, "a = Number(0xFFFF_FFFF_FFFF_FFFFn)", "a = Number(0xFFFFFFFFFFFFFFFFn);\n", "a = Number(0xFFFFFFFFFFFFFFFFn);\n")
  3729  
  3730  	expectPrintedNormalAndMangle(t, "a = Number()", "a = Number();\n", "a = 0;\n")
  3731  	expectPrintedNormalAndMangle(t, "a = Number(-123)", "a = Number(-123);\n", "a = -123;\n")
  3732  	expectPrintedNormalAndMangle(t, "a = Number(false)", "a = Number(false);\n", "a = 0;\n")
  3733  	expectPrintedNormalAndMangle(t, "a = Number(true)", "a = Number(true);\n", "a = 1;\n")
  3734  	expectPrintedNormalAndMangle(t, "a = Number(undefined)", "a = Number(void 0);\n", "a = NaN;\n")
  3735  	expectPrintedNormalAndMangle(t, "a = Number(null)", "a = Number(null);\n", "a = 0;\n")
  3736  	expectPrintedNormalAndMangle(t, "a = Number(b ? !c : !d)", "a = Number(b ? !c : !d);\n", "a = +(b ? !c : !d);\n")
  3737  }
  3738  
  3739  func TestMangleStringConstructor(t *testing.T) {
  3740  	expectPrintedNormalAndMangle(t, "a = String(x)", "a = String(x);\n", "a = String(x);\n")
  3741  	expectPrintedNormalAndMangle(t, "a = String('x'); var String", "a = String(\"x\");\nvar String;\n", "a = String(\"x\");\nvar String;\n")
  3742  
  3743  	expectPrintedNormalAndMangle(t, "a = String()", "a = String();\n", "a = \"\";\n")
  3744  	expectPrintedNormalAndMangle(t, "a = String('x')", "a = String(\"x\");\n", "a = \"x\";\n")
  3745  	expectPrintedNormalAndMangle(t, "a = String(b ? 'x' : 'y')", "a = String(b ? \"x\" : \"y\");\n", "a = b ? \"x\" : \"y\";\n")
  3746  }
  3747  
  3748  func TestMangleBigIntConstructor(t *testing.T) {
  3749  	expectPrintedNormalAndMangle(t, "a = BigInt(x)", "a = BigInt(x);\n", "a = BigInt(x);\n")
  3750  	expectPrintedNormalAndMangle(t, "a = BigInt(0n); var BigInt", "a = BigInt(0n);\nvar BigInt;\n", "a = BigInt(0n);\nvar BigInt;\n")
  3751  
  3752  	// Note: This throws instead of returning "0n"
  3753  	expectPrintedNormalAndMangle(t, "a = BigInt()", "a = BigInt();\n", "a = BigInt();\n")
  3754  
  3755  	// Note: Transforming this into "0n" is unsafe because that syntax may not be supported
  3756  	expectPrintedNormalAndMangle(t, "a = BigInt('0')", "a = BigInt(\"0\");\n", "a = BigInt(\"0\");\n")
  3757  
  3758  	expectPrintedNormalAndMangle(t, "a = BigInt(0n)", "a = BigInt(0n);\n", "a = 0n;\n")
  3759  	expectPrintedNormalAndMangle(t, "a = BigInt(b ? 0n : 1n)", "a = BigInt(b ? 0n : 1n);\n", "a = b ? 0n : 1n;\n")
  3760  }
  3761  
  3762  func TestMangleCharCodeAt(t *testing.T) {
  3763  	expectPrinted(t, "a = 'xy'.charCodeAt(0)", "a = \"xy\".charCodeAt(0);\n")
  3764  
  3765  	expectPrintedMangle(t, "a = 'xy'.charCodeAt()", "a = 120;\n")
  3766  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(0)", "a = 120;\n")
  3767  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(1)", "a = 121;\n")
  3768  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(-1)", "a = NaN;\n")
  3769  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(2)", "a = NaN;\n")
  3770  
  3771  	expectPrintedMangle(t, "a = 'šŸ§€'.charCodeAt()", "a = 55358;\n")
  3772  	expectPrintedMangle(t, "a = 'šŸ§€'.charCodeAt(0)", "a = 55358;\n")
  3773  	expectPrintedMangle(t, "a = 'šŸ§€'.charCodeAt(1)", "a = 56768;\n")
  3774  	expectPrintedMangle(t, "a = 'šŸ§€'.charCodeAt(-1)", "a = NaN;\n")
  3775  	expectPrintedMangle(t, "a = 'šŸ§€'.charCodeAt(2)", "a = NaN;\n")
  3776  
  3777  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(NaN)", "a = \"xy\".charCodeAt(NaN);\n")
  3778  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(-Infinity)", "a = \"xy\".charCodeAt(-Infinity);\n")
  3779  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(Infinity)", "a = \"xy\".charCodeAt(Infinity);\n")
  3780  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(0.5)", "a = \"xy\".charCodeAt(0.5);\n")
  3781  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(1e99)", "a = \"xy\".charCodeAt(1e99);\n")
  3782  	expectPrintedMangle(t, "a = 'xy'.charCodeAt('1')", "a = \"xy\".charCodeAt(\"1\");\n")
  3783  	expectPrintedMangle(t, "a = 'xy'.charCodeAt(1, 2)", "a = \"xy\".charCodeAt(1, 2);\n")
  3784  }
  3785  
  3786  func TestMangleFromCharCode(t *testing.T) {
  3787  	expectPrinted(t, "a = String.fromCharCode(120, 121)", "a = String.fromCharCode(120, 121);\n")
  3788  
  3789  	expectPrintedMangle(t, "a = String.fromCharCode()", "a = \"\";\n")
  3790  	expectPrintedMangle(t, "a = String.fromCharCode(0)", "a = \"\\0\";\n")
  3791  	expectPrintedMangle(t, "a = String.fromCharCode(120)", "a = \"x\";\n")
  3792  	expectPrintedMangle(t, "a = String.fromCharCode(120, 121)", "a = \"xy\";\n")
  3793  	expectPrintedMangle(t, "a = String.fromCharCode(55358, 56768)", "a = \"šŸ§€\";\n")
  3794  	expectPrintedMangle(t, "a = String.fromCharCode(0x10000)", "a = \"\\0\";\n")
  3795  	expectPrintedMangle(t, "a = String.fromCharCode(0x10078, 0x10079)", "a = \"xy\";\n")
  3796  	expectPrintedMangle(t, "a = String.fromCharCode(0x1_0000_FFFF)", "a = \"\uFFFF\";\n")
  3797  	expectPrintedMangle(t, "a = String.fromCharCode(NaN)", "a = \"\\0\";\n")
  3798  	expectPrintedMangle(t, "a = String.fromCharCode(-Infinity)", "a = \"\\0\";\n")
  3799  	expectPrintedMangle(t, "a = String.fromCharCode(Infinity)", "a = \"\\0\";\n")
  3800  	expectPrintedMangle(t, "a = String.fromCharCode(null)", "a = \"\\0\";\n")
  3801  	expectPrintedMangle(t, "a = String.fromCharCode(undefined)", "a = \"\\0\";\n")
  3802  	expectPrintedMangle(t, "a = String.fromCharCode('123')", "a = \"{\";\n")
  3803  
  3804  	expectPrintedMangle(t, "a = String.fromCharCode(x)", "a = String.fromCharCode(x);\n")
  3805  	expectPrintedMangle(t, "a = String.fromCharCode('x')", "a = String.fromCharCode(\"x\");\n")
  3806  	expectPrintedMangle(t, "a = String.fromCharCode('0.5')", "a = String.fromCharCode(\"0.5\");\n")
  3807  }
  3808  
  3809  func TestMangleToString(t *testing.T) {
  3810  	expectPrinted(t, "a = \"xy\".toString()", "a = \"xy\".toString();\n")
  3811  
  3812  	expectPrintedMangle(t, "a = false.toString()", "a = \"false\";\n")
  3813  	expectPrintedMangle(t, "a = true.toString()", "a = \"true\";\n")
  3814  	expectPrintedMangle(t, "a = \"xy\".toString()", "a = \"xy\";\n")
  3815  	expectPrintedMangle(t, "a = 0 .toString()", "a = \"0\";\n")
  3816  	expectPrintedMangle(t, "a = (-0).toString()", "a = \"0\";\n")
  3817  	expectPrintedMangle(t, "a = 123 .toString()", "a = \"123\";\n")
  3818  	expectPrintedMangle(t, "a = (-123).toString()", "a = \"-123\";\n")
  3819  	expectPrintedMangle(t, "a = NaN.toString()", "a = \"NaN\";\n")
  3820  	expectPrintedMangle(t, "a = Infinity.toString()", "a = \"Infinity\";\n")
  3821  	expectPrintedMangle(t, "a = (-Infinity).toString()", "a = \"-Infinity\";\n")
  3822  	expectPrintedMangle(t, "a = /a\\\\b/ig.toString()", "a = \"/a\\\\\\\\b/ig\";\n")
  3823  
  3824  	// Handle a radix other than 10
  3825  	expectPrintedMangle(t, "a = 100 .toString(0)", "a = 100 .toString(0);\n")
  3826  	expectPrintedMangle(t, "a = 100 .toString(1)", "a = 100 .toString(1);\n")
  3827  	expectPrintedMangle(t, "a = 100 .toString(2)", "a = \"1100100\";\n")
  3828  	expectPrintedMangle(t, "a = 100 .toString(5)", "a = \"400\";\n")
  3829  	expectPrintedMangle(t, "a = 100 .toString(8)", "a = \"144\";\n")
  3830  	expectPrintedMangle(t, "a = 100 .toString(13)", "a = \"79\";\n")
  3831  	expectPrintedMangle(t, "a = 100 .toString(16)", "a = \"64\";\n")
  3832  	expectPrintedMangle(t, "a = 10000 .toString(19)", "a = \"18d6\";\n")
  3833  	expectPrintedMangle(t, "a = 10000 .toString(23)", "a = \"iki\";\n")
  3834  	expectPrintedMangle(t, "a = 1000000 .toString(29)", "a = \"1c01m\";\n")
  3835  	expectPrintedMangle(t, "a = 1000000 .toString(31)", "a = \"12hi2\";\n")
  3836  	expectPrintedMangle(t, "a = 1000000 .toString(36)", "a = \"lfls\";\n")
  3837  	expectPrintedMangle(t, "a = (-1000000).toString(36)", "a = \"-lfls\";\n")
  3838  	expectPrintedMangle(t, "a = 0 .toString(36)", "a = \"0\";\n")
  3839  	expectPrintedMangle(t, "a = (-0).toString(36)", "a = \"0\";\n")
  3840  
  3841  	expectPrintedMangle(t, "a = false.toString(b)", "a = false.toString(b);\n")
  3842  	expectPrintedMangle(t, "a = true.toString(b)", "a = true.toString(b);\n")
  3843  	expectPrintedMangle(t, "a = \"xy\".toString(b)", "a = \"xy\".toString(b);\n")
  3844  	expectPrintedMangle(t, "a = 123 .toString(b)", "a = 123 .toString(b);\n")
  3845  	expectPrintedMangle(t, "a = 0.5.toString()", "a = 0.5.toString();\n")
  3846  	expectPrintedMangle(t, "a = 1e99.toString(b)", "a = 1e99.toString(b);\n")
  3847  	expectPrintedMangle(t, "a = /./.toString(b)", "a = /./.toString(b);\n")
  3848  }
  3849  
  3850  func TestMangleIf(t *testing.T) {
  3851  	expectPrintedNormalAndMangle(t, "1 ? a() : b()", "1 ? a() : b();\n", "a();\n")
  3852  	expectPrintedNormalAndMangle(t, "0 ? a() : b()", "0 ? a() : b();\n", "b();\n")
  3853  
  3854  	expectPrintedNormalAndMangle(t, "a ? a : b", "a ? a : b;\n", "a || b;\n")
  3855  	expectPrintedNormalAndMangle(t, "a ? b : a", "a ? b : a;\n", "a && b;\n")
  3856  	expectPrintedNormalAndMangle(t, "a.x ? a.x : b", "a.x ? a.x : b;\n", "a.x ? a.x : b;\n")
  3857  	expectPrintedNormalAndMangle(t, "a.x ? b : a.x", "a.x ? b : a.x;\n", "a.x ? b : a.x;\n")
  3858  
  3859  	expectPrintedNormalAndMangle(t, "a ? b() : c()", "a ? b() : c();\n", "a ? b() : c();\n")
  3860  	expectPrintedNormalAndMangle(t, "!a ? b() : c()", "!a ? b() : c();\n", "a ? c() : b();\n")
  3861  	expectPrintedNormalAndMangle(t, "!!a ? b() : c()", "!!a ? b() : c();\n", "a ? b() : c();\n")
  3862  	expectPrintedNormalAndMangle(t, "!!!a ? b() : c()", "!!!a ? b() : c();\n", "a ? c() : b();\n")
  3863  
  3864  	expectPrintedNormalAndMangle(t, "if (1) a(); else b()", "if (1) a();\nelse b();\n", "a();\n")
  3865  	expectPrintedNormalAndMangle(t, "if (0) a(); else b()", "if (0) a();\nelse b();\n", "b();\n")
  3866  	expectPrintedNormalAndMangle(t, "if (a) b(); else c()", "if (a) b();\nelse c();\n", "a ? b() : c();\n")
  3867  	expectPrintedNormalAndMangle(t, "if (!a) b(); else c()", "if (!a) b();\nelse c();\n", "a ? c() : b();\n")
  3868  	expectPrintedNormalAndMangle(t, "if (!!a) b(); else c()", "if (!!a) b();\nelse c();\n", "a ? b() : c();\n")
  3869  	expectPrintedNormalAndMangle(t, "if (!!!a) b(); else c()", "if (!!!a) b();\nelse c();\n", "a ? c() : b();\n")
  3870  
  3871  	expectPrintedNormalAndMangle(t, "if (1) a()", "if (1) a();\n", "a();\n")
  3872  	expectPrintedNormalAndMangle(t, "if (0) a()", "if (0) a();\n", "")
  3873  	expectPrintedNormalAndMangle(t, "if (a) b()", "if (a) b();\n", "a && b();\n")
  3874  	expectPrintedNormalAndMangle(t, "if (!a) b()", "if (!a) b();\n", "a || b();\n")
  3875  	expectPrintedNormalAndMangle(t, "if (!!a) b()", "if (!!a) b();\n", "a && b();\n")
  3876  	expectPrintedNormalAndMangle(t, "if (!!!a) b()", "if (!!!a) b();\n", "a || b();\n")
  3877  
  3878  	expectPrintedNormalAndMangle(t, "if (1) {} else a()", "if (1) {\n} else a();\n", "")
  3879  	expectPrintedNormalAndMangle(t, "if (0) {} else a()", "if (0) {\n} else a();\n", "a();\n")
  3880  	expectPrintedNormalAndMangle(t, "if (a) {} else b()", "if (a) {\n} else b();\n", "a || b();\n")
  3881  	expectPrintedNormalAndMangle(t, "if (!a) {} else b()", "if (!a) {\n} else b();\n", "a && b();\n")
  3882  	expectPrintedNormalAndMangle(t, "if (!!a) {} else b()", "if (!!a) {\n} else b();\n", "a || b();\n")
  3883  	expectPrintedNormalAndMangle(t, "if (!!!a) {} else b()", "if (!!!a) {\n} else b();\n", "a && b();\n")
  3884  
  3885  	expectPrintedNormalAndMangle(t, "if (a) {} else throw b", "if (a) {\n} else throw b;\n", "if (!a)\n  throw b;\n")
  3886  	expectPrintedNormalAndMangle(t, "if (!a) {} else throw b", "if (!a) {\n} else throw b;\n", "if (a)\n  throw b;\n")
  3887  	expectPrintedNormalAndMangle(t, "a(); if (b) throw c", "a();\nif (b) throw c;\n", "if (a(), b) throw c;\n")
  3888  	expectPrintedNormalAndMangle(t, "if (a) if (b) throw c", "if (a) {\n  if (b) throw c;\n}\n", "if (a && b) throw c;\n")
  3889  
  3890  	expectPrintedMangle(t, "if (true) { let a = b; if (c) throw d }",
  3891  		"{\n  let a = b;\n  if (c) throw d;\n}\n")
  3892  	expectPrintedMangle(t, "if (true) { if (a) throw b; if (c) throw d }",
  3893  		"if (a) throw b;\nif (c) throw d;\n")
  3894  
  3895  	expectPrintedMangle(t, "if (false) throw a; else { let b = c; if (d) throw e }",
  3896  		"{\n  let b = c;\n  if (d) throw e;\n}\n")
  3897  	expectPrintedMangle(t, "if (false) throw a; else { if (b) throw c; if (d) throw e }",
  3898  		"if (b) throw c;\nif (d) throw e;\n")
  3899  
  3900  	expectPrintedMangle(t, "if (a) { if (b) throw c; else { let d = e; if (f) throw g } }",
  3901  		"if (a) {\n  if (b) throw c;\n  {\n    let d = e;\n    if (f) throw g;\n  }\n}\n")
  3902  	expectPrintedMangle(t, "if (a) { if (b) throw c; else if (d) throw e; else if (f) throw g }",
  3903  		"if (a) {\n  if (b) throw c;\n  if (d) throw e;\n  if (f) throw g;\n}\n")
  3904  
  3905  	expectPrintedNormalAndMangle(t, "a = b ? true : false", "a = b ? true : false;\n", "a = !!b;\n")
  3906  	expectPrintedNormalAndMangle(t, "a = b ? false : true", "a = b ? false : true;\n", "a = !b;\n")
  3907  	expectPrintedNormalAndMangle(t, "a = !b ? true : false", "a = !b ? true : false;\n", "a = !b;\n")
  3908  	expectPrintedNormalAndMangle(t, "a = !b ? false : true", "a = !b ? false : true;\n", "a = !!b;\n")
  3909  
  3910  	expectPrintedNormalAndMangle(t, "a = b == c ? true : false", "a = b == c ? true : false;\n", "a = b == c;\n")
  3911  	expectPrintedNormalAndMangle(t, "a = b != c ? true : false", "a = b != c ? true : false;\n", "a = b != c;\n")
  3912  	expectPrintedNormalAndMangle(t, "a = b === c ? true : false", "a = b === c ? true : false;\n", "a = b === c;\n")
  3913  	expectPrintedNormalAndMangle(t, "a = b !== c ? true : false", "a = b !== c ? true : false;\n", "a = b !== c;\n")
  3914  
  3915  	expectPrintedNormalAndMangle(t, "a ? b(c) : b(d)", "a ? b(c) : b(d);\n", "a ? b(c) : b(d);\n")
  3916  	expectPrintedNormalAndMangle(t, "let a; a ? b(c) : b(d)", "let a;\na ? b(c) : b(d);\n", "let a;\na ? b(c) : b(d);\n")
  3917  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(c) : b(d)", "let a, b;\na ? b(c) : b(d);\n", "let a, b;\nb(a ? c : d);\n")
  3918  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(c, 0) : b(d)", "let a, b;\na ? b(c, 0) : b(d);\n", "let a, b;\na ? b(c, 0) : b(d);\n")
  3919  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(c) : b(d, 0)", "let a, b;\na ? b(c) : b(d, 0);\n", "let a, b;\na ? b(c) : b(d, 0);\n")
  3920  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(c, 0) : b(d, 1)", "let a, b;\na ? b(c, 0) : b(d, 1);\n", "let a, b;\na ? b(c, 0) : b(d, 1);\n")
  3921  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(c, 0) : b(d, 0)", "let a, b;\na ? b(c, 0) : b(d, 0);\n", "let a, b;\nb(a ? c : d, 0);\n")
  3922  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(...c) : b(d)", "let a, b;\na ? b(...c) : b(d);\n", "let a, b;\na ? b(...c) : b(d);\n")
  3923  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(c) : b(...d)", "let a, b;\na ? b(c) : b(...d);\n", "let a, b;\na ? b(c) : b(...d);\n")
  3924  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(...c) : b(...d)", "let a, b;\na ? b(...c) : b(...d);\n", "let a, b;\nb(...a ? c : d);\n")
  3925  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(a) : b(c)", "let a, b;\na ? b(a) : b(c);\n", "let a, b;\nb(a || c);\n")
  3926  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(c) : b(a)", "let a, b;\na ? b(c) : b(a);\n", "let a, b;\nb(a && c);\n")
  3927  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(...a) : b(...c)", "let a, b;\na ? b(...a) : b(...c);\n", "let a, b;\nb(...a || c);\n")
  3928  	expectPrintedNormalAndMangle(t, "let a, b; a ? b(...c) : b(...a)", "let a, b;\na ? b(...c) : b(...a);\n", "let a, b;\nb(...a && c);\n")
  3929  
  3930  	// Note: "a.x" may change "b" and "b.y" may change "a" in the examples
  3931  	// below, so the presence of these expressions must prevent reordering
  3932  	expectPrintedNormalAndMangle(t, "let a; a.x ? b(c) : b(d)", "let a;\na.x ? b(c) : b(d);\n", "let a;\na.x ? b(c) : b(d);\n")
  3933  	expectPrintedNormalAndMangle(t, "let a, b; a.x ? b(c) : b(d)", "let a, b;\na.x ? b(c) : b(d);\n", "let a, b;\na.x ? b(c) : b(d);\n")
  3934  	expectPrintedNormalAndMangle(t, "let a, b; a ? b.y(c) : b.y(d)", "let a, b;\na ? b.y(c) : b.y(d);\n", "let a, b;\na ? b.y(c) : b.y(d);\n")
  3935  	expectPrintedNormalAndMangle(t, "let a, b; a.x ? b.y(c) : b.y(d)", "let a, b;\na.x ? b.y(c) : b.y(d);\n", "let a, b;\na.x ? b.y(c) : b.y(d);\n")
  3936  
  3937  	expectPrintedNormalAndMangle(t, "a ? b : c ? b : d", "a ? b : c ? b : d;\n", "a || c ? b : d;\n")
  3938  	expectPrintedNormalAndMangle(t, "a ? b ? c : d : d", "a ? b ? c : d : d;\n", "a && b ? c : d;\n")
  3939  
  3940  	expectPrintedNormalAndMangle(t, "a ? c : (b, c)", "a ? c : (b, c);\n", "a || b, c;\n")
  3941  	expectPrintedNormalAndMangle(t, "a ? (b, c) : c", "a ? (b, c) : c;\n", "a && b, c;\n")
  3942  	expectPrintedNormalAndMangle(t, "a ? c : (b, d)", "a ? c : (b, d);\n", "a ? c : (b, d);\n")
  3943  	expectPrintedNormalAndMangle(t, "a ? (b, c) : d", "a ? (b, c) : d;\n", "a ? (b, c) : d;\n")
  3944  
  3945  	expectPrintedNormalAndMangle(t, "a ? b || c : c", "a ? b || c : c;\n", "a && b || c;\n")
  3946  	expectPrintedNormalAndMangle(t, "a ? b || c : d", "a ? b || c : d;\n", "a ? b || c : d;\n")
  3947  	expectPrintedNormalAndMangle(t, "a ? b && c : c", "a ? b && c : c;\n", "a ? b && c : c;\n")
  3948  
  3949  	expectPrintedNormalAndMangle(t, "a ? c : b && c", "a ? c : b && c;\n", "(a || b) && c;\n")
  3950  	expectPrintedNormalAndMangle(t, "a ? c : b && d", "a ? c : b && d;\n", "a ? c : b && d;\n")
  3951  	expectPrintedNormalAndMangle(t, "a ? c : b || c", "a ? c : b || c;\n", "a ? c : b || c;\n")
  3952  
  3953  	expectPrintedNormalAndMangle(t, "a = b == null ? c : b", "a = b == null ? c : b;\n", "a = b == null ? c : b;\n")
  3954  	expectPrintedNormalAndMangle(t, "a = b != null ? b : c", "a = b != null ? b : c;\n", "a = b != null ? b : c;\n")
  3955  
  3956  	expectPrintedNormalAndMangle(t, "let b; a = b == null ? c : b", "let b;\na = b == null ? c : b;\n", "let b;\na = b ?? c;\n")
  3957  	expectPrintedNormalAndMangle(t, "let b; a = b != null ? b : c", "let b;\na = b != null ? b : c;\n", "let b;\na = b ?? c;\n")
  3958  	expectPrintedNormalAndMangle(t, "let b; a = b == null ? b : c", "let b;\na = b == null ? b : c;\n", "let b;\na = b == null ? b : c;\n")
  3959  	expectPrintedNormalAndMangle(t, "let b; a = b != null ? c : b", "let b;\na = b != null ? c : b;\n", "let b;\na = b != null ? c : b;\n")
  3960  
  3961  	expectPrintedNormalAndMangle(t, "let b; a = null == b ? c : b", "let b;\na = null == b ? c : b;\n", "let b;\na = b ?? c;\n")
  3962  	expectPrintedNormalAndMangle(t, "let b; a = null != b ? b : c", "let b;\na = null != b ? b : c;\n", "let b;\na = b ?? c;\n")
  3963  	expectPrintedNormalAndMangle(t, "let b; a = null == b ? b : c", "let b;\na = null == b ? b : c;\n", "let b;\na = b == null ? b : c;\n")
  3964  	expectPrintedNormalAndMangle(t, "let b; a = null != b ? c : b", "let b;\na = null != b ? c : b;\n", "let b;\na = b != null ? c : b;\n")
  3965  
  3966  	// Don't do this if the condition has side effects
  3967  	expectPrintedNormalAndMangle(t, "let b; a = b.x == null ? c : b.x", "let b;\na = b.x == null ? c : b.x;\n", "let b;\na = b.x == null ? c : b.x;\n")
  3968  	expectPrintedNormalAndMangle(t, "let b; a = b.x != null ? b.x : c", "let b;\na = b.x != null ? b.x : c;\n", "let b;\na = b.x != null ? b.x : c;\n")
  3969  	expectPrintedNormalAndMangle(t, "let b; a = null == b.x ? c : b.x", "let b;\na = null == b.x ? c : b.x;\n", "let b;\na = b.x == null ? c : b.x;\n")
  3970  	expectPrintedNormalAndMangle(t, "let b; a = null != b.x ? b.x : c", "let b;\na = null != b.x ? b.x : c;\n", "let b;\na = b.x != null ? b.x : c;\n")
  3971  
  3972  	// Don't do this for strict equality comparisons
  3973  	expectPrintedNormalAndMangle(t, "let b; a = b === null ? c : b", "let b;\na = b === null ? c : b;\n", "let b;\na = b === null ? c : b;\n")
  3974  	expectPrintedNormalAndMangle(t, "let b; a = b !== null ? b : c", "let b;\na = b !== null ? b : c;\n", "let b;\na = b !== null ? b : c;\n")
  3975  	expectPrintedNormalAndMangle(t, "let b; a = null === b ? c : b", "let b;\na = null === b ? c : b;\n", "let b;\na = b === null ? c : b;\n")
  3976  	expectPrintedNormalAndMangle(t, "let b; a = null !== b ? b : c", "let b;\na = null !== b ? b : c;\n", "let b;\na = b !== null ? b : c;\n")
  3977  
  3978  	expectPrintedNormalAndMangle(t, "let b; a = null === b || b === undefined ? c : b", "let b;\na = null === b || b === void 0 ? c : b;\n", "let b;\na = b ?? c;\n")
  3979  	expectPrintedNormalAndMangle(t, "let b; a = b !== undefined && b !== null ? b : c", "let b;\na = b !== void 0 && b !== null ? b : c;\n", "let b;\na = b ?? c;\n")
  3980  
  3981  	// Distinguish between negative an non-negative zero (i.e. Object.is)
  3982  	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
  3983  	expectPrintedNormalAndMangle(t, "a(b ? 0 : 0)", "a(b ? 0 : 0);\n", "a((b, 0));\n")
  3984  	expectPrintedNormalAndMangle(t, "a(b ? +0 : -0)", "a(b ? 0 : -0);\n", "a(b ? 0 : -0);\n")
  3985  	expectPrintedNormalAndMangle(t, "a(b ? +0 : 0)", "a(b ? 0 : 0);\n", "a((b, 0));\n")
  3986  	expectPrintedNormalAndMangle(t, "a(b ? -0 : 0)", "a(b ? -0 : 0);\n", "a(b ? -0 : 0);\n")
  3987  
  3988  	expectPrintedNormalAndMangle(t, "a ? b : b", "a ? b : b;\n", "a, b;\n")
  3989  	expectPrintedNormalAndMangle(t, "let a; a ? b : b", "let a;\na ? b : b;\n", "let a;\nb;\n")
  3990  
  3991  	expectPrintedNormalAndMangle(t, "a ? -b : -b", "a ? -b : -b;\n", "a, -b;\n")
  3992  	expectPrintedNormalAndMangle(t, "a ? b.c : b.c", "a ? b.c : b.c;\n", "a, b.c;\n")
  3993  	expectPrintedNormalAndMangle(t, "a ? b?.c : b?.c", "a ? b?.c : b?.c;\n", "a, b?.c;\n")
  3994  	expectPrintedNormalAndMangle(t, "a ? b[c] : b[c]", "a ? b[c] : b[c];\n", "a, b[c];\n")
  3995  	expectPrintedNormalAndMangle(t, "a ? b() : b()", "a ? b() : b();\n", "a, b();\n")
  3996  	expectPrintedNormalAndMangle(t, "a ? b?.() : b?.()", "a ? b?.() : b?.();\n", "a, b?.();\n")
  3997  	expectPrintedNormalAndMangle(t, "a ? b?.[c] : b?.[c]", "a ? b?.[c] : b?.[c];\n", "a, b?.[c];\n")
  3998  	expectPrintedNormalAndMangle(t, "a ? b == c : b == c", "a ? b == c : b == c;\n", "a, b == c;\n")
  3999  	expectPrintedNormalAndMangle(t, "a ? b.c(d + e[f]) : b.c(d + e[f])", "a ? b.c(d + e[f]) : b.c(d + e[f]);\n", "a, b.c(d + e[f]);\n")
  4000  
  4001  	expectPrintedNormalAndMangle(t, "a ? -b : !b", "a ? -b : !b;\n", "a ? -b : b;\n")
  4002  	expectPrintedNormalAndMangle(t, "a ? b() : b(c)", "a ? b() : b(c);\n", "a ? b() : b(c);\n")
  4003  	expectPrintedNormalAndMangle(t, "a ? b(c) : b(d)", "a ? b(c) : b(d);\n", "a ? b(c) : b(d);\n")
  4004  	expectPrintedNormalAndMangle(t, "a ? b?.c : b.c", "a ? b?.c : b.c;\n", "a ? b?.c : b.c;\n")
  4005  	expectPrintedNormalAndMangle(t, "a ? b?.() : b()", "a ? b?.() : b();\n", "a ? b?.() : b();\n")
  4006  	expectPrintedNormalAndMangle(t, "a ? b?.[c] : b[c]", "a ? b?.[c] : b[c];\n", "a ? b?.[c] : b[c];\n")
  4007  	expectPrintedNormalAndMangle(t, "a ? b == c : b != c", "a ? b == c : b != c;\n", "a ? b == c : b != c;\n")
  4008  	expectPrintedNormalAndMangle(t, "a ? b.c(d + e[f]) : b.c(d + e[g])", "a ? b.c(d + e[f]) : b.c(d + e[g]);\n", "a ? b.c(d + e[f]) : b.c(d + e[g]);\n")
  4009  
  4010  	expectPrintedNormalAndMangle(t, "(a, b) ? c : d", "(a, b) ? c : d;\n", "a, b ? c : d;\n")
  4011  
  4012  	expectPrintedNormalAndMangle(t, "return a && ((b && c) && (d && e))", "return a && (b && c && (d && e));\n", "return a && b && c && d && e;\n")
  4013  	expectPrintedNormalAndMangle(t, "return a || ((b || c) || (d || e))", "return a || (b || c || (d || e));\n", "return a || b || c || d || e;\n")
  4014  	expectPrintedNormalAndMangle(t, "return a ?? ((b ?? c) ?? (d ?? e))", "return a ?? (b ?? c ?? (d ?? e));\n", "return a ?? b ?? c ?? d ?? e;\n")
  4015  	expectPrintedNormalAndMangle(t, "if (a) if (b) if (c) d", "if (a) {\n  if (b) {\n    if (c) d;\n  }\n}\n", "a && b && c && d;\n")
  4016  	expectPrintedNormalAndMangle(t, "if (!a) if (!b) if (!c) d", "if (!a) {\n  if (!b) {\n    if (!c) d;\n  }\n}\n", "a || b || c || d;\n")
  4017  	expectPrintedNormalAndMangle(t, "let a, b, c; return a != null ? a : b != null ? b : c", "let a, b, c;\nreturn a != null ? a : b != null ? b : c;\n", "let a, b, c;\nreturn a ?? b ?? c;\n")
  4018  
  4019  	expectPrintedMangle(t, "if (a) return c; if (b) return d;", "if (a) return c;\nif (b) return d;\n")
  4020  	expectPrintedMangle(t, "if (a) return c; if (b) return c;", "if (a || b) return c;\n")
  4021  	expectPrintedMangle(t, "if (a) return c; if (b) return;", "if (a) return c;\nif (b) return;\n")
  4022  	expectPrintedMangle(t, "if (a) return; if (b) return c;", "if (a) return;\nif (b) return c;\n")
  4023  	expectPrintedMangle(t, "if (a) return; if (b) return;", "if (a || b) return;\n")
  4024  	expectPrintedMangle(t, "if (a) throw c; if (b) throw d;", "if (a) throw c;\nif (b) throw d;\n")
  4025  	expectPrintedMangle(t, "if (a) throw c; if (b) throw c;", "if (a || b) throw c;\n")
  4026  	expectPrintedMangle(t, "while (x) { if (a) break; if (b) break; }", "for (; x && !(a || b); )\n  ;\n")
  4027  	expectPrintedMangle(t, "while (x) { if (a) continue; if (b) continue; }", "for (; x; )\n  a || b;\n")
  4028  	expectPrintedMangle(t, "while (x) { debugger; if (a) break; if (b) break; }", "for (; x; ) {\n  debugger;\n  if (a || b) break;\n}\n")
  4029  	expectPrintedMangle(t, "while (x) { debugger; if (a) continue; if (b) continue; }", "for (; x; ) {\n  debugger;\n  a || b;\n}\n")
  4030  	expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) break x; if (b) break y; }",
  4031  		"x: for (; x; ) y: for (; y; ) {\n  if (a) break x;\n  if (b) break y;\n}\n")
  4032  	expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) continue x; if (b) continue y; }",
  4033  		"x: for (; x; ) y: for (; y; ) {\n  if (a) continue x;\n  if (b) continue y;\n}\n")
  4034  	expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) break x; if (b) break x; }",
  4035  		"x: for (; x; ) for (; y; )\n  if (a || b) break x;\n")
  4036  	expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) continue x; if (b) continue x; }",
  4037  		"x: for (; x; ) for (; y; )\n  if (a || b) continue x;\n")
  4038  	expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) break y; if (b) break y; }",
  4039  		"for (; x; ) y: for (; y; )\n  if (a || b) break y;\n")
  4040  	expectPrintedMangle(t, "x: while (x) y: while (y) { if (a) continue y; if (b) continue y; }",
  4041  		"for (; x; ) y: for (; y; )\n  if (a || b) continue y;\n")
  4042  
  4043  	expectPrintedNormalAndMangle(t, "if (x ? y : 0) foo()", "if (x ? y : 0) foo();\n", "x && y && foo();\n")
  4044  	expectPrintedNormalAndMangle(t, "if (x ? y : 1) foo()", "if (x ? y : 1) foo();\n", "(!x || y) && foo();\n")
  4045  	expectPrintedNormalAndMangle(t, "if (x ? 0 : y) foo()", "if (x ? 0 : y) foo();\n", "!x && y && foo();\n")
  4046  	expectPrintedNormalAndMangle(t, "if (x ? 1 : y) foo()", "if (x ? 1 : y) foo();\n", "(x || y) && foo();\n")
  4047  
  4048  	expectPrintedNormalAndMangle(t, "if (x ? y : 0) ; else foo()", "if (x ? y : 0) ;\nelse foo();\n", "x && y || foo();\n")
  4049  	expectPrintedNormalAndMangle(t, "if (x ? y : 1) ; else foo()", "if (x ? y : 1) ;\nelse foo();\n", "!x || y || foo();\n")
  4050  	expectPrintedNormalAndMangle(t, "if (x ? 0 : y) ; else foo()", "if (x ? 0 : y) ;\nelse foo();\n", "!x && y || foo();\n")
  4051  	expectPrintedNormalAndMangle(t, "if (x ? 1 : y) ; else foo()", "if (x ? 1 : y) ;\nelse foo();\n", "x || y || foo();\n")
  4052  
  4053  	expectPrintedNormalAndMangle(t, "(x ? y : 0) && foo();", "(x ? y : 0) && foo();\n", "x && y && foo();\n")
  4054  	expectPrintedNormalAndMangle(t, "(x ? y : 1) && foo();", "(x ? y : 1) && foo();\n", "(!x || y) && foo();\n")
  4055  	expectPrintedNormalAndMangle(t, "(x ? 0 : y) && foo();", "(x ? 0 : y) && foo();\n", "!x && y && foo();\n")
  4056  	expectPrintedNormalAndMangle(t, "(x ? 1 : y) && foo();", "(x ? 1 : y) && foo();\n", "(x || y) && foo();\n")
  4057  
  4058  	expectPrintedNormalAndMangle(t, "(x ? y : 0) || foo();", "(x ? y : 0) || foo();\n", "x && y || foo();\n")
  4059  	expectPrintedNormalAndMangle(t, "(x ? y : 1) || foo();", "(x ? y : 1) || foo();\n", "!x || y || foo();\n")
  4060  	expectPrintedNormalAndMangle(t, "(x ? 0 : y) || foo();", "(x ? 0 : y) || foo();\n", "!x && y || foo();\n")
  4061  	expectPrintedNormalAndMangle(t, "(x ? 1 : y) || foo();", "(x ? 1 : y) || foo();\n", "x || y || foo();\n")
  4062  
  4063  	expectPrintedNormalAndMangle(t, "if (!!a || !!b) throw 0", "if (!!a || !!b) throw 0;\n", "if (a || b) throw 0;\n")
  4064  	expectPrintedNormalAndMangle(t, "if (!!a && !!b) throw 0", "if (!!a && !!b) throw 0;\n", "if (a && b) throw 0;\n")
  4065  	expectPrintedNormalAndMangle(t, "if (!!a ? !!b : !!c) throw 0", "if (!!a ? !!b : !!c) throw 0;\n", "if (a ? b : c) throw 0;\n")
  4066  
  4067  	expectPrintedNormalAndMangle(t, "if ((a + b) !== 0) throw 0", "if (a + b !== 0) throw 0;\n", "if (a + b !== 0) throw 0;\n")
  4068  	expectPrintedNormalAndMangle(t, "if ((a | b) !== 0) throw 0", "if ((a | b) !== 0) throw 0;\n", "if (a | b) throw 0;\n")
  4069  	expectPrintedNormalAndMangle(t, "if ((a & b) !== 0) throw 0", "if ((a & b) !== 0) throw 0;\n", "if (a & b) throw 0;\n")
  4070  	expectPrintedNormalAndMangle(t, "if ((a ^ b) !== 0) throw 0", "if ((a ^ b) !== 0) throw 0;\n", "if (a ^ b) throw 0;\n")
  4071  	expectPrintedNormalAndMangle(t, "if ((a << b) !== 0) throw 0", "if (a << b !== 0) throw 0;\n", "if (a << b) throw 0;\n")
  4072  	expectPrintedNormalAndMangle(t, "if ((a >> b) !== 0) throw 0", "if (a >> b !== 0) throw 0;\n", "if (a >> b) throw 0;\n")
  4073  	expectPrintedNormalAndMangle(t, "if ((a >>> b) !== 0) throw 0", "if (a >>> b !== 0) throw 0;\n", "if (a >>> b) throw 0;\n")
  4074  	expectPrintedNormalAndMangle(t, "if (+a !== 0) throw 0", "if (+a !== 0) throw 0;\n", "if (+a != 0) throw 0;\n")
  4075  	expectPrintedNormalAndMangle(t, "if (~a !== 0) throw 0", "if (~a !== 0) throw 0;\n", "if (~a) throw 0;\n")
  4076  
  4077  	expectPrintedNormalAndMangle(t, "if (0 != (a + b)) throw 0", "if (0 != a + b) throw 0;\n", "if (a + b != 0) throw 0;\n")
  4078  	expectPrintedNormalAndMangle(t, "if (0 != (a | b)) throw 0", "if (0 != (a | b)) throw 0;\n", "if (a | b) throw 0;\n")
  4079  	expectPrintedNormalAndMangle(t, "if (0 != (a & b)) throw 0", "if (0 != (a & b)) throw 0;\n", "if (a & b) throw 0;\n")
  4080  	expectPrintedNormalAndMangle(t, "if (0 != (a ^ b)) throw 0", "if (0 != (a ^ b)) throw 0;\n", "if (a ^ b) throw 0;\n")
  4081  	expectPrintedNormalAndMangle(t, "if (0 != (a << b)) throw 0", "if (0 != a << b) throw 0;\n", "if (a << b) throw 0;\n")
  4082  	expectPrintedNormalAndMangle(t, "if (0 != (a >> b)) throw 0", "if (0 != a >> b) throw 0;\n", "if (a >> b) throw 0;\n")
  4083  	expectPrintedNormalAndMangle(t, "if (0 != (a >>> b)) throw 0", "if (0 != a >>> b) throw 0;\n", "if (a >>> b) throw 0;\n")
  4084  	expectPrintedNormalAndMangle(t, "if (0 != +a) throw 0", "if (0 != +a) throw 0;\n", "if (+a != 0) throw 0;\n")
  4085  	expectPrintedNormalAndMangle(t, "if (0 != ~a) throw 0", "if (0 != ~a) throw 0;\n", "if (~a) throw 0;\n")
  4086  
  4087  	expectPrintedNormalAndMangle(t, "if ((a + b) === 0) throw 0", "if (a + b === 0) throw 0;\n", "if (a + b === 0) throw 0;\n")
  4088  	expectPrintedNormalAndMangle(t, "if ((a | b) === 0) throw 0", "if ((a | b) === 0) throw 0;\n", "if (!(a | b)) throw 0;\n")
  4089  	expectPrintedNormalAndMangle(t, "if ((a & b) === 0) throw 0", "if ((a & b) === 0) throw 0;\n", "if (!(a & b)) throw 0;\n")
  4090  	expectPrintedNormalAndMangle(t, "if ((a ^ b) === 0) throw 0", "if ((a ^ b) === 0) throw 0;\n", "if (!(a ^ b)) throw 0;\n")
  4091  	expectPrintedNormalAndMangle(t, "if ((a << b) === 0) throw 0", "if (a << b === 0) throw 0;\n", "if (!(a << b)) throw 0;\n")
  4092  	expectPrintedNormalAndMangle(t, "if ((a >> b) === 0) throw 0", "if (a >> b === 0) throw 0;\n", "if (!(a >> b)) throw 0;\n")
  4093  	expectPrintedNormalAndMangle(t, "if ((a >>> b) === 0) throw 0", "if (a >>> b === 0) throw 0;\n", "if (!(a >>> b)) throw 0;\n")
  4094  	expectPrintedNormalAndMangle(t, "if (+a === 0) throw 0", "if (+a === 0) throw 0;\n", "if (+a == 0) throw 0;\n")
  4095  	expectPrintedNormalAndMangle(t, "if (~a === 0) throw 0", "if (~a === 0) throw 0;\n", "if (!~a) throw 0;\n")
  4096  
  4097  	expectPrintedNormalAndMangle(t, "if (0 == (a + b)) throw 0", "if (0 == a + b) throw 0;\n", "if (a + b == 0) throw 0;\n")
  4098  	expectPrintedNormalAndMangle(t, "if (0 == (a | b)) throw 0", "if (0 == (a | b)) throw 0;\n", "if (!(a | b)) throw 0;\n")
  4099  	expectPrintedNormalAndMangle(t, "if (0 == (a & b)) throw 0", "if (0 == (a & b)) throw 0;\n", "if (!(a & b)) throw 0;\n")
  4100  	expectPrintedNormalAndMangle(t, "if (0 == (a ^ b)) throw 0", "if (0 == (a ^ b)) throw 0;\n", "if (!(a ^ b)) throw 0;\n")
  4101  	expectPrintedNormalAndMangle(t, "if (0 == (a << b)) throw 0", "if (0 == a << b) throw 0;\n", "if (!(a << b)) throw 0;\n")
  4102  	expectPrintedNormalAndMangle(t, "if (0 == (a >> b)) throw 0", "if (0 == a >> b) throw 0;\n", "if (!(a >> b)) throw 0;\n")
  4103  	expectPrintedNormalAndMangle(t, "if (0 == (a >>> b)) throw 0", "if (0 == a >>> b) throw 0;\n", "if (!(a >>> b)) throw 0;\n")
  4104  	expectPrintedNormalAndMangle(t, "if (0 == +a) throw 0", "if (0 == +a) throw 0;\n", "if (+a == 0) throw 0;\n")
  4105  	expectPrintedNormalAndMangle(t, "if (0 == ~a) throw 0", "if (0 == ~a) throw 0;\n", "if (!~a) throw 0;\n")
  4106  }
  4107  
  4108  func TestMangleWrapToAvoidAmbiguousElse(t *testing.T) {
  4109  	expectPrintedMangle(t, "if (a) { if (b) return c } else return d", "if (a) {\n  if (b) return c;\n} else return d;\n")
  4110  	expectPrintedMangle(t, "if (a) while (1) { if (b) return c } else return d", "if (a) {\n  for (; ; )\n    if (b) return c;\n} else return d;\n")
  4111  	expectPrintedMangle(t, "if (a) for (;;) { if (b) return c } else return d", "if (a) {\n  for (; ; )\n    if (b) return c;\n} else return d;\n")
  4112  	expectPrintedMangle(t, "if (a) for (x in y) { if (b) return c } else return d", "if (a) {\n  for (x in y)\n    if (b) return c;\n} else return d;\n")
  4113  	expectPrintedMangle(t, "if (a) for (x of y) { if (b) return c } else return d", "if (a) {\n  for (x of y)\n    if (b) return c;\n} else return d;\n")
  4114  	expectPrintedMangle(t, "if (a) with (x) { if (b) return c } else return d", "if (a) {\n  with (x)\n    if (b) return c;\n} else return d;\n")
  4115  	expectPrintedMangle(t, "if (a) x: { if (b) break x } else return c", "if (a) {\n  x:\n    if (b) break x;\n} else return c;\n")
  4116  }
  4117  
  4118  func TestMangleOptionalChain(t *testing.T) {
  4119  	expectPrintedMangle(t, "let a; return a != null ? a.b : undefined", "let a;\nreturn a?.b;\n")
  4120  	expectPrintedMangle(t, "let a; return a != null ? a[b] : undefined", "let a;\nreturn a?.[b];\n")
  4121  	expectPrintedMangle(t, "let a; return a != null ? a(b) : undefined", "let a;\nreturn a?.(b);\n")
  4122  
  4123  	expectPrintedMangle(t, "let a; return a == null ? undefined : a.b", "let a;\nreturn a?.b;\n")
  4124  	expectPrintedMangle(t, "let a; return a == null ? undefined : a[b]", "let a;\nreturn a?.[b];\n")
  4125  	expectPrintedMangle(t, "let a; return a == null ? undefined : a(b)", "let a;\nreturn a?.(b);\n")
  4126  
  4127  	expectPrintedMangle(t, "let a; return null != a ? a.b : undefined", "let a;\nreturn a?.b;\n")
  4128  	expectPrintedMangle(t, "let a; return null != a ? a[b] : undefined", "let a;\nreturn a?.[b];\n")
  4129  	expectPrintedMangle(t, "let a; return null != a ? a(b) : undefined", "let a;\nreturn a?.(b);\n")
  4130  
  4131  	expectPrintedMangle(t, "let a; return null == a ? undefined : a.b", "let a;\nreturn a?.b;\n")
  4132  	expectPrintedMangle(t, "let a; return null == a ? undefined : a[b]", "let a;\nreturn a?.[b];\n")
  4133  	expectPrintedMangle(t, "let a; return null == a ? undefined : a(b)", "let a;\nreturn a?.(b);\n")
  4134  
  4135  	expectPrintedMangle(t, "return a != null ? a.b : undefined", "return a != null ? a.b : void 0;\n")
  4136  	expectPrintedMangle(t, "let a; return a != null ? a.b : null", "let a;\nreturn a != null ? a.b : null;\n")
  4137  	expectPrintedMangle(t, "let a; return a != null ? b.a : undefined", "let a;\nreturn a != null ? b.a : void 0;\n")
  4138  	expectPrintedMangle(t, "let a; return a != 0 ? a.b : undefined", "let a;\nreturn a != 0 ? a.b : void 0;\n")
  4139  	expectPrintedMangle(t, "let a; return a !== null ? a.b : undefined", "let a;\nreturn a !== null ? a.b : void 0;\n")
  4140  	expectPrintedMangle(t, "let a; return a != undefined ? a.b : undefined", "let a;\nreturn a?.b;\n")
  4141  	expectPrintedMangle(t, "let a; return a != null ? a?.b : undefined", "let a;\nreturn a?.b;\n")
  4142  	expectPrintedMangle(t, "let a; return a != null ? a.b.c[d](e) : undefined", "let a;\nreturn a?.b.c[d](e);\n")
  4143  	expectPrintedMangle(t, "let a; return a != null ? a?.b.c[d](e) : undefined", "let a;\nreturn a?.b.c[d](e);\n")
  4144  	expectPrintedMangle(t, "let a; return a != null ? a.b.c?.[d](e) : undefined", "let a;\nreturn a?.b.c?.[d](e);\n")
  4145  	expectPrintedMangle(t, "let a; return a != null ? a?.b.c?.[d](e) : undefined", "let a;\nreturn a?.b.c?.[d](e);\n")
  4146  	expectPrintedMangleTarget(t, 2019, "let a; return a != null ? a.b : undefined", "let a;\nreturn a != null ? a.b : void 0;\n")
  4147  	expectPrintedMangleTarget(t, 2020, "let a; return a != null ? a.b : undefined", "let a;\nreturn a?.b;\n")
  4148  
  4149  	expectPrintedMangle(t, "a != null && a.b()", "a?.b();\n")
  4150  	expectPrintedMangle(t, "a == null || a.b()", "a?.b();\n")
  4151  	expectPrintedMangle(t, "null != a && a.b()", "a?.b();\n")
  4152  	expectPrintedMangle(t, "null == a || a.b()", "a?.b();\n")
  4153  
  4154  	expectPrintedMangle(t, "a == null && a.b()", "a == null && a.b();\n")
  4155  	expectPrintedMangle(t, "a != null || a.b()", "a != null || a.b();\n")
  4156  	expectPrintedMangle(t, "null == a && a.b()", "a == null && a.b();\n")
  4157  	expectPrintedMangle(t, "null != a || a.b()", "a != null || a.b();\n")
  4158  
  4159  	expectPrintedMangle(t, "x = a != null && a.b()", "x = a != null && a.b();\n")
  4160  	expectPrintedMangle(t, "x = a == null || a.b()", "x = a == null || a.b();\n")
  4161  
  4162  	expectPrintedMangle(t, "if (a != null) a.b()", "a?.b();\n")
  4163  	expectPrintedMangle(t, "if (a == null) ; else a.b()", "a?.b();\n")
  4164  
  4165  	expectPrintedMangle(t, "if (a == null) a.b()", "a == null && a.b();\n")
  4166  	expectPrintedMangle(t, "if (a != null) ; else a.b()", "a != null || a.b();\n")
  4167  }
  4168  
  4169  func TestMangleNullOrUndefinedWithSideEffects(t *testing.T) {
  4170  	expectPrintedNormalAndMangle(t, "x(y ?? 1)", "x(y ?? 1);\n", "x(y ?? 1);\n")
  4171  	expectPrintedNormalAndMangle(t, "x(y.z ?? 1)", "x(y.z ?? 1);\n", "x(y.z ?? 1);\n")
  4172  	expectPrintedNormalAndMangle(t, "x(y[z] ?? 1)", "x(y[z] ?? 1);\n", "x(y[z] ?? 1);\n")
  4173  
  4174  	expectPrintedNormalAndMangle(t, "x(0 ?? 1)", "x(0);\n", "x(0);\n")
  4175  	expectPrintedNormalAndMangle(t, "x(0n ?? 1)", "x(0n);\n", "x(0n);\n")
  4176  	expectPrintedNormalAndMangle(t, "x('' ?? 1)", "x(\"\");\n", "x(\"\");\n")
  4177  	expectPrintedNormalAndMangle(t, "x(/./ ?? 1)", "x(/./);\n", "x(/./);\n")
  4178  	expectPrintedNormalAndMangle(t, "x({} ?? 1)", "x({});\n", "x({});\n")
  4179  	expectPrintedNormalAndMangle(t, "x((() => {}) ?? 1)", "x(() => {\n});\n", "x(() => {\n});\n")
  4180  	expectPrintedNormalAndMangle(t, "x(class {} ?? 1)", "x(class {\n});\n", "x(class {\n});\n")
  4181  	expectPrintedNormalAndMangle(t, "x(function() {} ?? 1)", "x(function() {\n});\n", "x(function() {\n});\n")
  4182  
  4183  	expectPrintedNormalAndMangle(t, "x(null ?? 1)", "x(1);\n", "x(1);\n")
  4184  	expectPrintedNormalAndMangle(t, "x(undefined ?? 1)", "x(1);\n", "x(1);\n")
  4185  
  4186  	expectPrintedNormalAndMangle(t, "x(void y ?? 1)", "x(void y ?? 1);\n", "x(void y ?? 1);\n")
  4187  	expectPrintedNormalAndMangle(t, "x(-y ?? 1)", "x(-y);\n", "x(-y);\n")
  4188  	expectPrintedNormalAndMangle(t, "x(+y ?? 1)", "x(+y);\n", "x(+y);\n")
  4189  	expectPrintedNormalAndMangle(t, "x(!y ?? 1)", "x(!y);\n", "x(!y);\n")
  4190  	expectPrintedNormalAndMangle(t, "x(~y ?? 1)", "x(~y);\n", "x(~y);\n")
  4191  	expectPrintedNormalAndMangle(t, "x(--y ?? 1)", "x(--y);\n", "x(--y);\n")
  4192  	expectPrintedNormalAndMangle(t, "x(++y ?? 1)", "x(++y);\n", "x(++y);\n")
  4193  	expectPrintedNormalAndMangle(t, "x(y-- ?? 1)", "x(y--);\n", "x(y--);\n")
  4194  	expectPrintedNormalAndMangle(t, "x(y++ ?? 1)", "x(y++);\n", "x(y++);\n")
  4195  	expectPrintedNormalAndMangle(t, "x(delete y ?? 1)", "x(delete y);\n", "x(delete y);\n")
  4196  	expectPrintedNormalAndMangle(t, "x(typeof y ?? 1)", "x(typeof y);\n", "x(typeof y);\n")
  4197  
  4198  	expectPrintedNormalAndMangle(t, "x((y, 0) ?? 1)", "x((y, 0));\n", "x((y, 0));\n")
  4199  	expectPrintedNormalAndMangle(t, "x((y, !z) ?? 1)", "x((y, !z));\n", "x((y, !z));\n")
  4200  	expectPrintedNormalAndMangle(t, "x((y, null) ?? 1)", "x((y, null) ?? 1);\n", "x((y, null ?? 1));\n")
  4201  	expectPrintedNormalAndMangle(t, "x((y, void z) ?? 1)", "x((y, void z) ?? 1);\n", "x((y, void z ?? 1));\n")
  4202  
  4203  	expectPrintedNormalAndMangle(t, "x((y + z) ?? 1)", "x(y + z);\n", "x(y + z);\n")
  4204  	expectPrintedNormalAndMangle(t, "x((y - z) ?? 1)", "x(y - z);\n", "x(y - z);\n")
  4205  	expectPrintedNormalAndMangle(t, "x((y * z) ?? 1)", "x(y * z);\n", "x(y * z);\n")
  4206  	expectPrintedNormalAndMangle(t, "x((y / z) ?? 1)", "x(y / z);\n", "x(y / z);\n")
  4207  	expectPrintedNormalAndMangle(t, "x((y % z) ?? 1)", "x(y % z);\n", "x(y % z);\n")
  4208  	expectPrintedNormalAndMangle(t, "x((y ** z) ?? 1)", "x(y ** z);\n", "x(y ** z);\n")
  4209  	expectPrintedNormalAndMangle(t, "x((y << z) ?? 1)", "x(y << z);\n", "x(y << z);\n")
  4210  	expectPrintedNormalAndMangle(t, "x((y >> z) ?? 1)", "x(y >> z);\n", "x(y >> z);\n")
  4211  	expectPrintedNormalAndMangle(t, "x((y >>> z) ?? 1)", "x(y >>> z);\n", "x(y >>> z);\n")
  4212  	expectPrintedNormalAndMangle(t, "x((y | z) ?? 1)", "x(y | z);\n", "x(y | z);\n")
  4213  	expectPrintedNormalAndMangle(t, "x((y & z) ?? 1)", "x(y & z);\n", "x(y & z);\n")
  4214  	expectPrintedNormalAndMangle(t, "x((y ^ z) ?? 1)", "x(y ^ z);\n", "x(y ^ z);\n")
  4215  	expectPrintedNormalAndMangle(t, "x((y < z) ?? 1)", "x(y < z);\n", "x(y < z);\n")
  4216  	expectPrintedNormalAndMangle(t, "x((y > z) ?? 1)", "x(y > z);\n", "x(y > z);\n")
  4217  	expectPrintedNormalAndMangle(t, "x((y <= z) ?? 1)", "x(y <= z);\n", "x(y <= z);\n")
  4218  	expectPrintedNormalAndMangle(t, "x((y >= z) ?? 1)", "x(y >= z);\n", "x(y >= z);\n")
  4219  	expectPrintedNormalAndMangle(t, "x((y == z) ?? 1)", "x(y == z);\n", "x(y == z);\n")
  4220  	expectPrintedNormalAndMangle(t, "x((y != z) ?? 1)", "x(y != z);\n", "x(y != z);\n")
  4221  	expectPrintedNormalAndMangle(t, "x((y === z) ?? 1)", "x(y === z);\n", "x(y === z);\n")
  4222  	expectPrintedNormalAndMangle(t, "x((y !== z) ?? 1)", "x(y !== z);\n", "x(y !== z);\n")
  4223  
  4224  	expectPrintedNormalAndMangle(t, "x((y || z) ?? 1)", "x((y || z) ?? 1);\n", "x((y || z) ?? 1);\n")
  4225  	expectPrintedNormalAndMangle(t, "x((y && z) ?? 1)", "x((y && z) ?? 1);\n", "x((y && z) ?? 1);\n")
  4226  	expectPrintedNormalAndMangle(t, "x((y ?? z) ?? 1)", "x(y ?? z ?? 1);\n", "x(y ?? z ?? 1);\n")
  4227  }
  4228  
  4229  func TestMangleBooleanWithSideEffects(t *testing.T) {
  4230  	falsyNoSideEffects := []string{"false", "\"\"", "0", "0n", "null", "void 0"}
  4231  	truthyNoSideEffects := []string{"true", "\" \"", "1", "1n", "/./", "(() => {\n})", "function() {\n}", "[1, 2]", "{ a: 0 }"}
  4232  
  4233  	for _, value := range falsyNoSideEffects {
  4234  		expectPrintedMangle(t, "y(x && "+value+")", "y(x && "+value+");\n")
  4235  		expectPrintedMangle(t, "y(x || "+value+")", "y(x || "+value+");\n")
  4236  
  4237  		expectPrintedMangle(t, "y(!(x && "+value+"))", "y(!(x && false));\n")
  4238  		expectPrintedMangle(t, "y(!(x || "+value+"))", "y(!x);\n")
  4239  
  4240  		expectPrintedMangle(t, "if (x && "+value+") y", "x;\n")
  4241  		expectPrintedMangle(t, "if (x || "+value+") y", "x && y;\n")
  4242  
  4243  		expectPrintedMangle(t, "if (x && "+value+") y; else z", "x, z;\n")
  4244  		expectPrintedMangle(t, "if (x || "+value+") y; else z", "x ? y : z;\n")
  4245  
  4246  		expectPrintedMangle(t, "y(x && "+value+" ? y : z)", "y((x, z));\n")
  4247  		expectPrintedMangle(t, "y(x || "+value+" ? y : z)", "y(x ? y : z);\n")
  4248  
  4249  		expectPrintedMangle(t, "while ("+value+") x()", "for (; false; ) x();\n")
  4250  		expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; false; ) x();\n")
  4251  	}
  4252  
  4253  	for _, value := range truthyNoSideEffects {
  4254  		expectPrintedMangle(t, "y(x && "+value+")", "y(x && "+value+");\n")
  4255  		expectPrintedMangle(t, "y(x || "+value+")", "y(x || "+value+");\n")
  4256  
  4257  		expectPrintedMangle(t, "y(!(x && "+value+"))", "y(!x);\n")
  4258  		expectPrintedMangle(t, "y(!(x || "+value+"))", "y(!(x || true));\n")
  4259  
  4260  		expectPrintedMangle(t, "if (x && "+value+") y", "x && y;\n")
  4261  		expectPrintedMangle(t, "if (x || "+value+") y", "x, y;\n")
  4262  
  4263  		expectPrintedMangle(t, "if (x && "+value+") y; else z", "x ? y : z;\n")
  4264  		expectPrintedMangle(t, "if (x || "+value+") y; else z", "x, y;\n")
  4265  
  4266  		expectPrintedMangle(t, "y(x && "+value+" ? y : z)", "y(x ? y : z);\n")
  4267  		expectPrintedMangle(t, "y(x || "+value+" ? y : z)", "y((x, y));\n")
  4268  
  4269  		expectPrintedMangle(t, "while ("+value+") x()", "for (; ; ) x();\n")
  4270  		expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; ; ) x();\n")
  4271  	}
  4272  
  4273  	falsyHasSideEffects := []string{"void foo()"}
  4274  	truthyHasSideEffects := []string{"typeof foo()", "[foo()]", "{ [foo()]: 0 }"}
  4275  
  4276  	for _, value := range falsyHasSideEffects {
  4277  		expectPrintedMangle(t, "y(x && "+value+")", "y(x && "+value+");\n")
  4278  		expectPrintedMangle(t, "y(x || "+value+")", "y(x || "+value+");\n")
  4279  
  4280  		expectPrintedMangle(t, "y(!(x && "+value+"))", "y(!(x && "+value+"));\n")
  4281  		expectPrintedMangle(t, "y(!(x || "+value+"))", "y(!(x || "+value+"));\n")
  4282  
  4283  		expectPrintedMangle(t, "if (x || "+value+") y", "(x || "+value+") && y;\n")
  4284  		expectPrintedMangle(t, "if (x || "+value+") y; else z", "x || "+value+" ? y : z;\n")
  4285  		expectPrintedMangle(t, "y(x || "+value+" ? y : z)", "y(x || "+value+" ? y : z);\n")
  4286  
  4287  		expectPrintedMangle(t, "while ("+value+") x()", "for (; "+value+"; ) x();\n")
  4288  		expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; "+value+"; ) x();\n")
  4289  	}
  4290  
  4291  	for _, value := range truthyHasSideEffects {
  4292  		expectPrintedMangle(t, "y(x && "+value+")", "y(x && "+value+");\n")
  4293  		expectPrintedMangle(t, "y(x || "+value+")", "y(x || "+value+");\n")
  4294  
  4295  		expectPrintedMangle(t, "y(!(x || "+value+"))", "y(!(x || "+value+"));\n")
  4296  		expectPrintedMangle(t, "y(!(x && "+value+"))", "y(!(x && "+value+"));\n")
  4297  
  4298  		expectPrintedMangle(t, "if (x && "+value+") y", "x && "+value+" && y;\n")
  4299  		expectPrintedMangle(t, "if (x && "+value+") y; else z", "x && "+value+" ? y : z;\n")
  4300  		expectPrintedMangle(t, "y(x && "+value+" ? y : z)", "y(x && "+value+" ? y : z);\n")
  4301  
  4302  		expectPrintedMangle(t, "while ("+value+") x()", "for (; "+value+"; ) x();\n")
  4303  		expectPrintedMangle(t, "for (; "+value+"; ) x()", "for (; "+value+"; ) x();\n")
  4304  	}
  4305  }
  4306  
  4307  func TestMangleReturn(t *testing.T) {
  4308  	expectPrintedMangle(t, "function foo() { x(); return; }", "function foo() {\n  x();\n}\n")
  4309  	expectPrintedMangle(t, "let foo = function() { x(); return; }", "let foo = function() {\n  x();\n};\n")
  4310  	expectPrintedMangle(t, "let foo = () => { x(); return; }", "let foo = () => {\n  x();\n};\n")
  4311  	expectPrintedMangle(t, "function foo() { x(); return y; }", "function foo() {\n  return x(), y;\n}\n")
  4312  	expectPrintedMangle(t, "let foo = function() { x(); return y; }", "let foo = function() {\n  return x(), y;\n};\n")
  4313  	expectPrintedMangle(t, "let foo = () => { x(); return y; }", "let foo = () => (x(), y);\n")
  4314  
  4315  	// Don't trim a trailing top-level return because we may be compiling a partial module
  4316  	expectPrintedMangle(t, "x(); return;", "x();\nreturn;\n")
  4317  
  4318  	expectPrintedMangle(t, "function foo() { a = b; if (a) return a; if (b) c = b; return c; }",
  4319  		"function foo() {\n  return a = b, a || (b && (c = b), c);\n}\n")
  4320  	expectPrintedMangle(t, "function foo() { a = b; if (a) return; if (b) c = b; return c; }",
  4321  		"function foo() {\n  if (a = b, !a)\n    return b && (c = b), c;\n}\n")
  4322  	expectPrintedMangle(t, "function foo() { if (!a) return b; return c; }", "function foo() {\n  return a ? c : b;\n}\n")
  4323  
  4324  	expectPrintedMangle(t, "if (1) return a(); else return b()", "return a();\n")
  4325  	expectPrintedMangle(t, "if (0) return a(); else return b()", "return b();\n")
  4326  	expectPrintedMangle(t, "if (a) return b(); else return c()", "return a ? b() : c();\n")
  4327  	expectPrintedMangle(t, "if (!a) return b(); else return c()", "return a ? c() : b();\n")
  4328  	expectPrintedMangle(t, "if (!!a) return b(); else return c()", "return a ? b() : c();\n")
  4329  	expectPrintedMangle(t, "if (!!!a) return b(); else return c()", "return a ? c() : b();\n")
  4330  
  4331  	expectPrintedMangle(t, "if (1) return a(); return b()", "return a();\n")
  4332  	expectPrintedMangle(t, "if (0) return a(); return b()", "return b();\n")
  4333  	expectPrintedMangle(t, "if (a) return b(); return c()", "return a ? b() : c();\n")
  4334  	expectPrintedMangle(t, "if (!a) return b(); return c()", "return a ? c() : b();\n")
  4335  	expectPrintedMangle(t, "if (!!a) return b(); return c()", "return a ? b() : c();\n")
  4336  	expectPrintedMangle(t, "if (!!!a) return b(); return c()", "return a ? c() : b();\n")
  4337  
  4338  	expectPrintedMangle(t, "if (a) return b; else return c; return d;\n", "return a ? b : c;\n")
  4339  
  4340  	// Optimize implicit return
  4341  	expectPrintedMangle(t, "function x() { if (y) return; z(); }", "function x() {\n  y || z();\n}\n")
  4342  	expectPrintedMangle(t, "function x() { if (y) return; else z(); w(); }", "function x() {\n  y || (z(), w());\n}\n")
  4343  	expectPrintedMangle(t, "function x() { t(); if (y) return; z(); }", "function x() {\n  t(), !y && z();\n}\n")
  4344  	expectPrintedMangle(t, "function x() { t(); if (y) return; else z(); w(); }", "function x() {\n  t(), !y && (z(), w());\n}\n")
  4345  	expectPrintedMangle(t, "function x() { debugger; if (y) return; z(); }", "function x() {\n  debugger;\n  y || z();\n}\n")
  4346  	expectPrintedMangle(t, "function x() { debugger; if (y) return; else z(); w(); }", "function x() {\n  debugger;\n  y || (z(), w());\n}\n")
  4347  	expectPrintedMangle(t, "function x() { if (y) { if (z) return; } }",
  4348  		"function x() {\n  y && z;\n}\n")
  4349  	expectPrintedMangle(t, "function x() { if (y) { if (z) return; w(); } }",
  4350  		"function x() {\n  if (y) {\n    if (z) return;\n    w();\n  }\n}\n")
  4351  	expectPrintedMangle(t, "function foo(x) { if (!x.y) {} else return x }", "function foo(x) {\n  if (x.y)\n    return x;\n}\n")
  4352  	expectPrintedMangle(t, "function foo(x) { if (!x.y) return undefined; return x }", "function foo(x) {\n  if (x.y)\n    return x;\n}\n")
  4353  
  4354  	// Do not optimize implicit return for statements that care about scope
  4355  	expectPrintedMangle(t, "function x() { if (y) return; function y() {} }", "function x() {\n  if (y) return;\n  function y() {\n  }\n}\n")
  4356  	expectPrintedMangle(t, "function x() { if (y) return; let y }", "function x() {\n  if (y) return;\n  let y;\n}\n")
  4357  	expectPrintedMangle(t, "function x() { if (y) return; var y }", "function x() {\n  if (!y)\n    var y;\n}\n")
  4358  }
  4359  
  4360  func TestMangleThrow(t *testing.T) {
  4361  	expectPrintedNormalAndMangle(t,
  4362  		"function foo() { a = b; if (a) throw a; if (b) c = b; throw c; }",
  4363  		"function foo() {\n  a = b;\n  if (a) throw a;\n  if (b) c = b;\n  throw c;\n}\n",
  4364  		"function foo() {\n  throw a = b, a || (b && (c = b), c);\n}\n")
  4365  	expectPrintedNormalAndMangle(t,
  4366  		"function foo() { if (!a) throw b; throw c; }",
  4367  		"function foo() {\n  if (!a) throw b;\n  throw c;\n}\n",
  4368  		"function foo() {\n  throw a ? c : b;\n}\n")
  4369  
  4370  	expectPrintedNormalAndMangle(t, "if (1) throw a(); else throw b()", "if (1) throw a();\nelse throw b();\n", "throw a();\n")
  4371  	expectPrintedNormalAndMangle(t, "if (0) throw a(); else throw b()", "if (0) throw a();\nelse throw b();\n", "throw b();\n")
  4372  	expectPrintedNormalAndMangle(t, "if (a) throw b(); else throw c()", "if (a) throw b();\nelse throw c();\n", "throw a ? b() : c();\n")
  4373  	expectPrintedNormalAndMangle(t, "if (!a) throw b(); else throw c()", "if (!a) throw b();\nelse throw c();\n", "throw a ? c() : b();\n")
  4374  	expectPrintedNormalAndMangle(t, "if (!!a) throw b(); else throw c()", "if (!!a) throw b();\nelse throw c();\n", "throw a ? b() : c();\n")
  4375  	expectPrintedNormalAndMangle(t, "if (!!!a) throw b(); else throw c()", "if (!!!a) throw b();\nelse throw c();\n", "throw a ? c() : b();\n")
  4376  
  4377  	expectPrintedNormalAndMangle(t, "if (1) throw a(); throw b()", "if (1) throw a();\nthrow b();\n", "throw a();\n")
  4378  	expectPrintedNormalAndMangle(t, "if (0) throw a(); throw b()", "if (0) throw a();\nthrow b();\n", "throw b();\n")
  4379  	expectPrintedNormalAndMangle(t, "if (a) throw b(); throw c()", "if (a) throw b();\nthrow c();\n", "throw a ? b() : c();\n")
  4380  	expectPrintedNormalAndMangle(t, "if (!a) throw b(); throw c()", "if (!a) throw b();\nthrow c();\n", "throw a ? c() : b();\n")
  4381  	expectPrintedNormalAndMangle(t, "if (!!a) throw b(); throw c()", "if (!!a) throw b();\nthrow c();\n", "throw a ? b() : c();\n")
  4382  	expectPrintedNormalAndMangle(t, "if (!!!a) throw b(); throw c()", "if (!!!a) throw b();\nthrow c();\n", "throw a ? c() : b();\n")
  4383  }
  4384  
  4385  func TestMangleInitializer(t *testing.T) {
  4386  	expectPrintedNormalAndMangle(t, "const a = undefined", "const a = void 0;\n", "const a = void 0;\n")
  4387  	expectPrintedNormalAndMangle(t, "let a = undefined", "let a = void 0;\n", "let a;\n")
  4388  	expectPrintedNormalAndMangle(t, "let {} = undefined", "let {} = void 0;\n", "let {} = void 0;\n")
  4389  	expectPrintedNormalAndMangle(t, "let [] = undefined", "let [] = void 0;\n", "let [] = void 0;\n")
  4390  	expectPrintedNormalAndMangle(t, "var a = undefined", "var a = void 0;\n", "var a = void 0;\n")
  4391  	expectPrintedNormalAndMangle(t, "var {} = undefined", "var {} = void 0;\n", "var {} = void 0;\n")
  4392  	expectPrintedNormalAndMangle(t, "var [] = undefined", "var [] = void 0;\n", "var [] = void 0;\n")
  4393  }
  4394  
  4395  func TestMangleCall(t *testing.T) {
  4396  	expectPrintedNormalAndMangle(t, "x = foo(1, ...[], 2)", "x = foo(1, ...[], 2);\n", "x = foo(1, 2);\n")
  4397  	expectPrintedNormalAndMangle(t, "x = foo(1, ...2, 3)", "x = foo(1, ...2, 3);\n", "x = foo(1, ...2, 3);\n")
  4398  	expectPrintedNormalAndMangle(t, "x = foo(1, ...[2], 3)", "x = foo(1, ...[2], 3);\n", "x = foo(1, 2, 3);\n")
  4399  	expectPrintedNormalAndMangle(t, "x = foo(1, ...[2, 3], 4)", "x = foo(1, ...[2, 3], 4);\n", "x = foo(1, 2, 3, 4);\n")
  4400  	expectPrintedNormalAndMangle(t, "x = foo(1, ...[2, ...y, 3], 4)", "x = foo(1, ...[2, ...y, 3], 4);\n", "x = foo(1, 2, ...y, 3, 4);\n")
  4401  	expectPrintedNormalAndMangle(t, "x = foo(1, ...{a, b}, 4)", "x = foo(1, ...{ a, b }, 4);\n", "x = foo(1, ...{ a, b }, 4);\n")
  4402  
  4403  	// Holes must become undefined
  4404  	expectPrintedNormalAndMangle(t, "x = foo(1, ...[,2,,], 3)", "x = foo(1, ...[, 2, ,], 3);\n", "x = foo(1, void 0, 2, void 0, 3);\n")
  4405  }
  4406  
  4407  func TestMangleNew(t *testing.T) {
  4408  	expectPrintedNormalAndMangle(t, "x = new foo(1, ...[], 2)", "x = new foo(1, ...[], 2);\n", "x = new foo(1, 2);\n")
  4409  	expectPrintedNormalAndMangle(t, "x = new foo(1, ...2, 3)", "x = new foo(1, ...2, 3);\n", "x = new foo(1, ...2, 3);\n")
  4410  	expectPrintedNormalAndMangle(t, "x = new foo(1, ...[2], 3)", "x = new foo(1, ...[2], 3);\n", "x = new foo(1, 2, 3);\n")
  4411  	expectPrintedNormalAndMangle(t, "x = new foo(1, ...[2, 3], 4)", "x = new foo(1, ...[2, 3], 4);\n", "x = new foo(1, 2, 3, 4);\n")
  4412  	expectPrintedNormalAndMangle(t, "x = new foo(1, ...[2, ...y, 3], 4)", "x = new foo(1, ...[2, ...y, 3], 4);\n", "x = new foo(1, 2, ...y, 3, 4);\n")
  4413  	expectPrintedNormalAndMangle(t, "x = new foo(1, ...{a, b}, 4)", "x = new foo(1, ...{ a, b }, 4);\n", "x = new foo(1, ...{ a, b }, 4);\n")
  4414  
  4415  	// Holes must become undefined
  4416  	expectPrintedNormalAndMangle(t, "x = new foo(1, ...[,2,,], 3)", "x = new foo(1, ...[, 2, ,], 3);\n", "x = new foo(1, void 0, 2, void 0, 3);\n")
  4417  }
  4418  
  4419  func TestMangleArray(t *testing.T) {
  4420  	expectPrintedNormalAndMangle(t, "x = [1, ...[], 2]", "x = [1, ...[], 2];\n", "x = [1, 2];\n")
  4421  	expectPrintedNormalAndMangle(t, "x = [1, ...2, 3]", "x = [1, ...2, 3];\n", "x = [1, ...2, 3];\n")
  4422  	expectPrintedNormalAndMangle(t, "x = [1, ...[2], 3]", "x = [1, ...[2], 3];\n", "x = [1, 2, 3];\n")
  4423  	expectPrintedNormalAndMangle(t, "x = [1, ...[2, 3], 4]", "x = [1, ...[2, 3], 4];\n", "x = [1, 2, 3, 4];\n")
  4424  	expectPrintedNormalAndMangle(t, "x = [1, ...[2, ...y, 3], 4]", "x = [1, ...[2, ...y, 3], 4];\n", "x = [1, 2, ...y, 3, 4];\n")
  4425  	expectPrintedNormalAndMangle(t, "x = [1, ...{a, b}, 4]", "x = [1, ...{ a, b }, 4];\n", "x = [1, ...{ a, b }, 4];\n")
  4426  
  4427  	// Holes must become undefined, which is different than a hole
  4428  	expectPrintedNormalAndMangle(t, "x = [1, ...[,2,,], 3]", "x = [1, ...[, 2, ,], 3];\n", "x = [1, void 0, 2, void 0, 3];\n")
  4429  }
  4430  
  4431  func TestMangleObject(t *testing.T) {
  4432  	expectPrintedNormalAndMangle(t, "x = {['y']: z}", "x = { [\"y\"]: z };\n", "x = { y: z };\n")
  4433  	expectPrintedNormalAndMangle(t, "x = {['y']() {}}", "x = { [\"y\"]() {\n} };\n", "x = { y() {\n} };\n")
  4434  	expectPrintedNormalAndMangle(t, "x = {get ['y']() {}}", "x = { get [\"y\"]() {\n} };\n", "x = { get y() {\n} };\n")
  4435  	expectPrintedNormalAndMangle(t, "x = {set ['y'](z) {}}", "x = { set [\"y\"](z) {\n} };\n", "x = { set y(z) {\n} };\n")
  4436  	expectPrintedNormalAndMangle(t, "x = {async ['y']() {}}", "x = { async [\"y\"]() {\n} };\n", "x = { async y() {\n} };\n")
  4437  	expectPrintedNormalAndMangle(t, "({['y']: z} = x)", "({ [\"y\"]: z } = x);\n", "({ y: z } = x);\n")
  4438  
  4439  	expectPrintedNormalAndMangle(t, "x = {a, ...{}, b}", "x = { a, ...{}, b };\n", "x = { a, b };\n")
  4440  	expectPrintedNormalAndMangle(t, "x = {a, ...b, c}", "x = { a, ...b, c };\n", "x = { a, ...b, c };\n")
  4441  	expectPrintedNormalAndMangle(t, "x = {a, ...{b}, c}", "x = { a, ...{ b }, c };\n", "x = { a, b, c };\n")
  4442  	expectPrintedNormalAndMangle(t, "x = {a, ...{b() {}}, c}", "x = { a, ...{ b() {\n} }, c };\n", "x = { a, b() {\n}, c };\n")
  4443  	expectPrintedNormalAndMangle(t, "x = {a, ...{b, c}, d}", "x = { a, ...{ b, c }, d };\n", "x = { a, b, c, d };\n")
  4444  	expectPrintedNormalAndMangle(t, "x = {a, ...{b, ...y, c}, d}", "x = { a, ...{ b, ...y, c }, d };\n", "x = { a, b, ...y, c, d };\n")
  4445  	expectPrintedNormalAndMangle(t, "x = {a, ...[b, c], d}", "x = { a, ...[b, c], d };\n", "x = { a, ...[b, c], d };\n")
  4446  
  4447  	// Computed properties should be ok
  4448  	expectPrintedNormalAndMangle(t, "x = {a, ...{[b]: c}, d}", "x = { a, ...{ [b]: c }, d };\n", "x = { a, [b]: c, d };\n")
  4449  	expectPrintedNormalAndMangle(t, "x = {a, ...{[b]() {}}, c}", "x = { a, ...{ [b]() {\n} }, c };\n", "x = { a, [b]() {\n}, c };\n")
  4450  
  4451  	// Getters and setters are not supported
  4452  	expectPrintedNormalAndMangle(t,
  4453  		"x = {a, ...{b, get c() { return y++ }, d}, e}",
  4454  		"x = { a, ...{ b, get c() {\n  return y++;\n}, d }, e };\n",
  4455  		"x = { a, b, ...{ get c() {\n  return y++;\n}, d }, e };\n")
  4456  	expectPrintedNormalAndMangle(t,
  4457  		"x = {a, ...{b, set c(_) { throw _ }, d}, e}",
  4458  		"x = { a, ...{ b, set c(_) {\n  throw _;\n}, d }, e };\n",
  4459  		"x = { a, b, ...{ set c(_) {\n  throw _;\n}, d }, e };\n")
  4460  
  4461  	// "__proto__" is not supported
  4462  	expectPrintedNormalAndMangle(t,
  4463  		"x = {a, ...{b, __proto__: c, d}, e}",
  4464  		"x = { a, ...{ b, __proto__: c, d }, e };\n",
  4465  		"x = { a, b, ...{ __proto__: c, d }, e };\n")
  4466  	expectPrintedNormalAndMangle(t,
  4467  		"x = {a, ...{b, ['__proto__']: c, d}, e}",
  4468  		"x = { a, ...{ b, [\"__proto__\"]: c, d }, e };\n",
  4469  		"x = { a, b, [\"__proto__\"]: c, d, e };\n")
  4470  	expectPrintedNormalAndMangle(t,
  4471  		"x = {a, ...{b, __proto__() {}, c}, d}",
  4472  		"x = { a, ...{ b, __proto__() {\n}, c }, d };\n",
  4473  		"x = { a, b, __proto__() {\n}, c, d };\n")
  4474  
  4475  	// Spread is ignored for certain values
  4476  	expectPrintedNormalAndMangle(t, "x = {a, ...true, b}", "x = { a, ...true, b };\n", "x = { a, b };\n")
  4477  	expectPrintedNormalAndMangle(t, "x = {a, ...null, b}", "x = { a, ...null, b };\n", "x = { a, b };\n")
  4478  	expectPrintedNormalAndMangle(t, "x = {a, ...void 0, b}", "x = { a, ...void 0, b };\n", "x = { a, b };\n")
  4479  	expectPrintedNormalAndMangle(t, "x = {a, ...123, b}", "x = { a, ...123, b };\n", "x = { a, b };\n")
  4480  	expectPrintedNormalAndMangle(t, "x = {a, ...123n, b}", "x = { a, ...123n, b };\n", "x = { a, b };\n")
  4481  	expectPrintedNormalAndMangle(t, "x = {a, .../x/, b}", "x = { a, .../x/, b };\n", "x = { a, b };\n")
  4482  	expectPrintedNormalAndMangle(t, "x = {a, ...function(){}, b}", "x = { a, ...function() {\n}, b };\n", "x = { a, b };\n")
  4483  	expectPrintedNormalAndMangle(t, "x = {a, ...()=>{}, b}", "x = { a, ...() => {\n}, b };\n", "x = { a, b };\n")
  4484  	expectPrintedNormalAndMangle(t, "x = {a, ...'123', b}", "x = { a, ...\"123\", b };\n", "x = { a, ...\"123\", b };\n")
  4485  	expectPrintedNormalAndMangle(t, "x = {a, ...[1, 2, 3], b}", "x = { a, ...[1, 2, 3], b };\n", "x = { a, ...[1, 2, 3], b };\n")
  4486  	expectPrintedNormalAndMangle(t, "x = {a, ...(()=>{})(), b}", "x = { a, .../* @__PURE__ */ (() => {\n})(), b };\n", "x = { a, .../* @__PURE__ */ (() => {\n})(), b };\n")
  4487  
  4488  	// Check simple cases of object simplification (advanced cases are checked in end-to-end tests)
  4489  	expectPrintedNormalAndMangle(t, "x = {['y']: z}.y", "x = { [\"y\"]: z }.y;\n", "x = { y: z }.y;\n")
  4490  	expectPrintedNormalAndMangle(t, "x = {['y']: z}.y; var z", "x = { [\"y\"]: z }.y;\nvar z;\n", "x = z;\nvar z;\n")
  4491  	expectPrintedNormalAndMangle(t, "x = {foo: foo(), y: 1}.y", "x = { foo: foo(), y: 1 }.y;\n", "x = { foo: foo(), y: 1 }.y;\n")
  4492  	expectPrintedNormalAndMangle(t, "x = {foo: /* @__PURE__ */ foo(), y: 1}.y", "x = { foo: /* @__PURE__ */ foo(), y: 1 }.y;\n", "x = 1;\n")
  4493  	expectPrintedNormalAndMangle(t, "x = {__proto__: null}.y", "x = { __proto__: null }.y;\n", "x = void 0;\n")
  4494  	expectPrintedNormalAndMangle(t, "x = {__proto__: null, y: 1}.y", "x = { __proto__: null, y: 1 }.y;\n", "x = 1;\n")
  4495  	expectPrintedNormalAndMangle(t, "x = {__proto__: null}.__proto__", "x = { __proto__: null }.__proto__;\n", "x = void 0;\n")
  4496  	expectPrintedNormalAndMangle(t, "x = {['__proto__']: null}.y", "x = { [\"__proto__\"]: null }.y;\n", "x = { [\"__proto__\"]: null }.y;\n")
  4497  	expectPrintedNormalAndMangle(t, "x = {['__proto__']: null, y: 1}.y", "x = { [\"__proto__\"]: null, y: 1 }.y;\n", "x = { [\"__proto__\"]: null, y: 1 }.y;\n")
  4498  	expectPrintedNormalAndMangle(t, "x = {['__proto__']: null}.__proto__", "x = { [\"__proto__\"]: null }.__proto__;\n", "x = { [\"__proto__\"]: null }.__proto__;\n")
  4499  
  4500  	expectPrintedNormalAndMangle(t, "x = {y: 1}?.y", "x = { y: 1 }?.y;\n", "x = 1;\n")
  4501  	expectPrintedNormalAndMangle(t, "x = {y: 1}?.['y']", "x = { y: 1 }?.[\"y\"];\n", "x = 1;\n")
  4502  	expectPrintedNormalAndMangle(t, "x = {y: {z: 1}}?.y.z", "x = { y: { z: 1 } }?.y.z;\n", "x = 1;\n")
  4503  	expectPrintedNormalAndMangle(t, "x = {y: {z: 1}}?.y?.z", "x = { y: { z: 1 } }?.y?.z;\n", "x = { z: 1 }?.z;\n")
  4504  	expectPrintedNormalAndMangle(t, "x = {y() {}}?.y()", "x = { y() {\n} }?.y();\n", "x = { y() {\n} }.y();\n")
  4505  
  4506  	// Don't change the value of "this" for tagged template literals if the original syntax had a value for "this"
  4507  	expectPrintedNormalAndMangle(t, "function f(x) { return {x}.x`` }", "function f(x) {\n  return { x }.x``;\n}\n", "function f(x) {\n  return { x }.x``;\n}\n")
  4508  	expectPrintedNormalAndMangle(t, "function f(x) { return (0, {x}.x)`` }", "function f(x) {\n  return (0, { x }.x)``;\n}\n", "function f(x) {\n  return x``;\n}\n")
  4509  }
  4510  
  4511  func TestMangleObjectJSX(t *testing.T) {
  4512  	expectPrintedJSX(t, "x = <foo bar {...{}} />", "x = /* @__PURE__ */ React.createElement(\"foo\", { bar: true, ...{} });\n")
  4513  	expectPrintedJSX(t, "x = <foo bar {...null} />", "x = /* @__PURE__ */ React.createElement(\"foo\", { bar: true, ...null });\n")
  4514  	expectPrintedJSX(t, "x = <foo bar {...{bar}} />", "x = /* @__PURE__ */ React.createElement(\"foo\", { bar: true, ...{ bar } });\n")
  4515  	expectPrintedJSX(t, "x = <foo bar {...bar} />", "x = /* @__PURE__ */ React.createElement(\"foo\", { bar: true, ...bar });\n")
  4516  
  4517  	expectPrintedMangleJSX(t, "x = <foo bar {...{}} />", "x = /* @__PURE__ */ React.createElement(\"foo\", { bar: true });\n")
  4518  	expectPrintedMangleJSX(t, "x = <foo bar {...null} />", "x = /* @__PURE__ */ React.createElement(\"foo\", { bar: true });\n")
  4519  	expectPrintedMangleJSX(t, "x = <foo bar {...{bar}} />", "x = /* @__PURE__ */ React.createElement(\"foo\", { bar: true, bar });\n")
  4520  	expectPrintedMangleJSX(t, "x = <foo bar {...bar} />", "x = /* @__PURE__ */ React.createElement(\"foo\", { bar: true, ...bar });\n")
  4521  }
  4522  
  4523  func TestMangleArrow(t *testing.T) {
  4524  	expectPrintedNormalAndMangle(t, "var a = () => {}", "var a = () => {\n};\n", "var a = () => {\n};\n")
  4525  	expectPrintedNormalAndMangle(t, "var a = () => 123", "var a = () => 123;\n", "var a = () => 123;\n")
  4526  	expectPrintedNormalAndMangle(t, "var a = () => void 0", "var a = () => void 0;\n", "var a = () => {\n};\n")
  4527  	expectPrintedNormalAndMangle(t, "var a = () => undefined", "var a = () => void 0;\n", "var a = () => {\n};\n")
  4528  	expectPrintedNormalAndMangle(t, "var a = () => {return}", "var a = () => {\n  return;\n};\n", "var a = () => {\n};\n")
  4529  	expectPrintedNormalAndMangle(t, "var a = () => {return 123}", "var a = () => {\n  return 123;\n};\n", "var a = () => 123;\n")
  4530  	expectPrintedNormalAndMangle(t, "var a = () => {throw 123}", "var a = () => {\n  throw 123;\n};\n", "var a = () => {\n  throw 123;\n};\n")
  4531  }
  4532  
  4533  func TestMangleIIFE(t *testing.T) {
  4534  	expectPrintedNormalAndMangle(t, "var a = (() => {})()", "var a = /* @__PURE__ */ (() => {\n})();\n", "var a = /* @__PURE__ */ (() => {\n})();\n")
  4535  	expectPrintedNormalAndMangle(t, "(() => {})()", "/* @__PURE__ */ (() => {\n})();\n", "")
  4536  	expectPrintedNormalAndMangle(t, "(() => a())()", "(() => a())();\n", "a();\n")
  4537  	expectPrintedNormalAndMangle(t, "(() => { a() })()", "(() => {\n  a();\n})();\n", "a();\n")
  4538  	expectPrintedNormalAndMangle(t, "(() => { return a() })()", "(() => {\n  return a();\n})();\n", "a();\n")
  4539  	expectPrintedNormalAndMangle(t, "(() => { let b = a; b() })()", "(() => {\n  let b = a;\n  b();\n})();\n", "a();\n")
  4540  	expectPrintedNormalAndMangle(t, "(() => { let b = a; return b() })()", "(() => {\n  let b = a;\n  return b();\n})();\n", "a();\n")
  4541  	expectPrintedNormalAndMangle(t, "(async () => {})()", "(async () => {\n})();\n", "")
  4542  	expectPrintedNormalAndMangle(t, "(async () => { a() })()", "(async () => {\n  a();\n})();\n", "(async () => a())();\n")
  4543  	expectPrintedNormalAndMangle(t, "(async () => { let b = a; b() })()", "(async () => {\n  let b = a;\n  b();\n})();\n", "(async () => a())();\n")
  4544  
  4545  	expectPrintedNormalAndMangle(t, "var a = (function() {})()", "var a = /* @__PURE__ */ function() {\n}();\n", "var a = /* @__PURE__ */ function() {\n}();\n")
  4546  	expectPrintedNormalAndMangle(t, "(function() {})()", "/* @__PURE__ */ (function() {\n})();\n", "")
  4547  	expectPrintedNormalAndMangle(t, "(function*() {})()", "(function* () {\n})();\n", "")
  4548  	expectPrintedNormalAndMangle(t, "(async function() {})()", "(async function() {\n})();\n", "")
  4549  	expectPrintedNormalAndMangle(t, "(function() { a() })()", "(function() {\n  a();\n})();\n", "(function() {\n  a();\n})();\n")
  4550  	expectPrintedNormalAndMangle(t, "(function*() { a() })()", "(function* () {\n  a();\n})();\n", "(function* () {\n  a();\n})();\n")
  4551  	expectPrintedNormalAndMangle(t, "(async function() { a() })()", "(async function() {\n  a();\n})();\n", "(async function() {\n  a();\n})();\n")
  4552  
  4553  	expectPrintedNormalAndMangle(t, "(() => x)()", "(() => x)();\n", "x;\n")
  4554  	expectPrintedNormalAndMangle(t, "/* @__PURE__ */ (() => x)()", "/* @__PURE__ */ (() => x)();\n", "")
  4555  	expectPrintedNormalAndMangle(t, "/* @__PURE__ */ (() => x)(y, z)", "/* @__PURE__ */ (() => x)(y, z);\n", "y, z;\n")
  4556  }
  4557  
  4558  func TestMangleTemplate(t *testing.T) {
  4559  	expectPrintedNormalAndMangle(t, "_ = `a${x}b${y}c`", "_ = `a${x}b${y}c`;\n", "_ = `a${x}b${y}c`;\n")
  4560  	expectPrintedNormalAndMangle(t, "_ = `a${x}b${'y'}c`", "_ = `a${x}b${\"y\"}c`;\n", "_ = `a${x}byc`;\n")
  4561  	expectPrintedNormalAndMangle(t, "_ = `a${'x'}b${y}c`", "_ = `a${\"x\"}b${y}c`;\n", "_ = `axb${y}c`;\n")
  4562  	expectPrintedNormalAndMangle(t, "_ = `a${'x'}b${'y'}c`", "_ = `a${\"x\"}b${\"y\"}c`;\n", "_ = `axbyc`;\n")
  4563  
  4564  	expectPrintedNormalAndMangle(t, "tag`a${x}b${y}c`", "tag`a${x}b${y}c`;\n", "tag`a${x}b${y}c`;\n")
  4565  	expectPrintedNormalAndMangle(t, "tag`a${x}b${'y'}c`", "tag`a${x}b${\"y\"}c`;\n", "tag`a${x}b${\"y\"}c`;\n")
  4566  	expectPrintedNormalAndMangle(t, "tag`a${'x'}b${y}c`", "tag`a${\"x\"}b${y}c`;\n", "tag`a${\"x\"}b${y}c`;\n")
  4567  	expectPrintedNormalAndMangle(t, "tag`a${'x'}b${'y'}c`", "tag`a${\"x\"}b${\"y\"}c`;\n", "tag`a${\"x\"}b${\"y\"}c`;\n")
  4568  
  4569  	expectPrintedNormalAndMangle(t, "(1, x)``", "(1, x)``;\n", "x``;\n")
  4570  	expectPrintedNormalAndMangle(t, "(1, x.y)``", "(1, x.y)``;\n", "(0, x.y)``;\n")
  4571  	expectPrintedNormalAndMangle(t, "(1, x[y])``", "(1, x[y])``;\n", "(0, x[y])``;\n")
  4572  	expectPrintedNormalAndMangle(t, "(true && x)``", "x``;\n", "x``;\n")
  4573  	expectPrintedNormalAndMangle(t, "(true && x.y)``", "(0, x.y)``;\n", "(0, x.y)``;\n")
  4574  	expectPrintedNormalAndMangle(t, "(true && x[y])``", "(0, x[y])``;\n", "(0, x[y])``;\n")
  4575  	expectPrintedNormalAndMangle(t, "(false || x)``", "x``;\n", "x``;\n")
  4576  	expectPrintedNormalAndMangle(t, "(false || x.y)``", "(0, x.y)``;\n", "(0, x.y)``;\n")
  4577  	expectPrintedNormalAndMangle(t, "(false || x[y])``", "(0, x[y])``;\n", "(0, x[y])``;\n")
  4578  	expectPrintedNormalAndMangle(t, "(null ?? x)``", "x``;\n", "x``;\n")
  4579  	expectPrintedNormalAndMangle(t, "(null ?? x.y)``", "(0, x.y)``;\n", "(0, x.y)``;\n")
  4580  	expectPrintedNormalAndMangle(t, "(null ?? x[y])``", "(0, x[y])``;\n", "(0, x[y])``;\n")
  4581  
  4582  	expectPrintedMangleTarget(t, 2015, "class Foo { #foo() { return this.#foo`` } }", `var _Foo_instances, foo_fn;
  4583  class Foo {
  4584    constructor() {
  4585      __privateAdd(this, _Foo_instances);
  4586    }
  4587  }
  4588  _Foo_instances = new WeakSet(), foo_fn = function() {
  4589    return __privateMethod(this, _Foo_instances, foo_fn).bind(this)`+"``"+`;
  4590  };
  4591  `)
  4592  
  4593  	expectPrintedMangleTarget(t, 2015, "class Foo { #foo() { return (0, this.#foo)`` } }", `var _Foo_instances, foo_fn;
  4594  class Foo {
  4595    constructor() {
  4596      __privateAdd(this, _Foo_instances);
  4597    }
  4598  }
  4599  _Foo_instances = new WeakSet(), foo_fn = function() {
  4600    return __privateMethod(this, _Foo_instances, foo_fn)`+"``"+`;
  4601  };
  4602  `)
  4603  
  4604  	expectPrintedNormalAndMangle(t,
  4605  		"function f(a) { let c = a.b; return c`` }",
  4606  		"function f(a) {\n  let c = a.b;\n  return c``;\n}\n",
  4607  		"function f(a) {\n  return (0, a.b)``;\n}\n")
  4608  	expectPrintedNormalAndMangle(t,
  4609  		"function f(a) { let c = a.b; return c`${x}` }",
  4610  		"function f(a) {\n  let c = a.b;\n  return c`${x}`;\n}\n",
  4611  		"function f(a) {\n  return (0, a.b)`${x}`;\n}\n")
  4612  }
  4613  
  4614  func TestMangleTypeofIdentifier(t *testing.T) {
  4615  	expectPrintedNormalAndMangle(t, "return typeof (123, x)", "return typeof (123, x);\n", "return typeof (0, x);\n")
  4616  	expectPrintedNormalAndMangle(t, "return typeof (123, x.y)", "return typeof (123, x.y);\n", "return typeof x.y;\n")
  4617  	expectPrintedNormalAndMangle(t, "return typeof (123, x); var x", "return typeof (123, x);\nvar x;\n", "return typeof x;\nvar x;\n")
  4618  
  4619  	expectPrintedNormalAndMangle(t, "return typeof (true && x)", "return typeof (0, x);\n", "return typeof (0, x);\n")
  4620  	expectPrintedNormalAndMangle(t, "return typeof (true && x.y)", "return typeof x.y;\n", "return typeof x.y;\n")
  4621  	expectPrintedNormalAndMangle(t, "return typeof (true && x); var x", "return typeof x;\nvar x;\n", "return typeof x;\nvar x;\n")
  4622  
  4623  	expectPrintedNormalAndMangle(t, "return typeof (false || x)", "return typeof (0, x);\n", "return typeof (0, x);\n")
  4624  	expectPrintedNormalAndMangle(t, "return typeof (false || x.y)", "return typeof x.y;\n", "return typeof x.y;\n")
  4625  	expectPrintedNormalAndMangle(t, "return typeof (false || x); var x", "return typeof x;\nvar x;\n", "return typeof x;\nvar x;\n")
  4626  }
  4627  
  4628  func TestMangleTypeofEqualsUndefined(t *testing.T) {
  4629  	expectPrintedNormalAndMangle(t, "return typeof x !== 'undefined'", "return typeof x !== \"undefined\";\n", "return typeof x < \"u\";\n")
  4630  	expectPrintedNormalAndMangle(t, "return typeof x != 'undefined'", "return typeof x != \"undefined\";\n", "return typeof x < \"u\";\n")
  4631  	expectPrintedNormalAndMangle(t, "return 'undefined' !== typeof x", "return \"undefined\" !== typeof x;\n", "return typeof x < \"u\";\n")
  4632  	expectPrintedNormalAndMangle(t, "return 'undefined' != typeof x", "return \"undefined\" != typeof x;\n", "return typeof x < \"u\";\n")
  4633  
  4634  	expectPrintedNormalAndMangle(t, "return typeof x === 'undefined'", "return typeof x === \"undefined\";\n", "return typeof x > \"u\";\n")
  4635  	expectPrintedNormalAndMangle(t, "return typeof x == 'undefined'", "return typeof x == \"undefined\";\n", "return typeof x > \"u\";\n")
  4636  	expectPrintedNormalAndMangle(t, "return 'undefined' === typeof x", "return \"undefined\" === typeof x;\n", "return typeof x > \"u\";\n")
  4637  	expectPrintedNormalAndMangle(t, "return 'undefined' == typeof x", "return \"undefined\" == typeof x;\n", "return typeof x > \"u\";\n")
  4638  }
  4639  
  4640  func TestMangleEquals(t *testing.T) {
  4641  	expectPrintedNormalAndMangle(t, "return typeof x === y", "return typeof x === y;\n", "return typeof x === y;\n")
  4642  	expectPrintedNormalAndMangle(t, "return typeof x !== y", "return typeof x !== y;\n", "return typeof x !== y;\n")
  4643  	expectPrintedNormalAndMangle(t, "return y === typeof x", "return y === typeof x;\n", "return y === typeof x;\n")
  4644  	expectPrintedNormalAndMangle(t, "return y !== typeof x", "return y !== typeof x;\n", "return y !== typeof x;\n")
  4645  
  4646  	expectPrintedNormalAndMangle(t, "return typeof x === 'string'", "return typeof x === \"string\";\n", "return typeof x == \"string\";\n")
  4647  	expectPrintedNormalAndMangle(t, "return typeof x !== 'string'", "return typeof x !== \"string\";\n", "return typeof x != \"string\";\n")
  4648  	expectPrintedNormalAndMangle(t, "return 'string' === typeof x", "return \"string\" === typeof x;\n", "return typeof x == \"string\";\n")
  4649  	expectPrintedNormalAndMangle(t, "return 'string' !== typeof x", "return \"string\" !== typeof x;\n", "return typeof x != \"string\";\n")
  4650  
  4651  	expectPrintedNormalAndMangle(t, "return a === 0", "return a === 0;\n", "return a === 0;\n")
  4652  	expectPrintedNormalAndMangle(t, "return a !== 0", "return a !== 0;\n", "return a !== 0;\n")
  4653  	expectPrintedNormalAndMangle(t, "return +a === 0", "return +a === 0;\n", "return +a == 0;\n") // No BigInt hazard
  4654  	expectPrintedNormalAndMangle(t, "return +a !== 0", "return +a !== 0;\n", "return +a != 0;\n")
  4655  	expectPrintedNormalAndMangle(t, "return -a === 0", "return -a === 0;\n", "return -a === 0;\n") // BigInt hazard
  4656  	expectPrintedNormalAndMangle(t, "return -a !== 0", "return -a !== 0;\n", "return -a !== 0;\n")
  4657  
  4658  	expectPrintedNormalAndMangle(t, "return a === ''", "return a === \"\";\n", "return a === \"\";\n")
  4659  	expectPrintedNormalAndMangle(t, "return a !== ''", "return a !== \"\";\n", "return a !== \"\";\n")
  4660  	expectPrintedNormalAndMangle(t, "return (a + '!') === 'a!'", "return a + \"!\" === \"a!\";\n", "return a + \"!\" == \"a!\";\n")
  4661  	expectPrintedNormalAndMangle(t, "return (a + '!') !== 'a!'", "return a + \"!\" !== \"a!\";\n", "return a + \"!\" != \"a!\";\n")
  4662  	expectPrintedNormalAndMangle(t, "return (a += '!') === 'a!'", "return (a += \"!\") === \"a!\";\n", "return (a += \"!\") == \"a!\";\n")
  4663  	expectPrintedNormalAndMangle(t, "return (a += '!') !== 'a!'", "return (a += \"!\") !== \"a!\";\n", "return (a += \"!\") != \"a!\";\n")
  4664  
  4665  	expectPrintedNormalAndMangle(t, "return a === false", "return a === false;\n", "return a === false;\n")
  4666  	expectPrintedNormalAndMangle(t, "return a === true", "return a === true;\n", "return a === true;\n")
  4667  	expectPrintedNormalAndMangle(t, "return a !== false", "return a !== false;\n", "return a !== false;\n")
  4668  	expectPrintedNormalAndMangle(t, "return a !== true", "return a !== true;\n", "return a !== true;\n")
  4669  	expectPrintedNormalAndMangle(t, "return !a === false", "return !a === false;\n", "return !!a;\n")
  4670  	expectPrintedNormalAndMangle(t, "return !a === true", "return !a === true;\n", "return !a;\n")
  4671  	expectPrintedNormalAndMangle(t, "return !a !== false", "return !a !== false;\n", "return !a;\n")
  4672  	expectPrintedNormalAndMangle(t, "return !a !== true", "return !a !== true;\n", "return !!a;\n")
  4673  	expectPrintedNormalAndMangle(t, "return false === !a", "return false === !a;\n", "return !!a;\n")
  4674  	expectPrintedNormalAndMangle(t, "return true === !a", "return true === !a;\n", "return !a;\n")
  4675  	expectPrintedNormalAndMangle(t, "return false !== !a", "return false !== !a;\n", "return !a;\n")
  4676  	expectPrintedNormalAndMangle(t, "return true !== !a", "return true !== !a;\n", "return !!a;\n")
  4677  
  4678  	expectPrintedNormalAndMangle(t, "return a === !b", "return a === !b;\n", "return a === !b;\n")
  4679  	expectPrintedNormalAndMangle(t, "return a === !b", "return a === !b;\n", "return a === !b;\n")
  4680  	expectPrintedNormalAndMangle(t, "return a !== !b", "return a !== !b;\n", "return a !== !b;\n")
  4681  	expectPrintedNormalAndMangle(t, "return a !== !b", "return a !== !b;\n", "return a !== !b;\n")
  4682  	expectPrintedNormalAndMangle(t, "return !a === !b", "return !a === !b;\n", "return !a == !b;\n")
  4683  	expectPrintedNormalAndMangle(t, "return !a === !b", "return !a === !b;\n", "return !a == !b;\n")
  4684  	expectPrintedNormalAndMangle(t, "return !a !== !b", "return !a !== !b;\n", "return !a != !b;\n")
  4685  	expectPrintedNormalAndMangle(t, "return !a !== !b", "return !a !== !b;\n", "return !a != !b;\n")
  4686  
  4687  	// These have BigInt hazards and should not be changed
  4688  	expectPrintedNormalAndMangle(t, "return (a, -1n) !== -1", "return (a, -1n) !== -1;\n", "return a, -1n !== -1;\n")
  4689  	expectPrintedNormalAndMangle(t, "return (a, ~1n) !== -1", "return (a, ~1n) !== -1;\n", "return a, ~1n !== -1;\n")
  4690  	expectPrintedNormalAndMangle(t, "return (a -= 1n) !== -1", "return (a -= 1n) !== -1;\n", "return (a -= 1n) !== -1;\n")
  4691  	expectPrintedNormalAndMangle(t, "return (a *= 1n) !== -1", "return (a *= 1n) !== -1;\n", "return (a *= 1n) !== -1;\n")
  4692  	expectPrintedNormalAndMangle(t, "return (a **= 1n) !== -1", "return (a **= 1n) !== -1;\n", "return (a **= 1n) !== -1;\n")
  4693  	expectPrintedNormalAndMangle(t, "return (a /= 1n) !== -1", "return (a /= 1n) !== -1;\n", "return (a /= 1n) !== -1;\n")
  4694  	expectPrintedNormalAndMangle(t, "return (a %= 1n) !== -1", "return (a %= 1n) !== -1;\n", "return (a %= 1n) !== -1;\n")
  4695  	expectPrintedNormalAndMangle(t, "return (a &= 1n) !== -1", "return (a &= 1n) !== -1;\n", "return (a &= 1n) !== -1;\n")
  4696  	expectPrintedNormalAndMangle(t, "return (a |= 1n) !== -1", "return (a |= 1n) !== -1;\n", "return (a |= 1n) !== -1;\n")
  4697  	expectPrintedNormalAndMangle(t, "return (a ^= 1n) !== -1", "return (a ^= 1n) !== -1;\n", "return (a ^= 1n) !== -1;\n")
  4698  }
  4699  
  4700  func TestMangleUnaryInsideComma(t *testing.T) {
  4701  	expectPrintedNormalAndMangle(t, "return -(a, b)", "return -(a, b);\n", "return a, -b;\n")
  4702  	expectPrintedNormalAndMangle(t, "return +(a, b)", "return +(a, b);\n", "return a, +b;\n")
  4703  	expectPrintedNormalAndMangle(t, "return ~(a, b)", "return ~(a, b);\n", "return a, ~b;\n")
  4704  	expectPrintedNormalAndMangle(t, "return !(a, b)", "return !(a, b);\n", "return a, !b;\n")
  4705  	expectPrintedNormalAndMangle(t, "return void (a, b)", "return void (a, b);\n", "return a, void b;\n")
  4706  	expectPrintedNormalAndMangle(t, "return typeof (a, b)", "return typeof (a, b);\n", "return typeof (a, b);\n")
  4707  	expectPrintedNormalAndMangle(t, "return delete (a, b)", "return delete (a, b);\n", "return delete (a, b);\n")
  4708  }
  4709  
  4710  func TestMangleBinaryInsideComma(t *testing.T) {
  4711  	expectPrintedNormalAndMangle(t, "(a, b) && c", "(a, b) && c;\n", "a, b && c;\n")
  4712  	expectPrintedNormalAndMangle(t, "(a, b) == c", "(a, b) == c;\n", "a, b == c;\n")
  4713  	expectPrintedNormalAndMangle(t, "(a, b) + c", "(a, b) + c;\n", "a, b + c;\n")
  4714  	expectPrintedNormalAndMangle(t, "a && (b, c)", "a && (b, c);\n", "a && (b, c);\n")
  4715  	expectPrintedNormalAndMangle(t, "a == (b, c)", "a == (b, c);\n", "a == (b, c);\n")
  4716  	expectPrintedNormalAndMangle(t, "a + (b, c)", "a + (b, c);\n", "a + (b, c);\n")
  4717  }
  4718  
  4719  func TestMangleUnaryConstantFolding(t *testing.T) {
  4720  	expectPrintedNormalAndMangle(t, "x = +5", "x = 5;\n", "x = 5;\n")
  4721  	expectPrintedNormalAndMangle(t, "x = -5", "x = -5;\n", "x = -5;\n")
  4722  	expectPrintedNormalAndMangle(t, "x = ~5", "x = ~5;\n", "x = -6;\n")
  4723  	expectPrintedNormalAndMangle(t, "x = !5", "x = false;\n", "x = false;\n")
  4724  	expectPrintedNormalAndMangle(t, "x = typeof 5", "x = \"number\";\n", "x = \"number\";\n")
  4725  
  4726  	expectPrintedNormalAndMangle(t, "x = +''", "x = 0;\n", "x = 0;\n")
  4727  	expectPrintedNormalAndMangle(t, "x = +[]", "x = 0;\n", "x = 0;\n")
  4728  	expectPrintedNormalAndMangle(t, "x = +{}", "x = NaN;\n", "x = NaN;\n")
  4729  	expectPrintedNormalAndMangle(t, "x = +/1/", "x = NaN;\n", "x = NaN;\n")
  4730  	expectPrintedNormalAndMangle(t, "x = +[1]", "x = +[1];\n", "x = +[1];\n")
  4731  	expectPrintedNormalAndMangle(t, "x = +'123'", "x = 123;\n", "x = 123;\n")
  4732  	expectPrintedNormalAndMangle(t, "x = +'-123'", "x = -123;\n", "x = -123;\n")
  4733  	expectPrintedNormalAndMangle(t, "x = +'0x10'", "x = +\"0x10\";\n", "x = +\"0x10\";\n")
  4734  	expectPrintedNormalAndMangle(t, "x = +{toString:()=>1}", "x = +{ toString: () => 1 };\n", "x = +{ toString: () => 1 };\n")
  4735  	expectPrintedNormalAndMangle(t, "x = +{valueOf:()=>1}", "x = +{ valueOf: () => 1 };\n", "x = +{ valueOf: () => 1 };\n")
  4736  }
  4737  
  4738  func TestMangleBinaryConstantFolding(t *testing.T) {
  4739  	expectPrintedNormalAndMangle(t, "x = 3 + 6", "x = 3 + 6;\n", "x = 9;\n")
  4740  	expectPrintedNormalAndMangle(t, "x = 3 - 6", "x = 3 - 6;\n", "x = -3;\n")
  4741  	expectPrintedNormalAndMangle(t, "x = 3 * 6", "x = 3 * 6;\n", "x = 3 * 6;\n")
  4742  	expectPrintedNormalAndMangle(t, "x = 3 / 6", "x = 3 / 6;\n", "x = 3 / 6;\n")
  4743  	expectPrintedNormalAndMangle(t, "x = 3 % 6", "x = 3 % 6;\n", "x = 3 % 6;\n")
  4744  	expectPrintedNormalAndMangle(t, "x = 3 ** 6", "x = 3 ** 6;\n", "x = 3 ** 6;\n")
  4745  
  4746  	expectPrintedNormalAndMangle(t, "x = 0 / 0", "x = 0 / 0;\n", "x = NaN;\n")
  4747  	expectPrintedNormalAndMangle(t, "x = 123 / 0", "x = 123 / 0;\n", "x = Infinity;\n")
  4748  	expectPrintedNormalAndMangle(t, "x = 123 / -0", "x = 123 / -0;\n", "x = -Infinity;\n")
  4749  	expectPrintedNormalAndMangle(t, "x = -123 / 0", "x = -123 / 0;\n", "x = -Infinity;\n")
  4750  	expectPrintedNormalAndMangle(t, "x = -123 / -0", "x = -123 / -0;\n", "x = Infinity;\n")
  4751  
  4752  	expectPrintedNormalAndMangle(t, "x = 3 < 6", "x = 3 < 6;\n", "x = true;\n")
  4753  	expectPrintedNormalAndMangle(t, "x = 3 > 6", "x = 3 > 6;\n", "x = false;\n")
  4754  	expectPrintedNormalAndMangle(t, "x = 3 <= 6", "x = 3 <= 6;\n", "x = true;\n")
  4755  	expectPrintedNormalAndMangle(t, "x = 3 >= 6", "x = 3 >= 6;\n", "x = false;\n")
  4756  	expectPrintedNormalAndMangle(t, "x = 3 == 6", "x = false;\n", "x = false;\n")
  4757  	expectPrintedNormalAndMangle(t, "x = 3 != 6", "x = true;\n", "x = true;\n")
  4758  	expectPrintedNormalAndMangle(t, "x = 3 === 6", "x = false;\n", "x = false;\n")
  4759  	expectPrintedNormalAndMangle(t, "x = 3 !== 6", "x = true;\n", "x = true;\n")
  4760  
  4761  	expectPrintedNormalAndMangle(t, "x = 'a' < 'b'", "x = \"a\" < \"b\";\n", "x = true;\n")
  4762  	expectPrintedNormalAndMangle(t, "x = 'a' > 'b'", "x = \"a\" > \"b\";\n", "x = false;\n")
  4763  	expectPrintedNormalAndMangle(t, "x = 'a' <= 'b'", "x = \"a\" <= \"b\";\n", "x = true;\n")
  4764  	expectPrintedNormalAndMangle(t, "x = 'a' >= 'b'", "x = \"a\" >= \"b\";\n", "x = false;\n")
  4765  
  4766  	expectPrintedNormalAndMangle(t, "x = 'ab' < 'abc'", "x = \"ab\" < \"abc\";\n", "x = true;\n")
  4767  	expectPrintedNormalAndMangle(t, "x = 'ab' > 'abc'", "x = \"ab\" > \"abc\";\n", "x = false;\n")
  4768  	expectPrintedNormalAndMangle(t, "x = 'ab' <= 'abc'", "x = \"ab\" <= \"abc\";\n", "x = true;\n")
  4769  	expectPrintedNormalAndMangle(t, "x = 'ab' >= 'abc'", "x = \"ab\" >= \"abc\";\n", "x = false;\n")
  4770  
  4771  	// This checks for comparing by code point vs. by code unit
  4772  	expectPrintedNormalAndMangle(t, "x = '𐙩' < 'ﬔ'", "x = \"𐙩\" < \"ﬔ\";\n", "x = true;\n")
  4773  	expectPrintedNormalAndMangle(t, "x = '𐙩' > 'ﬔ'", "x = \"𐙩\" > \"ﬔ\";\n", "x = false;\n")
  4774  	expectPrintedNormalAndMangle(t, "x = '𐙩' <= 'ﬔ'", "x = \"𐙩\" <= \"ﬔ\";\n", "x = true;\n")
  4775  	expectPrintedNormalAndMangle(t, "x = '𐙩' >= 'ﬔ'", "x = \"𐙩\" >= \"ﬔ\";\n", "x = false;\n")
  4776  
  4777  	expectPrintedNormalAndMangle(t, "x = 3 in 6", "x = 3 in 6;\n", "x = 3 in 6;\n")
  4778  	expectPrintedNormalAndMangle(t, "x = 3 instanceof 6", "x = 3 instanceof 6;\n", "x = 3 instanceof 6;\n")
  4779  	expectPrintedNormalAndMangle(t, "x = (3, 6)", "x = (3, 6);\n", "x = 6;\n")
  4780  
  4781  	expectPrintedNormalAndMangle(t, "x = 10 << 0", "x = 10 << 0;\n", "x = 10;\n")
  4782  	expectPrintedNormalAndMangle(t, "x = 10 << 1", "x = 10 << 1;\n", "x = 20;\n")
  4783  	expectPrintedNormalAndMangle(t, "x = 10 << 16", "x = 10 << 16;\n", "x = 655360;\n")
  4784  	expectPrintedNormalAndMangle(t, "x = 10 << 17", "x = 10 << 17;\n", "x = 10 << 17;\n")
  4785  	expectPrintedNormalAndMangle(t, "x = 10 >> 0", "x = 10 >> 0;\n", "x = 10;\n")
  4786  	expectPrintedNormalAndMangle(t, "x = 10 >> 1", "x = 10 >> 1;\n", "x = 5;\n")
  4787  	expectPrintedNormalAndMangle(t, "x = 10 >>> 0", "x = 10 >>> 0;\n", "x = 10;\n")
  4788  	expectPrintedNormalAndMangle(t, "x = 10 >>> 1", "x = 10 >>> 1;\n", "x = 5;\n")
  4789  	expectPrintedNormalAndMangle(t, "x = -10 >>> 1", "x = -10 >>> 1;\n", "x = -10 >>> 1;\n")
  4790  	expectPrintedNormalAndMangle(t, "x = -1 >>> 0", "x = -1 >>> 0;\n", "x = -1 >>> 0;\n")
  4791  	expectPrintedNormalAndMangle(t, "x = -123 >>> 5", "x = -123 >>> 5;\n", "x = -123 >>> 5;\n")
  4792  	expectPrintedNormalAndMangle(t, "x = -123 >>> 6", "x = -123 >>> 6;\n", "x = 67108862;\n")
  4793  	expectPrintedNormalAndMangle(t, "x = 3 & 6", "x = 3 & 6;\n", "x = 2;\n")
  4794  	expectPrintedNormalAndMangle(t, "x = 3 | 6", "x = 3 | 6;\n", "x = 7;\n")
  4795  	expectPrintedNormalAndMangle(t, "x = 3 ^ 6", "x = 3 ^ 6;\n", "x = 5;\n")
  4796  
  4797  	expectPrintedNormalAndMangle(t, "x = 3 && 6", "x = 6;\n", "x = 6;\n")
  4798  	expectPrintedNormalAndMangle(t, "x = 3 || 6", "x = 3;\n", "x = 3;\n")
  4799  	expectPrintedNormalAndMangle(t, "x = 3 ?? 6", "x = 3;\n", "x = 3;\n")
  4800  }
  4801  
  4802  func TestMangleNestedLogical(t *testing.T) {
  4803  	expectPrintedNormalAndMangle(t, "(a && b) && c", "a && b && c;\n", "a && b && c;\n")
  4804  	expectPrintedNormalAndMangle(t, "a && (b && c)", "a && (b && c);\n", "a && b && c;\n")
  4805  	expectPrintedNormalAndMangle(t, "(a || b) && c", "(a || b) && c;\n", "(a || b) && c;\n")
  4806  	expectPrintedNormalAndMangle(t, "a && (b || c)", "a && (b || c);\n", "a && (b || c);\n")
  4807  
  4808  	expectPrintedNormalAndMangle(t, "(a || b) || c", "a || b || c;\n", "a || b || c;\n")
  4809  	expectPrintedNormalAndMangle(t, "a || (b || c)", "a || (b || c);\n", "a || b || c;\n")
  4810  	expectPrintedNormalAndMangle(t, "(a && b) || c", "a && b || c;\n", "a && b || c;\n")
  4811  	expectPrintedNormalAndMangle(t, "a || (b && c)", "a || b && c;\n", "a || b && c;\n")
  4812  }
  4813  
  4814  func TestMangleEqualsUndefined(t *testing.T) {
  4815  	expectPrintedNormalAndMangle(t, "return a === void 0", "return a === void 0;\n", "return a === void 0;\n")
  4816  	expectPrintedNormalAndMangle(t, "return a !== void 0", "return a !== void 0;\n", "return a !== void 0;\n")
  4817  	expectPrintedNormalAndMangle(t, "return void 0 === a", "return void 0 === a;\n", "return a === void 0;\n")
  4818  	expectPrintedNormalAndMangle(t, "return void 0 !== a", "return void 0 !== a;\n", "return a !== void 0;\n")
  4819  
  4820  	expectPrintedNormalAndMangle(t, "return a == void 0", "return a == void 0;\n", "return a == null;\n")
  4821  	expectPrintedNormalAndMangle(t, "return a != void 0", "return a != void 0;\n", "return a != null;\n")
  4822  	expectPrintedNormalAndMangle(t, "return void 0 == a", "return void 0 == a;\n", "return a == null;\n")
  4823  	expectPrintedNormalAndMangle(t, "return void 0 != a", "return void 0 != a;\n", "return a != null;\n")
  4824  
  4825  	expectPrintedNormalAndMangle(t, "return a === null || a === undefined", "return a === null || a === void 0;\n", "return a == null;\n")
  4826  	expectPrintedNormalAndMangle(t, "return a === null || a !== undefined", "return a === null || a !== void 0;\n", "return a === null || a !== void 0;\n")
  4827  	expectPrintedNormalAndMangle(t, "return a !== null || a === undefined", "return a !== null || a === void 0;\n", "return a !== null || a === void 0;\n")
  4828  	expectPrintedNormalAndMangle(t, "return a === null && a === undefined", "return a === null && a === void 0;\n", "return a === null && a === void 0;\n")
  4829  	expectPrintedNormalAndMangle(t, "return a.x === null || a.x === undefined", "return a.x === null || a.x === void 0;\n", "return a.x === null || a.x === void 0;\n")
  4830  
  4831  	expectPrintedNormalAndMangle(t, "return a === undefined || a === null", "return a === void 0 || a === null;\n", "return a == null;\n")
  4832  	expectPrintedNormalAndMangle(t, "return a === undefined || a !== null", "return a === void 0 || a !== null;\n", "return a === void 0 || a !== null;\n")
  4833  	expectPrintedNormalAndMangle(t, "return a !== undefined || a === null", "return a !== void 0 || a === null;\n", "return a !== void 0 || a === null;\n")
  4834  	expectPrintedNormalAndMangle(t, "return a === undefined && a === null", "return a === void 0 && a === null;\n", "return a === void 0 && a === null;\n")
  4835  	expectPrintedNormalAndMangle(t, "return a.x === undefined || a.x === null", "return a.x === void 0 || a.x === null;\n", "return a.x === void 0 || a.x === null;\n")
  4836  
  4837  	expectPrintedNormalAndMangle(t, "return a !== null && a !== undefined", "return a !== null && a !== void 0;\n", "return a != null;\n")
  4838  	expectPrintedNormalAndMangle(t, "return a !== null && a === undefined", "return a !== null && a === void 0;\n", "return a !== null && a === void 0;\n")
  4839  	expectPrintedNormalAndMangle(t, "return a === null && a !== undefined", "return a === null && a !== void 0;\n", "return a === null && a !== void 0;\n")
  4840  	expectPrintedNormalAndMangle(t, "return a !== null || a !== undefined", "return a !== null || a !== void 0;\n", "return a !== null || a !== void 0;\n")
  4841  	expectPrintedNormalAndMangle(t, "return a.x !== null && a.x !== undefined", "return a.x !== null && a.x !== void 0;\n", "return a.x !== null && a.x !== void 0;\n")
  4842  
  4843  	expectPrintedNormalAndMangle(t, "return a !== undefined && a !== null", "return a !== void 0 && a !== null;\n", "return a != null;\n")
  4844  	expectPrintedNormalAndMangle(t, "return a !== undefined && a === null", "return a !== void 0 && a === null;\n", "return a !== void 0 && a === null;\n")
  4845  	expectPrintedNormalAndMangle(t, "return a === undefined && a !== null", "return a === void 0 && a !== null;\n", "return a === void 0 && a !== null;\n")
  4846  	expectPrintedNormalAndMangle(t, "return a !== undefined || a !== null", "return a !== void 0 || a !== null;\n", "return a !== void 0 || a !== null;\n")
  4847  	expectPrintedNormalAndMangle(t, "return a.x !== undefined && a.x !== null", "return a.x !== void 0 && a.x !== null;\n", "return a.x !== void 0 && a.x !== null;\n")
  4848  }
  4849  
  4850  func TestMangleUnusedFunctionExpressionNames(t *testing.T) {
  4851  	expectPrintedNormalAndMangle(t, "x = function y() {}", "x = function y() {\n};\n", "x = function() {\n};\n")
  4852  	expectPrintedNormalAndMangle(t, "x = function y() { return y }", "x = function y() {\n  return y;\n};\n", "x = function y() {\n  return y;\n};\n")
  4853  	expectPrintedNormalAndMangle(t, "x = function y() { return eval('y') }", "x = function y() {\n  return eval(\"y\");\n};\n", "x = function y() {\n  return eval(\"y\");\n};\n")
  4854  	expectPrintedNormalAndMangle(t, "x = function y() { if (0) return y }", "x = function y() {\n  if (0) return y;\n};\n", "x = function() {\n};\n")
  4855  }
  4856  
  4857  func TestMangleClass(t *testing.T) {
  4858  	expectPrintedNormalAndMangle(t, "class x {['y'] = z}", "class x {\n  [\"y\"] = z;\n}\n", "class x {\n  y = z;\n}\n")
  4859  	expectPrintedNormalAndMangle(t, "class x {['y']() {}}", "class x {\n  [\"y\"]() {\n  }\n}\n", "class x {\n  y() {\n  }\n}\n")
  4860  	expectPrintedNormalAndMangle(t, "class x {get ['y']() {}}", "class x {\n  get [\"y\"]() {\n  }\n}\n", "class x {\n  get y() {\n  }\n}\n")
  4861  	expectPrintedNormalAndMangle(t, "class x {set ['y'](z) {}}", "class x {\n  set [\"y\"](z) {\n  }\n}\n", "class x {\n  set y(z) {\n  }\n}\n")
  4862  	expectPrintedNormalAndMangle(t, "class x {async ['y']() {}}", "class x {\n  async [\"y\"]() {\n  }\n}\n", "class x {\n  async y() {\n  }\n}\n")
  4863  
  4864  	expectPrintedNormalAndMangle(t, "x = class {['y'] = z}", "x = class {\n  [\"y\"] = z;\n};\n", "x = class {\n  y = z;\n};\n")
  4865  	expectPrintedNormalAndMangle(t, "x = class {['y']() {}}", "x = class {\n  [\"y\"]() {\n  }\n};\n", "x = class {\n  y() {\n  }\n};\n")
  4866  	expectPrintedNormalAndMangle(t, "x = class {get ['y']() {}}", "x = class {\n  get [\"y\"]() {\n  }\n};\n", "x = class {\n  get y() {\n  }\n};\n")
  4867  	expectPrintedNormalAndMangle(t, "x = class {set ['y'](z) {}}", "x = class {\n  set [\"y\"](z) {\n  }\n};\n", "x = class {\n  set y(z) {\n  }\n};\n")
  4868  	expectPrintedNormalAndMangle(t, "x = class {async ['y']() {}}", "x = class {\n  async [\"y\"]() {\n  }\n};\n", "x = class {\n  async y() {\n  }\n};\n")
  4869  }
  4870  
  4871  func TestMangleUnusedClassExpressionNames(t *testing.T) {
  4872  	expectPrintedNormalAndMangle(t, "x = class y {}", "x = class y {\n};\n", "x = class {\n};\n")
  4873  	expectPrintedNormalAndMangle(t, "x = class y { foo() { return y } }", "x = class y {\n  foo() {\n    return y;\n  }\n};\n", "x = class y {\n  foo() {\n    return y;\n  }\n};\n")
  4874  	expectPrintedNormalAndMangle(t, "x = class y { foo() { if (0) return y } }", "x = class y {\n  foo() {\n    if (0) return _y;\n  }\n};\n", "x = class {\n  foo() {\n  }\n};\n")
  4875  }
  4876  
  4877  func TestMangleUnused(t *testing.T) {
  4878  	expectPrintedNormalAndMangle(t, "null", "null;\n", "")
  4879  	expectPrintedNormalAndMangle(t, "void 0", "", "")
  4880  	expectPrintedNormalAndMangle(t, "void 0", "", "")
  4881  	expectPrintedNormalAndMangle(t, "false", "false;\n", "")
  4882  	expectPrintedNormalAndMangle(t, "true", "true;\n", "")
  4883  	expectPrintedNormalAndMangle(t, "123", "123;\n", "")
  4884  	expectPrintedNormalAndMangle(t, "123n", "123n;\n", "")
  4885  	expectPrintedNormalAndMangle(t, "'abc'", "\"abc\";\n", "\"abc\";\n") // Technically a directive, not a string expression
  4886  	expectPrintedNormalAndMangle(t, "0; 'abc'", "0;\n\"abc\";\n", "")    // Actually a string expression
  4887  	expectPrintedNormalAndMangle(t, "'abc'; 'use strict'", "\"abc\";\n\"use strict\";\n", "\"abc\";\n\"use strict\";\n")
  4888  	expectPrintedNormalAndMangle(t, "function f() { 'abc'; 'use strict' }", "function f() {\n  \"abc\";\n  \"use strict\";\n}\n", "function f() {\n  \"abc\";\n  \"use strict\";\n}\n")
  4889  	expectPrintedNormalAndMangle(t, "this", "this;\n", "")
  4890  	expectPrintedNormalAndMangle(t, "/regex/", "/regex/;\n", "")
  4891  	expectPrintedNormalAndMangle(t, "(function() {})", "(function() {\n});\n", "")
  4892  	expectPrintedNormalAndMangle(t, "(() => {})", "() => {\n};\n", "")
  4893  	expectPrintedNormalAndMangle(t, "import.meta", "import.meta;\n", "")
  4894  
  4895  	// Unary operators
  4896  	expectPrintedNormalAndMangle(t, "+x", "+x;\n", "+x;\n")
  4897  	expectPrintedNormalAndMangle(t, "-x", "-x;\n", "-x;\n")
  4898  	expectPrintedNormalAndMangle(t, "!x", "!x;\n", "x;\n")
  4899  	expectPrintedNormalAndMangle(t, "~x", "~x;\n", "~x;\n")
  4900  	expectPrintedNormalAndMangle(t, "++x", "++x;\n", "++x;\n")
  4901  	expectPrintedNormalAndMangle(t, "--x", "--x;\n", "--x;\n")
  4902  	expectPrintedNormalAndMangle(t, "x++", "x++;\n", "x++;\n")
  4903  	expectPrintedNormalAndMangle(t, "x--", "x--;\n", "x--;\n")
  4904  	expectPrintedNormalAndMangle(t, "void x", "void x;\n", "x;\n")
  4905  	expectPrintedNormalAndMangle(t, "delete x", "delete x;\n", "delete x;\n")
  4906  	expectPrintedNormalAndMangle(t, "typeof x", "typeof x;\n", "")
  4907  	expectPrintedNormalAndMangle(t, "typeof x()", "typeof x();\n", "x();\n")
  4908  	expectPrintedNormalAndMangle(t, "typeof (0, x)", "typeof (0, x);\n", "x;\n")
  4909  	expectPrintedNormalAndMangle(t, "typeof (0 || x)", "typeof (0, x);\n", "x;\n")
  4910  	expectPrintedNormalAndMangle(t, "typeof (1 && x)", "typeof (0, x);\n", "x;\n")
  4911  	expectPrintedNormalAndMangle(t, "typeof (1 ? x : 0)", "typeof (1 ? x : 0);\n", "x;\n")
  4912  	expectPrintedNormalAndMangle(t, "typeof (0 ? 1 : x)", "typeof (0 ? 1 : x);\n", "x;\n")
  4913  
  4914  	// Binary operators
  4915  	expectPrintedNormalAndMangle(t, "a + b", "a + b;\n", "a + b;\n")
  4916  	expectPrintedNormalAndMangle(t, "a - b", "a - b;\n", "a - b;\n")
  4917  	expectPrintedNormalAndMangle(t, "a * b", "a * b;\n", "a * b;\n")
  4918  	expectPrintedNormalAndMangle(t, "a / b", "a / b;\n", "a / b;\n")
  4919  	expectPrintedNormalAndMangle(t, "a % b", "a % b;\n", "a % b;\n")
  4920  	expectPrintedNormalAndMangle(t, "a ** b", "a ** b;\n", "a ** b;\n")
  4921  	expectPrintedNormalAndMangle(t, "a & b", "a & b;\n", "a & b;\n")
  4922  	expectPrintedNormalAndMangle(t, "a | b", "a | b;\n", "a | b;\n")
  4923  	expectPrintedNormalAndMangle(t, "a ^ b", "a ^ b;\n", "a ^ b;\n")
  4924  	expectPrintedNormalAndMangle(t, "a << b", "a << b;\n", "a << b;\n")
  4925  	expectPrintedNormalAndMangle(t, "a >> b", "a >> b;\n", "a >> b;\n")
  4926  	expectPrintedNormalAndMangle(t, "a >>> b", "a >>> b;\n", "a >>> b;\n")
  4927  	expectPrintedNormalAndMangle(t, "a === b", "a === b;\n", "a, b;\n")
  4928  	expectPrintedNormalAndMangle(t, "a !== b", "a !== b;\n", "a, b;\n")
  4929  	expectPrintedNormalAndMangle(t, "a == b", "a == b;\n", "a == b;\n")
  4930  	expectPrintedNormalAndMangle(t, "a != b", "a != b;\n", "a != b;\n")
  4931  	expectPrintedNormalAndMangle(t, "a, b", "a, b;\n", "a, b;\n")
  4932  
  4933  	expectPrintedNormalAndMangle(t, "a + '' == b", "a + \"\" == b;\n", "a + \"\" == b;\n")
  4934  	expectPrintedNormalAndMangle(t, "a + '' != b", "a + \"\" != b;\n", "a + \"\" != b;\n")
  4935  	expectPrintedNormalAndMangle(t, "a + '' == b + ''", "a + \"\" == b + \"\";\n", "a + \"\", b + \"\";\n")
  4936  	expectPrintedNormalAndMangle(t, "a + '' != b + ''", "a + \"\" != b + \"\";\n", "a + \"\", b + \"\";\n")
  4937  	expectPrintedNormalAndMangle(t, "a + '' == (b | c)", "a + \"\" == (b | c);\n", "a + \"\", b | c;\n")
  4938  	expectPrintedNormalAndMangle(t, "a + '' != (b | c)", "a + \"\" != (b | c);\n", "a + \"\", b | c;\n")
  4939  	expectPrintedNormalAndMangle(t, "typeof a == b + ''", "typeof a == b + \"\";\n", "b + \"\";\n")
  4940  	expectPrintedNormalAndMangle(t, "typeof a != b + ''", "typeof a != b + \"\";\n", "b + \"\";\n")
  4941  	expectPrintedNormalAndMangle(t, "typeof a == 'b'", "typeof a == \"b\";\n", "")
  4942  	expectPrintedNormalAndMangle(t, "typeof a != 'b'", "typeof a != \"b\";\n", "")
  4943  
  4944  	// Known globals can be removed
  4945  	expectPrintedNormalAndMangle(t, "Object", "Object;\n", "")
  4946  	expectPrintedNormalAndMangle(t, "Object()", "Object();\n", "Object();\n")
  4947  	expectPrintedNormalAndMangle(t, "NonObject", "NonObject;\n", "NonObject;\n")
  4948  
  4949  	expectPrintedNormalAndMangle(t, "var bound; unbound", "var bound;\nunbound;\n", "var bound;\nunbound;\n")
  4950  	expectPrintedNormalAndMangle(t, "var bound; bound", "var bound;\nbound;\n", "var bound;\n")
  4951  	expectPrintedNormalAndMangle(t, "foo, 123, bar", "foo, 123, bar;\n", "foo, bar;\n")
  4952  
  4953  	expectPrintedNormalAndMangle(t, "[[foo,, 123,, bar]]", "[[foo, , 123, , bar]];\n", "foo, bar;\n")
  4954  	expectPrintedNormalAndMangle(t, "var bound; [123, unbound, ...unbound, 234]", "var bound;\n[123, unbound, ...unbound, 234];\n", "var bound;\n[unbound, ...unbound];\n")
  4955  	expectPrintedNormalAndMangle(t, "var bound; [123, bound, ...bound, 234]", "var bound;\n[123, bound, ...bound, 234];\n", "var bound;\n[...bound];\n")
  4956  
  4957  	expectPrintedNormalAndMangle(t,
  4958  		"({foo, x: 123, [y]: 123, z: z, bar})",
  4959  		"({ foo, x: 123, [y]: 123, z, bar });\n",
  4960  		"foo, y + \"\", z, bar;\n")
  4961  	expectPrintedNormalAndMangle(t,
  4962  		"var bound; ({x: 123, unbound, ...unbound, [unbound]: null, y: 234})",
  4963  		"var bound;\n({ x: 123, unbound, ...unbound, [unbound]: null, y: 234 });\n",
  4964  		"var bound;\n({ unbound, ...unbound, [unbound]: 0 });\n")
  4965  	expectPrintedNormalAndMangle(t,
  4966  		"var bound; ({x: 123, bound, ...bound, [bound]: null, y: 234})",
  4967  		"var bound;\n({ x: 123, bound, ...bound, [bound]: null, y: 234 });\n",
  4968  		"var bound;\n({ ...bound, [bound]: 0 });\n")
  4969  	expectPrintedNormalAndMangle(t,
  4970  		"var bound; ({x: 123, bound, ...bound, [bound]: foo(), y: 234})",
  4971  		"var bound;\n({ x: 123, bound, ...bound, [bound]: foo(), y: 234 });\n",
  4972  		"var bound;\n({ ...bound, [bound]: foo() });\n")
  4973  
  4974  	expectPrintedNormalAndMangle(t, "console.log(1, foo(), bar())", "console.log(1, foo(), bar());\n", "console.log(1, foo(), bar());\n")
  4975  	expectPrintedNormalAndMangle(t, "/* @__PURE__ */ console.log(1, foo(), bar())", "/* @__PURE__ */ console.log(1, foo(), bar());\n", "foo(), bar();\n")
  4976  
  4977  	expectPrintedNormalAndMangle(t, "new TestCase(1, foo(), bar())", "new TestCase(1, foo(), bar());\n", "new TestCase(1, foo(), bar());\n")
  4978  	expectPrintedNormalAndMangle(t, "/* @__PURE__ */ new TestCase(1, foo(), bar())", "/* @__PURE__ */ new TestCase(1, foo(), bar());\n", "foo(), bar();\n")
  4979  
  4980  	expectPrintedNormalAndMangle(t, "let x = (1, 2)", "let x = (1, 2);\n", "let x = 2;\n")
  4981  	expectPrintedNormalAndMangle(t, "let x = (y, 2)", "let x = (y, 2);\n", "let x = (y, 2);\n")
  4982  	expectPrintedNormalAndMangle(t, "let x = (/* @__PURE__ */ foo(bar), 2)", "let x = (/* @__PURE__ */ foo(bar), 2);\n", "let x = (bar, 2);\n")
  4983  
  4984  	expectPrintedNormalAndMangle(t, "let x = (2, y)", "let x = (2, y);\n", "let x = y;\n")
  4985  	expectPrintedNormalAndMangle(t, "let x = (2, y)()", "let x = (2, y)();\n", "let x = y();\n")
  4986  	expectPrintedNormalAndMangle(t, "let x = (true && y)()", "let x = y();\n", "let x = y();\n")
  4987  	expectPrintedNormalAndMangle(t, "let x = (false || y)()", "let x = y();\n", "let x = y();\n")
  4988  	expectPrintedNormalAndMangle(t, "let x = (null ?? y)()", "let x = y();\n", "let x = y();\n")
  4989  	expectPrintedNormalAndMangle(t, "let x = (1 ? y : 2)()", "let x = (1 ? y : 2)();\n", "let x = y();\n")
  4990  	expectPrintedNormalAndMangle(t, "let x = (0 ? 1 : y)()", "let x = (0 ? 1 : y)();\n", "let x = y();\n")
  4991  
  4992  	// Make sure call targets with "this" values are preserved
  4993  	expectPrintedNormalAndMangle(t, "let x = (2, y.z)", "let x = (2, y.z);\n", "let x = y.z;\n")
  4994  	expectPrintedNormalAndMangle(t, "let x = (2, y.z)()", "let x = (2, y.z)();\n", "let x = (0, y.z)();\n")
  4995  	expectPrintedNormalAndMangle(t, "let x = (true && y.z)()", "let x = (0, y.z)();\n", "let x = (0, y.z)();\n")
  4996  	expectPrintedNormalAndMangle(t, "let x = (false || y.z)()", "let x = (0, y.z)();\n", "let x = (0, y.z)();\n")
  4997  	expectPrintedNormalAndMangle(t, "let x = (null ?? y.z)()", "let x = (0, y.z)();\n", "let x = (0, y.z)();\n")
  4998  	expectPrintedNormalAndMangle(t, "let x = (1 ? y.z : 2)()", "let x = (1 ? y.z : 2)();\n", "let x = (0, y.z)();\n")
  4999  	expectPrintedNormalAndMangle(t, "let x = (0 ? 1 : y.z)()", "let x = (0 ? 1 : y.z)();\n", "let x = (0, y.z)();\n")
  5000  
  5001  	expectPrintedNormalAndMangle(t, "let x = (2, y[z])", "let x = (2, y[z]);\n", "let x = y[z];\n")
  5002  	expectPrintedNormalAndMangle(t, "let x = (2, y[z])()", "let x = (2, y[z])();\n", "let x = (0, y[z])();\n")
  5003  	expectPrintedNormalAndMangle(t, "let x = (true && y[z])()", "let x = (0, y[z])();\n", "let x = (0, y[z])();\n")
  5004  	expectPrintedNormalAndMangle(t, "let x = (false || y[z])()", "let x = (0, y[z])();\n", "let x = (0, y[z])();\n")
  5005  	expectPrintedNormalAndMangle(t, "let x = (null ?? y[z])()", "let x = (0, y[z])();\n", "let x = (0, y[z])();\n")
  5006  	expectPrintedNormalAndMangle(t, "let x = (1 ? y[z] : 2)()", "let x = (1 ? y[z] : 2)();\n", "let x = (0, y[z])();\n")
  5007  	expectPrintedNormalAndMangle(t, "let x = (0 ? 1 : y[z])()", "let x = (0 ? 1 : y[z])();\n", "let x = (0, y[z])();\n")
  5008  
  5009  	// Make sure the return value of "delete" is preserved
  5010  	expectPrintedNormalAndMangle(t, "delete (x)", "delete x;\n", "delete x;\n")
  5011  	expectPrintedNormalAndMangle(t, "delete (x); var x", "delete x;\nvar x;\n", "delete x;\nvar x;\n")
  5012  	expectPrintedNormalAndMangle(t, "delete (x.y)", "delete x.y;\n", "delete x.y;\n")
  5013  	expectPrintedNormalAndMangle(t, "delete (x[y])", "delete x[y];\n", "delete x[y];\n")
  5014  	expectPrintedNormalAndMangle(t, "delete (x?.y)", "delete x?.y;\n", "delete x?.y;\n")
  5015  	expectPrintedNormalAndMangle(t, "delete (x?.[y])", "delete x?.[y];\n", "delete x?.[y];\n")
  5016  	expectPrintedNormalAndMangle(t, "delete (2, x)", "delete (2, x);\n", "delete (0, x);\n")
  5017  	expectPrintedNormalAndMangle(t, "delete (2, x); var x", "delete (2, x);\nvar x;\n", "delete (0, x);\nvar x;\n")
  5018  	expectPrintedNormalAndMangle(t, "delete (2, x.y)", "delete (2, x.y);\n", "delete (0, x.y);\n")
  5019  	expectPrintedNormalAndMangle(t, "delete (2, x[y])", "delete (2, x[y]);\n", "delete (0, x[y]);\n")
  5020  	expectPrintedNormalAndMangle(t, "delete (2, x?.y)", "delete (2, x?.y);\n", "delete (0, x?.y);\n")
  5021  	expectPrintedNormalAndMangle(t, "delete (2, x?.[y])", "delete (2, x?.[y]);\n", "delete (0, x?.[y]);\n")
  5022  	expectPrintedNormalAndMangle(t, "delete (true && x)", "delete (0, x);\n", "delete (0, x);\n")
  5023  	expectPrintedNormalAndMangle(t, "delete (false || x)", "delete (0, x);\n", "delete (0, x);\n")
  5024  	expectPrintedNormalAndMangle(t, "delete (null ?? x)", "delete (0, x);\n", "delete (0, x);\n")
  5025  	expectPrintedNormalAndMangle(t, "delete (1 ? x : 2)", "delete (1 ? x : 2);\n", "delete (0, x);\n")
  5026  	expectPrintedNormalAndMangle(t, "delete (0 ? 1 : x)", "delete (0 ? 1 : x);\n", "delete (0, x);\n")
  5027  	expectPrintedNormalAndMangle(t, "delete (NaN)", "delete NaN;\n", "delete NaN;\n")
  5028  	expectPrintedNormalAndMangle(t, "delete (Infinity)", "delete Infinity;\n", "delete Infinity;\n")
  5029  	expectPrintedNormalAndMangle(t, "delete (-Infinity)", "delete -Infinity;\n", "delete -Infinity;\n")
  5030  	expectPrintedNormalAndMangle(t, "delete (1, NaN)", "delete (1, NaN);\n", "delete (0, NaN);\n")
  5031  	expectPrintedNormalAndMangle(t, "delete (1, Infinity)", "delete (1, Infinity);\n", "delete (0, Infinity);\n")
  5032  	expectPrintedNormalAndMangle(t, "delete (1, -Infinity)", "delete (1, -Infinity);\n", "delete -Infinity;\n")
  5033  
  5034  	expectPrintedNormalAndMangle(t, "foo ? 1 : 2", "foo ? 1 : 2;\n", "foo;\n")
  5035  	expectPrintedNormalAndMangle(t, "foo ? 1 : bar", "foo ? 1 : bar;\n", "foo || bar;\n")
  5036  	expectPrintedNormalAndMangle(t, "foo ? bar : 2", "foo ? bar : 2;\n", "foo && bar;\n")
  5037  	expectPrintedNormalAndMangle(t, "foo ? bar : baz", "foo ? bar : baz;\n", "foo ? bar : baz;\n")
  5038  
  5039  	for _, op := range []string{"&&", "||", "??"} {
  5040  		expectPrintedNormalAndMangle(t, "foo "+op+" bar", "foo "+op+" bar;\n", "foo "+op+" bar;\n")
  5041  		expectPrintedNormalAndMangle(t, "var foo; foo "+op+" bar", "var foo;\nfoo "+op+" bar;\n", "var foo;\nfoo "+op+" bar;\n")
  5042  		expectPrintedNormalAndMangle(t, "var bar; foo "+op+" bar", "var bar;\nfoo "+op+" bar;\n", "var bar;\nfoo;\n")
  5043  		expectPrintedNormalAndMangle(t, "var foo, bar; foo "+op+" bar", "var foo, bar;\nfoo "+op+" bar;\n", "var foo, bar;\n")
  5044  	}
  5045  
  5046  	expectPrintedNormalAndMangle(t, "tag`a${b}c${d}e`", "tag`a${b}c${d}e`;\n", "tag`a${b}c${d}e`;\n")
  5047  	expectPrintedNormalAndMangle(t, "`a${b}c${d}e`", "`a${b}c${d}e`;\n", "`${b}${d}`;\n")
  5048  
  5049  	// These can't be reduced to string addition due to "valueOf". See:
  5050  	// https://github.com/terser/terser/issues/1128#issuecomment-994209801
  5051  	expectPrintedNormalAndMangle(t, "`stuff ${x} ${1}`", "`stuff ${x} ${1}`;\n", "`${x}`;\n")
  5052  	expectPrintedNormalAndMangle(t, "`stuff ${1} ${y}`", "`stuff ${1} ${y}`;\n", "`${y}`;\n")
  5053  	expectPrintedNormalAndMangle(t, "`stuff ${x} ${y}`", "`stuff ${x} ${y}`;\n", "`${x}${y}`;\n")
  5054  	expectPrintedNormalAndMangle(t, "`stuff ${x ? 1 : 2} ${y}`", "`stuff ${x ? 1 : 2} ${y}`;\n", "x, `${y}`;\n")
  5055  	expectPrintedNormalAndMangle(t, "`stuff ${x} ${y ? 1 : 2}`", "`stuff ${x} ${y ? 1 : 2}`;\n", "`${x}`, y;\n")
  5056  	expectPrintedNormalAndMangle(t, "`stuff ${x} ${y ? 1 : 2} ${z}`", "`stuff ${x} ${y ? 1 : 2} ${z}`;\n", "`${x}`, y, `${z}`;\n")
  5057  
  5058  	expectPrintedNormalAndMangle(t, "'a' + b + 'c' + d", "\"a\" + b + \"c\" + d;\n", "\"\" + b + d;\n")
  5059  	expectPrintedNormalAndMangle(t, "a + 'b' + c + 'd'", "a + \"b\" + c + \"d\";\n", "a + \"\" + c;\n")
  5060  	expectPrintedNormalAndMangle(t, "a + b + 'c' + 'd'", "a + b + \"cd\";\n", "a + b + \"\";\n")
  5061  	expectPrintedNormalAndMangle(t, "'a' + 'b' + c + d", "\"ab\" + c + d;\n", "\"\" + c + d;\n")
  5062  	expectPrintedNormalAndMangle(t, "(a + '') + (b + '')", "a + (b + \"\");\n", "a + (b + \"\");\n")
  5063  
  5064  	// Make sure identifiers inside "with" statements are kept
  5065  	expectPrintedNormalAndMangle(t, "with (a) []", "with (a) [];\n", "with (a) ;\n")
  5066  	expectPrintedNormalAndMangle(t, "var a; with (b) a", "var a;\nwith (b) a;\n", "var a;\nwith (b) a;\n")
  5067  }
  5068  
  5069  func TestMangleInlineLocals(t *testing.T) {
  5070  	check := func(a string, b string) {
  5071  		t.Helper()
  5072  		expectPrintedMangle(t, "function wrapper(arg0, arg1) {"+a+"}",
  5073  			"function wrapper(arg0, arg1) {"+strings.ReplaceAll("\n"+b, "\n", "\n  ")+"\n}\n")
  5074  	}
  5075  
  5076  	check("var x = 1; return x", "var x = 1;\nreturn x;")
  5077  	check("let x = 1; return x", "return 1;")
  5078  	check("const x = 1; return x", "return 1;")
  5079  
  5080  	check("let x = 1; if (false) x++; return x", "return 1;")
  5081  	check("let x = 1; if (true) x++; return x", "let x = 1;\nreturn x++, x;")
  5082  	check("let x = 1; return x + x", "let x = 1;\nreturn x + x;")
  5083  
  5084  	// Can substitute into normal unary operators
  5085  	check("let x = 1; return +x", "return +1;")
  5086  	check("let x = 1; return -x", "return -1;")
  5087  	check("let x = 1; return !x", "return !1;")
  5088  	check("let x = 1; return ~x", "return ~1;")
  5089  	check("let x = 1; return void x", "let x = 1;")
  5090  	check("let x = 1; return typeof x", "return typeof 1;")
  5091  
  5092  	// Can substitute into template literals
  5093  	check("let x = 1; return `<${x}>`", "return `<1>`;")
  5094  	check("let x = 1n; return `<${x}>`", "return `<1>`;")
  5095  	check("let x = null; return `<${x}>`", "return `<null>`;")
  5096  	check("let x = undefined; return `<${x}>`", "return `<undefined>`;")
  5097  	check("let x = false; return `<${x}>`", "return `<false>`;")
  5098  	check("let x = true; return `<${x}>`", "return `<true>`;")
  5099  
  5100  	// Check substituting a side-effect free value into normal binary operators
  5101  	check("let x = 1; return x + 2", "return 1 + 2;")
  5102  	check("let x = 1; return 2 + x", "return 2 + 1;")
  5103  	check("let x = 1; return x + arg0", "return 1 + arg0;")
  5104  	check("let x = 1; return arg0 + x", "return arg0 + 1;")
  5105  	check("let x = 1; return x + fn()", "return 1 + fn();")
  5106  	check("let x = 1; return fn() + x", "return fn() + 1;")
  5107  	check("let x = 1; return x + undef", "return 1 + undef;")
  5108  	check("let x = 1; return undef + x", "return undef + 1;")
  5109  
  5110  	// Check substituting a value with side-effects into normal binary operators
  5111  	check("let x = fn(); return x + 2", "return fn() + 2;")
  5112  	check("let x = fn(); return 2 + x", "return 2 + fn();")
  5113  	check("let x = fn(); return x + arg0", "return fn() + arg0;")
  5114  	check("let x = fn(); return arg0 + x", "let x = fn();\nreturn arg0 + x;")
  5115  	check("let x = fn(); return x + fn2()", "return fn() + fn2();")
  5116  	check("let x = fn(); return fn2() + x", "let x = fn();\nreturn fn2() + x;")
  5117  	check("let x = fn(); return x + undef", "return fn() + undef;")
  5118  	check("let x = fn(); return undef + x", "let x = fn();\nreturn undef + x;")
  5119  
  5120  	// Cannot substitute into mutating unary operators
  5121  	check("let x = 1; ++x", "let x = 1;\n++x;")
  5122  	check("let x = 1; --x", "let x = 1;\n--x;")
  5123  	check("let x = 1; x++", "let x = 1;\nx++;")
  5124  	check("let x = 1; x--", "let x = 1;\nx--;")
  5125  	check("let x = 1; delete x", "let x = 1;\ndelete x;")
  5126  
  5127  	// Cannot substitute into mutating binary operators
  5128  	check("let x = 1; x = 2", "let x = 1;\nx = 2;")
  5129  	check("let x = 1; x += 2", "let x = 1;\nx += 2;")
  5130  	check("let x = 1; x ||= 2", "let x = 1;\nx ||= 2;")
  5131  
  5132  	// Can substitute past mutating binary operators when the left operand has no side effects
  5133  	check("let x = 1; arg0 = x", "arg0 = 1;")
  5134  	check("let x = 1; arg0 += x", "arg0 += 1;")
  5135  	check("let x = 1; arg0 ||= x", "arg0 ||= 1;")
  5136  	check("let x = fn(); arg0 = x", "arg0 = fn();")
  5137  	check("let x = fn(); arg0 += x", "let x = fn();\narg0 += x;")
  5138  	check("let x = fn(); arg0 ||= x", "let x = fn();\narg0 ||= x;")
  5139  
  5140  	// Cannot substitute past mutating binary operators when the left operand has side effects
  5141  	check("let x = 1; y.z = x", "let x = 1;\ny.z = x;")
  5142  	check("let x = 1; y.z += x", "let x = 1;\ny.z += x;")
  5143  	check("let x = 1; y.z ||= x", "let x = 1;\ny.z ||= x;")
  5144  	check("let x = fn(); y.z = x", "let x = fn();\ny.z = x;")
  5145  	check("let x = fn(); y.z += x", "let x = fn();\ny.z += x;")
  5146  	check("let x = fn(); y.z ||= x", "let x = fn();\ny.z ||= x;")
  5147  
  5148  	// Can substitute code without side effects into branches
  5149  	check("let x = arg0; return x ? y : z;", "return arg0 ? y : z;")
  5150  	check("let x = arg0; return arg1 ? x : y;", "return arg1 ? arg0 : y;")
  5151  	check("let x = arg0; return arg1 ? y : x;", "return arg1 ? y : arg0;")
  5152  	check("let x = arg0; return x || y;", "return arg0 || y;")
  5153  	check("let x = arg0; return x && y;", "return arg0 && y;")
  5154  	check("let x = arg0; return x ?? y;", "return arg0 ?? y;")
  5155  	check("let x = arg0; return arg1 || x;", "return arg1 || arg0;")
  5156  	check("let x = arg0; return arg1 && x;", "return arg1 && arg0;")
  5157  	check("let x = arg0; return arg1 ?? x;", "return arg1 ?? arg0;")
  5158  
  5159  	// Can substitute code without side effects into branches past an expression with side effects
  5160  	check("let x = arg0; return y ? x : z;", "let x = arg0;\nreturn y ? x : z;")
  5161  	check("let x = arg0; return y ? z : x;", "let x = arg0;\nreturn y ? z : x;")
  5162  	check("let x = arg0; return (arg1 ? 1 : 2) ? x : 3;", "return arg0;")
  5163  	check("let x = arg0; return (arg1 ? 1 : 2) ? 3 : x;", "let x = arg0;\nreturn 3;")
  5164  	check("let x = arg0; return (arg1 ? y : 1) ? x : 2;", "let x = arg0;\nreturn !arg1 || y ? x : 2;")
  5165  	check("let x = arg0; return (arg1 ? 1 : y) ? x : 2;", "let x = arg0;\nreturn arg1 || y ? x : 2;")
  5166  	check("let x = arg0; return (arg1 ? y : 1) ? 2 : x;", "let x = arg0;\nreturn !arg1 || y ? 2 : x;")
  5167  	check("let x = arg0; return (arg1 ? 1 : y) ? 2 : x;", "let x = arg0;\nreturn arg1 || y ? 2 : x;")
  5168  	check("let x = arg0; return y || x;", "let x = arg0;\nreturn y || x;")
  5169  	check("let x = arg0; return y && x;", "let x = arg0;\nreturn y && x;")
  5170  	check("let x = arg0; return y ?? x;", "let x = arg0;\nreturn y ?? x;")
  5171  
  5172  	// Cannot substitute code with side effects into branches
  5173  	check("let x = fn(); return x ? arg0 : y;", "return fn() ? arg0 : y;")
  5174  	check("let x = fn(); return arg0 ? x : y;", "let x = fn();\nreturn arg0 ? x : y;")
  5175  	check("let x = fn(); return arg0 ? y : x;", "let x = fn();\nreturn arg0 ? y : x;")
  5176  	check("let x = fn(); return x || arg0;", "return fn() || arg0;")
  5177  	check("let x = fn(); return x && arg0;", "return fn() && arg0;")
  5178  	check("let x = fn(); return x ?? arg0;", "return fn() ?? arg0;")
  5179  	check("let x = fn(); return arg0 || x;", "let x = fn();\nreturn arg0 || x;")
  5180  	check("let x = fn(); return arg0 && x;", "let x = fn();\nreturn arg0 && x;")
  5181  	check("let x = fn(); return arg0 ?? x;", "let x = fn();\nreturn arg0 ?? x;")
  5182  
  5183  	// Test chaining
  5184  	check("let x = fn(); let y = x[prop]; let z = y.val; throw z", "throw fn()[prop].val;")
  5185  	check("let x = fn(), y = x[prop], z = y.val; throw z", "throw fn()[prop].val;")
  5186  
  5187  	// Can substitute an initializer with side effects
  5188  	check("let x = 0; let y = ++x; return y",
  5189  		"let x = 0;\nreturn ++x;")
  5190  
  5191  	// Can substitute an initializer without side effects past an expression without side effects
  5192  	check("let x = 0; let y = x; return [x, y]",
  5193  		"let x = 0;\nreturn [x, x];")
  5194  
  5195  	// Cannot substitute an initializer with side effects past an expression without side effects
  5196  	check("let x = 0; let y = ++x; return [x, y]",
  5197  		"let x = 0, y = ++x;\nreturn [x, y];")
  5198  
  5199  	// Cannot substitute an initializer without side effects past an expression with side effects
  5200  	check("let x = 0; let y = {valueOf() { x = 1 }}; let z = x; return [y == 1, z]",
  5201  		"let x = 0, y = { valueOf() {\n  x = 1;\n} }, z = x;\nreturn [y == 1, z];")
  5202  
  5203  	// Cannot inline past a spread operator, since that evaluates code
  5204  	check("let x = arg0; return [...x];", "return [...arg0];")
  5205  	check("let x = arg0; return [x, ...arg1];", "return [arg0, ...arg1];")
  5206  	check("let x = arg0; return [...arg1, x];", "let x = arg0;\nreturn [...arg1, x];")
  5207  	check("let x = arg0; return arg1(...x);", "return arg1(...arg0);")
  5208  	check("let x = arg0; return arg1(x, ...arg1);", "return arg1(arg0, ...arg1);")
  5209  	check("let x = arg0; return arg1(...arg1, x);", "let x = arg0;\nreturn arg1(...arg1, x);")
  5210  
  5211  	// Test various statement kinds
  5212  	check("let x = arg0; arg1(x);", "arg1(arg0);")
  5213  	check("let x = arg0; throw x;", "throw arg0;")
  5214  	check("let x = arg0; return x;", "return arg0;")
  5215  	check("let x = arg0; if (x) return 1;", "if (arg0) return 1;")
  5216  	check("let x = arg0; switch (x) { case 0: return 1; }", "switch (arg0) {\n  case 0:\n    return 1;\n}")
  5217  	check("let x = arg0; let y = x; return y + y;", "let y = arg0;\nreturn y + y;")
  5218  
  5219  	// Loops must not be substituted into because they evaluate multiple times
  5220  	check("let x = arg0; do {} while (x);", "let x = arg0;\ndo\n  ;\nwhile (x);")
  5221  	check("let x = arg0; while (x) return 1;", "let x = arg0;\nfor (; x; ) return 1;")
  5222  	check("let x = arg0; for (; x; ) return 1;", "let x = arg0;\nfor (; x; ) return 1;")
  5223  
  5224  	// Can substitute an expression without side effects into a branch due to optional chaining
  5225  	check("let x = arg0; return arg1?.[x];", "return arg1?.[arg0];")
  5226  	check("let x = arg0; return arg1?.(x);", "return arg1?.(arg0);")
  5227  
  5228  	// Cannot substitute an expression with side effects into a branch due to optional chaining,
  5229  	// since that would change the expression with side effects from being unconditionally
  5230  	// evaluated to being conditionally evaluated, which is a behavior change
  5231  	check("let x = fn(); return arg1?.[x];", "let x = fn();\nreturn arg1?.[x];")
  5232  	check("let x = fn(); return arg1?.(x);", "let x = fn();\nreturn arg1?.(x);")
  5233  
  5234  	// Can substitute an expression past an optional chaining operation, since it has side effects
  5235  	check("let x = arg0; return arg1?.a === x;", "let x = arg0;\nreturn arg1?.a === x;")
  5236  	check("let x = arg0; return arg1?.[0] === x;", "let x = arg0;\nreturn arg1?.[0] === x;")
  5237  	check("let x = arg0; return arg1?.(0) === x;", "let x = arg0;\nreturn arg1?.(0) === x;")
  5238  	check("let x = arg0; return arg1?.a[x];", "let x = arg0;\nreturn arg1?.a[x];")
  5239  	check("let x = arg0; return arg1?.a(x);", "let x = arg0;\nreturn arg1?.a(x);")
  5240  	check("let x = arg0; return arg1?.[a][x];", "let x = arg0;\nreturn arg1?.[a][x];")
  5241  	check("let x = arg0; return arg1?.[a](x);", "let x = arg0;\nreturn arg1?.[a](x);")
  5242  	check("let x = arg0; return arg1?.(a)[x];", "let x = arg0;\nreturn arg1?.(a)[x];")
  5243  	check("let x = arg0; return arg1?.(a)(x);", "let x = arg0;\nreturn arg1?.(a)(x);")
  5244  
  5245  	// Can substitute into an object as long as there are no side effects
  5246  	// beforehand. Note that computed properties must call "toString()" which
  5247  	// can have side effects.
  5248  	check("let x = arg0; return {x};", "return { x: arg0 };")
  5249  	check("let x = arg0; return {x: y, y: x};", "let x = arg0;\nreturn { x: y, y: x };")
  5250  	check("let x = arg0; return {x: arg1, y: x};", "return { x: arg1, y: arg0 };")
  5251  	check("let x = arg0; return {[x]: 0};", "return { [arg0]: 0 };")
  5252  	check("let x = arg0; return {[y]: x};", "let x = arg0;\nreturn { [y]: x };")
  5253  	check("let x = arg0; return {[arg1]: x};", "let x = arg0;\nreturn { [arg1]: x };")
  5254  	check("let x = arg0; return {y() {}, x};", "return { y() {\n}, x: arg0 };")
  5255  	check("let x = arg0; return {[y]() {}, x};", "let x = arg0;\nreturn { [y]() {\n}, x };")
  5256  	check("let x = arg0; return {...x};", "return { ...arg0 };")
  5257  	check("let x = arg0; return {...x, y};", "return { ...arg0, y };")
  5258  	check("let x = arg0; return {x, ...y};", "return { x: arg0, ...y };")
  5259  	check("let x = arg0; return {...y, x};", "let x = arg0;\nreturn { ...y, x };")
  5260  
  5261  	// Check substitutions into template literals
  5262  	check("let x = arg0; return `a${x}b${y}c`;", "return `a${arg0}b${y}c`;")
  5263  	check("let x = arg0; return `a${y}b${x}c`;", "let x = arg0;\nreturn `a${y}b${x}c`;")
  5264  	check("let x = arg0; return `a${arg1}b${x}c`;", "return `a${arg1}b${arg0}c`;")
  5265  	check("let x = arg0; return x`y`;", "return arg0`y`;")
  5266  	check("let x = arg0; return y`a${x}b`;", "let x = arg0;\nreturn y`a${x}b`;")
  5267  	check("let x = arg0; return arg1`a${x}b`;", "return arg1`a${arg0}b`;")
  5268  	check("let x = 'x'; return `a${x}b`;", "return `axb`;")
  5269  
  5270  	// Check substitutions into import expressions
  5271  	check("let x = arg0; return import(x);", "return import(arg0);")
  5272  	check("let x = arg0; return [import(y), x];", "let x = arg0;\nreturn [import(y), x];")
  5273  	check("let x = arg0; return [import(arg1), x];", "return [import(arg1), arg0];")
  5274  
  5275  	// Check substitutions into await expressions
  5276  	check("return async () => { let x = arg0; await x; };", "return async () => {\n  await arg0;\n};")
  5277  	check("return async () => { let x = arg0; await y; return x; };", "return async () => {\n  let x = arg0;\n  return await y, x;\n};")
  5278  	check("return async () => { let x = arg0; await arg1; return x; };", "return async () => {\n  let x = arg0;\n  return await arg1, x;\n};")
  5279  
  5280  	// Check substitutions into yield expressions
  5281  	check("return function* () { let x = arg0; yield x; };", "return function* () {\n  yield arg0;\n};")
  5282  	check("return function* () { let x = arg0; yield; return x; };", "return function* () {\n  let x = arg0;\n  return yield, x;\n};")
  5283  	check("return function* () { let x = arg0; yield y; return x; };", "return function* () {\n  let x = arg0;\n  return yield y, x;\n};")
  5284  	check("return function* () { let x = arg0; yield arg1; return x; };", "return function* () {\n  let x = arg0;\n  return yield arg1, x;\n};")
  5285  
  5286  	// Make sure that transforms which duplicate identifiers cause
  5287  	// them to no longer be considered single-use identifiers
  5288  	expectPrintedMangleTarget(t, 2015, "(x => { let y = x; throw y ?? z })()", "((x) => {\n  let y = x;\n  throw y != null ? y : z;\n})();\n")
  5289  	expectPrintedMangleTarget(t, 2015, "(x => { let y = x; y.z ??= z })()", "((x) => {\n  var _a;\n  let y = x;\n  (_a = y.z) != null || (y.z = z);\n})();\n")
  5290  	expectPrintedMangleTarget(t, 2015, "(x => { let y = x; y?.z })()", "((x) => {\n  let y = x;\n  y == null || y.z;\n})();\n")
  5291  
  5292  	// Cannot substitute into call targets when it would change "this"
  5293  	check("let x = arg0; x()", "arg0();")
  5294  	check("let x = arg0; (0, x)()", "arg0();")
  5295  	check("let x = arg0.foo; x.bar()", "arg0.foo.bar();")
  5296  	check("let x = arg0.foo; x[bar]()", "arg0.foo[bar]();")
  5297  	check("let x = arg0.foo; x()", "let x = arg0.foo;\nx();")
  5298  	check("let x = arg0[foo]; x()", "let x = arg0[foo];\nx();")
  5299  	check("let x = arg0?.foo; x()", "let x = arg0?.foo;\nx();")
  5300  	check("let x = arg0?.[foo]; x()", "let x = arg0?.[foo];\nx();")
  5301  	check("let x = arg0.foo; (0, x)()", "let x = arg0.foo;\nx();")
  5302  	check("let x = arg0[foo]; (0, x)()", "let x = arg0[foo];\nx();")
  5303  	check("let x = arg0?.foo; (0, x)()", "let x = arg0?.foo;\nx();")
  5304  	check("let x = arg0?.[foo]; (0, x)()", "let x = arg0?.[foo];\nx();")
  5305  
  5306  	// Explicitly allow reordering calls that are both marked as "/* @__PURE__ */".
  5307  	// This happens because only two expressions that are free from side-effects
  5308  	// can be freely reordered, and marking something as "/* @__PURE__ */" tells
  5309  	// us that it has no side effects.
  5310  	check("let x = arg0(); arg1() + x", "let x = arg0();\narg1() + x;")
  5311  	check("let x = arg0(); /* @__PURE__ */ arg1() + x", "let x = arg0();\n/* @__PURE__ */ arg1() + x;")
  5312  	check("let x = /* @__PURE__ */ arg0(); arg1() + x", "let x = /* @__PURE__ */ arg0();\narg1() + x;")
  5313  	check("let x = /* @__PURE__ */ arg0(); /* @__PURE__ */ arg1() + x", "/* @__PURE__ */ arg1() + /* @__PURE__ */ arg0();")
  5314  }
  5315  
  5316  func TestTrimCodeInDeadControlFlow(t *testing.T) {
  5317  	expectPrintedMangle(t, "if (1) a(); else { ; }", "a();\n")
  5318  	expectPrintedMangle(t, "if (1) a(); else { b() }", "a();\n")
  5319  	expectPrintedMangle(t, "if (1) a(); else { const b = c }", "a();\n")
  5320  	expectPrintedMangle(t, "if (1) a(); else { let b }", "a();\n")
  5321  	expectPrintedMangle(t, "if (1) a(); else { throw b }", "a();\n")
  5322  	expectPrintedMangle(t, "if (1) a(); else { return b }", "a();\n")
  5323  	expectPrintedMangle(t, "b: { if (x) a(); else { break b } }", "b:\n  if (x) a();\n  else\n    break b;\n")
  5324  	expectPrintedMangle(t, "b: { if (1) a(); else { break b } }", "a();\n")
  5325  	expectPrintedMangle(t, "b: { if (0) a(); else { break b } }", "")
  5326  	expectPrintedMangle(t, "b: while (1) if (x) a(); else { continue b }", "b: for (; ; ) if (x) a();\nelse\n  continue b;\n")
  5327  	expectPrintedMangle(t, "b: while (1) if (1) a(); else { continue b }", "for (; ; ) a();\n")
  5328  	expectPrintedMangle(t, "b: while (1) if (0) a(); else { continue b }", "b: for (; ; ) continue b;\n")
  5329  	expectPrintedMangle(t, "if (1) a(); else { class b {} }", "a();\n")
  5330  	expectPrintedMangle(t, "if (1) a(); else { debugger }", "a();\n")
  5331  	expectPrintedMangle(t, "if (1) a(); else { switch (1) { case 1: b() } }", "a();\n")
  5332  
  5333  	expectPrintedMangle(t, "if (0) {let a = 1} else a()", "a();\n")
  5334  	expectPrintedMangle(t, "if (1) {let a = 1} else a()", "{\n  let a = 1;\n}\n")
  5335  	expectPrintedMangle(t, "if (0) a(); else {let a = 1}", "{\n  let a = 1;\n}\n")
  5336  	expectPrintedMangle(t, "if (1) a(); else {let a = 1}", "a();\n")
  5337  
  5338  	expectPrintedMangle(t, "if (1) a(); else { var a = b }", "if (1) a();\nelse\n  var a;\n")
  5339  	expectPrintedMangle(t, "if (1) a(); else { var [a] = b }", "if (1) a();\nelse\n  var a;\n")
  5340  	expectPrintedMangle(t, "if (1) a(); else { var {x: a} = b }", "if (1) a();\nelse\n  var a;\n")
  5341  	expectPrintedMangle(t, "if (1) a(); else { var [] = b }", "a();\n")
  5342  	expectPrintedMangle(t, "if (1) a(); else { var {} = b }", "a();\n")
  5343  	expectPrintedMangle(t, "if (1) a(); else { function a() {} }", "if (1) a();\nelse\n  var a;\n")
  5344  	expectPrintedMangle(t, "if (1) a(); else { for(;;){var a} }", "if (1) a();\nelse\n  for (; ; )\n    var a;\n")
  5345  	expectPrintedMangle(t, "if (1) { a(); b() } else { var a; var b; }", "if (1)\n  a(), b();\nelse\n  var a, b;\n")
  5346  	expectPrintedMangle(t, "if (1) a(); else { switch (1) { case 1: case 2: var a } }", "if (1) a();\nelse\n  var a;\n")
  5347  }
  5348  
  5349  func TestPreservedComments(t *testing.T) {
  5350  	expectPrinted(t, "//", "")
  5351  	expectPrinted(t, "//preserve", "")
  5352  	expectPrinted(t, "//@__PURE__", "")
  5353  	expectPrinted(t, "//!", "//!\n")
  5354  	expectPrinted(t, "//@license", "//@license\n")
  5355  	expectPrinted(t, "//@preserve", "//@preserve\n")
  5356  	expectPrinted(t, "// @license", "// @license\n")
  5357  	expectPrinted(t, "// @preserve", "// @preserve\n")
  5358  
  5359  	expectPrinted(t, "/**/", "")
  5360  	expectPrinted(t, "/*preserve*/", "")
  5361  	expectPrinted(t, "/*@__PURE__*/", "")
  5362  	expectPrinted(t, "/*!*/", "/*!*/\n")
  5363  	expectPrinted(t, "/*@license*/", "/*@license*/\n")
  5364  	expectPrinted(t, "/*@preserve*/", "/*@preserve*/\n")
  5365  	expectPrinted(t, "/*\n * @license\n */", "/*\n * @license\n */\n")
  5366  	expectPrinted(t, "/*\n * @preserve\n */", "/*\n * @preserve\n */\n")
  5367  
  5368  	expectPrinted(t, "foo() //! test", "foo();\n//! test\n")
  5369  	expectPrinted(t, "//! test\nfoo()", "//! test\nfoo();\n")
  5370  	expectPrinted(t, "if (1) //! test\nfoo()", "if (1)\n  foo();\n")
  5371  	expectPrinted(t, "if (1) {//! test\nfoo()}", "if (1) {\n  //! test\n  foo();\n}\n")
  5372  	expectPrinted(t, "if (1) {foo() //! test\n}", "if (1) {\n  foo();\n  //! test\n}\n")
  5373  
  5374  	expectPrinted(t, "    /*!\r     * Re-indent test\r     */", "/*!\n * Re-indent test\n */\n")
  5375  	expectPrinted(t, "    /*!\n     * Re-indent test\n     */", "/*!\n * Re-indent test\n */\n")
  5376  	expectPrinted(t, "    /*!\r\n     * Re-indent test\r\n     */", "/*!\n * Re-indent test\n */\n")
  5377  	expectPrinted(t, "    /*!\u2028     * Re-indent test\u2028     */", "/*!\n * Re-indent test\n */\n")
  5378  	expectPrinted(t, "    /*!\u2029     * Re-indent test\u2029     */", "/*!\n * Re-indent test\n */\n")
  5379  
  5380  	expectPrinted(t, "\t\t/*!\r\t\t * Re-indent test\r\t\t */", "/*!\n * Re-indent test\n */\n")
  5381  	expectPrinted(t, "\t\t/*!\n\t\t * Re-indent test\n\t\t */", "/*!\n * Re-indent test\n */\n")
  5382  	expectPrinted(t, "\t\t/*!\r\n\t\t * Re-indent test\r\n\t\t */", "/*!\n * Re-indent test\n */\n")
  5383  	expectPrinted(t, "\t\t/*!\u2028\t\t * Re-indent test\u2028\t\t */", "/*!\n * Re-indent test\n */\n")
  5384  	expectPrinted(t, "\t\t/*!\u2029\t\t * Re-indent test\u2029\t\t */", "/*!\n * Re-indent test\n */\n")
  5385  
  5386  	expectPrinted(t, "x\r    /*!\r     * Re-indent test\r     */", "x;\n/*!\n * Re-indent test\n */\n")
  5387  	expectPrinted(t, "x\n    /*!\n     * Re-indent test\n     */", "x;\n/*!\n * Re-indent test\n */\n")
  5388  	expectPrinted(t, "x\r\n    /*!\r\n     * Re-indent test\r\n     */", "x;\n/*!\n * Re-indent test\n */\n")
  5389  	expectPrinted(t, "x\u2028    /*!\u2028     * Re-indent test\u2028     */", "x;\n/*!\n * Re-indent test\n */\n")
  5390  	expectPrinted(t, "x\u2029    /*!\u2029     * Re-indent test\u2029     */", "x;\n/*!\n * Re-indent test\n */\n")
  5391  }
  5392  
  5393  func TestUnicodeWhitespace(t *testing.T) {
  5394  	whitespace := []string{
  5395  		"\u0009", // character tabulation
  5396  		"\u000B", // line tabulation
  5397  		"\u000C", // form feed
  5398  		"\u0020", // space
  5399  		"\u00A0", // no-break space
  5400  		"\u1680", // ogham space mark
  5401  		"\u2000", // en quad
  5402  		"\u2001", // em quad
  5403  		"\u2002", // en space
  5404  		"\u2003", // em space
  5405  		"\u2004", // three-per-em space
  5406  		"\u2005", // four-per-em space
  5407  		"\u2006", // six-per-em space
  5408  		"\u2007", // figure space
  5409  		"\u2008", // punctuation space
  5410  		"\u2009", // thin space
  5411  		"\u200A", // hair space
  5412  		"\u202F", // narrow no-break space
  5413  		"\u205F", // medium mathematical space
  5414  		"\u3000", // ideographic space
  5415  		"\uFEFF", // zero width non-breaking space
  5416  	}
  5417  
  5418  	// Test "js_lexer.Next()"
  5419  	expectParseError(t, "var\u0008x", "<stdin>: ERROR: Expected identifier but found \"\\b\"\n")
  5420  	for _, s := range whitespace {
  5421  		expectPrinted(t, "var"+s+"x", "var x;\n")
  5422  	}
  5423  
  5424  	// Test "js_lexer.NextInsideJSXElement()"
  5425  	expectParseErrorJSX(t, "<x\u0008y/>", "<stdin>: ERROR: Expected \">\" but found \"\\b\"\n")
  5426  	for _, s := range whitespace {
  5427  		expectPrintedJSX(t, "<x"+s+"y/>", "/* @__PURE__ */ React.createElement(\"x\", { y: true });\n")
  5428  	}
  5429  
  5430  	// Test "js_lexer.NextJSXElementChild()"
  5431  	expectPrintedJSX(t, "<x>\n\u0008\n</x>", "/* @__PURE__ */ React.createElement(\"x\", null, \"\\b\");\n")
  5432  	for _, s := range whitespace {
  5433  		expectPrintedJSX(t, "<x>\n"+s+"\n</x>", "/* @__PURE__ */ React.createElement(\"x\", null);\n")
  5434  	}
  5435  
  5436  	// Test "fixWhitespaceAndDecodeJSXEntities()"
  5437  	expectPrintedJSX(t, "<x>\n\u0008&quot;\n</x>", "/* @__PURE__ */ React.createElement(\"x\", null, '\\b\"');\n")
  5438  	for _, s := range whitespace {
  5439  		expectPrintedJSX(t, "<x>\n"+s+"&quot;\n</x>", "/* @__PURE__ */ React.createElement(\"x\", null, '\"');\n")
  5440  	}
  5441  
  5442  	invalidWhitespaceInJS := []string{
  5443  		"\u0085", // next line (nel)
  5444  	}
  5445  
  5446  	// Test "js_lexer.Next()"
  5447  	for _, s := range invalidWhitespaceInJS {
  5448  		r, _ := helpers.DecodeWTF8Rune(s)
  5449  		expectParseError(t, "var"+s+"x", fmt.Sprintf("<stdin>: ERROR: Expected identifier but found \"\\u%04x\"\n", r))
  5450  	}
  5451  
  5452  	// Test "js_lexer.NextInsideJSXElement()"
  5453  	for _, s := range invalidWhitespaceInJS {
  5454  		r, _ := helpers.DecodeWTF8Rune(s)
  5455  		expectParseErrorJSX(t, "<x"+s+"y/>", fmt.Sprintf("<stdin>: ERROR: Expected \">\" but found \"\\u%04x\"\n", r))
  5456  	}
  5457  
  5458  	// Test "js_lexer.NextJSXElementChild()"
  5459  	for _, s := range invalidWhitespaceInJS {
  5460  		expectPrintedJSX(t, "<x>\n"+s+"\n</x>", "/* @__PURE__ */ React.createElement(\"x\", null, \""+s+"\");\n")
  5461  	}
  5462  
  5463  	// Test "fixWhitespaceAndDecodeJSXEntities()"
  5464  	for _, s := range invalidWhitespaceInJS {
  5465  		expectPrintedJSX(t, "<x>\n"+s+"&quot;\n</x>", "/* @__PURE__ */ React.createElement(\"x\", null, '"+s+"\"');\n")
  5466  	}
  5467  }
  5468  
  5469  // Make sure we can handle the unicode replacement character "ļæ½" in various places
  5470  func TestReplacementCharacter(t *testing.T) {
  5471  	expectPrinted(t, "//\uFFFD\n123", "123;\n")
  5472  	expectPrinted(t, "/*\uFFFD*/123", "123;\n")
  5473  
  5474  	expectPrinted(t, "'\uFFFD'", "\"\uFFFD\";\n")
  5475  	expectPrinted(t, "\"\uFFFD\"", "\"\uFFFD\";\n")
  5476  	expectPrinted(t, "`\uFFFD`", "`\uFFFD`;\n")
  5477  	expectPrinted(t, "/\uFFFD/", "/\uFFFD/;\n")
  5478  
  5479  	expectPrintedJSX(t, "<a>\uFFFD</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"\uFFFD\");\n")
  5480  }
  5481  
  5482  func TestNewTarget(t *testing.T) {
  5483  	expectPrinted(t, "function f() { new.target }", "function f() {\n  new.target;\n}\n")
  5484  	expectPrinted(t, "function f() { (new.target) }", "function f() {\n  new.target;\n}\n")
  5485  	expectPrinted(t, "function f() { () => new.target }", "function f() {\n  () => new.target;\n}\n")
  5486  	expectPrinted(t, "class Foo { x = new.target }", "class Foo {\n  x = new.target;\n}\n")
  5487  
  5488  	expectParseError(t, "new.t\\u0061rget", "<stdin>: ERROR: Unexpected \"t\\\\u0061rget\"\n")
  5489  	expectParseError(t, "new.target", "<stdin>: ERROR: Cannot use \"new.target\" here:\n")
  5490  	expectParseError(t, "() => new.target", "<stdin>: ERROR: Cannot use \"new.target\" here:\n")
  5491  	expectParseError(t, "class Foo { [new.target] }", "<stdin>: ERROR: Cannot use \"new.target\" here:\n")
  5492  }
  5493  
  5494  func TestJSX(t *testing.T) {
  5495  	expectParseErrorJSX(t, "<div>></div>",
  5496  		"<stdin>: WARNING: The character \">\" is not valid inside a JSX element\n"+
  5497  			"NOTE: Did you mean to escape it as \"{'>'}\" instead?\n")
  5498  	expectParseErrorJSX(t, "<div>{1}}</div>",
  5499  		"<stdin>: WARNING: The character \"}\" is not valid inside a JSX element\n"+
  5500  			"NOTE: Did you mean to escape it as \"{'}'}\" instead?\n")
  5501  	expectPrintedJSX(t, "<div>></div>", "/* @__PURE__ */ React.createElement(\"div\", null, \">\");\n")
  5502  	expectPrintedJSX(t, "<div>{1}}</div>", "/* @__PURE__ */ React.createElement(\"div\", null, 1, \"}\");\n")
  5503  
  5504  	expectParseError(t, "<a/>", "<stdin>: ERROR: The JSX syntax extension is not currently enabled\n"+
  5505  		"NOTE: The esbuild loader for this file is currently set to \"js\" but it must be set to \"jsx\" to be able to parse JSX syntax. "+
  5506  		"You can use 'Loader: map[string]api.Loader{\".js\": api.LoaderJSX}' to do that.\n")
  5507  
  5508  	expectPrintedJSX(t, "<a/>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5509  	expectPrintedJSX(t, "<a></a>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5510  	expectPrintedJSX(t, "<A/>", "/* @__PURE__ */ React.createElement(A, null);\n")
  5511  	expectPrintedJSX(t, "<a.b/>", "/* @__PURE__ */ React.createElement(a.b, null);\n")
  5512  	expectPrintedJSX(t, "<_a/>", "/* @__PURE__ */ React.createElement(_a, null);\n")
  5513  	expectPrintedJSX(t, "<a-b/>", "/* @__PURE__ */ React.createElement(\"a-b\", null);\n")
  5514  	expectPrintedJSX(t, "<a0/>", "/* @__PURE__ */ React.createElement(\"a0\", null);\n")
  5515  	expectParseErrorJSX(t, "<0a/>", "<stdin>: ERROR: Expected identifier but found \"0\"\n")
  5516  
  5517  	expectPrintedJSX(t, "<a b/>", "/* @__PURE__ */ React.createElement(\"a\", { b: true });\n")
  5518  	expectPrintedJSX(t, "<a b=\"\\\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"\\\\\" });\n")
  5519  	expectPrintedJSX(t, "<a b=\"<>\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"<>\" });\n")
  5520  	expectPrintedJSX(t, "<a b=\"&lt;&gt;\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"<>\" });\n")
  5521  	expectPrintedJSX(t, "<a b=\"&wrong;\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"&wrong;\" });\n")
  5522  	expectPrintedJSX(t, "<a b={1, 2}/>", "/* @__PURE__ */ React.createElement(\"a\", { b: (1, 2) });\n")
  5523  	expectPrintedJSX(t, "<a b={<c/>}/>", "/* @__PURE__ */ React.createElement(\"a\", { b: /* @__PURE__ */ React.createElement(\"c\", null) });\n")
  5524  	expectPrintedJSX(t, "<a {...props}/>", "/* @__PURE__ */ React.createElement(\"a\", { ...props });\n")
  5525  	expectPrintedJSX(t, "<a b=\"šŸ™‚\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"šŸ™‚\" });\n")
  5526  
  5527  	expectPrintedJSX(t, "<a>\n</a>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5528  	expectPrintedJSX(t, "<a>123</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"123\");\n")
  5529  	expectPrintedJSX(t, "<a>}</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"}\");\n")
  5530  	expectPrintedJSX(t, "<a>=</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"=\");\n")
  5531  	expectPrintedJSX(t, "<a>></a>", "/* @__PURE__ */ React.createElement(\"a\", null, \">\");\n")
  5532  	expectPrintedJSX(t, "<a>>=</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \">=\");\n")
  5533  	expectPrintedJSX(t, "<a>>></a>", "/* @__PURE__ */ React.createElement(\"a\", null, \">>\");\n")
  5534  	expectPrintedJSX(t, "<a>{}</a>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5535  	expectPrintedJSX(t, "<a>{/* comment */}</a>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5536  	expectPrintedJSX(t, "<a>b{}</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5537  	expectPrintedJSX(t, "<a>b{/* comment */}</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5538  	expectPrintedJSX(t, "<a>{}c</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"c\");\n")
  5539  	expectPrintedJSX(t, "<a>{/* comment */}c</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"c\");\n")
  5540  	expectPrintedJSX(t, "<a>b{}c</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\", \"c\");\n")
  5541  	expectPrintedJSX(t, "<a>b{/* comment */}c</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\", \"c\");\n")
  5542  	expectPrintedJSX(t, "<a>{1, 2}</a>", "/* @__PURE__ */ React.createElement(\"a\", null, (1, 2));\n")
  5543  	expectPrintedJSX(t, "<a>&lt;&gt;</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"<>\");\n")
  5544  	expectPrintedJSX(t, "<a>&wrong;</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"&wrong;\");\n")
  5545  	expectPrintedJSX(t, "<a>šŸ™‚</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚\");\n")
  5546  	expectPrintedJSX(t, "<a>{...children}</a>", "/* @__PURE__ */ React.createElement(\"a\", null, ...children);\n")
  5547  
  5548  	// Note: The TypeScript compiler and Babel disagree. This matches TypeScript.
  5549  	expectPrintedJSX(t, "<a b=\"   c\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"   c\" });\n")
  5550  	expectPrintedJSX(t, "<a b=\"   \nc\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"   \\nc\" });\n")
  5551  	expectPrintedJSX(t, "<a b=\"\n   c\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"\\n   c\" });\n")
  5552  	expectPrintedJSX(t, "<a b=\"c   \"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"c   \" });\n")
  5553  	expectPrintedJSX(t, "<a b=\"c   \n\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"c   \\n\" });\n")
  5554  	expectPrintedJSX(t, "<a b=\"c\n   \"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"c\\n   \" });\n")
  5555  	expectPrintedJSX(t, "<a b=\"c   d\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"c   d\" });\n")
  5556  	expectPrintedJSX(t, "<a b=\"c   \nd\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"c   \\nd\" });\n")
  5557  	expectPrintedJSX(t, "<a b=\"c\n   d\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"c\\n   d\" });\n")
  5558  	expectPrintedJSX(t, "<a b=\"   c\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"   c\" });\n")
  5559  	expectPrintedJSX(t, "<a b=\"   \nc\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"   \\nc\" });\n")
  5560  	expectPrintedJSX(t, "<a b=\"\n   c\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"\\n   c\" });\n")
  5561  
  5562  	// Same test as above except with multi-byte Unicode characters
  5563  	expectPrintedJSX(t, "<a b=\"   šŸ™‚\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"   šŸ™‚\" });\n")
  5564  	expectPrintedJSX(t, "<a b=\"   \nšŸ™‚\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"   \\nšŸ™‚\" });\n")
  5565  	expectPrintedJSX(t, "<a b=\"\n   šŸ™‚\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"\\n   šŸ™‚\" });\n")
  5566  	expectPrintedJSX(t, "<a b=\"šŸ™‚   \"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"šŸ™‚   \" });\n")
  5567  	expectPrintedJSX(t, "<a b=\"šŸ™‚   \n\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"šŸ™‚   \\n\" });\n")
  5568  	expectPrintedJSX(t, "<a b=\"šŸ™‚\n   \"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"šŸ™‚\\n   \" });\n")
  5569  	expectPrintedJSX(t, "<a b=\"šŸ™‚   šŸ•\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"šŸ™‚   šŸ•\" });\n")
  5570  	expectPrintedJSX(t, "<a b=\"šŸ™‚   \nšŸ•\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"šŸ™‚   \\nšŸ•\" });\n")
  5571  	expectPrintedJSX(t, "<a b=\"šŸ™‚\n   šŸ•\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"šŸ™‚\\n   šŸ•\" });\n")
  5572  	expectPrintedJSX(t, "<a b=\"   šŸ™‚\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"   šŸ™‚\" });\n")
  5573  	expectPrintedJSX(t, "<a b=\"   \nšŸ™‚\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"   \\nšŸ™‚\" });\n")
  5574  	expectPrintedJSX(t, "<a b=\"\n   šŸ™‚\"/>", "/* @__PURE__ */ React.createElement(\"a\", { b: \"\\n   šŸ™‚\" });\n")
  5575  
  5576  	expectPrintedJSX(t, "<a>   b</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"   b\");\n")
  5577  	expectPrintedJSX(t, "<a>   \nb</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5578  	expectPrintedJSX(t, "<a>\n   b</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5579  	expectPrintedJSX(t, "<a>b   </a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b   \");\n")
  5580  	expectPrintedJSX(t, "<a>b   \n</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5581  	expectPrintedJSX(t, "<a>b\n   </a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5582  	expectPrintedJSX(t, "<a>b   c</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b   c\");\n")
  5583  	expectPrintedJSX(t, "<a>b   \nc</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b c\");\n")
  5584  	expectPrintedJSX(t, "<a>b\n   c</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b c\");\n")
  5585  	expectPrintedJSX(t, "<a>   b</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"   b\");\n")
  5586  	expectPrintedJSX(t, "<a>   \nb</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5587  	expectPrintedJSX(t, "<a>\n   b</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5588  
  5589  	// Same test as above except with multi-byte Unicode characters
  5590  	expectPrintedJSX(t, "<a>   šŸ™‚</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"   šŸ™‚\");\n")
  5591  	expectPrintedJSX(t, "<a>   \nšŸ™‚</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚\");\n")
  5592  	expectPrintedJSX(t, "<a>\n   šŸ™‚</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚\");\n")
  5593  	expectPrintedJSX(t, "<a>šŸ™‚   </a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚   \");\n")
  5594  	expectPrintedJSX(t, "<a>šŸ™‚   \n</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚\");\n")
  5595  	expectPrintedJSX(t, "<a>šŸ™‚\n   </a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚\");\n")
  5596  	expectPrintedJSX(t, "<a>šŸ™‚   šŸ•</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚   šŸ•\");\n")
  5597  	expectPrintedJSX(t, "<a>šŸ™‚   \nšŸ•</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚ šŸ•\");\n")
  5598  	expectPrintedJSX(t, "<a>šŸ™‚\n   šŸ•</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚ šŸ•\");\n")
  5599  	expectPrintedJSX(t, "<a>   šŸ™‚</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"   šŸ™‚\");\n")
  5600  	expectPrintedJSX(t, "<a>   \nšŸ™‚</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚\");\n")
  5601  	expectPrintedJSX(t, "<a>\n   šŸ™‚</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"šŸ™‚\");\n")
  5602  
  5603  	// "<a>{x}</b></a>" with all combinations of "", " ", and "\n" inserted in between
  5604  	expectPrintedJSX(t, "<a>{x}<b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5605  	expectPrintedJSX(t, "<a>\n{x}<b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5606  	expectPrintedJSX(t, "<a>{x}\n<b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5607  	expectPrintedJSX(t, "<a>\n{x}\n<b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5608  	expectPrintedJSX(t, "<a>{x}<b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5609  	expectPrintedJSX(t, "<a>\n{x}<b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5610  	expectPrintedJSX(t, "<a>{x}\n<b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5611  	expectPrintedJSX(t, "<a>\n{x}\n<b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5612  	expectPrintedJSX(t, "<a> {x}<b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5613  	expectPrintedJSX(t, "<a> {x}\n<b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5614  	expectPrintedJSX(t, "<a> {x}<b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5615  	expectPrintedJSX(t, "<a> {x}\n<b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5616  	expectPrintedJSX(t, "<a>{x} <b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, \" \", /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5617  	expectPrintedJSX(t, "<a>\n{x} <b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, \" \", /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5618  	expectPrintedJSX(t, "<a>{x} <b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, \" \", /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5619  	expectPrintedJSX(t, "<a>\n{x} <b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, \" \", /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5620  	expectPrintedJSX(t, "<a> {x} <b/></a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, \" \", /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5621  	expectPrintedJSX(t, "<a> {x} <b/>\n</a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, \" \", /* @__PURE__ */ React.createElement(\"b\", null));\n")
  5622  	expectPrintedJSX(t, "<a>{x}<b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5623  	expectPrintedJSX(t, "<a>\n{x}<b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5624  	expectPrintedJSX(t, "<a>{x}\n<b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5625  	expectPrintedJSX(t, "<a>\n{x}\n<b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5626  	expectPrintedJSX(t, "<a> {x}<b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5627  	expectPrintedJSX(t, "<a> {x}\n<b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5628  	expectPrintedJSX(t, "<a>{x} <b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, \" \", /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5629  	expectPrintedJSX(t, "<a>\n{x} <b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, x, \" \", /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5630  	expectPrintedJSX(t, "<a> {x} <b/> </a>;", "/* @__PURE__ */ React.createElement(\"a\", null, \" \", x, \" \", /* @__PURE__ */ React.createElement(\"b\", null), \" \");\n")
  5631  
  5632  	expectParseErrorJSX(t, "<a b=true/>", "<stdin>: ERROR: Expected \"{\" but found \"true\"\n")
  5633  	expectParseErrorJSX(t, "</a>", "<stdin>: ERROR: Expected identifier but found \"/\"\n")
  5634  	expectParseErrorJSX(t, "<></b>",
  5635  		"<stdin>: ERROR: Unexpected closing \"b\" tag does not match opening fragment tag\n<stdin>: NOTE: The opening fragment tag is here:\n")
  5636  	expectParseErrorJSX(t, "<a></>",
  5637  		"<stdin>: ERROR: Unexpected closing fragment tag does not match opening \"a\" tag\n<stdin>: NOTE: The opening \"a\" tag is here:\n")
  5638  	expectParseErrorJSX(t, "<a></b>",
  5639  		"<stdin>: ERROR: Unexpected closing \"b\" tag does not match opening \"a\" tag\n<stdin>: NOTE: The opening \"a\" tag is here:\n")
  5640  	expectParseErrorJSX(t, "<\na\n.\nb\n>\n<\n/\nc\n.\nd\n>",
  5641  		"<stdin>: ERROR: Unexpected closing \"c.d\" tag does not match opening \"a.b\" tag\n<stdin>: NOTE: The opening \"a.b\" tag is here:\n")
  5642  	expectParseErrorJSX(t, "<a-b.c>", "<stdin>: ERROR: Expected \">\" but found \".\"\n")
  5643  	expectParseErrorJSX(t, "<a.b-c>", "<stdin>: ERROR: Unexpected \"-\"\n")
  5644  
  5645  	expectPrintedJSX(t, "< /**/ a/>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5646  	expectPrintedJSX(t, "< //\n a/>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5647  	expectPrintedJSX(t, "<a /**/ />", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5648  	expectPrintedJSX(t, "<a //\n />", "/* @__PURE__ */ React.createElement(\n  \"a\",\n  null\n);\n")
  5649  	expectPrintedJSX(t, "<a/ /**/ >", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5650  	expectPrintedJSX(t, "<a/ //\n >", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5651  
  5652  	expectPrintedJSX(t, "<a>b< /**/ /a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5653  	expectPrintedJSX(t, "<a>b< //\n /a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5654  	expectPrintedJSX(t, "<a>b</ /**/ a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5655  	expectPrintedJSX(t, "<a>b</ //\n a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5656  	expectPrintedJSX(t, "<a>b</a /**/ >", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5657  	expectPrintedJSX(t, "<a>b</a //\n >", "/* @__PURE__ */ React.createElement(\"a\", null, \"b\");\n")
  5658  
  5659  	expectPrintedJSX(t, "<a> /**/ </a>", "/* @__PURE__ */ React.createElement(\"a\", null, \" /**/ \");\n")
  5660  	expectPrintedJSX(t, "<a> //\n </a>", "/* @__PURE__ */ React.createElement(\"a\", null, \" //\");\n")
  5661  
  5662  	// Unicode tests
  5663  	expectPrintedJSX(t, "<\U00020000/>", "/* @__PURE__ */ React.createElement(\U00020000, null);\n")
  5664  	expectPrintedJSX(t, "<a>\U00020000</a>", "/* @__PURE__ */ React.createElement(\"a\", null, \"\U00020000\");\n")
  5665  	expectPrintedJSX(t, "<a \U00020000={0}/>", "/* @__PURE__ */ React.createElement(\"a\", { \"\U00020000\": 0 });\n")
  5666  
  5667  	// Comment tests
  5668  	expectParseErrorJSX(t, "<a /* />", "<stdin>: ERROR: Expected \"*/\" to terminate multi-line comment\n<stdin>: NOTE: The multi-line comment starts here:\n")
  5669  	expectParseErrorJSX(t, "<a /*/ />", "<stdin>: ERROR: Expected \"*/\" to terminate multi-line comment\n<stdin>: NOTE: The multi-line comment starts here:\n")
  5670  	expectParseErrorJSX(t, "<a // />", "<stdin>: ERROR: Expected \">\" but found end of file\n")
  5671  	expectParseErrorJSX(t, "<a /**/>", "<stdin>: ERROR: Unexpected end of file before a closing \"a\" tag\n<stdin>: NOTE: The opening \"a\" tag is here:\n")
  5672  	expectParseErrorJSX(t, "<a /**/ />", "")
  5673  	expectParseErrorJSX(t, "<a // \n />", "")
  5674  	expectParseErrorJSX(t, "<a b/* />", "<stdin>: ERROR: Expected \"*/\" to terminate multi-line comment\n<stdin>: NOTE: The multi-line comment starts here:\n")
  5675  	expectParseErrorJSX(t, "<a b/*/ />", "<stdin>: ERROR: Expected \"*/\" to terminate multi-line comment\n<stdin>: NOTE: The multi-line comment starts here:\n")
  5676  	expectParseErrorJSX(t, "<a b// />", "<stdin>: ERROR: Expected \">\" but found end of file\n")
  5677  	expectParseErrorJSX(t, "<a b/**/>", "<stdin>: ERROR: Unexpected end of file before a closing \"a\" tag\n<stdin>: NOTE: The opening \"a\" tag is here:\n")
  5678  	expectParseErrorJSX(t, "<a b/**/ />", "")
  5679  	expectParseErrorJSX(t, "<a b// \n />", "")
  5680  
  5681  	// JSX namespaced names
  5682  	for _, colon := range []string{":", " :", ": ", " : "} {
  5683  		expectPrintedJSX(t, "<a"+colon+"b/>", "/* @__PURE__ */ React.createElement(\"a:b\", null);\n")
  5684  		expectPrintedJSX(t, "<a-b"+colon+"c-d/>", "/* @__PURE__ */ React.createElement(\"a-b:c-d\", null);\n")
  5685  		expectPrintedJSX(t, "<a-"+colon+"b-/>", "/* @__PURE__ */ React.createElement(\"a-:b-\", null);\n")
  5686  		expectPrintedJSX(t, "<Te"+colon+"st/>", "/* @__PURE__ */ React.createElement(\"Te:st\", null);\n")
  5687  		expectPrintedJSX(t, "<x a"+colon+"b/>", "/* @__PURE__ */ React.createElement(\"x\", { \"a:b\": true });\n")
  5688  		expectPrintedJSX(t, "<x a-b"+colon+"c-d/>", "/* @__PURE__ */ React.createElement(\"x\", { \"a-b:c-d\": true });\n")
  5689  		expectPrintedJSX(t, "<x a-"+colon+"b-/>", "/* @__PURE__ */ React.createElement(\"x\", { \"a-:b-\": true });\n")
  5690  		expectPrintedJSX(t, "<x Te"+colon+"st/>", "/* @__PURE__ */ React.createElement(\"x\", { \"Te:st\": true });\n")
  5691  		expectPrintedJSX(t, "<x a"+colon+"b={0}/>", "/* @__PURE__ */ React.createElement(\"x\", { \"a:b\": 0 });\n")
  5692  		expectPrintedJSX(t, "<x a-b"+colon+"c-d={0}/>", "/* @__PURE__ */ React.createElement(\"x\", { \"a-b:c-d\": 0 });\n")
  5693  		expectPrintedJSX(t, "<x a-"+colon+"b-={0}/>", "/* @__PURE__ */ React.createElement(\"x\", { \"a-:b-\": 0 });\n")
  5694  		expectPrintedJSX(t, "<x Te"+colon+"st={0}/>", "/* @__PURE__ */ React.createElement(\"x\", { \"Te:st\": 0 });\n")
  5695  		expectPrintedJSX(t, "<a-b a-b={a-b}/>", "/* @__PURE__ */ React.createElement(\"a-b\", { \"a-b\": a - b });\n")
  5696  		expectParseErrorJSX(t, "<x"+colon+"/>", "<stdin>: ERROR: Expected identifier after \"x:\" in namespaced JSX name\n")
  5697  		expectParseErrorJSX(t, "<x"+colon+"y"+colon+"/>", "<stdin>: ERROR: Expected \">\" but found \":\"\n")
  5698  		expectParseErrorJSX(t, "<x"+colon+"0y/>", "<stdin>: ERROR: Expected identifier after \"x:\" in namespaced JSX name\n")
  5699  	}
  5700  
  5701  	// JSX elements as JSX attribute values
  5702  	expectPrintedJSX(t, "<a b=<c/>/>", "/* @__PURE__ */ React.createElement(\"a\", { b: /* @__PURE__ */ React.createElement(\"c\", null) });\n")
  5703  	expectPrintedJSX(t, "<a b=<></>/>", "/* @__PURE__ */ React.createElement(\"a\", { b: /* @__PURE__ */ React.createElement(React.Fragment, null) });\n")
  5704  	expectParseErrorJSX(t, "<a b=</a>/>", "<stdin>: ERROR: Expected identifier but found \"/\"\n")
  5705  	expectParseErrorJSX(t, "<a b=<>/>",
  5706  		"<stdin>: WARNING: The character \">\" is not valid inside a JSX element\nNOTE: Did you mean to escape it as \"{'>'}\" instead?\n"+
  5707  			"<stdin>: ERROR: Unexpected end of file before a closing fragment tag\n<stdin>: NOTE: The opening fragment tag is here:\n")
  5708  	expectParseErrorJSX(t, "<a b=<c>></a>",
  5709  		"<stdin>: WARNING: The character \">\" is not valid inside a JSX element\nNOTE: Did you mean to escape it as \"{'>'}\" instead?\n"+
  5710  			"<stdin>: ERROR: Unexpected closing \"a\" tag does not match opening \"c\" tag\n<stdin>: NOTE: The opening \"c\" tag is here:\n"+
  5711  			"<stdin>: ERROR: Expected \">\" but found end of file\n")
  5712  	expectParseErrorJSX(t, "<a b=<c>/>",
  5713  		"<stdin>: WARNING: The character \">\" is not valid inside a JSX element\nNOTE: Did you mean to escape it as \"{'>'}\" instead?\n"+
  5714  			"<stdin>: ERROR: Unexpected end of file before a closing \"c\" tag\n<stdin>: NOTE: The opening \"c\" tag is here:\n")
  5715  }
  5716  
  5717  func TestJSXSingleLine(t *testing.T) {
  5718  	expectPrintedJSX(t, "<x/>", "/* @__PURE__ */ React.createElement(\"x\", null);\n")
  5719  	expectPrintedJSX(t, "<x y/>", "/* @__PURE__ */ React.createElement(\"x\", { y: true });\n")
  5720  	expectPrintedJSX(t, "<x\n/>", "/* @__PURE__ */ React.createElement(\n  \"x\",\n  null\n);\n")
  5721  	expectPrintedJSX(t, "<x\ny/>", "/* @__PURE__ */ React.createElement(\n  \"x\",\n  {\n    y: true\n  }\n);\n")
  5722  	expectPrintedJSX(t, "<x y\n/>", "/* @__PURE__ */ React.createElement(\n  \"x\",\n  {\n    y: true\n  }\n);\n")
  5723  	expectPrintedJSX(t, "<x\n{...y}/>", "/* @__PURE__ */ React.createElement(\n  \"x\",\n  {\n    ...y\n  }\n);\n")
  5724  }
  5725  
  5726  func TestJSXPragmas(t *testing.T) {
  5727  	expectPrintedJSX(t, "// @jsx h\n<a/>", "/* @__PURE__ */ h(\"a\", null);\n")
  5728  	expectPrintedJSX(t, "/*@jsx h*/\n<a/>", "/* @__PURE__ */ h(\"a\", null);\n")
  5729  	expectPrintedJSX(t, "/* @jsx h */\n<a/>", "/* @__PURE__ */ h(\"a\", null);\n")
  5730  	expectPrintedJSX(t, "<a/>\n// @jsx h", "/* @__PURE__ */ h(\"a\", null);\n")
  5731  	expectPrintedJSX(t, "<a/>\n/*@jsx h*/", "/* @__PURE__ */ h(\"a\", null);\n")
  5732  	expectPrintedJSX(t, "<a/>\n/* @jsx h */", "/* @__PURE__ */ h(\"a\", null);\n")
  5733  	expectPrintedJSX(t, "// @jsx a.b.c\n<a/>", "/* @__PURE__ */ a.b.c(\"a\", null);\n")
  5734  	expectPrintedJSX(t, "/*@jsx a.b.c*/\n<a/>", "/* @__PURE__ */ a.b.c(\"a\", null);\n")
  5735  	expectPrintedJSX(t, "/* @jsx a.b.c */\n<a/>", "/* @__PURE__ */ a.b.c(\"a\", null);\n")
  5736  
  5737  	expectPrintedJSX(t, "// @jsxFrag f\n<></>", "/* @__PURE__ */ React.createElement(f, null);\n")
  5738  	expectPrintedJSX(t, "/*@jsxFrag f*/\n<></>", "/* @__PURE__ */ React.createElement(f, null);\n")
  5739  	expectPrintedJSX(t, "/* @jsxFrag f */\n<></>", "/* @__PURE__ */ React.createElement(f, null);\n")
  5740  	expectPrintedJSX(t, "<></>\n// @jsxFrag f", "/* @__PURE__ */ React.createElement(f, null);\n")
  5741  	expectPrintedJSX(t, "<></>\n/*@jsxFrag f*/", "/* @__PURE__ */ React.createElement(f, null);\n")
  5742  	expectPrintedJSX(t, "<></>\n/* @jsxFrag f */", "/* @__PURE__ */ React.createElement(f, null);\n")
  5743  	expectPrintedJSX(t, "// @jsxFrag a.b.c\n<></>", "/* @__PURE__ */ React.createElement(a.b.c, null);\n")
  5744  	expectPrintedJSX(t, "/*@jsxFrag a.b.c*/\n<></>", "/* @__PURE__ */ React.createElement(a.b.c, null);\n")
  5745  	expectPrintedJSX(t, "/* @jsxFrag a.b.c */\n<></>", "/* @__PURE__ */ React.createElement(a.b.c, null);\n")
  5746  }
  5747  
  5748  func TestJSXAutomatic(t *testing.T) {
  5749  	// Prod, without runtime imports
  5750  	p := JSXAutomaticTestOptions{Development: false, OmitJSXRuntimeForTests: true}
  5751  	expectPrintedJSXAutomatic(t, p, "<div>></div>", "/* @__PURE__ */ jsx(\"div\", { children: \">\" });\n")
  5752  	expectPrintedJSXAutomatic(t, p, "<div>{1}}</div>", "/* @__PURE__ */ jsxs(\"div\", { children: [\n  1,\n  \"}\"\n] });\n")
  5753  	expectPrintedJSXAutomatic(t, p, "<div key={true} />", "/* @__PURE__ */ jsx(\"div\", {}, true);\n")
  5754  	expectPrintedJSXAutomatic(t, p, "<div key=\"key\" />", "/* @__PURE__ */ jsx(\"div\", {}, \"key\");\n")
  5755  	expectPrintedJSXAutomatic(t, p, "<div key=\"key\" {...props} />", "/* @__PURE__ */ jsx(\"div\", { ...props }, \"key\");\n")
  5756  	expectPrintedJSXAutomatic(t, p, "<div {...props} key=\"key\" />", "/* @__PURE__ */ createElement(\"div\", { ...props, key: \"key\" });\n") // Falls back to createElement
  5757  	expectPrintedJSXAutomatic(t, p, "<div>{...children}</div>", "/* @__PURE__ */ jsxs(\"div\", { children: [\n  ...children\n] });\n")
  5758  	expectPrintedJSXAutomatic(t, p, "<div>{...children}<a/></div>", "/* @__PURE__ */ jsxs(\"div\", { children: [\n  ...children,\n  /* @__PURE__ */ jsx(\"a\", {})\n] });\n")
  5759  	expectPrintedJSXAutomatic(t, p, "<>></>", "/* @__PURE__ */ jsx(Fragment, { children: \">\" });\n")
  5760  
  5761  	expectParseErrorJSXAutomatic(t, p, "<a key/>",
  5762  		`<stdin>: ERROR: Please provide an explicit value for "key":
  5763  NOTE: Using "key" as a shorthand for "key={true}" is not allowed when using React's "automatic" JSX transform.
  5764  `)
  5765  	expectParseErrorJSXAutomatic(t, p, "<div __self={self} />",
  5766  		`<stdin>: ERROR: Duplicate "__self" prop found:
  5767  NOTE: Both "__source" and "__self" are set automatically by esbuild when using React's "automatic" JSX transform. This duplicate prop may have come from a plugin.
  5768  `)
  5769  	expectParseErrorJSXAutomatic(t, p, "<div __source=\"/path/to/source.jsx\" />",
  5770  		`<stdin>: ERROR: Duplicate "__source" prop found:
  5771  NOTE: Both "__source" and "__self" are set automatically by esbuild when using React's "automatic" JSX transform. This duplicate prop may have come from a plugin.
  5772  `)
  5773  
  5774  	// Prod, with runtime imports
  5775  	pr := JSXAutomaticTestOptions{Development: false}
  5776  	expectPrintedJSXAutomatic(t, pr, "<div/>", "import { jsx } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsx(\"div\", {});\n")
  5777  	expectPrintedJSXAutomatic(t, pr, "<><a/><b/></>", "import { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsxs(Fragment, { children: [\n  /* @__PURE__ */ jsx(\"a\", {}),\n  /* @__PURE__ */ jsx(\"b\", {})\n] });\n")
  5778  	expectPrintedJSXAutomatic(t, pr, "<div {...props} key=\"key\" />", "import { createElement } from \"react\";\n/* @__PURE__ */ createElement(\"div\", { ...props, key: \"key\" });\n")
  5779  	expectPrintedJSXAutomatic(t, pr, "<><div {...props} key=\"key\" /></>", "import { Fragment, jsx } from \"react/jsx-runtime\";\nimport { createElement } from \"react\";\n/* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ createElement(\"div\", { ...props, key: \"key\" }) });\n")
  5780  
  5781  	pri := JSXAutomaticTestOptions{Development: false, ImportSource: "my-jsx-lib"}
  5782  	expectPrintedJSXAutomatic(t, pri, "<div/>", "import { jsx } from \"my-jsx-lib/jsx-runtime\";\n/* @__PURE__ */ jsx(\"div\", {});\n")
  5783  	expectPrintedJSXAutomatic(t, pri, "<div {...props} key=\"key\" />", "import { createElement } from \"my-jsx-lib\";\n/* @__PURE__ */ createElement(\"div\", { ...props, key: \"key\" });\n")
  5784  
  5785  	// Impure JSX call expressions
  5786  	pi := JSXAutomaticTestOptions{SideEffects: true, ImportSource: "my-jsx-lib"}
  5787  	expectPrintedJSXAutomatic(t, pi, "<a/>", "import { jsx } from \"my-jsx-lib/jsx-runtime\";\njsx(\"a\", {});\n")
  5788  	expectPrintedJSXAutomatic(t, pi, "<></>", "import { Fragment, jsx } from \"my-jsx-lib/jsx-runtime\";\njsx(Fragment, {});\n")
  5789  
  5790  	// Dev, without runtime imports
  5791  	d := JSXAutomaticTestOptions{Development: true, OmitJSXRuntimeForTests: true}
  5792  	expectPrintedJSXAutomatic(t, d, "<div>></div>", "/* @__PURE__ */ jsxDEV(\"div\", { children: \">\" }, void 0, false, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5793  	expectPrintedJSXAutomatic(t, d, "<div>{1}}</div>", "/* @__PURE__ */ jsxDEV(\"div\", { children: [\n  1,\n  \"}\"\n] }, void 0, true, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5794  	expectPrintedJSXAutomatic(t, d, "<div key={true} />", "/* @__PURE__ */ jsxDEV(\"div\", {}, true, false, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5795  	expectPrintedJSXAutomatic(t, d, "<div key=\"key\" />", "/* @__PURE__ */ jsxDEV(\"div\", {}, \"key\", false, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5796  	expectPrintedJSXAutomatic(t, d, "<div key=\"key\" {...props} />", "/* @__PURE__ */ jsxDEV(\"div\", { ...props }, \"key\", false, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5797  	expectPrintedJSXAutomatic(t, d, "<div {...props} key=\"key\" />", "/* @__PURE__ */ createElement(\"div\", { ...props, key: \"key\" });\n") // Falls back to createElement
  5798  	expectPrintedJSXAutomatic(t, d, "<div>{...children}</div>", "/* @__PURE__ */ jsxDEV(\"div\", { children: [\n  ...children\n] }, void 0, true, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5799  	expectPrintedJSXAutomatic(t, d, "<div>\n  {...children}\n  <a/></div>", "/* @__PURE__ */ jsxDEV(\"div\", { children: [\n  ...children,\n  /* @__PURE__ */ jsxDEV(\"a\", {}, void 0, false, {\n    fileName: \"<stdin>\",\n    lineNumber: 3,\n    columnNumber: 3\n  }, this)\n] }, void 0, true, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5800  	expectPrintedJSXAutomatic(t, d, "<>></>", "/* @__PURE__ */ jsxDEV(Fragment, { children: \">\" }, void 0, false, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5801  
  5802  	expectParseErrorJSXAutomatic(t, d, "<a key/>",
  5803  		`<stdin>: ERROR: Please provide an explicit value for "key":
  5804  NOTE: Using "key" as a shorthand for "key={true}" is not allowed when using React's "automatic" JSX transform.
  5805  `)
  5806  	expectParseErrorJSXAutomatic(t, d, "<div __self={self} />",
  5807  		`<stdin>: ERROR: Duplicate "__self" prop found:
  5808  NOTE: Both "__source" and "__self" are set automatically by esbuild when using React's "automatic" JSX transform. This duplicate prop may have come from a plugin.
  5809  `)
  5810  	expectParseErrorJSXAutomatic(t, d, "<div __source=\"/path/to/source.jsx\" />",
  5811  		`<stdin>: ERROR: Duplicate "__source" prop found:
  5812  NOTE: Both "__source" and "__self" are set automatically by esbuild when using React's "automatic" JSX transform. This duplicate prop may have come from a plugin.
  5813  `)
  5814  
  5815  	// Line/column offset tests. Unlike Babel, TypeScript sometimes points to a
  5816  	// location other than the start of the element. I'm not sure if that's a bug
  5817  	// or not, but it seems weird. So I decided to match Babel instead.
  5818  	expectPrintedJSXAutomatic(t, d, "\r\n<x/>", "/* @__PURE__ */ jsxDEV(\"x\", {}, void 0, false, {\n  fileName: \"<stdin>\",\n  lineNumber: 2,\n  columnNumber: 1\n}, this);\n")
  5819  	expectPrintedJSXAutomatic(t, d, "\n\r<x/>", "/* @__PURE__ */ jsxDEV(\"x\", {}, void 0, false, {\n  fileName: \"<stdin>\",\n  lineNumber: 3,\n  columnNumber: 1\n}, this);\n")
  5820  	expectPrintedJSXAutomatic(t, d, "let 𐀀 = <x>šŸ•šŸ•šŸ•<y/></x>", "let 𐀀 = /* @__PURE__ */ jsxDEV(\"x\", { children: [\n  \"šŸ•šŸ•šŸ•\",\n  /* @__PURE__ */ jsxDEV(\"y\", {}, void 0, false, {\n    fileName: \"<stdin>\",\n    lineNumber: 1,\n    columnNumber: 19\n  }, this)\n] }, void 0, true, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 10\n}, this);\n")
  5821  
  5822  	// Dev, with runtime imports
  5823  	dr := JSXAutomaticTestOptions{Development: true}
  5824  	expectPrintedJSXAutomatic(t, dr, "<div/>", "import { jsxDEV } from \"react/jsx-dev-runtime\";\n/* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5825  	expectPrintedJSXAutomatic(t, dr, "<>\n  <a/>\n  <b/>\n</>", "import { Fragment, jsxDEV } from \"react/jsx-dev-runtime\";\n/* @__PURE__ */ jsxDEV(Fragment, { children: [\n  /* @__PURE__ */ jsxDEV(\"a\", {}, void 0, false, {\n    fileName: \"<stdin>\",\n    lineNumber: 2,\n    columnNumber: 3\n  }, this),\n  /* @__PURE__ */ jsxDEV(\"b\", {}, void 0, false, {\n    fileName: \"<stdin>\",\n    lineNumber: 3,\n    columnNumber: 3\n  }, this)\n] }, void 0, true, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5826  
  5827  	dri := JSXAutomaticTestOptions{Development: true, ImportSource: "preact"}
  5828  	expectPrintedJSXAutomatic(t, dri, "<div/>", "import { jsxDEV } from \"preact/jsx-dev-runtime\";\n/* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5829  	expectPrintedJSXAutomatic(t, dri, "<>\n  <a/>\n  <b/>\n</>", "import { Fragment, jsxDEV } from \"preact/jsx-dev-runtime\";\n/* @__PURE__ */ jsxDEV(Fragment, { children: [\n  /* @__PURE__ */ jsxDEV(\"a\", {}, void 0, false, {\n    fileName: \"<stdin>\",\n    lineNumber: 2,\n    columnNumber: 3\n  }, this),\n  /* @__PURE__ */ jsxDEV(\"b\", {}, void 0, false, {\n    fileName: \"<stdin>\",\n    lineNumber: 3,\n    columnNumber: 3\n  }, this)\n] }, void 0, true, {\n  fileName: \"<stdin>\",\n  lineNumber: 1,\n  columnNumber: 1\n}, this);\n")
  5830  
  5831  	// JSX namespaced names
  5832  	for _, colon := range []string{":", " :", ": ", " : "} {
  5833  		expectPrintedJSXAutomatic(t, p, "<a"+colon+"b/>", "/* @__PURE__ */ jsx(\"a:b\", {});\n")
  5834  		expectPrintedJSXAutomatic(t, p, "<a-b"+colon+"c-d/>", "/* @__PURE__ */ jsx(\"a-b:c-d\", {});\n")
  5835  		expectPrintedJSXAutomatic(t, p, "<a-"+colon+"b-/>", "/* @__PURE__ */ jsx(\"a-:b-\", {});\n")
  5836  		expectPrintedJSXAutomatic(t, p, "<Te"+colon+"st/>", "/* @__PURE__ */ jsx(\"Te:st\", {});\n")
  5837  		expectPrintedJSXAutomatic(t, p, "<x a"+colon+"b/>", "/* @__PURE__ */ jsx(\"x\", { \"a:b\": true });\n")
  5838  		expectPrintedJSXAutomatic(t, p, "<x a-b"+colon+"c-d/>", "/* @__PURE__ */ jsx(\"x\", { \"a-b:c-d\": true });\n")
  5839  		expectPrintedJSXAutomatic(t, p, "<x a-"+colon+"b-/>", "/* @__PURE__ */ jsx(\"x\", { \"a-:b-\": true });\n")
  5840  		expectPrintedJSXAutomatic(t, p, "<x Te"+colon+"st/>", "/* @__PURE__ */ jsx(\"x\", { \"Te:st\": true });\n")
  5841  		expectPrintedJSXAutomatic(t, p, "<x a"+colon+"b={0}/>", "/* @__PURE__ */ jsx(\"x\", { \"a:b\": 0 });\n")
  5842  		expectPrintedJSXAutomatic(t, p, "<x a-b"+colon+"c-d={0}/>", "/* @__PURE__ */ jsx(\"x\", { \"a-b:c-d\": 0 });\n")
  5843  		expectPrintedJSXAutomatic(t, p, "<x a-"+colon+"b-={0}/>", "/* @__PURE__ */ jsx(\"x\", { \"a-:b-\": 0 });\n")
  5844  		expectPrintedJSXAutomatic(t, p, "<x Te"+colon+"st={0}/>", "/* @__PURE__ */ jsx(\"x\", { \"Te:st\": 0 });\n")
  5845  		expectPrintedJSXAutomatic(t, p, "<a-b a-b={a-b}/>", "/* @__PURE__ */ jsx(\"a-b\", { \"a-b\": a - b });\n")
  5846  		expectParseErrorJSXAutomatic(t, p, "<x"+colon+"/>", "<stdin>: ERROR: Expected identifier after \"x:\" in namespaced JSX name\n")
  5847  		expectParseErrorJSXAutomatic(t, p, "<x"+colon+"y"+colon+"/>", "<stdin>: ERROR: Expected \">\" but found \":\"\n")
  5848  		expectParseErrorJSXAutomatic(t, p, "<x"+colon+"0y/>", "<stdin>: ERROR: Expected identifier after \"x:\" in namespaced JSX name\n")
  5849  	}
  5850  
  5851  	// Enabling the "automatic" runtime means that any JSX element will cause the
  5852  	// file to be implicitly in strict mode due to the automatically-generated
  5853  	// import statement. This is the same behavior as the TypeScript compiler.
  5854  	strictModeError := "<stdin>: ERROR: With statements cannot be used in strict mode\n" +
  5855  		"<stdin>: NOTE: This file is implicitly in strict mode due to the JSX element here:\n" +
  5856  		"NOTE: When React's \"automatic\" JSX transform is enabled, using a JSX element automatically inserts an \"import\" statement at the top of the file " +
  5857  		"for the corresponding the JSX helper function. This means the file is considered an ECMAScript module, and all ECMAScript modules use strict mode.\n"
  5858  	expectPrintedJSX(t, "with (x) y(<z/>)", "with (x) y(/* @__PURE__ */ React.createElement(\"z\", null));\n")
  5859  	expectPrintedJSXAutomatic(t, p, "with (x) y", "with (x) y;\n")
  5860  	expectParseErrorJSX(t, "with (x) y(<z/>) // @jsxRuntime automatic", strictModeError)
  5861  	expectParseErrorJSXAutomatic(t, p, "with (x) y(<z/>)", strictModeError)
  5862  }
  5863  
  5864  func TestJSXAutomaticPragmas(t *testing.T) {
  5865  	expectPrintedJSX(t, "// @jsxRuntime automatic\n<a/>", "import { jsx } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5866  	expectPrintedJSX(t, "/*@jsxRuntime automatic*/\n<a/>", "import { jsx } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5867  	expectPrintedJSX(t, "/* @jsxRuntime automatic */\n<a/>", "import { jsx } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5868  	expectPrintedJSX(t, "<a/>\n/*@jsxRuntime automatic*/", "import { jsx } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5869  	expectPrintedJSX(t, "<a/>\n/* @jsxRuntime automatic */", "import { jsx } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5870  
  5871  	expectPrintedJSX(t, "// @jsxRuntime classic\n<a/>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5872  	expectPrintedJSX(t, "/*@jsxRuntime classic*/\n<a/>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5873  	expectPrintedJSX(t, "/* @jsxRuntime classic */\n<a/>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5874  	expectPrintedJSX(t, "<a/>\n/*@jsxRuntime classic*/\n", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5875  	expectPrintedJSX(t, "<a/>\n/* @jsxRuntime classic */\n", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5876  
  5877  	expectParseErrorJSX(t, "// @jsxRuntime foo\n<a/>",
  5878  		`<stdin>: WARNING: Invalid JSX runtime: "foo"
  5879  NOTE: The JSX runtime can only be set to either "classic" or "automatic".
  5880  `)
  5881  
  5882  	expectPrintedJSX(t, "// @jsxRuntime automatic @jsxImportSource src\n<a/>", "import { jsx } from \"src/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5883  	expectPrintedJSX(t, "/*@jsxRuntime automatic @jsxImportSource src*/\n<a/>", "import { jsx } from \"src/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5884  	expectPrintedJSX(t, "/*@jsxRuntime automatic*//*@jsxImportSource src*/\n<a/>", "import { jsx } from \"src/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5885  	expectPrintedJSX(t, "/* @jsxRuntime automatic */\n/* @jsxImportSource src */\n<a/>", "import { jsx } from \"src/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5886  	expectPrintedJSX(t, "<a/>\n/*@jsxRuntime automatic @jsxImportSource src*/", "import { jsx } from \"src/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5887  	expectPrintedJSX(t, "<a/>\n/*@jsxRuntime automatic*/\n/*@jsxImportSource src*/", "import { jsx } from \"src/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5888  	expectPrintedJSX(t, "<a/>\n/* @jsxRuntime automatic */\n/* @jsxImportSource src */", "import { jsx } from \"src/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5889  
  5890  	expectPrintedJSX(t, "// @jsxRuntime classic @jsxImportSource src\n<a/>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5891  	expectParseErrorJSX(t, "// @jsxRuntime classic @jsxImportSource src\n<a/>",
  5892  		`<stdin>: WARNING: The JSX import source cannot be set without also enabling React's "automatic" JSX transform
  5893  NOTE: You can enable React's "automatic" JSX transform for this file by using a "@jsxRuntime automatic" comment.
  5894  `)
  5895  	expectParseErrorJSX(t, "// @jsxImportSource src\n<a/>",
  5896  		`<stdin>: WARNING: The JSX import source cannot be set without also enabling React's "automatic" JSX transform
  5897  NOTE: You can enable React's "automatic" JSX transform for this file by using a "@jsxRuntime automatic" comment.
  5898  `)
  5899  
  5900  	expectPrintedJSX(t, "// @jsxRuntime automatic @jsx h\n<a/>", "import { jsx } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsx(\"a\", {});\n")
  5901  	expectParseErrorJSX(t, "// @jsxRuntime automatic @jsx h\n<a/>", "<stdin>: WARNING: The JSX factory cannot be set when using React's \"automatic\" JSX transform\n")
  5902  
  5903  	expectPrintedJSX(t, "// @jsxRuntime automatic @jsxFrag f\n<></>", "import { Fragment, jsx } from \"react/jsx-runtime\";\n/* @__PURE__ */ jsx(Fragment, {});\n")
  5904  	expectParseErrorJSX(t, "// @jsxRuntime automatic @jsxFrag f\n<></>", "<stdin>: WARNING: The JSX fragment cannot be set when using React's \"automatic\" JSX transform\n")
  5905  }
  5906  
  5907  func TestJSXSideEffects(t *testing.T) {
  5908  	expectPrintedJSX(t, "<a/>", "/* @__PURE__ */ React.createElement(\"a\", null);\n")
  5909  	expectPrintedJSX(t, "<></>", "/* @__PURE__ */ React.createElement(React.Fragment, null);\n")
  5910  
  5911  	expectPrintedJSXSideEffects(t, "<a/>", "React.createElement(\"a\", null);\n")
  5912  	expectPrintedJSXSideEffects(t, "<></>", "React.createElement(React.Fragment, null);\n")
  5913  }
  5914  
  5915  func TestPreserveOptionalChainParentheses(t *testing.T) {
  5916  	expectPrinted(t, "a?.b.c", "a?.b.c;\n")
  5917  	expectPrinted(t, "(a?.b).c", "(a?.b).c;\n")
  5918  	expectPrinted(t, "a?.b.c.d", "a?.b.c.d;\n")
  5919  	expectPrinted(t, "(a?.b.c).d", "(a?.b.c).d;\n")
  5920  	expectPrinted(t, "a?.b[c]", "a?.b[c];\n")
  5921  	expectPrinted(t, "(a?.b)[c]", "(a?.b)[c];\n")
  5922  	expectPrinted(t, "a?.b(c)", "a?.b(c);\n")
  5923  	expectPrinted(t, "(a?.b)(c)", "(a?.b)(c);\n")
  5924  
  5925  	expectPrinted(t, "a?.[b][c]", "a?.[b][c];\n")
  5926  	expectPrinted(t, "(a?.[b])[c]", "(a?.[b])[c];\n")
  5927  	expectPrinted(t, "a?.[b][c][d]", "a?.[b][c][d];\n")
  5928  	expectPrinted(t, "(a?.[b][c])[d]", "(a?.[b][c])[d];\n")
  5929  	expectPrinted(t, "a?.[b].c", "a?.[b].c;\n")
  5930  	expectPrinted(t, "(a?.[b]).c", "(a?.[b]).c;\n")
  5931  	expectPrinted(t, "a?.[b](c)", "a?.[b](c);\n")
  5932  	expectPrinted(t, "(a?.[b])(c)", "(a?.[b])(c);\n")
  5933  
  5934  	expectPrinted(t, "a?.(b)(c)", "a?.(b)(c);\n")
  5935  	expectPrinted(t, "(a?.(b))(c)", "(a?.(b))(c);\n")
  5936  	expectPrinted(t, "a?.(b)(c)(d)", "a?.(b)(c)(d);\n")
  5937  	expectPrinted(t, "(a?.(b)(c))(d)", "(a?.(b)(c))(d);\n")
  5938  	expectPrinted(t, "a?.(b).c", "a?.(b).c;\n")
  5939  	expectPrinted(t, "(a?.(b)).c", "(a?.(b)).c;\n")
  5940  	expectPrinted(t, "a?.(b)[c]", "a?.(b)[c];\n")
  5941  	expectPrinted(t, "(a?.(b))[c]", "(a?.(b))[c];\n")
  5942  }
  5943  
  5944  func TestPrivateIdentifiers(t *testing.T) {
  5945  	expectParseError(t, "#foo", "<stdin>: ERROR: Unexpected \"#foo\"\n")
  5946  	expectParseError(t, "#foo in this", "<stdin>: ERROR: Unexpected \"#foo\"\n")
  5947  	expectParseError(t, "this.#foo", "<stdin>: ERROR: Expected identifier but found \"#foo\"\n")
  5948  	expectParseError(t, "this?.#foo", "<stdin>: ERROR: Expected identifier but found \"#foo\"\n")
  5949  	expectParseError(t, "({ #foo: 1 })", "<stdin>: ERROR: Expected identifier but found \"#foo\"\n")
  5950  	expectParseError(t, "class Foo { x = { #foo: 1 } }", "<stdin>: ERROR: Expected identifier but found \"#foo\"\n")
  5951  	expectParseError(t, "class Foo { x = #foo }", "<stdin>: ERROR: Expected \"in\" but found \"}\"\n")
  5952  	expectParseError(t, "class Foo { #foo; foo() { delete this.#foo } }",
  5953  		"<stdin>: ERROR: Deleting the private name \"#foo\" is forbidden\n")
  5954  	expectParseError(t, "class Foo { #foo; foo() { delete this?.#foo } }",
  5955  		"<stdin>: ERROR: Deleting the private name \"#foo\" is forbidden\n")
  5956  	expectParseError(t, "class Foo extends Bar { #foo; foo() { super.#foo } }",
  5957  		"<stdin>: ERROR: Expected identifier but found \"#foo\"\n")
  5958  	expectParseError(t, "class Foo { #foo = () => { for (#foo in this) ; } }",
  5959  		"<stdin>: ERROR: Unexpected \"#foo\"\n")
  5960  	expectParseError(t, "class Foo { #foo = () => { for (x = #foo in this) ; } }",
  5961  		"<stdin>: ERROR: Unexpected \"#foo\"\n")
  5962  
  5963  	expectPrinted(t, "class Foo { #foo }", "class Foo {\n  #foo;\n}\n")
  5964  	expectPrinted(t, "class Foo { #foo = 1 }", "class Foo {\n  #foo = 1;\n}\n")
  5965  	expectPrinted(t, "class Foo { #foo = #foo in this }", "class Foo {\n  #foo = #foo in this;\n}\n")
  5966  	expectPrinted(t, "class Foo { #foo = #foo in (#bar in this); #bar }", "class Foo {\n  #foo = #foo in (#bar in this);\n  #bar;\n}\n")
  5967  	expectPrinted(t, "class Foo { #foo() {} }", "class Foo {\n  #foo() {\n  }\n}\n")
  5968  	expectPrinted(t, "class Foo { get #foo() {} }", "class Foo {\n  get #foo() {\n  }\n}\n")
  5969  	expectPrinted(t, "class Foo { set #foo(x) {} }", "class Foo {\n  set #foo(x) {\n  }\n}\n")
  5970  	expectPrinted(t, "class Foo { static #foo }", "class Foo {\n  static #foo;\n}\n")
  5971  	expectPrinted(t, "class Foo { static #foo = 1 }", "class Foo {\n  static #foo = 1;\n}\n")
  5972  	expectPrinted(t, "class Foo { static #foo() {} }", "class Foo {\n  static #foo() {\n  }\n}\n")
  5973  	expectPrinted(t, "class Foo { static get #foo() {} }", "class Foo {\n  static get #foo() {\n  }\n}\n")
  5974  	expectPrinted(t, "class Foo { static set #foo(x) {} }", "class Foo {\n  static set #foo(x) {\n  }\n}\n")
  5975  	expectParseError(t, "class Foo { #foo = #foo in #bar in this; #bar }", "<stdin>: ERROR: Unexpected \"#bar\"\n")
  5976  
  5977  	// The name "#constructor" is forbidden
  5978  	expectParseError(t, "class Foo { #constructor }", "<stdin>: ERROR: Invalid field name \"#constructor\"\n")
  5979  	expectParseError(t, "class Foo { #constructor() {} }", "<stdin>: ERROR: Invalid method name \"#constructor\"\n")
  5980  	expectParseError(t, "class Foo { static #constructor }", "<stdin>: ERROR: Invalid field name \"#constructor\"\n")
  5981  	expectParseError(t, "class Foo { static #constructor() {} }", "<stdin>: ERROR: Invalid method name \"#constructor\"\n")
  5982  	expectParseError(t, "class Foo { #\\u0063onstructor }", "<stdin>: ERROR: Invalid field name \"#constructor\"\n")
  5983  	expectParseError(t, "class Foo { #\\u0063onstructor() {} }", "<stdin>: ERROR: Invalid method name \"#constructor\"\n")
  5984  	expectParseError(t, "class Foo { static #\\u0063onstructor }", "<stdin>: ERROR: Invalid field name \"#constructor\"\n")
  5985  	expectParseError(t, "class Foo { static #\\u0063onstructor() {} }", "<stdin>: ERROR: Invalid method name \"#constructor\"\n")
  5986  
  5987  	// Test escape sequences
  5988  	expectPrinted(t, "class Foo { #\\u0066oo; foo = this.#foo }", "class Foo {\n  #foo;\n  foo = this.#foo;\n}\n")
  5989  	expectPrinted(t, "class Foo { #fo\\u006f; foo = this.#foo }", "class Foo {\n  #foo;\n  foo = this.#foo;\n}\n")
  5990  	expectParseError(t, "class Foo { #\\u0020oo }", "<stdin>: ERROR: Invalid identifier: \"# oo\"\n")
  5991  	expectParseError(t, "class Foo { #fo\\u0020 }", "<stdin>: ERROR: Invalid identifier: \"#fo \"\n")
  5992  
  5993  	errorText := `<stdin>: ERROR: The symbol "#foo" has already been declared
  5994  <stdin>: NOTE: The symbol "#foo" was originally declared here:
  5995  `
  5996  
  5997  	// Scope tests
  5998  	expectParseError(t, "class Foo { #foo; #foo }", errorText)
  5999  	expectParseError(t, "class Foo { #foo; static #foo }", errorText)
  6000  	expectParseError(t, "class Foo { static #foo; #foo }", errorText)
  6001  	expectParseError(t, "class Foo { #foo; #foo() {} }", errorText)
  6002  	expectParseError(t, "class Foo { #foo; get #foo() {} }", errorText)
  6003  	expectParseError(t, "class Foo { #foo; set #foo(x) {} }", errorText)
  6004  	expectParseError(t, "class Foo { #foo() {} #foo }", errorText)
  6005  	expectParseError(t, "class Foo { get #foo() {} #foo }", errorText)
  6006  	expectParseError(t, "class Foo { set #foo(x) {} #foo }", errorText)
  6007  	expectParseError(t, "class Foo { get #foo() {} get #foo() {} }", errorText)
  6008  	expectParseError(t, "class Foo { set #foo(x) {} set #foo(x) {} }", errorText)
  6009  	expectParseError(t, "class Foo { get #foo() {} set #foo(x) {} #foo }", errorText)
  6010  	expectParseError(t, "class Foo { set #foo(x) {} get #foo() {} #foo }", errorText)
  6011  	expectPrinted(t, "class Foo { get #foo() {} set #foo(x) { this.#foo } }",
  6012  		"class Foo {\n  get #foo() {\n  }\n  set #foo(x) {\n    this.#foo;\n  }\n}\n")
  6013  	expectPrinted(t, "class Foo { set #foo(x) { this.#foo } get #foo() {} }",
  6014  		"class Foo {\n  set #foo(x) {\n    this.#foo;\n  }\n  get #foo() {\n  }\n}\n")
  6015  	expectPrinted(t, "class Foo { #foo } class Bar { #foo }", "class Foo {\n  #foo;\n}\nclass Bar {\n  #foo;\n}\n")
  6016  	expectPrinted(t, "class Foo { foo = this.#foo; #foo }", "class Foo {\n  foo = this.#foo;\n  #foo;\n}\n")
  6017  	expectPrinted(t, "class Foo { foo = this?.#foo; #foo }", "class Foo {\n  foo = this?.#foo;\n  #foo;\n}\n")
  6018  	expectParseError(t, "class Foo { #foo } class Bar { foo = this.#foo }",
  6019  		"<stdin>: ERROR: Private name \"#foo\" must be declared in an enclosing class\n")
  6020  	expectParseError(t, "class Foo { #foo } class Bar { foo = this?.#foo }",
  6021  		"<stdin>: ERROR: Private name \"#foo\" must be declared in an enclosing class\n")
  6022  	expectParseError(t, "class Foo { #foo } class Bar { foo = #foo in this }",
  6023  		"<stdin>: ERROR: Private name \"#foo\" must be declared in an enclosing class\n")
  6024  
  6025  	// Getter and setter warnings
  6026  	expectParseError(t, "class Foo { get #x() { this.#x = 1 } }",
  6027  		"<stdin>: WARNING: Writing to getter-only property \"#x\" will throw\n")
  6028  	expectParseError(t, "class Foo { get #x() { this.#x += 1 } }",
  6029  		"<stdin>: WARNING: Writing to getter-only property \"#x\" will throw\n")
  6030  	expectParseError(t, "class Foo { set #x(x) { this.#x } }",
  6031  		"<stdin>: WARNING: Reading from setter-only property \"#x\" will throw\n")
  6032  	expectParseError(t, "class Foo { set #x(x) { this.#x += 1 } }",
  6033  		"<stdin>: WARNING: Reading from setter-only property \"#x\" will throw\n")
  6034  
  6035  	// Writing to method warnings
  6036  	expectParseError(t, "class Foo { #x() { this.#x = 1 } }",
  6037  		"<stdin>: WARNING: Writing to read-only method \"#x\" will throw\n")
  6038  	expectParseError(t, "class Foo { #x() { this.#x += 1 } }",
  6039  		"<stdin>: WARNING: Writing to read-only method \"#x\" will throw\n")
  6040  
  6041  	expectPrinted(t, `class Foo {
  6042  	#if
  6043  	#im() { return this.#im(this.#if) }
  6044  	static #sf
  6045  	static #sm() { return this.#sm(this.#sf) }
  6046  	foo() {
  6047  		return class {
  6048  			#inner() {
  6049  				return [this.#im, this?.#inner, this?.x.#if]
  6050  			}
  6051  		}
  6052  	}
  6053  }
  6054  `, `class Foo {
  6055    #if;
  6056    #im() {
  6057      return this.#im(this.#if);
  6058    }
  6059    static #sf;
  6060    static #sm() {
  6061      return this.#sm(this.#sf);
  6062    }
  6063    foo() {
  6064      return class {
  6065        #inner() {
  6066          return [this.#im, this?.#inner, this?.x.#if];
  6067        }
  6068      };
  6069    }
  6070  }
  6071  `)
  6072  }
  6073  
  6074  func TestImportAssertions(t *testing.T) {
  6075  	expectPrinted(t, "import 'x' assert {}", "import \"x\" assert {};\n")
  6076  	expectPrinted(t, "import 'x' assert {\n}", "import \"x\" assert {};\n")
  6077  	expectPrinted(t, "import 'x' assert\n{}", "import \"x\" assert {};\n")
  6078  	expectPrinted(t, "import 'x'\nassert\n{}", "import \"x\";\nassert;\n{\n}\n")
  6079  	expectPrinted(t, "import 'x' assert {type: 'json'}", "import \"x\" assert { type: \"json\" };\n")
  6080  	expectPrinted(t, "import 'x' assert {type: 'json',}", "import \"x\" assert { type: \"json\" };\n")
  6081  	expectPrinted(t, "import 'x' assert {'type': 'json'}", "import \"x\" assert { \"type\": \"json\" };\n")
  6082  	expectPrinted(t, "import 'x' assert {a: 'b', c: 'd'}", "import \"x\" assert { a: \"b\", c: \"d\" };\n")
  6083  	expectPrinted(t, "import 'x' assert {a: 'b', c: 'd',}", "import \"x\" assert { a: \"b\", c: \"d\" };\n")
  6084  	expectPrinted(t, "import 'x' assert {if: 'keyword'}", "import \"x\" assert { if: \"keyword\" };\n")
  6085  	expectPrintedMangle(t, "import 'x' assert {'type': 'json'}", "import \"x\" assert { type: \"json\" };\n")
  6086  	expectPrintedMangle(t, "import 'x' assert {'ty pe': 'json'}", "import \"x\" assert { \"ty pe\": \"json\" };\n")
  6087  
  6088  	expectParseError(t, "import 'x' assert {,}", "<stdin>: ERROR: Expected identifier but found \",\"\n")
  6089  	expectParseError(t, "import 'x' assert {x}", "<stdin>: ERROR: Expected \":\" but found \"}\"\n")
  6090  	expectParseError(t, "import 'x' assert {x 'y'}", "<stdin>: ERROR: Expected \":\" but found \"'y'\"\n")
  6091  	expectParseError(t, "import 'x' assert {x: y}", "<stdin>: ERROR: Expected string but found \"y\"\n")
  6092  	expectParseError(t, "import 'x' assert {x: 'y',,}", "<stdin>: ERROR: Expected identifier but found \",\"\n")
  6093  	expectParseError(t, "import 'x' assert {`x`: 'y'}", "<stdin>: ERROR: Expected identifier but found \"`x`\"\n")
  6094  	expectParseError(t, "import 'x' assert {x: `y`}", "<stdin>: ERROR: Expected string but found \"`y`\"\n")
  6095  	expectParseError(t, "import 'x' assert: {x: 'y'}", "<stdin>: ERROR: Expected \"{\" but found \":\"\n")
  6096  
  6097  	expectParseError(t, "import 'x' assert {x: 'y', x: 'y'}",
  6098  		"<stdin>: ERROR: Duplicate import assertion \"x\"\n<stdin>: NOTE: The first \"x\" was here:\n")
  6099  	expectParseError(t, "import 'x' assert {x: 'y', \\u0078: 'y'}",
  6100  		"<stdin>: ERROR: Duplicate import assertion \"x\"\n<stdin>: NOTE: The first \"x\" was here:\n")
  6101  
  6102  	expectPrinted(t, "import x from 'x' assert {x: 'y'}", "import x from \"x\" assert { x: \"y\" };\n")
  6103  	expectPrinted(t, "import * as x from 'x' assert {x: 'y'}", "import * as x from \"x\" assert { x: \"y\" };\n")
  6104  	expectPrinted(t, "import {} from 'x' assert {x: 'y'}", "import {} from \"x\" assert { x: \"y\" };\n")
  6105  	expectPrinted(t, "export {} from 'x' assert {x: 'y'}", "export {} from \"x\" assert { x: \"y\" };\n")
  6106  	expectPrinted(t, "export * from 'x' assert {x: 'y'}", "export * from \"x\" assert { x: \"y\" };\n")
  6107  
  6108  	expectPrinted(t, "import(x ? 'y' : 'z')", "x ? import(\"y\") : import(\"z\");\n")
  6109  	expectPrinted(t, "import(x ? 'y' : 'z', {assert: {}})",
  6110  		"x ? import(\"y\", { assert: {} }) : import(\"z\", { assert: {} });\n")
  6111  	expectPrinted(t, "import(x ? 'y' : 'z', {assert: {a: 'b'}})",
  6112  		"x ? import(\"y\", { assert: { a: \"b\" } }) : import(\"z\", { assert: { a: \"b\" } });\n")
  6113  	expectPrinted(t, "import(x ? 'y' : 'z', {assert: {'a': 'b'}})",
  6114  		"x ? import(\"y\", { assert: { \"a\": \"b\" } }) : import(\"z\", { assert: { \"a\": \"b\" } });\n")
  6115  	expectPrintedMangle(t, "import(x ? 'y' : 'z', {assert: {'a': 'b'}})",
  6116  		"x ? import(\"y\", { assert: { a: \"b\" } }) : import(\"z\", { assert: { a: \"b\" } });\n")
  6117  	expectPrintedMangle(t, "import(x ? 'y' : 'z', {assert: {'a a': 'b'}})",
  6118  		"x ? import(\"y\", { assert: { \"a a\": \"b\" } }) : import(\"z\", { assert: { \"a a\": \"b\" } });\n")
  6119  
  6120  	expectPrinted(t, "import(x ? 'y' : 'z', {})", "import(x ? \"y\" : \"z\", {});\n")
  6121  	expectPrinted(t, "import(x ? 'y' : 'z', {assert: []})", "import(x ? \"y\" : \"z\", { assert: [] });\n")
  6122  	expectPrinted(t, "import(x ? 'y' : 'z', {asserts: {}})", "import(x ? \"y\" : \"z\", { asserts: {} });\n")
  6123  	expectPrinted(t, "import(x ? 'y' : 'z', {assert: {x: 1}})", "import(x ? \"y\" : \"z\", { assert: { x: 1 } });\n")
  6124  
  6125  	expectPrintedTarget(t, 2015, "import 'x' assert {x: 'y'}", "import \"x\";\n")
  6126  	expectPrintedTarget(t, 2015, "import(x, {assert: {x: 'y'}})", "import(x);\n")
  6127  	expectPrintedTarget(t, 2015, "import(x, {assert: {x: 1}})", "import(x);\n")
  6128  	expectPrintedTarget(t, 2015, "import(x ? 'y' : 'z', {assert: {x: 'y'}})", "x ? import(\"y\") : import(\"z\");\n")
  6129  	expectPrintedTarget(t, 2015, "import(x ? 'y' : 'z', {assert: {x: 1}})", "import(x ? \"y\" : \"z\");\n")
  6130  	expectParseErrorTarget(t, 2015, "import(x ? 'y' : 'z', {assert: {x: foo()}})",
  6131  		"<stdin>: ERROR: Using an arbitrary value as the second argument to \"import()\" is not possible in the configured target environment\n")
  6132  
  6133  	// Make sure there are no errors when bundling is disabled
  6134  	expectParseError(t, "import { foo } from 'x' assert {type: 'json'}", "")
  6135  	expectParseError(t, "export { foo } from 'x' assert {type: 'json'}", "")
  6136  
  6137  	// Only omit the second argument to "import()" if both assertions and attributes aren't supported
  6138  	expectPrintedWithUnsupportedFeatures(t, compat.ImportAssertions,
  6139  		"import 'x' assert {y: 'z'}; import('x', {assert: {y: 'z'}})",
  6140  		"import \"x\";\nimport(\"x\", { assert: { y: \"z\" } });\n")
  6141  	expectPrintedWithUnsupportedFeatures(t, compat.ImportAttributes,
  6142  		"import 'x' assert {y: 'z'}; import('x', {assert: {y: 'z'}})",
  6143  		"import \"x\" assert { y: \"z\" };\nimport(\"x\", { assert: { y: \"z\" } });\n")
  6144  	expectPrintedWithUnsupportedFeatures(t, compat.ImportAssertions|compat.ImportAttributes,
  6145  		"import 'x' assert {y: 'z'}; import('x', {assert: {y: 'z'}})",
  6146  		"import \"x\";\nimport(\"x\");\n")
  6147  }
  6148  
  6149  func TestImportAttributes(t *testing.T) {
  6150  	expectPrinted(t, "import 'x' with {}", "import \"x\" with {};\n")
  6151  	expectPrinted(t, "import 'x' with {\n}", "import \"x\" with {};\n")
  6152  	expectPrinted(t, "import 'x' with\n{}", "import \"x\" with {};\n")
  6153  	expectPrinted(t, "import 'x'\nwith\n{}", "import \"x\" with {};\n")
  6154  	expectPrinted(t, "import 'x' with {type: 'json'}", "import \"x\" with { type: \"json\" };\n")
  6155  	expectPrinted(t, "import 'x' with {type: 'json',}", "import \"x\" with { type: \"json\" };\n")
  6156  	expectPrinted(t, "import 'x' with {'type': 'json'}", "import \"x\" with { \"type\": \"json\" };\n")
  6157  	expectPrinted(t, "import 'x' with {a: 'b', c: 'd'}", "import \"x\" with { a: \"b\", c: \"d\" };\n")
  6158  	expectPrinted(t, "import 'x' with {a: 'b', c: 'd',}", "import \"x\" with { a: \"b\", c: \"d\" };\n")
  6159  	expectPrinted(t, "import 'x' with {if: 'keyword'}", "import \"x\" with { if: \"keyword\" };\n")
  6160  	expectPrintedMangle(t, "import 'x' with {'type': 'json'}", "import \"x\" with { type: \"json\" };\n")
  6161  	expectPrintedMangle(t, "import 'x' with {'ty pe': 'json'}", "import \"x\" with { \"ty pe\": \"json\" };\n")
  6162  
  6163  	expectParseError(t, "import 'x' with {,}", "<stdin>: ERROR: Expected identifier but found \",\"\n")
  6164  	expectParseError(t, "import 'x' with {x}", "<stdin>: ERROR: Expected \":\" but found \"}\"\n")
  6165  	expectParseError(t, "import 'x' with {x 'y'}", "<stdin>: ERROR: Expected \":\" but found \"'y'\"\n")
  6166  	expectParseError(t, "import 'x' with {x: y}", "<stdin>: ERROR: Expected string but found \"y\"\n")
  6167  	expectParseError(t, "import 'x' with {x: 'y',,}", "<stdin>: ERROR: Expected identifier but found \",\"\n")
  6168  	expectParseError(t, "import 'x' with {`x`: 'y'}", "<stdin>: ERROR: Expected identifier but found \"`x`\"\n")
  6169  	expectParseError(t, "import 'x' with {x: `y`}", "<stdin>: ERROR: Expected string but found \"`y`\"\n")
  6170  	expectParseError(t, "import 'x' with: {x: 'y'}", "<stdin>: ERROR: Expected \"{\" but found \":\"\n")
  6171  
  6172  	expectParseError(t, "import 'x' with {x: 'y', x: 'y'}",
  6173  		"<stdin>: ERROR: Duplicate import attribute \"x\"\n<stdin>: NOTE: The first \"x\" was here:\n")
  6174  	expectParseError(t, "import 'x' with {x: 'y', \\u0078: 'y'}",
  6175  		"<stdin>: ERROR: Duplicate import attribute \"x\"\n<stdin>: NOTE: The first \"x\" was here:\n")
  6176  
  6177  	expectPrinted(t, "import x from 'x' with {x: 'y'}", "import x from \"x\" with { x: \"y\" };\n")
  6178  	expectPrinted(t, "import * as x from 'x' with {x: 'y'}", "import * as x from \"x\" with { x: \"y\" };\n")
  6179  	expectPrinted(t, "import {} from 'x' with {x: 'y'}", "import {} from \"x\" with { x: \"y\" };\n")
  6180  	expectPrinted(t, "export {} from 'x' with {x: 'y'}", "export {} from \"x\" with { x: \"y\" };\n")
  6181  	expectPrinted(t, "export * from 'x' with {x: 'y'}", "export * from \"x\" with { x: \"y\" };\n")
  6182  
  6183  	expectPrinted(t, "import(x ? 'y' : 'z')", "x ? import(\"y\") : import(\"z\");\n")
  6184  	expectPrinted(t, "import(x ? 'y' : 'z', {with: {}})",
  6185  		"x ? import(\"y\", { with: {} }) : import(\"z\", { with: {} });\n")
  6186  	expectPrinted(t, "import(x ? 'y' : 'z', {with: {a: 'b'}})",
  6187  		"x ? import(\"y\", { with: { a: \"b\" } }) : import(\"z\", { with: { a: \"b\" } });\n")
  6188  	expectPrinted(t, "import(x ? 'y' : 'z', {with: {'a': 'b'}})",
  6189  		"x ? import(\"y\", { with: { \"a\": \"b\" } }) : import(\"z\", { with: { \"a\": \"b\" } });\n")
  6190  	expectPrintedMangle(t, "import(x ? 'y' : 'z', {with: {'a': 'b'}})",
  6191  		"x ? import(\"y\", { with: { a: \"b\" } }) : import(\"z\", { with: { a: \"b\" } });\n")
  6192  	expectPrintedMangle(t, "import(x ? 'y' : 'z', {with: {'a a': 'b'}})",
  6193  		"x ? import(\"y\", { with: { \"a a\": \"b\" } }) : import(\"z\", { with: { \"a a\": \"b\" } });\n")
  6194  
  6195  	expectPrinted(t, "import(x ? 'y' : 'z', {})", "import(x ? \"y\" : \"z\", {});\n")
  6196  	expectPrinted(t, "import(x ? 'y' : 'z', {with: []})", "import(x ? \"y\" : \"z\", { with: [] });\n")
  6197  	expectPrinted(t, "import(x ? 'y' : 'z', {whithe: {}})", "import(x ? \"y\" : \"z\", { whithe: {} });\n")
  6198  	expectPrinted(t, "import(x ? 'y' : 'z', {with: {x: 1}})", "import(x ? \"y\" : \"z\", { with: { x: 1 } });\n")
  6199  
  6200  	expectPrintedTarget(t, 2015, "import 'x' with {x: 'y'}", "import \"x\";\n")
  6201  	expectPrintedTarget(t, 2015, "import(x, {with: {x: 'y'}})", "import(x);\n")
  6202  	expectPrintedTarget(t, 2015, "import(x, {with: {x: 1}})", "import(x);\n")
  6203  	expectPrintedTarget(t, 2015, "import(x ? 'y' : 'z', {with: {x: 'y'}})", "x ? import(\"y\") : import(\"z\");\n")
  6204  	expectPrintedTarget(t, 2015, "import(x ? 'y' : 'z', {with: {x: 1}})", "import(x ? \"y\" : \"z\");\n")
  6205  	expectParseErrorTarget(t, 2015, "import(x ? 'y' : 'z', {with: {x: foo()}})",
  6206  		"<stdin>: ERROR: Using an arbitrary value as the second argument to \"import()\" is not possible in the configured target environment\n")
  6207  
  6208  	// Make sure there are no errors when bundling is disabled
  6209  	expectParseError(t, "import { foo } from 'x' with {type: 'json'}", "")
  6210  	expectParseError(t, "export { foo } from 'x' with {type: 'json'}", "")
  6211  
  6212  	// Only omit the second argument to "import()" if both assertions and attributes aren't supported
  6213  	expectPrintedWithUnsupportedFeatures(t, compat.ImportAssertions,
  6214  		"import 'x' with {y: 'z'}; import('x', {with: {y: 'z'}})",
  6215  		"import \"x\" with { y: \"z\" };\nimport(\"x\", { with: { y: \"z\" } });\n")
  6216  	expectPrintedWithUnsupportedFeatures(t, compat.ImportAttributes,
  6217  		"import 'x' with {y: 'z'}; import('x', {with: {y: 'z'}})",
  6218  		"import \"x\";\nimport(\"x\", { with: { y: \"z\" } });\n")
  6219  	expectPrintedWithUnsupportedFeatures(t, compat.ImportAssertions|compat.ImportAttributes,
  6220  		"import 'x' with {y: 'z'}; import('x', {with: {y: 'z'}})",
  6221  		"import \"x\";\nimport(\"x\");\n")
  6222  
  6223  	// Test the migration warning
  6224  	expectParseErrorWithUnsupportedFeatures(t, compat.ImportAssertions,
  6225  		"import x from 'y' assert {type: 'json'}",
  6226  		"<stdin>: WARNING: The \"assert\" keyword is not supported in the configured target environment\nNOTE: Did you mean to use \"with\" instead of \"assert\"?\n")
  6227  	expectParseErrorWithUnsupportedFeatures(t, compat.ImportAssertions,
  6228  		"export {default} from 'y' assert {type: 'json'}",
  6229  		"<stdin>: WARNING: The \"assert\" keyword is not supported in the configured target environment\nNOTE: Did you mean to use \"with\" instead of \"assert\"?\n")
  6230  	expectParseErrorWithUnsupportedFeatures(t, compat.ImportAssertions,
  6231  		"import('y', {assert: {type: 'json'}})",
  6232  		"<stdin>: WARNING: The \"assert\" keyword is not supported in the configured target environment\nNOTE: Did you mean to use \"with\" instead of \"assert\"?\n")
  6233  }
  6234  
  6235  func TestES5(t *testing.T) {
  6236  	// Do not generate "let" when emulating block-level function declarations and targeting ES5
  6237  	expectPrintedTarget(t, 2015, "if (1) function f() {}", "if (1) {\n  let f = function() {\n  };\n  var f = f;\n}\n")
  6238  	expectPrintedTarget(t, 5, "if (1) function f() {}", "if (1) {\n  var f = function() {\n  };\n  var f = f;\n}\n")
  6239  
  6240  	expectParseErrorTarget(t, 5, "function foo(x = 0) {}",
  6241  		"<stdin>: ERROR: Transforming default arguments to the configured target environment is not supported yet\n")
  6242  	expectParseErrorTarget(t, 5, "(function(x = 0) {})",
  6243  		"<stdin>: ERROR: Transforming default arguments to the configured target environment is not supported yet\n")
  6244  	expectParseErrorTarget(t, 5, "(x = 0) => {}",
  6245  		"<stdin>: ERROR: Transforming default arguments to the configured target environment is not supported yet\n")
  6246  	expectParseErrorTarget(t, 5, "function foo(...x) {}",
  6247  		"<stdin>: ERROR: Transforming rest arguments to the configured target environment is not supported yet\n")
  6248  	expectParseErrorTarget(t, 5, "(function(...x) {})",
  6249  		"<stdin>: ERROR: Transforming rest arguments to the configured target environment is not supported yet\n")
  6250  	expectParseErrorTarget(t, 5, "(...x) => {}",
  6251  		"<stdin>: ERROR: Transforming rest arguments to the configured target environment is not supported yet\n")
  6252  	expectParseErrorTarget(t, 5, "foo(...x)",
  6253  		"<stdin>: ERROR: Transforming rest arguments to the configured target environment is not supported yet\n")
  6254  	expectParseErrorTarget(t, 5, "[...x]",
  6255  		"<stdin>: ERROR: Transforming array spread to the configured target environment is not supported yet\n")
  6256  	expectParseErrorTarget(t, 5, "for (var x of y) ;",
  6257  		"<stdin>: ERROR: Transforming for-of loops to the configured target environment is not supported yet\n")
  6258  	expectPrintedTarget(t, 5, "({ x })", "({ x: x });\n")
  6259  	expectParseErrorTarget(t, 5, "({ [x]: y })",
  6260  		"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\n")
  6261  	expectParseErrorTarget(t, 5, "({ x() {} });",
  6262  		"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\n")
  6263  	expectParseErrorTarget(t, 5, "({ get x() {} });", "")
  6264  	expectParseErrorTarget(t, 5, "({ set x(x) {} });", "")
  6265  	expectParseErrorTarget(t, 5, "({ get [x]() {} });",
  6266  		"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\n")
  6267  	expectParseErrorTarget(t, 5, "({ set [x](x) {} });",
  6268  		"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\n")
  6269  	expectParseErrorTarget(t, 5, "function foo([]) {}",
  6270  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6271  	expectParseErrorTarget(t, 5, "function foo({}) {}",
  6272  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6273  	expectParseErrorTarget(t, 5, "(function([]) {})",
  6274  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6275  	expectParseErrorTarget(t, 5, "(function({}) {})",
  6276  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6277  	expectParseErrorTarget(t, 5, "([]) => {}",
  6278  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6279  	expectParseErrorTarget(t, 5, "({}) => {}",
  6280  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6281  	expectParseErrorTarget(t, 5, "var [] = [];",
  6282  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6283  	expectParseErrorTarget(t, 5, "var {} = {};",
  6284  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6285  	expectParseErrorTarget(t, 5, "([] = []);",
  6286  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6287  	expectParseErrorTarget(t, 5, "({} = {});",
  6288  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6289  	expectParseErrorTarget(t, 5, "for ([] in []);",
  6290  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6291  	expectParseErrorTarget(t, 5, "for ({} in []);",
  6292  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6293  	expectParseErrorTarget(t, 5, "function foo([...x]) {}",
  6294  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6295  	expectParseErrorTarget(t, 5, "(function([...x]) {})",
  6296  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6297  	expectParseErrorTarget(t, 5, "([...x]) => {}",
  6298  		"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n")
  6299  	expectParseErrorTarget(t, 5, "function foo([...[x]]) {}",
  6300  		`<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet
  6301  <stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet
  6302  <stdin>: ERROR: Transforming non-identifier array rest patterns to the configured target environment is not supported yet
  6303  `)
  6304  	expectParseErrorTarget(t, 5, "(function([...[x]]) {})",
  6305  		`<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet
  6306  <stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet
  6307  <stdin>: ERROR: Transforming non-identifier array rest patterns to the configured target environment is not supported yet
  6308  `)
  6309  	expectParseErrorTarget(t, 5, "([...[x]]) => {}",
  6310  		`<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet
  6311  <stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet
  6312  <stdin>: ERROR: Transforming non-identifier array rest patterns to the configured target environment is not supported yet
  6313  `)
  6314  	expectParseErrorTarget(t, 5, "([...[x]])",
  6315  		"<stdin>: ERROR: Transforming array spread to the configured target environment is not supported yet\n")
  6316  	expectPrintedTarget(t, 5, "`abc`;", "\"abc\";\n")
  6317  	expectPrintedTarget(t, 5, "`a${b}`;", "\"a\".concat(b);\n")
  6318  	expectPrintedTarget(t, 5, "`${a}b`;", "\"\".concat(a, \"b\");\n")
  6319  	expectPrintedTarget(t, 5, "`${a}${b}`;", "\"\".concat(a).concat(b);\n")
  6320  	expectPrintedTarget(t, 5, "`a${b}c`;", "\"a\".concat(b, \"c\");\n")
  6321  	expectPrintedTarget(t, 5, "`a${b}${c}`;", "\"a\".concat(b).concat(c);\n")
  6322  	expectPrintedTarget(t, 5, "`a${b}${c}d`;", "\"a\".concat(b).concat(c, \"d\");\n")
  6323  	expectPrintedTarget(t, 5, "`a${b}c${d}`;", "\"a\".concat(b, \"c\").concat(d);\n")
  6324  	expectPrintedTarget(t, 5, "`a${b}c${d}e`;", "\"a\".concat(b, \"c\").concat(d, \"e\");\n")
  6325  	expectPrintedTarget(t, 5, "tag``;", "var _a;\ntag(_a || (_a = __template([\"\"])));\n")
  6326  	expectPrintedTarget(t, 5, "tag`abc`;", "var _a;\ntag(_a || (_a = __template([\"abc\"])));\n")
  6327  	expectPrintedTarget(t, 5, "tag`\\utf`;", "var _a;\ntag(_a || (_a = __template([void 0], [\"\\\\utf\"])));\n")
  6328  	expectPrintedTarget(t, 5, "tag`${a}b`;", "var _a;\ntag(_a || (_a = __template([\"\", \"b\"])), a);\n")
  6329  	expectPrintedTarget(t, 5, "tag`a${b}`;", "var _a;\ntag(_a || (_a = __template([\"a\", \"\"])), b);\n")
  6330  	expectPrintedTarget(t, 5, "tag`a${b}c`;", "var _a;\ntag(_a || (_a = __template([\"a\", \"c\"])), b);\n")
  6331  	expectPrintedTarget(t, 5, "tag`a${b}\\u`;", "var _a;\ntag(_a || (_a = __template([\"a\", void 0], [\"a\", \"\\\\u\"])), b);\n")
  6332  	expectPrintedTarget(t, 5, "tag`\\u${b}c`;", "var _a;\ntag(_a || (_a = __template([void 0, \"c\"], [\"\\\\u\", \"c\"])), b);\n")
  6333  	expectParseErrorTarget(t, 5, "class Foo { constructor() { new.target } }",
  6334  		"<stdin>: ERROR: Transforming class syntax to the configured target environment is not supported yet\n"+
  6335  			"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\n"+
  6336  			"<stdin>: ERROR: Transforming new.target to the configured target environment is not supported yet\n")
  6337  	expectParseErrorTarget(t, 5, "const x = 1;",
  6338  		"<stdin>: ERROR: Transforming const to the configured target environment is not supported yet\n")
  6339  	expectParseErrorTarget(t, 5, "let x = 2;",
  6340  		"<stdin>: ERROR: Transforming let to the configured target environment is not supported yet\n")
  6341  	expectPrintedTarget(t, 5, "async => foo;", "(function(async) {\n  return foo;\n});\n")
  6342  	expectPrintedTarget(t, 5, "x => x;", "(function(x) {\n  return x;\n});\n")
  6343  	expectParseErrorTarget(t, 5, "async () => foo;",
  6344  		"<stdin>: ERROR: Transforming async functions to the configured target environment is not supported yet\n")
  6345  	expectParseErrorTarget(t, 5, "class Foo {}",
  6346  		"<stdin>: ERROR: Transforming class syntax to the configured target environment is not supported yet\n")
  6347  	expectParseErrorTarget(t, 5, "(class {});",
  6348  		"<stdin>: ERROR: Transforming class syntax to the configured target environment is not supported yet\n")
  6349  	expectParseErrorTarget(t, 5, "function* gen() {}",
  6350  		"<stdin>: ERROR: Transforming generator functions to the configured target environment is not supported yet\n")
  6351  	expectParseErrorTarget(t, 5, "(function* () {});",
  6352  		"<stdin>: ERROR: Transforming generator functions to the configured target environment is not supported yet\n")
  6353  	expectParseErrorTarget(t, 5, "({ *foo() {} });",
  6354  		"<stdin>: ERROR: Transforming generator functions to the configured target environment is not supported yet\n")
  6355  }
  6356  
  6357  func TestASCIIOnly(t *testing.T) {
  6358  	es5 := "<stdin>: ERROR: \"𐀀\" cannot be escaped in the configured target environment " +
  6359  		"but you can set the charset to \"utf8\" to allow unescaped Unicode characters\n"
  6360  
  6361  	// Some context: "Ļ€" is in the BMP (i.e. has a code point ≤0xFFFF) and "𐀀" is
  6362  	// not in the BMP (i.e. has a code point >0xFFFF). This distinction matters
  6363  	// because it's impossible to escape non-BMP characters before ES6.
  6364  
  6365  	expectPrinted(t, "Ļ€", "Ļ€;\n")
  6366  	expectPrinted(t, "𐀀", "𐀀;\n")
  6367  	expectPrintedASCII(t, "Ļ€", "\\u03C0;\n")
  6368  	expectPrintedASCII(t, "𐀀", "\\u{10000};\n")
  6369  	expectPrintedTargetASCII(t, 5, "Ļ€", "\\u03C0;\n")
  6370  	expectParseErrorTargetASCII(t, 5, "𐀀", es5)
  6371  
  6372  	expectPrinted(t, "var π", "var π;\n")
  6373  	expectPrinted(t, "var 𐀀", "var 𐀀;\n")
  6374  	expectPrintedASCII(t, "var π", "var \\u03C0;\n")
  6375  	expectPrintedASCII(t, "var 𐀀", "var \\u{10000};\n")
  6376  	expectPrintedTargetASCII(t, 5, "var π", "var \\u03C0;\n")
  6377  	expectParseErrorTargetASCII(t, 5, "var 𐀀", es5)
  6378  
  6379  	expectPrinted(t, "'Ļ€'", "\"Ļ€\";\n")
  6380  	expectPrinted(t, "'𐀀'", "\"𐀀\";\n")
  6381  	expectPrintedASCII(t, "'Ļ€'", "\"\\u03C0\";\n")
  6382  	expectPrintedASCII(t, "'𐀀'", "\"\\u{10000}\";\n")
  6383  	expectPrintedTargetASCII(t, 5, "'Ļ€'", "\"\\u03C0\";\n")
  6384  	expectPrintedTargetASCII(t, 5, "'𐀀'", "\"\\uD800\\uDC00\";\n")
  6385  
  6386  	expectPrinted(t, "x.Ļ€", "x.Ļ€;\n")
  6387  	expectPrinted(t, "x.𐀀", "x[\"𐀀\"];\n")
  6388  	expectPrintedASCII(t, "x.Ļ€", "x.\\u03C0;\n")
  6389  	expectPrintedASCII(t, "x.𐀀", "x[\"\\u{10000}\"];\n")
  6390  	expectPrintedTargetASCII(t, 5, "x.Ļ€", "x.\\u03C0;\n")
  6391  	expectPrintedTargetASCII(t, 5, "x.𐀀", "x[\"\\uD800\\uDC00\"];\n")
  6392  
  6393  	expectPrinted(t, "x?.Ļ€", "x?.Ļ€;\n")
  6394  	expectPrinted(t, "x?.𐀀", "x?.[\"𐀀\"];\n")
  6395  	expectPrintedASCII(t, "x?.Ļ€", "x?.\\u03C0;\n")
  6396  	expectPrintedASCII(t, "x?.𐀀", "x?.[\"\\u{10000}\"];\n")
  6397  	expectPrintedTargetASCII(t, 5, "x?.Ļ€", "x == null ? void 0 : x.\\u03C0;\n")
  6398  	expectPrintedTargetASCII(t, 5, "x?.𐀀", "x == null ? void 0 : x[\"\\uD800\\uDC00\"];\n")
  6399  
  6400  	expectPrinted(t, "0 .Ļ€", "0 .Ļ€;\n")
  6401  	expectPrinted(t, "0 .𐀀", "0[\"𐀀\"];\n")
  6402  	expectPrintedASCII(t, "0 .Ļ€", "0 .\\u03C0;\n")
  6403  	expectPrintedASCII(t, "0 .𐀀", "0[\"\\u{10000}\"];\n")
  6404  	expectPrintedTargetASCII(t, 5, "0 .Ļ€", "0 .\\u03C0;\n")
  6405  	expectPrintedTargetASCII(t, 5, "0 .𐀀", "0[\"\\uD800\\uDC00\"];\n")
  6406  
  6407  	expectPrinted(t, "0?.Ļ€", "0?.Ļ€;\n")
  6408  	expectPrinted(t, "0?.𐀀", "0?.[\"𐀀\"];\n")
  6409  	expectPrintedASCII(t, "0?.Ļ€", "0?.\\u03C0;\n")
  6410  	expectPrintedASCII(t, "0?.𐀀", "0?.[\"\\u{10000}\"];\n")
  6411  	expectPrintedTargetASCII(t, 5, "0?.Ļ€", "0 == null ? void 0 : 0 .\\u03C0;\n")
  6412  	expectPrintedTargetASCII(t, 5, "0?.𐀀", "0 == null ? void 0 : 0[\"\\uD800\\uDC00\"];\n")
  6413  
  6414  	expectPrinted(t, "import 'Ļ€'", "import \"Ļ€\";\n")
  6415  	expectPrinted(t, "import '𐀀'", "import \"𐀀\";\n")
  6416  	expectPrintedASCII(t, "import 'Ļ€'", "import \"\\u03C0\";\n")
  6417  	expectPrintedASCII(t, "import '𐀀'", "import \"\\u{10000}\";\n")
  6418  	expectPrintedTargetASCII(t, 5, "import 'Ļ€'", "import \"\\u03C0\";\n")
  6419  	expectPrintedTargetASCII(t, 5, "import '𐀀'", "import \"\\uD800\\uDC00\";\n")
  6420  
  6421  	expectPrinted(t, "({π: 0})", "({ π: 0 });\n")
  6422  	expectPrinted(t, "({𐀀: 0})", "({ \"𐀀\": 0 });\n")
  6423  	expectPrintedASCII(t, "({Ļ€: 0})", "({ \\u03C0: 0 });\n")
  6424  	expectPrintedASCII(t, "({𐀀: 0})", "({ \"\\u{10000}\": 0 });\n")
  6425  	expectPrintedTargetASCII(t, 5, "({Ļ€: 0})", "({ \\u03C0: 0 });\n")
  6426  	expectPrintedTargetASCII(t, 5, "({𐀀: 0})", "({ \"\\uD800\\uDC00\": 0 });\n")
  6427  
  6428  	expectPrinted(t, "({π})", "({ π });\n")
  6429  	expectPrinted(t, "({𐀀})", "({ \"𐀀\": 𐀀 });\n")
  6430  	expectPrintedASCII(t, "({Ļ€})", "({ \\u03C0 });\n")
  6431  	expectPrintedASCII(t, "({𐀀})", "({ \"\\u{10000}\": \\u{10000} });\n")
  6432  	expectPrintedTargetASCII(t, 5, "({Ļ€})", "({ \\u03C0: \\u03C0 });\n")
  6433  	expectParseErrorTargetASCII(t, 5, "({𐀀})", es5)
  6434  
  6435  	expectPrinted(t, "import * as π from 'path'; π", "import * as π from \"path\";\nπ;\n")
  6436  	expectPrinted(t, "import * as 𐀀 from 'path'; 𐀀", "import * as 𐀀 from \"path\";\n𐀀;\n")
  6437  	expectPrintedASCII(t, "import * as π from 'path'; π", "import * as \\u03C0 from \"path\";\n\\u03C0;\n")
  6438  	expectPrintedASCII(t, "import * as 𐀀 from 'path'; 𐀀", "import * as \\u{10000} from \"path\";\n\\u{10000};\n")
  6439  	expectPrintedTargetASCII(t, 5, "import * as π from 'path'; π", "import * as \\u03C0 from \"path\";\n\\u03C0;\n")
  6440  	expectParseErrorTargetASCII(t, 5, "import * as 𐀀 from 'path'", es5)
  6441  
  6442  	expectPrinted(t, "import {π} from 'path'; π", "import { π } from \"path\";\nπ;\n")
  6443  	expectPrinted(t, "import {𐀀} from 'path'; 𐀀", "import { 𐀀 } from \"path\";\n𐀀;\n")
  6444  	expectPrintedASCII(t, "import {π} from 'path'; π", "import { \\u03C0 } from \"path\";\n\\u03C0;\n")
  6445  	expectPrintedASCII(t, "import {𐀀} from 'path'; 𐀀", "import { \\u{10000} } from \"path\";\n\\u{10000};\n")
  6446  	expectPrintedTargetASCII(t, 5, "import {π} from 'path'; π", "import { \\u03C0 } from \"path\";\n\\u03C0;\n")
  6447  	expectParseErrorTargetASCII(t, 5, "import {𐀀} from 'path'", es5)
  6448  
  6449  	expectPrinted(t, "import {π as x} from 'path'", "import { π as x } from \"path\";\n")
  6450  	expectPrinted(t, "import {𐀀 as x} from 'path'", "import { 𐀀 as x } from \"path\";\n")
  6451  	expectPrintedASCII(t, "import {Ļ€ as x} from 'path'", "import { \\u03C0 as x } from \"path\";\n")
  6452  	expectPrintedASCII(t, "import {𐀀 as x} from 'path'", "import { \\u{10000} as x } from \"path\";\n")
  6453  	expectPrintedTargetASCII(t, 5, "import {Ļ€ as x} from 'path'", "import { \\u03C0 as x } from \"path\";\n")
  6454  	expectParseErrorTargetASCII(t, 5, "import {𐀀 as x} from 'path'", es5)
  6455  
  6456  	expectPrinted(t, "import {x as π} from 'path'", "import { x as π } from \"path\";\n")
  6457  	expectPrinted(t, "import {x as 𐀀} from 'path'", "import { x as 𐀀 } from \"path\";\n")
  6458  	expectPrintedASCII(t, "import {x as π} from 'path'", "import { x as \\u03C0 } from \"path\";\n")
  6459  	expectPrintedASCII(t, "import {x as 𐀀} from 'path'", "import { x as \\u{10000} } from \"path\";\n")
  6460  	expectPrintedTargetASCII(t, 5, "import {x as π} from 'path'", "import { x as \\u03C0 } from \"path\";\n")
  6461  	expectParseErrorTargetASCII(t, 5, "import {x as 𐀀} from 'path'", es5)
  6462  
  6463  	expectPrinted(t, "export * as π from 'path'; π", "export * as π from \"path\";\nπ;\n")
  6464  	expectPrinted(t, "export * as 𐀀 from 'path'; 𐀀", "export * as 𐀀 from \"path\";\n𐀀;\n")
  6465  	expectPrintedASCII(t, "export * as π from 'path'; π", "export * as \\u03C0 from \"path\";\n\\u03C0;\n")
  6466  	expectPrintedASCII(t, "export * as 𐀀 from 'path'; 𐀀", "export * as \\u{10000} from \"path\";\n\\u{10000};\n")
  6467  	expectPrintedTargetASCII(t, 5, "export * as π from 'path'", "import * as \\u03C0 from \"path\";\nexport { \\u03C0 };\n")
  6468  	expectParseErrorTargetASCII(t, 5, "export * as 𐀀 from 'path'", es5)
  6469  
  6470  	expectPrinted(t, "export {π} from 'path'; π", "export { π } from \"path\";\nπ;\n")
  6471  	expectPrinted(t, "export {𐀀} from 'path'; 𐀀", "export { 𐀀 } from \"path\";\n𐀀;\n")
  6472  	expectPrintedASCII(t, "export {π} from 'path'; π", "export { \\u03C0 } from \"path\";\n\\u03C0;\n")
  6473  	expectPrintedASCII(t, "export {𐀀} from 'path'; 𐀀", "export { \\u{10000} } from \"path\";\n\\u{10000};\n")
  6474  	expectPrintedTargetASCII(t, 5, "export {π} from 'path'; π", "export { \\u03C0 } from \"path\";\n\\u03C0;\n")
  6475  	expectParseErrorTargetASCII(t, 5, "export {𐀀} from 'path'", es5)
  6476  
  6477  	expectPrinted(t, "export {π as x} from 'path'", "export { π as x } from \"path\";\n")
  6478  	expectPrinted(t, "export {𐀀 as x} from 'path'", "export { 𐀀 as x } from \"path\";\n")
  6479  	expectPrintedASCII(t, "export {Ļ€ as x} from 'path'", "export { \\u03C0 as x } from \"path\";\n")
  6480  	expectPrintedASCII(t, "export {𐀀 as x} from 'path'", "export { \\u{10000} as x } from \"path\";\n")
  6481  	expectPrintedTargetASCII(t, 5, "export {Ļ€ as x} from 'path'", "export { \\u03C0 as x } from \"path\";\n")
  6482  	expectParseErrorTargetASCII(t, 5, "export {𐀀 as x} from 'path'", es5)
  6483  
  6484  	expectPrinted(t, "export {x as π} from 'path'", "export { x as π } from \"path\";\n")
  6485  	expectPrinted(t, "export {x as 𐀀} from 'path'", "export { x as 𐀀 } from \"path\";\n")
  6486  	expectPrintedASCII(t, "export {x as π} from 'path'", "export { x as \\u03C0 } from \"path\";\n")
  6487  	expectPrintedASCII(t, "export {x as 𐀀} from 'path'", "export { x as \\u{10000} } from \"path\";\n")
  6488  	expectPrintedTargetASCII(t, 5, "export {x as π} from 'path'", "export { x as \\u03C0 } from \"path\";\n")
  6489  	expectParseErrorTargetASCII(t, 5, "export {x as 𐀀} from 'path'", es5)
  6490  
  6491  	expectPrinted(t, "export {π}; var π", "export { π };\nvar π;\n")
  6492  	expectPrinted(t, "export {𐀀}; var 𐀀", "export { 𐀀 };\nvar 𐀀;\n")
  6493  	expectPrintedASCII(t, "export {π}; var π", "export { \\u03C0 };\nvar \\u03C0;\n")
  6494  	expectPrintedASCII(t, "export {𐀀}; var 𐀀", "export { \\u{10000} };\nvar \\u{10000};\n")
  6495  	expectPrintedTargetASCII(t, 5, "export {π}; var π", "export { \\u03C0 };\nvar \\u03C0;\n")
  6496  	expectParseErrorTargetASCII(t, 5, "export {𐀀}; var 𐀀", es5)
  6497  
  6498  	expectPrinted(t, "export var π", "export var π;\n")
  6499  	expectPrinted(t, "export var 𐀀", "export var 𐀀;\n")
  6500  	expectPrintedASCII(t, "export var π", "export var \\u03C0;\n")
  6501  	expectPrintedASCII(t, "export var 𐀀", "export var \\u{10000};\n")
  6502  	expectPrintedTargetASCII(t, 5, "export var π", "export var \\u03C0;\n")
  6503  	expectParseErrorTargetASCII(t, 5, "export var 𐀀", es5)
  6504  }
  6505  
  6506  func TestMangleCatch(t *testing.T) {
  6507  	expectPrintedMangle(t, "try { throw 0 } catch (e) { console.log(0) }", "try {\n  throw 0;\n} catch {\n  console.log(0);\n}\n")
  6508  	expectPrintedMangle(t, "try { throw 0 } catch (e) { console.log(0, e) }", "try {\n  throw 0;\n} catch (e) {\n  console.log(0, e);\n}\n")
  6509  	expectPrintedMangle(t, "try { throw 0 } catch (e) { 0 && console.log(0, e) }", "try {\n  throw 0;\n} catch {\n}\n")
  6510  	expectPrintedMangle(t, "try { thrower() } catch ([a]) { console.log(0) }", "try {\n  thrower();\n} catch ([a]) {\n  console.log(0);\n}\n")
  6511  	expectPrintedMangle(t, "try { thrower() } catch ({ a }) { console.log(0) }", "try {\n  thrower();\n} catch ({ a }) {\n  console.log(0);\n}\n")
  6512  	expectPrintedMangleTarget(t, 2018, "try { throw 0 } catch (e) { console.log(0) }", "try {\n  throw 0;\n} catch (e) {\n  console.log(0);\n}\n")
  6513  
  6514  	expectPrintedMangle(t, "try { throw 1 } catch (x) { y(x); var x = 2; y(x) }", "try {\n  throw 1;\n} catch (x) {\n  y(x);\n  var x = 2;\n  y(x);\n}\n")
  6515  	expectPrintedMangle(t, "try { throw 1 } catch (x) { var x = 2; y(x) }", "try {\n  throw 1;\n} catch (x) {\n  var x = 2;\n  y(x);\n}\n")
  6516  	expectPrintedMangle(t, "try { throw 1 } catch (x) { var x = 2 }", "try {\n  throw 1;\n} catch (x) {\n  var x = 2;\n}\n")
  6517  	expectPrintedMangle(t, "try { throw 1 } catch (x) { eval('x') }", "try {\n  throw 1;\n} catch (x) {\n  eval(\"x\");\n}\n")
  6518  	expectPrintedMangle(t, "if (y) try { throw 1 } catch (x) {} else eval('x')", "if (y) try {\n  throw 1;\n} catch {\n}\nelse eval(\"x\");\n")
  6519  }
  6520  
  6521  func TestAutoPureForObjectCreate(t *testing.T) {
  6522  	expectPrinted(t, "Object.create(null)", "/* @__PURE__ */ Object.create(null);\n")
  6523  	expectPrinted(t, "Object.create({})", "/* @__PURE__ */ Object.create({});\n")
  6524  
  6525  	expectPrinted(t, "Object.create()", "Object.create();\n")
  6526  	expectPrinted(t, "Object.create(x)", "Object.create(x);\n")
  6527  	expectPrinted(t, "Object.create(undefined)", "Object.create(void 0);\n")
  6528  }
  6529  
  6530  func TestAutoPureForSet(t *testing.T) {
  6531  	expectPrinted(t, "new Set", "/* @__PURE__ */ new Set();\n")
  6532  	expectPrinted(t, "new Set(null)", "/* @__PURE__ */ new Set(null);\n")
  6533  	expectPrinted(t, "new Set(undefined)", "/* @__PURE__ */ new Set(void 0);\n")
  6534  	expectPrinted(t, "new Set([])", "/* @__PURE__ */ new Set([]);\n")
  6535  	expectPrinted(t, "new Set([x])", "/* @__PURE__ */ new Set([x]);\n")
  6536  
  6537  	expectPrinted(t, "new Set(x)", "new Set(x);\n")
  6538  	expectPrinted(t, "new Set(false)", "new Set(false);\n")
  6539  	expectPrinted(t, "new Set({})", "new Set({});\n")
  6540  	expectPrinted(t, "new Set({ x })", "new Set({ x });\n")
  6541  }
  6542  
  6543  func TestAutoPureForMap(t *testing.T) {
  6544  	expectPrinted(t, "new Map", "/* @__PURE__ */ new Map();\n")
  6545  	expectPrinted(t, "new Map(null)", "/* @__PURE__ */ new Map(null);\n")
  6546  	expectPrinted(t, "new Map(undefined)", "/* @__PURE__ */ new Map(void 0);\n")
  6547  	expectPrinted(t, "new Map([])", "/* @__PURE__ */ new Map([]);\n")
  6548  	expectPrinted(t, "new Map([[]])", "/* @__PURE__ */ new Map([[]]);\n")
  6549  	expectPrinted(t, "new Map([[], []])", "/* @__PURE__ */ new Map([[], []]);\n")
  6550  
  6551  	expectPrinted(t, "new Map(x)", "new Map(x);\n")
  6552  	expectPrinted(t, "new Map(false)", "new Map(false);\n")
  6553  	expectPrinted(t, "new Map([x])", "new Map([x]);\n")
  6554  	expectPrinted(t, "new Map([x, []])", "new Map([x, []]);\n")
  6555  	expectPrinted(t, "new Map([[], x])", "new Map([[], x]);\n")
  6556  }
  6557  
  6558  func TestAutoPureForWeakSet(t *testing.T) {
  6559  	expectPrinted(t, "new WeakSet", "/* @__PURE__ */ new WeakSet();\n")
  6560  	expectPrinted(t, "new WeakSet(null)", "/* @__PURE__ */ new WeakSet(null);\n")
  6561  	expectPrinted(t, "new WeakSet(undefined)", "/* @__PURE__ */ new WeakSet(void 0);\n")
  6562  	expectPrinted(t, "new WeakSet([])", "/* @__PURE__ */ new WeakSet([]);\n")
  6563  
  6564  	expectPrinted(t, "new WeakSet([x])", "new WeakSet([x]);\n")
  6565  	expectPrinted(t, "new WeakSet(x)", "new WeakSet(x);\n")
  6566  	expectPrinted(t, "new WeakSet(false)", "new WeakSet(false);\n")
  6567  	expectPrinted(t, "new WeakSet({})", "new WeakSet({});\n")
  6568  	expectPrinted(t, "new WeakSet({ x })", "new WeakSet({ x });\n")
  6569  }
  6570  
  6571  func TestAutoPureForWeakMap(t *testing.T) {
  6572  	expectPrinted(t, "new WeakMap", "/* @__PURE__ */ new WeakMap();\n")
  6573  	expectPrinted(t, "new WeakMap(null)", "/* @__PURE__ */ new WeakMap(null);\n")
  6574  	expectPrinted(t, "new WeakMap(undefined)", "/* @__PURE__ */ new WeakMap(void 0);\n")
  6575  	expectPrinted(t, "new WeakMap([])", "/* @__PURE__ */ new WeakMap([]);\n")
  6576  
  6577  	expectPrinted(t, "new WeakMap([[]])", "new WeakMap([[]]);\n")
  6578  	expectPrinted(t, "new WeakMap([[], []])", "new WeakMap([[], []]);\n")
  6579  	expectPrinted(t, "new WeakMap(x)", "new WeakMap(x);\n")
  6580  	expectPrinted(t, "new WeakMap(false)", "new WeakMap(false);\n")
  6581  	expectPrinted(t, "new WeakMap([x])", "new WeakMap([x]);\n")
  6582  	expectPrinted(t, "new WeakMap([x, []])", "new WeakMap([x, []]);\n")
  6583  	expectPrinted(t, "new WeakMap([[], x])", "new WeakMap([[], x]);\n")
  6584  }
  6585  
  6586  func TestAutoPureForDate(t *testing.T) {
  6587  	expectPrinted(t, "new Date", "/* @__PURE__ */ new Date();\n")
  6588  	expectPrinted(t, "new Date(0)", "/* @__PURE__ */ new Date(0);\n")
  6589  	expectPrinted(t, "new Date('')", "/* @__PURE__ */ new Date(\"\");\n")
  6590  	expectPrinted(t, "new Date(null)", "/* @__PURE__ */ new Date(null);\n")
  6591  	expectPrinted(t, "new Date(true)", "/* @__PURE__ */ new Date(true);\n")
  6592  	expectPrinted(t, "new Date(false)", "/* @__PURE__ */ new Date(false);\n")
  6593  	expectPrinted(t, "new Date(undefined)", "/* @__PURE__ */ new Date(void 0);\n")
  6594  	expectPrinted(t, "new Date(`${foo}`)", "/* @__PURE__ */ new Date(`${foo}`);\n")
  6595  	expectPrinted(t, "new Date(foo ? 'x' : 'y')", "/* @__PURE__ */ new Date(foo ? \"x\" : \"y\");\n")
  6596  
  6597  	expectPrinted(t, "new Date(foo)", "new Date(foo);\n")
  6598  	expectPrinted(t, "new Date(foo``)", "new Date(foo``);\n")
  6599  	expectPrinted(t, "new Date(foo ? x : y)", "new Date(foo ? x : y);\n")
  6600  }
  6601  
  6602  // See: https://github.com/tc39/proposal-explicit-resource-management
  6603  func TestUsing(t *testing.T) {
  6604  	expectPrinted(t, "using x = y", "using x = y;\n")
  6605  	expectPrinted(t, "using x = y; z", "using x = y;\nz;\n")
  6606  	expectPrinted(t, "using x = y, z = _", "using x = y, z = _;\n")
  6607  	expectPrinted(t, "using x = y, \n z = _", "using x = y, z = _;\n")
  6608  	expectPrinted(t, "using \n x = y", "using;\nx = y;\n")
  6609  	expectPrinted(t, "using [x]", "using[x];\n")
  6610  	expectPrinted(t, "using [x] = y", "using[x] = y;\n")
  6611  	expectPrinted(t, "using \n [x] = y", "using[x] = y;\n")
  6612  	expectParseError(t, "using x", "<stdin>: ERROR: The declaration \"x\" must be initialized\n")
  6613  	expectParseError(t, "using {x}", "<stdin>: ERROR: Expected \";\" but found \"{\"\n")
  6614  	expectParseError(t, "using x = y, z", "<stdin>: ERROR: The declaration \"z\" must be initialized\n")
  6615  	expectParseError(t, "using x = y, [z] = _", "<stdin>: ERROR: Expected identifier but found \"[\"\n")
  6616  	expectParseError(t, "using x = y, {z} = _", "<stdin>: ERROR: Expected identifier but found \"{\"\n")
  6617  	expectParseError(t, "export using x = y", "<stdin>: ERROR: Unexpected \"using\"\n")
  6618  
  6619  	expectPrinted(t, "for (using x = y;;) ;", "for (using x = y; ; ) ;\n")
  6620  	expectPrinted(t, "for (using x of y) ;", "for (using x of y) ;\n")
  6621  	expectPrinted(t, "for (using of x) ;", "for (using of x) ;\n")
  6622  	expectPrinted(t, "for (using of of) ;", "for (using of of) ;\n")
  6623  	expectPrinted(t, "for (await using of of x) ;", "for (await using of of x) ;\n")
  6624  	expectPrinted(t, "for (await using of of of) ;", "for (await using of of of) ;\n")
  6625  	expectPrinted(t, "for await (using x of y) ;", "for await (using x of y) ;\n")
  6626  	expectPrinted(t, "for await (using of x) ;", "for await (using of x) ;\n")
  6627  	expectParseError(t, "for (using of of x) ;", "<stdin>: ERROR: Expected \")\" but found \"x\"\n")
  6628  	expectParseError(t, "for (using of of of) ;", "<stdin>: ERROR: Expected \")\" but found \"of\"\n")
  6629  	expectParseError(t, "for (using x in y) ;", "<stdin>: ERROR: \"using\" declarations are not allowed here\n")
  6630  	expectParseError(t, "for (using x;;) ;", "<stdin>: ERROR: The declaration \"x\" must be initialized\n")
  6631  	expectParseError(t, "for (using x = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
  6632  	expectParseError(t, "for (using \n x of y) ;", "<stdin>: ERROR: Expected \";\" but found \"x\"\n")
  6633  	expectParseError(t, "for await (using x = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
  6634  	expectParseError(t, "for await (using \n x of y) ;", "<stdin>: ERROR: Expected \"of\" but found \"x\"\n")
  6635  
  6636  	expectPrinted(t, "await using \n x = y", "await using;\nx = y;\n")
  6637  	expectPrinted(t, "await \n using \n x \n = \n y", "await using;\nx = y;\n")
  6638  	expectPrinted(t, "await using [x]", "await using[x];\n")
  6639  	expectPrinted(t, "await using ([x] = y)", "await using([x] = y);\n")
  6640  	expectPrinted(t, "await (using [x] = y)", "await (using[x] = y);\n")
  6641  	expectParseError(t, "await using [x] = y", "<stdin>: ERROR: Invalid assignment target\n")
  6642  	expectParseError(t, "for (await using x in y) ;", "<stdin>: ERROR: \"await using\" declarations are not allowed here\n")
  6643  	expectParseError(t, "for (await using x = y;;) ;", "<stdin>: ERROR: \"await using\" declarations are not allowed here\n")
  6644  	expectParseError(t, "for (await using of x) ;", "<stdin>: ERROR: Expected \";\" but found \"x\"\n")
  6645  	expectParseError(t, "for (await using x = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
  6646  	expectParseError(t, "for (await using \n x of y) ;", "<stdin>: ERROR: Expected \";\" but found \"x\"\n")
  6647  	expectParseError(t, "for await (await using of x) ;", "<stdin>: ERROR: Expected \"of\" but found \"x\"\n")
  6648  	expectParseError(t, "for await (await using x = y of z) ;", "<stdin>: ERROR: for-of loop variables cannot have an initializer\n")
  6649  	expectParseError(t, "for await (await using \n x of y) ;", "<stdin>: ERROR: Expected \"of\" but found \"x\"\n")
  6650  
  6651  	expectPrinted(t, "await using x = y", "await using x = y;\n")
  6652  	expectPrinted(t, "await using x = y, z = _", "await using x = y, z = _;\n")
  6653  	expectPrinted(t, "for (await using x of y) ;", "for (await using x of y) ;\n")
  6654  	expectPrinted(t, "for await (await using x of y) ;", "for await (await using x of y) ;\n")
  6655  
  6656  	expectPrinted(t, "function foo() { using x = y }", "function foo() {\n  using x = y;\n}\n")
  6657  	expectPrinted(t, "foo = function() { using x = y }", "foo = function() {\n  using x = y;\n};\n")
  6658  	expectPrinted(t, "foo = () => { using x = y }", "foo = () => {\n  using x = y;\n};\n")
  6659  	expectPrinted(t, "async function foo() { using x = y }", "async function foo() {\n  using x = y;\n}\n")
  6660  	expectPrinted(t, "foo = async function() { using x = y }", "foo = async function() {\n  using x = y;\n};\n")
  6661  	expectPrinted(t, "foo = async () => { using x = y }", "foo = async () => {\n  using x = y;\n};\n")
  6662  	expectPrinted(t, "async function foo() { await using x = y }", "async function foo() {\n  await using x = y;\n}\n")
  6663  	expectPrinted(t, "foo = async function() { await using x = y }", "foo = async function() {\n  await using x = y;\n};\n")
  6664  	expectPrinted(t, "foo = async () => { await using x = y }", "foo = async () => {\n  await using x = y;\n};\n")
  6665  
  6666  	expectParseError(t, "export using x = y", "<stdin>: ERROR: Unexpected \"using\"\n")
  6667  	expectParseError(t, "export await using x = y", "<stdin>: ERROR: Unexpected \"await\"\n")
  6668  
  6669  	needAsync := "<stdin>: ERROR: \"await\" can only be used inside an \"async\" function\n<stdin>: NOTE: Consider adding the \"async\" keyword here:\n"
  6670  	expectParseError(t, "function foo() { await using x = y }", needAsync)
  6671  	expectParseError(t, "foo = function() { await using x = y }", needAsync)
  6672  	expectParseError(t, "foo = () => { await using x = y }", needAsync)
  6673  
  6674  	// Can't use await at the top-level without top-level await
  6675  	err := "<stdin>: ERROR: Top-level await is not available in the configured target environment\n"
  6676  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "await using x = y;", err)
  6677  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "for (await using x of y) ;", err)
  6678  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) { await using x = y }", err)
  6679  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (true) for (await using x of y) ;", err)
  6680  	expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) { await using x = y }", "if (false) {\n  using x = y;\n}\n")
  6681  	expectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, "if (false) for (await using x of y) ;", "if (false) for (using x of y) ;\n")
  6682  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "with (x) y; if (false) { await using x = y }",
  6683  		"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n"+
  6684  			"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n")
  6685  	expectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, "with (x) y; if (false) for (await using x of y) ;",
  6686  		"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\n"+
  6687  			"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n")
  6688  
  6689  	// Optimization: "using" declarations initialized to null or undefined can avoid the "using" machinery
  6690  	expectPrinted(t, "using x = {}", "using x = {};\n")
  6691  	expectPrinted(t, "using x = null", "using x = null;\n")
  6692  	expectPrinted(t, "using x = undefined", "using x = void 0;\n")
  6693  	expectPrinted(t, "using x = (foo, y)", "using x = (foo, y);\n")
  6694  	expectPrinted(t, "using x = (foo, null)", "using x = (foo, null);\n")
  6695  	expectPrinted(t, "using x = (foo, undefined)", "using x = (foo, void 0);\n")
  6696  	expectPrintedMangle(t, "using x = {}", "using x = {};\n")
  6697  	expectPrintedMangle(t, "using x = null", "const x = null;\n")
  6698  	expectPrintedMangle(t, "using x = undefined", "const x = void 0;\n")
  6699  	expectPrintedMangle(t, "using x = (foo, y)", "using x = (foo, y);\n")
  6700  	expectPrintedMangle(t, "using x = (foo, null)", "const x = (foo, null);\n")
  6701  	expectPrintedMangle(t, "using x = (foo, undefined)", "const x = (foo, void 0);\n")
  6702  	expectPrintedMangle(t, "using x = null, y = undefined", "const x = null, y = void 0;\n")
  6703  	expectPrintedMangle(t, "using x = null, y = z", "using x = null, y = z;\n")
  6704  	expectPrintedMangle(t, "using x = z, y = undefined", "using x = z, y = void 0;\n")
  6705  }