1
0
mirror of https://github.com/mgechev/revive.git synced 2025-04-15 11:36:48 +02:00

identical-branches initial implementation

This commit is contained in:
chavacava 2020-05-08 22:08:00 +02:00
parent 579c7c761f
commit 0c49c6a991
3 changed files with 150 additions and 0 deletions

View File

@ -0,0 +1,98 @@
package rule
import (
"go/ast"
"reflect"
"github.com/mgechev/revive/lint"
)
// IdenticalBranchesRule warns on constant logical expressions.
type IdenticalBranchesRule struct{}
// Apply applies the rule to given file.
func (r *IdenticalBranchesRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
onFailure := func(failure lint.Failure) {
failures = append(failures, failure)
}
astFile := file.AST
w := &lintIdenticalBranches{astFile, onFailure}
ast.Walk(w, astFile)
return failures
}
// Name returns the rule name.
func (r *IdenticalBranchesRule) Name() string {
return "identical-branches"
}
type lintIdenticalBranches struct {
file *ast.File
onFailure func(lint.Failure)
}
func (w *lintIdenticalBranches) Visit(node ast.Node) ast.Visitor {
n, ok := node.(*ast.IfStmt)
if !ok {
return w
}
if n.Else == nil {
return w
}
branches := []*ast.BlockStmt{n.Body}
elseBranch, ok := n.Else.(*ast.BlockStmt)
if !ok { // if-else-if construction
return w
}
branches = append(branches, elseBranch)
if w.identicalBranches(branches) {
w.newFailure(n, "both branches of the if are identical")
}
return w
}
func (w *lintIdenticalBranches) identicalBranches(branches []*ast.BlockStmt) bool {
if len(branches) < 2 {
return false
}
ref := gofmt(branches[0])
for i := 1; i < len(branches); i++ {
if gofmt(branches[i]) != ref {
return false
}
}
return true
}
func (w *lintIdenticalBranches) identicalBranches2(branches []*ast.BlockStmt) bool {
if len(branches) < 2 {
return false
}
ref := branches[0]
for i := 1; i < len(branches); i++ {
if !reflect.DeepEqual(branches[i], ref) {
return false
}
}
return true
}
func (w lintIdenticalBranches) newFailure(node ast.Node, msg string) {
w.onFailure(lint.Failure{
Confidence: 1,
Node: node,
Category: "logic",
Failure: msg,
})
}

View File

@ -0,0 +1,12 @@
package test
import (
"testing"
"github.com/mgechev/revive/rule"
)
// IdenticalBranches rule.
func TestIdenticalBranches(t *testing.T) {
testRule(t, "identical-branches", &rule.IdenticalBranchesRule{})
}

40
testdata/identical-branches.go vendored Normal file
View File

@ -0,0 +1,40 @@
package fixtures
func identicalBranches() {
if true { // MATCH /both branches of the if are identical/
} else {
}
if true {
}
if true {
print()
} else {
}
if true { // MATCH /both branches of the if are identical/
print()
} else {
print()
}
if true {
if true { // MATCH /both branches of the if are identical/
print()
} else {
print()
}
} else {
println()
}
if true {
println("something")
} else {
println("else")
}
}