Class: RuboCop::Cop::Performance::CaseWhenSplat
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
AutoCorrector,
Base
|
|
Instance Chain:
self,
RangeHelp,
Alignment,
Base
|
|
Inherits: |
Base
|
Defined in: | lib/rubocop/cop/performance/case_when_splat.rb |
Overview
Reordering when
conditions with a splat to the end
of the when
branches can improve performance.
Ruby has to allocate memory for the splat expansion every time
that the case
when
statement is run. Since Ruby does not support
fall through inside of case
when
, like some other languages do,
the order of the when
branches should not matter. By placing any
splat expansions at the end of the list of when
branches we will
reduce the number of times that memory has to be allocated for
the expansion. The exception to this is if multiple of your when
conditions can be true for any given condition. A likely scenario for
this defining a higher level when condition to override a condition
that is inside of the splat expansion.
Constant Summary
-
ARRAY_MSG =
# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 64'Pass the contents of array literals directly to `when` conditions.'
-
MSG =
# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 63'Reordering `when` conditions with a splat to the end of the `when` branches can improve performance.'
Instance Method Summary
- #on_case(case_node)
- #autocorrect(corrector, when_node) private
- #indent_for(node) private
- #inline_fix_branch(corrector, when_node) private
- #needs_reorder?(when_node) ⇒ Boolean private
- #new_branch_without_then(node, new_condition) private
- #new_condition_with_then(node, new_condition) private
- #non_splat?(condition) ⇒ Boolean private
- #range(node) private
- #reorder_condition(corrector, when_node) private
- #reordering_correction(when_node) private
- #replacement(conditions) private
- #splat_offenses(when_conditions) private
- #when_branch_range(when_node) private
Instance Method Details
#autocorrect(corrector, when_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 83
def autocorrect(corrector, when_node) if needs_reorder?(when_node) reorder_condition(corrector, when_node) else inline_fix_branch(corrector, when_node) end end
#indent_for(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 140
def indent_for(node) ' ' * node.loc.column end
#inline_fix_branch(corrector, when_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 100
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
#needs_reorder?(when_node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 164
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
#new_branch_without_then(node, new_condition) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 136
def new_branch_without_then(node, new_condition) "\n#{indent_for(node)}when #{new_condition}\n#{indent_for(node.body)}#{node.body.source}" end
#new_condition_with_then(node, new_condition) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 132
def new_condition_with_then(node, new_condition) "\n#{indent_for(node)}when #{new_condition} then #{node.body.source}" end
#non_splat?(condition) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 158
def non_splat?(condition) variable, = *condition (condition.splat_type? && variable.array_type?) || !condition.splat_type? end
#on_case(case_node)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 66
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 = variable.array_type? ? ARRAY_MSG : MSG add_offense(range(condition), message: ) do |corrector| autocorrect(corrector, condition.parent) end end end
#range(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 91
def range(node) node.parent.loc.keyword.join(node.source_range) end
#reorder_condition(corrector, when_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 107
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
#reordering_correction(when_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 116
def reordering_correction(when_node) new_condition = replacement(when_node.conditions) 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 end
#replacement(conditions) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 95
def replacement(conditions) reordered = conditions.partition(&:splat_type?).reverse reordered.flatten.map(&:source).join(', ') end
#splat_offenses(when_conditions) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 144
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
#when_branch_range(when_node) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 126
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