yard 0.8.7.4 → 0.8.7.5

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

Potentially problematic release.


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

Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/README.md +5 -332
  4. data/lib/yard/cli/gems.rb +0 -1
  5. data/lib/yard/cli/stats.rb +3 -3
  6. data/lib/yard/cli/yardoc.rb +6 -2
  7. data/lib/yard/docstring_parser.rb +0 -3
  8. data/lib/yard/handlers/c/symbol_handler.rb +1 -1
  9. data/lib/yard/handlers/ruby/method_handler.rb +34 -6
  10. data/lib/yard/handlers/ruby/private_class_method_handler.rb +13 -2
  11. data/lib/yard/i18n/pot_generator.rb +2 -0
  12. data/lib/yard/logging.rb +1 -1
  13. data/lib/yard/parser/ruby/ast_node.rb +45 -11
  14. data/lib/yard/parser/ruby/ruby_parser.rb +24 -12
  15. data/lib/yard/rake/yardoc_task.rb +8 -1
  16. data/lib/yard/server/commands/library_command.rb +5 -2
  17. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +1 -1
  18. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +2 -1
  19. data/lib/yard/tags/library.rb +0 -2
  20. data/lib/yard/templates/helpers/html_helper.rb +4 -2
  21. data/lib/yard/templates/template.rb +3 -3
  22. data/lib/yard/version.rb +1 -1
  23. data/spec/cli/yardoc_spec.rb +6 -6
  24. data/spec/handlers/examples/private_class_method_handler_001.rb.txt +2 -0
  25. data/spec/handlers/examples/private_class_method_handler_002.rb.txt +18 -0
  26. data/spec/handlers/examples/private_class_method_handler_003.rb.txt +11 -0
  27. data/spec/handlers/private_class_method_handler_spec.rb +41 -6
  28. data/spec/i18n/pot_generator_spec.rb +30 -0
  29. data/spec/parser/c_parser_spec.rb +18 -0
  30. data/spec/parser/ruby/ruby_parser_spec.rb +42 -1
  31. data/spec/parser/source_parser_spec.rb +15 -5
  32. data/spec/rake/yardoc_task_spec.rb +27 -0
  33. data/spec/spec_helper.rb +2 -0
  34. data/spec/templates/helpers/html_helper_spec.rb +32 -0
  35. data/templates/default/fulldoc/html/full_list.erb +5 -1
  36. data/templates/default/fulldoc/html/js/full_list.js +4 -1
  37. metadata +43 -42
@@ -71,13 +71,41 @@ class YARD::Handlers::Ruby::MethodHandler < YARD::Handlers::Ruby::Base
71
71
 
72
72
  def format_args
73
73
  args = statement.parameters
74
+
74
75
  params = []
75
- params += args.required_params.map {|a| [a.source, nil] } if args.required_params
76
- params += args.optional_params.map {|a| [a[0].source, a[1].source] } if args.optional_params
77
- params << ["*" + args.splat_param.source, nil] if args.splat_param
78
- params << ["**" + args.keyword_param.source, nil] if args.keyword_param
79
- params += args.required_end_params.map {|a| [a.source, nil] } if args.required_end_params
80
- params << ["&" + args.block_param.source, nil] if args.block_param
76
+
77
+ if args.unnamed_required_params
78
+ params += args.unnamed_required_params.map { |a| [a.source, nil] }
79
+ end
80
+
81
+ if args.unnamed_optional_params
82
+ params += args.unnamed_optional_params.map do |a|
83
+ [a[0].source, a[1].source]
84
+ end
85
+ end
86
+
87
+ if args.splat_param
88
+ params << ['*' + args.splat_param.source, nil]
89
+ end
90
+
91
+ if args.unnamed_end_params
92
+ params += args.unnamed_end_params.map { |a| [a.source, nil] }
93
+ end
94
+
95
+ if args.named_params
96
+ params += args.named_params.map do |a|
97
+ [a[0].source, a[1] ? a[1].source : nil]
98
+ end
99
+ end
100
+
101
+ if args.double_splat_param
102
+ params << ['**' + args.double_splat_param.source, nil]
103
+ end
104
+
105
+ if args.block_param
106
+ params << ['&' + args.block_param.source, nil]
107
+ end
108
+
81
109
  params
82
110
  end
83
111
 
