rdoc 4.0.0.preview2 → 4.0.0.preview2.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rdoc might be problematic. Click here for more details.

Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.autotest +4 -1
  5. data/History.rdoc +26 -1
  6. data/Manifest.txt +2 -0
  7. data/Rakefile +1 -1
  8. data/lib/rdoc.rb +1 -1
  9. data/lib/rdoc/class_module.rb +13 -2
  10. data/lib/rdoc/context.rb +7 -5
  11. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +7 -1
  12. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +1 -1
  13. data/lib/rdoc/markdown/entities.rb +3 -0
  14. data/lib/rdoc/markup/document.rb +8 -8
  15. data/lib/rdoc/markup/formatter.rb +6 -1
  16. data/lib/rdoc/markup/heading.rb +2 -1
  17. data/lib/rdoc/markup/to_joined_paragraph.rb +5 -2
  18. data/lib/rdoc/markup/to_table_of_contents.rb +27 -1
  19. data/lib/rdoc/options.rb +36 -1
  20. data/lib/rdoc/parser.rb +30 -1
  21. data/lib/rdoc/parser/c.rb +56 -14
  22. data/lib/rdoc/parser/changelog.rb +186 -0
  23. data/lib/rdoc/parser/ruby.rb +53 -11
  24. data/lib/rdoc/rdoc.rb +9 -0
  25. data/lib/rdoc/ri/driver.rb +5 -1
  26. data/lib/rdoc/ruby_lex.rb +1 -1
  27. data/lib/rdoc/rubygems_hook.rb +16 -10
  28. data/lib/rdoc/servlet.rb +111 -6
  29. data/lib/rdoc/store.rb +110 -19
  30. data/test/test_rdoc_class_module.rb +32 -0
  31. data/test/test_rdoc_context.rb +25 -0
  32. data/test/test_rdoc_markup_document.rb +19 -0
  33. data/test/test_rdoc_markup_to_table_of_contents.rb +31 -0
  34. data/test/test_rdoc_options.rb +38 -0
  35. data/test/test_rdoc_parser.rb +56 -0
  36. data/test/test_rdoc_parser_c.rb +129 -6
  37. data/test/test_rdoc_parser_changelog.rb +294 -0
  38. data/test/test_rdoc_parser_ruby.rb +145 -8
  39. data/test/test_rdoc_rdoc.rb +25 -5
  40. data/test/test_rdoc_ri_driver.rb +27 -0
  41. data/test/test_rdoc_ruby_lex.rb +10 -0
  42. data/test/test_rdoc_rubygems_hook.rb +49 -18
  43. data/test/test_rdoc_store.rb +148 -37
  44. metadata +26 -23
  45. metadata.gz.sig +0 -0
@@ -1331,12 +1331,16 @@ The ri pager can be set with the 'RI_PAGER' environment variable or the
1331
1331
  elsif parts.length == 2 or parts.last =~ /::|#|\./ then
1332
1332
  type = parts.pop
1333
1333
  meth = nil
1334
+ elsif parts[1] == ':' then
1335
+ klass = parts.shift
1336
+ type = parts.shift
1337
+ meth = parts.join
1334
1338
  elsif parts[-2] != '::' or parts.last !~ /^[A-Z]/ then
1335
1339
  meth = parts.pop
1336
1340
  type = parts.pop
1337
1341
  end
1338
1342
 
1339
- klass = parts.join
1343
+ klass ||= parts.join
1340
1344
 
1341
1345
  [klass, type, meth]
1342
1346
  end
@@ -857,7 +857,7 @@ class RDoc::RubyLex
857
857
  end
858
858
 
859
859
  IDENT_RE = if defined? Encoding then
860
- /[\w\u0080-\uFFFF]/u
860
+ eval '/[\w\u{0080}-\u{FFFFF}]/u' # 1.8 can't parse \u{}
861
861
  else
862
862
  /[\w\x80-\xFF]/
863
863
  end
@@ -68,10 +68,12 @@ class RDoc::RubygemsHook
68
68
 
69
69
  ##
70
70
  # Creates a new documentation generator for +spec+. RDoc and ri data
71
- # generation can be disabled through +generate_rdoc+ and +generate_ri+
72
- # respectively.
71
+ # generation can be enabled or disabled through +generate_rdoc+ and
72
+ # +generate_ri+ respectively.
73
+ #
74
+ # Only +generate_ri+ is enabled by default.
73
75
 
