123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::Cop::EachToForCorrector

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Macros
Inherits: Object
Defined in: lib/rubocop/cop/correctors/each_to_for_corrector.rb

Overview

This class autocorrects #each enumeration to for iteration.

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(block_node) ⇒ EachToForCorrector

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 12

def initialize(block_node)
  @block_node = block_node
  @collection_node = block_node.receiver
  @argument_node = block_node.arguments
end

Instance Attribute Details

#argument_node (readonly, private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 25

attr_reader :block_node, :collection_node, :argument_node

#block_node (readonly, private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 25

attr_reader :block_node, :collection_node, :argument_node

#collection_node (readonly, private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 25

attr_reader :block_node, :collection_node, :argument_node

Instance Method Details

#call(corrector)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 18

def call(corrector)
  corrector.replace(offending_range, correction)
  corrector.replace(block_node.loc.end, closing_keyword) if block_node.braces?
end

#closing_keyword (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 56

def closing_keyword
  padding_needed?(block_node.loc.end.begin_pos - 1) ? ' end' : 'end'
end

#correction (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 27

def correction
  keyword = if block_node.arguments?
              format(
                CORRECTION_WITH_ARGUMENTS,
                collection: collection_node.source,
                variables: loop_variables
              )
            else
              format(CORRECTION_WITHOUT_ARGUMENTS, enumerable: collection_node.source)
            end

  padding_needed?(offending_range.end_pos) ? "#{keyword} " : keyword
end

#loop_variable(argument) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 47

def loop_variable(argument)
  return argument.source unless argument.mlhs_type?

  variables = argument.children.map { |child| loop_variable(child) }.join(', ')
  lone_target = argument.children.one? && !argument.children.first.restarg_type?

  lone_target ? "(#{variables},)" : "(#{variables})"
end

#loop_variables (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 41

def loop_variables
  variables = argument_node.children.map { |argument| loop_variable(argument) }.join(', ')

  argument_node.source.match?(/,\s*\|\z/) ? "#{variables}," : variables
end

#offending_range (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 66

def offending_range
  begin_range = block_node.source_range.begin

  if block_node.arguments?
    begin_range.join(argument_node.source_range.end)
  else
    begin_range.join(block_node.loc.begin.end)
  end
end

#padding_needed?(position) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/each_to_for_corrector.rb', line 60

def padding_needed?(position)
  character = block_node.source_range.source_buffer.source[position]

  !character.nil? && !character.match?(/\s/)
end