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.

identical-branches.go 1.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package rule
  2. import (
  3. "go/ast"
  4. "github.com/mgechev/revive/lint"
  5. )
  6. // IdenticalBranchesRule warns on constant logical expressions.
  7. type IdenticalBranchesRule struct{}
  8. // Apply applies the rule to given file.
  9. func (r *IdenticalBranchesRule) 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. astFile := file.AST
  15. w := &lintIdenticalBranches{astFile, onFailure}
  16. ast.Walk(w, astFile)
  17. return failures
  18. }
  19. // Name returns the rule name.
  20. func (r *IdenticalBranchesRule) Name() string {
  21. return "identical-branches"
  22. }
  23. type lintIdenticalBranches struct {
  24. file *ast.File
  25. onFailure func(lint.Failure)
  26. }
  27. func (w *lintIdenticalBranches) Visit(node ast.Node) ast.Visitor {
  28. n, ok := node.(*ast.IfStmt)
  29. if !ok {
  30. return w
  31. }
  32. if n.Else == nil {
  33. return w
  34. }
  35. branches := []*ast.BlockStmt{n.Body}
  36. elseBranch, ok := n.Else.(*ast.BlockStmt)
  37. if !ok { // if-else-if construction
  38. return w
  39. }
  40. branches = append(branches, elseBranch)
  41. if w.identicalBranches(branches) {
  42. w.newFailure(n, "both branches of the if are identical")
  43. }
  44. return w
  45. }
  46. func (w *lintIdenticalBranches) identicalBranches(branches []*ast.BlockStmt) bool {
  47. if len(branches) < 2 {
  48. return false
  49. }
  50. ref := gofmt(branches[0])
  51. for i := 1; i < len(branches); i++ {
  52. if gofmt(branches[i]) != ref {
  53. return false
  54. }
  55. }
  56. return true
  57. }
  58. func (w lintIdenticalBranches) newFailure(node ast.Node, msg string) {
  59. w.onFailure(lint.Failure{
  60. Confidence: 1,
  61. Node: node,
  62. Category: "logic",
  63. Failure: msg,
  64. })
  65. }