Class: PryDebugger::Processor

Inherits:
Object
  • Object
show all
Defined in:
lib/pry-debugger/processor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeProcessor

Returns a new instance of Processor.



8
9
10
11
12
# File 'lib/pry-debugger/processor.rb', line 8

def initialize
  Debugger.handler = self
  @always_enabled = false
  @delayed = Hash.new(0)
end

Instance Attribute Details

#pryObject

Returns the value of attribute pry.



6
7
8
# File 'lib/pry-debugger/processor.rb', line 6

def pry
  @pry
end

Instance Method Details

#at_breakpoint(context, breakpoint) ⇒ Object

Called when a breakpoint is triggered. Note: ‘at_line“ is called immediately after with the context’s ‘stop_reason == :breakpoint`.



96
97
98
99
100
101
102
103
104
105
# File 'lib/pry-debugger/processor.rb', line 96

def at_breakpoint(context, breakpoint)
  @pry.output.print Pry::Helpers::Text.bold("\nBreakpoint #{breakpoint.id}. ")
  @pry.output.puts  (breakpoint.hit_count == 1 ?
                       'First hit.' :
                       "Hit #{breakpoint.hit_count} times." )
  if (expr = breakpoint.expr)
    @pry.output.print Pry::Helpers::Text.bold("Condition: ")
    @pry.output.puts  expr
  end
end

#at_catchpoint(context, exception) ⇒ Object



107
108
109
# File 'lib/pry-debugger/processor.rb', line 107

def at_catchpoint(context, exception)
  # TODO
end

#at_line(context, file, line) ⇒ Object

— Callbacks from debugger C extension —



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/pry-debugger/processor.rb', line 69

def at_line(context, file, line)
  return if file && TRACE_IGNORE_FILES.include?(File.expand_path(file))

  # If stopped for a breakpoint or catchpoint, can't play any delayed steps
  # as they'll move away from the interruption point. (Unsure if scenario is
  # possible, but just keeping assertions in check.)
  @delayed = Hash.new(0) unless :step == context.stop_reason

  if @delayed[:next] > 1     # If any delayed nexts/steps, do 'em.
    step_over @delayed[:next] - 1
    @delayed = Hash.new(0)

  elsif @delayed[:step] > 1
    step @delayed[:step] - 1
    @delayed = Hash.new(0)

  elsif @delayed[:finish] > 0
    finish
    @delayed = Hash.new(0)

  else  # Otherwise, resume the pry session at the stopped line.
    resume_pry context
  end
end

#debugging=(enabled) ⇒ Object

Adjust debugging. When set to false, the Processor will manage enabling and disabling the debugger itself. When set to true, the debugger is always enabled.



56
57
58
59
60
61
62
63
64
# File 'lib/pry-debugger/processor.rb', line 56

def debugging=(enabled)
  if enabled
    @always_enabled = true
    Debugger.start unless Debugger.started?
  else
    @always_enabled = false
    # Debugger will get stopped if necessary in `stop` once the repl ends.
  end
end

#run(initial = true, &block) ⇒ Object

Wrap a Pry REPL to catch navigational commands and act on them.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/pry-debugger/processor.rb', line 15

def run(initial = true, &block)
  return_value = nil
  command = catch(:breakout_nav) do  # Throws from PryDebugger::Commands
    return_value = yield
    {}    # Nothing thrown == no navigational command
  end

  times = (command[:times] || 1).to_i   # Command argument
  times = 1 if times <= 0

  if [:step, :next, :finish].include? command[:action]
    @pry = command[:pry]   # Pry instance to resume after stepping
    Debugger.start unless Debugger.started?

    if initial
      # Movement when on the initial binding.pry line will have a frame
      # inside Debugger. If we step normally, it'll stop inside this
      # Processor. So jump out and stop at the above frame, then step/next
      # from our callback.
      Debugger.current_context.stop_frame = 1
      @delayed[command[:action]] = times

    elsif :next == command[:action]
      step_over times

    elsif :step == command[:action]
      step times

    elsif :finish == command[:action]
      finish
    end
  else
    stop
  end

  return_value
end