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

add _test.gox (classfile for testing) #1662

Merged
merged 7 commits into from
Jan 24, 2024
Merged
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
19 changes: 9 additions & 10 deletions cl/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,22 @@ import (

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

func initMathBig(pkg *gox.Package, conf *gox.Config, big *gox.PkgRef) {
big.EnsureImported()
func initMathBig(pkg *gox.Package, conf *gox.Config, big gox.PkgRef) {
conf.UntypedBigInt = big.Ref("UntypedBigint").Type().(*types.Named)
conf.UntypedBigRat = big.Ref("UntypedBigrat").Type().(*types.Named)
conf.UntypedBigFloat = big.Ref("UntypedBigfloat").Type().(*types.Named)
}

func initBuiltinFns(builtin *types.Package, scope *types.Scope, pkg *gox.PkgRef, fns []string) {
func initBuiltinFns(builtin *types.Package, scope *types.Scope, pkg gox.PkgRef, fns []string) {
for _, fn := range fns {
fnTitle := string(fn[0]-'a'+'A') + fn[1:]
scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, fn, pkg.Ref(fnTitle)))
}
}

func initBuiltin(pkg *gox.Package, builtin *types.Package, os, fmt, ng, iox, buil *gox.PkgRef) {
func initBuiltin(pkg *gox.Package, builtin *types.Package, os, fmt, ng, iox, buil gox.PkgRef) {
scope := builtin.Scope()
if ng != nil {
if ng.Types != nil {
typs := []string{"bigint", "bigrat", "bigfloat"}
for _, typ := range typs {
name := string(typ[0]-('a'-'A')) + typ[1:]
Expand All @@ -50,26 +49,26 @@ func initBuiltin(pkg *gox.Package, builtin *types.Package, os, fmt, ng, iox, bui
scope.Insert(types.NewTypeName(token.NoPos, builtin, "uint128", ng.Ref("Uint128").Type()))
scope.Insert(types.NewTypeName(token.NoPos, builtin, "int128", ng.Ref("Int128").Type()))
}
if fmt != nil {
if fmt.Types != nil {
scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "echo", fmt.Ref("Println")))
initBuiltinFns(builtin, scope, fmt, []string{
"print", "println", "printf", "errorf",
"fprint", "fprintln", "fprintf",
"sprint", "sprintln", "sprintf",
})
}
if os != nil {
if os.Types != nil {
initBuiltinFns(builtin, scope, os, []string{
"open", "create",
})
}
if iox != nil {
if iox.Types != nil {
initBuiltinFns(builtin, scope, iox, []string{
"lines",
})
scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "blines", iox.Ref("BLines")))
}
if buil != nil {
if buil.Types != nil {
scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "newRange", buil.Ref("NewRange__0")))
}
scope.Insert(types.NewTypeName(token.NoPos, builtin, "any", gox.TyEmptyInterface))
Expand All @@ -84,7 +83,7 @@ func newBuiltinDefault(pkg *gox.Package, conf *gox.Config) *types.Package {
iox := pkg.TryImport("github.com/goplus/gop/builtin/iox")
pkg.TryImport("strconv")
pkg.TryImport("strings")
if ng != nil {
if ng.Types != nil {
initMathBig(pkg, conf, ng)
}
initBuiltin(pkg, builtin, os, fmt, ng, iox, buil)
Expand Down
21 changes: 16 additions & 5 deletions cl/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ func TestErrStringLit(t *testing.T) {
})
}

func TestGmxMainFunc(t *testing.T) {
gmxMainFunc(nil, &pkgCtx{
projs: map[string]*gmxProject{
".a": {}, ".b": {},
},
}, false)
}

func TestNodeInterp(t *testing.T) {
ni := &nodeInterp{}
if v := ni.Caller(&ast.Ident{}); v != "the function call" {
Expand Down Expand Up @@ -206,7 +214,7 @@ func TestClRangeStmt(t *testing.T) {
// -----------------------------------------------------------------------------

func TestGetStringConst(t *testing.T) {
spx := &gox.PkgRef{Types: types.NewPackage("", "foo")}
spx := gox.PkgRef{Types: types.NewPackage("", "foo")}
if v := getStringConst(spx, "unknown"); v != "" {
t.Fatal("getStringConst:", v)
}
Expand All @@ -218,7 +226,7 @@ func TestSpxRef(t *testing.T) {
t.Fatal("TestSpxRef:", e)
}
}()
pkg := &gox.PkgRef{
pkg := gox.PkgRef{
Types: types.NewPackage("foo", "foo"),
}
spxRef(pkg, "bar")
Expand Down Expand Up @@ -277,7 +285,7 @@ func TestGmxProject(t *testing.T) {
}()
func() {
defer func() {
if e := recover(); e != "TODO: multiple project files found" {
if e := recover(); e != "multiple project files found: Game Game\n" {
t.Fatal("TestGmxProject failed:", e)
}
}()
Expand Down Expand Up @@ -319,10 +327,13 @@ func lookupClassErr(ext string) (c *modfile.Project, ok bool) {
}

func TestGetGoFile(t *testing.T) {
if f := genGoFile("a_test.gop", true); f != testingGoFile {
if f := genGoFile("a_test.gop", false); f != testingGoFile {
t.Fatal("TestGetGoFile:", f)
}
if f := genGoFile("a_test.gox", true); f != testingGoFile {
t.Fatal("TestGetGoFile:", f)
}
if f := genGoFile("a_test.gop", false); f != skippingGoFile {
if f := genGoFile("a.gop", false); f != defaultGoFile {
t.Fatal("TestGetGoFile:", f)
}
}
Expand Down
4 changes: 2 additions & 2 deletions cl/c.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ func c2goBase(base string) string {

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

func loadC2goPkg(ctx *blockCtx, realPath string, src *ast.BasicLit) *gox.PkgRef {
func loadC2goPkg(ctx *blockCtx, realPath string, src *ast.BasicLit) (ret gox.PkgRef) {
cpkg, err := ctx.cpkgs.Import(realPath)
if err != nil {
ctx.handleErrorf(src.Pos(),
"%v not found or not a valid C package (c2go.a.pub file not found).\n", realPath)
return nil
return
}
ctx.clookups = append(ctx.clookups, cpkg)
return cpkg.Pkg()
Expand Down
80 changes: 61 additions & 19 deletions cl/classfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ type gmxProject struct {
sptypes []string // <sptype>.spx
scheds []string
schedStmts []goast.Stmt // nil or len(scheds) == 2 (delayload)
pkgImps []*gox.PkgRef
pkgImps []gox.PkgRef
pkgPaths []string
hasScheds bool
gameIsPtr bool
isTest bool
}

func (p *gmxProject) getScheds(cb *gox.CodeBuilder) []goast.Stmt {
Expand Down Expand Up @@ -77,6 +78,10 @@ func ClassNameAndExt(file string) (name, ext string) {
return
}

func isGoxTestFile(ext string) bool {
return strings.HasSuffix(ext, "test.gox")
}

func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Config) *gmxProject {
tname, ext := ClassNameAndExt(file)
gt, ok := conf.LookupClass(ext)
Expand All @@ -89,10 +94,11 @@ func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Co
p = &gmxProject{pkgPaths: pkgPaths}
ctx.projs[gt.Ext] = p

p.pkgImps = make([]*gox.PkgRef, len(pkgPaths))
p.pkgImps = make([]gox.PkgRef, len(pkgPaths))
for i, pkgPath := range pkgPaths {
p.pkgImps[i] = pkg.Import(pkgPath)
}

spx := p.pkgImps[0]
if gt.Class != "" {
p.game, p.gameIsPtr = spxRef(spx, gt.Class)
Expand All @@ -107,12 +113,12 @@ func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Co
}
}
if f.IsProj {
if p.gameClass != "" {
panic("TODO: multiple project files found")
}
if tname == "main" {
tname = gt.Class
}
if p.gameClass != "" {
log.Panicln("multiple project files found:", tname, p.gameClass)
}
p.gameClass = tname
} else {
p.sptypes = append(p.sptypes, tname)
Expand All @@ -124,7 +130,7 @@ func loadClass(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Co
return p
}

func spxLookup(pkgImps []*gox.PkgRef, name string) gox.Ref {
func spxLookup(pkgImps []gox.PkgRef, name string) gox.Ref {
for _, pkg := range pkgImps {
if o := pkg.TryRef(name); o != nil {
return o
Expand All @@ -133,23 +139,23 @@ func spxLookup(pkgImps []*gox.PkgRef, name string) gox.Ref {
panic("spxLookup: symbol not found - " + name)
}

func spxTryRef(spx *gox.PkgRef, typ string) (obj types.Object, isPtr bool) {
func spxTryRef(spx gox.PkgRef, typ string) (obj types.Object, isPtr bool) {
if strings.HasPrefix(typ, "*") {
typ, isPtr = typ[1:], true
}
obj = spx.TryRef(typ)
return
}

func spxRef(spx *gox.PkgRef, typ string) (obj gox.Ref, isPtr bool) {
func spxRef(spx gox.PkgRef, typ string) (obj gox.Ref, isPtr bool) {
obj, isPtr = spxTryRef(spx, typ)
if obj == nil {
panic(spx.Path() + "." + typ + " not found")
}
return
}

func getStringConst(spx *gox.PkgRef, name string) string {
func getStringConst(spx gox.PkgRef, name string) string {
if o := spx.TryRef(name); o != nil {
if c, ok := o.(*types.Const); ok {
return constant.StringVal(c.Val())
Expand Down Expand Up @@ -185,14 +191,50 @@ func setBodyHandler(ctx *blockCtx) {
}
}

func gmxMainFunc(p *gox.Package, ctx *pkgCtx, noAutoGenMain bool) func() {
if len(ctx.projs) == 1 { // only one project file
var proj *gmxProject
for _, v := range ctx.projs {
proj = v
break
const (
casePrefix = "case"
)

func testNameSuffix(testType string) string {
if c := testType[0]; c >= 'A' && c <= 'Z' {
return testType
}
return "_" + testType
}

func gmxTestFunc(pkg *gox.Package, testType string, isProj bool) {
if isProj {
genTestFunc(pkg, "TestMain", testType, "m", "M")
} else {
name := testNameSuffix(testType)
genTestFunc(pkg, "Test"+name, casePrefix+name, "t", "T")
}
}

func genTestFunc(pkg *gox.Package, name, testType, param, paramType string) {
testing := pkg.Import("testing")
objT := testing.Ref(paramType)
paramT := types.NewParam(token.NoPos, pkg.Types, param, types.NewPointer(objT.Type()))
params := types.NewTuple(paramT)

pkg.NewFunc(nil, name, params, nil, false).BodyStart(pkg).
Val(pkg.Builtin().Ref("new")).Val(pkg.Ref(testType)).Call(1).
MemberVal("TestMain").Val(paramT).Call(1).EndStmt().
End()
}

func gmxMainFunc(pkg *gox.Package, ctx *pkgCtx, noAutoGenMain bool) func() {
var proj *gmxProject
for _, v := range ctx.projs {
if v.isTest {
continue
} else if proj != nil {
return nil
}
scope := p.Types.Scope()
proj = v
}
if proj != nil { // only one project file
scope := pkg.Types.Scope()
var o types.Object
if proj.gameClass != "" {
o = scope.Lookup(proj.gameClass)
Expand All @@ -205,10 +247,10 @@ func gmxMainFunc(p *gox.Package, ctx *pkgCtx, noAutoGenMain bool) func() {
if !noAutoGenMain && o != nil {
// new(Game).Main()
// new(Game).Main(workers...)
fn := p.NewFunc(nil, "main", nil, nil, false)
fn := pkg.NewFunc(nil, "main", nil, nil, false)
return func() {
new := p.Builtin().Ref("new")
cb := fn.BodyStart(p).Val(new).Val(o).Call(1).MemberVal("Main")
new := pkg.Builtin().Ref("new")
cb := fn.BodyStart(pkg).Val(new).Val(o).Call(1).MemberVal("Main")

sig := cb.Get(-1).Type.(*types.Signature)
narg := gmxMainNarg(sig)
Expand Down
Loading