yard 0.7.5 → 0.8.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 (339) hide show
  1. data/.yardopts +10 -2
  2. data/ChangeLog +1263 -38
  3. data/LEGAL +5 -5
  4. data/LICENSE +1 -1
  5. data/README.md +91 -82
  6. data/Rakefile +6 -6
  7. data/benchmarks/builtins_vs_eval.rb +1 -1
  8. data/benchmarks/erb_vs_erubis.rb +4 -4
  9. data/benchmarks/generation.rb +5 -5
  10. data/benchmarks/parsing.rb +2 -2
  11. data/benchmarks/registry_store_types.rb +48 -0
  12. data/bin/yard +9 -1
  13. data/bin/yardoc +9 -1
  14. data/bin/yri +10 -2
  15. data/docs/CodeObjects.md +10 -10
  16. data/docs/GettingStarted.md +85 -83
  17. data/docs/Handlers.md +21 -21
  18. data/docs/Overview.md +7 -7
  19. data/docs/Parser.md +30 -30
  20. data/docs/Tags.md +250 -554
  21. data/docs/TagsArch.md +123 -0
  22. data/docs/Templates.md +58 -80
  23. data/docs/WhatsNew.md +378 -133
  24. data/docs/templates/default/fulldoc/html/full_list_tag.erb +7 -0
  25. data/docs/templates/default/fulldoc/html/setup.rb +6 -0
  26. data/docs/templates/default/layout/html/setup.rb +8 -0
  27. data/docs/templates/default/layout/html/tag_list.erb +11 -0
  28. data/docs/templates/default/yard_tags/html/list.erb +18 -0
  29. data/docs/templates/default/yard_tags/html/setup.rb +27 -0
  30. data/docs/templates/plugin.rb +65 -0
  31. data/lib/yard.rb +1 -10
  32. data/lib/yard/autoload.rb +75 -27
  33. data/lib/yard/cli/command.rb +5 -2
  34. data/lib/yard/cli/command_parser.rb +3 -2
  35. data/lib/yard/cli/diff.rb +1 -1
  36. data/lib/yard/cli/i18n.rb +69 -0
  37. data/lib/yard/cli/list.rb +1 -1
  38. data/lib/yard/cli/server.rb +30 -7
  39. data/lib/yard/cli/stats.rb +5 -6
  40. data/lib/yard/cli/yardoc.rb +95 -45
  41. data/lib/yard/cli/yri.rb +24 -3
  42. data/lib/yard/code_objects/base.rb +35 -4
  43. data/lib/yard/code_objects/extra_file_object.rb +1 -1
  44. data/lib/yard/code_objects/macro_object.rb +56 -99
  45. data/lib/yard/code_objects/method_object.rb +44 -6
  46. data/lib/yard/config.rb +18 -8
  47. data/lib/yard/core_ext/symbol_hash.rb +1 -1
  48. data/lib/yard/docstring.rb +45 -85
  49. data/lib/yard/docstring_parser.rb +269 -0
  50. data/lib/yard/handlers/base.rb +129 -118
  51. data/lib/yard/handlers/c/alias_handler.rb +15 -0
  52. data/lib/yard/handlers/c/attribute_handler.rb +13 -0
  53. data/lib/yard/handlers/c/base.rb +110 -0
  54. data/lib/yard/handlers/c/class_handler.rb +26 -0
  55. data/lib/yard/handlers/c/constant_handler.rb +12 -0
  56. data/lib/yard/handlers/c/handler_methods.rb +165 -0
  57. data/lib/yard/handlers/c/init_handler.rb +16 -0
  58. data/lib/yard/handlers/c/method_handler.rb +35 -0
  59. data/lib/yard/handlers/c/mixin_handler.rb +13 -0
  60. data/lib/yard/handlers/c/module_handler.rb +16 -0
  61. data/lib/yard/handlers/c/override_comment_handler.rb +22 -0
  62. data/lib/yard/handlers/c/path_handler.rb +10 -0
  63. data/lib/yard/handlers/c/struct_handler.rb +12 -0
  64. data/lib/yard/handlers/c/symbol_handler.rb +7 -0
  65. data/lib/yard/handlers/processor.rb +41 -30
  66. data/lib/yard/handlers/ruby/alias_handler.rb +0 -2
  67. data/lib/yard/handlers/ruby/attribute_handler.rb +16 -17
  68. data/lib/yard/handlers/ruby/base.rb +10 -6
  69. data/lib/yard/handlers/ruby/comment_handler.rb +9 -0
  70. data/lib/yard/handlers/ruby/dsl_handler.rb +14 -0
  71. data/lib/yard/handlers/ruby/dsl_handler_methods.rb +71 -0
  72. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +0 -3
  73. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +16 -17
  74. data/lib/yard/handlers/ruby/legacy/base.rb +28 -6
  75. data/lib/yard/handlers/ruby/legacy/comment_handler.rb +9 -0
  76. data/lib/yard/handlers/ruby/legacy/dsl_handler.rb +16 -0
  77. data/lib/yard/handlers/ruby/legacy/method_handler.rb +0 -2
  78. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +1 -1
  79. data/lib/yard/handlers/ruby/legacy/module_function_handler.rb +18 -0
  80. data/lib/yard/handlers/ruby/method_handler.rb +10 -15
  81. data/lib/yard/handlers/ruby/mixin_handler.rb +1 -1
  82. data/lib/yard/handlers/ruby/module_function_handler.rb +26 -0
  83. data/lib/yard/handlers/ruby/struct_handler_methods.rb +3 -2
  84. data/lib/yard/i18n/pot_generator.rb +281 -0
  85. data/lib/yard/i18n/text.rb +72 -0
  86. data/lib/yard/logging.rb +3 -7
  87. data/lib/yard/options.rb +216 -0
  88. data/lib/yard/parser/c/c_parser.rb +225 -0
  89. data/lib/yard/parser/c/comment_parser.rb +131 -0
  90. data/lib/yard/parser/c/statement.rb +63 -0
  91. data/lib/yard/parser/ruby/ast_node.rb +91 -1
  92. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +1 -0
  93. data/lib/yard/parser/ruby/legacy/statement.rb +7 -2
  94. data/lib/yard/parser/ruby/legacy/statement_list.rb +13 -22
  95. data/lib/yard/parser/ruby/ruby_parser.rb +87 -26
  96. data/lib/yard/parser/source_parser.rb +89 -88
  97. data/lib/yard/rake/yardoc_task.rb +1 -1
  98. data/lib/yard/registry.rb +21 -10
  99. data/lib/yard/registry_store.rb +48 -0
  100. data/lib/yard/serializers/file_system_serializer.rb +18 -20
  101. data/lib/yard/serializers/yardoc_serializer.rb +1 -0
  102. data/lib/yard/server/adapter.rb +2 -2
  103. data/lib/yard/server/commands/base.rb +1 -1
  104. data/lib/yard/server/commands/display_object_command.rb +13 -6
  105. data/lib/yard/server/commands/frames_command.rb +4 -21
  106. data/lib/yard/server/commands/library_command.rb +57 -11
  107. data/lib/yard/server/commands/list_command.rb +10 -34
  108. data/lib/yard/server/commands/search_command.rb +8 -2
  109. data/lib/yard/server/doc_server_helper.rb +34 -0
  110. data/lib/yard/server/rack_adapter.rb +5 -1
  111. data/lib/yard/server/router.rb +4 -10
  112. data/lib/yard/server/static_caching.rb +2 -2
  113. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +2 -2
  114. data/lib/yard/server/templates/default/fulldoc/html/js/live.js +0 -15
  115. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +3 -3
  116. data/lib/yard/server/templates/default/layout/html/script_setup.erb +8 -0
  117. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +1 -1
  118. data/lib/yard/server/templates/doc_server/search/html/setup.rb +1 -1
  119. data/lib/yard/tags/default_factory.rb +31 -4
  120. data/lib/yard/tags/directives.rb +593 -0
  121. data/lib/yard/tags/library.rb +437 -35
  122. data/lib/yard/templates/engine.rb +17 -12
  123. data/lib/yard/templates/helpers/base_helper.rb +8 -2
  124. data/lib/yard/templates/helpers/html_helper.rb +57 -14
  125. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +1 -1
  126. data/lib/yard/templates/helpers/markup_helper.rb +9 -9
  127. data/lib/yard/templates/helpers/text_helper.rb +2 -2
  128. data/lib/yard/templates/template.rb +42 -13
  129. data/lib/yard/templates/template_options.rb +81 -0
  130. data/spec/cli/command_parser_spec.rb +4 -4
  131. data/spec/cli/command_spec.rb +3 -3
  132. data/spec/cli/config_spec.rb +13 -13
  133. data/spec/cli/diff_spec.rb +13 -10
  134. data/spec/cli/gems_spec.rb +12 -12
  135. data/spec/cli/help_spec.rb +2 -2
  136. data/spec/cli/i18n_spec.rb +111 -0
  137. data/spec/cli/server_spec.rb +66 -18
  138. data/spec/cli/stats_spec.rb +15 -15
  139. data/spec/cli/yardoc_spec.rb +124 -97
  140. data/spec/cli/yri_spec.rb +14 -12
  141. data/spec/code_objects/base_spec.rb +104 -46
  142. data/spec/code_objects/class_object_spec.rb +33 -33
  143. data/spec/code_objects/code_object_list_spec.rb +5 -5
  144. data/spec/code_objects/constants_spec.rb +4 -3
  145. data/spec/code_objects/extra_file_object_spec.rb +19 -19
  146. data/spec/code_objects/macro_object_spec.rb +31 -37
  147. data/spec/code_objects/method_object_spec.rb +46 -23
  148. data/spec/code_objects/module_object_spec.rb +16 -16
  149. data/spec/code_objects/namespace_object_spec.rb +6 -6
  150. data/spec/code_objects/proxy_spec.rb +19 -19
  151. data/spec/config_spec.rb +33 -24
  152. data/spec/core_ext/array_spec.rb +1 -1
  153. data/spec/core_ext/file_spec.rb +8 -8
  154. data/spec/core_ext/hash_spec.rb +1 -1
  155. data/spec/core_ext/insertion_spec.rb +3 -3
  156. data/spec/core_ext/module_spec.rb +1 -1
  157. data/spec/core_ext/string_spec.rb +6 -6
  158. data/spec/core_ext/symbol_hash_spec.rb +11 -11
  159. data/spec/docstring_parser_spec.rb +207 -0
  160. data/spec/docstring_spec.rb +33 -146
  161. data/spec/handlers/alias_handler_spec.rb +14 -14
  162. data/spec/handlers/attribute_handler_spec.rb +20 -20
  163. data/spec/handlers/base_spec.rb +16 -16
  164. data/spec/handlers/c/alias_handler_spec.rb +33 -0
  165. data/spec/handlers/c/attribute_handler_spec.rb +40 -0
  166. data/spec/handlers/c/class_handler_spec.rb +64 -0
  167. data/spec/handlers/c/constant_handler_spec.rb +68 -0
  168. data/spec/handlers/c/init_handler_spec.rb +36 -0
  169. data/spec/handlers/c/method_handler_spec.rb +228 -0
  170. data/spec/handlers/c/mixin_handler_spec.rb +27 -0
  171. data/spec/handlers/c/module_handler_spec.rb +38 -0
  172. data/spec/handlers/c/override_comment_handler_spec.rb +43 -0
  173. data/spec/handlers/c/path_handler_spec.rb +35 -0
  174. data/spec/handlers/c/spec_helper.rb +11 -0
  175. data/spec/handlers/c/struct_handler_spec.rb +15 -0
  176. data/spec/handlers/class_condition_handler_spec.rb +10 -10
  177. data/spec/handlers/class_handler_spec.rb +38 -38
  178. data/spec/handlers/class_variable_handler_spec.rb +1 -1
  179. data/spec/handlers/constant_handler_spec.rb +7 -7
  180. data/spec/handlers/{macro_handler_spec.rb → dsl_handler_spec.rb} +72 -53
  181. data/spec/handlers/examples/alias_handler_001.rb.txt +5 -5
  182. data/spec/handlers/examples/class_condition_handler_001.rb.txt +9 -9
  183. data/spec/handlers/examples/class_handler_001.rb.txt +1 -1
  184. data/spec/handlers/examples/dsl_handler_001.rb.txt +110 -0
  185. data/spec/handlers/examples/exception_handler_001.rb.txt +14 -14
  186. data/spec/handlers/examples/method_condition_handler_001.rb.txt +2 -2
  187. data/spec/handlers/examples/method_handler_001.rb.txt +16 -16
  188. data/spec/handlers/examples/mixin_handler_001.rb.txt +8 -4
  189. data/spec/handlers/examples/private_constant_handler_001.rb.txt +1 -1
  190. data/spec/handlers/examples/visibility_handler_001.rb.txt +3 -3
  191. data/spec/handlers/examples/yield_handler_001.rb.txt +13 -14
  192. data/spec/handlers/exception_handler_spec.rb +9 -9
  193. data/spec/handlers/extend_handler_spec.rb +2 -2
  194. data/spec/handlers/legacy_base_spec.rb +34 -34
  195. data/spec/handlers/method_condition_handler_spec.rb +2 -2
  196. data/spec/handlers/method_handler_spec.rb +33 -33
  197. data/spec/handlers/mixin_handler_spec.rb +13 -9
  198. data/spec/handlers/module_function_handler_spec.rb +82 -0
  199. data/spec/handlers/module_handler_spec.rb +6 -6
  200. data/spec/handlers/private_constant_handler_spec.rb +3 -3
  201. data/spec/handlers/processor_spec.rb +5 -5
  202. data/spec/handlers/ruby/base_spec.rb +10 -6
  203. data/spec/handlers/ruby/legacy/base_spec.rb +11 -7
  204. data/spec/handlers/spec_helper.rb +2 -3
  205. data/spec/handlers/visibility_handler_spec.rb +6 -6
  206. data/spec/handlers/yield_handler_spec.rb +8 -8
  207. data/spec/i18n/pot_generator_spec.rb +244 -0
  208. data/spec/i18n/text_spec.rb +69 -0
  209. data/spec/options_spec.rb +160 -0
  210. data/spec/parser/base_spec.rb +3 -3
  211. data/spec/parser/c_parser_spec.rb +31 -257
  212. data/spec/parser/examples/array.c.txt +187 -187
  213. data/spec/parser/examples/extrafile.c.txt +1 -1
  214. data/spec/parser/examples/override.c.txt +1 -1
  215. data/spec/parser/ruby/ast_node_spec.rb +1 -1
  216. data/spec/parser/ruby/legacy/statement_list_spec.rb +24 -24
  217. data/spec/parser/ruby/legacy/token_list_spec.rb +7 -7
  218. data/spec/parser/ruby/ruby_parser_spec.rb +56 -34
  219. data/spec/parser/source_parser_spec.rb +125 -65
  220. data/spec/parser/tag_parsing_spec.rb +4 -4
  221. data/spec/rake/yardoc_task_spec.rb +10 -8
  222. data/spec/registry_spec.rb +65 -36
  223. data/spec/registry_store_spec.rb +90 -40
  224. data/spec/serializers/file_system_serializer_spec.rb +12 -12
  225. data/spec/serializers/yardoc_serializer_spec.rb +2 -2
  226. data/spec/server/adapter_spec.rb +3 -3
  227. data/spec/server/commands/base_spec.rb +8 -8
  228. data/spec/server/commands/library_command_spec.rb +3 -3
  229. data/spec/server/commands/static_file_command_spec.rb +7 -7
  230. data/spec/server/doc_server_helper_spec.rb +1 -1
  231. data/spec/server/doc_server_serializer_spec.rb +6 -6
  232. data/spec/server/rack_adapter_spec.rb +3 -3
  233. data/spec/server/router_spec.rb +19 -19
  234. data/spec/server/static_caching_spec.rb +4 -4
  235. data/spec/spec_helper.rb +7 -7
  236. data/spec/tags/default_factory_spec.rb +24 -16
  237. data/spec/tags/directives_spec.rb +422 -0
  238. data/spec/tags/library_spec.rb +15 -4
  239. data/spec/tags/overload_tag_spec.rb +6 -6
  240. data/spec/tags/ref_tag_list_spec.rb +8 -8
  241. data/spec/templates/class_spec.rb +7 -7
  242. data/spec/templates/constant_spec.rb +7 -7
  243. data/spec/templates/engine_spec.rb +28 -36
  244. data/spec/templates/examples/class001.html +108 -108
  245. data/spec/templates/examples/class002.html +17 -17
  246. data/spec/templates/examples/constant001.txt +1 -1
  247. data/spec/templates/examples/method001.html +45 -45
  248. data/spec/templates/examples/method002.html +25 -25
  249. data/spec/templates/examples/method003.html +60 -60
  250. data/spec/templates/examples/method004.html +7 -7
  251. data/spec/templates/examples/method005.html +28 -28
  252. data/spec/templates/examples/module001.html +321 -321
  253. data/spec/templates/examples/module001.txt +1 -1
  254. data/spec/templates/examples/module002.html +130 -130
  255. data/spec/templates/examples/module003.html +74 -74
  256. data/spec/templates/examples/module004.html +388 -0
  257. data/spec/templates/helpers/base_helper_spec.rb +32 -32
  258. data/spec/templates/helpers/html_helper_spec.rb +87 -68
  259. data/spec/templates/helpers/html_syntax_highlight_helper_spec.rb +9 -9
  260. data/spec/templates/helpers/markup/rdoc_markup_spec.rb +16 -16
  261. data/spec/templates/helpers/markup_helper_spec.rb +31 -28
  262. data/spec/templates/helpers/method_helper_spec.rb +7 -7
  263. data/spec/templates/helpers/shared_signature_examples.rb +9 -7
  264. data/spec/templates/helpers/text_helper_spec.rb +3 -3
  265. data/spec/templates/method_spec.rb +13 -13
  266. data/spec/templates/module_spec.rb +70 -24
  267. data/spec/templates/onefile_spec.rb +32 -15
  268. data/spec/templates/section_spec.rb +23 -23
  269. data/spec/templates/spec_helper.rb +31 -1
  270. data/spec/templates/tag_spec.rb +5 -5
  271. data/spec/templates/template_spec.rb +54 -46
  272. data/spec/verifier_spec.rb +5 -5
  273. data/templates/default/class/setup.rb +2 -2
  274. data/templates/default/docstring/html/abstract.erb +1 -1
  275. data/templates/default/docstring/html/note.erb +1 -1
  276. data/templates/default/docstring/html/private.erb +1 -1
  277. data/templates/default/docstring/html/todo.erb +1 -1
  278. data/templates/default/docstring/setup.rb +2 -2
  279. data/templates/default/fulldoc/html/css/full_list.css +4 -2
  280. data/templates/default/fulldoc/html/css/style.css +50 -44
  281. data/templates/default/fulldoc/html/frames.erb +21 -6
  282. data/templates/default/fulldoc/html/full_list.erb +5 -3
  283. data/templates/default/fulldoc/html/{full_list_files.erb → full_list_file.erb} +0 -0
  284. data/templates/default/fulldoc/html/js/app.js +29 -26
  285. data/templates/default/fulldoc/html/js/full_list.js +9 -9
  286. data/templates/default/fulldoc/html/js/jquery.js +4 -16
  287. data/templates/default/fulldoc/html/setup.rb +42 -38
  288. data/templates/default/layout/dot/header.erb +1 -1
  289. data/templates/default/layout/html/breadcrumb.erb +6 -6
  290. data/templates/default/layout/html/files.erb +1 -1
  291. data/templates/default/layout/html/footer.erb +1 -1
  292. data/templates/default/layout/html/headers.erb +3 -6
  293. data/templates/default/layout/html/index.erb +1 -1
  294. data/templates/default/layout/html/layout.erb +3 -7
  295. data/templates/default/layout/html/objects.erb +1 -1
  296. data/templates/default/layout/html/script_setup.erb +5 -0
  297. data/templates/default/layout/html/search.erb +4 -1
  298. data/templates/default/layout/html/setup.rb +8 -8
  299. data/templates/default/method_details/html/method_signature.erb +10 -3
  300. data/templates/default/method_details/setup.rb +1 -0
  301. data/templates/default/module/dot/info.erb +1 -1
  302. data/templates/default/module/dot/setup.rb +2 -2
  303. data/templates/default/module/html/attribute_details.erb +1 -1
  304. data/templates/default/module/html/children.erb +1 -1
  305. data/templates/default/module/html/defines.erb +1 -1
  306. data/templates/default/module/html/inherited_methods.erb +5 -4
  307. data/templates/default/module/html/item_summary.erb +15 -5
  308. data/templates/default/module/html/method_details_list.erb +2 -2
  309. data/templates/default/module/setup.rb +25 -12
  310. data/templates/default/module/text/setup.rb +1 -1
  311. data/templates/default/onefile/html/layout.erb +1 -1
  312. data/templates/default/onefile/html/setup.rb +2 -2
  313. data/templates/default/tags/html/example.erb +4 -2
  314. data/templates/default/tags/html/option.erb +1 -1
  315. data/templates/default/tags/html/overload.erb +1 -1
  316. data/templates/default/tags/html/see.erb +1 -1
  317. data/templates/default/tags/html/tag.erb +1 -1
  318. data/templates/default/tags/setup.rb +4 -3
  319. data/templates/guide/fulldoc/html/css/style.css +8 -8
  320. data/templates/guide/fulldoc/html/js/app.js +6 -6
  321. data/templates/guide/fulldoc/html/setup.rb +12 -12
  322. data/templates/guide/layout/html/layout.erb +11 -11
  323. data/templates/guide/layout/html/setup.rb +9 -9
  324. data/templates/guide/method/html/header.erb +2 -2
  325. data/templates/guide/method/html/setup.rb +1 -1
  326. metadata +68 -18
  327. data/bin/yard-graph +0 -4
  328. data/bin/yard-server +0 -4
  329. data/docs/Glossary.md +0 -12
  330. data/lib/yard/handlers/ruby/legacy/macro_handler.rb +0 -39
  331. data/lib/yard/handlers/ruby/macro_handler.rb +0 -40
  332. data/lib/yard/handlers/ruby/macro_handler_methods.rb +0 -131
  333. data/lib/yard/parser/c_parser.rb +0 -497
  334. data/lib/yard/server/templates/default/layout/html/headers.erb +0 -16
  335. data/lib/yard/server/templates/doc_server/frames/html/frames.erb +0 -13
  336. data/lib/yard/server/templates/doc_server/frames/html/setup.rb +0 -3
  337. data/lib/yard/server/templates/doc_server/full_list/html/full_list.erb +0 -34
  338. data/lib/yard/server/templates/doc_server/full_list/html/setup.rb +0 -20
  339. data/spec/handlers/examples/macro_handler_001.rb.txt +0 -83
