yard 0.5.3 → 0.5.4

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 (90) hide show
  1. data/ChangeLog +443 -0
  2. data/README.md +5 -2
  3. data/docs/WhatsNew.md +8 -0
  4. data/lib/yard.rb +4 -4
  5. data/lib/yard/autoload.rb +34 -30
  6. data/lib/yard/cli/base.rb +14 -0
  7. data/lib/yard/cli/yard_graph.rb +5 -11
  8. data/lib/yard/cli/yardoc.rb +9 -8
  9. data/lib/yard/cli/yri.rb +2 -9
  10. data/lib/yard/code_objects/base.rb +9 -6
  11. data/lib/yard/code_objects/class_object.rb +5 -5
  12. data/lib/yard/code_objects/module_object.rb +3 -2
  13. data/lib/yard/core_ext/file.rb +1 -1
  14. data/lib/yard/docstring.rb +9 -20
  15. data/lib/yard/handlers/base.rb +13 -0
  16. data/lib/yard/handlers/ruby/alias_handler.rb +1 -1
  17. data/lib/yard/handlers/ruby/attribute_handler.rb +1 -1
  18. data/lib/yard/handlers/ruby/class_condition_handler.rb +1 -1
  19. data/lib/yard/handlers/ruby/class_handler.rb +1 -1
  20. data/lib/yard/handlers/ruby/class_variable_handler.rb +1 -1
  21. data/lib/yard/handlers/ruby/constant_handler.rb +1 -1
  22. data/lib/yard/handlers/ruby/exception_handler.rb +1 -1
  23. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +1 -1
  24. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +1 -1
  25. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +8 -0
  26. data/lib/yard/handlers/ruby/legacy/class_handler.rb +1 -1
  27. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +1 -1
  28. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +1 -1
  29. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +1 -1
  30. data/lib/yard/handlers/ruby/legacy/method_handler.rb +1 -1
  31. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +1 -1
  32. data/lib/yard/handlers/ruby/legacy/module_handler.rb +1 -1
  33. data/lib/yard/handlers/ruby/legacy/process_handler.rb +12 -0
  34. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +1 -1
  35. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +1 -1
  36. data/lib/yard/handlers/ruby/method_condition_handler.rb +1 -1
  37. data/lib/yard/handlers/ruby/method_handler.rb +1 -1
  38. data/lib/yard/handlers/ruby/mixin_handler.rb +1 -1
  39. data/lib/yard/handlers/ruby/module_handler.rb +1 -1
  40. data/lib/yard/handlers/ruby/process_handler.rb +12 -0
  41. data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
  42. data/lib/yard/handlers/ruby/yield_handler.rb +1 -1
  43. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +1 -1
  44. data/lib/yard/parser/ruby/legacy/statement.rb +6 -0
  45. data/lib/yard/parser/ruby/legacy/statement_list.rb +9 -3
  46. data/lib/yard/parser/ruby/ruby_parser.rb +16 -0
  47. data/lib/yard/tags/default_factory.rb +9 -13
  48. data/lib/yard/tags/library.rb +7 -7
  49. data/lib/yard/tags/overload_tag.rb +4 -4
  50. data/lib/yard/templates/erb_cache.rb +18 -0
  51. data/lib/yard/templates/helpers/html_helper.rb +24 -5
  52. data/lib/yard/templates/helpers/method_helper.rb +10 -2
  53. data/lib/yard/templates/template.rb +11 -7
  54. data/spec/code_objects/class_object_spec.rb +8 -1
  55. data/spec/code_objects/module_object_spec.rb +8 -1
  56. data/spec/core_ext/file_spec.rb +5 -1
  57. data/spec/docstring_spec.rb +80 -42
  58. data/spec/handlers/class_condition_handler_spec.rb +15 -13
  59. data/spec/handlers/examples/process_handler_001.rb.txt +11 -0
  60. data/spec/handlers/process_handler_spec.rb +17 -0
  61. data/spec/parser/source_parser_spec.rb +11 -0
  62. data/spec/tags/overload_tag_spec.rb +2 -2
  63. data/spec/templates/class_spec.rb +9 -0
  64. data/spec/templates/examples/class001.html +20 -17
  65. data/spec/templates/examples/class002.html +37 -0
  66. data/spec/templates/examples/method001.html +7 -7
  67. data/spec/templates/examples/method002.html +5 -5
  68. data/spec/templates/examples/method003.html +5 -5
  69. data/spec/templates/examples/method004.html +3 -3
  70. data/spec/templates/examples/method005.html +1 -1
  71. data/spec/templates/examples/module001.html +64 -36
  72. data/spec/templates/helpers/html_helper_spec.rb +28 -0
  73. data/spec/templates/helpers/method_helper_spec.rb +28 -0
  74. data/spec/templates/module_spec.rb +10 -1
  75. data/spec/templates/template_spec.rb +4 -0
  76. data/templates/default/class/setup.rb +1 -1
  77. data/templates/default/fulldoc/html/css/style.css +6 -1
  78. data/templates/default/fulldoc/html/frames.erb +1 -1
  79. data/templates/default/fulldoc/html/full_list.erb +1 -1
  80. data/templates/default/fulldoc/html/js/app.js +12 -0
  81. data/templates/default/fulldoc/html/js/full_list.js +11 -0
  82. data/templates/default/fulldoc/html/setup.rb +2 -1
  83. data/templates/default/layout/html/headers.erb +1 -1
  84. data/templates/default/layout/html/setup.rb +1 -1
  85. data/templates/default/module/html/box_info.erb +5 -0
  86. data/templates/default/module/html/constant_summary.erb +1 -1
  87. data/templates/default/module/html/inherited_methods.erb +10 -1
  88. data/templates/default/module/html/method_summary.erb +9 -7
  89. data/templates/default/module/setup.rb +17 -3
  90. metadata +9 -2
