1
0
mirror of https://github.com/mgechev/revive.git synced 2024-12-02 09:02:23 +02:00
revive/rule/bool_literal_in_expr.go
2024-11-19 13:58:14 -08:00

93 lines
1.8 KiB
Go

package rule
import (
"go/ast"
"go/token"
"github.com/mgechev/revive/lint"
)
// BoolLiteralRule warns when logic expressions contains Boolean literals.
type BoolLiteralRule struct{}
// Apply applies the rule to given file.
func (*BoolLiteralRule) 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 := &lintBoolLiteral{astFile, onFailure}
ast.Walk(w, astFile)
return failures
}
// Name returns the rule name.
func (*BoolLiteralRule) Name() string {
return "bool-literal-in-expr"
}
type lintBoolLiteral struct {
file *ast.File
onFailure func(lint.Failure)
}
func (w *lintBoolLiteral) Visit(node ast.Node) ast.Visitor {
switch n := node.(type) {
case *ast.BinaryExpr:
if !isBoolOp(n.Op) {
return w
}
lexeme, ok := isExprABooleanLit(n.X)
if !ok {
lexeme, ok = isExprABooleanLit(n.Y)
if !ok {
return w
}
}
isConstant := (n.Op == token.LAND && lexeme == "false") || (n.Op == token.LOR && lexeme == "true")
if isConstant {
w.addFailure(n, "Boolean expression seems to always evaluate to "+lexeme, "logic")
} else {
w.addFailure(n, "omit Boolean literal in expression", "style")
}
}
return w
}
func (w lintBoolLiteral) addFailure(node ast.Node, msg, cat string) {
w.onFailure(lint.Failure{
Confidence: 1,
Node: node,
Category: cat,
Failure: msg,
})
}
// isBoolOp returns true if the given token corresponds to a bool operator.
func isBoolOp(t token.Token) bool {
switch t {
case token.LAND, token.LOR, token.EQL, token.NEQ:
return true
}
return false
}
func isExprABooleanLit(n ast.Node) (lexeme string, ok bool) {
oper, ok := n.(*ast.Ident)
if !ok {
return "", false
}
return oper.Name, (oper.Name == "true" || oper.Name == "false")
}