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