(pos int, expression *ast.Expression, allowOptionalChain bool)
| 5345 | } |
| 5346 | |
| 5347 | func (p *Parser) parseMemberExpressionRest(pos int, expression *ast.Expression, allowOptionalChain bool) *ast.Expression { |
| 5348 | for { |
| 5349 | var questionDotToken *ast.Node |
| 5350 | isPropertyAccess := false |
| 5351 | if allowOptionalChain && p.isStartOfOptionalPropertyOrElementAccessChain() { |
| 5352 | questionDotToken = p.parseExpectedToken(ast.KindQuestionDotToken) |
| 5353 | isPropertyAccess = tokenIsIdentifierOrKeyword(p.token) |
| 5354 | } else { |
| 5355 | isPropertyAccess = p.parseOptional(ast.KindDotToken) |
| 5356 | } |
| 5357 | if isPropertyAccess { |
| 5358 | expression = p.parsePropertyAccessExpressionRest(pos, expression, questionDotToken) |
| 5359 | continue |
| 5360 | } |
| 5361 | // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName |
| 5362 | if (questionDotToken != nil || !p.inDecoratorContext()) && p.parseOptional(ast.KindOpenBracketToken) { |
| 5363 | expression = p.parseElementAccessExpressionRest(pos, expression, questionDotToken) |
| 5364 | continue |
| 5365 | } |
| 5366 | if p.isTemplateStartOfTaggedTemplate() { |
| 5367 | // Absorb type arguments into TemplateExpression when preceding expression is ExpressionWithTypeArguments |
| 5368 | if questionDotToken == nil && ast.IsExpressionWithTypeArguments(expression) { |
| 5369 | original := expression.AsExpressionWithTypeArguments() |
| 5370 | expression = p.parseTaggedTemplateRest(pos, original.Expression, questionDotToken, original.TypeArguments) |
| 5371 | p.unparseExpressionWithTypeArguments(original.Expression, original.TypeArguments, expression) |
| 5372 | } else { |
| 5373 | expression = p.parseTaggedTemplateRest(pos, expression, questionDotToken, nil /*typeArguments*/) |
| 5374 | } |
| 5375 | continue |
| 5376 | } |
| 5377 | if questionDotToken == nil { |
| 5378 | if p.token == ast.KindExclamationToken && !p.hasPrecedingLineBreak() { |
| 5379 | p.nextToken() |
| 5380 | expression = p.checkJSSyntax(p.finishNode(p.factory.NewNonNullExpression(expression, ast.NodeFlagsNone), pos)) |
| 5381 | continue |
| 5382 | } |
| 5383 | typeArguments := p.tryParseTypeArgumentsInExpression() |
| 5384 | if typeArguments != nil { |
| 5385 | expression = p.finishNode(p.factory.NewExpressionWithTypeArguments(expression, typeArguments), pos) |
| 5386 | continue |
| 5387 | } |
| 5388 | } |
| 5389 | return expression |
| 5390 | } |
| 5391 | } |
| 5392 | |
| 5393 | func (p *Parser) isStartOfOptionalPropertyOrElementAccessChain() bool { |
| 5394 | return p.token == ast.KindQuestionDotToken && p.lookAhead((*Parser).nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate) |
no test coverage detected