rdoc 3.2 → 3.3

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.

@@ -197,6 +197,7 @@ option)
197
197
  end unless @options.force_output
198
198
  else
199
199
  FileUtils.mkdir_p dir
200
+ FileUtils.touch output_flag_file dir
200
201
  end
201
202
 
202
203
  last
@@ -416,10 +417,13 @@ The internal error was:
416
417
 
417
418
  RDoc::TopLevel.complete @options.visibility
418
419
 
420
+ @stats.coverage_level = @options.coverage_report
421
+
419
422
  if @options.coverage_report then
420
423
  puts
424
+
421
425
  puts @stats.report
422
- elsif file_info.empty?
426
+ elsif file_info.empty? then
423
427
  $stderr.puts "\nNo newer files." unless @options.quiet
424
428
  else
425
429
  gen_klass = @options.generator
@@ -651,12 +651,14 @@ Options may also be set in the 'RI' environment variable.
651
651
 
652
652
  raise NotFoundError, name if found.empty?
653
653
 
654
+ filtered = filter_methods found, name
655
+
654
656
  out = RDoc::Markup::Document.new
655
657
 
656
658
  out << RDoc::Markup::Heading.new(1, name)
657
659
  out << RDoc::Markup::BlankLine.new
658
660
 
659
- found.each do |store, methods|
661
+ filtered.each do |store, methods|
660
662
  methods.each do |method|
661
663
  out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})")
662
664
 
@@ -753,6 +755,21 @@ Options may also be set in the 'RI' environment variable.
753
755
  "#{expand_class klass}#{selector}#{method}"
754
756
  end
755
757
 
758
+ ##
759
+ # Filters the methods in +found+ trying to find a match for +name+.
760
+
761
+ def filter_methods found, name
762
+ regexp = name_regexp name
763
+
764
+ filtered = found.find_all do |store, methods|
765
+ methods.any? { |method| method.full_name =~ regexp }
766
+ end
767
+
768
+ return filtered unless filtered.empty?
769
+
770
+ found
771
+ end
772
+
756
773
  ##
757
774
  # Yields items matching +name+ including the store they were found in, the
758
775
  # class being searched for, the class they were found in (an ancestor) the
@@ -948,10 +965,10 @@ Options may also be set in the 'RI' environment variable.
948
965
  methods = []
949
966
 
950
967
  methods << load_method(store, :class_methods, ancestor, '::', method) if
951
- types == :class or types == :both
968
+ [:class, :both].include? types
952
969
 
953
970
  methods << load_method(store, :instance_methods, ancestor, '#', method) if
954
- types == :instance or types == :both
971
+ [:instance, :both].include? types
955
972
 
956
973
  found << [store, methods.compact]
957
974
  end
@@ -970,6 +987,21 @@ Options may also be set in the 'RI' environment variable.
970
987
  end
971
988
  end
972
989
 
990
+ ##
991
+ # Returns a regular expression for +name+ that will match an
992
+ # RDoc::AnyMethod's name.
993
+
994
+ def name_regexp name
995
+ klass, type, name = parse_name name
996
+
997
+ case type
998
+ when '#', '::' then
999
+ /^#{klass}#{type}#{name}$/
1000
+ else
1001
+ /^#{klass}(#|::)#{name}$/
1002
+ end
1003
+ end
1004
+
973
1005
  ##
974
1006
  # Paginates output through a pager program.
975
1007
 
@@ -996,7 +1028,7 @@ Options may also be set in the 'RI' environment variable.
996
1028
  end
997
1029
 
998
1030
  ##
999
- # Extract the class, selector and method name parts from +name+ like
1031
+ # Extracts the class, selector and method name parts from +name+ like
1000
1032
  # Foo::Bar#baz.
1001
1033
  #
1002
1034
  # NOTE: Given Foo::Bar, Bar is considered a class even though it may be a
@@ -401,13 +401,15 @@ class RDoc::RubyLex
401
401
  |op, io|
402
402
  @ltype = "="
403
403
  res = ''
404
- until (ch = getc) == "\n" do res << ch end
404
+ nil until (ch = getc) == "\n"
405
+
405
406
  until peek_equal?("=end") && peek(4) =~ /\s/ do
406
407
  until (ch = getc) == "\n" do res << ch end
407
408
  end
408
- res << gets
409
+ gets # consume =end
410
+
409
411
  @ltype = nil
410
- Token(TkRD_COMMENT, res)
412
+ Token(TkCOMMENT, res)
411
413
  end
412
414
 
413
415
  @OP.def_rule("\n") do |op, io|
@@ -5,10 +5,19 @@ require 'rdoc/class_module'
5
5
 