@@ -57,7 +57,7 @@ class SymbolHash < Hash
57
57
  # @return [Boolean] whether the key exists
58
58
  def has_key?(key) super(key.to_sym) end
59
59
 
60
- # Updates the object with the contents of another Hash object
60
+ # Updates the object with the contents of another Hash object.
61
61
  # This method modifies the original SymbolHash object
62
62
  #
63
63
  # @param [Hash] hash the hash object to copy the values from
@@ -30,13 +30,39 @@ module YARD
30
30
  def hash_flag=(v) @hash_flag = v == nil ? false : v end
31
31
 
32
32
  # Matches a tag at the start of a comment line
33
- META_MATCH = /^@([a-z_0-9]+)(?:\s+(.*))?$/i
33
+ # @deprecated Use {DocstringParser::META_MATCH}
34
+ META_MATCH = DocstringParser::META_MATCH
34
35
 
35
36
  # @group Creating a Docstring Object
36
37
 
38
+ # Creates a new docstring without performing any parsing through
39
+ # a {DocstringParser}. This method is called by +DocstringParser+
40
+ # when creating the new docstring object.
41
+ #
42
+ # @param [String] text the textual portion of the docstring
43
+ # @param [Array<Tag>] tags the list of tag objects in the docstring
44
+ # @param [CodeObjects::Base, nil] object the object associated with the
45
+ # docstring. May be nil.
46
+ # @param [String] raw_data the complete docstring, including all
47
+ # original formatting and any unparsed tags/directives.
48
+ def self.new!(text, tags = [], object = nil, raw_data = nil)
49
+ docstring = allocate
50
+ docstring.replace(text, false)
51
+ docstring.object = object
52
+ docstring.add_tag(*tags)
53
+ docstring.instance_variable_set("@all", raw_data) if raw_data
54
+ docstring
55
+ end
56
+
37
57
  # Creates a new docstring with the raw contents attached to an optional
