class RuboCop::Cop::Performance::Sample::ShuffleAnalyzer

An internal class for representing a shuffle + method node analyzer.

Attributes

method_node[R]
shuffle_node[R]

Public Class Methods

new(shuffle_node) click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 42
def initialize(shuffle_node)
  @shuffle_node = shuffle_node
  @method_node  = shuffle_node.parent
end

Public Instance Methods

autocorrect() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 47
def autocorrect
  ->(corrector) { corrector.replace(source_range, correct) }
end
message() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 51
def message
  format(MSG, correct: correct, incorrect: source_range.source)
end
offensive?() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 55
def offensive?
  shuffle_node.to_a[1] == :shuffle && corrigible?
end
source_range() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 59
def source_range
  Parser::Source::Range.new(shuffle_node.source_range.source_buffer,
                            shuffle_node.loc.selector.begin_pos,
                            method_node.source_range.end_pos)
end

Private Instance Methods

correct() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 69
def correct
  args = [sample_arg, shuffle_arg].compact.join(', ')
  args.empty? ? 'sample' : "sample(#{args})"
end
corrigible?() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 74
def corrigible?
  case method
  when :first, :last then true
  when :[]           then sample_size != :unknown
  else false
  end
end
method() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 82
def method
  method_node.to_a[1]
end
method_arg() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 86
def method_arg
  _, _, arg = *method_node
  arg.source if arg
end
range_size(range_node) click to toggle source

FIXME: use Range#size once Ruby 1.9 support is dropped

# File lib/rubocop/cop/performance/sample.rb, line 92
def range_size(range_node)
  vals = *range_node
  return :unknown unless vals.all?(&:int_type?)
  low, high = *vals.map(&:to_a).map(&:first)
  return :unknown unless low.zero? && high >= 0
  case range_node.type
  when :erange then high - low
  when :irange then high - low + 1
  end
end
sample_arg() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 103
def sample_arg
  case method
  when :first, :last then method_arg
  when :[]           then sample_size
  end
end
sample_size() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 110
def sample_size
  _, _, *args = *method_node
  case args.size
  when 1
    arg = args.first
    case arg.type
    when :erange, :irange then range_size(arg)
    when :int             then arg.to_a.first.zero? ? nil : :unknown
    else :unknown
    end
  when 2
    first, second = *args
    return :unknown unless first.int_type? && first.to_a.first.zero?
    second.int_type? ? second.to_a.first : :unknown
  end
end
shuffle_arg() click to toggle source
# File lib/rubocop/cop/performance/sample.rb, line 127
def shuffle_arg
  _, _, arg = *shuffle_node
  arg.source if arg
end