MCPcopy Index your code
hub / github.com/microsoft/typescript-go / parseBinaryExpressionRest

Method parseBinaryExpressionRest

internal/parser/parser.go:4585–4659  ·  view source on GitHub ↗
(precedence ast.OperatorPrecedence, leftOperand *ast.Expression, pos int)

Source from the content-addressed store, hash-verified

4583}
4584
4585func (p *Parser) parseBinaryExpressionRest(precedence ast.OperatorPrecedence, leftOperand *ast.Expression, pos int) *ast.Expression {
4586 lastOperand := leftOperand
4587 for {
4588 // We either have a binary operator here, or we're finished. We call
4589 // reScanGreaterToken so that we merge token sequences like > and = into >=
4590 operator := p.reScanGreaterThanToken()
4591 newPrecedence := ast.GetBinaryOperatorPrecedence(operator)
4592 // Check the precedence to see if we should "take" this operator
4593 // - For left associative operator (all operator but **), consume the operator,
4594 // recursively call the function below, and parse binaryExpression as a rightOperand
4595 // of the caller if the new precedence of the operator is greater then or equal to the current precedence.
4596 // For example:
4597 // a - b - c;
4598 // ^token; leftOperand = b. Return b to the caller as a rightOperand
4599 // a * b - c
4600 // ^token; leftOperand = b. Return b to the caller as a rightOperand
4601 // a - b * c;
4602 // ^token; leftOperand = b. Return b * c to the caller as a rightOperand
4603 // - For right associative operator (**), consume the operator, recursively call the function
4604 // and parse binaryExpression as a rightOperand of the caller if the new precedence of
4605 // the operator is strictly grater than the current precedence
4606 // For example:
4607 // a ** b ** c;
4608 // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
4609 // a - b ** c;
4610 // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
4611 // a ** b - c
4612 // ^token; leftOperand = b. Return b to the caller as a rightOperand
4613 var consumeCurrentOperator bool
4614 if operator == ast.KindAsteriskAsteriskToken {
4615 consumeCurrentOperator = newPrecedence >= precedence
4616 } else {
4617 consumeCurrentOperator = newPrecedence > precedence
4618 }
4619 if !consumeCurrentOperator {
4620 break
4621 }
4622 if operator == ast.KindInKeyword && p.inDisallowInContext() {
4623 break
4624 }
4625 if operator == ast.KindAsKeyword || operator == ast.KindSatisfiesKeyword {
4626 // Make sure we *do* perform ASI for constructs like this:
4627 // var x = foo
4628 // as (Bar)
4629 // This should be parsed as an initialized variable, followed
4630 // by a function call to 'as' with the argument 'Bar'
4631 if p.hasPrecedingLineBreak() {
4632 break
4633 } else {
4634 p.nextToken()
4635 // When we have 'a ## b as SomeType' or 'a ## b satisfies SomeType', where ## is some binary
4636 // operator, we want to stop parsing on any following operator with a higher precedence than ##
4637 // because continuing would make it impossible to erase the `as` or `satisfies` without changing
4638 // the meaning of the expression. See https://github.com/microsoft/TypeScript/issues/63527.
4639 lastPrecedence := ast.OperatorPrecedenceHighest
4640 if ast.IsBinaryExpression(lastOperand) {
4641 lastPrecedence = ast.GetBinaryOperatorPrecedence(lastOperand.AsBinaryExpression().OperatorToken.Kind)
4642 }

Calls 13

inDisallowInContextMethod · 0.95
hasPrecedingLineBreakMethod · 0.95
nextTokenMethod · 0.95
parseTypeMethod · 0.95
makeAsExpressionMethod · 0.95
makeBinaryExpressionMethod · 0.95
parseTokenNodeMethod · 0.95
IsBinaryExpressionFunction · 0.92

Tested by

no test coverage detected