38
- # object.
58
+ # object. Parsing will be done by the {DocstringParser} class.
39
59
  #
60
+ # @note To properly parse directives with proper parser context within
61
+ # handlers, you should not use this method to create a Docstring.
62
+ # Instead, use {DocstringParser}, which takes a handler object that
63
+ # can pass parser state onto directives. If a Docstring is created
64
+ # with this method, directives do not have access to any parser
65
+ # state, and may not function as expected.
40
66
  # @example
41
67
  # Docstring.new("hello world\n@return Object return", someobj)
42
68
  #
@@ -68,16 +94,16 @@ module YARD
68
94
 
69
95
  # Replaces the docstring with new raw content. Called by {#all=}.
70
96
  # @param [String] content the raw comments to be parsed
71
- def replace(content)
97
+ def replace(content, parse = true)
72
98
  content = content.join("\n") if content.is_a?(Array)
73
99
  @tags, @ref_tags = [], []
74
100
  @all = content
75
- super parse_comments(content)
101
+ super(parse ? parse_comments(content) : content)
76
102
  end
77
103
  alias all= replace
78
-
104
+
79
105
  # Deep-copies a docstring
80
- #
106
+ #
81
107
  # @note This method creates a new docstring with new tag lists, but does
82
108
  # not create new individual tags. Modifying the tag objects will still