@@ -24,8 +24,19 @@ class YARD::Handlers::Ruby::PrivateClassMethodHandler < YARD::Handlers::Ruby::Ba
24
24
  def privatize_class_method(node)
25
25
  if node.literal?
26
26
  method = Proxy.new(namespace, node[0][0][0], :method)
27
- ensure_loaded!(method)
28
- method.visibility = :private
27
+
28
+ # Proxy will not have a #visibility method when handling inherited class methods
29
+ # like :new, yet "private_class_method :new" is valid Ruby syntax. Therefore
30
+ # if Proxy doesn't respond to #visibility, the object should be skipped.
31
+ #
32
+ # However, it is important to note that classes can be reopened, and
33
+ # private_class_method can be called inside these reopened classes.
34
+ # Therefore when encountering private_class_method, all of the files need
35
+ # to be parsed before checking if Proxy responds to #visibility. If this
36
+ # is not done, it is possible that class methods may be incorrectly marked
37
+ # public/private.
38
+ parser.parse_remaining_files
39
+ method.visibility = :private if method.respond_to? :visibility
29
40
  else
30
41
  raise UndocumentableError, "invalid argument to private_class_method: #{node.source}"
31
42
  end
@@ -235,6 +235,8 @@ EOH
235
235
  def extract_tag_documents(tag)
236
236
  extract_tag_name(tag)
237
237
  extract_tag_text(tag)
238
+
239
+ extract_documents(tag) if Tags::OverloadTag === tag
238
240
  end
239
241
 
240
242
  def extract_tag_name(tag)
data/lib/yard/logging.rb CHANGED
@@ -26,7 +26,7 @@ module YARD
26
26
  return false if YARD.ruby18? # threading is too ineffective for progress support
27
27
  return false if YARD.windows? # windows has poor ANSI support
28
28
  return false unless io.tty? # no TTY support on IO
29
- return false if level > WARN # no progress in verbose/debug modes
29
+ return false unless level > INFO # no progress in verbose/debug modes
30
30
  @show_progress
31
31
  end
32
32
  attr_writer :show_progress
@@ -376,18 +376,46 @@ module YARD
376
376
  end
377
377
 
378
378
  class ParameterNode < AstNode
379
- def required_params; self[0] end
380
- def required_end_params; self[3] end
381
- def splat_param; self[2] ? self[2][0] : nil end
382
- def block_param; self[-1] ? self[-1][0] : nil end
383
- def optional_params
384
- optional = self[1] || []
385
- if self[-3] && self[-3][0] && self[-3][0].type == :default_arg
386
- optional += self[-3]
379
+ def unnamed_required_params
380
+ self[0]
381
+ end
382
+
383
+ def unnamed_optional_params
384
+ return @unnamed_optional_params if defined?(@unnamed_optional_params)
385
+
386
+ params = self[1] || []
387
+ if self[-3] && self[-3][0] && self[-3][0].type == :unnamed_optional_arg
388
+ params += self[-3]
389
+ end
390
+
391
+ @unnamed_optional_params = params.empty? ? nil : params
392
+ end
393
+
394
+ def named_params
395
+ return @named_params if defined?(@named_params)
396
+
397
+ if YARD.ruby2? && self[-3] && self[-3][0] && self[-3][0].type == :named_arg
398
+ @named_params = self[-3]
399
+ else
400
+ @named_params = nil
387
401
  end
388
- optional.empty? ? nil : optional
389
402
  end
390
- def keyword_param; YARD.ruby2? ? self[-2] : nil end
403
+
404
+ def splat_param
405
+ self[2] ? self[2][0] : nil
406
+ end
407
+
408
+ def unnamed_end_params
409
+ self[3]
410
+ end
411
+
412
+ def double_splat_param
413
+ YARD.ruby2? ? self[-2] : nil
414
+ end
415
+
416
+ def block_param
417
+ self[-1] ? self[-1][0] : nil
418
+ end
391
419
  end
392
420
 
393
421
  class MethodCallNode < AstNode
@@ -396,7 +424,13 @@ module YARD
396
424
 
397
425
  def method_name(name_only = false)
398
426
  name = self[index_adjust]
399
- name_only ? name.jump(:ident).first.to_sym : name
427
+ if name == :call
428
+ nil
429
+ elsif name_only && Array === name
430
+ name.jump(:ident).first.to_sym
431
+ else
432
+ name
433
+ end
400
434
  end
