Skip to content

Commit c4a336e

Browse files
committed
internal/lsp: support renaming of import spec
This change allows renamings of the name of an import spec. Since there is not always explicit identifier available to select and rename, allow renaming packages from positions within the import spec. Change-Id: I0a8aaa92c26e1795ddb9c31a1165b2f2ee89aa34 Reviewed-on: https://go-review.googlesource.com/c/tools/+/191165 Run-TryBot: Suzy Mueller <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Cottrell <[email protected]>
1 parent aa644d2 commit c4a336e

File tree

4 files changed

+203
-19
lines changed

4 files changed

+203
-19
lines changed

internal/lsp/source/rename.go

+56-5
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,19 @@ func (i *IdentifierInfo) Rename(ctx context.Context, newName string) (map[span.U
4040
ctx, done := trace.StartSpan(ctx, "source.Rename")
4141
defer done()
4242

43+
// If the object declaration is nil, assume it is an import spec.
44+
if i.decl.obj == nil {
45+
// Find the corresponding package name for this import spec
46+
// and rename that instead.
47+
ident, err := i.getPkgName(ctx)
48+
if err != nil {
49+
return nil, err
50+
}
51+
return ident.Rename(ctx, newName)
52+
}
4353
if i.Name == newName {
4454
return nil, errors.Errorf("old and new names are the same: %s", newName)
4555
}
46-
// If the object declaration is nil, assume it is an import spec and return an error.
47-
// TODO(suzmue): support renaming of identifiers in an import spec.
48-
if i.decl.obj == nil {
49-
return nil, errors.Errorf("renaming import %q not supported", i.Name)
50-
}
5156
if !isValidIdentifier(i.Name) {
5257
return nil, errors.Errorf("invalid identifier to rename: %q", i.Name)
5358
}
@@ -104,6 +109,52 @@ func (i *IdentifierInfo) Rename(ctx context.Context, newName string) (map[span.U
104109
return changes, nil
105110
}
106111

112+
// getPkgName gets the pkg name associated with an identifer representing
113+
// the import path in an import spec.
114+
func (i *IdentifierInfo) getPkgName(ctx context.Context) (*IdentifierInfo, error) {
115+
file := i.File.FileSet().File(i.Range.Start)
116+
pkgLine := file.Line(i.Range.Start)
117+
118+
for _, obj := range i.pkg.GetTypesInfo().Defs {
119+
pkgName, ok := obj.(*types.PkgName)
120+
if ok && file.Line(pkgName.Pos()) == pkgLine {
121+
return getPkgNameIdentifier(ctx, i, pkgName)
122+
}
123+
}
124+
for _, obj := range i.pkg.GetTypesInfo().Implicits {
125+
pkgName, ok := obj.(*types.PkgName)
126+
if ok && file.Line(pkgName.Pos()) == pkgLine {
127+
return getPkgNameIdentifier(ctx, i, pkgName)
128+
}
129+
}
130+
return nil, errors.Errorf("no package name for %q", i.Name)
131+
}
132+
133+
// getPkgNameIdentifier returns an IdentifierInfo representing pkgName.
134+
// pkgName must be in the same package and file as ident.
135+
func getPkgNameIdentifier(ctx context.Context, ident *IdentifierInfo, pkgName *types.PkgName) (*IdentifierInfo, error) {
136+
decl := declaration{
137+
obj: pkgName,
138+
wasImplicit: true,
139+
}
140+
var err error
141+
if decl.rng, err = objToRange(ctx, ident.File.FileSet(), decl.obj); err != nil {
142+
return nil, err
143+
}
144+
if decl.node, err = objToNode(ctx, ident.File.View(), ident.pkg.GetTypes(), decl.obj, decl.rng); err != nil {
145+
return nil, err
146+
}
147+
return &IdentifierInfo{
148+
Name: pkgName.Name(),
149+
Range: decl.rng,
150+
File: ident.File,
151+
decl: decl,
152+
pkg: ident.pkg,
153+
wasEmbeddedField: false,
154+
qf: ident.qf,
155+
}, nil
156+
}
157+
107158
// Rename all references to the identifier.
108159
func (r *renamer) update() (map[span.URI][]diff.TextEdit, error) {
109160
result := make(map[span.URI][]diff.TextEdit)

internal/lsp/testdata/rename/a/random.go.golden

+145-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package a
55
import (
66
lg "log"
77
"fmt" //@rename("fmt", "fmty")
8-
f2 "fmt"
8+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
99
)
1010

1111
func Random() int {
@@ -43,14 +43,104 @@ func sw() {
4343
}
4444
}
4545

46+
-- f2name-rename --
47+
random.go:
48+
package a
49+
50+
import (
51+
lg "log"
52+
"fmt" //@rename("fmt", "fmty")
53+
f2name "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
54+
)
55+
56+
func Random() int {
57+
y := 6 + 7
58+
return y
59+
}
60+
61+
func Random2(y int) int { //@rename("y", "z")
62+
return y
63+
}
64+
65+
type Pos struct {
66+
x, y int
67+
}
68+
69+
func (p *Pos) Sum() int {
70+
return p.x + p.y //@rename("x", "myX")
71+
}
72+
73+
func _() {
74+
var p Pos //@rename("p", "pos")
75+
_ = p.Sum() //@rename("Sum", "GetSum")
76+
}
77+
78+
func sw() {
79+
var x interface{}
80+
81+
switch y := x.(type) { //@rename("y", "y0")
82+
case int:
83+
fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format")
84+
case string:
85+
lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log")
86+
default:
87+
f2name.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2")
88+
}
89+
}
90+
91+
-- f2y-rename --
92+
random.go:
93+
package a
94+
95+
import (
96+
lg "log"
97+
"fmt" //@rename("fmt", "fmty")
98+
f2y "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
99+
)
100+
101+
func Random() int {
102+
y := 6 + 7
103+
return y
104+
}
105+
106+
func Random2(y int) int { //@rename("y", "z")
107+
return y
108+
}
109+
110+
type Pos struct {
111+
x, y int
112+
}
113+
114+
func (p *Pos) Sum() int {
115+
return p.x + p.y //@rename("x", "myX")
116+
}
117+
118+
func _() {
119+
var p Pos //@rename("p", "pos")
120+
_ = p.Sum() //@rename("Sum", "GetSum")
121+
}
122+
123+
func sw() {
124+
var x interface{}
125+
126+
switch y := x.(type) { //@rename("y", "y0")
127+
case int:
128+
fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format")
129+
case string:
130+
lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log")
131+
default:
132+
f2y.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2")
133+
}
134+
}
135+
46136
-- fmt2-rename --
47137
random.go:
48138
package a
49139

50140
import (
51141
lg "log"
52142
"fmt" //@rename("fmt", "fmty")
53-
fmt2 "fmt"
143+
fmt2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
54144
)
55145

56146
func Random() int {
@@ -89,15 +179,58 @@ func sw() {
89179
}
90180

91181
-- fmty-rename --
92-
renaming import "fmt" not supported
182+
random.go:
183+
package a
184+
185+
import (
186+
lg "log"
187+
fmty "fmt" //@rename("fmt", "fmty")
188+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
189+
)
190+
191+
func Random() int {
192+
y := 6 + 7
193+
return y
194+
}
195+
196+
func Random2(y int) int { //@rename("y", "z")
197+
return y
198+
}
199+
200+
type Pos struct {
201+
x, y int
202+
}
203+
204+
func (p *Pos) Sum() int {
205+
return p.x + p.y //@rename("x", "myX")
206+
}
207+
208+
func _() {
209+
var p Pos //@rename("p", "pos")
210+
_ = p.Sum() //@rename("Sum", "GetSum")
211+
}
212+
213+
func sw() {
214+
var x interface{}
215+
216+
switch y := x.(type) { //@rename("y", "y0")
217+
case int:
218+
fmty.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format")
219+
case string:
220+
lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log")
221+
default:
222+
f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2")
223+
}
224+
}
225+
93226
-- format-rename --
94227
random.go:
95228
package a
96229

97230
import (
98231
lg "log"
99232
format "fmt" //@rename("fmt", "fmty")
100-
f2 "fmt"
233+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
101234
)
102235

103236
func Random() int {
@@ -142,7 +275,7 @@ package a
142275
import (
143276
"log"
144277
"fmt" //@rename("fmt", "fmty")
145-
f2 "fmt"
278+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
146279
)
147280

148281
func Random() int {
@@ -187,7 +320,7 @@ package a
187320
import (
188321
lg "log"
189322
"fmt" //@rename("fmt", "fmty")
190-
f2 "fmt"
323+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
191324
)
192325

193326
func Random() int {
@@ -232,7 +365,7 @@ package a
232365
import (
233366
lg "log"
234367
"fmt" //@rename("fmt", "fmty")
235-
f2 "fmt"
368+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
236369
)
237370

238371
func Random() int {
@@ -277,7 +410,7 @@ package a
277410
import (
278411
lg "log"
279412
"fmt" //@rename("fmt", "fmty")
280-
f2 "fmt"
413+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
281414
)
282415

283416
func Random() int {
@@ -322,7 +455,7 @@ package a
322455
import (
323456
lg "log"
324457
"fmt" //@rename("fmt", "fmty")
325-
f2 "fmt"
458+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
326459
)
327460

328461
func Random() int {
@@ -367,7 +500,7 @@ package a
367500
import (
368501
lg "log"
369502
"fmt" //@rename("fmt", "fmty")
370-
f2 "fmt"
503+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
371504
)
372505

373506
func Random() int {
@@ -412,7 +545,7 @@ package a
412545
import (
413546
lg "log"
414547
"fmt" //@rename("fmt", "fmty")
415-
f2 "fmt"
548+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
416549
)
417550

418551
func Random() int {
@@ -457,7 +590,7 @@ package a
457590
import (
458591
lg "log"
459592
"fmt" //@rename("fmt", "fmty")
460-
f2 "fmt"
593+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
461594
)
462595

463596
func Random() int {

internal/lsp/testdata/rename/a/random.go.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package a
33
import (
44
lg "log"
55
"fmt" //@rename("fmt", "fmty")
6-
f2 "fmt"
6+
f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y")
77
)
88

99
func Random() int {

internal/lsp/tests/tests.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const (
3838
ExpectedTypeDefinitionsCount = 2
3939
ExpectedHighlightsCount = 2
4040
ExpectedReferencesCount = 5
41-
ExpectedRenamesCount = 18
41+
ExpectedRenamesCount = 20
4242
ExpectedSymbolsCount = 1
4343
ExpectedSignaturesCount = 21
4444
ExpectedLinksCount = 4

0 commit comments

Comments
 (0)