Repository: goplus/gop
Pull request #1648 (2024-01-20 14:28:16)

initBuiltin: echo; call gmxMainFunc only if no main func


Patch:
diff --git a/ast/ast.go b/ast/ast.go
index 3d2836b6..423e60b9 100644
--- a/ast/ast.go
+++ b/ast/ast.go
@@ -1135,7 +1135,7 @@ type File struct {
 }
 
 // There is no entrypoint func to indicate the module entry point.
-func (f *File) NoEntrypoint() bool {
+func (f *File) HasShadowEntry() bool {
 	return f.ShadowEntry != nil
 }
 
diff --git a/cl/builtin.go b/cl/builtin.go
index 3058e246..661635ad 100644
--- a/cl/builtin.go
+++ b/cl/builtin.go
@@ -51,6 +51,7 @@ func initBuiltin(pkg *gox.Package, builtin *types.Package, os, fmt, ng, iox, bui
 		scope.Insert(types.NewTypeName(token.NoPos, builtin, "int128", ng.Ref("Int128").Type()))
 	}
 	if fmt != nil {
+		scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "echo", fmt.Ref("Println")))
 		initBuiltinFns(builtin, scope, fmt, []string{
 			"print", "println", "printf", "errorf",
 			"fprint", "fprintln", "fprintf",
diff --git a/cl/classfile.go b/cl/classfile.go
index 72777289..a9031c23 100644
--- a/cl/classfile.go
+++ b/cl/classfile.go
@@ -164,14 +164,16 @@ func setBodyHandler(ctx *blockCtx) {
 	}
 }
 
-func gmxMainFunc(p *gox.Package, ctx *pkgCtx) {
+func gmxMainFunc(p *gox.Package, ctx *pkgCtx) bool {
 	if o := p.Types.Scope().Lookup(ctx.gameClass); o != nil && hasMethod(o, "MainEntry") {
 		// new(Game).Main()
 		p.NewFunc(nil, "main", nil, nil, false).BodyStart(p).
 			Val(p.Builtin().Ref("new")).Val(o).Call(1).
 			MemberVal("Main").Call(0).EndStmt().
 			End()
+		return true
 	}
+	return false
 }
 
 // -----------------------------------------------------------------------------
diff --git a/cl/compile.go b/cl/compile.go
index 79435918..b112333c 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -561,10 +561,19 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
 		return sfiles[i].path < sfiles[j].path
 	})
 
+	// genMain = true if it is main package and no main func
+	var genMain bool
+	if pkg.Name == "main" {
+		_, hasMain := ctx.syms["main"]
+		genMain = !hasMain
+	}
+
 	for _, f := range sfiles {
 		if f.IsProj {
 			loadFile(ctx, f.File)
-			gmxMainFunc(p, ctx)
+			if genMain { // generate main func if need
+				genMain = !gmxMainFunc(p, ctx)
+			}
 			break
 		}
 	}
@@ -586,12 +595,10 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
 	}
 	err = ctx.complete()
 
-	if !conf.NoAutoGenMain && pkg.Name == "main" {
-		if obj := p.Types.Scope().Lookup("main"); obj == nil {
-			old, _ := p.SetCurFile(defaultGoFile, false)
-			p.NewFunc(nil, "main", nil, nil, false).BodyStart(p).End()
-			p.RestoreCurFile(old)
-		}
+	if genMain && !conf.NoAutoGenMain { // generate empty main func
+		old, _ := p.SetCurFile(defaultGoFile, false)
+		p.NewFunc(nil, "main", nil, nil, false).BodyStart(p).End()
+		p.RestoreCurFile(old)
 	}
 	return
 }
@@ -801,7 +808,7 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
 		}}}
 	}
 	// check class project no MainEntry and auto added
-	if f.IsProj && !conf.NoAutoGenMain && !f.NoEntrypoint() && f.Name.Name == "main" {
+	if f.IsProj && !conf.NoAutoGenMain && !f.HasShadowEntry() && f.Name.Name == "main" {
 		entry := getEntrypoint(f)
 		var hasEntry bool
 		for _, decl := range f.Decls {


Test patch:
diff --git a/cl/compile_test.go b/cl/compile_test.go
index 1c334d97..02e6afe8 100644
--- a/cl/compile_test.go
+++ b/cl/compile_test.go
@@ -123,7 +123,7 @@ func gopClTestFS(t *testing.T, conf *cl.Config, fs parser.FileSystem, pkgname, e
 }
 
 func TestStringLitBasic(t *testing.T) {
-	gopClTest(t, `println "$$"`, `package main
+	gopClTest(t, `echo "$$"`, `package main
 
 import "fmt"
 
diff --git a/parser/parsertest/parsertest.go b/parser/parsertest/parsertest.go
index 89a846d3..081d233a 100644
--- a/parser/parsertest/parsertest.go
+++ b/parser/parsertest/parsertest.go
@@ -111,7 +111,7 @@ func Fprint(w io.Writer, pkg *ast.Package) {
 	for _, fpath := range paths {
 		fmt.Fprintf(w, "\nfile %s\n", filepath.Base(fpath))
 		file := pkg.Files[fpath]
-		if file.NoEntrypoint() {
+		if file.HasShadowEntry() {
 			fmt.Fprintf(w, "noEntrypoint\n")
 		}
 		FprintNode(w, "", file.Decls, "", "  ")