12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package rule
-
- import (
- "github.com/mgechev/revive/lint"
- "go/ast"
- "go/token"
- )
-
- // ConstantLogicalExprRule warns on constant logical expressions.
- type ConstantLogicalExprRule struct{}
-
- // Apply applies the rule to given file.
- func (r *ConstantLogicalExprRule) 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 := &lintConstantLogicalExpr{astFile, onFailure}
- ast.Walk(w, astFile)
- return failures
- }
-
- // Name returns the rule name.
- func (r *ConstantLogicalExprRule) Name() string {
- return "constant-logical-expr"
- }
-
- type lintConstantLogicalExpr struct {
- file *ast.File
- onFailure func(lint.Failure)
- }
-
- func (w *lintConstantLogicalExpr) Visit(node ast.Node) ast.Visitor {
- switch n := node.(type) {
- case *ast.BinaryExpr:
- if !w.isOperatorWithLogicalResult(n.Op) {
- return w
- }
-
- if gofmt(n.X) != gofmt(n.Y) { // check if subexpressions are the same
- return w
- }
-
- if n.Op == token.EQL {
- w.newFailure(n, "expression always evaluates to true")
- return w
- }
-
- if w.isInequalityOperator(n.Op) {
- w.newFailure(n, "expression always evaluates to false")
- return w
- }
-
- w.newFailure(n, "left and right hand-side sub-expressions are the same")
- }
-
- return w
- }
-
- func (w *lintConstantLogicalExpr) isOperatorWithLogicalResult(t token.Token) bool {
- switch t {
- case token.LAND, token.LOR, token.EQL, token.LSS, token.GTR, token.NEQ, token.LEQ, token.GEQ:
- return true
- }
-
- return false
- }
-
- func (w *lintConstantLogicalExpr) isInequalityOperator(t token.Token) bool {
- switch t {
- case token.LSS, token.GTR, token.NEQ, token.LEQ, token.GEQ:
- return true
- }
-
- return false
- }
-
- func (w lintConstantLogicalExpr) newFailure(node ast.Node, msg string) {
- w.onFailure(lint.Failure{
- Confidence: 1,
- Node: node,
- Category: "logic",
- Failure: msg,
- })
- }
|