yard 0.5.8 → 0.6.0

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 (211) hide show
  1. data/.yardopts +2 -0
  2. data/ChangeLog +1064 -0
  3. data/README.md +103 -42
  4. data/Rakefile +3 -2
  5. data/benchmarks/parsing.rb +2 -1
  6. data/bin/yard +4 -0
  7. data/bin/yard-graph +1 -1
  8. data/bin/yard-server +4 -0
  9. data/docs/GettingStarted.md +8 -8
  10. data/docs/Handlers.md +5 -5
  11. data/docs/Overview.md +5 -5
  12. data/docs/Parser.md +1 -1
  13. data/docs/Tags.md +1 -1
  14. data/docs/Templates.md +27 -6
  15. data/docs/WhatsNew.md +222 -2
  16. data/lib/rubygems_plugin.rb +1 -0
  17. data/lib/yard.rb +7 -1
  18. data/lib/yard/autoload.rb +46 -6
  19. data/lib/yard/cli/{base.rb → command.rb} +20 -6
  20. data/lib/yard/cli/command_parser.rb +87 -0
  21. data/lib/yard/cli/diff.rb +176 -0
  22. data/lib/yard/cli/gems.rb +74 -0
  23. data/lib/yard/cli/{yard_graph.rb → graph.rb} +9 -8
  24. data/lib/yard/cli/help.rb +18 -0
  25. data/lib/yard/cli/server.rb +137 -0
  26. data/lib/yard/cli/stats.rb +210 -0
  27. data/lib/yard/cli/yardoc.rb +315 -116
  28. data/lib/yard/cli/yri.rb +45 -4
  29. data/lib/yard/code_objects/base.rb +73 -30
  30. data/lib/yard/code_objects/class_object.rb +9 -1
  31. data/lib/yard/code_objects/method_object.rb +11 -0
  32. data/lib/yard/code_objects/namespace_object.rb +8 -2
  33. data/lib/yard/code_objects/proxy.rb +2 -2
  34. data/lib/yard/core_ext/array.rb +3 -49
  35. data/lib/yard/core_ext/file.rb +7 -0
  36. data/lib/yard/core_ext/insertion.rb +60 -0
  37. data/lib/yard/docstring.rb +34 -7
  38. data/lib/yard/globals.rb +2 -2
  39. data/lib/yard/handlers/base.rb +101 -20
  40. data/lib/yard/handlers/processor.rb +23 -7
  41. data/lib/yard/handlers/ruby/alias_handler.rb +1 -0
  42. data/lib/yard/handlers/ruby/attribute_handler.rb +8 -0
  43. data/lib/yard/handlers/ruby/base.rb +71 -2
  44. data/lib/yard/handlers/ruby/class_condition_handler.rb +10 -0
  45. data/lib/yard/handlers/ruby/class_handler.rb +7 -4
  46. data/lib/yard/handlers/ruby/class_variable_handler.rb +1 -0
  47. data/lib/yard/handlers/ruby/constant_handler.rb +1 -0
  48. data/lib/yard/handlers/ruby/exception_handler.rb +1 -0
  49. data/lib/yard/handlers/ruby/extend_handler.rb +2 -3
  50. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +1 -0
  51. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +2 -0
  52. data/lib/yard/handlers/ruby/legacy/base.rb +15 -2
  53. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +5 -0
  54. data/lib/yard/handlers/ruby/legacy/class_handler.rb +7 -4
  55. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +1 -0
  56. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +1 -0
  57. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +1 -0
  58. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +1 -3
  59. data/lib/yard/handlers/ruby/legacy/method_handler.rb +7 -3
  60. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +2 -1
  61. data/lib/yard/handlers/ruby/legacy/module_handler.rb +1 -0
  62. data/lib/yard/handlers/ruby/legacy/process_handler.rb +1 -0
  63. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +1 -0
  64. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +1 -0
  65. data/lib/yard/handlers/ruby/method_condition_handler.rb +1 -0
  66. data/lib/yard/handlers/ruby/method_handler.rb +5 -1
  67. data/lib/yard/handlers/ruby/mixin_handler.rb +2 -1
  68. data/lib/yard/handlers/ruby/module_handler.rb +1 -0
  69. data/lib/yard/handlers/ruby/process_handler.rb +7 -1
  70. data/lib/yard/handlers/ruby/struct_handler_methods.rb +3 -0
  71. data/lib/yard/handlers/ruby/visibility_handler.rb +8 -2
  72. data/lib/yard/handlers/ruby/yield_handler.rb +1 -0
  73. data/lib/yard/logging.rb +7 -1
  74. data/lib/yard/parser/base.rb +1 -0
  75. data/lib/yard/parser/c_parser.rb +2 -0
  76. data/lib/yard/parser/ruby/ast_node.rb +82 -63
  77. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +36 -10
  78. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +1 -0
  79. data/lib/yard/parser/ruby/legacy/statement.rb +9 -5
  80. data/lib/yard/parser/ruby/legacy/statement_list.rb +20 -11
  81. data/lib/yard/parser/ruby/ruby_parser.rb +18 -1
  82. data/lib/yard/parser/source_parser.rb +6 -1
  83. data/lib/yard/registry.rb +284 -278
  84. data/lib/yard/registry_store.rb +4 -2
  85. data/lib/yard/serializers/base.rb +30 -13
  86. data/lib/yard/serializers/file_system_serializer.rb +10 -1
  87. data/lib/yard/server/adapter.rb +51 -0
  88. data/lib/yard/server/commands/base.rb +98 -0
  89. data/lib/yard/server/commands/display_file_command.rb +20 -0
  90. data/lib/yard/server/commands/display_object_command.rb +50 -0
  91. data/lib/yard/server/commands/frames_command.rb +31 -0
  92. data/lib/yard/server/commands/library_command.rb +83 -0
  93. data/lib/yard/server/commands/library_index_command.rb +23 -0
  94. data/lib/yard/server/commands/list_command.rb +44 -0
  95. data/lib/yard/server/commands/search_command.rb +67 -0
  96. data/lib/yard/server/commands/static_file_command.rb +45 -0
  97. data/lib/yard/server/doc_server_helper.rb +22 -0
  98. data/lib/yard/server/doc_server_serializer.rb +29 -0
  99. data/lib/yard/server/library_version.rb +86 -0
  100. data/lib/yard/server/rack_adapter.rb +38 -0
  101. data/lib/yard/server/router.rb +110 -0
  102. data/lib/yard/server/static_caching.rb +16 -0
  103. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +78 -0
  104. data/lib/yard/server/templates/default/fulldoc/html/images/processing.gif +0 -0
  105. data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +12 -0
  106. data/lib/yard/server/templates/default/fulldoc/html/js/live.js +32 -0
  107. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +46 -0
  108. data/lib/yard/server/templates/default/layout/html/headers.erb +11 -0
  109. data/lib/yard/server/templates/doc_server/frames/html/frames.erb +13 -0
  110. data/lib/yard/server/templates/doc_server/frames/html/setup.rb +3 -0
  111. data/lib/yard/server/templates/doc_server/full_list/html/full_list.erb +34 -0
  112. data/lib/yard/server/templates/doc_server/full_list/html/setup.rb +10 -0
  113. data/lib/yard/server/templates/doc_server/library_list/html/contents.erb +13 -0
  114. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +26 -0
  115. data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +12 -0
  116. data/lib/yard/server/templates/doc_server/library_list/html/setup.rb +3 -0
  117. data/lib/yard/server/templates/doc_server/library_list/html/title.erb +2 -0
  118. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +51 -0
  119. data/lib/yard/server/templates/doc_server/processing/html/setup.rb +3 -0
  120. data/lib/yard/server/templates/doc_server/search/html/search.erb +19 -0
  121. data/lib/yard/server/templates/doc_server/search/html/setup.rb +8 -0
  122. data/lib/yard/server/webrick_adapter.rb +38 -0
  123. data/lib/yard/tags/default_factory.rb +0 -5
  124. data/lib/yard/tags/library.rb +61 -22
  125. data/lib/yard/tags/tag.rb +26 -4
  126. data/lib/yard/templates/engine.rb +12 -1
  127. data/lib/yard/templates/erb_cache.rb +2 -1
  128. data/lib/yard/templates/helpers/base_helper.rb +96 -3
  129. data/lib/yard/templates/helpers/filter_helper.rb +5 -0
  130. data/lib/yard/templates/helpers/html_helper.rb +204 -94
  131. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +4 -0
  132. data/lib/yard/templates/helpers/markup_helper.rb +58 -3
  133. data/lib/yard/templates/helpers/method_helper.rb +7 -0
  134. data/lib/yard/templates/helpers/module_helper.rb +5 -0
  135. data/lib/yard/templates/helpers/text_helper.rb +10 -1
  136. data/lib/yard/templates/helpers/uml_helper.rb +13 -0
  137. data/lib/yard/templates/section.rb +106 -0
  138. data/lib/yard/templates/template.rb +20 -19
  139. data/lib/yard/verifier.rb +21 -2
  140. data/spec/cli/command_parser_spec.rb +43 -0
  141. data/spec/cli/diff_spec.rb +170 -0
  142. data/spec/cli/help_spec.rb +22 -0
  143. data/spec/cli/server_spec.rb +140 -0
  144. data/spec/cli/stats_spec.rb +75 -0
  145. data/spec/cli/yardoc_spec.rb +438 -182
  146. data/spec/cli/yri_spec.rb +13 -1
  147. data/spec/code_objects/base_spec.rb +51 -6
  148. data/spec/code_objects/class_object_spec.rb +15 -1
  149. data/spec/code_objects/method_object_spec.rb +29 -0
  150. data/spec/code_objects/namespace_object_spec.rb +150 -129
  151. data/spec/core_ext/array_spec.rb +4 -23
  152. data/spec/core_ext/insertion_spec.rb +37 -0
  153. data/spec/docstring_spec.rb +63 -0
  154. data/spec/handlers/attribute_handler_spec.rb +4 -0
  155. data/spec/handlers/base_spec.rb +98 -26
  156. data/spec/handlers/class_handler_spec.rb +5 -1
  157. data/spec/handlers/examples/attribute_handler_001.rb.txt +5 -0
  158. data/spec/handlers/examples/class_handler_001.rb.txt +4 -0
  159. data/spec/handlers/examples/module_handler_001.rb.txt +6 -1
  160. data/spec/handlers/examples/visibility_handler_001.rb.txt +4 -0
  161. data/spec/handlers/method_handler_spec.rb +5 -0
  162. data/spec/handlers/module_handler_spec.rb +4 -0
  163. data/spec/handlers/visibility_handler_spec.rb +6 -0
  164. data/spec/parser/source_parser_spec.rb +24 -0
  165. data/spec/registry_spec.rb +44 -8
  166. data/spec/server/adapter_spec.rb +38 -0
  167. data/spec/server/commands/base_spec.rb +87 -0
  168. data/spec/server/commands/static_file_command_spec.rb +67 -0
  169. data/spec/server/doc_server_serializer_spec.rb +58 -0
  170. data/spec/server/router_spec.rb +115 -0
  171. data/spec/server/spec_helper.rb +17 -0
  172. data/spec/server/static_caching_spec.rb +39 -0
  173. data/spec/server/webrick_servlet_spec.rb +20 -0
  174. data/spec/templates/constant_spec.rb +40 -0
  175. data/spec/templates/engine_spec.rb +9 -5
  176. data/spec/templates/examples/class002.html +1 -3
  177. data/spec/templates/examples/constant001.txt +25 -0
  178. data/spec/templates/examples/constant002.txt +7 -0
  179. data/spec/templates/examples/constant003.txt +11 -0
  180. data/spec/templates/examples/module001.txt +1 -1
  181. data/spec/templates/examples/module002.html +319 -0
  182. data/spec/templates/helpers/base_helper_spec.rb +2 -2
  183. data/spec/templates/helpers/html_helper_spec.rb +93 -3
  184. data/spec/templates/helpers/html_syntax_highlight_helper_spec.rb +5 -0
  185. data/spec/templates/helpers/markup_helper_spec.rb +94 -67
  186. data/spec/templates/helpers/shared_signature_examples.rb +9 -0
  187. data/spec/templates/helpers/text_helper_spec.rb +12 -0
  188. data/spec/templates/module_spec.rb +21 -4
  189. data/spec/templates/section_spec.rb +146 -0
  190. data/spec/templates/template_spec.rb +9 -20
  191. data/templates/default/class/setup.rb +5 -5
  192. data/templates/default/constant/text/header.erb +11 -0
  193. data/templates/default/constant/text/setup.rb +3 -0
  194. data/templates/default/fulldoc/html/css/style.css +29 -3
  195. data/templates/default/fulldoc/html/js/app.js +67 -1
  196. data/templates/default/fulldoc/html/js/full_list.js +3 -8
  197. data/templates/default/fulldoc/html/js/jquery.js +150 -15
  198. data/templates/default/fulldoc/html/setup.rb +9 -0
  199. data/templates/default/layout/html/footer.erb +1 -1
  200. data/templates/default/layout/html/setup.rb +7 -25
  201. data/templates/default/method_details/html/source.erb +1 -1
  202. data/templates/default/module/html/attribute_summary.erb +2 -2
  203. data/templates/default/module/html/method_summary.erb +2 -2
  204. data/templates/default/module/setup.rb +27 -4
  205. data/templates/default/onefile/html/files.erb +5 -0
  206. data/templates/default/onefile/html/layout.erb +22 -0
  207. data/templates/default/onefile/html/readme.erb +3 -0
  208. data/templates/default/onefile/html/setup.rb +40 -0
  209. data/templates/default/root/html/setup.rb +1 -0
  210. data/templates/default/tags/setup.rb +26 -33
  211. metadata +80 -10
