From fd25f74d64c69d636764ea11aa5a809b85e58f69 Mon Sep 17 00:00:00 2001 From: drbrain Date: Fri, 18 Jul 2008 00:46:16 +0000 Subject: Import RDoc r101. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18121 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/rdoc/ri/descriptions.rb | 3 +- lib/rdoc/ri/driver.rb | 154 +++++++++++++++++++++++++++++++------------- 2 files changed, 109 insertions(+), 48 deletions(-) (limited to 'lib/rdoc/ri') 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 - -- cgit v1.2.3