123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::Cop::CopDocumentation Private

Relationships & Source Files
Inherits: Object
Defined in: lib/rubocop/cop/cop_documentation.rb

Overview

Reads the documentation comment a cop carries above its class definition and splits it into the sections worth showing on their own.

YARD is a development dependency, so the comment is read straight from the source rather than through a doclet.

Constant Summary

Class Method Summary

Instance Method Summary

Constructor Details

.new(cop_class) ⇒ CopDocumentation

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 14

def initialize(cop_class)
  @cop_class = cop_class
end

Instance Method Details

#collect_comment_above(lines, index) (private)

Walks up from the class definition for as long as the lines are comments.

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 48

def collect_comment_above(lines, index)
  block = []
  while index >= 0 && lines[index].match?(/^\s*#/)
    block.unshift(lines[index].sub(/^\s*# ?/, ''))
    index -= 1
  end
  block
end

#comment_lines (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 30

def comment_lines
  path, line = source_location
  return [] unless path && File.file?(path)

  lines = File.readlines(path, chomp: true)
  collect_comment_above(lines, line - 2)
end

#section_title(tag, argument) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 71

def section_title(tag, argument)
  title = tag.capitalize
  argument.empty? ? title : "#{title}: #{argument}"
end

#sectionsArray<Array(String, Array<String>)>

Returns:

  • (Array<Array(String, Array<String>)>)

    title and body per section

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 19

def sections
  comment = comment_lines
  return [] if comment.empty?

  prose, tagged = split_on_first_tag(comment)

  [['Details', strip_blank(prose)], *tagged_sections(tagged)].reject { |_, b| b.empty? }
end

#source_location (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 38

def source_location
  name = @cop_class.name
  return [] unless name

  Module.const_source_location(name) || []
rescue NameError
  []
end

#split_on_first_tag(comment) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 57

def split_on_first_tag(comment)
  first_tag = comment.index { |line| line.match?(TAG) }
  return [comment, []] unless first_tag

  [comment[0...first_tag], comment[first_tag..]]
end

#strip_blank(lines) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 76

def strip_blank(lines)
  lines.drop_while(&:empty?).reverse.drop_while(&:empty?).reverse
end

#tagged_sections(lines) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/cop_documentation.rb', line 64

def tagged_sections(lines)
  lines.slice_before { |line| line.match?(TAG) }.map do |(head, *body)|
    tag, argument = head.match(TAG).captures
    [section_title(tag, argument), strip_blank(body)]
  end
end