class RuboCop::Cop::Lint::EmptyConditionalBody
Checks for the presence of ‘if`, `elsif` and `unless` branches without a body.
NOTE: empty ‘else` branches are handled by `Style/EmptyElse`.
@safety
Autocorrection for this cop is not safe. The conditions for empty branches that the autocorrection removes may have side effects, or the logic in subsequent branches may change due to the removal of a previous condition.
@example
# bad if condition end # bad unless condition end # bad if condition do_something elsif other_condition end # good if condition do_something end # good unless condition do_something end # good if condition do_something elsif other_condition do_something_else end
@example AllowComments: true (default)
# good if condition do_something elsif other_condition # noop end
@example AllowComments: false
# bad if condition do_something elsif other_condition # noop end
Constants
- MSG
Public Instance Methods
on_if(node)
click to toggle source
rubocop:disable Metrics/AbcSize
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 71 def on_if(node) return if node.body || same_line?(node.loc.begin, node.loc.end) return if cop_config['AllowComments'] && contains_comments?(node) range = offense_range(node) add_offense(range, message: format(MSG, keyword: node.keyword)) do |corrector| next if node.parent&.call_type? autocorrect(corrector, node) end end
Private Instance Methods
all_branches_body_missing?(node)
click to toggle source
rubocop:enable Metrics/AbcSize
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 177 def all_branches_body_missing?(node) return false unless node.parent&.if_type? node.parent.branches.compact.empty? end
autocorrect(corrector, node)
click to toggle source
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 95 def autocorrect(corrector, node) remove_comments(corrector, node) remove_empty_branch(corrector, node) correct_other_branches(corrector, node) end
branch_range(node)
click to toggle source
rubocop:disable Metrics/AbcSize
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 163 def branch_range(node) if empty_if_branch?(node) && else_branch?(node) node.source_range.with(end_pos: node.loc.else.begin_pos) elsif node.loc.else node.source_range.with(end_pos: node.condition.source_range.end_pos) elsif all_branches_body_missing?(node) if_node = node.ancestors.detect(&:if?) node.source_range.join(if_node.loc.end.end) else node.source_range end end
correct_other_branches(corrector, node)
click to toggle source
rubocop:enable Metrics/AbcSize
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 125 def correct_other_branches(corrector, node) return unless require_other_branches_correction?(node) if node.else_branch&.if_type? && !node.else_branch.modifier_form? # Replace an orphaned `elsif` with `if` corrector.replace(node.else_branch.loc.keyword, 'if') else # Flip orphaned `else` corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}") end end
deletion_range(range)
click to toggle source
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 183 def deletion_range(range) # Collect a range between the start of the `if` node and the next relevant node, # including final new line. # Based on `RangeHelp#range_by_whole_lines` but allows the `if` to not start # on the first column. buffer = @processed_source.buffer last_line = buffer.source_line(range.last_line) end_offset = last_line.length - range.last_column + 1 range.adjust(end_pos: end_offset).intersect(buffer.source_range) end
else_branch?(node)
click to toggle source
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 158 def else_branch?(node) node.else_branch && !node.else_branch.if_type? end
empty_elsif_branch?(node)
click to toggle source
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 152 def empty_elsif_branch?(node) return false unless (else_branch = node.else_branch) else_branch.if_type? && !else_branch.body end
empty_if_branch?(node)
click to toggle source
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 144 def empty_if_branch?(node) return false unless (parent = node.parent) return true unless parent.if_type? return true unless (if_branch = parent.if_branch) if_branch.if_type? && !if_branch.body end
offense_range(node)
click to toggle source
rubocop:enable Metrics/AbcSize
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 87 def offense_range(node) if node.loc.else node.source_range.begin.join(node.loc.else.begin) else node.source_range end end
remove_comments(corrector, node)
click to toggle source
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 101 def remove_comments(corrector, node) comments_in_range(node).each do |comment| range = range_by_whole_lines(comment.source_range, include_final_newline: true) corrector.remove(range) end end
remove_empty_branch(corrector, node)
click to toggle source
rubocop:disable Metrics/AbcSize
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 109 def remove_empty_branch(corrector, node) range = if empty_if_branch?(node) && else_branch?(node) branch_range(node) elsif same_line?(node, else_kw_loc = node.loc.else) node.source_range.begin.join(else_kw_loc.begin) elsif node.parent&.loc.respond_to?(:end) && same_line?(node, end_loc = node.parent.loc.end) node.source_range.begin.join(end_loc.begin) else deletion_range(branch_range(node)) end corrector.remove(range) end
require_other_branches_correction?(node)
click to toggle source
# File lib/rubocop/cop/lint/empty_conditional_body.rb, line 137 def require_other_branches_correction?(node) return false unless node.if_type? && node.else? return false if !empty_if_branch?(node) && node.elsif? !empty_elsif_branch?(node) end