Skip to content

Commit

Permalink
refactor (rule/error-return): replace AST walker by iteration over d…
Browse files Browse the repository at this point in the history
…eclarations
  • Loading branch information
chavacava committed Dec 4, 2024
1 parent 09fb350 commit a3387c5
Showing 1 changed file with 27 additions and 43 deletions.
70 changes: 27 additions & 43 deletions rule/error_return.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}

0 comments on commit a3387c5

Please sign in to comment.