summaryrefslogtreecommitdiff
path: root/lib/rdoc/stats.rb
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-12-20 03:22:49 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-12-20 03:22:49 +0000
commit2ef9c50c6e405717d06362787c4549ca4f1c6485 (patch)
treeee99486567461dd5796f3d6edcc9e204187f2666 /lib/rdoc/stats.rb
parentd7effd506f5b91a636f2e6452ef1946b923007c7 (diff)
Import RDoc 3
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30249 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rdoc/stats.rb')
-rw-r--r--lib/rdoc/stats.rb364
1 files changed, 202 insertions, 162 deletions
diff --git a/lib/rdoc/stats.rb b/lib/rdoc/stats.rb
index 6a5d96faa8..e0af445539 100644
--- a/lib/rdoc/stats.rb
+++ b/lib/rdoc/stats.rb
@@ -1,247 +1,287 @@
require 'rdoc'
##
-# RDoc stats collector
+# RDoc statistics collector which prints a summary and report of a project's
+# documentation totals.
class RDoc::Stats
- attr_reader :nodoc_constants
- attr_reader :nodoc_methods
+ ##
+ # Count of files parsed during parsing
- attr_reader :num_constants
- attr_reader :num_files
- attr_reader :num_methods
+ attr_reader :files_so_far
- attr_reader :total_files
+ ##
+ # Total number of files found
- def initialize(total_files, verbosity = 1)
- @nodoc_constants = 0
- @nodoc_methods = 0
+ attr_reader :num_files
- @num_constants = 0
- @num_files = 0
- @num_methods = 0
+ ##
+ # Creates a new Stats that will have +num_files+. +verbosity+ defaults to 1
+ # which will create an RDoc::Stats::Normal outputter.
- @total_files = total_files
+ def initialize num_files, verbosity = 1
+ @files_so_far = 0
+ @num_files = num_files
+ @fully_documented = nil
@start = Time.now
@display = case verbosity
- when 0 then Quiet.new total_files
- when 1 then Normal.new total_files
- else Verbose.new total_files
+ when 0 then Quiet.new num_files
+ when 1 then Normal.new num_files
+ else Verbose.new num_files
end
end
- def begin_adding
- @display.begin_adding
- end
+ ##
+ # Records the parsing of an alias +as+.
- def add_alias(as)
+ def add_alias as
@display.print_alias as
- @num_methods += 1
- @nodoc_methods += 1 if as.document_self and as.comment.empty?
end
- def add_class(klass)
+ ##
+ # Records the parsing of an attribute +attribute+
+
+ def add_attribute attribute
+ @display.print_attribute attribute
+ end
+
+ ##
+ # Records the parsing of a class +klass+
+
+ def add_class klass
@display.print_class klass
end
- def add_constant(constant)
+ ##
+ # Records the parsing of +constant+
+
+ def add_constant constant
@display.print_constant constant
- @num_constants += 1
- @nodoc_constants += 1 if constant.document_self and constant.comment.empty?
end
+ ##
+ # Records the parsing of +file+
+
def add_file(file)
- @display.print_file @num_files, file
- @num_files += 1
+ @files_so_far += 1
+ @display.print_file @files_so_far, file
end
+ ##
+ # Records the parsing of +method+
+
def add_method(method)
@display.print_method method
- @num_methods += 1
- @nodoc_methods += 1 if method.document_self and method.comment.empty?
end
+ ##
+ # Records the parsing of a module +mod+
+
def add_module(mod)
@display.print_module mod
end
- def done_adding
- @display.done_adding
- end
+ ##
+ # Call this to mark the beginning of parsing for display purposes
- def print
- classes = RDoc::TopLevel.classes
- num_classes = classes.length
- nodoc_classes = classes.select do |klass|
- klass.document_self and klass.comment.empty?
- end.length
-
- modules = RDoc::TopLevel.modules
- num_modules = modules.length
- nodoc_modules = modules.select do |mod|
- mod.document_self and mod.comment.empty?
- end.length
-
- items = num_classes + @num_constants + num_modules + @num_methods
- doc_items = items -
- nodoc_classes - @nodoc_constants - nodoc_modules - @nodoc_methods
-
- percent_doc = doc_items.to_f / items * 100 if items.nonzero?
-
- puts "Files: %5d" % @num_files
- puts "Classes: %5d (%5d undocumented)" % [num_classes, nodoc_classes]
- puts "Constants: %5d (%5d undocumented)" %
- [@num_constants, @nodoc_constants]
- puts "Modules: %5d (%5d undocumented)" % [num_modules, nodoc_modules]
- puts "Methods: %5d (%5d undocumented)" % [@num_methods, @nodoc_methods]
- puts "%6.2f%% documented" % percent_doc if percent_doc
- puts
- puts "Elapsed: %0.1fs" % (Time.now - @start)
+ def begin_adding
+ @display.begin_adding
end
##
- # Stats printer that prints nothing
-
- class Quiet
+ # Calculates documentation totals and percentages
- def initialize total_files
- @total_files = total_files
- end
-
- ##
- # Prints a message at the beginning of parsing
+ def calculate
+ return if @percent_doc
- def begin_adding(*) end
+ ucm = RDoc::TopLevel.unique_classes_and_modules
+ constants = []
+ ucm.each { |cm| constants.concat cm.constants }
- ##
- # Prints when an alias is added
+ methods = []
+ ucm.each { |cm| methods.concat cm.method_list }
- def print_alias(*) end
+ attributes = []
+ ucm.each { |cm| attributes.concat cm.attributes }
- ##
- # Prints when a class is added
+ @num_attributes, @undoc_attributes = doc_stats attributes
+ @num_classes, @undoc_classes = doc_stats RDoc::TopLevel.unique_classes
+ @num_constants, @undoc_constants = doc_stats constants
+ @num_methods, @undoc_methods = doc_stats methods
+ @num_modules, @undoc_modules = doc_stats RDoc::TopLevel.unique_modules
- def print_class(*) end
+ @num_items =
+ @num_attributes +
+ @num_classes +
+ @num_constants +
+ @num_methods +
+ @num_modules
- ##
- # Prints when a constant is added
+ @undoc_items =
+ @undoc_attributes +
+ @undoc_classes +
+ @undoc_constants +
+ @undoc_methods +
+ @undoc_modules
- def print_constant(*) end
+ @doc_items = @num_items - @undoc_items
- ##
- # Prints when a file is added
+ @fully_documented = (@num_items - @doc_items) == 0
- def print_file(*) end
-
- ##
- # Prints when a method is added
+ @percent_doc = @doc_items.to_f / @num_items * 100 if @num_items.nonzero?
+ end
- def print_method(*) end
+ ##
+ # Returns the length and number of undocumented items in +collection+.
- ##
- # Prints when a module is added
+ def doc_stats collection
+ [collection.length, collection.count { |item| not item.documented? }]
+ end
- def print_module(*) end
+ ##
+ # Call this to mark the end of parsing for display purposes
- ##
- # Prints when RDoc is done
+ def done_adding
+ @display.done_adding
+ end
- def 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
+ def fully_documented?
+ @fully_documented
end
##
- # Stats printer that prints just the files being documented with a progress
- # bar
+ # Returns a report on which items are not documented
- class Normal < Quiet
+ def report
+ report = []
- def begin_adding # :nodoc:
- puts "Parsing sources..."
- end
+ calculate
- ##
- # Prints a file with a progress bar
-
- def print_file(files_so_far, filename)
- progress_bar = sprintf("%3d%% [%2d/%2d] ",
- 100 * (files_so_far + 1) / @total_files,
- files_so_far + 1,
- @total_files)
-
- if $stdout.tty?
- # Print a progress bar, but make sure it fits on a single line. Filename
- # will be truncated if necessary.
- terminal_width = (ENV['COLUMNS'] || 80).to_i
- max_filename_size = terminal_width - progress_bar.size
- if filename.size > max_filename_size
- # Turn "some_long_filename.rb" to "...ong_filename.rb"
- filename = filename[(filename.size - max_filename_size) .. -1]
- filename[0..2] = "..."
- end
+ if @num_items == @doc_items then
+ report << '100% documentation!'
+ report << nil
+ report << 'Great Job!'
- # Pad the line with whitespaces so that leftover output from the
- # previous line doesn't show up.
- line = "#{progress_bar}#{filename}"
- padding = terminal_width - line.size
- line << (" " * padding) if padding > 0
-
- $stdout.print("#{line}\r")
- else
- $stdout.puts "#{progress_bar} #{filename}"
- end
- $stdout.flush
+ return report.join "\n"
end
- def done_adding # :nodoc:
- puts
- end
+ report << 'The following items are not documented:'
+ report << nil
+
+ ucm = RDoc::TopLevel.unique_classes_and_modules
+
+ ucm.sort.each do |cm|
+ type = case cm # TODO #definition
+ when RDoc::NormalClass then 'class'
+ when RDoc::SingleClass then 'class <<'
+ when RDoc::NormalModule then 'module'
+ end
+
+ if cm.fully_documented? then
+ next
+ elsif cm.in_files.empty? or
+ (cm.constants.empty? and cm.method_list.empty?) then
+ report << "# #{type} #{cm.full_name} is referenced but empty."
+ report << '#'
+ report << '# It probably came from another project. ' \
+ 'I\'m sorry I\'m holding it against you.'
+ report << nil
+
+ next
+ elsif cm.documented? then
+ report << "#{type} #{cm.full_name} # is documented"
+ else
+ report << '# in files:'
- end
+ cm.in_files.each do |file|
+ report << "# #{file.full_name}"
+ end
- ##
- # Stats printer that prints everything documented, including the documented
- # status
+ report << nil
- class Verbose < Normal
+ report << "#{type} #{cm.full_name}"
+ end
- ##
- # Returns a marker for RDoc::CodeObject +co+ being undocumented
+ unless cm.constants.empty? then
+ report << nil
- def nodoc co
- " (undocumented)" unless co.documented?
- end
+ cm.each_constant do |constant|
+ next if constant.documented?
+ report << " # in file #{constant.file.full_name}"
+ report << " #{constant.name} = nil"
+ end
+ end
- def print_alias as # :nodoc:
- puts "\t\talias #{as.new_name} #{as.old_name}#{nodoc as}"
- end
+ unless cm.attributes.empty? then
+ report << nil
- def print_class(klass) # :nodoc:
- puts "\tclass #{klass.full_name}#{nodoc klass}"
- end
+ cm.each_attribute do |attr|
+ next if attr.documented?
+ report << " #{attr.definition} #{attr.name} " \
+ "# in file #{attr.file.full_name}"
+ end
+ end
- def print_constant(constant) # :nodoc:
- puts "\t\t#{constant.name}#{nodoc constant}"
- end
+ unless cm.method_list.empty? then
+ report << nil
- def print_file(files_so_far, file) # :nodoc:
- super
- puts
- end
+ cm.each_method do |method|
+ next if method.documented?
+ report << " # in file #{method.file.full_name}"
+ report << " def #{method.name}#{method.params}; end"
+ report << nil
+ end
+ end
- def print_method(method) # :nodoc:
- puts "\t\t#{method.singleton ? '::' : '#'}#{method.name}#{nodoc method}"
+ report << 'end'
+ report << nil
end
- def print_module(mod) # :nodoc:
- puts "\tmodule #{mod.full_name}#{nodoc mod}"
- end
+ report.join "\n"
+ end
+ ##
+ # Returns a summary of the collected statistics.
+
+ def summary
+ calculate
+
+ report = []
+ report << 'Files: %5d' % @num_files
+ report << nil
+ report << 'Classes: %5d (%5d undocumented)' % [@num_classes,
+ @undoc_classes]
+ report << 'Modules: %5d (%5d undocumented)' % [@num_modules,
+ @undoc_modules]
+ report << 'Constants: %5d (%5d undocumented)' % [@num_constants,
+ @undoc_constants]
+ report << 'Attributes: %5d (%5d undocumented)' % [@num_attributes,
+ @undoc_attributes]
+ report << 'Methods: %5d (%5d undocumented)' % [@num_methods,
+ @undoc_methods]
+ report << nil
+ report << 'Total: %5d (%5d undocumented)' % [@num_items,
+ @undoc_items]
+
+ report << '%6.2f%% documented' % @percent_doc if @percent_doc
+ report << nil
+ report << 'Elapsed: %0.1fs' % (Time.now - @start)
+
+ report.join "\n"
end
-end
+ autoload :Quiet, 'rdoc/stats/quiet'
+ autoload :Normal, 'rdoc/stats/normal'
+ autoload :Verbose, 'rdoc/stats/verbose'
+end