Repository: goplus/gop
Pull request #1745 (2024-02-14 14:46:12)

NewDefaultConf: add (noTestFile bool) param


Patch:
diff --git a/cmd/internal/build/build.go b/cmd/internal/build/build.go
index fdee3a44..4879418e 100644
--- a/cmd/internal/build/build.go
+++ b/cmd/internal/build/build.go
@@ -74,7 +74,7 @@ func runCmd(cmd *base.Command, args []string) {
 		log.Panicln("too many arguments:", args)
 	}
 
-	conf, err := gop.NewDefaultConf(".")
+	conf, err := gop.NewDefaultConf(".", true)
 	if err != nil {
 		log.Panicln("gop.NewDefaultConf:", err)
 	}
diff --git a/cmd/internal/gengo/go.go b/cmd/internal/gengo/go.go
index be9fa033..1ec8c305 100644
--- a/cmd/internal/gengo/go.go
+++ b/cmd/internal/gengo/go.go
@@ -71,7 +71,7 @@ func runCmd(cmd *base.Command, args []string) {
 		cl.SetDisableRecover(true)
 	}
 
-	conf, err := gop.NewDefaultConf(".")
+	conf, err := gop.NewDefaultConf(".", false)
 	if err != nil {
 		log.Panicln("gop.NewDefaultConf:", err)
 	}
diff --git a/cmd/internal/install/install.go b/cmd/internal/install/install.go
index f7962a7b..0c510c2c 100644
--- a/cmd/internal/install/install.go
+++ b/cmd/internal/install/install.go
@@ -71,7 +71,7 @@ func runCmd(cmd *base.Command, args []string) {
 		cl.SetDisableRecover(true)
 	}
 
-	conf, err := gop.NewDefaultConf(".")
+	conf, err := gop.NewDefaultConf(".", true)
 	if err != nil {
 		log.Panicln("gop.NewDefaultConf:", err)
 	}
diff --git a/cmd/internal/run/run.go b/cmd/internal/run/run.go
index e2a8b004..48714ba7 100644
--- a/cmd/internal/run/run.go
+++ b/cmd/internal/run/run.go
@@ -80,7 +80,7 @@ func runCmd(cmd *base.Command, args []string) {
 	}
 
 	noChdir := *flagNoChdir
-	conf, err := gop.NewDefaultConf(".")
+	conf, err := gop.NewDefaultConf(".", true)
 	if err != nil {
 		log.Panicln("gop.NewDefaultConf:", err)
 	}
