From 0b6da24a5e24ff9ce8e153d2f073c2363e94b28e Mon Sep 17 00:00:00 2001 From: drbrain Date: Sat, 14 May 2011 00:39:16 +0000 Subject: * lib/rdoc.rb: Updated to RDoc 3.6 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31558 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/rdoc.rb | 38 +++++++++++++++++++++++--------------- lib/rdoc/attr.rb | 13 +++++++++++++ lib/rdoc/class_module.rb | 16 +++++++++++++--- lib/rdoc/code_object.rb | 14 ++++++++++++++ lib/rdoc/context.rb | 20 ++++++++++++++++---- lib/rdoc/method_attr.rb | 2 ++ lib/rdoc/options.rb | 4 +++- lib/rdoc/parser/c.rb | 2 +- lib/rdoc/parser/ruby.rb | 35 ++++++++++++++++++++++++----------- lib/rdoc/rdoc.rb | 39 ++++++++++++++++++++++++--------------- lib/rdoc/ri/driver.rb | 46 ++++++++++++++++++++++++++++++++++------------ lib/rdoc/ri/store.rb | 12 ++++++++++++ lib/rdoc/ruby_lex.rb | 6 ++++-- lib/rdoc/stats.rb | 2 +- lib/rdoc/task.rb | 21 ++++++++++----------- lib/rdoc/text.rb | 16 ++++------------ 16 files changed, 198 insertions(+), 88 deletions(-) (limited to 'lib') diff --git a/lib/rdoc.rb b/lib/rdoc.rb index d9948deebb..6414bd7683 100644 --- a/lib/rdoc.rb +++ b/lib/rdoc.rb @@ -3,31 +3,39 @@ $DEBUG_RDOC = nil # :main: README.txt ## -# = \RDoc - Ruby Documentation System -# -# This package contains RDoc and RDoc::Markup. RDoc is an application that -# produces documentation for one or more Ruby source files. It works similarly -# to JavaDoc, parsing the source, and extracting the definition for classes, -# modules, and methods (along with includes and requires). It associates with -# these optional documentation contained in the immediately preceding comment -# block, and then renders the result using a pluggable output formatter. -# RDoc::Markup is a library that converts plain text into various output -# formats. The markup library is used to interpret the comment blocks that -# RDoc uses to document methods, classes, and so on. +# RDoc is a Ruby documentation system which contains RDoc::RDoc for generating +# documentation, RDoc::RI for interactive documentation and RDoc::Markup for +# text markup. +# +# RDoc::RDoc produces documentation for Ruby source files. It works similarly +# to JavaDoc, parsing the source and extracting the definition for classes, +# modules, methods, includes and requires. It associates these with optional +# documentation contained in an immediately preceding comment block then +# renders the result using an output formatter. +# +# RDoc::Markup that converts plain text into various output formats. The +# markup library is used to interpret the comment blocks that RDoc uses to +# document methods, classes, and so on. +# +# RDoc::RI implements the +ri+ command-line tool which displays on-line +# documentation for ruby classes, methods, etc. +ri+ features several output +# formats and an interactive mode (ri -i). See ri --help +# for further details. # # == Roadmap # # * If you want to use RDoc to create documentation for your Ruby source files, -# read the summary below, and refer to rdoc --help for command line -# usage, and RDoc::Markup for a detailed description of RDoc's markup. +# see RDoc::Markup and refer to rdoc --help for command line +# usage. # * If you want to generate documentation for extensions written in C, see # RDoc::Parser::C +# * If you want to generate documentation using rake see RDoc::Task. # * If you want to drive RDoc programmatically, see RDoc::RDoc. # * If you want to use the library to format text blocks into HTML, look at # RDoc::Markup. # * If you want to make an RDoc plugin such as a generator or directive # handler see RDoc::RDoc. -# * If you want to try writing your own output generator see RDoc::Generator. +# * If you want to write your own output generator see RDoc::Generator. # # == Summary # @@ -95,7 +103,7 @@ module RDoc ## # RDoc version you are using - VERSION = '3.5.3' + VERSION = '3.6' ## # Method visibilities diff --git a/lib/rdoc/attr.rb b/lib/rdoc/attr.rb index 97fac3222d..f04fe168b1 100644 --- a/lib/rdoc/attr.rb +++ b/lib/rdoc/attr.rb @@ -68,6 +68,19 @@ class RDoc::Attr < RDoc::MethodAttr end end + def inspect # :nodoc: + alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil + visibility = self.visibility + visibility = "forced #{visibility}" if force_documentation + "#<%s:0x%x %s %s (%s)%s>" % [ + self.class, object_id, + full_name, + rw, + visibility, + alias_for, + ] + end + ## # Dumps this Attr for use by ri. See also #marshal_load diff --git a/lib/rdoc/class_module.rb b/lib/rdoc/class_module.rb index 3f2d04488e..89441b3e68 100644 --- a/lib/rdoc/class_module.rb +++ b/lib/rdoc/class_module.rb @@ -137,12 +137,22 @@ class RDoc::ClassModule < RDoc::Context remove_invisible min_visibility end + ## + # Iterates the ancestors of this class or module for which an + # RDoc::ClassModule exists. + + def each_ancestor # :yields: module + ancestors.each do |mod| + next if String === mod + yield mod + end + end + ## # Looks for a symbol in the #ancestors. See Context#find_local_symbol. def find_ancestor_local_symbol symbol - ancestors.each do |m| - next if m.is_a?(String) + each_ancestor do |m| res = m.find_local_symbol(symbol) return res if res end @@ -263,7 +273,7 @@ class RDoc::ClassModule < RDoc::Context class_module.each_attribute do |attr| if match = attributes.find { |a| a.name == attr.name } then - match.rw = [match.rw, attr.rw].compact.join + match.rw = [match.rw, attr.rw].compact.uniq.join else add_attribute attr end diff --git a/lib/rdoc/code_object.rb b/lib/rdoc/code_object.rb index 3a8adfab67..63f86afc64 100644 --- a/lib/rdoc/code_object.rb +++ b/lib/rdoc/code_object.rb @@ -180,6 +180,20 @@ class RDoc::CodeObject @document_children = @document_self end + ## + # Yields each parent of this CodeObject. See also + # RDoc::ClassModule#each_ancestor + + def each_parent + code_object = self + + while code_object = code_object.parent do + yield code_object + end + + self + end + ## # Force the documentation of this object unless documentation # has been turned off by :endoc: diff --git a/lib/rdoc/context.rb b/lib/rdoc/context.rb index 3f2856db05..0d7fc41529 100644 --- a/lib/rdoc/context.rb +++ b/lib/rdoc/context.rb @@ -480,7 +480,7 @@ class RDoc::Context < RDoc::CodeObject # Adds included module +include+ which should be an RDoc::Include def add_include(include) - add_to @includes, include + add_to @includes, include unless @includes.map { |i| i.full_name }.include?( include.full_name ) end ## @@ -950,10 +950,14 @@ class RDoc::Context < RDoc::CodeObject ## # Yields AnyMethod and Attr entries matching the list of names in +methods+. - def methods_matching(methods, singleton = false) + def methods_matching(methods, singleton = false, &block) (@method_list + @attributes).each do |m| yield m if methods.include?(m.name) and m.singleton == singleton end + + each_ancestor do |parent| + parent.methods_matching(methods, singleton, &block) + end end ## @@ -1021,11 +1025,19 @@ class RDoc::Context < RDoc::CodeObject remove_invisible_in @attributes, min_visibility end + ## + # Only called when min_visibility == :public or :private + def remove_invisible_in(array, min_visibility) # :nodoc: if min_visibility == :public - array.reject! { |e| e.visibility != :public } + array.reject! { |e| + e.visibility != :public and not e.force_documentation + } else - array.reject! { |e| e.visibility == :private } + array.reject! { |e| + e.visibility == :private and + not e.force_documentation + } end end diff --git a/lib/rdoc/method_attr.rb b/lib/rdoc/method_attr.rb index 15924d9ed0..a4cd3c5fff 100644 --- a/lib/rdoc/method_attr.rb +++ b/lib/rdoc/method_attr.rb @@ -333,6 +333,8 @@ class RDoc::MethodAttr < RDoc::CodeObject def inspect # :nodoc: alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil + visibility = self.visibility + visibility = "forced #{visibility}" if force_documentation "#<%s:0x%x %s (%s)%s>" % [ self.class, object_id, full_name, diff --git a/lib/rdoc/options.rb b/lib/rdoc/options.rb index dd91706638..bab5463897 100644 --- a/lib/rdoc/options.rb +++ b/lib/rdoc/options.rb @@ -256,7 +256,9 @@ class RDoc::Options @rdoc_include << "." if @rdoc_include.empty? - if @exclude.empty? then + if @exclude.nil? or Regexp === @exclude then + # done, #finish is being re-run + elsif @exclude.empty? then @exclude = nil else @exclude = Regexp.new(@exclude.join("|")) diff --git a/lib/rdoc/parser/c.rb b/lib/rdoc/parser/c.rb index bb015690bd..0f2196b2e8 100644 --- a/lib/rdoc/parser/c.rb +++ b/lib/rdoc/parser/c.rb @@ -376,7 +376,7 @@ class RDoc::Parser::C < RDoc::Parser when %r%((?>/\*.*?\*/\s*)?) ((?:(?:static|SWIGINTERN)\s+)? (?:intern\s+)?VALUE\s+#{meth_name} - \s*(\(.*?\))([^;]|$))%xm then + \s*(\([^)]*\))([^;]|$))%xm then comment = $1 body = $2 offset = $~.offset(2).first diff --git a/lib/rdoc/parser/ruby.rb b/lib/rdoc/parser/ruby.rb index bcf0ac1150..6bf1c8d308 100644 --- a/lib/rdoc/parser/ruby.rb +++ b/lib/rdoc/parser/ruby.rb @@ -1558,32 +1558,45 @@ class RDoc::Parser::Ruby < RDoc::Parser when TkNL, TkUNLESS_MOD, TkIF_MOD, TkSEMICOLON then container.ongoing_visibility = vis else - if vis_type == 'module_function' then + new_methods = [] + + case vis_type + when 'module_function' then args = parse_symbol_arg container.set_visibility_for args, :private, false - module_functions = [] - container.methods_matching args do |m| s_m = m.dup s_m.record_location @top_level s_m.singleton = true - s_m.visibility = :public - module_functions << s_m + new_methods << s_m end + when 'public_class_method', 'private_class_method' then + args = parse_symbol_arg - module_functions.each do |s_m| - case s_m - when RDoc::AnyMethod then - container.add_method s_m - when RDoc::Attr then - container.add_attribute s_m + container.methods_matching args, true do |m| + if m.parent != container then + m = m.dup + m.record_location @top_level + new_methods << m end + + m.visibility = vis end else args = parse_symbol_arg container.set_visibility_for args, vis, singleton end + + new_methods.each do |method| + case method + when RDoc::AnyMethod then + container.add_method method + when RDoc::Attr then + container.add_attribute method + end + method.visibility = vis + end end end diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb index 3eab6cdfc4..6d7c4eace6 100644 --- a/lib/rdoc/rdoc.rb +++ b/lib/rdoc/rdoc.rb @@ -418,7 +418,7 @@ The internal error was: @last_modified = setup_output_dir @options.op_dir, @options.force_update end - start_time = Time.now + @start_time = Time.now file_info = parse_files @options.files @@ -439,20 +439,7 @@ The internal error was: @generator = gen_klass.new @options - Dir.chdir @options.op_dir do - begin - self.class.current = self - - unless @options.quiet then - $stderr.puts "\nGenerating #{gen_klass.name.sub(/^.*::/, '')} format into #{Dir.pwd}..." - end - - @generator.generate file_info - update_output_dir ".", start_time, @last_modified - ensure - self.class.current = nil - end - end + generate file_info end if @stats and (@options.coverage_report or not @options.quiet) then @@ -463,6 +450,28 @@ The internal error was: exit @stats.fully_documented? if @options.coverage_report end + ## + # Generates documentation for +file_info+ (from #parse_files) into the + # output dir using the generator selected + # by the RDoc options + + def generate file_info + Dir.chdir @options.op_dir do + begin + self.class.current = self + + unless @options.quiet then + $stderr.puts "\nGenerating #{@generator.class.name.sub(/^.*::/, '')} format into #{Dir.pwd}..." + end + + @generator.generate file_info + update_output_dir '.', @start_time, @last_modified + ensure + self.class.current = nil + end + end + end + ## # Removes a siginfo handler and replaces the previous diff --git a/lib/rdoc/ri/driver.rb b/lib/rdoc/ri/driver.rb index 9a336f7f3f..46aeaeebc2 100644 --- a/lib/rdoc/ri/driver.rb +++ b/lib/rdoc/ri/driver.rb @@ -197,6 +197,13 @@ Options may also be set in the 'RI' environment variable. opt.separator nil + opt.on("--list", "-l", + "List classes ri knows about.") do + options[:list] = true + end + + opt.separator nil + opt.on("--[no-]profile", "Run with the ruby profiler") do |value| options[:profile] = value @@ -331,6 +338,7 @@ Options may also be set in the 'RI' environment variable. require 'profile' if options[:profile] @names = options[:names] + @list = options[:list] @doc_dirs = [] @stores = [] @@ -524,7 +532,10 @@ Options may also be set in the 'RI' environment variable. klass_name = method ? name : klass if name !~ /#|\./ then - completions.push(*klasses.grep(/^#{klass_name}/)) + completions = klasses.grep(/^#{klass_name}[^:]*$/) + completions.concat klasses.grep(/^#{name}[^:]*$/) if name =~ /::$/ + + completions << klass if classes.key? klass # to complete a method name elsif selector then completions << klass if classes.key? klass elsif classes.key? klass_name then @@ -546,7 +557,7 @@ Options may also be set in the 'RI' environment variable. completions.push(*methods) end - completions.sort + completions.sort.uniq end ## @@ -878,9 +889,10 @@ Options may also be set in the 'RI' environment variable. end ## - # Lists classes known to ri + # Lists classes known to ri starting with +names+. If +names+ is empty all + # known classes are shown. - def list_known_classes + def list_known_classes names = [] classes = [] stores.each do |store| @@ -889,9 +901,19 @@ Options may also be set in the 'RI' environment variable. classes = classes.flatten.uniq.sort + unless names.empty? then + filter = Regexp.union names.map { |name| /^#{name}/ } + + classes = classes.grep filter + end + page do |io| if paging? or io.tty? then - io.puts "Classes and Modules known to ri:" + if names.empty? then + io.puts "Classes and Modules known to ri:" + else + io.puts "Classes and Modules starting with #{names.join ', '}:" + end io.puts end @@ -910,7 +932,7 @@ Options may also be set in the 'RI' environment variable. methods = store.instance_methods[ancestor] if methods then - matches = methods.grep(/^#{method}/) + matches = methods.grep(/^#{Regexp.escape method.to_s}/) matches = matches.map do |match| "#{klass}##{match}" @@ -924,7 +946,7 @@ Options may also be set in the 'RI' environment variable. methods = store.class_methods[ancestor] next unless methods - matches = methods.grep(/^#{method}/) + matches = methods.grep(/^#{Regexp.escape method.to_s}/) matches = matches.map do |match| "#{klass}::#{match}" @@ -996,9 +1018,9 @@ Options may also be set in the 'RI' environment variable. case type when '#', '::' then - /^#{klass}#{type}#{name}$/ + /^#{klass}#{type}#{Regexp.escape name}$/ else - /^#{klass}(#|::)#{name}$/ + /^#{klass}(#|::)#{Regexp.escape name}$/ end end @@ -1064,10 +1086,10 @@ Options may also be set in the 'RI' environment variable. def run if @list_doc_dirs then puts @doc_dirs - elsif @interactive then + elsif @list then + list_known_classes @names + elsif @interactive or @names.empty? then interactive - elsif @names.empty? then - list_known_classes else display_names @names end diff --git a/lib/rdoc/ri/store.rb b/lib/rdoc/ri/store.rb index 1fcd313d0f..c3939c493a 100644 --- a/lib/rdoc/ri/store.rb +++ b/lib/rdoc/ri/store.rb @@ -7,6 +7,18 @@ require 'fileutils' # The store manages reading and writing ri data for a project (gem, path, # etc.) and maintains a cache of methods, classes and ancestors in the # store. +# +# The store maintains a #cache of its contents for faster lookup. After +# adding items to the store it must be flushed using #save_cache. The cache +# contains the following structures: +# +# @cache = { +# :class_methods => {}, # class name => class methods +# :instance_methods => {}, # class name => instance methods +# :attributes => {}, # class name => attributes +# :modules => [], # classes and modules in this store +# :ancestors => {}, # class name => ancestor names +# } class RDoc::RI::Store diff --git a/lib/rdoc/ruby_lex.rb b/lib/rdoc/ruby_lex.rb index e4f2445438..60d4a4c76b 100644 --- a/lib/rdoc/ruby_lex.rb +++ b/lib/rdoc/ruby_lex.rb @@ -403,9 +403,11 @@ class RDoc::RubyLex res = '' nil until (ch = getc) == "\n" - until peek_equal?("=end") && peek(4) =~ /\s/ do - until (ch = getc) == "\n" do res << ch end + until ( peek_equal?("=end") && peek(4) =~ /\s/ ) do + (ch = getc) + res << ch end + gets # consume =end @ltype = nil diff --git a/lib/rdoc/stats.rb b/lib/rdoc/stats.rb index c46a610d45..e6101bb457 100644 --- a/lib/rdoc/stats.rb +++ b/lib/rdoc/stats.rb @@ -31,7 +31,7 @@ class RDoc::Stats @coverage_level = 0 @doc_items = nil - @fully_documented = nil + @fully_documented = false @num_params = 0 @percent_doc = nil @start = Time.now diff --git a/lib/rdoc/task.rb b/lib/rdoc/task.rb index ebf8ccc188..ec7459729a 100644 --- a/lib/rdoc/task.rb +++ b/lib/rdoc/task.rb @@ -37,9 +37,8 @@ require 'rake' require 'rake/tasklib' ## -# Create a documentation task that will generate the RDoc files for a project. -# -# The RDoc::Task will create the following targets: +# RDoc::Task creates the following rake tasks to generate and clean up RDoc +# output: # # [rdoc] # Main task for this RDoc task. @@ -56,12 +55,12 @@ require 'rake/tasklib' # gem 'rdoc' # require 'rdoc/task' # -# RDoc::Task.new do |rd| -# rd.main = "README.rdoc" -# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") +# RDoc::Task.new do |rdoc| +# rdoc.main = "README.rdoc" +# rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb") # end # -# The +rd+ object passed to the block is an RDoc::Task object. See the +# The +rdoc+ object passed to the block is an RDoc::Task object. See the # attributes list for the RDoc::Task class for available customization options. # # == Specifying different task names @@ -73,10 +72,10 @@ require 'rake/tasklib' # gem 'rdoc' # require 'rdoc/task' # -# RDoc::Task.new :rdoc_dev do |rd| -# rd.main = "README.doc" -# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") -# rd.options << "--all" +# RDoc::Task.new :rdoc_dev do |rdoc| +# rdoc.main = "README.doc" +# rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb") +# rdoc.options << "--all" # end # # The tasks would then be named :rdoc_dev, diff --git a/lib/rdoc/text.rb b/lib/rdoc/text.rb index adbc630cf1..ace44bf56f 100644 --- a/lib/rdoc/text.rb +++ b/lib/rdoc/text.rb @@ -61,25 +61,17 @@ module RDoc::Text # Flush +text+ left based on the shortest line def flush_left text - indents = [] + indent = 9999 text.each_line do |line| - indents << (line =~ /[^\s]/ || 9999) + line_indent = line =~ /\S/ || 9999 + indent = line_indent if indent > line_indent end - indent = indents.min - - flush = [] - empty = '' empty.force_encoding text.encoding if Object.const_defined? :Encoding - text.each_line do |line| - line[/^ {0,#{indent}}/] = empty - flush << line - end - - flush.join + text.gsub(/^ {0,#{indent}}/, empty) end ## -- cgit v1.2.3