Skip to content

Commit 07549b2

Browse files
authored
Use ast.Inspect instead of checkExpr and manually calls (#226)
We only have `checkExpr` to recursively find `ast.FuncList` to check its block. We do this both recursively but also for each known node that has an expression. Since we only care about the `FuncLit` it's better to just use `ast.Inspect` and check block for both `FuncDecl` and `FuncLit` already in `Run`. This removes a lot of code and might also be faster potentially. We might get diagnostics out of order but we never guaranteed a specific order.
1 parent 6afd151 commit 07549b2

File tree

1 file changed

+15
-153
lines changed

1 file changed

+15
-153
lines changed

wsl.go

Lines changed: 15 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,16 @@ func New(file *ast.File, pass *analysis.Pass, cfg *Configuration) *WSL {
5555
// Run will run analysis on the file and pass passed to the constructor. It's
5656
// typically only supposed to be used by [analysis.Analyzer].
5757
func (w *WSL) Run() {
58-
for _, decl := range w.file.Decls {
59-
if funcDecl, ok := decl.(*ast.FuncDecl); ok {
60-
w.checkFunc(funcDecl)
58+
ast.Inspect(w.file, func(n ast.Node) bool {
59+
switch node := n.(type) {
60+
case *ast.FuncDecl:
61+
w.checkBlock(node.Body, NewCursor([]ast.Stmt{}))
62+
case *ast.FuncLit:
63+
w.checkBlock(node.Body, NewCursor([]ast.Stmt{}))
6164
}
62-
}
65+
66+
return true
67+
})
6368
}
6469

6570
func (w *WSL) checkStmt(stmt ast.Stmt, cursor *Cursor) {
@@ -127,124 +132,6 @@ func (w *WSL) checkStmt(stmt ast.Stmt, cursor *Cursor) {
127132
}
128133
}
129134

130-
//nolint:unparam // False positive on `cursor`
131-
func (w *WSL) checkExpr(expr ast.Expr, cursor *Cursor) {
132-
// This switch traverses all possible subexpressions in search
133-
// of anonymous functions, no matter how unlikely or perhaps even
134-
// semantically impossible it is.
135-
switch s := expr.(type) {
136-
case *ast.FuncLit:
137-
w.checkBlock(s.Body, NewCursor([]ast.Stmt{}))
138-
case *ast.CallExpr:
139-
w.checkExpr(s.Fun, cursor)
140-
141-
for _, e := range s.Args {
142-
w.checkExpr(e, cursor)
143-
}
144-
case *ast.StarExpr:
145-
w.checkExpr(s.X, cursor)
146-
case *ast.CompositeLit:
147-
w.checkExpr(s.Type, cursor)
148-
149-
for _, e := range s.Elts {
150-
w.checkExpr(e, cursor)
151-
}
152-
case *ast.KeyValueExpr:
153-
w.checkExpr(s.Key, cursor)
154-
w.checkExpr(s.Value, cursor)
155-
case *ast.ArrayType:
156-
w.checkExpr(s.Elt, cursor)
157-
w.checkExpr(s.Len, cursor)
158-
case *ast.BasicLit:
159-
case *ast.BinaryExpr:
160-
w.checkExpr(s.X, cursor)
161-
w.checkExpr(s.Y, cursor)
162-
case *ast.ChanType:
163-
w.checkExpr(s.Value, cursor)
164-
case *ast.Ellipsis:
165-
w.checkExpr(s.Elt, cursor)
166-
case *ast.FuncType:
167-
if params := s.TypeParams; params != nil {
168-
for _, f := range params.List {
169-
w.checkExpr(f.Type, cursor)
170-
}
171-
}
172-
173-
if params := s.Params; params != nil {
174-
for _, f := range params.List {
175-
w.checkExpr(f.Type, cursor)
176-
}
177-
}
178-
179-
if results := s.Results; results != nil {
180-
for _, f := range results.List {
181-
w.checkExpr(f.Type, cursor)
182-
}
183-
}
184-
case *ast.Ident:
185-
case *ast.IndexExpr:
186-
w.checkExpr(s.Index, cursor)
187-
w.checkExpr(s.X, cursor)
188-
case *ast.IndexListExpr:
189-
w.checkExpr(s.X, cursor)
190-
191-
for _, e := range s.Indices {
192-
w.checkExpr(e, cursor)
193-
}
194-
case *ast.InterfaceType:
195-
for _, f := range s.Methods.List {
196-
w.checkExpr(f.Type, cursor)
197-
}
198-
case *ast.MapType:
199-
w.checkExpr(s.Key, cursor)
200-
w.checkExpr(s.Value, cursor)
201-
case *ast.ParenExpr:
202-
w.checkExpr(s.X, cursor)
203-
case *ast.SelectorExpr:
204-
w.checkExpr(s.X, cursor)
205-
case *ast.SliceExpr:
206-
w.checkExpr(s.X, cursor)
207-
w.checkExpr(s.Low, cursor)
208-
w.checkExpr(s.High, cursor)
209-
w.checkExpr(s.Max, cursor)
210-
case *ast.StructType:
211-
for _, f := range s.Fields.List {
212-
w.checkExpr(f.Type, cursor)
213-
}
214-
case *ast.TypeAssertExpr:
215-
w.checkExpr(s.X, cursor)
216-
w.checkExpr(s.Type, cursor)
217-
case *ast.UnaryExpr:
218-
w.checkExpr(s.X, cursor)
219-
case nil:
220-
default:
221-
}
222-
}
223-
224-
func (w *WSL) checkDecl(decl ast.Decl, cursor *Cursor) {
225-
switch d := decl.(type) {
226-
case *ast.GenDecl:
227-
for _, spec := range d.Specs {
228-
w.checkSpec(spec, cursor)
229-
}
230-
case *ast.FuncDecl:
231-
w.checkStmt(d.Body, cursor)
232-
case *ast.BadDecl:
233-
default:
234-
}
235-
}
236-
237-
func (w *WSL) checkSpec(spec ast.Spec, cursor *Cursor) {
238-
switch s := spec.(type) {
239-
case *ast.ValueSpec:
240-
for _, expr := range s.Values {
241-
w.checkExpr(expr, cursor)
242-
}
243-
case *ast.ImportSpec, *ast.TypeSpec:
244-
default:
245-
}
246-
}
247-
248135
func (w *WSL) checkBody(body []ast.Stmt) {
249136
cursor := NewCursor(body)
250137

@@ -433,6 +320,11 @@ func (w *WSL) checkCuddlingWithoutIntersection(stmt ast.Node, cursor *Cursor) {
433320
}
434321

435322
func (w *WSL) checkBlock(block *ast.BlockStmt, cursor *Cursor) {
323+
// Block can be nil for function declarations without a body.
324+
if block == nil {
325+
return
326+
}
327+
436328
w.checkBlockLeadingNewline(block)
437329
w.checkTrailingNewline(block)
438330
w.checkNewlineAfterBlock(block, cursor)
@@ -537,22 +429,8 @@ func (w *WSL) checkCommClause(stmt *ast.CommClause, cursor *Cursor) {
537429
w.checkBody(stmt.Body)
538430
}
539431

540-
func (w *WSL) checkFunc(funcDecl *ast.FuncDecl) {
541-
if funcDecl.Body == nil {
542-
return
543-
}
544-
545-
w.checkBlock(funcDecl.Body, NewCursor([]ast.Stmt{}))
546-
}
547-
548432
func (w *WSL) checkAssign(stmt *ast.AssignStmt, cursor *Cursor) {
549-
defer func() {
550-
for _, expr := range stmt.Rhs {
551-
w.checkExpr(expr, cursor)
552-
}
553-
554-
w.checkAppend(stmt, cursor)
555-
}()
433+
defer w.checkAppend(stmt, cursor)
556434

557435
if _, ok := w.config.Checks[CheckAssign]; !ok {
558436
return
@@ -619,8 +497,6 @@ func (w *WSL) checkBranch(stmt *ast.BranchStmt, cursor *Cursor) {
619497
}
620498

621499
func (w *WSL) checkDeclStmt(stmt *ast.DeclStmt, cursor *Cursor) {
622-
w.checkDecl(stmt.Decl, cursor)
623-
624500
if _, ok := w.config.Checks[CheckDecl]; !ok {
625501
return
626502
}
@@ -643,7 +519,6 @@ func (w *WSL) checkDeclStmt(stmt *ast.DeclStmt, cursor *Cursor) {
643519
func (w *WSL) checkDefer(stmt *ast.DeferStmt, cursor *Cursor) {
644520
w.maybeCheckExpr(
645521
stmt,
646-
stmt.Call,
647522
cursor,
648523
func(n ast.Node) (int, bool) {
649524
_, previousIsDefer := n.(*ast.DeferStmt)
@@ -781,7 +656,6 @@ func (w *WSL) checkError(
781656
func (w *WSL) checkExprStmt(stmt *ast.ExprStmt, cursor *Cursor) {
782657
w.maybeCheckExpr(
783658
stmt,
784-
stmt.X,
785659
cursor,
786660
func(n ast.Node) (int, bool) {
787661
_, ok := n.(*ast.ExprStmt)
@@ -798,7 +672,6 @@ func (w *WSL) checkFor(stmt *ast.ForStmt, cursor *Cursor) {
798672
func (w *WSL) checkGo(stmt *ast.GoStmt, cursor *Cursor) {
799673
w.maybeCheckExpr(
800674
stmt,
801-
stmt.Call,
802675
cursor,
803676
// We can cuddle any amount `go` statements so only check cuddling if
804677
// the previous one isn't a `go` call.
@@ -840,8 +713,6 @@ func (w *WSL) checkIf(stmt *ast.IfStmt, cursor *Cursor, isElse bool) {
840713
}
841714

842715
func (w *WSL) checkIncDec(stmt *ast.IncDecStmt, cursor *Cursor) {
843-
defer w.checkExpr(stmt.X, cursor)
844-
845716
if _, ok := w.config.Checks[CheckIncDec]; !ok {
846717
return
847718
}
@@ -880,10 +751,6 @@ func (w *WSL) checkRange(stmt *ast.RangeStmt, cursor *Cursor) {
880751
}
881752

882753
func (w *WSL) checkReturn(stmt *ast.ReturnStmt, cursor *Cursor) {
883-
for _, expr := range stmt.Results {
884-
w.checkExpr(expr, cursor)
885-
}
886-
887754
if _, ok := w.config.Checks[CheckReturn]; !ok {
888755
return
889756
}
@@ -914,8 +781,6 @@ func (w *WSL) checkSelect(stmt *ast.SelectStmt, cursor *Cursor) {
914781
}
915782

916783
func (w *WSL) checkSend(stmt *ast.SendStmt, cursor *Cursor) {
917-
defer w.checkExpr(stmt.Value, cursor)
918-
919784
if _, ok := w.config.Checks[CheckSend]; !ok {
920785
return
921786
}
@@ -1288,13 +1153,10 @@ func (w *WSL) maybeCheckBlock(
12881153

12891154
func (w *WSL) maybeCheckExpr(
12901155
node ast.Node,
1291-
expr ast.Expr,
12921156
cursor *Cursor,
12931157
predicate func(ast.Node) (int, bool),
12941158
check CheckType,
12951159
) {
1296-
w.checkExpr(expr, cursor)
1297-
12981160
if _, ok := w.config.Checks[check]; ok {
12991161
cursor.SetChecker(check)
13001162
previousNode := cursor.PreviousNode()

0 commit comments

Comments
 (0)