401
435
 
402
436
  def parameters(include_block_param = true)
@@ -452,21 +452,23 @@ module YARD
452
452
 
453
453
  def on_params(*args)
454
454
  args.map! do |arg|
455
- if arg.class == Array
456
- if arg.first.class == Array
457
- arg.map! do |sub_arg|
458
- if sub_arg.class == Array
459
- AstNode.new(:default_arg, sub_arg, :listline => lineno..lineno, :listchar => charno..charno)
460
- else
461
- sub_arg
462
- end
455
+ next arg unless arg.class == Array
456
+
457
+ if arg.first.class == Array
458
+ arg.map! do |sub_arg|
459
+ next sub_arg unless sub_arg.class == Array
460
+ if sub_arg[0].type == :label
461
+ type = :named_arg
462
+ else
463
+ type = :unnamed_optional_arg
463
464
  end
465
+ AstNode.new(type, sub_arg, :listline => lineno..lineno, :listchar => charno..charno)
464
466
  end
465
- AstNode.new(:list, arg, :listline => lineno..lineno, :listchar => charno..charno)
466
- else
467
- arg
468
467
  end
468
+
469
+ AstNode.new(:list, arg, :listline => lineno..lineno, :listchar => charno..charno)
469
470
  end
471
+
470
472
  ParameterNode.new(:params, args, :listline => lineno..lineno, :listchar => charno..charno)
471
473
  end
472
474
 
@@ -503,7 +505,8 @@ module YARD
503
505
 
504
506
  hash_flag = $1 == '##' ? true : false
505
507
 
506
- if append_comment && @comments_last_column && @comments_last_column == column
508
+ if append_comment && @comments_last_column &&
509
+ @comments_last_column == column && comment_starts_line?(ch)
507
510
  @comments.delete(lineno - 1)
508
511
  @comments_flags[lineno] = @comments_flags[lineno - 1]
509
512
  @comments_flags.delete(lineno - 1)
@@ -542,6 +545,15 @@ module YARD
542
545
  raise ParserSyntaxError, "syntax error in `#{file}`:(#{lineno},#{column}): #{msg}"
543
546
  end
544
547
 
548
+ def comment_starts_line?(charno)
549
+ (charno-1).downto(0) do |i|
550
+ ch = @source[i]
551
+ break if ch == "\n"
552
+ return false if ch != " " && ch != "\t"
553
+ end
554
+ true
555
+ end
556
+
545
557
  def insert_comments
546
558
  root.traverse do |node|
547
559
  next if node.type == :comment || node.type == :list || node.parent.type != :list
@@ -14,6 +14,10 @@ module YARD
14
14
  # @return [Array<String>] the options passed to the commandline utility
15
15
  attr_accessor :options
16
16
 
17
+ # Options to pass to {CLI::Stats}
18
+ # @return [Array<String>] the options passed to the stats utility
19
+ attr_accessor :stats_options
20
+
17
21
  # The Ruby source files (and any extra documentation files separated by '-')
18
22
  # to process.
19
23
  # @example Task files assignment
@@ -46,11 +50,13 @@ module YARD
46
50
  def initialize(name = :yard)
47
51
  @name = name
48
52
  @options = []
53
+ @stats_options = []
49
54
  @files = []
50
55
 
51
56
  yield self if block_given?
52
57
  self.options += ENV['OPTS'].split(/[ ,]/) if ENV['OPTS']
53
58
  self.files += ENV['FILES'].split(/[ ,]/) if ENV['FILES']
59
+ self.options << '--no-stats' unless self.stats_options.empty?
54
60
 
55
61
  define
56
62
  end
@@ -66,9 +72,10 @@ module YARD
66
72
  yardoc = YARD::CLI::Yardoc.new
67
73
  yardoc.options[:verifier] = verifier if verifier
68
74
  yardoc.run *(options + files)
75
+ YARD::CLI::Stats.run(*(stats_options + ['--use-cache'])) unless stats_options.empty?
69
76
  after.call if after.is_a?(Proc)
70
77
  end
71
78
  end
72
79
  end
73
80
  end
74
- end
81
+ end
@@ -118,9 +118,12 @@ module YARD
118
118
  end
119
119
 
120
120
  def not_prepared
121
- self.caching = false
122
121
  options.update(:template => :doc_server, :type => :processing)
