Module: PryDebuggerJRuby

Extended by:
PryDebuggerJRuby
Included in:
PryDebuggerJRuby
Defined in:
lib/pry-debugger-jruby/base.rb,
lib/pry-debugger-jruby/version.rb,
lib/pry-debugger-jruby/commands.rb,
lib/pry-debugger-jruby/processor.rb,
lib/pry-debugger-jruby/breakpoints.rb

Defined Under Namespace

Modules: Breakpoints Classes: Processor

Constant Summary collapse

TRACE_IGNORE_FILES =
[*list_debugger_files, *list_pry_files].freeze
VERSION =
'2.1.1'.freeze
Commands =
Pry::CommandSet.new do
  create_command 'step' do
    description 'Step execution into the next line or method.'

    banner "      Usage: step [TIMES]\n\n      Step execution forward. By default, moves a single step.\n\n      Examples:\n\n        step                           Move a single step forward.\n        step 5                         Execute the next 5 steps.\n    BANNER\n\n    def process\n      check_file_context\n      breakout_navigation :step, args.first\n    end\n  end\n\n  create_command 'next' do\n    description 'Execute the next line within the current stack frame.'\n\n    banner <<-BANNER\n      Usage: next [LINES]\n\n      Step over within the same frame. By default, moves forward a single\n      line.\n      Differs from `step` in that it always stays within the same frame\n      (e.g. does not go into other method calls).\n\n      Examples:\n\n        next                           Move a single line forward.\n        next 4                         Execute the next 4 lines.\n    BANNER\n\n    def process\n      check_file_context\n      breakout_navigation :next, args.first\n    end\n  end\n\n  create_command 'finish' do\n    description 'Execute until current stack frame returns.'\n\n    banner <<-BANNER\n      Usage: finish\n\n      Execute until current stack frame returns.\n    BANNER\n\n    def process\n      check_file_context\n      breakout_navigation :finish\n    end\n  end\n\n  create_command 'continue' do\n    description 'End the Pry session and continue program execution.'\n\n    banner <<-BANNER\n      Usage: finish\n\n      End the Pry session and continue program execution.\n    BANNER\n\n    def process\n      check_file_context\n      run 'exit-all'\n    end\n  end\n\n  create_command 'break' do\n    description 'Set or edit a breakpoint.'\n\n    banner <<-BANNER\n      Usage:   break <METHOD | FILE:LINE | LINE> [if CONDITION]\n               break --condition N [CONDITION]\n               break [--show | --delete | --enable | --disable] N\n               break [--delete-all | --disable-all]\n      Aliases: breakpoint\n\n      Set a breakpoint. Accepts a line number in the current file, a file and\n      line number, or a method, and an optional condition.\n\n      Pass appropriate flags to manipulate existing breakpoints.\n\n      Examples:\n\n        break SomeClass#run            Break at the start of `SomeClass#run`.\n        break Foo#bar if baz?          Break at `Foo#bar` only if `baz?`.\n        break app/models/user.rb:15    Break at line 15 in user.rb.\n        break 14                       Break at line 14 in the current file.\n\n        break --condition 4 x > 2      Add/change condition on breakpoint #4.\n        break --condition 3            Remove the condition on breakpoint #3.\n\n        break --delete 5               Delete breakpoint #5.\n        break --disable-all            Disable all breakpoints.\n\n        break                          List all breakpoints. (Same as `breakpoints`)\n        break --show 2                 Show details about breakpoint #2.\n    BANNER\n\n    def options(opt)\n      opt.on :c, :condition,     'Change the condition of a breakpoint.', argument: true, as: Integer\n      opt.on :s, :show,          'Show breakpoint details and source.',   argument: true, as: Integer\n      opt.on :D, :delete,        'Delete a breakpoint.',                  argument: true, as: Integer\n      opt.on :d, :disable,       'Disable a breakpoint.',                 argument: true, as: Integer\n      opt.on :e, :enable,        'Enable a disabled breakpoint.',         argument: true, as: Integer\n      opt.on     :'disable-all', 'Disable all breakpoints.'\n      opt.on     :'delete-all',  'Delete all breakpoints.'\n      method_options(opt)\n    end\n\n    def process\n      Pry.processor.pry = pry_instance\n\n      {\n        delete:        :delete,\n        disable:       :disable,\n        enable:        :enable,\n        'disable-all': :disable_all,\n        'delete-all':  :clear,\n      }.each do |action, method|\n        if opts.present?(action)\n          Breakpoints.__send__ method, *(method == action ? [opts[action]] : [])\n          return run 'breakpoints'\n        end\n      end\n\n      if opts.present?(:condition)\n        Breakpoints.change(opts[:condition], args.empty? ? nil : args.join(' '))\n        run 'breakpoints'\n      elsif opts.present?(:show)\n        print_full_breakpoint Breakpoints.find_by_id(opts[:show])\n      elsif args.empty?\n        run 'breakpoints'\n      else\n        return unless PryDebuggerJRuby.check_trace_enabled\n        new_breakpoint\n      end\n    end\n\n    def new_breakpoint\n      place = args.shift\n      condition = args.join(' ') if 'if' == args.shift\n\n      file, line =\n        case place\n        when /^(\\d+)$/       # Line number only\n          line = $1\n          unless PryDebuggerJRuby.check_file_context(target)\n            raise ArgumentError, 'Line number declaration valid only in a file context.'\n          end\n          if target.respond_to?(:source_location)\n            [target.source_location.first, line]\n          else\n            [target.eval('__FILE__'), line]\n          end\n        when /^(.+):(\\d+)$/  # File and line number\n          [$1, $2]\n        else               # Method or class name\n          self.args = [place]\n          location = method_object.source_location\n          location[1] += 1\n          location\n        end\n\n      print_full_breakpoint Breakpoints.add(file, line.to_i, condition)\n    end\n  end\n  alias_command 'breakpoint', 'break'\n\n  create_command 'breakpoints' do\n    description 'List defined breakpoints.'\n\n    banner <<-BANNER\n      Usage:   breakpoints [--verbose]\n      Aliases: breaks\n\n      List registered breakpoints and their current status.\n    BANNER\n\n    def options(opt)\n      opt.on :v, :verbose, 'Print source around each breakpoint.'\n    end\n\n    def process\n      if Breakpoints.count > 0\n        if opts.verbose?   # Long-form with source output\n          Breakpoints.each { |b| print_full_breakpoint(b) }\n        else               # Simple table output\n          max_width = [Math.log10(Breakpoints.count).ceil, 1].max\n          header = \"\#{' ' * (max_width - 1)}#  Enabled  At \"\n\n          output.puts\n          output.puts Pry::Helpers::Text.bold(header)\n          output.puts Pry::Helpers::Text.bold('-' * header.size)\n          Breakpoints.each do |breakpoint|\n            output.printf \"%\#{max_width}d  \", breakpoint.id\n            output.print  breakpoint.enabled? ? 'Yes      ' : 'No       '\n            output.print  \"\#{breakpoint.source}:\#{breakpoint.pos}\"\n            output.print  \" (if \#{breakpoint.expr})\" if breakpoint.expr\n            output.puts\n          end\n          output.puts\n        end\n      else\n        output.puts Pry::Helpers::Text.bold('No breakpoints defined.')\n      end\n    end\n  end\n  alias_command 'breaks', 'breakpoints'\n\n  helpers do\n    def breakout_navigation(action, times = nil)\n      return unless PryDebuggerJRuby.check_trace_enabled\n\n      pry_instance.binding_stack.clear     # Clear the binding stack\n      throw :breakout_nav, {        # Break out of the REPL loop and\n        action: action,             #   signal the tracer\n        times:  times,\n        pry:    pry_instance,\n      }\n    end\n\n    # Ensures that a command is executed in a local file context.\n    def check_file_context\n      unless PryDebuggerJRuby.check_file_context(target)\n        raise Pry::CommandError, 'Cannot find local context. Did you use `binding.pry`?'\n      end\n    end\n\n    # Print out full information about a breakpoint including surrounding code\n    # at that point.\n    def print_full_breakpoint(breakpoint)\n      line = breakpoint.pos\n      output.print Pry::Helpers::Text.bold(\"Breakpoint \#{breakpoint.id}: \")\n      output.print \"\#{breakpoint.source} @ line \#{line} \"\n      output.print breakpoint.enabled? ? '(Enabled)' : '(Disabled)'\n      output.puts  ' :'\n      if (expr = breakpoint.expr)\n        output.puts \"\#{Pry::Helpers::Text.bold('Condition:')} \#{expr}\"\n      end\n      output.puts\n      output.puts(\n        Pry::Code.from_file(breakpoint.source)\n          .around(line, 3).with_line_numbers.with_marker(line).highlighted\n      )\n      output.puts\n    end\n  end\nend\n"

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#current_remote_serverObject

Reference to currently running pry-remote server. Used by the processor.



52
53
54
# File 'lib/pry-debugger-jruby/base.rb', line 52

def current_remote_server
  @current_remote_server
end

Instance Method Details

#check_file_context(target) ⇒ Object

Checks that a binding is in a local file context. Extracted from github.com/pry/pry/blob/master/lib/pry/default_commands/context.rb



29
30
31
32
# File 'lib/pry-debugger-jruby/base.rb', line 29

def check_file_context(target)
  file = target.respond_to?(:source_location) ? target.source_location.first : target.eval('__FILE__')
  file == Pry.eval_path || (file !~ /(\(.*\))|<.*>/ && file != '' && file != '-e')
end

#check_trace_enabledObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/pry-debugger-jruby/base.rb', line 34

def check_trace_enabled
  return true if org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED
  warn "You are currently running JRuby without the --debug flag enabled, and without it this command will not work correctly.\n\nTo fix it, either:\n\n* add the --debug flag to your ruby/jruby command\n* or add the --debug flag to the JRUBY_OPTS environment variable\n* or enable the jruby.debug.fullTrace option\n\nDo note that having this option on all the time has a performance penalty, so we recommend you only enable it while debugging.\nSafe prying, fellow rubyst!\n"
  false
end