github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/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  	"github.com/nuvolaris/goja/ast"
    11  	"github.com/nuvolaris/goja/file"
    12  	"github.com/nuvolaris/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.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  		// LabelledStatement
   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) // Push the label
   113  		self.scope.allowLet = false
   114  		statement := self.parseStatement()
   115  		self.scope.labels = self.scope.labels[:len(self.scope.labels)-1] // Pop the label
   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  		// Use expect error handling
   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  		// Use expect error handling
   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  				// treat as identifier
   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  			// method
   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  			// field
   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 { // Hackish
   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  	self.expect(token.SWITCH)
   515  	self.expect(token.LEFT_PARENTHESIS)
   516  	node := &ast.SwitchStatement{
   517  		Discriminant: self.parseExpression(),
   518  		Default:      -1,
   519  	}
   520  	self.expect(token.RIGHT_PARENTHESIS)
   521  
   522  	self.expect(token.LEFT_BRACE)
   523  
   524  	inSwitch := self.scope.inSwitch
   525  	self.scope.inSwitch = true
   526  	defer func() {
   527  		self.scope.inSwitch = inSwitch
   528  	}()
   529  
   530  	for index := 0; self.token != token.EOF; index++ {
   531  		if self.token == token.RIGHT_BRACE {
   532  			self.next()
   533  			break
   534  		}
   535  
   536  		clause := self.parseCaseStatement()
   537  		if clause.Test == nil {
   538  			if node.Default != -1 {
   539  				self.error(clause.Case, "Already saw a default in switch")
   540  			}
   541  			node.Default = index
   542  		}
   543  		node.Body = append(node.Body, clause)
   544  	}
   545  
   546  	return node
   547  }
   548  
   549  func (self *_parser) parseWithStatement() ast.Statement {
   550  	self.expect(token.WITH)
   551  	self.expect(token.LEFT_PARENTHESIS)
   552  	node := &ast.WithStatement{
   553  		Object: self.parseExpression(),
   554  	}
   555  	self.expect(token.RIGHT_PARENTHESIS)
   556  	self.scope.allowLet = false
   557  	node.Body = self.parseStatement()
   558  
   559  	return node
   560  }
   561  
   562  func (self *_parser) parseCaseStatement() *ast.CaseStatement {
   563  
   564  	node := &ast.CaseStatement{
   565  		Case: self.idx,
   566  	}
   567  	if self.token == token.DEFAULT {
   568  		self.next()
   569  	} else {
   570  		self.expect(token.CASE)
   571  		node.Test = self.parseExpression()
   572  	}
   573  	self.expect(token.COLON)
   574  
   575  	for {
   576  		if self.token == token.EOF ||
   577  			self.token == token.RIGHT_BRACE ||
   578  			self.token == token.CASE ||
   579  			self.token == token.DEFAULT {
   580  			break
   581  		}
   582  		self.scope.allowLet = true
   583  		node.Consequent = append(node.Consequent, self.parseStatement())
   584  
   585  	}
   586  
   587  	return node
   588  }
   589  
   590  func (self *_parser) parseIterationStatement() ast.Statement {
   591  	inIteration := self.scope.inIteration
   592  	self.scope.inIteration = true
   593  	defer func() {
   594  		self.scope.inIteration = inIteration
   595  	}()
   596  	self.scope.allowLet = false
   597  	return self.parseStatement()
   598  }
   599  
   600  func (self *_parser) parseForIn(idx file.Idx, into ast.ForInto) *ast.ForInStatement {
   601  
   602  	// Already have consumed "<into> in"
   603  
   604  	source := self.parseExpression()
   605  	self.expect(token.RIGHT_PARENTHESIS)
   606  
   607  	return &ast.ForInStatement{
   608  		For:    idx,
   609  		Into:   into,
   610  		Source: source,
   611  		Body:   self.parseIterationStatement(),
   612  	}
   613  }
   614  
   615  func (self *_parser) parseForOf(idx file.Idx, into ast.ForInto) *ast.ForOfStatement {
   616  
   617  	// Already have consumed "<into> of"
   618  
   619  	source := self.parseAssignmentExpression()
   620  	self.expect(token.RIGHT_PARENTHESIS)
   621  
   622  	return &ast.ForOfStatement{
   623  		For:    idx,
   624  		Into:   into,
   625  		Source: source,
   626  		Body:   self.parseIterationStatement(),
   627  	}
   628  }
   629  
   630  func (self *_parser) parseFor(idx file.Idx, initializer ast.ForLoopInitializer) *ast.ForStatement {
   631  
   632  	// Already have consumed "<initializer> ;"
   633  
   634  	var test, update ast.Expression
   635  
   636  	if self.token != token.SEMICOLON {
   637  		test = self.parseExpression()
   638  	}
   639  	self.expect(token.SEMICOLON)
   640  
   641  	if self.token != token.RIGHT_PARENTHESIS {
   642  		update = self.parseExpression()
   643  	}
   644  	self.expect(token.RIGHT_PARENTHESIS)
   645  
   646  	return &ast.ForStatement{
   647  		For:         idx,
   648  		Initializer: initializer,
   649  		Test:        test,
   650  		Update:      update,
   651  		Body:        self.parseIterationStatement(),
   652  	}
   653  }
   654  
   655  func (self *_parser) parseForOrForInStatement() ast.Statement {
   656  	idx := self.expect(token.FOR)
   657  	self.expect(token.LEFT_PARENTHESIS)
   658  
   659  	var initializer ast.ForLoopInitializer
   660  
   661  	forIn := false
   662  	forOf := false
   663  	var into ast.ForInto
   664  	if self.token != token.SEMICOLON {
   665  
   666  		allowIn := self.scope.allowIn
   667  		self.scope.allowIn = false
   668  		tok := self.token
   669  		if tok == token.LET {
   670  			switch self.peek() {
   671  			case token.IDENTIFIER, token.LEFT_BRACKET, token.LEFT_BRACE:
   672  			default:
   673  				tok = token.IDENTIFIER
   674  			}
   675  		}
   676  		if tok == token.VAR || tok == token.LET || tok == token.CONST {
   677  			idx := self.idx
   678  			self.next()
   679  			var list []*ast.Binding
   680  			if tok == token.VAR {
   681  				list = self.parseVarDeclarationList(idx)
   682  			} else {
   683  				list = self.parseVariableDeclarationList()
   684  			}
   685  			if len(list) == 1 {
   686  				if self.token == token.IN {
   687  					self.next() // in
   688  					forIn = true
   689  				} else if self.token == token.IDENTIFIER && self.literal == "of" {
   690  					self.next()
   691  					forOf = true
   692  				}
   693  			}
   694  			if forIn || forOf {
   695  				if list[0].Initializer != nil {
   696  					self.error(list[0].Initializer.Idx0(), "for-in loop variable declaration may not have an initializer")
   697  				}
   698  				if tok == token.VAR {
   699  					into = &ast.ForIntoVar{
   700  						Binding: list[0],
   701  					}
   702  				} else {
   703  					into = &ast.ForDeclaration{
   704  						Idx:     idx,
   705  						IsConst: tok == token.CONST,
   706  						Target:  list[0].Target,
   707  					}
   708  				}
   709  			} else {
   710  				self.ensurePatternInit(list)
   711  				if tok == token.VAR {
   712  					initializer = &ast.ForLoopInitializerVarDeclList{
   713  						List: list,
   714  					}
   715  				} else {
   716  					initializer = &ast.ForLoopInitializerLexicalDecl{
   717  						LexicalDeclaration: ast.LexicalDeclaration{
   718  							Idx:   idx,
   719  							Token: tok,
   720  							List:  list,
   721  						},
   722  					}
   723  				}
   724  			}
   725  		} else {
   726  			expr := self.parseExpression()
   727  			if self.token == token.IN {
   728  				self.next()
   729  				forIn = true
   730  			} else if self.token == token.IDENTIFIER && self.literal == "of" {
   731  				self.next()
   732  				forOf = true
   733  			}
   734  			if forIn || forOf {
   735  				switch e := expr.(type) {
   736  				case *ast.Identifier, *ast.DotExpression, *ast.PrivateDotExpression, *ast.BracketExpression, *ast.Binding:
   737  					// These are all acceptable
   738  				case *ast.ObjectLiteral:
   739  					expr = self.reinterpretAsObjectAssignmentPattern(e)
   740  				case *ast.ArrayLiteral:
   741  					expr = self.reinterpretAsArrayAssignmentPattern(e)
   742  				default:
   743  					self.error(idx, "Invalid left-hand side in for-in or for-of")
   744  					self.nextStatement()
   745  					return &ast.BadStatement{From: idx, To: self.idx}
   746  				}
   747  				into = &ast.ForIntoExpression{
   748  					Expression: expr,
   749  				}
   750  			} else {
   751  				initializer = &ast.ForLoopInitializerExpression{
   752  					Expression: expr,
   753  				}
   754  			}
   755  		}
   756  		self.scope.allowIn = allowIn
   757  	}
   758  
   759  	if forIn {
   760  		return self.parseForIn(idx, into)
   761  	}
   762  	if forOf {
   763  		return self.parseForOf(idx, into)
   764  	}
   765  
   766  	self.expect(token.SEMICOLON)
   767  	return self.parseFor(idx, initializer)
   768  }
   769  
   770  func (self *_parser) ensurePatternInit(list []*ast.Binding) {
   771  	for _, item := range list {
   772  		if _, ok := item.Target.(ast.Pattern); ok {
   773  			if item.Initializer == nil {
   774  				self.error(item.Idx1(), "Missing initializer in destructuring declaration")
   775  				break
   776  			}
   777  		}
   778  	}
   779  }
   780  
   781  func (self *_parser) parseVariableStatement() *ast.VariableStatement {
   782  
   783  	idx := self.expect(token.VAR)
   784  
   785  	list := self.parseVarDeclarationList(idx)
   786  	self.ensurePatternInit(list)
   787  	self.semicolon()
   788  
   789  	return &ast.VariableStatement{
   790  		Var:  idx,
   791  		List: list,
   792  	}
   793  }
   794  
   795  func (self *_parser) parseLexicalDeclaration(tok token.Token) *ast.LexicalDeclaration {
   796  	idx := self.expect(tok)
   797  	if !self.scope.allowLet {
   798  		self.error(idx, "Lexical declaration cannot appear in a single-statement context")
   799  	}
   800  
   801  	list := self.parseVariableDeclarationList()
   802  	self.ensurePatternInit(list)
   803  	self.semicolon()
   804  
   805  	return &ast.LexicalDeclaration{
   806  		Idx:   idx,
   807  		Token: tok,
   808  		List:  list,
   809  	}
   810  }
   811  
   812  func (self *_parser) parseDoWhileStatement() ast.Statement {
   813  	inIteration := self.scope.inIteration
   814  	self.scope.inIteration = true
   815  	defer func() {
   816  		self.scope.inIteration = inIteration
   817  	}()
   818  
   819  	self.expect(token.DO)
   820  	node := &ast.DoWhileStatement{}
   821  	if self.token == token.LEFT_BRACE {
   822  		node.Body = self.parseBlockStatement()
   823  	} else {
   824  		self.scope.allowLet = false
   825  		node.Body = self.parseStatement()
   826  	}
   827  
   828  	self.expect(token.WHILE)
   829  	self.expect(token.LEFT_PARENTHESIS)
   830  	node.Test = self.parseExpression()
   831  	self.expect(token.RIGHT_PARENTHESIS)
   832  	if self.token == token.SEMICOLON {
   833  		self.next()
   834  	}
   835  
   836  	return node
   837  }
   838  
   839  func (self *_parser) parseWhileStatement() ast.Statement {
   840  	self.expect(token.WHILE)
   841  	self.expect(token.LEFT_PARENTHESIS)
   842  	node := &ast.WhileStatement{
   843  		Test: self.parseExpression(),
   844  	}
   845  	self.expect(token.RIGHT_PARENTHESIS)
   846  	node.Body = self.parseIterationStatement()
   847  
   848  	return node
   849  }
   850  
   851  func (self *_parser) parseIfStatement() ast.Statement {
   852  	self.expect(token.IF)
   853  	self.expect(token.LEFT_PARENTHESIS)
   854  	node := &ast.IfStatement{
   855  		Test: self.parseExpression(),
   856  	}
   857  	self.expect(token.RIGHT_PARENTHESIS)
   858  
   859  	if self.token == token.LEFT_BRACE {
   860  		node.Consequent = self.parseBlockStatement()
   861  	} else {
   862  		self.scope.allowLet = false
   863  		node.Consequent = self.parseStatement()
   864  	}
   865  
   866  	if self.token == token.ELSE {
   867  		self.next()
   868  		self.scope.allowLet = false
   869  		node.Alternate = self.parseStatement()
   870  	}
   871  
   872  	return node
   873  }
   874  
   875  func (self *_parser) parseSourceElements() (body []ast.Statement) {
   876  	for self.token != token.EOF {
   877  		self.scope.allowLet = true
   878  		body = append(body, self.parseStatement())
   879  	}
   880  
   881  	return body
   882  }
   883  
   884  func (self *_parser) parseProgram() *ast.Program {
   885  	prg := &ast.Program{
   886  		Body:            self.parseSourceElements(),
   887  		DeclarationList: self.scope.declarationList,
   888  		File:            self.file,
   889  	}
   890  	self.file.SetSourceMap(self.parseSourceMap())
   891  	return prg
   892  }
   893  
   894  func extractSourceMapLine(str string) string {
   895  	for {
   896  		p := strings.LastIndexByte(str, '\n')
   897  		line := str[p+1:]
   898  		if line != "" && line != "})" {
   899  			if strings.HasPrefix(line, "//# sourceMappingURL=") {
   900  				return line
   901  			}
   902  			break
   903  		}
   904  		if p >= 0 {
   905  			str = str[:p]
   906  		} else {
   907  			break
   908  		}
   909  	}
   910  	return ""
   911  }
   912  
   913  func (self *_parser) parseSourceMap() *sourcemap.Consumer {
   914  	if self.opts.disableSourceMaps {
   915  		return nil
   916  	}
   917  	if smLine := extractSourceMapLine(self.str); smLine != "" {
   918  		urlIndex := strings.Index(smLine, "=")
   919  		urlStr := smLine[urlIndex+1:]
   920  
   921  		var data []byte
   922  		var err error
   923  		if strings.HasPrefix(urlStr, "data:application/json") {
   924  			b64Index := strings.Index(urlStr, ",")
   925  			b64 := urlStr[b64Index+1:]
   926  			data, err = base64.StdEncoding.DecodeString(b64)
   927  		} else {
   928  			if sourceURL := file.ResolveSourcemapURL(self.file.Name(), urlStr); sourceURL != nil {
   929  				if self.opts.sourceMapLoader != nil {
   930  					data, err = self.opts.sourceMapLoader(sourceURL.String())
   931  				} else {
   932  					if sourceURL.Scheme == "" || sourceURL.Scheme == "file" {
   933  						data, err = os.ReadFile(sourceURL.Path)
   934  					} else {
   935  						err = fmt.Errorf("unsupported source map URL scheme: %s", sourceURL.Scheme)
   936  					}
   937  				}
   938  			}
   939  		}
   940  
   941  		if err != nil {
   942  			self.error(file.Idx(0), "Could not load source map: %v", err)
   943  			return nil
   944  		}
   945  		if data == nil {
   946  			return nil
   947  		}
   948  
   949  		if sm, err := sourcemap.Parse(self.file.Name(), data); err == nil {
   950  			return sm
   951  		} else {
   952  			self.error(file.Idx(0), "Could not parse source map: %v", err)
   953  		}
   954  	}
   955  	return nil
   956  }
   957  
   958  func (self *_parser) parseBreakStatement() ast.Statement {
   959  	idx := self.expect(token.BREAK)
   960  	semicolon := self.implicitSemicolon
   961  	if self.token == token.SEMICOLON {
   962  		semicolon = true
   963  		self.next()
   964  	}
   965  
   966  	if semicolon || self.token == token.RIGHT_BRACE {
   967  		self.implicitSemicolon = false
   968  		if !self.scope.inIteration && !self.scope.inSwitch {
   969  			goto illegal
   970  		}
   971  		return &ast.BranchStatement{
   972  			Idx:   idx,
   973  			Token: token.BREAK,
   974  		}
   975  	}
   976  
   977  	self.tokenToBindingId()
   978  	if self.token == token.IDENTIFIER {
   979  		identifier := self.parseIdentifier()
   980  		if !self.scope.hasLabel(identifier.Name) {
   981  			self.error(idx, "Undefined label '%s'", identifier.Name)
   982  			return &ast.BadStatement{From: idx, To: identifier.Idx1()}
   983  		}
   984  		self.semicolon()
   985  		return &ast.BranchStatement{
   986  			Idx:   idx,
   987  			Token: token.BREAK,
   988  			Label: identifier,
   989  		}
   990  	}
   991  
   992  	self.expect(token.IDENTIFIER)
   993  
   994  illegal:
   995  	self.error(idx, "Illegal break statement")
   996  	self.nextStatement()
   997  	return &ast.BadStatement{From: idx, To: self.idx}
   998  }
   999  
  1000  func (self *_parser) parseContinueStatement() ast.Statement {
  1001  	idx := self.expect(token.CONTINUE)
  1002  	semicolon := self.implicitSemicolon
  1003  	if self.token == token.SEMICOLON {
  1004  		semicolon = true
  1005  		self.next()
  1006  	}
  1007  
  1008  	if semicolon || self.token == token.RIGHT_BRACE {
  1009  		self.implicitSemicolon = false
  1010  		if !self.scope.inIteration {
  1011  			goto illegal
  1012  		}
  1013  		return &ast.BranchStatement{
  1014  			Idx:   idx,
  1015  			Token: token.CONTINUE,
  1016  		}
  1017  	}
  1018  
  1019  	self.tokenToBindingId()
  1020  	if self.token == token.IDENTIFIER {
  1021  		identifier := self.parseIdentifier()
  1022  		if !self.scope.hasLabel(identifier.Name) {
  1023  			self.error(idx, "Undefined label '%s'", identifier.Name)
  1024  			return &ast.BadStatement{From: idx, To: identifier.Idx1()}
  1025  		}
  1026  		if !self.scope.inIteration {
  1027  			goto illegal
  1028  		}
  1029  		self.semicolon()
  1030  		return &ast.BranchStatement{
  1031  			Idx:   idx,
  1032  			Token: token.CONTINUE,
  1033  			Label: identifier,
  1034  		}
  1035  	}
  1036  
  1037  	self.expect(token.IDENTIFIER)
  1038  
  1039  illegal:
  1040  	self.error(idx, "Illegal continue statement")
  1041  	self.nextStatement()
  1042  	return &ast.BadStatement{From: idx, To: self.idx}
  1043  }
  1044  
  1045  // Find the next statement after an error (recover)
  1046  func (self *_parser) nextStatement() {
  1047  	for {
  1048  		switch self.token {
  1049  		case token.BREAK, token.CONTINUE,
  1050  			token.FOR, token.IF, token.RETURN, token.SWITCH,
  1051  			token.VAR, token.DO, token.TRY, token.WITH,
  1052  			token.WHILE, token.THROW, token.CATCH, token.FINALLY:
  1053  			// Return only if parser made some progress since last
  1054  			// sync or if it has not reached 10 next calls without
  1055  			// progress. Otherwise consume at least one token to
  1056  			// avoid an endless parser loop
  1057  			if self.idx == self.recover.idx && self.recover.count < 10 {
  1058  				self.recover.count++
  1059  				return
  1060  			}
  1061  			if self.idx > self.recover.idx {
  1062  				self.recover.idx = self.idx
  1063  				self.recover.count = 0
  1064  				return
  1065  			}
  1066  			// Reaching here indicates a parser bug, likely an
  1067  			// incorrect token list in this function, but it only
  1068  			// leads to skipping of possibly correct code if a
  1069  			// previous error is present, and thus is preferred
  1070  			// over a non-terminating parse.
  1071  		case token.EOF:
  1072  			return
  1073  		}
  1074  		self.next()
  1075  	}
  1076  }