...

Source file src/github.com/dop251/goja/parser/statement.go

Documentation: github.com/dop251/goja/parser

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

View as plain text