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:
parent
672b7cdf37
commit
6ebe5bbb1e
@ -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 |
|
| `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 |
|
| `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 |
|
| `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
|
## Configurable rules
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ var allRules = append([]lint.Rule{
|
|||||||
&rule.FunctionResultsLimitRule{},
|
&rule.FunctionResultsLimitRule{},
|
||||||
&rule.MaxPublicStructsRule{},
|
&rule.MaxPublicStructsRule{},
|
||||||
&rule.RangeValInClosureRule{},
|
&rule.RangeValInClosureRule{},
|
||||||
|
&rule.WaitGroupByCopyRule{},
|
||||||
}, defaultRules...)
|
}, defaultRules...)
|
||||||
|
|
||||||
var allFormatters = []lint.Formatter{
|
var allFormatters = []lint.Formatter{
|
||||||
|
21
fixtures/waitgroup-by-copy.go
Normal file
21
fixtures/waitgroup-by-copy.go
Normal 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
65
rule/waitgroup-by-copy.go
Normal 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"
|
||||||
|
}
|
11
test/waitgroup-by-copy_test.go
Normal file
11
test/waitgroup-by-copy_test.go
Normal 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{})
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user