base int // Pos value range for this file is [base...base+size]
size int // file size as provided to AddFile
- // lines and infos are protected by set.mutex
+ // lines and infos are protected by mutex
+ mutex sync.Mutex
lines []int // lines contains the offset of the first character for each line (the first entry is always 0)
infos []lineInfo
}
// LineCount returns the number of lines in file f.
func (f *File) LineCount() int {
- f.set.mutex.RLock()
+ f.mutex.Lock()
n := len(f.lines)
- f.set.mutex.RUnlock()
+ f.mutex.Unlock()
return n
}
// and smaller than the file size; otherwise the line offset is ignored.
//
func (f *File) AddLine(offset int) {
- f.set.mutex.Lock()
+ f.mutex.Lock()
if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
f.lines = append(f.lines, offset)
}
- f.set.mutex.Unlock()
+ f.mutex.Unlock()
}
// MergeLine merges a line with the following line. It is akin to replacing
if line <= 0 {
panic("illegal line number (line numbering starts at 1)")
}
- f.set.mutex.Lock()
- defer f.set.mutex.Unlock()
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
if line >= len(f.lines) {
panic("illegal line number")
}
}
// set lines table
- f.set.mutex.Lock()
+ f.mutex.Lock()
f.lines = lines
- f.set.mutex.Unlock()
+ f.mutex.Unlock()
return true
}
}
// set lines table
- f.set.mutex.Lock()
+ f.mutex.Lock()
f.lines = lines
- f.set.mutex.Unlock()
+ f.mutex.Unlock()
}
// A lineInfo object describes alternative file and line number
// information for //line filename:line comments in source files.
//
func (f *File) AddLineInfo(offset int, filename string, line int) {
- f.set.mutex.Lock()
+ f.mutex.Lock()
if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size {
f.infos = append(f.infos, lineInfo{offset, filename, line})
}
- f.set.mutex.Unlock()
+ f.mutex.Unlock()
}
// Pos returns the Pos value for the given file offset;
// possibly adjusted by //line comments; otherwise those comments are ignored.
//
func (f *File) unpack(offset int, adjusted bool) (filename string, line, column int) {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
filename = f.name
if i := searchInts(f.lines, offset); i >= 0 {
line, column = i+1, offset-f.lines[i]+1
panic("illegal base or size")
}
// base >= s.base && size >= 0
- f := &File{s, filename, base, size, []int{0}, nil}
+ f := &File{set: s, name: filename, base: base, size: size, lines: []int{0}}
base += size + 1 // +1 because EOF also has a position
if base < 0 {
panic("token.Pos offset overflow (> 2G of source code in file set)")
func (s *FileSet) PositionFor(p Pos, adjusted bool) (pos Position) {
if p != NoPos {
if f := s.file(p); f != nil {
- s.mutex.RLock()
- pos = f.position(p, adjusted)
- s.mutex.RUnlock()
+ return f.position(p, adjusted)
}
}
return
files := make([]*File, len(ss.Files))
for i := 0; i < len(ss.Files); i++ {
f := &ss.Files[i]
- files[i] = &File{s, f.Name, f.Base, f.Size, f.Lines, f.Infos}
+ files[i] = &File{
+ set: s,
+ name: f.Name,
+ base: f.Base,
+ size: f.Size,
+ lines: f.Lines,
+ infos: f.Infos,
+ }
}
s.files = files
s.last = nil
ss.Base = s.base
files := make([]serializedFile, len(s.files))
for i, f := range s.files {
- files[i] = serializedFile{f.name, f.base, f.size, f.lines, f.infos}
+ f.mutex.Lock()
+ files[i] = serializedFile{
+ Name: f.name,
+ Base: f.base,
+ Size: f.size,
+ Lines: append([]int(nil), f.lines...),
+ Infos: append([]lineInfo(nil), f.infos...),
+ }
+ f.mutex.Unlock()
}
ss.Files = files
s.mutex.Unlock()