summaryrefslogtreecommitdiff
path: root/lib/rdoc/class_module.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rdoc/class_module.rb')
-rw-r--r--lib/rdoc/class_module.rb267
1 files changed, 227 insertions, 40 deletions
diff --git a/lib/rdoc/class_module.rb b/lib/rdoc/class_module.rb
index 27066d8bd7..04f0132b7d 100644
--- a/lib/rdoc/class_module.rb
+++ b/lib/rdoc/class_module.rb
@@ -1,5 +1,3 @@
-require 'rdoc/context'
-
##
# ClassModule is the base class for objects representing either a class or a
# module.
@@ -13,8 +11,17 @@ class RDoc::ClassModule < RDoc::Context
# * Added file to constants
# * Added file to includes
# * Added file to methods
-
- MARSHAL_VERSION = 1 # :nodoc:
+ # 2::
+ # RDoc 3.13
+ # * Added extends
+ # 3::
+ # RDoc 4.0
+ # * Added sections
+ # * Added in_files
+ # * Added parent name
+ # * Complete Constant dump
+
+ MARSHAL_VERSION = 3 # :nodoc:
##
# Constants that are aliases for this class or module
@@ -56,6 +63,7 @@ class RDoc::ClassModule < RDoc::Context
klass.external_aliases.concat mod.external_aliases
klass.constants.concat mod.constants
klass.includes.concat mod.includes
+ klass.extends.concat mod.extends
klass.methods_hash.update mod.methods_hash
klass.constants_hash.update mod.constants_hash
@@ -84,6 +92,7 @@ class RDoc::ClassModule < RDoc::Context
klass.external_aliases +
klass.constants +
klass.includes +
+ klass.extends +
klass.classes +
klass.modules).each do |obj|
obj.parent = klass
@@ -115,16 +124,32 @@ class RDoc::ClassModule < RDoc::Context
# across multiple runs.
def add_comment comment, location
- return if comment.empty? or not document_self
+ return unless document_self
original = comment
- comment = normalize_comment comment
+ comment = case comment
+ when RDoc::Comment then
+ comment.normalize
+ else
+ normalize_comment comment
+ end
@comment_location << [comment, location]
self.comment = original
end
+ def add_things my_things, other_things # :nodoc:
+ other_things.each do |group, things|
+ my_things[group].each { |thing| yield false, thing } if
+ my_things.include? group
+
+ things.each do |thing|
+ yield true, thing
+ end
+ end
+ end
+
##
# Ancestors list for this ClassModule: the list of included modules
# (classes will add their superclass if any).
@@ -142,6 +167,11 @@ class RDoc::ClassModule < RDoc::Context
end
##
+ # Ancestors of this class or module only
+
+ alias direct_ancestors ancestors
+
+ ##
# Clears the comment. Used by the ruby parser.
def clear_comment
@@ -155,9 +185,13 @@ class RDoc::ClassModule < RDoc::Context
# more like <tt>+=</tt>.
def comment= comment
- return if comment.empty?
+ comment = case comment
+ when RDoc::Comment then
+ comment.normalize
+ else
+ normalize_comment comment
+ end
- comment = normalize_comment comment
comment = "#{@comment}\n---\n#{comment}" unless @comment.empty?
super comment
@@ -166,7 +200,7 @@ class RDoc::ClassModule < RDoc::Context
##
# Prepares this ClassModule for use by a generator.
#
- # See RDoc::TopLevel::complete
+ # See RDoc::Store#complete
def complete min_visibility
update_aliases
@@ -176,12 +210,22 @@ class RDoc::ClassModule < RDoc::Context
end
##
+ # Does this ClassModule or any of its methods have document_self set?
+
+ def document_self_or_methods
+ document_self || method_list.any?{ |m| m.document_self }
+ end
+
+ ##
# Iterates the ancestors of this class or module for which an
# RDoc::ClassModule exists.
def each_ancestor # :yields: module
+ return enum_for __method__ unless block_given?
+
ancestors.each do |mod|
next if String === mod
+ next if self == mod
yield mod
end
end
@@ -215,8 +259,8 @@ class RDoc::ClassModule < RDoc::Context
# Return the fully qualified name of this class or module
def full_name
- @full_name ||= if RDoc::ClassModule === @parent then
- "#{@parent.full_name}::#{@name}"
+ @full_name ||= if RDoc::ClassModule === parent then
+ "#{parent.full_name}::#{@name}"
else
@name
end
@@ -250,13 +294,20 @@ class RDoc::ClassModule < RDoc::Context
@superclass,
parse(@comment_location),
attrs,
- constants.map do |const|
- [const.name, parse(const.comment), const.file_name]
- end,
+ constants,
includes.map do |incl|
[incl.name, parse(incl.comment), incl.file_name]
end,
method_types,
+ extends.map do |ext|
+ [ext.name, parse(ext.comment), ext.file_name]
+ end,
+ @sections.values,
+ @in_files.map do |tl|
+ tl.absolute_name
+ end,
+ parent.full_name,
+ parent.class,
]
end
@@ -268,6 +319,8 @@ class RDoc::ClassModule < RDoc::Context
@parent = nil
@temporary_section = nil
@visibility = nil
+ @classes = {}
+ @modules = {}
@name = array[1]
@full_name = array[2]
@@ -291,9 +344,14 @@ class RDoc::ClassModule < RDoc::Context
attr.record_location RDoc::TopLevel.new file
end
- array[6].each do |name, comment, file|
- const = add_constant RDoc::Constant.new(name, nil, comment)
- const.record_location RDoc::TopLevel.new file
+ array[6].each do |constant, comment, file|
+ case constant
+ when RDoc::Constant then
+ add_constant constant
+ else
+ constant = add_constant RDoc::Constant.new(constant, nil, comment)
+ constant.record_location RDoc::TopLevel.new file
+ end
end
array[7].each do |name, comment, file|
@@ -313,6 +371,27 @@ class RDoc::ClassModule < RDoc::Context
end
end
end
+
+ array[9].each do |name, comment, file|
+ ext = add_extend RDoc::Extend.new(name, comment)
+ ext.record_location RDoc::TopLevel.new file
+ end if array[9] # Support Marshal version 1
+
+ sections = (array[10] || []).map do |section|
+ [section.title, section]
+ end
+
+ @sections = Hash[*sections.flatten]
+ @current_section = add_section nil
+
+ @in_files = []
+
+ (array[11] || []).each do |filename|
+ record_location RDoc::TopLevel.new filename
+ end
+
+ @parent_name = array[12]
+ @parent_class = array[13]
end
##
@@ -321,6 +400,9 @@ class RDoc::ClassModule < RDoc::Context
# The data in +class_module+ is preferred over the receiver.
def merge class_module
+ @parent = class_module.parent
+ @parent_name = class_module.parent_name
+
other_document = parse class_module.comment_location
if other_document then
@@ -360,6 +442,18 @@ class RDoc::ClassModule < RDoc::Context
end
end
+ @includes.uniq! # clean up
+
+ merge_collections extends, cm.extends, other_files do |add, ext|
+ if add then
+ add_extend ext
+ else
+ @extends.delete ext
+ end
+ end
+
+ @extends.uniq! # clean up
+
merge_collections method_list, cm.method_list, other_files do |add, meth|
if add then
add_method meth
@@ -369,6 +463,8 @@ class RDoc::ClassModule < RDoc::Context
end
end
+ merge_sections cm
+
self
end
@@ -391,22 +487,46 @@ class RDoc::ClassModule < RDoc::Context
my_things = mine. group_by { |thing| thing.file }
other_things = other.group_by { |thing| thing.file }
- my_things.delete_if do |file, things|
- next false unless other_files.include? file
+ remove_things my_things, other_files, &block
+ add_things my_things, other_things, &block
+ end
- things.each do |thing|
- yield false, thing
- end
+ ##
+ # Merges the comments in this ClassModule with the comments in the other
+ # ClassModule +cm+.
- true
+ def merge_sections cm # :nodoc:
+ my_sections = sections.group_by { |section| section.title }
+ other_sections = cm.sections.group_by { |section| section.title }
+
+ other_files = cm.in_files
+
+ remove_things my_sections, other_files do |_, section|
+ @sections.delete section.title
end
- other_things.each do |file, things|
- my_things[file].each { |thing| yield false, thing } if
- my_things.include?(file)
+ other_sections.each do |group, sections|
+ if my_sections.include? group
+ my_sections[group].each do |my_section|
+ other_section = cm.sections_hash[group]
- things.each do |thing|
- yield true, thing
+ my_comments = my_section.comments
+ other_comments = other_section.comments
+
+ other_files = other_section.in_files
+
+ merge_collections my_comments, other_comments, other_files do |add, comment|
+ if add then
+ my_section.add_comment comment
+ else
+ my_section.remove_comment comment
+ end
+ end
+ end
+ else
+ sections.each do |section|
+ add_section group, section.comments
+ end
end
end
end
@@ -438,11 +558,15 @@ class RDoc::ClassModule < RDoc::Context
when Array then
docs = comment_location.map do |comment, location|
doc = super comment
- doc.file = location.absolute_name
+ doc.file = location
doc
end
RDoc::Markup::Document.new(*docs)
+ when RDoc::Comment then
+ doc = super comment_location.text, comment_location.format
+ doc.file = comment_location.location
+ doc
when RDoc::Markup::Document then
return comment_location
else
@@ -451,10 +575,10 @@ class RDoc::ClassModule < RDoc::Context
end
##
- # Path to this class or module
+ # Path to this class or module for use with HTML generator output.
def path
- http_url RDoc::RDoc.current.generator.class_dir
+ http_url @store.rdoc.generator.class_dir
end
##
@@ -488,21 +612,61 @@ class RDoc::ClassModule < RDoc::Context
modules_hash.each_key do |name|
full_name = prefix + name
- modules_hash.delete name unless RDoc::TopLevel.all_modules_hash[full_name]
+ modules_hash.delete name unless @store.modules_hash[full_name]
end
classes_hash.each_key do |name|
full_name = prefix + name
- classes_hash.delete name unless RDoc::TopLevel.all_classes_hash[full_name]
+ classes_hash.delete name unless @store.classes_hash[full_name]
end
end
+ def remove_things my_things, other_files # :nodoc:
+ my_things.delete_if do |file, things|
+ next false unless other_files.include? file
+
+ things.each do |thing|
+ yield false, thing
+ end
+
+ true
+ end
+ end
+
+ ##
+ # Search record used by RDoc::Generator::JsonIndex
+
+ def search_record
+ [
+ name,
+ full_name,
+ full_name,
+ '',
+ path,
+ '',
+ snippet(@comment_location),
+ ]
+ end
+
+ ##
+ # Sets the store for this class or module and its contained code objects.
+
+ def store= store
+ super
+
+ @attributes .each do |attr| attr.store = store end
+ @constants .each do |const| const.store = store end
+ @includes .each do |incl| incl.store = store end
+ @extends .each do |ext| ext.store = store end
+ @method_list.each do |meth| meth.store = store end
+ end
+
##
# Get the superclass of this class. Attempts to retrieve the superclass
# object, returns the name if it is not known.
def superclass
- RDoc::TopLevel.find_class_named(@superclass) || @superclass
+ @store.find_class_named(@superclass) || @superclass
end
##
@@ -533,7 +697,7 @@ class RDoc::ClassModule < RDoc::Context
# aliases through a constant.
#
# The aliased module/class is replaced in the children and in
- # RDoc::TopLevel::all_modules_hash or RDoc::TopLevel::all_classes_hash
+ # RDoc::Store#modules_hash or RDoc::Store#classes_hash
# by a copy that has <tt>RDoc::ClassModule#is_alias_for</tt> set to
# the aliased module/class, and this copy is added to <tt>#aliases</tt>
# of the aliased module/class.
@@ -548,16 +712,21 @@ class RDoc::ClassModule < RDoc::Context
next unless cm = const.is_alias_for
cm_alias = cm.dup
cm_alias.name = const.name
- cm_alias.parent = self
- cm_alias.full_name = nil # force update for new parent
+
+ # Don't move top-level aliases under Object, they look ugly there
+ unless RDoc::TopLevel === cm_alias.parent then
+ cm_alias.parent = self
+ cm_alias.full_name = nil # force update for new parent
+ end
+
cm_alias.aliases.clear
cm_alias.is_alias_for = cm
if cm.module? then
- RDoc::TopLevel.all_modules_hash[cm_alias.full_name] = cm_alias
+ @store.modules_hash[cm_alias.full_name] = cm_alias
modules_hash[const.name] = cm_alias
else
- RDoc::TopLevel.all_classes_hash[cm_alias.full_name] = cm_alias
+ @store.classes_hash[cm_alias.full_name] = cm_alias
classes_hash[const.name] = cm_alias
end
@@ -574,8 +743,26 @@ class RDoc::ClassModule < RDoc::Context
def update_includes
includes.reject! do |include|
mod = include.module
- !(String === mod) && RDoc::TopLevel.all_modules_hash[mod.full_name].nil?
+ !(String === mod) && @store.modules_hash[mod.full_name].nil?
end
+
+ includes.uniq!
+ end
+
+ ##
+ # Deletes from #extends those whose module has been removed from the
+ # documentation.
+ #--
+ # FIXME: like update_includes, extends are not reliably removed
+
+ def update_extends
+ extends.reject! do |ext|
+ mod = ext.module
+
+ !(String === mod) && @store.modules_hash[mod.full_name].nil?
+ end
+
+ extends.uniq!
end
end