/
bare-return.go
84 lines (66 loc) 路 1.79 KB
/
bare-return.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package rule
import (
"go/ast"
"github.com/mgechev/revive/lint"
)
// BareReturnRule lints given else constructs.
type BareReturnRule struct{}
// Apply applies the rule to given file.
func (*BareReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
onFailure := func(failure lint.Failure) {
failures = append(failures, failure)
}
w := lintBareReturnRule{onFailure: onFailure}
ast.Walk(w, file.AST)
return failures
}
// Name returns the rule name.
func (*BareReturnRule) Name() string {
return "bare-return"
}
type lintBareReturnRule struct {
onFailure func(lint.Failure)
}
func (w lintBareReturnRule) Visit(node ast.Node) ast.Visitor {
switch n := node.(type) {
case *ast.FuncDecl:
w.checkFunc(n.Type.Results, n.Body)
case *ast.FuncLit: // to cope with deferred functions and go-routines
w.checkFunc(n.Type.Results, n.Body)
}
return w
}
// checkFunc will verify if the given function has named result and bare returns
func (w lintBareReturnRule) checkFunc(results *ast.FieldList, body *ast.BlockStmt) {
hasNamedResults := results != nil && len(results.List) > 0 && results.List[0].Names != nil
if !hasNamedResults || body == nil {
return // nothing to do
}
brf := bareReturnFinder{w.onFailure}
ast.Walk(brf, body)
}
type bareReturnFinder struct {
onFailure func(lint.Failure)
}
func (w bareReturnFinder) Visit(node ast.Node) ast.Visitor {
_, ok := node.(*ast.FuncLit)
if ok {
// skip analysing function literals
// they will be analysed by the lintBareReturnRule.Visit method
return nil
}
rs, ok := node.(*ast.ReturnStmt)
if !ok {
return w
}
if len(rs.Results) > 0 {
return w
}
w.onFailure(lint.Failure{
Confidence: 1,
Node: rs,
Failure: "avoid using bare returns, please add return expressions",
})
return w
}