Repository: goplus/gop
Pull request #1794 (2024-03-08 13:08:31)

classfile: Main(...), Classfname()
- [this.Sprite.Main(...) or this.Game.MainEntry(...)](https://github.com/goplus/gop/commit/766e6b27235567e45e20ec15ff8930d53f7a28f7)
- [spxClass: Classfname() string](https://github.com/goplus/gop/commit/1abc2bc0e89fe60bdda80981b720c7c8d007e221)


Patch:
diff --git a/cl/classfile.go b/cl/classfile.go
index c19d16ef..527500da 100644
--- a/cl/classfile.go
+++ b/cl/classfile.go
@@ -33,9 +33,10 @@ import (
 // -----------------------------------------------------------------------------
 
 type gmxClass struct {
-	tname string // class type
-	ext   string
-	proj  *gmxProject
+	tname   string // class type
+	clsfile string
+	ext     string
+	proj    *gmxProject
 }
 
 type gmxProject struct {
@@ -70,11 +71,12 @@ func (p *gmxProject) getScheds(cb *gox.CodeBuilder) []goast.Stmt {
 	return p.schedStmts
 }
 
-func ClassNameAndExt(file string) (name, ext string) {
+func ClassNameAndExt(file string) (name, clsfile, ext string) {
 	fname := filepath.Base(file)
-	name, ext = modfile.SplitFname(fname)
-	if idx := strings.Index(name, "."); idx > 0 {
-		name = name[:idx]
+	clsfile, ext = modfile.SplitFname(fname)
+	name = clsfile
+	if strings.ContainsAny(name, ":-.") {
+		name = strings.NewReplacer(":", "", "-", "_", ".", "_").Replace(name)
 	}
 	return
 }
@@ -84,7 +86,7 @@ func isGoxTestFile(ext string) bool {
 }
 
 func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Config) *gmxProject {
-	tname, ext := ClassNameAndExt(file)
+	tname, clsfile, ext := ClassNameAndExt(file)
 	gt, ok := conf.LookupClass(ext)
 	if !ok {
 		panic("TODO: class not found")
@@ -138,7 +140,7 @@ func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Co
 	} else {
 		p.sptypes = append(p.sptypes, tname)
 	}
-	ctx.classes[f] = gmxClass{tname, ext, p}
+	ctx.classes[f] = &gmxClass{tname, clsfile, ext, p}
 	if debugLoad {
 		log.Println("==> InitClass", tname, "isProj:", f.IsProj)
 	}
@@ -298,16 +300,38 @@ func gmxMainNarg(sig *types.Signature) int {
 }
 
 func hasMethod(o types.Object, name string) bool {
+	return findMethod(o, name) != nil
+}
+
+func findMethod(o types.Object, name string) *types.Func {
 	if obj, ok := o.(*types.TypeName); ok {
 		if t, ok := obj.Type().(*types.Named); ok {
 			for i, n := 0, t.NumMethods(); i < n; i++ {
-				if t.Method(i).Name() == name {
-					return true
+				f := t.Method(i)
+				if f.Name() == name {
+					return f
 				}
 			}
 		}
 	}
-	return false
+	return nil
+}
+
+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()
+	params := make([]*types.Var, nin)
+	paramName := []byte(paramNameTempl)
+	for i := 0; i < nin; i++ {
+		paramName[len(paramNameTempl)-1] = byte('0' + i)
+		params[i] = types.NewParam(token.NoPos, pkg, string(paramName), in.At(i).Type())
+	}
+	return types.NewSignatureType(recv, nil, nil, types.NewTuple(params...), nil, false)
 }
 
 // -----------------------------------------------------------------------------
diff --git a/cl/compile.go b/cl/compile.go
index 846c0564..7cc31aeb 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -338,7 +338,7 @@ func doInitMethods(ld *typeLoader) {
 type pkgCtx struct {
 	*nodeInterp
 	projs    map[string]*gmxProject // .gmx => project
-	classes  map[*ast.File]gmxClass
+	classes  map[*ast.File]*gmxClass
 	fset     *token.FileSet
 	cpkgs    *cpackages.Importer
 	syms     map[string]loader
@@ -369,9 +369,12 @@ type blockCtx struct {
 	tlookup    *typeParamLookup
 	c2goBase   string // default is `github.com/goplus/`
 	relBaseDir string
-	classRecv  *ast.FieldList // available when gmxSettings != nil
-	fileScope  *types.Scope   // only valid when isGopFile
-	rec        *goxRecorder
+
+	classRecv *ast.FieldList // available when isClass
+	baseClass types.Object   // available when isClass
+
+	fileScope *types.Scope // available when isGopFile
+	rec       *goxRecorder
 
 	fileLine  bool
 	isClass   bool
@@ -488,7 +491,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
 		fset:       fset,
 		nodeInterp: interp,
 		projs:      make(map[string]*gmxProject),
-		classes:    make(map[*ast.File]gmxClass),
+		classes:    make(map[*ast.File]*gmxClass),
 		syms:       make(map[string]loader),
 		generics:   make(map[string]bool),
 	}
@@ -715,6 +718,7 @@ func genGoFile(file string, goxTestFile bool) string {
 
 func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, conf *Config) {
 	var proj *gmxProject
+	var c *gmxClass
 	var classType string
 	var testType string
 	var baseTypeName string
@@ -724,12 +728,12 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
 	var parent = ctx.pkgCtx
 	if f.IsClass {
 		if f.IsNormalGox {
-			classType, _ = ClassNameAndExt(file)
+			classType, _, _ = ClassNameAndExt(file)
 			if classType == "main" {
 				classType = "_main"
 			}
 		} else {
-			c := parent.classes[f]
+			c = parent.classes[f]
 			classType = c.tname
 			proj, ctx.proj = c.proj, c.proj
 			ctx.autoimps = proj.autoimps
@@ -742,12 +746,14 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
 			}
 			if f.IsProj {
 				o := proj.game
+				ctx.baseClass = o
 				baseTypeName, baseType = o.Name(), o.Type()
 				if proj.gameIsPtr {
 					baseType = types.NewPointer(baseType)
 				}
 			} else {
 				o := proj.sprite[c.ext]
+				ctx.baseClass = o
 				baseTypeName, baseType, spxClass = o.Name(), o.Type(), true
 			}
 		}
@@ -846,6 +852,31 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
 				X: &ast.Ident{Name: classType},
 			},
 		}}}
+		// func Classfname() string
+		if spxClass {
+			f.Decls = append(f.Decls, &ast.FuncDecl{
+				Name: &ast.Ident{
+					Name: "Classfname",
+				},
+				Type: &ast.FuncType{
+					Params: &ast.FieldList{},
+					Results: &ast.FieldList{
+						List: []*ast.Field{
+							{Type: &ast.Ident{Name: "string"}},
+						},
+					},
+				},
+				Body: &ast.BlockStmt{
+					List: []ast.Stmt{
+						&ast.ReturnStmt{
+							Results: []ast.Expr{
+								&ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(c.clsfile)},
+							},
+						},
+					},
+				},
+			})
+		}
 	}
 	if d := f.ShadowEntry; d != nil {
 		d.Name.Name = getEntrypoint(f)
@@ -1215,8 +1246,17 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
 			log.Printf("==> Load method %v.%s\n", recv.Type(), name)
 		}
 	}
-	pkg := ctx.pkg
-	if d.Operator {
+	var pkg = ctx.pkg
+	var sigBase *types.Signature
+	if d.Shadow {
+		if recv != nil {
+			if base := ctx.baseClass; base != nil {
+				if f := findMethod(base, name); f != nil {
+					sigBase = makeMainSig(recv, f)
+				}
+			}
+		}
+	} else if d.Operator {
 		if recv != nil { // binary op
 			if v, ok := binaryGopNames[name]; ok {
 				name = v
@@ -1232,7 +1272,10 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
 			}
 		}
 	}
-	sig := toFuncType(ctx, d.Type, recv, d)
+	sig := sigBase
+	if sig == nil {
+		sig = toFuncType(ctx, d.Type, recv, d)
+	}
 	fn, err := pkg.NewFuncWith(d.Name.Pos(), name, sig, func() token.Pos {
 		return d.Recv.List[0].Type.Pos()
 	})
@@ -1253,11 +1296,11 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
 				file := pkg.CurFile()
 				ctx.inits = append(ctx.inits, func() { // interface issue: #795
 					old := pkg.RestoreCurFile(file)
-					loadFuncBody(ctx, fn, body, d)
+					loadFuncBody(ctx, fn, body, sigBase, d)
 					pkg.RestoreCurFile(old)
 				})
 			} else {
-				loadFuncBody(ctx, fn, body, d)
+				loadFuncBody(ctx, fn, body, nil, d)
 			}
 		}
 	}
