MCPcopy
hub / github.com/hashicorp/hcl / parseExpressionTraversals

Method parseExpressionTraversals

hclsyntax/parser.go:625–926  ·  hclsyntax/parser.go::parser.parseExpressionTraversals
(from Expression)

Source from the content-addressed store, hash-verified

623}
624
625func (p *parser) parseExpressionTraversals(from Expression) (Expression, hcl.Diagnostics) {
626 var diags hcl.Diagnostics
627 ret := from
628
629Traversal:
630 for {
631 next := p.Peek()
632
633 switch next.Type {
634 case TokenDot:
635 // Attribute access or splat
636 dot := p.Read()
637 attrTok := p.Peek()
638
639 switch attrTok.Type {
640 case TokenIdent:
641 attrTok = p.Read() // eat token
642 name := string(attrTok.Bytes)
643 rng := hcl.RangeBetween(dot.Range, attrTok.Range)
644 step := hcl.TraverseAttr{
645 Name: name,
646 SrcRange: rng,
647 }
648
649 ret = makeRelativeTraversal(ret, step, rng)
650
651 case TokenNumberLit:
652 // This is a weird form we inherited from HIL, allowing numbers
653 // to be used as attributes as a weird way of writing [n].
654 // This was never actually a first-class thing in HIL, but
655 // HIL tolerated sequences like .0. in its variable names and
656 // calling applications like Terraform exploited that to
657 // introduce indexing syntax where none existed.
658 numTok := p.Read() // eat token
659 attrTok = numTok
660
661 // This syntax is ambiguous if multiple indices are used in
662 // succession, like foo.0.1.baz: that actually parses as
663 // a fractional number 0.1. Since we're only supporting this
664 // syntax for compatibility with legacy Terraform
665 // configurations, and Terraform does not tend to have lists
666 // of lists, we'll choose to reject that here with a helpful
667 // error message, rather than failing later because the index
668 // isn't a whole number.
669 if dotIdx := bytes.IndexByte(numTok.Bytes, '.'); dotIdx >= 0 {
670 first := numTok.Bytes[:dotIdx]
671 second := numTok.Bytes[dotIdx+1:]
672 diags = append(diags, &hcl.Diagnostic{
673 Severity: hcl.DiagError,
674 Summary: "Invalid legacy index syntax",
675 Detail: fmt.Sprintf("When using the legacy index syntax, chaining two indexes together is not permitted. Use the proper index syntax instead, like [%s][%s].", first, second),
676 Subject: &attrTok.Range,
677 })
678 rng := hcl.RangeBetween(dot.Range, numTok.Range)
679 step := hcl.TraverseIndex{
680 Key: cty.DynamicVal,
681 SrcRange: rng,
682 }

Callers 1

Calls 15

numberLitValueMethod · 0.95
setRecoveryMethod · 0.95
recoverMethod · 0.95
RangeMethod · 0.95
ParseExpressionMethod · 0.95
makeRelativeTraversalFunction · 0.85
NextRangeMethod · 0.80
PtrMethod · 0.80
PushIncludeNewlinesMethod · 0.80
HasErrorsMethod · 0.80
PopIncludeNewlinesMethod · 0.80
IsStringLiteralMethod · 0.80

Tested by

no test coverage detected