github.com/songshiyun/revive@v1.1.5-0.20220323112655-f8433a19b3c5/rule/function-result-limit.go (about)

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