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  }