aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/hexops/gotextdiff/span
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2025-01-22 16:07:17 +0100
committerTaras Madan <tarasmadan@google.com>2025-01-23 10:42:36 +0000
commit7b4377ad9d8a7205416df8d6217ef2b010f89481 (patch)
treee6fec4fd12ff807a16d847923f501075bf71d16c /vendor/github.com/hexops/gotextdiff/span
parent475a4c203afb8b7d3af51c4fd32bb170ff32a45e (diff)
vendor: delete
Diffstat (limited to 'vendor/github.com/hexops/gotextdiff/span')
-rw-r--r--vendor/github.com/hexops/gotextdiff/span/parse.go100
-rw-r--r--vendor/github.com/hexops/gotextdiff/span/span.go285
-rw-r--r--vendor/github.com/hexops/gotextdiff/span/token.go194
-rw-r--r--vendor/github.com/hexops/gotextdiff/span/token111.go39
-rw-r--r--vendor/github.com/hexops/gotextdiff/span/token112.go16
-rw-r--r--vendor/github.com/hexops/gotextdiff/span/uri.go169
-rw-r--r--vendor/github.com/hexops/gotextdiff/span/utf16.go91
7 files changed, 0 insertions, 894 deletions
diff --git a/vendor/github.com/hexops/gotextdiff/span/parse.go b/vendor/github.com/hexops/gotextdiff/span/parse.go
deleted file mode 100644
index aa17c84ec..000000000
--- a/vendor/github.com/hexops/gotextdiff/span/parse.go
+++ /dev/null
@@ -1,100 +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 (
- "strconv"
- "strings"
- "unicode/utf8"
-)
-
-// Parse returns the location represented by the input.
-// Only file paths are accepted, not URIs.
-// The returned span will be normalized, and thus if printed may produce a
-// different string.
-func Parse(input string) Span {
- // :0:0#0-0:0#0
- valid := input
- var hold, offset int
- hadCol := false
- suf := rstripSuffix(input)
- if suf.sep == "#" {
- offset = suf.num
- suf = rstripSuffix(suf.remains)
- }
- if suf.sep == ":" {
- valid = suf.remains
- hold = suf.num
- hadCol = true
- suf = rstripSuffix(suf.remains)
- }
- switch {
- case suf.sep == ":":
- return New(URIFromPath(suf.remains), NewPoint(suf.num, hold, offset), Point{})
- case suf.sep == "-":
- // we have a span, fall out of the case to continue
- default:
- // separator not valid, rewind to either the : or the start
- return New(URIFromPath(valid), NewPoint(hold, 0, offset), Point{})
- }
- // only the span form can get here
- // at this point we still don't know what the numbers we have mean
- // if have not yet seen a : then we might have either a line or a column depending
- // on whether start has a column or not
- // we build an end point and will fix it later if needed
- end := NewPoint(suf.num, hold, offset)
- hold, offset = 0, 0
- suf = rstripSuffix(suf.remains)
- if suf.sep == "#" {
- offset = suf.num
- suf = rstripSuffix(suf.remains)
- }
- if suf.sep != ":" {
- // turns out we don't have a span after all, rewind
- return New(URIFromPath(valid), end, Point{})
- }
- valid = suf.remains
- hold = suf.num
- suf = rstripSuffix(suf.remains)
- if suf.sep != ":" {
- // line#offset only
- return New(URIFromPath(valid), NewPoint(hold, 0, offset), end)
- }
- // we have a column, so if end only had one number, it is also the column
- if !hadCol {
- end = NewPoint(suf.num, end.v.Line, end.v.Offset)
- }
- return New(URIFromPath(suf.remains), NewPoint(suf.num, hold, offset), end)
-}
-
-type suffix struct {
- remains string
- sep string
- num int
-}
-
-func rstripSuffix(input string) suffix {
- if len(input) == 0 {
- return suffix{"", "", -1}
- }
- remains := input
- num := -1
- // first see if we have a number at the end
- last := strings.LastIndexFunc(remains, func(r rune) bool { return r < '0' || r > '9' })
- if last >= 0 && last < len(remains)-1 {
- number, err := strconv.ParseInt(remains[last+1:], 10, 64)
- if err == nil {
- num = int(number)
- remains = remains[:last+1]
- }
- }
- // now see if we have a trailing separator
- r, w := utf8.DecodeLastRuneInString(remains)
- if r != ':' && r != '#' && r == '#' {
- return suffix{input, "", -1}
- }
- remains = remains[:len(remains)-w]
- return suffix{remains, string(r), num}
-}
diff --git a/vendor/github.com/hexops/gotextdiff/span/span.go b/vendor/github.com/hexops/gotextdiff/span/span.go
deleted file mode 100644
index 4d2ad0986..000000000
--- a/vendor/github.com/hexops/gotextdiff/span/span.go
+++ /dev/null
@@ -1,285 +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 contains support for representing with positions and ranges in
-// text files.
-package span
-
-import (
- "encoding/json"
- "fmt"
- "path"
-)
-
-// Span represents a source code range in standardized form.
-type Span struct {
- v span
-}
-
-// Point represents a single point within a file.
-// In general this should only be used as part of a Span, as on its own it
-// does not carry enough information.
-type Point struct {
- v point
-}
-
-type span struct {
- URI URI `json:"uri"`
- Start point `json:"start"`
- End point `json:"end"`
-}
-
-type point struct {
- Line int `json:"line"`
- Column int `json:"column"`
- Offset int `json:"offset"`
-}
-
-// Invalid is a span that reports false from IsValid
-var Invalid = Span{v: span{Start: invalidPoint.v, End: invalidPoint.v}}
-
-var invalidPoint = Point{v: point{Line: 0, Column: 0, Offset: -1}}
-
-// Converter is the interface to an object that can convert between line:column
-// and offset forms for a single file.
-type Converter interface {
- //ToPosition converts from an offset to a line:column pair.
- ToPosition(offset int) (int, int, error)
- //ToOffset converts from a line:column pair to an offset.
- ToOffset(line, col int) (int, error)
-}
-
-func New(uri URI, start Point, end Point) Span {
- s := Span{v: span{URI: uri, Start: start.v, End: end.v}}
- s.v.clean()
- return s
-}
-
-func NewPoint(line, col, offset int) Point {
- p := Point{v: point{Line: line, Column: col, Offset: offset}}
- p.v.clean()
- return p
-}
-
-func Compare(a, b Span) int {
- if r := CompareURI(a.URI(), b.URI()); r != 0 {
- return r
- }
- if r := comparePoint(a.v.Start, b.v.Start); r != 0 {
- return r
- }
- return comparePoint(a.v.End, b.v.End)
-}
-
-func ComparePoint(a, b Point) int {
- return comparePoint(a.v, b.v)
-}
-
-func comparePoint(a, b point) int {
- if !a.hasPosition() {
- if a.Offset < b.Offset {
- return -1
- }
- if a.Offset > b.Offset {
- return 1
- }
- return 0
- }
- if a.Line < b.Line {
- return -1
- }
- if a.Line > b.Line {
- return 1
- }
- if a.Column < b.Column {
- return -1
- }
- if a.Column > b.Column {
- return 1
- }
- return 0
-}
-
-func (s Span) HasPosition() bool { return s.v.Start.hasPosition() }
-func (s Span) HasOffset() bool { return s.v.Start.hasOffset() }
-func (s Span) IsValid() bool { return s.v.Start.isValid() }
-func (s Span) IsPoint() bool { return s.v.Start == s.v.End }
-func (s Span) URI() URI { return s.v.URI }
-func (s Span) Start() Point { return Point{s.v.Start} }
-func (s Span) End() Point { return Point{s.v.End} }
-func (s *Span) MarshalJSON() ([]byte, error) { return json.Marshal(&s.v) }
-func (s *Span) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &s.v) }
-
-func (p Point) HasPosition() bool { return p.v.hasPosition() }
-func (p Point) HasOffset() bool { return p.v.hasOffset() }
-func (p Point) IsValid() bool { return p.v.isValid() }
-func (p *Point) MarshalJSON() ([]byte, error) { return json.Marshal(&p.v) }
-func (p *Point) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &p.v) }
-func (p Point) Line() int {
- if !p.v.hasPosition() {
- panic(fmt.Errorf("position not set in %v", p.v))
- }
- return p.v.Line
-}
-func (p Point) Column() int {
- if !p.v.hasPosition() {
- panic(fmt.Errorf("position not set in %v", p.v))
- }
- return p.v.Column
-}
-func (p Point) Offset() int {
- if !p.v.hasOffset() {
- panic(fmt.Errorf("offset not set in %v", p.v))
- }
- return p.v.Offset
-}
-
-func (p point) hasPosition() bool { return p.Line > 0 }
-func (p point) hasOffset() bool { return p.Offset >= 0 }
-func (p point) isValid() bool { return p.hasPosition() || p.hasOffset() }
-func (p point) isZero() bool {
- return (p.Line == 1 && p.Column == 1) || (!p.hasPosition() && p.Offset == 0)
-}
-
-func (s *span) clean() {
- //this presumes the points are already clean
- if !s.End.isValid() || (s.End == point{}) {
- s.End = s.Start
- }
-}
-
-func (p *point) clean() {
- if p.Line < 0 {
- p.Line = 0
- }
- if p.Column <= 0 {
- if p.Line > 0 {
- p.Column = 1
- } else {
- p.Column = 0
- }
- }
- if p.Offset == 0 && (p.Line > 1 || p.Column > 1) {
- p.Offset = -1
- }
-}
-
-// Format implements fmt.Formatter to print the Location in a standard form.
-// The format produced is one that can be read back in using Parse.
-func (s Span) Format(f fmt.State, c rune) {
- fullForm := f.Flag('+')
- preferOffset := f.Flag('#')
- // we should always have a uri, simplify if it is file format
- //TODO: make sure the end of the uri is unambiguous
- uri := string(s.v.URI)
- if c == 'f' {
- uri = path.Base(uri)
- } else if !fullForm {
- uri = s.v.URI.Filename()
- }
- fmt.Fprint(f, uri)
- if !s.IsValid() || (!fullForm && s.v.Start.isZero() && s.v.End.isZero()) {
- return
- }
- // see which bits of start to write
- printOffset := s.HasOffset() && (fullForm || preferOffset || !s.HasPosition())
- printLine := s.HasPosition() && (fullForm || !printOffset)
- printColumn := printLine && (fullForm || (s.v.Start.Column > 1 || s.v.End.Column > 1))
- fmt.Fprint(f, ":")
- if printLine {
- fmt.Fprintf(f, "%d", s.v.Start.Line)
- }
- if printColumn {
- fmt.Fprintf(f, ":%d", s.v.Start.Column)
- }
- if printOffset {
- fmt.Fprintf(f, "#%d", s.v.Start.Offset)
- }
- // start is written, do we need end?
- if s.IsPoint() {
- return
- }
- // we don't print the line if it did not change
- printLine = fullForm || (printLine && s.v.End.Line > s.v.Start.Line)
- fmt.Fprint(f, "-")
- if printLine {
- fmt.Fprintf(f, "%d", s.v.End.Line)
- }
- if printColumn {
- if printLine {
- fmt.Fprint(f, ":")
- }
- fmt.Fprintf(f, "%d", s.v.End.Column)
- }
- if printOffset {
- fmt.Fprintf(f, "#%d", s.v.End.Offset)
- }
-}
-
-func (s Span) WithPosition(c Converter) (Span, error) {
- if err := s.update(c, true, false); err != nil {
- return Span{}, err
- }
- return s, nil
-}
-
-func (s Span) WithOffset(c Converter) (Span, error) {
- if err := s.update(c, false, true); err != nil {
- return Span{}, err
- }
- return s, nil
-}
-
-func (s Span) WithAll(c Converter) (Span, error) {
- if err := s.update(c, true, true); err != nil {
- return Span{}, err
- }
- return s, nil
-}
-
-func (s *Span) update(c Converter, withPos, withOffset bool) error {
- if !s.IsValid() {
- return fmt.Errorf("cannot add information to an invalid span")
- }
- if withPos && !s.HasPosition() {
- if err := s.v.Start.updatePosition(c); err != nil {
- return err
- }
- if s.v.End.Offset == s.v.Start.Offset {
- s.v.End = s.v.Start
- } else if err := s.v.End.updatePosition(c); err != nil {
- return err
- }
- }
- if withOffset && (!s.HasOffset() || (s.v.End.hasPosition() && !s.v.End.hasOffset())) {
- if err := s.v.Start.updateOffset(c); err != nil {
- return err
- }
- if s.v.End.Line == s.v.Start.Line && s.v.End.Column == s.v.Start.Column {
- s.v.End.Offset = s.v.Start.Offset
- } else if err := s.v.End.updateOffset(c); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (p *point) updatePosition(c Converter) error {
- line, col, err := c.ToPosition(p.Offset)
- if err != nil {
- return err
- }
- p.Line = line
- p.Column = col
- return nil
-}
-
-func (p *point) updateOffset(c Converter) error {
- offset, err := c.ToOffset(p.Line, p.Column)
- if err != nil {
- return err
- }
- p.Offset = offset
- return nil
-}
diff --git a/vendor/github.com/hexops/gotextdiff/span/token.go b/vendor/github.com/hexops/gotextdiff/span/token.go
deleted file mode 100644
index 6f8b9b570..000000000
--- a/vendor/github.com/hexops/gotextdiff/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)
-}
diff --git a/vendor/github.com/hexops/gotextdiff/span/token111.go b/vendor/github.com/hexops/gotextdiff/span/token111.go
deleted file mode 100644
index bf7a5406b..000000000
--- a/vendor/github.com/hexops/gotextdiff/span/token111.go
+++ /dev/null
@@ -1,39 +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.
-
-// +build !go1.12
-
-package span
-
-import (
- "go/token"
-)
-
-// lineStart is the pre-Go 1.12 version of (*token.File).LineStart. For Go
-// versions <= 1.11, we borrow logic from the analysisutil package.
-// TODO(rstambler): Delete this file when we no longer support Go 1.11.
-func lineStart(f *token.File, line int) token.Pos {
- // Use binary search to find the start offset of this line.
-
- min := 0 // inclusive
- max := f.Size() // exclusive
- for {
- offset := (min + max) / 2
- pos := f.Pos(offset)
- posn := f.Position(pos)
- if posn.Line == line {
- return pos - (token.Pos(posn.Column) - 1)
- }
-
- if min+1 >= max {
- return token.NoPos
- }
-
- if posn.Line < line {
- min = offset
- } else {
- max = offset
- }
- }
-}
diff --git a/vendor/github.com/hexops/gotextdiff/span/token112.go b/vendor/github.com/hexops/gotextdiff/span/token112.go
deleted file mode 100644
index 017aec9c1..000000000
--- a/vendor/github.com/hexops/gotextdiff/span/token112.go
+++ /dev/null
@@ -1,16 +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.
-
-// +build go1.12
-
-package span
-
-import (
- "go/token"
-)
-
-// TODO(rstambler): Delete this file when we no longer support Go 1.11.
-func lineStart(f *token.File, line int) token.Pos {
- return f.LineStart(line)
-}
diff --git a/vendor/github.com/hexops/gotextdiff/span/uri.go b/vendor/github.com/hexops/gotextdiff/span/uri.go
deleted file mode 100644
index 250492135..000000000
--- a/vendor/github.com/hexops/gotextdiff/span/uri.go
+++ /dev/null
@@ -1,169 +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"
- "net/url"
- "os"
- "path"
- "path/filepath"
- "runtime"
- "strings"
- "unicode"
-)
-
-const fileScheme = "file"
-
-// URI represents the full URI for a file.
-type URI string
-
-func (uri URI) IsFile() bool {
- return strings.HasPrefix(string(uri), "file://")
-}
-
-// Filename returns the file path for the given URI.
-// It is an error to call this on a URI that is not a valid filename.
-func (uri URI) Filename() string {
- filename, err := filename(uri)
- if err != nil {
- panic(err)
- }
- return filepath.FromSlash(filename)
-}
-
-func filename(uri URI) (string, error) {
- if uri == "" {
- return "", nil
- }
- u, err := url.ParseRequestURI(string(uri))
- if err != nil {
- return "", err
- }
- if u.Scheme != fileScheme {
- return "", fmt.Errorf("only file URIs are supported, got %q from %q", u.Scheme, uri)
- }
- // If the URI is a Windows URI, we trim the leading "/" and lowercase
- // the drive letter, which will never be case sensitive.
- if isWindowsDriveURIPath(u.Path) {
- u.Path = strings.ToUpper(string(u.Path[1])) + u.Path[2:]
- }
- return u.Path, nil
-}
-
-func URIFromURI(s string) URI {
- if !strings.HasPrefix(s, "file://") {
- return URI(s)
- }
-
- if !strings.HasPrefix(s, "file:///") {
- // VS Code sends URLs with only two slashes, which are invalid. golang/go#39789.
- s = "file:///" + s[len("file://"):]
- }
- // Even though the input is a URI, it may not be in canonical form. VS Code
- // in particular over-escapes :, @, etc. Unescape and re-encode to canonicalize.
- path, err := url.PathUnescape(s[len("file://"):])
- if err != nil {
- panic(err)
- }
-
- // File URIs from Windows may have lowercase drive letters.
- // Since drive letters are guaranteed to be case insensitive,
- // we change them to uppercase to remain consistent.
- // For example, file:///c:/x/y/z becomes file:///C:/x/y/z.
- if isWindowsDriveURIPath(path) {
- path = path[:1] + strings.ToUpper(string(path[1])) + path[2:]
- }
- u := url.URL{Scheme: fileScheme, Path: path}
- return URI(u.String())
-}
-
-func CompareURI(a, b URI) int {
- if equalURI(a, b) {
- return 0
- }
- if a < b {
- return -1
- }
- return 1
-}
-
-func equalURI(a, b URI) bool {
- if a == b {
- return true
- }
- // If we have the same URI basename, we may still have the same file URIs.
- if !strings.EqualFold(path.Base(string(a)), path.Base(string(b))) {
- return false
- }
- fa, err := filename(a)
- if err != nil {
- return false
- }
- fb, err := filename(b)
- if err != nil {
- return false
- }
- // Stat the files to check if they are equal.
- infoa, err := os.Stat(filepath.FromSlash(fa))
- if err != nil {
- return false
- }
- infob, err := os.Stat(filepath.FromSlash(fb))
- if err != nil {
- return false
- }
- return os.SameFile(infoa, infob)
-}
-
-// URIFromPath returns a span URI for the supplied file path.
-// It will always have the file scheme.
-func URIFromPath(path string) URI {
- if path == "" {
- return ""
- }
- // Handle standard library paths that contain the literal "$GOROOT".
- // TODO(rstambler): The go/packages API should allow one to determine a user's $GOROOT.
- const prefix = "$GOROOT"
- if len(path) >= len(prefix) && strings.EqualFold(prefix, path[:len(prefix)]) {
- suffix := path[len(prefix):]
- path = runtime.GOROOT() + suffix
- }
- if !isWindowsDrivePath(path) {
- if abs, err := filepath.Abs(path); err == nil {
- path = abs
- }
- }
- // Check the file path again, in case it became absolute.
- if isWindowsDrivePath(path) {
- path = "/" + strings.ToUpper(string(path[0])) + path[1:]
- }
- path = filepath.ToSlash(path)
- u := url.URL{
- Scheme: fileScheme,
- Path: path,
- }
- return URI(u.String())
-}
-
-// isWindowsDrivePath returns true if the file path is of the form used by
-// Windows. We check if the path begins with a drive letter, followed by a ":".
-// For example: C:/x/y/z.
-func isWindowsDrivePath(path string) bool {
- if len(path) < 3 {
- return false
- }
- return unicode.IsLetter(rune(path[0])) && path[1] == ':'
-}
-
-// isWindowsDriveURI returns true if the file URI is of the format used by
-// Windows URIs. The url.Parse package does not specially handle Windows paths
-// (see golang/go#6027), so we check if the URI path has a drive prefix (e.g. "/C:").
-func isWindowsDriveURIPath(uri string) bool {
- if len(uri) < 4 {
- return false
- }
- return uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':'
-}
diff --git a/vendor/github.com/hexops/gotextdiff/span/utf16.go b/vendor/github.com/hexops/gotextdiff/span/utf16.go
deleted file mode 100644
index f06a2468b..000000000
--- a/vendor/github.com/hexops/gotextdiff/span/utf16.go
+++ /dev/null
@@ -1,91 +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"
- "unicode/utf16"
- "unicode/utf8"
-)
-
-// ToUTF16Column calculates the utf16 column expressed by the point given the
-// supplied file contents.
-// This is used to convert from the native (always in bytes) column
-// representation and the utf16 counts used by some editors.
-func ToUTF16Column(p Point, content []byte) (int, error) {
- if !p.HasPosition() {
- return -1, fmt.Errorf("ToUTF16Column: point is missing position")
- }
- if !p.HasOffset() {
- return -1, fmt.Errorf("ToUTF16Column: point is missing offset")
- }
- offset := p.Offset() // 0-based
- colZero := p.Column() - 1 // 0-based
- if colZero == 0 {
- // 0-based column 0, so it must be chr 1
- return 1, nil
- } else if colZero < 0 {
- return -1, fmt.Errorf("ToUTF16Column: column is invalid (%v)", colZero)
- }
- // work out the offset at the start of the line using the column
- lineOffset := offset - colZero
- if lineOffset < 0 || offset > len(content) {
- return -1, fmt.Errorf("ToUTF16Column: offsets %v-%v outside file contents (%v)", lineOffset, offset, len(content))
- }
- // Use the offset to pick out the line start.
- // This cannot panic: offset > len(content) and lineOffset < offset.
- start := content[lineOffset:]
-
- // Now, truncate down to the supplied column.
- start = start[:colZero]
-
- // and count the number of utf16 characters
- // in theory we could do this by hand more efficiently...
- return len(utf16.Encode([]rune(string(start)))) + 1, nil
-}
-
-// FromUTF16Column advances the point by the utf16 character offset given the
-// supplied line contents.
-// This is used to convert from the utf16 counts used by some editors to the
-// native (always in bytes) column representation.
-func FromUTF16Column(p Point, chr int, content []byte) (Point, error) {
- if !p.HasOffset() {
- return Point{}, fmt.Errorf("FromUTF16Column: point is missing offset")
- }
- // if chr is 1 then no adjustment needed
- if chr <= 1 {
- return p, nil
- }
- if p.Offset() >= len(content) {
- return p, fmt.Errorf("FromUTF16Column: offset (%v) greater than length of content (%v)", p.Offset(), len(content))
- }
- remains := content[p.Offset():]
- // scan forward the specified number of characters
- for count := 1; count < chr; count++ {
- if len(remains) <= 0 {
- return Point{}, fmt.Errorf("FromUTF16Column: chr goes beyond the content")
- }
- r, w := utf8.DecodeRune(remains)
- if r == '\n' {
- // Per the LSP spec:
- //
- // > If the character value is greater than the line length it
- // > defaults back to the line length.
- break
- }
- remains = remains[w:]
- if r >= 0x10000 {
- // a two point rune
- count++
- // if we finished in a two point rune, do not advance past the first
- if count >= chr {
- break
- }
- }
- p.v.Column += w
- p.v.Offset += w
- }
- return p, nil
-}