internal/lsp: rename all the package names in the renamed package

This CL contains a partial implementation of package renaming. Currently gopls is only able to rename references to the renaming package within the renaming package itself.

prepareRename is still expected to return an error for renaming a package.

For golang/go#41567

Change-Id: I3683a0a7128bba7620ef30db528f45b753e6c08f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/420219
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Dylan Le <dungtuanle@google.com>
This commit is contained in:
Dylan Le 2022-07-29 16:50:30 -04:00
parent 9f65685098
commit bd3f524777
2 changed files with 72 additions and 0 deletions

View File

@ -10,6 +10,7 @@ import (
"golang.org/x/tools/internal/lsp/protocol"
. "golang.org/x/tools/internal/lsp/regtest"
"golang.org/x/tools/internal/testenv"
)
func TestPrepareRenamePackage(t *testing.T) {
@ -51,6 +52,41 @@ func main() {
})
}
func TestRenamePackageInRenamedPackage(t *testing.T) {
// Failed at Go 1.13; not investigated
testenv.NeedsGo1Point(t, 14)
const files = `
-- go.mod --
module mod.com
go 1.18
-- main.go --
package main
import (
"fmt"
"a.go"
)
func main() {
fmt.Println(a.C)
}
-- a.go --
package main
const C = 1
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
pos := env.RegexpSearch("main.go", "main")
env.Rename("main.go", pos, "pkg")
// Check if the new package name exists.
env.RegexpSearch("main.go", "package pkg")
env.RegexpSearch("a.go", "package pkg")
})
}
// Test for golang/go#47564.
func TestRenameInTestVariant(t *testing.T) {
const files = `

View File

@ -118,6 +118,41 @@ func Rename(ctx context.Context, s Snapshot, f FileHandle, pp protocol.Position,
ctx, done := event.Start(ctx, "source.Rename")
defer done()
pgf, err := s.ParseGo(ctx, f, ParseFull)
if err != nil {
return nil, err
}
inPackageName, err := isInPackageName(ctx, s, f, pgf, pp)
if err != nil {
return nil, err
}
if inPackageName {
renamingPkg, err := s.PackageForFile(ctx, f.URI(), TypecheckAll, NarrowestPackage)
if err != nil {
return nil, err
}
result := make(map[span.URI][]protocol.TextEdit)
// Rename internal references to the package in the renaming package
// Todo(dle): need more investigation on case when pkg.GoFiles != pkg.CompiledGoFiles if using cgo.
for _, f := range renamingPkg.CompiledGoFiles() {
pkgNameMappedRange := NewMappedRange(f.Tok, f.Mapper, f.File.Name.Pos(), f.File.Name.End())
rng, err := pkgNameMappedRange.Range()
if err != nil {
return nil, err
}
result[f.URI] = []protocol.TextEdit{
{
Range: rng,
NewText: newName,
},
}
}
return result, nil
}
qos, err := qualifiedObjsAtProtocolPos(ctx, s, f.URI(), pp)
if err != nil {
return nil, err
@ -182,6 +217,7 @@ func Rename(ctx context.Context, s Snapshot, f FileHandle, pp protocol.Position,
if err != nil {
return nil, err
}
result := make(map[span.URI][]protocol.TextEdit)
for uri, edits := range changes {
// These edits should really be associated with FileHandles for maximal correctness.