class RuboCop::Cop::Layout::LineEndStringConcatenationIndentation

Checks the indentation of the next line after a line that ends with a string literal and a backslash.

If ‘EnforcedStyle: aligned` is set, the concatenated string parts shall be aligned with the first part. There are some exceptions, such as implicit return values, where the concatenated string parts shall be indented regardless of `EnforcedStyle` configuration.

If ‘EnforcedStyle: indented` is set, it’s the second line that shall be indented one step more than the first line. Lines 3 and forward shall be aligned with line 2.

@example

# bad
def some_method
  'x' \
  'y' \
  'z'
end

my_hash = {
  first: 'a message' \
    'in two parts'
}

# good
def some_method
  'x' \
    'y' \
    'z'
end

@example EnforcedStyle: aligned (default)

# bad
puts 'x' \
  'y'

my_hash = {
  first: 'a message' \
    'in two parts'
}

# good
puts 'x' \
     'y'

my_hash = {
  first: 'a message' \
         'in two parts'
}

@example EnforcedStyle: indented

# bad
result = 'x' \
         'y'

my_hash = {
  first: 'a message' \
         'in two parts'
}

# good
result = 'x' \
  'y'

my_hash = {
  first: 'a message' \
    'in two parts'
}

Constants

MSG_ALIGN
MSG_INDENT
PARENT_TYPES_FOR_INDENTED

Public Instance Methods

autocorrect(corrector, node) click to toggle source
# File lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb, line 95
def autocorrect(corrector, node)
  AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
end
on_dstr(node) click to toggle source
# File lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb, line 83
def on_dstr(node)
  return unless strings_concatenated_with_backslash?(node)

  children = node.children
  if style == :aligned && !always_indented?(node)
    check_aligned(children, 1)
  else
    check_indented(children)
    check_aligned(children, 2)
  end
end

Private Instance Methods

add_offense_and_correction(node, message) click to toggle source
# File lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb, line 135
def add_offense_and_correction(node, message)
  add_offense(node, message: message) { |corrector| autocorrect(corrector, node) }
end
always_indented?(dstr_node) click to toggle source
# File lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb, line 107
def always_indented?(dstr_node)
  PARENT_TYPES_FOR_INDENTED.include?(dstr_node.parent&.type)
end
base_column(child) click to toggle source
# File lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb, line 126
def base_column(child)
  grandparent = child.parent.parent
  if grandparent&.type == :pair
    grandparent.loc.column
  else
    child.source_range.source_line =~ /\S/
  end
end
check_aligned(children, start_index) click to toggle source
# File lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb, line 111
def check_aligned(children, start_index)
  base_column = children[start_index - 1].loc.column
  children[start_index..].each do |child|
    @column_delta = base_column - child.loc.column
    add_offense_and_correction(child, MSG_ALIGN) if @column_delta != 0
    base_column = child.loc.column
  end
end
check_indented(children) click to toggle source
# File lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb, line 120
def check_indented(children)
  @column_delta = base_column(children[0]) + configured_indentation_width -
                  children[1].loc.column
  add_offense_and_correction(children[1], MSG_INDENT) if @column_delta != 0
end
strings_concatenated_with_backslash?(dstr_node) click to toggle source
# File lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb, line 101
def strings_concatenated_with_backslash?(dstr_node)
  dstr_node.multiline? &&
    dstr_node.children.all? { |c| c.str_type? || c.dstr_type? } &&
    dstr_node.children.none?(&:multiline?)
end