class RuboCop::Cop::Style::LineEndConcatenation

This cop checks for string literal concatenation at the end of a line.

@example

# bad
some_str = 'ala' +
           'bala'

some_str = 'ala' <<
           'bala'

# good
some_str = 'ala'             'bala'

Constants

COMPLEX_STRING_EDGE_TOKEN_TYPES
CONCAT_TOKEN_TYPES
HIGH_PRECEDENCE_OP_TOKEN_TYPES
MSG
QUOTE_DELIMITERS
SIMPLE_STRING_TOKEN_TYPE

Public Instance Methods

autocorrect(operator_range) click to toggle source
# File lib/rubocop/cop/style/line_end_concatenation.rb, line 38
def autocorrect(operator_range)
  # Include any trailing whitespace so we don't create a syntax error.
  operator_range = range_with_surrounding_space(operator_range,
                                                :right,
                                                !:with_newline)
  one_more_char = operator_range.resize(operator_range.size + 1)
  # Don't create a double backslash at the end of the line, in case
  # there already was a backslash after the concatenation operator.
  operator_range = one_more_char if one_more_char.source.end_with?('\')

  ->(corrector) { corrector.replace(operator_range, '\') }
end
investigate(processed_source) click to toggle source
# File lib/rubocop/cop/style/line_end_concatenation.rb, line 32
def investigate(processed_source)
  processed_source.tokens.each_index do |index|
    check_token_set(index)
  end
end

Private Instance Methods

check_token_set(index) click to toggle source
# File lib/rubocop/cop/style/line_end_concatenation.rb, line 53
def check_token_set(index)
  predecessor, operator, successor = processed_source.tokens[index, 3]
  return unless successor
  return unless CONCAT_TOKEN_TYPES.include?(operator.type)
  return unless standard_string_literal?(predecessor)
  return unless standard_string_literal?(successor)
  return if operator.pos.line == successor.pos.line

  next_successor = token_after_last_string(successor, index)
  return if next_successor &&
            HIGH_PRECEDENCE_OP_TOKEN_TYPES.include?(next_successor.type)

  add_offense(operator.pos, operator.pos)
end
standard_string_literal?(token) click to toggle source
# File lib/rubocop/cop/style/line_end_concatenation.rb, line 84
def standard_string_literal?(token)
  case token.type
  when SIMPLE_STRING_TOKEN_TYPE
    true
  when *COMPLEX_STRING_EDGE_TOKEN_TYPES
    QUOTE_DELIMITERS.include?(token.text)
  else
    false
  end
end
token_after_last_string(successor, base_index) click to toggle source
# File lib/rubocop/cop/style/line_end_concatenation.rb, line 68
def token_after_last_string(successor, base_index)
  index = base_index + 3
  begin_token, end_token = COMPLEX_STRING_EDGE_TOKEN_TYPES
  if successor.type == begin_token
    ends_to_find = 1
    while ends_to_find > 0
      case processed_source.tokens[index].type
      when begin_token then ends_to_find += 1
      when end_token then ends_to_find -= 1
      end
      index += 1
    end
  end
  processed_source.tokens[index]
end