123
- [202, {'Content-Type' => 'text/html'}, [render]]
122
+ self.caching = false
123
+ self.status = 202
124
+ self.body = render
125
+ self.headers = {'Content-Type' => 'text/html'}
126
+ [status, headers, [body]]
124
127
  end
125
128
 
126
129
  # Hack to load a custom fulldoc template object that does
@@ -1,5 +1,5 @@
1
1
  <form class="search" method="get" action="/<%= base_path(router.search_prefix) %>">
2
- Search: <input name="q" type="search" placeholder="Search" id="search_box" size="30" value="<%= @query %>" />
2
+ Search: <input name="q" type="search" placeholder="Search" id="search_box" size="30" value="<%= h @query %>" />
3
3
  </form>
4
4
  <script type="text/javascript" charset="utf-8">
5
5
  $(function() {
@@ -8,7 +8,8 @@
8
8
  <script type="text/javascript" charset="utf-8" src="/js/jquery.js"></script>
9
9
  <script type="text/javascript" charset="utf-8">
10
10
  function checkPage(process) {
11
- $.ajax({cache: false, url: "<%= router.request.path %>" + (process ? "?process=true" : ""), statusCode: { 200: function() { window.location = "<%= @path %>"; } } });
11
+ $.ajax({cache: false, url: "<%= router.request.path %>" + (process ? "?process=true" : ""),
12
+ statusCode: { 200: function() { window.location.reload(true); } } });
12
13
  setTimeout('checkPage()', 2000);
13
14
  }
14
15
  function setFade() {
@@ -78,8 +78,6 @@ module YARD
78
78
  # @example
79
79
  # YARD::Tags::Library.default_factory = MyFactory
80
80
  #
81
- # @param [Class, Object] factory the factory that parses all tags
82
- #
83
81
  # @see DefaultFactory
84
82
  def default_factory
85
83
  @default_factory ||= DefaultFactory.new
@@ -61,7 +61,8 @@ module YARD
61
61
  provider.new(text, :autolink).to_html
62
62
  elsif provider.to_s == 'RedcarpetCompat'
63
63
  provider.new(text, :no_intraemphasis, :gh_blockcode,
64
- :fenced_code, :autolink).to_html
64
+ :fenced_code, :autolink, :tables,
65
+ :lax_spacing).to_html
65
66
  else
66
67
  provider.new(text).to_html
67
68
  end
@@ -267,7 +268,7 @@ module YARD
267
268
  title = h(object.relative_path(obj))
268
269
  end
269
270
  else
270
- title = h(obj.to_s)
271
+ title = h(obj.title)
271
272
  end
272
273
  return title unless serializer
273
274
  return title if obj.is_a?(CodeObjects::Proxy)
@@ -327,6 +328,7 @@ module YARD
327
328
  objpath = serializer.serialized_path(obj)
328
329
  return link unless objpath
329
330
 
331
+ relative = false if object == Registry.root
330
332
  if relative
331
333
  fromobj = object
332
334
  if object.is_a?(CodeObjects::Base) &&
@@ -314,11 +314,11 @@ module YARD
314
314
 
315
315
  # Calls the ERB file from the last inherited template with {#section}.erb
316
316
  #
317
- # @param [Symbol, String] section if provided, uses a specific section name
317
+ # @param [Symbol, String] sect if provided, uses a specific section name
318
318
  # @return [String] the rendered ERB file in any of the inherited template
319
319
  # paths.
320
- def superb(section = section, &block)
321
- filename = self.class.find_nth_file(erb_file_for(section), 2)
320
+ def superb(sect = section, &block)
321
+ filename = self.class.find_nth_file(erb_file_for(sect), 2)
322
322
  return "" unless filename
323
323
  method_name = ErbCache.method_for(filename) { erb_with(IO.read(filename), filename) }
324
324
  send(method_name, &block)
data/lib/yard/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module YARD
2
- VERSION = '0.8.7.4'
2
+ VERSION = '0.8.7.5'
3
3
  end
@@ -320,7 +320,7 @@ describe YARD::CLI::Yardoc do
320
320
 
321
321
  CodeObjects::ExtraFileObject.stub!(:new).with('extra_file1').and_return(extra_file_object1)
322
322
  CodeObjects::ExtraFileObject.stub!(:new).with('extra_file2').and_return(extra_file_object2)
323
- Dir.stub!(:glob).with('README*').and_return([])
323
+ Dir.stub!(:glob).with('README{,*[^~]}').and_return([])
324
324
  File.stub!(:file?).with('extra_file1').and_return(true)
325
325
  File.stub!(:file?).with('extra_file2').and_return(true)
326
326
  @yardoc.run('--locale=fr', '-', 'extra_file1', 'extra_file2')
@@ -562,7 +562,7 @@ describe YARD::CLI::Yardoc do
562
562
 
563
563
  describe 'Extra file arguments' do
564
564
  it "should accept extra files if specified after '-' with source files" do
565
- Dir.should_receive(:glob).with('README*').and_return([])
565
+ Dir.should_receive(:glob).with('README{,*[^~]}').and_return([])
566
566
  File.should_receive(:file?).with('extra_file1').and_return(true)
567
567
  File.should_receive(:file?).with('extra_file2').and_return(true)
568
568
  File.should_receive(:read).with('extra_file1').and_return('')
@@ -575,14 +575,14 @@ describe YARD::CLI::Yardoc do
575
575
  end
576
576
 
577
577
  it "should accept files section only containing extra files" do
578
- Dir.should_receive(:glob).with('README*').and_return([])
578
+ Dir.should_receive(:glob).with('README{,*[^~]}').and_return([])
579
579
  @yardoc.parse_arguments *%w( - LICENSE )
580
580
  @yardoc.files.should == %w( {lib,app}/**/*.rb ext/**/*.c )
581
581
  @yardoc.options.files.should == [CodeObjects::ExtraFileObject.new('LICENSE', '')]
582
582
  end
583
583
 
584
584
  it "should accept globs as extra files" do
585
- Dir.should_receive(:glob).with('README*').and_return []
585
+ Dir.should_receive(:glob).with('README{,*[^~]}').and_return []
586
586
  Dir.should_receive(:glob).with('*.txt').and_return ['a.txt', 'b.txt']
587
587
  File.should_receive(:read).with('a.txt').and_return('')
588
588
  File.should_receive(:read).with('b.txt').and_return('')
@@ -606,7 +606,7 @@ describe YARD::CLI::Yardoc do
606
606
  end
607
607
 
608
608
  it "should use first file as readme if no readme is specified when using --one-file" do
609
- Dir.should_receive(:glob).with('README*').and_return []
609
+ Dir.should_receive(:glob).with('README{,*[^~]}').and_return []
610
610
  Dir.should_receive(:glob).with('lib/*.rb').and_return(['lib/foo.rb'])
611
611
  File.should_receive(:read).with('lib/foo.rb').and_return('')
612
612
  @yardoc.parse_arguments *%w( --one-file lib/*.rb )
@@ -614,7 +614,7 @@ describe YARD::CLI::Yardoc do
614
614
  end
615
615
 
616
616
  it "should use readme it exists when using --one-file" do
617
- Dir.should_receive(:glob).with('README*').and_return ['README']
617
+ Dir.should_receive(:glob).with('README{,*[^~]}').and_return ['README']
618
618
  File.should_receive(:read).with('README').and_return('')
619
619
  @yardoc.parse_arguments *%w( --one-file lib/*.rb )
620
620
  @yardoc.options.readme.should == CodeObjects::ExtraFileObject.new('README', '')
@@ -2,6 +2,8 @@ class A
2
2
  def self.b; end
3
3
  def self.c; end
4
4
  def self.d; end
5
+ def self.e; end
5
6
 
6
7
  private_class_method(:c, :d)
8
+ private_class_method("e")
7
9
  end
@@ -0,0 +1,18 @@
1
+ class SingletonClass
2
+
3
+ # Public
4
+ def self.foo
5
+ 'foo'
6
+ end
7
+
8
+ # Private
9
+ def self.bar
10
+ end
11
+
12
+ # Private from reopening class.
13
+ def self.baz
14
+ end
15
+
16
+ private_class_method :new, :bar
17
+
18
+ end
@@ -0,0 +1,11 @@
1
+ class SingletonClass
2
+ # Reopening singleton class from
3
+ # private_class_method_handler_002.rb.txt
4
+
5
+ private_class_method :baz
6
+
7
+ # Public from reopened class.
8
+ def self.bat
9
+ end
10
+
11
+ end