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



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

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

  if abs_frame_pos >= Context.stack_size
    return errmsg("Can't navigate beyond the oldest frame")
  elsif abs_frame_pos < 0
    return errmsg("Can't navigate beyond the newest frame")
  end

  @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.prev_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



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

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

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

#get_frame_block_and_method(pos) ⇒ Object



57
58
59
60
61
62
# File 'lib/byebug/commands/frame.rb', line 57

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]
  frame_block_and_method.map { |x| x.nil? ? '' : x }
end

#get_frame_call(prefix, pos) ⇒ Object



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

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

  call_str
end

#get_frame_class(style, pos) ⇒ Object



52
53
54
55
# File 'lib/byebug/commands/frame.rb', line 52

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


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/byebug/commands/frame.rb', line 15

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
  new_pos
end


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

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


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

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 += format('#%-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}"
  else
    frame_str += " #{file_line}"
  end

  puts frame_str
end

#shortpath(fullpath) ⇒ Object



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

def shortpath(fullpath)
  components = Pathname(fullpath).each_filename.to_a
  return File.join(components) if components.size <= 2

  File.join('...', components[-3..-1])
end

#switch_to_frame(frame_no) ⇒ Object



11
12
13
# File 'lib/byebug/commands/frame.rb', line 11

def switch_to_frame(frame_no)
  frame_no >= 0 ? frame_no : Context.stack_size + frame_no
end