data/docs/WhatsNew.md CHANGED
@@ -12,6 +12,7 @@ What's New in 0.5.x?
12
12
  8. **Generating HTML docs now adds frames view** (0.5.3)
13
13
  9. **Tree view for class list** (0.5.3)
14
14
  10. **Ability to specify markup format of extra files** (0.5.3)
15
+ 11. **Keyboard shortcuts for default HTML template** (0.5.4)
15
16
 
16
17
  Support for documenting native Ruby C code (0.5.0)
17
18
  --------------------------------------------------
@@ -162,6 +163,13 @@ top of the file with a shebang-like line:
162
163
  The above file contents will be rendered with a textile markup engine
163
164
  (eg. RedCloth).
164
165
 
166
+ Keyboard shortcuts for default HTML template (0.5.4)
167
+ ----------------------------------------------------
168
+
169
+ You can now access the "Class List", "Method List" and "File List" with the
170
+ 'c', 'm' and 'f' keyboard shortcuts in the default HTML template, allowing
171
+ for keyboard-only navigation around YARD documentation.
172
+
165
173
 
166
174
  What's New in 0.4.x?
167
175
  ====================
data/lib/yard.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module YARD
2
- VERSION = "0.5.3"
3
- ROOT = File.dirname(__FILE__)
4
- TEMPLATE_ROOT = File.join(File.dirname(__FILE__), '..', 'templates')
2
+ VERSION = "0.5.4"
3
+ ROOT = File.expand_path(File.dirname(__FILE__))
4
+ TEMPLATE_ROOT = File.join(ROOT, '..', 'templates')
5
5
  CONFIG_DIR = File.expand_path('~/.yard')
6
6
 
7
7
  # An alias to {Parser::SourceParser}'s parsing method
@@ -49,7 +49,7 @@ end
49
49
  $LOAD_PATH.push('.') if RUBY_VERSION >= '1.9.2'
50
50
 
51
51
  # Keep track of Ruby version for compatibility code
52
- RUBY19, RUBY18 = *(RUBY_VERSION >= "1.9" ? [true, false] : [false, true])
52
+ RUBY19, RUBY18 = *(RUBY_VERSION >= "1.9.1" ? [true, false] : [false, true])
53
53
 