74
- def initialize spec, generate_rdoc = true, generate_ri = true
76
+ def initialize spec, generate_rdoc = false, generate_ri = true
75
77
  @doc_dir = spec.doc_dir
76
78
  @force = false
77
79
  @rdoc = nil
@@ -139,13 +141,11 @@ class RDoc::RubygemsHook
139
141
 
140
142
  setup
141
143
 
142
- options = ::RDoc::Options.new
143
- options.default_title = "#{@spec.full_name} Documentation"
144
- options.files = []
145
- options.files.concat @spec.require_paths
146
- options.files.concat @spec.extra_rdoc_files
144
+ options = nil
147
145
 
148
146
  args = @spec.rdoc_options
147
+ args.concat @spec.require_paths
148
+ args.concat @spec.extra_rdoc_files
149
149
 
150
150
  case config_args = Gem.configuration[:rdoc]
151
151
  when String then
@@ -155,7 +155,13 @@ class RDoc::RubygemsHook
155
155
  end
156
156
 
157
157
  delete_legacy_args args
158
- options.parse args
158
+
159
+ Dir.chdir @spec.full_gem_path do
160
+ options = ::RDoc::Options.new
161
+ options.default_title = "#{@spec.full_name} Documentation"
162
+ options.parse args
163
+ end
164
+
159
165
  options.quiet = !Gem.configuration.really_verbose
160
166
 
161
167
  @rdoc = new_rdoc
@@ -167,7 +173,7 @@ class RDoc::RubygemsHook
167
173
  store.main = options.main_page
168
174
  store.title = options.title
169
175
 
170
- @rdoc.store = RDoc::Store.new
176
+ @rdoc.store = store
171
177
 
172
178
  say "Parsing documentation for #{@spec.full_name}"
173
179
 
@@ -2,21 +2,60 @@ require 'rdoc'
2
2
  require 'time'
3
3
  require 'webrick'
4
4
 
5
+ ##
6
+ # This is a WEBrick servlet that allows you to browse ri documentation.
7
+ #
8
+ # You can show documentation through either `ri --server` or, with RubyGems
9
+ # 2.0 or newer, `gem server`. For ri, the server runs on port 8214 by
10
+ # default. For RubyGems the server runs on port 8808 by default.
11
+ #
12
+ # You can use this servlet in your own project by mounting it on a WEBrick
13
+ # server:
14
+ #
15
+ # require 'webrick'
16
+ #
17
+ # server = WEBrick::HTTPServer.new Port: 8000
18
+ #
19
+ # server.mount '/', RDoc::Servlet
20
+ #
21
+ # If you want to mount the servlet some other place than the root, provide the
22
+ # base path when mounting:
23
+ #
24
+ # server.mount '/rdoc', RDoc::Servlet, '/rdoc'
25
+
5
26
  class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
6
27
 
7
28
  @server_stores = Hash.new { |hash, server| hash[server] = {} }
8
29
  @cache = Hash.new { |hash, store| hash[store] = {} }
9
30
 
31
+ ##
32
+ # Maps an asset type to its path on the filesystem
33
+
10
34
  attr_reader :asset_dirs
11
35
 
36
+ ##
37
+ # An RDoc::Options instance used for rendering options
38
+
12
39
  attr_reader :options
13
40
 
14
- def self.get_instance server, *options
41
+ ##
42
+ # Creates an instance of this servlet that shares cached data between
43
+ # requests.
44
+
45
+ def self.get_instance server, *options # :nodoc:
15
46
  stores = @server_stores[server]
16
47
 
17
48
  new server, stores, @cache, *options
18
49
  end
19
50
 
51
+ ##
52
+ # Creates a new WEBrick servlet.
53
+ #
54
+ # Use +mount_path+ when mounting the servlet somewhere other than /.
55
+ #
56
+ # +server+ is provided automatically by WEBrick when mounting. +stores+ and
57
+ # +cache+ are provided automatically by the servlet.
58
+
20
59
  def initialize server, stores, cache, mount_path = nil
21
60
  super server
22
61
 
@@ -44,6 +83,9 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
44
83
  }
45
84
  end
46
85
 
86
+ ##
87
+ # Serves the asset at the path in +req+ for +generator_name+ via +res+.
88
+
47
89
  def asset generator_name, req, res
48
90
  asset_dir = @asset_dirs[generator_name]
49
91
 
@@ -60,6 +102,9 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
60
102
  end
61
103
  end
62
104
 
105
+ ##
106
+ # GET request entry point. Fills in +res+ for the path, etc. in +req+.
107
+
63
108
  def do_GET req, res
