Repository: goplus/gop
Pull request #2122 (2025-02-24 09:41:41)

cl: main func in normal gox file


Patch:
diff --git a/cl/classfile.go b/cl/classfile.go
index 073f059c..badebbc2 100644
--- a/cl/classfile.go
+++ b/cl/classfile.go
@@ -394,14 +394,12 @@ func gmxProjMain(pkg *gogen.Package, parent *pkgCtx, proj *gmxProject) {
 	})
 }
 
-func gmxMainFunc(pkg *gogen.Package, proj *gmxProject) func() {
-	return func() {
-		if o := pkg.TryRef(proj.gameClass); o != nil {
-			// new(gameClass).Main()
-			new := pkg.Builtin().Ref("new")
-			pkg.NewFunc(nil, "main", nil, nil, false).
-				BodyStart(pkg).Val(new).Val(o).Call(1).MemberVal("Main").Call(0).EndStmt().End()
-		}
+func genMainFunc(pkg *gogen.Package, gameClass string) {
+	if o := pkg.TryRef(gameClass); o != nil {
+		// new(gameClass).Main()
+		new := pkg.Builtin().Ref("new")
+		pkg.NewFunc(nil, "main", nil, nil, false).
+			BodyStart(pkg).Val(new).Val(o).Call(1).MemberVal("Main").Call(0).EndStmt().End()
 	}
 }
 
diff --git a/cl/compile.go b/cl/compile.go
index afe723cc..24e22e87 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -342,6 +342,9 @@ type pkgCtx struct {
 	generics map[string]bool // generic type record
 	idents   []*ast.Ident    // toType ident recored
 	inInst   int             // toType in generic instance
+
+	goxMain      int // normal gox files with main func
+	goxMainClass string
 }
 
 type pkgImp struct {
@@ -595,7 +598,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gogen.Packag
 
 	// genMain = true if it is main package and no main func
 	var genMain bool
-	var gen func()
+	var mainClass string
 	if pkg.Name == "main" {
 		_, hasMain := ctx.syms["main"]
 		genMain = !hasMain
@@ -608,8 +611,12 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gogen.Packag
 	}
 
 	if genMain { // make classfile main func if need
-		if proj != nil && !multi { // only one project file
-			gen = gmxMainFunc(p, proj)
+		if proj != nil {
+			if !multi { // only one project file
+				mainClass = proj.gameClass
+			}
+		} else if ctx.goxMain == 1 {
+			mainClass = ctx.goxMainClass // main func in normal gox file
 		}
 	}
 
@@ -631,8 +638,8 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gogen.Packag
 	}
 	err = ctx.complete()
 
-	if gen != nil { // generate classfile main func
-		gen()
+	if mainClass != "" { // generate classfile main func
+		genMainFunc(p, mainClass)
 	} else if genMain && !conf.NoAutoGenMain { // generate empty main func
 		old, _ := p.SetCurFile(defaultGoFile, false)
 		p.NewFunc(nil, "main", nil, nil, false).BodyStart(p).End()
@@ -726,6 +733,10 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c
 			if classType == "main" {
 				classType = "_main"
 			}
+			if f.ShadowEntry != nil {
+				parent.goxMainClass = classType
+				parent.goxMain++
+			}
 		} else {
 			c = parent.classes[f]
 			classType = c.tname
diff --git a/cmd/chore/gopbuiltingen/builtingen.gop b/cmd/chore/gopbuiltingen/builtingen.gox
similarity index 75%
rename from cmd/chore/gopbuiltingen/builtingen.gop
rename to cmd/chore/gopbuiltingen/builtingen.gox
index 5d5a9b32..7fd051b6 100644
--- a/cmd/chore/gopbuiltingen/builtingen.gop
+++ b/cmd/chore/gopbuiltingen/builtingen.gox
@@ -18,12 +18,12 @@ type builtinTI struct {
 	Methods []builtin
 }
 
-type builtinPkg struct {
+var (
 	Builtins []builtin
 	Types    []*builtinTI
-}
+)
 
-func (p *builtinPkg) initBuiltinTIs(fn gopq.NodeSet) (tistr *builtinTI) {
+func initBuiltinTIs(fn gopq.NodeSet) (tistr *builtinTI) {
 	ti := fn.body.any.assignStmt.rhs(0).x.compositeLit("BuiltinTI")
 	methods := ti.elt("methods").cache
 	for method <- methods {
@@ -40,7 +40,7 @@ func (p *builtinPkg) initBuiltinTIs(fn gopq.NodeSet) (tistr *builtinTI) {
 				aTI.Methods <- builtin{mthd, {"", name}}
 			}
 		}
-		p.Types <- aTI
+		Types <- aTI
 		if len(aTI.Methods) > 10 {
 			tistr = aTI
 		}
@@ -48,7 +48,7 @@ func (p *builtinPkg) initBuiltinTIs(fn gopq.NodeSet) (tistr *builtinTI) {
 	return
 }
 
-func (p *builtinPkg) newBuiltinDefault(fn gopq.NodeSet, tistr *builtinTI) {
+func newBuiltinDefault(fn gopq.NodeSet, tistr *builtinTI) {
 	methods := fn.body.any.exprStmt.x.callExpr("ti.AddMethods").cache
 	for method <- methods {
 		aTI := &builtinTI{}
@@ -64,12 +64,12 @@ func (p *builtinPkg) newBuiltinDefault(fn gopq.NodeSet, tistr *builtinTI) {
 			}
 		}
 		if len(aTI.Methods) > 0 {
-			p.Types <- aTI
+			Types <- aTI
 		}
 	}
 }
 
-func (p *builtinPkg) initBuiltin(fn gopq.NodeSet) {
+func initBuiltin(fn gopq.NodeSet) {
 	stmt := fn.body.any.exprStmt.x.cache
 	item := stmt.callExpr("scope.Insert").arg(0).cache
 	for call <- item.callExpr("gogen.NewOverloadFunc") {
@@ -77,27 +77,25 @@ func (p *builtinPkg) initBuiltin(fn gopq.NodeSet) {
 		ref := call.arg(3).callExpr.one
 		pkg := ref.fun.x.ident!
 		name := ref.arg(0).unquotedString!
-		p.Builtins <- builtin{built, {pkg, name}}
+		Builtins <- builtin{built, {pkg, name}}
 	}
 	for call <- stmt.callExpr("initBuiltinFns") {
 		pkg := call.arg(2).ident!
 		builtins := call.arg(3).unquotedStringElts!
 		for built <- builtins {
-			p.Builtins <- builtin{built, {pkg, built.capitalize}}
+			Builtins <- builtin{built, {pkg, built.capitalize}}
 		}
 	}
 }
 
-var pkg builtinPkg
-
 root := env.GOPROOT()
 fset := token.newFileSet
 
 fns := gopq.fromFile(fset, "${root}/../gogen/builtin.go", nil, parser.ParseComments)!.funcs
-tistr := pkg.initBuiltinTIs(fns.funcDecl("initBuiltinTIs").one)
+tistr := initBuiltinTIs(fns.funcDecl("initBuiltinTIs").one)
 
 fns = gopq.fromFile(fset, "${root}/cl/builtin.go", nil, parser.ParseComments)!.funcs
-pkg.initBuiltin fns.funcDecl("initBuiltin").one
-pkg.newBuiltinDefault fns.funcDecl("newBuiltinDefault").one, tistr
+initBuiltin fns.funcDecl("initBuiltin").one
+newBuiltinDefault fns.funcDecl("newBuiltinDefault").one, tistr
 
-echo string(json.marshalIndent(&pkg, "", "  ")!)
+echo string(json.marshalIndent(this, "", "  ")!)


Test patch:
diff --git a/x/build/build_test.go b/x/build/build_test.go
index 9944747b..ea82939a 100644
--- a/x/build/build_test.go
+++ b/x/build/build_test.go
@@ -119,6 +119,7 @@ func (this *Rect) Main() {
 	fmt.Println("Go+")
 }
 func main() {
+	new(Rect).Main()
 }
 `)
 	gopClTestEx(t, "Rect.gox", `
@@ -146,6 +147,7 @@ func (this *Rect) Main() {
 	fmt.Println("Go+")
 }
 func main() {
+	new(Rect).Main()
 }
 `)
 	gopClTestEx(t, "Rect.gox", `
@@ -173,6 +175,7 @@ func (this *Rect) Main() {
 	fmt.Println("Go+")
 }
 func main() {
+	new(Rect).Main()
 }
 `)
 	gopClTestEx(t, "Rect.gox", `
@@ -198,6 +201,7 @@ func (this *Rect) Main() {
 	fmt.Println("Go+")
 }
 func main() {
+	new(Rect).Main()
 }
 `)
 	gopClTestEx(t, "Rect.gox", `
@@ -223,6 +227,7 @@ func (this *Rect) Main() {
 	fmt.Println("Go+")
 }
 func main() {
+	new(Rect).Main()
 }
 `)
 }