54
54
  # Load Ruby core extension classes
55
55
  Dir.glob(File.join(YARD::ROOT, 'yard', 'core_ext', '*')).each do |file|
data/lib/yard/autoload.rb CHANGED
@@ -49,42 +49,45 @@ module YARD
49
49
  module Handlers
50
50
  module Ruby # All Ruby handlers
51
51
  module Legacy # Handlers for old Ruby 1.8 parser
52
- autoload :Base, __p('handlers/ruby/legacy/base')
52
+ autoload :Base, __p('handlers/ruby/legacy/base')
53
53
 
54
- autoload :AliasHandler, __p('handlers/ruby/legacy/alias_handler')
55
- autoload :AttributeHandler, __p('handlers/ruby/legacy/attribute_handler')
56
- autoload :ClassHandler, __p('handlers/ruby/legacy/class_handler')
57
- autoload :ClassVariableHandler, __p('handlers/ruby/legacy/class_variable_handler')
58
- autoload :ConstantHandler, __p('handlers/ruby/legacy/constant_handler')
59
- autoload :ExceptionHandler, __p('handlers/ruby/legacy/exception_handler')
60
- autoload :ExtendHandler, __p('handlers/ruby/legacy/extend_handler')
61
- autoload :MethodHandler, __p('handlers/ruby/legacy/method_handler')
62
- autoload :MixinHandler, __p('handlers/ruby/legacy/mixin_handler')
63
- autoload :ModuleHandler, __p('handlers/ruby/legacy/module_handler')
64
- autoload :VisibilityHandler, __p('handlers/ruby/legacy/visibility_handler')
65
- autoload :YieldHandler, __p('handlers/ruby/legacy/yield_handler')
54
+ autoload :AliasHandler, __p('handlers/ruby/legacy/alias_handler')
55
+ autoload :AttributeHandler, __p('handlers/ruby/legacy/attribute_handler')
56
+ autoload :ClassHandler, __p('handlers/ruby/legacy/class_handler')
57
+ autoload :ClassConditionHandler, __p('handlers/ruby/legacy/class_condition_handler')
58
+ autoload :ClassVariableHandler, __p('handlers/ruby/legacy/class_variable_handler')
59
+ autoload :ConstantHandler, __p('handlers/ruby/legacy/constant_handler')
60
+ autoload :ExceptionHandler, __p('handlers/ruby/legacy/exception_handler')
61
+ autoload :ExtendHandler, __p('handlers/ruby/legacy/extend_handler')
62
+ autoload :MethodHandler, __p('handlers/ruby/legacy/method_handler')
63
+ autoload :MixinHandler, __p('handlers/ruby/legacy/mixin_handler')
64
+ autoload :ModuleHandler, __p('handlers/ruby/legacy/module_handler')
65
+ autoload :ProcessHandler, __p('handlers/ruby/legacy/process_handler')
66
+ autoload :VisibilityHandler, __p('handlers/ruby/legacy/visibility_handler')
67
+ autoload :YieldHandler, __p('handlers/ruby/legacy/yield_handler')
66
68
  end
67
69
 
68
- autoload :Base, __p('handlers/ruby/base')
70
+ autoload :Base, __p('handlers/ruby/base')
69
71
 
