rlp/rlpgen: fix

This commit is contained in:
Felix Lange 2025-06-19 17:02:07 +02:00
parent e1c23fa1f3
commit e9242f8de2

View file

@ -22,7 +22,6 @@ import (
"go/format" "go/format"
"go/types" "go/types"
"sort" "sort"
"strings"
"github.com/ethereum/go-ethereum/rlp/internal/rlpstruct" "github.com/ethereum/go-ethereum/rlp/internal/rlpstruct"
"golang.org/x/tools/go/packages" "golang.org/x/tools/go/packages"
@ -98,14 +97,19 @@ func (bctx *buildContext) typeToStructType(typ types.Type) *rlpstruct.Type {
// file and assigns unique names of temporary variables. // file and assigns unique names of temporary variables.
type genContext struct { type genContext struct {
inPackage *types.Package inPackage *types.Package
imports map[string]string // Changed from map[string]struct{} to map[string]string to store package aliases imports map[string]genImportPackage
tempCounter int tempCounter int
} }
type genImportPackage struct {
alias string
pkg *types.Package
}
func newGenContext(inPackage *types.Package) *genContext { func newGenContext(inPackage *types.Package) *genContext {
return &genContext{ return &genContext{
inPackage: inPackage, inPackage: inPackage,
imports: make(map[string]string), imports: make(map[string]genImportPackage),
tempCounter: 0, tempCounter: 0,
} }
} }
@ -120,24 +124,21 @@ func (ctx *genContext) resetTemp() {
ctx.tempCounter = 0 ctx.tempCounter = 0
} }
func (ctx *genContext) addImport(path string) string { func (ctx *genContext) addImportPath(path string) {
if path == ctx.inPackage.Path() {
return "" // avoid importing the package that we're generating in
}
// Check if we already have an alias for this package
if alias, exists := ctx.imports[path]; exists {
return alias
}
// Get the package name and check for conflicts
pkg, err := ctx.loadPackage(path) pkg, err := ctx.loadPackage(path)
if err != nil { if err != nil {
// If we can't load the package, use the last component of the path panic(fmt.Sprintf("can't load package %q: %v", path, err))
parts := strings.Split(path, "/")
pkg = types.NewPackage(path, parts[len(parts)-1])
} }
ctx.addImport(pkg)
}
func (ctx *genContext) addImport(pkg *types.Package) string {
if pkg.Path() == ctx.inPackage.Path() {
return "" // avoid importing the package that we're generating in
}
if p, exists := ctx.imports[pkg.Path()]; exists {
return p.alias
}
baseName := pkg.Name() baseName := pkg.Name()
alias := baseName alias := baseName
counter := 1 counter := 1
@ -148,14 +149,14 @@ func (ctx *genContext) addImport(path string) string {
counter++ counter++
} }
ctx.imports[path] = alias ctx.imports[pkg.Path()] = genImportPackage{alias, pkg}
return alias return alias
} }
// hasAlias checks if an alias is already in use // hasAlias checks if an alias is already in use
func (ctx *genContext) hasAlias(alias string) bool { func (ctx *genContext) hasAlias(alias string) bool {
for _, existingAlias := range ctx.imports { for _, p := range ctx.imports {
if existingAlias == alias { if p.alias == alias {
return true return true
} }
} }
@ -180,19 +181,19 @@ func (ctx *genContext) qualify(pkg *types.Package) string {
if pkg.Path() == ctx.inPackage.Path() { if pkg.Path() == ctx.inPackage.Path() {
return "" return ""
} }
return ctx.addImport(pkg.Path()) return ctx.addImport(pkg)
} }
// importsList returns all packages that need to be imported // importsList returns all packages that need to be imported
func (ctx *genContext) importsList() []string { func (ctx *genContext) importsList() []string {
imp := make([]string, 0, len(ctx.imports)) imp := make([]string, 0, len(ctx.imports))
for path, alias := range ctx.imports { for path, p := range ctx.imports {
if alias == pkg.Name() { if p.alias == p.pkg.Name() {
// If the alias matches the package name, use standard import // If the alias matches the package name, use standard import
imp = append(imp, fmt.Sprintf("%q", path)) imp = append(imp, fmt.Sprintf("%q", path))
} else { } else {
// If we have a custom alias, use aliased import // If we have a custom alias, use aliased import
imp = append(imp, fmt.Sprintf("%s %q", alias, path)) imp = append(imp, fmt.Sprintf("%s %q", p.alias, path))
} }
} }
sort.Strings(imp) sort.Strings(imp)
@ -413,7 +414,7 @@ func (op uint256Op) genWrite(ctx *genContext, v string) string {
} }
func (op uint256Op) genDecode(ctx *genContext) (string, string) { func (op uint256Op) genDecode(ctx *genContext) (string, string) {
ctx.addImport("github.com/holiman/uint256") ctx.addImportPath("github.com/holiman/uint256")
var b bytes.Buffer var b bytes.Buffer
resultV := ctx.temp() resultV := ctx.temp()
@ -786,7 +787,7 @@ func (bctx *buildContext) makeOp(name *types.Named, typ types.Type, tags rlpstru
// generateDecoder generates the DecodeRLP method on 'typ'. // generateDecoder generates the DecodeRLP method on 'typ'.
func generateDecoder(ctx *genContext, typ string, op op) []byte { func generateDecoder(ctx *genContext, typ string, op op) []byte {
ctx.resetTemp() ctx.resetTemp()
ctx.addImport(pathOfPackageRLP) ctx.addImportPath(pathOfPackageRLP)
result, code := op.genDecode(ctx) result, code := op.genDecode(ctx)
var b bytes.Buffer var b bytes.Buffer
@ -801,8 +802,8 @@ func generateDecoder(ctx *genContext, typ string, op op) []byte {
// generateEncoder generates the EncodeRLP method on 'typ'. // generateEncoder generates the EncodeRLP method on 'typ'.
func generateEncoder(ctx *genContext, typ string, op op) []byte { func generateEncoder(ctx *genContext, typ string, op op) []byte {
ctx.resetTemp() ctx.resetTemp()
ctx.addImport("io") ctx.addImportPath("io")
ctx.addImport(pathOfPackageRLP) ctx.addImportPath(pathOfPackageRLP)
var b bytes.Buffer var b bytes.Buffer
fmt.Fprintf(&b, "func (obj *%s) EncodeRLP(_w io.Writer) error {\n", typ) fmt.Fprintf(&b, "func (obj *%s) EncodeRLP(_w io.Writer) error {\n", typ)
@ -837,7 +838,7 @@ func (bctx *buildContext) generate(typ *types.Named, encoder, decoder bool) ([]b
var b bytes.Buffer var b bytes.Buffer
fmt.Fprintf(&b, "package %s\n\n", pkg.Name()) fmt.Fprintf(&b, "package %s\n\n", pkg.Name())
for _, imp := range ctx.importsList() { for _, imp := range ctx.importsList() {
fmt.Fprintf(&b, "import %q\n", imp) fmt.Fprintf(&b, "import %s\n", imp)
} }
if encoder { if encoder {
fmt.Fprintln(&b) fmt.Fprintln(&b)