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 }