diff --git a/load.go b/load.go
index 214a14ee..f14f90aa 100644
--- a/load.go
+++ b/load.go
@@ -21,6 +21,7 @@ import (
 	"go/types"
 	"io/fs"
 	"os"
+	"path"
 	"strings"
 
 	"github.com/goplus/gop/ast"
@@ -126,7 +127,8 @@ type Config struct {
 	DontUpdateGoMod    bool
 }
 
-func NewDefaultConf(dir string) (conf *Config, err error) {
+// NewDefaultConf creates a dfault configuration for common cases.
+func NewDefaultConf(dir string, noTestFile bool) (conf *Config, err error) {
 	mod, err := LoadMod(dir)
 	if err != nil {
 		return
@@ -134,12 +136,17 @@ func NewDefaultConf(dir string) (conf *Config, err error) {
 	gop := gopenv.Get()
 	fset := token.NewFileSet()
 	imp := NewImporter(mod, gop, fset)
-	return &Config{Gop: gop, Fset: fset, Mod: mod, Importer: imp}, nil
+	conf = &Config{Gop: gop, Fset: fset, Mod: mod, Importer: imp}
+	if noTestFile {
+		conf.Filter = FilterNoTestFiles
+	}
+	return
 }
 
+// LoadMod loads a Go+ module from a specified directory.
 func LoadMod(dir string) (mod *gopmod.Module, err error) {
 	mod, err = gopmod.Load(dir)
-	if err != nil && !NotFound(err) {
+	if err != nil && !gopmod.IsNotFound(err) {
 		err = errors.NewWith(err, `gopmod.Load(dir, 0)`, -2, "gopmod.Load", dir, 0)
 		return
 	}
@@ -153,6 +160,23 @@ func LoadMod(dir string) (mod *gopmod.Module, err error) {
 	return gopmod.Default, nil
 }
 
+// FilterNoTestFiles filters to skip all testing files.
+func FilterNoTestFiles(fi fs.FileInfo) bool {
+	fname := fi.Name()
+	suffix := ""
+	switch path.Ext(fname) {
+	case ".gox":
+		suffix = "test.gox"
+	case ".gop":
+		suffix = "_test.gop"
+	case ".go":
+		suffix = "_test.go"
+	default:
+		return true
+	}
+	return !strings.HasSuffix(fname, suffix)
+}
+
 func hasModfile(mod *gopmod.Module) bool {
 	f := mod.File
 	return f != nil && f.Syntax != nil
@@ -160,6 +184,7 @@ func hasModfile(mod *gopmod.Module) bool {
 
 // -----------------------------------------------------------------------------
 
+// LoadDir loads Go+ packages from a specified directory.
 func LoadDir(dir string, conf *Config, genTestPkg bool, promptGenGo ...bool) (out, test *gox.Package, err error) {
 	if conf == nil {
 		conf = new(Config)
@@ -271,6 +296,7 @@ func relativeBaseOf(mod *gopmod.Module) string {
 
 // -----------------------------------------------------------------------------
 
+// LoadDir loads a Go+ package from specified files.
 func LoadFiles(dir string, files []string, conf *Config) (out *gox.Package, err error) {
 	if conf == nil {
 		conf = new(Config)
diff --git a/parser/parser_gop.go b/parser/parser_gop.go
index 54013c62..16a15971 100644
--- a/parser/parser_gop.go
+++ b/parser/parser_gop.go
@@ -229,7 +229,7 @@ func ParseFSEntry(fset *token.FileSet, fs FileSystem, filename string, src inter
 
 func filter(d fs.DirEntry, fn func(fs.FileInfo) bool) bool {
 	fi, err := d.Info()
-	return err != nil || fn(fi)
+	return err == nil && fn(fi)
 }
 
 func reqPkg(pkgs map[string]*ast.Package, name string) *ast.Package {
diff --git a/x/typesutil/check.go b/x/typesutil/check.go
index 03a3a5ef..28cc2c29 100644
--- a/x/typesutil/check.go
+++ b/x/typesutil/check.go
@@ -148,7 +148,7 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 		LookupPub:      c2go.LookupPub(mod),
 		LookupClass:    mod.LookupClass,
 		Importer:       conf.Importer,
-		Recorder:       gopRecorder{p.gopInfo},
+		Recorder:       NewRecorder(p.gopInfo),
 		NoFileLine:     true,
 		NoAutoGenMain:  true,
 		NoSkipConstant: true,
@@ -169,12 +169,14 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 			log.Println("typesutil.Check err:", err)
 			log.SingleStack()
 		}
+		// don't return even if err != nil
 	}
 	if len(files) > 0 {
 		scope := pkgTypes.Scope()
 		objMap := DeleteObjects(scope, files)
 		checker := types.NewChecker(conf, fset, pkgTypes, p.goInfo)
 		err = checker.Files(files)
+		// TODO: how to process error?
 		CorrectTypesInfo(scope, objMap, p.gopInfo.Uses)
 	}
 	return
diff --git a/x/typesutil/gopinfo.go b/x/typesutil/gopinfo.go
index e1594d39..39f67b38 100644
--- a/x/typesutil/gopinfo.go
+++ b/x/typesutil/gopinfo.go
@@ -20,6 +20,7 @@ import (
 	"go/types"
 
 	"github.com/goplus/gop/ast"
+	"github.com/goplus/gop/cl"
 	"github.com/goplus/gox"
 	"github.com/qiniu/x/log"
 )
@@ -168,6 +169,11 @@ type gopRecorder struct {
 	*Info
 }
 
+// NewRecorder creates a new recorder for cl.NewPackage.
+func NewRecorder(info *Info) cl.Recorder {
+	return gopRecorder{info}
+}
+
 // Type maps expressions to their types, and for constant
 // expressions, also their values. Invalid expressions are
 // omitted.


Test patch:
diff --git a/cmd/internal/test/test.go b/cmd/internal/test/test.go
index a9d119ae..09efde54 100644
--- a/cmd/internal/test/test.go
+++ b/cmd/internal/test/test.go
@@ -69,7 +69,7 @@ func runCmd(cmd *base.Command, args []string) {
 		cl.SetDisableRecover(true)
 	}
 
-	conf, err := gop.NewDefaultConf(".")
+	conf, err := gop.NewDefaultConf(".", false)
 	if err != nil {
 		log.Panicln("gop.NewDefaultConf:", err)
 	}
diff --git a/parser/parser_test.go b/parser/parser_test.go
index b0dd4b7e..742b3646 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -27,12 +27,31 @@ import (
 
 // -----------------------------------------------------------------------------
 
+type fileInfo struct {
+	*fsx.FileInfo
+}
+
+func (p fileInfo) Info() (fs.FileInfo, error) {
+	return nil, fs.ErrNotExist
+}
+
 func TestFilter(t *testing.T) {
 	d := fsx.NewFileInfo("foo.go", 10)
 	if filter(d, func(fi fs.FileInfo) bool {
 		return false
 	}) {
-		t.Fatal("TestFilter failed")
+		t.Fatal("TestFilter: true?")
+	}
+	if !filter(d, func(fi fs.FileInfo) bool {
+		return true
+	}) {
+		t.Fatal("TestFilter: false?")
+	}
+	d2 := fileInfo{d}
+	if filter(d2, func(fi fs.FileInfo) bool {
+		return true
+	}) {
+		t.Fatal("TestFilter: true?")
 	}
 }