gopls/internal/lsp/source: move edit logic into the protocol package
Change-Id: I8a2dcafc109bf298b6edfe7a7029f8b9098880d6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/543920
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/cmd/cmd.go b/gopls/internal/cmd/cmd.go
index 83577f6..08aaa85 100644
--- a/gopls/internal/cmd/cmd.go
+++ b/gopls/internal/cmd/cmd.go
@@ -29,7 +29,6 @@
"golang.org/x/tools/gopls/internal/lsp/filecache"
"golang.org/x/tools/gopls/internal/lsp/lsprpc"
"golang.org/x/tools/gopls/internal/lsp/protocol"
- "golang.org/x/tools/gopls/internal/lsp/source"
"golang.org/x/tools/gopls/internal/settings"
"golang.org/x/tools/internal/constraints"
"golang.org/x/tools/internal/diff"
@@ -585,7 +584,7 @@
if len(edits) == 0 {
return nil
}
- newContent, renameEdits, err := source.ApplyProtocolEdits(mapper, edits)
+ newContent, renameEdits, err := protocol.ApplyEdits(mapper, edits)
if err != nil {
return err
}
diff --git a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_tidy.go
index 1964259..31a35a5 100644
--- a/gopls/internal/lsp/cache/mod_tidy.go
+++ b/gopls/internal/lsp/cache/mod_tidy.go
@@ -457,7 +457,7 @@
}
// Calculate the edits to be made due to the change.
edits := computeEdits(string(m.Content), string(newContent))
- return ToProtocolEdits(m, edits)
+ return protocol.EditsFromDiffEdits(m, edits)
}
// missingModuleForImport creates an error for a given import path that comes
diff --git a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go
index 2ab4694..44dcfa3 100644
--- a/gopls/internal/lsp/cache/pkg.go
+++ b/gopls/internal/lsp/cache/pkg.go
@@ -75,7 +75,6 @@
RemoveIntermediateTestVariants = source.RemoveIntermediateTestVariants
IsCommandLineArguments = source.IsCommandLineArguments
BundleQuickFixes = source.BundleQuickFixes
- ToProtocolEdits = source.ToProtocolEdits
NewFilterer = source.NewFilterer
)
diff --git a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go
index 3ff48b6..ce1b358 100644
--- a/gopls/internal/lsp/command.go
+++ b/gopls/internal/lsp/command.go
@@ -471,7 +471,7 @@
}
// Calculate the edits to be made due to the change.
diff := snapshot.Options().ComputeEdits(string(pm.Mapper.Content), string(newContent))
- return source.ToProtocolEdits(pm.Mapper, diff)
+ return protocol.EditsFromDiffEdits(pm.Mapper, diff)
}
func (c *commandHandler) Test(ctx context.Context, uri protocol.DocumentURI, tests, benchmarks []string) error {
@@ -677,7 +677,7 @@
m := protocol.NewMapper(fh.URI(), oldContent)
diff := snapshot.Options().ComputeEdits(string(oldContent), string(newContent))
- edits, err := source.ToProtocolEdits(m, diff)
+ edits, err := protocol.EditsFromDiffEdits(m, diff)
if err != nil {
return nil, err
}
diff --git a/gopls/internal/lsp/fake/edit.go b/gopls/internal/lsp/fake/edit.go
index 40762f2..2fac24b 100644
--- a/gopls/internal/lsp/fake/edit.go
+++ b/gopls/internal/lsp/fake/edit.go
@@ -6,7 +6,6 @@
import (
"golang.org/x/tools/gopls/internal/lsp/protocol"
- "golang.org/x/tools/gopls/internal/lsp/source"
"golang.org/x/tools/internal/diff"
)
@@ -36,7 +35,7 @@
// and returns a new slice containing the lines of the patched file.
// It is a wrapper around diff.Apply; see that function for preconditions.
func applyEdits(mapper *protocol.Mapper, edits []protocol.TextEdit, windowsLineEndings bool) ([]byte, error) {
- diffEdits, err := source.FromProtocolEdits(mapper, edits)
+ diffEdits, err := protocol.EditsToDiffEdits(mapper, edits)
if err != nil {
return nil, err
}
diff --git a/gopls/internal/lsp/mod/format.go b/gopls/internal/lsp/mod/format.go
index b04baa2..7b0c6b1 100644
--- a/gopls/internal/lsp/mod/format.go
+++ b/gopls/internal/lsp/mod/format.go
@@ -27,5 +27,5 @@
}
// Calculate the edits to be made due to the change.
diffs := snapshot.Options().ComputeEdits(string(pm.Mapper.Content), string(formatted))
- return source.ToProtocolEdits(pm.Mapper, diffs)
+ return protocol.EditsFromDiffEdits(pm.Mapper, diffs)
}
diff --git a/gopls/internal/lsp/protocol/edits.go b/gopls/internal/lsp/protocol/edits.go
new file mode 100644
index 0000000..44694c5
--- /dev/null
+++ b/gopls/internal/lsp/protocol/edits.go
@@ -0,0 +1,62 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protocol
+
+import "golang.org/x/tools/internal/diff"
+
+// EditsFromDiffEdits converts diff.Edits to a non-nil slice of LSP TextEdits.
+// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textEditArray
+func EditsFromDiffEdits(m *Mapper, edits []diff.Edit) ([]TextEdit, error) {
+ // LSP doesn't require TextEditArray to be sorted:
+ // this is the receiver's concern. But govim, and perhaps
+ // other clients have historically relied on the order.
+ edits = append([]diff.Edit(nil), edits...)
+ diff.SortEdits(edits)
+
+ result := make([]TextEdit, len(edits))
+ for i, edit := range edits {
+ rng, err := m.OffsetRange(edit.Start, edit.End)
+ if err != nil {
+ return nil, err
+ }
+ result[i] = TextEdit{
+ Range: rng,
+ NewText: edit.New,
+ }
+ }
+ return result, nil
+}
+
+// EditsToDiffEdits converts LSP TextEdits to diff.Edits.
+// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textEditArray
+func EditsToDiffEdits(m *Mapper, edits []TextEdit) ([]diff.Edit, error) {
+ if edits == nil {
+ return nil, nil
+ }
+ result := make([]diff.Edit, len(edits))
+ for i, edit := range edits {
+ start, end, err := m.RangeOffsets(edit.Range)
+ if err != nil {
+ return nil, err
+ }
+ result[i] = diff.Edit{
+ Start: start,
+ End: end,
+ New: edit.NewText,
+ }
+ }
+ return result, nil
+}
+
+// ApplyEdits applies the patch (edits) to m.Content and returns the result.
+// It also returns the edits converted to diff-package form.
+func ApplyEdits(m *Mapper, edits []TextEdit) ([]byte, []diff.Edit, error) {
+ diffEdits, err := EditsToDiffEdits(m, edits)
+ if err != nil {
+ return nil, nil, err
+ }
+ out, err := diff.ApplyBytes(m.Content, diffEdits)
+ return out, diffEdits, err
+}
diff --git a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/marker.go
index a96b409..e279396 100644
--- a/gopls/internal/lsp/regtest/marker.go
+++ b/gopls/internal/lsp/regtest/marker.go
@@ -33,7 +33,6 @@
"golang.org/x/tools/gopls/internal/lsp/lsprpc"
"golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/gopls/internal/lsp/safetoken"
- "golang.org/x/tools/gopls/internal/lsp/source"
"golang.org/x/tools/gopls/internal/lsp/tests"
"golang.org/x/tools/gopls/internal/lsp/tests/compare"
"golang.org/x/tools/internal/diff"
@@ -1675,9 +1674,7 @@
}
filename := mark.path()
mapper := mark.mapper()
- patched, _, err := source.ApplyProtocolEdits(mapper, append([]protocol.TextEdit{
- *selected.TextEdit,
- }, selected.AdditionalTextEdits...))
+ patched, _, err := protocol.ApplyEdits(mapper, append([]protocol.TextEdit{*selected.TextEdit}, selected.AdditionalTextEdits...))
if err != nil {
mark.errorf("ApplyProtocolEdits failed: %v", err)
@@ -1739,7 +1736,7 @@
mark.errorf("Editor.Mapper(%s) failed: %v", filename, err)
return
}
- got, _, err := source.ApplyProtocolEdits(mapper, edits)
+ got, _, err := protocol.ApplyEdits(mapper, edits)
if err != nil {
mark.errorf("ApplyProtocolEdits failed: %v", err)
return
@@ -1766,7 +1763,7 @@
mark.errorf("Editor.Mapper(%s) failed: %v", filename, err)
}
- got, _, err = source.ApplyProtocolEdits(mapper, edits)
+ got, _, err = protocol.ApplyEdits(mapper, edits)
if err != nil {
mark.errorf("ApplyProtocolEdits failed: %v", err)
return
@@ -2008,7 +2005,7 @@
if err != nil {
return err
}
- patched, _, err := source.ApplyProtocolEdits(mapper, change.TextDocumentEdit.Edits)
+ patched, _, err := protocol.ApplyEdits(mapper, change.TextDocumentEdit.Edits)
if err != nil {
return err
}
@@ -2400,7 +2397,7 @@
}
m := mark.mapper()
- got, _, err := source.ApplyProtocolEdits(m, edits)
+ got, _, err := protocol.ApplyEdits(m, edits)
if err != nil {
mark.errorf("ApplyProtocolEdits: %v", err)
return
diff --git a/gopls/internal/lsp/source/change_quote.go b/gopls/internal/lsp/source/change_quote.go
index 6bb7f37..4c2661d 100644
--- a/gopls/internal/lsp/source/change_quote.go
+++ b/gopls/internal/lsp/source/change_quote.go
@@ -69,7 +69,7 @@
End: end,
New: newText,
}}
- pedits, err := ToProtocolEdits(pgf.Mapper, edits)
+ pedits, err := protocol.EditsFromDiffEdits(pgf.Mapper, edits)
if err != nil {
bug.Reportf("failed to convert diff.Edit to protocol.TextEdit:%v", err)
return protocol.CodeAction{}, false
diff --git a/gopls/internal/lsp/source/change_signature.go b/gopls/internal/lsp/source/change_signature.go
index dcd1185..5f30629 100644
--- a/gopls/internal/lsp/source/change_signature.go
+++ b/gopls/internal/lsp/source/change_signature.go
@@ -164,7 +164,7 @@
}
edits := diff.Bytes(before, after)
mapper := protocol.NewMapper(uri, before)
- pedits, err := ToProtocolEdits(mapper, edits)
+ pedits, err := protocol.EditsFromDiffEdits(mapper, edits)
if err != nil {
return nil, fmt.Errorf("computing edits for %s: %v", uri, err)
}
diff --git a/gopls/internal/lsp/source/completion/util.go b/gopls/internal/lsp/source/completion/util.go
index 4b6ec09..e29e9f5 100644
--- a/gopls/internal/lsp/source/completion/util.go
+++ b/gopls/internal/lsp/source/completion/util.go
@@ -316,7 +316,7 @@
if err != nil {
return nil, err // can't happen: from/to came from c
}
- return source.ToProtocolEdits(c.mapper, []diff.Edit{{
+ return protocol.EditsFromDiffEdits(c.mapper, []diff.Edit{{
Start: start,
End: end,
New: newText,
diff --git a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/format.go
index 9f3597c..d36d50b 100644
--- a/gopls/internal/lsp/source/format.go
+++ b/gopls/internal/lsp/source/format.go
@@ -306,7 +306,7 @@
defer done()
edits := snapshot.Options().ComputeEdits(string(pgf.Src), formatted)
- return ToProtocolEdits(pgf.Mapper, edits)
+ return protocol.EditsFromDiffEdits(pgf.Mapper, edits)
}
// protocolEditsFromSource converts text edits to LSP edits using the original
@@ -333,57 +333,6 @@
return result, nil
}
-// ToProtocolEdits converts diff.Edits to a non-nil slice of LSP TextEdits.
-// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textEditArray
func ToProtocolEdits(m *protocol.Mapper, edits []diff.Edit) ([]protocol.TextEdit, error) {
- // LSP doesn't require TextEditArray to be sorted:
- // this is the receiver's concern. But govim, and perhaps
- // other clients have historically relied on the order.
- edits = append([]diff.Edit(nil), edits...)
- diff.SortEdits(edits)
-
- result := make([]protocol.TextEdit, len(edits))
- for i, edit := range edits {
- rng, err := m.OffsetRange(edit.Start, edit.End)
- if err != nil {
- return nil, err
- }
- result[i] = protocol.TextEdit{
- Range: rng,
- NewText: edit.New,
- }
- }
- return result, nil
-}
-
-// FromProtocolEdits converts LSP TextEdits to diff.Edits.
-// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textEditArray
-func FromProtocolEdits(m *protocol.Mapper, edits []protocol.TextEdit) ([]diff.Edit, error) {
- if edits == nil {
- return nil, nil
- }
- result := make([]diff.Edit, len(edits))
- for i, edit := range edits {
- start, end, err := m.RangeOffsets(edit.Range)
- if err != nil {
- return nil, err
- }
- result[i] = diff.Edit{
- Start: start,
- End: end,
- New: edit.NewText,
- }
- }
- return result, nil
-}
-
-// ApplyProtocolEdits applies the patch (edits) to m.Content and returns the result.
-// It also returns the edits converted to diff-package form.
-func ApplyProtocolEdits(m *protocol.Mapper, edits []protocol.TextEdit) ([]byte, []diff.Edit, error) {
- diffEdits, err := FromProtocolEdits(m, edits)
- if err != nil {
- return nil, nil, err
- }
- out, err := diff.ApplyBytes(m.Content, diffEdits)
- return out, diffEdits, err
+ return protocol.EditsFromDiffEdits(m, edits)
}
diff --git a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rename.go
index 936ef6a..42a22d2 100644
--- a/gopls/internal/lsp/source/rename.go
+++ b/gopls/internal/lsp/source/rename.go
@@ -276,7 +276,7 @@
return nil, false, err
}
m := protocol.NewMapper(uri, data)
- protocolEdits, err := ToProtocolEdits(m, edits)
+ protocolEdits, err := protocol.EditsFromDiffEdits(m, edits)
if err != nil {
return nil, false, err
}
diff --git a/gopls/internal/lsp/work/format.go b/gopls/internal/lsp/work/format.go
index 4fc6dd7..ef86952 100644
--- a/gopls/internal/lsp/work/format.go
+++ b/gopls/internal/lsp/work/format.go
@@ -25,5 +25,5 @@
formatted := modfile.Format(pw.File.Syntax)
// Calculate the edits to be made due to the change.
diffs := snapshot.Options().ComputeEdits(string(pw.Mapper.Content), string(formatted))
- return source.ToProtocolEdits(pw.Mapper, diffs)
+ return protocol.EditsFromDiffEdits(pw.Mapper, diffs)
}