You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

error-return.go 1.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package rule
  2. import (
  3. "go/ast"
  4. "github.com/mgechev/revive/lint"
  5. )
  6. // ErrorReturnRule lints given else constructs.
  7. type ErrorReturnRule struct{}
  8. // Apply applies the rule to given file.
  9. func (r *ErrorReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
  10. var failures []lint.Failure
  11. fileAst := file.AST
  12. walker := lintErrorReturn{
  13. file: file,
  14. fileAst: fileAst,
  15. onFailure: func(failure lint.Failure) {
  16. failures = append(failures, failure)
  17. },
  18. }
  19. ast.Walk(walker, fileAst)
  20. return failures
  21. }
  22. // Name returns the rule name.
  23. func (r *ErrorReturnRule) Name() string {
  24. return "error-return"
  25. }
  26. type lintErrorReturn struct {
  27. file *lint.File
  28. fileAst *ast.File
  29. onFailure func(lint.Failure)
  30. }
  31. func (w lintErrorReturn) Visit(n ast.Node) ast.Visitor {
  32. fn, ok := n.(*ast.FuncDecl)
  33. if !ok || fn.Type.Results == nil {
  34. return w
  35. }
  36. ret := fn.Type.Results.List
  37. if len(ret) <= 1 {
  38. return w
  39. }
  40. if isIdent(ret[len(ret)-1].Type, "error") {
  41. return nil
  42. }
  43. // An error return parameter should be the last parameter.
  44. // Flag any error parameters found before the last.
  45. for _, r := range ret[:len(ret)-1] {
  46. if isIdent(r.Type, "error") {
  47. w.onFailure(lint.Failure{
  48. Category: "arg-order",
  49. Confidence: 0.9,
  50. Node: fn,
  51. Failure: "error should be the last type when returning multiple items",
  52. })
  53. break // only flag one
  54. }
  55. }
  56. return w
  57. }