aboutsummaryrefslogtreecommitdiff
path: root/internal/span/token.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/span/token.go')
-rw-r--r--internal/span/token.go194
1 files changed, 0 insertions, 194 deletions
diff --git a/internal/span/token.go b/internal/span/token.go
deleted file mode 100644
index 6f8b9b570..000000000
--- a/internal/span/token.go
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package span
-
-import (
- "fmt"
- "go/token"
-)
-
-// Range represents a source code range in token.Pos form.
-// It also carries the FileSet that produced the positions, so that it is
-// self contained.
-type Range struct {
- FileSet *token.FileSet
- Start token.Pos
- End token.Pos
- Converter Converter
-}
-
-type FileConverter struct {
- file *token.File
-}
-
-// TokenConverter is a Converter backed by a token file set and file.
-// It uses the file set methods to work out the conversions, which
-// makes it fast and does not require the file contents.
-type TokenConverter struct {
- FileConverter
- fset *token.FileSet
-}
-
-// NewRange creates a new Range from a FileSet and two positions.
-// To represent a point pass a 0 as the end pos.
-func NewRange(fset *token.FileSet, start, end token.Pos) Range {
- return Range{
- FileSet: fset,
- Start: start,
- End: end,
- }
-}
-
-// NewTokenConverter returns an implementation of Converter backed by a
-// token.File.
-func NewTokenConverter(fset *token.FileSet, f *token.File) *TokenConverter {
- return &TokenConverter{fset: fset, FileConverter: FileConverter{file: f}}
-}
-
-// NewContentConverter returns an implementation of Converter for the
-// given file content.
-func NewContentConverter(filename string, content []byte) *TokenConverter {
- fset := token.NewFileSet()
- f := fset.AddFile(filename, -1, len(content))
- f.SetLinesForContent(content)
- return NewTokenConverter(fset, f)
-}
-
-// IsPoint returns true if the range represents a single point.
-func (r Range) IsPoint() bool {
- return r.Start == r.End
-}
-
-// Span converts a Range to a Span that represents the Range.
-// It will fill in all the members of the Span, calculating the line and column
-// information.
-func (r Range) Span() (Span, error) {
- if !r.Start.IsValid() {
- return Span{}, fmt.Errorf("start pos is not valid")
- }
- f := r.FileSet.File(r.Start)
- if f == nil {
- return Span{}, fmt.Errorf("file not found in FileSet")
- }
- return FileSpan(f, r.Converter, r.Start, r.End)
-}
-
-// FileSpan returns a span within tok, using converter to translate between
-// offsets and positions.
-func FileSpan(tok *token.File, converter Converter, start, end token.Pos) (Span, error) {
- var s Span
- var err error
- var startFilename string
- startFilename, s.v.Start.Line, s.v.Start.Column, err = position(tok, start)
- if err != nil {
- return Span{}, err
- }
- s.v.URI = URIFromPath(startFilename)
- if end.IsValid() {
- var endFilename string
- endFilename, s.v.End.Line, s.v.End.Column, err = position(tok, end)
- if err != nil {
- return Span{}, err
- }
- // In the presence of line directives, a single File can have sections from
- // multiple file names.
- if endFilename != startFilename {
- return Span{}, fmt.Errorf("span begins in file %q but ends in %q", startFilename, endFilename)
- }
- }
- s.v.Start.clean()
- s.v.End.clean()
- s.v.clean()
- if converter != nil {
- return s.WithOffset(converter)
- }
- if startFilename != tok.Name() {
- return Span{}, fmt.Errorf("must supply Converter for file %q containing lines from %q", tok.Name(), startFilename)
- }
- return s.WithOffset(&FileConverter{tok})
-}
-
-func position(f *token.File, pos token.Pos) (string, int, int, error) {
- off, err := offset(f, pos)
- if err != nil {
- return "", 0, 0, err
- }
- return positionFromOffset(f, off)
-}
-
-func positionFromOffset(f *token.File, offset int) (string, int, int, error) {
- if offset > f.Size() {
- return "", 0, 0, fmt.Errorf("offset %v is past the end of the file %v", offset, f.Size())
- }
- pos := f.Pos(offset)
- p := f.Position(pos)
- // TODO(golang/go#41029): Consider returning line, column instead of line+1, 1 if
- // the file's last character is not a newline.
- if offset == f.Size() {
- return p.Filename, p.Line + 1, 1, nil
- }
- return p.Filename, p.Line, p.Column, nil
-}
-
-// offset is a copy of the Offset function in go/token, but with the adjustment
-// that it does not panic on invalid positions.
-func offset(f *token.File, pos token.Pos) (int, error) {
- if int(pos) < f.Base() || int(pos) > f.Base()+f.Size() {
- return 0, fmt.Errorf("invalid pos")
- }
- return int(pos) - f.Base(), nil
-}
-
-// Range converts a Span to a Range that represents the Span for the supplied
-// File.
-func (s Span) Range(converter *TokenConverter) (Range, error) {
- s, err := s.WithOffset(converter)
- if err != nil {
- return Range{}, err
- }
- // 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 %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 %v", s.End(), converter.file.Size())
- }
- return Range{
- FileSet: converter.fset,
- Start: converter.file.Pos(s.Start().Offset()),
- End: converter.file.Pos(s.End().Offset()),
- Converter: converter,
- }, nil
-}
-
-func (l *FileConverter) ToPosition(offset int) (int, int, error) {
- _, line, col, err := positionFromOffset(l.file, offset)
- return line, col, err
-}
-
-func (l *FileConverter) ToOffset(line, col int) (int, error) {
- if line < 0 {
- return -1, fmt.Errorf("line is not valid")
- }
- lineMax := l.file.LineCount() + 1
- if line > lineMax {
- 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")
- }
- // at the end of the file, allowing for a trailing eol
- return l.file.Size(), nil
- }
- pos := lineStart(l.file, line)
- if !pos.IsValid() {
- return -1, fmt.Errorf("line is not in file")
- }
- // we assume that column is in bytes here, and that the first byte of a
- // line is at column 1
- pos += token.Pos(col - 1)
- return offset(l.file, pos)
-}