@@ -1,5 +1,5 @@
1
1
  class Array
2
- # Places a value before or after another object (by value) in
2
+ # Places values before or after another object (by value) in
3
3
  # an array. This is used in tandem with the before and after
4
4
  # methods of the {Insertion} class.
5
5
  #
@@ -7,55 +7,9 @@ class Array
7
7
  # [1, 2, 3].place(4).before(3) # => [1, 2, 4, 3]
8
8
  # @example Places an item after another
9
9
  # [:a, :b, :c].place(:x).after(:a) # => [:a, :x, :b, :c]
10
- # @param [Object] value value to insert
10
+ # @param [Array] values value to insert
11
11
  # @return [Insertion] an insertion object to
12
12
  # @see Insertion#before
13
13
  # @see Insertion#after
14
- def place(value) Insertion.new(self, value) end
15
- end
16
-
17
- # The Insertion class inserts a value before or after another
18
- # value in a list.
19
- #
20
- # @example
21
- # Insertion.new([1, 2, 3], 4).before(3) # => [1, 2, 4, 3]
22
- class Insertion
23
- # Creates an insertion object on a list with a value to be
24
- # inserted. To finalize the insertion, call {#before} or
25
- # {#after} on the object.
26
- #
27
- # @param [Array] list the list to perform the insertion on
28
- # @param [Object] value the value to insert
29
- def initialize(list, value) @list, @value = list, value end
30
-
31
- # Inserts the value before +val+
32
- # @param [Object] val the object the value will be inserted before
33
- def before(val) insertion(val, 0) end
34
-
35
- # Inserts the value after +val+.
36
- #
37
- # @example If subsections are ignored
38
- # Insertion.new([1, [2], 3], :X).after(1) # => [1, [2], :X, 3]
39
- # @param [Object] val the object the value will be inserted after
40
- # @param [Boolean] ignore_subsections treat any Array objects that follow val as
41
- # associated and do not split them up.
42
- def after(val, ignore_subsections = true) insertion(val, 1, ignore_subsections) end
43
-
44
- private
45
-
46
- # This method performs the actual insertion
47
- #
48
- # @param [Object] val the value to insert
49
- # @param [Fixnum] rel the relative index (0 or 1) of where the object
50
- # should be placed
51
- # @param [Boolean] ignore_subsections see {#after} for an explanation.
52
- def insertion(val, rel, ignore_subsections = true)
53
- if index = @list.index(val)
54
- if ignore_subsections && rel == 1 && @list[index + 1].is_a?(Array)
55
- rel += 1
56
- end
57
- @list[index+rel,0] = @value
58
- end
59
- @list
60
- end
14
+ def place(*values) Insertion.new(self, values) end
61
15
  end