6
6
  class RDoc::SingleClass < RDoc::ClassModule
7
7
 
8
+ ##
8
9
  # Adds the superclass to the included modules.
10
+
9
11
  def ancestors
10
12
  superclass ? super + [superclass] : super
11
13
  end
12
14
 
15
+ ##
16
+ # The definition of this singleton class, <tt>class << MyClassName</tt>
17
+
18
+ def definition
19
+ "class << #{full_name}"
20
+ end
21
+
13
22
  end
14
23
 
@@ -6,6 +6,11 @@ require 'rdoc'
6
6
 
7
7
  class RDoc::Stats
8
8
 
9
+ ##
10
+ # Output level for the coverage report
11
+
12
+ attr_reader :coverage_level
13
+
9
14
  ##
10
15
  # Count of files parsed during parsing
11
16
 
@@ -23,10 +28,13 @@ class RDoc::Stats
23
28
  def initialize num_files, verbosity = 1
24
29
  @files_so_far = 0
25
30
  @num_files = num_files
31
+
32
+ @coverage_level = 0
26
33
  @fully_documented = nil
34
+ @num_params = 0
27
35
  @percent_doc = nil
28
-
29
36
  @start = Time.now
37
+ @undoc_params = 0
30
38
 
31
39
  @display = case verbosity
32
40
  when 0 then Quiet.new num_files
@@ -93,10 +101,11 @@ class RDoc::Stats
93
101
  end
94
102
 
95
103
  ##
96
- # Calculates documentation totals and percentages
104
+ # Calculates documentation totals and percentages for classes, modules,
105
+ # constants, attributes and methods.
97
106
 
98
107
  def calculate
99
- return if @percent_doc
108
+ return if @doc_items
100
109
 
101
110
  ucm = RDoc::TopLevel.unique_classes_and_modules
102
111
  constants = []
@@ -119,20 +128,31 @@ class RDoc::Stats
119
128
  @num_classes +
120
129
  @num_constants +
121
130
  @num_methods +
122
- @num_modules
131
+ @num_modules +
132
+ @num_params
123
133
 
124
134
  @undoc_items =
125
135
  @undoc_attributes +
126
136
  @undoc_classes +
127
137
  @undoc_constants +
128
138
  @undoc_methods +
129
- @undoc_modules
139
+ @undoc_modules +
140
+ @undoc_params
130
141
 
131
142
  @doc_items = @num_items - @undoc_items
143
+ end
132
144
 
133
- @fully_documented = (@num_items - @doc_items) == 0
145
+ ##
146
+ # Sets coverage report level. Accepted values are:
147
+ #
148
+ # false or nil:: No report
149
+ # 0:: Classes, modules, constants, attributes, methods
150
+ # 1:: Level 0 + method parameters
134
151
 
135
- @percent_doc = @doc_items.to_f / @num_items * 100 if @num_items.nonzero?
152
+ def coverage_level= level
153
+ level = -1 unless level
154
+
155
+ @coverage_level = level
136
156
  end
137
157
 
138
158
  ##
@@ -159,97 +179,186 @@ class RDoc::Stats
159
179
  @fully_documented
160
180
  end
161
181
 
182
+ ##
183
+ # A report that says you did a great job!
184
+
185
+ def great_job
186
+ report = []
187
+ report << '100% documentation!'
188
+ report << nil
189
+ report << 'Great Job!'
190
+
191
+ report.join "\n"
192
+ end
193
+
194
+ ##
195
+ # Calculates the percentage of items documented.
196
+
197
+ def percent_doc
198
+ return @percent_doc if @percent_doc
199
+
200
+ @fully_documented = (@num_items - @doc_items) == 0
201
+
202
+ @percent_doc = @doc_items.to_f / @num_items * 100 if @num_items.nonzero?
203
+ @percent_doc ||= 0
204
+
205
+ @percent_doc
206
+ end
207
+
162
208
  ##
163
209
  # Returns a report on which items are not documented
164
210
 
165
211
  def report
212
+ if @coverage_level > 0 then
213
+ require 'rdoc/markup/to_tt_only'
214
+ require 'rdoc/generator/markup'
215
+ require 'rdoc/text'
216
+ extend RDoc::Text
217
+ end
218
+
166
219
  report = []
167
220
 
