docspring 3.0.0 → 3.1.0

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 (523) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile.lock +4 -4
  4. data/README.md +11 -5
  5. data/docs/CreateHtmlSubmissionData.md +3 -1
  6. data/docs/CreatePdfSubmissionData.md +3 -1
  7. data/docs/PDFApi.md +156 -10
  8. data/docs/PublishVersionData.md +20 -0
  9. data/docs/RestoreVersionData.md +18 -0
  10. data/docs/Submission.md +4 -0
  11. data/docs/SubmissionPreview.md +4 -0
  12. data/docs/Template.md +15 -1
  13. data/docs/TemplateDeleteResponse.md +24 -0
  14. data/docs/TemplatePreview.md +13 -1
  15. data/docs/TemplatePublishVersionResponse.md +22 -0
  16. data/lib/docspring/api/pdf_api.rb +152 -5
  17. data/lib/docspring/api_client.rb +1 -1
  18. data/lib/docspring/models/combined_submission_action.rb +1 -5
  19. data/lib/docspring/models/create_html_submission_data.rb +13 -4
  20. data/lib/docspring/models/create_pdf_submission_data.rb +13 -4
  21. data/lib/docspring/models/publish_version_data.rb +230 -0
  22. data/lib/docspring/models/restore_version_data.rb +221 -0
  23. data/lib/docspring/models/submission.rb +41 -1
  24. data/lib/docspring/models/submission_data_request_event.rb +1 -5
  25. data/lib/docspring/models/submission_preview.rb +41 -1
  26. data/lib/docspring/models/template.rb +106 -4
  27. data/lib/docspring/models/template_delete_response.rb +287 -0
  28. data/lib/docspring/models/template_preview.rb +88 -4
  29. data/lib/docspring/models/template_publish_version_response.rb +282 -0
  30. data/lib/docspring/version.rb +1 -1
  31. data/lib/docspring.rb +4 -0
  32. data/spec/api/pdf_api_spec.rb +27 -2
  33. data/spec/models/create_html_submission_data_spec.rb +6 -0
  34. data/spec/models/create_pdf_submission_data_spec.rb +6 -0
  35. data/spec/models/publish_version_data_spec.rb +42 -0
  36. data/spec/models/restore_version_data_spec.rb +36 -0
  37. data/spec/models/submission_preview_spec.rb +16 -0
  38. data/spec/models/submission_spec.rb +16 -0
  39. data/spec/models/template_delete_response_spec.rb +58 -0
  40. data/spec/models/template_preview_spec.rb +40 -0
  41. data/spec/models/template_publish_version_response_spec.rb +52 -0
  42. data/spec/models/template_spec.rb +46 -0
  43. data/vendor/bundle/ruby/3.3.0/bin/irb +29 -0
  44. data/vendor/bundle/ruby/3.3.0/bin/rdbg +29 -0
  45. data/vendor/bundle/ruby/3.3.0/bin/rdoc +29 -0
  46. data/vendor/bundle/ruby/3.3.0/bin/ri +29 -0
  47. data/vendor/bundle/ruby/3.3.0/cache/ast-2.4.3.gem +0 -0
  48. data/vendor/bundle/ruby/3.3.0/cache/debug-1.10.0.gem +0 -0
  49. data/vendor/bundle/ruby/3.3.0/cache/io-console-0.8.0.gem +0 -0
  50. data/vendor/bundle/ruby/3.3.0/cache/irb-1.15.1.gem +0 -0
  51. data/vendor/bundle/ruby/3.3.0/cache/parser-3.3.7.2.gem +0 -0
  52. data/vendor/bundle/ruby/3.3.0/cache/pp-0.6.2.gem +0 -0
  53. data/vendor/bundle/ruby/3.3.0/cache/prettyprint-0.2.0.gem +0 -0
  54. data/vendor/bundle/ruby/3.3.0/cache/rdoc-6.12.0.gem +0 -0
  55. data/vendor/bundle/ruby/3.3.0/cache/reline-0.6.0.gem +0 -0
  56. data/vendor/bundle/ruby/3.3.0/extensions/arm64-darwin-24/3.3.0/debug-1.10.0/debug/debug.bundle +0 -0
  57. data/vendor/bundle/ruby/3.3.0/extensions/arm64-darwin-24/3.3.0/debug-1.10.0/gem.build_complete +0 -0
  58. data/vendor/bundle/ruby/3.3.0/extensions/arm64-darwin-24/3.3.0/debug-1.10.0/gem_make.out +19 -0
  59. data/vendor/bundle/ruby/3.3.0/extensions/arm64-darwin-24/3.3.0/io-console-0.8.0/gem.build_complete +0 -0
  60. data/vendor/bundle/ruby/3.3.0/extensions/arm64-darwin-24/3.3.0/io-console-0.8.0/gem_make.out +31 -0
  61. data/vendor/bundle/ruby/3.3.0/extensions/arm64-darwin-24/3.3.0/io-console-0.8.0/io/console.bundle +0 -0
  62. data/vendor/bundle/ruby/3.3.0/extensions/arm64-darwin-24/3.3.0/io-console-0.8.0/mkmf.log +447 -0
  63. data/vendor/bundle/ruby/3.3.0/gems/ast-2.4.3/LICENSE.MIT +20 -0
  64. data/vendor/bundle/ruby/3.3.0/gems/ast-2.4.3/README.YARD.md +12 -0
  65. data/vendor/bundle/ruby/3.3.0/gems/ast-2.4.3/lib/ast/node.rb +268 -0
  66. data/vendor/bundle/ruby/3.3.0/gems/ast-2.4.3/lib/ast/processor/mixin.rb +288 -0
  67. data/vendor/bundle/ruby/3.3.0/gems/ast-2.4.3/lib/ast/processor.rb +12 -0
  68. data/vendor/bundle/ruby/3.3.0/gems/ast-2.4.3/lib/ast/sexp.rb +30 -0
  69. data/vendor/bundle/ruby/3.3.0/gems/ast-2.4.3/lib/ast.rb +17 -0
  70. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/CONTRIBUTING.md +573 -0
  71. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/Gemfile +10 -0
  72. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/LICENSE.txt +22 -0
  73. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/README.md +970 -0
  74. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/Rakefile +57 -0
  75. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/TODO.md +23 -0
  76. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/debug.gemspec +33 -0
  77. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/exe/rdbg +53 -0
  78. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/ext/debug/Makefile +270 -0
  79. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/ext/debug/debug.c +228 -0
  80. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/ext/debug/debug_version.h +1 -0
  81. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/ext/debug/extconf.rb +27 -0
  82. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/ext/debug/iseq_collector.c +93 -0
  83. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/abbrev_command.rb +77 -0
  84. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/breakpoint.rb +556 -0
  85. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/client.rb +263 -0
  86. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/color.rb +123 -0
  87. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/config.rb +590 -0
  88. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/console.rb +213 -0
  89. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/dap_custom/traceInspector.rb +336 -0
  90. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/debug.bundle +0 -0
  91. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/frame_info.rb +188 -0
  92. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/irb_integration.rb +37 -0
  93. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/local.rb +115 -0
  94. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/open.rb +13 -0
  95. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/open_nonstop.rb +15 -0
  96. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/prelude.rb +50 -0
  97. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/server.rb +534 -0
  98. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/server_cdp.rb +1348 -0
  99. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/server_dap.rb +1108 -0
  100. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/session.rb +2659 -0
  101. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/source_repository.rb +150 -0
  102. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/start.rb +5 -0
  103. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/thread_client.rb +1455 -0
  104. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/tracer.rb +241 -0
  105. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug/version.rb +5 -0
  106. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/lib/debug.rb +9 -0
  107. data/vendor/bundle/ruby/3.3.0/gems/debug-1.10.0/misc/README.md.erb +636 -0
  108. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/.document +5 -0
  109. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/BSDL +22 -0
  110. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/COPYING +56 -0
  111. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/README.md +46 -0
  112. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/ext/io/console/Makefile +272 -0
  113. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/ext/io/console/console.c +1969 -0
  114. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/ext/io/console/extconf.rb +61 -0
  115. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/ext/io/console/win32_vk.inc +1390 -0
  116. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/lib/io/console/size.rb +23 -0
  117. data/vendor/bundle/ruby/3.3.0/gems/io-console-0.8.0/lib/io/console.bundle +0 -0
  118. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/Gemfile +29 -0
  119. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/LICENSE.txt +22 -0
  120. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/README.md +125 -0
  121. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/Rakefile +52 -0
  122. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/bin/console +6 -0
  123. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/bin/setup +6 -0
  124. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/doc/irb/irb-tools.rd.ja +184 -0
  125. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/doc/irb/irb.rd.ja +425 -0
  126. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/exe/irb +9 -0
  127. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/irb.gemspec +46 -0
  128. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/cmd/nop.rb +4 -0
  129. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/color.rb +263 -0
  130. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/color_printer.rb +56 -0
  131. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/backtrace.rb +17 -0
  132. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/base.rb +60 -0
  133. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/break.rb +17 -0
  134. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/catch.rb +17 -0
  135. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/cd.rb +51 -0
  136. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/chws.rb +40 -0
  137. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/context.rb +16 -0
  138. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/continue.rb +17 -0
  139. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/copy.rb +73 -0
  140. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/debug.rb +73 -0
  141. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/delete.rb +17 -0
  142. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/disable_irb.rb +19 -0
  143. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/edit.rb +63 -0
  144. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/exit.rb +18 -0
  145. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/finish.rb +17 -0
  146. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/force_exit.rb +18 -0
  147. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/help.rb +83 -0
  148. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/history.rb +45 -0
  149. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/info.rb +17 -0
  150. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/internal_helpers.rb +27 -0
  151. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/irb_info.rb +33 -0
  152. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/load.rb +91 -0
  153. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/ls.rb +167 -0
  154. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/measure.rb +49 -0
  155. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/next.rb +17 -0
  156. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/pushws.rb +65 -0
  157. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/show_doc.rb +51 -0
  158. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/show_source.rb +74 -0
  159. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/step.rb +17 -0
  160. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/subirb.rb +123 -0
  161. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command/whereami.rb +23 -0
  162. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/command.rb +23 -0
  163. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/completion.rb +504 -0
  164. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/context.rb +751 -0
  165. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/debug/ui.rb +101 -0
  166. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/debug.rb +127 -0
  167. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/default_commands.rb +279 -0
  168. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/easter-egg.rb +152 -0
  169. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ext/change-ws.rb +37 -0
  170. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ext/eval_history.rb +149 -0
  171. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ext/loader.rb +127 -0
  172. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ext/multi-irb.rb +258 -0
  173. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ext/tracer.rb +39 -0
  174. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ext/use-loader.rb +67 -0
  175. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ext/workspaces.rb +36 -0
  176. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/frame.rb +80 -0
  177. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/help.rb +28 -0
  178. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/helper_method/base.rb +16 -0
  179. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/helper_method/conf.rb +11 -0
  180. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/helper_method.rb +29 -0
  181. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/history.rb +116 -0
  182. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/init.rb +540 -0
  183. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/input-method.rb +515 -0
  184. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/inspector.rb +136 -0
  185. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/lc/error.rb +52 -0
  186. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/lc/help-message +55 -0
  187. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/lc/ja/error.rb +53 -0
  188. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/lc/ja/help-message +58 -0
  189. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/locale.rb +153 -0
  190. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/nesting_parser.rb +239 -0
  191. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/notifier.rb +230 -0
  192. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/output-method.rb +80 -0
  193. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/pager.rb +213 -0
  194. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ruby-lex.rb +476 -0
  195. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ruby_logo.aa +118 -0
  196. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/source_finder.rb +138 -0
  197. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/statement.rb +101 -0
  198. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/version.rb +11 -0
  199. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/workspace.rb +171 -0
  200. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/ws-for-case-2.rb +9 -0
  201. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb/xmp.rb +164 -0
  202. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/lib/irb.rb +736 -0
  203. data/vendor/bundle/ruby/3.3.0/gems/irb-1.15.1/man/irb.1 +292 -0
  204. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/LICENSE.txt +26 -0
  205. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/bin/ruby-parse +7 -0
  206. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/bin/ruby-rewrite +7 -0
  207. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/gauntlet_parser.rb +123 -0
  208. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/all.rb +17 -0
  209. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ast/node.rb +40 -0
  210. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ast/processor.rb +293 -0
  211. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/base.rb +291 -0
  212. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/builders/default.rb +2338 -0
  213. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/clobbering_error.rb +13 -0
  214. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/color.rb +32 -0
  215. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/context.rb +51 -0
  216. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/current.rb +137 -0
  217. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/current_arg_stack.rb +46 -0
  218. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/deprecation.rb +13 -0
  219. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/diagnostic/engine.rb +104 -0
  220. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/diagnostic.rb +163 -0
  221. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/lexer/dedenter.rb +88 -0
  222. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/lexer/explanation.rb +55 -0
  223. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/lexer/literal.rb +284 -0
  224. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/lexer/stack_state.rb +49 -0
  225. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/lexer-F0.rb +12922 -0
  226. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/lexer-F1.rb +14875 -0
  227. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/lexer-strings.rb +5424 -0
  228. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/macruby.rb +9634 -0
  229. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/max_numparam_stack.rb +56 -0
  230. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/messages.rb +125 -0
  231. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/meta.rb +48 -0
  232. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/rewriter.rb +105 -0
  233. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby18.rb +9272 -0
  234. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby19.rb +9558 -0
  235. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby20.rb +10229 -0
  236. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby21.rb +10203 -0
  237. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby22.rb +10302 -0
  238. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby23.rb +10322 -0
  239. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby24.rb +10454 -0
  240. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby25.rb +10374 -0
  241. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby26.rb +10352 -0
  242. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby27.rb +11947 -0
  243. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby30.rb +12243 -0
  244. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby31.rb +12716 -0
  245. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby32.rb +12704 -0
  246. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby33.rb +12589 -0
  247. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/ruby34.rb +12596 -0
  248. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/rubymotion.rb +9515 -0
  249. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/runner/ruby_parse.rb +157 -0
  250. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/runner/ruby_rewrite.rb +101 -0
  251. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/runner.rb +299 -0
  252. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/buffer.rb +369 -0
  253. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/comment/associator.rb +233 -0
  254. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/comment.rb +134 -0
  255. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/collection.rb +18 -0
  256. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/condition.rb +21 -0
  257. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/constant.rb +32 -0
  258. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/definition.rb +23 -0
  259. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/for.rb +19 -0
  260. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/heredoc.rb +19 -0
  261. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/index.rb +33 -0
  262. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/keyword.rb +20 -0
  263. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/method_definition.rb +25 -0
  264. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/objc_kwarg.rb +19 -0
  265. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/operator.rb +17 -0
  266. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/rescue_body.rb +21 -0
  267. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/send.rb +36 -0
  268. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/ternary.rb +18 -0
  269. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map/variable.rb +31 -0
  270. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/map.rb +186 -0
  271. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/range.rb +326 -0
  272. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/rewriter/action.rb +44 -0
  273. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/rewriter.rb +513 -0
  274. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/tree_rewriter/action.rb +243 -0
  275. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/source/tree_rewriter.rb +431 -0
  276. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/static_environment.rb +134 -0
  277. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/syntax_error.rb +21 -0
  278. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/tree_rewriter.rb +133 -0
  279. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/unknown_encoding_in_magic_comment_error.rb +15 -0
  280. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/variables_stack.rb +36 -0
  281. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser/version.rb +5 -0
  282. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/lib/parser.rb +91 -0
  283. data/vendor/bundle/ruby/3.3.0/gems/parser-3.3.7.2/parser.gemspec +43 -0
  284. data/vendor/bundle/ruby/3.3.0/gems/pp-0.6.2/BSDL +22 -0
  285. data/vendor/bundle/ruby/3.3.0/gems/pp-0.6.2/COPYING +56 -0
  286. data/vendor/bundle/ruby/3.3.0/gems/pp-0.6.2/lib/pp.rb +699 -0
  287. data/vendor/bundle/ruby/3.3.0/gems/pp-0.6.2/pp.gemspec +35 -0
  288. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/.github/dependabot.yml +6 -0
  289. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/.github/workflows/test.yml +41 -0
  290. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/.gitignore +8 -0
  291. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/Gemfile +4 -0
  292. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/LICENSE.txt +22 -0
  293. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/README.md +43 -0
  294. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/Rakefile +10 -0
  295. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/bin/console +14 -0
  296. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/bin/setup +8 -0
  297. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/lib/prettyprint.rb +558 -0
  298. data/vendor/bundle/ruby/3.3.0/gems/prettyprint-0.2.0/prettyprint.gemspec +29 -0
  299. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/CONTRIBUTING.rdoc +219 -0
  300. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/CVE-2013-0256.rdoc +49 -0
  301. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/ExampleMarkdown.md +39 -0
  302. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/ExampleRDoc.rdoc +210 -0
  303. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/History.rdoc +1668 -0
  304. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/LEGAL.rdoc +50 -0
  305. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/LICENSE.rdoc +59 -0
  306. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/README.rdoc +142 -0
  307. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/RI.md +842 -0
  308. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/TODO.rdoc +60 -0
  309. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/exe/rdoc +43 -0
  310. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/exe/ri +12 -0
  311. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/alias.rb +111 -0
  312. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/anon_class.rb +10 -0
  313. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/any_method.rb +379 -0
  314. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/attr.rb +175 -0
  315. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/class_module.rb +871 -0
  316. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/constant.rb +186 -0
  317. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/context/section.rb +175 -0
  318. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/context.rb +1264 -0
  319. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/extend.rb +9 -0
  320. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/ghost_method.rb +6 -0
  321. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/include.rb +9 -0
  322. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/meta_method.rb +6 -0
  323. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/method_attr.rb +430 -0
  324. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/mixin.rb +120 -0
  325. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/normal_class.rb +92 -0
  326. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/normal_module.rb +73 -0
  327. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/require.rb +51 -0
  328. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/single_class.rb +30 -0
  329. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object/top_level.rb +291 -0
  330. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_object.rb +426 -0
  331. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/code_objects.rb +5 -0
  332. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/comment.rb +239 -0
  333. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/cross_reference.rb +228 -0
  334. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/encoding.rb +120 -0
  335. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/erb_partial.rb +18 -0
  336. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/erbio.rb +37 -0
  337. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/darkfish.rb +824 -0
  338. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/json_index.rb +300 -0
  339. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/markup.rb +159 -0
  340. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/pot/message_extractor.rb +68 -0
  341. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/pot/po.rb +84 -0
  342. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/pot/po_entry.rb +141 -0
  343. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/pot.rb +99 -0
  344. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/ri.rb +30 -0
  345. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_footer.rhtml +5 -0
  346. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_head.rhtml +43 -0
  347. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +19 -0
  348. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +34 -0
  349. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +15 -0
  350. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +9 -0
  351. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +15 -0
  352. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +15 -0
  353. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +21 -0
  354. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml +11 -0
  355. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +32 -0
  356. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +6 -0
  357. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +14 -0
  358. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +11 -0
  359. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +39 -0
  360. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml +3 -0
  361. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/class.rhtml +206 -0
  362. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/css/fonts.css +167 -0
  363. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/css/rdoc.css +668 -0
  364. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf +0 -0
  365. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf +0 -0
  366. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf +0 -0
  367. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf +0 -0
  368. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
  369. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
  370. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/add.png +0 -0
  371. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/arrow_up.png +0 -0
  372. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/brick.png +0 -0
  373. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/brick_link.png +0 -0
  374. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/bug.png +0 -0
  375. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/bullet_black.png +0 -0
  376. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png +0 -0
  377. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png +0 -0
  378. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/date.png +0 -0
  379. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/delete.png +0 -0
  380. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/find.png +0 -0
  381. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif +0 -0
  382. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png +0 -0
  383. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/package.png +0 -0
  384. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/page_green.png +0 -0
  385. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/page_white_text.png +0 -0
  386. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/page_white_width.png +0 -0
  387. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/plugin.png +0 -0
  388. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/ruby.png +0 -0
  389. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/tag_blue.png +0 -0
  390. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/tag_green.png +0 -0
  391. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/transparent.png +0 -0
  392. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/wrench.png +0 -0
  393. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/wrench_orange.png +0 -0
  394. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/images/zoom.png +0 -0
  395. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/index.rhtml +23 -0
  396. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/js/darkfish.js +120 -0
  397. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/js/search.js +110 -0
  398. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/page.rhtml +18 -0
  399. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +20 -0
  400. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +65 -0
  401. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +70 -0
  402. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/json_index/js/navigation.js +105 -0
  403. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator/template/json_index/js/searcher.js +229 -0
  404. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/generator.rb +51 -0
  405. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/i18n/locale.rb +102 -0
  406. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/i18n/text.rb +126 -0
  407. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/i18n.rb +10 -0
  408. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/known_classes.rb +74 -0
  409. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markdown/entities.rb +2131 -0
  410. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markdown/literals.kpeg +21 -0
  411. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markdown/literals.rb +454 -0
  412. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markdown.kpeg +1244 -0
  413. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markdown.rb +16793 -0
  414. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/attr_changer.rb +22 -0
  415. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/attr_span.rb +35 -0
  416. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/attribute_manager.rb +405 -0
  417. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/attributes.rb +70 -0
  418. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/blank_line.rb +27 -0
  419. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/block_quote.rb +14 -0
  420. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/document.rb +164 -0
  421. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/formatter.rb +272 -0
  422. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/hard_break.rb +31 -0
  423. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/heading.rb +78 -0
  424. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/include.rb +42 -0
  425. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/indented_paragraph.rb +47 -0
  426. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/list.rb +101 -0
  427. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/list_item.rb +99 -0
  428. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/paragraph.rb +28 -0
  429. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/parser.rb +585 -0
  430. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/pre_process.rb +318 -0
  431. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/raw.rb +69 -0
  432. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/regexp_handling.rb +40 -0
  433. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/rule.rb +20 -0
  434. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/table.rb +56 -0
  435. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_ansi.rb +93 -0
  436. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_bs.rb +102 -0
  437. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_html.rb +452 -0
  438. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_html_crossref.rb +226 -0
  439. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_html_snippet.rb +287 -0
  440. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_joined_paragraph.rb +46 -0
  441. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_label.rb +74 -0
  442. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_markdown.rb +191 -0
  443. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_rdoc.rb +352 -0
  444. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_table_of_contents.rb +88 -0
  445. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_test.rb +69 -0
  446. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/to_tt_only.rb +120 -0
  447. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup/verbatim.rb +83 -0
  448. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/markup.rb +240 -0
  449. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/options.rb +1397 -0
  450. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/c.rb +1260 -0
  451. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/changelog.rb +350 -0
  452. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/markdown.rb +22 -0
  453. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/prism_ruby.rb +1099 -0
  454. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/rd.rb +22 -0
  455. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/ripper_state_lex.rb +302 -0
  456. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/ruby.rb +2381 -0
  457. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/ruby_tools.rb +165 -0
  458. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/simple.rb +61 -0
  459. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser/text.rb +11 -0
  460. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/parser.rb +297 -0
  461. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/rd/block_parser.rb +1706 -0
  462. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/rd/block_parser.ry +643 -0
  463. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/rd/inline.rb +71 -0
  464. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/rd/inline_parser.rb +1854 -0
  465. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/rd/inline_parser.ry +593 -0
  466. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/rd.rb +99 -0
  467. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/rdoc.rb +566 -0
  468. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/ri/driver.rb +1558 -0
  469. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/ri/formatter.rb +6 -0
  470. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/ri/paths.rb +171 -0
  471. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/ri/store.rb +6 -0
  472. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/ri/task.rb +71 -0
  473. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/ri.rb +20 -0
  474. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/rubygems_hook.rb +330 -0
  475. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/servlet.rb +451 -0
  476. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/stats/normal.rb +58 -0
  477. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/stats/quiet.rb +59 -0
  478. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/stats/verbose.rb +44 -0
  479. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/stats.rb +461 -0
  480. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/store.rb +1001 -0
  481. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/task.rb +354 -0
  482. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/text.rb +322 -0
  483. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/token_stream.rb +118 -0
  484. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/tom_doc.rb +257 -0
  485. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc/version.rb +10 -0
  486. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rdoc.rb +211 -0
  487. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/lib/rubygems_plugin.rb +23 -0
  488. data/vendor/bundle/ruby/3.3.0/gems/rdoc-6.12.0/man/ri.1 +247 -0
  489. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/BSDL +22 -0
  490. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/COPYING +56 -0
  491. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/README.md +94 -0
  492. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/config.rb +373 -0
  493. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/face.rb +199 -0
  494. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/history.rb +76 -0
  495. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/io/ansi.rb +325 -0
  496. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/io/dumb.rb +120 -0
  497. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/io/windows.rb +530 -0
  498. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/io.rb +55 -0
  499. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/key_actor/base.rb +37 -0
  500. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/key_actor/composite.rb +17 -0
  501. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/key_actor/emacs.rb +517 -0
  502. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/key_actor/vi_command.rb +518 -0
  503. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/key_actor/vi_insert.rb +517 -0
  504. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/key_actor.rb +8 -0
  505. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/key_stroke.rb +119 -0
  506. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/kill_ring.rb +125 -0
  507. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/line_editor.rb +2382 -0
  508. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/unicode/east_asian_width.rb +1267 -0
  509. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/unicode.rb +415 -0
  510. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline/version.rb +3 -0
  511. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/lib/reline.rb +519 -0
  512. data/vendor/bundle/ruby/3.3.0/gems/reline-0.6.0/license_of_rb-readline +25 -0
  513. data/vendor/bundle/ruby/3.3.0/plugins/rdoc_plugin.rb +1 -0
  514. data/vendor/bundle/ruby/3.3.0/specifications/ast-2.4.3.gemspec +29 -0
  515. data/vendor/bundle/ruby/3.3.0/specifications/debug-1.10.0.gemspec +32 -0
  516. data/vendor/bundle/ruby/3.3.0/specifications/io-console-0.8.0.gemspec +25 -0
  517. data/vendor/bundle/ruby/3.3.0/specifications/irb-1.15.1.gemspec +31 -0
  518. data/vendor/bundle/ruby/3.3.0/specifications/parser-3.3.7.2.gemspec +37 -0
  519. data/vendor/bundle/ruby/3.3.0/specifications/pp-0.6.2.gemspec +27 -0
  520. data/vendor/bundle/ruby/3.3.0/specifications/prettyprint-0.2.0.gemspec +23 -0
  521. data/vendor/bundle/ruby/3.3.0/specifications/rdoc-6.12.0.gemspec +31 -0
  522. data/vendor/bundle/ruby/3.3.0/specifications/reline-0.6.0.gemspec +26 -0
  523. metadata +499 -3