83
109
  # affect the original tags.
@@ -124,10 +150,10 @@ module YARD
124
150
  @summary += '.' unless @summary.empty?
125
151
  @summary
126
152
  end
127
-
153
+
128
154
  # Reformats and returns a raw representation of the tag data using the
129
155
  # current tag and docstring data, not the original text.
130
- #
156
+ #
131
157
  # @return [String] the updated raw formatted docstring data
132
158
  # @since 0.7.0
133
159
  # @todo Add Tags::Tag#to_raw and refactor
@@ -153,33 +179,10 @@ module YARD
153
179
 
154
180
  # @group Creating and Accessing Meta-data
155
181
 
156
- # Creates a tag from the {Tags::DefaultFactory tag factory}.
157
- #
158
- # To add an already created tag object, use {#add_tag}
159
- #
160
- # @param [String] tag_name the tag name
161
- # @param [String] tag_buf the text attached to the tag with newlines removed.
162
- # @return [Tags::Tag, Tags::RefTag] a tag
163
- def create_tag(tag_name, tag_buf)
164
- if tag_buf =~ /\A\s*(?:(\S+)\s+)?\(\s*see\s+(\S+)\s*\)\s*\Z/
165
- return create_ref_tag(tag_name, $1, $2)
166
- end
167
-
168
- tag_factory = Tags::Library.instance
169
- tag_method = "#{tag_name}_tag"
170
- if tag_name && tag_factory.respond_to?(tag_method)
171
- add_tag(*[tag_factory.send(tag_method, tag_buf)].flatten)
172
- else
173
- log.warn "Unknown tag @#{tag_name}" + (object ? " in file `#{object.file}` near line #{object.line}" : "")
174
- end
175
- rescue Tags::TagFormatError
176
- log.warn "Invalid tag format for @#{tag_name}" + (object ? " in file `#{object.file}` near line #{object.line}" : "")
177
- end
178
-
179
182
  # Adds a tag or reftag object to the tag list. If you want to parse