64
109
  req.path.sub!(/^#{Regexp.escape @mount_path}/o, '') if @mount_path
65
110
 
@@ -82,6 +127,13 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
82
127
  error e, req, res
83
128
  end
84
129
 
130
+ ##
131
+ # Fills in +res+ with the class, module or page for +req+ from +store+.
132
+ #
133
+ # +path+ is relative to the mount_path and is used to determine the class,
134
+ # module or page name (/RDoc/Servlet.html becomes RDoc::Servlet).
135
+ # +generator+ is used to create the page.
136
+
85
137
  def documentation_page store, generator, path, req, res
86
138
  name = path.sub(/.html$/, '').gsub '/', '::'
87
139
 
@@ -94,6 +146,10 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
94
146
  end
95
147
  end
96
148
 
149
+ ##
150
+ # Creates the JSON search index on +res+ for the given +store+. +generator+
151
+ # must respond to \#json_index to build. +req+ is ignored.
152
+
97
153
  def documentation_search store, generator, req, res
98
154
  json_index = @cache[store].fetch :json_index do
99
155
  @cache[store][:json_index] =
@@ -104,6 +160,10 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
104
160
  res.body = "var search_data = #{json_index}"
105
161
  end
106
162
 
163
+ ##
164
+ # Returns the RDoc::Store and path relative to +mount_path+ for
165
+ # documentation at +path+.
166
+
107
167
  def documentation_source path
108
168
  _, source_name, path = path.split '/', 3
109
169
 
@@ -119,8 +179,11 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
119
179
  return store, path
120
180
  end
121
181
 
122
- def error e, req, res
123
- backtrace = e.backtrace.join "\n"
182
+ ##
183
+ # Generates an error page for the +exception+ while handling +req+ on +res+.
184
+
185
+ def error exception, req, res
186
+ backtrace = exception.backtrace.join "\n"
124
187
 
125
188
  res.content_type = 'text/html'
126
189
  res.status = 500
@@ -130,7 +193,7 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
130
193
  <head>
131
194
  <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
132
195
 
133
- <title>Error - #{ERB::Util.html_escape e.class}</title>
196
+ <title>Error - #{ERB::Util.html_escape exception.class}</title>
134
197
 
135
198
  <link type="text/css" media="screen" href="#{@mount_path}/rdoc.css" rel="stylesheet">
136
199
  </head>
@@ -138,10 +201,17 @@ class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
138
201
  <h1>Error</h1>
139
202
 
140
203
  <p>While processing <code>#{ERB::Util.html_escape req.request_uri}</code> the
141
- RDoc server has encountered a <code>#{ERB::Util.html_escape e.class}</code>
204
+ RDoc (#{ERB::Util.html_escape RDoc::VERSION}) server has encountered a
205
+ <code>#{ERB::Util.html_escape exception.class}</code>
142
206
  exception:
143
207
 
144
- <pre>#{ERB::Util.html_escape e.message}</pre>
208
+ <pre>#{ERB::Util.html_escape exception.message}</pre>
209
+
210
+ <p>Please report this to the
211
+ <a href="https://github.com/rdoc/rdoc/issues">RDoc issues tracker</a>. Please
212
+ include the RDoc version, the URI above and exception class, message and
213
+ backtrace. If you're viewing a gem's documentation, include the gem name and
214
+ version. If you're viewing Ruby's documentation, include the version of ruby.
145
215
 
146
216
  <p>Backtrace:
147
217
 
@@ -152,6 +222,9 @@ exception:
152
222
  BODY
153
223
  end
154
224
 
225
+ ##
226
+ # Instantiates a Darkfish generator for +store+
227
+
155
228
  def generator_for store
156
229
  generator = RDoc::Generator::Darkfish.new store, @options
157
230
  generator.file_output = false
@@ -168,6 +241,11 @@ exception:
168
241
  generator
169
242
  end
170
243
 
244
+ ##
245
+ # Handles the If-Modified-Since HTTP header on +req+ for +path+. If the
246
+ # file has not been modified a Not Modified response is returned. If the
247
+ # file has been modified a Last-Modified header is added to +res+.
248
+
171
249
  def if_modified_since req, res, path = nil
172
250
  last_modified = File.stat(path).mtime if path
173
251
 
@@ -183,6 +261,14 @@ exception:
183
261
  end
184
262
  end
185
263
 
264
+ ##
265
+ # Returns an Array of installed documentation.
266
+ #
267
+ # Each entry contains the documentation name (gem name, 'Ruby
268
+ # Documentation', etc.), the path relative to the mount point, whether the
269
+ # documentation exists, the type of documentation (See RDoc::RI::Paths#each)
270
+ # and the filesystem to the RDoc::Store for the documentation.
271
+
186
272
  def installed_docs
187
273
  ri_paths.map do |path, type|
188
274
  store = RDoc::Store.new path, type
@@ -202,15 +288,24 @@ exception:
202
288
  end
203
289
  end
204
290
 
291
+ ##
292
+ # Returns a 404 page built by +generator+ for +req+ on +res+.
293
+
205
294
  def not_found generator, req, res
206
295
  res.body = generator.generate_servlet_not_found req.path
207
296
  res.status = 404
208
297
  end
209
298
 
299
+ ##
300
+ # Enumerates the ri paths. See RDoc::RI::Paths#each
301
+
210
302
  def ri_paths &block
211
303
  RDoc::RI::Paths.each true, true, true, :all, &block
212
304
  end
213
305
 
306
+ ##
307
+ # Generates the root page on +res+. +req+ is ignored.
308
+
214
309
  def root req, res
215
310
  generator = RDoc::Generator::Darkfish.new nil, @options
216
311
 
@@ -219,6 +314,9 @@ exception:
219
314
  res.content_type = 'text/html'
220
315
  end
221
316
 
317
+ ##
318
+ # Generates a search index for the root page on +res+. +req+ is ignored.
319
+
222
320
  def root_search req, res
223
321
  search_index = []
224
322
  info = []
@@ -259,6 +357,10 @@ exception:
259
357
  res.content_type = 'application/javascript'
260
358
  end
261
359
 
360
+ ##
361
+ # Displays documentation for +req+ on +res+, whether that be HTML or some
362
+ # asset.
363
+
262
364
  def show_documentation req, res
263
365
  store, path = documentation_source req.path
264
366
 
@@ -280,6 +382,9 @@ exception:
280
382
  res.content_type ||= 'text/html'
281
383
  end
282
384
 
385
+ ##
386
+ # Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name).
387
+
283
388
  def store_for source_name
284
389
  case source_name
285
390
  when 'ruby' then
@@ -59,7 +59,7 @@ class RDoc::Store
59
59
  @name = name
60
60
  end
61
61
 
62
- def message
62
+ def message # :nodoc:
63
63
  "store at #{@store.path} missing file #{@file} for #{@name}"
64
64
  end
65
65
 
@@ -69,7 +69,19 @@ class RDoc::Store
69
69
  # Stores the name of the C variable a class belongs to. This helps wire up
70
70
  # classes defined from C across files.
71
71
 
72
- attr_reader :c_enclosure_classes
72
+ attr_reader :c_enclosure_classes # :nodoc:
73
+
74
+ attr_reader :c_enclosure_names # :nodoc:
75
+
76
+ ##
77
+ # Maps C variables to class or module names for each parsed C file.
78
+
79
+ attr_reader :c_class_variables
80
+
81
+ ##
82
+ # Maps C variables to singleton class names for each parsed C file.
83
+
84
+ attr_reader :c_singleton_class_variables
73
85
 
74
86
  ##
75
87
  # If true this Store will not write any files
@@ -114,15 +126,17 @@ class RDoc::Store
114
126
  @type = type
115
127
 
116
128
  @cache = {
117
- :ancestors => {},
118
- :attributes => {},
119
- :class_methods => {},
120
- :encoding => @encoding,
121
- :instance_methods => {},
122
- :main => nil,
123
- :modules => [],
124
- :pages => [],
125
- :title => nil,
129
+ :ancestors => {},
130
+ :attributes => {},
131
+ :class_methods => {},
132
+ :c_class_variables => {},
133
+ :c_singleton_class_variables => {},
134
+ :encoding => @encoding,
135
+ :instance_methods => {},
136
+ :main => nil,
137
+ :modules => [],
138
+ :pages => [],
139
+ :title => nil,
126
140
  }
127
141
 
128
142
  @classes_hash = {}
@@ -130,11 +144,34 @@ class RDoc::Store
130
144
  @files_hash = {}
131
145
 
132
146
  @c_enclosure_classes = {}
147
+ @c_enclosure_names = {}
148
+
149
+ @c_class_variables = {}
150
+ @c_singleton_class_variables = {}
133
151
 
134
152
  @unique_classes = nil
135
153
  @unique_modules = nil
136
154
  end
137
155
 
156
+ ##
157
+ # Adds +module+ as an enclosure (namespace) for the given +variable+ for C
158
+ # files.
159
+
160
+ def add_c_enclosure variable, namespace
161
+ @c_enclosure_classes[variable] = namespace
162
+ end
163
+
164
+ ##
165
+ # Adds C variables from an RDoc::Parser::C
166
+
167
+ def add_c_variables c_parser
168
+ filename = c_parser.top_level.relative_name
169
+
170
+ @c_class_variables[filename] = make_variable_map c_parser.classes
171
+
172
+ @c_singleton_class_variables[filename] = c_parser.singleton_classes
173
+ end
174
+
138
175
  ##
139
176
  # Adds the file with +name+ as an RDoc::TopLevel to the store. Returns the
140
177
  # created RDoc::TopLevel.
@@ -304,6 +341,28 @@ class RDoc::Store
304
341
  @files_hash
305
342
  end
306
343
 
344
+ ##
345
+ # Finds the enclosure (namespace) for the given C +variable+.
346
+
347
+ def find_c_enclosure variable
348
+ @c_enclosure_classes.fetch variable do
349
+ break unless name = @c_enclosure_names[variable]
350
+
351
+ mod = find_class_or_module name
352
+
353
+ unless mod then
354
+ loaded_mod = load_class_data name
355
+
356
+ file = loaded_mod.in_files.first
357
+ file.store = self
358
+
359
+ mod = file.add_module RDoc::NormalModule, name
360
+ end
361
+
362
+ @c_enclosure_classes[variable] = mod
363
+ end
364
+ end
365
+
307
366
  ##
308
367
  # Finds the class with +name+ in all discovered classes
309
368
 
@@ -500,22 +559,26 @@ class RDoc::Store
500
559
 
501
560
  @encoding = load_enc unless @encoding
502
561
 
503
- @cache[:pages] ||= []
504
- @cache[:main] ||= nil
562
+ @cache[:pages] ||= []
563
+ @cache[:main] ||= nil
564
+ @cache[:c_class_variables] ||= {}
565
+ @cache[:c_singleton_class_variables] ||= {}
566
+
567
+ @cache[:c_class_variables].each do |_, map|
568
+ map.each do |variable, name|
569
+ @c_enclosure_names[variable] = name
570
+ end
571
+ end
505
572
 
506
573
  @cache
507
574
  rescue Errno::ENOENT
508
575
  end
509
576
 
510
577
  ##
511
- # Loads ri data for +klass_name+
578
+ # Loads ri data for +klass_name+ and hooks it up to this store.
512
579
 
513
580
  def load_class klass_name
514
- file = class_file klass_name
515
-
516
- obj = open file, 'rb' do |io|
517
- Marshal.load io.read
518
- end
581
+ obj = load_class_data klass_name
519
582
 
520
583
  obj.store = self
521
584
 
@@ -525,6 +588,17 @@ class RDoc::Store
525
588
  when RDoc::NormalModule then
526
589
  @modules_hash[klass_name] = obj
527
590
  end
591
+ end
592
+
593
+ ##
594
+ # Loads ri data for +klass_name+
595
+
596
+ def load_class_data klass_name
597
+ file = class_file klass_name
598
+
599
+ open file, 'rb' do |io|
600
+ Marshal.load io.read
601
+ end
528
602
  rescue Errno::ENOENT => e
529
603
  error = MissingFileError.new(self, file, klass_name)
530
604
  error.set_backtrace e.backtrace
@@ -583,6 +657,20 @@ class RDoc::Store
583
657
  @cache[:main] = page
584
658
  end
585
659
 
660
+ ##
661
+ # Converts the variable => ClassModule map +variables+ from a C parser into
662
+ # a variable => class name map.
663
+
664
+ def make_variable_map variables
665
+ map = {}
666
+
667
+ variables.each { |variable, class_module|
668
+ map[variable] = class_module.full_name
669
+ }
670
+
671
+ map
672
+ end
673
+
586
674
  ##
587
675
  # Path to the ri data for +method_name+ in +klass_name+
588
676
 
@@ -688,6 +776,9 @@ class RDoc::Store
688
776
 
689
777
  @cache[:encoding] = @encoding # this gets set twice due to assert_cache
690
778
 
779
+ @cache[:c_class_variables].merge! @c_class_variables
780
+ @cache[:c_singleton_class_variables].merge! @c_singleton_class_variables
781
+
691
782
  return if @dry_run
692
783
 
693
784
  marshal = Marshal.dump @cache