()
| 480 | } |
| 481 | |
| 482 | func (p *parser) parseTernaryConditional() (Expression, hcl.Diagnostics) { |
| 483 | // The ternary conditional operator (.. ? .. : ..) behaves somewhat |
| 484 | // like a binary operator except that the "symbol" is itself |
| 485 | // an expression enclosed in two punctuation characters. |
| 486 | // The middle expression is parsed as if the ? and : symbols |
| 487 | // were parentheses. The "rhs" (the "false expression") is then |
| 488 | // treated right-associatively so it behaves similarly to the |
| 489 | // middle in terms of precedence. |
| 490 | |
| 491 | startRange := p.NextRange() |
| 492 | var condExpr, trueExpr, falseExpr Expression |
| 493 | var diags hcl.Diagnostics |
| 494 | |
| 495 | condExpr, condDiags := p.parseBinaryOps(binaryOps) |
| 496 | diags = append(diags, condDiags...) |
| 497 | if p.recovery && condDiags.HasErrors() { |
| 498 | return condExpr, diags |
| 499 | } |
| 500 | |
| 501 | questionMark := p.Peek() |
| 502 | if questionMark.Type != TokenQuestion { |
| 503 | return condExpr, diags |
| 504 | } |
| 505 | |
| 506 | p.Read() // eat question mark |
| 507 | |
| 508 | trueExpr, trueDiags := p.ParseExpression() |
| 509 | diags = append(diags, trueDiags...) |
| 510 | if p.recovery && trueDiags.HasErrors() { |
| 511 | return condExpr, diags |
| 512 | } |
| 513 | |
| 514 | colon := p.Peek() |
| 515 | if colon.Type != TokenColon { |
| 516 | diags = append(diags, &hcl.Diagnostic{ |
| 517 | Severity: hcl.DiagError, |
| 518 | Summary: "Missing false expression in conditional", |
| 519 | Detail: "The conditional operator (...?...:...) requires a false expression, delimited by a colon.", |
| 520 | Subject: &colon.Range, |
| 521 | Context: hcl.RangeBetween(startRange, colon.Range).Ptr(), |
| 522 | }) |
| 523 | return condExpr, diags |
| 524 | } |
| 525 | |
| 526 | p.Read() // eat colon |
| 527 | |
| 528 | falseExpr, falseDiags := p.ParseExpression() |
| 529 | diags = append(diags, falseDiags...) |
| 530 | if p.recovery && falseDiags.HasErrors() { |
| 531 | return condExpr, diags |
| 532 | } |
| 533 | |
| 534 | return &ConditionalExpr{ |
| 535 | Condition: condExpr, |
| 536 | TrueResult: trueExpr, |
| 537 | FalseResult: falseExpr, |
| 538 | |
| 539 | SrcRange: hcl.RangeBetween(startRange, falseExpr.Range()), |
no test coverage detected