class RuboCop::Cop::Layout::ClosingHeredocIndentation

Checks the indentation of here document closings.

@example

# bad
class Foo
  def bar
    <<~SQL
      'Hi'
  SQL
  end
end

# good
class Foo
  def bar
    <<~SQL
      'Hi'
    SQL
  end
end

# bad

# heredoc contents is before closing heredoc.
foo arg,
    <<~EOS
  Hi
    EOS

# good
foo arg,
    <<~EOS
  Hi
EOS

# good
foo arg,
    <<~EOS
      Hi
    EOS

Constants

MSG
MSG_ARG
SIMPLE_HEREDOC

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 65
def autocorrect(node)
  lambda do |corrector|
    corrector.replace(node.loc.heredoc_end, indented_end(node))
  end
end
on_heredoc(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 57
def on_heredoc(node)
  return if heredoc_type(node) == SIMPLE_HEREDOC ||
            opening_indentation(node) == closing_indentation(node) ||
            argument_indentation_correct?(node)

  add_offense(node, location: :heredoc_end)
end

Private Instance Methods

argument_indentation_correct?(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 77
def argument_indentation_correct?(node)
  return unless node.argument? || node.chained?

  opening_indentation(
    find_node_used_heredoc_argument(node.parent)
  ) == closing_indentation(node)
end
closing_indentation(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 85
def closing_indentation(node)
  indent_level(heredoc_closing(node))
end
find_node_used_heredoc_argument(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 104
def find_node_used_heredoc_argument(node)
  if node.parent&.send_type?
    find_node_used_heredoc_argument(node.parent)
  else
    node
  end
end
heredoc_closing(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 93
def heredoc_closing(node)
  node.loc.heredoc_end.source_line
end
heredoc_opening(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 89
def heredoc_opening(node)
  node.loc.expression.source_line
end
indent_level(source_line) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 120
def indent_level(source_line)
  source_line[/\A */].length
end
indented_end(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 97
def indented_end(node)
  closing_indent = closing_indentation(node)
  opening_indent = opening_indentation(node)
  closing_text = heredoc_closing(node)
  closing_text.gsub(/^\s{#{closing_indent}}/, ' ' * opening_indent)
end
message(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 112
def message(node)
  format(
    node.argument? ? MSG_ARG : MSG,
    closing: heredoc_closing(node).strip,
    opening: heredoc_opening(node).strip
  )
end
opening_indentation(node) click to toggle source
# File lib/rubocop/cop/layout/closing_heredoc_indentation.rb, line 73
def opening_indentation(node)
  indent_level(heredoc_opening(node))
end