Skip to content

Commit e1c23fa

Browse files
VolodymyrBgfjl
authored andcommitted
rlp/rlpgen: implement package renaming support
This commit adds support for package renaming in the RLP code generator to handle import name conflicts. Key changes include: - Added automatic package alias generation for conflicting imports - Implemented package loading to get correct package names - Modified import handling to support aliased imports - Updated importsList to generate proper import statements with aliases - Added helper functions for alias management The changes allow the code generator to handle cases where multiple imported packages have the same base name by automatically generating unique aliases, improving the robustness of the generated code.
1 parent d4a3bf1 commit e1c23fa

File tree

1 file changed

+72
-18
lines changed

1 file changed

+72
-18
lines changed

rlp/rlpgen/gen.go

Lines changed: 72 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import (
2222
"go/format"
2323
"go/types"
2424
"sort"
25+
"strings"
2526

2627
"github.com/ethereum/go-ethereum/rlp/internal/rlpstruct"
28+
"golang.org/x/tools/go/packages"
2729
)
2830

2931
// buildContext keeps the data needed for make*Op.
@@ -96,14 +98,15 @@ func (bctx *buildContext) typeToStructType(typ types.Type) *rlpstruct.Type {
9698
// file and assigns unique names of temporary variables.
9799
type genContext struct {
98100
inPackage *types.Package
99-
imports map[string]struct{}
101+
imports map[string]string // Changed from map[string]struct{} to map[string]string to store package aliases
100102
tempCounter int
101103
}
102104

103105
func newGenContext(inPackage *types.Package) *genContext {
104106
return &genContext{
105-
inPackage: inPackage,
106-
imports: make(map[string]struct{}),
107+
inPackage: inPackage,
108+
imports: make(map[string]string),
109+
tempCounter: 0,
107110
}
108111
}
109112

@@ -117,32 +120,83 @@ func (ctx *genContext) resetTemp() {
117120
ctx.tempCounter = 0
118121
}
119122

120-
func (ctx *genContext) addImport(path string) {
123+
func (ctx *genContext) addImport(path string) string {
121124
if path == ctx.inPackage.Path() {
122-
return // avoid importing the package that we're generating in.
125+
return "" // avoid importing the package that we're generating in
123126
}
124-
// TODO: renaming?
125-
ctx.imports[path] = struct{}{}
127+
128+
// Check if we already have an alias for this package
129+
if alias, exists := ctx.imports[path]; exists {
130+
return alias
131+
}
132+
133+
// Get the package name and check for conflicts
134+
pkg, err := ctx.loadPackage(path)
135+
if err != nil {
136+
// If we can't load the package, use the last component of the path
137+
parts := strings.Split(path, "/")
138+
pkg = types.NewPackage(path, parts[len(parts)-1])
139+
}
140+
141+
baseName := pkg.Name()
142+
alias := baseName
143+
counter := 1
144+
145+
// If the base name conflicts with any existing import, add a numeric suffix
146+
for ctx.hasAlias(alias) {
147+
alias = fmt.Sprintf("%s%d", baseName, counter)
148+
counter++
149+
}
150+
151+
ctx.imports[path] = alias
152+
return alias
153+
}
154+
155+
// hasAlias checks if an alias is already in use
156+
func (ctx *genContext) hasAlias(alias string) bool {
157+
for _, existingAlias := range ctx.imports {
158+
if existingAlias == alias {
159+
return true
160+
}
161+
}
162+
return false
126163
}
127164

128-
// importsList returns all packages that need to be imported.
129-
func (ctx *genContext) importsList() []string {
130-
imp := make([]string, 0, len(ctx.imports))
131-
for k := range ctx.imports {
132-
imp = append(imp, k)
165+
// loadPackage attempts to load package information
166+
func (ctx *genContext) loadPackage(path string) (*types.Package, error) {
167+
cfg := &packages.Config{Mode: packages.NeedName}
168+
pkgs, err := packages.Load(cfg, path)
169+
if err != nil {
170+
return nil, err
133171
}
134-
sort.Strings(imp)
135-
return imp
172+
if len(pkgs) == 0 {
173+
return nil, fmt.Errorf("no package found for path %s", path)
174+
}
175+
return types.NewPackage(path, pkgs[0].Name), nil
136176
}
137177

138-
// qualify is the types.Qualifier used for printing types.
178+
// qualify is the types.Qualifier used for printing types
139179
func (ctx *genContext) qualify(pkg *types.Package) string {
140180
if pkg.Path() == ctx.inPackage.Path() {
141181
return ""
142182
}
143-
ctx.addImport(pkg.Path())
144-
// TODO: renaming?
145-
return pkg.Name()
183+
return ctx.addImport(pkg.Path())
184+
}
185+
186+
// importsList returns all packages that need to be imported
187+
func (ctx *genContext) importsList() []string {
188+
imp := make([]string, 0, len(ctx.imports))
189+
for path, alias := range ctx.imports {
190+
if alias == pkg.Name() {
191+
// If the alias matches the package name, use standard import
192+
imp = append(imp, fmt.Sprintf("%q", path))
193+
} else {
194+
// If we have a custom alias, use aliased import
195+
imp = append(imp, fmt.Sprintf("%s %q", alias, path))
196+
}
197+
}
198+
sort.Strings(imp)
199+
return imp
146200
}
147201

148202
type op interface {

0 commit comments

Comments
 (0)