From a3387c58db5bb8215fc20988188b1c8bb3a60834 Mon Sep 17 00:00:00 2001 From: chavacava Date: Wed, 4 Dec 2024 08:30:23 +0100 Subject: [PATCH] refactor (rule/error-return): replace AST walker by iteration over declarations --- rule/error_return.go | 70 +++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/rule/error_return.go b/rule/error_return.go index f26d807dd..c5d3f46c4 100644 --- a/rule/error_return.go +++ b/rule/error_return.go @@ -13,16 +13,34 @@ type ErrorReturnRule struct{} func (*ErrorReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { var failures []lint.Failure - fileAst := file.AST - walker := lintErrorReturn{ - file: file, - fileAst: fileAst, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } + for _, decl := range file.AST.Decls { + funcDecl, ok := decl.(*ast.FuncDecl) + isFunctionWithMoreThanOneResult := ok && funcDecl.Type.Results != nil && len(funcDecl.Type.Results.List) > 1 + if !isFunctionWithMoreThanOneResult { + continue + } + + funcResults := funcDecl.Type.Results.List + isLastResultError := isIdent(funcResults[len(funcResults)-1].Type, "error") + if isLastResultError { + continue + } - ast.Walk(walker, fileAst) + // An error return parameter should be the last parameter. + // Flag any error parameters found before the last. + for _, r := range funcResults[:len(funcResults)-1] { + if isIdent(r.Type, "error") { + failures = append(failures, lint.Failure{ + Category: "style", + Confidence: 0.9, + Node: funcDecl, + Failure: "error should be the last type when returning multiple items", + }) + + break // only flag one + } + } + } return failures } @@ -31,37 +49,3 @@ func (*ErrorReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure func (*ErrorReturnRule) Name() string { return "error-return" } - -type lintErrorReturn struct { - file *lint.File - fileAst *ast.File - onFailure func(lint.Failure) -} - -func (w lintErrorReturn) Visit(n ast.Node) ast.Visitor { - fn, ok := n.(*ast.FuncDecl) - if !ok || fn.Type.Results == nil { - return w - } - ret := fn.Type.Results.List - if len(ret) <= 1 { - return w - } - if isIdent(ret[len(ret)-1].Type, "error") { - return nil - } - // An error return parameter should be the last parameter. - // Flag any error parameters found before the last. - for _, r := range ret[:len(ret)-1] { - if isIdent(r.Type, "error") { - w.onFailure(lint.Failure{ - Category: "arg-order", - Confidence: 0.9, - Node: fn, - Failure: "error should be the last type when returning multiple items", - }) - break // only flag one - } - } - return w -}