Skip to content

Commit 5a7a316

Browse files
committed
internal/refactor/inline: improve package local name by preserving alias
The existing implementation generates package local names by appending a numeric suffix to package name, which reduces readability. This improvement preserves existing import alias when available and fall back to the existing name generation mechanism if a conflict occurs. Updates golang/go#63352 Fixes golang/go#74965 Signed-off-by: Gavin Lam <[email protected]>
1 parent df501f0 commit 5a7a316

File tree

4 files changed

+81
-20
lines changed

4 files changed

+81
-20
lines changed

internal/refactor/inline/inline.go

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -491,14 +491,10 @@ func (i *importState) importName(pkgPath string, shadow shadowMap) string {
491491
return ""
492492
}
493493

494-
// localName returns the local name for a given imported package path,
495-
// adding one if it doesn't exists.
496-
func (i *importState) localName(pkgPath, pkgName string, shadow shadowMap) string {
497-
// Does an import already exist that works in this shadowing context?
498-
if name := i.importName(pkgPath, shadow); name != "" {
499-
return name
500-
}
501-
494+
// findNewLocalName returns a new local name to use in a particular shadowing
495+
// context. It considers the existing package alias, or construct a new alias
496+
// based on the package name.
497+
func (i *importState) findNewLocalName(pkgName, pkgAlias string, shadow shadowMap) string {
502498
newlyAdded := func(name string) bool {
503499
return slices.ContainsFunc(i.newImports, func(n newImport) bool { return n.pkgName == name })
504500
}
@@ -516,20 +512,35 @@ func (i *importState) localName(pkgPath, pkgName string, shadow shadowMap) strin
516512

517513
// import added by callee
518514
//
519-
// Choose local PkgName based on last segment of
515+
// Try to preserve the package alias first.
516+
//
517+
// If that is shadowed, choose local PkgName based on last segment of
520518
// package path plus, if needed, a numeric suffix to
521519
// ensure uniqueness.
522520
//
523521
// "init" is not a legal PkgName.
524-
//
525-
// TODO(rfindley): is it worth preserving local package names for callee
526-
// imports? Are they likely to be better or worse than the name we choose
527-
// here?
522+
if shadow[pkgAlias] == 0 && !shadowedInCaller(pkgAlias) && !newlyAdded(pkgAlias) && pkgAlias != "init" {
523+
return pkgAlias
524+
}
525+
528526
base := pkgName
529527
name := base
530528
for n := 0; shadow[name] != 0 || shadowedInCaller(name) || newlyAdded(name) || name == "init"; n++ {
531529
name = fmt.Sprintf("%s%d", base, n)
532530
}
531+
532+
return name
533+
}
534+
535+
// localName returns the local name for a given imported package path,
536+
// adding one if it doesn't exists.
537+
func (i *importState) localName(pkgPath, pkgName, pkgAlias string, shadow shadowMap) string {
538+
// Does an import already exist that works in this shadowing context?
539+
if name := i.importName(pkgPath, shadow); name != "" {
540+
return name
541+
}
542+
543+
name := i.findNewLocalName(pkgName, pkgAlias, shadow)
533544
i.logf("adding import %s %q", name, pkgPath)
534545
spec := &ast.ImportSpec{
535546
Path: &ast.BasicLit{
@@ -1338,7 +1349,7 @@ func (st *state) renameFreeObjs(istate *importState) ([]ast.Expr, error) {
13381349
var newName ast.Expr
13391350
if obj.Kind == "pkgname" {
13401351
// Use locally appropriate import, creating as needed.
1341-
n := istate.localName(obj.PkgPath, obj.PkgName, obj.Shadow)
1352+
n := istate.localName(obj.PkgPath, obj.PkgName, obj.Name, obj.Shadow)
13421353
newName = makeIdent(n) // imported package
13431354
} else if !obj.ValidPos {
13441355
// Built-in function, type, or value (e.g. nil, zero):
@@ -1383,7 +1394,7 @@ func (st *state) renameFreeObjs(istate *importState) ([]ast.Expr, error) {
13831394

13841395
// Form a qualified identifier, pkg.Name.
13851396
if qualify {
1386-
pkgName := istate.localName(obj.PkgPath, obj.PkgName, obj.Shadow)
1397+
pkgName := istate.localName(obj.PkgPath, obj.PkgName, obj.PkgName, obj.Shadow)
13871398
newName = &ast.SelectorExpr{
13881399
X: makeIdent(pkgName),
13891400
Sel: makeIdent(obj.Name),

internal/refactor/inline/testdata/assignment.txtar

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,11 @@ func _() {
126126
package a
127127

128128
import (
129-
"testdata/c"
130-
c0 "testdata/c2"
129+
c1 "testdata/c"
130+
c2 "testdata/c2"
131131
)
132132

133133
func _() {
134-
x, y := c.C(0), c0.C(1) //@ inline(re"B", b4)
134+
x, y := c1.C(0), c2.C(1) //@ inline(re"B", b4)
135135
_, _ = x, y
136136
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Test of inlining a function and preserve the imported package alias.
2+
3+
-- go.mod --
4+
module example.com
5+
go 1.19
6+
7+
-- main/main.go --
8+
package main
9+
10+
import "example.com/util"
11+
12+
func main() {
13+
util.A() //@ inline(re"A", result)
14+
}
15+
16+
-- util/util.go --
17+
package util
18+
19+
import stringutil "example.com/string/util"
20+
import urlutil "example.com/url/util"
21+
22+
func A() {
23+
stringutil.A()
24+
urlutil.A()
25+
}
26+
27+
-- string/util/util.go --
28+
package util
29+
30+
func A() {
31+
}
32+
33+
-- url/util/util.go --
34+
package util
35+
36+
func A() {
37+
}
38+
39+
-- result --
40+
package main
41+
42+
import (
43+
stringutil "example.com/string/util"
44+
urlutil "example.com/url/util"
45+
)
46+
47+
func main() {
48+
stringutil.A()
49+
urlutil.A() //@ inline(re"A", result)
50+
}

internal/refactor/inline/testdata/issue63298.txtar

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ func B() {}
3838
package a
3939

4040
import (
41-
b0 "testdata/another/b"
41+
anotherb "testdata/another/b"
4242
"testdata/b"
4343
)
4444

4545
func _() {
4646
b.B()
47-
b0.B() //@ inline(re"a2", result)
47+
anotherb.B() //@ inline(re"a2", result)
4848
}

0 commit comments

Comments
 (0)