168
- calculate
221
+ if @coverage_level.zero? then
222
+ calculate
223
+
224
+ return great_job if @num_items == @doc_items
225
+ end
226
+
227
+ ucm = RDoc::TopLevel.unique_classes_and_modules
228
+
229
+ ucm.sort.each do |cm|
230
+ report << report_class_module(cm) {
231
+ [
232
+ report_constants(cm),
233
+ report_attributes(cm),
234
+ report_methods(cm),
235
+ ].compact
236
+ }
237
+ end
238
+
239
+ if @coverage_level > 0 then
240
+ calculate
241
+
242
+ return great_job if @num_items == @doc_items
243
+ end
244
+
245
+ report.unshift nil
246
+ report.unshift 'The following items are not documented:'
247
+
248
+ report.join "\n"
249
+ end
250
+
251
+ ##
252
+ # Returns a report on undocumented attributes in ClassModule +cm+
253
+
254
+ def report_attributes cm
255
+ return if cm.attributes.empty?
256
+
257
+ report = []
258
+
259
+ cm.each_attribute do |attr|
260
+ next if attr.documented?
261
+ report << " #{attr.definition} :#{attr.name} " \
262
+ "# in file #{attr.file.full_name}"
263
+ end
264
+
265
+ report
266
+ end
267
+
268
+ ##
269
+ # Returns a report on undocumented items in ClassModule +cm+
270
+
271
+ def report_class_module cm
272
+ return if cm.fully_documented? and @coverage_level.zero?
273
+
274
+ report = []
275
+
276
+ if cm.in_files.empty? then
277
+ report << "# #{cm.definition} is referenced but empty."
278
+ report << '#'
279
+ report << '# It probably came from another project. ' \
280
+ "I'm sorry I'm holding it against you."
281
+ report << nil
282
+
283
+ return report
284
+ elsif cm.documented? then
285
+ documented = true
286
+ report << "#{cm.definition} # is documented"
287
+ else
288
+ report << '# in files:'
289
+
290
+ cm.in_files.each do |file|
291
+ report << "# #{file.full_name}"
292
+ end
169
293
 
170
- if @num_items == @doc_items then
171
- report << '100% documentation!'
172
294
  report << nil
173
- report << 'Great Job!'
174
295
 
175
- return report.join "\n"
296
+ report << "#{cm.definition}"
176
297
  end
177
298
 
178
- report << 'The following items are not documented:'
299
+ body = yield.flatten # HACK remove #flatten
300
+
301
+ return if body.empty? and documented
302
+
303
+ report << nil << body unless body.empty?
304
+
305
+ report << 'end'
179
306
  report << nil
180
307
 
181
- ucm = RDoc::TopLevel.unique_classes_and_modules
308
+ report
309
+ end
182
310
 
183
- ucm.sort.each do |cm|
184
- type = case cm # TODO #definition
185
- when RDoc::NormalClass then 'class'
186
- when RDoc::SingleClass then 'class <<'
187
- when RDoc::NormalModule then 'module'
188
- end
189
-
190
- if cm.fully_documented? then
191
- next
192
- elsif cm.in_files.empty? or
193
- (cm.constants.empty? and cm.method_list.empty?) then
194
- report << "# #{type} #{cm.full_name} is referenced but empty."
195
- report << '#'
196
- report << '# It probably came from another project. ' \
197
- 'I\'m sorry I\'m holding it against you.'
198
- report << nil
199
-
200
- next
201
- elsif cm.documented? then
202
- report << "#{type} #{cm.full_name} # is documented"
203
- else
204
- report << '# in files:'
205
-
206
- cm.in_files.each do |file|
207
- report << "# #{file.full_name}"
208
- end
311
+ ##
312
+ # Returns a report on undocumented constants in ClassModule +cm+
209
313
 
210
- report << nil
314
+ def report_constants cm
315
+ return if cm.constants.empty?
211
316
 
212
- report << "#{type} #{cm.full_name}"
213
- end
317
+ report = []
214
318
 
215
- unless cm.constants.empty? then
216
- report << nil
319
+ cm.each_constant do |constant|
320
+ # TODO constant aliases are listed in the summary but not reported
321
+ # figure out what to do here
322
+ next if constant.documented? || constant.is_alias_for
323
+ report << " # in file #{constant.file.full_name}"
324
+ report << " #{constant.name} = nil"
325
+ end
217
326
 
218
- cm.each_constant do |constant|
219
- # TODO constant aliases are listed in the summary but not reported
220
- # figure out what to do here
221
- next if constant.documented? || constant.is_alias_for
222
- report << " # in file #{constant.file.full_name}"
223
- report << " #{constant.name} = nil"
224
- end
225
- end
327
+ report
328
+ end
329
+
330
+ ##
331
+ # Returns a report on undocumented methods in ClassModule +cm+
226
332
 
227
- unless cm.attributes.empty? then
228
- report << nil
333
+ def report_methods cm
334
+ return if cm.method_list.empty?
229
335
 
