Remove optional offset and fallback, guarantee offset by construction
ParserError.Offset is now a plain exported int field, always set: - The parser sets it via setErrOffset() when capturing parse errors - strict.go sets it from the key's Raw range at construction - wrapDecodeError computes it inline from cap(document) - cap(highlight) This eliminates: - The SetOffset/Offset() accessor methods and offsetValid flag - The subsliceOffset fallback function in errors.go - Any conditional logic around whether the offset is present The offset is guaranteed by construction at every path that creates or consumes a ParserError. Co-authored-by: Thomas Pelletier <thomas@pelletier.dev>
This commit is contained in:
+11
-25
@@ -18,8 +18,9 @@ type ParserError struct {
|
||||
Message string
|
||||
Key []string // optional
|
||||
|
||||
offset int
|
||||
offsetValid bool
|
||||
// Offset is the byte offset of Highlight within the document.
|
||||
// Set by the parser when the error is captured.
|
||||
Offset int
|
||||
}
|
||||
|
||||
// Error is the implementation of the error interface.
|
||||
@@ -27,21 +28,6 @@ func (e *ParserError) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// SetOffset records the byte offset of the error highlight within the
|
||||
// document. Used by the parser to cache position information so
|
||||
// downstream consumers don't need to re-derive it from pointers.
|
||||
func (e *ParserError) SetOffset(offset int) {
|
||||
e.offset = offset
|
||||
e.offsetValid = true
|
||||
}
|
||||
|
||||
// Offset returns the byte offset of the error highlight within the
|
||||
// document, if it was previously set by the parser. The boolean
|
||||
// indicates whether the offset is valid.
|
||||
func (e *ParserError) Offset() (int, bool) {
|
||||
return e.offset, e.offsetValid
|
||||
}
|
||||
|
||||
// NewParserError is a convenience function to create a ParserError
|
||||
//
|
||||
// Warning: Highlight needs to be a subslice of Parser.data, so only slices
|
||||
@@ -145,11 +131,15 @@ func (p *Parser) NextExpression() bool {
|
||||
p.left, p.err = p.parseNewline(p.left)
|
||||
}
|
||||
|
||||
if len(p.left) == 0 || p.err != nil {
|
||||
if p.err != nil {
|
||||
p.setErrOffset()
|
||||
return false
|
||||
}
|
||||
|
||||
if len(p.left) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
p.ref, p.left, p.err = p.parseExpression(p.left)
|
||||
|
||||
if p.err != nil {
|
||||
@@ -176,9 +166,8 @@ func (p *Parser) Error() error {
|
||||
return p.err
|
||||
}
|
||||
|
||||
// setErrOffset computes and caches the byte offset of the error's
|
||||
// highlight within p.data, so downstream consumers can use it
|
||||
// without pointer arithmetic.
|
||||
// setErrOffset sets the byte offset on the parser error from the
|
||||
// highlight's position within p.data.
|
||||
func (p *Parser) setErrOffset() {
|
||||
if p.err == nil {
|
||||
return
|
||||
@@ -187,10 +176,7 @@ func (p *Parser) setErrOffset() {
|
||||
if !errors.As(p.err, &perr) {
|
||||
return
|
||||
}
|
||||
if perr.offsetValid || len(perr.Highlight) == 0 {
|
||||
return
|
||||
}
|
||||
perr.SetOffset(p.subsliceOffset(perr.Highlight))
|
||||
perr.Offset = p.subsliceOffset(perr.Highlight)
|
||||
}
|
||||
|
||||
// Position describes a position in the input.
|
||||
|
||||
Reference in New Issue
Block a user