const debug … type Position … // IsValid reports whether the position is valid. func (pos *Position) IsValid() bool { … } // String returns a string in one of several forms: // // file:line:column valid position with file name // file:line valid position with file name but no column (column == 0) // line:column valid position without file name // line valid position without file name and no column (column == 0) // file invalid position with file name // - invalid position without file name func (pos Position) String() string { … } type Pos … const NoPos … // IsValid reports whether the position is valid. func (p Pos) IsValid() bool { … } type File … // Name returns the file name of file f as registered with AddFile. func (f *File) Name() string { … } // Base returns the base offset of file f as registered with AddFile. func (f *File) Base() int { … } // Size returns the size of file f as registered with AddFile. func (f *File) Size() int { … } // LineCount returns the number of lines in file f. func (f *File) LineCount() int { … } // AddLine adds the line offset for a new line. // The line offset must be larger than the offset for the previous line // and smaller than the file size; otherwise the line offset is ignored. func (f *File) AddLine(offset int) { … } // MergeLine merges a line with the following line. It is akin to replacing // the newline character at the end of the line with a space (to not change the // remaining offsets). To obtain the line number, consult e.g. [Position.Line]. // MergeLine will panic if given an invalid line number. func (f *File) MergeLine(line int) { … } // Lines returns the effective line offset table of the form described by [File.SetLines]. // Callers must not mutate the result. func (f *File) Lines() []int { … } // SetLines sets the line offsets for a file and reports whether it succeeded. // The line offsets are the offsets of the first character of each line; // for instance for the content "ab\nc\n" the line offsets are {0, 3}. // An empty file has an empty line offset table. // Each line offset must be larger than the offset for the previous line // and smaller than the file size; otherwise SetLines fails and returns // false. // Callers must not mutate the provided slice after SetLines returns. func (f *File) SetLines(lines []int) bool { … } // SetLinesForContent sets the line offsets for the given file content. // It ignores position-altering //line comments. func (f *File) SetLinesForContent(content []byte) { … } // LineStart returns the [Pos] value of the start of the specified line. // It ignores any alternative positions set using [File.AddLineColumnInfo]. // LineStart panics if the 1-based line number is invalid. func (f *File) LineStart(line int) Pos { … } type lineInfo … // AddLineInfo is like [File.AddLineColumnInfo] with a column = 1 argument. // It is here for backward-compatibility for code prior to Go 1.11. func (f *File) AddLineInfo(offset int, filename string, line int) { … } // AddLineColumnInfo adds alternative file, line, and column number // information for a given file offset. The offset must be larger // than the offset for the previously added alternative line info // and smaller than the file size; otherwise the information is // ignored. // // AddLineColumnInfo is typically used to register alternative position // information for line directives such as //line filename:line:column. func (f *File) AddLineColumnInfo(offset int, filename string, line, column int) { … } // fixOffset fixes an out-of-bounds offset such that 0 <= offset <= f.size. func (f *File) fixOffset(offset int) int { … } // Pos returns the Pos value for the given file offset. // // If offset is negative, the result is the file's start // position; if the offset is too large, the result is // the file's end position (see also go.dev/issue/57490). // // The following invariant, though not true for Pos values // in general, holds for the result p: // f.Pos(f.Offset(p)) == p. func (f *File) Pos(offset int) Pos { … } // Offset returns the offset for the given file position p. // // If p is before the file's start position (or if p is NoPos), // the result is 0; if p is past the file's end position, // the result is the file size (see also go.dev/issue/57490). // // The following invariant, though not true for offset values // in general, holds for the result offset: // f.Offset(f.Pos(offset)) == offset func (f *File) Offset(p Pos) int { … } // Line returns the line number for the given file position p; // p must be a [Pos] value in that file or [NoPos]. func (f *File) Line(p Pos) int { … } func searchLineInfos(a []lineInfo, x int) int { … } // unpack returns the filename and line and column number for a file offset. // If adjusted is set, unpack will return the filename and line information // possibly adjusted by //line comments; otherwise those comments are ignored. func (f *File) unpack(offset int, adjusted bool) (filename string, line, column int) { … } func (f *File) position(p Pos, adjusted bool) (pos Position) { … } // PositionFor returns the Position value for the given file position p. // If p is out of bounds, it is adjusted to match the File.Offset behavior. // If adjusted is set, the position may be adjusted by position-altering // //line comments; otherwise those comments are ignored. // p must be a Pos value in f or NoPos. func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) { … } // Position returns the Position value for the given file position p. // If p is out of bounds, it is adjusted to match the File.Offset behavior. // Calling f.Position(p) is equivalent to calling f.PositionFor(p, true). func (f *File) Position(p Pos) (pos Position) { … } type FileSet … // NewFileSet creates a new file set. func NewFileSet() *FileSet { … } // Base returns the minimum base offset that must be provided to // [FileSet.AddFile] when adding the next file. func (s *FileSet) Base() int { … } // AddFile adds a new file with a given filename, base offset, and file size // to the file set s and returns the file. Multiple files may have the same // name. The base offset must not be smaller than the [FileSet.Base], and // size must not be negative. As a special case, if a negative base is provided, // the current value of the [FileSet.Base] is used instead. // // Adding the file will set the file set's [FileSet.Base] value to base + size + 1 // as the minimum base value for the next file. The following relationship // exists between a [Pos] value p for a given file offset offs: // // int(p) = base + offs // // with offs in the range [0, size] and thus p in the range [base, base+size]. // For convenience, [File.Pos] may be used to create file-specific position // values from a file offset. func (s *FileSet) AddFile(filename string, base, size int) *File { … } // RemoveFile removes a file from the [FileSet] so that subsequent // queries for its [Pos] interval yield a negative result. // This reduces the memory usage of a long-lived [FileSet] that // encounters an unbounded stream of files. // // Removing a file that does not belong to the set has no effect. func (s *FileSet) RemoveFile(file *File) { … } // Iterate calls f for the files in the file set in the order they were added // until f returns false. func (s *FileSet) Iterate(f func(*File) bool) { … } func searchFiles(a []*File, x int) int { … } func (s *FileSet) file(p Pos) *File { … } // File returns the file that 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) { … } // PositionFor converts a [Pos] p in the fileset into a [Position] value. // If adjusted is set, the position may be adjusted by position-altering // //line comments; otherwise those comments are ignored. // p must be a [Pos] value in s or [NoPos]. func (s *FileSet) PositionFor(p Pos, adjusted bool) (pos Position) { … } // Position converts a [Pos] p in the fileset into a Position value. // Calling s.Position(p) is equivalent to calling s.PositionFor(p, true). func (s *FileSet) Position(p Pos) (pos Position) { … } func searchInts(a []int, x int) int { … }