yard 0.9.18 → 0.9.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +26 -26
  3. data/CHANGELOG.md +742 -728
  4. data/LEGAL +66 -66
  5. data/LICENSE +22 -22
  6. data/README.md +328 -328
  7. data/Rakefile +42 -53
  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 +308 -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 +789 -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 -615
  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 +134 -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 +11 -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 -386
  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 +212 -211
  95. data/lib/yard/handlers/c/init_handler.rb +20 -20
  96. data/lib/yard/handlers/c/method_handler.rb +45 -45
  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/common/method_handler.rb +19 -0
  104. data/lib/yard/handlers/processor.rb +200 -200
  105. data/lib/yard/handlers/ruby/alias_handler.rb +44 -44
  106. data/lib/yard/handlers/ruby/attribute_handler.rb +87 -87
  107. data/lib/yard/handlers/ruby/base.rb +165 -165
  108. data/lib/yard/handlers/ruby/class_condition_handler.rb +92 -92
  109. data/lib/yard/handlers/ruby/class_handler.rb +119 -119
  110. data/lib/yard/handlers/ruby/class_variable_handler.rb +17 -17
  111. data/lib/yard/handlers/ruby/comment_handler.rb +10 -10
  112. data/lib/yard/handlers/ruby/constant_handler.rb +59 -59
  113. data/lib/yard/handlers/ruby/decorator_handler_methods.rb +123 -123
  114. data/lib/yard/handlers/ruby/dsl_handler.rb +15 -15
  115. data/lib/yard/handlers/ruby/dsl_handler_methods.rb +96 -96
  116. data/lib/yard/handlers/ruby/exception_handler.rb +27 -27
  117. data/lib/yard/handlers/ruby/extend_handler.rb +22 -22
  118. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +37 -37
  119. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +65 -65
  120. data/lib/yard/handlers/ruby/legacy/base.rb +245 -245
  121. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +83 -83
  122. data/lib/yard/handlers/ruby/legacy/class_handler.rb +113 -113
  123. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +15 -15
  124. data/lib/yard/handlers/ruby/legacy/comment_handler.rb +10 -10
  125. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +29 -29
  126. data/lib/yard/handlers/ruby/legacy/dsl_handler.rb +17 -17
  127. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +13 -13
  128. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +21 -21
  129. data/lib/yard/handlers/ruby/legacy/method_handler.rb +90 -90
  130. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +39 -39
  131. data/lib/yard/handlers/ruby/legacy/module_function_handler.rb +19 -19
  132. data/lib/yard/handlers/ruby/legacy/module_handler.rb +12 -12
  133. data/lib/yard/handlers/ruby/legacy/private_class_method_handler.rb +22 -22
  134. data/lib/yard/handlers/ruby/legacy/private_constant_handler.rb +22 -22
  135. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +17 -17
  136. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +29 -29
  137. data/lib/yard/handlers/ruby/method_condition_handler.rb +9 -9
  138. data/lib/yard/handlers/ruby/method_handler.rb +114 -118
  139. data/lib/yard/handlers/ruby/mixin_handler.rb +37 -37
  140. data/lib/yard/handlers/ruby/module_function_handler.rb +27 -27
  141. data/lib/yard/handlers/ruby/module_handler.rb +12 -12
  142. data/lib/yard/handlers/ruby/private_class_method_handler.rb +14 -14
  143. data/lib/yard/handlers/ruby/private_constant_handler.rb +43 -43
  144. data/lib/yard/handlers/ruby/public_class_method_handler.rb +14 -14
  145. data/lib/yard/handlers/ruby/struct_handler_methods.rb +143 -143
  146. data/lib/yard/handlers/ruby/visibility_handler.rb +22 -22
  147. data/lib/yard/handlers/ruby/yield_handler.rb +31 -31
  148. data/lib/yard/i18n/locale.rb +67 -67
  149. data/lib/yard/i18n/message.rb +57 -57
  150. data/lib/yard/i18n/messages.rb +56 -56
  151. data/lib/yard/i18n/po_parser.rb +61 -61
  152. data/lib/yard/i18n/pot_generator.rb +290 -290
  153. data/lib/yard/i18n/text.rb +173 -173
  154. data/lib/yard/logging.rb +205 -205
  155. data/lib/yard/options.rb +217 -217
  156. data/lib/yard/parser/base.rb +57 -57
  157. data/lib/yard/parser/c/c_parser.rb +235 -235
  158. data/lib/yard/parser/c/comment_parser.rb +134 -134
  159. data/lib/yard/parser/c/statement.rb +64 -64
  160. data/lib/yard/parser/ruby/ast_node.rb +540 -540
  161. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +1354 -1354
  162. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +32 -32
  163. data/lib/yard/parser/ruby/legacy/statement.rb +66 -66
  164. data/lib/yard/parser/ruby/legacy/statement_list.rb +394 -394
  165. data/lib/yard/parser/ruby/legacy/token_list.rb +74 -74
  166. data/lib/yard/parser/ruby/ruby_parser.rb +687 -687
  167. data/lib/yard/parser/ruby/token_resolver.rb +156 -156
  168. data/lib/yard/parser/source_parser.rb +526 -526
  169. data/lib/yard/rake/yardoc_task.rb +81 -81
  170. data/lib/yard/registry.rb +439 -439
  171. data/lib/yard/registry_resolver.rb +189 -189
  172. data/lib/yard/registry_store.rb +337 -337
  173. data/lib/yard/rubygems/backports.rb +10 -10
  174. data/lib/yard/rubygems/backports/LICENSE.txt +57 -57
  175. data/lib/yard/rubygems/backports/MIT.txt +20 -20
  176. data/lib/yard/rubygems/backports/gem.rb +10 -10
  177. data/lib/yard/rubygems/backports/source_index.rb +365 -365
  178. data/lib/yard/rubygems/doc_manager.rb +90 -90
  179. data/lib/yard/rubygems/hook.rb +197 -197
  180. data/lib/yard/rubygems/specification.rb +50 -50
  181. data/lib/yard/serializers/base.rb +83 -83
  182. data/lib/yard/serializers/file_system_serializer.rb +123 -123
  183. data/lib/yard/serializers/process_serializer.rb +24 -24
  184. data/lib/yard/serializers/stdout_serializer.rb +34 -34
  185. data/lib/yard/serializers/yardoc_serializer.rb +152 -152
  186. data/lib/yard/server.rb +13 -13
  187. data/lib/yard/server/adapter.rb +100 -100
  188. data/lib/yard/server/commands/base.rb +209 -209
  189. data/lib/yard/server/commands/display_file_command.rb +29 -29
  190. data/lib/yard/server/commands/display_object_command.rb +65 -65
  191. data/lib/yard/server/commands/frames_command.rb +16 -16
  192. data/lib/yard/server/commands/library_command.rb +187 -187
  193. data/lib/yard/server/commands/library_index_command.rb +28 -28
  194. data/lib/yard/server/commands/list_command.rb +25 -25
  195. data/lib/yard/server/commands/root_request_command.rb +15 -15
  196. data/lib/yard/server/commands/search_command.rb +79 -79
  197. data/lib/yard/server/commands/static_file_command.rb +23 -23
  198. data/lib/yard/server/commands/static_file_helpers.rb +62 -62
  199. data/lib/yard/server/doc_server_helper.rb +91 -91
  200. data/lib/yard/server/doc_server_serializer.rb +39 -39
  201. data/lib/yard/server/library_version.rb +277 -277
  202. data/lib/yard/server/rack_adapter.rb +89 -89
  203. data/lib/yard/server/router.rb +187 -187
  204. data/lib/yard/server/static_caching.rb +46 -46
  205. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +127 -127
  206. data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +11 -11
  207. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +37 -37
  208. data/lib/yard/server/templates/default/layout/html/script_setup.erb +7 -7
  209. data/lib/yard/server/templates/default/layout/html/setup.rb +8 -8
  210. data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -4
  211. data/lib/yard/server/templates/default/method_details/html/setup.rb +5 -5
  212. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +8 -8
  213. data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +14 -14
  214. data/lib/yard/server/templates/doc_server/library_list/html/listing.erb +13 -13
  215. data/lib/yard/server/templates/doc_server/library_list/html/setup.rb +6 -6
  216. data/lib/yard/server/templates/doc_server/library_list/html/title.erb +2 -2
  217. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +52 -52
  218. data/lib/yard/server/templates/doc_server/processing/html/setup.rb +4 -4
  219. data/lib/yard/server/templates/doc_server/search/html/search.erb +18 -18
  220. data/lib/yard/server/templates/doc_server/search/html/setup.rb +9 -9
  221. data/lib/yard/server/webrick_adapter.rb +45 -45
  222. data/lib/yard/tags/default_factory.rb +191 -191
  223. data/lib/yard/tags/default_tag.rb +13 -13
  224. data/lib/yard/tags/directives.rb +616 -616
  225. data/lib/yard/tags/library.rb +633 -633
  226. data/lib/yard/tags/option_tag.rb +13 -13
  227. data/lib/yard/tags/overload_tag.rb +71 -71
  228. data/lib/yard/tags/ref_tag.rb +8 -8
  229. data/lib/yard/tags/ref_tag_list.rb +28 -28
  230. data/lib/yard/tags/tag.rb +71 -71
  231. data/lib/yard/tags/tag_format_error.rb +7 -7
  232. data/lib/yard/tags/types_explainer.rb +162 -162
  233. data/lib/yard/templates/engine.rb +186 -186
  234. data/lib/yard/templates/erb_cache.rb +23 -23
  235. data/lib/yard/templates/helpers/base_helper.rb +215 -215
  236. data/lib/yard/templates/helpers/filter_helper.rb +27 -27
  237. data/lib/yard/templates/helpers/html_helper.rb +646 -646
  238. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +78 -78
  239. data/lib/yard/templates/helpers/markup/rdoc_markdown.rb +23 -23
  240. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +109 -109
  241. data/lib/yard/templates/helpers/markup_helper.rb +172 -172
  242. data/lib/yard/templates/helpers/method_helper.rb +75 -75
  243. data/lib/yard/templates/helpers/module_helper.rb +21 -21
  244. data/lib/yard/templates/helpers/text_helper.rb +112 -112
  245. data/lib/yard/templates/helpers/uml_helper.rb +47 -47
  246. data/lib/yard/templates/section.rb +105 -105
  247. data/lib/yard/templates/template.rb +418 -418
  248. data/lib/yard/templates/template_options.rb +92 -92
  249. data/lib/yard/verifier.rb +151 -151
  250. data/lib/yard/version.rb +6 -6
  251. data/spec/cli/command_parser_spec.rb +43 -43
  252. data/spec/cli/command_spec.rb +36 -36
  253. data/spec/cli/config_spec.rb +148 -148
  254. data/spec/cli/diff_spec.rb +254 -254
  255. data/spec/cli/display_spec.rb +30 -30
  256. data/spec/cli/gems_spec.rb +81 -81
  257. data/spec/cli/graph_spec.rb +18 -18
  258. data/spec/cli/help_spec.rb +22 -22
  259. data/spec/cli/i18n_spec.rb +107 -107
  260. data/spec/cli/list_spec.rb +8 -8
  261. data/spec/cli/markup_types_spec.rb +22 -22
  262. data/spec/cli/server_spec.rb +324 -324
  263. data/spec/cli/stats_spec.rb +96 -96
  264. data/spec/cli/yard_on_yard_spec.rb +38 -38
  265. data/spec/cli/yardoc_spec.rb +896 -862
  266. data/spec/cli/yri_spec.rb +101 -101
  267. data/spec/code_objects/base_spec.rb +470 -470
  268. data/spec/code_objects/class_object_spec.rb +226 -226
  269. data/spec/code_objects/code_object_list_spec.rb +36 -36
  270. data/spec/code_objects/constants_spec.rb +116 -116
  271. data/spec/code_objects/extra_file_object_spec.rb +160 -160
  272. data/spec/code_objects/macro_object_spec.rb +150 -150
  273. data/spec/code_objects/method_object_spec.rb +184 -184
  274. data/spec/code_objects/module_object_spec.rb +142 -142
  275. data/spec/code_objects/namespace_object_spec.rb +171 -171
  276. data/spec/code_objects/proxy_spec.rb +141 -141
  277. data/spec/code_objects/spec_helper.rb +3 -3
  278. data/spec/config_spec.rb +171 -171
  279. data/spec/core_ext/array_spec.rb +13 -13
  280. data/spec/core_ext/file_spec.rb +72 -72
  281. data/spec/core_ext/hash_spec.rb +14 -14
  282. data/spec/core_ext/insertion_spec.rb +37 -37
  283. data/spec/core_ext/module_spec.rb +9 -15
  284. data/spec/core_ext/string_spec.rb +42 -42
  285. data/spec/core_ext/symbol_hash_spec.rb +89 -89
  286. data/spec/docstring_parser_spec.rb +280 -280
  287. data/spec/docstring_spec.rb +373 -373
  288. data/spec/examples.txt +1883 -1875
  289. data/spec/handlers/alias_handler_spec.rb +82 -82
  290. data/spec/handlers/attribute_handler_spec.rb +96 -96
  291. data/spec/handlers/base_spec.rb +216 -216
  292. data/spec/handlers/c/alias_handler_spec.rb +34 -34
  293. data/spec/handlers/c/attribute_handler_spec.rb +41 -41
  294. data/spec/handlers/c/class_handler_spec.rb +78 -78
  295. data/spec/handlers/c/constant_handler_spec.rb +71 -71
  296. data/spec/handlers/c/init_handler_spec.rb +48 -48
  297. data/spec/handlers/c/method_handler_spec.rb +327 -325
  298. data/spec/handlers/c/mixin_handler_spec.rb +44 -44
  299. data/spec/handlers/c/module_handler_spec.rb +71 -71
  300. data/spec/handlers/c/override_comment_handler_spec.rb +47 -47
  301. data/spec/handlers/c/path_handler_spec.rb +36 -36
  302. data/spec/handlers/c/spec_helper.rb +23 -23
  303. data/spec/handlers/c/struct_handler_spec.rb +16 -16
  304. data/spec/handlers/class_condition_handler_spec.rb +87 -87
  305. data/spec/handlers/class_handler_spec.rb +247 -247
  306. data/spec/handlers/class_method_handler_shared_examples.rb +133 -133
  307. data/spec/handlers/class_variable_handler_spec.rb +12 -12
  308. data/spec/handlers/constant_handler_spec.rb +112 -112
  309. data/spec/handlers/decorator_handler_methods_spec.rb +393 -393
  310. data/spec/handlers/dsl_handler_spec.rb +219 -219
  311. data/spec/handlers/examples/alias_handler_001.rb.txt +45 -45
  312. data/spec/handlers/examples/attribute_handler_001.rb.txt +31 -31
  313. data/spec/handlers/examples/class_condition_handler_001.rb.txt +68 -68
  314. data/spec/handlers/examples/class_handler_001.rb.txt +120 -120
  315. data/spec/handlers/examples/class_variable_handler_001.rb.txt +9 -9
  316. data/spec/handlers/examples/constant_handler_001.rb.txt +35 -35
  317. data/spec/handlers/examples/dsl_handler_001.rb.txt +154 -154
  318. data/spec/handlers/examples/exception_handler_001.rb.txt +58 -58
  319. data/spec/handlers/examples/extend_handler_001.rb.txt +15 -15
  320. data/spec/handlers/examples/method_condition_handler_001.rb.txt +9 -9
  321. data/spec/handlers/examples/method_handler_001.rb.txt +128 -128
  322. data/spec/handlers/examples/mixin_handler_001.rb.txt +37 -37
  323. data/spec/handlers/examples/module_handler_001.rb.txt +29 -29
  324. data/spec/handlers/examples/private_constant_handler_001.rb.txt +8 -8
  325. data/spec/handlers/examples/process_handler_001.rb.txt +11 -11
  326. data/spec/handlers/examples/visibility_handler_001.rb.txt +35 -35
  327. data/spec/handlers/examples/yield_handler_001.rb.txt +54 -54
  328. data/spec/handlers/exception_handler_spec.rb +49 -49
  329. data/spec/handlers/extend_handler_spec.rb +24 -24
  330. data/spec/handlers/legacy_base_spec.rb +128 -128
  331. data/spec/handlers/method_condition_handler_spec.rb +15 -15
  332. data/spec/handlers/method_handler_spec.rb +190 -190
  333. data/spec/handlers/mixin_handler_spec.rb +56 -56
  334. data/spec/handlers/module_function_handler_spec.rb +106 -106
  335. data/spec/handlers/module_handler_spec.rb +35 -35
  336. data/spec/handlers/private_class_method_handler_spec.rb +11 -11
  337. data/spec/handlers/private_constant_handler_spec.rb +25 -25
  338. data/spec/handlers/processor_spec.rb +35 -35
  339. data/spec/handlers/public_class_method_handler_spec.rb +11 -11
  340. data/spec/handlers/ruby/base_spec.rb +95 -95
  341. data/spec/handlers/ruby/legacy/base_spec.rb +84 -84
  342. data/spec/handlers/spec_helper.rb +33 -33
  343. data/spec/handlers/visibility_handler_spec.rb +44 -44
  344. data/spec/handlers/yield_handler_spec.rb +52 -52
  345. data/spec/i18n/locale_spec.rb +81 -81
  346. data/spec/i18n/message_spec.rb +52 -52
  347. data/spec/i18n/messages_spec.rb +67 -67
  348. data/spec/i18n/pot_generator_spec.rb +295 -295
  349. data/spec/i18n/text_spec.rb +184 -184
  350. data/spec/logging_spec.rb +44 -44
  351. data/spec/options_spec.rb +171 -171
  352. data/spec/parser/base_spec.rb +24 -24
  353. data/spec/parser/c_parser_spec.rb +236 -236
  354. data/spec/parser/examples/array.c.txt +6267 -6267
  355. data/spec/parser/examples/example1.rb.txt +7 -7
  356. data/spec/parser/examples/extrafile.c.txt +8 -8
  357. data/spec/parser/examples/file.c.txt +28 -28
  358. data/spec/parser/examples/multifile.c.txt +22 -22
  359. data/spec/parser/examples/namespace.cpp.txt +68 -68
  360. data/spec/parser/examples/override.c.txt +424 -424
  361. data/spec/parser/examples/parse_in_order_001.rb.txt +2 -2
  362. data/spec/parser/examples/parse_in_order_002.rb.txt +1 -1
  363. data/spec/parser/examples/tag_handler_001.rb.txt +7 -7
  364. data/spec/parser/ruby/ast_node_spec.rb +33 -33
  365. data/spec/parser/ruby/legacy/statement_list_spec.rb +299 -299
  366. data/spec/parser/ruby/legacy/token_list_spec.rb +79 -79
  367. data/spec/parser/ruby/ruby_parser_spec.rb +508 -508
  368. data/spec/parser/ruby/token_resolver_spec.rb +165 -165
  369. data/spec/parser/source_parser_spec.rb +727 -727
  370. data/spec/parser/tag_parsing_spec.rb +17 -17
  371. data/spec/rake/yardoc_task_spec.rb +118 -118
  372. data/spec/registry_spec.rb +463 -463
  373. data/spec/registry_store_spec.rb +316 -316
  374. data/spec/rubygems/doc_manager_spec.rb +112 -112
  375. data/spec/serializers/data/serialized_yardoc/checksums +1 -1
  376. data/spec/serializers/file_system_serializer_spec.rb +145 -145
  377. data/spec/serializers/spec_helper.rb +2 -2
  378. data/spec/serializers/yardoc_serializer_spec.rb +78 -78
  379. data/spec/server/adapter_spec.rb +39 -39
  380. data/spec/server/commands/base_spec.rb +91 -91
  381. data/spec/server/commands/library_command_spec.rb +39 -39
  382. data/spec/server/doc_server_helper_spec.rb +72 -72
  383. data/spec/server/doc_server_serializer_spec.rb +60 -60
  384. data/spec/server/rack_adapter_spec.rb +21 -21
  385. data/spec/server/router_spec.rb +123 -123
  386. data/spec/server/spec_helper.rb +22 -22
  387. data/spec/server/static_caching_spec.rb +47 -47
  388. data/spec/server/webrick_servlet_spec.rb +20 -20
  389. data/spec/server_spec.rb +19 -19
  390. data/spec/spec_helper.rb +212 -212
  391. data/spec/tags/default_factory_spec.rb +168 -168
  392. data/spec/tags/default_tag_spec.rb +11 -11
  393. data/spec/tags/directives_spec.rb +463 -463
  394. data/spec/tags/library_spec.rb +48 -48
  395. data/spec/tags/overload_tag_spec.rb +53 -53
  396. data/spec/tags/ref_tag_list_spec.rb +53 -53
  397. data/spec/tags/types_explainer_spec.rb +203 -203
  398. data/spec/templates/class_spec.rb +45 -45
  399. data/spec/templates/constant_spec.rb +41 -41
  400. data/spec/templates/engine_spec.rb +131 -131
  401. data/spec/templates/examples/class001.html +308 -308
  402. data/spec/templates/examples/class001.txt +36 -36
  403. data/spec/templates/examples/class002.html +39 -39
  404. data/spec/templates/examples/constant001.txt +24 -24
  405. data/spec/templates/examples/constant002.txt +6 -6
  406. data/spec/templates/examples/constant003.txt +10 -10
  407. data/spec/templates/examples/method001.html +137 -137
  408. data/spec/templates/examples/method001.txt +35 -35
  409. data/spec/templates/examples/method002.html +91 -91
  410. data/spec/templates/examples/method002.txt +20 -20
  411. data/spec/templates/examples/method003.html +165 -165
  412. data/spec/templates/examples/method003.txt +45 -45
  413. data/spec/templates/examples/method004.html +48 -48
  414. data/spec/templates/examples/method004.txt +10 -10
  415. data/spec/templates/examples/method005.html +105 -105
  416. data/spec/templates/examples/method005.txt +33 -33
  417. data/spec/templates/examples/method006.html +107 -107
  418. data/spec/templates/examples/method006.txt +20 -20
  419. data/spec/templates/examples/module001.dot +33 -33
  420. data/spec/templates/examples/module001.html +833 -833
  421. data/spec/templates/examples/module001.txt +33 -33
  422. data/spec/templates/examples/module002.html +341 -341
  423. data/spec/templates/examples/module003.html +202 -202
  424. data/spec/templates/examples/module004.html +394 -394
  425. data/spec/templates/examples/module005.html +81 -81
  426. data/spec/templates/examples/tag001.txt +82 -82
  427. data/spec/templates/helpers/base_helper_spec.rb +171 -171
  428. data/spec/templates/helpers/html_helper_spec.rb +687 -668
  429. data/spec/templates/helpers/html_syntax_highlight_helper_spec.rb +65 -65
  430. data/spec/templates/helpers/markup/rdoc_markup_spec.rb +84 -84
  431. data/spec/templates/helpers/markup_helper_spec.rb +136 -136
  432. data/spec/templates/helpers/method_helper_spec.rb +107 -107
  433. data/spec/templates/helpers/module_helper_spec.rb +35 -35
  434. data/spec/templates/helpers/shared_signature_examples.rb +126 -126
  435. data/spec/templates/helpers/text_helper_spec.rb +65 -65
  436. data/spec/templates/method_spec.rb +118 -118
  437. data/spec/templates/module_spec.rb +203 -203
  438. data/spec/templates/onefile_spec.rb +66 -66
  439. data/spec/templates/section_spec.rb +144 -144
  440. data/spec/templates/spec_helper.rb +76 -76
  441. data/spec/templates/tag_spec.rb +52 -52
  442. data/spec/templates/template_spec.rb +410 -410
  443. data/spec/verifier_spec.rb +106 -106
  444. data/templates/default/class/dot/setup.rb +7 -7
  445. data/templates/default/class/dot/superklass.erb +2 -2
  446. data/templates/default/class/html/constructor_details.erb +8 -8
  447. data/templates/default/class/html/setup.rb +2 -2
  448. data/templates/default/class/html/subclasses.erb +4 -4
  449. data/templates/default/class/setup.rb +36 -36
  450. data/templates/default/class/text/setup.rb +12 -12
  451. data/templates/default/class/text/subclasses.erb +5 -5
  452. data/templates/default/constant/text/header.erb +11 -11
  453. data/templates/default/constant/text/setup.rb +4 -4
  454. data/templates/default/docstring/html/abstract.erb +4 -4
  455. data/templates/default/docstring/html/deprecated.erb +1 -1
  456. data/templates/default/docstring/html/index.erb +5 -5
  457. data/templates/default/docstring/html/note.erb +6 -6
  458. data/templates/default/docstring/html/private.erb +4 -4
  459. data/templates/default/docstring/html/text.erb +1 -1
  460. data/templates/default/docstring/html/todo.erb +6 -6
  461. data/templates/default/docstring/setup.rb +52 -52
  462. data/templates/default/docstring/text/abstract.erb +2 -2
  463. data/templates/default/docstring/text/deprecated.erb +2 -2
  464. data/templates/default/docstring/text/index.erb +2 -2
  465. data/templates/default/docstring/text/note.erb +3 -3
  466. data/templates/default/docstring/text/private.erb +2 -2
  467. data/templates/default/docstring/text/text.erb +1 -1
  468. data/templates/default/docstring/text/todo.erb +3 -3
  469. data/templates/default/fulldoc/html/css/full_list.css +58 -58
  470. data/templates/default/fulldoc/html/css/style.css +496 -496
  471. data/templates/default/fulldoc/html/frames.erb +17 -17
  472. data/templates/default/fulldoc/html/full_list.erb +37 -37
  473. data/templates/default/fulldoc/html/full_list_class.erb +2 -2
  474. data/templates/default/fulldoc/html/full_list_file.erb +7 -7
  475. data/templates/default/fulldoc/html/full_list_method.erb +10 -10
  476. data/templates/default/fulldoc/html/js/app.js +303 -292
  477. data/templates/default/fulldoc/html/js/full_list.js +216 -216
  478. data/templates/default/fulldoc/html/js/jquery.js +3 -3
  479. data/templates/default/fulldoc/html/setup.rb +241 -241
  480. data/templates/default/layout/dot/header.erb +5 -5
  481. data/templates/default/layout/dot/setup.rb +15 -15
  482. data/templates/default/layout/html/breadcrumb.erb +11 -11
  483. data/templates/default/layout/html/files.erb +11 -11
  484. data/templates/default/layout/html/footer.erb +5 -5
  485. data/templates/default/layout/html/headers.erb +15 -15
  486. data/templates/default/layout/html/index.erb +2 -2
  487. data/templates/default/layout/html/layout.erb +23 -23
  488. data/templates/default/layout/html/listing.erb +4 -4
  489. data/templates/default/layout/html/objects.erb +32 -32
  490. data/templates/default/layout/html/script_setup.erb +4 -4
  491. data/templates/default/layout/html/search.erb +12 -12
  492. data/templates/default/layout/html/setup.rb +89 -89
  493. data/templates/default/method/html/header.erb +16 -16
  494. data/templates/default/method/setup.rb +4 -4
  495. data/templates/default/method_details/html/header.erb +2 -2
  496. data/templates/default/method_details/html/method_signature.erb +24 -24
  497. data/templates/default/method_details/html/source.erb +9 -9
  498. data/templates/default/method_details/setup.rb +11 -11
  499. data/templates/default/method_details/text/header.erb +10 -10
  500. data/templates/default/method_details/text/method_signature.erb +12 -12
  501. data/templates/default/method_details/text/setup.rb +11 -11
  502. data/templates/default/module/dot/child.erb +1 -1
  503. data/templates/default/module/dot/dependencies.erb +2 -2
  504. data/templates/default/module/dot/header.erb +6 -6
  505. data/templates/default/module/dot/info.erb +13 -13
  506. data/templates/default/module/dot/setup.rb +15 -15
  507. data/templates/default/module/html/attribute_details.erb +10 -10
  508. data/templates/default/module/html/attribute_summary.erb +8 -8
  509. data/templates/default/module/html/box_info.erb +43 -43
  510. data/templates/default/module/html/children.erb +8 -8
  511. data/templates/default/module/html/constant_summary.erb +17 -17
  512. data/templates/default/module/html/defines.erb +2 -2
  513. data/templates/default/module/html/header.erb +5 -5
  514. data/templates/default/module/html/inherited_attributes.erb +14 -14
  515. data/templates/default/module/html/inherited_constants.erb +8 -8
  516. data/templates/default/module/html/inherited_methods.erb +18 -18
  517. data/templates/default/module/html/item_summary.erb +40 -40
  518. data/templates/default/module/html/method_details_list.erb +9 -9
  519. data/templates/default/module/html/method_summary.erb +13 -13
  520. data/templates/default/module/html/methodmissing.erb +12 -12
  521. data/templates/default/module/setup.rb +167 -167
  522. data/templates/default/module/text/children.erb +9 -9
  523. data/templates/default/module/text/class_meths_list.erb +7 -7
  524. data/templates/default/module/text/extends.erb +7 -7
  525. data/templates/default/module/text/header.erb +7 -7
  526. data/templates/default/module/text/includes.erb +7 -7
  527. data/templates/default/module/text/instance_meths_list.erb +7 -7
  528. data/templates/default/module/text/setup.rb +13 -13
  529. data/templates/default/onefile/html/files.erb +4 -4
  530. data/templates/default/onefile/html/headers.erb +6 -6
  531. data/templates/default/onefile/html/layout.erb +17 -17
  532. data/templates/default/onefile/html/readme.erb +2 -2
  533. data/templates/default/onefile/html/setup.rb +62 -62
  534. data/templates/default/root/dot/child.erb +2 -2
  535. data/templates/default/root/dot/setup.rb +6 -6
  536. data/templates/default/root/html/setup.rb +2 -2
  537. data/templates/default/tags/html/example.erb +10 -10
  538. data/templates/default/tags/html/index.erb +2 -2
  539. data/templates/default/tags/html/option.erb +24 -24
  540. data/templates/default/tags/html/overload.erb +13 -13
  541. data/templates/default/tags/html/see.erb +7 -7
  542. data/templates/default/tags/html/tag.erb +20 -20
  543. data/templates/default/tags/setup.rb +57 -57
  544. data/templates/default/tags/text/example.erb +12 -12
  545. data/templates/default/tags/text/index.erb +1 -1
  546. data/templates/default/tags/text/option.erb +20 -20
  547. data/templates/default/tags/text/overload.erb +19 -19
  548. data/templates/default/tags/text/see.erb +11 -11
  549. data/templates/default/tags/text/tag.erb +13 -13
  550. data/templates/guide/class/html/setup.rb +2 -2
  551. data/templates/guide/docstring/html/setup.rb +2 -2
  552. data/templates/guide/fulldoc/html/css/style.css +108 -108
  553. data/templates/guide/fulldoc/html/js/app.js +33 -33
  554. data/templates/guide/fulldoc/html/setup.rb +74 -74
  555. data/templates/guide/layout/html/layout.erb +81 -81
  556. data/templates/guide/layout/html/setup.rb +25 -25
  557. data/templates/guide/method/html/header.erb +17 -17
  558. data/templates/guide/method/html/setup.rb +22 -22
  559. data/templates/guide/module/html/header.erb +6 -6
  560. data/templates/guide/module/html/method_list.erb +4 -4
  561. data/templates/guide/module/html/setup.rb +27 -27
  562. data/templates/guide/onefile/html/files.erb +4 -4
  563. data/templates/guide/onefile/html/setup.rb +6 -6
  564. data/templates/guide/onefile/html/toc.erb +3 -3
  565. data/templates/guide/tags/html/setup.rb +9 -9
  566. data/yard.gemspec +43 -43
  567. metadata +4 -3
@@ -1,615 +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
-
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
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