Repository: goplus/gop
Pull request #1606 (2024-01-07 18:22:13)

classExt: support _[class].gox or .[class]


Patch:
diff --git a/ast/ast.go b/ast/ast.go
index f0b48953..e174dbb1 100644
--- a/ast/ast.go
+++ b/ast/ast.go
@@ -1135,7 +1135,7 @@ type File struct {
 	Code        []byte
 	ShadowEntry *FuncDecl // no entrypoint func to indicate the module entry point.
 	NoPkgDecl   bool      // no `package xxx` declaration
-	IsClass     bool      // is a classfile
+	IsClass     bool      // is a classfile (including normal .gox file)
 	IsProj      bool      // is a project classfile
 	IsNormalGox bool      // is a normal .gox file
 }
diff --git a/cl/classfile.go b/cl/classfile.go
index 91cbb18f..e3490163 100644
--- a/cl/classfile.go
+++ b/cl/classfile.go
@@ -26,6 +26,7 @@ import (
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/token"
 	"github.com/goplus/gox"
+	"github.com/goplus/mod/modfile"
 )
 
 // -----------------------------------------------------------------------------
@@ -59,8 +60,18 @@ func (p *gmxSettings) getScheds(cb *gox.CodeBuilder) []goast.Stmt {
 	return p.schedStmts
 }
 
