class RDoc::Stats
RDoc statistics collector which prints a summary and report of a project’s documentation totals.
Constants
- GREAT_JOB_MESSAGE
-
Message displayed when all items are documented
- TYPE_ORDER
-
Display order for item types in the coverage report
Attributes
Output level for the coverage report
Count of files parsed during parsing
Total number of files found
Public Class Methods
Creates a new Stats that will have num_files. verbosity defaults to 1 which will create an RDoc::Stats::Normal outputter.
# File lib/rdoc/stats.rb, line 43 def initialize(store, num_files, verbosity = 1) @num_files = num_files @store = store @coverage_level = 0 @doc_items = nil @files_so_far = 0 @fully_documented = false @num_params = 0 @percent_doc = nil @start = Time.now @undoc_params = 0 self.verbosity = verbosity end
Public Instance Methods
Records the parsing of an alias as.
# File lib/rdoc/stats.rb, line 73 def add_alias(as) @display.print_alias as end
Records the parsing of an attribute attribute
# File lib/rdoc/stats.rb, line 80 def add_attribute(attribute) @display.print_attribute attribute end
Records the parsing of a class klass
# File lib/rdoc/stats.rb, line 87 def add_class(klass) @display.print_class klass end
Records the parsing of constant
# File lib/rdoc/stats.rb, line 94 def add_constant(constant) @display.print_constant constant end
Records the parsing of file
# File lib/rdoc/stats.rb, line 101 def add_file(file) @files_so_far += 1 @display.print_file @files_so_far, file end
Records the parsing of method
# File lib/rdoc/stats.rb, line 109 def add_method(method) @display.print_method method end
Records the parsing of a module mod
# File lib/rdoc/stats.rb, line 116 def add_module(mod) @display.print_module mod end
Call this to mark the beginning of parsing for display purposes
# File lib/rdoc/stats.rb, line 123 def begin_adding @display.begin_adding end
Calculates documentation totals and percentages for classes, modules, constants, attributes and methods.
# File lib/rdoc/stats.rb, line 131 def calculate return if @doc_items ucm = @store.unique_classes_and_modules classes = @store.unique_classes.reject { |cm| cm.full_name == 'Object' } constants = [] ucm.each { |cm| constants.concat cm.constants } methods = [] ucm.each { |cm| methods.concat cm.method_list } attributes = [] ucm.each { |cm| attributes.concat cm.attributes } @num_attributes, @undoc_attributes = doc_stats attributes @num_classes, @undoc_classes = doc_stats classes @num_constants, @undoc_constants = doc_stats constants @num_methods, @undoc_methods = doc_stats methods @num_modules, @undoc_modules = doc_stats @store.unique_modules @num_items = @num_attributes + @num_classes + @num_constants + @num_methods + @num_modules + @num_params @undoc_items = @undoc_attributes + @undoc_classes + @undoc_constants + @undoc_methods + @undoc_modules + @undoc_params @doc_items = @num_items - @undoc_items end
Collects undocumented attributes from class_module into items.
# File lib/rdoc/stats.rb, line 358 def collect_undocumented_attributes(class_module, items) class_module.attributes.each do |attr| next unless attr.display? next if attr.documented? file = attr.file&.full_name next unless file scope = attr.singleton ? "." : "#" items << { type: "Attribute", name: "#{class_module.full_name}#{scope}#{attr.name}", file: file, line: attr.line, } end end
Collects undocumented classes or modules from class_module into items. Reopened classes/modules are reported in every file they appear in.
# File lib/rdoc/stats.rb, line 324 def collect_undocumented_class_module(class_module, items) class_module.in_files.map(&:full_name).uniq.each do |file| items << { type: class_module.type.capitalize, name: class_module.full_name, file: file, line: nil, } end end
Collects undocumented constants from class_module into items.
# File lib/rdoc/stats.rb, line 338 def collect_undocumented_constants(class_module, items) class_module.constants.each do |constant| next unless constant.display? next if constant.documented? || constant.is_alias_for file = constant.file&.full_name next unless file items << { type: "Constant", name: constant.full_name, file: file, line: constant.line, } end end
Collects all undocumented items across all classes and modules. Returns [items, empty_classes] where items is an Array of Hashes with keys :type, :name, :file, :line, and empty_classes is an Array of ClassModule objects that are referenced but have no files.
# File lib/rdoc/stats.rb, line 296 def collect_undocumented_items empty_classes = [] items = [] @store.unique_classes_and_modules.each do |class_module| next unless class_module.display? if class_module.in_files.empty? empty_classes << class_module next end unless class_module.documented? || class_module.full_name == 'Object' collect_undocumented_class_module(class_module, items) end collect_undocumented_constants(class_module, items) collect_undocumented_attributes(class_module, items) collect_undocumented_methods(class_module, items) end [items, empty_classes] end
Collects undocumented methods from class_module into items. At coverage level > 0, also counts undocumented parameters.
# File lib/rdoc/stats.rb, line 380 def collect_undocumented_methods(class_module, items) class_module.each_method do |method| next unless method.display? next if method.documented? && @coverage_level.zero? undoc_param_names = nil if @coverage_level > 0 params, undoc = undoc_params method @num_params += params unless undoc.empty? @undoc_params += undoc.length undoc_param_names = undoc end end next if method.documented? && !undoc_param_names file = method.file&.full_name next unless file scope = method.singleton ? "." : "#" item = { type: "Method", name: "#{class_module.full_name}#{scope}#{method.name}", file: file, line: method.line, } item[:undoc_params] = undoc_param_names if undoc_param_names items << item end end
Sets coverage report level. Accepted values are:
- false or nil
-
No report
- 0
-
Classes, modules, constants, attributes, methods
- 1
-
Level 0 + method parameters
# File lib/rdoc/stats.rb, line 179 def coverage_level=(level) level = -1 unless level @coverage_level = level end
Returns the length and number of undocumented items in collection.
# File lib/rdoc/stats.rb, line 188 def doc_stats(collection) visible = collection.select { |item| item.display? } [visible.length, visible.count { |item| not item.documented? }] end
Call this to mark the end of parsing for display purposes
# File lib/rdoc/stats.rb, line 196 def done_adding @display.done_adding end
The documentation status of this project. true when 100%, false when less than 100% and nil when unknown.
Set by calling calculate
# File lib/rdoc/stats.rb, line 206 def fully_documented? @fully_documented end
Calculates the percentage of items documented.
# File lib/rdoc/stats.rb, line 213 def percent_doc return @percent_doc if @percent_doc @fully_documented = (@num_items - @doc_items) == 0 @percent_doc = @doc_items.to_f / @num_items * 100 if @num_items.nonzero? @percent_doc ||= 0 @percent_doc end
Returns a report on which items are not documented
# File lib/rdoc/stats.rb, line 227 def report if @coverage_level > 0 extend Text end if @coverage_level.zero? calculate return GREAT_JOB_MESSAGE if @num_items == @doc_items end items, empty_classes = collect_undocumented_items if @coverage_level > 0 calculate return GREAT_JOB_MESSAGE if @num_items == @doc_items end report = +"" report << "The following items are not documented:\n\n" # Referenced-but-empty classes empty_classes.each do |cm| report << "#{cm.full_name} is referenced but empty.\n" report << "It probably came from another project. I'm sorry I'm holding it against you.\n\n" end # Group items by file, then by type by_file = items.group_by { |item| item[:file] } by_file.sort_by { |file, _| file }.each do |file, file_items| report << "#{file}:\n" by_type = file_items.group_by { |item| item[:type] } TYPE_ORDER.each do |type| next unless by_type[type] report << " #{type}:\n" sorted = by_type[type].sort_by { |item| [item[:line] || 0, item[:name]] } name_width = sorted.reduce(0) { |max, item| item[:line] && item[:name].length > max ? item[:name].length : max } sorted.each do |item| if item[:line] report << " %-*s %s:%d\n" % [name_width, item[:name], item[:file], item[:line]] else report << " #{item[:name]}\n" end if item[:undoc_params] report << " Undocumented params: #{item[:undoc_params].join(', ')}\n" end end end report << "\n" end report end
Returns a summary of the collected statistics.
# File lib/rdoc/stats.rb, line 418 def summary calculate num_width = [@num_files, @num_items].max.to_s.length undoc_width = [ @undoc_attributes, @undoc_classes, @undoc_constants, @undoc_items, @undoc_methods, @undoc_modules, @undoc_params, ].max.to_s.length report = +"" report << "Files: %*d\n" % [num_width, @num_files] report << "\n" report << "Classes: %*d (%*d undocumented)\n" % [ num_width, @num_classes, undoc_width, @undoc_classes] report << "Modules: %*d (%*d undocumented)\n" % [ num_width, @num_modules, undoc_width, @undoc_modules] report << "Constants: %*d (%*d undocumented)\n" % [ num_width, @num_constants, undoc_width, @undoc_constants] report << "Attributes: %*d (%*d undocumented)\n" % [ num_width, @num_attributes, undoc_width, @undoc_attributes] report << "Methods: %*d (%*d undocumented)\n" % [ num_width, @num_methods, undoc_width, @undoc_methods] report << "Parameters: %*d (%*d undocumented)\n" % [ num_width, @num_params, undoc_width, @undoc_params] if @coverage_level > 0 report << "\n" report << "Total: %*d (%*d undocumented)\n" % [ num_width, @num_items, undoc_width, @undoc_items] report << "%6.2f%% documented\n" % percent_doc report << "\n" report << "Elapsed: %0.1fs\n" % (Time.now - @start) report end
Determines which parameters in method were not documented. Returns a total parameter count and an Array of undocumented methods.
# File lib/rdoc/stats.rb, line 463 def undoc_params(method) @formatter ||= Markup::ToTtOnly.new params = method.param_list params = params.map { |param| param.gsub(/^\*\*?/, '') } return 0, [] if params.empty? document = parse method.comment tts = document.accept @formatter undoc = params - tts [params.length, undoc] end
Sets the verbosity level, rebuilding the display outputter.
# File lib/rdoc/stats.rb, line 62 def verbosity=(verbosity) @display = case verbosity when 0 then Quiet.new @num_files when 1 then Normal.new @num_files else Verbose.new @num_files end end