class RuboCop::Cop::Lint::UselessTimes

Checks for uses of `Integer#times` that will never yield (when the integer <= 0) or that will only ever yield once (`1.times`).

@safety

This cop is unsafe as `times` returns its receiver, which is
*usually* OK, but might change behavior.

@example

# bad
-5.times { do_something }
0.times { do_something }
1.times { do_something  }
1.times { |i| do_something(i) }

# good
do_something
do_something(1)

Constants

MSG
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/lint/useless_times.rb, line 46
def on_send(node)
  return unless (count, proc_name = times_call?(node))
  return if count > 1

  # Get the block node if applicable
  node = node.block_node if node.block_literal?

  add_offense(node, message: format(MSG, count: count)) do |corrector|
    next if !own_line?(node) || node.parent&.send_type?

    autocorrect(corrector, count, node, proc_name)
  end
end

Private Instance Methods

autocorrect(corrector, count, node, proc_name) click to toggle source
# File lib/rubocop/cop/lint/useless_times.rb, line 62
def autocorrect(corrector, count, node, proc_name)
  if never_process?(count, node)
    remove_node(corrector, node)
  elsif !proc_name.empty?
    autocorrect_block_pass(corrector, node, proc_name)
  else
    autocorrect_block(corrector, node)
  end
end
autocorrect_block(corrector, node) click to toggle source
# File lib/rubocop/cop/lint/useless_times.rb, line 84
def autocorrect_block(corrector, node)
  block_arg = block_arg(node)
  return if block_reassigns_arg?(node, block_arg)

  source = node.body.source
  source.gsub!(/\b#{block_arg}\b/, '0') if block_arg

  corrector.replace(node, fix_indentation(source, node.loc.column...node.body.loc.column))
end
autocorrect_block_pass(corrector, node, proc_name) click to toggle source
# File lib/rubocop/cop/lint/useless_times.rb, line 80
def autocorrect_block_pass(corrector, node, proc_name)
  corrector.replace(node, proc_name)
end
fix_indentation(source, range) click to toggle source
# File lib/rubocop/cop/lint/useless_times.rb, line 94
def fix_indentation(source, range)
  # Cleanup indentation in a multiline block
  source_lines = source.split("\n")

  source_lines[1..].each do |line|
    next if line.empty?

    line[range] = ''
  end
  source_lines.join("\n")
end
never_process?(count, node) click to toggle source
# File lib/rubocop/cop/lint/useless_times.rb, line 72
def never_process?(count, node)
  count < 1 || (node.block_type? && node.body.nil?)
end
own_line?(node) click to toggle source
# File lib/rubocop/cop/lint/useless_times.rb, line 106
def own_line?(node)
  # If there is anything else on the line other than whitespace,
  # don't try to autocorrect
  processed_source.buffer.source_line(node.loc.line)[0...node.loc.column] !~ /\S/
end
remove_node(corrector, node) click to toggle source
# File lib/rubocop/cop/lint/useless_times.rb, line 76
def remove_node(corrector, node)
  corrector.remove(range_by_whole_lines(node.loc.expression, include_final_newline: true))
end