Consolidate subslice offset into a single SubsliceOffset function
Remove the private subsliceOffset methods from both parser.go and errors.go. Replace them with a single exported SubsliceOffset function in ast.go (next to the Range type it serves). SubsliceOffset finds the byte offset by comparing element addresses: &data[i] == &subslice[0]. This is well-defined Go pointer comparison on elements of the same backing array. This fixes the v2.3.0 regression (#1047) where the parser's subsliceOffset used len(data) - len(b), which only works for suffix slices, not arbitrary subslices like error highlights. It also removes the reflect-based implementation from errors.go. Fixes #1047 Co-authored-by: Thomas Pelletier <thomas@pelletier.dev>
This commit is contained in:
@@ -99,7 +99,7 @@ func (e *DecodeError) Key() Key {
|
||||
//
|
||||
//nolint:funlen
|
||||
func wrapDecodeError(document []byte, de *unstable.ParserError) *DecodeError {
|
||||
offset := subsliceOffset(document, de.Highlight)
|
||||
offset := unstable.SubsliceOffset(document, de.Highlight)
|
||||
|
||||
errMessage := de.Error()
|
||||
errLine, errColumn := positionAtEnd(document[:offset])
|
||||
@@ -261,17 +261,3 @@ func positionAtEnd(b []byte) (row int, column int) {
|
||||
|
||||
return row, column
|
||||
}
|
||||
|
||||
// subsliceOffset finds the byte offset of subslice within data by
|
||||
// scanning for the matching element address.
|
||||
func subsliceOffset(data []byte, subslice []byte) int {
|
||||
if len(subslice) == 0 {
|
||||
return len(data)
|
||||
}
|
||||
for i := range data {
|
||||
if &data[i] == &subslice[0] {
|
||||
return i
|
||||
}
|
||||
}
|
||||
panic("subslice is not within data")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user