@@ -4,6 +4,8 @@ class File
4
4
  RELATIVE_PARENTDIR = '..'
5
5
  RELATIVE_SAMEDIR = '.'
6
6
 
7
+ # @group Manipulating Paths
8
+
7
9
  # Turns a path +to+ into a relative path from starting
8
10
  # point +from+. The argument +from+ is assumed to be
9
11
  # a filename. To treat it as a directory, make sure it
@@ -43,7 +45,11 @@ class File
43
45
  File.join(*path)
44
46
  end
45
47
 
48
+ # @group Reading Files
49
+
46
50
  # Forces opening a file (for writing) by first creating the file's directory
51
+ # @param [String] file the filename to open
52
+ # @since 0.5.2
47
53
  def self.open!(file, *args, &block)
48
54
  dir = dirname(file)
49
55
  FileUtils.mkdir_p(dir) unless directory?(dir)
@@ -52,6 +58,7 @@ class File
52
58
 
53
59
  # Reads a file with binary encoding
54
60
  # @return [String] the ascii-8bit encoded data
61
+ # @since 0.5.3
55
62
  def self.read_binary(file)
56
63
  File.open(file, 'rb') {|f| f.read }
57
64
  end
@@ -0,0 +1,60 @@
1
+ # The Insertion class inserts a value before or after another
2
+ # value in a list.
3
+ #
4
+ # @example
5
+ # Insertion.new([1, 2, 3], 4).before(3) # => [1, 2, 4, 3]
6
+ class Insertion
7
+ # Creates an insertion object on a list with a value to be
8
+ # inserted. To finalize the insertion, call {#before} or
9
+ # {#after} on the object.
10
+ #
11
+ # @param [Array] list the list to perform the insertion on
12
+ # @param [Object] value the value to insert
13
+ def initialize(list, value) @list, @values = list, (Array === value ? value : [value]) end
14
+
15
+ # Inserts the value before +val+
16
+ # @param [Object] val the object the value will be inserted before
17
+ # @param [Boolean] recursive look inside sublists
18
+ def before(val, recursive = false) insertion(val, 0, recursive) end
19
+
20
+ # Inserts the value after +val+.
21
+ #
22
+ # @example If subsections are ignored
23
+ # Insertion.new([1, [2], 3], :X).after(1) # => [1, [2], :X, 3]
24
+ # @param [Object] val the object the value will be inserted after
25
+ # @param [Boolean] recursive look inside sublists
26
+ def after(val, recursive = false) insertion(val, 1, recursive) end
27
+
28
+ # Alias for {#before} with +recursive+ set to true
29
+ # @since 0.6.0
30
+ def before_any(val) insertion(val, 0, true) end
31
+
32
+ # Alias for {#after} with +recursive+ set to true
33
+ # @since 0.6.0
34
+ def after_any(val) insertion(val, 1, true) end
35
+
36
+ private
37
+
38
+ # This method performs the actual insertion
39
+ #
40
+ # @param [Object] val the value to insert
41
+ # @param [Fixnum] rel the relative index (0 or 1) of where the object
42
+ # should be placed
43
+ # @param [Boolean] recursive look inside sublists
44
+ # @param [Array] list the list to place objects into
45
+ def insertion(val, rel, recursive = false, list = @list)
46
+ if recursive
47
+ list.each do |item|
48
+ next unless item.is_a?(Array)
49
+ tmp = item.dup
50
+ insertion(val, rel, recursive, item)
51
+ return(list) unless item == tmp
52
+ end
53
+ end
54
+
55
+ if index = list.index(val)
56
+ list[index+rel,0] = @values
57
+ end
58
+ list
59
+ end
60
+ end
@@ -26,8 +26,10 @@ module YARD
26
26
  attr_reader :all
