internal/span: end of file is now last line +1
We already accepted it as a valid input, but for output we still produced
last_line,last_column+1
Also add package docs and improve error messages
Change-Id: I017aa326e8392134e67e8fabec47e750c8055454
Reviewed-on: https://go-review.googlesource.com/c/tools/+/199641
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/span/span.go b/internal/span/span.go
index b66bd7a..4d2ad09 100644
--- a/internal/span/span.go
+++ b/internal/span/span.go
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// Package span contains support for representing with positions and ranges in
+// text files.
package span
import (
@@ -34,6 +36,9 @@
Offset int `json:"offset"`
}
+// Invalid is a span that reports false from IsValid
+var Invalid = Span{v: span{Start: invalidPoint.v, End: invalidPoint.v}}
+
var invalidPoint = Point{v: point{Line: 0, Column: 0, Offset: -1}}
// Converter is the interface to an object that can convert between line:column
diff --git a/internal/span/token.go b/internal/span/token.go
index 4efd0c8..ce44541 100644
--- a/internal/span/token.go
+++ b/internal/span/token.go
@@ -102,10 +102,10 @@
// go/token will panic if the offset is larger than the file's size,
// so check here to avoid panicking.
if s.Start().Offset() > converter.file.Size() {
- return Range{}, fmt.Errorf("start offset %v is past the end of the file", s.Start())
+ return Range{}, fmt.Errorf("start offset %v is past the end of the file %v", s.Start(), converter.file.Size())
}
if s.End().Offset() > converter.file.Size() {
- return Range{}, fmt.Errorf("end offset %v is past the end of the file", s.End())
+ return Range{}, fmt.Errorf("end offset %v is past the end of the file %v", s.End(), converter.file.Size())
}
return Range{
FileSet: converter.fset,
@@ -116,10 +116,13 @@
func (l *TokenConverter) ToPosition(offset int) (int, int, error) {
if offset > l.file.Size() {
- return 0, 0, fmt.Errorf("offset %v is past the end of the file", offset)
+ return 0, 0, fmt.Errorf("offset %v is past the end of the file %v", offset, l.file.Size())
}
pos := l.file.Pos(offset)
p := l.fset.Position(pos)
+ if offset == l.file.Size() {
+ return p.Line + 1, 1, nil
+ }
return p.Line, p.Column, nil
}
@@ -129,7 +132,7 @@
}
lineMax := l.file.LineCount() + 1
if line > lineMax {
- return -1, fmt.Errorf("line is beyond end of file")
+ return -1, fmt.Errorf("line is beyond end of file %v", lineMax)
} else if line == lineMax {
if col > 1 {
return -1, fmt.Errorf("column is beyond end of file")
diff --git a/internal/span/token_test.go b/internal/span/token_test.go
index 7e5b467..c9fce77 100644
--- a/internal/span/token_test.go
+++ b/internal/span/token_test.go
@@ -24,14 +24,17 @@
//
//
// file b.go
-package test
-`)},
+package test`)},
+ {"/c.go", []byte(`
+// file c.go
+package test`)},
}
var tokenTests = []span.Span{
span.New(span.FileURI("/a.go"), span.NewPoint(1, 1, 0), span.Point{}),
span.New(span.FileURI("/a.go"), span.NewPoint(3, 7, 20), span.NewPoint(3, 7, 20)),
span.New(span.FileURI("/b.go"), span.NewPoint(4, 9, 15), span.NewPoint(4, 13, 19)),
+ span.New(span.FileURI("/c.go"), span.NewPoint(4, 1, 26), span.Point{}),
}
func TestToken(t *testing.T) {
@@ -70,6 +73,6 @@
expected := fmt.Sprintf("%+v", expect)
got := fmt.Sprintf("%+v", gotLoc)
if expected != got {
- t.Errorf("Expected %q got %q", expected, got)
+ t.Errorf("For %v expected %q got %q", in, expected, got)
}
}