@@ -34,49 +34,58 @@ func run(pass *analysis.Pass) (interface{}, error) {
34
34
inspect := pass .ResultOf [inspect .Analyzer ].(* inspector.Inspector )
35
35
36
36
nodeFilter := []ast.Node {
37
- (* ast .File )(nil ),
37
+ (* ast .FuncDecl )(nil ),
38
+ (* ast .FuncLit )(nil ),
38
39
}
39
40
40
41
inspect .Preorder (nodeFilter , func (n ast.Node ) {
41
42
switch n := n .(type ) {
42
- case * ast.File :
43
- for _ , decl := range n .Decls {
44
-
45
- funcDecl , ok := decl .(* ast.FuncDecl )
46
- if ! ok {
47
- continue
48
- }
49
- checkFunc (pass , funcDecl , pass .Fset .File (n .Pos ()).Name ())
50
- }
43
+ case * ast.FuncDecl :
44
+ checkFuncDecl (pass , n , pass .Fset .File (n .Pos ()).Name ())
45
+ case * ast.FuncLit :
46
+ checkFuncLit (pass , n , pass .Fset .File (n .Pos ()).Name ())
51
47
}
52
48
})
53
49
54
50
return nil , nil
55
51
}
56
52
57
- func checkFunc (pass * analysis.Pass , n * ast.FuncDecl , fileName string ) {
58
- argName , ok := targetRunner (n , fileName )
59
- if ok {
60
- for _ , stmt := range n .Body .List {
61
- switch stmt := stmt .(type ) {
62
- case * ast.ExprStmt :
63
- if ! checkExprStmt (pass , stmt , n , argName ) {
64
- continue
65
- }
66
- case * ast.IfStmt :
67
- if ! checkIfStmt (pass , stmt , n , argName ) {
68
- continue
69
- }
70
- case * ast.AssignStmt :
71
- if ! checkAssignStmt (pass , stmt , n , argName ) {
72
- continue
73
- }
53
+ func checkFuncDecl (pass * analysis.Pass , f * ast.FuncDecl , fileName string ) {
54
+ argName , ok := targetRunner (f .Type .Params .List , fileName )
55
+ if ! ok {
56
+ return
57
+ }
58
+ checkStmts (pass , f .Body .List , f .Name .Name , argName )
59
+ }
60
+
61
+ func checkFuncLit (pass * analysis.Pass , f * ast.FuncLit , fileName string ) {
62
+ argName , ok := targetRunner (f .Type .Params .List , fileName )
63
+ if ! ok {
64
+ return
65
+ }
66
+ checkStmts (pass , f .Body .List , "function literal" , argName )
67
+ }
68
+
69
+ func checkStmts (pass * analysis.Pass , stmts []ast.Stmt , funcName , argName string ) {
70
+ for _ , stmt := range stmts {
71
+ switch stmt := stmt .(type ) {
72
+ case * ast.ExprStmt :
73
+ if ! checkExprStmt (pass , stmt , funcName , argName ) {
74
+ continue
75
+ }
76
+ case * ast.IfStmt :
77
+ if ! checkIfStmt (pass , stmt , funcName , argName ) {
78
+ continue
79
+ }
80
+ case * ast.AssignStmt :
81
+ if ! checkAssignStmt (pass , stmt , funcName , argName ) {
82
+ continue
74
83
}
75
84
}
76
85
}
77
86
}
78
87
79
- func checkExprStmt (pass * analysis.Pass , stmt * ast.ExprStmt , n * ast. FuncDecl , argName string ) bool {
88
+ func checkExprStmt (pass * analysis.Pass , stmt * ast.ExprStmt , funcName , argName string ) bool {
80
89
callExpr , ok := stmt .X .(* ast.CallExpr )
81
90
if ! ok {
82
91
return false
@@ -94,12 +103,12 @@ func checkExprStmt(pass *analysis.Pass, stmt *ast.ExprStmt, n *ast.FuncDecl, arg
94
103
if argName == "" {
95
104
argName = "testing"
96
105
}
97
- pass .Reportf (stmt .Pos (), "os.Setenv() can be replaced by `%s.Setenv()` in %s" , argName , n . Name . Name )
106
+ pass .Reportf (stmt .Pos (), "os.Setenv() can be replaced by `%s.Setenv()` in %s" , argName , funcName )
98
107
}
99
108
return true
100
109
}
101
110
102
- func checkIfStmt (pass * analysis.Pass , stmt * ast.IfStmt , n * ast. FuncDecl , argName string ) bool {
111
+ func checkIfStmt (pass * analysis.Pass , stmt * ast.IfStmt , funcName , argName string ) bool {
103
112
assignStmt , ok := stmt .Init .(* ast.AssignStmt )
104
113
if ! ok {
105
114
return false
@@ -121,12 +130,12 @@ func checkIfStmt(pass *analysis.Pass, stmt *ast.IfStmt, n *ast.FuncDecl, argName
121
130
if argName == "" {
122
131
argName = "testing"
123
132
}
124
- pass .Reportf (stmt .Pos (), "os.Setenv() can be replaced by `%s.Setenv()` in %s" , argName , n . Name . Name )
133
+ pass .Reportf (stmt .Pos (), "os.Setenv() can be replaced by `%s.Setenv()` in %s" , argName , funcName )
125
134
}
126
135
return true
127
136
}
128
137
129
- func checkAssignStmt (pass * analysis.Pass , stmt * ast.AssignStmt , n * ast. FuncDecl , argName string ) bool {
138
+ func checkAssignStmt (pass * analysis.Pass , stmt * ast.AssignStmt , funcName , argName string ) bool {
130
139
rhs , ok := stmt .Rhs [0 ].(* ast.CallExpr )
131
140
if ! ok {
132
141
return false
@@ -144,13 +153,12 @@ func checkAssignStmt(pass *analysis.Pass, stmt *ast.AssignStmt, n *ast.FuncDecl,
144
153
if argName == "" {
145
154
argName = "testing"
146
155
}
147
- pass .Reportf (stmt .Pos (), "os.Setenv() can be replaced by `%s.Setenv()` in %s" , argName , n . Name . Name )
156
+ pass .Reportf (stmt .Pos (), "os.Setenv() can be replaced by `%s.Setenv()` in %s" , argName , funcName )
148
157
}
149
158
return true
150
159
}
151
160
152
- func targetRunner (funcDecl * ast.FuncDecl , fileName string ) (string , bool ) {
153
- params := funcDecl .Type .Params .List
161
+ func targetRunner (params []* ast.Field , fileName string ) (string , bool ) {
154
162
for _ , p := range params {
155
163
switch typ := p .Type .(type ) {
156
164
case * ast.StarExpr :
0 commit comments