27
27
 
28
28
  # Matches a tag at the start of a comment line
29
- META_MATCH = /^@([a-z_]+)(?:\s+(.*))?$/i
29
+ META_MATCH = /^@([a-z_0-9]+)(?:\s+(.*))?$/i
30
30
 
31
+ # @group Creating a Docstring Object
32
+
31
33
  # Creates a new docstring with the raw contents attached to an optional
32
34
  # object.
33
35
  #
@@ -45,6 +47,20 @@ module YARD
45
47
  self.all = content
46
48
  end
47
49
 
50
+ # Adds another {Docstring}, copying over tags.
51
+ #
52
+ # @param [Docstring, String] other the other docstring (or string) to
53
+ # add.
54
+ # @return [Docstring] a new docstring with both docstrings combines
55
+ def +(other)
56
+ case other
57
+ when Docstring
58
+ Docstring.new([all, other.all].join("\n"), object)
59
+ else
60
+ super
61
+ end
62
+ end
63
+
48
64
  # Replaces the docstring with new raw content. Called by {#all=}.
49
65
  # @param [String] content the raw comments to be parsed
50
66
  def replace(content)
@@ -53,6 +69,8 @@ module YARD
53
69
  super parse_comments(content)
54
70
  end
55
71
  alias all= replace
72
+
73
+ # @endgroup
56
74
 
