mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
This change provides support to rename identifiers within a single package. The renaming is performed by finding all references to an identifier, and then creating text edits to replace the existing text with the new identifier. Editing an import spec is not supported. Fixes #27571 Change-Id: I0881b65a1b3c72d7c53d7d6ab1ea386160dc00fb Reviewed-on: https://go-review.googlesource.com/c/tools/+/182585 Run-TryBot: Suzy Mueller <suzmue@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
package source
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"go/token"
|
|
"go/types"
|
|
|
|
"golang.org/x/tools/internal/span"
|
|
)
|
|
|
|
// Rename returns a map of TextEdits for each file modified when renaming a given identifier within a package.
|
|
func Rename(ctx context.Context, view View, f GoFile, pos token.Pos, newName string) (map[span.URI][]TextEdit, error) {
|
|
pkg := f.GetPackage(ctx)
|
|
if pkg == nil || pkg.IsIllTyped() {
|
|
return nil, fmt.Errorf("package for %s is ill typed", f.URI())
|
|
}
|
|
|
|
// Get the identifier to rename.
|
|
ident, err := Identifier(ctx, view, f, pos)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if ident.Name == newName {
|
|
return nil, fmt.Errorf("old and new names are the same: %s", newName)
|
|
}
|
|
|
|
// Do not rename identifiers declared in another package.
|
|
if pkg.GetTypes() != ident.decl.obj.Pkg() {
|
|
return nil, fmt.Errorf("failed to rename because %q is declared in package %q", ident.Name, ident.decl.obj.Pkg().Name())
|
|
}
|
|
|
|
// TODO(suzmue): Support renaming of imported packages.
|
|
if _, ok := ident.decl.obj.(*types.PkgName); ok {
|
|
return nil, fmt.Errorf("renaming imported package %s not supported", ident.Name)
|
|
}
|
|
|
|
// TODO(suzmue): Check that renaming ident is ok.
|
|
refs, err := ident.References(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
changes := make(map[span.URI][]TextEdit)
|
|
for _, ref := range refs {
|
|
refSpan, err := ref.Range.Span()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
edit := TextEdit{
|
|
Span: refSpan,
|
|
NewText: newName,
|
|
}
|
|
changes[refSpan.URI()] = append(changes[refSpan.URI()], edit)
|
|
}
|
|
|
|
return changes, nil
|
|
}
|