Repository: goplus/gop
Pull request #1282 (2022-06-17 08:58:52)

use github.com/qiniu/x/errors


Patch:
diff --git a/cl/classfile.go b/cl/classfile.go
index b23d1614..a5ed6d96 100644
--- a/cl/classfile.go
+++ b/cl/classfile.go
@@ -60,7 +60,12 @@ func (p *gmxSettings) getScheds(cb *gox.CodeBuilder) []goast.Stmt {
 	return p.schedStmts
 }
 
-func newGmx(pkg *gox.Package, file string, conf *Config) *gmxSettings {
+func newGmx(ctx *pkgCtx, pkg *gox.Package, file string, conf *Config) *gmxSettings {
+	defer func() {
+		if e := recover(); e != nil {
+			ctx.handleRecover(e)
+		}
+	}()
 	_, name := filepath.Split(file)
 	ext := filepath.Ext(name)
 	if idx := strings.Index(name, "."); idx > 0 {
diff --git a/cl/compile.go b/cl/compile.go
index 1b6c8154..8d04bfff 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -18,7 +18,6 @@
 package cl
 
 import (
-	"errors"
 	"fmt"
 	"go/types"
 	"log"
@@ -32,6 +31,7 @@ import (
 	"github.com/goplus/gox"
 	"github.com/goplus/gox/cpackages"
 	"github.com/goplus/mod/modfile"
+	"github.com/qiniu/x/errors"
 )
 
 const (
@@ -58,18 +58,6 @@ func SetDebug(flags int) {
 	debugLookup = (flags & DbgFlagLookup) != 0
 }
 
-type Errors struct {
-	Errs []error
-}
-
-func (p *Errors) Error() string {
-	msgs := make([]string, len(p.Errs))
-	for i, err := range p.Errs {
-		msgs[i] = err.Error()
-	}
-	return strings.Join(msgs, "\n")
-}
-
 // -----------------------------------------------------------------------------
 
 type Class = modfile.Classfile
@@ -254,7 +242,7 @@ type pkgCtx struct {
 	syms  map[string]loader
 	inits []func()
 	tylds []*typeLoader
-	errs  []error
+	errs  errors.List
 }
 
 type blockCtx struct {
@@ -308,10 +296,7 @@ func (p *pkgCtx) loadNamed(at *gox.Package, t *types.Named) {
 }
 
 func (p *pkgCtx) complete() error {
-	if p.errs != nil {
-		return &Errors{Errs: p.errs}
-	}
-	return nil
+	return p.errs.ToError()
 }
 
 func (p *pkgCtx) loadType(name string) {
@@ -394,10 +379,13 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
 	})
 	for file, gmx := range files {
 		if gmx.IsProj {
-			ctx.gmxSettings = newGmx(p, file, conf)
+			ctx.gmxSettings = newGmx(ctx, p, file, conf)
 			break
 		}
 	}
+	if ctx.errs != nil {
+		return nil, ctx.errs.ToError()
+	}
 	for fpath, f := range files {
 		fileLine := !conf.NoFileLine
 		ctx := &blockCtx{
diff --git a/cmd/internal/mod/tidy.go b/cmd/internal/mod/tidy.go
index 615afe46..3157bb47 100644
--- a/cmd/internal/mod/tidy.go
+++ b/cmd/internal/mod/tidy.go
@@ -18,7 +18,6 @@ package mod
 
 import (
 	"fmt"
-	"log"
 	"os"
 	"syscall"
 
@@ -42,8 +41,9 @@ func runTidy(cmd *base.Command, args []string) {
 	if err != nil {
 		if err == syscall.ENOENT {
 			fmt.Fprintln(os.Stderr, "gop.mod not found")
-			os.Exit(1)
+		} else {
+			fmt.Fprintln(os.Stderr, err)
 		}
-		log.Panicln(err)
+		os.Exit(1)
 	}
 }
diff --git a/gengo.go b/gengo.go
index badd25c3..c44d53e5 100644
--- a/gengo.go
+++ b/gengo.go
@@ -27,6 +27,7 @@ import (
 	"github.com/goplus/mod/gopmod"
 	"github.com/goplus/mod/modcache"
 	"github.com/goplus/mod/modfetch"
+	"github.com/qiniu/x/errors"
 )
 
 const (
@@ -48,18 +49,23 @@ func GenGo(dir string, conf *Config, genTestPkg bool) (string, bool, error) {
 
 func genGoDir(dir string, conf *Config, genTestPkg, recursively bool) (err error) {
 	if recursively {
-		return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
+		var list errors.List
+		fn := func(path string, d fs.DirEntry, err error) error {
 			if err == nil && d.IsDir() {
 				if strings.HasPrefix(d.Name(), "_") { // skip _
 					return filepath.SkipDir
 				}
-				err = genGoIn(path, conf, genTestPkg, true)
-				if err != nil {
-					fmt.Fprintln(os.Stderr, err)
+				if e := genGoIn(path, conf, genTestPkg, true); e != nil {
+					list.Add(e)
 				}
 			}
 			return err
-		})
+		}
+		err = filepath.WalkDir(dir, fn)
+		if err != nil {
+			return errors.NewWith(err, `filepath.WalkDir(dir, fn)`, -2, "filepath.WalkDir", dir, fn)
+		}
+		return list.ToError()
 	}
 	return genGoIn(dir, conf, genTestPkg, false)
 }
diff --git a/go.mod b/go.mod
index ffc227d3..a767e1b3 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.16
 
 require (
 	github.com/goplus/c2go v0.7.7
-	github.com/goplus/gox v1.11.11-0.20220608064319-a874b7d2ce42
+	github.com/goplus/gox v1.11.11
 	github.com/goplus/libc v0.3.9
 	github.com/goplus/mod v0.9.12
 	github.com/qiniu/x v1.11.9
diff --git a/go.sum b/go.sum
index 75adacb3..7a14ab7b 100644
--- a/go.sum
+++ b/go.sum
@@ -5,8 +5,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
 github.com/goplus/c2go v0.7.7 h1:/Gw1JmIT8ZxIv9+lQq2XiYKwsseD0mSdhVpWSE3sFpM=
 github.com/goplus/c2go v0.7.7/go.mod h1:PvO1amuwqAPjRs4zIDsrEP+ZC94hl7i6nfUHKXSfRmw=
 github.com/goplus/gox v1.11.10/go.mod h1:gu7fuQF8RmWPZUjd+tEJGuV3m/vOEv0bHrct0x/KatM=
-github.com/goplus/gox v1.11.11-0.20220608064319-a874b7d2ce42 h1:j3B3GhEmewHT/EcaOGFYnsVCifmGF5IZfq1QakUvlHo=
-github.com/goplus/gox v1.11.11-0.20220608064319-a874b7d2ce42/go.mod h1:gu7fuQF8RmWPZUjd+tEJGuV3m/vOEv0bHrct0x/KatM=
+github.com/goplus/gox v1.11.11 h1:CWRKWhVrdMeaGSY2KT4RWkROZLLIpoNRcO8UG9gikdw=
+github.com/goplus/gox v1.11.11/go.mod h1:wRCRSNukie4cDqADF4w0Btc2Gk6V3p3V6hI5+rsVqa8=
 github.com/goplus/libc v0.3.9 h1:1mZngVccEfPlhVa3iVVY7Z0s6Dm4CbO2OiI5x2z46lg=
 github.com/goplus/libc v0.3.9/go.mod h1:ewlp1FCnlqDNJtkjNi7DikLMVfUcLaABJjL4z7QnkNU=
 github.com/goplus/mod v0.9.10/go.mod h1:NHU13OjeNV3ez1f+R9FLJIlIun0KNSuZb0jnmP3N3o8=
@@ -52,8 +52,9 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
 golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
+golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/tidy.go b/tidy.go
index 826ef003..dc11867f 100644
--- a/tidy.go
+++ b/tidy.go
@@ -24,50 +24,52 @@ import (
 	"github.com/goplus/mod/env"
 	"github.com/goplus/mod/gopmod"
 	"github.com/goplus/mod/modfetch"
+	"github.com/qiniu/x/errors"
 )
 
 func Tidy(dir string, gop *env.Gop) (err error) {
-	mod, err := gopmod.Load(dir, mod.GopModOnly)
+	modObj, err := gopmod.Load(dir, mod.GopModOnly)
 	if err != nil {
-		return
+		return errors.NewWith(err, `gopmod.Load(dir, mod.GopModOnly)`, -2, "gopmod.Load", dir, mod.GopModOnly)
 	}
 
-	modRoot := mod.Root()
-	depMods, err := GenDepMods(mod, modRoot, true)
+	modRoot := modObj.Root()
+	depMods, err := GenDepMods(modObj, modRoot, true)
 	if err != nil {
-		return
+		return errors.NewWith(err, `GenDepMods(modObj, modRoot, true)`, -2, "gop.GenDepMods", modObj, modRoot, true)
 	}
 
-	old := mod.DepMods()
+	old := modObj.DepMods()
 	for modPath := range old {
 		if _, ok := depMods[modPath]; !ok { // removed
-			mod.DropRequire(modPath)
+			modObj.DropRequire(modPath)
 		}
 	}
 	for modPath := range depMods {
 		if _, ok := old[modPath]; !ok { // added
 			if newMod, e := modfetch.Get(modPath); e != nil {
-				return e
+				return errors.NewWith(e, `modfetch.Get(modPath)`, -1, "modfetch.Get", modPath)
 			} else {
-				mod.AddRequire(newMod.Path, newMod.Version)
+				modObj.AddRequire(newMod.Path, newMod.Version)
 			}
 		}
 	}
 
-	mod.Cleanup()
-	err = mod.Save()
+	modObj.Cleanup()
+	err = modObj.Save()
 	if err != nil {
-		return
+		return errors.NewWith(err, `modObj.Save()`, -2, "(*gopmod.Module).Save")
 	}
 
-	err = genGoDir(modRoot, &Config{DontUpdateGoMod: true, Gop: gop}, true, true)
+	conf := &Config{DontUpdateGoMod: true, Gop: gop}
+	err = genGoDir(modRoot, conf, true, true)
 	if err != nil {
-		return
+		return errors.NewWith(err, `genGoDir(modRoot, conf, true, true)`, -2, "gop.genGoDir", modRoot, conf, true, true)
 	}
 
-	err = mod.UpdateGoMod(gop, true)
+	err = modObj.UpdateGoMod(gop, true)
 	if err != nil {
-		return
+		return errors.NewWith(err, `modObj.UpdateGoMod(gop, true)`, -2, "(*gopmod.Module).UpdateGoMod", gop, true)
 	}
 
 	cmd := exec.Command("go", "mod", "tidy")
@@ -75,5 +77,9 @@ func Tidy(dir string, gop *env.Gop) (err error) {
 	cmd.Stderr = os.Stderr
 	cmd.Stdin = os.Stdin
 	cmd.Dir = modRoot
-	return cmd.Run()
+	err = cmd.Run()
+	if err != nil {
+		err = errors.NewWith(err, `cmd.Run()`, -2, "(*exec.Cmd).Run")
+	}
+	return
 }


Test patch:
diff --git a/cl/builtin_test.go b/cl/builtin_test.go
index 9d64a164..61a230a4 100644
--- a/cl/builtin_test.go
+++ b/cl/builtin_test.go
@@ -99,7 +99,7 @@ func TestCanAutoCall(t *testing.T) {
 
 func TestGmxSettings(t *testing.T) {
 	pkg := gox.NewPackage("", "foo", goxConf)
-	gmx := newGmx(pkg, "main.t2gmx", &Config{
+	gmx := newGmx(nil, pkg, "main.t2gmx", &Config{
 		LookupClass: lookupClass,
 	})
 	scheds := gmx.getScheds(pkg.CB())
@@ -110,6 +110,16 @@ func TestGmxSettings(t *testing.T) {
 	if gmx.getScheds(nil) != nil {
 		t.Fatal("TestGmxSettings failed: hasScheds?")
 	}
+	_, err := NewPackage("", &ast.Package{Files: map[string]*ast.File{
+		"main.t2gmx": {
+			IsProj: true,
+		},
+	}}, &Config{
+		LookupClass: lookupClassErr,
+	})
+	if e := err.Error(); e != `github.com/goplus/gop/cl/internal/libc.Gop_game not found` {
+		t.Fatal("newGmx:", e)
+	}
 }
 
 func TestSpxLookup(t *testing.T) {
@@ -131,6 +141,16 @@ func lookupClass(ext string) (c *gopmod.Class, ok bool) {
 	return
 }
 
+func lookupClassErr(ext string) (c *gopmod.Class, ok bool) {
+	switch ext {
+	case ".t2gmx", ".t2spx":
+		return &gopmod.Class{
+			ProjExt: ".t2gmx", WorkExt: ".t2spx",
+			PkgPaths: []string{"github.com/goplus/gop/cl/internal/libc"}}, true
+	}
+	return
+}
+
 func TestGetGoFile(t *testing.T) {
 	if f := getGoFile("a_test.gop", true); f != testingGoFile {
 		t.Fatal("TestGetGoFile:", f)