From 2ef9c50c6e405717d06362787c4549ca4f1c6485 Mon Sep 17 00:00:00 2001 From: drbrain Date: Mon, 20 Dec 2010 03:22:49 +0000 Subject: Import RDoc 3 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30249 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/rdoc/top_level.rb | 269 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 230 insertions(+), 39 deletions(-) (limited to 'lib/rdoc/top_level.rb') diff --git a/lib/rdoc/top_level.rb b/lib/rdoc/top_level.rb index 306790fc15..d0ea621f8c 100644 --- a/lib/rdoc/top_level.rb +++ b/lib/rdoc/top_level.rb @@ -20,7 +20,14 @@ class RDoc::TopLevel < RDoc::Context attr_accessor :absolute_name - attr_accessor :diagram + ## + # All the classes or modules that were declared in + # this file. These are assigned to either +#classes_hash+ + # or +#modules_hash+ once we know what they really are. + + attr_reader :classes_or_modules + + attr_accessor :diagram # :nodoc: ## # The parser that processed this file @@ -28,45 +35,110 @@ class RDoc::TopLevel < RDoc::Context attr_accessor :parser ## - # Returns all classes and modules discovered by RDoc + # Returns all classes discovered by RDoc - def self.all_classes_and_modules - classes_hash.values + modules_hash.values + def self.all_classes + @all_classes_hash.values end ## - # Returns all classes discovered by RDoc + # Returns all classes and modules discovered by RDoc - def self.classes - classes_hash.values + def self.all_classes_and_modules + @all_classes_hash.values + @all_modules_hash.values end ## # Hash of all classes known to RDoc - def self.classes_hash - @all_classes + def self.all_classes_hash + @all_classes_hash end ## # All TopLevels known to RDoc - def self.files - @all_files.values + def self.all_files + @all_files_hash.values end ## # Hash of all files known to RDoc - def self.files_hash - @all_files + def self.all_files_hash + @all_files_hash + end + + ## + # Returns all modules discovered by RDoc + + def self.all_modules + all_modules_hash.values + end + + ## + # Hash of all modules known to RDoc + + def self.all_modules_hash + @all_modules_hash + end + + ## + # Prepares the RDoc code object tree for use by a generator. + # + # It finds unique classes/modules defined, and replaces classes/modules that + # are aliases for another one by a copy with RDoc::ClassModule#is_alias_for + # set. + # + # It updates the RDoc::ClassModule#constant_aliases attribute of "real" + # classes or modules. + # + # It also completely removes the classes and modules that should be removed + # from the documentation and the methods that have a visibility below + # +min_visibility+, which is the --visibility option. + # + # See also RDoc::Context#remove_from_documentation? + + def self.complete min_visibility + fix_basic_object_inheritance + + # cache included modules before they are removed from the documentation + all_classes_and_modules.each { |cm| cm.ancestors } + + remove_nodoc @all_classes_hash + remove_nodoc @all_modules_hash + + @unique_classes = find_unique @all_classes_hash + @unique_modules = find_unique @all_modules_hash + + unique_classes_and_modules.each do |cm| + cm.complete min_visibility + end + + @all_files_hash.each_key do |file_name| + tl = @all_files_hash[file_name] + + unless RDoc::Parser::Simple === tl.parser then + tl.modules_hash.clear + tl.classes_hash.clear + + tl.classes_or_modules.each do |cm| + name = cm.full_name + if cm.type == 'class' then + tl.classes_hash[name] = cm if @all_classes_hash[name] + else + tl.modules_hash[name] = cm if @all_modules_hash[name] + end + end + end + end end ## # Finds the class with +name+ in all discovered classes def self.find_class_named(name) - classes_hash[name] + @all_classes_hash[name] end ## @@ -91,9 +163,7 @@ class RDoc::TopLevel < RDoc::Context # Finds the class or module with +name+ def self.find_class_or_module(name) - name =~ /^::/ - name = $' || name - + name = $' if name =~ /^::/ RDoc::TopLevel.classes_hash[name] || RDoc::TopLevel.modules_hash[name] end @@ -101,7 +171,7 @@ class RDoc::TopLevel < RDoc::Context # Finds the file with +name+ in all discovered files def self.find_file_named(name) - @all_files[name] + @all_files_hash[name] end ## @@ -112,26 +182,98 @@ class RDoc::TopLevel < RDoc::Context end ## - # Returns all modules discovered by RDoc + # Finds unique classes/modules defined in +all_hash+, + # and returns them as an array. Performs the alias + # updates in +all_hash+: see ::complete. + #-- + # TODO aliases should be registered by Context#add_module_alias - def self.modules - modules_hash.values + def self.find_unique(all_hash) + unique = [] + + all_hash.each_pair do |full_name, cm| + unique << cm if full_name == cm.full_name + end + + unique end ## - # Hash of all modules known to RDoc + # Fixes the erroneous BasicObject < Object in 1.9. + # + # Because we assumed all classes without a stated superclass + # inherit from Object, we have the above wrong inheritance. + # + # We fix BasicObject right away if we are running in a Ruby + # version >= 1.9. If not, we may be documenting 1.9 source + # while running under 1.8: we search the files of BasicObject + # for "object.c", and fix the inheritance if we find it. + + def self.fix_basic_object_inheritance + basic = all_classes_hash['BasicObject'] + return unless basic + if RUBY_VERSION >= '1.9' + basic.superclass = nil + elsif basic.in_files.any? { |f| File.basename(f.full_name) == 'object.c' } + basic.superclass = nil + end + end - def self.modules_hash - @all_modules + ## + # Removes from +all_hash+ the contexts that are nodoc or have no content. + # + # See RDoc::Context#remove_from_documentation? + + def self.remove_nodoc(all_hash) + all_hash.keys.each do |name| + context = all_hash[name] + all_hash.delete(name) if context.remove_from_documentation? + end end ## # Empties RDoc of stored class, module and file information def self.reset - @all_classes = {} - @all_modules = {} - @all_files = {} + @all_classes_hash = {} + @all_modules_hash = {} + @all_files_hash = {} + end + + ## + # Returns the unique classes discovered by RDoc. + # + # ::complete must have been called prior to using this method. + + def self.unique_classes + @unique_classes + end + + ## + # Returns the unique classes and modules discovered by RDoc. + # ::complete must have been called prior to using this method. + + def self.unique_classes_and_modules + @unique_classes + @unique_modules + end + + ## + # Returns the unique modules discovered by RDoc. + # ::complete must have been called prior to using this method. + + def self.unique_modules + @unique_modules + end + + class << self + alias classes all_classes + alias classes_hash all_classes_hash + + alias files all_files + alias files_hash all_files_hash + + alias modules all_modules + alias modules_hash all_modules_hash end reset @@ -148,17 +290,49 @@ class RDoc::TopLevel < RDoc::Context @diagram = nil @parser = nil + @classes_or_modules = [] + RDoc::TopLevel.files_hash[file_name] = self end ## - # Adds +method+ to Object instead of RDoc::TopLevel + # Adds +an_alias+ to +Object+ instead of +self+. + + def add_alias(an_alias) + return an_alias unless @document_self + object_class.add_alias an_alias + end + + ## + # Adds +constant+ to +Object+ instead of +self+. + + def add_constant(constant) + return constant unless @document_self + object_class.add_constant constant + end + + ## + # Adds +include+ to +Object+ instead of +self+. + + def add_include(include) + return include unless @document_self + object_class.add_include include + end + + ## + # Adds +method+ to +Object+ instead of +self+. def add_method(method) - object = self.class.find_class_named 'Object' - object = add_class RDoc::NormalClass, 'Object' unless object + return method unless @document_self + object_class.add_method method + end + + ## + # Adds class or module +mod+. Used in the building phase + # by the ruby parser. - object.add_method method + def add_to_classes_or_modules mod + @classes_or_modules << mod end ## @@ -168,8 +342,13 @@ class RDoc::TopLevel < RDoc::Context File.basename @absolute_name end + alias name base_name + ## - # See RDoc::TopLevel.find_class_or_module + # See RDoc::TopLevel::find_class_or_module + #-- + # TODO Why do we search through all classes/modules found, not just the + # ones of this instance? def find_class_or_module name RDoc::TopLevel.find_class_or_module name @@ -186,11 +365,11 @@ class RDoc::TopLevel < RDoc::Context # Finds a module or class with +name+ def find_module_named(name) - find_class_or_module(name) || find_enclosing_module_named(name) + find_class_or_module(name) end ## - # The name of this file + # Returns the relative name of this file def full_name @relative_name @@ -215,16 +394,24 @@ class RDoc::TopLevel < RDoc::Context end ## - # Date this file was last modified, if known + # Time this file was last modified, if known def last_modified - @file_stat ? file_stat.mtime.to_s : 'Unknown' + @file_stat ? file_stat.mtime : nil end ## - # Base name of this file - - alias name base_name + # Returns the NormalClass "Object", creating it if not found. + # + # Records +self+ as a location in "Object". + + def object_class + @object_class ||= begin + oc = self.class.find_class_named('Object') || add_class(RDoc::NormalClass, 'Object') + oc.record_location self + oc + end + end ## # Path to this file @@ -244,5 +431,9 @@ class RDoc::TopLevel < RDoc::Context end end + def to_s # :nodoc: + "file #{full_name}" + end + end -- cgit v1.2.3