github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/parser/parser_test.go (about)

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