@@ -1316,8 +1359,18 @@ var unaryGopNames = map[string]string{
 	"<-": "Gop_Recv",
 }
 
-func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, src ast.Node) {
+func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, sigBase *types.Signature, src ast.Node) {
 	cb := fn.BodyStart(ctx.pkg, body)
+	if sigBase != nil {
+		// this.Sprite.Main(...) or this.Game.MainEntry(...)
+		cb.VarVal("this").MemberVal(ctx.baseClass.Name()).MemberVal(fn.Name())
+		params := sigBase.Params()
+		n := params.Len()
+		for i := 0; i < n; i++ {
+			cb.Val(params.At(i))
+		}
+		cb.Call(n).EndStmt()
+	}
 	compileStmts(ctx, body.List)
 	if rec := ctx.recorder(); rec != nil {
 		switch fn := src.(type) {
diff --git a/cl/expr.go b/cl/expr.go
index 8ffc3b12..735c3a5b 100644
--- a/cl/expr.go
+++ b/cl/expr.go
@@ -904,7 +904,7 @@ func compileFuncLit(ctx *blockCtx, v *ast.FuncLit) {
 	}
 	fn := cb.NewClosureWith(sig)
 	if body := v.Body; body != nil {
-		loadFuncBody(ctx, fn, body, v)
+		loadFuncBody(ctx, fn, body, nil, v)
 		cb.SetComments(comments, once)
 	}
 }
diff --git a/cl/internal/spx3/spx3.go b/cl/internal/spx3/spx3.go
index 8f1d8574..551fcdb1 100644
--- a/cl/internal/spx3/spx3.go
+++ b/cl/internal/spx3/spx3.go
@@ -38,7 +38,7 @@ func (p *Sprite) Name() string {
 	return "sprite"
 }
 
-func (p *Sprite) initSprite(name string) {}
+func (p *Sprite) Main(name string) {}
 
-func Gopt_Game_Main(game interface{ initGame() }, workers ...interface{ initSprite(name string) }) {
+func Gopt_Game_Main(game interface{ initGame() }, workers ...interface{ Main(name string) }) {
 }
diff --git a/cl/stmt.go b/cl/stmt.go
index 359f5481..7d9b1eca 100644
--- a/cl/stmt.go
+++ b/cl/stmt.go
@@ -53,6 +53,10 @@ func commentStmt(ctx *blockCtx, stmt ast.Stmt) {
 
 func commentStmtEx(cb *gox.CodeBuilder, ctx *pkgCtx, stmt ast.Stmt) {
 	start := stmt.Pos()
+	if start == token.NoPos {
+		cb.SetComments(nil, false)
+		return
+	}
 	if doc := checkStmtDoc(stmt); doc != nil {
 		start = doc.Pos()
 	}
diff --git a/x/typesutil/check.go b/x/typesutil/check.go
index 6ee70a17..737b7f82 100644
--- a/x/typesutil/check.go
+++ b/x/typesutil/check.go
@@ -82,9 +82,6 @@ type Config struct {
 
 	// If IgnoreFuncBodies is set, skip compiling function bodies (optional).
 	IgnoreFuncBodies bool
-
-	// If UpdateGoTypesOverload is set, update go types overload data (optional).
-	UpdateGoTypesOverload bool
 }
 
 // A Checker maintains the state of the type checker.
@@ -178,16 +175,13 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 		}
 		// don't return even if err != nil
 	}
-	if len(files) > 0 {
+	if len(files) > 0 && p.goInfo != nil {
 		scope := pkgTypes.Scope()
 		objMap := DeleteObjects(scope, files)
 		checker := types.NewChecker(conf, fset, pkgTypes, p.goInfo)
 		err = checker.Files(files)
 		// TODO: how to process error?
 		CorrectTypesInfo(scope, objMap, p.gopInfo.Uses)
-		if opts.UpdateGoTypesOverload {
-			gox.InitThisGopPkg(pkgTypes)
-		}
 	}
 	return
 }


Test patch:
diff --git a/cl/builtin_test.go b/cl/builtin_test.go
index cdb95b97..ffa51f46 100644
--- a/cl/builtin_test.go
+++ b/cl/builtin_test.go
@@ -287,8 +287,12 @@ func TestMarkAutogen(t *testing.T) {
 }
 
 func TestClassNameAndExt(t *testing.T) {
-	name, ext := ClassNameAndExt("/foo/bar.abc_yap.gox")
-	if name != "bar" || ext != "_yap.gox" {
+	name, clsfile, ext := ClassNameAndExt("/foo/bar.abc_yap.gox")
+	if name != "bar_abc" || clsfile != "bar.abc" || ext != "_yap.gox" {
+		t.Fatal("classNameAndExt:", name, ext)
+	}
+	name, clsfile, ext = ClassNameAndExt("/foo/get-bar_:id.yap")
+	if name != "get_bar_id" || clsfile != "get-bar_:id" || ext != ".yap" {
 		t.Fatal("classNameAndExt:", name, ext)
 	}
 }
@@ -447,7 +451,7 @@ func TestGmxProject(t *testing.T) {
 	pkg := gox.NewPackage("", "foo", goxConf)
 	ctx := &pkgCtx{
 		projs:   make(map[string]*gmxProject),
-		classes: make(map[*ast.File]gmxClass),
+		classes: make(map[*ast.File]*gmxClass),
 	}
 	gmx := loadClass(ctx, pkg, "main.t2gmx", &ast.File{IsProj: true}, &Config{
 		LookupClass: lookupClass,
diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go
index c7689599..8892aae1 100644
--- a/cl/compile_spx_test.go
+++ b/cl/compile_spx_test.go
@@ -206,6 +206,9 @@ func (this *Kai) onMsg(msg string) {
 		this.Say("Hi")
 	}
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.tgmx", "Kai.tspx")
 }
 
@@ -250,6 +253,9 @@ func (this *index) onInit() {
 	this.bar()
 	fmt.Println("Hi")
 }
+func (this *bar) Classfname() string {
+	return "bar"
+}
 `)
 }
 
@@ -278,6 +284,9 @@ func (this *index) MainEntry() {
 func main() {
 	spx.Gopt_MyGame_Main(new(index))
 }
+func (this *bar) Classfname() string {
+	return "bar"
+}
 `)
 }
 
@@ -314,6 +323,9 @@ func (this *index) MainEntry() {
 func main() {
 	spx.Gopt_MyGame_Main(new(index))
 }
+func (this *bar) Classfname() string {
+	return "bar"
+}
 `)
 }
 
@@ -359,6 +371,9 @@ func (this *bar) onInit() {
 	this.Say("Where do you come from?", 2)
 	this.Broadcast__0("msg2")
 }
+func (this *bar) Classfname() string {
+	return "bar"
+}
 `, "Game.tgmx", "bar.tspx")
 }
 
@@ -408,6 +423,9 @@ func (this *Kai) onInit() {
 func (this *Kai) onCloned() {
 	this.Say("Hi")
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.tgmx", "Kai.tspx")
 }
 
@@ -451,6 +469,9 @@ func main() {
 func (this *Kai) Main() {
 	fmt.Println("Hi")
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "index.tgmx", "Kai.tspx")
 }
 
@@ -486,9 +507,13 @@ func (this *Game) MainEntry() {
 func main() {
 	spx3.Gopt_Game_Main(new(Game), new(Kai))
 }
-func (this *Kai) Main() {
+func (this *Kai) Main(_gop_arg0 string) {
+	this.Sprite.Main(_gop_arg0)
 	fmt.Println(jwt.Token("Hi"))
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "main_spx.gox", "Kai_spx.gox")
 }
 
@@ -522,6 +547,9 @@ func (this *Game) MainEntry() {
 func main() {
 	spx3.Gopt_Game_Main(new(Game), new(Kai))
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "main_spx.gox", "Kai_spx.gox")
 }
 
@@ -554,6 +582,9 @@ func main() {
 }
 func (this *Kai) onMsg(msg string) {
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.t2gmx", "Kai.t2spx")
 }
 
@@ -586,6 +617,9 @@ func main() {
 }
 func (this *Kai) onMsg(msg string) {
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.t2gmx", "Kai.t2spx2")
 }
 
@@ -612,8 +646,14 @@ 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"
+}
 `, "Dog_t3spx.gox", "Kai.t3spx2")
 }
 
@@ -641,6 +681,9 @@ func (this *Game) MainEntry() {
 func main() {
 	new(Game).Main()
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.t2gmx", "Kai.t2spx", "")
 	gopSpxTestExConf(t, "OnlyGmx", &conf, `
 var (
@@ -665,6 +708,9 @@ func (this *Game) MainEntry() {
 func main() {
 	new(Game).Main()
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.t2gmx", "Kai.t2spx", "")
 
 	gopSpxTestExConf(t, "KaiAndGmx", &conf, `
@@ -707,6 +753,9 @@ func (this *Kai) Main() {
 }
 func (this *Kai) onMsg(msg string) {
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.t2gmx", "Kai.t2spx", "")
 }
 
@@ -745,6 +794,9 @@ func (this *Kai) onMsg(msg string) {
 		this.Say("Hi")
 	}
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.tgmx", "Kai.tspx")
 }
 
@@ -809,6 +861,9 @@ func (this *Kai) onInit() {
 func (this *Kai) onCloned() {
 	this.Say("Hi")
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.tgmx", "Kai.tspx")
 }
 
@@ -846,6 +901,9 @@ func main() {
 }
 func (this *Kai) onMsg(msg string) {
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.tgmx", "Kai.tspx")
 }
 
@@ -880,6 +938,9 @@ func main() {
 func (this *Kai) onMsg(msg string) {
 	this.Position().Add__0(100, 200)
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.tgmx", "Kai.tspx")
 }
 
@@ -939,6 +1000,9 @@ func (this *Kai) onMsg(msg string) {
 	fmt.Println(this.Vector().X)
 	fmt.Println(this.Vector().Self().Self())
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.tgmx", "Kai.tspx")
 }
 
@@ -1040,6 +1104,9 @@ func (this *Kai) Main() {
 	spx.Gopt_Sprite_OnKey2(this, "hello", func(key string) {
 	})
 }
+func (this *Kai) Classfname() string {
+	return "Kai"
+}
 `, "Game.tgmx", "Kai.tspx")
 }
 
@@ -1076,6 +1143,9 @@ 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)
 }
@@ -1104,6 +1174,9 @@ 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)
 }
diff --git a/x/build/build_test.go b/x/build/build_test.go
index 8e2f621f..fed51751 100644
--- a/x/build/build_test.go
+++ b/x/build/build_test.go
@@ -401,6 +401,9 @@ func main() {
 func (this *Cat) Main() {
 	fmt.Println("hi")
 }
+func (this *Cat) Classfname() string {
+	return "Cat"
+}
 `)
 }
 
diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go
index 42b76216..22a28855 100644
--- a/x/typesutil/info_test.go
+++ b/x/typesutil/info_test.go
@@ -21,7 +21,6 @@ import (
 	"github.com/goplus/gop/parser"
 	"github.com/goplus/gop/token"
 	"github.com/goplus/gop/x/typesutil"
-	"github.com/goplus/gox"
 	"github.com/goplus/mod/env"
 	"github.com/goplus/mod/gopmod"
 	"github.com/goplus/mod/modfile"
@@ -62,16 +61,16 @@ func spxParserConf() parser.Config {
 	}
 }
 
-func parseMixedSource(mod *gopmod.Module, fset *token.FileSet, name, src string, goname string, gosrc string, parserConf parser.Config, updateGoTypesOverload bool) (*types.Package, *typesutil.Info, *types.Info, error) {
+func parseMixedSource(mod *gopmod.Module, fset *token.FileSet, name, src string, goname string, gosrc string, parserConf parser.Config) (*typesutil.Info, *types.Info, error) {
 	f, err := parser.ParseEntry(fset, name, src, parserConf)
 	if err != nil {
-		return nil, nil, nil, err
+		return nil, nil, err
 	}
 	var gofiles []*goast.File
 	if len(gosrc) > 0 {
 		f, err := goparser.ParseFile(fset, goname, gosrc, goparser.ParseComments)
 		if err != nil {
-			return nil, nil, nil, err
+			return nil, nil, err
 		}
 		gofiles = append(gofiles, f)
 	}
@@ -79,10 +78,9 @@ func parseMixedSource(mod *gopmod.Module, fset *token.FileSet, name, src string,
 	conf := &types.Config{}
 	conf.Importer = gop.NewImporter(nil, &env.Gop{Root: "../..", Version: "1.0"}, fset)
 	chkOpts := &typesutil.Config{
-		Types:                 types.NewPackage("main", f.Name.Name),
-		Fset:                  fset,
-		Mod:                   mod,
-		UpdateGoTypesOverload: updateGoTypesOverload,
+		Types: types.NewPackage("main", f.Name.Name),
+		Fset:  fset,
+		Mod:   mod,
 	}
 	info := &typesutil.Info{
 		Types:      make(map[ast.Expr]types.TypeAndValue),
@@ -103,7 +101,7 @@ func parseMixedSource(mod *gopmod.Module, fset *token.FileSet, name, src string,
 	}
 	check := typesutil.NewChecker(conf, chkOpts, ginfo, info)
 	err = check.Files(gofiles, []*ast.File{f})
-	return chkOpts.Types, info, ginfo, err
+	return info, ginfo, err
 }
 
 func parseSource(fset *token.FileSet, filename string, src interface{}, mode parser.Mode) (*types.Package, *typesutil.Info, error) {
@@ -168,7 +166,7 @@ func testSpxInfo(t *testing.T, name string, src string, expect string) {
 
 func testGopInfoEx(t *testing.T, mod *gopmod.Module, name string, src string, goname string, gosrc string, expect string, parseConf parser.Config) {
 	fset := token.NewFileSet()
-	_, info, _, err := parseMixedSource(mod, fset, name, src, goname, gosrc, parseConf, false)
+	info, _, err := parseMixedSource(mod, fset, name, src, goname, gosrc, parseConf)
 	if err != nil {
 		t.Fatal("parserMixedSource error", err)
 	}
@@ -1625,53 +1623,57 @@ func onCloned() {
 	say("Hi")
 }
 `, `== types ==
-000:  0: 0 | Kai                 *ast.Ident                     | type    : main.Kai | type
-001:  3: 4 | int                 *ast.Ident                     | type    : int | type
-002:  6:11 | struct {
+000:  0: 0 | "Kai"               *ast.BasicLit                  | value   : untyped string = "Kai" | constant
+001:  0: 0 | Kai                 *ast.Ident                     | type    : main.Kai | type
+002:  0: 0 | string              *ast.Ident                     | type    : string | 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
-003:  7: 4 | int                 *ast.Ident                     | type    : int | type
-004:  8: 4 | int                 *ast.Ident                     | type    : int | type
-005: 12: 2 | a                   *ast.Ident                     | var     : int | variable
-006: 12: 6 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
-007: 13: 2 | clone               *ast.Ident                     | value   : func(sprite interface{}) | value
-008: 14: 2 | clone               *ast.Ident                     | value   : func(sprite interface{}, data interface{}) | value
-009: 14: 2 | clone info{1, 2}    *ast.CallExpr                  | void    : () | no value
-010: 14: 8 | info                *ast.Ident                     | type    : main.info | type
-011: 14: 8 | info{1, 2}          *ast.CompositeLit              | value   : main.info | value
-012: 14:13 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
-013: 14:15 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
-014: 15: 2 | clone               *ast.Ident                     | value   : func(sprite interface{}, data interface{}) | value
-015: 15: 2 | clone &info{1, 2}   *ast.CallExpr                  | void    : () | no value
-016: 15: 8 | &info{1, 2}         *ast.UnaryExpr                 | value   : *main.info | value
-017: 15: 9 | info                *ast.Ident                     | type    : main.info | type
-018: 15: 9 | info{1, 2}          *ast.CompositeLit              | value   : main.info | value
-019: 15:14 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
-020: 15:16 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
-021: 19: 2 | say                 *ast.Ident                     | value   : func(msg string, secs ...float64) | value
-022: 19: 2 | say("Hi")           *ast.CallExpr                  | void    : () | no value
-023: 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 interface{}) | value
+010: 14: 2 | clone               *ast.Ident                     | value   : func(sprite interface{}, data interface{}) | 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 interface{}, data interface{}) | 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 | this                | var this *main.Kai
-001:  3: 2 | a                   | field a int
-002:  6: 6 | info                | type main.info struct{x int; y int}
-003:  7: 2 | x                   | field x int
-004:  8: 2 | y                   | field y int
-005: 11: 6 | onInit              | func (*main.Kai).onInit()
-006: 18: 6 | onCloned            | func (*main.Kai).onCloned()
+000:  0: 0 | Classfname          | func (*main.Kai).Classfname() string
+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; a int}
-001:  3: 4 | int                 | type int
-002:  7: 4 | int                 | type int
-003:  8: 4 | int                 | type int
-004: 12: 2 | a                   | field a int
-005: 13: 2 | clone               | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__0(sprite interface{})
-006: 14: 2 | clone               | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite interface{}, data interface{})
-007: 14: 8 | info                | type main.info struct{x int; y int}
-008: 15: 2 | clone               | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite interface{}, data interface{})
-009: 15: 9 | info                | type main.info struct{x int; y int}
-010: 19: 2 | say                 | func (*github.com/goplus/gop/cl/internal/spx.Sprite).Say(msg string, secs ...float64)`)
+001:  0: 0 | string              | type string
+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 interface{})
+007: 14: 2 | clone               | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite interface{}, data interface{})
+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 interface{}, data interface{})
+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)`)
 }
 
 func TestScopesInfo(t *testing.T) {
@@ -1881,103 +1883,3 @@ func _() {
 }
 `)
 }
