internal/lsp: update doc comments on rename
Replace doc comment text for the declaration of an identifier with the new name. This implementation is taken from golang.org/x/tools/refactor/rename. Change-Id: Id1b80fad456646a46c8ae2caa4e8febf05aaf798 Reviewed-on: https://go-review.googlesource.com/c/tools/+/183261 Reviewed-by: Rebecca Stambler <rstambler@golang.org> Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
8ea4f8e3e5
commit
70d37148ca
|
@ -15,10 +15,11 @@ import (
|
||||||
|
|
||||||
// ReferenceInfo holds information about reference to an identifier in Go source.
|
// ReferenceInfo holds information about reference to an identifier in Go source.
|
||||||
type ReferenceInfo struct {
|
type ReferenceInfo struct {
|
||||||
Name string
|
Name string
|
||||||
Range span.Range
|
Range span.Range
|
||||||
ident *ast.Ident
|
ident *ast.Ident
|
||||||
obj types.Object
|
obj types.Object
|
||||||
|
isDeclaration bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// References returns a list of references for a given identifier within a package.
|
// References returns a list of references for a given identifier within a package.
|
||||||
|
@ -44,9 +45,10 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro
|
||||||
// This occurs when the variable is declared in a type switch statement
|
// This occurs when the variable is declared in a type switch statement
|
||||||
// or is an implicit package name.
|
// or is an implicit package name.
|
||||||
references = append(references, &ReferenceInfo{
|
references = append(references, &ReferenceInfo{
|
||||||
Name: i.decl.obj.Name(),
|
Name: i.decl.obj.Name(),
|
||||||
Range: i.decl.rng,
|
Range: i.decl.rng,
|
||||||
obj: i.decl.obj,
|
obj: i.decl.obj,
|
||||||
|
isDeclaration: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,10 +57,11 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
references = append(references, &ReferenceInfo{
|
references = append(references, &ReferenceInfo{
|
||||||
Name: ident.Name,
|
Name: ident.Name,
|
||||||
Range: span.NewRange(i.File.FileSet(), ident.Pos(), ident.End()),
|
Range: span.NewRange(i.File.FileSet(), ident.Pos(), ident.End()),
|
||||||
ident: ident,
|
ident: ident,
|
||||||
obj: obj,
|
obj: obj,
|
||||||
|
isDeclaration: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,10 @@ package source
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"golang.org/x/tools/go/types/typeutil"
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
"golang.org/x/tools/internal/span"
|
"golang.org/x/tools/internal/span"
|
||||||
|
@ -89,6 +91,7 @@ func Rename(ctx context.Context, view View, f GoFile, pos token.Pos, newName str
|
||||||
func (r *renamer) update(ctx context.Context, view View) (map[span.URI][]TextEdit, error) {
|
func (r *renamer) update(ctx context.Context, view View) (map[span.URI][]TextEdit, error) {
|
||||||
result := make(map[span.URI][]TextEdit)
|
result := make(map[span.URI][]TextEdit)
|
||||||
|
|
||||||
|
docRegexp := regexp.MustCompile(`\b` + r.from + `\b`)
|
||||||
for _, ref := range r.refs {
|
for _, ref := range r.refs {
|
||||||
refSpan, err := ref.Range.Span()
|
refSpan, err := ref.Range.Span()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -100,7 +103,57 @@ func (r *renamer) update(ctx context.Context, view View) (map[span.URI][]TextEdi
|
||||||
NewText: r.to,
|
NewText: r.to,
|
||||||
}
|
}
|
||||||
result[refSpan.URI()] = append(result[refSpan.URI()], edit)
|
result[refSpan.URI()] = append(result[refSpan.URI()], edit)
|
||||||
|
|
||||||
|
if ref.isDeclaration {
|
||||||
|
// Perform the rename in doc comments too (declared in the original package)
|
||||||
|
if doc := r.docComment(r.pkg, ref.ident); doc != nil {
|
||||||
|
for _, comment := range doc.List {
|
||||||
|
for _, locs := range docRegexp.FindAllStringIndex(comment.Text, -1) {
|
||||||
|
rng := span.NewRange(r.fset, comment.Pos()+token.Pos(locs[0]), comment.Pos()+token.Pos(locs[1]))
|
||||||
|
spn, err := rng.Span()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result[refSpan.URI()] = append(result[refSpan.URI()], TextEdit{
|
||||||
|
Span: spn,
|
||||||
|
NewText: r.to,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
comment.Text = docRegexp.ReplaceAllString(comment.Text, r.to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// docComment returns the doc for an identifier.
|
||||||
|
func (r *renamer) docComment(pkg Package, id *ast.Ident) *ast.CommentGroup {
|
||||||
|
_, nodes, _ := pathEnclosingInterval(r.fset, pkg, id.Pos(), id.End())
|
||||||
|
for _, node := range nodes {
|
||||||
|
switch decl := node.(type) {
|
||||||
|
case *ast.FuncDecl:
|
||||||
|
return decl.Doc
|
||||||
|
case *ast.Field:
|
||||||
|
return decl.Doc
|
||||||
|
case *ast.GenDecl:
|
||||||
|
return decl.Doc
|
||||||
|
// For {Type,Value}Spec, if the doc on the spec is absent,
|
||||||
|
// search for the enclosing GenDecl
|
||||||
|
case *ast.TypeSpec:
|
||||||
|
if decl.Doc != nil {
|
||||||
|
return decl.Doc
|
||||||
|
}
|
||||||
|
case *ast.ValueSpec:
|
||||||
|
if decl.Doc != nil {
|
||||||
|
return decl.Doc
|
||||||
|
}
|
||||||
|
case *ast.Ident:
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue