1
0
mirror of https://github.com/mgechev/revive.git synced 2025-04-15 11:36:48 +02:00

waitgroup-by-value (new rule) (#76)

* waitgroup-by-value (new rule)

* code simplification
This commit is contained in:
SalvadorC 2018-09-30 21:29:11 +02:00 committed by Minko Gechev
parent 672b7cdf37
commit 6ebe5bbb1e
5 changed files with 99 additions and 0 deletions

View File

@ -272,6 +272,7 @@ List of all available rules. The rules ported from `golint` are left unchanged a
| `function-result-limit` | int | Specifies the maximum number of results a function can return | no | no |
| `imports-blacklist` | []string | Disallows importing the specified packages | no | no |
| `range-val-in-closure`| n/a | Warns if range value is used in a closure dispatched as goroutine| no | no |
| `waitgroup-by-value `| n/a | Warns on functions taking sync.WaitGroup as a by-value parameter | no | no |
## Configurable rules

View File

@ -68,6 +68,7 @@ var allRules = append([]lint.Rule{
&rule.FunctionResultsLimitRule{},
&rule.MaxPublicStructsRule{},
&rule.RangeValInClosureRule{},
&rule.WaitGroupByCopyRule{},
}, defaultRules...)
var allFormatters = []lint.Formatter{

View File

@ -0,0 +1,21 @@
package fixtures
import (
"sync"
)
func foo(a int, b float32, c char, d sync.WaitGroup) { // MATCH /sync.WaitGroup passed by value, the function will get a copy of the original one/
}
func bar(a, b sync.WaitGroup) { // MATCH /sync.WaitGroup passed by value, the function will get a copy of the original one/
}
func baz(zz sync.WaitGroup) { // MATCH /sync.WaitGroup passed by value, the function will get a copy of the original one/
}
func ok(zz *sync.WaitGroup) {
}

65
rule/waitgroup-by-copy.go Normal file
View File

@ -0,0 +1,65 @@
package rule
import (
"github.com/mgechev/revive/lint"
"go/ast"
)
// WaitGroupByCopyRule lints sync.WaitGroup passed by copy in functions.
type WaitGroupByCopyRule struct{}
// Apply applies the rule to given file.
func (r *WaitGroupByCopyRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
onFailure := func(failure lint.Failure) {
failures = append(failures, failure)
}
w := lintWaitGroupByCopyRule{onFailure: onFailure}
ast.Walk(w, file.AST)
return failures
}
// Name returns the rule name.
func (r *WaitGroupByCopyRule) Name() string {
return "waitgroup-by-copy"
}
type lintWaitGroupByCopyRule struct {
onFailure func(lint.Failure)
}
func (w lintWaitGroupByCopyRule) Visit(node ast.Node) ast.Visitor {
// look for function declarations
fd, ok := node.(*ast.FuncDecl)
if !ok {
return w
}
// Check all function's parameters
for _, field := range fd.Type.Params.List {
if !w.isWaitGroup(field.Type) {
continue
}
w.onFailure(lint.Failure{
Confidence: 1,
Node: field,
Failure: "sync.WaitGroup passed by value, the function will get a copy of the original one",
})
}
return nil
}
func (lintWaitGroupByCopyRule) isWaitGroup(ft ast.Expr) bool {
se, ok := ft.(*ast.SelectorExpr)
if !ok {
return false
}
x, _ := se.X.(*ast.Ident)
sel := se.Sel.Name
return x.Name == "sync" && sel == "WaitGroup"
}

View File

@ -0,0 +1,11 @@
package test
import (
"testing"
"github.com/mgechev/revive/rule"
)
func TestWaitGroupByCopy(t *testing.T) {
testRule(t, "waitgroup-by-copy", &rule.WaitGroupByCopyRule{})
}