+func classNameAndExt(file string) (name, ext string) {
+	fname := filepath.Base(file)
+	name, ext = modfile.SplitFname(fname)
+	if idx := strings.Index(name, "."); idx > 0 {
+		name = name[:idx]
+	}
+	return
+}
+
 func newGmx(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Config) *gmxSettings {
-	ext := ClassFileExt(file)
+	fname := filepath.Base(file)
+	ext := modfile.ClassExt(fname)
 	gt, ok := conf.LookupClass(ext)
 	if !ok {
 		panic("TODO: class not found")
@@ -105,19 +116,11 @@ func spxLookup(pkgImps []*gox.PkgRef, name string) gox.Ref {
 	panic("spxLookup: symbol not found - " + name)
 }
 
-func getDefaultClass(file string) string {
-	_, name := filepath.Split(file)
-	if idx := strings.Index(name, "."); idx > 0 {
-		name = name[:idx]
-	}
-	return name
-}
-
 func spxTryRef(spx *gox.PkgRef, typ string) (obj types.Object, isPtr bool) {
 	if strings.HasPrefix(typ, "*") {
 		typ, isPtr = typ[1:], true
 	}
-	obj = spx.Ref(typ)
+	obj = spx.TryRef(typ)
 	return
 }
 
@@ -176,16 +179,3 @@ func gmxMainFunc(p *gox.Package, ctx *pkgCtx) {
 }
 
 // -----------------------------------------------------------------------------
-
-// ClassFileExt returns the classfile extension
-func ClassFileExt(path string) (ext string) {
-	ext = filepath.Ext(path)
-	if ext == ".gox" {
-		if c := filepath.Ext(path[:len(path)-4]); c != "" {
-			return c
-		}
-	}
-	return
-}
-
-// -----------------------------------------------------------------------------
diff --git a/cl/compile.go b/cl/compile.go
index dbf70914..d1193145 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -386,12 +386,6 @@ func (p *pkgCtx) newCodeErrorf(pos token.Pos, format string, args ...interface{}
 	return &gox.CodeError{Fset: p.nodeInterp, Pos: pos, Msg: fmt.Sprintf(format, args...)}
 }
 
-/*
-func (p *pkgCtx) handleError(pos token.Pos, msg string) {
-	p.handleErr(p.newCodeError(pos, msg))
-}
-*/
-
 func (p *pkgCtx) handleErrorf(pos token.Pos, format string, args ...interface{}) {
 	p.handleErr(p.newCodeErrorf(pos, format, args...))
 }
@@ -701,10 +695,10 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
 			baseType = types.NewPointer(baseType)
 		}
 	case f.IsClass:
-		classType = getDefaultClass(file)
+		var classExt string
+		classType, classExt = classNameAndExt(file)
 		if parent.gmxSettings != nil {
-			ext := ClassFileExt(file)
-			o, ok := parent.sprite[ext]
+			o, ok := parent.sprite[classExt]
 			if ok {
 				baseTypeName, baseType, spxClass = o.Name(), o.Type(), true
 			}
diff --git a/go.mod b/go.mod
index c40d4154..3c45fc97 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
 	github.com/fsnotify/fsnotify v1.7.0
 	github.com/goplus/c2go v0.7.19
 	github.com/goplus/gox v1.13.2
-	github.com/goplus/mod v0.12.0
+	github.com/goplus/mod v0.12.1
 	github.com/qiniu/x v1.13.2
 	golang.org/x/tools v0.16.1
 )
diff --git a/go.sum b/go.sum
index 17af2381..428d4cd3 100644
--- a/go.sum
+++ b/go.sum
@@ -8,8 +8,9 @@ github.com/goplus/c2go v0.7.19 h1:pPMarGN1RiNJFAYlL8oZlM7VNXeg054B4czDgBlck0o=
 github.com/goplus/c2go v0.7.19/go.mod h1:EJgnt9CEHnXuWQc4y78w3DhKErL1aBzgE41NZaEa/3c=
 github.com/goplus/gox v1.13.2 h1:XZZtLcZasRVKOYNzTnJ9E2Cu350TWu9K+CYMJTItkis=
 github.com/goplus/gox v1.13.2/go.mod h1:iIchh0wp8Ye0DOPcFgHc5d0qlMOx8/OJ+DBQfe7hcTs=
-github.com/goplus/mod v0.12.0 h1:b1nPDFRPjksb/BXBUiIA1uVNHc3egRVfYSlShlq3nZE=
 github.com/goplus/mod v0.12.0/go.mod h1:ZtlS9wHOcAVxZ/zq7WLdKVes1HG/8Yn3KNuWZGcpeTs=
+github.com/goplus/mod v0.12.1 h1:4M1py5liQ/bfxPPXcmVbYn3JAjfcDpTANtih5omFI6c=
+github.com/goplus/mod v0.12.1/go.mod h1:ZtlS9wHOcAVxZ/zq7WLdKVes1HG/8Yn3KNuWZGcpeTs=
 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/parser/parser_gop.go b/parser/parser_gop.go
index 0b76a19e..77cf548c 100644
--- a/parser/parser_gop.go
+++ b/parser/parser_gop.go
@@ -132,9 +132,8 @@ func ParseFSDir(fset *token.FileSet, fs FileSystem, dir string, conf Config) (pk
 			continue
 		}
 		fname := d.Name()
-		fnameRmGox := fname
 		ext := path.Ext(fname)
-		var isProj, isClass, isNormalGox, useGoParser, rmGox bool
+		var isProj, isClass, isNormalGox, useGoParser bool
 		switch ext {
 		case ".gop":
 		case ".go":
@@ -143,23 +142,15 @@ func ParseFSDir(fset *token.FileSet, fs FileSystem, dir string, conf Config) (pk
 			}
 			useGoParser = (conf.Mode & ParseGoAsGoPlus) == 0
 		case ".gox":
-			isClass = true
-			t := fname[:len(fname)-4]
-			if c := path.Ext(t); c != "" {
-				fnameRmGox, rmGox = t, true
-			} else {
-				isNormalGox = true
-			}
+			isNormalGox = true
 			fallthrough
 		default:
-			if !isNormalGox {
-				if isProj, isClass = conf.ClassKind(fnameRmGox); !isClass {
-					if !rmGox { // unknown fileKind
-						continue
-					}
-					// not found Go+ class by ext, but is a .gox file
-					isClass, isNormalGox = true, true
-				}
+			if isProj, isClass = conf.ClassKind(fname); isClass {
+				isNormalGox = false
+			} else if isNormalGox { // not found Go+ class by ext, but is a .gox file
+				isClass = true
+			} else { // unknown fileKind
+				continue
 			}
 		}
 		mode := conf.Mode


Test patch:
diff --git a/cl/builtin_test.go b/cl/builtin_test.go
index db438e40..759150d7 100644
--- a/cl/builtin_test.go
+++ b/cl/builtin_test.go
@@ -39,17 +39,10 @@ func getGoxConf() *gox.Config {
 	return &gox.Config{Fset: fset, Importer: imp}
 }
 
-func TestExt(t *testing.T) {
-	cases := [][2]string{
-		{"t.spx.gox", ".spx"},
-		{"t.spx", ".spx"},
-		{"t.gox", ".gox"},
-		{"t.abc", ".abc"},
-	}
-	for _, c := range cases {
-		if ret := ClassFileExt(c[0]); ret != c[1] {
-			t.Fatal("ClassFileExt:", c[0], "expected:", c[1], "got:", ret)
-		}
+func TestClassNameAndExt(t *testing.T) {
+	name, ext := classNameAndExt("/foo/bar.abc_yap.gox")
+	if name != "bar" || ext != "_yap.gox" {
+		t.Fatal("classNameAndExt:", name, ext)
 	}
 }
 
diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go
index e2fbc587..314fdf2e 100644
--- a/cl/compile_spx_test.go
+++ b/cl/compile_spx_test.go
@@ -42,9 +42,9 @@ func lookupClass(ext string) (c *modfile.Project, ok bool) {
 			Works: []*modfile.Class{{Ext: ".t2spx", Class: "Sprite"},
 				{Ext: ".t2spx2", Class: "Sprite2"}},
 			PkgPaths: []string{"github.com/goplus/gop/cl/internal/spx2"}}, true
-	case ".t3spx", ".t3spx2":
+	case "_t3spx.gox", ".t3spx2":
 		return &modfile.Project{
-			Works: []*modfile.Class{{Ext: ".t3spx", Class: "Sprite"},
+			Works: []*modfile.Class{{Ext: "_t3spx.gox", Class: "Sprite"},
 				{Ext: ".t3spx2", Class: "Sprite2"}},
 			PkgPaths: []string{"github.com/goplus/gop/cl/internal/spx2"}}, true
 	}
@@ -460,7 +460,7 @@ type Kai struct {
 
 func (this *Kai) onMsg(msg string) {
 }
-`, "Dog.t3spx", "Kai.t3spx2")
+`, "Dog_t3spx.gox", "Kai.t3spx2")
 }
 
 func TestSpxMainEntry(t *testing.T) {
@@ -589,7 +589,7 @@ func (this *Kai) onMsg(msg string) {
 		this.Say("Hi")
 	}
 }
-`, "Game.tgmx.gox", "Kai.tspx.gox")
+`, "Game.tgmx", "Kai.tspx")
 }
 
 func TestSpxClone(t *testing.T) {