class RuboCop::Cop::Style::NonNilCheck
end
if !x.nil?
# bad
@example IncludeSemanticChanges: true
end
if !x.nil?
# good
@example IncludeSemanticChanges: false (default)
end
!current_user.nil?
def signed_in?
# good
# Non-nil checks are allowed if they are the final nodes of predicate.
end
if x
# good
end
if x != nil
# bad
@example
is usually OK, but might change behavior.
for ‘!x.nil?` and autocorrects that and `x != nil` to solely `x`, which
With `IncludeSemanticChanges` set to `true`, this cop reports offenses
change behavior.
does not report offenses for `!x.nil?` and does no changes that might
With `IncludeSemanticChanges` set to `false` by default, this cop
This cop checks for non-nil checks, which are usually redundant.
def autocorrect(corrector, node)
def autocorrect(corrector, node) case node.method_name when :!= autocorrect_comparison(corrector, node) when :! autocorrect_non_nil(corrector, node, node.receiver) when :nil? autocorrect_unless_nil(corrector, node, node.receiver) end end
def autocorrect_comparison(corrector, node)
def autocorrect_comparison(corrector, node) expr = node.source new_code = if include_semantic_changes? expr.sub(/\s*!=\s*nil/, '') else expr.sub(/^(\S*)\s*!=\s*nil/, '!\1.nil?') end return if expr == new_code corrector.replace(node, new_code) end
def autocorrect_non_nil(corrector, node, inner_node)
def autocorrect_non_nil(corrector, node, inner_node) if inner_node.receiver corrector.replace(node, inner_node.receiver.source) else corrector.replace(node, 'self') end end
def autocorrect_unless_nil(corrector, node, receiver)
def autocorrect_unless_nil(corrector, node, receiver) corrector.replace(node.parent.loc.keyword, 'if') corrector.replace(node, receiver.source) end
def find_offense_node(node)
def find_offense_node(node) if not_equal_to_nil?(node) node.loc.selector elsif include_semantic_changes? && (not_and_nil_check?(node) || unless_and_nil_check?(node)) node end end
def include_semantic_changes?
def include_semantic_changes? cop_config['IncludeSemanticChanges'] end
def message(node)
def message(node) if node.method?(:!=) 'Prefer `!expression.nil?` over `expression != nil`.' else 'Explicit non-nil checks are usually redundant.' end end
def on_def(node)
def on_def(node) body = node.body return unless node.predicate_method? && body if body.begin_type? ignore_node(body.children.last) else ignore_node(body) end end
def on_send(node)
def on_send(node) return if ignored_node?(node) return unless (offense_node = find_offense_node(node)) message = message(node) add_offense(offense_node, message: message) do |corrector| autocorrect(corrector, node) end end
def unless_and_nil_check?(send_node)
def unless_and_nil_check?(send_node) parent = send_node.parent nil_check?(send_node) && unless_check?(parent) && !parent.ternary? && parent.unless? end