class RuboCop::Cop::Style::IfWithBooleanLiteralBranches
Checks for redundant `if` with boolean literal branches. It checks only conditions to return boolean value (`true` or `false`) for safe detection. The conditions to be checked are comparison methods, predicate methods, and double negative. `nonzero?` method is allowed by default. These are customizable with `AllowedMethods` option.
@safety
Autocorrection is unsafe because there is no guarantee that all predicate methods will return a boolean value. Those methods can be allowed with `AllowedMethods` config.
@example
# bad if foo == bar true else false end # bad foo == bar ? true : false # good foo == bar
@example
# bad if foo.do_something? true else false end # good (but potentially an unsafe correction) foo.do_something?
@example AllowedMethods: ['nonzero?'] (default)
# good num.nonzero? ? true : false
Constants
- MSG
- MSG_FOR_ELSIF
Public Instance Methods
on_if(node)
click to toggle source
# File lib/rubocop/cop/style/if_with_boolean_literal_branches.rb, line 59 def on_if(node) return unless if_with_boolean_literal_branches?(node) condition = node.condition range, keyword = offense_range_with_keyword(node, condition) add_offense(range, message: message(node, keyword)) do |corrector| replacement = replacement_condition(node, condition) if node.elsif? corrector.insert_before(node, "else\n") corrector.replace(node, "#{indent(node.if_branch)}#{replacement}") else corrector.replace(node, replacement) end end end
Private Instance Methods
assume_boolean_value?(condition)
click to toggle source
# File lib/rubocop/cop/style/if_with_boolean_literal_branches.rb, line 109 def assume_boolean_value?(condition) return false unless condition.send_type? return false if allowed_method?(condition.method_name) condition.comparison_method? || condition.predicate_method? || double_negative?(condition) end
message(node, keyword)
click to toggle source
# File lib/rubocop/cop/style/if_with_boolean_literal_branches.rb, line 91 def message(node, keyword) message_template = node.elsif? ? MSG_FOR_ELSIF : MSG format(message_template, keyword: keyword) end
offense_range_with_keyword(node, condition)
click to toggle source
# File lib/rubocop/cop/style/if_with_boolean_literal_branches.rb, line 79 def offense_range_with_keyword(node, condition) if node.ternary? range = condition.source_range.end.join(node.source_range.end) [range, 'ternary operator'] else keyword = node.loc.keyword [keyword, "`#{keyword.source}`"] end end
opposite_condition?(node)
click to toggle source
# File lib/rubocop/cop/style/if_with_boolean_literal_branches.rb, line 126 def opposite_condition?(node) (!node.unless? && node.if_branch.false_type?) || (node.unless? && node.if_branch.true_type?) end
replacement_condition(node, condition)
click to toggle source
# File lib/rubocop/cop/style/if_with_boolean_literal_branches.rb, line 116 def replacement_condition(node, condition) bang = '!' if opposite_condition?(node) if bang && require_parentheses?(condition) "#{bang}(#{condition.source})" else "#{bang}#{condition.source}" end end
require_parentheses?(condition)
click to toggle source
# File lib/rubocop/cop/style/if_with_boolean_literal_branches.rb, line 131 def require_parentheses?(condition) condition.and_type? || condition.or_type? || (condition.send_type? && condition.comparison_method?) end
return_boolean_value?(condition)
click to toggle source
# File lib/rubocop/cop/style/if_with_boolean_literal_branches.rb, line 97 def return_boolean_value?(condition) if condition.begin_type? return_boolean_value?(condition.children.first) elsif condition.or_type? return_boolean_value?(condition.lhs) && return_boolean_value?(condition.rhs) elsif condition.and_type? return_boolean_value?(condition.rhs) else assume_boolean_value?(condition) end end