lib/byebug/context.rb in byebug-3.5.1 vs lib/byebug/context.rb in byebug-4.0.0

- old
+ new

@@ -3,63 +3,70 @@ # Mantains context information for the debugger and it's the main # communication point between the library and the C-extension through the # at_breakpoint, at_catchpoint, at_tracing, at_line and at_return callbacks # class Context - class << self - def stack_size(byebug_frames = false) - backtrace = Thread.current.backtrace_locations(0) - return 0 unless backtrace + # + # List of files byebug will ignore while debugging + # + def self.ignored_files + Byebug.mode == :standalone ? lib_files + [bin_file] : lib_files + end - unless byebug_frames - backtrace = backtrace.drop_while { |l| !ignored(l.path) } - .drop_while { |l| ignored(l.path) } - .take_while { |l| !ignored(l.path) } - end + def self.bin_file + @bin_file ||= Gem.bin_path('byebug', 'byebug') + end - backtrace.size - end + def self.lib_files + @lib_files ||= Dir.glob(File.expand_path('../../**/*.rb', __FILE__)) + end - def ignored(path) - IGNORED_FILES.include?(path) - end - private :ignored + # + # Tells whether a file is ignored by the debugger. + # + # @param path [String] filename to be checked. + # + def ignored_file?(path) + self.class.ignored_files.include?(path) end + def stack_size + return 0 unless backtrace + + backtrace.drop_while { |l| ignored_file?(l.first.path) } + .take_while { |l| !ignored_file?(l.first.path) } + .size + end + def interrupt step_into 1 end + # + # Gets local variables for a frame. + # + # @param frame_no Frame index in the backtrace. Defaults to 0. + # + # TODO: Use brand new local_variable_{get,set,defined?} for rubies >= 2.1 + # def frame_locals(frame_no = 0) - bind = frame_binding frame_no - eval 'local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}', bind - end + bind = frame_binding(frame_no) + return [] unless bind - def c_frame_args(frame_no) - myself = frame_self frame_no - return [] unless myself.to_s != 'main' - myself.send(:method, frame_method(frame_no)).parameters + bind.eval('local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}') end - def ruby_frame_args(bind) - return [] unless eval '__method__', bind - begin - eval 'self.method(__method__).parameters', bind - rescue NameError => e - puts "WARNING: Got exception #{e.class}: \"#{e.message}\" " \ - 'while retreving parameters from frame' - return [] - end - end - + # + # Gets current method arguments for a frame. + # + # @param frame_no Frame index in the backtrace. Defaults to 0. + # def frame_args(frame_no = 0) - bind = frame_binding frame_no - if bind.nil? - c_frame_args frame_no - else - ruby_frame_args bind - end + bind = frame_binding(frame_no) + return c_frame_args(frame_no) unless bind + + ruby_frame_args(bind) end def handler Byebug.handler || fail('No interface loaded') end @@ -71,17 +78,46 @@ def at_catchpoint(excpt) handler.at_catchpoint(self, excpt) end def at_tracing(file, line) - handler.at_tracing(self, file, line) + handler.at_tracing(self, file, line) unless ignored_file?(file) end def at_line(file, line) - handler.at_line(self, file, line) unless IGNORED_FILES.include?(file) + handler.at_line(self, file, line) unless ignored_file?(file) end def at_return(file, line) - handler.at_return(self, file, line) + handler.at_return(self, file, line) unless ignored_file?(file) + end + + private + + # + # Gets method arguments for a c-frame. + # + # @param frame_no Frame index in the backtrace. + # + def c_frame_args(frame_no) + myself = frame_self(frame_no) + return [] unless myself.to_s != 'main' + + myself.method(frame_method(frame_no)).parameters + end + + # + # Gets method arguments for a ruby-frame. + # + # @param bind Binding for the ruby-frame. + # + def ruby_frame_args(bind) + return [] unless bind.eval('__method__') + + bind.eval('method(__method__).parameters') + rescue NameError => e + Byebug.errmsg \ + "Exception #{e.class} (#{e.message}) while retreving frame params" + [] end end end