internal/lsp/source: sort references and implementations results
We should make sure to return deterministic results for these requests.
Fixes golang/go#40904
Change-Id: If10489e3eca0e1b6a5e449de851d332f2d91ceb4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/250737
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/lsp/source/implementation.go b/internal/lsp/source/implementation.go
index 76a27a0..bd5af1f 100644
--- a/internal/lsp/source/implementation.go
+++ b/internal/lsp/source/implementation.go
@@ -11,6 +11,7 @@
"go/ast"
"go/token"
"go/types"
+ "sort"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/lsp/protocol"
@@ -42,6 +43,13 @@
Range: pr,
})
}
+ sort.Slice(locations, func(i, j int) bool {
+ li, lj := locations[i], locations[j]
+ if li.URI == lj.URI {
+ return protocol.CompareRange(li.Range, lj.Range) < 0
+ }
+ return li.URI < lj.URI
+ })
return locations, nil
}
@@ -195,8 +203,10 @@
sourcePkg Package
}
-var errBuiltin = errors.New("builtin object")
-var errNoObjectFound = errors.New("no object found")
+var (
+ errBuiltin = errors.New("builtin object")
+ errNoObjectFound = errors.New("no object found")
+)
// qualifiedObjsAtProtocolPos returns info for all the type.Objects
// referenced at the given position. An object will be returned for
diff --git a/internal/lsp/source/references.go b/internal/lsp/source/references.go
index 1eb8308..204e185 100644
--- a/internal/lsp/source/references.go
+++ b/internal/lsp/source/references.go
@@ -9,6 +9,7 @@
"go/ast"
"go/token"
"go/types"
+ "sort"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/lsp/protocol"
@@ -40,7 +41,22 @@
if err != nil {
return nil, err
}
- return references(ctx, s, qualifiedObjs, includeDeclaration)
+ refs, err := references(ctx, s, qualifiedObjs, includeDeclaration)
+ if err != nil {
+ return nil, err
+ }
+ toSort := refs
+ if includeDeclaration {
+ toSort = refs[1:]
+ }
+ sort.Slice(toSort, func(i, j int) bool {
+ x := span.CompareURI(toSort[i].URI(), toSort[j].URI())
+ if x == 0 {
+ return toSort[i].ident.Pos() < toSort[j].ident.Pos()
+ }
+ return x < 0
+ })
+ return refs, nil
}
// references is a helper function to avoid recomputing qualifiedObjsAtProtocolPos.