180
- # tag data based on the {Tags::DefaultFactory} tag factory, use {#create_tag}
181
- # instead.
182
- #
183
+ # tag data based on the {Tags::DefaultFactory} tag factory, use
184
+ # {DocstringParser} instead.
185
+ #
183
186
  # @param [Tags::Tag, Tags::RefTag] tags list of tag objects to add
184
187
  # @return [void]
185
188
  def add_tag(*tags)
@@ -188,7 +191,7 @@ module YARD
188
191
  when Tags::Tag
189
192
  tag.object = object
190
193
  @tags << tag
191
- when Tags::RefTag
194
+ when Tags::RefTag, Tags::RefTagList
192
195
  @ref_tags << tag
193
196
  else
194
197
  raise ArgumentError, "expected Tag or RefTag, got #{tag.class} (at index #{i})"
@@ -226,7 +229,7 @@ module YARD
226
229
  def has_tag?(name)
227
230
  tags.any? {|tag| tag.tag_name.to_s == name.to_s }
228
231
  end
229
-
232
+
230
233
  # Delete all tags with +name+
231
234
  # @param [String] name the tag name
232
235
  # @return [void]
@@ -234,10 +237,10 @@ module YARD
234
237
  def delete_tags(name)
235
238
  delete_tag_if {|tag| tag.tag_name.to_s == name.to_s }