70
- autoload :AliasHandler, __p('handlers/ruby/alias_handler')
71
- autoload :AttributeHandler, __p('handlers/ruby/attribute_handler')
72
- autoload :ClassHandler, __p('handlers/ruby/class_handler')
73
- autoload :ClassConditionHandler, __p('handlers/ruby/class_condition_handler')
74
- autoload :ClassVariableHandler, __p('handlers/ruby/class_variable_handler')
75
- autoload :ConstantHandler, __p('handlers/ruby/constant_handler')
76
- autoload :ExceptionHandler, __p('handlers/ruby/exception_handler')
77
- autoload :ExtendHandler, __p('handlers/ruby/extend_handler')
78
- autoload :MethodHandler, __p('handlers/ruby/method_handler')
79
- autoload :MethodConditionHandler, __p('handlers/ruby/method_condition_handler')
80
- autoload :MixinHandler, __p('handlers/ruby/mixin_handler')
81
- autoload :ModuleHandler, __p('handlers/ruby/module_handler')
82
- autoload :VisibilityHandler, __p('handlers/ruby/visibility_handler')
83
- autoload :YieldHandler, __p('handlers/ruby/yield_handler')
72
+ autoload :AliasHandler, __p('handlers/ruby/alias_handler')
73
+ autoload :AttributeHandler, __p('handlers/ruby/attribute_handler')
74
+ autoload :ClassHandler, __p('handlers/ruby/class_handler')
75
+ autoload :ClassConditionHandler, __p('handlers/ruby/class_condition_handler')
76
+ autoload :ClassVariableHandler, __p('handlers/ruby/class_variable_handler')
77
+ autoload :ConstantHandler, __p('handlers/ruby/constant_handler')
78
+ autoload :ExceptionHandler, __p('handlers/ruby/exception_handler')
79
+ autoload :ExtendHandler, __p('handlers/ruby/extend_handler')
80
+ autoload :MethodHandler, __p('handlers/ruby/method_handler')
81
+ autoload :MethodConditionHandler, __p('handlers/ruby/method_condition_handler')
82
+ autoload :MixinHandler, __p('handlers/ruby/mixin_handler')
83
+ autoload :ModuleHandler, __p('handlers/ruby/module_handler')
84
+ autoload :ProcessHandler, __p('handlers/ruby/process_handler')
85
+ autoload :VisibilityHandler, __p('handlers/ruby/visibility_handler')
86
+ autoload :YieldHandler, __p('handlers/ruby/yield_handler')
84
87
  end
85
88
 
86
- autoload :Base, __p('handlers/base')
87
- autoload :Processor, __p('handlers/processor')
89
+ autoload :Base, __p('handlers/base')
90
+ autoload :Processor, __p('handlers/processor')
88
91
  end
89
92
 
90
93
  # The parser namespace holds all parsing engines used by YARD.
@@ -147,6 +150,7 @@ module YARD
147
150
 
148
151
  autoload :Engine, __p('templates/engine')
149
152
  autoload :Template, __p('templates/template')
153
+ autoload :ErbCache, __p('templates/erb_cache')
150
154
  end
151
155
 
152
156
  autoload :Docstring, __p('docstring')
data/lib/yard/cli/base.rb CHANGED
@@ -11,6 +11,8 @@ module YARD
11
11
  log.show_backtraces = false
12
12
  end
13
13
 
14
+ protected
15
+
14
16
  # Adds a set of common options to the tail of the OptionParser
15
17
  #
16
18
  # @param [OptionParser] opts the option parser object
@@ -25,6 +27,18 @@ module YARD
25
27
  opts.on_tail('-v', '--version', 'Show version.') { puts "yard #{YARD::VERSION}"; exit }
26
28
  opts.on_tail('-h', '--help', 'Show this help.') { puts opts; exit }
27
29
  end
30
+
31
+ # Parses the option and gracefully handles invalid switches
32
+ #
33
+ # @param [OptionParser] opts the option parser object
34
+ # @param [Array<String>] args the arguments passed from input. This
35
+ # array will be modified.
36
+ # @return [void]
37
+ def parse_options(opts, args)
38
+ opts.parse!(args)
39
+ rescue OptionParser::InvalidOption => e
40
+ log.warn "Unrecognized/#{e.message}"
41
+ end
28
42
  end
29
43
  end
30
44
  end
@@ -90,18 +90,12 @@ module YARD
90
90
  end
91
91
 
92
92
  common_options(opts)
93
+ parse_options(opts, args)
93
94
 
