Skip to content

Commit

Permalink
Merge pull request #1741 from xushiwei/t
Browse files Browse the repository at this point in the history
compileExpr: tryGopExec (see TestSpxGopExec)
  • Loading branch information
xushiwei authored Feb 14, 2024
2 parents cb85048 + b2e69de commit e3e161a
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 127 deletions.
94 changes: 87 additions & 7 deletions cl/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package cl
import (
"errors"
"go/types"
"log"
"testing"

"github.com/goplus/gop/ast"
Expand All @@ -39,6 +40,85 @@ func getGoxConf() *gox.Config {
return &gox.Config{Fset: fset, Importer: imp}
}

func TestCompileLambdaExpr(t *testing.T) {
ctx := &blockCtx{
pkgCtx: &pkgCtx{},
}
lhs := []*ast.Ident{ast.NewIdent("x")}
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
e := compileLambdaExpr(ctx, &ast.LambdaExpr{Lhs: lhs}, sig)
if ce := e.(*gox.CodeError); ce.Msg != `too many arguments in lambda expression
have (x)
want ()` {
t.Fatal("compileLambdaExpr:", ce.Msg)
}
}

func TestCompileLambda1(t *testing.T) {
defer func() {
if e := recover(); e != nil {
if ce := e.(*gox.CodeError); ce.Msg != `too many arguments in lambda expression
have (x)
want ()` {
t.Fatal("compileLambda:", ce.Msg)
}
}
}()
ctx := &blockCtx{
pkgCtx: &pkgCtx{},
}
lhs := []*ast.Ident{ast.NewIdent("x")}
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
compileLambda(ctx, &ast.LambdaExpr{Lhs: lhs}, sig)
}

func TestCompileLambda2(t *testing.T) {
defer func() {
if e := recover(); e != nil {
if ce := e.(*gox.CodeError); ce.Msg != `too many arguments in lambda expression
have (x)
want ()` {
t.Fatal("compileLambda:", ce.Msg)
}
}
}()
ctx := &blockCtx{
pkgCtx: &pkgCtx{},
}
lhs := []*ast.Ident{ast.NewIdent("x")}
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
compileLambda(ctx, &ast.LambdaExpr2{Lhs: lhs}, sig)
}

func TestCompileExpr(t *testing.T) {
defer func() {
if e := recover(); e != "compileExpr failed: unknown - *ast.Ellipsis\n" {
t.Fatal("compileExpr:", e)
}
}()
compileExpr(nil, &ast.Ellipsis{})
}

func TestCompileStmt(t *testing.T) {
old := enableRecover
defer func() {
enableRecover = old
if e := recover(); e != "compileStmt failed: unknown - *ast.BadStmt\n" {
t.Fatal("compileStmt:", e)
}
}()
enableRecover = false
ctx := &blockCtx{}
compileStmt(ctx, &ast.BadStmt{})
}

func TestTryGopExec(t *testing.T) {
pkg := gox.NewPackage("", "foo", goxConf)
if tryGopExec(pkg.CB(), nil) {
t.Fatal("tryGopExec")
}
}

func TestCompileFuncAlias(t *testing.T) {
ctx := &blockCtx{
pkgCtx: &pkgCtx{
Expand Down Expand Up @@ -185,6 +265,12 @@ func TestNodeInterp(t *testing.T) {
if v := ni.Caller(&ast.Ident{}); v != "the function call" {
t.Fatal("TestNodeInterp:", v)
}
defer func() {
if e := recover(); e == nil {
log.Fatal("TestNodeInterp: no error")
}
}()
ni.Caller(&ast.CallExpr{})
}

func TestMarkAutogen(t *testing.T) {
Expand Down Expand Up @@ -293,16 +379,10 @@ func TestGetTypeName(t *testing.T) {

func TestHandleRecover(t *testing.T) {
var ctx pkgCtx
ctx.handleRecover("hello")
ctx.handleRecover("hello", nil)
if !(len(ctx.errs) == 1 && ctx.errs[0].Error() == "hello") {
t.Fatal("TestHandleRecover failed:", ctx.errs)
}
defer func() {
if e := recover(); e == nil {
t.Fatal("TestHandleRecover failed: no error?")
}
}()
ctx.handleRecover(100)
}

func TestCheckCommandWithoutArgs(t *testing.T) {
Expand Down
27 changes: 18 additions & 9 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ func (p *pkgCtx) loadSymbol(name string) bool {
if enableRecover {
defer func() {
if e := recover(); e != nil {
p.handleRecover(e)
p.handleRecover(e, nil)
}
}()
}
Expand All @@ -443,16 +443,22 @@ func (p *pkgCtx) loadSymbol(name string) bool {
return false
}

func (p *pkgCtx) handleRecover(e interface{}) {
func (p *pkgCtx) handleRecover(e interface{}, src ast.Node) {
err := p.recoverErr(e, src)
p.handleErr(err)
}

func (p *pkgCtx) recoverErr(e interface{}, src ast.Node) error {
err, ok := e.(error)
if !ok {
if msg, ok := e.(string); ok {
err = errors.New(msg)
if src != nil {
text := p.LoadExpr(src)
err = p.newCodeErrorf(src.Pos(), "compile `%v`: %v", text, e)
} else {
panic(e)
err = fmt.Errorf("%v", e)
}
}
p.handleErr(err)
return err
}

const (
Expand Down Expand Up @@ -502,7 +508,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
if enableRecover {
defer func() {
if e := recover(); e != nil {
ctx.handleRecover(e)
ctx.handleRecover(e, nil)
err = ctx.errs.ToError()
}
}()
Expand Down Expand Up @@ -1315,7 +1321,7 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) {
if enableRecover {
defer func() {
if e := recover(); e != nil {
ctx.handleRecover(e)
ctx.handleRecover(e, spec)
}
}()
}
Expand Down Expand Up @@ -1431,7 +1437,10 @@ func loadVars(ctx *blockCtx, v *ast.ValueSpec, doc *ast.CommentGroup, global boo
switch e := val.(type) {
case *ast.LambdaExpr, *ast.LambdaExpr2:
if len(v.Values) == 1 {
sig := checkLambdaFuncType(ctx, e, typ, clLambaAssign, v.Names[0])
sig, err := checkLambdaFuncType(ctx, e, typ, clLambaAssign, v.Names[0])
if err != nil {
panic(err)
}
compileLambda(ctx, e, sig)
} else {
panic(ctx.newCodeErrorf(e.Pos(), "lambda unsupport multiple assignment"))
Expand Down
4 changes: 4 additions & 0 deletions cl/compile_spx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ func (this *index) onInit() {
func TestSpxGopExec(t *testing.T) {
gopSpxTest(t, `
vim "a.txt"
vim
ls 10
capout => { ls }
capout => { ls "-l" }
`, ``, `package main
Expand All @@ -272,6 +274,8 @@ type index struct {
func (this *index) MainEntry() {
this.Gop_Exec("vim", "a.txt")
this.Gop_Exec("vim")
this.Ls(10)
this.Capout(func() {
this.Gop_Exec("ls")
})
Expand Down
24 changes: 23 additions & 1 deletion cl/error_msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,28 @@ func codeErrorTestAst(t *testing.T, pkgname, filename, msg, src string) {
}
}

func TestErrVargCommand(t *testing.T) {
codeErrorTest(t, `bar.gop:5:1: not enough arguments in call to Ls
have ()
want (int)`, `
func Ls(int) {
}
ls
`)
codeErrorTest(t, `bar.gop:8:1: not enough arguments in call to f.Ls
have ()
want (int)`, `
type foo int
func (f foo) Ls(int) {
}
var f foo
f.ls
`)
}

func TestErrUnsafe(t *testing.T) {
codeErrorTest(t, `bar.gop:2:9: undefined: Sizeof`, `
println Sizeof(0)
Expand Down Expand Up @@ -990,7 +1012,7 @@ a := uint128(b)
}

func TestErrCompileFunc(t *testing.T) {
codeErrorTest(t, `bar.gop:2:1: compile func printf("%+v\n", int32) error: unreachable`, `
codeErrorTest(t, "bar.gop:2:1: compile `printf(\"%+v\\n\", int32)`: unreachable", `
printf("%+v\n", int32)
`)
}
Expand Down
Loading

0 comments on commit e3e161a

Please sign in to comment.