Commit 1612b873 authored by Robert Griesemer's avatar Robert Griesemer

token/position.go: provide FileSet.File(), minor optimizations

R=rsc
CC=golang-dev
https://golang.org/cl/3399042
parent 1e287646
......@@ -25,14 +25,6 @@ type Position struct {
}
// TODO(gri): Remove Pos() below once all code is switched to using token.Pos.
// Pos is an accessor method for anonymous Position fields.
// It returns its receiver.
//
func (pos *Position) Pos() Position { return *pos }
// IsValid returns true if the position is valid.
func (pos *Position) IsValid() bool { return pos.Line > 0 }
......@@ -113,6 +105,28 @@ func (s *FileSet) file(p Pos) *File {
}
// File returns the file which contains the position p.
// If no such file is found (for instance for p == NoPos),
// the result is nil.
//
func (s *FileSet) File(p Pos) (f *File) {
if p != NoPos {
s.mutex.RLock()
f = s.file(p)
s.mutex.RUnlock()
}
return
}
func (f *File) position(p Pos) (pos Position) {
offset := int(p) - f.base
pos.Offset = offset
pos.Filename, pos.Line, pos.Column = f.info(offset)
return
}
// Position converts a Pos in the fileset into a general Position.
func (s *FileSet) Position(p Pos) (pos Position) {
if p != NoPos {
......@@ -122,9 +136,7 @@ func (s *FileSet) Position(p Pos) (pos Position) {
// of search
s.mutex.RLock()
if f := s.file(p); f != nil {
offset := int(p) - f.base
pos.Offset = offset
pos.Filename, pos.Line, pos.Column = f.info(offset)
pos = f.position(p)
}
s.mutex.RUnlock()
}
......@@ -274,8 +286,7 @@ func (f *File) Position(p Pos) (pos Position) {
if int(p) < f.base || int(p) > f.base+f.size {
panic("illegal Pos value")
}
// TODO(gri) compute Position directly instead of going via the fset!
pos = f.set.Position(p)
pos = f.position(p)
}
return
}
......@@ -309,6 +320,9 @@ func (f *File) info(offset int) (filename string, line, column int) {
// A FileSet represents a set of source files.
// Methods of file sets are synchronized; multiple goroutines
// may invoke them concurrently.
//
type FileSet struct {
mutex sync.RWMutex // protects the file set
base int // base offset for the next file
......@@ -330,7 +344,11 @@ func NewFileSet() *FileSet {
// AddFile when adding the next file.
//
func (s *FileSet) Base() int {
return s.base
s.mutex.RLock()
b := s.base
s.mutex.RUnlock()
return b
}
......
......@@ -89,6 +89,9 @@ func TestPositions(t *testing.T) {
if f.Size() != test.size {
t.Errorf("%s: expected file size %d; got %d", f.Name(), test.size, f.Size())
}
if fset.File(f.Pos(0)) != f {
t.Errorf("%s: f.Pos(0) was not found in f", f.Name())
}
// add lines individually and verify all positions
for i, offset := range test.lines {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment