yard 0.9.16 → 0.9.17

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 (566) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +26 -26
  3. data/CHANGELOG.md +728 -728
  4. data/LEGAL +66 -66
  5. data/LICENSE +22 -22
  6. data/README.md +328 -328
  7. data/Rakefile +53 -47
  8. data/benchmarks/builtins_vs_eval.rb +24 -24
  9. data/benchmarks/concat_vs_join.rb +13 -13
  10. data/benchmarks/erb_vs_erubis.rb +54 -54
  11. data/benchmarks/format_args.rb +47 -47
  12. data/benchmarks/generation.rb +38 -38
  13. data/benchmarks/marshal_vs_dbm.rb +64 -64
  14. data/benchmarks/parsing.rb +46 -46
  15. data/benchmarks/pathname_vs_string.rb +50 -50
  16. data/benchmarks/rdoc_vs_yardoc.rb +11 -11
  17. data/benchmarks/registry_store_types.rb +49 -49
  18. data/benchmarks/ri_vs_yri.rb +19 -19
  19. data/benchmarks/ripper_parser.rb +13 -13
  20. data/benchmarks/splat_vs_flatten.rb +13 -13
  21. data/benchmarks/template_erb.rb +23 -23
  22. data/benchmarks/template_format.rb +7 -7
  23. data/benchmarks/template_profile.rb +18 -18
  24. data/benchmarks/yri_cache.rb +20 -20
  25. data/bin/yard +13 -13
  26. data/bin/yardoc +13 -13
  27. data/bin/yri +13 -13
  28. data/docs/CodeObjects.md +115 -115
  29. data/docs/GettingStarted.md +679 -679
  30. data/docs/Handlers.md +152 -152
  31. data/docs/Overview.md +61 -61
  32. data/docs/Parser.md +191 -191
  33. data/docs/Tags.md +283 -283
  34. data/docs/TagsArch.md +123 -123
  35. data/docs/Templates.md +496 -496
  36. data/docs/WhatsNew.md +1245 -1245
  37. data/docs/templates/default/fulldoc/html/full_list_tag.erb +8 -8
  38. data/docs/templates/default/fulldoc/html/setup.rb +6 -6
  39. data/docs/templates/default/layout/html/setup.rb +9 -9
  40. data/docs/templates/default/layout/html/tag_list.erb +11 -11
  41. data/docs/templates/default/yard_tags/html/list.erb +18 -18
  42. data/docs/templates/default/yard_tags/html/setup.rb +26 -26
  43. data/docs/templates/plugin.rb +70 -70
  44. data/lib/rubygems_plugin.rb +9 -9
  45. data/lib/yard.rb +69 -69
  46. data/lib/yard/autoload.rb +303 -303
  47. data/lib/yard/cli/command.rb +85 -85
  48. data/lib/yard/cli/command_parser.rb +93 -93
  49. data/lib/yard/cli/config.rb +198 -198
  50. data/lib/yard/cli/diff.rb +270 -270
  51. data/lib/yard/cli/display.rb +69 -69
  52. data/lib/yard/cli/gems.rb +84 -84
  53. data/lib/yard/cli/graph.rb +125 -125
  54. data/lib/yard/cli/help.rb +20 -20
  55. data/lib/yard/cli/i18n.rb +70 -70
  56. data/lib/yard/cli/list.rb +23 -23
  57. data/lib/yard/cli/markup_types.rb +32 -32
  58. data/lib/yard/cli/server.rb +257 -257
  59. data/lib/yard/cli/stats.rb +231 -231
  60. data/lib/yard/cli/yardoc.rb +788 -788
  61. data/lib/yard/cli/yardopts_command.rb +110 -110
  62. data/lib/yard/cli/yri.rb +215 -215
  63. data/lib/yard/code_objects/base.rb +615 -610
  64. data/lib/yard/code_objects/class_object.rb +146 -146
  65. data/lib/yard/code_objects/class_variable_object.rb +11 -11
  66. data/lib/yard/code_objects/constant_object.rb +16 -16
  67. data/lib/yard/code_objects/extended_method_object.rb +24 -24
  68. data/lib/yard/code_objects/extra_file_object.rb +131 -131
  69. data/lib/yard/code_objects/macro_object.rb +172 -172
  70. data/lib/yard/code_objects/method_object.rb +196 -196
  71. data/lib/yard/code_objects/module_object.rb +21 -21
  72. data/lib/yard/code_objects/namespace_mapper.rb +114 -114
  73. data/lib/yard/code_objects/namespace_object.rb +200 -200
  74. data/lib/yard/code_objects/proxy.rb +240 -240
  75. data/lib/yard/code_objects/root_object.rb +19 -19
  76. data/lib/yard/config.rb +270 -270
  77. data/lib/yard/core_ext/array.rb +16 -16
  78. data/lib/yard/core_ext/file.rb +69 -69
  79. data/lib/yard/core_ext/hash.rb +16 -16
  80. data/lib/yard/core_ext/insertion.rb +63 -63
  81. data/lib/yard/core_ext/module.rb +20 -20
  82. data/lib/yard/core_ext/string.rb +68 -68
  83. data/lib/yard/core_ext/symbol_hash.rb +75 -75
  84. data/lib/yard/docstring.rb +386 -378
  85. data/lib/yard/docstring_parser.rb +345 -345
  86. data/lib/yard/gem_index.rb +29 -29
  87. data/lib/yard/globals.rb +22 -22
  88. data/lib/yard/handlers/base.rb +595 -595
  89. data/lib/yard/handlers/c/alias_handler.rb +16 -16
  90. data/lib/yard/handlers/c/attribute_handler.rb +13 -13
  91. data/lib/yard/handlers/c/base.rb +129 -129
  92. data/lib/yard/handlers/c/class_handler.rb +27 -27
  93. data/lib/yard/handlers/c/constant_handler.rb +13 -13
  94. data/lib/yard/handlers/c/handler_methods.rb +211 -211
  95. data/lib/yard/handlers/c/init_handler.rb +20 -20
  96. data/lib/yard/handlers/c/method_handler.rb +45 -36
  97. data/lib/yard/handlers/c/mixin_handler.rb +21 -21
  98. data/lib/yard/handlers/c/module_handler.rb +17 -17
  99. data/lib/yard/handlers/c/override_comment_handler.rb +31 -31
  100. data/lib/yard/handlers/c/path_handler.rb +11 -11
  101. data/lib/yard/handlers/c/struct_handler.rb +13 -13
  102. data/lib/yard/handlers/c/symbol_handler.rb +8 -8
  103. data/lib/yard/handlers/processor.rb +200 -200
  104. data/lib/yard/handlers/ruby/alias_handler.rb +44 -44
  105. data/lib/yard/handlers/ruby/attribute_handler.rb +87 -87
  106. data/lib/yard/handlers/ruby/base.rb +165 -165
  107. data/lib/yard/handlers/ruby/class_condition_handler.rb +92 -92
  108. data/lib/yard/handlers/ruby/class_handler.rb +119 -119
  109. data/lib/yard/handlers/ruby/class_variable_handler.rb +17 -17
  110. data/lib/yard/handlers/ruby/comment_handler.rb +10 -10
  111. data/lib/yard/handlers/ruby/constant_handler.rb +59 -59
  112. data/lib/yard/handlers/ruby/decorator_handler_methods.rb +123 -123
  113. data/lib/yard/handlers/ruby/dsl_handler.rb +15 -15
  114. data/lib/yard/handlers/ruby/dsl_handler_methods.rb +96 -95
  115. data/lib/yard/handlers/ruby/exception_handler.rb +27 -27
  116. data/lib/yard/handlers/ruby/extend_handler.rb +22 -22
  117. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +37 -37
  118. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +65 -65
  119. data/lib/yard/handlers/ruby/legacy/base.rb +245 -245
  120. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +83 -83
  121. data/lib/yard/handlers/ruby/legacy/class_handler.rb +113 -113
  122. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +15 -15
  123. data/lib/yard/handlers/ruby/legacy/comment_handler.rb +10 -10
  124. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +29 -29
  125. data/lib/yard/handlers/ruby/legacy/dsl_handler.rb +17 -17
  126. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +13 -13
  127. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +21 -21
  128. data/lib/yard/handlers/ruby/legacy/method_handler.rb +90 -90
  129. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +39 -39
  130. data/lib/yard/handlers/ruby/legacy/module_function_handler.rb +19 -19
  131. data/lib/yard/handlers/ruby/legacy/module_handler.rb +12 -12
  132. data/lib/yard/handlers/ruby/legacy/private_class_method_handler.rb +22 -22
  133. data/lib/yard/handlers/ruby/legacy/private_constant_handler.rb +22 -22
  134. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +17 -17
  135. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +29 -29
  136. data/lib/yard/handlers/ruby/method_condition_handler.rb +9 -9
  137. data/lib/yard/handlers/ruby/method_handler.rb +118 -118
  138. data/lib/yard/handlers/ruby/mixin_handler.rb +37 -37
  139. data/lib/yard/handlers/ruby/module_function_handler.rb +27 -27
  140. data/lib/yard/handlers/ruby/module_handler.rb +12 -12
  141. data/lib/yard/handlers/ruby/private_class_method_handler.rb +14 -14
  142. data/lib/yard/handlers/ruby/private_constant_handler.rb +43 -43
  143. data/lib/yard/handlers/ruby/public_class_method_handler.rb +14 -14
  144. data/lib/yard/handlers/ruby/struct_handler_methods.rb +143 -143
  145. data/lib/yard/handlers/ruby/visibility_handler.rb +22 -22
  146. data/lib/yard/handlers/ruby/yield_handler.rb +31 -31
  147. data/lib/yard/i18n/locale.rb +67 -67
  148. data/lib/yard/i18n/message.rb +57 -57
  149. data/lib/yard/i18n/messages.rb +56 -56
  150. data/lib/yard/i18n/po_parser.rb +61 -61
  151. data/lib/yard/i18n/pot_generator.rb +290 -290
  152. data/lib/yard/i18n/text.rb +173 -173
  153. data/lib/yard/logging.rb +205 -205
  154. data/lib/yard/options.rb +217 -217
  155. data/lib/yard/parser/base.rb +57 -57
  156. data/lib/yard/parser/c/c_parser.rb +235 -235
  157. data/lib/yard/parser/c/comment_parser.rb +134 -134
  158. data/lib/yard/parser/c/statement.rb +64 -64
  159. data/lib/yard/parser/ruby/ast_node.rb +540 -540
  160. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +1354 -1354
  161. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +32 -32
  162. data/lib/yard/parser/ruby/legacy/statement.rb +66 -66
  163. data/lib/yard/parser/ruby/legacy/statement_list.rb +394 -394
  164. data/lib/yard/parser/ruby/legacy/token_list.rb +74 -74
  165. data/lib/yard/parser/ruby/ruby_parser.rb +687 -687
  166. data/lib/yard/parser/ruby/token_resolver.rb +156 -156
  167. data/lib/yard/parser/source_parser.rb +526 -526
  168. data/lib/yard/rake/yardoc_task.rb +81 -81
  169. data/lib/yard/registry.rb +439 -439
  170. data/lib/yard/registry_resolver.rb +189 -189
  171. data/lib/yard/registry_store.rb +337 -337
  172. data/lib/yard/rubygems/backports.rb +10 -10
  173. data/lib/yard/rubygems/backports/LICENSE.txt +57 -57
  174. data/lib/yard/rubygems/backports/MIT.txt +20 -20
  175. data/lib/yard/rubygems/backports/gem.rb +10 -10
  176. data/lib/yard/rubygems/backports/source_index.rb +365 -365
  177. data/lib/yard/rubygems/doc_manager.rb +90 -90
  178. data/lib/yard/rubygems/hook.rb +197 -197
  179. data/lib/yard/rubygems/specification.rb +50 -50
  180. data/lib/yard/serializers/base.rb +83 -83
  181. data/lib/yard/serializers/file_system_serializer.rb +123 -123
  182. data/lib/yard/serializers/process_serializer.rb +24 -24
  183. data/lib/yard/serializers/stdout_serializer.rb +34 -34
  184. data/lib/yard/serializers/yardoc_serializer.rb +152 -152
  185. data/lib/yard/server.rb +13 -13
  186. data/lib/yard/server/adapter.rb +100 -100
  187. data/lib/yard/server/commands/base.rb +209 -209
  188. data/lib/yard/server/commands/display_file_command.rb +29 -29
  189. data/lib/yard/server/commands/display_object_command.rb +65 -65
  190. data/lib/yard/server/commands/frames_command.rb +16 -16
  191. data/lib/yard/server/commands/library_command.rb +187 -187
  192. data/lib/yard/server/commands/library_index_command.rb +28 -28
  193. data/lib/yard/server/commands/list_command.rb +25 -25
  194. data/lib/yard/server/commands/root_request_command.rb +15 -15
  195. data/lib/yard/server/commands/search_command.rb +79 -79
  196. data/lib/yard/server/commands/static_file_command.rb +23 -23
  197. data/lib/yard/server/commands/static_file_helpers.rb +62 -62
  198. data/lib/yard/server/doc_server_helper.rb +91 -91
  199. data/lib/yard/server/doc_server_serializer.rb +39 -39
  200. data/lib/yard/server/library_version.rb +277 -277
  201. data/lib/yard/server/rack_adapter.rb +89 -89
  202. data/lib/yard/server/router.rb +187 -187
  203. data/lib/yard/server/static_caching.rb +46 -46
  204. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +127 -127
  205. data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +11 -11
  206. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +37 -37
  207. data/lib/yard/server/templates/default/layout/html/script_setup.erb +7 -7
  208. data/lib/yard/server/templates/default/layout/html/setup.rb +8 -8
  209. data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -4
  210. data/lib/yard/server/templates/default/method_details/html/setup.rb +5 -5
  211. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +8 -8
  212. data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +14 -14
  213. data/lib/yard/server/templates/doc_server/library_list/html/listing.erb +13 -13
  214. data/lib/yard/server/templates/doc_server/library_list/html/setup.rb +6 -6
  215. data/lib/yard/server/templates/doc_server/library_list/html/title.erb +2 -2
  216. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +52 -52
  217. data/lib/yard/server/templates/doc_server/processing/html/setup.rb +4 -4
  218. data/lib/yard/server/templates/doc_server/search/html/search.erb +18 -18
  219. data/lib/yard/server/templates/doc_server/search/html/setup.rb +9 -9
  220. data/lib/yard/server/webrick_adapter.rb +45 -45
  221. data/lib/yard/tags/default_factory.rb +191 -191
  222. data/lib/yard/tags/default_tag.rb +13 -13
  223. data/lib/yard/tags/directives.rb +616 -616
  224. data/lib/yard/tags/library.rb +633 -633
  225. data/lib/yard/tags/option_tag.rb +13 -13
  226. data/lib/yard/tags/overload_tag.rb +71 -71
  227. data/lib/yard/tags/ref_tag.rb +8 -8
  228. data/lib/yard/tags/ref_tag_list.rb +28 -28
  229. data/lib/yard/tags/tag.rb +71 -71
  230. data/lib/yard/tags/tag_format_error.rb +7 -7
  231. data/lib/yard/tags/types_explainer.rb +162 -162
  232. data/lib/yard/templates/engine.rb +186 -186
  233. data/lib/yard/templates/erb_cache.rb +23 -23
  234. data/lib/yard/templates/helpers/base_helper.rb +215 -215
  235. data/lib/yard/templates/helpers/filter_helper.rb +27 -27
  236. data/lib/yard/templates/helpers/html_helper.rb +646 -642
  237. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +78 -78
  238. data/lib/yard/templates/helpers/markup/rdoc_markdown.rb +23 -23
  239. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +109 -109
  240. data/lib/yard/templates/helpers/markup_helper.rb +172 -172
  241. data/lib/yard/templates/helpers/method_helper.rb +75 -75
  242. data/lib/yard/templates/helpers/module_helper.rb +21 -21
  243. data/lib/yard/templates/helpers/text_helper.rb +112 -112
  244. data/lib/yard/templates/helpers/uml_helper.rb +47 -47
  245. data/lib/yard/templates/section.rb +105 -105
  246. data/lib/yard/templates/template.rb +418 -418
  247. data/lib/yard/templates/template_options.rb +92 -92
  248. data/lib/yard/verifier.rb +151 -151
  249. data/lib/yard/version.rb +3 -1
  250. data/spec/cli/command_parser_spec.rb +43 -43
  251. data/spec/cli/command_spec.rb +36 -36
  252. data/spec/cli/config_spec.rb +148 -148
  253. data/spec/cli/diff_spec.rb +254 -254
  254. data/spec/cli/display_spec.rb +30 -30
  255. data/spec/cli/gems_spec.rb +81 -81
  256. data/spec/cli/graph_spec.rb +18 -18
  257. data/spec/cli/help_spec.rb +22 -22
  258. data/spec/cli/i18n_spec.rb +107 -107
  259. data/spec/cli/list_spec.rb +8 -8
  260. data/spec/cli/markup_types_spec.rb +22 -22
  261. data/spec/cli/server_spec.rb +324 -324
  262. data/spec/cli/stats_spec.rb +96 -96
  263. data/spec/cli/yard_on_yard_spec.rb +38 -38
  264. data/spec/cli/yardoc_spec.rb +862 -849
  265. data/spec/cli/yri_spec.rb +101 -101
  266. data/spec/code_objects/base_spec.rb +470 -460
  267. data/spec/code_objects/class_object_spec.rb +226 -226
  268. data/spec/code_objects/code_object_list_spec.rb +36 -36
  269. data/spec/code_objects/constants_spec.rb +116 -116
  270. data/spec/code_objects/extra_file_object_spec.rb +160 -160
  271. data/spec/code_objects/macro_object_spec.rb +150 -150
  272. data/spec/code_objects/method_object_spec.rb +184 -184
  273. data/spec/code_objects/module_object_spec.rb +142 -142
  274. data/spec/code_objects/namespace_object_spec.rb +171 -171
  275. data/spec/code_objects/proxy_spec.rb +141 -141
  276. data/spec/code_objects/spec_helper.rb +3 -3
  277. data/spec/config_spec.rb +171 -171
  278. data/spec/core_ext/array_spec.rb +13 -13
  279. data/spec/core_ext/file_spec.rb +72 -72
  280. data/spec/core_ext/hash_spec.rb +14 -14
  281. data/spec/core_ext/insertion_spec.rb +37 -37
  282. data/spec/core_ext/module_spec.rb +15 -15
  283. data/spec/core_ext/string_spec.rb +42 -42
  284. data/spec/core_ext/symbol_hash_spec.rb +89 -89
  285. data/spec/docstring_parser_spec.rb +280 -262
  286. data/spec/docstring_spec.rb +373 -364
  287. data/spec/examples.txt +1875 -1871
  288. data/spec/handlers/alias_handler_spec.rb +82 -82
  289. data/spec/handlers/attribute_handler_spec.rb +96 -96
  290. data/spec/handlers/base_spec.rb +216 -216
  291. data/spec/handlers/c/alias_handler_spec.rb +34 -34
  292. data/spec/handlers/c/attribute_handler_spec.rb +41 -41
  293. data/spec/handlers/c/class_handler_spec.rb +78 -78
  294. data/spec/handlers/c/constant_handler_spec.rb +71 -71
  295. data/spec/handlers/c/init_handler_spec.rb +48 -48
  296. data/spec/handlers/c/method_handler_spec.rb +325 -325
  297. data/spec/handlers/c/mixin_handler_spec.rb +44 -44
  298. data/spec/handlers/c/module_handler_spec.rb +71 -71
  299. data/spec/handlers/c/override_comment_handler_spec.rb +47 -47
  300. data/spec/handlers/c/path_handler_spec.rb +36 -36
  301. data/spec/handlers/c/spec_helper.rb +23 -23
  302. data/spec/handlers/c/struct_handler_spec.rb +16 -16
  303. data/spec/handlers/class_condition_handler_spec.rb +87 -87
  304. data/spec/handlers/class_handler_spec.rb +247 -247
  305. data/spec/handlers/class_method_handler_shared_examples.rb +133 -133
  306. data/spec/handlers/class_variable_handler_spec.rb +12 -12
  307. data/spec/handlers/constant_handler_spec.rb +112 -112
  308. data/spec/handlers/decorator_handler_methods_spec.rb +393 -393
  309. data/spec/handlers/dsl_handler_spec.rb +219 -219
  310. data/spec/handlers/examples/alias_handler_001.rb.txt +45 -45
  311. data/spec/handlers/examples/attribute_handler_001.rb.txt +31 -31
  312. data/spec/handlers/examples/class_condition_handler_001.rb.txt +68 -68
  313. data/spec/handlers/examples/class_handler_001.rb.txt +120 -120
  314. data/spec/handlers/examples/class_variable_handler_001.rb.txt +9 -9
  315. data/spec/handlers/examples/constant_handler_001.rb.txt +35 -35
  316. data/spec/handlers/examples/dsl_handler_001.rb.txt +154 -154
  317. data/spec/handlers/examples/exception_handler_001.rb.txt +58 -58
  318. data/spec/handlers/examples/extend_handler_001.rb.txt +15 -15
  319. data/spec/handlers/examples/method_condition_handler_001.rb.txt +9 -9
  320. data/spec/handlers/examples/method_handler_001.rb.txt +128 -128
  321. data/spec/handlers/examples/mixin_handler_001.rb.txt +37 -37
  322. data/spec/handlers/examples/module_handler_001.rb.txt +29 -29
  323. data/spec/handlers/examples/private_constant_handler_001.rb.txt +8 -8
  324. data/spec/handlers/examples/process_handler_001.rb.txt +11 -11
  325. data/spec/handlers/examples/visibility_handler_001.rb.txt +35 -35
  326. data/spec/handlers/examples/yield_handler_001.rb.txt +54 -54
  327. data/spec/handlers/exception_handler_spec.rb +49 -49
  328. data/spec/handlers/extend_handler_spec.rb +24 -24
  329. data/spec/handlers/legacy_base_spec.rb +128 -128
  330. data/spec/handlers/method_condition_handler_spec.rb +15 -15
  331. data/spec/handlers/method_handler_spec.rb +190 -190
  332. data/spec/handlers/mixin_handler_spec.rb +56 -56
  333. data/spec/handlers/module_function_handler_spec.rb +106 -106
  334. data/spec/handlers/module_handler_spec.rb +35 -35
  335. data/spec/handlers/private_class_method_handler_spec.rb +11 -11
  336. data/spec/handlers/private_constant_handler_spec.rb +25 -25
  337. data/spec/handlers/processor_spec.rb +35 -35
  338. data/spec/handlers/public_class_method_handler_spec.rb +11 -11
  339. data/spec/handlers/ruby/base_spec.rb +95 -95
  340. data/spec/handlers/ruby/legacy/base_spec.rb +84 -84
  341. data/spec/handlers/spec_helper.rb +33 -33
  342. data/spec/handlers/visibility_handler_spec.rb +44 -44
  343. data/spec/handlers/yield_handler_spec.rb +52 -52
  344. data/spec/i18n/locale_spec.rb +81 -81
  345. data/spec/i18n/message_spec.rb +52 -52
  346. data/spec/i18n/messages_spec.rb +67 -67
  347. data/spec/i18n/pot_generator_spec.rb +295 -295
  348. data/spec/i18n/text_spec.rb +184 -184
  349. data/spec/logging_spec.rb +44 -44
  350. data/spec/options_spec.rb +171 -171
  351. data/spec/parser/base_spec.rb +24 -24
  352. data/spec/parser/c_parser_spec.rb +236 -223
  353. data/spec/parser/examples/array.c.txt +6267 -6267
  354. data/spec/parser/examples/example1.rb.txt +7 -7
  355. data/spec/parser/examples/extrafile.c.txt +8 -8
  356. data/spec/parser/examples/file.c.txt +28 -0
  357. data/spec/parser/examples/multifile.c.txt +22 -22
  358. data/spec/parser/examples/namespace.cpp.txt +68 -68
  359. data/spec/parser/examples/override.c.txt +424 -424
  360. data/spec/parser/examples/parse_in_order_001.rb.txt +2 -2
  361. data/spec/parser/examples/parse_in_order_002.rb.txt +1 -1
  362. data/spec/parser/examples/tag_handler_001.rb.txt +7 -7
  363. data/spec/parser/ruby/ast_node_spec.rb +33 -33
  364. data/spec/parser/ruby/legacy/statement_list_spec.rb +299 -299
  365. data/spec/parser/ruby/legacy/token_list_spec.rb +79 -79
  366. data/spec/parser/ruby/ruby_parser_spec.rb +508 -508
  367. data/spec/parser/ruby/token_resolver_spec.rb +165 -165
  368. data/spec/parser/source_parser_spec.rb +727 -727
  369. data/spec/parser/tag_parsing_spec.rb +17 -17
  370. data/spec/rake/yardoc_task_spec.rb +118 -118
  371. data/spec/registry_spec.rb +463 -463
  372. data/spec/registry_store_spec.rb +316 -316
  373. data/spec/rubygems/doc_manager_spec.rb +112 -112
  374. data/spec/serializers/data/serialized_yardoc/checksums +1 -1
  375. data/spec/serializers/file_system_serializer_spec.rb +145 -145
  376. data/spec/serializers/spec_helper.rb +2 -2
  377. data/spec/serializers/yardoc_serializer_spec.rb +78 -78
  378. data/spec/server/adapter_spec.rb +39 -39
  379. data/spec/server/commands/base_spec.rb +91 -91
  380. data/spec/server/commands/library_command_spec.rb +39 -39
  381. data/spec/server/doc_server_helper_spec.rb +72 -72
  382. data/spec/server/doc_server_serializer_spec.rb +60 -60
  383. data/spec/server/rack_adapter_spec.rb +21 -21
  384. data/spec/server/router_spec.rb +123 -123
  385. data/spec/server/spec_helper.rb +22 -22
  386. data/spec/server/static_caching_spec.rb +47 -47
  387. data/spec/server/webrick_servlet_spec.rb +20 -20
  388. data/spec/server_spec.rb +19 -19
  389. data/spec/spec_helper.rb +212 -212
  390. data/spec/tags/default_factory_spec.rb +168 -168
  391. data/spec/tags/default_tag_spec.rb +11 -11
  392. data/spec/tags/directives_spec.rb +463 -463
  393. data/spec/tags/library_spec.rb +48 -48
  394. data/spec/tags/overload_tag_spec.rb +53 -53
  395. data/spec/tags/ref_tag_list_spec.rb +53 -53
  396. data/spec/tags/types_explainer_spec.rb +203 -203
  397. data/spec/templates/class_spec.rb +45 -45
  398. data/spec/templates/constant_spec.rb +41 -41
  399. data/spec/templates/engine_spec.rb +131 -131
  400. data/spec/templates/examples/class001.html +308 -308
  401. data/spec/templates/examples/class001.txt +36 -36
  402. data/spec/templates/examples/class002.html +39 -39
  403. data/spec/templates/examples/constant001.txt +24 -24
  404. data/spec/templates/examples/constant002.txt +6 -6
  405. data/spec/templates/examples/constant003.txt +10 -10
  406. data/spec/templates/examples/method001.html +137 -137
  407. data/spec/templates/examples/method001.txt +35 -35
  408. data/spec/templates/examples/method002.html +91 -91
  409. data/spec/templates/examples/method002.txt +20 -20
  410. data/spec/templates/examples/method003.html +165 -165
  411. data/spec/templates/examples/method003.txt +45 -45
  412. data/spec/templates/examples/method004.html +48 -48
  413. data/spec/templates/examples/method004.txt +10 -10
  414. data/spec/templates/examples/method005.html +105 -105
  415. data/spec/templates/examples/method005.txt +33 -33
  416. data/spec/templates/examples/method006.html +107 -107
  417. data/spec/templates/examples/method006.txt +20 -20
  418. data/spec/templates/examples/module001.dot +33 -33
  419. data/spec/templates/examples/module001.html +833 -833
  420. data/spec/templates/examples/module001.txt +33 -33
  421. data/spec/templates/examples/module002.html +341 -341
  422. data/spec/templates/examples/module003.html +202 -202
  423. data/spec/templates/examples/module004.html +394 -394
  424. data/spec/templates/examples/module005.html +81 -81
  425. data/spec/templates/examples/tag001.txt +82 -82
  426. data/spec/templates/helpers/base_helper_spec.rb +171 -171
  427. data/spec/templates/helpers/html_helper_spec.rb +668 -653
  428. data/spec/templates/helpers/html_syntax_highlight_helper_spec.rb +65 -65
  429. data/spec/templates/helpers/markup/rdoc_markup_spec.rb +84 -84
  430. data/spec/templates/helpers/markup_helper_spec.rb +136 -136
  431. data/spec/templates/helpers/method_helper_spec.rb +107 -107
  432. data/spec/templates/helpers/module_helper_spec.rb +35 -35
  433. data/spec/templates/helpers/shared_signature_examples.rb +126 -126
  434. data/spec/templates/helpers/text_helper_spec.rb +65 -65
  435. data/spec/templates/method_spec.rb +118 -118
  436. data/spec/templates/module_spec.rb +203 -203
  437. data/spec/templates/onefile_spec.rb +66 -66
  438. data/spec/templates/section_spec.rb +144 -144
  439. data/spec/templates/spec_helper.rb +76 -76
  440. data/spec/templates/tag_spec.rb +52 -52
  441. data/spec/templates/template_spec.rb +410 -410
  442. data/spec/verifier_spec.rb +106 -106
  443. data/templates/default/class/dot/setup.rb +7 -7
  444. data/templates/default/class/dot/superklass.erb +2 -2
  445. data/templates/default/class/html/constructor_details.erb +8 -8
  446. data/templates/default/class/html/setup.rb +2 -2
  447. data/templates/default/class/html/subclasses.erb +4 -4
  448. data/templates/default/class/setup.rb +36 -36
  449. data/templates/default/class/text/setup.rb +12 -12
  450. data/templates/default/class/text/subclasses.erb +5 -5
  451. data/templates/default/constant/text/header.erb +11 -11
  452. data/templates/default/constant/text/setup.rb +4 -4
  453. data/templates/default/docstring/html/abstract.erb +4 -4
  454. data/templates/default/docstring/html/deprecated.erb +1 -1
  455. data/templates/default/docstring/html/index.erb +5 -5
  456. data/templates/default/docstring/html/note.erb +6 -6
  457. data/templates/default/docstring/html/private.erb +4 -4
  458. data/templates/default/docstring/html/text.erb +1 -1
  459. data/templates/default/docstring/html/todo.erb +6 -6
  460. data/templates/default/docstring/setup.rb +52 -52
  461. data/templates/default/docstring/text/abstract.erb +2 -2
  462. data/templates/default/docstring/text/deprecated.erb +2 -2
  463. data/templates/default/docstring/text/index.erb +2 -2
  464. data/templates/default/docstring/text/note.erb +3 -3
  465. data/templates/default/docstring/text/private.erb +2 -2
  466. data/templates/default/docstring/text/text.erb +1 -1
  467. data/templates/default/docstring/text/todo.erb +3 -3
  468. data/templates/default/fulldoc/html/css/full_list.css +58 -58
  469. data/templates/default/fulldoc/html/css/style.css +496 -496
  470. data/templates/default/fulldoc/html/frames.erb +17 -17
  471. data/templates/default/fulldoc/html/full_list.erb +37 -37
  472. data/templates/default/fulldoc/html/full_list_class.erb +2 -2
  473. data/templates/default/fulldoc/html/full_list_file.erb +7 -7
  474. data/templates/default/fulldoc/html/full_list_method.erb +10 -10
  475. data/templates/default/fulldoc/html/js/app.js +292 -292
  476. data/templates/default/fulldoc/html/js/full_list.js +216 -216
  477. data/templates/default/fulldoc/html/js/jquery.js +3 -3
  478. data/templates/default/fulldoc/html/setup.rb +241 -241
  479. data/templates/default/layout/dot/header.erb +5 -5
  480. data/templates/default/layout/dot/setup.rb +15 -15
  481. data/templates/default/layout/html/breadcrumb.erb +11 -11
  482. data/templates/default/layout/html/files.erb +11 -11
  483. data/templates/default/layout/html/footer.erb +5 -5
  484. data/templates/default/layout/html/headers.erb +15 -15
  485. data/templates/default/layout/html/index.erb +2 -2
  486. data/templates/default/layout/html/layout.erb +23 -23
  487. data/templates/default/layout/html/listing.erb +4 -4
  488. data/templates/default/layout/html/objects.erb +32 -32
  489. data/templates/default/layout/html/script_setup.erb +4 -4
  490. data/templates/default/layout/html/search.erb +12 -12
  491. data/templates/default/layout/html/setup.rb +89 -89
  492. data/templates/default/method/html/header.erb +16 -16
  493. data/templates/default/method/setup.rb +4 -4
  494. data/templates/default/method_details/html/header.erb +2 -2
  495. data/templates/default/method_details/html/method_signature.erb +24 -24
  496. data/templates/default/method_details/html/source.erb +9 -9
  497. data/templates/default/method_details/setup.rb +11 -11
  498. data/templates/default/method_details/text/header.erb +10 -10
  499. data/templates/default/method_details/text/method_signature.erb +12 -12
  500. data/templates/default/method_details/text/setup.rb +11 -11
  501. data/templates/default/module/dot/child.erb +1 -1
  502. data/templates/default/module/dot/dependencies.erb +2 -2
  503. data/templates/default/module/dot/header.erb +6 -6
  504. data/templates/default/module/dot/info.erb +13 -13
  505. data/templates/default/module/dot/setup.rb +15 -15
  506. data/templates/default/module/html/attribute_details.erb +10 -10
  507. data/templates/default/module/html/attribute_summary.erb +8 -8
  508. data/templates/default/module/html/box_info.erb +43 -43
  509. data/templates/default/module/html/children.erb +8 -8
  510. data/templates/default/module/html/constant_summary.erb +17 -17
  511. data/templates/default/module/html/defines.erb +2 -2
  512. data/templates/default/module/html/header.erb +5 -5
  513. data/templates/default/module/html/inherited_attributes.erb +14 -14
  514. data/templates/default/module/html/inherited_constants.erb +8 -8
  515. data/templates/default/module/html/inherited_methods.erb +18 -18
  516. data/templates/default/module/html/item_summary.erb +40 -40
  517. data/templates/default/module/html/method_details_list.erb +9 -9
  518. data/templates/default/module/html/method_summary.erb +13 -13
  519. data/templates/default/module/html/methodmissing.erb +12 -12
  520. data/templates/default/module/setup.rb +167 -167
  521. data/templates/default/module/text/children.erb +9 -9
  522. data/templates/default/module/text/class_meths_list.erb +7 -7
  523. data/templates/default/module/text/extends.erb +7 -7
  524. data/templates/default/module/text/header.erb +7 -7
  525. data/templates/default/module/text/includes.erb +7 -7
  526. data/templates/default/module/text/instance_meths_list.erb +7 -7
  527. data/templates/default/module/text/setup.rb +13 -13
  528. data/templates/default/onefile/html/files.erb +4 -4
  529. data/templates/default/onefile/html/headers.erb +6 -6
  530. data/templates/default/onefile/html/layout.erb +17 -17
  531. data/templates/default/onefile/html/readme.erb +2 -2
  532. data/templates/default/onefile/html/setup.rb +62 -62
  533. data/templates/default/root/dot/child.erb +2 -2
  534. data/templates/default/root/dot/setup.rb +6 -6
  535. data/templates/default/root/html/setup.rb +2 -2
  536. data/templates/default/tags/html/example.erb +10 -10
  537. data/templates/default/tags/html/index.erb +2 -2
  538. data/templates/default/tags/html/option.erb +24 -24
  539. data/templates/default/tags/html/overload.erb +13 -13
  540. data/templates/default/tags/html/see.erb +7 -7
  541. data/templates/default/tags/html/tag.erb +20 -20
  542. data/templates/default/tags/setup.rb +57 -57
  543. data/templates/default/tags/text/example.erb +12 -12
  544. data/templates/default/tags/text/index.erb +1 -1
  545. data/templates/default/tags/text/option.erb +20 -20
  546. data/templates/default/tags/text/overload.erb +19 -19
  547. data/templates/default/tags/text/see.erb +11 -11
  548. data/templates/default/tags/text/tag.erb +13 -13
  549. data/templates/guide/class/html/setup.rb +2 -2
  550. data/templates/guide/docstring/html/setup.rb +2 -2
  551. data/templates/guide/fulldoc/html/css/style.css +108 -108
  552. data/templates/guide/fulldoc/html/js/app.js +33 -33
  553. data/templates/guide/fulldoc/html/setup.rb +74 -74
  554. data/templates/guide/layout/html/layout.erb +81 -81
  555. data/templates/guide/layout/html/setup.rb +25 -25
  556. data/templates/guide/method/html/header.erb +17 -17
  557. data/templates/guide/method/html/setup.rb +22 -22
  558. data/templates/guide/module/html/header.erb +6 -6
  559. data/templates/guide/module/html/method_list.erb +4 -4
  560. data/templates/guide/module/html/setup.rb +27 -27
  561. data/templates/guide/onefile/html/files.erb +4 -4
  562. data/templates/guide/onefile/html/setup.rb +6 -6
  563. data/templates/guide/onefile/html/toc.erb +3 -3
  564. data/templates/guide/tags/html/setup.rb +9 -9
  565. data/yard.gemspec +43 -43
  566. metadata +4 -4