57
75
  # @return [Fixnum] the first line of the {#line_range}.
58
76
  def line
@@ -83,6 +101,8 @@ module YARD
83
101
  @summary += '.' unless @summary.empty?
84
102
  @summary
85
103
  end
104
+
105
+ # @group Creating and Accessing Meta-data
86
106
 
87
107
  # Adds a tag or reftag object to the tag list
88
108
  # @param [Tags::Tag, Tags::RefTag] tags list of tag objects to add
@@ -123,7 +143,6 @@ module YARD
123
143
  list.select {|tag| tag.tag_name.to_s == name.to_s }
124
144
  end
125
145
 
126
- ##
127
146
  # Returns true if at least one tag by the name +name+ was declared
128
147
  #
129
148
  # @param [String] name the tag name to search for
@@ -132,12 +151,20 @@ module YARD
132
151
  tags.any? {|tag| tag.tag_name.to_s == name.to_s }
133
152
  end
134
153
 
135
- # Returns true if the docstring has no content
154
+ # Returns true if the docstring has no content that is visible to a template.
136
155
  #
156
+ # @param [Boolean] only_visible_tags whether only {Tags::Library.visible_tags}
157
+ # should be checked, or if all tags should be considered.
137
158
  # @return [Boolean] whether or not the docstring has content
