class RuboCop::Cop::Layout::ClosingHeredocIndentation


EOS
Hi
<<~EOS
foo arg,
# good
EOS
Hi
<<~EOS
foo arg,
# good
EOS
Hi
<<~EOS
foo arg,
# heredoc contents is before closing heredoc.
# bad
end
end
SQL
’Hi’
<<~SQL
def bar
class Foo
# good
end
end
SQL
’Hi’
<<~SQL
def bar
class Foo
# bad
@example
Checks the indentation of here document closings.

def autocorrect(node)

def autocorrect(node)
  lambda do |corrector|
    corrector.replace(node.loc.heredoc_end, indented_end(node))
  end
end

def closing_indentation(node)

def closing_indentation(node)
  indent_level(heredoc_closing(node))
end

def contents_indentation(node)

def contents_indentation(node)
  source_lines = node.loc.heredoc_body.source.split("\n")
  source_lines.reject(&:empty?).map do |line|
    indent_level(line)
  end.min
end

def find_node_used_heredoc_argument(node)

def find_node_used_heredoc_argument(node)
  if node.parent && node.parent.send_type?
    find_node_used_heredoc_argument(node.parent)
  else
    node
  end
end

def heredoc_closing(node)

def heredoc_closing(node)
  node.loc.heredoc_end.source_line
end

def heredoc_opening(node)

def heredoc_opening(node)
  node.loc.expression.source_line
end

def indent_level(source_line)

def indent_level(source_line)
  source_line[/\A */].length
end

def indented_end(node)

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

def message(node)

def message(node)
  format(
    node.argument? ? MSG_ARG : MSG,
    closing: heredoc_closing(node).strip,
    opening: heredoc_opening(node).strip
  )
end

def on_heredoc(node)

def on_heredoc(node)
  if node.loc.heredoc_body.source.empty? ||
     contents_indentation(node) >= closing_indentation(node)
    return if opening_indentation(node) == closing_indentation(node)
    return if node.argument? &&
              opening_indentation(
                find_node_used_heredoc_argument(node.parent)
              ) == closing_indentation(node)
  end
  add_offense(node, location: :heredoc_end)
end

def opening_indentation(node)

def opening_indentation(node)
  indent_level(heredoc_opening(node))
end