From d8ec8f9530721859060aa1ff75dfc67069490518 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 14 Mar 2025 21:04:28 +0800 Subject: [PATCH 1/9] loadFunc: Main/MainEntry --- cl/compile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/compile.go b/cl/compile.go index eb51ba2fd..0b5371d39 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -1298,7 +1298,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, name string, d *ast.FuncDecl, genB var pkg = ctx.pkg var sigBase *types.Signature if d.Shadow { - if recv != nil { + if recv != nil && (name == "Main" || name == "MainEntry") { if base := ctx.baseClass; base != nil { if f := findMethod(base, name); f != nil { sigBase = makeMainSig(recv, f) From dd6e2ea2d45755f160f38332f10e36a340bd08c0 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 14 Mar 2025 21:16:29 +0800 Subject: [PATCH 2/9] cl: initBaseMain --- cl/compile.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 0b5371d39..348be75b7 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -367,6 +367,7 @@ type blockCtx struct { classRecv *ast.FieldList // available when isClass baseClass types.Object // available when isClass + baseMain *types.Func fileScope *types.Scope // available when isGopFile rec *goxRecorder @@ -376,6 +377,11 @@ type blockCtx struct { isGopFile bool // is Go+ file or not } +func (p *blockCtx) initBaseMain(base types.Object, name string) { + p.baseClass = base + p.baseMain = findMethod(base, name) +} + func (p *blockCtx) cstr() gogen.Ref { if p.cstr_ == nil { p.cstr_ = p.pkg.Import(pathLibc).Ref("Str") @@ -751,7 +757,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c } if f.IsProj { o := proj.game - ctx.baseClass = o + ctx.initBaseMain(o, "MainEntry") baseTypeName, baseType = o.Name(), o.Type() if proj.gameIsPtr { baseType = types.NewPointer(baseType) @@ -759,7 +765,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c } else { sp := proj.sprite[c.ext] o := sp.obj - ctx.baseClass = o + ctx.initBaseMain(o, "Main") baseTypeName, baseType, spxProj, spxClass = o.Name(), o.Type(), sp.proj, true } } @@ -1299,10 +1305,8 @@ func loadFunc(ctx *blockCtx, recv *types.Var, name string, d *ast.FuncDecl, genB var sigBase *types.Signature if d.Shadow { if recv != nil && (name == "Main" || name == "MainEntry") { - if base := ctx.baseClass; base != nil { - if f := findMethod(base, name); f != nil { - sigBase = makeMainSig(recv, f) - } + if baseMain := ctx.baseMain; baseMain != nil { + sigBase = makeMainSig(recv, baseMain) } } } else if d.Operator { From 5057cefdb145e246d0f707187e02f5e87ff706f2 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 14 Mar 2025 21:25:26 +0800 Subject: [PATCH 3/9] cl: initBaseMainSig --- cl/classfile.go | 3 +-- cl/compile.go | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cl/classfile.go b/cl/classfile.go index badebbc2f..95476662d 100644 --- a/cl/classfile.go +++ b/cl/classfile.go @@ -417,11 +417,10 @@ func findMethod(o types.Object, name string) *types.Func { return nil } -func makeMainSig(recv *types.Var, f *types.Func) *types.Signature { +func makeMainSig(recv *types.Var, sig *types.Signature) *types.Signature { const ( paramNameTempl = "_gop_arg0" ) - sig := f.Type().(*types.Signature) in := sig.Params() nin := in.Len() pkg := recv.Pkg() diff --git a/cl/compile.go b/cl/compile.go index 348be75b7..9d528700c 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -365,9 +365,10 @@ type blockCtx struct { pystr_ gogen.Ref relBaseDir string + baseClass types.Object // available when isClass + baseMainSig *types.Signature + classRecv *ast.FieldList // available when isClass - baseClass types.Object // available when isClass - baseMain *types.Func fileScope *types.Scope // available when isGopFile rec *goxRecorder @@ -377,9 +378,11 @@ type blockCtx struct { isGopFile bool // is Go+ file or not } -func (p *blockCtx) initBaseMain(base types.Object, name string) { +func (p *blockCtx) initBaseMainSig(base types.Object, name string) { p.baseClass = base - p.baseMain = findMethod(base, name) + if f := findMethod(base, name); f != nil { + p.baseMainSig = f.Type().(*types.Signature) + } } func (p *blockCtx) cstr() gogen.Ref { @@ -757,7 +760,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c } if f.IsProj { o := proj.game - ctx.initBaseMain(o, "MainEntry") + ctx.initBaseMainSig(o, "MainEntry") baseTypeName, baseType = o.Name(), o.Type() if proj.gameIsPtr { baseType = types.NewPointer(baseType) @@ -765,7 +768,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c } else { sp := proj.sprite[c.ext] o := sp.obj - ctx.initBaseMain(o, "Main") + ctx.initBaseMainSig(o, "Main") baseTypeName, baseType, spxProj, spxClass = o.Name(), o.Type(), sp.proj, true } } @@ -1305,8 +1308,8 @@ func loadFunc(ctx *blockCtx, recv *types.Var, name string, d *ast.FuncDecl, genB var sigBase *types.Signature if d.Shadow { if recv != nil && (name == "Main" || name == "MainEntry") { - if baseMain := ctx.baseMain; baseMain != nil { - sigBase = makeMainSig(recv, baseMain) + if baseMainSig := ctx.baseMainSig; baseMainSig != nil { + sigBase = makeMainSig(recv, baseMainSig) } } } else if d.Operator { From 7d2ddebb822991c74e2f61ee700894e2f7501b84 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 14 Mar 2025 21:40:51 +0800 Subject: [PATCH 4/9] cl: rm initBaseMainSig --- cl/compile.go | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 9d528700c..de59eeefd 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -365,10 +365,8 @@ type blockCtx struct { pystr_ gogen.Ref relBaseDir string - baseClass types.Object // available when isClass - baseMainSig *types.Signature - classRecv *ast.FieldList // available when isClass + baseClass types.Object // available when isClass fileScope *types.Scope // available when isGopFile rec *goxRecorder @@ -378,12 +376,30 @@ type blockCtx struct { isGopFile bool // is Go+ file or not } +/* +func (p *blockCtx) spxNeedMethod(name string) bool { + if sig := p.baseMainSig; sig != nil && sig.Variadic() { + in := sig.Params() + last := in.At(in.Len() - 1) + elt := last.Type().(*types.Slice).Elem() + if intf, ok := elt.(*types.Interface); ok { + for i, n := 0, intf.NumMethods(); i < n; i++ { + if intf.Method(i).Name() == name { + return true + } + } + } + } + return false +} + func (p *blockCtx) initBaseMainSig(base types.Object, name string) { p.baseClass = base if f := findMethod(base, name); f != nil { p.baseMainSig = f.Type().(*types.Signature) } } +*/ func (p *blockCtx) cstr() gogen.Ref { if p.cstr_ == nil { @@ -760,7 +776,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c } if f.IsProj { o := proj.game - ctx.initBaseMainSig(o, "MainEntry") + ctx.baseClass = o baseTypeName, baseType = o.Name(), o.Type() if proj.gameIsPtr { baseType = types.NewPointer(baseType) @@ -768,7 +784,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c } else { sp := proj.sprite[c.ext] o := sp.obj - ctx.initBaseMainSig(o, "Main") + ctx.baseClass = o baseTypeName, baseType, spxProj, spxClass = o.Name(), o.Type(), sp.proj, true } } @@ -1308,8 +1324,11 @@ func loadFunc(ctx *blockCtx, recv *types.Var, name string, d *ast.FuncDecl, genB var sigBase *types.Signature if d.Shadow { if recv != nil && (name == "Main" || name == "MainEntry") { - if baseMainSig := ctx.baseMainSig; baseMainSig != nil { - sigBase = makeMainSig(recv, baseMainSig) + if base := ctx.baseClass; base != nil { + if f := findMethod(base, name); f != nil { + baseMainSig := f.Type().(*types.Signature) + sigBase = makeMainSig(recv, baseMainSig) + } } } } else if d.Operator { From 9897f758b5e4ad3f8966c58a8e051e714dbc1fc2 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 14 Mar 2025 22:36:18 +0800 Subject: [PATCH 5/9] cl: spriteFeatures --- cl/classfile.go | 46 +++++++++++++++++++++++++++++++++++++--- cl/compile.go | 28 +----------------------- cl/internal/spx3/spx3.go | 8 ++++++- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/cl/classfile.go b/cl/classfile.go index 95476662d..d879aa983 100644 --- a/cl/classfile.go +++ b/cl/classfile.go @@ -47,8 +47,9 @@ type spxObj struct { } type gmxProject struct { - gameClass string // .gmx - game gogen.Ref // Game (project base class) + gameClass string // .gmx + game gogen.Ref // Game (project base class) + spfeats spriteFeat sprite map[string]spxObj // .spx => Sprite sptypes []string // .spx scheds []string @@ -62,6 +63,43 @@ type gmxProject struct { hasMain_ bool } +type spriteFeat uint + +const ( + spriteClassfname spriteFeat = 1 << iota + spriteClassclone +) + +func spriteFeatures(game gogen.Ref) (feats spriteFeat) { + if mainFn := findMethod(game, "Main"); mainFn != nil { + sig := mainFn.Type().(*types.Signature) + if t, ok := gogen.CheckSigFuncEx(sig); ok { + if t, ok := t.(*gogen.TyTemplateRecvMethod); ok { + sig = t.Func.Type().(*types.Signature) + } + } + if sig.Variadic() { + in := sig.Params() + last := in.At(in.Len() - 1) + elt := last.Type().(*types.Slice).Elem() + if tn, ok := elt.(*types.Named); ok { + elt = tn.Underlying() + } + if intf, ok := elt.(*types.Interface); ok { + for i, n := 0, intf.NumMethods(); i < n; i++ { + switch intf.Method(i).Name() { + case "Classfname": + feats |= spriteClassfname + case "Classclone": + feats |= spriteClassclone + } + } + } + } + } + return +} + func (p *gmxProject) hasMain() bool { if !p.hasMain_ { imps := p.pkgImps @@ -165,6 +203,7 @@ func loadClass(ctx *pkgCtx, pkg *gogen.Package, file string, f *ast.File, conf * spx := p.pkgImps[0] if gt.Class != "" { p.game, p.gameIsPtr = spxRef(spx, gt.Class) + p.spfeats = spriteFeatures(p.game) } p.sprite = make(map[string]spxObj) for _, v := range gt.Works { @@ -417,10 +456,11 @@ func findMethod(o types.Object, name string) *types.Func { return nil } -func makeMainSig(recv *types.Var, sig *types.Signature) *types.Signature { +func makeMainSig(recv *types.Var, f *types.Func) *types.Signature { const ( paramNameTempl = "_gop_arg0" ) + sig := f.Type().(*types.Signature) in := sig.Params() nin := in.Len() pkg := recv.Pkg() diff --git a/cl/compile.go b/cl/compile.go index de59eeefd..0b5371d39 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -376,31 +376,6 @@ type blockCtx struct { isGopFile bool // is Go+ file or not } -/* -func (p *blockCtx) spxNeedMethod(name string) bool { - if sig := p.baseMainSig; sig != nil && sig.Variadic() { - in := sig.Params() - last := in.At(in.Len() - 1) - elt := last.Type().(*types.Slice).Elem() - if intf, ok := elt.(*types.Interface); ok { - for i, n := 0, intf.NumMethods(); i < n; i++ { - if intf.Method(i).Name() == name { - return true - } - } - } - } - return false -} - -func (p *blockCtx) initBaseMainSig(base types.Object, name string) { - p.baseClass = base - if f := findMethod(base, name); f != nil { - p.baseMainSig = f.Type().(*types.Signature) - } -} -*/ - func (p *blockCtx) cstr() gogen.Ref { if p.cstr_ == nil { p.cstr_ = p.pkg.Import(pathLibc).Ref("Str") @@ -1326,8 +1301,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, name string, d *ast.FuncDecl, genB if recv != nil && (name == "Main" || name == "MainEntry") { if base := ctx.baseClass; base != nil { if f := findMethod(base, name); f != nil { - baseMainSig := f.Type().(*types.Signature) - sigBase = makeMainSig(recv, baseMainSig) + sigBase = makeMainSig(recv, f) } } } diff --git a/cl/internal/spx3/spx3.go b/cl/internal/spx3/spx3.go index 551fcdb16..44f16f1f4 100644 --- a/cl/internal/spx3/spx3.go +++ b/cl/internal/spx3/spx3.go @@ -40,5 +40,11 @@ func (p *Sprite) Name() string { func (p *Sprite) Main(name string) {} -func Gopt_Game_Main(game interface{ initGame() }, workers ...interface{ Main(name string) }) { +type iHandler interface { + Main(name string) + Classfname() string + // Classclone() any +} + +func Gopt_Game_Main(game interface{ initGame() }, workers ...iHandler) { } From bc45aece502abec18a0a4020decf5c9fbc760490 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 14 Mar 2025 22:47:00 +0800 Subject: [PATCH 6/9] cl: use proj.spfeats (spriteFeatures) --- cl/compile.go | 7 ++-- cl/compile_spx_test.go | 72 ------------------------------------------ 2 files changed, 5 insertions(+), 74 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 0b5371d39..7e6b82b3f 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -725,6 +725,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c var baseType types.Type var spxProj string var spxClass bool + var spxClassfname bool var goxTestFile bool var parent = ctx.pkgCtx if f.IsClass { @@ -760,7 +761,9 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c sp := proj.sprite[c.ext] o := sp.obj ctx.baseClass = o - baseTypeName, baseType, spxProj, spxClass = o.Name(), o.Type(), sp.proj, true + baseTypeName, baseType, spxProj = o.Name(), o.Type(), sp.proj + spxClassfname = (proj.spfeats & spriteClassfname) != 0 + spxClass = true } } } @@ -864,7 +867,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c }, }}} // func Classfname() string - if spxClass { + if spxClassfname { f.Decls = append(f.Decls, astFnClassfname(c)) } } diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go index e6a2539e6..2db95da34 100644 --- a/cl/compile_spx_test.go +++ b/cl/compile_spx_test.go @@ -57,9 +57,6 @@ type MyGame struct { *spx.MyGame } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func (this *MyGame) Main() { @@ -142,9 +139,6 @@ func (this *Kai) onMsg(msg string) { this.Say("Hi") } } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -199,9 +193,6 @@ func (this *index) MainEntry() { func (this *index) Main() { spx.Gopt_MyGame_Main(this) } -func (this *bar) Classfname() string { - return "bar" -} func (this *bar) Main() { } func main() { @@ -234,9 +225,6 @@ func (this *index) MainEntry() { func (this *index) Main() { spx.Gopt_MyGame_Main(this) } -func (this *bar) Classfname() string { - return "bar" -} func (this *bar) Main() { } func main() { @@ -270,9 +258,6 @@ func (this *index) MainEntry() { func (this *index) Main() { spx.Gopt_MyGame_Main(this) } -func (this *bar) Classfname() string { - return "bar" -} func (this *bar) Main() { } func main() { @@ -314,9 +299,6 @@ func (this *index) MainEntry() { func (this *index) Main() { spx.Gopt_MyGame_Main(this) } -func (this *bar) Classfname() string { - return "bar" -} func (this *bar) Main() { } func main() { @@ -372,9 +354,6 @@ func (this *bar) onInit() { this.Say("Where do you come from?", 2) this.Broadcast__0("msg2") } -func (this *bar) Classfname() string { - return "bar" -} func (this *bar) Main() { } func main() { @@ -434,9 +413,6 @@ func (this *Kai) onInit() { func (this *Kai) onCloned() { this.Say("Hi") } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -485,9 +461,6 @@ func (this *index) Main() { func (this *Kai) Main() { fmt.Println("Hi") } -func (this *Kai) Classfname() string { - return "Kai" -} func main() { new(index).Main() } @@ -610,9 +583,6 @@ func (this *Game) Main() { } func (this *Kai) onMsg(msg string) { } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -650,9 +620,6 @@ func (this *Game) Main() { } func (this *Kai) onMsg(msg string) { } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -684,14 +651,8 @@ type Kai struct { func (this *Dog) Main() { fmt.Println("Hi, Sprite") } -func (this *Dog) Classfname() string { - return "Dog" -} func (this *Kai) onMsg(msg string) { } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } `, "Dog_t3spx.gox", "Kai.t3spx2") @@ -721,9 +682,6 @@ func (this *Game) MainEntry() { func (this *Game) Main() { (*spx2.Game).Main(&this.Game) } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -753,9 +711,6 @@ func (this *Game) MainEntry() { func (this *Game) Main() { (*spx2.Game).Main(&this.Game) } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -803,9 +758,6 @@ func (this *Kai) Main() { } func (this *Kai) onMsg(msg string) { } -func (this *Kai) Classfname() string { - return "Kai" -} func main() { new(Game).Main() } @@ -852,9 +804,6 @@ func (this *Kai) onMsg(msg string) { this.Say("Hi") } } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -929,9 +878,6 @@ func (this *Kai) onInit() { func (this *Kai) onCloned() { this.Say("Hi") } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -974,9 +920,6 @@ func (this *Game) Main() { } func (this *Kai) onMsg(msg string) { } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -1016,9 +959,6 @@ func (this *Game) Main() { func (this *Kai) onMsg(msg string) { this.Position().Add__0(100, 200) } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -1083,9 +1023,6 @@ func (this *Kai) onMsg(msg string) { fmt.Println(this.Vector().X) fmt.Println(this.Vector().Self().Self()) } -func (this *Kai) Classfname() string { - return "Kai" -} func (this *Kai) Main() { } func main() { @@ -1197,9 +1134,6 @@ func (this *Kai) Main() { spx.Gopt_Sprite_OnKey2(this, "hello", func(key string) { }) } -func (this *Kai) Classfname() string { - return "Kai" -} func main() { new(Game).Main() } @@ -1239,9 +1173,6 @@ func (this *caseFoo) Main() { t.Fatal("failed") }) } -func (this *caseFoo) Classfname() string { - return "Foo" -} func TestFoo(t *testing.T) { test.Gopt_Case_TestMain(new(caseFoo), t) } @@ -1270,9 +1201,6 @@ type case_foo struct { func (this *case_foo) Main() { this.T().Log("Hi") } -func (this *case_foo) Classfname() string { - return "foo" -} func Test_foo(t *testing.T) { test.Gopt_Case_TestMain(new(case_foo), t) } From 5e91d73445ed6896df4aff30e1bb4c70e85a3c49 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 15 Mar 2025 00:07:26 +0800 Subject: [PATCH 7/9] cl: astFnClassclone --- cl/builtin_test.go | 7 +++++++ cl/classfile.go | 34 ++++++++++++++++++++++++++++++++++ cl/compile.go | 9 +++++++++ cl/compile_spx_test.go | 8 ++++++++ cl/internal/spx3/spx3.go | 2 +- 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/cl/builtin_test.go b/cl/builtin_test.go index 0b4ad415f..6c553c16f 100644 --- a/cl/builtin_test.go +++ b/cl/builtin_test.go @@ -39,6 +39,13 @@ func getGoxConf() *gogen.Config { return &gogen.Config{Fset: fset, Importer: imp} } +func TestLoadExpr(t *testing.T) { + var ni nodeInterp + if v := ni.LoadExpr(&ast.Ident{Name: "x"}); v != "" { + t.Fatal("LoadExpr:", v) + } +} + func TestSimplifyPkgPath(t *testing.T) { if simplifyPkgPath("c/lua") != "github.com/goplus/llgo/c/lua" { t.Fatal("simplifyPkgPath: c/lua") diff --git a/cl/classfile.go b/cl/classfile.go index d879aa983..0bdf1c56c 100644 --- a/cl/classfile.go +++ b/cl/classfile.go @@ -499,6 +499,40 @@ func astFnClassfname(c *gmxClass) *ast.FuncDecl { } } +func astFnClassclone() *ast.FuncDecl { + ret := &ast.Ident{Name: "_gop_ret"} + return &ast.FuncDecl{ + Name: &ast.Ident{ + Name: "Classclone", + }, + Type: &ast.FuncType{ + Params: &ast.FieldList{}, + Results: &ast.FieldList{ + List: []*ast.Field{ + {Type: &ast.Ident{Name: "any"}}, + }, + }, + }, + Body: &ast.BlockStmt{ + List: []ast.Stmt{ + &ast.AssignStmt{ + Lhs: []ast.Expr{ret}, + Tok: token.DEFINE, + Rhs: []ast.Expr{ + &ast.StarExpr{X: &ast.Ident{Name: "this"}}, + }, + }, + &ast.ReturnStmt{ + Results: []ast.Expr{ + &ast.UnaryExpr{Op: token.AND, X: ret}, + }, + }, + }, + }, + Shadow: true, + } +} + func astEmptyEntrypoint(f *ast.File) { var entry = getEntrypoint(f) var hasEntry bool diff --git a/cl/compile.go b/cl/compile.go index 7e6b82b3f..2c56fbb3c 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -226,6 +226,9 @@ func (p *nodeInterp) Caller(node ast.Node) string { func (p *nodeInterp) LoadExpr(node ast.Node) string { start := node.Pos() + if start == token.NoPos { + return "" + } pos := p.fset.Position(start) f := p.files[pos.Filename] n := int(node.End() - start) @@ -726,6 +729,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c var spxProj string var spxClass bool var spxClassfname bool + var spxClassclone bool var goxTestFile bool var parent = ctx.pkgCtx if f.IsClass { @@ -763,6 +767,7 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c ctx.baseClass = o baseTypeName, baseType, spxProj = o.Name(), o.Type(), sp.proj spxClassfname = (proj.spfeats & spriteClassfname) != 0 + spxClassclone = (proj.spfeats & spriteClassclone) != 0 spxClass = true } } @@ -870,6 +875,10 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c if spxClassfname { f.Decls = append(f.Decls, astFnClassfname(c)) } + // func Classclone() any + if spxClassclone { + f.Decls = append(f.Decls, astFnClassclone()) + } } if d := f.ShadowEntry; d != nil { diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go index 2db95da34..6f6a59522 100644 --- a/cl/compile_spx_test.go +++ b/cl/compile_spx_test.go @@ -506,6 +506,10 @@ func (this *Kai) Main(_gop_arg0 string) { func (this *Kai) Classfname() string { return "Kai" } +func (this *Kai) Classclone() interface{} { + _gop_ret := *this + return &_gop_ret +} func main() { new(Game).Main() } @@ -545,6 +549,10 @@ func (this *Game) Main() { func (this *Kai) Classfname() string { return "Kai" } +func (this *Kai) Classclone() interface{} { + _gop_ret := *this + return &_gop_ret +} func (this *Kai) Main(_gop_arg0 string) { this.Sprite.Main(_gop_arg0) } diff --git a/cl/internal/spx3/spx3.go b/cl/internal/spx3/spx3.go index 44f16f1f4..3697a3a78 100644 --- a/cl/internal/spx3/spx3.go +++ b/cl/internal/spx3/spx3.go @@ -43,7 +43,7 @@ func (p *Sprite) Main(name string) {} type iHandler interface { Main(name string) Classfname() string - // Classclone() any + Classclone() any } func Gopt_Game_Main(game interface{ initGame() }, workers ...iHandler) { From ec4dbdaa887c1ea9fc8a07ed902e855fd09a9375 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 15 Mar 2025 00:16:22 +0800 Subject: [PATCH 8/9] x --- x/build/build_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/x/build/build_test.go b/x/build/build_test.go index 1bebeca94..cdc10801d 100644 --- a/x/build/build_test.go +++ b/x/build/build_test.go @@ -410,9 +410,6 @@ type MyGame struct { func (this *Cat) Main() { fmt.Println("hi") } -func (this *Cat) Classfname() string { - return "Cat" -} func (this *MyGame) Main() { spx.Gopt_MyGame_Main(this) } From 50d1bdb4be1a1b3c2ce0c094762db472f630f3c7 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 15 Mar 2025 00:28:17 +0800 Subject: [PATCH 9/9] TestSpxInfo --- x/typesutil/info_test.go | 92 +++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go index 600753988..1cede6fa6 100644 --- a/x/typesutil/info_test.go +++ b/x/typesutil/info_test.go @@ -1679,61 +1679,57 @@ func onCloned() { say("Hi") } `, `== types == -000: 0: 0 | "Kai" *ast.BasicLit | value : untyped string = "Kai" | constant -001: 0: 0 | *MyGame *ast.StarExpr | type : *main.MyGame | type -002: 0: 0 | Kai *ast.Ident | type : main.Kai | type -003: 0: 0 | MyGame *ast.Ident | type : main.MyGame | type -004: 0: 0 | string *ast.Ident | type : string | type -005: 3: 4 | int *ast.Ident | type : int | type -006: 6:11 | struct { +000: 0: 0 | *MyGame *ast.StarExpr | type : *main.MyGame | type +001: 0: 0 | Kai *ast.Ident | type : main.Kai | type +002: 0: 0 | MyGame *ast.Ident | type : main.MyGame | type +003: 3: 4 | int *ast.Ident | type : int | type +004: 6:11 | struct { x int y int } *ast.StructType | type : struct{x int; y int} | type -007: 7: 4 | int *ast.Ident | type : int | type -008: 8: 4 | int *ast.Ident | type : int | type -009: 12: 2 | a *ast.Ident | var : int | variable -010: 12: 6 | 1 *ast.BasicLit | value : untyped int = 1 | constant -011: 13: 2 | clone *ast.Ident | value : func(sprite any) | value -012: 14: 2 | clone *ast.Ident | value : func(sprite any, data any) | value -013: 14: 2 | clone info{1, 2} *ast.CallExpr | void : () | no value -014: 14: 8 | info *ast.Ident | type : main.info | type -015: 14: 8 | info{1, 2} *ast.CompositeLit | value : main.info | value -016: 14:13 | 1 *ast.BasicLit | value : untyped int = 1 | constant -017: 14:15 | 2 *ast.BasicLit | value : untyped int = 2 | constant -018: 15: 2 | clone *ast.Ident | value : func(sprite any, data any) | value -019: 15: 2 | clone &info{1, 2} *ast.CallExpr | void : () | no value -020: 15: 8 | &info{1, 2} *ast.UnaryExpr | value : *main.info | value -021: 15: 9 | info *ast.Ident | type : main.info | type -022: 15: 9 | info{1, 2} *ast.CompositeLit | value : main.info | value -023: 15:14 | 1 *ast.BasicLit | value : untyped int = 1 | constant -024: 15:16 | 2 *ast.BasicLit | value : untyped int = 2 | constant -025: 19: 2 | say *ast.Ident | value : func(msg string, secs ...float64) | value -026: 19: 2 | say("Hi") *ast.CallExpr | void : () | no value -027: 19: 6 | "Hi" *ast.BasicLit | value : untyped string = "Hi" | constant +005: 7: 4 | int *ast.Ident | type : int | type +006: 8: 4 | int *ast.Ident | type : int | type +007: 12: 2 | a *ast.Ident | var : int | variable +008: 12: 6 | 1 *ast.BasicLit | value : untyped int = 1 | constant +009: 13: 2 | clone *ast.Ident | value : func(sprite any) | value +010: 14: 2 | clone *ast.Ident | value : func(sprite any, data any) | value +011: 14: 2 | clone info{1, 2} *ast.CallExpr | void : () | no value +012: 14: 8 | info *ast.Ident | type : main.info | type +013: 14: 8 | info{1, 2} *ast.CompositeLit | value : main.info | value +014: 14:13 | 1 *ast.BasicLit | value : untyped int = 1 | constant +015: 14:15 | 2 *ast.BasicLit | value : untyped int = 2 | constant +016: 15: 2 | clone *ast.Ident | value : func(sprite any, data any) | value +017: 15: 2 | clone &info{1, 2} *ast.CallExpr | void : () | no value +018: 15: 8 | &info{1, 2} *ast.UnaryExpr | value : *main.info | value +019: 15: 9 | info *ast.Ident | type : main.info | type +020: 15: 9 | info{1, 2} *ast.CompositeLit | value : main.info | value +021: 15:14 | 1 *ast.BasicLit | value : untyped int = 1 | constant +022: 15:16 | 2 *ast.BasicLit | value : untyped int = 2 | constant +023: 19: 2 | say *ast.Ident | value : func(msg string, secs ...float64) | value +024: 19: 2 | say("Hi") *ast.CallExpr | void : () | no value +025: 19: 6 | "Hi" *ast.BasicLit | value : untyped string = "Hi" | constant == defs == -000: 0: 0 | Classfname | func (*main.Kai).Classfname() string -001: 0: 0 | Main | func (*main.Kai).Main() -002: 0: 0 | this | var this *main.Kai -003: 3: 2 | a | field a int -004: 6: 6 | info | type main.info struct{x int; y int} -005: 7: 2 | x | field x int -006: 8: 2 | y | field y int -007: 11: 6 | onInit | func (*main.Kai).onInit() -008: 18: 6 | onCloned | func (*main.Kai).onCloned() +000: 0: 0 | Main | func (*main.Kai).Main() +001: 0: 0 | this | var this *main.Kai +002: 3: 2 | a | field a int +003: 6: 6 | info | type main.info struct{x int; y int} +004: 7: 2 | x | field x int +005: 8: 2 | y | field y int +006: 11: 6 | onInit | func (*main.Kai).onInit() +007: 18: 6 | onCloned | func (*main.Kai).onCloned() == uses == 000: 0: 0 | Kai | type main.Kai struct{github.com/goplus/gop/cl/internal/spx.Sprite; *main.MyGame; a int} 001: 0: 0 | MyGame | type main.MyGame struct{*github.com/goplus/gop/cl/internal/spx.MyGame} -002: 0: 0 | string | type string -003: 3: 4 | int | type int -004: 7: 4 | int | type int -005: 8: 4 | int | type int -006: 12: 2 | a | field a int -007: 13: 2 | clone | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__0(sprite any) -008: 14: 2 | clone | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite any, data any) -009: 14: 8 | info | type main.info struct{x int; y int} -010: 15: 2 | clone | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite any, data any) -011: 15: 9 | info | type main.info struct{x int; y int} -012: 19: 2 | say | func (*github.com/goplus/gop/cl/internal/spx.Sprite).Say(msg string, secs ...float64) +002: 3: 4 | int | type int +003: 7: 4 | int | type int +004: 8: 4 | int | type int +005: 12: 2 | a | field a int +006: 13: 2 | clone | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__0(sprite any) +007: 14: 2 | clone | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite any, data any) +008: 14: 8 | info | type main.info struct{x int; y int} +009: 15: 2 | clone | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite any, data any) +010: 15: 9 | info | type main.info struct{x int; y int} +011: 19: 2 | say | func (*github.com/goplus/gop/cl/internal/spx.Sprite).Say(msg string, secs ...float64) == overloads == 000: 13: 2 | clone | func (github.com/goplus/gop/cl/internal/spx.Sprite).Clone(__gop_overload_args__ interface{_()}) 001: 14: 2 | clone | func (github.com/goplus/gop/cl/internal/spx.Sprite).Clone(__gop_overload_args__ interface{_()})