94
- begin
95
- opts.parse!(args)
96
- if args.first
97
- @objects = args.map {|o| Registry.at(o) }.compact
98
- else
99
- @objects = [Registry.root]
100
- end
101
- rescue => e
102
- STDERR.puts e.message
103
- STDERR << "\n" << opts
104
- exit
95
+ if args.first
96
+ @objects = args.map {|o| Registry.at(o) }.compact
97
+ else
98
+ @objects = [Registry.root]
105
99
  end
106
100
  end
107
101
  end
@@ -323,6 +323,14 @@ module YARD
323
323
  options[:serializer] = nil
324
324
  serialopts[:basepath] = dir
325
325
  end
326
+
327
+ opts.on('--charset ENC', 'Character set to use for HTML output (default is utf-8)') do |encoding|
328
+ begin
329
+ Encoding.default_external = encoding
330
+ rescue ArgumentError => e
331
+ raise OptionParser::InvalidOption, e
332
+ end
333
+ end
326
334
 
327
335
  opts.on('-t', '--template TEMPLATE',
328
336
  'The template to use. (defaults to "default")') do |template|
@@ -340,14 +348,7 @@ module YARD
340
348
  end
341
349
 
342
350
  common_options(opts)
343
-
344
- begin
345
- opts.parse!(args)
346
- rescue OptionParser::InvalidOption => e
347
- STDERR.puts e.message
348
- STDERR << "\n" << opts
349
- exit
350
- end
351
+ parse_options(opts, args)
351
352
 
352
353
  # Last minute modifications
353
354
  build_gems(do_rebuild_gems) if do_build_gems
data/lib/yard/cli/yri.rb CHANGED
@@ -129,15 +129,8 @@ module YARD
129
129
  end
130
130
 
131
131
  common_options(opts)
132
-
133
- begin
134
- opts.parse!(args)
135
- @name = args.first
136
- rescue => e
137
- STDERR.puts e.message
138
- STDERR << "\n" << opts
139
- exit
140
- end
132
+ parse_options(opts, args)
133
+ @name = args.first
141
134
  end
142
135
  end
143
136
  end
@@ -280,12 +280,15 @@ module YARD
280
280
  end
281
281
  end
282
282
 
283
- # Checks if the method matches the name of an existing custom
284
- # attribute.
285
- #
286
- # @param [Symbol] meth the name of the method/attribute
287
- # @raise [NoMethodError] if no method or custom attribute exists by
288
- # the name +meth+
283
+ # @overload dynamic_attr_name
284
+ # @return the value of attribute named by the method attribute name
285
+ # @raise [NoMethodError] if no method or custom attribute exists by
286
+ # the attribute name
287
+ # @see #[]
288
+ # @overload dynamic_attr_name=(value)
289
+ # @param value a value to set
290
+ # @return +value+
291
+ # @see #[]=
289
292
  def method_missing(meth, *args, &block)
290
293
  if meth.to_s =~ /=$/
291
294
  self[meth.to_s[0..-2]] = args.first
@@ -11,15 +11,15 @@ module YARD::CodeObjects
11
11
  super
12
12
 
13
13
  if is_exception?
14
- self.superclass ||= :Exception unless P(namespace, name) == P(:Exception)
14
+ self.superclass ||= "::Exception" unless P(namespace, name) == P(:Exception)
15
15
  else
16
16
  case P(namespace, name).path
17
17
  when "BasicObject"
18
18
  nil
19
19
  when "Object"
20
- self.superclass ||= :BasicObject
20
+ self.superclass ||= "::BasicObject"
21
21
  else
22
- self.superclass ||= :Object
22
+ self.superclass ||= "::Object"
23
23
  end
24
24
  end
25
25
  end
@@ -38,7 +38,7 @@ module YARD::CodeObjects
38
38
  # @return [Array<NamespaceObject>] the list of code objects that make up
39
39
  # the inheritance tree.
40
40
  def inheritance_tree(include_mods = false)
41
- list = (include_mods ? mixins(:instance) : [])
41
+ list = (include_mods ? mixins(:instance, :class) : [])
42
42
  if superclass.is_a?(Proxy) || superclass.respond_to?(:inheritance_tree)
