2018-06-16 11:50:59 +00:00
|
|
|
module Ameba::Rule::Lint
|
2017-10-31 22:47:29 +00:00
|
|
|
# A rule that disallows comparison to booleans.
|
|
|
|
#
|
|
|
|
# For example, these are considered invalid:
|
|
|
|
#
|
|
|
|
# ```
|
|
|
|
# foo == true
|
|
|
|
# bar != false
|
|
|
|
# false === baz
|
|
|
|
# ```
|
2017-11-14 07:24:36 +00:00
|
|
|
#
|
2017-10-31 22:47:29 +00:00
|
|
|
# This is because these expressions evaluate to `true` or `false`, so you
|
2017-11-01 10:23:12 +00:00
|
|
|
# could get the same result by using either the variable directly,
|
|
|
|
# or negating the variable.
|
2017-11-01 17:30:08 +00:00
|
|
|
#
|
2017-11-14 07:24:36 +00:00
|
|
|
# YAML configuration example:
|
|
|
|
#
|
|
|
|
# ```
|
2018-09-03 19:53:11 +00:00
|
|
|
# Lint/ComparisonToBoolean:
|
2017-11-14 07:24:36 +00:00
|
|
|
# Enabled: true
|
|
|
|
# ```
|
2021-01-18 15:45:35 +00:00
|
|
|
class ComparisonToBoolean < Base
|
2021-11-16 21:30:33 +00:00
|
|
|
include AST::Util
|
|
|
|
|
2017-11-22 06:44:29 +00:00
|
|
|
properties do
|
2018-05-03 15:57:47 +00:00
|
|
|
enabled false
|
|
|
|
description "Disallows comparison to booleans"
|
2017-11-22 06:44:29 +00:00
|
|
|
end
|
|
|
|
|
2021-01-17 16:49:45 +00:00
|
|
|
MSG = "Comparison to a boolean is pointless"
|
|
|
|
OP_NAMES = %w(== != ===)
|
2018-04-17 04:29:43 +00:00
|
|
|
|
2017-10-31 22:47:29 +00:00
|
|
|
def test(source, node : Crystal::Call)
|
2021-11-16 21:30:33 +00:00
|
|
|
return unless node.name.in?(OP_NAMES)
|
|
|
|
return unless node.args.size == 1
|
|
|
|
|
|
|
|
arg, obj = node.args.first, node.obj
|
|
|
|
case
|
|
|
|
when arg.is_a?(Crystal::BoolLiteral)
|
|
|
|
bool, exp = arg, obj
|
|
|
|
when obj.is_a?(Crystal::BoolLiteral)
|
|
|
|
bool, exp = obj, arg
|
|
|
|
end
|
|
|
|
|
|
|
|
return unless bool && exp
|
|
|
|
return unless exp_code = node_source(exp, source.lines)
|
|
|
|
|
|
|
|
not =
|
|
|
|
case node.name
|
|
|
|
when "==", "===" then !bool.value # foo == false
|
|
|
|
when "!=" then bool.value # foo != true
|
|
|
|
end
|
|
|
|
|
|
|
|
exp_code = "!#{exp_code}" if not
|
2017-11-07 21:40:06 +00:00
|
|
|
|
2021-11-16 21:30:33 +00:00
|
|
|
issue_for node, MSG do |corrector|
|
|
|
|
corrector.replace(node, exp_code)
|
|
|
|
end
|
2017-10-31 22:47:29 +00:00
|
|
|
end
|
2017-10-31 21:15:24 +00:00
|
|
|
end
|
|
|
|
end
|