Repository: goplus/gop
Pull request #1798 (2024-03-08 17:30:30)

gox => gogen


Patch:
diff --git a/ast/commentmap.go b/ast/commentmap.go
index 8cebf7e1..83e0fca3 100644
--- a/ast/commentmap.go
+++ b/ast/commentmap.go
@@ -31,7 +31,6 @@ func (a byPos) Less(i, j int) bool { return a[i].Pos() < a[j].Pos() }
 func (a byPos) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
 
 // sortComments sorts the list of comment groups in source order.
-//
 func sortComments(list []*CommentGroup) {
 	// TODO(gri): Does it make sense to check for sorted-ness
 	//            first (because we know that sorted-ness is
@@ -44,7 +43,6 @@ func sortComments(list []*CommentGroup) {
 // A CommentMap maps an AST node to a list of comment groups
 // associated with it. See NewCommentMap for a description of
 // the association.
-//
 type CommentMap map[Node][]*CommentGroup
 
 func (cmap CommentMap) addComment(n Node, c *CommentGroup) {
@@ -58,7 +56,6 @@ func (cmap CommentMap) addComment(n Node, c *CommentGroup) {
 }
 
 // nodeList returns the list of nodes of the AST n in source order.
-//
 func nodeList(n Node) []Node {
 	var list []Node
 	Inspect(n, func(n Node) bool {
@@ -79,7 +76,6 @@ func nodeList(n Node) []Node {
 }
 
 // A commentListReader helps iterating through a list of comment groups.
-//
 type commentListReader struct {
 	fset     *token.FileSet
 	list     []*CommentGroup
@@ -103,12 +99,10 @@ func (r *commentListReader) next() {
 
 // A nodeStack keeps track of nested nodes.
 // A node lower on the stack lexically contains the nodes higher on the stack.
-//
 type nodeStack []Node
 
 // push pops all nodes that appear lexically before n
 // and then pushes n on the stack.
-//
 func (s *nodeStack) push(n Node) {
 	s.pop(n.Pos())
 	*s = append((*s), n)
@@ -117,7 +111,6 @@ func (s *nodeStack) push(n Node) {
 // pop pops all nodes that appear lexically before pos
 // (i.e., whose lexical extent has ended before or at pos).
 // It returns the last node popped.
-//
 func (s *nodeStack) pop(pos token.Pos) (top Node) {
 	i := len(*s)
 	for i > 0 && (*s)[i-1].End() <= pos {
@@ -143,7 +136,6 @@ func (s *nodeStack) pop(pos token.Pos) (top Node) {
 // node possible: For instance, if the comment is a line comment
 // trailing an assignment, the comment is associated with the entire
 // assignment rather than just the last operand in the assignment.
-//
 func NewCommentMap(fset *token.FileSet, node Node, comments []*CommentGroup) CommentMap {
 	if len(comments) == 0 {
 		return nil // no comments to map
@@ -246,7 +238,6 @@ func NewCommentMap(fset *token.FileSet, node Node, comments []*CommentGroup) Com
 // Update replaces an old node in the comment map with the new node
 // and returns the new node. Comments that were associated with the
 // old node are associated with the new node.
-//
 func (cmap CommentMap) Update(old, new Node) Node {
 	if list := cmap[old]; len(list) > 0 {
 		delete(cmap, old)
@@ -258,7 +249,6 @@ func (cmap CommentMap) Update(old, new Node) Node {
 // Filter returns a new comment map consisting of only those
 // entries of cmap for which a corresponding node exists in
 // the AST specified by node.
-//
 func (cmap CommentMap) Filter(node Node) CommentMap {
 	umap := make(CommentMap)
 	Inspect(node, func(n Node) bool {
@@ -272,7 +262,6 @@ func (cmap CommentMap) Filter(node Node) CommentMap {
 
 // Comments returns the list of comment groups in the comment map.
 // The result is sorted in source order.
-//
 func (cmap CommentMap) Comments() []*CommentGroup {
 	list := make([]*CommentGroup, 0, len(cmap))
 	for _, e := range cmap {
diff --git a/ast/resolve.go b/ast/resolve.go
index b796d213..54e3696f 100644
--- a/ast/resolve.go
+++ b/ast/resolve.go
@@ -83,7 +83,6 @@ type Importer func(imports map[string]*Object, path string) (pkg *Object, err er
 // belong to different packages, one package name is selected and files with
 // different package names are reported and then ignored.
 // The result is a package node and a scanner.ErrorList if there were errors.
-//
 func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer, universe *Scope) (*Package, error) {
 	var p pkgBuilder
 	p.fset = fset
diff --git a/ast/scope.go b/ast/scope.go
index 38d7d0a5..cd0a7025 100644
--- a/ast/scope.go
+++ b/ast/scope.go
@@ -28,7 +28,6 @@ import (
 // A Scope maintains the set of named language entities declared
 // in the scope and a link to the immediately surrounding (outer)
 // scope.
-//
 type Scope struct {
 	Outer   *Scope
 	Objects map[string]*Object
@@ -43,7 +42,6 @@ func NewScope(outer *Scope) *Scope {
 // Lookup returns the object with the given name if it is
 // found in scope s, otherwise it returns nil. Outer scopes
 // are ignored.
-//
 func (s *Scope) Lookup(name string) *Object {
 	return s.Objects[name]
 }
@@ -52,7 +50,6 @@ func (s *Scope) Lookup(name string) *Object {
 // If the scope already contains an object alt with the same name,
 // Insert leaves the scope unchanged and returns alt. Otherwise
 // it inserts obj and returns nil.
-//
 func (s *Scope) Insert(obj *Object) (alt *Object) {
 	if alt = s.Objects[obj.Name]; alt == nil {
 		s.Objects[obj.Name] = obj
@@ -85,7 +82,6 @@ func (s *Scope) String() string {
 //	Kind    Data type         Data value
 //	Pkg     *Scope            package scope
 //	Con     int               iota for the respective declaration
-//
 type Object struct {
 	Kind ObjKind
 	Name string      // declared name
diff --git a/cl/builtin.go b/cl/builtin.go
index 7f2ad239..e1d59757 100644
--- a/cl/builtin.go
+++ b/cl/builtin.go
@@ -20,25 +20,25 @@ import (
 	"go/token"
 	"go/types"
 
-	"github.com/goplus/gox"
+	"github.com/goplus/gogen"
 )
 
 // -----------------------------------------------------------------------------
 
-func initMathBig(_ *gox.Package, conf *gox.Config, big gox.PkgRef) {
+func initMathBig(_ *gogen.Package, conf *gogen.Config, big gogen.PkgRef) {
 	conf.UntypedBigInt = big.Ref("UntypedBigint").Type().(*types.Named)
 	conf.UntypedBigRat = big.Ref("UntypedBigrat").Type().(*types.Named)
 	conf.UntypedBigFloat = big.Ref("UntypedBigfloat").Type().(*types.Named)
 }
 
-func initBuiltinFns(builtin *types.Package, scope *types.Scope, pkg gox.PkgRef, fns []string) {
+func initBuiltinFns(builtin *types.Package, scope *types.Scope, pkg gogen.PkgRef, fns []string) {
 	for _, fn := range fns {
 		fnTitle := string(fn[0]-'a'+'A') + fn[1:]
-		scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, fn, pkg.Ref(fnTitle)))
+		scope.Insert(gogen.NewOverloadFunc(token.NoPos, builtin, fn, pkg.Ref(fnTitle)))
 	}
 }
 
-func initBuiltin(_ *gox.Package, builtin *types.Package, os, fmt, ng, iox, buil gox.PkgRef) {
+func initBuiltin(_ *gogen.Package, builtin *types.Package, os, fmt, ng, iox, buil gogen.PkgRef) {
 	scope := builtin.Scope()
 	if ng.Types != nil {
 		typs := []string{"bigint", "bigrat", "bigfloat"}
@@ -50,7 +50,7 @@ func initBuiltin(_ *gox.Package, builtin *types.Package, os, fmt, ng, iox, buil
 		scope.Insert(types.NewTypeName(token.NoPos, builtin, "int128", ng.Ref("Int128").Type()))
 	}
 	if fmt.Types != nil {
-		scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "echo", fmt.Ref("Println")))
+		scope.Insert(gogen.NewOverloadFunc(token.NoPos, builtin, "echo", fmt.Ref("Println")))
 		initBuiltinFns(builtin, scope, fmt, []string{
 			"print", "println", "printf", "errorf",
 			"fprint", "fprintln", "fprintf",
@@ -66,15 +66,15 @@ func initBuiltin(_ *gox.Package, builtin *types.Package, os, fmt, ng, iox, buil
 		initBuiltinFns(builtin, scope, iox, []string{
 			"lines",
 		})
-		scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "blines", iox.Ref("BLines")))
+		scope.Insert(gogen.NewOverloadFunc(token.NoPos, builtin, "blines", iox.Ref("BLines")))
 	}
 	if buil.Types != nil {
-		scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "newRange", buil.Ref("NewRange__0")))
+		scope.Insert(gogen.NewOverloadFunc(token.NoPos, builtin, "newRange", buil.Ref("NewRange__0")))
 	}
-	scope.Insert(types.NewTypeName(token.NoPos, builtin, "any", gox.TyEmptyInterface))
+	scope.Insert(types.NewTypeName(token.NoPos, builtin, "any", gogen.TyEmptyInterface))
 }
 
-func newBuiltinDefault(pkg *gox.Package, conf *gox.Config) *types.Package {
+func newBuiltinDefault(pkg *gogen.Package, conf *gogen.Config) *types.Package {
 	builtin := types.NewPackage("", "")
 	fmt := pkg.TryImport("fmt")
 	os := pkg.TryImport("os")
@@ -87,7 +87,7 @@ func newBuiltinDefault(pkg *gox.Package, conf *gox.Config) *types.Package {
 		initMathBig(pkg, conf, ng)
 	}
 	initBuiltin(pkg, builtin, os, fmt, ng, iox, buil)
-	gox.InitBuiltin(pkg, builtin, conf)
+	gogen.InitBuiltin(pkg, builtin, conf)
 	return builtin
 }
 
diff --git a/cl/c.go b/cl/c.go
index bf0d15ae..ef5b8bff 100644
--- a/cl/c.go
+++ b/cl/c.go
@@ -19,8 +19,8 @@ package cl
 import (
 	"strings"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
-	"github.com/goplus/gox"
 )
 
 const (
@@ -57,7 +57,7 @@ func c2goBase(base string) string {
 
 // -----------------------------------------------------------------------------
 
-func loadC2goPkg(ctx *blockCtx, realPath string, src *ast.BasicLit) (ret gox.PkgRef) {
+func loadC2goPkg(ctx *blockCtx, realPath string, src *ast.BasicLit) (ret gogen.PkgRef) {
 	cpkg, err := ctx.cpkgs.Import(realPath)
 	if err != nil {
 		ctx.handleErrorf(src.Pos(),
diff --git a/cl/classfile.go b/cl/classfile.go
index 97ed339b..6f09e237 100644
--- a/cl/classfile.go
+++ b/cl/classfile.go
@@ -24,9 +24,9 @@ import (
 	"path/filepath"
 	"strings"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
 	"github.com/goplus/mod/modfile"
 )
 
@@ -40,13 +40,13 @@ type gmxClass struct {
 }
 
 type gmxProject struct {
-	gameClass  string             // <gmtype>.gmx
-	game       gox.Ref            // Game
-	sprite     map[string]gox.Ref // .spx => Sprite
-	sptypes    []string           // <sptype>.spx
+	gameClass  string               // <gmtype>.gmx
+	game       gogen.Ref            // Game
+	sprite     map[string]gogen.Ref // .spx => Sprite
+	sptypes    []string             // <sptype>.spx
 	scheds     []string
 	schedStmts []goast.Stmt // nil or len(scheds) == 2 (delayload)
-	pkgImps    []gox.PkgRef
+	pkgImps    []gogen.PkgRef
 	pkgPaths   []string
 	autoimps   map[string]pkgImp // auto-import statement in gop.mod
 	hasScheds  bool
@@ -54,7 +54,7 @@ type gmxProject struct {
 	isTest     bool
 }
 
-func (p *gmxProject) getScheds(cb *gox.CodeBuilder) []goast.Stmt {
+func (p *gmxProject) getScheds(cb *gogen.CodeBuilder) []goast.Stmt {
 	if p == nil || !p.hasScheds {
 		return nil
 	}
@@ -89,7 +89,7 @@ func isGoxTestFile(ext string) bool {
 	return strings.HasSuffix(ext, "test.gox")
 }
 
-func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Config) *gmxProject {
+func loadClass(ctx *pkgCtx, pkg *gogen.Package, file string, f *ast.File, conf *Config) *gmxProject {
 	tname, clsfile, ext := ClassNameAndExt(file)
 	gt, ok := conf.LookupClass(ext)
 	if !ok {
@@ -101,7 +101,7 @@ func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Co
 		p = &gmxProject{pkgPaths: pkgPaths, isTest: isGoxTestFile(ext)}
 		ctx.projs[gt.Ext] = p
 
-		p.pkgImps = make([]gox.PkgRef, len(pkgPaths))
+		p.pkgImps = make([]gogen.PkgRef, len(pkgPaths))
 		for i, pkgPath := range pkgPaths {
 			p.pkgImps[i] = pkg.Import(pkgPath)
 		}
@@ -151,7 +151,7 @@ func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Co
 	return p
 }
 
-func spxLookup(pkgImps []gox.PkgRef, name string) gox.Ref {
+func spxLookup(pkgImps []gogen.PkgRef, name string) gogen.Ref {
 	for _, pkg := range pkgImps {
 		if o := pkg.TryRef(name); o != nil {
 			return o
@@ -160,7 +160,7 @@ func spxLookup(pkgImps []gox.PkgRef, name string) gox.Ref {
 	panic("spxLookup: symbol not found - " + name)
 }
 
-func spxTryRef(spx gox.PkgRef, typ string) (obj types.Object, isPtr bool) {
+func spxTryRef(spx gogen.PkgRef, typ string) (obj types.Object, isPtr bool) {
 	if strings.HasPrefix(typ, "*") {
 		typ, isPtr = typ[1:], true
 	}
@@ -168,7 +168,7 @@ func spxTryRef(spx gox.PkgRef, typ string) (obj types.Object, isPtr bool) {
 	return
 }
 
-func spxRef(spx gox.PkgRef, typ string) (obj gox.Ref, isPtr bool) {
+func spxRef(spx gogen.PkgRef, typ string) (obj gogen.Ref, isPtr bool) {
 	obj, isPtr = spxTryRef(spx, typ)
 	if obj == nil {
 		panic(spx.Path() + "." + typ + " not found")
@@ -176,7 +176,7 @@ func spxRef(spx gox.PkgRef, typ string) (obj gox.Ref, isPtr bool) {
 	return
 }
 
-func getStringConst(spx gox.PkgRef, name string) string {
+func getStringConst(spx gogen.PkgRef, name string) string {
 	if o := spx.TryRef(name); o != nil {
 		if c, ok := o.(*types.Const); ok {
 			return constant.StringVal(c.Val())
@@ -206,7 +206,7 @@ func setBodyHandler(ctx *blockCtx) {
 				if len(body.List) == 0 {
 					idx = 1
 				}
-				gox.InsertStmtFront(body, scheds[idx])
+				gogen.InsertStmtFront(body, scheds[idx])
 			})
 		}
 	}
@@ -223,7 +223,7 @@ func testNameSuffix(testType string) string {
 	return "_" + testType
 }
 
-func gmxTestFunc(pkg *gox.Package, testType string, isProj bool) {
+func gmxTestFunc(pkg *gogen.Package, testType string, isProj bool) {
 	if isProj {
 		genTestFunc(pkg, "TestMain", testType, "m", "M")
 	} else {
@@ -232,7 +232,7 @@ func gmxTestFunc(pkg *gox.Package, testType string, isProj bool) {
 	}
 }
 
-func genTestFunc(pkg *gox.Package, name, testType, param, paramType string) {
+func genTestFunc(pkg *gogen.Package, name, testType, param, paramType string) {
 	testing := pkg.Import("testing")
 	objT := testing.Ref(paramType)
 	paramT := types.NewParam(token.NoPos, pkg.Types, param, types.NewPointer(objT.Type()))
@@ -244,7 +244,7 @@ func genTestFunc(pkg *gox.Package, name, testType, param, paramType string) {
 		End()
 }
 
-func gmxMainFunc(pkg *gox.Package, ctx *pkgCtx, noAutoGenMain bool) func() {
+func gmxMainFunc(pkg *gogen.Package, ctx *pkgCtx, noAutoGenMain bool) func() {
 	var proj *gmxProject
 	for _, v := range ctx.projs {
 		if v.isTest {
@@ -294,8 +294,8 @@ func gmxMainFunc(pkg *gox.Package, ctx *pkgCtx, noAutoGenMain bool) func() {
 }
 
 func gmxMainNarg(sig *types.Signature) int {
-	if fex, ok := gox.CheckFuncEx(sig); ok {
-		if trm, ok := fex.(*gox.TyTemplateRecvMethod); ok {
+	if fex, ok := gogen.CheckFuncEx(sig); ok {
+		if trm, ok := fex.(*gogen.TyTemplateRecvMethod); ok {
 			sig = trm.Func.Type().(*types.Signature)
 			return sig.Params().Len() - 1
 		}
diff --git a/cl/compile.go b/cl/compile.go
index 7cc31aeb..5359e50c 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -26,11 +26,11 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/goplus/gogen"
+	"github.com/goplus/gogen/cpackages"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/ast/fromgo"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
-	"github.com/goplus/gox/cpackages"
 	"github.com/goplus/mod/modfile"
 	"github.com/qiniu/x/errors"
 )
@@ -353,18 +353,18 @@ type pkgCtx struct {
 }
 
 type pkgImp struct {
-	gox.PkgRef
+	gogen.PkgRef
 	pkgName *types.PkgName
 }
 
 type blockCtx struct {
 	*pkgCtx
 	proj       *gmxProject
-	pkg        *gox.Package
-	cb         *gox.CodeBuilder
+	pkg        *gogen.Package
+	cb         *gogen.CodeBuilder
 	imports    map[string]pkgImp
 	autoimps   map[string]pkgImp
-	lookups    []gox.PkgRef
+	lookups    []gogen.PkgRef
 	clookups   []cpackages.PkgRef
 	tlookup    *typeParamLookup
 	c2goBase   string // default is `github.com/goplus/`
@@ -397,11 +397,11 @@ func (p *blockCtx) findImport(name string) (pi pkgImp, ok bool) {
 }
 
 func (p *pkgCtx) newCodeError(pos token.Pos, msg string) error {
-	return &gox.CodeError{Fset: p.nodeInterp, Pos: pos, Msg: msg}
+	return &gogen.CodeError{Fset: p.nodeInterp, Pos: pos, Msg: msg}
 }
 
 func (p *pkgCtx) newCodeErrorf(pos token.Pos, format string, args ...interface{}) error {
-	return &gox.CodeError{Fset: p.nodeInterp, Pos: pos, Msg: fmt.Sprintf(format, args...)}
+	return &gogen.CodeError{Fset: p.nodeInterp, Pos: pos, Msg: fmt.Sprintf(format, args...)}
 }
 
 func (p *pkgCtx) handleErrorf(pos token.Pos, format string, args ...interface{}) {
@@ -412,7 +412,7 @@ func (p *pkgCtx) handleErr(err error) {
 	p.errs = append(p.errs, err)
 }
 
-func (p *pkgCtx) loadNamed(at *gox.Package, t *types.Named) {
+func (p *pkgCtx) loadNamed(at *gogen.Package, t *types.Named) {
 	o := t.Obj()
 	if o.Pkg() == at.Types {
 		p.loadType(o.Name())
@@ -480,7 +480,7 @@ const (
 )
 
 // NewPackage creates a Go+ package instance.
-func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package, err error) {
+func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gogen.Package, err error) {
 	relBaseDir := conf.RelativeBase
 	fset := conf.Fset
 	files := pkg.Files
@@ -495,7 +495,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
 		syms:       make(map[string]loader),
 		generics:   make(map[string]bool),
 	}
-	confGox := &gox.Config{
+	confGox := &gogen.Config{
 		Types:           conf.Types,
 		Fset:            fset,
 		Importer:        conf.Importer,
@@ -521,7 +521,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
 			}
 		}()
 	}
-	p = gox.NewPackage(pkgPath, pkg.Name, confGox)
+	p = gogen.NewPackage(pkgPath, pkg.Name, confGox)
 
 	if !noMarkAutogen {
 		p.CB().NewConstStart(nil, "_").Val(true).EndInit(1)
@@ -636,7 +636,7 @@ func isOverloadFunc(name string) bool {
 	return n > 3 && name[n-3:n-1] == "__"
 }
 
-func initGopPkg(ctx *pkgCtx, pkg *gox.Package, gopSyms map[string]bool) {
+func initGopPkg(ctx *pkgCtx, pkg *gogen.Package, gopSyms map[string]bool) {
 	for name, f := range ctx.syms {
 		if gopSyms[name] {
 			continue
@@ -654,7 +654,7 @@ func initGopPkg(ctx *pkgCtx, pkg *gox.Package, gopSyms map[string]bool) {
 			ctx.loadType(lbi.(*ast.Ident).Name)
 		}
 	}
-	gox.InitThisGopPkg(pkg.Types)
+	gogen.InitThisGopPkg(pkg.Types)
 }
 
 func inMainPkg(f *ast.File) bool {
@@ -716,7 +716,7 @@ func genGoFile(file string, goxTestFile bool) string {
 	return defaultGoFile
 }
 
-func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, conf *Config) {
+func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, conf *Config) {
 	var proj *gmxProject
 	var c *gmxClass
 	var classType string
@@ -764,7 +764,7 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
 			log.Println("==> Preload type", classType)
 		}
 		if proj != nil {
-			ctx.lookups = make([]gox.PkgRef, len(proj.pkgPaths))
+			ctx.lookups = make([]gogen.PkgRef, len(proj.pkgPaths))
 			for i, pkgPath := range proj.pkgPaths {
 				ctx.lookups[i] = p.Import(pkgPath)
 			}
@@ -928,7 +928,7 @@ retry:
 	panic("TODO: parseTypeEmbedName unexpected")
 }
 
-func preloadFile(p *gox.Package, ctx *blockCtx, f *ast.File, goFile string, genFnBody bool) {
+func preloadFile(p *gogen.Package, ctx *blockCtx, f *ast.File, goFile string, genFnBody bool) {
 	parent := ctx.pkgCtx
 	syms := parent.syms
 	old, _ := p.SetCurFile(goFile, true)
@@ -1359,7 +1359,7 @@ var unaryGopNames = map[string]string{
 	"<-": "Gop_Recv",
 }
 
-func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, sigBase *types.Signature, src ast.Node) {
+func loadFuncBody(ctx *blockCtx, fn *gogen.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(...)
@@ -1398,7 +1398,7 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) {
 			}
 		}()
 	}
-	var pkg gox.PkgRef
+	var pkg gogen.PkgRef
 	var pkgPath = toString(spec.Path)
 	if realPath, kind := checkC2go(pkgPath); kind != c2goInvalid {
 		if kind == c2goStandard {
@@ -1444,14 +1444,14 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) {
 	ctx.imports[name] = pkgImp{pkg, pkgName}
 }
 
-func loadConstSpecs(ctx *blockCtx, cdecl *gox.ConstDefs, specs []ast.Spec) {
+func loadConstSpecs(ctx *blockCtx, cdecl *gogen.ConstDefs, specs []ast.Spec) {
 	for iotav, spec := range specs {
 		vSpec := spec.(*ast.ValueSpec)
 		loadConsts(ctx, cdecl, vSpec, iotav)
 	}
 }
 
-func loadConsts(ctx *blockCtx, cdecl *gox.ConstDefs, v *ast.ValueSpec, iotav int) {
+func loadConsts(ctx *blockCtx, cdecl *gogen.ConstDefs, v *ast.ValueSpec, iotav int) {
 	vNames := v.Names
 	names := makeNames(vNames)
 	if v.Values == nil {
@@ -1469,7 +1469,7 @@ func loadConsts(ctx *blockCtx, cdecl *gox.ConstDefs, v *ast.ValueSpec, iotav int
 	if debugLoad {
 		log.Println("==> Load const", names, typ)
 	}
-	fn := func(cb *gox.CodeBuilder) int {
+	fn := func(cb *gogen.CodeBuilder) int {
 		for _, val := range v.Values {
 			compileExpr(ctx, val)
 		}
diff --git a/cl/expr.go b/cl/expr.go
index 735c3a5b..d81cdf4c 100644
--- a/cl/expr.go
+++ b/cl/expr.go
@@ -28,11 +28,11 @@ import (
 	"strings"
 	"syscall"
 
+	"github.com/goplus/gogen"
+	"github.com/goplus/gogen/cpackages"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/printer"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
-	"github.com/goplus/gox/cpackages"
 )
 
 /*-----------------------------------------------------------------------------
@@ -79,7 +79,7 @@ const (
 	objGopExec = objGopExecOrEnv
 )
 
-func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (pkg gox.PkgRef, kind int) {
+func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (pkg gogen.PkgRef, kind int) {
 	fvalue := (flags&clIdentSelectorExpr) != 0 || (flags&clIdentLHS) == 0
 	cb := ctx.cb
 	name := ident.Name
@@ -143,7 +143,7 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (pkg gox.PkgRef, k
 	}
 
 	// object from import . "xxx"
-	if compilePkgRef(ctx, gox.PkgRef{}, ident, flags, objPkgRef) {
+	if compilePkgRef(ctx, gogen.PkgRef{}, ident, flags, objPkgRef) {
 		return
 	}
 
@@ -179,7 +179,7 @@ find:
 	}
 	if rec := ctx.recorder(); rec != nil {
 		e := cb.Get(-1)
-		if oldo != nil && gox.IsTypeEx(e.Type) { // for builtin object
+		if oldo != nil && gogen.IsTypeEx(e.Type) { // for builtin object
 			rec.recordIdent(ident, oldo)
 			return
 		}
@@ -188,7 +188,7 @@ find:
 	return
 }
 
-func classRecv(cb *gox.CodeBuilder) *types.Var {
+func classRecv(cb *gogen.CodeBuilder) *types.Var {
 	if fn := cb.Func(); fn != nil {
 		sig := fn.Ancestor().Type().(*types.Signature)
 		return sig.Recv()
@@ -196,8 +196,8 @@ func classRecv(cb *gox.CodeBuilder) *types.Var {
 	return nil
 }
 
-func gopMember(cb *gox.CodeBuilder, recv *types.Var, op string, src ...ast.Node) error {
-	_, e := cb.Val(recv).Member(op, gox.MemberFlagVal, src...)
+func gopMember(cb *gogen.CodeBuilder, recv *types.Var, op string, src ...ast.Node) error {
+	_, e := cb.Val(recv).Member(op, gogen.MemberFlagVal, src...)
 	return e
 }
 
@@ -209,14 +209,14 @@ func isBuiltin(o types.Object) bool {
 }
 
 func compileMember(ctx *blockCtx, v ast.Node, name string, flags int) error {
-	var mflag gox.MemberFlag
+	var mflag gogen.MemberFlag
 	switch {
 	case (flags & clIdentLHS) != 0:
-		mflag = gox.MemberFlagRef
+		mflag = gogen.MemberFlagRef
 	case (flags & clIdentCanAutoCall) != 0:
-		mflag = gox.MemberFlagAutoProperty
+		mflag = gogen.MemberFlagAutoProperty
 	default:
-		mflag = gox.MemberFlagMethodAlias
+		mflag = gogen.MemberFlagMethodAlias
 	}
 	_, err := ctx.cb.Member(name, mflag, v)
 	return err
@@ -258,7 +258,7 @@ func identOrSelectorFlags(inFlags []int) (flags int, cmdNoArgs bool) {
 }
 
 func callCmdNoArgs(ctx *blockCtx, src ast.Node, panicErr bool) (err error) {
-	if gox.IsFunc(ctx.cb.InternalStack().Get(-1).Type) {
+	if gogen.IsFunc(ctx.cb.InternalStack().Get(-1).Type) {
 		if err = ctx.cb.CallWithEx(0, 0, src); err != nil {
 			if panicErr {
 				panic(err)
@@ -471,10 +471,10 @@ func compileFuncAlias(ctx *blockCtx, scope *types.Scope, x *ast.Ident, flags int
 	return false
 }
 
-func pkgRef(at gox.PkgRef, name string) (o types.Object, alias bool) {
+func pkgRef(at gogen.PkgRef, name string) (o types.Object, alias bool) {
 	if c := name[0]; c >= 'a' && c <= 'z' {
 		name = string(rune(c)+('A'-'a')) + name[1:]
-		if v := at.TryRef(name); v != nil && gox.IsFunc(v.Type()) {
+		if v := at.TryRef(name); v != nil && gogen.IsFunc(v.Type()) {
 			return v, true
 		}
 		return
@@ -483,7 +483,7 @@ func pkgRef(at gox.PkgRef, name string) (o types.Object, alias bool) {
 }
 
 // allow pkg.Types to be nil
-func lookupPkgRef(ctx *blockCtx, pkg gox.PkgRef, x *ast.Ident, pkgKind int) (o types.Object, alias bool) {
+func lookupPkgRef(ctx *blockCtx, pkg gogen.PkgRef, x *ast.Ident, pkgKind int) (o types.Object, alias bool) {
 	if pkg.Types != nil {
 		return pkgRef(pkg, x.Name)
 	}
@@ -515,7 +515,7 @@ func lookupPkgRef(ctx *blockCtx, pkg gox.PkgRef, x *ast.Ident, pkgKind int) (o t
 }
 
 // allow at.Types to be nil
-func compilePkgRef(ctx *blockCtx, at gox.PkgRef, x *ast.Ident, flags, pkgKind int) bool {
+func compilePkgRef(ctx *blockCtx, at gogen.PkgRef, x *ast.Ident, flags, pkgKind int) bool {
 	if v, alias := lookupPkgRef(ctx, at, x, pkgKind); v != nil {
 		if (flags & clIdentLHS) != 0 {
 			if rec := ctx.recorder(); rec != nil {
@@ -533,7 +533,7 @@ func identVal(ctx *blockCtx, x *ast.Ident, flags int, v types.Object, alias bool
 	autocall := false
 	if alias {
 		if autocall = (flags & clIdentCanAutoCall) != 0; autocall {
-			if !gox.HasAutoProperty(v.Type()) {
+			if !gogen.HasAutoProperty(v.Type()) {
 				return false
 			}
 		}
@@ -580,7 +580,7 @@ func (p *fnType) init(base int, t *types.Signature) {
 	}
 }
 
-func (p *fnType) initTypeType(t *gox.TypeType) {
+func (p *fnType) initTypeType(t *gogen.TypeType) {
 	param := types.NewParam(0, nil, "", t.Type())
 	p.params, p.typetype = types.NewTuple(param), true
 	p.size = 1
@@ -588,15 +588,15 @@ func (p *fnType) initTypeType(t *gox.TypeType) {
 
 func (p *fnType) load(fnt types.Type) {
 	switch v := fnt.(type) {
-	case *gox.TypeType:
+	case *gogen.TypeType:
 		p.initTypeType(v)
 	case *types.Signature:
-		typ, objs := gox.CheckSigFuncExObjects(v)
+		typ, objs := gogen.CheckSigFuncExObjects(v)
 		switch typ.(type) {
-		case *gox.TyOverloadFunc, *gox.TyOverloadMethod:
+		case *gogen.TyOverloadFunc, *gogen.TyOverloadMethod:
 			p.initFuncs(0, objs)
 			return
-		case *gox.TyTemplateRecvMethod:
+		case *gogen.TyTemplateRecvMethod:
 			p.initFuncs(1, objs)
 			return
 		}
@@ -653,13 +653,13 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) {
 	var stk = ctx.cb.InternalStack()
 	var base = stk.Len()
 	var fnt = stk.Get(-1).Type
-	var flags gox.InstrFlags
+	var flags gogen.InstrFlags
 	var ellipsis = v.Ellipsis != gotoken.NoPos
 	if ellipsis {
-		flags = gox.InstrFlagEllipsis
+		flags = gogen.InstrFlagEllipsis
 	}
 	if (inFlags & clCallWithTwoValue) != 0 {
-		flags |= gox.InstrFlagTwoValue
+		flags |= gogen.InstrFlagTwoValue
 	}
 	fn := &fnType{}
 	fn.load(fnt)
@@ -685,7 +685,7 @@ func toBasicLit(fn *ast.Ident) *ast.BasicLit {
 
 // maybe builtin new/delete: see TestSpxNewObj, TestMayBuiltinDelete
 // maybe Gop_Exec: see TestSpxGopExec
-func builtinOrGopExec(ctx *blockCtx, ifn *ast.Ident, v *ast.CallExpr, flags gox.InstrFlags) error {
+func builtinOrGopExec(ctx *blockCtx, ifn *ast.Ident, v *ast.CallExpr, flags gogen.InstrFlags) error {
 	cb := ctx.cb
 	switch name := ifn.Name; name {
 	case "new", "delete":
@@ -701,7 +701,7 @@ func builtinOrGopExec(ctx *blockCtx, ifn *ast.Ident, v *ast.CallExpr, flags gox.
 	return syscall.ENOENT
 }
 
-func tryGopExec(cb *gox.CodeBuilder, ifn *ast.Ident) bool {
+func tryGopExec(cb *gogen.CodeBuilder, ifn *ast.Ident) bool {
 	if recv := classRecv(cb); recv != nil {
 		cb.InternalStack().PopN(1)
 		if gopMember(cb, recv, "Gop_Exec", ifn) == nil {
@@ -712,14 +712,14 @@ func tryGopExec(cb *gox.CodeBuilder, ifn *ast.Ident) bool {
 	return false
 }
 
-func fnCall(ctx *blockCtx, v *ast.CallExpr, flags gox.InstrFlags, extra int) error {
+func fnCall(ctx *blockCtx, v *ast.CallExpr, flags gogen.InstrFlags, extra int) error {
 	for _, arg := range v.Args {
 		compileExpr(ctx, arg)
 	}
 	return ctx.cb.CallWithEx(len(v.Args)+extra, flags, v)
 }
 
-func compileCallArgs(fn *fnType, ctx *blockCtx, v *ast.CallExpr, ellipsis bool, flags gox.InstrFlags) (err error) {
+func compileCallArgs(fn *fnType, ctx *blockCtx, v *ast.CallExpr, ellipsis bool, flags gogen.InstrFlags) (err error) {
 	for i, arg := range v.Args {
 		switch expr := arg.(type) {
 		case *ast.LambdaExpr:
@@ -840,7 +840,7 @@ func makeLambdaParams(ctx *blockCtx, pos token.Pos, lhs []*ast.Ident, in *types.
 	return types.NewTuple(params...), nil
 }
 
-func makeLambdaResults(pkg *gox.Package, out *types.Tuple) *types.Tuple {
+func makeLambdaResults(pkg *gogen.Package, out *types.Tuple) *types.Tuple {
 	nout := out.Len()
 	if nout == 0 {
 		return nil
@@ -938,7 +938,7 @@ func compileBasicLit(ctx *blockCtx, v *ast.BasicLit) {
 	}
 }
 
-func basicLit(cb *gox.CodeBuilder, v *ast.BasicLit) {
+func basicLit(cb *gogen.CodeBuilder, v *ast.BasicLit) {
 	cb.Val(&goast.BasicLit{Kind: gotoken.Token(v.Kind), Value: v.Value}, v)
 }
 
@@ -946,7 +946,7 @@ const (
 	stringutilPkgPath = "github.com/qiniu/x/stringutil"
 )
 
-func compileStringLitEx(ctx *blockCtx, cb *gox.CodeBuilder, lit *ast.BasicLit) {
+func compileStringLitEx(ctx *blockCtx, cb *gogen.CodeBuilder, lit *ast.BasicLit) {
 	pos := lit.ValuePos + 1
 	quote := lit.Value[:1]
 	parts := lit.Extra.Parts
@@ -971,7 +971,7 @@ func compileStringLitEx(ctx *blockCtx, cb *gox.CodeBuilder, lit *ast.BasicLit) {
 			compileExpr(ctx, v, flags)
 			t := cb.Get(-1).Type
 			if t.Underlying() != types.Typ[types.String] {
-				cb.Member("string", gox.MemberFlagAutoProperty)
+				cb.Member("string", gogen.MemberFlagAutoProperty)
 			}
 			pos = v.End()
 		default:
@@ -1246,7 +1246,7 @@ func compileComprehensionExpr(ctx *blockCtx, v *ast.ComprehensionExpr, twoValue
 	kind := comprehensionKind(v)
 	pkg, cb := ctx.pkg, ctx.cb
 	var results *types.Tuple
-	var ret *gox.Param
+	var ret *gogen.Param
 	if v.Elt == nil {
 		boolean := pkg.NewParam(token.NoPos, "_gop_ok", types.Typ[types.Bool])
 		results = types.NewTuple(boolean)
@@ -1358,7 +1358,7 @@ func compileErrWrapExpr(ctx *blockCtx, v *ast.ErrWrapExpr, inFlags int) {
 	var ret []*types.Var
 	if n > 0 {
 		i, retName := 0, "_gop_ret"
-		ret = make([]*gox.Param, n)
+		ret = make([]*gogen.Param, n)
 		for {
 			ret[i] = pkg.NewAutoParam(retName)
 			i++
diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go
index 5d139dd6..31b2b357 100644
--- a/cl/func_type_and_var.go
+++ b/cl/func_type_and_var.go
@@ -23,9 +23,9 @@ import (
 	"math/big"
 	"strconv"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
 )
 
 // -----------------------------------------------------------------------------
@@ -93,7 +93,7 @@ func toParams(ctx *blockCtx, flds []*ast.Field) (typ *types.Tuple, variadic bool
 	return types.NewTuple(args...), ok
 }
 
-func toParam(ctx *blockCtx, fld *ast.Field, args []*gox.Param) []*gox.Param {
+func toParam(ctx *blockCtx, fld *ast.Field, args []*gogen.Param) []*gogen.Param {
 	typ := toType(ctx, fld.Type)
 	pkg := ctx.pkg
 	if len(fld.Names) == 0 {
@@ -251,7 +251,7 @@ func toIdentType(ctx *blockCtx, ident *ast.Ident) (ret types.Type) {
 		obj = t
 		return t.Type()
 	}
-	if v, _ := lookupPkgRef(ctx, gox.PkgRef{}, ident, objPkgRef); v != nil {
+	if v, _ := lookupPkgRef(ctx, gogen.PkgRef{}, ident, objPkgRef); v != nil {
 		if t, ok := v.(*types.TypeName); ok {
 			obj = t
 			return t.Type()
diff --git a/cl/internal/typesutil/api.go b/cl/internal/typesutil/api.go
index 0699ccfc..12b17e17 100644
--- a/cl/internal/typesutil/api.go
+++ b/cl/internal/typesutil/api.go
@@ -21,7 +21,7 @@ import (
 	"go/types"
 	"unsafe"
 
-	"github.com/goplus/gox"
+	"github.com/goplus/gogen"
 )
 
 // An OperandMode specifies the (addressing) mode of an operand.
@@ -51,7 +51,7 @@ type TypeAndValue struct {
 
 func NewTypeAndValueForType(typ types.Type) (ret types.TypeAndValue) {
 	switch t := typ.(type) {
-	case *gox.TypeType:
+	case *gogen.TypeType:
 		typ = t.Type()
 	}
 	ret.Type = typ
@@ -61,7 +61,7 @@ func NewTypeAndValueForType(typ types.Type) (ret types.TypeAndValue) {
 
 func NewTypeAndValueForValue(typ types.Type, val constant.Value, mode OperandMode) (ret types.TypeAndValue) {
 	switch t := typ.(type) {
-	case *gox.TypeType:
+	case *gogen.TypeType:
 		typ = t.Type()
 	}
 	if val != nil {
diff --git a/cl/outline/outline.go b/cl/outline/outline.go
index 7adab5ac..1ed4d215 100644
--- a/cl/outline/outline.go
+++ b/cl/outline/outline.go
@@ -20,10 +20,10 @@ import (
 	"go/types"
 	"strings"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
 	"github.com/goplus/mod/modfile"
 	"golang.org/x/tools/go/types/typeutil"
 )
@@ -53,7 +53,7 @@ type Config struct {
 
 type Package struct {
 	pkg  *types.Package
-	docs gox.ObjectDocs
+	docs gogen.ObjectDocs
 }
 
 // NewPackage creates a Go/Go+ outline package.
@@ -362,7 +362,7 @@ func (p Var) Doc() string {
 
 type Func struct {
 	*types.Func
-	docs gox.ObjectDocs
+	docs gogen.ObjectDocs
 }
 
 func (p Func) Obj() types.Object {
@@ -523,7 +523,7 @@ func (p Type) CheckNamed(pkg Package) (_ Named, ok bool) {
 
 type Named struct {
 	*types.Named
-	docs gox.ObjectDocs
+	docs gogen.ObjectDocs
 }
 
 func (p Named) Methods() []Func {
diff --git a/cl/recorder.go b/cl/recorder.go
index 8ebe7071..beccc1b9 100644
--- a/cl/recorder.go
+++ b/cl/recorder.go
@@ -19,11 +19,11 @@ package cl
 import (
 	"go/types"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/ast/fromgo"
 	"github.com/goplus/gop/cl/internal/typesutil"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
 )
 
 type goxRecorder struct {
@@ -121,7 +121,7 @@ func (rec *goxRecorder) instantiate(expr ast.Expr, _, typ types.Type) {
 
 func (rec *goxRecorder) recordTypeValue(ctx *blockCtx, expr ast.Expr, mode typesutil.OperandMode) {
 	e := ctx.cb.Get(-1)
-	t, _ := gox.DerefType(e.Type)
+	t, _ := gogen.DerefType(e.Type)
 	rec.Type(expr, typesutil.NewTypeAndValueForValue(t, e.CVal, mode))
 }
 
diff --git a/cl/stmt.go b/cl/stmt.go
index 7d9b1eca..90b784c9 100644
--- a/cl/stmt.go
+++ b/cl/stmt.go
@@ -26,9 +26,9 @@ import (
 	gotoken "go/token"
 	"go/types"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
 )
 
 func fileLineFile(relBaseDir, absFile string) string {
@@ -51,7 +51,7 @@ func commentStmt(ctx *blockCtx, stmt ast.Stmt) {
 	}
 }
 
-func commentStmtEx(cb *gox.CodeBuilder, ctx *pkgCtx, stmt ast.Stmt) {
+func commentStmtEx(cb *gogen.CodeBuilder, ctx *pkgCtx, stmt ast.Stmt) {
 	start := stmt.Pos()
 	if start == token.NoPos {
 		cb.SetComments(nil, false)
@@ -80,7 +80,7 @@ func checkStmtDoc(stmt ast.Stmt) *ast.CommentGroup {
 	return nil
 }
 
-func commentFunc(ctx *blockCtx, fn *gox.Func, decl *ast.FuncDecl) {
+func commentFunc(ctx *blockCtx, fn *gogen.Func, decl *ast.FuncDecl) {
 	start := decl.Name.Pos()
 	if ctx.fileLine && start != token.NoPos {
 		if decl.Doc != nil {
@@ -653,7 +653,7 @@ func compileTypeSwitchStmt(ctx *blockCtx, v *ast.TypeSwitchStmt) {
 		for _, citem := range c.List {
 			compileExpr(ctx, citem)
 			T := cb.Get(-1).Type
-			if tt, ok := T.(*gox.TypeType); ok {
+			if tt, ok := T.(*gogen.TypeType); ok {
 				T = tt.Type()
 			}
 			var haserr bool
@@ -857,7 +857,7 @@ func compileBranchStmt(ctx *blockCtx, v *ast.BranchStmt) {
 	}
 }
 
-func getLabel(ctx *blockCtx, label *ast.Ident) *gox.Label {
+func getLabel(ctx *blockCtx, label *ast.Ident) *gogen.Label {
 	if label != nil {
 		if l, ok := ctx.cb.LookupLabel(label.Name); ok {
 			return l
diff --git a/cmd/gop/main.go b/cmd/gop/main.go
index 16a78dd1..aa552ce3 100644
--- a/cmd/gop/main.go
+++ b/cmd/gop/main.go
@@ -24,6 +24,7 @@ import (
 
 	"github.com/qiniu/x/log"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/cmd/internal/base"
 	"github.com/goplus/gop/cmd/internal/bug"
 	"github.com/goplus/gop/cmd/internal/build"
@@ -42,7 +43,6 @@ import (
 	"github.com/goplus/gop/cmd/internal/test"
 	"github.com/goplus/gop/cmd/internal/version"
 	"github.com/goplus/gop/cmd/internal/watch"
-	"github.com/goplus/gox"
 )
 
 func mainUsage() {
@@ -87,7 +87,7 @@ func main() {
 		help.Help(os.Stderr, args[1:])
 		return
 	}
-	gox.GeneratedHeader = "// Code generated by gop (Go+); DO NOT EDIT.\n\n"
+	gogen.GeneratedHeader = "// Code generated by gop (Go+); DO NOT EDIT.\n\n"
 
 BigCmdLoop:
 	for bigCmd := base.Gop; ; {
diff --git a/cmd/internal/build/build.go b/cmd/internal/build/build.go
index 4879418e..fdb2509b 100644
--- a/cmd/internal/build/build.go
+++ b/cmd/internal/build/build.go
@@ -24,12 +24,12 @@ import (
 	"path/filepath"
 	"reflect"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/cmd/internal/base"
 	"github.com/goplus/gop/x/gocmd"
 	"github.com/goplus/gop/x/gopprojs"
-	"github.com/goplus/gox"
 )
 
 // gop build
@@ -56,7 +56,7 @@ func runCmd(cmd *base.Command, args []string) {
 	}
 
 	if *flagDebug {
-		gox.SetDebug(gox.DbgFlagAll &^ gox.DbgFlagComments)
+		gogen.SetDebug(gogen.DbgFlagAll &^ gogen.DbgFlagComments)
 		cl.SetDebug(cl.DbgFlagAll)
 		cl.SetDisableRecover(true)
 	}
diff --git a/cmd/internal/doc/doc.go b/cmd/internal/doc/doc.go
index c369a2b5..6c755e22 100644
--- a/cmd/internal/doc/doc.go
+++ b/cmd/internal/doc/doc.go
@@ -25,13 +25,13 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/cl/outline"
 	"github.com/goplus/gop/cmd/internal/base"
 	"github.com/goplus/gop/x/gopenv"
 	"github.com/goplus/gop/x/gopprojs"
-	"github.com/goplus/gox"
 )
 
 // -----------------------------------------------------------------------------
@@ -70,7 +70,7 @@ func runCmd(cmd *base.Command, args []string) {
 	}
 
 	if *debug {
-		gox.SetDebug(gox.DbgFlagAll &^ gox.DbgFlagComments)
+		gogen.SetDebug(gogen.DbgFlagAll &^ gogen.DbgFlagComments)
 		cl.SetDebug(cl.DbgFlagAll)
 		cl.SetDisableRecover(true)
 	}
diff --git a/cmd/internal/gengo/go.go b/cmd/internal/gengo/go.go
index 1ec8c305..ac51e1c6 100644
--- a/cmd/internal/gengo/go.go
+++ b/cmd/internal/gengo/go.go
@@ -23,11 +23,11 @@ import (
 	"os"
 	"reflect"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/cmd/internal/base"
 	"github.com/goplus/gop/x/gopprojs"
-	"github.com/goplus/gox"
 	"github.com/qiniu/x/errors"
 )
 
@@ -66,7 +66,7 @@ func runCmd(cmd *base.Command, args []string) {
 	}
 
 	if *flagVerbose {
-		gox.SetDebug(gox.DbgFlagAll &^ gox.DbgFlagComments)
+		gogen.SetDebug(gogen.DbgFlagAll &^ gogen.DbgFlagComments)
 		cl.SetDebug(cl.DbgFlagAll)
 		cl.SetDisableRecover(true)
 	}
diff --git a/cmd/internal/install/install.go b/cmd/internal/install/install.go
index 0c510c2c..b469c1be 100644
--- a/cmd/internal/install/install.go
+++ b/cmd/internal/install/install.go
@@ -23,12 +23,12 @@ import (
 	"os"
 	"reflect"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/cmd/internal/base"
 	"github.com/goplus/gop/x/gocmd"
 	"github.com/goplus/gop/x/gopprojs"
-	"github.com/goplus/gox"
 	"github.com/goplus/mod/modfetch"
 )
 
@@ -66,7 +66,7 @@ func runCmd(cmd *base.Command, args []string) {
 
 	if *flagDebug {
 		modfetch.SetDebug(modfetch.DbgFlagAll)
-		gox.SetDebug(gox.DbgFlagAll &^ gox.DbgFlagComments)
+		gogen.SetDebug(gogen.DbgFlagAll &^ gogen.DbgFlagComments)
 		cl.SetDebug(cl.DbgFlagAll)
 		cl.SetDisableRecover(true)
 	}
diff --git a/cmd/internal/run/run.go b/cmd/internal/run/run.go
index 8adead75..b7d1c57f 100644
--- a/cmd/internal/run/run.go
+++ b/cmd/internal/run/run.go
@@ -22,12 +22,12 @@ import (
 	"os"
 	"reflect"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/cmd/internal/base"
 	"github.com/goplus/gop/x/gocmd"
 	"github.com/goplus/gop/x/gopprojs"
-	"github.com/goplus/gox"
 	"github.com/qiniu/x/log"
 )
 
@@ -68,11 +68,11 @@ func runCmd(cmd *base.Command, args []string) {
 	if *flagQuiet {
 		log.SetOutputLevel(0x7000)
 	} else if *flagDebug {
-		gox.SetDebug(gox.DbgFlagAll &^ gox.DbgFlagComments)
+		gogen.SetDebug(gogen.DbgFlagAll &^ gogen.DbgFlagComments)
 		cl.SetDebug(cl.DbgFlagAll)
 		cl.SetDisableRecover(true)
 	} else if *flagAsm {
-		gox.SetDebug(gox.DbgFlagInstruction)
+		gogen.SetDebug(gogen.DbgFlagInstruction)
 	}
 
 	if *flagProf {
diff --git a/gengo.go b/gengo.go
index df3868e3..336bf21e 100644
--- a/gengo.go
+++ b/gengo.go
@@ -160,7 +160,7 @@ func genGoSingleFile(file string, conf *Config, flags GenFlags) (err error) {
 		return nil
 	}
 	if err := out.WriteFile(autogen); err != nil {
-		return errors.NewWith(err, `out.WriteFile(autogen)`, -2, "(*gox.Package).WriteFile", out, autogen)
+		return errors.NewWith(err, `out.WriteFile(autogen)`, -2, "(*gogen.Package).WriteFile", out, autogen)
 	}
 	return nil
 }
@@ -180,7 +180,7 @@ func genGoIn(dir string, conf *Config, genTestPkg bool, flags GenFlags, gen ...*
 	file := filepath.Join(dir, autoGenFile)
 	err = out.WriteFile(file)
 	if err != nil {
-		return errors.NewWith(err, `out.WriteFile(file)`, -2, "(*gox.Package).WriteFile", out, file)
+		return errors.NewWith(err, `out.WriteFile(file)`, -2, "(*gogen.Package).WriteFile", out, file)
 	}
 	if gen != nil { // say `gop_autogen.go generated`
 		*gen[0] = true
@@ -189,14 +189,14 @@ func genGoIn(dir string, conf *Config, genTestPkg bool, flags GenFlags, gen ...*
 	testFile := filepath.Join(dir, autoGenTestFile)
 	err = out.WriteFile(testFile, testingGoFile)
 	if err != nil && err != syscall.ENOENT {
-		return errors.NewWith(err, `out.WriteFile(testFile, testingGoFile)`, -2, "(*gox.Package).WriteFile", out, testFile, testingGoFile)
+		return errors.NewWith(err, `out.WriteFile(testFile, testingGoFile)`, -2, "(*gogen.Package).WriteFile", out, testFile, testingGoFile)
 	}
 
 	if test != nil {
 		testFile = filepath.Join(dir, autoGen2TestFile)
 		err = test.WriteFile(testFile, testingGoFile)
 		if err != nil {
-			return errors.NewWith(err, `test.WriteFile(testFile, testingGoFile)`, -2, "(*gox.Package).WriteFile", test, testFile, testingGoFile)
+			return errors.NewWith(err, `test.WriteFile(testFile, testingGoFile)`, -2, "(*gogen.Package).WriteFile", test, testFile, testingGoFile)
 		}
 	} else {
 		err = nil
@@ -293,7 +293,7 @@ func GenGoFiles(autogen string, files []string, conf *Config) (outFiles []string
 	}
 	err = out.WriteFile(autogen)
 	if err != nil {
-		err = errors.NewWith(err, `out.WriteFile(autogen)`, -2, "(*gox.Package).WriteFile", out, autogen)
+		err = errors.NewWith(err, `out.WriteFile(autogen)`, -2, "(*gogen.Package).WriteFile", out, autogen)
 	}
 	outFiles = []string{autogen}
 	return
diff --git a/go.mod b/go.mod
index 3e3aa76c..f71d1939 100644
--- a/go.mod
+++ b/go.mod
@@ -4,9 +4,9 @@ go 1.18
 
 require (
 	github.com/fsnotify/fsnotify v1.7.0
-	github.com/goplus/c2go v0.7.24-0.20240221044754-e542e30f9dbc
-	github.com/goplus/gox v1.14.13-0.20240308130321-6ff7f61cfae8
-	github.com/goplus/mod v0.13.9-0.20240305182112-59522d2cc81d
+	github.com/goplus/c2go v0.7.25
+	github.com/goplus/gogen v1.15.0
+	github.com/goplus/mod v0.13.9
 	github.com/qiniu/x v1.13.9
 	golang.org/x/tools v0.19.0
 )
diff --git a/go.sum b/go.sum
index 8c9fa143..5ac4a157 100644
--- a/go.sum
+++ b/go.sum
@@ -4,12 +4,12 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
 github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/goplus/c2go v0.7.24-0.20240221044754-e542e30f9dbc h1:HGH6KoedGQ+DikZ1n9cDkCpMjODHftxbPqEhb7zDz4I=
-github.com/goplus/c2go v0.7.24-0.20240221044754-e542e30f9dbc/go.mod h1:m+2bOIErSOA4sxyrg0deb7RS6cnC3czzo7AaL9IZ+YE=
-github.com/goplus/gox v1.14.13-0.20240308130321-6ff7f61cfae8 h1:8k8q34xFRhvbh7AETX4+pp+BSMmf1Nyt8xa3/as/qZo=
-github.com/goplus/gox v1.14.13-0.20240308130321-6ff7f61cfae8/go.mod h1:Q1x9L9gugS3964fLAsgJWGBw+/5tZFrGgD7Klk8zdJc=
-github.com/goplus/mod v0.13.9-0.20240305182112-59522d2cc81d h1:QwGi092U1kLvSJ38xFnv98vygtOYrpMJmX+S+leQKLc=
-github.com/goplus/mod v0.13.9-0.20240305182112-59522d2cc81d/go.mod h1:MibsLSftGmxaQq78YzUzNviyFwB9RtpMaoscufvEKH4=
+github.com/goplus/c2go v0.7.25 h1:QvQfOwGVGKFYOTLry8i4p9U55jnIOQWeLsnSyFg0hhc=
+github.com/goplus/c2go v0.7.25/go.mod h1:e9oe4jDVhGFMJLEGmPSrVkLuXbLZAEmAu0/uD6fSz5E=
+github.com/goplus/gogen v1.15.0 h1:mQphpjiw/Fka46lEVnDSWwql3s6VF9VGjKc0EohlEYI=
+github.com/goplus/gogen v1.15.0/go.mod h1:92qEzVgv7y8JEFICWG9GvYI5IzfEkxYdsA1DbmnTkqk=
+github.com/goplus/mod v0.13.9 h1:B9zZoHi2AzMltTSOFqZNVjqGlSMlhhNTWwEzVqhTQzg=
+github.com/goplus/mod v0.13.9/go.mod h1:MibsLSftGmxaQq78YzUzNviyFwB9RtpMaoscufvEKH4=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
diff --git a/imp.go b/imp.go
index 95531cbb..5e6f8edf 100644
--- a/imp.go
+++ b/imp.go
@@ -24,7 +24,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/goplus/gox/packages"
+	"github.com/goplus/gogen/packages"
 	"github.com/goplus/mod/env"
 	"github.com/goplus/mod/gopmod"
 	"github.com/goplus/mod/modfetch"
diff --git a/load.go b/load.go
index ea58ce56..bc958bef 100644
--- a/load.go
+++ b/load.go
@@ -24,13 +24,13 @@ import (
 	"path"
 	"strings"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/parser"
 	"github.com/goplus/gop/token"
 	"github.com/goplus/gop/x/c2go"
 	"github.com/goplus/gop/x/gopenv"
-	"github.com/goplus/gox"
 	"github.com/goplus/mod/env"
 	"github.com/goplus/mod/gopmod"
 	"github.com/qiniu/x/errors"
@@ -54,11 +54,11 @@ func IgnoreNotated(err error) bool {
 // ErrorPos returns where the error occurs.
 func ErrorPos(err error) token.Pos {
 	switch v := err.(type) {
-	case *gox.CodeError:
+	case *gogen.CodeError:
 		return v.Pos
-	case *gox.MatchError:
+	case *gogen.MatchError:
 		return v.Pos()
-	case *gox.ImportError:
+	case *gogen.ImportError:
 		return v.Pos
 	}
 	return token.NoPos
@@ -124,7 +124,7 @@ type Config struct {
 	Filter func(fs.FileInfo) bool
 
 	// If not nil, it is used for returning result of checks Go+ dependencies.
-	// see https://pkg.go.dev/github.com/goplus/gox#File.CheckGopDeps
+	// see https://pkg.go.dev/github.com/goplus/gogen#File.CheckGopDeps
 	GopDeps *int
 
 	IgnoreNotatedError bool
@@ -184,7 +184,7 @@ func FilterNoTestFiles(fi fs.FileInfo) bool {
 // -----------------------------------------------------------------------------
 
 // LoadDir loads Go+ packages from a specified directory.
-func LoadDir(dir string, conf *Config, genTestPkg bool, promptGenGo ...bool) (out, test *gox.Package, err error) {
+func LoadDir(dir string, conf *Config, genTestPkg bool, promptGenGo ...bool) (out, test *gogen.Package, err error) {
 	if conf == nil {
 		conf = new(Config)
 	}
@@ -266,7 +266,7 @@ func LoadDir(dir string, conf *Config, genTestPkg bool, promptGenGo ...bool) (ou
 	return
 }
 
-func afterLoad(mod *gopmod.Module, gop *env.Gop, out, test *gox.Package, conf *Config) {
+func afterLoad(mod *gopmod.Module, gop *env.Gop, out, test *gogen.Package, conf *Config) {
 	if mod.Path() == gopMod { // nothing to do for Go+ itself
 		return
 	}
@@ -287,8 +287,8 @@ func afterLoad(mod *gopmod.Module, gop *env.Gop, out, test *gox.Package, conf *C
 	}
 }
 
-func checkGopDeps(pkg *gox.Package) (flags int) {
-	pkg.ForEachFile(func(fname string, file *gox.File) {
+func checkGopDeps(pkg *gogen.Package) (flags int) {
+	pkg.ForEachFile(func(fname string, file *gogen.File) {
 		flags |= file.CheckGopDeps(pkg)
 	})
 	return
@@ -305,7 +305,7 @@ func relativeBaseOf(mod *gopmod.Module) string {
 // -----------------------------------------------------------------------------
 
 // LoadDir loads a Go+ package from specified files.
-func LoadFiles(dir string, files []string, conf *Config) (out *gox.Package, err error) {
+func LoadFiles(dir string, files []string, conf *Config) (out *gogen.Package, err error) {
 	if conf == nil {
 		conf = new(Config)
 	}
diff --git a/scanner/errors.go b/scanner/errors.go
index 6fd5da0b..77deee5c 100644
--- a/scanner/errors.go
+++ b/scanner/errors.go
@@ -22,17 +22,14 @@ import (
 )
 
 // Error is an alias of go/scanner.Error
-//
 type Error = scanner.Error
 
 // ErrorList is an alias of go/scanner.ErrorList
-//
 type ErrorList = scanner.ErrorList
 
 // PrintError is a utility function that prints a list of errors to w,
 // one error per line, if the err parameter is an ErrorList. Otherwise
 // it prints the err string.
-//
 func PrintError(w io.Writer, err error) {
 	scanner.PrintError(w, err)
 }
diff --git a/token/token.go b/token/token.go
index 7b13d64b..1bd7f2a9 100644
--- a/token/token.go
+++ b/token/token.go
@@ -22,7 +22,7 @@ import (
 	"go/token"
 	"strconv"
 
-	xtoken "github.com/goplus/gox/token"
+	xtoken "github.com/goplus/gogen/token"
 )
 
 // Token is the set of lexical tokens of the Go+ programming language.
diff --git a/x/build/build.go b/x/build/build.go
index 10fae033..c5d5eead 100644
--- a/x/build/build.go
+++ b/x/build/build.go
@@ -23,13 +23,13 @@ import (
 	"go/types"
 	"path/filepath"
 
+	"github.com/goplus/gogen"
+	"github.com/goplus/gogen/packages"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/parser"
 	"github.com/goplus/gop/parser/fsx/memfs"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
-	"github.com/goplus/gox/packages"
 	"github.com/goplus/mod/modfile"
 )
 
@@ -60,7 +60,7 @@ func init() {
 
 type Package struct {
 	Fset *token.FileSet
-	Pkg  *gox.Package
+	Pkg  *gogen.Package
 }
 
 func (p *Package) ToSource() ([]byte, error) {
diff --git a/x/typesutil/check.go b/x/typesutil/check.go
index 6ee70a17..3f148446 100644
--- a/x/typesutil/check.go
+++ b/x/typesutil/check.go
@@ -22,12 +22,12 @@ import (
 	"path/filepath"
 	"strings"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/token"
 	"github.com/goplus/gop/x/c2go"
 	"github.com/goplus/gop/x/typesutil/internal/typesutil"
-	"github.com/goplus/gox"
 	"github.com/goplus/mod/gopmod"
 	"github.com/qiniu/x/errors"
 	"github.com/qiniu/x/log"
@@ -186,7 +186,7 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 		// TODO: how to process error?
 		CorrectTypesInfo(scope, objMap, p.gopInfo.Uses)
 		if opts.UpdateGoTypesOverload {
-			gox.InitThisGopPkg(pkgTypes)
+			gogen.InitThisGopPkg(pkgTypes)
 		}
 	}
 	return
@@ -240,17 +240,17 @@ func DeleteObjects(scope *types.Scope, files []*goast.File) objMapT {
 
 func convErr(fset *token.FileSet, e error) (ret types.Error, ok bool) {
 	switch v := e.(type) {
-	case *gox.CodeError:
+	case *gogen.CodeError:
 		ret.Pos, ret.Msg = v.Pos, v.Msg
 		typesutil.SetErrorGo116(&ret, 0, v.Pos, v.Pos)
-	case *gox.MatchError:
+	case *gogen.MatchError:
 		end := token.NoPos
 		if v.Src != nil {
 			ret.Pos, end = v.Src.Pos(), v.Src.End()
 		}
 		ret.Msg = v.Message("")
 		typesutil.SetErrorGo116(&ret, 0, ret.Pos, end)
-	case *gox.ImportError:
+	case *gogen.ImportError:
 		ret.Pos, ret.Msg = v.Pos, v.Err.Error()
 		typesutil.SetErrorGo116(&ret, 0, v.Pos, v.Pos)
 	default:
diff --git a/x/typesutil/gopinfo.go b/x/typesutil/gopinfo.go
index c5c04f13..e2c00d71 100644
--- a/x/typesutil/gopinfo.go
+++ b/x/typesutil/gopinfo.go
@@ -19,9 +19,9 @@ package typesutil
 import (
 	"go/types"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/cl"
-	"github.com/goplus/gox"
 	"github.com/qiniu/x/log"
 )
 
@@ -254,7 +254,7 @@ func (info gopRecorder) Use(id *ast.Ident, obj types.Object) {
 	}
 	if info.Overloads != nil {
 		if sig, ok := obj.Type().(*types.Signature); ok {
-			if ext, objs := gox.CheckSigFuncExObjects(sig); len(objs) > 1 {
+			if ext, objs := gogen.CheckSigFuncExObjects(sig); len(objs) > 1 {
 				if debugVerbose {
 					log.Println("==> Overloads:", id, ext)
 				}


Test patch:
diff --git a/cl/builtin_test.go b/cl/builtin_test.go
index ffa51f46..d8666ce1 100644
--- a/cl/builtin_test.go
+++ b/cl/builtin_test.go
@@ -22,11 +22,11 @@ import (
 	"log"
 	"testing"
 
+	"github.com/goplus/gogen"
+	"github.com/goplus/gogen/cpackages"
+	"github.com/goplus/gogen/packages"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
-	"github.com/goplus/gox/cpackages"
-	"github.com/goplus/gox/packages"
 	"github.com/goplus/mod/modfile"
 )
 
@@ -34,10 +34,10 @@ var (
 	goxConf = getGoxConf()
 )
 
-func getGoxConf() *gox.Config {
+func getGoxConf() *gogen.Config {
 	fset := token.NewFileSet()
 	imp := packages.NewImporter(fset)
-	return &gox.Config{Fset: fset, Importer: imp}
+	return &gogen.Config{Fset: fset, Importer: imp}
 }
 
 func TestCompileLambdaExpr(t *testing.T) {
@@ -47,7 +47,7 @@ func TestCompileLambdaExpr(t *testing.T) {
 	lhs := []*ast.Ident{ast.NewIdent("x")}
 	sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
 	e := compileLambdaExpr(ctx, &ast.LambdaExpr{Lhs: lhs}, sig)
-	if ce := e.(*gox.CodeError); ce.Msg != `too many arguments in lambda expression
+	if ce := e.(*gogen.CodeError); ce.Msg != `too many arguments in lambda expression
 	have (x)
 	want ()` {
 		t.Fatal("compileLambdaExpr:", ce.Msg)
@@ -57,7 +57,7 @@ func TestCompileLambdaExpr(t *testing.T) {
 func TestCompileLambda1(t *testing.T) {
 	defer func() {
 		if e := recover(); e != nil {
-			if ce := e.(*gox.CodeError); ce.Msg != `too many arguments in lambda expression
+			if ce := e.(*gogen.CodeError); ce.Msg != `too many arguments in lambda expression
 	have (x)
 	want ()` {
 				t.Fatal("compileLambda:", ce.Msg)
@@ -75,7 +75,7 @@ func TestCompileLambda1(t *testing.T) {
 func TestCompileLambda2(t *testing.T) {
 	defer func() {
 		if e := recover(); e != nil {
-			if ce := e.(*gox.CodeError); ce.Msg != `too many arguments in lambda expression
+			if ce := e.(*gogen.CodeError); ce.Msg != `too many arguments in lambda expression
 	have (x)
 	want ()` {
 				t.Fatal("compileLambda:", ce.Msg)
@@ -113,7 +113,7 @@ func TestCompileStmt(t *testing.T) {
 }
 
 func TestTryGopExec(t *testing.T) {
-	pkg := gox.NewPackage("", "foo", goxConf)
+	pkg := gogen.NewPackage("", "foo", goxConf)
 	if tryGopExec(pkg.CB(), nil) {
 		t.Fatal("tryGopExec")
 	}
@@ -149,7 +149,7 @@ func TestErrStringLit(t *testing.T) {
 }
 
 func TestErrPreloadFile(t *testing.T) {
-	pkg := gox.NewPackage("", "foo", goxConf)
+	pkg := gogen.NewPackage("", "foo", goxConf)
 	ctx := &blockCtx{pkgCtx: &pkgCtx{}}
 	t.Run("overloadName", func(t *testing.T) {
 		defer func() {
@@ -355,7 +355,7 @@ func TestCompileErrWrapExpr(t *testing.T) {
 			t.Fatal("TestCompileErrWrapExpr failed")
 		}
 	}()
-	pkg := gox.NewPackage("", "foo", goxConf)
+	pkg := gogen.NewPackage("", "foo", goxConf)
 	ctx := &blockCtx{pkg: pkg, cb: pkg.CB()}
 	compileErrWrapExpr(ctx, &ast.ErrWrapExpr{Tok: token.QUESTION}, 0)
 }
@@ -401,7 +401,7 @@ func TestCheckCommandWithoutArgs(t *testing.T) {
 
 func TestClRangeStmt(t *testing.T) {
 	ctx := &blockCtx{
-		cb: &gox.CodeBuilder{},
+		cb: &gogen.CodeBuilder{},
 	}
 	stmt := &ast.RangeStmt{
 		Tok:  token.DEFINE,
@@ -417,7 +417,7 @@ func TestClRangeStmt(t *testing.T) {
 // -----------------------------------------------------------------------------
 
 func TestGetStringConst(t *testing.T) {
-	spx := gox.PkgRef{Types: types.NewPackage("", "foo")}
+	spx := gogen.PkgRef{Types: types.NewPackage("", "foo")}
 	if v := getStringConst(spx, "unknown"); v != "" {
 		t.Fatal("getStringConst:", v)
 	}
@@ -429,7 +429,7 @@ func TestSpxRef(t *testing.T) {
 			t.Fatal("TestSpxRef:", e)
 		}
 	}()
-	pkg := gox.PkgRef{
+	pkg := gogen.PkgRef{
 		Types: types.NewPackage("foo", "foo"),
 	}
 	spxRef(pkg, "bar")
@@ -448,7 +448,7 @@ func isError(e interface{}, msg string) bool {
 }
 
 func TestGmxProject(t *testing.T) {
-	pkg := gox.NewPackage("", "foo", goxConf)
+	pkg := gogen.NewPackage("", "foo", goxConf)
 	ctx := &pkgCtx{
 		projs:   make(map[string]*gmxProject),
 		classes: make(map[*ast.File]*gmxClass),
@@ -578,7 +578,7 @@ func TestErrLoadImport(t *testing.T) {
 
 func TestErrCompileBasicLit(t *testing.T) {
 	testPanic(t, "compileBasicLit: invalid syntax\n", func() {
-		ctx := &blockCtx{cb: new(gox.CodeBuilder)}
+		ctx := &blockCtx{cb: new(gogen.CodeBuilder)}
 		compileBasicLit(ctx, &ast.BasicLit{Kind: token.CSTRING, Value: `\\x`})
 	})
 }
diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go
index 8892aae1..bca91346 100644
--- a/cl/compile_spx_test.go
+++ b/cl/compile_spx_test.go
@@ -105,7 +105,7 @@ func gopSpxTestExConf(t *testing.T, name string, conf *cl.Config, gmx, spxcode,
 		var b bytes.Buffer
 		err = pkg.WriteTo(&b, resultFile)
 		if err != nil {
-			t.Fatal("gox.WriteTo failed:", err)
+			t.Fatal("gogen.WriteTo failed:", err)
 		}
 		result := b.String()
 		if result != expected {
diff --git a/cl/compile_test.go b/cl/compile_test.go
index 7a1f7bdb..7c026ef6 100644
--- a/cl/compile_test.go
+++ b/cl/compile_test.go
@@ -23,13 +23,13 @@ import (
 	"sync"
 	"testing"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/parser"
 	"github.com/goplus/gop/parser/fsx/memfs"
 	"github.com/goplus/gop/scanner"
 	"github.com/goplus/gop/token"
-	"github.com/goplus/gox"
 	"github.com/goplus/mod/env"
 )
 
@@ -44,7 +44,7 @@ var (
 )
 
 func init() {
-	gox.SetDebug(gox.DbgFlagAll)
+	gogen.SetDebug(gogen.DbgFlagAll)
 	cl.SetDebug(cl.DbgFlagAll | cl.FlagNoMarkAutogen)
 	gblFset = token.NewFileSet()
 	imp := gop.NewImporter(nil, &env.Gop{Root: gopRootDir, Version: "1.0"}, gblFset)
@@ -114,7 +114,7 @@ func gopClTestFS(t *testing.T, conf *cl.Config, fs parser.FileSystem, pkgname, e
 	var b bytes.Buffer
 	err = pkg.WriteTo(&b)
 	if err != nil {
-		t.Fatal("gox.WriteTo failed:", err)
+		t.Fatal("gogen.WriteTo failed:", err)
 	}
 	result := b.String()
 	if result != expected {
@@ -1620,7 +1620,7 @@ var x = ng.Bigrat_Init__2(big.NewRat(7, 2))
 }
 
 func TestBigRatAdd(t *testing.T) {
-	gox.SetDebug(gox.DbgFlagAll)
+	gogen.SetDebug(gogen.DbgFlagAll)
 	gopClTest(t, `
 var x = 3 + 1/2r
 var y = x + 100
diff --git a/cl/internal/typesutil/api_test.go b/cl/internal/typesutil/api_test.go
index a726797f..f8b4bc70 100644
--- a/cl/internal/typesutil/api_test.go
+++ b/cl/internal/typesutil/api_test.go
@@ -21,12 +21,12 @@ import (
 	"go/types"
 	"testing"
 
-	"github.com/goplus/gox"
+	"github.com/goplus/gogen"
 )
 
 func TestTypeAndValue(t *testing.T) {
 	tyInt := types.Typ[types.Int]
-	ty := gox.NewTypeType(tyInt)
+	ty := gogen.NewTypeType(tyInt)
 	ret := NewTypeAndValueForType(ty)
 	if !ret.IsType() {
 		t.Fatal("NewTypeAndValueForType: not type?")
diff --git a/cl/run_test.go b/cl/run_test.go
index c117fe98..502497d2 100644
--- a/cl/run_test.go
+++ b/cl/run_test.go
@@ -96,7 +96,7 @@ func genGo(t *testing.T, conf *cl.Config, gopcode string) []byte {
 	var b bytes.Buffer
 	err = pkg.WriteTo(&b)
 	if err != nil {
-		t.Fatal("gox.WriteTo failed:", err)
+		t.Fatal("gogen.WriteTo failed:", err)
 	}
 	return b.Bytes()
 }
diff --git a/cmd/internal/test/test.go b/cmd/internal/test/test.go
index 09efde54..d578ec0e 100644
--- a/cmd/internal/test/test.go
+++ b/cmd/internal/test/test.go
@@ -23,12 +23,12 @@ import (
 	"os"
 	"reflect"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/cmd/internal/base"
 	"github.com/goplus/gop/x/gocmd"
 	"github.com/goplus/gop/x/gopprojs"
-	"github.com/goplus/gox"
 )
 
 // gop test
@@ -64,7 +64,7 @@ func runCmd(cmd *base.Command, args []string) {
 	}
 
 	if *flagDebug {
-		gox.SetDebug(gox.DbgFlagAll &^ gox.DbgFlagComments)
+		gogen.SetDebug(gogen.DbgFlagAll &^ gogen.DbgFlagComments)
 		cl.SetDebug(cl.DbgFlagAll)
 		cl.SetDisableRecover(true)
 	}
diff --git a/printer/printer_test.go b/printer/printer_test.go
index be038741..d38d48bf 100644
--- a/printer/printer_test.go
+++ b/printer/printer_test.go
@@ -83,7 +83,6 @@ func format(src []byte, mode checkMode) ([]byte, error) {
 // TestLineComments, using a simple test case, checks that consecutive line
 // comments are properly terminated with a newline even if the AST position
 // information is incorrect.
-//
 func TestLineComments(t *testing.T) {
 	const src = `// comment 1
 	// comment 2
diff --git a/testdata/_helloc2go/go.mod b/testdata/_helloc2go/go.mod
index 050eb82f..49ca4aeb 100644
--- a/testdata/_helloc2go/go.mod
+++ b/testdata/_helloc2go/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/google/gofuzz v1.0.0 // indirect
 	github.com/goplus/c2go v0.7.15 // indirect
-	github.com/goplus/gox v1.12.0 // indirect
+	github.com/goplus/gogen v1.12.0 // indirect
 	github.com/goplus/mod v0.11.5 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
diff --git a/testdata/_helloc2go/go.sum b/testdata/_helloc2go/go.sum
index 63c018c3..6339eb2c 100644
--- a/testdata/_helloc2go/go.sum
+++ b/testdata/_helloc2go/go.sum
@@ -2,7 +2,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/goplus/c2go v0.7.15/go.mod h1:SKSY0OvbO9JBkHRjyiJz3vz0rHpwPETjNj6AQ/rQZOg=
-github.com/goplus/gox v1.12.0/go.mod h1:Ek4bXv4xzfBiFuHC6yfkzHXrhUHXfrM9QyXtMusdkGo=
+github.com/goplus/gogen v1.12.0/go.mod h1:Ek4bXv4xzfBiFuHC6yfkzHXrhUHXfrM9QyXtMusdkGo=
 github.com/goplus/libc v0.3.15 h1:xfo4Lc66Sf7Dyel+gAT+5fCG0XOB7PxRE4892MH5zgg=
 github.com/goplus/libc v0.3.15/go.mod h1:ExS/KlOepeNJkY10ykY1Qgg6GPql+AItHNNsXuIZwgw=
 github.com/goplus/mod v0.11.5/go.mod h1:NDC5E+XOT8vcJCMjqKhLDJHTHX7lyVN4Vbfi2U7dBhs=
diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go
index f23d03db..cda5e112 100644
--- a/x/typesutil/info_test.go
+++ b/x/typesutil/info_test.go
@@ -15,13 +15,13 @@ import (
 	"testing"
 	"unsafe"
 
+	"github.com/goplus/gogen"
 	"github.com/goplus/gop"
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/format"
 	"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"
@@ -1972,11 +1972,11 @@ func (p *N) Test__1(n int) {
 	if named.NumMethods() == 2 {
 		t.Fatal("found overload method failed")
 	}
-	ext, ok := gox.CheckFuncEx(named.Method(2).Type().(*types.Signature))
+	ext, ok := gogen.CheckFuncEx(named.Method(2).Type().(*types.Signature))
 	if !ok {
 		t.Fatal("checkFuncEx failed")
 	}
-	m, ok := ext.(*gox.TyOverloadMethod)
+	m, ok := ext.(*gogen.TyOverloadMethod)
 	if !ok || len(m.Methods) != 2 {
 		t.Fatal("check TyOverloadMethod failed")
 	}