internal/lsp/protocol: add a compare function for span.URI
Add an additional check to handle URI comparisons. This fixes Hover on
Windows.
Change-Id: Ibfc816f1ec374144377a873c5b52867fafa3d7e8
Reviewed-on: https://go-review.googlesource.com/c/tools/+/172659
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/internal/lsp/protocol/span.go b/internal/lsp/protocol/span.go
index d4d841d..9045b2c 100644
--- a/internal/lsp/protocol/span.go
+++ b/internal/lsp/protocol/span.go
@@ -40,7 +40,7 @@
}
func (m *ColumnMapper) Range(s span.Span) (Range, error) {
- if m.URI != s.URI() {
+ if span.CompareURI(m.URI, s.URI()) != 0 {
return Range{}, fmt.Errorf("column mapper is for file %q instead of %q", m.URI, s.URI())
}
s, err := s.WithAll(m.Converter)
diff --git a/internal/span/span.go b/internal/span/span.go
index 0ac35a2..b5733252 100644
--- a/internal/span/span.go
+++ b/internal/span/span.go
@@ -7,7 +7,6 @@
import (
"encoding/json"
"fmt"
- "strings"
)
// Span represents a source code range in standardized form.
@@ -58,7 +57,7 @@
}
func Compare(a, b Span) int {
- if r := strings.Compare(string(a.v.URI), string(b.v.URI)); r != 0 {
+ if r := CompareURI(a.URI(), b.URI()); r != 0 {
return r
}
if r := comparePoint(a.v.Start, b.v.Start); r != 0 {
diff --git a/internal/span/uri.go b/internal/span/uri.go
index 33755cf..63d7ba8 100644
--- a/internal/span/uri.go
+++ b/internal/span/uri.go
@@ -7,6 +7,7 @@
import (
"fmt"
"net/url"
+ "os"
"path/filepath"
"runtime"
"strings"
@@ -54,6 +55,29 @@
return FileURI(s)
}
+func CompareURI(a, b URI) int {
+ if a == b {
+ return 0
+ }
+ // If we have the same URI basename, we may still have the same file URIs.
+ if fa, err := a.Filename(); err == nil {
+ if fb, err := b.Filename(); err == nil {
+ if filepath.Base(fa) == filepath.Base(fb) {
+ // Stat the files to check if they are equal.
+ if infoa, err := os.Stat(fa); err == nil {
+ if infob, err := os.Stat(fb); err == nil {
+ if os.SameFile(infoa, infob) {
+ return 0
+ }
+ }
+ }
+ }
+ return strings.Compare(fa, fb)
+ }
+ }
+ return strings.Compare(string(a), string(b))
+}
+
// FileURI returns a span URI for the supplied file path.
// It will always have the file scheme.
func FileURI(path string) URI {