hcl: RangeOver function
This is a generalization of RangeBetween that finds a single range that covers the full extent of both given ranges, possibly also including some additional content between the ranges if they do not overlap.
This commit is contained in:
parent
d34d4686fb
commit
1365a2cfe5
34
hcl/pos.go
34
hcl/pos.go
@ -60,6 +60,40 @@ func RangeBetween(start, end Range) Range {
|
||||
}
|
||||
}
|
||||
|
||||
// RangeOver returns a new range that covers both of the given ranges and
|
||||
// possibly additional content between them if the two ranges do not overlap.
|
||||
//
|
||||
// If either range is empty then it is ignored. The result is empty if both
|
||||
// given ranges are empty.
|
||||
//
|
||||
// The result is meaningless if the two ranges to not belong to the same
|
||||
// source file.
|
||||
func RangeOver(a, b Range) Range {
|
||||
if a.Empty() {
|
||||
return b
|
||||
}
|
||||
if b.Empty() {
|
||||
return a
|
||||
}
|
||||
|
||||
var start, end Pos
|
||||
if a.Start.Byte < b.Start.Byte {
|
||||
start = a.Start
|
||||
} else {
|
||||
start = b.Start
|
||||
}
|
||||
if a.End.Byte > b.End.Byte {
|
||||
end = a.End
|
||||
} else {
|
||||
end = b.End
|
||||
}
|
||||
return Range{
|
||||
Filename: a.Filename,
|
||||
Start: start,
|
||||
End: end,
|
||||
}
|
||||
}
|
||||
|
||||
// ContainsOffset returns true if and only if the given byte offset is within
|
||||
// the receiving Range.
|
||||
func (r Range) ContainsOffset(offset int) bool {
|
||||
|
150
hcl/pos_test.go
150
hcl/pos_test.go
@ -7,6 +7,156 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRangeOver(t *testing.T) {
|
||||
tests := []struct {
|
||||
A Range
|
||||
B Range
|
||||
Want Range
|
||||
}{
|
||||
{
|
||||
Range{ // ##
|
||||
Start: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
End: Pos{Byte: 4, Line: 1, Column: 5},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 0, Line: 1, Column: 1},
|
||||
End: Pos{Byte: 4, Line: 1, Column: 5},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // #####
|
||||
Start: Pos{Byte: 0, Line: 1, Column: 1},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
End: Pos{Byte: 6, Line: 1, Column: 7},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // #####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 6, Line: 1, Column: 7},
|
||||
},
|
||||
},
|
||||
{
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // ##
|
||||
Start: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
End: Pos{Byte: 4, Line: 1, Column: 5},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
Range{ // ###
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 4, Line: 1, Column: 5},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
Range{ // ###
|
||||
Start: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 1, Line: 1, Column: 2},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
Range{ // ####
|
||||
Start: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
End: Pos{Byte: 5, Line: 1, Column: 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
Range{ // ##
|
||||
Start: Pos{Byte: 0, Line: 1, Column: 1},
|
||||
End: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
},
|
||||
Range{ // ##
|
||||
Start: Pos{Byte: 4, Line: 1, Column: 5},
|
||||
End: Pos{Byte: 6, Line: 1, Column: 7},
|
||||
},
|
||||
Range{ // ######
|
||||
Start: Pos{Byte: 0, Line: 1, Column: 1},
|
||||
End: Pos{Byte: 6, Line: 1, Column: 7},
|
||||
},
|
||||
},
|
||||
{
|
||||
Range{ // ##
|
||||
Start: Pos{Byte: 4, Line: 1, Column: 5},
|
||||
End: Pos{Byte: 6, Line: 1, Column: 7},
|
||||
},
|
||||
Range{ // ##
|
||||
Start: Pos{Byte: 0, Line: 1, Column: 1},
|
||||
End: Pos{Byte: 2, Line: 1, Column: 3},
|
||||
},
|
||||
Range{ // ######
|
||||
Start: Pos{Byte: 0, Line: 1, Column: 1},
|
||||
End: Pos{Byte: 6, Line: 1, Column: 7},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("%s<=>%s", test.A, test.B), func(t *testing.T) {
|
||||
got := RangeOver(test.A, test.B)
|
||||
if !reflect.DeepEqual(got, test.Want) {
|
||||
t.Errorf(
|
||||
"wrong result\nA : %-10s %s\nB : %-10s %s\ngot : %-10s %s\nwant: %-10s %s",
|
||||
visRangeOffsets(test.A), test.A,
|
||||
visRangeOffsets(test.B), test.B,
|
||||
visRangeOffsets(got), got,
|
||||
visRangeOffsets(test.Want), test.Want,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPosOverlap(t *testing.T) {
|
||||
tests := []struct {
|
||||
A Range
|
||||
|
Loading…
Reference in New Issue
Block a user