| 
									
										
										
										
											2023-03-31 08:34:33 -07:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 11:45:18 -08:00
										 |  |  | require "attrable" | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | require "mutex_m" | 
					
						
							| 
									
										
										
										
											2021-04-13 17:39:59 +01:00
										 |  |  | require "ignorable" | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 03:45:47 +02:00
										 |  |  | # Helper module for debugging formulae. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # @api private | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | module Debrew | 
					
						
							|  |  |  |   extend Mutex_m | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 03:45:47 +02:00
										 |  |  |   # Module for allowing to debug formulae. | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   module Formula | 
					
						
							| 
									
										
										
										
											2014-10-11 01:45:55 -05:00
										 |  |  |     def install | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |       Debrew.debrew { super } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-26 19:42:11 -05:00
										 |  |  |     def patch | 
					
						
							|  |  |  |       Debrew.debrew { super } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     def test | 
					
						
							|  |  |  |       Debrew.debrew { super } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-02-07 18:58:41 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-14 03:45:47 +02:00
										 |  |  |   # Module for displaying a debugging menu. | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   class Menu | 
					
						
							|  |  |  |     Entry = Struct.new(:name, :action) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     attr_accessor :prompt, :entries | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |     sig { void } | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     def initialize | 
					
						
							|  |  |  |       @entries = [] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def choice(name, &action) | 
					
						
							|  |  |  |       entries << Entry.new(name.to_s, action) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def self.choose | 
					
						
							|  |  |  |       menu = new | 
					
						
							|  |  |  |       yield menu | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-31 08:34:33 -07:00
										 |  |  |       choice = T.let(nil, T.nilable(Entry)) | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |       while choice.nil? | 
					
						
							| 
									
										
										
										
											2017-06-01 16:06:51 +02:00
										 |  |  |         menu.entries.each_with_index { |e, i| puts "#{i + 1}. #{e.name}" } | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |         print menu.prompt unless menu.prompt.nil? | 
					
						
							| 
									
										
										
										
											2012-02-21 01:14:02 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-06 15:45:52 +08:00
										 |  |  |         input = $stdin.gets || exit | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |         input.chomp! | 
					
						
							| 
									
										
										
										
											2014-03-14 13:03:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |         i = input.to_i | 
					
						
							| 
									
										
										
										
											2017-09-24 20:12:58 +01:00
										 |  |  |         if i.positive? | 
					
						
							| 
									
										
										
										
											2017-06-01 16:06:51 +02:00
										 |  |  |           choice = menu.entries[i - 1] | 
					
						
							| 
									
										
										
										
											2014-03-13 10:05:55 -05:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2018-09-02 20:14:54 +01:00
										 |  |  |           possible = menu.entries.select { |e| e.name.start_with?(input) } | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |           case possible.size | 
					
						
							|  |  |  |           when 0 then puts "No such option" | 
					
						
							|  |  |  |           when 1 then choice = possible.first | 
					
						
							|  |  |  |           else puts "Multiple options match: #{possible.map(&:name).join(" ")}" | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2014-03-13 10:05:55 -05:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       choice[:action].call | 
					
						
							| 
									
										
										
										
											2014-03-13 10:05:55 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   @active = false | 
					
						
							|  |  |  |   @debugged_exceptions = Set.new | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   class << self | 
					
						
							| 
									
										
										
										
											2023-12-28 11:45:18 -08:00
										 |  |  |     extend Attrable | 
					
						
							| 
									
										
										
										
											2017-06-26 07:30:28 +02:00
										 |  |  |     attr_predicate :active? | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     attr_reader :debugged_exceptions | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def self.debrew | 
					
						
							|  |  |  |     @active = true | 
					
						
							| 
									
										
										
										
											2021-04-13 17:39:59 +01:00
										 |  |  |     Ignorable.hook_raise | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							|  |  |  |       yield | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     rescue SystemExit | 
					
						
							| 
									
										
										
										
											2021-04-13 17:39:59 +01:00
										 |  |  |       raise | 
					
						
							| 
									
										
										
										
											2023-03-31 08:34:33 -07:00
										 |  |  |     rescue Ignorable::ExceptionMixin => e | 
					
						
							| 
									
										
										
										
											2021-04-07 02:14:55 +01:00
										 |  |  |       e.ignore if debug(e) == :ignore # execution jumps back to where the exception was thrown | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     ensure | 
					
						
							| 
									
										
										
										
											2021-04-13 17:39:59 +01:00
										 |  |  |       Ignorable.unhook_raise | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |       @active = false | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-09 21:58:57 +00:00
										 |  |  |   def self.debug(exception) | 
					
						
							| 
									
										
										
										
											2023-03-31 08:34:33 -07:00
										 |  |  |     raise(exception) if !active? || !debugged_exceptions.add?(exception) || !mu_try_lock | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							| 
									
										
										
										
											2023-04-11 21:12:13 +01:00
										 |  |  |       puts exception.backtrace.first | 
					
						
							| 
									
										
										
										
											2023-03-09 21:58:57 +00:00
										 |  |  |       puts Formatter.error(exception, label: exception.class.name) | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       loop do | 
					
						
							|  |  |  |         Menu.choose do |menu| | 
					
						
							|  |  |  |           menu.prompt = "Choose an action: " | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-14 11:09:57 +01:00
										 |  |  |           menu.choice(:raise) { raise(exception) } | 
					
						
							| 
									
										
										
										
											2023-03-09 21:58:57 +00:00
										 |  |  |           menu.choice(:ignore) { return :ignore } if exception.is_a?(Ignorable::ExceptionMixin) | 
					
						
							|  |  |  |           menu.choice(:backtrace) { puts exception.backtrace } | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-09 21:58:57 +00:00
										 |  |  |           if exception.is_a?(Ignorable::ExceptionMixin) | 
					
						
							| 
									
										
										
										
											2016-09-20 22:03:08 +02:00
										 |  |  |             menu.choice(:irb) do | 
					
						
							|  |  |  |               puts "When you exit this IRB session, execution will continue." | 
					
						
							| 
									
										
										
										
											2018-07-01 01:43:04 +02:00
										 |  |  |               set_trace_func proc { |event, _, _, id, binding, klass| | 
					
						
							| 
									
										
										
										
											2021-04-13 17:39:59 +01:00
										 |  |  |                 if klass == Object && id == :raise && event == "return" | 
					
						
							| 
									
										
										
										
											2016-09-20 22:03:08 +02:00
										 |  |  |                   set_trace_func(nil) | 
					
						
							| 
									
										
										
										
											2023-12-06 00:01:16 +00:00
										 |  |  |                   mu_synchronize do | 
					
						
							|  |  |  |                     require "debrew/irb" | 
					
						
							|  |  |  |                     IRB.start_within(binding) | 
					
						
							|  |  |  |                   end | 
					
						
							| 
									
										
										
										
											2016-09-20 22:03:08 +02:00
										 |  |  |                 end | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               return :ignore | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |           menu.choice(:shell) do | 
					
						
							|  |  |  |             puts "When you exit this shell, you will return to the menu." | 
					
						
							|  |  |  |             interactive_shell | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2012-02-21 01:14:02 -06:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     ensure | 
					
						
							| 
									
										
										
										
											2023-03-31 08:34:33 -07:00
										 |  |  |       mu_unlock | 
					
						
							| 
									
										
										
										
											2012-02-21 01:14:02 -06:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-02-21 01:14:02 -06:00
										 |  |  | end |