1 package parser
2
3 import (
4 "encoding/base64"
5 "fmt"
6 "os"
7 "strings"
8
9 "github.com/dop251/goja/ast"
10 "github.com/dop251/goja/file"
11 "github.com/dop251/goja/token"
12 "github.com/go-sourcemap/sourcemap"
13 )
14
15 func (self *_parser) parseBlockStatement() *ast.BlockStatement {
16 node := &ast.BlockStatement{}
17 node.LeftBrace = self.expect(token.LEFT_BRACE)
18 node.List = self.parseStatementList()
19 node.RightBrace = self.expect(token.RIGHT_BRACE)
20
21 return node
22 }
23
24 func (self *_parser) parseEmptyStatement() ast.Statement {
25 idx := self.expect(token.SEMICOLON)
26 return &ast.EmptyStatement{Semicolon: idx}
27 }
28
29 func (self *_parser) parseStatementList() (list []ast.Statement) {
30 for self.token != token.RIGHT_BRACE && self.token != token.EOF {
31 self.scope.allowLet = true
32 list = append(list, self.parseStatement())
33 }
34
35 return
36 }
37
38 func (self *_parser) parseStatement() ast.Statement {
39
40 if self.token == token.EOF {
41 self.errorUnexpectedToken(self.token)
42 return &ast.BadStatement{From: self.idx, To: self.idx + 1}
43 }
44
45 switch self.token {
46 case token.SEMICOLON:
47 return self.parseEmptyStatement()
48 case token.LEFT_BRACE:
49 return self.parseBlockStatement()
50 case token.IF:
51 return self.parseIfStatement()
52 case token.DO:
53 return self.parseDoWhileStatement()
54 case token.WHILE:
55 return self.parseWhileStatement()
56 case token.FOR:
57 return self.parseForOrForInStatement()
58 case token.BREAK:
59 return self.parseBreakStatement()
60 case token.CONTINUE:
61 return self.parseContinueStatement()
62 case token.DEBUGGER:
63 return self.parseDebuggerStatement()
64 case token.WITH:
65 return self.parseWithStatement()
66 case token.VAR:
67 return self.parseVariableStatement()
68 case token.LET:
69 tok := self.peek()
70 if tok == token.LEFT_BRACKET || self.scope.allowLet && (token.IsId(tok) || tok == token.LEFT_BRACE) {
71 return self.parseLexicalDeclaration(self.token)
72 }
73 self.insertSemicolon = true
74 case token.CONST:
75 return self.parseLexicalDeclaration(self.token)
76 case token.ASYNC:
77 if f := self.parseMaybeAsyncFunction(true); f != nil {
78 return &ast.FunctionDeclaration{
79 Function: f,
80 }
81 }
82 case token.FUNCTION:
83 return &ast.FunctionDeclaration{
84 Function: self.parseFunction(true, false, self.idx),
85 }
86 case token.CLASS:
87 return &ast.ClassDeclaration{
88 Class: self.parseClass(true),
89 }
90 case token.SWITCH:
91 return self.parseSwitchStatement()
92 case token.RETURN:
93 return self.parseReturnStatement()
94 case token.THROW:
95 return self.parseThrowStatement()
96 case token.TRY:
97 return self.parseTryStatement()
98 }
99
100 expression := self.parseExpression()
101
102 if identifier, isIdentifier := expression.(*ast.Identifier); isIdentifier && self.token == token.COLON {
103
104 colon := self.idx
105 self.next()
106 label := identifier.Name
107 for _, value := range self.scope.labels {
108 if label == value {
109 self.error(identifier.Idx0(), "Label '%s' already exists", label)
110 }
111 }
112 self.scope.labels = append(self.scope.labels, label)
113 self.scope.allowLet = false
114 statement := self.parseStatement()
115 self.scope.labels = self.scope.labels[:len(self.scope.labels)-1]
116 return &ast.LabelledStatement{
117 Label: identifier,
118 Colon: colon,
119 Statement: statement,
120 }
121 }
122
123 self.optionalSemicolon()
124
125 return &ast.ExpressionStatement{
126 Expression: expression,
127 }
128 }
129
130 func (self *_parser) parseTryStatement() ast.Statement {
131
132 node := &ast.TryStatement{
133 Try: self.expect(token.TRY),
134 Body: self.parseBlockStatement(),
135 }
136
137 if self.token == token.CATCH {
138 catch := self.idx
139 self.next()
140 var parameter ast.BindingTarget
141 if self.token == token.LEFT_PARENTHESIS {
142 self.next()
143 parameter = self.parseBindingTarget()
144 self.expect(token.RIGHT_PARENTHESIS)
145 }
146 node.Catch = &ast.CatchStatement{
147 Catch: catch,
148 Parameter: parameter,
149 Body: self.parseBlockStatement(),
150 }
151 }
152
153 if self.token == token.FINALLY {
154 self.next()
155 node.Finally = self.parseBlockStatement()
156 }
157
158 if node.Catch == nil && node.Finally == nil {
159 self.error(node.Try, "Missing catch or finally after try")
160 return &ast.BadStatement{From: node.Try, To: node.Body.Idx1()}
161 }
162
163 return node
164 }
165
166 func (self *_parser) parseFunctionParameterList() *ast.ParameterList {
167 opening := self.expect(token.LEFT_PARENTHESIS)
168 var list []*ast.Binding
169 var rest ast.Expression
170 if !self.scope.inFuncParams {
171 self.scope.inFuncParams = true
172 defer func() {
173 self.scope.inFuncParams = false
174 }()
175 }
176 for self.token != token.RIGHT_PARENTHESIS && self.token != token.EOF {
177 if self.token == token.ELLIPSIS {
178 self.next()
179 rest = self.reinterpretAsDestructBindingTarget(self.parseAssignmentExpression())
180 break
181 }
182 self.parseVariableDeclaration(&list)
183 if self.token != token.RIGHT_PARENTHESIS {
184 self.expect(token.COMMA)
185 }
186 }
187 closing := self.expect(token.RIGHT_PARENTHESIS)
188
189 return &ast.ParameterList{
190 Opening: opening,
191 List: list,
192 Rest: rest,
193 Closing: closing,
194 }
195 }
196
197 func (self *_parser) parseMaybeAsyncFunction(declaration bool) *ast.FunctionLiteral {
198 if self.peek() == token.FUNCTION {
199 idx := self.idx
200 self.next()
201 return self.parseFunction(declaration, true, idx)
202 }
203 return nil
204 }
205
206 func (self *_parser) parseFunction(declaration, async bool, start file.Idx) *ast.FunctionLiteral {
207
208 node := &ast.FunctionLiteral{
209 Function: start,
210 Async: async,
211 }
212 self.expect(token.FUNCTION)
213
214 if self.token == token.MULTIPLY {
215 node.Generator = true
216 self.next()
217 }
218
219 if !declaration {
220 if async != self.scope.allowAwait {
221 self.scope.allowAwait = async
222 defer func() {
223 self.scope.allowAwait = !async
224 }()
225 }
226 if node.Generator != self.scope.allowYield {
227 self.scope.allowYield = node.Generator
228 defer func() {
229 self.scope.allowYield = !node.Generator
230 }()
231 }
232 }
233
234 self.tokenToBindingId()
235 var name *ast.Identifier
236 if self.token == token.IDENTIFIER {
237 name = self.parseIdentifier()
238 } else if declaration {
239
240 self.expect(token.IDENTIFIER)
241 }
242 node.Name = name
243
244 if declaration {
245 if async != self.scope.allowAwait {
246 self.scope.allowAwait = async
247 defer func() {
248 self.scope.allowAwait = !async
249 }()
250 }
251 if node.Generator != self.scope.allowYield {
252 self.scope.allowYield = node.Generator
253 defer func() {
254 self.scope.allowYield = !node.Generator
255 }()
256 }
257 }
258
259 node.ParameterList = self.parseFunctionParameterList()
260 node.Body, node.DeclarationList = self.parseFunctionBlock(async, async, self.scope.allowYield)
261 node.Source = self.slice(node.Idx0(), node.Idx1())
262
263 return node
264 }
265
266 func (self *_parser) parseFunctionBlock(async, allowAwait, allowYield bool) (body *ast.BlockStatement, declarationList []*ast.VariableDeclaration) {
267 self.openScope()
268 self.scope.inFunction = true
269 self.scope.inAsync = async
270 self.scope.allowAwait = allowAwait
271 self.scope.allowYield = allowYield
272 defer self.closeScope()
273 body = self.parseBlockStatement()
274 declarationList = self.scope.declarationList
275 return
276 }
277
278 func (self *_parser) parseArrowFunctionBody(async bool) (ast.ConciseBody, []*ast.VariableDeclaration) {
279 if self.token == token.LEFT_BRACE {
280 return self.parseFunctionBlock(async, async, false)
281 }
282 if async != self.scope.inAsync || async != self.scope.allowAwait {
283 inAsync := self.scope.inAsync
284 allowAwait := self.scope.allowAwait
285 self.scope.inAsync = async
286 self.scope.allowAwait = async
287 allowYield := self.scope.allowYield
288 self.scope.allowYield = false
289 defer func() {
290 self.scope.inAsync = inAsync
291 self.scope.allowAwait = allowAwait
292 self.scope.allowYield = allowYield
293 }()
294 }
295
296 return &ast.ExpressionBody{
297 Expression: self.parseAssignmentExpression(),
298 }, nil
299 }
300
301 func (self *_parser) parseClass(declaration bool) *ast.ClassLiteral {
302 if !self.scope.allowLet && self.token == token.CLASS {
303 self.errorUnexpectedToken(token.CLASS)
304 }
305
306 node := &ast.ClassLiteral{
307 Class: self.expect(token.CLASS),
308 }
309
310 self.tokenToBindingId()
311 var name *ast.Identifier
312 if self.token == token.IDENTIFIER {
313 name = self.parseIdentifier()
314 } else if declaration {
315
316 self.expect(token.IDENTIFIER)
317 }
318
319 node.Name = name
320
321 if self.token != token.LEFT_BRACE {
322 self.expect(token.EXTENDS)
323 node.SuperClass = self.parseLeftHandSideExpressionAllowCall()
324 }
325
326 self.expect(token.LEFT_BRACE)
327
328 for self.token != token.RIGHT_BRACE && self.token != token.EOF {
329 if self.token == token.SEMICOLON {
330 self.next()
331 continue
332 }
333 start := self.idx
334 static := false
335 if self.token == token.STATIC {
336 switch self.peek() {
337 case token.ASSIGN, token.SEMICOLON, token.RIGHT_BRACE, token.LEFT_PARENTHESIS:
338
339 default:
340 self.next()
341 if self.token == token.LEFT_BRACE {
342 b := &ast.ClassStaticBlock{
343 Static: start,
344 }
345 b.Block, b.DeclarationList = self.parseFunctionBlock(false, true, false)
346 b.Source = self.slice(b.Block.LeftBrace, b.Block.Idx1())
347 node.Body = append(node.Body, b)
348 continue
349 }
350 static = true
351 }
352 }
353
354 var kind ast.PropertyKind
355 var async bool
356 methodBodyStart := self.idx
357 if self.literal == "get" || self.literal == "set" {
358 if tok := self.peek(); tok != token.SEMICOLON && tok != token.LEFT_PARENTHESIS {
359 if self.literal == "get" {
360 kind = ast.PropertyKindGet
361 } else {
362 kind = ast.PropertyKindSet
363 }
364 self.next()
365 }
366 } else if self.token == token.ASYNC {
367 if tok := self.peek(); tok != token.SEMICOLON && tok != token.LEFT_PARENTHESIS {
368 async = true
369 kind = ast.PropertyKindMethod
370 self.next()
371 }
372 }
373 generator := false
374 if self.token == token.MULTIPLY && (kind == "" || kind == ast.PropertyKindMethod) {
375 generator = true
376 kind = ast.PropertyKindMethod
377 self.next()
378 }
379
380 _, keyName, value, tkn := self.parseObjectPropertyKey()
381 if value == nil {
382 continue
383 }
384 computed := tkn == token.ILLEGAL
385 _, private := value.(*ast.PrivateIdentifier)
386
387 if static && !private && keyName == "prototype" {
388 self.error(value.Idx0(), "Classes may not have a static property named 'prototype'")
389 }
390
391 if kind == "" && self.token == token.LEFT_PARENTHESIS {
392 kind = ast.PropertyKindMethod
393 }
394
395 if kind != "" {
396
397 if keyName == "constructor" && !computed {
398 if !static {
399 if kind != ast.PropertyKindMethod {
400 self.error(value.Idx0(), "Class constructor may not be an accessor")
401 } else if async {
402 self.error(value.Idx0(), "Class constructor may not be an async method")
403 } else if generator {
404 self.error(value.Idx0(), "Class constructor may not be a generator")
405 }
406 } else if private {
407 self.error(value.Idx0(), "Class constructor may not be a private method")
408 }
409 }
410 md := &ast.MethodDefinition{
411 Idx: start,
412 Key: value,
413 Kind: kind,
414 Body: self.parseMethodDefinition(methodBodyStart, kind, generator, async),
415 Static: static,
416 Computed: computed,
417 }
418 node.Body = append(node.Body, md)
419 } else {
420
421 isCtor := !computed && keyName == "constructor"
422 if !isCtor {
423 if name, ok := value.(*ast.PrivateIdentifier); ok {
424 isCtor = name.Name == "constructor"
425 }
426 }
427 if isCtor {
428 self.error(value.Idx0(), "Classes may not have a field named 'constructor'")
429 }
430 var initializer ast.Expression
431 if self.token == token.ASSIGN {
432 self.next()
433 initializer = self.parseExpression()
434 }
435
436 if !self.implicitSemicolon && self.token != token.SEMICOLON && self.token != token.RIGHT_BRACE {
437 self.errorUnexpectedToken(self.token)
438 break
439 }
440 node.Body = append(node.Body, &ast.FieldDefinition{
441 Idx: start,
442 Key: value,
443 Initializer: initializer,
444 Static: static,
445 Computed: computed,
446 })
447 }
448 }
449
450 node.RightBrace = self.expect(token.RIGHT_BRACE)
451 node.Source = self.slice(node.Class, node.RightBrace+1)
452
453 return node
454 }
455
456 func (self *_parser) parseDebuggerStatement() ast.Statement {
457 idx := self.expect(token.DEBUGGER)
458
459 node := &ast.DebuggerStatement{
460 Debugger: idx,
461 }
462
463 self.semicolon()
464
465 return node
466 }
467
468 func (self *_parser) parseReturnStatement() ast.Statement {
469 idx := self.expect(token.RETURN)
470
471 if !self.scope.inFunction {
472 self.error(idx, "Illegal return statement")
473 self.nextStatement()
474 return &ast.BadStatement{From: idx, To: self.idx}
475 }
476
477 node := &ast.ReturnStatement{
478 Return: idx,
479 }
480
481 if !self.implicitSemicolon && self.token != token.SEMICOLON && self.token != token.RIGHT_BRACE && self.token != token.EOF {
482 node.Argument = self.parseExpression()
483 }
484
485 self.semicolon()
486
487 return node
488 }
489
490 func (self *_parser) parseThrowStatement() ast.Statement {
491 idx := self.expect(token.THROW)
492
493 if self.implicitSemicolon {
494 if self.chr == -1 {
495 self.error(idx, "Unexpected end of input")
496 } else {
497 self.error(idx, "Illegal newline after throw")
498 }
499 self.nextStatement()
500 return &ast.BadStatement{From: idx, To: self.idx}
501 }
502
503 node := &ast.ThrowStatement{
504 Throw: idx,
505 Argument: self.parseExpression(),
506 }
507
508 self.semicolon()
509
510 return node
511 }
512
513 func (self *_parser) parseSwitchStatement() ast.Statement {
514 idx := self.expect(token.SWITCH)
515 self.expect(token.LEFT_PARENTHESIS)
516 node := &ast.SwitchStatement{
517 Switch: idx,
518 Discriminant: self.parseExpression(),
519 Default: -1,
520 }
521 self.expect(token.RIGHT_PARENTHESIS)
522
523 self.expect(token.LEFT_BRACE)
524
525 inSwitch := self.scope.inSwitch
526 self.scope.inSwitch = true
527 defer func() {
528 self.scope.inSwitch = inSwitch
529 }()
530
531 for index := 0; self.token != token.EOF; index++ {
532 if self.token == token.RIGHT_BRACE {
533 node.RightBrace = self.idx
534 self.next()
535 break
536 }
537
538 clause := self.parseCaseStatement()
539 if clause.Test == nil {
540 if node.Default != -1 {
541 self.error(clause.Case, "Already saw a default in switch")
542 }
543 node.Default = index
544 }
545 node.Body = append(node.Body, clause)
546 }
547
548 return node
549 }
550
551 func (self *_parser) parseWithStatement() ast.Statement {
552 node := &ast.WithStatement{}
553 node.With = self.expect(token.WITH)
554 self.expect(token.LEFT_PARENTHESIS)
555 node.Object = self.parseExpression()
556 self.expect(token.RIGHT_PARENTHESIS)
557 self.scope.allowLet = false
558 node.Body = self.parseStatement()
559
560 return node
561 }
562
563 func (self *_parser) parseCaseStatement() *ast.CaseStatement {
564
565 node := &ast.CaseStatement{
566 Case: self.idx,
567 }
568 if self.token == token.DEFAULT {
569 self.next()
570 } else {
571 self.expect(token.CASE)
572 node.Test = self.parseExpression()
573 }
574 self.expect(token.COLON)
575
576 for {
577 if self.token == token.EOF ||
578 self.token == token.RIGHT_BRACE ||
579 self.token == token.CASE ||
580 self.token == token.DEFAULT {
581 break
582 }
583 self.scope.allowLet = true
584 node.Consequent = append(node.Consequent, self.parseStatement())
585
586 }
587
588 return node
589 }
590
591 func (self *_parser) parseIterationStatement() ast.Statement {
592 inIteration := self.scope.inIteration
593 self.scope.inIteration = true
594 defer func() {
595 self.scope.inIteration = inIteration
596 }()
597 self.scope.allowLet = false
598 return self.parseStatement()
599 }
600
601 func (self *_parser) parseForIn(idx file.Idx, into ast.ForInto) *ast.ForInStatement {
602
603
604
605 source := self.parseExpression()
606 self.expect(token.RIGHT_PARENTHESIS)
607
608 return &ast.ForInStatement{
609 For: idx,
610 Into: into,
611 Source: source,
612 Body: self.parseIterationStatement(),
613 }
614 }
615
616 func (self *_parser) parseForOf(idx file.Idx, into ast.ForInto) *ast.ForOfStatement {
617
618
619
620 source := self.parseAssignmentExpression()
621 self.expect(token.RIGHT_PARENTHESIS)
622
623 return &ast.ForOfStatement{
624 For: idx,
625 Into: into,
626 Source: source,
627 Body: self.parseIterationStatement(),
628 }
629 }
630
631 func (self *_parser) parseFor(idx file.Idx, initializer ast.ForLoopInitializer) *ast.ForStatement {
632
633
634
635 var test, update ast.Expression
636
637 if self.token != token.SEMICOLON {
638 test = self.parseExpression()
639 }
640 self.expect(token.SEMICOLON)
641
642 if self.token != token.RIGHT_PARENTHESIS {
643 update = self.parseExpression()
644 }
645 self.expect(token.RIGHT_PARENTHESIS)
646
647 return &ast.ForStatement{
648 For: idx,
649 Initializer: initializer,
650 Test: test,
651 Update: update,
652 Body: self.parseIterationStatement(),
653 }
654 }
655
656 func (self *_parser) parseForOrForInStatement() ast.Statement {
657 idx := self.expect(token.FOR)
658 self.expect(token.LEFT_PARENTHESIS)
659
660 var initializer ast.ForLoopInitializer
661
662 forIn := false
663 forOf := false
664 var into ast.ForInto
665 if self.token != token.SEMICOLON {
666
667 allowIn := self.scope.allowIn
668 self.scope.allowIn = false
669 tok := self.token
670 if tok == token.LET {
671 switch self.peek() {
672 case token.IDENTIFIER, token.LEFT_BRACKET, token.LEFT_BRACE:
673 default:
674 tok = token.IDENTIFIER
675 }
676 }
677 if tok == token.VAR || tok == token.LET || tok == token.CONST {
678 idx := self.idx
679 self.next()
680 var list []*ast.Binding
681 if tok == token.VAR {
682 list = self.parseVarDeclarationList(idx)
683 } else {
684 list = self.parseVariableDeclarationList()
685 }
686 if len(list) == 1 {
687 if self.token == token.IN {
688 self.next()
689 forIn = true
690 } else if self.token == token.IDENTIFIER && self.literal == "of" {
691 self.next()
692 forOf = true
693 }
694 }
695 if forIn || forOf {
696 if list[0].Initializer != nil {
697 self.error(list[0].Initializer.Idx0(), "for-in loop variable declaration may not have an initializer")
698 }
699 if tok == token.VAR {
700 into = &ast.ForIntoVar{
701 Binding: list[0],
702 }
703 } else {
704 into = &ast.ForDeclaration{
705 Idx: idx,
706 IsConst: tok == token.CONST,
707 Target: list[0].Target,
708 }
709 }
710 } else {
711 self.ensurePatternInit(list)
712 if tok == token.VAR {
713 initializer = &ast.ForLoopInitializerVarDeclList{
714 List: list,
715 }
716 } else {
717 initializer = &ast.ForLoopInitializerLexicalDecl{
718 LexicalDeclaration: ast.LexicalDeclaration{
719 Idx: idx,
720 Token: tok,
721 List: list,
722 },
723 }
724 }
725 }
726 } else {
727 expr := self.parseExpression()
728 if self.token == token.IN {
729 self.next()
730 forIn = true
731 } else if self.token == token.IDENTIFIER && self.literal == "of" {
732 self.next()
733 forOf = true
734 }
735 if forIn || forOf {
736 switch e := expr.(type) {
737 case *ast.Identifier, *ast.DotExpression, *ast.PrivateDotExpression, *ast.BracketExpression, *ast.Binding:
738
739 case *ast.ObjectLiteral:
740 expr = self.reinterpretAsObjectAssignmentPattern(e)
741 case *ast.ArrayLiteral:
742 expr = self.reinterpretAsArrayAssignmentPattern(e)
743 default:
744 self.error(idx, "Invalid left-hand side in for-in or for-of")
745 self.nextStatement()
746 return &ast.BadStatement{From: idx, To: self.idx}
747 }
748 into = &ast.ForIntoExpression{
749 Expression: expr,
750 }
751 } else {
752 initializer = &ast.ForLoopInitializerExpression{
753 Expression: expr,
754 }
755 }
756 }
757 self.scope.allowIn = allowIn
758 }
759
760 if forIn {
761 return self.parseForIn(idx, into)
762 }
763 if forOf {
764 return self.parseForOf(idx, into)
765 }
766
767 self.expect(token.SEMICOLON)
768 return self.parseFor(idx, initializer)
769 }
770
771 func (self *_parser) ensurePatternInit(list []*ast.Binding) {
772 for _, item := range list {
773 if _, ok := item.Target.(ast.Pattern); ok {
774 if item.Initializer == nil {
775 self.error(item.Idx1(), "Missing initializer in destructuring declaration")
776 break
777 }
778 }
779 }
780 }
781
782 func (self *_parser) parseVariableStatement() *ast.VariableStatement {
783
784 idx := self.expect(token.VAR)
785
786 list := self.parseVarDeclarationList(idx)
787 self.ensurePatternInit(list)
788 self.semicolon()
789
790 return &ast.VariableStatement{
791 Var: idx,
792 List: list,
793 }
794 }
795
796 func (self *_parser) parseLexicalDeclaration(tok token.Token) *ast.LexicalDeclaration {
797 idx := self.expect(tok)
798 if !self.scope.allowLet {
799 self.error(idx, "Lexical declaration cannot appear in a single-statement context")
800 }
801
802 list := self.parseVariableDeclarationList()
803 self.ensurePatternInit(list)
804 self.semicolon()
805
806 return &ast.LexicalDeclaration{
807 Idx: idx,
808 Token: tok,
809 List: list,
810 }
811 }
812
813 func (self *_parser) parseDoWhileStatement() ast.Statement {
814 inIteration := self.scope.inIteration
815 self.scope.inIteration = true
816 defer func() {
817 self.scope.inIteration = inIteration
818 }()
819
820 node := &ast.DoWhileStatement{}
821 node.Do = self.expect(token.DO)
822 if self.token == token.LEFT_BRACE {
823 node.Body = self.parseBlockStatement()
824 } else {
825 self.scope.allowLet = false
826 node.Body = self.parseStatement()
827 }
828
829 self.expect(token.WHILE)
830 self.expect(token.LEFT_PARENTHESIS)
831 node.Test = self.parseExpression()
832 node.RightParenthesis = self.expect(token.RIGHT_PARENTHESIS)
833 if self.token == token.SEMICOLON {
834 self.next()
835 }
836
837 return node
838 }
839
840 func (self *_parser) parseWhileStatement() ast.Statement {
841 idx := self.expect(token.WHILE)
842 self.expect(token.LEFT_PARENTHESIS)
843 node := &ast.WhileStatement{
844 While: idx,
845 Test: self.parseExpression(),
846 }
847 self.expect(token.RIGHT_PARENTHESIS)
848 node.Body = self.parseIterationStatement()
849
850 return node
851 }
852
853 func (self *_parser) parseIfStatement() ast.Statement {
854 self.expect(token.IF)
855 self.expect(token.LEFT_PARENTHESIS)
856 node := &ast.IfStatement{
857 Test: self.parseExpression(),
858 }
859 self.expect(token.RIGHT_PARENTHESIS)
860
861 if self.token == token.LEFT_BRACE {
862 node.Consequent = self.parseBlockStatement()
863 } else {
864 self.scope.allowLet = false
865 node.Consequent = self.parseStatement()
866 }
867
868 if self.token == token.ELSE {
869 self.next()
870 self.scope.allowLet = false
871 node.Alternate = self.parseStatement()
872 }
873
874 return node
875 }
876
877 func (self *_parser) parseSourceElements() (body []ast.Statement) {
878 for self.token != token.EOF {
879 self.scope.allowLet = true
880 body = append(body, self.parseStatement())
881 }
882
883 return body
884 }
885
886 func (self *_parser) parseProgram() *ast.Program {
887 prg := &ast.Program{
888 Body: self.parseSourceElements(),
889 DeclarationList: self.scope.declarationList,
890 File: self.file,
891 }
892 self.file.SetSourceMap(self.parseSourceMap())
893 return prg
894 }
895
896 func extractSourceMapLine(str string) string {
897 for {
898 p := strings.LastIndexByte(str, '\n')
899 line := str[p+1:]
900 if line != "" && line != "})" {
901 if strings.HasPrefix(line, "//# sourceMappingURL=") {
902 return line
903 }
904 break
905 }
906 if p >= 0 {
907 str = str[:p]
908 } else {
909 break
910 }
911 }
912 return ""
913 }
914
915 func (self *_parser) parseSourceMap() *sourcemap.Consumer {
916 if self.opts.disableSourceMaps {
917 return nil
918 }
919 if smLine := extractSourceMapLine(self.str); smLine != "" {
920 urlIndex := strings.Index(smLine, "=")
921 urlStr := smLine[urlIndex+1:]
922
923 var data []byte
924 var err error
925 if strings.HasPrefix(urlStr, "data:application/json") {
926 b64Index := strings.Index(urlStr, ",")
927 b64 := urlStr[b64Index+1:]
928 data, err = base64.StdEncoding.DecodeString(b64)
929 } else {
930 if sourceURL := file.ResolveSourcemapURL(self.file.Name(), urlStr); sourceURL != nil {
931 if self.opts.sourceMapLoader != nil {
932 data, err = self.opts.sourceMapLoader(sourceURL.String())
933 } else {
934 if sourceURL.Scheme == "" || sourceURL.Scheme == "file" {
935 data, err = os.ReadFile(sourceURL.Path)
936 } else {
937 err = fmt.Errorf("unsupported source map URL scheme: %s", sourceURL.Scheme)
938 }
939 }
940 }
941 }
942
943 if err != nil {
944 self.error(file.Idx(0), "Could not load source map: %v", err)
945 return nil
946 }
947 if data == nil {
948 return nil
949 }
950
951 if sm, err := sourcemap.Parse(self.file.Name(), data); err == nil {
952 return sm
953 } else {
954 self.error(file.Idx(0), "Could not parse source map: %v", err)
955 }
956 }
957 return nil
958 }
959
960 func (self *_parser) parseBreakStatement() ast.Statement {
961 idx := self.expect(token.BREAK)
962 semicolon := self.implicitSemicolon
963 if self.token == token.SEMICOLON {
964 semicolon = true
965 self.next()
966 }
967
968 if semicolon || self.token == token.RIGHT_BRACE {
969 self.implicitSemicolon = false
970 if !self.scope.inIteration && !self.scope.inSwitch {
971 goto illegal
972 }
973 return &ast.BranchStatement{
974 Idx: idx,
975 Token: token.BREAK,
976 }
977 }
978
979 self.tokenToBindingId()
980 if self.token == token.IDENTIFIER {
981 identifier := self.parseIdentifier()
982 if !self.scope.hasLabel(identifier.Name) {
983 self.error(idx, "Undefined label '%s'", identifier.Name)
984 return &ast.BadStatement{From: idx, To: identifier.Idx1()}
985 }
986 self.semicolon()
987 return &ast.BranchStatement{
988 Idx: idx,
989 Token: token.BREAK,
990 Label: identifier,
991 }
992 }
993
994 self.expect(token.IDENTIFIER)
995
996 illegal:
997 self.error(idx, "Illegal break statement")
998 self.nextStatement()
999 return &ast.BadStatement{From: idx, To: self.idx}
1000 }
1001
1002 func (self *_parser) parseContinueStatement() ast.Statement {
1003 idx := self.expect(token.CONTINUE)
1004 semicolon := self.implicitSemicolon
1005 if self.token == token.SEMICOLON {
1006 semicolon = true
1007 self.next()
1008 }
1009
1010 if semicolon || self.token == token.RIGHT_BRACE {
1011 self.implicitSemicolon = false
1012 if !self.scope.inIteration {
1013 goto illegal
1014 }
1015 return &ast.BranchStatement{
1016 Idx: idx,
1017 Token: token.CONTINUE,
1018 }
1019 }
1020
1021 self.tokenToBindingId()
1022 if self.token == token.IDENTIFIER {
1023 identifier := self.parseIdentifier()
1024 if !self.scope.hasLabel(identifier.Name) {
1025 self.error(idx, "Undefined label '%s'", identifier.Name)
1026 return &ast.BadStatement{From: idx, To: identifier.Idx1()}
1027 }
1028 if !self.scope.inIteration {
1029 goto illegal
1030 }
1031 self.semicolon()
1032 return &ast.BranchStatement{
1033 Idx: idx,
1034 Token: token.CONTINUE,
1035 Label: identifier,
1036 }
1037 }
1038
1039 self.expect(token.IDENTIFIER)
1040
1041 illegal:
1042 self.error(idx, "Illegal continue statement")
1043 self.nextStatement()
1044 return &ast.BadStatement{From: idx, To: self.idx}
1045 }
1046
1047
1048 func (self *_parser) nextStatement() {
1049 for {
1050 switch self.token {
1051 case token.BREAK, token.CONTINUE,
1052 token.FOR, token.IF, token.RETURN, token.SWITCH,
1053 token.VAR, token.DO, token.TRY, token.WITH,
1054 token.WHILE, token.THROW, token.CATCH, token.FINALLY:
1055
1056
1057
1058
1059 if self.idx == self.recover.idx && self.recover.count < 10 {
1060 self.recover.count++
1061 return
1062 }
1063 if self.idx > self.recover.idx {
1064 self.recover.idx = self.idx
1065 self.recover.count = 0
1066 return
1067 }
1068
1069
1070
1071
1072
1073 case token.EOF:
1074 return
1075 }
1076 self.next()
1077 }
1078 }
1079
View as plain text