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
|
// ContainsOffset returns true if and only if the given byte offset is within
|
||||||
// the receiving Range.
|
// the receiving Range.
|
||||||
func (r Range) ContainsOffset(offset int) bool {
|
func (r Range) ContainsOffset(offset int) bool {
|
||||||
|
150
hcl/pos_test.go
150
hcl/pos_test.go
@ -7,6 +7,156 @@ import (
|
|||||||
"testing"
|
"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) {
|
func TestPosOverlap(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
A Range
|
A Range
|
||||||
|
Loading…
Reference in New Issue
Block a user