43
43
  list += [superclass] unless superclass == P(:Object) || superclass == P(:BasicObject)
44
44
  end
@@ -126,7 +126,7 @@ module YARD::CodeObjects
126
126
 
127
127
  if @superclass == self
128
128
  msg = "superclass #{@superclass.inspect} cannot be the same as the declared class #{self.inspect}"
129
- @superclass = P(:Object)
129
+ @superclass = P("::Object")
130
130
  raise ArgumentError, msg
131
131
  end
132
132
  end
@@ -8,10 +8,11 @@ module YARD::CodeObjects
8
8
  # @return [Array<NamespaceObject>] a list of namespace objects
9
9
  def inheritance_tree(include_mods = false)
10
10
  return [self] unless include_mods
11
- [self] + mixins(:instance).map do |m|
11
+ [self] + mixins(:instance, :class).map do |m|
12
+ next if m == self
12
13
  next m unless m.respond_to?(:inheritance_tree)
13
14
  m.inheritance_tree(true)
14
- end.flatten
15
+ end.compact.flatten
15
16
  end
16
17
  end
17
18
  end
@@ -34,7 +34,7 @@ class File
34
34
  path = path.split(SEPARATOR)
35
35
  path = path.inject([]) do |acc, comp|
36
36
  next acc if comp == RELATIVE_SAMEDIR
37
- if comp == RELATIVE_PARENTDIR && acc.size > 0
37
+ if comp == RELATIVE_PARENTDIR && acc.size > 0 && acc.last != RELATIVE_PARENTDIR
38
38
  acc.pop
39
39
  next acc
40
40
  end
@@ -157,9 +157,8 @@ module YARD
157
157
  #
158
158
  # @param [String] tag_name the tag name
159
159
  # @param [String] tag_buf the text attached to the tag with newlines removed.
160
- # @param [String] raw_buf the raw buffer of text without removed newlines.
161
160
  # @return [Tags::Tag, Tags::RefTag] a tag
162
- def create_tag(tag_name, tag_buf, raw_buf)
161
+ def create_tag(tag_name, tag_buf)
163
162
  if tag_buf =~ /\A\s*(?:(\S+)\s+)?\(\s*see\s+(\S+)\s*\)\s*\Z/
164
163
  return create_ref_tag(tag_name, $1, $2)
165
164
  end
@@ -167,11 +166,7 @@ module YARD
167
166
  tag_factory = Tags::Library.instance
168
167
  tag_method = "#{tag_name}_tag"
169
168
  if tag_name && tag_factory.respond_to?(tag_method)
170
- if tag_factory.method(tag_method).arity == 2
171
- add_tag *tag_factory.send(tag_method, tag_buf, raw_buf.join("\n"))
172
- else
173
- add_tag *tag_factory.send(tag_method, tag_buf)
174
- end
169
+ add_tag *tag_factory.send(tag_method, tag_buf)
175
170
  else
176
171
  log.warn "Unknown tag @#{tag_name}" + (object ? " in file `#{object.file}` near line #{object.line}" : "")
177
172
  end
@@ -195,7 +190,7 @@ module YARD
195
190
  indent, last_indent = comments.first[/^\s*/].length, 0
196
191
  orig_indent = 0
197
192
  last_line = ""
198
- tag_name, tag_klass, tag_buf, raw_buf = nil, nil, "", []
193
+ tag_name, tag_klass, tag_buf = nil, nil, []
199
194
 
200
195
  (comments+['']).each_with_index do |line, index|
201
196
  indent = line[/^\s*/].length
@@ -204,27 +199,21 @@ module YARD
204
199
 
205
200
  if tag_name && (((indent < orig_indent && !empty) || done) ||
206
201
  (indent <= last_indent && line =~ META_MATCH))
207
- create_tag(tag_name, tag_buf, raw_buf)
208
- tag_name, tag_buf, raw_buf = nil, '', []
202
+ create_tag(tag_name, tag_buf.join("\n"))
203
+ tag_name, tag_buf, = nil, []
209
204
  orig_indent = 0
