class RuboCop::Cop::Performance::Sample::ShuffleAnalyzer
An internal class for representing a shuffle + method node analyzer.
def autocorrect
def autocorrect ->(corrector) { corrector.replace(source_range, correct) } end
def correct
def correct args = [sample_arg, shuffle_arg].compact.join(', ') args.empty? ? 'sample' : "sample(#{args})" end
def corrigible?
def corrigible? case method when :first, :last then true when :[] then sample_size != :unknown else false end end
def initialize(shuffle_node)
def initialize(shuffle_node) @shuffle_node = shuffle_node @method_node = shuffle_node.parent end
def message
def message format(MSG, correct: correct, incorrect: source_range.source) end
def method
def method method_node.to_a[1] end
def method_arg
def method_arg _, _, arg = *method_node arg.loc.expression.source if arg end
def offensive?
def offensive? shuffle_node.to_a[1] == :shuffle && corrigible? end
def range_size(range_node)
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
def sample_arg
def sample_arg case method when :first, :last then method_arg when :[] then sample_size end end
def sample_size
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
def shuffle_arg
def shuffle_arg _, _, arg = *shuffle_node arg.loc.expression.source if arg end
def source_range
def source_range Parser::Source::Range.new(shuffle_node.loc.expression.source_buffer, shuffle_node.loc.selector.begin_pos, method_node.loc.expression.end_pos) end