diff options
Diffstat (limited to 'lib/rdoc/generator/ri.rb')
-rw-r--r-- | lib/rdoc/generator/ri.rb | 226 |
1 files changed, 40 insertions, 186 deletions
diff --git a/lib/rdoc/generator/ri.rb b/lib/rdoc/generator/ri.rb index 6b7a5932f8..ad9932a02a 100644 --- a/lib/rdoc/generator/ri.rb +++ b/lib/rdoc/generator/ri.rb @@ -1,225 +1,79 @@ require 'rdoc/generator' -require 'rdoc/markup/to_flow' +require 'rdoc/ri' -require 'rdoc/ri/cache' -require 'rdoc/ri/reader' -require 'rdoc/ri/writer' -require 'rdoc/ri/descriptions' +## +# Generates ri data files class RDoc::Generator::RI - ## - # Generator may need to return specific subclasses depending on the - # options they are passed. Because of this we create them using a factory + RDoc::RDoc.add_generator self - def self.for(options) - new(options) + def self.for options + new options end ## # Set up a new ri generator - def initialize(options) #:not-new: - @options = options - @ri_writer = RDoc::RI::Writer.new "." - @markup = RDoc::Markup.new - @to_flow = RDoc::Markup::ToFlow.new - - @generated = {} + def initialize options #:not-new: + @options = options + @store = RDoc::RI::Store.new '.' + @old_siginfo = nil + @current = nil end ## - # Build the initial indices and output objects based on an array of - # TopLevel objects containing the extracted information. - - def generate(toplevels) - RDoc::TopLevel.all_classes_and_modules.each do |cls| - process_class cls - end - end - - def process_class(from_class) - generate_class_info(from_class) + # Build the initial indices and output objects based on an array of TopLevel + # objects containing the extracted information. - # now recurse into this class' constituent classes - from_class.each_classmodule do |mod| - process_class(mod) - end - end - - def generate_class_info(cls) - case cls - when RDoc::NormalModule then - cls_desc = RDoc::RI::ModuleDescription.new - else - cls_desc = RDoc::RI::ClassDescription.new - cls_desc.superclass = cls.superclass - end + def generate top_levels + install_siginfo_handler - cls_desc.name = cls.name - cls_desc.full_name = cls.full_name - cls_desc.comment = markup(cls.comment) + RDoc::TopLevel.all_classes_and_modules.each do |klass| + @current = "#{klass.class}: #{klass.full_name}" - cls_desc.attributes = cls.attributes.sort.map do |a| - RDoc::RI::Attribute.new(a.name, a.rw, markup(a.comment)) - end + @store.save_class klass - cls_desc.constants = cls.constants.map do |c| - RDoc::RI::Constant.new(c.name, c.value, markup(c.comment)) - end - - cls_desc.includes = cls.includes.map do |i| - RDoc::RI::IncludedModule.new(i.name) - end - - class_methods, instance_methods = method_list(cls) - - cls_desc.class_methods = class_methods.map do |m| - RDoc::RI::MethodSummary.new(m.name) - end - - cls_desc.instance_methods = instance_methods.map do |m| - RDoc::RI::MethodSummary.new(m.name) - end - - update_or_replace(cls_desc) - - class_methods.each do |m| - generate_method_info(cls_desc, m) - end + klass.each_method do |method| + @current = "#{method.class}: #{method.full_name}" + @store.save_method klass, method + end - instance_methods.each do |m| - generate_method_info(cls_desc, m) + klass.each_attribute do |attribute| + @store.save_method klass, attribute + end end - end - def generate_method_info(cls_desc, method) - meth_desc = RDoc::RI::MethodDescription.new - meth_desc.name = method.name - meth_desc.full_name = cls_desc.full_name - if method.singleton - meth_desc.full_name += "::" - else - meth_desc.full_name += "#" - end - meth_desc.full_name << method.name + @current = 'saving cache' - meth_desc.comment = markup(method.comment) - meth_desc.params = params_of(method) - meth_desc.visibility = method.visibility.to_s - meth_desc.is_singleton = method.singleton - meth_desc.block_params = method.block_params + @store.save_cache - meth_desc.aliases = method.aliases.map do |a| - RDoc::RI::AliasName.new(a.name) - end + ensure + @current = nil - @ri_writer.add_method(cls_desc, meth_desc) + remove_siginfo_handler end - private - ## - # Returns a list of class and instance methods that we'll be documenting - - def method_list(cls) - list = cls.method_list - unless @options.show_all - list = list.find_all do |m| - m.visibility == :public || m.visibility == :protected || m.force_documentation - end - end + # Installs a siginfo handler that prints the current filename. - c = [] - i = [] - list.sort.each do |m| - if m.singleton - c << m - else - i << m - end - end - return c,i - end + def install_siginfo_handler + return unless Signal.list.key? 'INFO' - def params_of(method) - if method.call_seq - method.call_seq - else - params = method.params || "" - - p = params.gsub(/\s*\#.*/, '') - p = p.tr("\n", " ").squeeze(" ") - p = "(" + p + ")" unless p[0] == ?( - - if (block = method.block_params) - block.gsub!(/\s*\#.*/, '') - block = block.tr("\n", " ").squeeze(" ") - if block[0] == ?( - block.sub!(/^\(/, '').sub!(/\)/, '') - end - p << " {|#{block.strip}| ...}" - end - p + @old_siginfo = trap 'INFO' do + puts @current if @current end end - def markup(comment) - return nil if !comment || comment.empty? - - # Convert leading comment markers to spaces, but only - # if all non-blank lines have them - - if comment =~ /^(?>\s*)[^\#]/ - content = comment - else - content = comment.gsub(/^\s*(#+)/) { $1.tr('#',' ') } - end - @markup.convert(content, @to_flow) - end - ## - # By default we replace existing classes with the same name. If the - # --merge option was given, we instead merge this definition into an - # existing class. We add our methods, aliases, etc to that class, but do - # not change the class's description. - - def update_or_replace(cls_desc) - old_cls = nil - - if @options.merge - rdr = RDoc::RI::Reader.new RDoc::RI::Cache.new(@options.op_dir) - - namespace = rdr.top_level_namespace - namespace = rdr.lookup_namespace_in(cls_desc.name, namespace) - if namespace.empty? - $stderr.puts "You asked me to merge this source into existing " - $stderr.puts "documentation. This file references a class or " - $stderr.puts "module called #{cls_desc.name} which I don't" - $stderr.puts "have existing documentation for." - $stderr.puts - $stderr.puts "Perhaps you need to generate its documentation first" - exit 1 - else - old_cls = namespace[0] - end - end - - prev_cls = @generated[cls_desc.full_name] + # Removes a siginfo handler and replaces the previous - if old_cls and not prev_cls then - old_desc = rdr.get_class old_cls - cls_desc.merge_in old_desc - end - - if prev_cls then - cls_desc.merge_in prev_cls - end + def remove_siginfo_handler + return unless Signal.list.key? 'INFO' - @generated[cls_desc.full_name] = cls_desc + handler = @old_siginfo || 'DEFAULT' - @ri_writer.remove_class cls_desc - @ri_writer.add_class cls_desc + trap 'INFO', handler end end |