1 package parser
2
3 import (
4 "errors"
5 "regexp"
6 "strings"
7 "testing"
8
9 "github.com/dop251/goja/ast"
10 "github.com/dop251/goja/file"
11 "github.com/dop251/goja/token"
12 "github.com/dop251/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
204
205
206
207
208
209
210
211
212
213
214
215
216
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
287
288
289
290
291
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
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 {
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 {
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
717 test("var test7_3_1\nabc = 66;", nil)
718 test("var test7_3_1\u2028abc = 66;", nil)
719
720
721 test("//\u2028 =;", "(anonymous): Line 2:2 Unexpected token =")
722
723
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
733 test(`var $\u0030 = 0;`, nil)
734
735
736 test(`switch = 1`, "(anonymous): Line 1:8 Unexpected token =")
737
738
739 test(`.0 === 0.0`, nil)
740
741
742 test("var regExp = /\\\rn/;", "(anonymous): Line 1:14 Invalid regular expression: missing /")
743
744
745 test("var regExp = /=/;", nil)
746
747
748 test("/*/", "(anonymous): Line 1:4 Unexpected end of input")
749
750
751 test(`
752 do {
753 ;
754 } while (false) true
755 `, nil)
756
757
758 test(`
759 {a:1
760 } 3
761 `, nil)
762
763 test(`
764 abc
765 ++def
766 `, nil)
767
768
769 test(`
770 for(false;false
771 ) {
772 break;
773 }
774 `, "(anonymous): Line 3:13 Unexpected token )")
775
776
777 test(`
778 do {};
779 while (false)
780 `, "(anonymous): Line 2:18 Unexpected token ;")
781
782
783 test(`
784 "x\0y"
785 `, nil)
786
787
788 test(`
789 10e10000
790 `, nil)
791
792
793 test(`
794 "abc\
795 def"
796 `, nil)
797
798 test("'\\\n'", nil)
799
800 test("'\\\r\n'", nil)
801
802
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
807 test(`
808 abc /= "1"
809 `, nil)
810
811
812 test(`
813 try{};catch(){}
814 `, "(anonymous): Line 2:13 Missing catch or finally after try")
815
816
817 test(`
818 try{};finally{}
819 `, "(anonymous): Line 2:13 Missing catch or finally after try")
820
821
822 test(`
823 while (true) {
824 break abc;
825 }
826 `, "(anonymous): Line 3:17 Undefined label 'abc'")
827
828
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
848 test(`
849 function = 1
850 `, "(anonymous): Line 2:22 Unexpected token =")
851
852
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
983 test("'\\a'", "a")
984 test("'\u0410'", "\u0410")
985
986
987 test("'\\0'", "\u0000")
988
989
990 test("'\u0000'", "\u0000")
991
992
993 test("\"'abc'\\\n'def'\"", "'abc''def'")
994
995
996 test("\"'abc'\\\r\n'def'\"", "'abc''def'")
997
998
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
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
1052 is(parser.slice(0, 1), "")
1053 is(parser.slice(0, 10), "")
1054
1055
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 node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.FunctionLiteral).Body.List[0].(*ast.ReturnStatement)
1091 is(parser.slice(node.Idx0(), node.Idx1()), "return abc")
1092
1093 parser = newParser("", "(function(){ return; })")
1094 program, err = parser.parse()
1095 is(err, nil)
1096 node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.FunctionLiteral).Body.List[0].(*ast.ReturnStatement)
1097 is(parser.slice(node.Idx0(), node.Idx1()), "return")
1098
1099 parser = newParser("", "true ? 1 : 2")
1100 program, err = parser.parse()
1101 is(err, nil)
1102 node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.ConditionalExpression)
1103 is(parser.slice(node.Idx0(), node.Idx1()), "true ? 1 : 2")
1104
1105 parser = newParser("", "a++")
1106 program, err = parser.parse()
1107 is(err, nil)
1108 node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.UnaryExpression)
1109 is(parser.slice(node.Idx0(), node.Idx1()), "a++")
1110
1111 parser = newParser("", "++a")
1112 program, err = parser.parse()
1113 is(err, nil)
1114 node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.UnaryExpression)
1115 is(parser.slice(node.Idx0(), node.Idx1()), "++a")
1116
1117 parser = newParser("", "xyz: for (i = 0; i < 10; i++) { if (i == 5) continue xyz; }")
1118 program, err = parser.parse()
1119 is(err, nil)
1120 node = program.Body[0].(*ast.LabelledStatement)
1121 is(parser.slice(node.Idx0(), node.Idx1()), "xyz: for (i = 0; i < 10; i++) { if (i == 5) continue xyz; }")
1122 node = program.Body[0].(*ast.LabelledStatement).Statement.(*ast.ForStatement)
1123 is(parser.slice(node.Idx0(), node.Idx1()), "for (i = 0; i < 10; i++) { if (i == 5) continue xyz; }")
1124 block := program.Body[0].(*ast.LabelledStatement).Statement.(*ast.ForStatement).Body.(*ast.BlockStatement)
1125 node = block.List[0].(*ast.IfStatement).Consequent.(*ast.BranchStatement)
1126 is(parser.slice(node.Idx0(), node.Idx1()), "continue xyz")
1127
1128 parser = newParser("", "for (p in o) { break; }")
1129 program, err = parser.parse()
1130 is(err, nil)
1131 node = program.Body[0].(*ast.ForInStatement)
1132 is(parser.slice(node.Idx0(), node.Idx1()), "for (p in o) { break; }")
1133 node = program.Body[0].(*ast.ForInStatement).Body.(*ast.BlockStatement).List[0].(*ast.BranchStatement)
1134 is(parser.slice(node.Idx0(), node.Idx1()), "break")
1135
1136 parser = newParser("", "while (i < 10) { i++; }")
1137 program, err = parser.parse()
1138 is(err, nil)
1139 node = program.Body[0].(*ast.WhileStatement)
1140 is(parser.slice(node.Idx0(), node.Idx1()), "while (i < 10) { i++; }")
1141
1142 parser = newParser("", "do { i++; } while (i < 10 )")
1143 program, err = parser.parse()
1144 is(err, nil)
1145 node = program.Body[0].(*ast.DoWhileStatement)
1146 is(parser.slice(node.Idx0(), node.Idx1()), "do { i++; } while (i < 10 )")
1147
1148 parser = newParser("", "with (1) {}")
1149 program, err = parser.parse()
1150 is(err, nil)
1151 node = program.Body[0].(*ast.WithStatement)
1152 is(parser.slice(node.Idx0(), node.Idx1()), "with (1) {}")
1153
1154 parser = newParser("", `switch (a) {
1155 case 1: x--;
1156 case 2:
1157 default: x++;
1158 }`)
1159 program, err = parser.parse()
1160 is(err, nil)
1161 node = program.Body[0].(*ast.SwitchStatement)
1162 is(parser.slice(node.Idx0(), node.Idx1()), `switch (a) {
1163 case 1: x--;
1164 case 2:
1165 default: x++;
1166 }`)
1167 })
1168 }
1169
1170 func TestExtractSourceMapLine(t *testing.T) {
1171 tt(t, func() {
1172 is(extractSourceMapLine(""), "")
1173 is(extractSourceMapLine("\n"), "")
1174 is(extractSourceMapLine(" "), "")
1175 is(extractSourceMapLine("1\n2\n3\n4\n"), "")
1176
1177 src := `"use strict";
1178 var x = {};
1179 //# sourceMappingURL=delme.js.map`
1180 modSrc := `(function(exports, require, module) {` + src + `
1181 })`
1182 is(extractSourceMapLine(modSrc), "//# sourceMappingURL=delme.js.map")
1183 is(extractSourceMapLine(modSrc+"\n\n\n\n"), "//# sourceMappingURL=delme.js.map")
1184 })
1185 }
1186
1187 func TestSourceMapOptions(t *testing.T) {
1188 tt(t, func() {
1189 count := 0
1190 requestedPath := ""
1191 loader := func(p string) ([]byte, error) {
1192 count++
1193 requestedPath = p
1194 return nil, nil
1195 }
1196 src := `"use strict";
1197 var x = {};
1198 //# sourceMappingURL=delme.js.map`
1199 _, err := ParseFile(nil, "delme.js", src, 0, WithSourceMapLoader(loader))
1200 is(err, nil)
1201 is(count, 1)
1202 is(requestedPath, "delme.js.map")
1203
1204 count = 0
1205 _, err = ParseFile(nil, "", src, 0, WithSourceMapLoader(loader))
1206 is(err, nil)
1207 is(count, 1)
1208 is(requestedPath, "delme.js.map")
1209
1210 count = 0
1211 _, err = ParseFile(nil, "delme.js", src, 0, WithDisableSourceMaps)
1212 is(err, nil)
1213 is(count, 0)
1214
1215 _, err = ParseFile(nil, "/home/user/src/delme.js", src, 0, WithSourceMapLoader(loader))
1216 is(err, nil)
1217 is(count, 1)
1218 is(requestedPath, "/home/user/src/delme.js.map")
1219
1220 count = 0
1221 _, err = ParseFile(nil, "https://site.com/delme.js", src, 0, WithSourceMapLoader(loader))
1222 is(err, nil)
1223 is(count, 1)
1224 is(requestedPath, "https://site.com/delme.js.map")
1225 })
1226 }
1227
1228 func TestParseTemplateCharacters(t *testing.T) {
1229 parser := newParser("", "`test\\\r\\\n${a}`")
1230 parser.next()
1231 if parser.token != token.BACKTICK {
1232 t.Fatalf("Token: %s", parser.token)
1233 }
1234 checkParseTemplateChars := func(expectedLiteral string, expectedParsed unistring.String, expectedFinished, expectParseErr, expectErr bool) {
1235 literal, parsed, finished, parseErr, err := parser.parseTemplateCharacters()
1236 if err != "" != expectErr {
1237 t.Fatal(err)
1238 }
1239 if literal != expectedLiteral {
1240 t.Fatalf("Literal: %q", literal)
1241 }
1242 if parsed != expectedParsed {
1243 t.Fatalf("Parsed: %q", parsed)
1244 }
1245 if finished != expectedFinished {
1246 t.Fatal(finished)
1247 }
1248 if parseErr != "" != expectParseErr {
1249 t.Fatalf("parseErr: %v", parseErr)
1250 }
1251 }
1252 checkParseTemplateChars("test\\\n\\\n", "test", false, false, false)
1253 parser.next()
1254 parser.expect(token.IDENTIFIER)
1255 if len(parser.errors) > 0 {
1256 t.Fatal(parser.errors)
1257 }
1258 if parser.token != token.RIGHT_BRACE {
1259 t.Fatal("Expected }")
1260 }
1261 if len(parser.errors) > 0 {
1262 t.Fatal(parser.errors)
1263 }
1264 checkParseTemplateChars("", "", true, false, false)
1265 if parser.chr != -1 {
1266 t.Fatal("Expected EOF")
1267 }
1268 }
1269
1270 func TestParseTemplateLiteral(t *testing.T) {
1271 parser := newParser("", "f()\n`test${a}`")
1272 prg, err := parser.parse()
1273 if err != nil {
1274 t.Fatal(err)
1275 }
1276 if st, ok := prg.Body[0].(*ast.ExpressionStatement); ok {
1277 if expr, ok := st.Expression.(*ast.TemplateLiteral); ok {
1278 if expr.Tag == nil {
1279 t.Fatal("tag is nil")
1280 }
1281 if idx0 := expr.Tag.Idx0(); idx0 != 1 {
1282 t.Fatalf("Tag.Idx0(): %d", idx0)
1283 }
1284 if expr.OpenQuote != 5 {
1285 t.Fatalf("OpenQuote: %d", expr.OpenQuote)
1286 }
1287 if expr.CloseQuote != 14 {
1288 t.Fatalf("CloseQuote: %d", expr.CloseQuote)
1289 }
1290 if l := len(expr.Elements); l != 2 {
1291 t.Fatalf("len elements: %d", l)
1292 }
1293 if l := len(expr.Expressions); l != 1 {
1294 t.Fatalf("len expressions: %d", l)
1295 }
1296 } else {
1297 t.Fatal(st)
1298 }
1299 } else {
1300 t.Fatal(prg.Body[0])
1301 }
1302 }
1303
1304 func TestParseTemplateLiteralWithTail(t *testing.T) {
1305 parser := newParser("", "f()\n`test${a}tail` ")
1306 prg, err := parser.parse()
1307 if err != nil {
1308 t.Fatal(err)
1309 }
1310 if st, ok := prg.Body[0].(*ast.ExpressionStatement); ok {
1311 if expr, ok := st.Expression.(*ast.TemplateLiteral); ok {
1312 if expr.CloseQuote != 18 {
1313 t.Fatalf("CloseQuote: %d", expr.CloseQuote)
1314 }
1315 } else {
1316 t.Fatal(st)
1317 }
1318 } else {
1319 t.Fatal(prg.Body[0])
1320 }
1321 }
1322
View as plain text