hcl/zcl/hclhil/shim.go

68 lines
1.7 KiB
Go

package hclhil
import (
hclparser "github.com/hashicorp/hcl/hcl/parser"
hcltoken "github.com/hashicorp/hcl/hcl/token"
"github.com/hashicorp/hcl2/zcl"
hilast "github.com/hashicorp/hil/ast"
hilparser "github.com/hashicorp/hil/parser"
)
// errorRange attempts to extract a source range from the given error,
// returning a pointer to the range if possible or nil if not.
//
// errorRange understands HCL's "PosError" type, which wraps an error
// with a source position.
func errorRange(err error) *zcl.Range {
switch terr := err.(type) {
case *hclparser.PosError:
rng := rangeFromHCLPos(terr.Pos)
return &rng
case *hilparser.ParseError:
rng := rangeFromHILPos(terr.Pos)
return &rng
default:
return nil
}
}
func rangeFromHCLPos(pos hcltoken.Pos) zcl.Range {
// HCL only marks single positions rather than ranges, so we adapt this
// by creating a single-character range at the given position.
return zcl.Range{
Filename: pos.Filename,
Start: zcl.Pos{
Byte: pos.Offset,
Line: pos.Line,
Column: pos.Column,
},
End: zcl.Pos{
Byte: pos.Offset + 1,
Line: pos.Line,
Column: pos.Column + 1,
},
}
}
func rangeFromHILPos(pos hilast.Pos) zcl.Range {
// HIL only marks single positions rather than ranges, so we adapt this
// by creating a single-character range at the given position.
// HIL also doesn't track byte offsets, so we will hard-code these to
// zero so that no position can be considered to be "inside" these
// from a byte offset perspective.
return zcl.Range{
Filename: pos.Filename,
Start: zcl.Pos{
Byte: 0,
Line: pos.Line,
Column: pos.Column,
},
End: zcl.Pos{
Byte: 0,
Line: pos.Line,
Column: pos.Column + 1,
},
}
}