Skip to content

Commit 813e70a

Browse files
committed
gopls/internal/server: redo completion counters
Rearrange the counters so that there is one set describing the set of suggested completions (empty, short, long) and one set describing what the user does (used, not used, can't tell). A set of suggested completions is long if there are more than ten of them, which is about how many clients show to users. If a client sends back changes to file, gopls can decide if a completion was used or not, but it does not try to tell if the client sends back a new whole file. These sets of counters correspond to two partitions. Change-Id: I861a5743b16e488074fd2e58cb63c6a8aea52735 Reviewed-on: https://go-review.googlesource.com/c/tools/+/572315 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 2ba7cf9 commit 813e70a

File tree

4 files changed

+27
-26
lines changed

4 files changed

+27
-26
lines changed

gopls/internal/server/completion.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ func (s *server) Completion(ctx context.Context, params *protocol.CompletionPara
4040
var surrounding *completion.Selection
4141
switch snapshot.FileKind(fh) {
4242
case file.Go:
43-
complCnt.Inc() // completion requests for Go programs
4443
candidates, surrounding, err = completion.Completion(ctx, snapshot, fh, params.Position, params.Context)
4544
case file.Mod:
4645
candidates, surrounding = nil, nil
@@ -87,6 +86,8 @@ func (s *server) Completion(ctx context.Context, params *protocol.CompletionPara
8786
if len(items) > 10 {
8887
// TODO(pjw): long completions are ok for field lists
8988
complLong.Inc()
89+
} else {
90+
complShort.Inc()
9091
}
9192
return &protocol.CompletionList{
9293
IsIncomplete: incompleteResults,
@@ -97,6 +98,7 @@ func (s *server) Completion(ctx context.Context, params *protocol.CompletionPara
9798
func (s *server) saveLastCompletion(uri protocol.DocumentURI, version int32, items []protocol.CompletionItem, pos protocol.Position) {
9899
s.efficacyMu.Lock()
99100
defer s.efficacyMu.Unlock()
101+
s.efficacyVersion = version
100102
s.efficacyURI = uri
101103
s.efficacyPos = pos
102104
s.efficacyItems = items

gopls/internal/server/counters.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,21 @@ import "golang.org/x/telemetry/counter"
88

99
// Proposed counters for evaluating gopls code completion.
1010
var (
11-
complCnt = counter.New("gopls/completion/cnt") // for Go programs
12-
complEmpty = counter.New("gopls/completion/empty") // count empty responses
13-
complLong = counter.New("gopls/completion/long") // returning more than 10 items
11+
complEmpty = counter.New("gopls/completion/len:0") // count empty suggestions
12+
complShort = counter.New("gopls/completion/len:<=10") // not empty, not long
13+
complLong = counter.New("gopls/completion/len:>10") // returning more than 10 items
1414

15-
changeMulti = counter.New("gopls/completion/multi-change") // multiple changes in didChange
16-
changeFull = counter.New("gopls/completion/full-change") // full file change in didChange
15+
changeFull = counter.New("gopls/completion/used:unknown") // full file change in didChange
16+
complUnused = counter.New("gopls/completion/used:no") // did not use a completion
17+
complUsed = counter.New("gopls/completion/used:yes") // used a completion
1718

18-
complUsed = counter.New("gopls/completion/used") // used a completion
19-
20-
// exported so tests can verify that counters are incrementd
19+
// exported so tests can verify that counters are incremented
2120
CompletionCounters = []*counter.Counter{
22-
complCnt,
2321
complEmpty,
22+
complShort,
2423
complLong,
25-
changeMulti,
2624
changeFull,
25+
complUnused,
2726
complUsed,
2827
}
2928
)

gopls/internal/server/text_synchronization.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,6 @@ func (s *server) applyIncrementalChanges(ctx context.Context, uri protocol.Docum
329329
if err != nil {
330330
return nil, fmt.Errorf("%w: file not found (%v)", jsonrpc2.ErrInternal, err)
331331
}
332-
if len(changes) > 1 {
333-
changeMulti.Inc()
334-
}
335332
for i, change := range changes {
336333
// TODO(adonovan): refactor to use diff.Apply, which is robust w.r.t.
337334
// out-of-order or overlapping changes---and much more efficient.
@@ -396,6 +393,7 @@ func (s *server) checkEfficacy(uri protocol.DocumentURI, version int32, change p
396393
}
397394
}
398395
}
396+
complUnused.Inc()
399397
}
400398

401399
func changeTypeToFileAction(ct protocol.FileChangeType) file.Action {

gopls/internal/test/integration/completion/completion_test.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,9 +1003,8 @@ func Join() {}
10031003
})
10041004
}
10051005

1006-
// show that the counters get exercised. Fortuntely a small program
1007-
// exercises them all (except for mulit-chnage, for which see the code
1008-
// in env.setBufferContentLocked)
1006+
// show that the efficacy counters get exercised. Fortuntely a small program
1007+
// exercises them all
10091008
func TestCounters(t *testing.T) {
10101009
const files = `
10111010
-- go.mod --
@@ -1028,33 +1027,36 @@ func main() {
10281027
}
10291028
return ans
10301029
}
1030+
before := cts()
10311031
env.OpenFile("x.go")
10321032
env.Await(env.DoneWithOpen())
10331033
saved := env.BufferText("x.go")
10341034
lines := strings.Split(saved, "\n")
1035-
loc := env.RegexpSearch("x.go", "p")
1036-
before := cts()
1035+
// make sure the unused counter is exercised
1036+
loc := env.RegexpSearch("x.go", "main")
1037+
loc.Range.End = loc.Range.Start
1038+
env.Completion(loc) // ignore the proposed completions
1039+
env.RegexpReplace("x.go", "main", "Main") // completions are unused
1040+
env.SetBufferContent("x.go", saved) // restore x.go
1041+
// used:no
1042+
10371043
// all the action is after 4 characters on line 2 (counting from 0)
1038-
// (doing the whole file is too expensive)
10391044
for i := 2; i < len(lines); i++ {
10401045
l := lines[i]
10411046
loc.Range.Start.Line = uint32(i)
1042-
for j := 5; j < len(l); j++ {
1047+
for j := 4; j < len(l); j++ {
10431048
loc.Range.Start.Character = uint32(j)
10441049
loc.Range.End = loc.Range.Start
10451050
res := env.Completion(loc)
1046-
for _, r := range res.Items {
1051+
if len(res.Items) > 0 {
1052+
r := res.Items[0]
10471053
env.AcceptCompletion(loc, r)
10481054
env.SetBufferContent("x.go", saved)
10491055
}
10501056
}
10511057
}
10521058
after := cts()
10531059
for c := range after {
1054-
if c.Name() == "gopls/completion/multi-change" {
1055-
// don't know how to force multi-change
1056-
continue
1057-
}
10581060
if after[c] <= before[c] {
10591061
t.Errorf("%s did not increase", c.Name())
10601062
}

0 commit comments

Comments
 (0)