Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] gop go -multi-files: option generate multi files #2005

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions cl/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,13 +550,18 @@ func lookupClassErr(ext string) (c *modfile.Project, ok bool) {
}

func TestGetGoFile(t *testing.T) {
if f := genGoFile("a_test.gop", false); f != testingGoFile {
ctx := &pkgCtx{}
if f := ctx.genGoFile("a_test.gop", false); f != testingGoFile {
t.Fatal("TestGetGoFile:", f)
}
if f := genGoFile("a_test.gox", true); f != testingGoFile {
if f := ctx.genGoFile("a_test.gox", true); f != testingGoFile {
t.Fatal("TestGetGoFile:", f)
}
if f := genGoFile("a.gop", false); f != defaultGoFile {
if f := ctx.genGoFile("a.gop", false); f != defaultGoFile {
t.Fatal("TestGetGoFile:", f)
}
ctx.multiFiles = true
if f := ctx.genGoFile("a.gop", false); f != "a.gop" {
t.Fatal("TestGetGoFile:", f)
}
}
Expand Down
15 changes: 9 additions & 6 deletions cl/classfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type gmxProject struct {
gameIsPtr bool
isTest bool
hasMain_ bool
file string
}

func (p *gmxProject) hasMain() bool {
Expand Down Expand Up @@ -319,14 +320,14 @@ func gmxProjMain(pkg *gogen.Package, parent *pkgCtx, proj *gmxProject) {
classType = base.Name()
proj.gameClass = classType
}

goFile := parent.genGoFile(proj.file, false)
ld := getTypeLoader(parent, parent.syms, token.NoPos, proj.gameClass)
if ld.typ == nil {
ld.typ = func() {
if debugLoad {
log.Println("==> Load > NewType", classType)
}
old, _ := pkg.SetCurFile(defaultGoFile, true)
old, _ := pkg.SetCurFile(goFile, true)
defer pkg.RestoreCurFile(old)

baseType := base.Type()
Expand All @@ -342,7 +343,7 @@ func gmxProjMain(pkg *gogen.Package, parent *pkgCtx, proj *gmxProject) {
if debugLoad {
log.Println("==> Load > InitType", classType)
}
old, _ := pkg.SetCurFile(defaultGoFile, true)
old, _ := pkg.SetCurFile(goFile, true)
defer pkg.RestoreCurFile(old)

decl.InitType(pkg, types.NewStruct(flds, nil))
Expand All @@ -351,7 +352,7 @@ func gmxProjMain(pkg *gogen.Package, parent *pkgCtx, proj *gmxProject) {
}
}
ld.methods = append(ld.methods, func() {
old, _ := pkg.SetCurFile(defaultGoFile, true)
old, _ := pkg.SetCurFile(goFile, true)
defer pkg.RestoreCurFile(old)
doInitType(ld)

Expand All @@ -360,7 +361,7 @@ func gmxProjMain(pkg *gogen.Package, parent *pkgCtx, proj *gmxProject) {
fn := pkg.NewFunc(recv, "Main", nil, nil, false)

parent.inits = append(parent.inits, func() {
old, _ := pkg.SetCurFile(defaultGoFile, true)
old, _ := pkg.SetCurFile(goFile, true)
defer pkg.RestoreCurFile(old)

cb := fn.BodyStart(pkg).Typ(base.Type()).MemberVal("Main")
Expand Down Expand Up @@ -389,9 +390,11 @@ func gmxProjMain(pkg *gogen.Package, parent *pkgCtx, proj *gmxProject) {
})
}

func gmxMainFunc(pkg *gogen.Package, proj *gmxProject) func() {
func gmxMainFunc(pkg *gogen.Package, ctx *pkgCtx, proj *gmxProject) func() {
return func() {
if o := pkg.TryRef(proj.gameClass); o != nil {
old, _ := pkg.SetCurFile(ctx.genGoFile(proj.file, false), true)
defer pkg.RestoreCurFile(old)
// new(gameClass).Main()
new := pkg.Builtin().Ref("new")
pkg.NewFunc(nil, "main", nil, nil, false).
Expand Down
18 changes: 14 additions & 4 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ type Config struct {

// Outline = true means to skip compiling function bodies.
Outline bool

// MultiFiles = true means generate multi files.
MultiFiles bool
}

type nodeInterp struct {
Expand Down Expand Up @@ -342,6 +345,8 @@ type pkgCtx struct {
generics map[string]bool // generic type record
idents []*ast.Ident // toType ident recored
inInst int // toType in generic instance

multiFiles bool // generate multi files
}

type pkgImp struct {
Expand Down Expand Up @@ -501,6 +506,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gogen.Packag
overpos: make(map[string]token.Pos),
syms: make(map[string]loader),
generics: make(map[string]bool),
multiFiles: conf.MultiFiles,
}
confGox := &gogen.Config{
Types: conf.Types,
Expand Down Expand Up @@ -609,7 +615,7 @@ 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)
gen = gmxMainFunc(p, ctx, proj)
}
}

Expand All @@ -634,7 +640,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gogen.Packag
if gen != nil { // generate classfile main func
gen()
} else if genMain && !conf.NoAutoGenMain { // generate empty main func
old, _ := p.SetCurFile(defaultGoFile, false)
old, _ := p.SetCurFile(ctx.genGoFile("", false), false)
p.NewFunc(nil, "main", nil, nil, false).BodyStart(p).End()
p.RestoreCurFile(old)
}
Expand Down Expand Up @@ -702,10 +708,13 @@ func loadFile(ctx *pkgCtx, f *ast.File) {
//
// *_test.gop
// *test.gox
func genGoFile(file string, goxTestFile bool) string {
func (ctx *pkgCtx) genGoFile(file string, goxTestFile bool) string {
if goxTestFile || strings.HasSuffix(file, "_test.gop") {
return testingGoFile
}
if ctx.multiFiles {
return file
}
return defaultGoFile
}

Expand Down Expand Up @@ -744,14 +753,15 @@ func preloadGopFile(p *gogen.Package, ctx *blockCtx, file string, f *ast.File, c
if proj.gameIsPtr {
baseType = types.NewPointer(baseType)
}
proj.file = file
} else {
o := proj.sprite[c.ext]
ctx.baseClass = o
baseTypeName, baseType, spxClass = o.Name(), o.Type(), true
}
}
}
goFile := genGoFile(file, goxTestFile)
goFile := ctx.genGoFile(file, goxTestFile)
if classType != "" {
if debugLoad {
log.Println("==> Preload type", classType)
Expand Down
3 changes: 2 additions & 1 deletion cmd/internal/clean/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
)

const (
autoGenFilePrefix = "gop_autogen_"
autoGenFileSuffix = "_autogen.go"
autoGenTestFile = "gop_autogen_test.go"
autoGen2TestFile = "gop_autogen2_test.go"
Expand All @@ -53,7 +54,7 @@ func cleanAGFiles(dir string, execAct bool) {
}
continue
}
if strings.HasSuffix(fname, autoGenFileSuffix) {
if strings.HasSuffix(fname, autoGenFileSuffix) || strings.HasPrefix(fname, autoGenFilePrefix) {
file := filepath.Join(dir, fname)
fmt.Printf("Cleaning %s ...\n", file)
if execAct {
Expand Down
4 changes: 4 additions & 0 deletions cmd/internal/gengo/go.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ var (
flagSingleMode = flag.Bool("s", false, "run in single file mode for package")
flagIgnoreNotatedErr = flag.Bool(
"ignore-notated-error", false, "ignore notated errors, only available together with -t (check mode)")
flagMultiFiles = flag.Bool("multi-files", false, "genarate multi files for package")
)

func init() {
Expand Down Expand Up @@ -87,6 +88,9 @@ func runCmd(cmd *base.Command, args []string) {
if *flagSingleMode {
flags |= gop.GenFlagSingleFile
}
if *flagMultiFiles {
flags |= gop.GenFlagMultiFiles
}
for _, proj := range projs {
switch v := proj.(type) {
case *gopprojs.DirProj:
Expand Down
44 changes: 39 additions & 5 deletions gengo.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"strings"
"syscall"

"github.com/goplus/gogen"
"github.com/goplus/mod/gopmod"
"github.com/goplus/mod/modcache"
"github.com/goplus/mod/modfetch"
Expand All @@ -35,13 +36,15 @@ const (
autoGenFile = "gop_autogen.go"
autoGenTestFile = "gop_autogen_test.go"
autoGen2TestFile = "gop_autogen2_test.go"
autoGenPrefix = "gop_autogen_"
)

type GenFlags int

const (
GenFlagCheckOnly GenFlags = 1 << iota
GenFlagSingleFile
GenFlagMultiFiles
GenFlagPrintError
GenFlagPrompt
)
Expand Down Expand Up @@ -166,7 +169,7 @@ func genGoSingleFile(file string, conf *Config, flags GenFlags) (err error) {
}

func genGoIn(dir string, conf *Config, genTestPkg bool, flags GenFlags, gen ...*bool) (err error) {
out, test, err := LoadDir(dir, conf, genTestPkg, (flags&GenFlagPrompt) != 0)
out, test, err := LoadDir(dir, conf, genTestPkg, (flags&GenFlagPrompt) != 0, (flags&GenFlagMultiFiles) != 0)
if err != nil {
if NotFound(err) { // no Go+ source files
return nil
Expand All @@ -177,10 +180,18 @@ func genGoIn(dir string, conf *Config, genTestPkg bool, flags GenFlags, gen ...*
return nil
}
os.MkdirAll(dir, 0755)
file := filepath.Join(dir, autoGenFile)
err = out.WriteFile(file)
if err != nil {
return errors.NewWith(err, `out.WriteFile(file)`, -2, "(*gogen.Package).WriteFile", out, file)

if flags&GenFlagMultiFiles != 0 {
err = writeMultiFiles(out, dir)
if err != nil {
return errors.NewWith(err, `writeMultiFiles(out, dir)`, -2, "(*gogen.Package).WriteFile", out, dir)
}
} else {
file := filepath.Join(dir, autoGenFile)
err = out.WriteFile(file)
if err != nil {
return errors.NewWith(err, `out.WriteFile(file)`, -2, "(*gogen.Package).WriteFile", out, file)
}
}
if gen != nil { // say `gop_autogen.go generated`
*gen[0] = true
Expand All @@ -204,6 +215,29 @@ func genGoIn(dir string, conf *Config, genTestPkg bool, flags GenFlags, gen ...*
return
}

func writeMultiFiles(pkg *gogen.Package, dir string) error {
names := make(map[string]string)
pkg.ForEachFile(func(fname string, file *gogen.File) {
if fname == "" {
names[fname] = autoGenFile
} else {
_, name := filepath.Split(fname)
name = name[:len(name)-len(filepath.Ext(name))]
if strings.HasSuffix(name, "_test") {
return
}
names[fname] = autoGenPrefix + name + ".go"
}
})
for fname, file := range names {
err := pkg.WriteFile(filepath.Join(dir, file), fname)
if err != nil {
return err
}
}
return nil
}

// -----------------------------------------------------------------------------

const (
Expand Down
3 changes: 3 additions & 0 deletions load.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ func LoadDir(dir string, conf *Config, genTestPkg bool, promptGenGo ...bool) (ou
Importer: imp,
LookupClass: mod.LookupClass,
}
if len(promptGenGo) > 1 && promptGenGo[1] {
clConf.MultiFiles = true
}

for name, pkg := range pkgs {
if strings.HasSuffix(name, "_test") {
Expand Down