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
See for more details: github.com/rubocop/rubocop/pull/6163<br>and run slightly slower.
it is possible that moving the splat condition to the end will use more memory,
normalized in a manner that favors hitting a condition in the splat expansion,
performance improvement. If the data being processed by the ‘case` condition is
This cop is not unsafe autocorrection because it is not a guaranteed
@safety
that is inside of the splat expansion.
this defining a higher level when condition to override a condition
conditions can be true for any given condition. A likely scenario for
the expansion. The exception to this is if multiple of your `when`
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 should 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 `when` branches can improve performance.
Reordering `when` conditions with a splat to the end

def autocorrect(corrector, when_node)

def autocorrect(corrector, when_node)
  if needs_reorder?(when_node)
    reorder_condition(corrector, when_node)
  else
    inline_fix_branch(corrector, when_node)
  end
end

def indent_for(node)

def indent_for(node)
  ' ' * node.loc.column
end

def inline_fix_branch(corrector, when_node)

def inline_fix_branch(corrector, when_node)
  conditions = when_node.conditions
  range = range_between(conditions[0].source_range.begin_pos, conditions[-1].source_range.end_pos)
  corrector.replace(range, replacement(conditions))
end

def needs_reorder?(when_node)

def needs_reorder?(when_node)
  following_branches = when_node.parent.when_branches[(when_node.branch_index + 1)..]
  following_branches.any? do |when_branch|
    when_branch.conditions.any? do |condition|
      non_splat?(condition)
    end
  end
end

def new_branch_without_then(node, new_condition)

def new_branch_without_then(node, new_condition)
  new_branch = "\n#{indent_for(node)}when #{new_condition}\n"
  if node.body
    "#{new_branch}#{indent_for(node.body)}#{node.body.source}"
  else
    new_branch
  end
end

def new_condition_with_then(node, new_condition)

def new_condition_with_then(node, new_condition)
  "\n#{indent_for(node)}when #{new_condition} then #{node.body.source}"
end

def non_splat?(condition)

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

def on_case(case_node)

def on_case(case_node)
  when_conditions = case_node.when_branches.flat_map(&:conditions)
  splat_offenses(when_conditions).reverse_each do |condition|
    next if ignored_node?(condition.parent)
    ignore_node(condition.parent)
    variable, = *condition
    message = variable.array_type? ? ARRAY_MSG : MSG
    add_offense(range(condition), message: message) do |corrector|
      autocorrect(corrector, condition.parent)
    end
  end
end

def range(node)

def range(node)
  node.parent.loc.keyword.join(node.source_range)
end

def reorder_condition(corrector, when_node)

def reorder_condition(corrector, when_node)
  when_branches = when_node.parent.when_branches
  return if when_branches.one?
  corrector.remove(when_branch_range(when_node))
  corrector.insert_after(when_branches.last, reordering_correction(when_node))
end

def reordering_correction(when_node)

def reordering_correction(when_node)
  new_condition = replacement(when_node.conditions)
  condition =
    if same_line?(when_node, when_node.body)
      new_condition_with_then(when_node, new_condition)
    else
      new_branch_without_then(when_node, new_condition)
    end
  condition_comments = comments_in_range(when_node).map do |comment_node|
    "#{indent_for(comment_node)}#{comment_node.source}"
  end.join("\n")
  "#{condition}#{condition_comments}"
end

def replacement(conditions)

def replacement(conditions)
  reordered = conditions.partition(&:splat_type?).reverse
  reordered.flatten.map(&:source).join(', ')
end

def splat_offenses(when_conditions)

def splat_offenses(when_conditions)
  found_non_splat = false
  offenses = when_conditions.reverse.map do |condition|
    found_non_splat ||= non_splat?(condition)
    next if non_splat?(condition)
    condition if found_non_splat
  end
  offenses.compact
end

def when_branch_range(when_node)

def when_branch_range(when_node)
  next_branch = when_node.parent.when_branches[when_node.branch_index + 1]
  range_between(when_node.source_range.begin_pos, next_branch.source_range.begin_pos)
end