diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-27 04:28:14 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-27 04:28:14 +0000 |
commit | 1c279a7d2753949c725754e1302f791b76358114 (patch) | |
tree | 36aa3bdde250e564445eba5f2e25fcb96bcb6cef /lib/rdoc/extend.rb | |
parent | c72f0daa877808e4fa5018b3191ca09d4b97c03d (diff) | |
download | ruby-1c279a7d2753949c725754e1302f791b76358114.tar.gz |
* lib/rdoc*: Updated to RDoc 4.0 (pre-release)
* bin/rdoc: ditto
* test/rdoc: ditto
* NEWS: Updated with RDoc 4.0 information
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37889 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rdoc/extend.rb')
-rw-r--r-- | lib/rdoc/extend.rb | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/lib/rdoc/extend.rb b/lib/rdoc/extend.rb new file mode 100644 index 0000000000..2bccfba084 --- /dev/null +++ b/lib/rdoc/extend.rb @@ -0,0 +1,117 @@ +## +# A Module extension in a class with \#extend + +class RDoc::Extend < RDoc::CodeObject + + ## + # Name of extension module + + attr_accessor :name + + ## + # Creates a new Extend for +name+ with +comment+ + + def initialize(name, comment) + super() + @name = name + self.comment = comment + @module = nil # cache for module if found + end + + ## + # Extends are sorted by name + + def <=> other + return unless self.class === other + + name <=> other.name + end + + def == other # :nodoc: + self.class === other and @name == other.name + end + + alias eql? == + + ## + # Full name based on #module + + def full_name + m = self.module + RDoc::ClassModule === m ? m.full_name : @name + end + + def hash # :nodoc: + [@name, self.module].hash + end + + def inspect # :nodoc: + "#<%s:0x%x %s.extend %s>" % [ + self.class, + object_id, + parent_name, @name, + ] + end + + ## + # Attempts to locate the extend module object. Returns the name if not + # known. + # + # The scoping rules of Ruby to resolve the name of an extension module are: + # - first look into the children of the current context; + # - if not found, look into the children of extension modules, + # in reverse extend order; + # - if still not found, go up the hierarchy of names. + # + # This method has <code>O(n!)</code> behavior when the module calling + # extend is referencing nonexistent modules. Avoid calling #module until + # after all the files are parsed. This behavior is due to ruby's constant + # lookup behavior. + + def module + return @module if @module + + # search the current context + return @name unless parent + full_name = parent.child_name(@name) + @module = @store.modules_hash[full_name] + return @module if @module + return @name if @name =~ /^::/ + + # search the includes before this one, in reverse order + searched = parent.extends.take_while { |i| i != self }.reverse + searched.each do |i| + ext = i.module + next if String === ext + full_name = ext.child_name(@name) + @module = @store.modules_hash[full_name] + return @module if @module + end + + # go up the hierarchy of names + up = parent.parent + while up + full_name = up.child_name(@name) + @module = @store.modules_hash[full_name] + return @module if @module + up = up.parent + end + + @name + end + + ## + # Sets the store for this class or module and its contained code objects. + + def store= store + super + + @file = @store.add_file @file.full_name if @file + end + + def to_s # :nodoc: + "extend #@name in: #{parent}" + end + +end + |