summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/rdoc.rb38
-rw-r--r--lib/rdoc/attr.rb13
-rw-r--r--lib/rdoc/class_module.rb16
-rw-r--r--lib/rdoc/code_object.rb14
-rw-r--r--lib/rdoc/context.rb20
-rw-r--r--lib/rdoc/method_attr.rb2
-rw-r--r--lib/rdoc/options.rb4
-rw-r--r--lib/rdoc/parser/c.rb2
-rw-r--r--lib/rdoc/parser/ruby.rb35
-rw-r--r--lib/rdoc/rdoc.rb39
-rw-r--r--lib/rdoc/ri/driver.rb46
-rw-r--r--lib/rdoc/ri/store.rb12
-rw-r--r--lib/rdoc/ruby_lex.rb6
-rw-r--r--lib/rdoc/stats.rb2
-rw-r--r--lib/rdoc/task.rb21
-rw-r--r--lib/rdoc/text.rb16
16 files changed, 198 insertions, 88 deletions
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 (<tt>ri -i</tt>). See <tt>ri --help</tt>
+# 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 <tt>rdoc --help</tt> for command line
-# usage, and RDoc::Markup for a detailed description of RDoc's markup.
+# see RDoc::Markup and refer to <tt>rdoc --help</tt> 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 <tt>rake</tt> 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
@@ -138,11 +138,21 @@ class RDoc::ClassModule < RDoc::Context
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
@@ -181,6 +181,20 @@ class RDoc::CodeObject
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
@@ -464,6 +451,28 @@ The internal error was:
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
def remove_siginfo_handler
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 :<em>rdoc_dev</em>,
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
##