class RuboCop::Cop::AlignmentCorrector

This class does auto-correction of nodes that should just be moved to the left or to the right, amount being determined by the instance variable column_delta.

Attributes

processed_source[R]

Public Class Methods

align_end(processed_source, node, align_to) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 30
def align_end(processed_source, node, align_to)
  @processed_source = processed_source
  whitespace = whitespace_range(node)
  return false unless whitespace.source.strip.empty?

  column = alignment_column(align_to)
  ->(corrector) { corrector.replace(whitespace, ' ' * column) }
end
correct(processed_source, node, column_delta) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 15
def correct(processed_source, node, column_delta)
  return unless node

  @processed_source = processed_source
  expr = node.respond_to?(:loc) ? node.loc.expression : node
  return if block_comment_within?(expr)

  lambda do |corrector|
    each_line(expr) do |line_begin_pos|
      autocorrect_line(corrector, line_begin_pos, expr, column_delta,
                       heredoc_ranges(node))
    end
  end
end

Private Class Methods

alignment_column(align_to) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 108
def alignment_column(align_to)
  if !align_to
    0
  elsif align_to.respond_to?(:loc)
    align_to.source_range.column
  else
    align_to.column
  end
end
autocorrect_line(corrector, line_begin_pos, expr, column_delta, heredoc_ranges) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 41
def autocorrect_line(corrector, line_begin_pos, expr, column_delta,
                     heredoc_ranges)
  range = calculate_range(expr, line_begin_pos, column_delta)
  # We must not change indentation of heredoc strings.
  return if heredoc_ranges.any? { |h| within?(range, h) }

  if column_delta.positive?
    unless range.source == "\n"
      # TODO: Fix ranges instead of using `begin`
      corrector.insert_before(range.begin, ' ' * column_delta)
    end
  elsif range.source =~ /\A[ \t]+\z/
    remove(range, corrector)
  end
end
block_comment_within?(expr) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 65
def block_comment_within?(expr)
  processed_source.comments.select(&:document?).any? do |c|
    within?(c.loc.expression, expr)
  end
end
calculate_range(expr, line_begin_pos, column_delta) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 71
def calculate_range(expr, line_begin_pos, column_delta)
  starts_with_space =
    expr.source_buffer.source[line_begin_pos].start_with?(' ')
  pos_to_remove = if column_delta.positive? || starts_with_space
                    line_begin_pos
                  else
                    line_begin_pos - column_delta.abs
                  end

  range_between(pos_to_remove, pos_to_remove + column_delta.abs)
end
each_line(expr) { |line_begin_pos| ... } click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 94
def each_line(expr)
  line_begin_pos = expr.begin_pos
  expr.source.each_line do |line|
    yield line_begin_pos
    line_begin_pos += line.length
  end
end
heredoc_ranges(node) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 57
def heredoc_ranges(node)
  return [] unless node.is_a?(Parser::AST::Node)

  node.each_node(:dstr)
      .select(&:heredoc?)
      .map { |n| n.loc.heredoc_body.join(n.loc.heredoc_end) }
end
remove(range, corrector) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 83
def remove(range, corrector)
  original_stderr = $stderr
  $stderr = StringIO.new # Avoid error messages on console
  corrector.remove(range)
rescue RuntimeError
  range = range_between(range.begin_pos + 1, range.end_pos + 1)
  retry if range.source =~ /^ +$/
ensure
  $stderr = original_stderr
end
whitespace_range(node) click to toggle source
# File lib/rubocop/cop/correctors/alignment_corrector.rb, line 102
def whitespace_range(node)
  begin_pos = node.loc.end.begin_pos

  range_between(begin_pos - node.loc.end.column, begin_pos)
end