github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/pkg/golinters/monkit/unused.go (about) 1 // Copyright (C) 2020 Storj Labs, Inc. 2 // See LICENSE for copying information. 3 4 // check-monkit finds problems with using monkit. 5 package monkit 6 7 import ( 8 "github.com/elek/golangci-lint/pkg/golinters/goanalysis" 9 "go/ast" 10 11 "golang.org/x/tools/go/analysis" 12 "golang.org/x/tools/go/analysis/passes/inspect" 13 "golang.org/x/tools/go/analysis/singlechecker" 14 "golang.org/x/tools/go/ast/inspector" 15 ) 16 17 func main() { singlechecker.Main(Analyzer) } 18 19 func NewMonkitCheck() *goanalysis.Linter { 20 return goanalysis.NewLinter( 21 "monkit", 22 "STORJ: check for unfinished calls to mon.Task()(ctx)(&err)", 23 []*analysis.Analyzer{ 24 Analyzer, 25 }, 26 nil, 27 ).WithLoadMode(goanalysis.LoadModeWholeProgram) 28 } 29 30 // Analyzer implements unused task analysis pass. 31 var Analyzer = &analysis.Analyzer{ 32 Name: "monkit", 33 Doc: `check for unfinished calls to mon.Task()(ctx)(&err)`, 34 Requires: []*analysis.Analyzer{inspect.Analyzer}, 35 Run: run, 36 } 37 38 func run(pass *analysis.Pass) (interface{}, error) { 39 inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) 40 41 nodeFilter := []ast.Node{ 42 (*ast.CallExpr)(nil), 43 } 44 inspect.WithStack(nodeFilter, func(n ast.Node, push bool, stack []ast.Node) (proceed bool) { 45 if push { 46 return true 47 } 48 49 call, ok := n.(*ast.CallExpr) 50 if !ok { 51 return true // not a call statement 52 } 53 54 typ := pass.TypesInfo.TypeOf(call) 55 if typ == nil || typ.String() != `github.com/spacemonkeygo/monkit/v3.Task` { 56 return true 57 } 58 59 start := stack[len(stack)-2] 60 stop := stack[len(stack)-3] 61 62 if _, ok = start.(*ast.CallExpr); !ok { 63 if _, ok := start.(*ast.AssignStmt); ok { 64 return true 65 } 66 if _, ok := start.(*ast.ValueSpec); ok { 67 return true 68 } 69 pass.Reportf(call.Lparen, "monitoring not started") 70 return true 71 } 72 if _, ok = stop.(*ast.CallExpr); !ok { 73 if _, ok := stop.(*ast.AssignStmt); ok { 74 return true 75 } 76 pass.Reportf(call.Lparen, "monitoring not stopped") 77 return true 78 } 79 80 return true 81 }) 82 return nil, nil 83 }