sa9003.go raw
1 package sa9003
2
3 import (
4 "go/ast"
5
6 "golang.org/x/tools/go/analysis"
7 "honnef.co/go/tools/analysis/facts/generated"
8 "honnef.co/go/tools/analysis/lint"
9 "honnef.co/go/tools/analysis/report"
10 "honnef.co/go/tools/go/ir/irutil"
11 "honnef.co/go/tools/internal/passes/buildir"
12 )
13
14 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
15 Analyzer: &analysis.Analyzer{
16 Name: "SA9003",
17 Run: run,
18 Requires: []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer},
19 },
20 Doc: &lint.RawDocumentation{
21 Title: `Empty body in an if or else branch`,
22 Since: "2017.1",
23 NonDefault: true,
24 Severity: lint.SeverityWarning,
25 MergeIf: lint.MergeIfAny,
26 },
27 })
28
29 var Analyzer = SCAnalyzer.Analyzer
30
31 func run(pass *analysis.Pass) (interface{}, error) {
32 for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
33 if fn.Source() == nil {
34 continue
35 }
36 if irutil.IsExample(fn) {
37 continue
38 }
39 cb := func(node ast.Node) bool {
40 ifstmt, ok := node.(*ast.IfStmt)
41 if !ok {
42 return true
43 }
44 if ifstmt.Else != nil {
45 b, ok := ifstmt.Else.(*ast.BlockStmt)
46 if !ok || len(b.List) != 0 {
47 return true
48 }
49 report.Report(pass, ifstmt.Else, "empty branch", report.FilterGenerated(), report.ShortRange())
50 }
51 if len(ifstmt.Body.List) != 0 {
52 return true
53 }
54 report.Report(pass, ifstmt, "empty branch", report.FilterGenerated(), report.ShortRange())
55 return true
56 }
57 if source := fn.Source(); source != nil {
58 ast.Inspect(source, cb)
59 }
60 }
61 return nil, nil
62 }
63