From 88ebabc4bc11d4b373e5545a2d16e44f203d1dbb Mon Sep 17 00:00:00 2001 From: Denis Isaev Date: Thu, 28 Jun 2018 10:09:44 +0300 Subject: [PATCH] Fix #109, #116, #131: don't report in deadcode about unused test functions in main package --- Gopkg.lock | 2 +- test/testdata/deadcode_main_pkg/main_test.go | 15 ++++++++++ .../golangci/go-misc/deadcode/deadcode.go | 28 ++++++++++++++----- 3 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 test/testdata/deadcode_main_pkg/main_test.go diff --git a/Gopkg.lock b/Gopkg.lock index 6a44a743..34100fb4 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -69,7 +69,7 @@ branch = "master" name = "github.com/golangci/go-misc" packages = ["deadcode"] - revision = "a61b005a223b50d3656798639dd87073ca5c1981" + revision = "927a3d87b613e9f6f0fb7ef8bb8de8b83c30a5a2" [[projects]] branch = "master" diff --git a/test/testdata/deadcode_main_pkg/main_test.go b/test/testdata/deadcode_main_pkg/main_test.go new file mode 100644 index 00000000..6a30794f --- /dev/null +++ b/test/testdata/deadcode_main_pkg/main_test.go @@ -0,0 +1,15 @@ +package main + +import "testing" + +func TestF(t *testing.T) { + +} + +func BenchmarkF(t *testing.B) { + +} + +func ExampleF() { + +} diff --git a/vendor/github.com/golangci/go-misc/deadcode/deadcode.go b/vendor/github.com/golangci/go-misc/deadcode/deadcode.go index 2a48adf5..2e7cfc96 100644 --- a/vendor/github.com/golangci/go-misc/deadcode/deadcode.go +++ b/vendor/github.com/golangci/go-misc/deadcode/deadcode.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "sort" + "strings" "golang.org/x/tools/go/loader" ) @@ -50,9 +51,8 @@ type Context struct { program *loader.Program } -// error formats the error to standard error, adding program -// identification and a newline -func (ctx *Context) errorf(pos token.Pos, format string, args ...interface{}) { +// pos resolves a compact position encoding into a verbose one +func (ctx *Context) pos(pos token.Pos) token.Position { if ctx.cwd == "" { ctx.cwd, _ = os.Getwd() } @@ -61,6 +61,13 @@ func (ctx *Context) errorf(pos token.Pos, format string, args ...interface{}) { if err == nil { p.Filename = f } + return p +} + +// error formats the error to standard error, adding program +// identification and a newline +func (ctx *Context) errorf(pos token.Pos, format string, args ...interface{}) { + p := ctx.pos(pos) fmt.Fprintf(os.Stderr, p.String()+": "+format+"\n", args...) exitCode = 2 } @@ -73,18 +80,22 @@ func (ctx *Context) Process() []types.Object { prog := ctx.program var allUnused []types.Object for _, pkg := range prog.Imported { - unused := doPackage(prog, pkg) + unused := ctx.doPackage(prog, pkg) allUnused = append(allUnused, unused...) } for _, pkg := range prog.Created { - unused := doPackage(prog, pkg) + unused := ctx.doPackage(prog, pkg) allUnused = append(allUnused, unused...) } sort.Sort(objects(allUnused)) return allUnused } -func doPackage(prog *loader.Program, pkg *loader.PackageInfo) []types.Object { +func isTestFuncByName(name string) bool { + return strings.HasPrefix(name, "Test") || strings.HasPrefix(name, "Benchmark") || strings.HasPrefix(name, "Example") +} + +func (ctx *Context) doPackage(prog *loader.Program, pkg *loader.PackageInfo) []types.Object { used := make(map[types.Object]bool) for _, file := range pkg.Files { ast.Inspect(file, func(n ast.Node) bool { @@ -107,7 +118,10 @@ func doPackage(prog *loader.Program, pkg *loader.PackageInfo) []types.Object { continue } obj := global.Lookup(name) - if !used[obj] && (pkg.Pkg.Name() == "main" || !ast.IsExported(name)) { + _, isSig := obj.Type().(*types.Signature) + pos := ctx.pos(obj.Pos()) + isTestMethod := isSig && isTestFuncByName(obj.Name()) && strings.HasSuffix(pos.Filename, "_test.go") + if !used[obj] && ((pkg.Pkg.Name() == "main" && !isTestMethod) || !ast.IsExported(name)) { unused = append(unused, obj) } }