Skip to content

Commit 8f54012

Browse files
authoredDec 5, 2024
refactor (rule/unused-receiver): replace AST walker by iteration over declarations (#1171)
1 parent 278246d commit 8f54012

File tree

1 file changed

+22
-45
lines changed

1 file changed

+22
-45
lines changed
 

‎rule/unused_receiver.go

+22-45
Original file line numberDiff line numberDiff line change
@@ -51,74 +51,51 @@ func (r *UnusedReceiverRule) Apply(file *lint.File, args lint.Arguments) []lint.
5151
r.configureOnce.Do(func() { r.configure(args) })
5252
var failures []lint.Failure
5353

54-
onFailure := func(failure lint.Failure) {
55-
failures = append(failures, failure)
56-
}
57-
58-
w := lintUnusedReceiverRule{
59-
onFailure: onFailure,
60-
allowRegex: r.allowRegex,
61-
failureMsg: r.failureMsg,
62-
}
63-
64-
ast.Walk(w, file.AST)
65-
66-
return failures
67-
}
68-
69-
// Name returns the rule name.
70-
func (*UnusedReceiverRule) Name() string {
71-
return "unused-receiver"
72-
}
73-
74-
type lintUnusedReceiverRule struct {
75-
onFailure func(lint.Failure)
76-
allowRegex *regexp.Regexp
77-
failureMsg string
78-
}
79-
80-
func (w lintUnusedReceiverRule) Visit(node ast.Node) ast.Visitor {
81-
switch n := node.(type) {
82-
case *ast.FuncDecl:
83-
if n.Recv == nil {
84-
return nil // skip this func decl, not a method
54+
for _, decl := range file.AST.Decls {
55+
funcDecl, ok := decl.(*ast.FuncDecl)
56+
isMethod := ok && funcDecl.Recv != nil
57+
if !isMethod {
58+
continue
8559
}
8660

87-
rec := n.Recv.List[0] // safe to access only the first (unique) element of the list
61+
rec := funcDecl.Recv.List[0] // safe to access only the first (unique) element of the list
8862
if len(rec.Names) < 1 {
89-
return nil // the receiver is anonymous: func (aType) Foo(...) ...
63+
continue // the receiver is anonymous: func (aType) Foo(...) ...
9064
}
9165

9266
recID := rec.Names[0]
9367
if recID.Name == "_" {
94-
return nil // the receiver is already named _
68+
continue // the receiver is already named _
9569
}
9670

97-
if w.allowRegex != nil && w.allowRegex.FindStringIndex(recID.Name) != nil {
98-
return nil
71+
if r.allowRegex != nil && r.allowRegex.FindStringIndex(recID.Name) != nil {
72+
continue
9973
}
10074

10175
// inspect the func body looking for references to the receiver id
102-
fselect := func(n ast.Node) bool {
76+
selectReceiverUses := func(n ast.Node) bool {
10377
ident, isAnID := n.(*ast.Ident)
10478

10579
return isAnID && ident.Obj == recID.Obj
10680
}
107-
refs2recID := pick(n.Body, fselect)
81+
receiverUses := pick(funcDecl.Body, selectReceiverUses)
10882

109-
if len(refs2recID) > 0 {
110-
return nil // the receiver is referenced in the func body
83+
if len(receiverUses) > 0 {
84+
continue // the receiver is referenced in the func body
11185
}
11286

113-
w.onFailure(lint.Failure{
87+
failures = append(failures, lint.Failure{
11488
Confidence: 1,
11589
Node: recID,
11690
Category: "bad practice",
117-
Failure: fmt.Sprintf(w.failureMsg, recID.Name),
91+
Failure: fmt.Sprintf(r.failureMsg, recID.Name),
11892
})
119-
120-
return nil // full method body already inspected
12193
}
12294

123-
return w
95+
return failures
96+
}
97+
98+
// Name returns the rule name.
99+
func (*UnusedReceiverRule) Name() string {
100+
return "unused-receiver"
124101
}

0 commit comments

Comments
 (0)
Please sign in to comment.