yard 0.9.16 → 0.9.17

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yard might be problematic. Click here for more details.

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