github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/rule/context-as-argument.go (about)

     1  package rule
     2  
     3  import (
     4  	"go/ast"
     5  
     6  	"github.com/mgechev/revive/lint"
     7  )
     8  
     9  // ContextAsArgumentRule lints given else constructs.
    10  type ContextAsArgumentRule struct{}
    11  
    12  // Apply applies the rule to given file.
    13  func (r *ContextAsArgumentRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
    14  	var failures []lint.Failure
    15  
    16  	fileAst := file.AST
    17  	walker := lintContextArguments{
    18  		file:    file,
    19  		fileAst: fileAst,
    20  		onFailure: func(failure lint.Failure) {
    21  			failures = append(failures, failure)
    22  		},
    23  	}
    24  
    25  	ast.Walk(walker, fileAst)
    26  
    27  	return failures
    28  }
    29  
    30  // Name returns the rule name.
    31  func (r *ContextAsArgumentRule) Name() string {
    32  	return "context-as-argument"
    33  }
    34  
    35  type lintContextArguments struct {
    36  	file      *lint.File
    37  	fileAst   *ast.File
    38  	onFailure func(lint.Failure)
    39  }
    40  
    41  func (w lintContextArguments) Visit(n ast.Node) ast.Visitor {
    42  	fn, ok := n.(*ast.FuncDecl)
    43  	if !ok || len(fn.Type.Params.List) <= 1 {
    44  		return w
    45  	}
    46  	// A context.Context should be the first parameter of a function.
    47  	// Flag any that show up after the first.
    48  	previousArgIsCtx := isPkgDot(fn.Type.Params.List[0].Type, "context", "Context")
    49  	for _, arg := range fn.Type.Params.List[1:] {
    50  		argIsCtx := isPkgDot(arg.Type, "context", "Context")
    51  		if argIsCtx && !previousArgIsCtx {
    52  			w.onFailure(lint.Failure{
    53  				Node:       arg,
    54  				Category:   "arg-order",
    55  				Failure:    "context.Context should be the first parameter of a function",
    56  				Confidence: 0.9,
    57  			})
    58  			break // only flag one
    59  		}
    60  		previousArgIsCtx = argIsCtx
    61  	}
    62  	return w
    63  }