230
- cm.each_attribute do |attr|
231
- next if attr.documented?
232
- report << " #{attr.definition} #{attr.name} " \
233
- "# in file #{attr.file.full_name}"
234
- end
235
- end
336
+ report = []
337
+
338
+ cm.each_method do |method|
339
+ next if method.documented? and @coverage_level.zero?
340
+
341
+ if @coverage_level > 0 then
342
+ params, undoc = undoc_params method
236
343
 
237
- unless cm.method_list.empty? then
238
- report << nil
344
+ @num_params += params
239
345
 
240
- cm.each_method do |method|
241
- next if method.documented?
242
- report << " # in file #{method.file.full_name}"
243
- report << " def #{method.name}#{method.params}; end"
244
- report << nil
346
+ unless undoc.empty? then
347
+ @undoc_params += undoc.length
348
+
349
+ undoc = undoc.map do |param| "+#{param}+" end
350
+ param_report = " # #{undoc.join ', '} is not documented"
245
351
  end
246
352
  end
247
353
 
248
- report << 'end'
354
+ next if method.documented? and not param_report
355
+ report << " # in file #{method.file.full_name}"
356
+ report << param_report if param_report
357
+ report << " def #{method.name}#{method.params}; end"
249
358
  report << nil
250
359
  end
251
360
 
252
- report.join "\n"
361
+ report
253
362
  end
254
363
 
255
364
  ##
@@ -259,13 +368,14 @@ class RDoc::Stats
259
368
  calculate
260
369
 
261
370
  num_width = [@num_files, @num_items].max.to_s.length
262
- nodoc_width = [
371
+ undoc_width = [
263
372
  @undoc_attributes,
264
373
  @undoc_classes,
265
374
  @undoc_constants,
266
375
  @undoc_items,
267
376
  @undoc_methods,
268
377
  @undoc_modules,
378
+ @undoc_params,
269
379
  ].max.to_s.length
270
380
 
271
381
  report = []
@@ -274,28 +384,51 @@ class RDoc::Stats
274
384
  report << nil
275
385
 
276
386
  report << 'Classes: %*d (%*d undocumented)' % [
277
- num_width, @num_classes, nodoc_width, @undoc_classes]
387
+ num_width, @num_classes, undoc_width, @undoc_classes]
278
388
  report << 'Modules: %*d (%*d undocumented)' % [
279
- num_width, @num_modules, nodoc_width, @undoc_modules]
389
+ num_width, @num_modules, undoc_width, @undoc_modules]
280
390
  report << 'Constants: %*d (%*d undocumented)' % [
281
- num_width, @num_constants, nodoc_width, @undoc_constants]
391
+ num_width, @num_constants, undoc_width, @undoc_constants]
282
392
  report << 'Attributes: %*d (%*d undocumented)' % [
283
- num_width, @num_attributes, nodoc_width, @undoc_attributes]
393
+ num_width, @num_attributes, undoc_width, @undoc_attributes]
284
394
  report << 'Methods: %*d (%*d undocumented)' % [
285
- num_width, @num_methods, nodoc_width, @undoc_methods]
395
+ num_width, @num_methods, undoc_width, @undoc_methods]
396
+ report << 'Parameters: %*d (%*d undocumented)' % [
397
+ num_width, @num_params, undoc_width, @undoc_params] if
398
+ @coverage_level > 0
286
399
 
287
400
  report << nil
288
401
 
289
402
  report << 'Total: %*d (%*d undocumented)' % [
290
- num_width, @num_items, nodoc_width, @undoc_items]
403
+ num_width, @num_items, undoc_width, @undoc_items]
291
404
 
292
- report << '%6.2f%% documented' % @percent_doc if @percent_doc
405
+ report << '%6.2f%% documented' % percent_doc
293
406
  report << nil
294
407
  report << 'Elapsed: %0.1fs' % (Time.now - @start)
295
408
 
296
409
  report.join "\n"
297
410
  end
298
411
 
412
+ ##
413
+ # Determines which parametecs in +method+ were not documented. Returns a
414
+ # total parameter count and an Array of undocumented methods.
415
+
416
+ def undoc_params method
417
+ @formatter ||= RDoc::Markup::ToTtOnly.new
418
+
419
+ params = method.param_list
420
+
421
+ return 0, [] if params.empty?
422
+
423
+ document = parse method.comment
424
+
425
+ tts = document.accept @formatter
426
+
427
+ undoc = params - tts
428
+
429
+ [params.length, undoc]
430
+ end
431
+
299
432
  autoload :Quiet, 'rdoc/stats/quiet'
300
433
  autoload :Normal, 'rdoc/stats/normal'
301
434
  autoload :Verbose, 'rdoc/stats/verbose'