github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/rule/waitgroup-by-value.go (about) 1 package rule 2 3 import ( 4 "go/ast" 5 6 "github.com/mgechev/revive/lint" 7 ) 8 9 // WaitGroupByValueRule lints sync.WaitGroup passed by copy in functions. 10 type WaitGroupByValueRule struct{} 11 12 // Apply applies the rule to given file. 13 func (r *WaitGroupByValueRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { 14 var failures []lint.Failure 15 16 onFailure := func(failure lint.Failure) { 17 failures = append(failures, failure) 18 } 19 20 w := lintWaitGroupByValueRule{onFailure: onFailure} 21 ast.Walk(w, file.AST) 22 return failures 23 } 24 25 // Name returns the rule name. 26 func (r *WaitGroupByValueRule) Name() string { 27 return "waitgroup-by-value" 28 } 29 30 type lintWaitGroupByValueRule struct { 31 onFailure func(lint.Failure) 32 } 33 34 func (w lintWaitGroupByValueRule) Visit(node ast.Node) ast.Visitor { 35 // look for function declarations 36 fd, ok := node.(*ast.FuncDecl) 37 if !ok { 38 return w 39 } 40 41 // Check all function's parameters 42 for _, field := range fd.Type.Params.List { 43 if !w.isWaitGroup(field.Type) { 44 continue 45 } 46 47 w.onFailure(lint.Failure{ 48 Confidence: 1, 49 Node: field, 50 Failure: "sync.WaitGroup passed by value, the function will get a copy of the original one", 51 }) 52 } 53 54 return nil 55 } 56 57 func (lintWaitGroupByValueRule) isWaitGroup(ft ast.Expr) bool { 58 se, ok := ft.(*ast.SelectorExpr) 59 if !ok { 60 return false 61 } 62 63 x, _ := se.X.(*ast.Ident) 64 sel := se.Sel.Name 65 return x.Name == "sync" && sel == "WaitGroup" 66 }