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.

bare-return.go 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package rule
  2. import (
  3. "go/ast"
  4. "github.com/mgechev/revive/lint"
  5. )
  6. // BareReturnRule lints given else constructs.
  7. type BareReturnRule struct{}
  8. // Apply applies the rule to given file.
  9. func (r *BareReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
  10. var failures []lint.Failure
  11. onFailure := func(failure lint.Failure) {
  12. failures = append(failures, failure)
  13. }
  14. w := lintBareReturnRule{onFailure: onFailure}
  15. ast.Walk(w, file.AST)
  16. return failures
  17. }
  18. // Name returns the rule name.
  19. func (r *BareReturnRule) Name() string {
  20. return "bare-return"
  21. }
  22. type lintBareReturnRule struct {
  23. onFailure func(lint.Failure)
  24. }
  25. func (w lintBareReturnRule) Visit(node ast.Node) ast.Visitor {
  26. switch n := node.(type) {
  27. case *ast.FuncDecl:
  28. w.checkFunc(n.Type.Results, n.Body)
  29. case *ast.FuncLit: // to cope with deferred functions and go-routines
  30. w.checkFunc(n.Type.Results, n.Body)
  31. }
  32. return w
  33. }
  34. // checkFunc will verify if the given function has named result and bare returns
  35. func (w lintBareReturnRule) checkFunc(results *ast.FieldList, body *ast.BlockStmt) {
  36. hasNamedResults := results != nil && len(results.List) > 0 && results.List[0].Names != nil
  37. if !hasNamedResults || body == nil {
  38. return // nothing to do
  39. }
  40. brf := bareReturnFinder{w.onFailure}
  41. ast.Walk(brf, body)
  42. }
  43. type bareReturnFinder struct {
  44. onFailure func(lint.Failure)
  45. }
  46. func (w bareReturnFinder) Visit(node ast.Node) ast.Visitor {
  47. _, ok := node.(*ast.FuncLit)
  48. if ok {
  49. // skip analysing function literals
  50. // they will analyzed by the lintBareReturnRule.Visit method
  51. return nil
  52. }
  53. rs, ok := node.(*ast.ReturnStmt)
  54. if !ok {
  55. return w
  56. }
  57. if len(rs.Results) > 0 {
  58. return w
  59. }
  60. w.onFailure(lint.Failure{
  61. Confidence: 1,
  62. Node: rs,
  63. Failure: "avoid using bare returns, please add return expressions",
  64. })
  65. return w
  66. }