internal/lsp: add changeMethods logic to rename check
This logic is directly copied from the refactor/rename package. See
https://github.com/golang/tools/blob/master/refactor/rename/rename.go#L321.
Fixes golang/go#39269
Change-Id: Ibe335aab37c495d2a960cb9da254b24b6fbac8e8
Reviewed-on: https://go-review.googlesource.com/c/tools/+/242158
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
index 0e7114b..bbc7c7b 100644
--- a/internal/lsp/cache/snapshot.go
+++ b/internal/lsp/cache/snapshot.go
@@ -615,6 +615,7 @@
scope, ok := s.workspacePackages[id]
return scope, ok
}
+
func (s *snapshot) FindFile(uri span.URI) source.FileHandle {
f, err := s.view.getFile(uri)
if err != nil {
diff --git a/internal/lsp/source/rename.go b/internal/lsp/source/rename.go
index 2c1cd57..ef2bc0b 100644
--- a/internal/lsp/source/rename.go
+++ b/internal/lsp/source/rename.go
@@ -104,6 +104,19 @@
to: newName,
packages: make(map[*types.Package]Package),
}
+
+ // A renaming initiated at an interface method indicates the
+ // intention to rename abstract and concrete methods as needed
+ // to preserve assignability.
+ for _, ref := range refs {
+ if obj, ok := ref.obj.(*types.Func); ok {
+ recv := obj.Type().(*types.Signature).Recv()
+ if recv != nil && isInterface(recv.Type().Underlying()) {
+ r.changeMethods = true
+ break
+ }
+ }
+ }
for _, from := range refs {
r.packages[from.pkg.GetTypes()] = from.pkg
}
diff --git a/internal/lsp/source/rename_check.go b/internal/lsp/source/rename_check.go
index 1541f0e..8823951 100644
--- a/internal/lsp/source/rename_check.go
+++ b/internal/lsp/source/rename_check.go
@@ -502,7 +502,6 @@
r.selectionConflict(from, delta, syntax, obj)
return
}
-
} else if sel.Obj().Name() == r.to {
if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), isAddressable, from.Pkg(), from.Name()); obj == from {
// Renaming 'from' may cause this existing
@@ -845,7 +844,7 @@
// The zero value is returned if not found.
//
func pathEnclosingInterval(fset *token.FileSet, pkg Package, start, end token.Pos) (resPkg Package, path []ast.Node, exact bool) {
- var pkgs = []Package{pkg}
+ pkgs := []Package{pkg}
for _, f := range pkg.GetSyntax() {
for _, imp := range f.Imports {
if imp == nil {
diff --git a/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden
index c8691ef..3a0e3f1 100644
--- a/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden
+++ b/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden
@@ -1,27 +1,3 @@
--- error-rename --
-package b
-
-var c int //@rename("int", "uint")
-
-func _() {
- error := 1 //@rename("a", "error")
- error = 2
- _ = error
-}
-
-var (
- // Hello there.
- // Foo does the thing.
- Foo int //@rename("Foo", "Bob")
-)
-
-/*
-Hello description
-*/
-func Hello() {} //@rename("Hello", "Goodbye")
-
--- uint-rename --
-builtin object "int"
-- Bob-rename --
package b
@@ -66,3 +42,27 @@
*/
func Goodbye() {} //@rename("Hello", "Goodbye")
+-- error-rename --
+package b
+
+var c int //@rename("int", "uint")
+
+func _() {
+ error := 1 //@rename("a", "error")
+ error = 2
+ _ = error
+}
+
+var (
+ // Hello there.
+ // Foo does the thing.
+ Foo int //@rename("Foo", "Bob")
+)
+
+/*
+Hello description
+*/
+func Hello() {} //@rename("Hello", "Goodbye")
+
+-- uint-rename --
+builtin object "int"
diff --git a/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/another/another.go b/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/another/another.go
new file mode 100644
index 0000000..9b50af2
--- /dev/null
+++ b/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/another/another.go
@@ -0,0 +1,13 @@
+package another
+
+type (
+ I interface{ F() }
+ C struct{ I }
+)
+
+func (C) g()
+
+func _() {
+ var x I = C{}
+ x.F() //@rename("F", "G")
+}
diff --git a/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/another/another.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/another/another.go.golden
new file mode 100644
index 0000000..d3fccda
--- /dev/null
+++ b/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/another/another.go.golden
@@ -0,0 +1,15 @@
+-- G-rename --
+package another
+
+type (
+ I interface{ G() }
+ C struct{ I }
+)
+
+func (C) g()
+
+func _() {
+ var x I = C{}
+ x.G() //@rename("F", "G")
+}
+
diff --git a/internal/lsp/testdata/lsp/summary.txt.golden b/internal/lsp/testdata/lsp/summary.txt.golden
index bf5762f..31f7f43 100644
--- a/internal/lsp/testdata/lsp/summary.txt.golden
+++ b/internal/lsp/testdata/lsp/summary.txt.golden
@@ -16,7 +16,7 @@
TypeDefinitionsCount = 2
HighlightsCount = 69
ReferencesCount = 11
-RenamesCount = 27
+RenamesCount = 28
PrepareRenamesCount = 7
SymbolsCount = 3
WorkspaceSymbolsCount = 2