Module: Byebug::FrameFunctions

Defined in:
lib/byebug/commands/frame.rb

Overview

Mixin to assist command parsing

Instance Method Summary collapse

Instance Method Details

#adjust_frame(frame_pos, absolute) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/byebug/commands/frame.rb', line 35

def adjust_frame(frame_pos, absolute)
  if absolute
    abs_frame_pos = switch_to_frame(frame_pos)
    return errmsg "Can't navigate to c-frame\n" if c_frame?(abs_frame_pos)
  else
    abs_frame_pos = navigate_to_frame(frame_pos)
  end

  return errmsg "Can't navigate beyond the oldest frame\n" if
    abs_frame_pos >= Context.stack_size
  return errmsg "Can't navigate beyond the newest frame\n" if
    abs_frame_pos < 0

  @state.frame_pos = abs_frame_pos
  @state.file = @state.context.frame_file @state.frame_pos
  @state.line = @state.context.frame_line @state.frame_pos
  @state.previous_line = nil
  ListCommand.new(@state).execute
end

#c_frame?(frame_no) ⇒ Boolean

Returns:

  • (Boolean)


7
8
9
# File 'lib/byebug/commands/frame.rb', line 7

def c_frame?(frame_no)
  @state.context.frame_binding(frame_no).nil?
end

#get_frame_args(style, pos) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/byebug/commands/frame.rb', line 67

def get_frame_args(style, pos)
  args = @state.context.frame_args pos
  return '' if args.empty?

  locals = @state.context.frame_locals pos if style == 'long'
  my_args = args.map do |arg|
    case arg[0]
      when :block
        prefix, default = '&', 'block'
      when :rest
        prefix, default = '*', 'args'
      else
        prefix, default = '', nil
    end
    klass = style == 'long' && arg[1] ? "##{locals[arg[1]].class}" : ''
    "#{prefix}#{arg[1] || default}#{klass}"
  end

  return "(#{my_args.join(', ')})"
end

#get_frame_block_and_method(pos) ⇒ Object



60
61
62
63
64
65
# File 'lib/byebug/commands/frame.rb', line 60

def get_frame_block_and_method(pos)
  frame_deco_regexp = /((?:block(?: \(\d+ levels\))?|rescue) in )?(.+)/
  frame_deco_method = "#{@state.context.frame_method pos}"
  frame_block_and_method = frame_deco_regexp.match(frame_deco_method)[1..2]
  return frame_block_and_method.map{ |x| x.nil? ? '' : x }
end

#get_frame_call(prefix, pos) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/byebug/commands/frame.rb', line 88

def get_frame_call(prefix, pos)
  frame_block, frame_method = get_frame_block_and_method(pos)
  frame_class = get_frame_class(Setting[:callstyle], pos)
  frame_args = get_frame_args(Setting[:callstyle], pos)

  call_str = frame_block + frame_class + frame_method + frame_args

  max_call_str_size = Setting[:width] - prefix.size
  if call_str.size > max_call_str_size
    call_str = call_str[0..max_call_str_size - 5] + "...)"
  end

  return call_str
end

#get_frame_class(style, pos) ⇒ Object



55
56
57
58
# File 'lib/byebug/commands/frame.rb', line 55

def get_frame_class(style, pos)
  frame_class = style == 'short' ? '' : "#{@state.context.frame_class pos}"
  return frame_class == '' ? '' : "#{frame_class}."
end


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/byebug/commands/frame.rb', line 19

def navigate_to_frame(jump_no)
  return if jump_no == 0
  total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame_pos
  step = jump_no/total_jumps
  loop do
    new_pos += step
    return new_pos if new_pos < 0 || new_pos >= Context.stack_size

    next if c_frame?(new_pos)

    current_jumps += 1
    break if current_jumps == total_jumps
  end
  return new_pos
end


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/byebug/commands/frame.rb', line 103

def print_backtrace
  realsize = Context.stack_size
  calcedsize = @state.context.calced_stack_size
  if calcedsize != realsize
    if Byebug.post_mortem?
      stacksize = calcedsize
    else
      errmsg "Byebug's stacksize (#{calcedsize}) should be #{realsize}. " \
             "This might be a bug in byebug or ruby's debugging API's\n"
      stacksize = realsize
    end
  else
    stacksize = calcedsize
  end
  (0...stacksize).each do |idx|
    print_frame(idx)
  end
end


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/byebug/commands/frame.rb', line 127

def print_frame(pos, mark_current = true)
  fullpath = @state.context.frame_file pos
  file = Setting[:fullpath] ? fullpath : shortpath(fullpath)
  line = @state.context.frame_line pos

  if mark_current
    frame_str = (pos == @state.frame_pos) ? '--> ' : '    '
  else
    frame_str = ""
  end
  frame_str += c_frame?(pos) ? ' ͱ-- ' : ''

  frame_str += sprintf "#%-2d ", pos
  frame_str += get_frame_call frame_str, pos
  file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}"
  if frame_str.size + file_line.size + 1 > Setting[:width]
    frame_str += "\n      #{file_line}\n"
  else
    frame_str += " #{file_line}\n"
  end

  print frame_str
end

#shortpath(fullpath) ⇒ Object



122
123
124
125
# File 'lib/byebug/commands/frame.rb', line 122

def shortpath(fullpath)
  separator = File::ALT_SEPARATOR || File::SEPARATOR
  "...#{separator}" + fullpath.split(separator)[-3..-1].join(separator)
end

#switch_to_frame(frame_no) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/byebug/commands/frame.rb', line 11

def switch_to_frame(frame_no)
  if frame_no < 0
    abs_frame_no = Context.stack_size + frame_no
  else
    abs_frame_no = frame_no
  end
end