aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rdoc/top_level.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/top_level.rb
parentd7effd506f5b91a636f2e6452ef1946b923007c7 (diff)
downloadruby-2ef9c50c6e405717d06362787c4549ca4f1c6485.tar.gz
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/top_level.rb')
-rw-r--r--lib/rdoc/top_level.rb269
1 files changed, 230 insertions, 39 deletions
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 <tt>--visibility</tt> 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 <tt>BasicObject < Object</tt> 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