aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Shaposhnikov <k.shaposhnikov@gmail.com>2016-06-27 17:13:15 +0800
committerIan Lance Taylor <iant@golang.org>2016-06-28 22:09:00 +0000
commit85a4f44745859ecdd71c034171d40263651f8594 (patch)
treeede9b4b7655ef1be37411cf5b19ae9deb47855b8
parent733aefd06e5cf708637308a4ad7a048aa97db5cd (diff)
downloadgo-85a4f44745859ecdd71c034171d40263651f8594.tar.gz
go-85a4f44745859ecdd71c034171d40263651f8594.zip
cmd/vet: make checking example names in _test packages more robust
Prior to this change package "foo" had to be installed in order to check example names in "foo_test" package. However by the time "foo_test" package is checked a parsed "foo" package has been already constructed. Use it to check example names. Also change TestDivergentPackagesExamples test to pass directory of the package to the vet tool as it is the most common way to invoke it. This requires changes to errchk to add support for grabbing source files from a directory. Fixes #16189 Change-Id: Ief103d07b024822282b86c24250835cc591793e8 Reviewed-on: https://go-review.googlesource.com/24488 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/cmd/vet/main.go22
-rw-r--r--src/cmd/vet/testdata/divergent/buf_test.go12
-rw-r--r--src/cmd/vet/tests.go31
-rw-r--r--src/cmd/vet/vet_test.go2
-rwxr-xr-xtest/errchk11
5 files changed, 49 insertions, 29 deletions
diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go
index 8212a14f03..4f3cca8f6d 100644
--- a/src/cmd/vet/main.go
+++ b/src/cmd/vet/main.go
@@ -182,6 +182,9 @@ type File struct {
file *ast.File
b bytes.Buffer // for use by methods
+ // Parsed package "foo" when checking package "foo_test"
+ basePkg *Package
+
// The objects that are receivers of a "String() string" method.
// This is used by the recursiveStringer method in print.go.
stringers map[*ast.Object]bool
@@ -238,7 +241,7 @@ func main() {
}
os.Exit(exitCode)
}
- if !doPackage(".", flag.Args()) {
+ if doPackage(".", flag.Args(), nil) == nil {
warnf("no files checked")
}
os.Exit(exitCode)
@@ -278,12 +281,12 @@ func doPackageDir(directory string) {
names = append(names, pkg.TestGoFiles...) // These are also in the "foo" package.
names = append(names, pkg.SFiles...)
prefixDirectory(directory, names)
- doPackage(directory, names)
+ basePkg := doPackage(directory, names, nil)
// Is there also a "foo_test" package? If so, do that one as well.
if len(pkg.XTestGoFiles) > 0 {
names = pkg.XTestGoFiles
prefixDirectory(directory, names)
- doPackage(directory, names)
+ doPackage(directory, names, basePkg)
}
}
@@ -299,8 +302,8 @@ type Package struct {
}
// doPackage analyzes the single package constructed from the named files.
-// It returns whether any files were checked.
-func doPackage(directory string, names []string) bool {
+// It returns the parsed Package or nil if none of the files have been checked.
+func doPackage(directory string, names []string, basePkg *Package) *Package {
var files []*File
var astFiles []*ast.File
fs := token.NewFileSet()
@@ -309,7 +312,7 @@ func doPackage(directory string, names []string) bool {
if err != nil {
// Warn but continue to next package.
warnf("%s: %s", name, err)
- return false
+ return nil
}
checkBuildTag(name, data)
var parsedFile *ast.File
@@ -317,14 +320,14 @@ func doPackage(directory string, names []string) bool {
parsedFile, err = parser.ParseFile(fs, name, data, 0)
if err != nil {
warnf("%s: %s", name, err)
- return false
+ return nil
}
astFiles = append(astFiles, parsedFile)
}
files = append(files, &File{fset: fs, content: data, name: name, file: parsedFile})
}
if len(astFiles) == 0 {
- return false
+ return nil
}
pkg := new(Package)
pkg.path = astFiles[0].Name.Name
@@ -346,13 +349,14 @@ func doPackage(directory string, names []string) bool {
}
for _, file := range files {
file.pkg = pkg
+ file.basePkg = basePkg
file.checkers = chk
if file.file != nil {
file.walkFile(file.name, file.file)
}
}
asmCheck(pkg)
- return true
+ return pkg
}
func visit(path string, f os.FileInfo, err error) error {
diff --git a/src/cmd/vet/testdata/divergent/buf_test.go b/src/cmd/vet/testdata/divergent/buf_test.go
index 6b9cba3f01..b75d55eaf4 100644
--- a/src/cmd/vet/testdata/divergent/buf_test.go
+++ b/src/cmd/vet/testdata/divergent/buf_test.go
@@ -4,11 +4,11 @@ package buf_test
func Example() {} // OK because is package-level.
-func Example_suffix() // OK because refers to suffix annotation.
+func Example_suffix() {} // OK because refers to suffix annotation.
-func Example_BadSuffix() // ERROR "Example_BadSuffix has malformed example suffix: BadSuffix"
+func Example_BadSuffix() {} // ERROR "Example_BadSuffix has malformed example suffix: BadSuffix"
-func ExampleBuf() // OK because refers to known top-level type.
+func ExampleBuf() {} // OK because refers to known top-level type.
func ExampleBuf_Append() {} // OK because refers to known method.
@@ -28,8 +28,8 @@ func ExampleBuf_Len(i int) {} // ERROR "ExampleBuf_Len should be niladic"
// "Puffer" is German for "Buffer".
-func ExamplePuffer() // ERROR "ExamplePuffer refers to unknown identifier: Puffer"
+func ExamplePuffer() {} // ERROR "ExamplePuffer refers to unknown identifier: Puffer"
-func ExamplePuffer_Append() // ERROR "ExamplePuffer_Append refers to unknown identifier: Puffer"
+func ExamplePuffer_Append() {} // ERROR "ExamplePuffer_Append refers to unknown identifier: Puffer"
-func ExamplePuffer_suffix() // ERROR "ExamplePuffer_suffix refers to unknown identifier: Puffer"
+func ExamplePuffer_suffix() {} // ERROR "ExamplePuffer_suffix refers to unknown identifier: Puffer"
diff --git a/src/cmd/vet/tests.go b/src/cmd/vet/tests.go
index 076835b980..8c051f1336 100644
--- a/src/cmd/vet/tests.go
+++ b/src/cmd/vet/tests.go
@@ -59,23 +59,28 @@ func lookup(name string, scopes []*types.Scope) types.Object {
return nil
}
-func extendedScope(pkg *Package) []*types.Scope {
- scopes := []*types.Scope{pkg.typesPkg.Scope()}
-
- pkgName := pkg.typesPkg.Name()
- if strings.HasSuffix(pkgName, "_test") {
- basePkg := strings.TrimSuffix(pkgName, "_test")
- for _, p := range pkg.typesPkg.Imports() {
- if p.Name() == basePkg {
- scopes = append(scopes, p.Scope())
- break
+func extendedScope(f *File) []*types.Scope {
+ scopes := []*types.Scope{f.pkg.typesPkg.Scope()}
+ if f.basePkg != nil {
+ scopes = append(scopes, f.basePkg.typesPkg.Scope())
+ } else {
+ // If basePkg is not specified (e.g. when checking a single file) try to
+ // find it among imports.
+ pkgName := f.pkg.typesPkg.Name()
+ if strings.HasSuffix(pkgName, "_test") {
+ basePkgName := strings.TrimSuffix(pkgName, "_test")
+ for _, p := range f.pkg.typesPkg.Imports() {
+ if p.Name() == basePkgName {
+ scopes = append(scopes, p.Scope())
+ break
+ }
}
}
}
return scopes
}
-func checkExample(fn *ast.FuncDecl, pkg *Package, report reporter) {
+func checkExample(fn *ast.FuncDecl, f *File, report reporter) {
fnName := fn.Name.Name
if params := fn.Type.Params; len(params.List) != 0 {
report("%s should be niladic", fnName)
@@ -100,7 +105,7 @@ func checkExample(fn *ast.FuncDecl, pkg *Package, report reporter) {
exName = strings.TrimPrefix(fnName, "Example")
elems = strings.SplitN(exName, "_", 3)
ident = elems[0]
- obj = lookup(ident, extendedScope(pkg))
+ obj = lookup(ident, extendedScope(f))
)
if ident != "" && obj == nil {
// Check ExampleFoo and ExampleBadFoo.
@@ -173,7 +178,7 @@ func checkTestFunctions(f *File, node ast.Node) {
switch {
case strings.HasPrefix(fn.Name.Name, "Example"):
- checkExample(fn, f.pkg, report)
+ checkExample(fn, f, report)
case strings.HasPrefix(fn.Name.Name, "Test"):
checkTest(fn, "Test", report)
case strings.HasPrefix(fn.Name.Name, "Benchmark"):
diff --git a/src/cmd/vet/vet_test.go b/src/cmd/vet/vet_test.go
index 2dd8ae4053..31d4b9001d 100644
--- a/src/cmd/vet/vet_test.go
+++ b/src/cmd/vet/vet_test.go
@@ -102,7 +102,7 @@ func TestVet(t *testing.T) {
func TestDivergentPackagesExamples(t *testing.T) {
Build(t)
// errchk ./testvet
- Vet(t, []string{"testdata/divergent/buf.go", "testdata/divergent/buf_test.go"})
+ Vet(t, []string{"testdata/divergent"})
}
func TestIncompleteExamples(t *testing.T) {
diff --git a/test/errchk b/test/errchk
index b07bbc739d..bc8ef19cb0 100755
--- a/test/errchk
+++ b/test/errchk
@@ -37,6 +37,17 @@ foreach(reverse 0 .. @ARGV-1) {
}
}
+# If no files have been specified try to grab SOURCEFILES from the last
+# argument that is an existing directory if any
+unless(@file) {
+ foreach(reverse 0 .. @ARGV-1) {
+ if(-d $ARGV[$_]) {
+ @file = glob($ARGV[$_] . "/*.go");
+ last;
+ }
+ }
+}
+
foreach $file (@file) {
open(SRC, $file) || die "BUG: errchk: open $file: $!";
$src{$file} = [<SRC>];