@@ -1,610 +1,615 @@
1
- # frozen_string_literal: true
2
- module YARD
3
- module CodeObjects
4
- # A list of code objects. This array acts like a set (no unique items)
5
- # but also disallows any {Proxy} objects from being added.
6
- class CodeObjectList < Array
7
- # Creates a new object list associated with a namespace
8
- #
9
- # @param [NamespaceObject] owner the namespace the list should be associated with
10
- # @return [CodeObjectList]
11
- def initialize(owner = Registry.root)
12
- @owner = owner
13
- end
14
-
15
- # Adds a new value to the list
16
- #
17
- # @param [Base] value a code object to add
18
- # @return [CodeObjectList] self
19
- def push(value)
20
- value = Proxy.new(@owner, value) if value.is_a?(String) || value.is_a?(Symbol)
21
- if value.is_a?(CodeObjects::Base) || value.is_a?(Proxy)
22
- super(value) unless include?(value)
23
- else
24
- raise ArgumentError, "#{value.class} is not a valid CodeObject"
25
- end
26
- self
27
- end
28
- alias << push
29
- end
30
-
31
- extend NamespaceMapper
32
-
33
- # Namespace separator
34
- NSEP = '::'
35
-
36
- # Regex-quoted namespace separator
37
- NSEPQ = NSEP
38
-
39
- # Instance method separator
40
- ISEP = '#'
41
-
42
- # Regex-quoted instance method separator
43
- ISEPQ = ISEP
44
-
45
- # Class method separator
46
- CSEP = '.'
47
-
48
- # Regex-quoted class method separator
49
- CSEPQ = Regexp.quote CSEP
50
-
51
- # Regular expression to match constant name
52
- CONSTANTMATCH = /[A-Z]\w*/
53
-
54
- # Regular expression to match the beginning of a constant
55
- CONSTANTSTART = /^[A-Z]/
56
-
57
- # Regular expression to match namespaces (const A or complex path A::B)
58
- NAMESPACEMATCH = /(?:(?:#{NSEPQ}\s*)?#{CONSTANTMATCH})+/
59
-
60
- # Regular expression to match a method name
61
- METHODNAMEMATCH = %r{[a-zA-Z_]\w*[!?=]?|[-+~]\@|<<|>>|=~|===?|![=~]?|<=>|[<>]=?|\*\*|[-/+%^&*~`|]|\[\]=?}
62
-
63
- # Regular expression to match a fully qualified method def (self.foo, Class.foo).
64
- METHODMATCH = /(?:(?:#{NAMESPACEMATCH}|[a-z]\w*)\s*(?:#{CSEPQ}|#{NSEPQ})\s*)?#{METHODNAMEMATCH}/
65
-
66
- # All builtin Ruby exception classes for inheritance tree.
67
- BUILTIN_EXCEPTIONS = ["ArgumentError", "ClosedQueueError", "EncodingError",
68
- "EOFError", "Exception", "FiberError", "FloatDomainError", "IndexError",
69
- "Interrupt", "IOError", "KeyError", "LoadError", "LocalJumpError",
70
- "NameError", "NoMemoryError", "NoMethodError", "NotImplementedError",
71
- "RangeError", "RegexpError", "RuntimeError", "ScriptError", "SecurityError",
72
- "SignalException", "StandardError", "StopIteration", "SyntaxError",
73
- "SystemCallError", "SystemExit", "SystemStackError", "ThreadError",
74
- "TypeError", "UncaughtThrowError", "ZeroDivisionError"]
75
-
76
- # All builtin Ruby classes for inheritance tree.
77
- # @note MatchingData is a 1.8.x legacy class
78
- BUILTIN_CLASSES = ["Array", "Bignum", "Binding", "Class", "Complex",
79
- "ConditionVariable", "Data", "Dir", "Encoding", "Enumerator", "FalseClass",
80
- "Fiber", "File", "Fixnum", "Float", "Hash", "IO", "Integer", "MatchData",
81
- "Method", "Module", "NilClass", "Numeric", "Object", "Proc", "Queue",
82
- "Random", "Range", "Rational", "Regexp", "RubyVM", "SizedQueue", "String",
83
- "Struct", "Symbol", "Thread", "ThreadGroup", "Time", "TracePoint",
84
- "TrueClass", "UnboundMethod"] + BUILTIN_EXCEPTIONS
85
-
86
- # All builtin Ruby modules for mixin handling.
87
- BUILTIN_MODULES = ["Comparable", "Enumerable", "Errno", "FileTest", "GC",
88
- "Kernel", "Marshal", "Math", "ObjectSpace", "Precision", "Process", "Signal"]
89
-
90
- # All builtin Ruby classes and modules.
91
- BUILTIN_ALL = BUILTIN_CLASSES + BUILTIN_MODULES
92
-
93
- # Hash of {BUILTIN_EXCEPTIONS} as keys and true as value (for O(1) lookups)
94
- BUILTIN_EXCEPTIONS_HASH = BUILTIN_EXCEPTIONS.inject({}) {|h, n| h.update(n => true) }
95
-
96
- # +Base+ is the superclass of all code objects recognized by YARD. A code
97
- # object is any entity in the Ruby language (class, method, module). A
98
- # DSL might subclass +Base+ to create a new custom object representing
99
- # a new entity type.
100
- #
101
- # == Registry Integration
102
- # Any created object associated with a namespace is immediately registered
103
- # with the registry. This allows the Registry to act as an identity map
104
- # to ensure that no object is represented by more than one Ruby object
105
- # in memory. A unique {#path} is essential for this identity map to work
106
- # correctly.
107
- #
108
- # == Custom Attributes
109
- # Code objects allow arbitrary custom attributes to be set using the
110
- # {#[]=} assignment method.
111
- #
112
- # == Namespaces
113
- # There is a special type of object called a "namespace". These are subclasses
114
- # of the {NamespaceObject} and represent Ruby entities that can have
115
- # objects defined within them. Classically these are modules and classes,
116
- # though a DSL might create a custom {NamespaceObject} to describe a
117
- # specific set of objects.
118
- #
119
- # == Separators
120
- # Custom classes with different separator tokens should define their own
121
- # separators using the {NamespaceMapper.register_separator} method. The
122
- # standard Ruby separators have already been defined ('::', '#', '.', etc).
123
- #
124
- # @abstract This class should not be used directly. Instead, create a
125
- # subclass that implements {#path}, {#sep} or {#type}. You might also
126
- # need to register custom separators if {#sep} uses alternate separator
127
- # tokens.
128
- # @see Registry
129
- # @see #path
130
- # @see #[]=
131
- # @see NamespaceObject
132
- # @see NamespaceMapper.register_separator
133
- class Base
134
- # The files the object was defined in. To add a file, use {#add_file}.
135
- # @return [Array<Array(String, Integer)>] a list of files
136
- # @see #add_file
137
- attr_reader :files
138
-
139
- # The namespace the object is defined in. If the object is in the
140
- # top level namespace, this is {Registry.root}
141
- # @return [NamespaceObject] the namespace object
142
- attr_reader :namespace
143
-
144
- # The source code associated with the object
145
- # @return [String, nil] source, if present, or nil
146
- attr_reader :source
147
-
148
- # Language of the source code associated with the object. Defaults to
149
- # +:ruby+.
150
- #
151
- # @return [Symbol] the language type
152
- attr_accessor :source_type
153
-
154
- # The one line signature representing an object. For a method, this will
155
- # be of the form "def meth(arguments...)". This is usually the first
156
- # source line.
157
- #
158
- # @return [String] a line of source
159
- attr_accessor :signature
160
-
161
- # The non-localized documentation string associated with the object
162
- # @return [Docstring] the documentation string
163
- # @since 0.8.4
164
- attr_reader :base_docstring
165
- undef base_docstring
166
- def base_docstring; @docstring end
167
-
168
- # Marks whether or not the method is conditionally defined at runtime
169
- # @return [Boolean] true if the method is conditionally defined at runtime
170
- attr_accessor :dynamic
171
-
172
- # @return [String] the group this object is associated with
173
- # @since 0.6.0
174
- attr_accessor :group
175
-
176
- # Is the object defined conditionally at runtime?
177
- # @see #dynamic
178
- def dynamic?; @dynamic end
179
-
180
- # @return [Symbol] the visibility of an object (:public, :private, :protected)
181
- attr_accessor :visibility
182
- undef visibility=
183
- def visibility=(v) @visibility = v.to_sym end
184
-
185
- class << self
186
- # Allocates a new code object
187
- # @return [Base]
188
- # @see #initialize
189
- def new(namespace, name, *args, &block)
190
- raise ArgumentError, "invalid empty object name" if name.to_s.empty?
191
- if namespace.is_a?(ConstantObject)
192
- namespace = Proxy.new(namespace.namespace, namespace.value)
193
- end
194
-
195
- if name.to_s[0, 2] == NSEP
196
- name = name.to_s[2..-1]
197
- namespace = Registry.root
198
- end
199
-
200
- if name =~ /(?:#{NSEPQ})([^:]+)$/
201
- return new(Proxy.new(namespace, $`), $1, *args, &block)
202
- end
203
-
204
- obj = super(namespace, name, *args)
205
- existing_obj = Registry.at(obj.path)
206
- obj = existing_obj if existing_obj && existing_obj.class == self
207
- yield(obj) if block_given?
208
- obj
209
- end
210
-
211
- # Compares the class with subclasses
212
- #
213
- # @param [Object] other the other object to compare classes with
214
- # @return [Boolean] true if other is a subclass of self
215
- def ===(other)
216
- other.is_a?(self)
217
- end
218
- end
219
-
220
- # Creates a new code object
221
- #
222
- # @example Create a method in the root namespace
223
- # CodeObjects::Base.new(:root, '#method') # => #<yardoc method #method>
224
- # @example Create class Z inside namespace X::Y
225
- # CodeObjects::Base.new(P("X::Y"), :Z) # or
226
- # CodeObjects::Base.new(Registry.root, "X::Y")
227
- # @param [NamespaceObject] namespace the namespace the object belongs in,
228
- # {Registry.root} or :root should be provided if it is associated with
229
- # the top level namespace.
230
- # @param [Symbol, String] name the name (or complex path) of the object.
231
- # @yield [self] a block to perform any extra initialization on the object
232
- # @yieldparam [Base] self the newly initialized code object
233
- # @return [Base] the newly created object
234
- def initialize(namespace, name, *)
235
- if namespace && namespace != :root &&
236
- !namespace.is_a?(NamespaceObject) && !namespace.is_a?(Proxy)
237
- raise ArgumentError, "Invalid namespace object: #{namespace}"
238
- end
239
-
240
- @files = []
241
- @current_file_has_comments = false
242
- @name = name.to_sym
243
- @source_type = :ruby
244
- @visibility = :public
245
- @tags = []
246
- @docstrings = {}
247
- @docstring = Docstring.new!('', [], self)
248
- @namespace = nil
249
- self.namespace = namespace
250
- yield(self) if block_given?
251
- end
252
-
253
- # Copies all data in this object to another code object, except for
254
- # uniquely identifying information (path, namespace, name, scope).
255
- #
256
- # @param [Base] other the object to copy data to
257
- # @return [Base] the other object
258
- # @since 0.8.0
259
- def copy_to(other)
260
- copyable_attributes.each do |ivar|
261
- ivar = "@#{ivar}"
262
- other.instance_variable_set(ivar, instance_variable_get(ivar))
263
- end
264
- other.docstring = @docstring.to_raw
265
- other
266
- end
267
-
268
- # The name of the object
269
- # @param [Boolean] prefix whether to show a prefix. Implement
270
- # this in a subclass to define how the prefix is showed.
271
- # @return [Symbol] if prefix is false, the symbolized name
272
- # @return [String] if prefix is true, prefix + the name as a String.
273
- # This must be implemented by the subclass.
274
- def name(prefix = false)
275
- prefix ? @name.to_s : (defined?(@name) && @name)
276
- end
277
-
278
- # Associates a file with a code object, optionally adding the line where it was defined.
279
- # By convention, '<stdin>' should be used to associate code that comes form standard input.
280
- #
281
- # @param [String] file the filename ('<stdin>' for standard input)
282
- # @param [Fixnum, nil] line the line number where the object lies in the file
283
- # @param [Boolean] has_comments whether or not the definition has comments associated. This
284
- # will allow {#file} to return the definition where the comments were made instead
285
- # of any empty definitions that might have been parsed before (module namespaces for instance).
286
- def add_file(file, line = nil, has_comments = false)
287
- raise(ArgumentError, "file cannot be nil or empty") if file.nil? || file == ''
288
- obj = [file.to_s, line]
289
- return if files.include?(obj)
290
- if has_comments && !@current_file_has_comments
291
- @current_file_has_comments = true
292
- @files.unshift(obj)
293
- else
294
- @files << obj # back of the line
295
- end
296
- end
297
-
298
- # Returns the filename the object was first parsed at, taking
299
- # definitions with docstrings first.
300
- #
301
- # @return [String] a filename
302
- def file
303
- @files.first ? @files.first[0] : nil
304
- end
305
-
306
- # Returns the line the object was first parsed at (or nil)
307
- #
308
- # @return [Fixnum] the line where the object was first defined.
309
- # @return [nil] if there is no line associated with the object
310
- def line
311
- @files.first ? @files.first[1] : nil
312
- end
313
-
314
- # Tests if another object is equal to this, including a proxy
315
- # @param [Base, Proxy] other if other is a {Proxy}, tests if
316
- # the paths are equal
317
- # @return [Boolean] whether or not the objects are considered the same
318
- def equal?(other)
319
- if other.is_a?(Base) || other.is_a?(Proxy)
320
- path == other.path
321
- else
322
- super
323
- end
324
- end
325
- alias == equal?
326
- alias eql? equal?
327
-
328
- # @return [Integer] the object's hash value (for equality checking)
329
- def hash; path.hash end
330
-
331
- # @return [nil] this object does not turn into an array
332
- def to_ary; nil end
333
-
334
- # Accesses a custom attribute on the object
335
- # @param [#to_s] key the name of the custom attribute
336
- # @return [Object, nil] the custom attribute or nil if not found.
337
- # @see #[]=
338
- def [](key)
339
- if respond_to?(key)
340
- send(key)
341
- elsif instance_variable_defined?("@#{key}")
342
- instance_variable_get("@#{key}")
343
- end
344
- end
345
-
346
- # Sets a custom attribute on the object
347
- # @param [#to_s] key the name of the custom attribute
348
- # @param [Object] value the value to associate
349
- # @return [void]
350
- # @see #[]
351
- def []=(key, value)
352
- if respond_to?("#{key}=")
353
- send("#{key}=", value)
354
- else
355
- instance_variable_set("@#{key}", value)
356
- end
357
- end
358
-
359
- # @overload dynamic_attr_name
360
- # @return the value of attribute named by the method attribute name
361
- # @raise [NoMethodError] if no method or custom attribute exists by
362
- # the attribute name
363
- # @see #[]
364
- # @overload dynamic_attr_name=(value)
365
- # @param value a value to set
366
- # @return +value+
367
- # @see #[]=
368
- def method_missing(meth, *args, &block)
369
- if meth.to_s =~ /=$/
370
- self[meth.to_s[0..-2]] = args.first
371
- elsif instance_variable_get("@#{meth}")
372
- self[meth]
373
- else
374
- super
375
- end
376
- end
377
-
378
- # Attaches source code to a code object with an optional file location
379
- #
380
- # @param [#source, String] statement
381
- # the +Parser::Statement+ holding the source code or the raw source
382
- # as a +String+ for the definition of the code object only (not the block)
383
- def source=(statement)
384
- if statement.respond_to?(:source)
385
- self.signature = statement.first_line
386
- @source = format_source(statement.source.strip)
387
- else
388
- @source = format_source(statement.to_s)
389
- end
390
- end
391
-
392
- # The documentation string associated with the object
393
- #
394
- # @param [String, I18n::Locale] locale (I18n::Locale.default)
395
- # the locale of the documentation string.
396
- # @return [Docstring] the documentation string
397
- def docstring(locale = I18n::Locale.default)
398
- if locale.nil?
399
- @docstring.resolve_reference
400
- return @docstring
401
- end
402
-
403
- if locale.is_a?(String)
404
- locale_name = locale
405
- locale = nil
406
- else
407
- locale_name = locale.name
408
- end
409
- @docstrings[locale_name] ||=
410
- translate_docstring(locale || Registry.locale(locale_name))
411
- end
412
-
413
- # Attaches a docstring to a code object by parsing the comments attached to the statement
414
- # and filling the {#tags} and {#docstring} methods with the parsed information.
415
- #
416
- # @param [String, Array<String>, Docstring] comments
417
- # the comments attached to the code object to be parsed
418
- # into a docstring and meta tags.
419
- def docstring=(comments)
420
- @docstrings.clear
421
- @docstring = Docstring === comments ?
422
- comments : Docstring.new(comments, self)
423
- end
424
-
425
- # Default type is the lowercase class name without the "Object" suffix.
426
- # Override this method to provide a custom object type
427
- #
428
- # @return [Symbol] the type of code object this represents
429
- def type
430
- self.class.name.split('::').last.gsub(/Object$/, '').downcase.to_sym
431
- end
432
-
433
- # Represents the unique path of the object. The default implementation
434
- # joins the path of {#namespace} with {#name} via the value of {#sep}.
435
- # Custom code objects should ensure that the path is unique to the code
436
- # object by either overriding {#sep} or this method.
437
- #
438
- # @example The path of an instance method
439
- # MethodObject.new(P("A::B"), :c).path # => "A::B#c"
440
- # @return [String] the unique path of the object
441
- # @see #sep
442
- def path
443
- @path ||= if parent && !parent.root?
444
- [parent.path, name.to_s].join(sep)
445
- else
446
- name.to_s
447
- end
448
- end
449
- alias to_s path
450
-
451
- # @note
452
- # Override this method if your object has a special title that does
453
- # not match the {#path} attribute value. This title will be used
454
- # when linking or displaying the object.
455
- # @return [String] the display title for an object
456
- # @see 0.8.4
457
- def title
458
- path
459
- end
460
-
461
- # @param [Base, String] other another code object (or object path)
462
- # @return [String] the shortest relative path from this object to +other+
463
- # @since 0.5.3
464
- def relative_path(other)
465
- other = Registry.at(other) if String === other && Registry.at(other)
466
- same_parent = false
467
- if other.respond_to?(:path)
468
- same_parent = other.parent == parent
469
- other = other.path
470
- end
471
- return other unless namespace
472
- common = [path, other].join(" ").match(/^(\S*)\S*(?: \1\S*)*$/)[1]
473
- common = path unless common =~ /(\.|::|#)$/
474
- common = common.sub(/(\.|::|#)[^:#\.]*?$/, '') if same_parent
475
- suffix = %w(. :).include?(common[-1, 1]) || other[common.size, 1] == '#' ?
476
- '' : '(::|\.)'
477
- result = other.sub(/^#{Regexp.quote common}#{suffix}/, '')
478
- result.empty? ? other : result
479
- end
480
-
481
- # Renders the object using the {Templates::Engine templating system}.
482
- #
483
- # @example Formats a class in plaintext
484
- # puts P('MyClass').format
485
- # @example Formats a method in html with rdoc markup
486
- # puts P('MyClass#meth').format(:format => :html, :markup => :rdoc)
487
- # @param [Hash] options a set of options to pass to the template
488
- # @option options [Symbol] :format (:text) :html, :text or another output format
489
- # @option options [Symbol] :template (:default) a specific template to use
490
- # @option options [Symbol] :markup (nil) the markup type (:rdoc, :markdown, :textile)
491
- # @option options [Serializers::Base] :serializer (nil) see Serializers
492
- # @return [String] the rendered template
493
- # @see Templates::Engine#render
494
- def format(options = {})
495
- options = options.merge(:object => self)
496
- options = options.merge(:type => type) unless options[:type]
497
- Templates::Engine.render(options)
498
- end
499
-
500
- # Inspects the object, returning the type and path
501
- # @return [String] a string describing the object
502
- def inspect
503
- "#<yardoc #{type} #{path}>"
504
- end
505
-
506
- # Sets the namespace the object is defined in.
507
- #
508
- # @param [NamespaceObject, :root, nil] obj the new namespace (:root
509
- # for {Registry.root}). If obj is nil, the object is unregistered
510
- # from the Registry.
511
- def namespace=(obj)
512
- if @namespace
513
- @namespace.children.delete(self)
514
- Registry.delete(self)
515
- end
516
-
517
- @namespace = (obj == :root ? Registry.root : obj)
518
-
519
- if @namespace
520
- reg_obj = Registry.at(path)
521
- return if reg_obj && reg_obj.class == self.class
522
- @namespace.children << self unless @namespace.is_a?(Proxy)
523
- Registry.register(self)
524
- end
525
- end
526
-
527
- alias parent namespace
528
- alias parent= namespace=
529
-
530
- # Gets a tag from the {#docstring}
531
- # @see Docstring#tag
532
- def tag(name); docstring.tag(name) end
533
-
534
- # Gets a list of tags from the {#docstring}
535
- # @see Docstring#tags
536
- def tags(name = nil); docstring.tags(name) end
537
-
538
- # Tests if the {#docstring} has a tag
539
- # @see Docstring#has_tag?
540
- def has_tag?(name); docstring.has_tag?(name) end
541
-
542
- # Add tags to the {#docstring}
543
- # @see Docstring#add_tag
544
- # @since 0.8.4
545
- def add_tag(*tags)
546
- @docstrings.clear
547
- @docstring.add_tag(*tags)
548
- end
549
-
550
- # @return whether or not this object is a RootObject
551
- def root?; false end
552
-
553
- # Override this method with a custom component separator. For instance,
554
- # {MethodObject} implements sep as '#' or '.' (depending on if the
555
- # method is instance or class respectively). {#path} depends on this
556
- # value to generate the full path in the form: namespace.path + sep + name
557
- #
558
- # @return [String] the component that separates the namespace path
559
- # and the name (default is {NSEP})
560
- def sep; NSEP end
561
-
562
- protected
563
-
564
- # Override this method if your code object subclass does not allow
565
- # copying of certain attributes.
566
- #
567
- # @return [Array<String>] the list of instance variable names (without
568
- # "@" prefix) that should be copied when {#copy_to} is called
569
- # @see #copy_to
570
- # @since 0.8.0
571
- def copyable_attributes
572
- vars = instance_variables.map {|ivar| ivar.to_s[1..-1] }
573
- vars -= %w(docstring docstrings namespace name path)
574
- vars
575
- end
576
-
577
- private
578
-
579
- # Formats source code by removing leading indentation
580
- #
581
- # @param [String] source the source code to format
582
- # @return [String] formatted source
583
- def format_source(source)
584
- source = source.chomp
585
- last = source.split(/\r?\n/).last
586
- indent = last ? last[/^([ \t]*)/, 1].length : 0
587
- source.gsub(/^[ \t]{#{indent}}/, '')
588
- end
589
-
590
- def translate_docstring(locale)
591
- @docstring.resolve_reference
592
- return @docstring if locale.nil?
593
-
594
- text = I18n::Text.new(@docstring)
595
- localized_text = text.translate(locale)
596
- docstring = Docstring.new(localized_text, self)
597
- @docstring.tags.each do |tag|
598
- if tag.is_a?(Tags::Tag)
599
- localized_tag = tag.clone
600
- localized_tag.text = I18n::Text.new(tag.text).translate(locale)
601
- docstring.add_tag(localized_tag)
602
- else
603
- docstring.add_tag(tag)
604
- end
605
- end
606
- docstring
607
- end
608
- end
609
- end
610
- end
1
+ # frozen_string_literal: true
2
+ module YARD
3
+ module CodeObjects
4
+ # A list of code objects. This array acts like a set (no unique items)
5
+ # but also disallows any {Proxy} objects from being added.
6
+ class CodeObjectList < Array
7
+ # Creates a new object list associated with a namespace
8
+ #
9
+ # @param [NamespaceObject] owner the namespace the list should be associated with
10
+ # @return [CodeObjectList]
11
+ def initialize(owner = Registry.root)
12
+ @owner = owner
13
+ end
14
+
15
+ # Adds a new value to the list
16
+ #
17
+ # @param [Base] value a code object to add
18
+ # @return [CodeObjectList] self
19
+ def push(value)
20
+ value = Proxy.new(@owner, value) if value.is_a?(String) || value.is_a?(Symbol)
21
+ if value.is_a?(CodeObjects::Base) || value.is_a?(Proxy)
22
+ super(value) unless include?(value)
23
+ else
24
+ raise ArgumentError, "#{value.class} is not a valid CodeObject"
25
+ end
26
+ self
27
+ end
28
+ alias << push
29
+ end
30
+
31
+ extend NamespaceMapper
32
+
33
+ # Namespace separator
34
+ NSEP = '::'
35
+
36
+ # Regex-quoted namespace separator
37
+ NSEPQ = NSEP
38
+
39
+ # Instance method separator
40
+ ISEP = '#'
41
+
42
+ # Regex-quoted instance method separator
43
+ ISEPQ = ISEP
44
+
45
+ # Class method separator
46
+ CSEP = '.'
47
+
48
+ # Regex-quoted class method separator
49
+ CSEPQ = Regexp.quote CSEP
50
+
51
+ # Regular expression to match constant name
52
+ CONSTANTMATCH = /[A-Z]\w*/
53
+
54
+ # Regular expression to match the beginning of a constant
55
+ CONSTANTSTART = /^[A-Z]/
56
+
57
+ # Regular expression to match namespaces (const A or complex path A::B)
58
+ NAMESPACEMATCH = /(?:(?:#{NSEPQ}\s*)?#{CONSTANTMATCH})+/
59
+
60
+ # Regular expression to match a method name
61
+ METHODNAMEMATCH = %r{[a-zA-Z_]\w*[!?=]?|[-+~]\@|<<|>>|=~|===?|![=~]?|<=>|[<>]=?|\*\*|[-/+%^&*~`|]|\[\]=?}
62
+
63
+ # Regular expression to match a fully qualified method def (self.foo, Class.foo).
64
+ METHODMATCH = /(?:(?:#{NAMESPACEMATCH}|[a-z]\w*)\s*(?:#{CSEPQ}|#{NSEPQ})\s*)?#{METHODNAMEMATCH}/
65
+
66
+ # All builtin Ruby exception classes for inheritance tree.
67
+ BUILTIN_EXCEPTIONS = ["ArgumentError", "ClosedQueueError", "EncodingError",
68
+ "EOFError", "Exception", "FiberError", "FloatDomainError", "IndexError",
69
+ "Interrupt", "IOError", "KeyError", "LoadError", "LocalJumpError",
70
+ "NameError", "NoMemoryError", "NoMethodError", "NotImplementedError",
71
+ "RangeError", "RegexpError", "RuntimeError", "ScriptError", "SecurityError",
72
+ "SignalException", "StandardError", "StopIteration", "SyntaxError",
73
+ "SystemCallError", "SystemExit", "SystemStackError", "ThreadError",
74
+ "TypeError", "UncaughtThrowError", "ZeroDivisionError"]
75
+
76
+ # All builtin Ruby classes for inheritance tree.
77
+ # @note MatchingData is a 1.8.x legacy class
78
+ BUILTIN_CLASSES = ["Array", "Bignum", "Binding", "Class", "Complex",
79
+ "ConditionVariable", "Data", "Dir", "Encoding", "Enumerator", "FalseClass",
80
+ "Fiber", "File", "Fixnum", "Float", "Hash", "IO", "Integer", "MatchData",
81
+ "Method", "Module", "NilClass", "Numeric", "Object", "Proc", "Queue",
82
+ "Random", "Range", "Rational", "Regexp", "RubyVM", "SizedQueue", "String",
83
+ "Struct", "Symbol", "Thread", "ThreadGroup", "Time", "TracePoint",
84
+ "TrueClass", "UnboundMethod"] + BUILTIN_EXCEPTIONS
85
+
86
+ # All builtin Ruby modules for mixin handling.
87
+ BUILTIN_MODULES = ["Comparable", "Enumerable", "Errno", "FileTest", "GC",
88
+ "Kernel", "Marshal", "Math", "ObjectSpace", "Precision", "Process", "Signal"]
89
+
90
+ # All builtin Ruby classes and modules.
91
+ BUILTIN_ALL = BUILTIN_CLASSES + BUILTIN_MODULES
92
+
93
+ # Hash of {BUILTIN_EXCEPTIONS} as keys and true as value (for O(1) lookups)
94
+ BUILTIN_EXCEPTIONS_HASH = BUILTIN_EXCEPTIONS.inject({}) {|h, n| h.update(n => true) }
95
+
96
+ # +Base+ is the superclass of all code objects recognized by YARD. A code
97
+ # object is any entity in the Ruby language (class, method, module). A
98
+ # DSL might subclass +Base+ to create a new custom object representing
99
+ # a new entity type.
100
+ #
101
+ # == Registry Integration
102
+ # Any created object associated with a namespace is immediately registered
103
+ # with the registry. This allows the Registry to act as an identity map
104
+ # to ensure that no object is represented by more than one Ruby object
105
+ # in memory. A unique {#path} is essential for this identity map to work
106
+ # correctly.
107
+ #
108
+ # == Custom Attributes
109
+ # Code objects allow arbitrary custom attributes to be set using the
110
+ # {#[]=} assignment method.
111
+ #
112
+ # == Namespaces
113
+ # There is a special type of object called a "namespace". These are subclasses
114
+ # of the {NamespaceObject} and represent Ruby entities that can have
115
+ # objects defined within them. Classically these are modules and classes,
116
+ # though a DSL might create a custom {NamespaceObject} to describe a
117
+ # specific set of objects.
118
+ #
119
+ # == Separators
120
+ # Custom classes with different separator tokens should define their own
121
+ # separators using the {NamespaceMapper.register_separator} method. The
122
+ # standard Ruby separators have already been defined ('::', '#', '.', etc).
123
+ #
124
+ # @abstract This class should not be used directly. Instead, create a
125
+ # subclass that implements {#path}, {#sep} or {#type}. You might also
126
+ # need to register custom separators if {#sep} uses alternate separator
127
+ # tokens.
128
+ # @see Registry
129
+ # @see #path
130
+ # @see #[]=
131
+ # @see NamespaceObject
132
+ # @see NamespaceMapper.register_separator
133
+ class Base
134
+ # The files the object was defined in. To add a file, use {#add_file}.
135
+ # @return [Array<Array(String, Integer)>] a list of files
136
+ # @see #add_file
137
+ attr_reader :files
138
+
139
+ # The namespace the object is defined in. If the object is in the
140
+ # top level namespace, this is {Registry.root}
141
+ # @return [NamespaceObject] the namespace object
142
+ attr_reader :namespace
143
+
144
+ # The source code associated with the object
145
+ # @return [String, nil] source, if present, or nil
146
+ attr_reader :source
147
+
148
+ # Language of the source code associated with the object. Defaults to
149
+ # +:ruby+.
150
+ #
151
+ # @return [Symbol] the language type
152
+ attr_accessor :source_type
153
+
154
+ # The one line signature representing an object. For a method, this will
155
+ # be of the form "def meth(arguments...)". This is usually the first
156
+ # source line.
157
+ #
158
+ # @return [String] a line of source
159
+ attr_accessor :signature
160
+
161
+ # The non-localized documentation string associated with the object
162
+ # @return [Docstring] the documentation string
163
+ # @since 0.8.4
164
+ attr_reader :base_docstring
165
+ undef base_docstring
166
+ def base_docstring; @docstring end
167
+
168
+ # Marks whether or not the method is conditionally defined at runtime
169
+ # @return [Boolean] true if the method is conditionally defined at runtime
170
+ attr_accessor :dynamic
171
+
172
+ # @return [String] the group this object is associated with
173
+ # @since 0.6.0
174
+ attr_accessor :group
175
+
176
+ # Is the object defined conditionally at runtime?
177
+ # @see #dynamic
178
+ def dynamic?; @dynamic end
179
+
180
+ # @return [Symbol] the visibility of an object (:public, :private, :protected)
181
+ attr_accessor :visibility
182
+ undef visibility=
183
+ def visibility=(v) @visibility = v.to_sym end
184
+
185
+ class << self
186
+ # Allocates a new code object
187
+ # @return [Base]
188
+ # @see #initialize
189
+ def new(namespace, name, *args, &block)
190
+ raise ArgumentError, "invalid empty object name" if name.to_s.empty?
191
+ if namespace.is_a?(ConstantObject)
192
+ namespace = Proxy.new(namespace.namespace, namespace.value)
193
+ end
194
+
195
+ if name.to_s[0, 2] == NSEP
196
+ name = name.to_s[2..-1]
197
+ namespace = Registry.root
198
+ end
199
+
200
+ if name =~ /(?:#{NSEPQ})([^:]+)$/
201
+ return new(Proxy.new(namespace, $`), $1, *args, &block)
202
+ end
203
+
204
+ obj = super(namespace, name, *args)
205
+ existing_obj = Registry.at(obj.path)
206
+ obj = existing_obj if existing_obj && existing_obj.class == self
207
+ yield(obj) if block_given?
208
+ obj
209
+ end
210
+
211
+ # Compares the class with subclasses
212
+ #
213
+ # @param [Object] other the other object to compare classes with
214
+ # @return [Boolean] true if other is a subclass of self
215
+ def ===(other)
216
+ other.is_a?(self)
217
+ end
218
+ end
219
+
220
+ # Creates a new code object
221
+ #
222
+ # @example Create a method in the root namespace
223
+ # CodeObjects::Base.new(:root, '#method') # => #<yardoc method #method>
224
+ # @example Create class Z inside namespace X::Y
225
+ # CodeObjects::Base.new(P("X::Y"), :Z) # or
226
+ # CodeObjects::Base.new(Registry.root, "X::Y")
227
+ # @param [NamespaceObject] namespace the namespace the object belongs in,
228
+ # {Registry.root} or :root should be provided if it is associated with
229
+ # the top level namespace.
230
+ # @param [Symbol, String] name the name (or complex path) of the object.
231
+ # @yield [self] a block to perform any extra initialization on the object
232
+ # @yieldparam [Base] self the newly initialized code object
233
+ # @return [Base] the newly created object
234
+ def initialize(namespace, name, *)
235
+ if namespace && namespace != :root &&
236
+ !namespace.is_a?(NamespaceObject) && !namespace.is_a?(Proxy)
237
+ raise ArgumentError, "Invalid namespace object: #{namespace}"
238
+ end
239
+
240
+ @files = []
241
+ @current_file_has_comments = false
242
+ @name = name.to_sym
243
+ @source_type = :ruby
244
+ @visibility = :public
245
+ @tags = []
246
+ @docstrings = {}
247
+ @docstring = Docstring.new!('', [], self)
248
+ @namespace = nil
249
+ self.namespace = namespace
250
+ yield(self) if block_given?
251
+ end
252
+
253
+ # Copies all data in this object to another code object, except for
254
+ # uniquely identifying information (path, namespace, name, scope).
255
+ #
256
+ # @param [Base] other the object to copy data to
257
+ # @return [Base] the other object
258
+ # @since 0.8.0
259
+ def copy_to(other)
260
+ copyable_attributes.each do |ivar|
261
+ ivar = "@#{ivar}"
262
+ other.instance_variable_set(ivar, instance_variable_get(ivar))
263
+ end
264
+ other.docstring = @docstring.to_raw
265
+ other
266
+ end
267
+
268
+ # The name of the object
269
+ # @param [Boolean] prefix whether to show a prefix. Implement
270
+ # this in a subclass to define how the prefix is showed.
271
+ # @return [Symbol] if prefix is false, the symbolized name
272
+ # @return [String] if prefix is true, prefix + the name as a String.
273
+ # This must be implemented by the subclass.
274
+ def name(prefix = false)
275
+ prefix ? @name.to_s : (defined?(@name) && @name)
276
+ end
277
+
278
+ # Associates a file with a code object, optionally adding the line where it was defined.
279
+ # By convention, '<stdin>' should be used to associate code that comes form standard input.
280
+ #
281
+ # @param [String] file the filename ('<stdin>' for standard input)
282
+ # @param [Fixnum, nil] line the line number where the object lies in the file
283
+ # @param [Boolean] has_comments whether or not the definition has comments associated. This
284
+ # will allow {#file} to return the definition where the comments were made instead
285
+ # of any empty definitions that might have been parsed before (module namespaces for instance).
286
+ def add_file(file, line = nil, has_comments = false)
287
+ raise(ArgumentError, "file cannot be nil or empty") if file.nil? || file == ''
288
+ obj = [file.to_s, line]
289
+ return if files.include?(obj)
290
+ if has_comments && !@current_file_has_comments
291
+ @current_file_has_comments = true
292
+ @files.unshift(obj)
293
+ else
294
+ @files << obj # back of the line
295
+ end
296
+ end
297
+
298
+ # Returns the filename the object was first parsed at, taking
299
+ # definitions with docstrings first.
300
+ #
301
+ # @return [String] a filename
302
+ def file
303
+ @files.first ? @files.first[0] : nil
304
+ end
305
+
306
+ # Returns the line the object was first parsed at (or nil)
307
+ #
308
+ # @return [Fixnum] the line where the object was first defined.
309
+ # @return [nil] if there is no line associated with the object
310
+ def line
311
+ @files.first ? @files.first[1] : nil
312
+ end
313
+
314
+ # Tests if another object is equal to this, including a proxy
315
+ # @param [Base, Proxy] other if other is a {Proxy}, tests if
316
+ # the paths are equal
317
+ # @return [Boolean] whether or not the objects are considered the same
318
+ def equal?(other)
319
+ if other.is_a?(Base) || other.is_a?(Proxy)
320
+ path == other.path
321
+ else
322
+ super
323
+ end
324
+ end
325
+ alias == equal?
326
+ alias eql? equal?
327
+
328
+ # @return [Integer] the object's hash value (for equality checking)
329
+ def hash; path.hash end
330
+
331
+ # @return [nil] this object does not turn into an array
332
+ def to_ary; nil end
333
+
334
+ # Accesses a custom attribute on the object
335
+ # @param [#to_s] key the name of the custom attribute
336
+ # @return [Object, nil] the custom attribute or nil if not found.
337
+ # @see #[]=
338
+ def [](key)
339
+ if respond_to?(key)
340
+ send(key)
341
+ elsif instance_variable_defined?("@#{key}")
342
+ instance_variable_get("@#{key}")
343
+ end
344
+ end
345
+
346
+ # Sets a custom attribute on the object
347
+ # @param [#to_s] key the name of the custom attribute
348
+ # @param [Object] value the value to associate
349
+ # @return [void]
350
+ # @see #[]
351
+ def []=(key, value)
352
+ if respond_to?("#{key}=")
353
+ send("#{key}=", value)
354
+ else
355
+ instance_variable_set("@#{key}", value)
356
+ end
357
+ end
358
+
359
+ # @overload dynamic_attr_name
360
+ # @return the value of attribute named by the method attribute name
361
+ # @raise [NoMethodError] if no method or custom attribute exists by
362
+ # the attribute name
363
+ # @see #[]
364
+ # @overload dynamic_attr_name=(value)
365
+ # @param value a value to set
366
+ # @return +value+
367
+ # @see #[]=
368
+ def method_missing(meth, *args, &block)
369
+ if meth.to_s =~ /=$/
370
+ self[meth.to_s[0..-2]] = args.first
371
+ elsif instance_variable_get("@#{meth}")
372
+ self[meth]
373
+ else
374
+ super
375
+ end
376
+ end
377
+
378
+ # Attaches source code to a code object with an optional file location
379
+ #
380
+ # @param [#source, String] statement
381
+ # the +Parser::Statement+ holding the source code or the raw source
382
+ # as a +String+ for the definition of the code object only (not the block)
383
+ def source=(statement)
384
+ if statement.respond_to?(:source)
385
+ self.signature = statement.first_line
386
+ @source = format_source(statement.source.strip)
387
+ else
388
+ @source = format_source(statement.to_s)
389
+ end
390
+ end
391
+
392
+ # The documentation string associated with the object
393
+ #
394
+ # @param [String, I18n::Locale] locale (I18n::Locale.default)
395
+ # the locale of the documentation string.
396
+ # @return [Docstring] the documentation string
397
+ def docstring(locale = I18n::Locale.default)
398
+ if locale.nil?
399
+ @docstring.resolve_reference
400
+ return @docstring
401
+ end
402
+
403
+ if locale.is_a?(String)
404
+ locale_name = locale
405
+ locale = nil
406
+ else
407
+ locale_name = locale.name
408
+ end
409
+ @docstrings[locale_name] ||=
410
+ translate_docstring(locale || Registry.locale(locale_name))
411
+ end
412
+
413
+ # Attaches a docstring to a code object by parsing the comments attached to the statement
414
+ # and filling the {#tags} and {#docstring} methods with the parsed information.
415
+ #
416
+ # @param [String, Array<String>, Docstring] comments
417
+ # the comments attached to the code object to be parsed
418
+ # into a docstring and meta tags.
419
+ def docstring=(comments)
420
+ @docstrings.clear
421
+ @docstring = Docstring === comments ?
422
+ comments : Docstring.new(comments, self)
423
+ end
424
+
425
+ # Default type is the lowercase class name without the "Object" suffix.
426
+ # Override this method to provide a custom object type
427
+ #
428
+ # @return [Symbol] the type of code object this represents
429
+ def type
430
+ self.class.name.split('::').last.gsub(/Object$/, '').downcase.to_sym
431
+ end
432
+
433
+ # Represents the unique path of the object. The default implementation
434
+ # joins the path of {#namespace} with {#name} via the value of {#sep}.
435
+ # Custom code objects should ensure that the path is unique to the code
436
+ # object by either overriding {#sep} or this method.
437
+ #
438
+ # @example The path of an instance method
439
+ # MethodObject.new(P("A::B"), :c).path # => "A::B#c"
440
+ # @return [String] the unique path of the object
441
+ # @see #sep
442
+ def path
443
+ @path ||= if parent && !parent.root?
444
+ [parent.path, name.to_s].join(sep)
445
+ else
446
+ name.to_s
447
+ end
448
+ end
449
+ alias to_s path
450
+
451
+ # @note
452
+ # Override this method if your object has a special title that does
453
+ # not match the {#path} attribute value. This title will be used
454
+ # when linking or displaying the object.
455
+ # @return [String] the display title for an object
456
+ # @see 0.8.4
457
+ def title
458
+ path
459
+ end
460
+
461
+ # @param [Base, String] other another code object (or object path)
462
+ # @return [String] the shortest relative path from this object to +other+
463
+ # @since 0.5.3
464
+ def relative_path(other)
465
+ other = Registry.at(other) if String === other && Registry.at(other)
466
+ same_parent = false
467
+ if other.respond_to?(:path)
468
+ same_parent = other.parent == parent
469
+ other = other.path
470
+ end
471
+ return other unless namespace
472
+ common = [path, other].join(" ").match(/^(\S*)\S*(?: \1\S*)*$/)[1]
473
+ common = path unless common =~ /(\.|::|#)$/
474
+ common = common.sub(/(\.|::|#)[^:#\.]*?$/, '') if same_parent
475
+ suffix = %w(. :).include?(common[-1, 1]) || other[common.size, 1] == '#' ?
476
+ '' : '(::|\.)'
477
+ result = other.sub(/^#{Regexp.quote common}#{suffix}/, '')
478
+ result.empty? ? other : result
479
+ end
480
+
481
+ # Renders the object using the {Templates::Engine templating system}.
482
+ #
483
+ # @example Formats a class in plaintext
484
+ # puts P('MyClass').format
485
+ # @example Formats a method in html with rdoc markup
486
+ # puts P('MyClass#meth').format(:format => :html, :markup => :rdoc)
487
+ # @param [Hash] options a set of options to pass to the template
488
+ # @option options [Symbol] :format (:text) :html, :text or another output format
489
+ # @option options [Symbol] :template (:default) a specific template to use
490
+ # @option options [Symbol] :markup (nil) the markup type (:rdoc, :markdown, :textile)
491
+ # @option options [Serializers::Base] :serializer (nil) see Serializers
492
+ # @return [String] the rendered template
493
+ # @see Templates::Engine#render
494
+ def format(options = {})
495
+ options = options.merge(:object => self)
496
+ options = options.merge(:type => type) unless options[:type]
497
+ Templates::Engine.render(options)
498
+ end
499
+
500
+ # Inspects the object, returning the type and path
501
+ # @return [String] a string describing the object
502
+ def inspect
503
+ "#<yardoc #{type} #{path}>"
504
+ end
505
+
506
+ # Sets the namespace the object is defined in.
507
+ #
508
+ # @param [NamespaceObject, :root, nil] obj the new namespace (:root
509
+ # for {Registry.root}). If obj is nil, the object is unregistered
510
+ # from the Registry.
511
+ def namespace=(obj)
512
+ if @namespace
513
+ @namespace.children.delete(self)
514
+ Registry.delete(self)
515
+ end
516
+
517
+ @namespace = (obj == :root ? Registry.root : obj)
518
+
519
+ if @namespace
520
+ reg_obj = Registry.at(path)
521
+ return if reg_obj && reg_obj.class == self.class
522
+
523
+ unless @namespace.is_a?(Proxy)
524
+ # remove prior objects from obj's children that match this one
525
+ @namespace.children.delete_if {|o| o.path == path }
526
+ @namespace.children << self
527
+ end
528
+ Registry.register(self)
529
+ end
530
+ end
531
+
532
+ alias parent namespace
533
+ alias parent= namespace=
534
+
535
+ # Gets a tag from the {#docstring}
536
+ # @see Docstring#tag
537
+ def tag(name); docstring.tag(name) end
538
+
539
+ # Gets a list of tags from the {#docstring}
540
+ # @see Docstring#tags
541
+ def tags(name = nil); docstring.tags(name) end
542
+
543
+ # Tests if the {#docstring} has a tag
544
+ # @see Docstring#has_tag?
545
+ def has_tag?(name); docstring.has_tag?(name) end
546
+
547
+ # Add tags to the {#docstring}
548
+ # @see Docstring#add_tag
549
+ # @since 0.8.4
550
+ def add_tag(*tags)
551
+ @docstrings.clear
552
+ @docstring.add_tag(*tags)
553
+ end
554
+
555
+ # @return whether or not this object is a RootObject
556
+ def root?; false end
557
+
558
+ # Override this method with a custom component separator. For instance,
559
+ # {MethodObject} implements sep as '#' or '.' (depending on if the
560
+ # method is instance or class respectively). {#path} depends on this
561
+ # value to generate the full path in the form: namespace.path + sep + name
562
+ #
563
+ # @return [String] the component that separates the namespace path
564
+ # and the name (default is {NSEP})
565
+ def sep; NSEP end
566
+
567
+ protected
568
+
569
+ # Override this method if your code object subclass does not allow
570
+ # copying of certain attributes.
571
+ #
572
+ # @return [Array<String>] the list of instance variable names (without
573
+ # "@" prefix) that should be copied when {#copy_to} is called
574
+ # @see #copy_to
575
+ # @since 0.8.0
576
+ def copyable_attributes
577
+ vars = instance_variables.map {|ivar| ivar.to_s[1..-1] }
578
+ vars -= %w(docstring docstrings namespace name path)
579
+ vars
580
+ end
581
+
582
+ private
583
+
584
+ # Formats source code by removing leading indentation
585
+ #
586
+ # @param [String] source the source code to format
587
+ # @return [String] formatted source
588
+ def format_source(source)
589
+ source = source.chomp
590
+ last = source.split(/\r?\n/).last
591
+ indent = last ? last[/^([ \t]*)/, 1].length : 0
592
+ source.gsub(/^[ \t]{#{indent}}/, '')
593
+ end
594
+
595
+ def translate_docstring(locale)
596
+ @docstring.resolve_reference
597
+ return @docstring if locale.nil?
598
+
599
+ text = I18n::Text.new(@docstring)
600
+ localized_text = text.translate(locale)
601
+ docstring = Docstring.new(localized_text, self)
602
+ @docstring.tags.each do |tag|
603
+ if tag.is_a?(Tags::Tag)
604
+ localized_tag = tag.clone
605
+ localized_tag.text = I18n::Text.new(tag.text).translate(locale)
606
+ docstring.add_tag(localized_tag)
607
+ else
608
+ docstring.add_tag(tag)
609
+ end
610
+ end
611
+ docstring
612
+ end
613
+ end
614
+ end
615
+ end