Skip to content

Commit

Permalink
Merge pull request #1794 from xushiwei/t
Browse files Browse the repository at this point in the history
classfile: Main(...), Classfname()
  • Loading branch information
xushiwei committed Mar 8, 2024
2 parents 4ef9bfb + acf0a7d commit 2fc73ae
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 73 deletions.
10 changes: 7 additions & 3 deletions cl/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,12 @@ func TestMarkAutogen(t *testing.T) {
}

func TestClassNameAndExt(t *testing.T) {
name, ext := ClassNameAndExt("/foo/bar.abc_yap.gox")
if name != "bar" || ext != "_yap.gox" {
name, clsfile, ext := ClassNameAndExt("/foo/bar.abc_yap.gox")
if name != "bar_abc" || clsfile != "bar.abc" || ext != "_yap.gox" {
t.Fatal("classNameAndExt:", name, ext)
}
name, clsfile, ext = ClassNameAndExt("/foo/get-bar_:id.yap")
if name != "get_bar_id" || clsfile != "get-bar_:id" || ext != ".yap" {
t.Fatal("classNameAndExt:", name, ext)
}
}
Expand Down Expand Up @@ -447,7 +451,7 @@ func TestGmxProject(t *testing.T) {
pkg := gox.NewPackage("", "foo", goxConf)
ctx := &pkgCtx{
projs: make(map[string]*gmxProject),
classes: make(map[*ast.File]gmxClass),
classes: make(map[*ast.File]*gmxClass),
}
gmx := loadClass(ctx, pkg, "main.t2gmx", &ast.File{IsProj: true}, &Config{
LookupClass: lookupClass,
Expand Down
48 changes: 36 additions & 12 deletions cl/classfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ import (
// -----------------------------------------------------------------------------

type gmxClass struct {
tname string // class type
ext string
proj *gmxProject
tname string // class type
clsfile string
ext string
proj *gmxProject
}

type gmxProject struct {
Expand Down Expand Up @@ -70,11 +71,12 @@ func (p *gmxProject) getScheds(cb *gox.CodeBuilder) []goast.Stmt {
return p.schedStmts
}

func ClassNameAndExt(file string) (name, ext string) {
func ClassNameAndExt(file string) (name, clsfile, ext string) {
fname := filepath.Base(file)
name, ext = modfile.SplitFname(fname)
if idx := strings.Index(name, "."); idx > 0 {
name = name[:idx]
clsfile, ext = modfile.SplitFname(fname)
name = clsfile
if strings.ContainsAny(name, ":-.") {
name = strings.NewReplacer(":", "", "-", "_", ".", "_").Replace(name)
}
return
}
Expand All @@ -84,7 +86,7 @@ func isGoxTestFile(ext string) bool {
}

func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Config) *gmxProject {
tname, ext := ClassNameAndExt(file)
tname, clsfile, ext := ClassNameAndExt(file)
gt, ok := conf.LookupClass(ext)
if !ok {
panic("TODO: class not found")
Expand Down Expand Up @@ -138,7 +140,7 @@ func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Co
} else {
p.sptypes = append(p.sptypes, tname)
}
ctx.classes[f] = gmxClass{tname, ext, p}
ctx.classes[f] = &gmxClass{tname, clsfile, ext, p}
if debugLoad {
log.Println("==> InitClass", tname, "isProj:", f.IsProj)
}
Expand Down Expand Up @@ -298,16 +300,38 @@ func gmxMainNarg(sig *types.Signature) int {
}

func hasMethod(o types.Object, name string) bool {
return findMethod(o, name) != nil
}

func findMethod(o types.Object, name string) *types.Func {
if obj, ok := o.(*types.TypeName); ok {
if t, ok := obj.Type().(*types.Named); ok {
for i, n := 0, t.NumMethods(); i < n; i++ {
if t.Method(i).Name() == name {
return true
f := t.Method(i)
if f.Name() == name {
return f
}
}
}
}
return false
return nil
}

func makeMainSig(recv *types.Var, f *types.Func) *types.Signature {
const (
paramNameTempl = "_gop_arg0"
)
sig := f.Type().(*types.Signature)
in := sig.Params()
nin := in.Len()
pkg := recv.Pkg()
params := make([]*types.Var, nin)
paramName := []byte(paramNameTempl)
for i := 0; i < nin; i++ {
paramName[len(paramNameTempl)-1] = byte('0' + i)
params[i] = types.NewParam(token.NoPos, pkg, string(paramName), in.At(i).Type())
}
return types.NewSignatureType(recv, nil, nil, types.NewTuple(params...), nil, false)
}

// -----------------------------------------------------------------------------
79 changes: 66 additions & 13 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func doInitMethods(ld *typeLoader) {
type pkgCtx struct {
*nodeInterp
projs map[string]*gmxProject // .gmx => project
classes map[*ast.File]gmxClass
classes map[*ast.File]*gmxClass
fset *token.FileSet
cpkgs *cpackages.Importer
syms map[string]loader
Expand Down Expand Up @@ -369,9 +369,12 @@ type blockCtx struct {
tlookup *typeParamLookup
c2goBase string // default is `github.com/goplus/`
relBaseDir string
classRecv *ast.FieldList // available when gmxSettings != nil
fileScope *types.Scope // only valid when isGopFile
rec *goxRecorder

classRecv *ast.FieldList // available when isClass
baseClass types.Object // available when isClass

fileScope *types.Scope // available when isGopFile
rec *goxRecorder

fileLine bool
isClass bool
Expand Down Expand Up @@ -488,7 +491,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
fset: fset,
nodeInterp: interp,
projs: make(map[string]*gmxProject),
classes: make(map[*ast.File]gmxClass),
classes: make(map[*ast.File]*gmxClass),
syms: make(map[string]loader),
generics: make(map[string]bool),
}
Expand Down Expand Up @@ -715,6 +718,7 @@ func genGoFile(file string, goxTestFile bool) string {

func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, conf *Config) {
var proj *gmxProject
var c *gmxClass
var classType string
var testType string
var baseTypeName string
Expand All @@ -724,12 +728,12 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
var parent = ctx.pkgCtx
if f.IsClass {
if f.IsNormalGox {
classType, _ = ClassNameAndExt(file)
classType, _, _ = ClassNameAndExt(file)
if classType == "main" {
classType = "_main"
}
} else {
c := parent.classes[f]
c = parent.classes[f]
classType = c.tname
proj, ctx.proj = c.proj, c.proj
ctx.autoimps = proj.autoimps
Expand All @@ -742,12 +746,14 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
}
if f.IsProj {
o := proj.game
ctx.baseClass = o
baseTypeName, baseType = o.Name(), o.Type()
if proj.gameIsPtr {
baseType = types.NewPointer(baseType)
}
} else {
o := proj.sprite[c.ext]
ctx.baseClass = o
baseTypeName, baseType, spxClass = o.Name(), o.Type(), true
}
}
Expand Down Expand Up @@ -846,6 +852,31 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
X: &ast.Ident{Name: classType},
},
}}}
// func Classfname() string
if spxClass {
f.Decls = append(f.Decls, &ast.FuncDecl{
Name: &ast.Ident{
Name: "Classfname",
},
Type: &ast.FuncType{
Params: &ast.FieldList{},
Results: &ast.FieldList{
List: []*ast.Field{
{Type: &ast.Ident{Name: "string"}},
},
},
},
Body: &ast.BlockStmt{
List: []ast.Stmt{
&ast.ReturnStmt{
Results: []ast.Expr{
&ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(c.clsfile)},
},
},
},
},
})
}
}
if d := f.ShadowEntry; d != nil {
d.Name.Name = getEntrypoint(f)
Expand Down Expand Up @@ -1215,8 +1246,17 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
log.Printf("==> Load method %v.%s\n", recv.Type(), name)
}
}
pkg := ctx.pkg
if d.Operator {
var pkg = ctx.pkg
var sigBase *types.Signature
if d.Shadow {
if recv != nil {
if base := ctx.baseClass; base != nil {
if f := findMethod(base, name); f != nil {
sigBase = makeMainSig(recv, f)
}
}
}
} else if d.Operator {
if recv != nil { // binary op
if v, ok := binaryGopNames[name]; ok {
name = v
Expand All @@ -1232,7 +1272,10 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
}
}
}
sig := toFuncType(ctx, d.Type, recv, d)
sig := sigBase
if sig == nil {
sig = toFuncType(ctx, d.Type, recv, d)
}
fn, err := pkg.NewFuncWith(d.Name.Pos(), name, sig, func() token.Pos {
return d.Recv.List[0].Type.Pos()
})
Expand All @@ -1253,11 +1296,11 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
file := pkg.CurFile()
ctx.inits = append(ctx.inits, func() { // interface issue: #795
old := pkg.RestoreCurFile(file)
loadFuncBody(ctx, fn, body, d)
loadFuncBody(ctx, fn, body, sigBase, d)
pkg.RestoreCurFile(old)
})
} else {
loadFuncBody(ctx, fn, body, d)
loadFuncBody(ctx, fn, body, nil, d)
}
}
}
Expand Down Expand Up @@ -1316,8 +1359,18 @@ var unaryGopNames = map[string]string{
"<-": "Gop_Recv",
}

func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, src ast.Node) {
func loadFuncBody(ctx *blockCtx, fn *gox.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(...)
cb.VarVal("this").MemberVal(ctx.baseClass.Name()).MemberVal(fn.Name())
params := sigBase.Params()
n := params.Len()
for i := 0; i < n; i++ {
cb.Val(params.At(i))
}
cb.Call(n).EndStmt()
}
compileStmts(ctx, body.List)
if rec := ctx.recorder(); rec != nil {
switch fn := src.(type) {
Expand Down
Loading

0 comments on commit 2fc73ae

Please sign in to comment.