From f25bc3985af52253e834627bb523475477fbcb81 Mon Sep 17 00:00:00 2001 From: visualfc Date: Sat, 11 Oct 2025 19:49:33 +0800 Subject: [PATCH 1/3] newOverload check exist object --- import.go | 76 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/import.go b/import.go index d4407d6d..5cfc9d1b 100644 --- a/import.go +++ b/import.go @@ -98,11 +98,6 @@ func isXGoCommon(name string) bool { // InitXGoPackage initializes a XGo package. func InitXGoPackage(pkg *types.Package) { - InitXGoPackageEx(pkg, nil) -} - -// InitXGoPackageEx initializes a XGo package. pos map overload name to position. -func InitXGoPackageEx(pkg *types.Package, pos map[string]token.Pos) { scope := pkg.Scope() gopos := make([]string, 0, 4) overloads := make(map[omthd][]types.Object) @@ -162,7 +157,7 @@ func InitXGoPackageEx(pkg *types.Package, pos map[string]token.Pos) { } } if len(fns) > 0 { - newOverload(pkg, scope, m, fns, pos) + newOverload(token.NoPos, pkg, scope, m, fns) } delete(overloads, m) } @@ -170,7 +165,7 @@ func InitXGoPackageEx(pkg *types.Package, pos map[string]token.Pos) { for key, items := range overloads { off := len(key.name) + 2 fns := overloadFuncs(off, items) - newOverload(pkg, scope, key, fns, pos) + newOverload(token.NoPos, pkg, scope, key, fns) } for name, items := range onameds { off := len(name) + 2 @@ -319,21 +314,78 @@ func checkOverloads(scope *types.Scope, gopoName string) (ret []string, exists b return } -func newOverload(pkg *types.Package, scope *types.Scope, m omthd, fns []types.Object, pos map[string]token.Pos) { +func setOverloadFuncs(obj types.Object, fns []types.Object) bool { + sig, ok := obj.Type().(*types.Signature) + if !ok { + return false + } + ext, ok := CheckFuncEx(sig) + if !ok { + return false + } + typ, ok := ext.(*TyOverloadFunc) + if !ok { + return false + } + typ.Funcs = fns + return true +} + +func setOverloadMethods(obj types.Object, fns []types.Object) bool { + sig, ok := obj.Type().(*types.Signature) + if !ok { + return false + } + ext, ok := CheckFuncEx(sig) + if !ok { + return false + } + typ, ok := ext.(*TyOverloadMethod) + if !ok { + return false + } + typ.Methods = fns + return true +} + +func newOverload(pos token.Pos, pkg *types.Package, scope *types.Scope, m omthd, fns []types.Object) { if m.typ == nil { if debugImport { log.Println("==> NewOverloadFunc", m.name) } - o := NewOverloadFunc(pos[m.name], pkg, m.name, fns...) - scope.Insert(o) - checkXGotsx(pkg, scope, m.name, o) + if obj := scope.Lookup(m.name); obj != nil { + if !setOverloadFuncs(obj, fns) { + log.Panicf("object not overload func: %v", obj) + } + checkXGotsx(pkg, scope, m.name, obj) + } else { + o := NewOverloadFunc(pos, pkg, m.name, fns...) + scope.Insert(o) + checkXGotsx(pkg, scope, m.name, o) + } } else { typName := m.typ.Obj().Name() if debugImport { log.Println("==> NewOverloadMethod", typName, m.name) } - NewOverloadMethod(m.typ, pos[typName+"."+m.name], pkg, m.name, fns...) + if obj := findMethod(m.typ, m.name); obj != nil { + if !setOverloadMethods(obj, fns) { + log.Panicf("object not overload method: %v", obj) + } + } else { + NewOverloadMethod(m.typ, pos, pkg, m.name, fns...) + } + } +} + +func findMethod(typ *types.Named, name string) *types.Func { + n := typ.NumMethods() + for i := 0; i < n; i++ { + if m := typ.Method(i); m.Name() == name { + return m + } } + return nil } func overloadFuncs(off int, items []types.Object) []types.Object { From a7c16c1fbf02b911587d0bb4e5dfc3e24ee54fec Mon Sep 17 00:00:00 2001 From: visualfc Date: Sun, 12 Oct 2025 21:47:53 +0800 Subject: [PATCH 2/3] remove InitXGoPackageEx --- import.go | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/import.go b/import.go index 5cfc9d1b..c5ebed83 100644 --- a/import.go +++ b/import.go @@ -314,21 +314,17 @@ func checkOverloads(scope *types.Scope, gopoName string) (ret []string, exists b return } -func setOverloadFuncs(obj types.Object, fns []types.Object) bool { +func checkOverload[T TyFuncEx](obj types.Object) (t T, ok bool) { sig, ok := obj.Type().(*types.Signature) if !ok { - return false + return } ext, ok := CheckFuncEx(sig) if !ok { - return false - } - typ, ok := ext.(*TyOverloadFunc) - if !ok { - return false + return } - typ.Funcs = fns - return true + t, ok = ext.(T) + return } func setOverloadMethods(obj types.Object, fns []types.Object) bool { @@ -353,25 +349,29 @@ func newOverload(pos token.Pos, pkg *types.Package, scope *types.Scope, m omthd, if debugImport { log.Println("==> NewOverloadFunc", m.name) } - if obj := scope.Lookup(m.name); obj != nil { - if !setOverloadFuncs(obj, fns) { - log.Panicf("object not overload func: %v", obj) + var obj types.Object + if obj = scope.Lookup(m.name); obj != nil { + t, ok := checkOverload[*TyOverloadFunc](obj) + if !ok { + log.Panicf("Object not OverloadFunc: %v", obj) } - checkXGotsx(pkg, scope, m.name, obj) + t.Funcs = fns } else { - o := NewOverloadFunc(pos, pkg, m.name, fns...) - scope.Insert(o) - checkXGotsx(pkg, scope, m.name, o) + obj = NewOverloadFunc(pos, pkg, m.name, fns...) + scope.Insert(obj) } + checkXGotsx(pkg, scope, m.name, obj) } else { typName := m.typ.Obj().Name() if debugImport { log.Println("==> NewOverloadMethod", typName, m.name) } if obj := findMethod(m.typ, m.name); obj != nil { - if !setOverloadMethods(obj, fns) { - log.Panicf("object not overload method: %v", obj) + t, ok := checkOverload[*TyOverloadMethod](obj) + if !ok { + log.Panicf("Object not OverloadMethod: %v", obj) } + t.Methods = fns } else { NewOverloadMethod(m.typ, pos, pkg, m.name, fns...) } From f987cceff538cbb70c2ad1c68902ed29504671b6 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 13 Oct 2025 08:20:55 +0800 Subject: [PATCH 3/3] TestNewOverload funcs --- builtin_test.go | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ import.go | 17 -------- 2 files changed, 104 insertions(+), 17 deletions(-) diff --git a/builtin_test.go b/builtin_test.go index aaea8d50..a05393a6 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -350,6 +350,110 @@ func TestIsTypeEx(t *testing.T) { } } +func TestNewOverloadFunc1(t *testing.T) { + pkg := types.NewPackage("", "foo") + pkg.Scope().Insert(types.NewConst(0, pkg, "XGoPackage", types.Typ[types.Bool], constant.MakeBool(true))) + f1 := types.NewFunc(0, pkg, "bar__0", types.NewSignature(nil, nil, nil, false)) + f2 := types.NewFunc(0, pkg, "bar__1", types.NewSignature(nil, types.NewTuple(types.NewVar(0, pkg, "n", types.Typ[types.Int])), nil, false)) + pkg.Scope().Insert(f1) + pkg.Scope().Insert(f2) + InitXGoPackage(pkg) + of := pkg.Scope().Lookup("bar") + _, objs := CheckSigFuncExObjects(of.Type().(*types.Signature)) + if len(objs) != 2 { + t.Fatal("error") + } +} + +func TestNewOverloadFunc2(t *testing.T) { + pkg := types.NewPackage("", "foo") + pkg.Scope().Insert(types.NewConst(0, pkg, "XGoPackage", types.Typ[types.Bool], constant.MakeBool(true))) + of := NewOverloadFunc(0, pkg, "bar") + f1 := types.NewFunc(0, pkg, "bar__0", types.NewSignature(nil, nil, nil, false)) + f2 := types.NewFunc(0, pkg, "bar__1", types.NewSignature(nil, types.NewTuple(types.NewVar(0, pkg, "n", types.Typ[types.Int])), nil, false)) + pkg.Scope().Insert(of) + pkg.Scope().Insert(f1) + pkg.Scope().Insert(f2) + InitXGoPackage(pkg) + _, objs := CheckSigFuncExObjects(of.Type().(*types.Signature)) + if len(objs) != 2 { + t.Fatal("error") + } +} + +func TestNewOverloadFuncError(t *testing.T) { + defer func() { + err := recover() + if err == nil { + t.Fatal("no error?") + } + }() + pkg := types.NewPackage("", "foo") + pkg.Scope().Insert(types.NewConst(0, pkg, "XGoPackage", types.Typ[types.Bool], constant.MakeBool(true))) + of := types.NewVar(0, pkg, "bar", types.Typ[types.Int]) + f1 := types.NewFunc(0, pkg, "bar__0", types.NewSignature(nil, nil, nil, false)) + f2 := types.NewFunc(0, pkg, "bar__1", types.NewSignature(nil, types.NewTuple(types.NewVar(0, pkg, "n", types.Typ[types.Int])), nil, false)) + pkg.Scope().Insert(of) + pkg.Scope().Insert(f1) + pkg.Scope().Insert(f2) + InitXGoPackage(pkg) +} + +func TestNewOverloadMethod1(t *testing.T) { + pkg := types.NewPackage("", "foo") + pkg.Scope().Insert(types.NewConst(0, pkg, "XGoPackage", types.Typ[types.Bool], constant.MakeBool(true))) + typ := types.NewNamed(types.NewTypeName(0, pkg, "T", nil), types.Typ[types.Int], nil) + pkg.Scope().Insert(typ.Obj()) + f1 := types.NewFunc(0, pkg, "bar__0", types.NewSignature(types.NewVar(0, pkg, "", typ), nil, nil, false)) + f2 := types.NewFunc(0, pkg, "bar__1", types.NewSignature(types.NewVar(0, pkg, "", typ), types.NewTuple(types.NewVar(0, pkg, "n", types.Typ[types.Int])), nil, false)) + typ.AddMethod(f1) + typ.AddMethod(f2) + InitXGoPackage(pkg) + of := findMethod(typ, "bar") + _, objs := CheckSigFuncExObjects(of.Type().(*types.Signature)) + if typ.NumMethods() != 3 || len(objs) != 2 { + t.Fatal("error") + } +} + +func TestNewOverloadMethod2(t *testing.T) { + pkg := types.NewPackage("", "foo") + pkg.Scope().Insert(types.NewConst(0, pkg, "XGoPackage", types.Typ[types.Bool], constant.MakeBool(true))) + typ := types.NewNamed(types.NewTypeName(0, pkg, "T", nil), types.Typ[types.Int], nil) + pkg.Scope().Insert(typ.Obj()) + of := NewOverloadMethod(typ, 0, pkg, "bar") + types.NewFunc(0, pkg, "bar__0", types.NewSignature(types.NewVar(0, pkg, "", typ), nil, nil, false)) + f1 := types.NewFunc(0, pkg, "bar__0", types.NewSignature(types.NewVar(0, pkg, "", typ), nil, nil, false)) + f2 := types.NewFunc(0, pkg, "bar__1", types.NewSignature(types.NewVar(0, pkg, "", typ), types.NewTuple(types.NewVar(0, pkg, "n", types.Typ[types.Int])), nil, false)) + typ.AddMethod(f1) + typ.AddMethod(f2) + InitXGoPackage(pkg) + _, objs := CheckSigFuncExObjects(of.Type().(*types.Signature)) + if typ.NumMethods() != 3 || len(objs) != 2 { + t.Fatal("error") + } +} + +func TestNewOverloadMethodError(t *testing.T) { + defer func() { + err := recover() + if err == nil { + t.Fatal("no error?") + } + }() + pkg := types.NewPackage("", "foo") + pkg.Scope().Insert(types.NewConst(0, pkg, "XGoPackage", types.Typ[types.Bool], constant.MakeBool(true))) + typ := types.NewNamed(types.NewTypeName(0, pkg, "T", nil), types.Typ[types.Int], nil) + pkg.Scope().Insert(typ.Obj()) + of := types.NewFunc(0, pkg, "bar", types.NewSignature(types.NewVar(0, pkg, "", typ), nil, nil, false)) + f1 := types.NewFunc(0, pkg, "bar__0", types.NewSignature(types.NewVar(0, pkg, "", typ), nil, nil, false)) + f2 := types.NewFunc(0, pkg, "bar__1", types.NewSignature(types.NewVar(0, pkg, "", typ), types.NewTuple(types.NewVar(0, pkg, "n", types.Typ[types.Int])), nil, false)) + typ.AddMethod(of) + typ.AddMethod(f1) + typ.AddMethod(f2) + InitXGoPackage(pkg) +} + func TestGetBuiltinTI(t *testing.T) { pkg := NewPackage("", "foo", nil) cb := &pkg.cb diff --git a/import.go b/import.go index c5ebed83..79eeccde 100644 --- a/import.go +++ b/import.go @@ -327,23 +327,6 @@ func checkOverload[T TyFuncEx](obj types.Object) (t T, ok bool) { return } -func setOverloadMethods(obj types.Object, fns []types.Object) bool { - sig, ok := obj.Type().(*types.Signature) - if !ok { - return false - } - ext, ok := CheckFuncEx(sig) - if !ok { - return false - } - typ, ok := ext.(*TyOverloadMethod) - if !ok { - return false - } - typ.Methods = fns - return true -} - func newOverload(pos token.Pos, pkg *types.Package, scope *types.Scope, m omthd, fns []types.Object) { if m.typ == nil { if debugImport {