diff --git a/gnovm/pkg/gnolang/gotypecheck.go b/gnovm/pkg/gnolang/gotypecheck.go index db2891c9c02..346158ba8d4 100644 --- a/gnovm/pkg/gnolang/gotypecheck.go +++ b/gnovm/pkg/gnolang/gotypecheck.go @@ -2,6 +2,7 @@ package gnolang import ( "bytes" + "errors" "go/ast" "go/format" "go/parser" @@ -13,6 +14,7 @@ import ( "github.com/gnolang/gno/gnovm" "go.uber.org/multierr" + "golang.org/x/tools/go/ast/astutil" ) // type checking (using go/types) @@ -140,6 +142,11 @@ func (g *gnoImporter) parseCheckMemPackage(mpkg *gnovm.MemPackage, fmt bool) (*t deleteOldIdents(delFunc, f) } + if err := filterCrossing(f); err != nil { + errs = multierr.Append(errs, err) + continue + } + // enforce formatting if fmt { var buf bytes.Buffer @@ -179,3 +186,34 @@ func deleteOldIdents(idents map[string]func(), f *ast.File) { } } } + +func filterCrossing(f *ast.File) (err error) { + astutil.Apply(f, nil, func(c *astutil.Cursor) bool { + switch n := c.Node().(type) { + case *ast.ExprStmt: + if ce, ok := n.X.(*ast.CallExpr); ok { + if id, ok := ce.Fun.(*ast.Ident); ok && id.Name == "crossing" { + // Validate syntax. + if len(ce.Args) != 0 { + err = errors.New("crossing called with non empty parameters") + } + // Delete statement 'crossing()'. + c.Delete() + } + } + case *ast.CallExpr: + if id, ok := n.Fun.(*ast.Ident); ok && id.Name == "cross" { + // Replace expression 'cross(x)' by 'x'. + var a ast.Node + if len(n.Args) == 1 { + a = n.Args[0] + } else { + err = errors.New("cross called with invalid parameters") + } + c.Replace(a) + } + } + return true + }) + return err +} diff --git a/gnovm/pkg/test/filetest.go b/gnovm/pkg/test/filetest.go index c4d90859d71..bd982bf4211 100644 --- a/gnovm/pkg/test/filetest.go +++ b/gnovm/pkg/test/filetest.go @@ -262,6 +262,12 @@ func (opts *TestOptions) runTest(m *gno.Machine, pkgPath, filename string, conte } orig, tx := m.Store, m.Store.BeginTransaction(nil, nil, nil) m.Store = tx + + // Validate Gno syntax and type check. + if err := gno.TypeCheckMemPackageTest(memPkg, m.Store); err != nil { + return runResult{Error: err.Error()} + } + // Run decls and init functions. m.RunMemPackage(memPkg, true) // Clear store cache and reconstruct machine from committed info diff --git a/gnovm/tests/files/extern/timtadh/data_structures/types/string.gno b/gnovm/tests/files/extern/timtadh/data_structures/types/string.gno index 13f94950dfa..5ccf12fd8a1 100644 --- a/gnovm/tests/files/extern/timtadh/data_structures/types/string.gno +++ b/gnovm/tests/files/extern/timtadh/data_structures/types/string.gno @@ -70,8 +70,8 @@ func (self ByteSlice) Hash() int { func hash(s []byte) int { res := sha256.Sum256(s) - return int(s[0]) | - int(s[1]<<8) | - int(s[2]<<16) | - int(s[3]<<24) + return int(res[0]) | + int(res[1]<<8) | + int(res[2]<<16) | + int(res[3]<<24) }