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

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