class RuboCop::Cop::Style::CommentedKeyword

end
y
class X # :nodoc:
# good
end
statement
if condition
# good
def x; end # comment
# bad
end
statement
class X # comment
# bad
end # end if
statement
if condition
# bad
@example
allowed.
Note that some comments (such as ‘:nodoc:` and `rubocop:disable`) are
These keywords are: `begin`, `class`, `def`, `end`, `module`.
This cop checks for comments put on the same line as some keywords.

def extract_heredoc_lines(ast)

def extract_heredoc_lines(ast)
  return [] unless ast
  ast.each_node(:str, :dstr, :xstr).select(&:heredoc?).map do |node|
    body = node.location.heredoc_body
    (body.first_line...body.last_line)
  end
end

def investigate(processed_source)

def investigate(processed_source)
  heredoc_lines = extract_heredoc_lines(processed_source.ast)
  processed_source.each_comment do |comment|
    location = comment.location
    line_position = location.line
    line = processed_source.lines[line_position - 1]
    next if heredoc_lines.any? { |r| r.include?(line_position) }
    next unless offensive?(line)
    range = source_range(processed_source.buffer,
                         line_position,
                         (location.column)...(location.last_column))
    add_offense(range, location: range)
  end
end

def message(node)

def message(node)
  line = node.source_line
  keyword = /^\s*(\S+).*#/.match(line)[1]
  format(MSG, keyword: keyword)
end

def offensive?(line)

def offensive?(line)
  line = line.lstrip
  KEYWORDS.any? { |word| line =~ /^#{word}\s/ } &&
    ALLOWED_COMMENTS.none? { |c| line =~ /#\s*#{c}/ }
end