github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/rule/constant-logical-expr.go (about) 1 package rule 2 3 import ( 4 "github.com/mgechev/revive/lint" 5 "go/ast" 6 "go/token" 7 ) 8 9 // ConstantLogicalExprRule warns on constant logical expressions. 10 type ConstantLogicalExprRule struct{} 11 12 // Apply applies the rule to given file. 13 func (r *ConstantLogicalExprRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { 14 var failures []lint.Failure 15 16 onFailure := func(failure lint.Failure) { 17 failures = append(failures, failure) 18 } 19 20 astFile := file.AST 21 w := &lintConstantLogicalExpr{astFile, onFailure} 22 ast.Walk(w, astFile) 23 return failures 24 } 25 26 // Name returns the rule name. 27 func (r *ConstantLogicalExprRule) Name() string { 28 return "constant-logical-expr" 29 } 30 31 type lintConstantLogicalExpr struct { 32 file *ast.File 33 onFailure func(lint.Failure) 34 } 35 36 func (w *lintConstantLogicalExpr) Visit(node ast.Node) ast.Visitor { 37 switch n := node.(type) { 38 case *ast.BinaryExpr: 39 if !w.isOperatorWithLogicalResult(n.Op) { 40 return w 41 } 42 43 if gofmt(n.X) != gofmt(n.Y) { // check if subexpressions are the same 44 return w 45 } 46 47 if n.Op == token.EQL { 48 w.newFailure(n, "expression always evaluates to true") 49 return w 50 } 51 52 if w.isInequalityOperator(n.Op) { 53 w.newFailure(n, "expression always evaluates to false") 54 return w 55 } 56 57 w.newFailure(n, "left and right hand-side sub-expressions are the same") 58 } 59 60 return w 61 } 62 63 func (w *lintConstantLogicalExpr) isOperatorWithLogicalResult(t token.Token) bool { 64 switch t { 65 case token.LAND, token.LOR, token.EQL, token.LSS, token.GTR, token.NEQ, token.LEQ, token.GEQ: 66 return true 67 } 68 69 return false 70 } 71 72 func (w *lintConstantLogicalExpr) isInequalityOperator(t token.Token) bool { 73 switch t { 74 case token.LSS, token.GTR, token.NEQ, token.LEQ, token.GEQ: 75 return true 76 } 77 78 return false 79 } 80 81 func (w lintConstantLogicalExpr) newFailure(node ast.Node, msg string) { 82 w.onFailure(lint.Failure{ 83 Confidence: 1, 84 Node: node, 85 Category: "logic", 86 Failure: msg, 87 }) 88 }