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,74 +1,74 @@
1
- # frozen_string_literal: true
2
- module YARD
3
- module Parser::Ruby::Legacy
4
- class TokenList < Array
5
- include RubyToken
6
-
7
- def initialize(content = nil)
8
- self << content if content
9
- end
10
-
11
- def to_s(full_statement = false, show_block = true)
12
- inject([]) do |acc, token|
13
- break acc if !full_statement && TkStatementEnd === token
14
- acc << (!show_block && TkBlockContents === token ? "" : token.text)
15
- end.join
16
- end
17
-
18
- # @param [TokenList, Token, String] tokens
19
- # A list of tokens. If the token is a string, it
20
- # is parsed with {RubyLex}.
21
- def push(*tokens)
22
- tokens.each do |tok|
23
- if tok.is_a?(TokenList) || tok.is_a?(Array)
24
- concat tok
25
- elsif tok.is_a?(Token)
26
- super tok
27
- elsif tok.is_a?(String)
28
- parse_content(tok)
29
- else
30
- raise ArgumentError, "Expecting token, list of tokens or string of code to be tokenized. Got #{tok.class}"
31
- end
32
- end
33
- self
34
- end
35
- alias << push
36
-
37
- def squeeze(type = TkSPACE)
38
- last = nil
39
- TokenList.new(map {|t| x = t.is_a?(type) && last.is_a?(type) ? nil : t; last = t; x })
40
- end
41
-
42
- private
43
-
44
- def parse_content(content)
45
- lex = RubyLex.new(content)
46
- loop do
47
- tk = lex.token
48
- break if tk.nil?
49
- self << convert_token(lex, tk)
50
- end
51
- end
52
-
53
- def convert_token(lex, tk)
54
- if TkIDENTIFIER === tk && lex.peek == ':'
55
- next_tk = lex.token
56
- sym = TkLABEL.new(tk.line_no, tk.char_no, nil)
57
- sym.lex_state = lex.lex_state
58
- sym.set_text(tk.text + next_tk.text)
59
- elsif TkSYMBEG === tk
60
- next_tk = lex.token
61
- if next_tk
62
- sym = TkSYMBOL.new(tk.line_no, tk.char_no, nil)
63
- sym.lex_state = lex.lex_state
64
- sym.set_text(tk.text + next_tk.text)
65
- else
66
- tk
67
- end
68
- else
69
- tk
70
- end
71
- end
72
- end
73
- end
74
- end
1
+ # frozen_string_literal: true
2
+ module YARD
3
+ module Parser::Ruby::Legacy
4
+ class TokenList < Array
5
+ include RubyToken
6
+
7
+ def initialize(content = nil)
8
+ self << content if content
9
+ end
10
+
11
+ def to_s(full_statement = false, show_block = true)
12
+ inject([]) do |acc, token|
13
+ break acc if !full_statement && TkStatementEnd === token
14
+ acc << (!show_block && TkBlockContents === token ? "" : token.text)
15
+ end.join
16
+ end
17
+
18
+ # @param [TokenList, Token, String] tokens
19
+ # A list of tokens. If the token is a string, it
20
+ # is parsed with {RubyLex}.
21
+ def push(*tokens)
22
+ tokens.each do |tok|
23
+ if tok.is_a?(TokenList) || tok.is_a?(Array)
24
+ concat tok
25
+ elsif tok.is_a?(Token)
26
+ super tok
27
+ elsif tok.is_a?(String)
28
+ parse_content(tok)
29
+ else
30
+ raise ArgumentError, "Expecting token, list of tokens or string of code to be tokenized. Got #{tok.class}"
31
+ end
32
+ end
33
+ self
34
+ end
35
+ alias << push
36
+
37
+ def squeeze(type = TkSPACE)
38
+ last = nil
39
+ TokenList.new(map {|t| x = t.is_a?(type) && last.is_a?(type) ? nil : t; last = t; x })
40
+ end
41
+
42
+ private
43
+
44
+ def parse_content(content)
45
+ lex = RubyLex.new(content)
46
+ loop do
47
+ tk = lex.token
48
+ break if tk.nil?
49
+ self << convert_token(lex, tk)
50
+ end
51
+ end
52
+
53
+ def convert_token(lex, tk)
54
+ if TkIDENTIFIER === tk && lex.peek == ':'
55
+ next_tk = lex.token
56
+ sym = TkLABEL.new(tk.line_no, tk.char_no, nil)
57
+ sym.lex_state = lex.lex_state
58
+ sym.set_text(tk.text + next_tk.text)
59
+ elsif TkSYMBEG === tk
60
+ next_tk = lex.token
61
+ if next_tk
62
+ sym = TkSYMBOL.new(tk.line_no, tk.char_no, nil)
63
+ sym.lex_state = lex.lex_state
64
+ sym.set_text(tk.text + next_tk.text)
65
+ else
66
+ tk
67
+ end
68
+ else
69
+ tk
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,687 +1,687 @@
1
- # frozen_string_literal: true
2
- begin require 'ripper'; rescue LoadError; nil end
3
-
4
- module YARD
5
- module Parser
6
- module Ruby
7
- # Ruby 1.9 parser
8
- # @!attribute [r] encoding_line
9
- # @!attribute [r] frozen_string_line
10
- # @!attribute [r] shebang_line
11
- # @!attribute [r] enumerator
12
- class RubyParser < Parser::Base
13
- def initialize(source, filename)
14
- @parser = RipperParser.new(source, filename)
15
- end
16
-
17
- def parse; @parser.parse end
18
- def tokenize; @parser.tokens end
19
- def enumerator; @parser.enumerator end
20
- def shebang_line; @parser.shebang_line end
21
- def encoding_line; @parser.encoding_line end
22
- def frozen_string_line; @parser.frozen_string_line end
23
- end
24
-
25
- # Internal parser class
26
- # @since 0.5.6
27
- class RipperParser < Ripper
28
- attr_reader :ast, :charno, :comments, :file, :tokens
29
- attr_reader :shebang_line, :encoding_line, :frozen_string_line
30
- alias root ast
31
-
32
- def initialize(source, filename, *args)
33
- super
34
- @last_ns_token = nil
35
- @file = filename
36
- @source = source
37
- @tokens = []
38
- @comments = {}
39
- @comments_range = {}
40
- @comments_flags = {}
41
- @heredoc_tokens = nil
42
- @heredoc_state = nil
43
- @map = {}
44
- @ns_charno = 0
45
- @list = []
46
- @charno = 0
47
- @shebang_line = nil
48
- @encoding_line = nil
49
- @frozen_string_line = nil
50
- @file_encoding = nil
51
- @newline = true
52
- @percent_ary = nil
53
- end
54
-
55
- def parse
56
- @ast = super
57
- @ast.full_source = @source
58
- @ast.file = @file
59
- freeze_tree
60
- insert_comments
61
- self
62
- end
63
-
64
- def enumerator
65
- ast.children
66
- end
67
-
68
- def file_encoding
69
- return nil unless defined?(::Encoding)
70
- return @file_encoding if @file_encoding
71
- return Encoding.default_internal unless @encoding_line
72
- match = @encoding_line.match(SourceParser::ENCODING_LINE)
73
- @file_encoding = match.captures.last if match
74
- end
75
-
76
- private
77
-
78
- MAPPINGS = {
79
- :BEGIN => "BEGIN",
80
- :END => "END",
81
- :alias => "alias",
82
- :array => :lbracket,
83
- :arg_paren => :lparen,
84
- :begin => "begin",
85
- :blockarg => "&",
86
- :brace_block => :lbrace,
87
- :break => "break",
88
- :case => "case",
89
- :class => "class",
90
- :def => "def",
91
- :defined => "defined?",
92
- :defs => "def",
93
- :do_block => "do",
94
- :else => "else",
95
- :elsif => "elsif",
96
- :ensure => "ensure",
97
- :for => "for",
98
- :hash => :lbrace,
99
- :if => "if",
100
- :lambda => [:tlambda, "lambda"],
101
- :module => "module",
102
- :next => "next",
103
- :paren => :lparen,
104
- :qwords_literal => :qwords_beg,
105
- :words_literal => :words_beg,
106
- :qsymbols_literal => :qsymbols_beg,
107
- :symbols_literal => :symbols_beg,
108
- :redo => "redo",
109
- :regexp_literal => :regexp_beg,
110
- :rescue => "rescue",
111
- :rest_param => "*",
112
- :retry => "retry",
113
- :return => "return",
114
- :return0 => "return",
115
- :sclass => "class",
116
- :string_embexpr => :embexpr_beg,
117
- :string_literal => [:tstring_beg, :heredoc_beg],
118
- :super => "super",
119
- :symbol => :symbeg,
120
- :top_const_ref => "::",
121
- :undef => "undef",
122
- :unless => "unless",
123
- :until => "until",
124
- :when => "when",
125
- :while => "while",
126
- :xstring_literal => :backtick,
127
- :yield => "yield",
128
- :yield0 => "yield",
129
- :zsuper => "super"
130
- }
131
- REV_MAPPINGS = {}
132
-
133
- AST_TOKENS = [:CHAR, :backref, :const, :cvar, :gvar, :heredoc_end, :ident,
134
- :int, :float, :ivar, :label, :period, :regexp_end, :tstring_content, :backtick]
135
-
136
- MAPPINGS.each do |k, v|
137
- if Array === v
138
- v.each {|vv| (REV_MAPPINGS[vv] ||= []) << k }
139
- else
140
- (REV_MAPPINGS[v] ||= []) << k
141
- end
142
- end
143
-
144
- PARSER_EVENT_TABLE.each do |event, arity|
145
- node_class = AstNode.node_class_for(event)
146
-
147
- if /_new\z/ =~ event.to_s && arity == 0
148
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
149
- def on_#{event}(*args)
150
- #{node_class}.new(:list, args, :listchar => charno...charno, :listline => lineno..lineno)
151
- end
152
- eof
153
- elsif /_add(_.+)?\z/ =~ event.to_s
154
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
155
- begin; undef on_#{event}; rescue NameError; end
156
- def on_#{event}(list, item)
157
- list.push(item)
158
- list
159
- end
160
- eof
161
- elsif MAPPINGS.key?(event)
162
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
163
- begin; undef on_#{event}; rescue NameError; end
164
- def on_#{event}(*args)
165
- visit_event #{node_class}.new(:#{event}, args)
166
- end
167
- eof
168
- else
169
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
170
- begin; undef on_#{event}; rescue NameError; end
171
- def on_#{event}(*args)
172
- #{node_class}.new(:#{event}, args, :listline => lineno..lineno, :listchar => charno...charno)
173
- end
174
- eof
175
- end
176
- end
177
-
178
- SCANNER_EVENTS.each do |event|
179
- ast_token = AST_TOKENS.include?(event)
180
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
181
- begin; undef on_#{event}; rescue NameError; end
182
- def on_#{event}(tok)
183
- visit_ns_token(:#{event}, tok, #{ast_token.inspect})
184
- end
185
- eof
186
- end
187
-
188
- REV_MAPPINGS.select {|k, _v| k.is_a?(Symbol) }.each do |pair|
189
- event = pair.first
190
- ast_token = AST_TOKENS.include?(event)
191
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
192
- begin; undef on_#{event}; rescue NameError; end
193
- def on_#{event}(tok)
194
- (@map[:#{event}] ||= []) << [lineno, charno]
195
- visit_ns_token(:#{event}, tok, #{ast_token.inspect})
196
- end
197
- eof
198
- end
199
-
200
- [:kw, :op].each do |event|
201
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
202
- begin; undef on_#{event}; rescue NameError; end
203
- def on_#{event}(tok)
204
- unless @last_ns_token == [:kw, "def"] ||
205
- (@tokens.last && @tokens.last[0] == :symbeg) ||
206
- (!@newline && %w(if while until unless).include?(tok))
207
- (@map[tok] ||= []) << [lineno, charno]
208
- end
209
- visit_ns_token(:#{event}, tok, true)
210
- end
211
- eof
212
- end
213
-
214
- [:nl, :ignored_nl].each do |event|
215
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
216
- begin; undef on_#{event}; rescue NameError; end
217
- def on_#{event}(tok)
218
- add_token(:#{event}, tok)
219
- @newline = true
220
- @charno += tok ? tok.length : 0
221
- end
222
- eof
223
- end
224
-
225
- undef on_sp
226
-
227
- def on_sp(tok)
228
- add_token(:sp, tok)
229
- @charno += tok.length
230
- end
231
-
232
- def visit_event(node)
233
- map = @map[MAPPINGS[node.type]]
234
- lstart, sstart = *(map ? map.pop : [lineno, @ns_charno - 1])
235
- node.source_range = Range.new(sstart, @ns_charno - 1)
236
- node.line_range = Range.new(lstart, lineno)
237
- if node.respond_to?(:block)
238
- sr = node.block.source_range
239
- lr = node.block.line_range
240
- node.block.source_range = Range.new(sr.first, @tokens.last[2][1] - 1)
241
- node.block.line_range = Range.new(lr.first, @tokens.last[2][0])
242
- end
243
- node
244
- end
245
-
246
- def visit_event_arr(node)
247
- mapping = MAPPINGS[node.type].find {|k| @map[k] && !@map[k].empty? }
248
- lstart, sstart = *@map[mapping].pop
249
- node.source_range = Range.new(sstart, @ns_charno - 1)
250
- node.line_range = Range.new(lstart, lineno)
251
- node
252
- end
253
-
254
- def visit_ns_token(token, data, ast_token = false)
255
- add_token(token, data)
256
- ch = charno
257
- @last_ns_token = [token, data]
258
- @charno += data.length
259
- @ns_charno = charno
260
- @newline = [:semicolon, :comment, :kw, :op, :lparen, :lbrace].include?(token)
261
- if ast_token
262
- AstNode.new(token, [data], :line => lineno..lineno, :char => ch..charno - 1, :token => true)
263
- end
264
- end
265
-
266
- def add_token(token, data)
267
- if @percent_ary
268
- if token == :words_sep && data !~ /\s\z/
269
- rng = @percent_ary.source_range
270
- rng = Range.new(rng.first, rng.last + data.length)
271
- @percent_ary.source_range = rng
272
- @tokens << [token, data, [lineno, charno]]
273
- @percent_ary = nil
274
- return
275
- elsif token == :tstring_end && data =~ /\A\s/
276
- rng = @percent_ary.source_range
277
- rng = Range.new(rng.first, rng.last + data.length)
278
- @percent_ary.source_range = rng
279
- @tokens << [token, data, [lineno, charno]]
280
- @percent_ary = nil
281
- return
282
- end
283
- end
284
-
285
- if @tokens.last && (@tokens.last[0] == :symbeg ||
286
- (@tokens.last[0] == :symbol && token.to_s =~ /^tstring/))
287
- @tokens[-1] = [:symbol, @tokens.last[1] + data, @tokens.last[2]]
288
- elsif @heredoc_state == :started
289
- @heredoc_tokens << [token, data, [lineno, charno]]
290
-
291
- # fix ripper encoding of heredoc bug
292
- # (see http://bugs.ruby-lang.org/issues/6200)
293
- data.force_encoding(file_encoding) if file_encoding
294
-
295
- @heredoc_state = :ended if token == :heredoc_end
296
- elsif (token == :nl || token == :comment) && @heredoc_state == :ended
297
- @heredoc_tokens.unshift([token, data, [lineno, charno]])
298
- @tokens += @heredoc_tokens
299
- @heredoc_tokens = nil
300
- @heredoc_state = nil
301
- else
302
- @tokens << [token, data, [lineno, charno]]
303
- if token == :heredoc_beg
304
- @heredoc_state = :started
305
- @heredoc_tokens = []
306
- end
307
- end
308
- end
309
-
310
- undef on_program
311
- undef on_assoc_new
312
- undef on_array
313
- undef on_hash
314
- undef on_bare_assoc_hash
315
- undef on_assoclist_from_args
316
- undef on_aref
317
- undef on_aref_field
318
- undef on_lbracket
319
- undef on_rbracket
320
- undef on_string_literal
321
- undef on_lambda
322
- undef on_unary
323
- undef on_string_content
324
- undef on_rescue
325
- undef on_void_stmt
326
- undef on_params
327
- undef on_label
328
- undef on_comment
329
- undef on_embdoc_beg
330
- undef on_embdoc
331
- undef on_embdoc_end
332
- undef on_parse_error
333
- undef on_bodystmt
334
- undef on_top_const_ref
335
- undef on_const_path_ref
336
-
337
- def on_program(*args)
338
- args.first
339
- end
340
-
341
- def on_body_stmt(*args)
342
- args.compact.size == 1 ? args.first : AstNode.new(:list, args)
343
- end
344
- alias on_bodystmt on_body_stmt
345
-
346
- def on_assoc_new(*args)
347
- AstNode.new(:assoc, args)
348
- end
349
-
350
- def on_hash(*args)
351
- visit_event AstNode.new(:hash, args.first || [])
352
- end
353
-
354
- def on_bare_assoc_hash(*args)
355
- AstNode.new(:list, args.first)
356
- end
357
-
358
- def on_assoclist_from_args(*args)
359
- args.first
360
- end
361
-
362
- def on_unary(op, val)
363
- map = @map[op.to_s[0, 1]]
364
- lstart, sstart = *(map ? map.pop : [lineno, @ns_charno - 1])
365
- node = AstNode.node_class_for(:unary).new(:unary, [op, val])
366
- node.source_range = Range.new(sstart, @ns_charno - 1)
367
- node.line_range = Range.new(lstart, lineno)
368
- node
369
- end
370
-
371
- def on_aref(*args)
372
- @map[:lbracket].pop
373
- ll, lc = *@map[:aref].pop
374
- sr = args.first.source_range.first..lc
375
- lr = args.first.line_range.first..ll
376
- AstNode.new(:aref, args, :char => sr, :line => lr)
377
- end
378
-
379
- def on_aref_field(*args)
380
- @map[:lbracket].pop
381
- AstNode.new(:aref_field, args,
382
- :listline => lineno..lineno, :listchar => charno...charno)
383
- end
384
-
385
- def on_array(other)
386
- node = AstNode.node_class_for(:array).new(:array, [other])
387
- map = @map[MAPPINGS[node.type]]
388
- if map && !map.empty?
389
- lstart, sstart = *map.pop
390
- node.source_range = Range.new(sstart, @ns_charno - 1)
391
- node.line_range = Range.new(lstart, lineno)
392
- else
393
- sstart = other.source_range.begin
394
- lstart = other.line_range.begin
395
- node.source_range = Range.new(sstart, @ns_charno - 1)
396
- node.line_range = Range.new(lstart, lineno)
397
- node.source_range = other.source_range
398
- node.line_range = other.line_range
399
- end
400
- node
401
- end
402
-
403
- def on_lbracket(tok)
404
- (@map[:lbracket] ||= []) << [lineno, charno]
405
- visit_ns_token(:lbracket, tok, false)
406
- end
407
-
408
- def on_rbracket(tok)
409
- (@map[:aref] ||= []) << [lineno, charno]
410
- visit_ns_token(:rbracket, tok, false)
411
- end
412
-
413
- def on_top_const_ref(*args)
414
- type = :top_const_ref
415
- node = AstNode.node_class_for(type).new(type, args)
416
- mapping = @map[MAPPINGS[type]]
417
- extra_op = mapping.last[1] + 2 == charno ? mapping.pop : nil
418
- lstart, sstart = *mapping.pop
419
- node.source_range = Range.new(sstart, args.last.source_range.last)
420
- node.line_range = Range.new(lstart, args.last.line_range.last)
421
- mapping.push(extra_op) if extra_op
422
- node
423
- end
424
-
425
- def on_const_path_ref(*args)
426
- ReferenceNode.new(:const_path_ref, args, :listline => lineno..lineno, :listchar => charno..charno)
427
- end
428
-
429
- [:if_mod, :unless_mod, :while_mod, :until_mod].each do |kw|
430
- node_class = AstNode.node_class_for(kw)
431
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
432
- begin; undef on_#{kw}; rescue NameError; end
433
- def on_#{kw}(*args)
434
- sr = args.last.source_range.first..args.first.source_range.last
435
- lr = args.last.line_range.first..args.first.line_range.last
436
- #{node_class}.new(:#{kw}, args, :line => lr, :char => sr)
437
- end
438
- eof
439
- end
440
-
441
- %w(symbols qsymbols words qwords).each do |kw|
442
- module_eval(<<-eof, __FILE__, __LINE__ + 1)
443
- begin; undef on_#{kw}_new; rescue NameError; end
444
- def on_#{kw}_new(*args)
445
- node = LiteralNode.new(:#{kw}_literal, args)
446
- @percent_ary = node
447
- if @map[:#{kw}_beg]
448
- lstart, sstart = *@map[:#{kw}_beg].pop
449
- node.source_range = Range.new(sstart, @ns_charno-1)
450
- node.line_range = Range.new(lstart, lineno)
451
- end
452
- node
453
- end
454
-
455
- begin; undef on_#{kw}_add; rescue NameError; end
456
- def on_#{kw}_add(list, item)
457
- last = @source[@ns_charno,1] == "\n" ? @ns_charno - 1 : @ns_charno
458
- list.source_range = (list.source_range.first..last)
459
- list.line_range = (list.line_range.first..lineno)
460
- list.push(item)
461
- list
462
- end
463
- eof
464
- end
465
-
466
- def on_string_literal(*args)
467
- node = visit_event_arr(LiteralNode.new(:string_literal, args))
468
- if args.size == 1
469
- r = args[0].source_range
470
- if node.source_range != Range.new(r.first - 1, r.last + 1)
471
- klass = AstNode.node_class_for(node[0].type)
472
- r = Range.new(node.source_range.first + 1, node.source_range.last - 1)
473
- node[0] = klass.new(node[0].type, [@source[r]], :line => node.line_range, :char => r)
474
- end
475
- end
476
- node
477
- end
478
-
479
- def on_lambda(*args)
480
- visit_event_arr AstNode.new(:lambda, args)
481
- end
482
-
483
- def on_string_content(*args)
484
- AstNode.new(:string_content, args, :listline => lineno..lineno, :listchar => charno..charno)
485
- end
486
-
487
- def on_rescue(exc, *args)
488
- exc = AstNode.new(:list, exc) if exc
489
- visit_event AstNode.new(:rescue, [exc, *args])
490
- end
491
-
492
- def on_void_stmt
493
- AstNode.new(:void_stmt, [], :line => lineno..lineno, :char => charno...charno)
494
- end
495
-
496
- def on_params(*args)
497
- args.map! do |arg|
498
- next arg unless arg.class == Array
499
-
500
- if arg.first.class == Array
501
- arg.map! do |sub_arg|
502
- next sub_arg unless sub_arg.class == Array
503
- type = sub_arg[0].type == :label ?
504
- :named_arg : :unnamed_optional_arg
505
- AstNode.new(type, sub_arg, :listline => lineno..lineno, :listchar => charno..charno)
506
- end
507
- end
508
-
509
- AstNode.new(:list, arg, :listline => lineno..lineno, :listchar => charno..charno)
510
- end
511
-
512
- ParameterNode.new(:params, args, :listline => lineno..lineno, :listchar => charno..charno)
513
- end
514
-
515
- def on_label(data)
516
- add_token(:label, data)
517
- ch = charno
518
- @charno += data.length
519
- @ns_charno = charno
520
- AstNode.new(:label, [data[0...-1]], :line => lineno..lineno, :char => ch..charno - 1, :token => true)
521
- end
522
-
523
- def on_comment(comment)
524
- not_comment = false
525
- if @last_ns_token.nil? || @last_ns_token.empty?
526
- if comment =~ SourceParser::SHEBANG_LINE && !@encoding_line
527
- @shebang_line = comment
528
- not_comment = true
529
- elsif comment =~ SourceParser::ENCODING_LINE
530
- @encoding_line = comment
531
- not_comment = true
532
- elsif comment =~ SourceParser::FROZEN_STRING_LINE
533
- @frozen_string_line = comment
534
- not_comment = true
535
- end
536
- end
537
-
538
- ch = charno
539
- visit_ns_token(:comment, comment)
540
- if not_comment
541
- @last_ns_token = nil
542
- return
543
- end
544
-
545
- source_range = ch..(charno - 1)
546
- comment = comment.gsub(/^(\#+)\s{0,1}/, '').chomp
547
- append_comment = @comments[lineno - 1]
548
-
549
- hash_flag = $1 == '##' ? true : false
550
-
551
- if append_comment && @comments_last_column &&
552
- @comments_last_column == column && comment_starts_line?(ch)
553
- @comments.delete(lineno - 1)
554
- @comments_flags[lineno] = @comments_flags[lineno - 1]
555
- @comments_flags.delete(lineno - 1)
556
- range = @comments_range.delete(lineno - 1)
557
- source_range = range.first..source_range.last
558
- comment = append_comment + "\n" + comment
559
- end
560
-
561
- @comments[lineno] = comment
562
- @comments_range[lineno] = source_range
563
- @comments_flags[lineno] = hash_flag unless append_comment
564
- @comments_last_column = column
565
- end
566
-
567
- def on_embdoc_beg(text)
568
- visit_ns_token(:embdoc_beg, text)
569
- @embdoc_start = charno - text.length
570
- @embdoc = String.new("")
571
- end
572
-
573
- def on_embdoc(text)
574
- visit_ns_token(:embdoc, text)
575
- @embdoc << text
576
- end
577
-
578
- def on_embdoc_end(text)
579
- visit_ns_token(:embdoc_end, text)
580
- @comments_last_column = nil
581
- @comments[lineno] = @embdoc
582
- @comments_range[lineno] = @embdoc_start...charno
583
- @embdoc_start = nil
584
- @embdoc = nil
585
- end
586
-
587
- def on_parse_error(msg)
588
- raise ParserSyntaxError, "syntax error in `#{file}`:(#{lineno},#{column}): #{msg}"
589
- end
590
- alias compile_error on_parse_error
591
-
592
- def comment_starts_line?(charno)
593
- (charno - 1).downto(0) do |i|
594
- ch = @source[i]
595
- break if ch == "\n"
596
- return false if ch != " " && ch != "\t"
597
- end
598
- true
599
- end
600
-
601
- def insert_comments
602
- root.traverse do |node|
603
- next if node.type == :comment || node.type == :list || node.parent.type != :list
604
-
605
- # never attach comments to if/unless mod nodes
606
- if node.type == :if_mod || node.type == :unless_mod
607
- node = node.then_block
608
- end
609
-
610
- # check upwards from line before node; check node's line at the end
611
- ((node.line - 1).downto(node.line - 2).to_a + [node.line]).each do |line|
612
- comment = @comments[line]
613
- if comment && !comment.empty?
614
- add_comment(line, node)
615
- break
616
- end
617
- end
618
-
619
- @comments.keys.each do |line|
620
- add_comment(line, nil, node) if node.line > line
621
- end
622
- end
623
-
624
- # insert any lone unadded comments before node
625
- root.traverse do |node|
626
- next if node.type == :list || node.parent.type != :list
627
- @comments.keys.each do |line|
628
- next unless node.line_range.include?(line)
629
- pick = nil
630
- node.traverse do |subnode|
631
- next unless subnode.type == :list
632
- pick ||= subnode
633
- next unless subnode.line_range.include?(line)
634
- pick = subnode
635
- end
636
- add_comment(line, nil, pick, true) if pick
637
- end
638
- end unless @comments.empty?
639
-
640
- # insert all remaining comments
641
- @comments.each do |line, _comment|
642
- add_comment(line, nil, root, true)
643
- end
644
-
645
- @comments = {}
646
- end
647
-
648
- def add_comment(line, node = nil, before_node = nil, into = false)
649
- comment = @comments[line]
650
- source_range = @comments_range[line]
651
- line_range = ((line - comment.count("\n"))..line)
652
- if node.nil?
653
- node = CommentNode.new(:comment, [comment], :line => line_range, :char => source_range)
654
- if into
655
- before_node.push(node)
656
- before_node.unfreeze
657
- node.parent = before_node
658
- elsif before_node
659
- parent_node = before_node.parent
660
- idx = parent_node.index(before_node)
661
- parent_node.insert(idx, node)
662
- parent_node.unfreeze
663
- node.parent = parent_node
664
- end
665
- end
666
- node.docstring = comment
667
- node.docstring_hash_flag = @comments_flags[line]
668
- node.docstring_range = line_range
669
- @comments.delete(line)
670
- @comments_range.delete(line)
671
- @comments_flags.delete(line)
672
- end
673
-
674
- def freeze_tree(node = nil)
675
- nodes = [node || root]
676
- until nodes.empty?
677
- p_node = nodes.shift
678
- p_node.children.each do |child|
679
- child.parent = p_node
680
- nodes << child
681
- end
682
- end
683
- end
684
- end if defined?(::Ripper)
685
- end
686
- end
687
- end
1
+ # frozen_string_literal: true
2
+ begin require 'ripper'; rescue LoadError; nil end
3
+
4
+ module YARD
5
+ module Parser
6
+ module Ruby
7
+ # Ruby 1.9 parser
8
+ # @!attribute [r] encoding_line
9
+ # @!attribute [r] frozen_string_line
10
+ # @!attribute [r] shebang_line
11
+ # @!attribute [r] enumerator
12
+ class RubyParser < Parser::Base
13
+ def initialize(source, filename)
14
+ @parser = RipperParser.new(source, filename)
15
+ end
16
+
17
+ def parse; @parser.parse end
18
+ def tokenize; @parser.tokens end
19
+ def enumerator; @parser.enumerator end
20
+ def shebang_line; @parser.shebang_line end
21
+ def encoding_line; @parser.encoding_line end
22
+ def frozen_string_line; @parser.frozen_string_line end
23
+ end
24
+
25
+ # Internal parser class
26
+ # @since 0.5.6
27
+ class RipperParser < Ripper
28
+ attr_reader :ast, :charno, :comments, :file, :tokens
29
+ attr_reader :shebang_line, :encoding_line, :frozen_string_line
30
+ alias root ast
31
+
32
+ def initialize(source, filename, *args)
33
+ super
34
+ @last_ns_token = nil
35
+ @file = filename
36
+ @source = source
37
+ @tokens = []
38
+ @comments = {}
39
+ @comments_range = {}
40
+ @comments_flags = {}
41
+ @heredoc_tokens = nil
42
+ @heredoc_state = nil
43
+ @map = {}
44
+ @ns_charno = 0
45
+ @list = []
46
+ @charno = 0
47
+ @shebang_line = nil
48
+ @encoding_line = nil
49
+ @frozen_string_line = nil
50
+ @file_encoding = nil
51
+ @newline = true
52
+ @percent_ary = nil
53
+ end
54
+
55
+ def parse
56
+ @ast = super
57
+ @ast.full_source = @source
58
+ @ast.file = @file
59
+ freeze_tree
60
+ insert_comments
61
+ self
62
+ end
63
+
64
+ def enumerator
65
+ ast.children
66
+ end
67
+
68
+ def file_encoding
69
+ return nil unless defined?(::Encoding)
70
+ return @file_encoding if @file_encoding
71
+ return Encoding.default_internal unless @encoding_line
72
+ match = @encoding_line.match(SourceParser::ENCODING_LINE)
73
+ @file_encoding = match.captures.last if match
74
+ end
75
+
76
+ private
77
+
78
+ MAPPINGS = {
79
+ :BEGIN => "BEGIN",
80
+ :END => "END",
81
+ :alias => "alias",
82
+ :array => :lbracket,
83
+ :arg_paren => :lparen,
84
+ :begin => "begin",
85
+ :blockarg => "&",
86
+ :brace_block => :lbrace,
87
+ :break => "break",
88
+ :case => "case",
89
+ :class => "class",
90
+ :def => "def",
91
+ :defined => "defined?",
92
+ :defs => "def",
93
+ :do_block => "do",
94
+ :else => "else",
95
+ :elsif => "elsif",
96
+ :ensure => "ensure",
97
+ :for => "for",
98
+ :hash => :lbrace,
99
+ :if => "if",
100
+ :lambda => [:tlambda, "lambda"],
101
+ :module => "module",
102
+ :next => "next",
103
+ :paren => :lparen,
104
+ :qwords_literal => :qwords_beg,
105
+ :words_literal => :words_beg,
106
+ :qsymbols_literal => :qsymbols_beg,
107
+ :symbols_literal => :symbols_beg,
108
+ :redo => "redo",
109
+ :regexp_literal => :regexp_beg,
110
+ :rescue => "rescue",
111
+ :rest_param => "*",
112
+ :retry => "retry",
113
+ :return => "return",
114
+ :return0 => "return",
115
+ :sclass => "class",
116
+ :string_embexpr => :embexpr_beg,
117
+ :string_literal => [:tstring_beg, :heredoc_beg],
118
+ :super => "super",
119
+ :symbol => :symbeg,
120
+ :top_const_ref => "::",
121
+ :undef => "undef",
122
+ :unless => "unless",
123
+ :until => "until",
124
+ :when => "when",
125
+ :while => "while",
126
+ :xstring_literal => :backtick,
127
+ :yield => "yield",
128
+ :yield0 => "yield",
129
+ :zsuper => "super"
130
+ }
131
+ REV_MAPPINGS = {}
132
+
133
+ AST_TOKENS = [:CHAR, :backref, :const, :cvar, :gvar, :heredoc_end, :ident,
134
+ :int, :float, :ivar, :label, :period, :regexp_end, :tstring_content, :backtick]
135
+
136
+ MAPPINGS.each do |k, v|
137
+ if Array === v
138
+ v.each {|vv| (REV_MAPPINGS[vv] ||= []) << k }
139
+ else
140
+ (REV_MAPPINGS[v] ||= []) << k
141
+ end
142
+ end
143
+
144
+ PARSER_EVENT_TABLE.each do |event, arity|
145
+ node_class = AstNode.node_class_for(event)
146
+
147
+ if /_new\z/ =~ event.to_s && arity == 0
148
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
149
+ def on_#{event}(*args)
150
+ #{node_class}.new(:list, args, :listchar => charno...charno, :listline => lineno..lineno)
151
+ end
152
+ eof
153
+ elsif /_add(_.+)?\z/ =~ event.to_s
154
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
155
+ begin; undef on_#{event}; rescue NameError; end
156
+ def on_#{event}(list, item)
157
+ list.push(item)
158
+ list
159
+ end
160
+ eof
161
+ elsif MAPPINGS.key?(event)
162
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
163
+ begin; undef on_#{event}; rescue NameError; end
164
+ def on_#{event}(*args)
165
+ visit_event #{node_class}.new(:#{event}, args)
166
+ end
167
+ eof
168
+ else
169
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
170
+ begin; undef on_#{event}; rescue NameError; end
171
+ def on_#{event}(*args)
172
+ #{node_class}.new(:#{event}, args, :listline => lineno..lineno, :listchar => charno...charno)
173
+ end
174
+ eof
175
+ end
176
+ end
177
+
178
+ SCANNER_EVENTS.each do |event|
179
+ ast_token = AST_TOKENS.include?(event)
180
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
181
+ begin; undef on_#{event}; rescue NameError; end
182
+ def on_#{event}(tok)
183
+ visit_ns_token(:#{event}, tok, #{ast_token.inspect})
184
+ end
185
+ eof
186
+ end
187
+
188
+ REV_MAPPINGS.select {|k, _v| k.is_a?(Symbol) }.each do |pair|
189
+ event = pair.first
190
+ ast_token = AST_TOKENS.include?(event)
191
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
192
+ begin; undef on_#{event}; rescue NameError; end
193
+ def on_#{event}(tok)
194
+ (@map[:#{event}] ||= []) << [lineno, charno]
195
+ visit_ns_token(:#{event}, tok, #{ast_token.inspect})
196
+ end
197
+ eof
198
+ end
199
+
200
+ [:kw, :op].each do |event|
201
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
202
+ begin; undef on_#{event}; rescue NameError; end
203
+ def on_#{event}(tok)
204
+ unless @last_ns_token == [:kw, "def"] ||
205
+ (@tokens.last && @tokens.last[0] == :symbeg) ||
206
+ (!@newline && %w(if while until unless).include?(tok))
207
+ (@map[tok] ||= []) << [lineno, charno]
208
+ end
209
+ visit_ns_token(:#{event}, tok, true)
210
+ end
211
+ eof
212
+ end
213
+
214
+ [:nl, :ignored_nl].each do |event|
215
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
216
+ begin; undef on_#{event}; rescue NameError; end
217
+ def on_#{event}(tok)
218
+ add_token(:#{event}, tok)
219
+ @newline = true
220
+ @charno += tok ? tok.length : 0
221
+ end
222
+ eof
223
+ end
224
+
225
+ undef on_sp
226
+
227
+ def on_sp(tok)
228
+ add_token(:sp, tok)
229
+ @charno += tok.length
230
+ end
231
+
232
+ def visit_event(node)
233
+ map = @map[MAPPINGS[node.type]]
234
+ lstart, sstart = *(map ? map.pop : [lineno, @ns_charno - 1])
235
+ node.source_range = Range.new(sstart, @ns_charno - 1)
236
+ node.line_range = Range.new(lstart, lineno)
237
+ if node.respond_to?(:block)
238
+ sr = node.block.source_range
239
+ lr = node.block.line_range
240
+ node.block.source_range = Range.new(sr.first, @tokens.last[2][1] - 1)
241
+ node.block.line_range = Range.new(lr.first, @tokens.last[2][0])
242
+ end
243
+ node
244
+ end
245
+
246
+ def visit_event_arr(node)
247
+ mapping = MAPPINGS[node.type].find {|k| @map[k] && !@map[k].empty? }
248
+ lstart, sstart = *@map[mapping].pop
249
+ node.source_range = Range.new(sstart, @ns_charno - 1)
250
+ node.line_range = Range.new(lstart, lineno)
251
+ node
252
+ end
253
+
254
+ def visit_ns_token(token, data, ast_token = false)
255
+ add_token(token, data)
256
+ ch = charno
257
+ @last_ns_token = [token, data]
258
+ @charno += data.length
259
+ @ns_charno = charno
260
+ @newline = [:semicolon, :comment, :kw, :op, :lparen, :lbrace].include?(token)
261
+ if ast_token
262
+ AstNode.new(token, [data], :line => lineno..lineno, :char => ch..charno - 1, :token => true)
263
+ end
264
+ end
265
+
266
+ def add_token(token, data)
267
+ if @percent_ary
268
+ if token == :words_sep && data !~ /\s\z/
269
+ rng = @percent_ary.source_range
270
+ rng = Range.new(rng.first, rng.last + data.length)
271
+ @percent_ary.source_range = rng
272
+ @tokens << [token, data, [lineno, charno]]
273
+ @percent_ary = nil
274
+ return
275
+ elsif token == :tstring_end && data =~ /\A\s/
276
+ rng = @percent_ary.source_range
277
+ rng = Range.new(rng.first, rng.last + data.length)
278
+ @percent_ary.source_range = rng
279
+ @tokens << [token, data, [lineno, charno]]
280
+ @percent_ary = nil
281
+ return
282
+ end
283
+ end
284
+
285
+ if @tokens.last && (@tokens.last[0] == :symbeg ||
286
+ (@tokens.last[0] == :symbol && token.to_s =~ /^tstring/))
287
+ @tokens[-1] = [:symbol, @tokens.last[1] + data, @tokens.last[2]]
288
+ elsif @heredoc_state == :started
289
+ @heredoc_tokens << [token, data, [lineno, charno]]
290
+
291
+ # fix ripper encoding of heredoc bug
292
+ # (see http://bugs.ruby-lang.org/issues/6200)
293
+ data.force_encoding(file_encoding) if file_encoding
294
+
295
+ @heredoc_state = :ended if token == :heredoc_end
296
+ elsif (token == :nl || token == :comment) && @heredoc_state == :ended
297
+ @heredoc_tokens.unshift([token, data, [lineno, charno]])
298
+ @tokens += @heredoc_tokens
299
+ @heredoc_tokens = nil
300
+ @heredoc_state = nil
301
+ else
302
+ @tokens << [token, data, [lineno, charno]]
303
+ if token == :heredoc_beg
304
+ @heredoc_state = :started
305
+ @heredoc_tokens = []
306
+ end
307
+ end
308
+ end
309
+
310
+ undef on_program
311
+ undef on_assoc_new
312
+ undef on_array
313
+ undef on_hash
314
+ undef on_bare_assoc_hash
315
+ undef on_assoclist_from_args
316
+ undef on_aref
317
+ undef on_aref_field
318
+ undef on_lbracket
319
+ undef on_rbracket
320
+ undef on_string_literal
321
+ undef on_lambda
322
+ undef on_unary
323
+ undef on_string_content
324
+ undef on_rescue
325
+ undef on_void_stmt
326
+ undef on_params
327
+ undef on_label
328
+ undef on_comment
329
+ undef on_embdoc_beg
330
+ undef on_embdoc
331
+ undef on_embdoc_end
332
+ undef on_parse_error
333
+ undef on_bodystmt
334
+ undef on_top_const_ref
335
+ undef on_const_path_ref
336
+
337
+ def on_program(*args)
338
+ args.first
339
+ end
340
+
341
+ def on_body_stmt(*args)
342
+ args.compact.size == 1 ? args.first : AstNode.new(:list, args)
343
+ end
344
+ alias on_bodystmt on_body_stmt
345
+
346
+ def on_assoc_new(*args)
347
+ AstNode.new(:assoc, args)
348
+ end
349
+
350
+ def on_hash(*args)
351
+ visit_event AstNode.new(:hash, args.first || [])
352
+ end
353
+
354
+ def on_bare_assoc_hash(*args)
355
+ AstNode.new(:list, args.first)
356
+ end
357
+
358
+ def on_assoclist_from_args(*args)
359
+ args.first
360
+ end
361
+
362
+ def on_unary(op, val)
363
+ map = @map[op.to_s[0, 1]]
364
+ lstart, sstart = *(map ? map.pop : [lineno, @ns_charno - 1])
365
+ node = AstNode.node_class_for(:unary).new(:unary, [op, val])
366
+ node.source_range = Range.new(sstart, @ns_charno - 1)
367
+ node.line_range = Range.new(lstart, lineno)
368
+ node
369
+ end
370
+
371
+ def on_aref(*args)
372
+ @map[:lbracket].pop
373
+ ll, lc = *@map[:aref].pop
374
+ sr = args.first.source_range.first..lc
375
+ lr = args.first.line_range.first..ll
376
+ AstNode.new(:aref, args, :char => sr, :line => lr)
377
+ end
378
+
379
+ def on_aref_field(*args)
380
+ @map[:lbracket].pop
381
+ AstNode.new(:aref_field, args,
382
+ :listline => lineno..lineno, :listchar => charno...charno)
383
+ end
384
+
385
+ def on_array(other)
386
+ node = AstNode.node_class_for(:array).new(:array, [other])
387
+ map = @map[MAPPINGS[node.type]]
388
+ if map && !map.empty?
389
+ lstart, sstart = *map.pop
390
+ node.source_range = Range.new(sstart, @ns_charno - 1)
391
+ node.line_range = Range.new(lstart, lineno)
392
+ else
393
+ sstart = other.source_range.begin
394
+ lstart = other.line_range.begin
395
+ node.source_range = Range.new(sstart, @ns_charno - 1)
396
+ node.line_range = Range.new(lstart, lineno)
397
+ node.source_range = other.source_range
398
+ node.line_range = other.line_range
399
+ end
400
+ node
401
+ end
402
+
403
+ def on_lbracket(tok)
404
+ (@map[:lbracket] ||= []) << [lineno, charno]
405
+ visit_ns_token(:lbracket, tok, false)
406
+ end
407
+
408
+ def on_rbracket(tok)
409
+ (@map[:aref] ||= []) << [lineno, charno]
410
+ visit_ns_token(:rbracket, tok, false)
411
+ end
412
+
413
+ def on_top_const_ref(*args)
414
+ type = :top_const_ref
415
+ node = AstNode.node_class_for(type).new(type, args)
416
+ mapping = @map[MAPPINGS[type]]
417
+ extra_op = mapping.last[1] + 2 == charno ? mapping.pop : nil
418
+ lstart, sstart = *mapping.pop
419
+ node.source_range = Range.new(sstart, args.last.source_range.last)
420
+ node.line_range = Range.new(lstart, args.last.line_range.last)
421
+ mapping.push(extra_op) if extra_op
422
+ node
423
+ end
424
+
425
+ def on_const_path_ref(*args)
426
+ ReferenceNode.new(:const_path_ref, args, :listline => lineno..lineno, :listchar => charno..charno)
427
+ end
428
+
429
+ [:if_mod, :unless_mod, :while_mod, :until_mod].each do |kw|
430
+ node_class = AstNode.node_class_for(kw)
431
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
432
+ begin; undef on_#{kw}; rescue NameError; end
433
+ def on_#{kw}(*args)
434
+ sr = args.last.source_range.first..args.first.source_range.last
435
+ lr = args.last.line_range.first..args.first.line_range.last
436
+ #{node_class}.new(:#{kw}, args, :line => lr, :char => sr)
437
+ end
438
+ eof
439
+ end
440
+
441
+ %w(symbols qsymbols words qwords).each do |kw|
442
+ module_eval(<<-eof, __FILE__, __LINE__ + 1)
443
+ begin; undef on_#{kw}_new; rescue NameError; end
444
+ def on_#{kw}_new(*args)
445
+ node = LiteralNode.new(:#{kw}_literal, args)
446
+ @percent_ary = node
447
+ if @map[:#{kw}_beg]
448
+ lstart, sstart = *@map[:#{kw}_beg].pop
449
+ node.source_range = Range.new(sstart, @ns_charno-1)
450
+ node.line_range = Range.new(lstart, lineno)
451
+ end
452
+ node
453
+ end
454
+
455
+ begin; undef on_#{kw}_add; rescue NameError; end
456
+ def on_#{kw}_add(list, item)
457
+ last = @source[@ns_charno,1] == "\n" ? @ns_charno - 1 : @ns_charno
458
+ list.source_range = (list.source_range.first..last)
459
+ list.line_range = (list.line_range.first..lineno)
460
+ list.push(item)
461
+ list
462
+ end
463
+ eof
464
+ end
465
+
466
+ def on_string_literal(*args)
467
+ node = visit_event_arr(LiteralNode.new(:string_literal, args))
468
+ if args.size == 1
469
+ r = args[0].source_range
470
+ if node.source_range != Range.new(r.first - 1, r.last + 1)
471
+ klass = AstNode.node_class_for(node[0].type)
472
+ r = Range.new(node.source_range.first + 1, node.source_range.last - 1)
473
+ node[0] = klass.new(node[0].type, [@source[r]], :line => node.line_range, :char => r)
474
+ end
475
+ end
476
+ node
477
+ end
478
+
479
+ def on_lambda(*args)
480
+ visit_event_arr AstNode.new(:lambda, args)
481
+ end
482
+
483
+ def on_string_content(*args)
484
+ AstNode.new(:string_content, args, :listline => lineno..lineno, :listchar => charno..charno)
485
+ end
486
+
487
+ def on_rescue(exc, *args)
488
+ exc = AstNode.new(:list, exc) if exc
489
+ visit_event AstNode.new(:rescue, [exc, *args])
490
+ end
491
+
492
+ def on_void_stmt
493
+ AstNode.new(:void_stmt, [], :line => lineno..lineno, :char => charno...charno)
494
+ end
495
+
496
+ def on_params(*args)
497
+ args.map! do |arg|
498
+ next arg unless arg.class == Array
499
+
500
+ if arg.first.class == Array
501
+ arg.map! do |sub_arg|
502
+ next sub_arg unless sub_arg.class == Array
503
+ type = sub_arg[0].type == :label ?
504
+ :named_arg : :unnamed_optional_arg
505
+ AstNode.new(type, sub_arg, :listline => lineno..lineno, :listchar => charno..charno)
506
+ end
507
+ end
508
+
509
+ AstNode.new(:list, arg, :listline => lineno..lineno, :listchar => charno..charno)
510
+ end
511
+
512
+ ParameterNode.new(:params, args, :listline => lineno..lineno, :listchar => charno..charno)
513
+ end
514
+
515
+ def on_label(data)
516
+ add_token(:label, data)
517
+ ch = charno
518
+ @charno += data.length
519
+ @ns_charno = charno
520
+ AstNode.new(:label, [data[0...-1]], :line => lineno..lineno, :char => ch..charno - 1, :token => true)
521
+ end
522
+
523
+ def on_comment(comment)
524
+ not_comment = false
525
+ if @last_ns_token.nil? || @last_ns_token.empty?
526
+ if comment =~ SourceParser::SHEBANG_LINE && !@encoding_line
527
+ @shebang_line = comment
528
+ not_comment = true
529
+ elsif comment =~ SourceParser::ENCODING_LINE
530
+ @encoding_line = comment
531
+ not_comment = true
532
+ elsif comment =~ SourceParser::FROZEN_STRING_LINE
533
+ @frozen_string_line = comment
534
+ not_comment = true
535
+ end
536
+ end
537
+
538
+ ch = charno
539
+ visit_ns_token(:comment, comment)
540
+ if not_comment
541
+ @last_ns_token = nil
542
+ return
543
+ end
544
+
545
+ source_range = ch..(charno - 1)
546
+ comment = comment.gsub(/^(\#+)\s{0,1}/, '').chomp
547
+ append_comment = @comments[lineno - 1]
548
+
549
+ hash_flag = $1 == '##' ? true : false
550
+
551
+ if append_comment && @comments_last_column &&
552
+ @comments_last_column == column && comment_starts_line?(ch)
553
+ @comments.delete(lineno - 1)
554
+ @comments_flags[lineno] = @comments_flags[lineno - 1]
555
+ @comments_flags.delete(lineno - 1)
556
+ range = @comments_range.delete(lineno - 1)
557
+ source_range = range.first..source_range.last
558
+ comment = append_comment + "\n" + comment
559
+ end
560
+
561
+ @comments[lineno] = comment
562
+ @comments_range[lineno] = source_range
563
+ @comments_flags[lineno] = hash_flag unless append_comment
564
+ @comments_last_column = column
565
+ end
566
+
567
+ def on_embdoc_beg(text)
568
+ visit_ns_token(:embdoc_beg, text)
569
+ @embdoc_start = charno - text.length
570
+ @embdoc = String.new("")
571
+ end
572
+
573
+ def on_embdoc(text)
574
+ visit_ns_token(:embdoc, text)
575
+ @embdoc << text
576
+ end
577
+
578
+ def on_embdoc_end(text)
579
+ visit_ns_token(:embdoc_end, text)
580
+ @comments_last_column = nil
581
+ @comments[lineno] = @embdoc
582
+ @comments_range[lineno] = @embdoc_start...charno
583
+ @embdoc_start = nil
584
+ @embdoc = nil
585
+ end
586
+
587
+ def on_parse_error(msg)
588
+ raise ParserSyntaxError, "syntax error in `#{file}`:(#{lineno},#{column}): #{msg}"
589
+ end
590
+ alias compile_error on_parse_error
591
+
592
+ def comment_starts_line?(charno)
593
+ (charno - 1).downto(0) do |i|
594
+ ch = @source[i]
595
+ break if ch == "\n"
596
+ return false if ch != " " && ch != "\t"
597
+ end
598
+ true
599
+ end
600
+
601
+ def insert_comments
602
+ root.traverse do |node|
603
+ next if node.type == :comment || node.type == :list || node.parent.type != :list
604
+
605
+ # never attach comments to if/unless mod nodes
606
+ if node.type == :if_mod || node.type == :unless_mod
607
+ node = node.then_block
608
+ end
609
+
610
+ # check upwards from line before node; check node's line at the end
611
+ ((node.line - 1).downto(node.line - 2).to_a + [node.line]).each do |line|
612
+ comment = @comments[line]
613
+ if comment && !comment.empty?
614
+ add_comment(line, node)
615
+ break
616
+ end
617
+ end
618
+
619
+ @comments.keys.each do |line|
620
+ add_comment(line, nil, node) if node.line > line
621
+ end
622
+ end
623
+
624
+ # insert any lone unadded comments before node
625
+ root.traverse do |node|
626
+ next if node.type == :list || node.parent.type != :list
627
+ @comments.keys.each do |line|
628
+ next unless node.line_range.include?(line)
629
+ pick = nil
630
+ node.traverse do |subnode|
631
+ next unless subnode.type == :list
632
+ pick ||= subnode
633
+ next unless subnode.line_range.include?(line)
634
+ pick = subnode
635
+ end
636
+ add_comment(line, nil, pick, true) if pick
637
+ end
638
+ end unless @comments.empty?
639
+
640
+ # insert all remaining comments
641
+ @comments.each do |line, _comment|
642
+ add_comment(line, nil, root, true)
643
+ end
644
+
645
+ @comments = {}
646
+ end
647
+
648
+ def add_comment(line, node = nil, before_node = nil, into = false)
649
+ comment = @comments[line]
650
+ source_range = @comments_range[line]
651
+ line_range = ((line - comment.count("\n"))..line)
652
+ if node.nil?
653
+ node = CommentNode.new(:comment, [comment], :line => line_range, :char => source_range)
654
+ if into
655
+ before_node.push(node)
656
+ before_node.unfreeze
657
+ node.parent = before_node
658
+ elsif before_node
659
+ parent_node = before_node.parent
660
+ idx = parent_node.index(before_node)
661
+ parent_node.insert(idx, node)
662
+ parent_node.unfreeze
663
+ node.parent = parent_node
664
+ end
665
+ end
666
+ node.docstring = comment
667
+ node.docstring_hash_flag = @comments_flags[line]
668
+ node.docstring_range = line_range
669
+ @comments.delete(line)
670
+ @comments_range.delete(line)
671
+ @comments_flags.delete(line)
672
+ end
673
+
674
+ def freeze_tree(node = nil)
675
+ nodes = [node || root]
676
+ until nodes.empty?
677
+ p_node = nodes.shift
678
+ p_node.children.each do |child|
679
+ child.parent = p_node
680
+ nodes << child
681
+ end
682
+ end
683
+ end
684
+ end if defined?(::Ripper)
685
+ end
686
+ end
687
+ end