@@ -0,0 +1,2659 @@
1
+ # frozen_string_literal: true
2
+
3
+ return if ENV['RUBY_DEBUG_ENABLE'] == '0'
4
+
5
+ # skip to load debugger for bundle exec
6
+
7
+ if $0.end_with?('bin/bundle') && ARGV.first == 'exec'
8
+ trace_var(:$0) do |file|
9
+ trace_var(:$0, nil)
10
+ if /-r (#{Regexp.escape(__dir__)}\S+)/ =~ ENV['RUBYOPT']
11
+ lib = $1
12
+ $LOADED_FEATURES.delete_if{|path| path.start_with?(__dir__)}
13
+ ENV['RUBY_DEBUG_INITIAL_SUSPEND_PATH'] = file
14
+ require lib
15
+ ENV['RUBY_DEBUG_INITIAL_SUSPEND_PATH'] = nil
16
+ end
17
+ end
18
+
19
+ return
20
+ end
21
+
22
+ # restore RUBYOPT
23
+ if (added_opt = ENV['RUBY_DEBUG_ADDED_RUBYOPT']) &&
24
+ (rubyopt = ENV['RUBYOPT']) &&
25
+ rubyopt.end_with?(added_opt)
26
+
27
+ ENV['RUBYOPT'] = rubyopt.delete_suffix(added_opt)
28
+ ENV['RUBY_DEBUG_ADDED_RUBYOPT'] = nil
29
+ end
30
+
31
+ require_relative 'frame_info'
32
+ require_relative 'config'
33
+ require_relative 'thread_client'
34
+ require_relative 'source_repository'
35
+ require_relative 'breakpoint'
36
+ require_relative 'tracer'
37
+
38
+ # To prevent loading old lib/debug.rb in Ruby 2.6 to 3.0
39
+ $LOADED_FEATURES << 'debug.rb'
40
+ $LOADED_FEATURES << File.expand_path(File.join(__dir__, '..', 'debug.rb'))
41
+ require 'debug' # invalidate the $LOADED_FEATURE cache
42
+
43
+ require 'json' if ENV['RUBY_DEBUG_TEST_UI'] == 'terminal'
44
+ require 'pp'
45
+
46
+ class RubyVM::InstructionSequence
47
+ def traceable_lines_norec lines
48
+ code = self.to_a[13]
49
+ line = 0
50
+ code.each{|e|
51
+ case e
52
+ when Integer
53
+ line = e
54
+ when Symbol
55
+ if /\ARUBY_EVENT_/ =~ e.to_s
56
+ lines[line] = [e, *lines[line]]
57
+ end
58
+ end
59
+ }
60
+ end
61
+
62
+ def traceable_lines_rec lines
63
+ self.each_child{|ci| ci.traceable_lines_rec(lines)}
64
+ traceable_lines_norec lines
65
+ end
66
+
67
+ def type
68
+ self.to_a[9]
69
+ end unless method_defined?(:type)
70
+
71
+ def parameters_symbols
72
+ ary = self.to_a
73
+ argc = ary[4][:arg_size]
74
+ locals = ary.to_a[10]
75
+ locals[0...argc]
76
+ end unless method_defined?(:parameters_symbols)
77
+
78
+ def last_line
79
+ self.to_a[4][:code_location][2]
80
+ end unless method_defined?(:last_line)
81
+
82
+ def first_line
83
+ self.to_a[4][:code_location][0]
84
+ end unless method_defined?(:first_line)
85
+ end if defined?(RubyVM::InstructionSequence)
86
+
87
+ module DEBUGGER__
88
+ PresetCommands = Struct.new(:commands, :source, :auto_continue)
89
+ SessionCommand = Struct.new(:block, :repeat, :unsafe, :cancel_auto_continue, :postmortem)
90
+
91
+ class PostmortemError < RuntimeError; end
92
+
93
+ class Session
94
+ attr_reader :intercepted_sigint_cmd, :process_group, :subsession_id
95
+
96
+ include Color
97
+
98
+ def initialize
99
+ @ui = nil
100
+ @sr = SourceRepository.new
101
+ @bps = {} # bp.key => bp
102
+ # [file, line] => LineBreakpoint
103
+ # "Error" => CatchBreakpoint
104
+ # "Foo#bar" => MethodBreakpoint
105
+ # [:watch, ivar] => WatchIVarBreakpoint
106
+ # [:check, expr] => CheckBreakpoint
107
+ #
108
+ @tracers = {}
109
+ @th_clients = {} # {Thread => ThreadClient}
110
+ @q_evt = Queue.new
111
+ @displays = []
112
+ @tc = nil
113
+ @tc_id = 0
114
+ @preset_command = nil
115
+ @postmortem_hook = nil
116
+ @postmortem = false
117
+ @intercept_trap_sigint = false
118
+ @intercepted_sigint_cmd = 'DEFAULT'
119
+ @process_group = ProcessGroup.new
120
+ @subsession_stack = []
121
+ @subsession_id = 0
122
+
123
+ @frame_map = {} # for DAP: {id => [threadId, frame_depth]} and CDP: {id => frame_depth}
124
+ @var_map = {1 => [:globals], } # {id => ...} for DAP
125
+ @src_map = {} # {id => src}
126
+
127
+ @scr_id_map = {} # for CDP
128
+ @obj_map = {} # { object_id => ... } for CDP
129
+
130
+ @tp_thread_begin = nil
131
+ @tp_thread_end = nil
132
+
133
+ @commands = {}
134
+ @unsafe_context = false
135
+
136
+ @has_keep_script_lines = defined?(RubyVM.keep_script_lines)
137
+
138
+ @tp_load_script = TracePoint.new(:script_compiled){|tp|
139
+ eval_script = tp.eval_script unless @has_keep_script_lines
140
+ ThreadClient.current.on_load tp.instruction_sequence, eval_script
141
+ }
142
+ @tp_load_script.enable
143
+
144
+ @thread_stopper = thread_stopper
145
+ self.postmortem = CONFIG[:postmortem]
146
+
147
+ register_default_command
148
+ end
149
+
150
+ def active?
151
+ !@q_evt.closed?
152
+ end
153
+
154
+ def remote?
155
+ @ui.remote?
156
+ end
157
+
158
+ def stop_stepping? file, line, subsession_id = nil
159
+ if @bps.has_key? [file, line]
160
+ true
161
+ elsif subsession_id && @subsession_id != subsession_id
162
+ true
163
+ else
164
+ false
165
+ end
166
+ end
167
+
168
+ def activate ui = nil, on_fork: false
169
+ @ui = ui if ui
170
+
171
+ @tp_thread_begin&.disable
172
+ @tp_thread_end&.disable
173
+ @tp_thread_begin = nil
174
+ @tp_thread_end = nil
175
+ @ui.activate self, on_fork: on_fork
176
+
177
+ q = Queue.new
178
+ first_q = Queue.new
179
+ @session_server = Thread.new do
180
+ # make sure `@session_server` is assigned
181
+ first_q.pop; first_q = nil
182
+
183
+ Thread.current.name = 'DEBUGGER__::SESSION@server'
184
+ Thread.current.abort_on_exception = true
185
+
186
+ # Thread management
187
+ setup_threads
188
+ thc = get_thread_client Thread.current
189
+ thc.mark_as_management
190
+
191
+ if @ui.respond_to?(:reader_thread) && thc = get_thread_client(@ui.reader_thread)
192
+ thc.mark_as_management
193
+ end
194
+
195
+ @tp_thread_begin = TracePoint.new(:thread_begin) do |tp|
196
+ get_thread_client
197
+ end
198
+ @tp_thread_begin.enable
199
+
200
+ @tp_thread_end = TracePoint.new(:thread_end) do |tp|
201
+ @th_clients.delete(Thread.current)
202
+ end
203
+ @tp_thread_end.enable
204
+
205
+ # session start
206
+ q << true
207
+ session_server_main
208
+ end
209
+ first_q << :ok
210
+
211
+ q.pop
212
+
213
+ # For activating irb:rdbg with startup config like `RUBY_DEBUG_IRB_CONSOLE=1`
214
+ # Because in that case the `Config#if_updated` callback would not be triggered
215
+ if CONFIG[:irb_console] && !CONFIG[:open]
216
+ activate_irb_integration
217
+ end
218
+ end
219
+
220
+ def deactivate
221
+ get_thread_client.deactivate
222
+ @thread_stopper.disable
223
+ @tp_load_script.disable
224
+ @tp_thread_begin.disable
225
+ @tp_thread_end.disable
226
+ @bps.each_value{|bp| bp.disable}
227
+ @th_clients.each_value{|thc| thc.close}
228
+ @tracers.values.each{|t| t.disable}
229
+ @q_evt.close
230
+ @ui&.deactivate
231
+ @ui = nil
232
+ end
233
+
234
+ def reset_ui ui
235
+ @ui.deactivate
236
+ @ui = ui
237
+
238
+ # activate new ui
239
+ @tp_thread_begin.disable
240
+ @tp_thread_end.disable
241
+ @ui.activate self
242
+ if @ui.respond_to?(:reader_thread) && thc = get_thread_client(@ui.reader_thread)
243
+ thc.mark_as_management
244
+ end
245
+ @tp_thread_begin.enable
246
+ @tp_thread_end.enable
247
+ end
248
+
249
+ def pop_event
250
+ @q_evt.pop
251
+ end
252
+
253
+ def session_server_main
254
+ while evt = pop_event
255
+ process_event evt
256
+ end
257
+ ensure
258
+ deactivate
259
+ end
260
+
261
+ def request_tc(req)
262
+ @tc << req
263
+ end
264
+
265
+ def request_tc_with_restarted_threads(req)
266
+ restart_all_threads
267
+ request_tc(req)
268
+ end
269
+
270
+ def request_eval type, src
271
+ request_tc_with_restarted_threads [:eval, type, src]
272
+ end
273
+
274
+ def process_event evt
275
+ # variable `@internal_info` is only used for test
276
+ tc, output, ev, @internal_info, *ev_args = evt
277
+
278
+ output.each{|str| @ui.puts str} if ev != :suspend
279
+
280
+ # special event, tc is nil
281
+ # and we don't want to set @tc to the newly created thread's ThreadClient
282
+ if ev == :thread_begin
283
+ th = ev_args.shift
284
+ q = ev_args.shift
285
+ on_thread_begin th
286
+ q << true
287
+
288
+ return
289
+ end
290
+
291
+ @tc = tc
292
+
293
+ case ev
294
+ when :init
295
+ enter_subsession
296
+ wait_command_loop
297
+ when :load
298
+ iseq, src = ev_args
299
+ on_load iseq, src
300
+ request_tc :continue
301
+
302
+ when :trace
303
+ trace_id, msg = ev_args
304
+ if t = @tracers.values.find{|t| t.object_id == trace_id}
305
+ t.puts msg
306
+ end
307
+ request_tc :continue
308
+
309
+ when :suspend
310
+ enter_subsession if ev_args.first != :replay
311
+ output.each{|str| @ui.puts str} unless @ui.ignore_output_on_suspend?
312
+
313
+ case ev_args.first
314
+ when :breakpoint
315
+ bp, i = bp_index ev_args[1]
316
+ clean_bps unless bp
317
+ @ui.event :suspend_bp, i, bp, @tc.id
318
+ when :trap
319
+ @ui.event :suspend_trap, sig = ev_args[1], @tc.id
320
+
321
+ if sig == :SIGINT && (@intercepted_sigint_cmd.kind_of?(Proc) || @intercepted_sigint_cmd.kind_of?(String))
322
+ @ui.puts "#{@intercepted_sigint_cmd.inspect} is registered as SIGINT handler."
323
+ @ui.puts "`sigint` command execute it."
324
+ end
325
+ else
326
+ @ui.event :suspended, @tc.id
327
+ end
328
+
329
+ if @displays.empty?
330
+ wait_command_loop
331
+ else
332
+ request_eval :display, @displays
333
+ end
334
+ when :result
335
+ raise "[BUG] not in subsession" if @subsession_stack.empty?
336
+
337
+ case ev_args.first
338
+ when :try_display
339
+ failed_results = ev_args[1]
340
+ if failed_results.size > 0
341
+ i, _msg = failed_results.last
342
+ if i+1 == @displays.size
343
+ @ui.puts "canceled: #{@displays.pop}"
344
+ end
345
+ end
346
+
347
+ stop_all_threads
348
+ when :method_breakpoint, :watch_breakpoint
349
+ bp = ev_args[1]
350
+ if bp
351
+ add_bp(bp)
352
+ show_bps bp
353
+ else
354
+ # can't make a bp
355
+ end
356
+ when :trace_pass
357
+ obj_id = ev_args[1]
358
+ obj_inspect = ev_args[2]
359
+ opt = ev_args[3]
360
+ add_tracer ObjectTracer.new(@ui, obj_id, obj_inspect, **opt)
361
+ stop_all_threads
362
+ else
363
+ stop_all_threads
364
+ end
365
+
366
+ wait_command_loop
367
+
368
+ when :protocol_result
369
+ process_protocol_result ev_args
370
+ wait_command_loop
371
+ end
372
+ end
373
+
374
+ def add_preset_commands name, cmds, kick: true, continue: true
375
+ cs = cmds.map{|c|
376
+ c.each_line.map{|line|
377
+ line = line.strip.gsub(/\A\s*\#.*/, '').strip
378
+ line unless line.empty?
379
+ }.compact
380
+ }.flatten.compact
381
+
382
+ if @preset_command && !@preset_command.commands.empty?
383
+ @preset_command.commands += cs
384
+ else
385
+ @preset_command = PresetCommands.new(cs, name, continue)
386
+ end
387
+
388
+ ThreadClient.current.on_init name if kick
389
+ end
390
+
391
+ def source iseq
392
+ if !CONFIG[:no_color]
393
+ @sr.get_colored(iseq)
394
+ else
395
+ @sr.get(iseq)
396
+ end
397
+ end
398
+
399
+ def inspect
400
+ "DEBUGGER__::SESSION"
401
+ end
402
+
403
+ def wait_command_loop
404
+ loop do
405
+ case wait_command
406
+ when :retry
407
+ # nothing
408
+ else
409
+ break
410
+ end
411
+ rescue Interrupt
412
+ @ui.puts "\n^C"
413
+ retry
414
+ end
415
+ end
416
+
417
+ def prompt
418
+ if @postmortem
419
+ '(rdbg:postmortem) '
420
+ elsif @process_group.multi?
421
+ "(rdbg@#{process_info}) "
422
+ else
423
+ '(rdbg) '
424
+ end
425
+ end
426
+
427
+ def wait_command
428
+ if @preset_command
429
+ if @preset_command.commands.empty?
430
+ if @preset_command.auto_continue
431
+ @preset_command = nil
432
+
433
+ leave_subsession :continue
434
+ return
435
+ else
436
+ @preset_command = nil
437
+ return :retry
438
+ end
439
+ else
440
+ line = @preset_command.commands.shift
441
+ @ui.puts "(rdbg:#{@preset_command.source}) #{line}"
442
+ end
443
+ else
444
+ @ui.puts "INTERNAL_INFO: #{JSON.generate(@internal_info)}" if ENV['RUBY_DEBUG_TEST_UI'] == 'terminal'
445
+ line = @ui.readline prompt
446
+ end
447
+
448
+ case line
449
+ when String
450
+ process_command line
451
+ when Hash
452
+ process_protocol_request line # defined in server.rb
453
+ else
454
+ raise "unexpected input: #{line.inspect}"
455
+ end
456
+ end
457
+
458
+ private def register_command *names,
459
+ repeat: false, unsafe: true, cancel_auto_continue: false, postmortem: true,
460
+ &b
461
+ cmd = SessionCommand.new(b, repeat, unsafe, cancel_auto_continue, postmortem)
462
+
463
+ names.each{|name|
464
+ @commands[name] = cmd
465
+ }
466
+ end
467
+
468
+ def register_default_command
469
+ ### Control flow
470
+
471
+ # * `s[tep]`
472
+ # * Step in. Resume the program until next breakable point.
473
+ # * `s[tep] <n>`
474
+ # * Step in, resume the program at `<n>`th breakable point.
475
+ register_command 's', 'step',
476
+ repeat: true,
477
+ cancel_auto_continue: true,
478
+ postmortem: false do |arg|
479
+ step_command :in, arg
480
+ end
481
+
482
+ # * `n[ext]`
483
+ # * Step over. Resume the program until next line.
484
+ # * `n[ext] <n>`
485
+ # * Step over, same as `step <n>`.
486
+ register_command 'n', 'next',
487
+ repeat: true,
488
+ cancel_auto_continue: true,
489
+ postmortem: false do |arg|
490
+ step_command :next, arg
491
+ end
492
+
493
+ # * `fin[ish]`
494
+ # * Finish this frame. Resume the program until the current frame is finished.
495
+ # * `fin[ish] <n>`
496
+ # * Finish `<n>`th frames.
497
+ register_command 'fin', 'finish',
498
+ repeat: true,
499
+ cancel_auto_continue: true,
500
+ postmortem: false do |arg|
501
+ if arg&.to_i == 0
502
+ raise 'finish command with 0 does not make sense.'
503
+ end
504
+
505
+ step_command :finish, arg
506
+ end
507
+
508
+ # * `u[ntil]`
509
+ # * Similar to `next` command, but only stop later lines or the end of the current frame.
510
+ # * Similar to gdb's `advance` command.
511
+ # * `u[ntil] <[file:]line>`
512
+ # * Run til the program reaches given location or the end of the current frame.
513
+ # * `u[ntil] <name>`
514
+ # * Run til the program invokes a method `<name>`. `<name>` can be a regexp with `/name/`.
515
+ register_command 'u', 'until',
516
+ repeat: true,
517
+ cancel_auto_continue: true,
518
+ postmortem: false do |arg|
519
+
520
+ step_command :until, arg
521
+ end
522
+
523
+ # * `c` or `cont` or `continue`
524
+ # * Resume the program.
525
+ register_command 'c', 'cont', 'continue',
526
+ repeat: true,
527
+ cancel_auto_continue: true do |arg|
528
+ leave_subsession :continue
529
+ end
530
+
531
+ # * `q[uit]` or `Ctrl-D`
532
+ # * Finish debugger (with the debuggee process on non-remote debugging).
533
+ register_command 'q', 'quit' do |arg|
534
+ if ask 'Really quit?'
535
+ @ui.quit arg.to_i do
536
+ request_tc :quit
537
+ end
538
+ leave_subsession :continue
539
+ else
540
+ next :retry
541
+ end
542
+ end
543
+
544
+ # * `q[uit]!`
545
+ # * Same as q[uit] but without the confirmation prompt.
546
+ register_command 'q!', 'quit!', unsafe: false do |arg|
547
+ @ui.quit arg.to_i do
548
+ request_tc :quit
549
+ end
550
+ leave_subsession :continue
551
+ end
552
+
553
+ # * `kill`
554
+ # * Stop the debuggee process with `Kernel#exit!`.
555
+ register_command 'kill' do |arg|
556
+ if ask 'Really kill?'
557
+ exit! (arg || 1).to_i
558
+ else
559
+ next :retry
560
+ end
561
+ end
562
+
563
+ # * `kill!`
564
+ # * Same as kill but without the confirmation prompt.
565
+ register_command 'kill!', unsafe: false do |arg|
566
+ exit! (arg || 1).to_i
567
+ end
568
+
569
+ # * `sigint`
570
+ # * Execute SIGINT handler registered by the debuggee.
571
+ # * Note that this command should be used just after stop by `SIGINT`.
572
+ register_command 'sigint' do
573
+ begin
574
+ case cmd = @intercepted_sigint_cmd
575
+ when nil, 'IGNORE', :IGNORE, 'DEFAULT', :DEFAULT
576
+ # ignore
577
+ when String
578
+ eval(cmd)
579
+ when Proc
580
+ cmd.call
581
+ end
582
+
583
+ leave_subsession :continue
584
+
585
+ rescue Exception => e
586
+ @ui.puts "Exception: #{e}"
587
+ @ui.puts e.backtrace.map{|line| " #{e}"}
588
+ next :retry
589
+ end
590
+ end
591
+
592
+ ### Breakpoint
593
+
594
+ # * `b[reak]`
595
+ # * Show all breakpoints.
596
+ # * `b[reak] <line>`
597
+ # * Set breakpoint on `<line>` at the current frame's file.
598
+ # * `b[reak] <file>:<line>` or `<file> <line>`
599
+ # * Set breakpoint on `<file>:<line>`.
600
+ # * `b[reak] <class>#<name>`
601
+ # * Set breakpoint on the method `<class>#<name>`.
602
+ # * `b[reak] <expr>.<name>`
603
+ # * Set breakpoint on the method `<expr>.<name>`.
604
+ # * `b[reak] ... if: <expr>`
605
+ # * break if `<expr>` is true at specified location.
606
+ # * `b[reak] ... pre: <command>`
607
+ # * break and run `<command>` before stopping.
608
+ # * `b[reak] ... do: <command>`
609
+ # * break and run `<command>`, and continue.
610
+ # * `b[reak] ... path: <path>`
611
+ # * break if the path matches to `<path>`. `<path>` can be a regexp with `/regexp/`.
612
+ # * `b[reak] if: <expr>`
613
+ # * break if: `<expr>` is true at any lines.
614
+ # * Note that this feature is super slow.
615
+ register_command 'b', 'break', postmortem: false, unsafe: false do |arg|
616
+ if arg == nil
617
+ show_bps
618
+ next :retry
619
+ else
620
+ case bp = repl_add_breakpoint(arg)
621
+ when :noretry
622
+ when nil
623
+ next :retry
624
+ else
625
+ show_bps bp
626
+ next :retry
627
+ end
628
+ end
629
+ end
630
+
631
+ # * `catch <Error>`
632
+ # * Set breakpoint on raising `<Error>`.
633
+ # * `catch ... if: <expr>`
634
+ # * stops only if `<expr>` is true as well.
635
+ # * `catch ... pre: <command>`
636
+ # * runs `<command>` before stopping.
637
+ # * `catch ... do: <command>`
638
+ # * stops and run `<command>`, and continue.
639
+ # * `catch ... path: <path>`
640
+ # * stops if the exception is raised from a `<path>`. `<path>` can be a regexp with `/regexp/`.
641
+ register_command 'catch', postmortem: false, unsafe: false do |arg|
642
+ if arg
643
+ bp = repl_add_catch_breakpoint arg
644
+ show_bps bp if bp
645
+ else
646
+ show_bps
647
+ end
648
+
649
+ :retry
650
+ end
651
+
652
+ # * `watch @ivar`
653
+ # * Stop the execution when the result of current scope's `@ivar` is changed.
654
+ # * Note that this feature is super slow.
655
+ # * `watch ... if: <expr>`
656
+ # * stops only if `<expr>` is true as well.
657
+ # * `watch ... pre: <command>`
658
+ # * runs `<command>` before stopping.
659
+ # * `watch ... do: <command>`
660
+ # * stops and run `<command>`, and continue.
661
+ # * `watch ... path: <path>`
662
+ # * stops if the path matches `<path>`. `<path>` can be a regexp with `/regexp/`.
663
+ register_command 'wat', 'watch', postmortem: false, unsafe: false do |arg|
664
+ if arg && arg.match?(/\A@\w+/)
665
+ repl_add_watch_breakpoint(arg)
666
+ else
667
+ show_bps
668
+ :retry
669
+ end
670
+ end
671
+
672
+ # * `del[ete]`
673
+ # * delete all breakpoints.
674
+ # * `del[ete] <bpnum>`
675
+ # * delete specified breakpoint.
676
+ register_command 'del', 'delete', postmortem: false, unsafe: false do |arg|
677
+ case arg
678
+ when nil
679
+ show_bps
680
+ if ask "Remove all breakpoints?", 'N'
681
+ delete_bp
682
+ end
683
+ when /\d+/
684
+ bp = delete_bp arg.to_i
685
+ else
686
+ nil
687
+ end
688
+ @ui.puts "deleted: \##{bp[0]} #{bp[1]}" if bp
689
+ :retry
690
+ end
691
+
692
+ ### Information
693
+
694
+ # * `bt` or `backtrace`
695
+ # * Show backtrace (frame) information.
696
+ # * `bt <num>` or `backtrace <num>`
697
+ # * Only shows first `<num>` frames.
698
+ # * `bt /regexp/` or `backtrace /regexp/`
699
+ # * Only shows frames with method name or location info that matches `/regexp/`.
700
+ # * `bt <num> /regexp/` or `backtrace <num> /regexp/`
701
+ # * Only shows first `<num>` frames with method name or location info that matches `/regexp/`.
702
+ register_command 'bt', 'backtrace', unsafe: false do |arg|
703
+ case arg
704
+ when /\A(\d+)\z/
705
+ request_tc_with_restarted_threads [:show, :backtrace, arg.to_i, nil]
706
+ when /\A\/(.*)\/\z/
707
+ pattern = $1
708
+ request_tc_with_restarted_threads [:show, :backtrace, nil, Regexp.compile(pattern)]
709
+ when /\A(\d+)\s+\/(.*)\/\z/
710
+ max, pattern = $1, $2
711
+ request_tc_with_restarted_threads [:show, :backtrace, max.to_i, Regexp.compile(pattern)]
712
+ else
713
+ request_tc_with_restarted_threads [:show, :backtrace, nil, nil]
714
+ end
715
+ end
716
+
717
+ # * `l[ist]`
718
+ # * Show current frame's source code.
719
+ # * Next `list` command shows the successor lines.
720
+ # * `l[ist] -`
721
+ # * Show predecessor lines as opposed to the `list` command.
722
+ # * `l[ist] <start>` or `l[ist] <start>-<end>`
723
+ # * Show current frame's source code from the line <start> to <end> if given.
724
+ register_command 'l', 'list', repeat: true, unsafe: false do |arg|
725
+ case arg ? arg.strip : nil
726
+ when /\A(\d+)\z/
727
+ request_tc [:show, :list, {start_line: arg.to_i - 1}]
728
+ when /\A-\z/
729
+ request_tc [:show, :list, {dir: -1}]
730
+ when /\A(\d+)-(\d+)\z/
731
+ request_tc [:show, :list, {start_line: $1.to_i - 1, end_line: $2.to_i}]
732
+ when nil
733
+ request_tc [:show, :list]
734
+ else
735
+ @ui.puts "Can not handle list argument: #{arg}"
736
+ :retry
737
+ end
738
+ end
739
+
740
+ # * `whereami`
741
+ # * Show the current frame with source code.
742
+ register_command 'whereami', unsafe: false do
743
+ request_tc [:show, :whereami]
744
+ end
745
+
746
+ # * `edit`
747
+ # * Open the current file on the editor (use `EDITOR` environment variable).
748
+ # * Note that edited file will not be reloaded.
749
+ # * `edit <file>`
750
+ # * Open <file> on the editor.
751
+ register_command 'edit' do |arg|
752
+ if @ui.remote?
753
+ @ui.puts "not supported on the remote console."
754
+ next :retry
755
+ end
756
+
757
+ begin
758
+ arg = resolve_path(arg) if arg
759
+ rescue Errno::ENOENT
760
+ @ui.puts "not found: #{arg}"
761
+ next :retry
762
+ end
763
+
764
+ request_tc [:show, :edit, arg]
765
+ end
766
+
767
+ info_subcommands = nil
768
+ info_subcommands_abbrev = nil
769
+
770
+ # * `i[nfo]`
771
+ # * Show information about current frame (local/instance variables and defined constants).
772
+ # * `i[nfo]` <subcommand>
773
+ # * `info` has the following sub-commands.
774
+ # * Sub-commands can be specified with few letters which is unambiguous, like `l` for 'locals'.
775
+ # * `i[nfo] l or locals or local_variables`
776
+ # * Show information about the current frame (local variables)
777
+ # * It includes `self` as `%self` and a return value as `_return`.
778
+ # * `i[nfo] i or ivars or instance_variables`
779
+ # * Show information about instance variables about `self`.
780
+ # * `info ivars <expr>` shows the instance variables of the result of `<expr>`.
781
+ # * `i[nfo] c or consts or constants`
782
+ # * Show information about accessible constants except toplevel constants.
783
+ # * `info consts <expr>` shows the constants of a class/module of the result of `<expr>`
784
+ # * `i[nfo] g or globals or global_variables`
785
+ # * Show information about global variables
786
+ # * `i[nfo] th or threads`
787
+ # * Show all threads (same as `th[read]`).
788
+ # * `i[nfo] b or breakpoints or w or watchpoints`
789
+ # * Show all breakpoints and watchpoints.
790
+ # * `i[nfo] ... /regexp/`
791
+ # * Filter the output with `/regexp/`.
792
+ register_command 'i', 'info', unsafe: false do |arg|
793
+ if /\/(.+)\/\z/ =~ arg
794
+ pat = Regexp.compile($1)
795
+ sub = $~.pre_match.strip
796
+ else
797
+ sub = arg
798
+ end
799
+
800
+ if /\A(.+?)\b(.+)/ =~ sub
801
+ sub = $1
802
+ opt = $2.strip
803
+ opt = nil if opt.empty?
804
+ end
805
+
806
+ if sub && !info_subcommands
807
+ info_subcommands = {
808
+ locals: %w[ locals local_variables ],
809
+ ivars: %w[ ivars instance_variables ],
810
+ consts: %w[ consts constants ],
811
+ globals:%w[ globals global_variables ],
812
+ threads:%w[ threads ],
813
+ breaks: %w[ breakpoints ],
814
+ watchs: %w[ watchpoints ],
815
+ }
816
+
817
+ require_relative 'abbrev_command'
818
+ info_subcommands_abbrev = AbbrevCommand.new(info_subcommands)
819
+ end
820
+
821
+ if sub
822
+ sub = info_subcommands_abbrev.search sub, :unknown do |candidates|
823
+ # note: unreached now
824
+ @ui.puts "Ambiguous command '#{sub}': #{candidates.join(' ')}"
825
+ end
826
+ end
827
+
828
+ case sub
829
+ when nil
830
+ request_tc_with_restarted_threads [:show, :default, pat] # something useful
831
+ when :locals
832
+ request_tc_with_restarted_threads [:show, :locals, pat]
833
+ when :ivars
834
+ request_tc_with_restarted_threads [:show, :ivars, pat, opt]
835
+ when :consts
836
+ request_tc_with_restarted_threads [:show, :consts, pat, opt]
837
+ when :globals
838
+ request_tc_with_restarted_threads [:show, :globals, pat]
839
+ when :threads
840
+ thread_list
841
+ :retry
842
+ when :breaks, :watchs
843
+ show_bps
844
+ :retry
845
+ else
846
+ @ui.puts "unrecognized argument for info command: #{arg}"
847
+ show_help 'info'
848
+ :retry
849
+ end
850
+ end
851
+
852
+ # * `o[utline]` or `ls`
853
+ # * Show you available methods, constants, local variables, and instance variables in the current scope.
854
+ # * `o[utline] <expr>` or `ls <expr>`
855
+ # * Show you available methods and instance variables of the given object.
856
+ # * If the object is a class/module, it also lists its constants.
857
+ register_command 'outline', 'o', 'ls', unsafe: false do |arg|
858
+ request_tc_with_restarted_threads [:show, :outline, arg]
859
+ end
860
+
861
+ # * `display`
862
+ # * Show display setting.
863
+ # * `display <expr>`
864
+ # * Show the result of `<expr>` at every suspended timing.
865
+ register_command 'display', postmortem: false do |arg|
866
+ if arg && !arg.empty?
867
+ @displays << arg
868
+ request_eval :try_display, @displays
869
+ else
870
+ request_eval :display, @displays
871
+ end
872
+ end
873
+
874
+ # * `undisplay`
875
+ # * Remove all display settings.
876
+ # * `undisplay <displaynum>`
877
+ # * Remove a specified display setting.
878
+ register_command 'undisplay', postmortem: false, unsafe: false do |arg|
879
+ case arg
880
+ when /(\d+)/
881
+ if @displays[n = $1.to_i]
882
+ @displays.delete_at n
883
+ end
884
+ request_eval :display, @displays
885
+ when nil
886
+ if ask "clear all?", 'N'
887
+ @displays.clear
888
+ end
889
+ :retry
890
+ end
891
+ end
892
+
893
+ ### Frame control
894
+
895
+ # * `f[rame]`
896
+ # * Show the current frame.
897
+ # * `f[rame] <framenum>`
898
+ # * Specify a current frame. Evaluation are run on specified frame.
899
+ register_command 'frame', 'f', unsafe: false do |arg|
900
+ request_tc [:frame, :set, arg]
901
+ end
902
+
903
+ # * `up`
904
+ # * Specify the upper frame.
905
+ register_command 'up', repeat: true, unsafe: false do |arg|
906
+ request_tc [:frame, :up]
907
+ end
908
+
909
+ # * `down`
910
+ # * Specify the lower frame.
911
+ register_command 'down', repeat: true, unsafe: false do |arg|
912
+ request_tc [:frame, :down]
913
+ end
914
+
915
+ ### Evaluate
916
+
917
+ # * `p <expr>`
918
+ # * Evaluate like `p <expr>` on the current frame.
919
+ register_command 'p' do |arg|
920
+ request_eval :p, arg.to_s
921
+ end
922
+
923
+ # * `pp <expr>`
924
+ # * Evaluate like `pp <expr>` on the current frame.
925
+ register_command 'pp' do |arg|
926
+ request_eval :pp, arg.to_s
927
+ end
928
+
929
+ # * `eval <expr>`
930
+ # * Evaluate `<expr>` on the current frame.
931
+ register_command 'eval', 'call' do |arg|
932
+ if arg == nil || arg.empty?
933
+ show_help 'eval'
934
+ @ui.puts "\nTo evaluate the variable `#{cmd}`, use `pp #{cmd}` instead."
935
+ :retry
936
+ else
937
+ request_eval :call, arg
938
+ end
939
+ end
940
+
941
+ # * `irb`
942
+ # * Activate and switch to `irb:rdbg` console
943
+ register_command 'irb' do |arg|
944
+ if @ui.remote?
945
+ @ui.puts "\nIRB is not supported on the remote console."
946
+ else
947
+ config_set :irb_console, true
948
+ end
949
+
950
+ :retry
951
+ end
952
+
953
+ ### Trace
954
+ # * `trace`
955
+ # * Show available tracers list.
956
+ # * `trace line`
957
+ # * Add a line tracer. It indicates line events.
958
+ # * `trace call`
959
+ # * Add a call tracer. It indicate call/return events.
960
+ # * `trace exception`
961
+ # * Add an exception tracer. It indicates raising exceptions.
962
+ # * `trace object <expr>`
963
+ # * Add an object tracer. It indicates that an object by `<expr>` is passed as a parameter or a receiver on method call.
964
+ # * `trace ... /regexp/`
965
+ # * Indicates only matched events to `/regexp/`.
966
+ # * `trace ... into: <file>`
967
+ # * Save trace information into: `<file>`.
968
+ # * `trace off <num>`
969
+ # * Disable tracer specified by `<num>` (use `trace` command to check the numbers).
970
+ # * `trace off [line|call|pass]`
971
+ # * Disable all tracers. If `<type>` is provided, disable specified type tracers.
972
+ register_command 'trace', postmortem: false, unsafe: false do |arg|
973
+ if (re = /\s+into:\s*(.+)/) =~ arg
974
+ into = $1
975
+ arg.sub!(re, '')
976
+ end
977
+
978
+ if (re = /\s\/(.+)\/\z/) =~ arg
979
+ pattern = $1
980
+ arg.sub!(re, '')
981
+ end
982
+
983
+ case arg
984
+ when nil
985
+ @ui.puts 'Tracers:'
986
+ @tracers.values.each_with_index{|t, i|
987
+ @ui.puts "* \##{i} #{t}"
988
+ }
989
+ @ui.puts
990
+ :retry
991
+
992
+ when /\Aline\z/
993
+ add_tracer LineTracer.new(@ui, pattern: pattern, into: into)
994
+ :retry
995
+
996
+ when /\Acall\z/
997
+ add_tracer CallTracer.new(@ui, pattern: pattern, into: into)
998
+ :retry
999
+
1000
+ when /\Aexception\z/
1001
+ add_tracer ExceptionTracer.new(@ui, pattern: pattern, into: into)
1002
+ :retry
1003
+
1004
+ when /\Aobject\s+(.+)/
1005
+ request_tc_with_restarted_threads [:trace, :object, $1.strip, {pattern: pattern, into: into}]
1006
+
1007
+ when /\Aoff\s+(\d+)\z/
1008
+ if t = @tracers.values[$1.to_i]
1009
+ t.disable
1010
+ @ui.puts "Disable #{t.to_s}"
1011
+ else
1012
+ @ui.puts "Unmatched: #{$1}"
1013
+ end
1014
+ :retry
1015
+
1016
+ when /\Aoff(\s+(line|call|exception|object))?\z/
1017
+ @tracers.values.each{|t|
1018
+ if $2.nil? || t.type == $2
1019
+ t.disable
1020
+ @ui.puts "Disable #{t.to_s}"
1021
+ end
1022
+ }
1023
+ :retry
1024
+
1025
+ else
1026
+ @ui.puts "Unknown trace option: #{arg.inspect}"
1027
+ :retry
1028
+ end
1029
+ end
1030
+
1031
+ # Record
1032
+ # * `record`
1033
+ # * Show recording status.
1034
+ # * `record [on|off]`
1035
+ # * Start/Stop recording.
1036
+ # * `step back`
1037
+ # * Start replay. Step back with the last execution log.
1038
+ # * `s[tep]` does stepping forward with the last log.
1039
+ # * `step reset`
1040
+ # * Stop replay .
1041
+ register_command 'record', postmortem: false, unsafe: false do |arg|
1042
+ case arg
1043
+ when nil, 'on', 'off'
1044
+ request_tc [:record, arg&.to_sym]
1045
+ else
1046
+ @ui.puts "unknown command: #{arg}"
1047
+ :retry
1048
+ end
1049
+ end
1050
+
1051
+ ### Thread control
1052
+
1053
+ # * `th[read]`
1054
+ # * Show all threads.
1055
+ # * `th[read] <thnum>`
1056
+ # * Switch thread specified by `<thnum>`.
1057
+ register_command 'th', 'thread', unsafe: false do |arg|
1058
+ case arg
1059
+ when nil, 'list', 'l'
1060
+ thread_list
1061
+ when /(\d+)/
1062
+ switch_thread $1.to_i
1063
+ else
1064
+ @ui.puts "unknown thread command: #{arg}"
1065
+ end
1066
+ :retry
1067
+ end
1068
+
1069
+ ### Configuration
1070
+ # * `config`
1071
+ # * Show all configuration with description.
1072
+ # * `config <name>`
1073
+ # * Show current configuration of <name>.
1074
+ # * `config set <name> <val>` or `config <name> = <val>`
1075
+ # * Set <name> to <val>.
1076
+ # * `config append <name> <val>` or `config <name> << <val>`
1077
+ # * Append `<val>` to `<name>` if it is an array.
1078
+ # * `config unset <name>`
1079
+ # * Set <name> to default.
1080
+ register_command 'config', unsafe: false do |arg|
1081
+ config_command arg
1082
+ :retry
1083
+ end
1084
+
1085
+ # * `source <file>`
1086
+ # * Evaluate lines in `<file>` as debug commands.
1087
+ register_command 'source' do |arg|
1088
+ if arg
1089
+ begin
1090
+ cmds = File.readlines(path = File.expand_path(arg))
1091
+ add_preset_commands path, cmds, kick: true, continue: false
1092
+ rescue Errno::ENOENT
1093
+ @ui.puts "File not found: #{arg}"
1094
+ end
1095
+ else
1096
+ show_help 'source'
1097
+ end
1098
+ :retry
1099
+ end
1100
+
1101
+ # * `open`
1102
+ # * open debuggee port on UNIX domain socket and wait for attaching.
1103
+ # * Note that `open` command is EXPERIMENTAL.
1104
+ # * `open [<host>:]<port>`
1105
+ # * open debuggee port on TCP/IP with given `[<host>:]<port>` and wait for attaching.
1106
+ # * `open vscode`
1107
+ # * open debuggee port for VSCode and launch VSCode if available.
1108
+ # * `open chrome`
1109
+ # * open debuggee port for Chrome and wait for attaching.
1110
+ register_command 'open' do |arg|
1111
+ case arg&.downcase
1112
+ when '', nil
1113
+ ::DEBUGGER__.open nonstop: true
1114
+ when /\A(\d+)z/
1115
+ ::DEBUGGER__.open_tcp host: nil, port: $1.to_i, nonstop: true
1116
+ when /\A(.+):(\d+)\z/
1117
+ ::DEBUGGER__.open_tcp host: $1, port: $2.to_i, nonstop: true
1118
+ when 'tcp'
1119
+ ::DEBUGGER__.open_tcp host: CONFIG[:host], port: (CONFIG[:port] || 0), nonstop: true
1120
+ when 'vscode'
1121
+ CONFIG[:open] = 'vscode'
1122
+ ::DEBUGGER__.open nonstop: true
1123
+ when 'chrome', 'cdp'
1124
+ CONFIG[:open] = 'chrome'
1125
+ ::DEBUGGER__.open_tcp host: CONFIG[:host], port: (CONFIG[:port] || 0), nonstop: true
1126
+ else
1127
+ raise "Unknown arg: #{arg}"
1128
+ end
1129
+
1130
+ :retry
1131
+ end
1132
+
1133
+ ### Help
1134
+
1135
+ # * `h[elp]`
1136
+ # * Show help for all commands.
1137
+ # * `h[elp] <command>`
1138
+ # * Show help for the given command.
1139
+ register_command 'h', 'help', '?', unsafe: false do |arg|
1140
+ show_help arg
1141
+ :retry
1142
+ end
1143
+ end
1144
+
1145
+ def process_command line
1146
+ if line.empty?
1147
+ if @repl_prev_line
1148
+ line = @repl_prev_line
1149
+ else
1150
+ return :retry
1151
+ end
1152
+ else
1153
+ @repl_prev_line = line
1154
+ end
1155
+
1156
+ /([^\s]+)(?:\s+(.+))?/ =~ line
1157
+ cmd_name, cmd_arg = $1, $2
1158
+
1159
+ if cmd = @commands[cmd_name]
1160
+ check_postmortem if !cmd.postmortem
1161
+ check_unsafe if cmd.unsafe
1162
+ cancel_auto_continue if cmd.cancel_auto_continue
1163
+ @repl_prev_line = nil if !cmd.repeat
1164
+
1165
+ cmd.block.call(cmd_arg)
1166
+ else
1167
+ @repl_prev_line = nil
1168
+ check_unsafe
1169
+
1170
+ request_eval :pp, line
1171
+ end
1172
+
1173
+ rescue Interrupt
1174
+ return :retry
1175
+ rescue SystemExit
1176
+ raise
1177
+ rescue PostmortemError => e
1178
+ @ui.puts e.message
1179
+ return :retry
1180
+ rescue Exception => e
1181
+ @ui.puts "[REPL ERROR] #{e.inspect}"
1182
+ @ui.puts e.backtrace.map{|e| ' ' + e}
1183
+ return :retry
1184
+ end
1185
+
1186
+ def step_command type, arg
1187
+ if type == :until
1188
+ leave_subsession [:step, type, arg]
1189
+ return
1190
+ end
1191
+
1192
+ case arg
1193
+ when nil, /\A\d+\z/
1194
+ if type == :in && @tc.recorder&.replaying?
1195
+ request_tc [:step, type, arg&.to_i]
1196
+ else
1197
+ leave_subsession [:step, type, arg&.to_i]
1198
+ end
1199
+ when /\A(back)\z/, /\A(back)\s+(\d+)\z/, /\A(reset)\z/
1200
+ if type != :in
1201
+ @ui.puts "only `step #{arg}` is supported."
1202
+ :retry
1203
+ else
1204
+ type = $1.to_sym
1205
+ iter = $2&.to_i
1206
+ request_tc [:step, type, iter]
1207
+ end
1208
+ else
1209
+ @ui.puts "Unknown option: #{arg}"
1210
+ :retry
1211
+ end
1212
+ end
1213
+
1214
+ def config_show key
1215
+ key = key.to_sym
1216
+ config_detail = CONFIG_SET[key]
1217
+
1218
+ if config_detail
1219
+ v = CONFIG[key]
1220
+ kv = "#{key} = #{v.inspect}"
1221
+ desc = config_detail[1]
1222
+
1223
+ if config_default = config_detail[3]
1224
+ desc += " (default: #{config_default})"
1225
+ end
1226
+
1227
+ line = "%-34s \# %s" % [kv, desc]
1228
+ if line.size > SESSION.width
1229
+ @ui.puts "\# #{desc}\n#{kv}"
1230
+ else
1231
+ @ui.puts line
1232
+ end
1233
+ else
1234
+ @ui.puts "Unknown configuration: #{key}. 'config' shows all configurations."
1235
+ end
1236
+ end
1237
+
1238
+ def config_set key, val, append: false
1239
+ if CONFIG_SET[key = key.to_sym]
1240
+ begin
1241
+ if append
1242
+ CONFIG.append_config(key, val)
1243
+ else
1244
+ CONFIG[key] = val
1245
+ end
1246
+ rescue => e
1247
+ @ui.puts e.message
1248
+ end
1249
+ end
1250
+
1251
+ config_show key
1252
+ end
1253
+
1254
+ def config_command arg
1255
+ case arg
1256
+ when nil
1257
+ CONFIG_SET.each do |k, _|
1258
+ config_show k
1259
+ end
1260
+
1261
+ when /\Aunset\s+(.+)\z/
1262
+ if CONFIG_SET[key = $1.to_sym]
1263
+ CONFIG[key] = nil
1264
+ end
1265
+ config_show key
1266
+
1267
+ when /\A(\w+)\s*=\s*(.+)\z/
1268
+ config_set $1, $2
1269
+
1270
+ when /\A\s*set\s+(\w+)\s+(.+)\z/
1271
+ config_set $1, $2
1272
+
1273
+ when /\A(\w+)\s*<<\s*(.+)\z/
1274
+ config_set $1, $2, append: true
1275
+
1276
+ when /\A\s*append\s+(\w+)\s+(.+)\z/
1277
+ config_set $1, $2, append: true
1278
+
1279
+ when /\A(\w+)\z/
1280
+ config_show $1
1281
+
1282
+ else
1283
+ @ui.puts "Can not parse parameters: #{arg}"
1284
+ end
1285
+ end
1286
+
1287
+
1288
+ def cancel_auto_continue
1289
+ if @preset_command&.auto_continue
1290
+ @preset_command.auto_continue = false
1291
+ end
1292
+ end
1293
+
1294
+ def show_help arg = nil
1295
+ instructions = (DEBUGGER__.commands.keys + DEBUGGER__.commands.values).uniq
1296
+ print_instructions = proc do |desc|
1297
+ desc.split("\n").each do |line|
1298
+ next if line.start_with?(" ") # workaround for step back
1299
+ formatted_line = line.gsub(/[\[\]\*]/, "").strip
1300
+ instructions.each do |inst|
1301
+ if formatted_line.start_with?("`#{inst}")
1302
+ desc.sub!(line, colorize(line, [:CYAN, :BOLD]))
1303
+ end
1304
+ end
1305
+ end
1306
+ @ui.puts desc
1307
+ end
1308
+
1309
+ print_category = proc do |cat|
1310
+ @ui.puts "\n"
1311
+ @ui.puts colorize("### #{cat}", [:GREEN, :BOLD])
1312
+ @ui.puts "\n"
1313
+ end
1314
+
1315
+ DEBUGGER__.helps.each { |cat, cs|
1316
+ # categories
1317
+ if arg.nil?
1318
+ print_category.call(cat)
1319
+ else
1320
+ cs.each { |ws, _|
1321
+ if ws.include?(arg)
1322
+ print_category.call(cat)
1323
+ break
1324
+ end
1325
+ }
1326
+ end
1327
+
1328
+ # instructions
1329
+ cs.each { |ws, desc|
1330
+ if arg.nil? || ws.include?(arg)
1331
+ print_instructions.call(desc.dup)
1332
+ return if arg
1333
+ end
1334
+ }
1335
+ }
1336
+
1337
+ @ui.puts "not found: #{arg}" if arg
1338
+ end
1339
+
1340
+ def ask msg, default = 'Y'
1341
+ opts = '[y/n]'.tr(default.downcase, default)
1342
+ input = @ui.ask("#{msg} #{opts} ")
1343
+ input = default if input.empty?
1344
+ case input
1345
+ when 'y', 'Y'
1346
+ true
1347
+ else
1348
+ false
1349
+ end
1350
+ end
1351
+
1352
+ # breakpoint management
1353
+
1354
+ def iterate_bps
1355
+ deleted_bps = []
1356
+ i = 0
1357
+ @bps.each{|key, bp|
1358
+ if !bp.deleted?
1359
+ yield key, bp, i
1360
+ i += 1
1361
+ else
1362
+ deleted_bps << bp
1363
+ end
1364
+ }
1365
+ ensure
1366
+ deleted_bps.each{|bp| @bps.delete bp}
1367
+ end
1368
+
1369
+ def show_bps specific_bp = nil
1370
+ iterate_bps do |key, bp, i|
1371
+ @ui.puts "#%d %s" % [i, bp.to_s] if !specific_bp || bp == specific_bp
1372
+ end
1373
+ end
1374
+
1375
+ def bp_index specific_bp_key
1376
+ iterate_bps do |key, bp, i|
1377
+ if key == specific_bp_key
1378
+ return [bp, i]
1379
+ end
1380
+ end
1381
+ nil
1382
+ end
1383
+
1384
+ def rehash_bps
1385
+ bps = @bps.values
1386
+ @bps.clear
1387
+ bps.each{|bp|
1388
+ add_bp bp
1389
+ }
1390
+ end
1391
+
1392
+ def clean_bps
1393
+ @bps.delete_if{|_k, bp|
1394
+ bp.deleted?
1395
+ }
1396
+ end
1397
+
1398
+ def add_bp bp
1399
+ # don't repeat commands that add breakpoints
1400
+ if @bps.has_key? bp.key
1401
+ if bp.duplicable?
1402
+ bp
1403
+ else
1404
+ @ui.puts "duplicated breakpoint: #{bp}"
1405
+ bp.disable
1406
+ nil
1407
+ end
1408
+ else
1409
+ @bps[bp.key] = bp
1410
+ end
1411
+ end
1412
+
1413
+ def delete_bp arg = nil
1414
+ case arg
1415
+ when nil
1416
+ @bps.each{|key, bp| bp.delete}
1417
+ @bps.clear
1418
+ else
1419
+ del_bp = nil
1420
+ iterate_bps{|key, bp, i| del_bp = bp if i == arg}
1421
+ if del_bp
1422
+ del_bp.delete
1423
+ @bps.delete del_bp.key
1424
+ return [arg, del_bp]
1425
+ end
1426
+ end
1427
+ end
1428
+
1429
+ BREAK_KEYWORDS = %w(if: do: pre: path:).freeze
1430
+
1431
+ private def parse_break type, arg
1432
+ mode = :sig
1433
+ expr = Hash.new{|h, k| h[k] = []}
1434
+ arg.split(' ').each{|w|
1435
+ if BREAK_KEYWORDS.any?{|pat| w == pat}
1436
+ mode = w[0..-2].to_sym
1437
+ else
1438
+ expr[mode] << w
1439
+ end
1440
+ }
1441
+ expr.default_proc = nil
1442
+ expr = expr.transform_values{|v| v.join(' ')}
1443
+
1444
+ if (path = expr[:path]) && path =~ /\A\/(.*)\/\z/
1445
+ expr[:path] = Regexp.compile($1)
1446
+ end
1447
+
1448
+ if expr[:do] || expr[:pre]
1449
+ check_unsafe
1450
+ expr[:cmd] = [type, expr[:pre], expr[:do]]
1451
+ end
1452
+
1453
+ expr
1454
+ end
1455
+
1456
+ def repl_add_breakpoint arg
1457
+ expr = parse_break 'break', arg.strip
1458
+ cond = expr[:if]
1459
+ cmd = expr[:cmd]
1460
+ path = expr[:path]
1461
+
1462
+ case expr[:sig]
1463
+ when /\A(\d+)\z/
1464
+ add_line_breakpoint @tc.location.path, $1.to_i, cond: cond, command: cmd
1465
+ when /\A(.+)[:\s+](\d+)\z/
1466
+ add_line_breakpoint $1, $2.to_i, cond: cond, command: cmd
1467
+ when /\A(.+)([\.\#])(.+)\z/
1468
+ request_tc [:breakpoint, :method, $1, $2, $3, cond, cmd, path]
1469
+ return :noretry
1470
+ when nil
1471
+ add_check_breakpoint cond, path, cmd
1472
+ else
1473
+ @ui.puts "Unknown breakpoint format: #{arg}"
1474
+ @ui.puts
1475
+ show_help 'b'
1476
+ end
1477
+ end
1478
+
1479
+ def repl_add_catch_breakpoint arg
1480
+ expr = parse_break 'catch', arg.strip
1481
+ cond = expr[:if]
1482
+ cmd = expr[:cmd]
1483
+ path = expr[:path]
1484
+
1485
+ bp = CatchBreakpoint.new(expr[:sig], cond: cond, command: cmd, path: path)
1486
+ add_bp bp
1487
+ end
1488
+
1489
+ def repl_add_watch_breakpoint arg
1490
+ expr = parse_break 'watch', arg.strip
1491
+ cond = expr[:if]
1492
+ cmd = expr[:cmd]
1493
+ path = Regexp.compile(expr[:path]) if expr[:path]
1494
+
1495
+ request_tc [:breakpoint, :watch, expr[:sig], cond, cmd, path]
1496
+ end
1497
+
1498
+ def add_catch_breakpoint pat, cond: nil
1499
+ bp = CatchBreakpoint.new(pat, cond: cond)
1500
+ add_bp bp
1501
+ end
1502
+
1503
+ def add_check_breakpoint cond, path, command
1504
+ bp = CheckBreakpoint.new(cond: cond, path: path, command: command)
1505
+ add_bp bp
1506
+ end
1507
+
1508
+ def add_line_breakpoint file, line, **kw
1509
+ file = resolve_path(file)
1510
+ bp = LineBreakpoint.new(file, line, **kw)
1511
+
1512
+ add_bp bp
1513
+ rescue Errno::ENOENT => e
1514
+ @ui.puts e.message
1515
+ end
1516
+
1517
+ def clear_breakpoints(&condition)
1518
+ @bps.delete_if do |k, bp|
1519
+ if condition.call(k, bp)
1520
+ bp.delete
1521
+ true
1522
+ end
1523
+ end
1524
+ end
1525
+
1526
+ def clear_line_breakpoints path
1527
+ path = resolve_path(path)
1528
+ clear_breakpoints do |k, bp|
1529
+ bp.is_a?(LineBreakpoint) && bp.path_is?(path)
1530
+ end
1531
+ rescue Errno::ENOENT
1532
+ # just ignore
1533
+ end
1534
+
1535
+ def clear_catch_breakpoints *exception_names
1536
+ clear_breakpoints do |k, bp|
1537
+ bp.is_a?(CatchBreakpoint) && exception_names.include?(k[1])
1538
+ end
1539
+ end
1540
+
1541
+ def clear_all_breakpoints
1542
+ clear_breakpoints{true}
1543
+ end
1544
+
1545
+ def add_iseq_breakpoint iseq, **kw
1546
+ bp = ISeqBreakpoint.new(iseq, [:line], **kw)
1547
+ add_bp bp
1548
+ end
1549
+
1550
+ # tracers
1551
+
1552
+ def add_tracer tracer
1553
+ if @tracers[tracer.key]&.enabled?
1554
+ tracer.disable
1555
+ @ui.puts "Duplicated tracer: #{tracer}"
1556
+ else
1557
+ @tracers[tracer.key] = tracer
1558
+ @ui.puts "Enable #{tracer}"
1559
+ end
1560
+ end
1561
+
1562
+ # threads
1563
+
1564
+ def update_thread_list
1565
+ list = Thread.list
1566
+ thcs = []
1567
+ unmanaged = []
1568
+
1569
+ list.each{|th|
1570
+ if thc = @th_clients[th]
1571
+ if !thc.management?
1572
+ thcs << thc
1573
+ end
1574
+ else
1575
+ unmanaged << th
1576
+ end
1577
+ }
1578
+
1579
+ return thcs.sort_by{|thc| thc.id}, unmanaged
1580
+ end
1581
+
1582
+ def thread_list
1583
+ thcs, unmanaged_ths = update_thread_list
1584
+ thcs.each_with_index{|thc, i|
1585
+ @ui.puts "#{@tc == thc ? "--> " : " "}\##{i} #{thc}"
1586
+ }
1587
+
1588
+ if !unmanaged_ths.empty?
1589
+ @ui.puts "The following threads are not managed yet by the debugger:"
1590
+ unmanaged_ths.each{|th|
1591
+ @ui.puts " " + th.to_s
1592
+ }
1593
+ end
1594
+ end
1595
+
1596
+ def managed_thread_clients
1597
+ thcs, _unmanaged_ths = update_thread_list
1598
+ thcs
1599
+ end
1600
+
1601
+ def switch_thread n
1602
+ thcs, _unmanaged_ths = update_thread_list
1603
+
1604
+ if tc = thcs[n]
1605
+ if tc.waiting?
1606
+ @tc = tc
1607
+ else
1608
+ @ui.puts "#{tc.thread} is not controllable yet."
1609
+ end
1610
+ end
1611
+ thread_list
1612
+ end
1613
+
1614
+ def setup_threads
1615
+ prev_clients = @th_clients
1616
+ @th_clients = {}
1617
+
1618
+ Thread.list.each{|th|
1619
+ if tc = prev_clients[th]
1620
+ @th_clients[th] = tc
1621
+ else
1622
+ create_thread_client(th)
1623
+ end
1624
+ }
1625
+ end
1626
+
1627
+ def on_thread_begin th
1628
+ if @th_clients.has_key? th
1629
+ # TODO: NG?
1630
+ else
1631
+ create_thread_client th
1632
+ end
1633
+ end
1634
+
1635
+ private def create_thread_client th
1636
+ # TODO: Ractor support
1637
+ raise "Only session_server can create thread_client" unless Thread.current == @session_server
1638
+ @th_clients[th] = ThreadClient.new((@tc_id += 1), @q_evt, Queue.new, th)
1639
+ end
1640
+
1641
+ private def ask_thread_client th
1642
+ # TODO: Ractor support
1643
+ q2 = Queue.new
1644
+ # tc, output, ev, @internal_info, *ev_args = evt
1645
+ @q_evt << [nil, [], :thread_begin, nil, th, q2]
1646
+ q2.pop
1647
+
1648
+ @th_clients[th] or raise "unexpected error"
1649
+ end
1650
+
1651
+ # can be called by other threads
1652
+ def get_thread_client th = Thread.current
1653
+ if @th_clients.has_key? th
1654
+ @th_clients[th]
1655
+ else
1656
+ if Thread.current == @session_server
1657
+ create_thread_client th
1658
+ else
1659
+ ask_thread_client th
1660
+ end
1661
+ end
1662
+ end
1663
+
1664
+ private def running_thread_clients_count
1665
+ @th_clients.count{|th, tc|
1666
+ next if tc.management?
1667
+ next unless tc.running?
1668
+ true
1669
+ }
1670
+ end
1671
+
1672
+ private def waiting_thread_clients
1673
+ @th_clients.map{|th, tc|
1674
+ next if tc.management?
1675
+ next unless tc.waiting?
1676
+ tc
1677
+ }.compact
1678
+ end
1679
+
1680
+ private def thread_stopper
1681
+ TracePoint.new(:line) do
1682
+ # run on each thread
1683
+ tc = ThreadClient.current
1684
+ next if tc.management?
1685
+ next unless tc.running?
1686
+ next if tc == @tc
1687
+
1688
+ tc.on_pause
1689
+ end
1690
+ end
1691
+
1692
+ private def stop_all_threads
1693
+ return if running_thread_clients_count == 0
1694
+
1695
+ stopper = @thread_stopper
1696
+ stopper.enable unless stopper.enabled?
1697
+ end
1698
+
1699
+ private def restart_all_threads
1700
+ stopper = @thread_stopper
1701
+ stopper.disable if stopper.enabled?
1702
+
1703
+ waiting_thread_clients.each{|tc|
1704
+ next if @tc == tc
1705
+ tc << :continue
1706
+ }
1707
+ end
1708
+
1709
+ private def enter_subsession
1710
+ @subsession_id += 1
1711
+ if !@subsession_stack.empty?
1712
+ DEBUGGER__.debug{ "Enter subsession (nested #{@subsession_stack.size})" }
1713
+ else
1714
+ DEBUGGER__.debug{ "Enter subsession" }
1715
+ stop_all_threads
1716
+ @process_group.lock
1717
+ end
1718
+
1719
+ @subsession_stack << true
1720
+ end
1721
+
1722
+ private def leave_subsession type
1723
+ raise '[BUG] leave_subsession: not entered' if @subsession_stack.empty?
1724
+ @subsession_stack.pop
1725
+
1726
+ if @subsession_stack.empty?
1727
+ DEBUGGER__.debug{ "Leave subsession" }
1728
+ @process_group.unlock
1729
+ restart_all_threads
1730
+ else
1731
+ DEBUGGER__.debug{ "Leave subsession (nested #{@subsession_stack.size})" }
1732
+ end
1733
+
1734
+ request_tc type if type
1735
+ @tc = nil
1736
+ rescue Exception => e
1737
+ STDERR.puts PP.pp([e, e.backtrace], ''.dup)
1738
+ raise
1739
+ end
1740
+
1741
+ def in_subsession?
1742
+ !@subsession_stack.empty?
1743
+ end
1744
+
1745
+ ## event
1746
+
1747
+ def on_load iseq, src
1748
+ DEBUGGER__.info "Load #{iseq.absolute_path || iseq.path}"
1749
+
1750
+ file_path, reloaded = @sr.add(iseq, src)
1751
+ @ui.event :load, file_path, reloaded
1752
+
1753
+ # check breakpoints
1754
+ if file_path
1755
+ @bps.find_all do |_key, bp|
1756
+ LineBreakpoint === bp && bp.path_is?(file_path) && (iseq.first_lineno..iseq.last_line).cover?(bp.line)
1757
+ end.each do |_key, bp|
1758
+ if !bp.iseq
1759
+ bp.try_activate iseq
1760
+ elsif reloaded
1761
+ @bps.delete bp.key # to allow duplicate
1762
+
1763
+ # When we delete a breakpoint from the @bps hash, we also need to deactivate it or else its tracepoint event
1764
+ # will continue to be enabled and we'll suspend on ghost breakpoints
1765
+ bp.delete
1766
+
1767
+ nbp = LineBreakpoint.copy(bp, iseq)
1768
+ add_bp nbp
1769
+ end
1770
+ end
1771
+ else # !file_path => file_path is not existing
1772
+ @bps.find_all do |_key, bp|
1773
+ LineBreakpoint === bp && !bp.iseq && DEBUGGER__.compare_path(bp.path, (iseq.absolute_path || iseq.path))
1774
+ end.each do |_key, bp|
1775
+ bp.try_activate iseq
1776
+ end
1777
+ end
1778
+ end
1779
+
1780
+ def resolve_path file
1781
+ File.realpath(File.expand_path(file))
1782
+ rescue Errno::ENOENT
1783
+ case file
1784
+ when '-e', '-'
1785
+ return file
1786
+ else
1787
+ $LOAD_PATH.each do |lp|
1788
+ libpath = File.join(lp, file)
1789
+ return File.realpath(libpath)
1790
+ rescue Errno::ENOENT
1791
+ # next
1792
+ end
1793
+ end
1794
+
1795
+ raise
1796
+ end
1797
+
1798
+ def method_added tp
1799
+ b = tp.binding
1800
+
1801
+ if var_name = b.local_variables.first
1802
+ mid = b.local_variable_get(var_name)
1803
+ resolved = true
1804
+
1805
+ @bps.each{|k, bp|
1806
+ case bp
1807
+ when MethodBreakpoint
1808
+ if bp.method.nil?
1809
+ if bp.sig_method_name == mid.to_s
1810
+ bp.try_enable(added: true)
1811
+ end
1812
+ end
1813
+
1814
+ resolved = false if !bp.enabled?
1815
+ end
1816
+ }
1817
+
1818
+ if resolved
1819
+ Session.deactivate_method_added_trackers
1820
+ end
1821
+
1822
+ case mid
1823
+ when :method_added, :singleton_method_added
1824
+ Session.create_method_added_tracker(tp.self, mid)
1825
+ Session.activate_method_added_trackers unless resolved
1826
+ end
1827
+ end
1828
+ end
1829
+
1830
+ class ::Module
1831
+ undef method_added
1832
+ def method_added mid; end
1833
+ end
1834
+
1835
+ class ::BasicObject
1836
+ undef singleton_method_added
1837
+ def singleton_method_added mid; end
1838
+ end
1839
+
1840
+ def self.create_method_added_tracker mod, method_added_id, method_accessor = :method
1841
+ m = mod.__send__(method_accessor, method_added_id)
1842
+ METHOD_ADDED_TRACKERS[m] = TracePoint.new(:call) do |tp|
1843
+ SESSION.method_added tp
1844
+ end
1845
+ end
1846
+
1847
+ def self.activate_method_added_trackers
1848
+ METHOD_ADDED_TRACKERS.each do |m, tp|
1849
+ tp.enable(target: m) unless tp.enabled?
1850
+ rescue ArgumentError
1851
+ DEBUGGER__.warn "Methods defined under #{m.owner} can not track by the debugger."
1852
+ end
1853
+ end
1854
+
1855
+ def self.deactivate_method_added_trackers
1856
+ METHOD_ADDED_TRACKERS.each do |m, tp|
1857
+ tp.disable if tp.enabled?
1858
+ end
1859
+ end
1860
+
1861
+ METHOD_ADDED_TRACKERS = Hash.new
1862
+ create_method_added_tracker Module, :method_added, :instance_method
1863
+ create_method_added_tracker BasicObject, :singleton_method_added, :instance_method
1864
+
1865
+ def width
1866
+ @ui.width
1867
+ end
1868
+
1869
+ def check_postmortem
1870
+ if @postmortem
1871
+ raise PostmortemError, "Can not use this command on postmortem mode."
1872
+ end
1873
+ end
1874
+
1875
+ def check_unsafe
1876
+ if @unsafe_context
1877
+ raise RuntimeError, "#{@repl_prev_line.dump} is not allowed on unsafe context."
1878
+ end
1879
+ end
1880
+
1881
+ def activate_irb_integration
1882
+ require_relative "irb_integration"
1883
+ thc = get_thread_client(@session_server)
1884
+ thc.activate_irb_integration
1885
+ end
1886
+
1887
+ def enter_postmortem_session exc
1888
+ return unless exc.instance_variable_defined? :@__debugger_postmortem_frames
1889
+
1890
+ frames = exc.instance_variable_get(:@__debugger_postmortem_frames)
1891
+ @postmortem = true
1892
+ ThreadClient.current.suspend :postmortem, postmortem_frames: frames, postmortem_exc: exc
1893
+ ensure
1894
+ @postmortem = false
1895
+ end
1896
+
1897
+ def capture_exception_frames *exclude_path
1898
+ postmortem_hook = TracePoint.new(:raise){|tp|
1899
+ exc = tp.raised_exception
1900
+ frames = DEBUGGER__.capture_frames(__dir__)
1901
+
1902
+ exclude_path.each{|ex|
1903
+ if Regexp === ex
1904
+ frames.delete_if{|e| ex =~ e.path}
1905
+ else
1906
+ frames.delete_if{|e| e.path.start_with? ex.to_s}
1907
+ end
1908
+ }
1909
+ exc.instance_variable_set(:@__debugger_postmortem_frames, frames)
1910
+ }
1911
+ postmortem_hook.enable
1912
+
1913
+ begin
1914
+ yield
1915
+ nil
1916
+ rescue Exception => e
1917
+ if e.instance_variable_defined? :@__debugger_postmortem_frames
1918
+ e
1919
+ else
1920
+ raise
1921
+ end
1922
+ ensure
1923
+ postmortem_hook.disable
1924
+ end
1925
+ end
1926
+
1927
+ def postmortem=(is_enable)
1928
+ if is_enable
1929
+ unless @postmortem_hook
1930
+ @postmortem_hook = TracePoint.new(:raise){|tp|
1931
+ exc = tp.raised_exception
1932
+ frames = DEBUGGER__.capture_frames(__dir__)
1933
+ exc.instance_variable_set(:@__debugger_postmortem_frames, frames)
1934
+ }
1935
+ at_exit{
1936
+ @postmortem_hook.disable
1937
+ if CONFIG[:postmortem] && (exc = $!) != nil
1938
+ exc = exc.cause while exc.cause
1939
+
1940
+ begin
1941
+ @ui.puts "Enter postmortem mode with #{exc.inspect}"
1942
+ @ui.puts exc.backtrace.map{|e| ' ' + e}
1943
+ @ui.puts "\n"
1944
+
1945
+ enter_postmortem_session exc
1946
+ rescue SystemExit
1947
+ exit!
1948
+ rescue Exception => e
1949
+ @ui = STDERR unless @ui
1950
+ @ui.puts "Error while postmortem console: #{e.inspect}"
1951
+ end
1952
+ end
1953
+ }
1954
+ end
1955
+
1956
+ if !@postmortem_hook.enabled?
1957
+ @postmortem_hook.enable
1958
+ end
1959
+ else
1960
+ if @postmortem_hook && @postmortem_hook.enabled?
1961
+ @postmortem_hook.disable
1962
+ end
1963
+ end
1964
+ end
1965
+
1966
+ def set_no_sigint_hook old, new
1967
+ return unless old != new
1968
+ return unless @ui.respond_to? :activate_sigint
1969
+
1970
+ if old # no -> yes
1971
+ @ui.activate_sigint
1972
+ else
1973
+ @ui.deactivate_sigint
1974
+ end
1975
+ end
1976
+
1977
+ def save_int_trap cmd
1978
+ prev, @intercepted_sigint_cmd = @intercepted_sigint_cmd, cmd
1979
+ prev
1980
+ end
1981
+
1982
+ def intercept_trap_sigint?
1983
+ @intercept_trap_sigint
1984
+ end
1985
+
1986
+ def intercept_trap_sigint flag, &b
1987
+ prev = @intercept_trap_sigint
1988
+ @intercept_trap_sigint = flag
1989
+ yield
1990
+ ensure
1991
+ @intercept_trap_sigint = prev
1992
+ end
1993
+
1994
+ def intercept_trap_sigint_start prev
1995
+ @intercept_trap_sigint = true
1996
+ @intercepted_sigint_cmd = prev
1997
+ end
1998
+
1999
+ def intercept_trap_sigint_end
2000
+ @intercept_trap_sigint = false
2001
+ prev, @intercepted_sigint_cmd = @intercepted_sigint_cmd, nil
2002
+ prev
2003
+ end
2004
+
2005
+ def process_info
2006
+ if @process_group.multi?
2007
+ "#{$0}\##{Process.pid}"
2008
+ end
2009
+ end
2010
+
2011
+ def before_fork need_lock = true
2012
+ if need_lock
2013
+ @process_group.multi_process!
2014
+ end
2015
+ end
2016
+
2017
+ def after_fork_parent
2018
+ @ui.after_fork_parent
2019
+ end
2020
+
2021
+ # experimental API
2022
+ def extend_feature session: nil, thread_client: nil, ui: nil
2023
+ Session.include session if session
2024
+ ThreadClient.include thread_client if thread_client
2025
+ @ui.extend ui if ui
2026
+ end
2027
+ end
2028
+
2029
+ class ProcessGroup
2030
+ def initialize
2031
+ @lock_file = nil
2032
+ end
2033
+
2034
+ def locked?
2035
+ true
2036
+ end
2037
+
2038
+ def trylock
2039
+ true
2040
+ end
2041
+
2042
+ def lock
2043
+ true
2044
+ end
2045
+
2046
+ def unlock
2047
+ true
2048
+ end
2049
+
2050
+ def sync
2051
+ yield
2052
+ end
2053
+
2054
+ def after_fork
2055
+ end
2056
+
2057
+ def multi?
2058
+ @lock_file
2059
+ end
2060
+
2061
+ def multi_process!
2062
+ require 'tempfile'
2063
+ @lock_tempfile = Tempfile.open("ruby-debug-lock-")
2064
+ @lock_tempfile.close
2065
+ extend MultiProcessGroup
2066
+ end
2067
+ end
2068
+
2069
+ module MultiProcessGroup
2070
+ def multi_process!
2071
+ end
2072
+
2073
+ def after_fork child: true
2074
+ if child || !@lock_file
2075
+ @m = Mutex.new unless @m
2076
+ @m.synchronize do
2077
+ @lock_level = 0
2078
+ @lock_file = open(@lock_tempfile.path, 'w')
2079
+ end
2080
+ end
2081
+ end
2082
+
2083
+ def info msg
2084
+ DEBUGGER__.info "#{msg} (#{@lock_level})" # #{caller.first(1).map{|bt| bt.sub(__dir__, '')}}"
2085
+ end
2086
+
2087
+ def locked?
2088
+ # DEBUGGER__.debug{ "locked? #{@lock_level}" }
2089
+ @lock_level > 0
2090
+ end
2091
+
2092
+ private def lock_level_up
2093
+ raise unless @m.owned?
2094
+ @lock_level += 1
2095
+ end
2096
+
2097
+ private def lock_level_down
2098
+ raise unless @m.owned?
2099
+ raise "@lock_level underflow: #{@lock_level}" if @lock_level < 1
2100
+ @lock_level -= 1
2101
+ end
2102
+
2103
+ private def trylock
2104
+ @m.synchronize do
2105
+ if locked?
2106
+ lock_level_up
2107
+ info "Try lock, already locked"
2108
+ true
2109
+ else
2110
+ case r = @lock_file.flock(File::LOCK_EX | File::LOCK_NB)
2111
+ when 0
2112
+ lock_level_up
2113
+ info "Try lock with file: success"
2114
+ true
2115
+ when false
2116
+ info "Try lock with file: failed"
2117
+ false
2118
+ else
2119
+ raise "unknown flock result: #{r.inspect}"
2120
+ end
2121
+ end
2122
+ end
2123
+ end
2124
+
2125
+ def lock
2126
+ unless trylock
2127
+ @m.synchronize do
2128
+ if locked?
2129
+ lock_level_up
2130
+ else
2131
+ info "Lock: block"
2132
+ @lock_file.flock(File::LOCK_EX)
2133
+ lock_level_up
2134
+ end
2135
+ end
2136
+
2137
+ info "Lock: success"
2138
+ end
2139
+ end
2140
+
2141
+ def unlock
2142
+ @m.synchronize do
2143
+ raise "lock file is not opened (#{@lock_file.inspect})" if @lock_file.closed?
2144
+ lock_level_down
2145
+ @lock_file.flock(File::LOCK_UN) unless locked?
2146
+ info "Unlocked"
2147
+ end
2148
+ end
2149
+
2150
+ def sync &b
2151
+ info "sync"
2152
+
2153
+ lock
2154
+ begin
2155
+ b.call if b
2156
+ ensure
2157
+ unlock
2158
+ end
2159
+ end
2160
+ end
2161
+
2162
+ class UI_Base
2163
+ def event type, *args
2164
+ case type
2165
+ when :suspend_bp
2166
+ i, bp = *args
2167
+ puts "\nStop by \##{i} #{bp}" if bp
2168
+ when :suspend_trap
2169
+ puts "\nStop by #{args.first}"
2170
+ end
2171
+ end
2172
+
2173
+ def ignore_output_on_suspend?
2174
+ false
2175
+ end
2176
+
2177
+ def flush
2178
+ end
2179
+ end
2180
+
2181
+ # manual configuration methods
2182
+
2183
+ def self.add_line_breakpoint file, line, **kw
2184
+ ::DEBUGGER__::SESSION.add_line_breakpoint file, line, **kw
2185
+ end
2186
+
2187
+ def self.add_catch_breakpoint pat
2188
+ ::DEBUGGER__::SESSION.add_catch_breakpoint pat
2189
+ end
2190
+
2191
+ # String for requiring location
2192
+ # nil for -r
2193
+ def self.require_location
2194
+ locs = caller_locations
2195
+ dir_prefix = /#{Regexp.escape(__dir__)}/
2196
+
2197
+ locs.each do |loc|
2198
+ case loc.absolute_path
2199
+ when dir_prefix
2200
+ when %r{rubygems/core_ext/kernel_require\.rb}
2201
+ when %r{bundled_gems\.rb}
2202
+ else
2203
+ return loc if loc.absolute_path
2204
+ end
2205
+ end
2206
+ nil
2207
+ end
2208
+
2209
+ # start methods
2210
+
2211
+ def self.start nonstop: false, **kw
2212
+ CONFIG.set_config(**kw)
2213
+
2214
+ if CONFIG[:open]
2215
+ open nonstop: nonstop, **kw
2216
+ else
2217
+ unless defined? SESSION
2218
+ require_relative 'local'
2219
+ initialize_session{ UI_LocalConsole.new }
2220
+ end
2221
+ setup_initial_suspend unless nonstop
2222
+ end
2223
+ end
2224
+
2225
+ def self.open host: nil, port: CONFIG[:port], sock_path: nil, sock_dir: nil, nonstop: false, **kw
2226
+ CONFIG.set_config(**kw)
2227
+ require_relative 'server'
2228
+
2229
+ if port || CONFIG[:open] == 'chrome' || (!::Addrinfo.respond_to?(:unix))
2230
+ open_tcp host: host, port: (port || 0), nonstop: nonstop
2231
+ else
2232
+ open_unix sock_path: sock_path, sock_dir: sock_dir, nonstop: nonstop
2233
+ end
2234
+ end
2235
+
2236
+ def self.open_tcp host: nil, port:, nonstop: false, **kw
2237
+ CONFIG.set_config(**kw)
2238
+ require_relative 'server'
2239
+
2240
+ if defined? SESSION
2241
+ SESSION.reset_ui UI_TcpServer.new(host: host, port: port)
2242
+ else
2243
+ initialize_session{ UI_TcpServer.new(host: host, port: port) }
2244
+ end
2245
+
2246
+ setup_initial_suspend unless nonstop
2247
+ end
2248
+
2249
+ def self.open_unix sock_path: nil, sock_dir: nil, nonstop: false, **kw
2250
+ CONFIG.set_config(**kw)
2251
+ require_relative 'server'
2252
+
2253
+ if defined? SESSION
2254
+ SESSION.reset_ui UI_UnixDomainServer.new(sock_dir: sock_dir, sock_path: sock_path)
2255
+ else
2256
+ initialize_session{ UI_UnixDomainServer.new(sock_dir: sock_dir, sock_path: sock_path) }
2257
+ end
2258
+
2259
+ setup_initial_suspend unless nonstop
2260
+ end
2261
+
2262
+ # boot utilities
2263
+
2264
+ def self.setup_initial_suspend
2265
+ if !CONFIG[:nonstop]
2266
+ case
2267
+ when CONFIG[:stop_at_load]
2268
+ add_line_breakpoint __FILE__, __LINE__ + 1, oneshot: true, hook_call: false
2269
+ nil # stop here
2270
+ when path = ENV['RUBY_DEBUG_INITIAL_SUSPEND_PATH']
2271
+ add_line_breakpoint path, 0, oneshot: true, hook_call: false
2272
+ when loc = ::DEBUGGER__.require_location
2273
+ # require 'debug/start' or 'debug'
2274
+ add_line_breakpoint loc.absolute_path, loc.lineno + 1, oneshot: true, hook_call: false
2275
+ else
2276
+ # -r
2277
+ add_line_breakpoint $0, 0, oneshot: true, hook_call: false
2278
+ end
2279
+ end
2280
+ end
2281
+
2282
+ class << self
2283
+ define_method :initialize_session do |&init_ui|
2284
+ DEBUGGER__.info "Session start (pid: #{Process.pid})"
2285
+ ::DEBUGGER__.const_set(:SESSION, Session.new)
2286
+ SESSION.activate init_ui.call
2287
+ load_rc
2288
+ end
2289
+ end
2290
+
2291
+ # Exiting control
2292
+
2293
+ class << self
2294
+ def skip_all
2295
+ @skip_all = true
2296
+ end
2297
+
2298
+ def skip?
2299
+ @skip_all
2300
+ end
2301
+ end
2302
+
2303
+ def self.load_rc
2304
+ [[File.expand_path('~/.rdbgrc'), true],
2305
+ [File.expand_path('~/.rdbgrc.rb'), true],
2306
+ # ['./.rdbgrc', true], # disable because of security concern
2307
+ [CONFIG[:init_script], false],
2308
+ ].each{|(path, rc)|
2309
+ next unless path
2310
+ next if rc && CONFIG[:no_rc] # ignore rc
2311
+
2312
+ if File.file? path
2313
+ if path.end_with?('.rb')
2314
+ load path
2315
+ else
2316
+ ::DEBUGGER__::SESSION.add_preset_commands path, File.readlines(path)
2317
+ end
2318
+ elsif !rc
2319
+ warn "Not found: #{path}"
2320
+ end
2321
+ }
2322
+
2323
+ # given debug commands
2324
+ if CONFIG[:commands]
2325
+ cmds = CONFIG[:commands].split(';;')
2326
+ ::DEBUGGER__::SESSION.add_preset_commands "commands", cmds, kick: false, continue: false
2327
+ end
2328
+ end
2329
+
2330
+ # Inspector
2331
+
2332
+ SHORT_INSPECT_LENGTH = 40
2333
+
2334
+ class LimitedPP
2335
+ def self.pp(obj, max=80)
2336
+ out = self.new(max)
2337
+ catch out do
2338
+ PP.singleline_pp(obj, out)
2339
+ end
2340
+ out.buf
2341
+ end
2342
+
2343
+ attr_reader :buf
2344
+
2345
+ def initialize max
2346
+ @max = max
2347
+ @cnt = 0
2348
+ @buf = String.new
2349
+ end
2350
+
2351
+ def <<(other)
2352
+ @buf << other
2353
+
2354
+ if @buf.size >= @max
2355
+ @buf = @buf[0..@max] + '...'
2356
+ throw self
2357
+ end
2358
+ end
2359
+ end
2360
+
2361
+ def self.safe_inspect obj, max_length: SHORT_INSPECT_LENGTH, short: false
2362
+ if short
2363
+ LimitedPP.pp(obj, max_length)
2364
+ else
2365
+ obj.inspect
2366
+ end
2367
+ rescue NoMethodError => e
2368
+ klass, oid = M_CLASS.bind_call(obj), M_OBJECT_ID.bind_call(obj)
2369
+ if obj == (r = e.receiver)
2370
+ "<\##{klass.name}#{oid} does not have \#inspect>"
2371
+ else
2372
+ rklass, roid = M_CLASS.bind_call(r), M_OBJECT_ID.bind_call(r)
2373
+ "<\##{klass.name}:#{roid} contains <\##{rklass}:#{roid} and it does not have #inspect>"
2374
+ end
2375
+ rescue Exception => e
2376
+ "<#inspect raises #{e.inspect}>"
2377
+ end
2378
+
2379
+ def self.warn msg
2380
+ log :WARN, msg
2381
+ end
2382
+
2383
+ def self.info msg
2384
+ log :INFO, msg
2385
+ end
2386
+
2387
+ def self.check_loglevel level
2388
+ lv = LOG_LEVELS[level]
2389
+ config_lv = LOG_LEVELS[CONFIG[:log_level]]
2390
+ lv <= config_lv
2391
+ end
2392
+
2393
+ def self.debug(&b)
2394
+ if check_loglevel :DEBUG
2395
+ log :DEBUG, b.call
2396
+ end
2397
+ end
2398
+
2399
+ def self.log level, msg
2400
+ if check_loglevel level
2401
+ @logfile = STDERR unless defined? @logfile
2402
+ return if @logfile.closed?
2403
+
2404
+ if defined? SESSION
2405
+ pi = SESSION.process_info
2406
+ process_info = pi ? "[#{pi}]" : nil
2407
+ end
2408
+
2409
+ if level == :WARN
2410
+ # :WARN on debugger is general information
2411
+ @logfile.puts "DEBUGGER#{process_info}: #{msg}"
2412
+ @logfile.flush
2413
+ else
2414
+ @logfile.puts "DEBUGGER#{process_info} (#{level}): #{msg}"
2415
+ @logfile.flush
2416
+ end
2417
+ end
2418
+ end
2419
+
2420
+ def self.step_in &b
2421
+ if defined?(SESSION) && SESSION.active?
2422
+ SESSION.add_iseq_breakpoint RubyVM::InstructionSequence.of(b), oneshot: true
2423
+ end
2424
+
2425
+ yield
2426
+ end
2427
+
2428
+ if File.identical?(__FILE__.upcase, __FILE__.downcase)
2429
+ # For case insensitive file system (like Windows)
2430
+ # Note that this check is not enough because case sensitive/insensitive is
2431
+ # depend on the file system. So this check is only roughly estimation.
2432
+
2433
+ def self.compare_path(a, b)
2434
+ a&.downcase == b&.downcase
2435
+ end
2436
+ else
2437
+ def self.compare_path(a, b)
2438
+ a == b
2439
+ end
2440
+ end
2441
+
2442
+ module ForkInterceptor
2443
+ if Process.respond_to? :_fork
2444
+ def _fork
2445
+ return super unless defined?(SESSION) && SESSION.active?
2446
+
2447
+ parent_hook, child_hook = __fork_setup_for_debugger
2448
+
2449
+ super.tap do |pid|
2450
+ if pid != 0
2451
+ # after fork: parent
2452
+ parent_hook.call pid
2453
+ else
2454
+ # after fork: child
2455
+ child_hook.call
2456
+ end
2457
+ end
2458
+ end
2459
+ else
2460
+ def fork(&given_block)
2461
+ return super unless defined?(SESSION) && SESSION.active?
2462
+ parent_hook, child_hook = __fork_setup_for_debugger
2463
+
2464
+ if given_block
2465
+ new_block = proc {
2466
+ # after fork: child
2467
+ child_hook.call
2468
+ given_block.call
2469
+ }
2470
+ super(&new_block).tap{|pid| parent_hook.call(pid)}
2471
+ else
2472
+ super.tap do |pid|
2473
+ if pid
2474
+ # after fork: parent
2475
+ parent_hook.call pid
2476
+ else
2477
+ # after fork: child
2478
+ child_hook.call
2479
+ end
2480
+ end
2481
+ end
2482
+ end
2483
+ end
2484
+
2485
+ module DaemonInterceptor
2486
+ def daemon(*args)
2487
+ return super unless defined?(SESSION) && SESSION.active?
2488
+
2489
+ _, child_hook = __fork_setup_for_debugger(:child)
2490
+
2491
+ unless SESSION.remote?
2492
+ DEBUGGER__.warn "Can't debug the code after Process.daemon locally. Use the remote debugging feature."
2493
+ end
2494
+
2495
+ super.tap do
2496
+ child_hook.call
2497
+ end
2498
+ end
2499
+ end
2500
+
2501
+ private def __fork_setup_for_debugger fork_mode = nil
2502
+ fork_mode ||= CONFIG[:fork_mode]
2503
+
2504
+ if fork_mode == :both && CONFIG[:parent_on_fork]
2505
+ fork_mode = :parent
2506
+ end
2507
+
2508
+ parent_pid = Process.pid
2509
+
2510
+ # before fork
2511
+ case fork_mode
2512
+ when :parent
2513
+ parent_hook = -> child_pid {
2514
+ # Do nothing
2515
+ }
2516
+ child_hook = -> {
2517
+ DEBUGGER__.info "Detaching after fork from child process #{Process.pid}"
2518
+ SESSION.deactivate
2519
+ }
2520
+ when :child
2521
+ SESSION.before_fork false
2522
+
2523
+ parent_hook = -> child_pid {
2524
+ DEBUGGER__.info "Detaching after fork from parent process #{Process.pid}"
2525
+ SESSION.after_fork_parent
2526
+ SESSION.deactivate
2527
+ }
2528
+ child_hook = -> {
2529
+ DEBUGGER__.info "Attaching after process #{parent_pid} fork to child process #{Process.pid}"
2530
+ SESSION.activate on_fork: true
2531
+ }
2532
+ when :both
2533
+ SESSION.before_fork
2534
+
2535
+ parent_hook = -> child_pid {
2536
+ SESSION.process_group.after_fork
2537
+ SESSION.after_fork_parent
2538
+ }
2539
+ child_hook = -> {
2540
+ DEBUGGER__.info "Attaching after process #{parent_pid} fork to child process #{Process.pid}"
2541
+ SESSION.process_group.after_fork child: true
2542
+ SESSION.activate on_fork: true
2543
+ }
2544
+ end
2545
+
2546
+ return parent_hook, child_hook
2547
+ end
2548
+ end
2549
+
2550
+ module TrapInterceptor
2551
+ def trap sig, *command, &command_proc
2552
+ sym =
2553
+ case sig
2554
+ when String
2555
+ sig.to_sym
2556
+ when Integer
2557
+ Signal.signame(sig)&.to_sym
2558
+ else
2559
+ sig
2560
+ end
2561
+
2562
+ case sym
2563
+ when :INT, :SIGINT
2564
+ if defined?(SESSION) && SESSION.active? && SESSION.intercept_trap_sigint?
2565
+ return SESSION.save_int_trap(command.empty? ? command_proc : command.first)
2566
+ end
2567
+ end
2568
+
2569
+ super
2570
+ end
2571
+ end
2572
+
2573
+ if Process.respond_to? :_fork
2574
+ module ::Process
2575
+ class << self
2576
+ prepend ForkInterceptor
2577
+ prepend DaemonInterceptor
2578
+ end
2579
+ end
2580
+
2581
+ # trap
2582
+ module ::Kernel
2583
+ prepend TrapInterceptor
2584
+ end
2585
+ module ::Signal
2586
+ class << self
2587
+ prepend TrapInterceptor
2588
+ end
2589
+ end
2590
+ else
2591
+ if RUBY_VERSION >= '3.0.0'
2592
+ module ::Kernel
2593
+ prepend ForkInterceptor
2594
+ prepend TrapInterceptor
2595
+ end
2596
+ else
2597
+ class ::Object
2598
+ include ForkInterceptor
2599
+ include TrapInterceptor
2600
+ end
2601
+ end
2602
+
2603
+ module ::Kernel
2604
+ class << self
2605
+ prepend ForkInterceptor
2606
+ prepend TrapInterceptor
2607
+ end
2608
+ end
2609
+
2610
+ module ::Process
2611
+ class << self
2612
+ prepend ForkInterceptor
2613
+ prepend DaemonInterceptor
2614
+ end
2615
+ end
2616
+ end
2617
+
2618
+ module ::Signal
2619
+ class << self
2620
+ prepend TrapInterceptor
2621
+ end
2622
+ end
2623
+ end
2624
+
2625
+ module Kernel
2626
+ def debugger pre: nil, do: nil, up_level: 0
2627
+ return if !defined?(::DEBUGGER__::SESSION) || !::DEBUGGER__::SESSION.active?
2628
+
2629
+ if pre || (do_expr = binding.local_variable_get(:do))
2630
+ cmds = ['#debugger', pre, do_expr]
2631
+ end
2632
+
2633
+ if ::DEBUGGER__::SESSION.in_subsession?
2634
+ if cmds
2635
+ commands = [*cmds[1], *cmds[2]].map{|c| c.split(';;').join("\n")}
2636
+ ::DEBUGGER__::SESSION.add_preset_commands cmds[0], commands, kick: false, continue: false
2637
+ end
2638
+ else
2639
+ loc = caller_locations(up_level, 1).first; ::DEBUGGER__.add_line_breakpoint loc.path, loc.lineno + 1, oneshot: true, command: cmds
2640
+ end
2641
+ self
2642
+ end
2643
+
2644
+ alias bb debugger if ENV['RUBY_DEBUG_BB']
2645
+ end
2646
+
2647
+ class Binding
2648
+ alias break debugger
2649
+ alias b debugger
2650
+ end
2651
+
2652
+ # for Ruby 2.6 compatibility
2653
+ unless method(:p).unbind.respond_to? :bind_call
2654
+ class UnboundMethod
2655
+ def bind_call(obj, *args)
2656
+ self.bind(obj).call(*args)
2657
+ end
2658
+ end
2659
+ end