-
-func TestAddress2(t *testing.T) {
-	testInfo(t, `package load
-import "os"
-
-func _() { _ = os.Stdout }
-func _() {
-	var a int
-	_ = a
-}
-func _() {
-	var p *int
-	_ = *p
-}
-func _() {
-	var s []int
-	_ = s[0]
-}
-func _() {
-	var s struct{f int}
-	_ = s.f
-}
-func _() {
-	var a [10]int
-	_ = a[0]
-}
-func _(x int) {
-	_ = x
-}
-func _()(x int) {
-	_ = x
-	return
-}
-type T int
-func (x T) _() {
-	_ = x
-}
-
-func _() {
-	var a, b int
-	_ = a + b
-}
-func _() {
-	_ = &[]int{1}
-}
-func _() {
-	_ = func(){}
-}
-func f() { _ = f }
-func _() {
-	var m map[int]int
-	_ = m[0]
-	_, _ = m[0]
-}
-func _() {
-	var ch chan int
-	_ = <-ch
-	_, _ = <-ch
-}
-`)
-}
-
-func TestMixedPackage(t *testing.T) {
-	fset := token.NewFileSet()
-	pkg, _, _, err := parseMixedSource(gopmod.Default, fset, "main.gop", `
-Test
-Test 100
-var n N
-n.test
-n.test 100
-`, "main.go", `
-package main
-
-func Test__0() {
-}
-func Test__1(n int) {
-}
-type N struct {
-}
-func (p *N) Test__0() {
-}
-func (p *N) Test__1(n int) {
-}`, parser.Config{}, true)
-	if err != nil {
-		t.Fatal(err)
-	}
-	obj := pkg.Scope().Lookup("N")
-	named := obj.Type().(*types.Named)
-	if named.NumMethods() == 2 {
-		t.Fatal("found overload method failed")
-	}
-	ext, ok := gox.CheckFuncEx(named.Method(2).Type().(*types.Signature))
-	if !ok {
-		t.Fatal("checkFuncEx failed")
-	}
-	m, ok := ext.(*gox.TyOverloadMethod)
-	if !ok || len(m.Methods) != 2 {
-		t.Fatal("check TyOverloadMethod failed")
-	}
-}