internal/lsp: order struct fields completions by definition
Previously struct fields completions are ordered alphabetically.
Now it is ordered by its order in definition.
Fixes golang/go#42626
Change-Id: I8c404205b97fa9f1a5a66a95a84033b6f0f48eae
Reviewed-on: https://go-review.googlesource.com/c/tools/+/270777
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/regtest/completion_test.go b/gopls/internal/regtest/completion_test.go
index 2651f59..5978f56 100644
--- a/gopls/internal/regtest/completion_test.go
+++ b/gopls/internal/regtest/completion_test.go
@@ -193,6 +193,54 @@
})
}
+// Test the order of completion suggestions
+func TestStructLiteralCompletion(t *testing.T) {
+ const files = `
+-- go.mod --
+module mod.com
+
+-- foo.go --
+package foo
+
+type Foo struct {
+ c int
+ b int
+ a int
+}
+
+func f() {
+ foo := Foo{
+
+ }
+}
+`
+
+ want := []string{"c", "b", "a"}
+
+ run(t, files, func(t *testing.T, env *Env) {
+ env.OpenFile("foo.go")
+ completions := env.Completion("foo.go", fake.Pos{
+ Line: 10,
+ Column: 0,
+ })
+
+ diff := compareCompletionResultsOnlyHead(want, completions.Items)
+ if diff != "" {
+ t.Fatal(diff)
+ return
+ }
+ })
+}
+
+func compareCompletionResultsOnlyHead(want []string, gotItems []protocol.CompletionItem) string {
+ for i := range want {
+ if want[i] != gotItems[i].Label {
+ return fmt.Sprintf("completion results are not the same: got %v, want %v", gotItems[i].Label, want[i])
+ }
+ }
+ return ""
+}
+
func compareCompletionResults(want []string, gotItems []protocol.CompletionItem) string {
if len(gotItems) != len(want) {
return fmt.Sprintf("got %v completion(s), want %v", len(gotItems), len(want))
diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go
index 78dac5b..b87154a 100644
--- a/internal/lsp/source/completion/completion.go
+++ b/internal/lsp/source/completion/completion.go
@@ -1522,6 +1522,7 @@
}
}
+ deltaScore := 0.0001
switch t := clInfo.clType.(type) {
case *types.Struct:
for i := 0; i < t.NumFields(); i++ {
@@ -1529,7 +1530,7 @@
if !addedFields[field] {
c.deepState.enqueue(candidate{
obj: field,
- score: highScore,
+ score: highScore - float64(i)*deltaScore,
})
}
}