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  }