138
- def blank?
139
- empty? && @tags.empty? && @ref_tags.empty?
159
+ def blank?(only_visible_tags = true)
160
+ if only_visible_tags
161
+ empty? && !tags.any? {|tag| Tags::Library.visible_tags.include?(tag.tag_name.to_sym) }
162
+ else
163
+ empty? && @tags.empty? && @ref_tags.empty?
164
+ end
140
165
  end
166
+
167
+ # @endgroup
141
168
 
142
169
  private
143
170
 
@@ -198,8 +225,8 @@ module YARD
198
225
  empty = (line =~ /^\s*$/ ? true : false)
199
226
  done = comments.size == index
200
227
 
201
- if tag_name && (((indent < orig_indent && !empty) || done) ||
202
- (indent <= last_indent && line =~ META_MATCH))
228
+ if tag_name && (((indent < orig_indent && !empty) || done ||
229
+ (indent == 0 && !empty)) || (indent <= last_indent && line =~ META_MATCH))
203
230
  create_tag(tag_name, tag_buf.join("\n"))
204
231
  tag_name, tag_buf, = nil, []
205
232
  orig_indent = 0
data/lib/yard/globals.rb CHANGED
@@ -1,9 +1,9 @@
1
- # Global methods
1
+ # @group Global Convenience Methods
2
2
 
3
3
  # Shortcut for creating a YARD::CodeObjects::Proxy via a path
