@@ -5,56 +5,61 @@ import (
5
5
"strings"
6
6
7
7
"golang.org/x/tools/go/analysis"
8
+ "golang.org/x/tools/go/analysis/passes/inspect"
9
+ "golang.org/x/tools/go/ast/inspector"
8
10
)
9
11
10
- type analyzer struct {}
11
-
12
12
func NewAnalyzer () * analysis.Analyzer {
13
- a := & analyzer {}
14
-
15
13
return & analysis.Analyzer {
16
- Name : "noinlineerr" ,
17
- Doc : "Disallows inline error handling using `if err := ...; err != nil`" ,
18
- Run : a .run ,
14
+ Name : "noinlineerr" ,
15
+ Doc : "Disallows inline error handling (`if err := ...; err != nil {`)" ,
16
+ Run : run ,
17
+ Requires : []* analysis.Analyzer {inspect .Analyzer },
19
18
}
20
19
}
21
20
22
- func (a * analyzer ) run (pass * analysis.Pass ) (any , error ) {
23
- for _ , file := range pass .Files {
24
- ast .Inspect (file , func (n ast.Node ) bool {
25
- // look for if statements with an Init clause
26
- ifStmt , ok := n .(* ast.IfStmt )
27
- if ! ok || ifStmt .Init == nil {
28
- return true
29
- }
21
+ func run (pass * analysis.Pass ) (any , error ) {
22
+ insp , ok := pass .ResultOf [inspect .Analyzer ].(* inspector.Inspector )
23
+ if ! ok {
24
+ return nil , nil //nolint:nilnil // nothing to return
25
+ }
26
+
27
+ nodeFilter := []ast.Node {
28
+ (* ast .IfStmt )(nil ),
29
+ }
30
30
31
- // check if the init clause is an assignment
32
- assignStmt , ok := ifStmt .Init .(* ast.AssignStmt )
31
+ insp .Preorder (nodeFilter , func (n ast.Node ) {
32
+ ifStmt , ok := n .(* ast.IfStmt )
33
+ if ! ok || ifStmt .Init == nil {
34
+ return
35
+ }
36
+
37
+ // check if the init clause is an assignment
38
+ assignStmt , ok := ifStmt .Init .(* ast.AssignStmt )
39
+ if ! ok {
40
+ return
41
+ }
42
+
43
+ // iterate over left-hand side variables of the assignment
44
+ for _ , lhs := range assignStmt .Lhs {
45
+ ident , ok := lhs .(* ast.Ident )
33
46
if ! ok {
34
- return true
47
+ continue
35
48
}
36
49
37
- // iterate over left-hand side variables of the assignment
38
- for _ , lhs := range assignStmt .Lhs {
39
- ident , ok := lhs .(* ast.Ident )
40
- if ! ok {
41
- continue
42
- }
43
-
44
- // confirm type is error
45
- obj := pass .TypesInfo .ObjectOf (ident )
46
- if obj == nil || ! strings .Contains (obj .Type ().String (), "error" ) {
47
- continue
48
- }
49
-
50
- // report usage of inline error assignment
51
- pass .Reportf (
52
- ident .Pos (),
53
- "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" ,
54
- )
50
+ // confirm type is error
51
+ obj := pass .TypesInfo .ObjectOf (ident )
52
+ if obj == nil || ! strings .Contains (obj .Type ().String (), "error" ) {
53
+ continue
55
54
}
56
- return true
57
- })
58
- }
55
+
56
+ // report usage of inline error assignment
57
+ pass .Reportf (
58
+ ident .Pos (),
59
+ "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" ,
60
+ )
61
+ }
62
+ })
63
+
59
64
return nil , nil //nolint:nilnil // nothing to return
60
65
}
0 commit comments