210
205
  end
211
206
 
212
207
  # Found a meta tag
213
208
  if line =~ META_MATCH
214
- orig_indent = indent
215
- tag_name, tag_buf = $1, ($2 || '')
216
- raw_buf = [tag_buf.dup]
209
+ tag_name, tag_buf = $1, [($2 || '')]
217
210
  elsif tag_name && indent >= orig_indent && !empty
211
+ orig_indent = indent if orig_indent == 0
218
212
  # Extra data added to the tag on the next line
219
213
  last_empty = last_line =~ /^[ \t]*$/ ? true : false
220
214
 
221
- if last_empty
222
- tag_buf << "\n\n"
223
- raw_buf << ''
224
- end
225
-
226
- tag_buf << line.gsub(/^[ \t]{#{indent}}/, last_empty ? '' : ' ')
227
- raw_buf << line.gsub(/^[ \t]{#{orig_indent}}/, '')
215
+ tag_buf << '' if last_empty
216
+ tag_buf << line.gsub(/^[ \t]{#{orig_indent}}/, '')
228
217
  elsif !tag_name
229
218
  # Regular docstring text
230
219
  docstring << line << "\n"
@@ -203,6 +203,19 @@ module YARD
203
203
  def namespace_only?
204
204
  @namespace_only ? true : false
205
205
  end
206
+
207
+ # Generates a +process+ method, equivalent to +def process; ... end+.
208
+ # Blocks defined with this syntax will be wrapped inside an anonymous
209
+ # module so that the handler class can be extended with mixins that
210
+ # override the +process+ method without alias chaining.
211
+ #
212
+ # @see #process
213
+ # @return [void]
214
+ def process(&block)
215
+ mod = Module.new
216
+ mod.send(:define_method, :process, &block)
217
+ include mod
218
+ end
206
219
  end
207
220
 
208
221
  def initialize(source_parser, stmt)
@@ -1,7 +1,7 @@
1
1
  class YARD::Handlers::Ruby::AliasHandler < YARD::Handlers::Ruby::Base
2
2
  handles :alias, method_call(:alias_method)
3
3
 
4
- def process
4
+ process do
5
5
  names = []
6
6
  if statement.type == :alias
7
7
  names = statement.map {|o| o.jump(:ident, :op, :kw, :const).first }
@@ -4,7 +4,7 @@ class YARD::Handlers::Ruby::AttributeHandler < YARD::Handlers::Ruby::Base
4
4
  handles method_call(:attr_writer)
5
5
  handles method_call(:attr_accessor)
6
6
 
7
- def process
7
+ process do
8
8
  return if statement.type == :var_ref
9
9
  read, write = true, false
10
10
  params = statement.parameters(false).dup
@@ -2,7 +2,7 @@ class YARD::Handlers::Ruby::ClassConditionHandler < YARD::Handlers::Ruby::Base
2
2
  namespace_only
3
3
  handles meta_type(:condition)
4
4
 
5
- def process
5
+ process do
6
6
  condition = parse_condition
7
7
  if condition == nil
8
8
  # Parse both blocks if we're unsure of the condition
@@ -2,7 +2,7 @@ class YARD::Handlers::Ruby::ClassHandler < YARD::Handlers::Ruby::Base
2
2
  namespace_only
3
3
  handles :class, :sclass
4
4
 
5
- def process
5
+ process do
6
6
  if statement.type == :class
7
7
  classname = statement[0].source
8
8
  superclass = parse_superclass(statement[1])
@@ -2,7 +2,7 @@ class YARD::Handlers::Ruby::ClassVariableHandler < YARD::Handlers::Ruby::Base
2
2
  namespace_only
3
3
  handles :assign
4
4
 
5
- def process
5
+ process do
6
6
  if statement[0].type == :var_field && statement[0][0].type == :cvar
7
7
  name = statement[0][0][0]
8
8
  value = statement[1].source