Skip to content

Commit 920d665

Browse files
committed
gopls/internal/cmd: factor three loops in fix subcommand
Change-Id: I4cfeaf9d785bedc445cf5b4d2ea6a6bf2b824377 Reviewed-on: https://go-review.googlesource.com/c/tools/+/553755 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent 7825736 commit 920d665

File tree

2 files changed

+33
-33
lines changed

2 files changed

+33
-33
lines changed

gopls/internal/cmd/suggested_fix.go

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"fmt"
1111

1212
"golang.org/x/tools/gopls/internal/lsp/protocol"
13+
"golang.org/x/tools/gopls/internal/util/slices"
1314
"golang.org/x/tools/internal/tool"
1415
)
1516

@@ -148,42 +149,22 @@ func (s *suggestedFix) Run(ctx context.Context, args ...string) error {
148149
continue
149150
}
150151

151-
// Partially apply CodeAction.Edit, a WorkspaceEdit.
152-
// (See also conn.Client.applyWorkspaceEdit(a.Edit)).
153-
if !from.HasPosition() {
154-
for _, c := range a.Edit.DocumentChanges {
155-
if c.TextDocumentEdit != nil {
156-
if c.TextDocumentEdit.TextDocument.URI == uri {
157-
edits = append(edits, protocol.AsTextEdits(c.TextDocumentEdit.Edits)...)
158-
}
159-
}
160-
}
152+
// If the provided span has a position (not just offsets),
153+
// and the action has diagnostics, the action must have a
154+
// diagnostic with the same range as it.
155+
if from.HasPosition() && len(a.Diagnostics) > 0 &&
156+
!slices.ContainsFunc(a.Diagnostics, func(diag protocol.Diagnostic) bool {
157+
return diag.Range.Start == rng.Start
158+
}) {
161159
continue
162160
}
163161

164-
// The provided span has a position (not just offsets).
165-
// Find the code action that has the same range as it.
166-
for _, diag := range a.Diagnostics {
167-
if diag.Range.Start == rng.Start {
168-
for _, c := range a.Edit.DocumentChanges {
169-
if c.TextDocumentEdit != nil {
170-
if c.TextDocumentEdit.TextDocument.URI == uri {
171-
edits = append(edits, protocol.AsTextEdits(c.TextDocumentEdit.Edits)...)
172-
}
173-
}
174-
}
175-
break
176-
}
177-
}
178-
179-
// If suggested fix is not a diagnostic, still must collect edits.
180-
if len(a.Diagnostics) == 0 {
181-
for _, c := range a.Edit.DocumentChanges {
182-
if c.TextDocumentEdit != nil {
183-
if c.TextDocumentEdit.TextDocument.URI == uri {
184-
edits = append(edits, protocol.AsTextEdits(c.TextDocumentEdit.Edits)...)
185-
}
186-
}
162+
// Partially apply CodeAction.Edit, a WorkspaceEdit.
163+
// (See also conn.Client.applyWorkspaceEdit(a.Edit)).
164+
for _, c := range a.Edit.DocumentChanges {
165+
tde := c.TextDocumentEdit
166+
if tde != nil && tde.TextDocument.URI == uri {
167+
edits = append(edits, protocol.AsTextEdits(tde.Edits)...)
187168
}
188169
}
189170
}

gopls/internal/util/slices/slices.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,25 @@ func Contains[S ~[]E, E comparable](slice S, x E) bool {
1515
return false
1616
}
1717

18+
// IndexFunc returns the first index i satisfying f(s[i]),
19+
// or -1 if none do.
20+
// TODO(adonovan): use go1.19 slices.IndexFunc.
21+
func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
22+
for i := range s {
23+
if f(s[i]) {
24+
return i
25+
}
26+
}
27+
return -1
28+
}
29+
30+
// ContainsFunc reports whether at least one
31+
// element e of s satisfies f(e).
32+
// TODO(adonovan): use go1.19 slices.ContainsFunc.
33+
func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
34+
return IndexFunc(s, f) >= 0
35+
}
36+
1837
// Concat returns a new slice concatenating the passed in slices.
1938
// TODO(rfindley): use go1.22 slices.Contains.
2039
func Concat[S ~[]E, E any](slices ...S) S {

0 commit comments

Comments
 (0)