[前][次][番号順一覧][スレッド一覧]

ruby-changes:26199

From: drbrain <ko1@a...>
Date: Fri, 7 Dec 2012 14:23:05 +0900 (JST)
Subject: [ruby-changes:26199] drbrain:r38256 (trunk): * lib/rdoc/markup/to_joined_paragraph.rb: Completed documentation

drbrain	2012-12-07 14:22:50 +0900 (Fri, 07 Dec 2012)

  New Revision: 38256

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38256

  Log:
    * lib/rdoc/markup/to_joined_paragraph.rb:  Completed documentation
    * lib/rdoc/parser/c.rb:  ditto
    * lib/rdoc/parser/changelog.rb:  ditto
    * lib/rdoc/servlet.rb:  ditto
    * lib/rdoc/store.rb:  ditto
    
    * lib/rdoc/store.rb:  Improved HTML error page.  Completed
      documentation
    
    * lib/rdoc/parser/ruby.rb:  Fixed bug attaching a comment to A::B = 42
    * test/rdoc/test_rdoc_parser_ruby.rb:  Test for above
    
    * test/rdoc/test_rdoc_comment.rb:  Removed garbage

  Modified files:
    trunk/ChangeLog
    trunk/lib/rdoc/markup/to_joined_paragraph.rb
    trunk/lib/rdoc/parser/c.rb
    trunk/lib/rdoc/parser/changelog.rb
    trunk/lib/rdoc/parser/ruby.rb
    trunk/lib/rdoc/servlet.rb
    trunk/lib/rdoc/store.rb
    trunk/test/rdoc/test_rdoc_comment.rb
    trunk/test/rdoc/test_rdoc_parser_ruby.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38255)
+++ ChangeLog	(revision 38256)
@@ -1,3 +1,19 @@
+Fri Dec  7 14:22:29 2012  Eric Hodel  <drbrain@s...>
+
+	* lib/rdoc/markup/to_joined_paragraph.rb:  Completed documentation
+	* lib/rdoc/parser/c.rb:  ditto
+	* lib/rdoc/parser/changelog.rb:  ditto
+	* lib/rdoc/servlet.rb:  ditto
+	* lib/rdoc/store.rb:  ditto
+
+	* lib/rdoc/store.rb:  Improved HTML error page.  Completed
+	  documentation
+
+	* lib/rdoc/parser/ruby.rb:  Fixed bug attaching a comment to A::B = 42
+	* test/rdoc/test_rdoc_parser_ruby.rb:  Test for above
+
+	* test/rdoc/test_rdoc_comment.rb:  Removed garbage
+
 Fri Dec  7 14:03:59 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/timeout.rb (Timeout#timeout): since async_interrupt_timing
Index: lib/rdoc/store.rb
===================================================================
--- lib/rdoc/store.rb	(revision 38255)
+++ lib/rdoc/store.rb	(revision 38256)
@@ -59,7 +59,7 @@
       @name  = name
     end
 
-    def message
+    def message # :nodoc:
       "store at #{@store.path} missing file #{@file} for #{@name}"
     end
 
Index: lib/rdoc/markup/to_joined_paragraph.rb
===================================================================
--- lib/rdoc/markup/to_joined_paragraph.rb	(revision 38255)
+++ lib/rdoc/markup/to_joined_paragraph.rb	(revision 38256)
@@ -12,12 +12,15 @@
     super nil
   end
 
-  def start_accepting
+  def start_accepting # :nodoc:
   end
 
-  def end_accepting
+  def end_accepting # :nodoc:
   end
 
+  ##
+  # Converts the parts of +paragraph+ to a single entry.
+
   def accept_paragraph paragraph
     parts = []
     string = false
Index: lib/rdoc/servlet.rb
===================================================================
--- lib/rdoc/servlet.rb	(revision 38255)
+++ lib/rdoc/servlet.rb	(revision 38256)
@@ -2,21 +2,60 @@
 require 'time'
 require 'webrick'
 
+##
+# This is a WEBrick servlet that allows you to browse ri documentation.
+#
+# You can show documentation through either `ri --server` or, with RubyGems
+# 2.0 or newer, `gem server`.  For ri, the server runs on port 8214 by
+# default.  For RubyGems the server runs on port 8808 by default.
+#
+# You can use this servlet in your own project by mounting it on a WEBrick
+# server:
+#
+#   require 'webrick'
+#
+#   server = WEBrick::HTTPServer.new Port: 8000
+#
+#   server.mount '/', RDoc::Servlet
+#
+# If you want to mount the servlet some other place than the root, provide the
+# base path when mounting:
+#
+#   server.mount '/rdoc', RDoc::Servlet, '/rdoc'
+
 class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
 
   @server_stores = Hash.new { |hash, server| hash[server] = {} }
   @cache         = Hash.new { |hash, store|  hash[store]  = {} }
 
+  ##
+  # Maps an asset type to its path on the filesystem
+
   attr_reader :asset_dirs
 
+  ##
+  # An RDoc::Options instance used for rendering options
+
   attr_reader :options
 
-  def self.get_instance server, *options
+  ##
+  # Creates an instance of this servlet that shares cached data between
+  # requests.
+
+  def self.get_instance server, *options # :nodoc:
     stores = @server_stores[server]
 
     new server, stores, @cache, *options
   end
 
+  ##
+  # Creates a new WEBrick servlet.
+  #
+  # Use +mount_path+ when mounting the servlet somewhere other than /.
+  #
+  # +server+ is provided automatically by WEBrick when mounting.  +stores+ and
+  # +cache+ are provided automatically by the servlet.
+
   def initialize server, stores, cache, mount_path = nil
     super server
 
@@ -44,6 +83,9 @@
     }
   end
 
