class RuboCop::Cop::InternalAffairs::ExampleHeredocDelimiter

Use ‘RUBY` for heredoc delimiter of example Ruby code.

Some editors may apply better syntax highlighting by using appropriate language names for the delimiter.

@example

# bad
expect_offense(<<~CODE)
  example_ruby_code
CODE

# good
expect_offense(<<~RUBY)
  example_ruby_code
RUBY

Constants

EXPECTED_HEREDOC_DELIMITER
MSG
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source

@param node [RuboCop::AST::SendNode] @return [void]

# File lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb, line 37
def on_send(node)
  heredoc_node = heredoc_node_from(node)
  return unless heredoc_node
  return if expected_heredoc_delimiter?(heredoc_node)
  return if expected_heredoc_delimiter_in_body?(heredoc_node)

  add_offense(heredoc_node) do |corrector|
    autocorrect(corrector, heredoc_node)
  end
end

Private Instance Methods

autocorrect(corrector, node) click to toggle source

@param corrector [RuboCop::Cop::Corrector] @param node [RuboCop::AST::StrNode] @return [void]

# File lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb, line 53
def autocorrect(corrector, node)
  [
    heredoc_opening_delimiter_range_from(node),
    heredoc_closing_delimiter_range_from(node)
  ].each do |range|
    corrector.replace(range, EXPECTED_HEREDOC_DELIMITER)
  end
end
expected_heredoc_delimiter?(node) click to toggle source

@param node [RuboCop::AST::StrNode] @return [Boolean]

# File lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb, line 72
def expected_heredoc_delimiter?(node)
  heredoc_delimiter_string_from(node) == EXPECTED_HEREDOC_DELIMITER
end
expected_heredoc_delimiter_in_body?(node) click to toggle source

@param node [RuboCop::AST::StrNode] @return [Boolean]

# File lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb, line 64
def expected_heredoc_delimiter_in_body?(node)
  node.location.heredoc_body.source.lines.any? do |line|
    line.strip == EXPECTED_HEREDOC_DELIMITER
  end
end
heredoc_closing_delimiter_range_from(node) click to toggle source

@param node [RuboCop::AST::StrNode] @return [Parser::Source::Range]

# File lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb, line 103
def heredoc_closing_delimiter_range_from(node)
  node.location.heredoc_end.end.adjust(
    begin_pos: -heredoc_delimiter_string_from(node).length
  )
end
heredoc_delimiter_string_from(node) click to toggle source

@param node [RuboCop::AST::StrNode] @return [String]

# File lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb, line 87
def heredoc_delimiter_string_from(node)
  node.source[Heredoc::OPENING_DELIMITER, 2]
end
heredoc_node_from(node) click to toggle source

@param node [RuboCop::AST::SendNode] @return [RuboCop::AST::StrNode, nil]

# File lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb, line 78
def heredoc_node_from(node)
  return unless node.first_argument.respond_to?(:heredoc?)
  return unless node.first_argument.heredoc?

  node.first_argument
end
heredoc_opening_delimiter_range_from(node) click to toggle source

@param node [RuboCop::AST::StrNode] @return [Parser::Source::Range]

# File lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb, line 93
def heredoc_opening_delimiter_range_from(node)
  match_data = node.source.match(Heredoc::OPENING_DELIMITER)
  node.source_range.begin.adjust(
    begin_pos: match_data.begin(2),
    end_pos: match_data.end(2)
  )
end