class RuboCop::Cop::Layout::DotPosition

method
something.
# good
.method
something
# bad
@example EnforcedStyle: trailing
.method
something
# good
method
something.
# bad
@example EnforcedStyle: leading (default)
Checks the . position in multi-line method calls.

def self.autocorrect_incompatible_with

def self.autocorrect_incompatible_with
  [Style::RedundantSelf]
end

def ampersand_dot?(node)

def ampersand_dot?(node)
  node.loc.respond_to?(:dot) && node.loc.dot && node.loc.dot.is?('&.')
end

def autocorrect(corrector, dot, node)

def autocorrect(corrector, dot, node)
  dot_range = if processed_source[dot.line - 1].strip == '.'
                range_by_whole_lines(dot, include_final_newline: true)
              else
                dot
              end
  corrector.remove(dot_range)
  case style
  when :leading
    corrector.insert_before(selector_range(node), dot.source)
  when :trailing
    corrector.insert_after(node.receiver, dot.source)
  end
end

def correct_dot_position_style?(dot_line, selector_line)

def correct_dot_position_style?(dot_line, selector_line)
  case style
  when :leading then dot_line == selector_line
  when :trailing then dot_line != selector_line
  end
end

def end_range(node)

def end_range(node)
  node.source_range.end
end

def heredoc?(node)

def heredoc?(node)
  (node.str_type? || node.dstr_type?) && node.heredoc?
end

def last_heredoc_line(node)

def last_heredoc_line(node)
  if node.send_type?
    node.arguments.select { |arg| heredoc?(arg) }.map { |arg| arg.loc.heredoc_end.line }.max
  elsif heredoc?(node)
    node.loc.heredoc_end.line
  end
end

def line_between?(first_line, second_line)

def line_between?(first_line, second_line)
  (first_line - second_line) > 1
end

def message(dot)

def message(dot)
  "Place the #{dot.source} on the " +
    case style
    when :leading
      'next line, together with the method name.'
    when :trailing
      'previous line, together with the method call receiver.'
    end
end

def on_send(node)

def on_send(node)
  return unless node.dot? || ampersand_dot?(node)
  return correct_style_detected if proper_dot_position?(node)
  opposite_style_detected
  dot = node.loc.dot
  message = message(dot)
  add_offense(dot, message: message) { |corrector| autocorrect(corrector, dot, node) }
end

def proper_dot_position?(node)

def proper_dot_position?(node)
  selector_range = selector_range(node)
  return true if same_line?(selector_range, end_range(node.receiver))
  selector_line = selector_range.line
  receiver_line = receiver_end_line(node.receiver)
  dot_line = node.loc.dot.line
  # don't register an offense if there is a line comment between the
  # dot and the selector otherwise, we might break the code while
  # "correcting" it (even if there is just an extra blank line, treat
  # it the same)
  # Also, in the case of a heredoc, the receiver will end after the dot,
  # because the heredoc body is on subsequent lines, so use the highest
  # line to compare to.
  return true if line_between?(selector_line, [receiver_line, dot_line].max)
  correct_dot_position_style?(dot_line, selector_line)
end

def receiver_end_line(node)

def receiver_end_line(node)
  if (line = last_heredoc_line(node))
    line
  else
    node.source_range.end.line
  end
end

def selector_range(node)

def selector_range(node)
  return node unless node.call_type?
  # l.(1) has no selector, so we use the opening parenthesis instead
  node.loc.selector || node.loc.begin
end