From b173f63244b205f246f3575ee26ae2438ea43e3d Mon Sep 17 00:00:00 2001 From: Christian Mehlmauer <105281+firefart@users.noreply.github.com> Date: Sun, 17 Apr 2022 15:41:08 +0200 Subject: [PATCH] Add nonamedreturns linter (#2701) --- .golangci.example.yml | 2 + go.mod | 1 + go.sum | 2 + pkg/golinters/godot.go | 2 +- pkg/golinters/nonamedreturns.go | 17 ++++++ pkg/lint/lintersdb/manager.go | 5 ++ test/testdata/nonamedreturns.go | 94 +++++++++++++++++++++++++++++++++ 7 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 pkg/golinters/nonamedreturns.go create mode 100644 test/testdata/nonamedreturns.go diff --git a/.golangci.example.yml b/.golangci.example.yml index 20d285e280d3..326c155bed28 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -790,6 +790,7 @@ linters-settings: - lostcancel - nilfunc - nilness + - nonamedreturns - printf - reflectvaluecompare - shadow @@ -833,6 +834,7 @@ linters-settings: - lostcancel - nilfunc - nilness + - nonamedreturns - printf - reflectvaluecompare - shadow diff --git a/go.mod b/go.mod index f2ac5bf132a2..d9a1b2bf06a0 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/denis-tingaikin/go-header v0.4.3 github.com/esimonov/ifshort v1.0.4 github.com/fatih/color v1.13.0 + github.com/firefart/nonamedreturns v1.0.0 github.com/fzipp/gocyclo v0.5.1 github.com/go-critic/go-critic v0.6.3 github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b diff --git a/go.sum b/go.sum index 1d67d7752886..bc630033a124 100644 --- a/go.sum +++ b/go.sum @@ -175,6 +175,8 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/firefart/nonamedreturns v1.0.0 h1:TKZUsLIQ7rks6+g5qdG+MAtMIvZEvVSYGNDeybB7jO0= +github.com/firefart/nonamedreturns v1.0.0/go.mod h1:D3dpIBojGGNh5UfElmwPu73SwDCm+VKhHYqwlNOk2uQ= github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= diff --git a/pkg/golinters/godot.go b/pkg/golinters/godot.go index cd5b2a43ef02..09eb9b5b2e9f 100644 --- a/pkg/golinters/godot.go +++ b/pkg/golinters/godot.go @@ -37,7 +37,7 @@ func NewGodot() *goanalysis.Linter { // Convert deprecated setting // todo(butuzov): remove on v2 release - if cfg.CheckAll { // nolint:staticcheck + if cfg.CheckAll { // nolint:staticcheck // Keep for retro-compatibility. settings.Scope = godot.AllScope } diff --git a/pkg/golinters/nonamedreturns.go b/pkg/golinters/nonamedreturns.go new file mode 100644 index 000000000000..8c943d83eeb9 --- /dev/null +++ b/pkg/golinters/nonamedreturns.go @@ -0,0 +1,17 @@ +package golinters + +import ( + "github.com/firefart/nonamedreturns/analyzer" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +func NewNoNamedReturns() *goanalysis.Linter { + return goanalysis.NewLinter( + "nonamedreturns", + "Reports all named returns", + []*analysis.Analyzer{analyzer.Analyzer}, + nil, + ).WithLoadMode(goanalysis.LoadModeSyntax) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index fad6721c51d3..f0771648a712 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -526,6 +526,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithURL("https://github.com/sonatard/noctx"). WithNoopFallback(m.cfg), + linter.NewConfig(golinters.NewNoNamedReturns()). + WithSince("v1.46.0"). + WithPresets(linter.PresetStyle). + WithURL("https://github.com/firefart/nonamedreturns"), + linter.NewConfig(golinters.NewParallelTest()). WithSince("v1.33.0"). WithPresets(linter.PresetStyle, linter.PresetTest). diff --git a/test/testdata/nonamedreturns.go b/test/testdata/nonamedreturns.go new file mode 100644 index 000000000000..5850281db892 --- /dev/null +++ b/test/testdata/nonamedreturns.go @@ -0,0 +1,94 @@ +//args: -Enonamedreturns +package testdata + +import "fmt" + +type asdf struct { + test string +} + +func noParams() { + return +} + +var c = func() { + return +} + +var d = func() error { + return nil +} + +var e = func() (err error) { // ERROR `named return "err" with type "error" found` + err = nil + return +} + +var ( + f = func() { + return + } + + g = func() error { + return nil + } + + h = func() (err error) { // ERROR `named return "err" with type "error" found` + err = nil + return + } +) + +// this should not match as the implementation does not need named parameters (see below) +type funcDefintion func(arg1, arg2 interface{}) (num int, err error) + +func funcDefintionImpl(arg1, arg2 interface{}) (int, error) { + return 0, nil +} + +func funcDefintionImpl2(arg1, arg2 interface{}) (num int, err error) { // ERROR `named return "num" with type "int" found` + return 0, nil +} + +var funcVar = func() (msg string) { // ERROR `named return "msg" with type "string" found` + msg = "c" + return msg +} + +func test() { + a := funcVar() + _ = a + + var function funcDefintion + function = funcDefintionImpl + i, err := function("", "") + _ = i + _ = err + function = funcDefintionImpl2 + i, err = function("", "") + _ = i + _ = err +} + +func good(i string) string { + return i +} + +func bad(i string, a, b int) (ret1 string, ret2 interface{}, ret3, ret4 int, ret5 asdf) { // ERROR `named return "ret1" with type "string" found` + x := "dummy" + return fmt.Sprintf("%s", x), nil, 1, 2, asdf{} +} + +func bad2() (msg string, err error) { // ERROR `named return "msg" with type "string" found` + msg = "" + err = nil + return +} + +func myLog(format string, args ...interface{}) { + return +} + +type obj struct{} + +func (o *obj) func1() (err error) { return nil } // ERROR `named return "err" with type "error" found`