aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rdoc/ri
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-18 00:46:16 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-18 00:46:16 +0000
commitfd25f74d64c69d636764ea11aa5a809b85e58f69 (patch)
tree40585659bf4b9665ad0d258c415a6765a056d35d /lib/rdoc/ri
parent0af4a490b48bb6fef8d4f392d0c0b215db8e06f9 (diff)
downloadruby-fd25f74d64c69d636764ea11aa5a809b85e58f69.tar.gz
Import RDoc r101.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18121 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rdoc/ri')
-rw-r--r--lib/rdoc/ri/descriptions.rb3
-rw-r--r--lib/rdoc/ri/driver.rb154
2 files changed, 109 insertions, 48 deletions
diff --git a/lib/rdoc/ri/descriptions.rb b/lib/rdoc/ri/descriptions.rb
index 0aef189025..6a30f51c9b 100644
--- a/lib/rdoc/ri/descriptions.rb
+++ b/lib/rdoc/ri/descriptions.rb
@@ -2,11 +2,10 @@ require 'yaml'
require 'rdoc/markup/fragments'
require 'rdoc/ri'
-#--
+##
# Descriptions are created by RDoc (in ri_generator) and written out in
# serialized form into the documentation tree. ri then reads these to generate
# the documentation
-#++
class RDoc::RI::NamedThing
attr_reader :name
diff --git a/lib/rdoc/ri/driver.rb b/lib/rdoc/ri/driver.rb
index 7ac2e0f15c..ecf1bf9f27 100644
--- a/lib/rdoc/ri/driver.rb
+++ b/lib/rdoc/ri/driver.rb
@@ -11,6 +11,64 @@ require 'rdoc/markup/to_flow'
class RDoc::RI::Driver
+ class Hash < ::Hash
+ def self.convert(hash)
+ hash = new.update hash
+
+ hash.each do |key, value|
+ hash[key] = case value
+ when ::Hash then
+ convert value
+ when Array then
+ value = value.map do |v|
+ ::Hash === v ? convert(v) : v
+ end
+ value
+ else
+ value
+ end
+ end
+
+ hash
+ end
+
+ def method_missing method, *args
+ self[method.to_s]
+ end
+
+ def merge_enums(other)
+ other.each do |k, v|
+ if self[k] then
+ case v
+ when Array then
+ # HACK dunno
+ if String === self[k] and self[k].empty? then
+ self[k] = v
+ else
+ self[k] += v
+ end
+ when Hash then
+ self[k].update v
+ else
+ # do nothing
+ end
+ else
+ self[k] = v
+ end
+ end
+ end
+ end
+
+ class Error < RDoc::RI::Error; end
+
+ class NotFoundError < Error
+ def message
+ "Nothing known about #{super}"
+ end
+ end
+
+ attr_accessor :homepath # :nodoc:
+
def self.process_args(argv)
options = {}
options[:use_stdout] = !$stdout.tty?
@@ -234,7 +292,7 @@ Options may also be set in the 'RI' environment variable.
@class_cache = if up_to_date then
load_cache_for @class_cache_name
else
- class_cache = {}
+ class_cache = RDoc::RI::Driver::Hash.new
classes = map_dirs('**/cdesc*.yaml', :sys) { |f| Dir[f] }
populate_class_cache class_cache, classes
@@ -261,16 +319,24 @@ Options may also be set in the 'RI' environment variable.
def display_class(name)
klass = class_cache[name]
+ klass = RDoc::RI::Driver::Hash.convert klass
@display.display_class_info klass, class_cache
end
+ def get_info_for(arg)
+ @names = [arg]
+ run
+ end
+
def load_cache_for(klassname)
path = cache_file_for klassname
+ cache = nil
+
if File.exist? path and
File.mtime(path) >= File.mtime(class_cache_file_path) then
File.open path, 'rb' do |fp|
- Marshal.load fp.read
+ cache = Marshal.load fp.read
end
else
class_cache = nil
@@ -283,7 +349,7 @@ Options may also be set in the 'RI' environment variable.
return nil unless klass
method_files = klass["sources"]
- cache = {}
+ cache = RDoc::RI::Driver::Hash.new
sys_dir = @sys_dirs.first
method_files.each do |f|
@@ -296,12 +362,28 @@ Options may also be set in the 'RI' environment variable.
ext_path = f
ext_path = "gem #{$1}" if f =~ %r%gems/[\d.]+/doc/([^/]+)%
method["source_path"] = ext_path unless system_file
- cache[name] = method
+ cache[name] = RDoc::RI::Driver::Hash.convert method
end
end
write_cache cache, path
end
+
+ RDoc::RI::Driver::Hash.convert cache
+ end
+
+ ##
+ # Finds the method
+
+ def lookup_method(name, klass)
+ cache = load_cache_for klass
+ raise NotFoundError, name unless cache
+
+ method = cache[name.gsub('.', '#')]
+ method = cache[name.gsub('.', '::')] unless method
+ raise NotFoundError, name unless method
+
+ method
end
def map_dirs(file_name, system=false)
@@ -318,6 +400,22 @@ Options may also be set in the 'RI' environment variable.
dirs.map { |dir| yield File.join(dir, file_name) }.flatten.compact
end
+ ##
+ # Extract the class and method name parts from +name+ like Foo::Bar#baz
+
+ def parse_name(name)
+ parts = name.split(/(::|\#|\.)/)
+
+ if parts[-2] != '::' or parts.last !~ /^[A-Z]/ then
+ meth = parts.pop
+ parts.pop
+ end
+
+ klass = parts.join
+
+ [klass, meth]
+ end
+
def populate_class_cache(class_cache, classes, extension = false)
classes.each do |cdesc|
desc = read_yaml cdesc
@@ -351,11 +449,6 @@ Options may also be set in the 'RI' environment variable.
YAML.load data
end
- def get_info_for(arg)
- @names = [arg]
- run
- end
-
def run
if @names.empty? then
@display.list_known_classes class_cache.keys.sort
@@ -368,15 +461,10 @@ Options may also be set in the 'RI' environment variable.
else
meth = nil
- parts = name.split(/::|\#|\./)
- meth = parts.pop unless parts.last =~ /^[A-Z]/
- klass = parts.join '::'
+ klass, meth = parse_name name
+
+ method = lookup_method name, klass
- cache = load_cache_for klass
- # HACK Does not support F.n
- abort "Nothing known about #{name}" unless cache
- method = cache[name.gsub(/\./, '#')]
- abort "Nothing known about #{name}" unless method
@display.display_method_info method
end
else
@@ -385,7 +473,7 @@ Options may also be set in the 'RI' environment variable.
else
methods = select_methods(/^#{name}/)
if methods.size == 0
- abort "Nothing known about #{name}"
+ raise NotFoundError, name
elsif methods.size == 1
@display.display_method_info methods.first
else
@@ -395,6 +483,8 @@ Options may also be set in the 'RI' environment variable.
end
end
end
+ rescue NotFoundError => e
+ abort e.message
end
def select_methods(pattern)
@@ -422,31 +512,3 @@ Options may also be set in the 'RI' environment variable.
end
-class Hash # HACK don't add stuff to Hash.
- def method_missing method, *args
- self[method.to_s]
- end
-
- def merge_enums(other)
- other.each do |k,v|
- if self[k] then
- case v
- when Array then
- # HACK dunno
- if String === self[k] and self[k].empty? then
- self[k] = v
- else
- self[k] += v
- end
- when Hash then
- self[k].merge! v
- else
- # do nothing
- end
- else
- self[k] = v
- end
- end
- end
-end
-