From 35f3f551e07f10264aad3942ba593dbf7f96d899 Mon Sep 17 00:00:00 2001 From: visualfc Date: Sat, 11 Oct 2025 19:53:27 +0800 Subject: [PATCH 1/2] cl: ast.OverloadFuncDecl preload overload func --- cl/compile.go | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index f0a0404bd..568f1ea59 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -1005,7 +1005,7 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge old, _ := p.SetCurFile(goFile, true) defer p.RestoreCurFile(old) - preloadFuncDecl := func(d *ast.FuncDecl) { + preloadFuncDecl := func(d *ast.FuncDecl, overload bool) { if ctx.classRecv != nil { // in class file (.spx/.gmx) if recv := d.Recv; recv == nil || len(recv.List) == 0 { d.Recv = ctx.classRecv @@ -1018,7 +1018,13 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge fn := func() { old, _ := p.SetCurFile(goFile, true) defer p.RestoreCurFile(old) - loadFunc(ctx, nil, fname, d, genFnBody) + if overload { + pkg := ctx.pkg.Types + fn := gogen.NewOverloadFunc(d.Name.Pos(), pkg, fname) + pkg.Scope().Insert(fn) + } else { + loadFunc(ctx, nil, fname, d, genFnBody) + } } if fname == "init" { if genFnBody { @@ -1060,7 +1066,13 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge defer p.RestoreCurFile(old) doInitType(ld) recv := toRecv(ctx, d.Recv) - loadFunc(ctx, recv, fname, d, genFnBody) + if overload { + pkg := ctx.pkg.Types + typ := pkg.Scope().Lookup(tname).Type().(*types.Named) + gogen.NewOverloadMethod(typ, d.Name.Pos(), pkg, fname) + } else { + loadFunc(ctx, recv, fname, d, genFnBody) + } } ld.methods = append(ld.methods, fn) } @@ -1194,7 +1206,7 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge } case *ast.FuncDecl: - preloadFuncDecl(d) + preloadFuncDecl(d, false) case *ast.OverloadFuncDecl: var recv *ast.Ident @@ -1282,12 +1294,33 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge Name: id, Type: expr.Type, Body: expr.Body, - }) + }, false) default: ctx.handleErrorf(expr.Pos(), expr.End(), "unknown func %v", ctx.LoadExpr(expr)) break LoopFunc } } + if d.Recv == nil { + ctx.lbinames = append(ctx.lbinames, d.Name.Name) + } + preloadFuncDecl(&ast.FuncDecl{ + Doc: d.Doc, + Recv: d.Recv, + Name: d.Name, + Type: &ast.FuncType{ + Params: &ast.FieldList{ + List: []*ast.Field{ + &ast.Field{ + Names: []*ast.Ident{ + ast.NewIdent(overloadArgs), + }, + Type: ast.NewIdent("any"), + }, + }, + }, + }, + }, true) + if exov { // need Gopo_xxx oname, err := overloadName(recv, name.Name, d.Operator) if err != nil { @@ -1324,6 +1357,10 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge } } +const ( + overloadArgs = "__xgo_overload_args__" +) + func checkOverloadMethodRecvType(ot *ast.Ident, recv ast.Expr) (*ast.Ident, bool) { rtyp, _, ok := getRecvType(recv) if !ok { From 73d55f2ca992cdad985d17c82ef58b3b9f60916d Mon Sep 17 00:00:00 2001 From: visualfc Date: Sun, 12 Oct 2025 21:33:16 +0800 Subject: [PATCH 2/2] cl: remove pkgCtx.overpos --- cl/compile.go | 60 +++++++++++++++++++--------------------- x/typesutil/info_test.go | 21 +++++++------- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 568f1ea59..b1d80d994 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -338,7 +338,6 @@ type pkgCtx struct { nproj int // number of non-test projects projs map[string]*gmxProject // .gmx => project classes map[*ast.File]*gmxClass - overpos map[string]token.Pos // overload => pos fset *token.FileSet syms map[string]loader lbinames []any // names that should load before initGopPkg (can be string/func or *ast.Ident/type) @@ -578,7 +577,6 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gogen.Packag nodeInterp: interp, projs: make(map[string]*gmxProject), classes: make(map[*ast.File]*gmxClass), - overpos: make(map[string]token.Pos), syms: make(map[string]loader), generics: make(map[string]bool), } @@ -750,7 +748,7 @@ func initGopPkg(ctx *pkgCtx, pkg *gogen.Package, gopSyms map[string]bool) { ctx.loadType(lbi.(*ast.Ident).Name) } } - gogen.InitThisGopPkgEx(pkg.Types, ctx.overpos) + gogen.InitThisGopPkg(pkg.Types) } func loadFile(ctx *pkgCtx, f *ast.File) { @@ -1237,6 +1235,7 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge onames := make([]string, 0, 4) exov := false name := d.Name + var hasErr bool LoopFunc: for idx, fn := range d.Funcs { @@ -1244,6 +1243,7 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge case *ast.Ident: if d.Recv != nil && !d.Operator && !d.IsClass { ctx.handleErrorf(expr.Pos(), expr.End(), "invalid method %v", ctx.LoadExpr(expr)) + hasErr = true break LoopFunc } exov = true @@ -1263,11 +1263,13 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge case *ast.SelectorExpr: if d.Recv == nil || d.IsClass { ctx.handleErrorf(expr.Pos(), expr.End(), "invalid func %v", ctx.LoadExpr(expr)) + hasErr = true break LoopFunc } rtyp, ok := checkOverloadMethodRecvType(recv, expr.X) if !ok { ctx.handleErrorf(expr.Pos(), expr.End(), "invalid recv type %v", ctx.LoadExpr(expr.X)) + hasErr = true break LoopFunc } @@ -1280,6 +1282,7 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge case *ast.FuncLit: if d.Recv != nil && !d.Operator && !d.IsClass { ctx.handleErrorf(expr.Pos(), expr.End(), "invalid method %v", ctx.LoadExpr(expr)) + hasErr = true break LoopFunc } name1 := overloadFuncName(name.Name, idx) @@ -1297,29 +1300,10 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge }, false) default: ctx.handleErrorf(expr.Pos(), expr.End(), "unknown func %v", ctx.LoadExpr(expr)) + hasErr = true break LoopFunc } } - if d.Recv == nil { - ctx.lbinames = append(ctx.lbinames, d.Name.Name) - } - preloadFuncDecl(&ast.FuncDecl{ - Doc: d.Doc, - Recv: d.Recv, - Name: d.Name, - Type: &ast.FuncType{ - Params: &ast.FieldList{ - List: []*ast.Field{ - &ast.Field{ - Names: []*ast.Ident{ - ast.NewIdent(overloadArgs), - }, - Type: ast.NewIdent("any"), - }, - }, - }, - }, - }, true) if exov { // need Gopo_xxx oname, err := overloadName(recv, name.Name, d.Operator) @@ -1327,11 +1311,6 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge ctx.handleErrorf(name.Pos(), name.End(), "%v", err) break } - if recv != nil { - ctx.overpos[recv.Name+"."+name.Name] = name.NamePos - } else { - ctx.overpos[name.Name] = name.NamePos - } oval := strings.Join(onames, ",") preloadConst(&ast.GenDecl{ Doc: d.Doc, @@ -1344,13 +1323,32 @@ func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, ge }, }) ctx.lbinames = append(ctx.lbinames, oname) - } else { - ctx.overpos[name.Name] = name.NamePos + } + if !hasErr { + if d.Recv == nil { + ctx.lbinames = append(ctx.lbinames, d.Name.Name) + } + preloadFuncDecl(&ast.FuncDecl{ + Doc: d.Doc, + Recv: d.Recv, + Name: d.Name, + Type: &ast.FuncType{ + Params: &ast.FieldList{ + List: []*ast.Field{ + &ast.Field{ + Names: []*ast.Ident{ + ast.NewIdent(overloadArgs), + }, + Type: ast.NewIdent("any"), + }, + }, + }, + }, + }, true) } if ctx.rec != nil { ctx.rec.ReferDef(d.Name, d) } - default: log.Panicf("TODO - cl.preloadFile: unknown decl - %T\n", decl) } diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go index 72817efd7..4c123f679 100644 --- a/x/typesutil/info_test.go +++ b/x/typesutil/info_test.go @@ -2285,16 +2285,17 @@ var d = a.mul(c) 010: 9:30 | *foo *ast.StarExpr | type : *main.foo | type 011: 9:31 | foo *ast.Ident | type : main.foo | type 012: 10: 9 | a *ast.Ident | var : *main.foo | variable -013: 18:10 | *foo *ast.StarExpr | type : *main.foo | type -014: 18:11 | foo *ast.Ident | type : main.foo | type -015: 19: 9 | a *ast.Ident | var : *main.foo | variable -016: 19: 9 | a.mul *ast.SelectorExpr | value : func(b int) *main.foo | value -017: 19: 9 | a.mul(100) *ast.CallExpr | value : *main.foo | value -018: 19:15 | 100 *ast.BasicLit | value : untyped int = 100 | constant -019: 20: 9 | a *ast.Ident | var : *main.foo | variable -020: 20: 9 | a.mul *ast.SelectorExpr | value : func(b *main.foo) *main.foo | value -021: 20: 9 | a.mul(c) *ast.CallExpr | value : *main.foo | value -022: 20:15 | c *ast.Ident | var : *main.foo | variable +013: 13: 7 | foo *ast.Ident | type : main.foo | type +014: 18:10 | *foo *ast.StarExpr | type : *main.foo | type +015: 18:11 | foo *ast.Ident | type : main.foo | type +016: 19: 9 | a *ast.Ident | var : *main.foo | variable +017: 19: 9 | a.mul *ast.SelectorExpr | value : func(b int) *main.foo | value +018: 19: 9 | a.mul(100) *ast.CallExpr | value : *main.foo | value +019: 19:15 | 100 *ast.BasicLit | value : untyped int = 100 | constant +020: 20: 9 | a *ast.Ident | var : *main.foo | variable +021: 20: 9 | a.mul *ast.SelectorExpr | value : func(b *main.foo) *main.foo | value +022: 20: 9 | a.mul(c) *ast.CallExpr | value : *main.foo | value +023: 20:15 | c *ast.Ident | var : *main.foo | variable == defs == 000: 0: 0 | Gopo_foo_mul | const main.Gopo_foo_mul untyped string 001: 2: 6 | foo | type main.foo struct{}