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

     1  package rule
     2  
     3  import (
     4  	"fmt"
     5  	"go/ast"
     6  
     7  	"github.com/mgechev/revive/lint"
     8  )
     9  
    10  // ArgumentsLimitRule lints given else constructs.
    11  type ArgumentsLimitRule struct{}
    12  
    13  // Apply applies the rule to given file.
    14  func (r *ArgumentsLimitRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
    15  	if len(arguments) != 1 {
    16  		panic(`invalid configuration for "argument-limit"`)
    17  	}
    18  
    19  	total, ok := arguments[0].(int64) // Alt. non panicking version
    20  	if !ok {
    21  		panic(`invalid value passed as argument number to the "argument-list" rule`)
    22  	}
    23  
    24  	var failures []lint.Failure
    25  
    26  	walker := lintArgsNum{
    27  		total: int(total),
    28  		onFailure: func(failure lint.Failure) {
    29  			failures = append(failures, failure)
    30  		},
    31  	}
    32  
    33  	ast.Walk(walker, file.AST)
    34  
    35  	return failures
    36  }
    37  
    38  // Name returns the rule name.
    39  func (r *ArgumentsLimitRule) Name() string {
    40  	return "argument-limit"
    41  }
    42  
    43  type lintArgsNum struct {
    44  	total     int
    45  	onFailure func(lint.Failure)
    46  }
    47  
    48  func (w lintArgsNum) Visit(n ast.Node) ast.Visitor {
    49  	node, ok := n.(*ast.FuncDecl)
    50  	if ok {
    51  		num := 0
    52  		for _, l := range node.Type.Params.List {
    53  			for range l.Names {
    54  				num++
    55  			}
    56  		}
    57  		if num > w.total {
    58  			w.onFailure(lint.Failure{
    59  				Confidence: 1,
    60  				Failure:    fmt.Sprintf("maximum number of arguments per function exceeded; max %d but got %d", w.total, num),
    61  				Node:       node.Type,
    62  			})
    63  			return w
    64  		}
    65  	}
    66  	return w
    67  }