]> Cypherpunks repositories - gostls13.git/commitdiff
token/position.go: provide FileSet.File(), minor optimizations
authorRobert Griesemer <gri@golang.org>
Wed, 8 Dec 2010 05:50:08 +0000 (21:50 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 8 Dec 2010 05:50:08 +0000 (21:50 -0800)
R=rsc
CC=golang-dev
https://golang.org/cl/3399042

src/pkg/go/token/position.go
src/pkg/go/token/position_test.go

index 64a89c2814e5121ec4778b99426017e8c4c4e1f2..10ec0e39b79bb37448c3b35779375fca9c3b1a84 100644 (file)
@@ -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
+
 }
 
 
index 7e5f3d3dfad79e776895586652487bde19b4954b..bc10ef6c0ae2acc9d7c5ab070b495c81e8c6b834 100644 (file)
@@ -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 {