+  ##
+  # Serves the asset at the path in +req+ for +generator_name+ via +res+.
+
   def asset generator_name, req, res
     asset_dir = @asset_dirs[generator_name]
 
@@ -60,6 +102,9 @@
                        end
   end
 
+  ##
+  # GET request entry point.  Fills in +res+ for the path, etc. in +req+.
+
   def do_GET req, res
     req.path.sub!(/^#{Regexp.escape @mount_path}/o, '') if @mount_path
 
@@ -82,6 +127,13 @@
     error e, req, res
   end
 
+  ##
+  # Fills in +res+ with the class, module or page for +req+ from +store+.
+  #
+  # +path+ is relative to the mount_path and is used to determine the class,
+  # module or page name (/RDoc/Servlet.html becomes RDoc::Servlet).
+  # +generator+ is used to create the page.
+
   def documentation_page store, generator, path, req, res
     name = path.sub(/.html$/, '').gsub '/', '::'
 
@@ -94,6 +146,10 @@
     end
   end
 
+  ##
+  # Creates the JSON search index on +res+ for the given +store+.  +generator+
+  # must respond to \#json_index to build.  +req+ is ignored.
+
   def documentation_search store, generator, req, res
     json_index = @cache[store].fetch :json_index do
       @cache[store][:json_index] =
@@ -104,6 +160,10 @@
     res.body = "var search_data = #{json_index}"
   end
 
+  ##
+  # Returns the RDoc::Store and path relative to +mount_path+ for
+  # documentation at +path+.
+
   def documentation_source path
     _, source_name, path = path.split '/', 3
 
@@ -119,9 +179,12 @@
     return store, path
   end
 
-  def error e, req, res
-    backtrace = e.backtrace.join "\n"
+  ##
+  # Generates an error page for the +exception+ while handling +req+ on +res+.
 
+  def error exception, req, res
+    backtrace = exception.backtrace.join "\n"
+
     res.content_type = 'text/html'
     res.status = 500
     res.body = <<-BODY
@@ -130,7 +193,7 @@
 <head>
 <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
 
-<title>Error - #{ERB::Util.html_escape e.class}</title>
+<title>Error - #{ERB::Util.html_escape exception.class}</title>
 
 <link type="text/css" media="screen" href="#{@mount_path}/rdoc.css" rel="stylesheet">
 </head>
@@ -138,11 +201,18 @@
 <h1>Error</h1>
 
 <p>While processing <code>#{ERB::Util.html_escape req.request_uri}</code> the
-RDoc server has encountered a <code>#{ERB::Util.html_escape e.class}</code>
+RDoc (#{ERB::Util.html_escape RDoc::VERSION}) server has encountered a
+<code>#{ERB::Util.html_escape exception.class}</code>
 exception:
 
-<pre>#{ERB::Util.html_escape e.message}</pre>
+<pre>#{ERB::Util.html_escape exception.message}</pre>
 
+<p>Please report this to the
+<a href="https://github.com/rdoc/rdoc/issues">RDoc issues tracker</a>.  Please
+include the RDoc version, the URI above and exception class, message and
+backtrace.  If you're viewing a gem's documentation, include the gem name and
+version.  If you're viewing Ruby's documentation, include the version of ruby.
+
 <p>Backtrace:
 
 <pre>#{ERB::Util.html_escape backtrace}</pre>
@@ -152,6 +222,9 @@
     BODY
   end
 
+  ##
+  # Instantiates a Darkfish generator for +store+
+
   def generator_for store
     generator = RDoc::Generator::Darkfish.new store, @options
     generator.file_output = false
@@ -168,6 +241,11 @@
     generator
   end
 
+  ##
+  # Handles the If-Modified-Since HTTP header on +req+ for +path+.  If the
+  # file has not been modified a Not Modified response is returned.  If the
+  # file has been modified a Last-Modified header is added to +res+.
+
   def if_modified_since req, res, path = nil
     last_modified = File.stat(path).mtime if path
 
@@ -183,6 +261,14 @@
     end
   end
 
+  ##
+  # Returns an Array of installed documentation.
+  #
+  # Each entry contains the documentation name (gem name, 'Ruby
+  # Documentation', etc.), the path relative to the mount point, whether the
+  # documentation exists, the type of documentation (See RDoc::RI::Paths#each)
+  # and the filesystem to the RDoc::Store for the documentation.
+
   def installed_docs
     ri_paths.map do |path, type|
       store = RDoc::Store.new path, type
@@ -202,15 +288,24 @@
     end
   end
 
+  ##
+  # Returns a 404 page built by +generator+ for +req+ on +res+.
+
   def not_found generator, req, res
     res.body = generator.generate_servlet_not_found req.path
     res.status = 404
   end
 
+  ##
+  # Enumerates the ri paths.  See RDoc::RI::Paths#each
+
   def ri_paths &block
     RDoc::RI::Paths.each true, true, true, :all, &block
   end
 
+  ##
+  # Generates the root page on +res+.  +req+ is ignored.
+
   def root req, res
     generator = RDoc::Generator::Darkfish.new nil, @options
 
@@ -219,6 +314,9 @@
     res.content_type = 'text/html'
   end
 
+  ##
+  # Generates a search index for the root page on +res+.  +req+ is ignored.
+
   def root_search req, res
     search_index = []
     info         = []
@@ -259,6 +357,10 @@
     res.content_type = 'application/javascript'
   end
 
+  ##
+  # Displays documentation for +req+ on +res+, whether that be HTML or some
+  # asset.
+
   def show_documentation req, res
     store, path = documentation_source req.path
 
@@ -280,6 +382,9 @@
     res.content_type ||= 'text/html'
   end
 
+  ##
+  # Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name).
+
   def store_for source_name
     case source_name
     when 'ruby' then
Index: lib/rdoc/parser/ruby.rb
===================================================================
--- lib/rdoc/parser/ruby.rb	(revision 38255)
+++ lib/rdoc/parser/ruby.rb	(revision 38256)
@@ -240,7 +240,7 @@
   # with :: separated named) and return the ultimate name, the associated
   # container, and the given name (with the ::).
 
-  def get_class_or_module container
+  def get_class_or_module container, ignore_constants = false
     skip_tkspace
     name_t = get_tk
     given_name = ''
@@ -259,9 +259,16 @@
     while TkCOLON2 === peek_tk do
       prev_container = container
       container = container.find_module_named name_t.name
-      container ||= prev_container.add_module RDoc::NormalModule, name_t.name
+      container ||=
+        if ignore_constants then
+          RDoc::Context.new
+        else
+          c = prev_container.add_module RDoc::NormalModule, name_t.name
+          c.ignore unless prev_container.document_children
+          c
+        end
 
-      container.ignore unless prev_container.document_children
+      container.record_location @top_level
 
       get_tk
       skip_tkspace false
@@ -663,9 +670,10 @@
   end
 
   ##
-  # Parses a constant in +context+ with +comment+
+  # Parses a constant in +context+ with +comment+.  If +ignore_constants+ is
+  # true, no found constants will be added to RDoc.
 
-  def parse_constant container, tk, comment
+  def parse_constant container, tk, comment, ignore_constants = false
     offset  = tk.seek
     line_no = tk.line_no
 
@@ -676,6 +684,17 @@
 
     eq_tk = get_tk
 
+    if TkCOLON2 === eq_tk then
+      unget_tk eq_tk
+      unget_tk tk
+
+      container, name_t, = get_class_or_module container, ignore_constants
+
+      name = name_t.name
+
+      eq_tk = get_tk
+    end
+
     unless TkASSIGN === eq_tk then
       unget_tk eq_tk
       return false
@@ -1335,6 +1354,26 @@
   end
 
   ##
+  # Parses a rescue
+
+  def parse_rescue
+    skip_tkspace false
+
+    while tk = get_tk
+      case tk
+      when TkNL, TkSEMICOLON then
+        break
+      when TkCOMMA then
+        skip_tkspace false
+
+        get_tk if TkNL === peek_tk
+      end
+
+      skip_tkspace false
+    end
+  end
+
+  ##
   # The core of the ruby parser.
 
   def parse_statements(container, single = NORMAL, current_method = nil,
@@ -1407,7 +1446,7 @@
         parse_method container, single, tk, comment
 
       when TkCONSTANT then
-        unless parse_constant container, tk, comment then
+        unless parse_constant container, tk, comment, current_method then
           try_parse_comment = true
         end
 
@@ -1441,6 +1480,9 @@
       when TkSUPER then
         current_method.calls_super = true if current_method
 
+      when TkRESCUE then
+        parse_rescue
+
       when TkIDENTIFIER then
         if nest == 1 and current_method.nil? then
           case tk.name
Index: lib/rdoc/parser/c.rb
===================================================================
--- lib/rdoc/parser/c.rb	(revision 38255)
+++ lib/rdoc/parser/c.rb	(revision 38256)
@@ -446,6 +446,10 @@
     end
   end
 
+  ##
+  # Creates classes and module that were missing were defined due to the file
+  # order being different than the declaration order.
+
   def do_missing
     return if @missing_dependencies.empty?
 
Index: lib/rdoc/parser/changelog.rb
===================================================================
--- lib/rdoc/parser/changelog.rb	(revision 38255)
+++ lib/rdoc/parser/changelog.rb	(revision 38256)
@@ -1,11 +1,28 @@
 require 'time'
 
+##
+# A ChangeLog file parser.
+#
+# This parser converts a ChangeLog into an RDoc::Markup::Document.  When
+# viewed as HTML a ChangeLog page will have an entry for each day's entries in
+# the sidebar table of contents.
+#
+# This parser is meant to parse the MRI ChangeLog, but can be used to parse any
+# {GNU style Change
+# Log}[http://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html].
+
 class RDoc::Parser::ChangeLog < RDoc::Parser
 
   include RDoc::Parser::Text
 
   parse_files_matching(/(\/|\\|\A)ChangeLog[^\/\\]*\z/)
 
+  ##
+  # Attaches the +continuation+ of the previous line to the +entry_body+.
+  #
+  # Continued function listings are joined together as a single entry.
+  # Continued descriptions are joined to make a single paragraph.
+
   def continue_entry_body entry_body, continuation
     return unless last = entry_body.last
 
@@ -21,6 +38,9 @@
     end
   end
 
+  ##
+  # Creates an RDoc::Markup::Document given the +groups+ of ChangeLog entries.
+
   def create_document groups
     doc = RDoc::Markup::Document.new
     doc.omit_headings_below = 2
@@ -39,6 +59,10 @@
     doc
   end
 
+  ##
+  # Returns a list of ChangeLog entries an RDoc::Markup nodes for the given
+  # +entries+.
+
   def create_entries entries
     out = []
 
@@ -52,6 +76,10 @@
     out
   end
 
+  ##
+  # Returns an RDoc::Markup::List containing the given +items+ in the
+  # ChangeLog
+
   def create_items items
     list = RDoc::Markup::List.new :NOTE
 
@@ -69,12 +97,30 @@
     list
   end
 
+  ##
+  # Groups +entries+ by date.
+
   def group_entries entries
-    entries.group_by do |title, body|
+    entries.group_by do |title, _|
       Time.parse(title).strftime "%Y-%m-%d"
     end
   end
 
+  ##
+  # Parses the entries in the ChangeLog.
+  #
+  # Returns an Array of each ChangeLog entry in order of parsing.
+  #
+  # A ChangeLog entry is an Array containing the ChangeLog title (date and
+  # committer) and an Array of ChangeLog items (file and function changed with
+  # description).
+  #
+  # An example result would be:
+  #
+  #    [ 'Tue Dec  4 08:33:46 2012  Eric Hodel  <drbrain@s...>',
+  #      [ 'README.EXT:  Converted to RDoc format',
+  #        'README.EXT.ja:  ditto']]
+
   def parse_entries
     entries = []
     entry_name = nil
@@ -122,6 +168,9 @@
     entries
   end
 
+  ##
+  # Converts the ChangeLog into an RDoc::Markup::Document
+
   def scan
     entries = parse_entries
     grouped_entries = group_entries entries
Index: test/rdoc/test_rdoc_comment.rb
===================================================================
--- test/rdoc/test_rdoc_comment.rb	(revision 38255)
+++ test/rdoc/test_rdoc_comment.rb	(revision 38256)
@@ -70,7 +70,7 @@
     comment = RDoc::Comment.new <<-COMMENT, @top_level
 # call-seq:
 #   bla => true or false
-#\s
+# 
 # moar comment
     COMMENT
 
Index: test/rdoc/test_rdoc_parser_ruby.rb
===================================================================
--- test/rdoc/test_rdoc_parser_ruby.rb	(revision 38255)
+++ test/rdoc/test_rdoc_parser_ruby.rb	(revision 38256)
@@ -80,23 +80,53 @@
     assert_equal 'A', name_t.text
     assert_equal 'A', given_name
 
-    cont, name_t, given_name = util_parser('A::B') .get_class_or_module ctxt
+    cont, name_t, given_name = util_parser('B::C') .get_class_or_module ctxt
 
-    assert_equal @store.find_module_named('A'), cont
-    assert_equal 'B', name_t.text
-    assert_equal 'A::B', given_name
+    b = @store.find_module_named('B')
+    assert_equal b, cont
+    assert_equal [@top_level], b.in_files
+    assert_equal 'C', name_t.text
+    assert_equal 'B::C', given_name
 
-    cont, name_t, given_name = util_parser('A:: B').get_class_or_module ctxt
+    cont, name_t, given_name = util_parser('D:: E').get_class_or_module ctxt
 
-    assert_equal @store.find_module_named('A'), cont
-    assert_equal 'B', name_t.text
-    assert_equal 'A::B', given_name
+    assert_equal @store.find_module_named('D'), cont
+    assert_equal 'E', name_t.text
+    assert_equal 'D::E', given_name
 
     assert_raises NoMethodError do
       util_parser("A::\nB").get_class_or_module ctxt
     end
   end
 
+  def test_get_class_or_module_document_children
+    ctxt = @top_level.add_class RDoc::NormalClass, 'A'
+    ctxt.stop_doc
+
+    util_parser('B::C').get_class_or_module ctxt
+
+    b = @store.find_module_named('A::B')
+    assert b.ignored?
+
+    d = @top_level.add_class RDoc::NormalClass, 'A::D'
+
+    util_parser('D::E').get_class_or_module ctxt
+
+    refute d.ignored?
+  end
+
+  def test_get_class_or_module_ignore_constants
+    ctxt = RDoc::Context.new
+    ctxt.store = @store
+
+    util_parser('A')   .get_class_or_module ctxt, true
+    util_parser('A::B').get_class_or_module ctxt, true
+
+    assert_empty ctxt.constants
+    assert_empty @store.modules_hash.keys
+    assert_empty @store.classes_hash.keys
+  end
+
   def test_get_class_specification
     assert_equal 'A',    util_parser('A')   .get_class_specification
     assert_equal 'A::B', util_parser('A::B').get_class_specification
@@ -1108,6 +1138,37 @@
     assert_equal 'A', bar.find_module_named('A').full_name
   end
 
+  def test_parse_constant_in_method
+    klass = @top_level.add_class RDoc::NormalClass, 'Foo'
+
+    util_parser 'A::B = v'
+
+    tk = @parser.get_tk
+
+    @parser.parse_constant klass, tk, @comment, true
+
+    assert_empty klass.constants
+
+    assert_empty @store.modules_hash.keys
+    assert_equal %w[Foo], @store.classes_hash.keys
+  end
+
+  def test_parse_constant_rescue
+    klass = @top_level.add_class RDoc::NormalClass, 'Foo'
+
+    util_parser "A => e"
+
+    tk = @parser.get_tk
+
+    @parser.parse_constant klass, tk, @comment
+
+    assert_empty klass.constants
+    assert_empty klass.modules
+
+    assert_empty @store.modules_hash.keys
+    assert_equal %w[Foo], @store.classes_hash.keys
+  end
+
   def test_parse_constant_stopdoc
     klass = @top_level.add_class RDoc::NormalClass, 'Foo'
     klass.stop_doc
@@ -1121,6 +1182,27 @@
     assert_empty klass.constants
   end
 
+  def test_parse_comment_nested
+    content = <<-CONTENT
+A::B::C = 1
+    CONTENT
+
+    util_parser content
+
+    tk = @parser.get_tk
+
+    parsed = @parser.parse_constant @top_level, tk, 'comment'
+
+    assert parsed
+
+    a = @top_level.find_module_named 'A'
+    b = a.find_module_named 'B'
+    c = b.constants.first
+
+    assert_equal 'A::B::C', c.full_name
+    assert_equal 'comment', c.comment
+  end
+
   def test_parse_include
     klass = RDoc::NormalClass.new 'C'
     klass.parent = @top_level
@@ -2585,6 +2667,61 @@
     assert_equal 'A nice girl', m.comment.text
   end
 
+  def test_scan_constant_in_method
+    content = <<-CONTENT # newline is after M is important
+module M
+  def m
+    A
+    B::C
+  end
+end
+    CONTENT
+
+    util_parser content
+
+    @parser.scan
+
+    m = @top_level.modules.first
+
+    assert_empty m.constants
+
+    assert_empty @store.classes_hash.keys
+    assert_equal %w[M], @store.modules_hash.keys
+  end
+
+  def test_scan_constant_in_rescue
+    content = <<-CONTENT # newline is after M is important
+module M
+  def m
+  rescue A::B
+  rescue A::C => e
+  rescue A::D, A::E
+  rescue A::F,
+         A::G
+  rescue H
+  rescue I => e
+  rescue J, K
+  rescue L =>
+    e
+  rescue M;
+  rescue N,
+         O => e
+  end
+end
+    CONTENT
+
+    util_parser content
+
+    @parser.scan
+
+    m = @top_level.modules.first
+
+    assert_empty m.c (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]