4
4
  #
5
5
  # @see YARD::CodeObjects::Proxy
6
- # @see YARD::Registry#resolve
6
+ # @see YARD::Registry.resolve
7
7
  def P(namespace, name = nil)
8
8
  namespace, name = nil, namespace if name.nil?
9
9
  YARD::Registry.resolve(namespace, name, false, true)
@@ -11,8 +11,6 @@ module YARD
11
11
  def initialize(object) @object = object end
12
12
  end
13
13
 
14
- # = Handlers
15
- #
16
14
  # Handlers are pluggable semantic parsers for YARD's code generation
17
15
  # phase. They allow developers to control what information gets
18
16
  # generated by YARD, giving them the ability to, for instance, document
@@ -188,18 +186,35 @@ module YARD
188
186
  (@handlers ||= []).push(*matches)
189
187
  end
190
188
 
189
+ # This class is implemented by {Ruby::Base} and {Ruby::Legacy::Base}.
190
+ # To implement a base handler class for another language, implement
191
+ # this method to return true if the handler should process the given
192
+ # statement object. Use {handlers} to enumerate the matchers declared
193
+ # for the handler class.
194
+ #
195
+ # @param statement a statement object or node (depends on language type)
196
+ # @return [Boolean] whether or not this handler object should process
197
+ # the given statement
191
198
  def handles?(statement)
192
199
  raise NotImplementedError, "override #handles? in a subclass"
193
200
  end
194
201
 
202
+ # @return [Array] a list of matchers for the handler object.
203
+ # @see handles?
195
204
  def handlers
196
205
  @handlers ||= []
197
206
  end
198
207
 
208
+ # Declares that the handler should only be called when inside a
209
+ # {CodeObjects::NamespaceObject}, not a method body.
210
+ #
211
+ # @return [void]
199
212
  def namespace_only
200
213
  @namespace_only = true
201
214
  end
202
215
 
216
+ # @return [Boolean] whether the handler should only be processed inside
217
+ # a namespace.
203
218
  def namespace_only?
204
219
  (@namespace_only ||= false) ? true : false
205
220
  end
@@ -211,6 +226,7 @@ module YARD
211
226
  #
212
227
  # @see #process
213
228
  # @return [void]
229
+ # @since 0.5.4
214
230
  def process(&block)
215
231
  mod = Module.new
216
232
  mod.send(:define_method, :process, &block)
@@ -243,14 +259,36 @@ module YARD
243
259
  raise NotImplementedError, "#{self} did not implement a #process method for handling."
244
260
  end
245
261
 
262
+ # Parses the semantic "block" contained in the statement node.
263
+ #
264
+ # @abstract Subclasses should call {Processor#process parser.process}
246
265
  def parse_block(*args)
247
266
  raise NotImplementedError, "#{self} did not implement a #parse_block method for handling"
248
267
  end
249
268
 
250
269
  protected
251
270
 
252
- attr_reader :parser, :statement
253
- attr_accessor :owner, :namespace, :visibility, :scope
271
+ # @return [Processor] the processor object that manages all global state
272
+ # during handling.
273
+ attr_reader :parser
274
+
275
+ # @return [Object] the statement object currently being processed. Usually
276
+ # refers to one semantic language statement, though the strict definition
277
+ # depends on the parser used.
278
+ attr_reader :statement
279
+
280
+ # (see Processor#owner)
281
+ attr_accessor :owner
282
+
283
+ # (see Processor#namespace)
284
+ attr_accessor :namespace
285
+
286
+ # (see Processor#visibility)
287
+ attr_accessor :visibility
288
+
289
+ # (see Processor#scope)
290
+ attr_accessor :scope
291
+
254
292
  undef owner, owner=, namespace, namespace=
255
293
  undef visibility, visibility=, scope, scope=
256
294
 
@@ -263,30 +301,37 @@ module YARD
263
301
  def scope; parser.scope end
264
302
  def scope=(v); parser.scope=(v) end
265
303
 
