class RuboCop::Cop::Performance::CaseWhenSplat

end
baz
when 5
bar
when 1, 2, 3, 4
case foo
end
bar
when *condition
foobar
when baz
case foo
# good
end
baz
when 5
bar
when *[1, 2, 3, 4]
case foo
end
foobar
when baz
bar
when *condition
case foo
# bad
@example
and run slightly slower.
moving the splat condition to the end will use more memory,
hitting a condition in the splat expansion, it is possible that
processed by the ‘case` condition is normalized in a manner that favors
This is not a guaranteed performance improvement. If the data being
the expansion.
reduce the number of times that memory has to be allocated for
splat expansions at the end of the list of `when` branches we will
the order of the `when` branches does not matter. By placing any
fall through inside of `case` `when`, like some other languages do,
that the `case` `when` statement is run. Since Ruby does not support
Ruby has to allocate memory for the splat expansion every time
of the list of `when` branches.
Place `when` conditions that use splat at the end

def autocorrect(node)

def autocorrect(node)
  *conditions, _body = *node
  new_condition =
    conditions.each_with_object([]) do |condition, correction|
      variable, = *condition
      if variable.respond_to?(:array_type?) && variable.array_type?
        correction << expand_percent_array(variable)
        next
      end
      correction << condition.source
    end
  new_condition = new_condition.join(', ')
  lambda do |corrector|
    if needs_reorder?(conditions)
      reorder_condition(corrector, node, new_condition)
    else
      inline_fix_branch(corrector, node, conditions, new_condition)
    end
  end
end

def error_condition?(condition)

def error_condition?(condition)
  variable, = *condition
  (condition.splat_type? && variable.array_type?) ||
    !condition.splat_type?
end

def expand_percent_array(array)

def expand_percent_array(array)
  array_start = array.loc.begin.source
  elements = *array
  elements = elements.map(&:source)
  if array_start.start_with?(PERCENT_W)
    "'#{elements.join("', '")}'"
  elsif array_start.start_with?(PERCENT_CAPITAL_W)
    %("#{elements.join('", "')}")
  elsif array_start.start_with?(PERCENT_I)
    ":#{elements.join(', :')}"
  elsif array_start.start_with?(PERCENT_CAPITAL_I)
    %(:"#{elements.join('", :"')}")
  else
    elements.join(', ')
  end
end

def inline_fix_branch(corrector, node, conditions, new_condition)

def inline_fix_branch(corrector, node, conditions, new_condition)
  range =
    Parser::Source::Range.new(node.loc.expression.source_buffer,
                              conditions[0].loc.expression.begin_pos,
                              conditions[-1].loc.expression.end_pos)
  corrector.replace(range, new_condition)
end

def needs_reorder?(conditions)

def needs_reorder?(conditions)
  conditions.any? do |condition|
    variable, = *condition
    condition.splat_type? && !(variable && variable.array_type?)
  end
end

def new_branch_without_then(node, body, new_condition)

def new_branch_without_then(node, body, new_condition)
  "\n#{' ' * node.loc.column}when #{new_condition}\n" \
    "#{' ' * body.loc.column}#{node.children.last.source}"
end

def new_condition_with_then(node, new_condition)

def new_condition_with_then(node, new_condition)
  "\n#{' ' * node.loc.column}when " \
    "#{new_condition} then #{node.children.last.source}"
end

def on_case(node)

def on_case(node)
  _case_branch, *when_branches, _else_branch = *node
  when_conditions =
    when_branches.each_with_object([]) do |branch, conditions|
      *condition, _ = *branch
      condition.each { |c| conditions << c }
    end
  splat_offenses(when_conditions).reverse_each do |condition|
    range = condition.parent.loc.keyword.join(condition.source_range)
    variable, = *condition
    message = variable.array_type? ? ARRAY_MSG : MSG
    add_offense(condition.parent, range, message)
  end
end

def reorder_condition(corrector, node, new_condition)

def reorder_condition(corrector, node, new_condition)
  *_conditions, body = *node
  parent = node.parent
  _case_branch, *when_branches, _else_branch = *parent
  current_index = when_branches.index { |branch| branch == node }
  next_branch = when_branches[current_index + 1]
  range = Parser::Source::Range.new(parent,
                                    node.source_range.begin_pos,
                                    next_branch.source_range.begin_pos)
  corrector.remove(range)
  correction = if same_line?(node, body)
                 new_condition_with_then(node, new_condition)
               else
                 new_branch_without_then(node, body, new_condition)
               end
  corrector.insert_after(when_branches.last.source_range, correction)
end

def same_line?(node, other)

def same_line?(node, other)
  node.loc.first_line == other.loc.first_line
end

def splat_offenses(when_conditions)

def splat_offenses(when_conditions)
  found_non_splat = false
  when_conditions.reverse.each_with_object([]) do |condition, result|
    found_non_splat ||= error_condition?(condition)
    next unless condition.splat_type?
    result << condition if found_non_splat
  end
end