236
239
  end
237
-
240
+
238
241
  # Deletes all tags where the block returns true
239
242
  # @yieldparam [Tags::Tag] tag the tag that is being tested
240
- # @yieldreturn [Boolean] true if the tag should be deleted
243
+ # @yieldreturn [Boolean] true if the tag should be deleted
241
244
  # @return [void]
242
245
  # @since 0.7.0
243
246
  def delete_tag_if(&block)
@@ -270,11 +273,6 @@ module YARD
270
273
  list.map {|t| t.tags }.flatten
271
274
  end
272
275
 
273
- # Creates a {Tags::RefTag}
274
- def create_ref_tag(tag_name, name, object_name)
275
- @ref_tags << Tags::RefTagList.new(tag_name, P(object, object_name), name)
276
- end
277
-
278
276
  # Parses out comments split by newlines into a new code object
279
277
  #
280
278
  # @param [String] comments
@@ -284,48 +282,10 @@ module YARD
284
282
  # @return [String] the non-metadata portion of the comments to
285
283
  # be used as a docstring
286
284
  def parse_comments(comments)
287
- comments = comments.split(/\r?\n/) if comments.is_a?(String)
288
- return '' if !comments || comments.empty?
289
- docstring = ""
290
-
291
- indent, last_indent = comments.first[/^\s*/].length, 0
292
- orig_indent = 0
293
- last_line = ""
294
- tag_name, tag_klass, tag_buf = nil, nil, []
295
-
296
- (comments+['']).each_with_index do |line, index|
297
- indent = line[/^\s*/].length
298
- empty = (line =~ /^\s*$/ ? true : false)
299
- done = comments.size == index
300
-
301
- if tag_name && (((indent < orig_indent && !empty) || done ||
302
- (indent == 0 && !empty)) || (indent <= last_indent && line =~ META_MATCH))
303
- create_tag(tag_name, tag_buf.join("\n"))
304
- tag_name, tag_buf, = nil, []
305
- orig_indent = 0
306
- end
307
-
308
- # Found a meta tag
309
- if line =~ META_MATCH
310
- tag_name, tag_buf = $1, [($2 || '')]
311
- elsif tag_name && indent >= orig_indent && !empty
312
- orig_indent = indent if orig_indent == 0
313
- # Extra data added to the tag on the next line
314
- last_empty = last_line =~ /^[ \t]*$/ ? true : false
315
-
316
- tag_buf << '' if last_empty
317
- tag_buf << line.gsub(/^[ \t]{#{orig_indent}}/, '')
318
- elsif !tag_name
319
- # Regular docstring text
320
- docstring << line << "\n"
321
- end
322
-
323
- last_indent = indent
324
- last_line = line
325
- end
326
-
327
- # Remove trailing/leading whitespace / newlines
328
- docstring.gsub!(/\A[\r\n\s]+|[\r\n\s]+\Z/, '')
285
+ parser = DocstringParser.new
286
+ parser.parse(comments, object)
287
+ add_tag(*parser.tags)
288
+ parser.text
329
289
  end
330
290
  end
331
291
  end
@@ -0,0 +1,269 @@
1
+ require 'ostruct'
2
+
3
+ module YARD
4
+ # Parses text and creates a {Docstring} object to represent documentation
5
+ # for a {CodeObjects::Base}. To create a new docstring, you should initialize
6
+ # the parser and call {#parse} followed by {#to_docstring}.
7
+ #
8
+ # @example Creating a Docstring with a DocstringParser
9
+ # DocstringParser.new.parse("text here").to_docstring
10
+ # @since 0.8.0
11
+ class DocstringParser
12
+ # Creates a callback that is called after a docstring is successfully
13
+ # parsed. Use this method to perform sanity checks on a docstring's
14
+ # tag data, or add any extra tags automatically to a docstring.
15
+ #
16
+ # @yield [parser] a block to be called after a docstring is parsed
17
+ # @yieldparam [DocstringParser] parser the docstring parser object
18
+ # with all directives and tags created.
19
+ # @yieldreturn [void]
20
+ # @return [void]
21
+ def self.after_parse(&block)
22
+ self.after_parse_callbacks << block
23
+ end
24
+
25
+ # @return [Array<Proc>] the {#after_parse} callback proc objects
26
+ # @private
27
+ def self.after_parse_callbacks
28
+ @after_parse_callbacks ||= []
29
+ end
30
+
31
+ # @return [String] the parsed text portion of the docstring,
32
+ # with tags removed.
33
+ attr_reader :text
34
+
35
+ # @return [String] the complete input string to the parser.
36
+ attr_reader :raw_text
37
+
38
+ # @return [Array<Tag>] the list of meta-data tags identified
39
+ # by the parser
40
+ attr_reader :tags
41
+
42
+ # @return [Array<Directive>] a list of directives identified
43
+ # by the parser. This list will not be passed on to the
44
+ # Docstring object.
45
+ attr_reader :directives
46
+
47
+ # @return [OpenStruct] any arbitrary state to be passed between
48
+ # tags during parsing. Mainly used by directives to coordinate
49
+ # behaviour (so that directives can be aware of other directives
50
+ # used in a docstring).
51
+ attr_reader :state
52
+
53
+ # @return [CodeObjects::Base, nil] the object associated with
54
+ # the docstring being parsed. May be nil if the docstring is
55
+ # not attached to any object.
56
+ attr_accessor :object
57
+
58
+ # @return [Handlers::Base, nil] the handler parsing this
59
+ # docstring. May be nil if this docstring parser is not
60
+ # initialized through
61
+ attr_accessor :handler
62
+
63
+ # @return [Tags::Library] the tag library being used to
64
+ # identify registered tags in the docstring.
65
+ attr_accessor :library
66
+
67
+ # The regular expression to match the tag syntax
68
+ META_MATCH = /^@(!)?((?:\w\.?)+)(?:\s+(.*))?$/i
69
+
70
+ # Creates a new parser to parse docstring data
71
+ #
72
+ # @param [Tags::Library] library a tag library for recognizing
73
+ # tags.
74
+ def initialize(library = Tags::Library.instance)
75
+ @text = ""
76
+ @raw_text = ""
77
+ @tags = []
78
+ @directives = []
79
+ @library = library
80
+ @object = nil
81
+ @handler = nil
82
+ @state = OpenStruct.new
83
+ end
84
+
85
+ # Parses all content and returns itself.
86
+ #
87
+ # @param [String] content the docstring text to parse
88
+ # @param [CodeObjects::Base] object the object that the docstring
89
+ # is attached to. Will be passed to directives to act on
90
+ # this object.
91
+ # @param [Handlers::Base, nil] handler the handler object that is
92
+ # parsing this object. May be nil if this parser is not being
93
+ # called from a {Parser::SourceParser} context.
94
+ # @return [self] the parser object. To get the docstring,
95
+ # call {#to_docstring}.
96
+ # @see #to_docstring
97
+ def parse(content, object = nil, handler = nil)
98
+ @object = object
99
+ @handler = handler
100
+ @raw_text = content
101
+ text = parse_content(content)
102
+ # Remove trailing/leading whitespace / newlines
103
+ @text = text.gsub(/\A[\r\n\s]+|[\r\n\s]+\Z/, '')
104
+ call_directives_after_parse
105
+ call_after_parse_callbacks
106
+ self
107
+ end
108
+
109
+ # @return [Docstring] translates parsed text into
110
+ # a Docstring object.
111
+ def to_docstring
112
+ Docstring.new!(text, tags, object, raw_text)
113
+ end
114
+
115
+ private
116
+
117
+ # Parses all text and tags
118
+ def parse_content(content)
119
+ content = content.split(/\r?\n/) if content.is_a?(String)
120
+ return '' if !content || content.empty?
121
+ docstring = ""
122
+
123
+ indent, last_indent = content.first[/^\s*/].length, 0
124
+ orig_indent = 0
125
+ directive = false
126
+ last_line = ""
127
+ tag_name, tag_klass, tag_buf = nil, nil, []
128
+
129
+ (content+['']).each_with_index do |line, index|
130
+ indent = line[/^\s*/].length
131
+ empty = (line =~ /^\s*$/ ? true : false)
132
+ done = content.size == index
133
+
134
+ if tag_name && (((indent < orig_indent && !empty) || done ||
135
+ (indent == 0 && !empty)) || (indent <= last_indent && line =~ META_MATCH))
136
+ buf = tag_buf.join("\n")
137
+ if directive || tag_is_directive?(tag_name)
138
+ directive = create_directive(tag_name, buf)
139
+ if directive
140
+ docstring << parse_content(directive.expanded_text).chomp
141
+ end
142
+ else
143
+ create_tag(tag_name, buf)
144
+ end
145
+ tag_name, tag_buf, directive = nil, [], false
146
+ orig_indent = 0
147
+ end
148
+
149
+ # Found a meta tag
150
+ if line =~ META_MATCH
151
+ directive, tag_name, tag_buf = $1, $2, [($3 || '')]
152
+ elsif tag_name && indent >= orig_indent && !empty
153
+ orig_indent = indent if orig_indent == 0
154
+ # Extra data added to the tag on the next line
155
+ last_empty = last_line =~ /^[ \t]*$/ ? true : false
156
+
157
+ tag_buf << '' if last_empty
158
+ tag_buf << line.gsub(/^[ \t]{#{orig_indent}}/, '')
159
+ elsif !tag_name
160
+ # Regular docstring text
161
+ docstring << line << "\n"
162
+ end
163
+
164
+ last_indent = indent
165
+ last_line = line
166
+ end
167
+
168
+ docstring
169
+ end
170
+
171
+ private
172
+
173
+ # Creates a tag from the {Tags::DefaultFactory tag factory}.
174
+ #
175
+ # To add an already created tag object, use {#add_tag}
176
+ #
177
+ # @param [String] tag_name the tag name
178
+ # @param [String] tag_buf the text attached to the tag with newlines removed.
179
+ # @return [Tags::Tag, Tags::RefTag] a tag
180
+ def create_tag(tag_name, tag_buf)
181
+ if tag_buf =~ /\A\s*(?:(\S+)\s+)?\(\s*see\s+(\S+)\s*\)\s*\Z/
182
+ return create_ref_tag(tag_name, $1, $2)
183
+ end
184
+
185
+ if library.has_tag?(tag_name)
186
+ @tags += [library.tag_create(tag_name, tag_buf)].flatten
187
+ else
188
+ log.warn "Unknown tag @#{tag_name}" +
189
+ (object ? " in file `#{object.file}` near line #{object.line}" : "")
190
+ end
191
+ rescue Tags::TagFormatError
192
+ log.warn "Invalid tag format for @#{tag_name}" +
193
+ (object ? " in file `#{object.file}` near line #{object.line}" : "")
194
+ end
195
+
196
+ # Creates a {Tags::RefTag}
197
+ def create_ref_tag(tag_name, name, object_name)
198
+ @tags << Tags::RefTagList.new(tag_name, P(object, object_name), name)
199
+ end
200
+
201
+ # Creates a new directive using the registered {#library}
202
+ # @return [Directive] the directive object that is created
203
+ def create_directive(tag_name, tag_buf)
204
+ if library.has_directive?(tag_name)
205
+ dir = library.directive_create(tag_name, tag_buf, self)
206
+ if dir.is_a?(Tags::Directive)
207
+ @directives << dir
208
+ dir
209
+ end
210
+ else
211
+ log.warn "Unknown directive @!#{tag_name}" +
212
+ (object ? " in file `#{object.file}` near line #{object.line}" : "")
213
+ nil
214
+ end
215
+ rescue Tags::TagFormatError
216
+ log.warn "Invalid directive format for @!#{tag_name}" +
217
+ (object ? " in file `#{object.file}` near line #{object.line}" : "")
218
+ nil
219
+ end
220
+
221
+ # Calls the {Directive#after_parse} callback on all the
222
+ # created directives.
223
+ def call_directives_after_parse
224
+ directives.each do |dir|
225
+ dir.after_parse
226
+ end
227
+ end
228
+
229
+ # Backward compatibility to detect old tags that should be specified
230
+ # as directives in 0.8 and onward.
231
+ def tag_is_directive?(tag_name)
232
+ list = %w(attribute endgroup group macro method scope visibility)
233
+ list.include?(tag_name)
234
+ end
235
+
236
+ # Calls all {after_parse} callbacks
237
+ def call_after_parse_callbacks
238
+ self.class.after_parse_callbacks.each do |cb|
239
+ cb.call(self)
240
+ end
241
+ end
242
+
243
+ # Define a callback to check that @param tags are properly named
244
+ after_parse do |parser|
245
+ next unless parser.object
246
+ next unless parser.object.is_a?(CodeObjects::MethodObject)
247
+ next if parser.object.parameters.empty? # method has no params or
248
+ # YARD couldn't detect any.
249
+ # but don't warn user (?)
250
+ names = parser.object.parameters.map {|l| l.first.gsub(/\W/, '') }
251
+ seen_names = []
252
+ infile_info = "\n in file `#{parser.object.file}' " +
253
+ "near line #{parser.object.line}"
254
+ parser.tags.each do |tag|
255
+ next if tag.is_a?(Tags::RefTagList) # we don't handle this yet
256
+ next unless tag.tag_name == "param"
257
+ if names.include?(tag.name)
258
+ seen_names << tag.name
259
+ elsif seen_names.include?(tag.name)
260
+ log.warn "@param tag has duplicate parameter name: " +
261
+ "#{tag.name} #{infile_info}"
262
+ else
263
+ log.warn "@param tag has unknown parameter name: " +
264
+ "#{tag.name} #{infile_info}"
265
+ end
266
+ end
267
+ end
268
+ end
269
+ end