304
+ # Executes a given block with specific state values for {#owner},
305
+ # {#namespace} and {#scope}.
306
+ #
307
+ # @param [Proc] block the block to execute with specific state
308
+ # @option opts [CodeObjects::NamespaceObject] :namespace (value of #namespace)
309
+ # the namespace object that {#namespace} will be equal to for the
310
+ # duration of the block.
311
+ # @option opts [Symbol] :scope (:instance)
312
+ # the scope for the duration of the block.
313
+ # @option opts [CodeObjects::Base] :owner (value of #owner)
314
+ # the owner object (method) for the duration of the block
315
+ # @yield a block to execute with the given state values.
266
316
  def push_state(opts = {}, &block)
267
317
  opts = {
268
- :namespace => nil,
318
+ :namespace => namespace,
269
319
  :scope => :instance,
270
- :owner => nil
320
+ :owner => owner || namespace
271
321
  }.update(opts)
272
322
 
273
- if opts[:namespace]
274
- ns, vis, sc = namespace, visibility, scope
275
- self.namespace = opts[:namespace]
276
- self.visibility = :public
277
- self.scope = opts[:scope]
278
- end
323
+ ns, vis, sc, oo = namespace, visibility, scope, owner
324
+ self.namespace = opts[:namespace]
325
+ self.visibility = :public
326
+ self.scope = opts[:scope]
327
+ self.owner = opts[:owner]
279
328
 
280
- oldowner, self.owner = self.owner, opts[:owner] ? opts[:owner] : namespace
281
329
  yield
282
- self.owner = oldowner
283
330
 
284
- if opts[:namespace]
285
- self.namespace = ns
286
- self.owner = namespace
287
- self.visibility = vis
288
- self.scope = sc
289
- end
331
+ self.namespace = ns
332
+ self.visibility = vis
333
+ self.scope = sc
334
+ self.owner = oo
290
335
  end
291
336
 
292
337
  # Do some post processing on a list of code objects.
@@ -324,6 +369,22 @@ module YARD
324
369
  object.docstring = statement.comments if statement.comments
325
370
  object.docstring.line_range = statement.comments_range
326
371
 
372
+ # Add group information
373
+ if statement.group
374
+ unless object.namespace.is_a?(Proxy)
375
+ object.namespace.groups |= [statement.group]
376
+ end
377
+ object.group = statement.group
378
+ end
379
+
380
+ # Add transitive tags
381
+ Tags::Library.transitive_tags.each do |tag|
382
+ next if object.namespace.is_a?(Proxy)
383
+ next unless object.namespace.has_tag?(tag)
384
+ next if object.has_tag?(tag)
385
+ object.docstring.add_tag(*object.namespace.tags(tag))
386
+ end
387
+
327
388
  # Add source only to non-class non-module objects
328
389
  unless object.is_a?(NamespaceObject)
329
390
  object.source ||= statement
@@ -336,6 +397,26 @@ module YARD
336
397
  objects.size == 1 ? objects.first : objects
337
398
  end
338
399
 
400
+ # Ensures that a specific +object+ has been parsed and loaded into the
401
+ # registry. This is necessary when adding data to a namespace, for instance,
402
+ # since the namespace may not have been processed yet (it can be located
403
+ # in a file that has not been handled).
404
+ #
405
+ # Calling this method defers the handler until all other files have been
406
+ # processed. If the object gets resolved, the rest of the handler continues,
407
+ # otherwise an exception is raised.
408
+ #
409
+ # @example Adding a mixin to the String class programmatically
410
+ # ensure_loaded! P('String')
411
+ # # "String" is now guaranteed to be loaded
412
+ # P('String').mixins << P('MyMixin')
413
+ #
414
+ # @param [Proxy, CodeObjects::Base] object the object to resolve.
415
+ # @param [Integer] max_retries the number of times to defer the handler
416
+ # before raising a +NamespaceMissingError+.
417
+ # @raise [NamespaceMissingError] if the object is not resolved within
418
+ # +max_retries+ attempts, this exception is raised and the handler
419
+ # finishes processing.
339
420
  def ensure_loaded!(object, max_retries = 1)
340
421
  return if object.root?
341
422
  unless parser.load_order_errors