byebug 3.5.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/.rubocop.yml +18 -1
  4. data/.travis.yml +21 -1
  5. data/CHANGELOG.md +356 -308
  6. data/CONTRIBUTING.md +31 -15
  7. data/GUIDE.md +859 -475
  8. data/Gemfile +8 -10
  9. data/LICENSE +1 -1
  10. data/README.md +41 -45
  11. data/Rakefile +30 -28
  12. data/byebug.gemspec +18 -18
  13. data/ext/byebug/breakpoint.c +88 -75
  14. data/ext/byebug/byebug.c +253 -252
  15. data/ext/byebug/byebug.h +53 -53
  16. data/ext/byebug/context.c +188 -159
  17. data/ext/byebug/extconf.rb +9 -6
  18. data/ext/byebug/locker.c +53 -11
  19. data/ext/byebug/threads.c +137 -39
  20. data/lib/byebug/attacher.rb +7 -2
  21. data/lib/byebug/breakpoint.rb +30 -0
  22. data/lib/byebug/command.rb +36 -32
  23. data/lib/byebug/commands/break.rb +49 -48
  24. data/lib/byebug/commands/catch.rb +64 -0
  25. data/lib/byebug/commands/condition.rb +13 -9
  26. data/lib/byebug/commands/continue.rb +8 -4
  27. data/lib/byebug/commands/delete.rb +10 -4
  28. data/lib/byebug/commands/display.rb +33 -25
  29. data/lib/byebug/commands/edit.rb +18 -13
  30. data/lib/byebug/commands/enable_disable.rb +26 -24
  31. data/lib/byebug/commands/eval.rb +77 -35
  32. data/lib/byebug/commands/finish.rb +9 -5
  33. data/lib/byebug/commands/frame.rb +66 -125
  34. data/lib/byebug/commands/help.rb +14 -21
  35. data/lib/byebug/commands/history.rb +5 -1
  36. data/lib/byebug/commands/info.rb +41 -106
  37. data/lib/byebug/commands/interrupt.rb +6 -2
  38. data/lib/byebug/commands/irb.rb +5 -2
  39. data/lib/byebug/commands/kill.rb +6 -2
  40. data/lib/byebug/commands/list.rb +21 -14
  41. data/lib/byebug/commands/method.rb +17 -9
  42. data/lib/byebug/commands/pry.rb +13 -3
  43. data/lib/byebug/commands/quit.rb +10 -5
  44. data/lib/byebug/commands/restart.rb +12 -19
  45. data/lib/byebug/commands/save.rb +10 -6
  46. data/lib/byebug/commands/set.rb +15 -14
  47. data/lib/byebug/commands/show.rb +8 -8
  48. data/lib/byebug/commands/source.rb +14 -8
  49. data/lib/byebug/commands/stepping.rb +15 -29
  50. data/lib/byebug/commands/threads.rb +73 -49
  51. data/lib/byebug/commands/tracevar.rb +56 -0
  52. data/lib/byebug/commands/undisplay.rb +8 -4
  53. data/lib/byebug/commands/untracevar.rb +38 -0
  54. data/lib/byebug/commands/var.rb +107 -0
  55. data/lib/byebug/context.rb +78 -42
  56. data/lib/byebug/core.rb +78 -40
  57. data/lib/byebug/helper.rb +58 -42
  58. data/lib/byebug/history.rb +12 -1
  59. data/lib/byebug/interface.rb +91 -11
  60. data/lib/byebug/interfaces/local_interface.rb +12 -19
  61. data/lib/byebug/interfaces/remote_interface.rb +12 -15
  62. data/lib/byebug/interfaces/script_interface.rb +14 -18
  63. data/lib/byebug/interfaces/test_interface.rb +54 -0
  64. data/lib/byebug/printers/base.rb +64 -0
  65. data/lib/byebug/printers/plain.rb +53 -0
  66. data/lib/byebug/processor.rb +20 -1
  67. data/lib/byebug/processors/command_processor.rb +57 -172
  68. data/lib/byebug/processors/control_command_processor.rb +16 -43
  69. data/lib/byebug/remote.rb +13 -7
  70. data/lib/byebug/runner.rb +102 -54
  71. data/lib/byebug/setting.rb +45 -68
  72. data/lib/byebug/settings/autoeval.rb +2 -0
  73. data/lib/byebug/settings/autoirb.rb +3 -0
  74. data/lib/byebug/settings/autolist.rb +3 -0
  75. data/lib/byebug/settings/autosave.rb +2 -0
  76. data/lib/byebug/settings/basename.rb +2 -0
  77. data/lib/byebug/settings/callstyle.rb +2 -0
  78. data/lib/byebug/settings/fullpath.rb +2 -0
  79. data/lib/byebug/settings/histfile.rb +2 -0
  80. data/lib/byebug/settings/histsize.rb +2 -0
  81. data/lib/byebug/settings/linetrace.rb +2 -0
  82. data/lib/byebug/settings/listsize.rb +2 -0
  83. data/lib/byebug/settings/post_mortem.rb +7 -2
  84. data/lib/byebug/settings/stack_on_error.rb +2 -0
  85. data/lib/byebug/settings/verbose.rb +2 -0
  86. data/lib/byebug/settings/width.rb +2 -0
  87. data/lib/byebug/state.rb +12 -0
  88. data/lib/byebug/states/control_state.rb +26 -0
  89. data/lib/byebug/states/regular_state.rb +178 -0
  90. data/lib/byebug/version.rb +1 -1
  91. metadata +24 -109
  92. data/lib/byebug/commands/catchpoint.rb +0 -53
  93. data/lib/byebug/commands/reload.rb +0 -29
  94. data/lib/byebug/commands/trace.rb +0 -50
  95. data/lib/byebug/commands/variables.rb +0 -206
  96. data/lib/byebug/options.rb +0 -46
  97. data/lib/byebug/settings/autoreload.rb +0 -12
  98. data/lib/byebug/settings/forcestep.rb +0 -14
  99. data/lib/byebug/settings/testing.rb +0 -12
  100. data/lib/byebug/settings/tracing_plus.rb +0 -11
  101. data/test/commands/break_test.rb +0 -364
  102. data/test/commands/condition_test.rb +0 -85
  103. data/test/commands/continue_test.rb +0 -47
  104. data/test/commands/delete_test.rb +0 -26
  105. data/test/commands/display_test.rb +0 -37
  106. data/test/commands/edit_test.rb +0 -52
  107. data/test/commands/eval_test.rb +0 -89
  108. data/test/commands/finish_test.rb +0 -74
  109. data/test/commands/frame_test.rb +0 -223
  110. data/test/commands/help_test.rb +0 -66
  111. data/test/commands/history_test.rb +0 -61
  112. data/test/commands/info_test.rb +0 -238
  113. data/test/commands/interrupt_test.rb +0 -45
  114. data/test/commands/irb_test.rb +0 -28
  115. data/test/commands/kill_test.rb +0 -50
  116. data/test/commands/list_test.rb +0 -174
  117. data/test/commands/method_test.rb +0 -52
  118. data/test/commands/post_mortem_test.rb +0 -71
  119. data/test/commands/pry_test.rb +0 -26
  120. data/test/commands/quit_test.rb +0 -53
  121. data/test/commands/reload_test.rb +0 -39
  122. data/test/commands/restart_test.rb +0 -46
  123. data/test/commands/save_test.rb +0 -67
  124. data/test/commands/set_test.rb +0 -140
  125. data/test/commands/show_test.rb +0 -76
  126. data/test/commands/source_test.rb +0 -46
  127. data/test/commands/stepping_test.rb +0 -192
  128. data/test/commands/thread_test.rb +0 -164
  129. data/test/commands/trace_test.rb +0 -71
  130. data/test/commands/undisplay_test.rb +0 -75
  131. data/test/commands/variables_test.rb +0 -105
  132. data/test/debugger_alias_test.rb +0 -7
  133. data/test/runner_test.rb +0 -150
  134. data/test/support/matchers.rb +0 -65
  135. data/test/support/test_interface.rb +0 -59
  136. data/test/support/utils.rb +0 -122
  137. data/test/test_helper.rb +0 -58
@@ -1,12 +1,14 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Mixin to assist command parsing
4
6
  #
5
7
  module EnableDisableFunctions
6
8
  def enable_disable_breakpoints(is_enable, args)
7
- return errmsg('No breakpoints have been set') if Breakpoint.none?
9
+ return errmsg(pr('toggle.errors.no_breakpoints')) if Breakpoint.none?
8
10
 
9
- all_breakpoints = Byebug.breakpoints.sort_by { |b| b.id }
11
+ all_breakpoints = Byebug.breakpoints.sort_by(&:id)
10
12
  if args.empty?
11
13
  selected_breakpoints = all_breakpoints
12
14
  else
@@ -18,16 +20,15 @@ module Byebug
18
20
 
19
21
  selected_ids << pos
20
22
  end
21
- selected_breakpoints = all_breakpoints.select do
22
- |b| selected_ids.include?(b.id)
23
+ selected_breakpoints = all_breakpoints.select do |b|
24
+ selected_ids.include?(b.id)
23
25
  end
24
26
  end
25
27
 
26
28
  selected_breakpoints.each do |b|
27
29
  enabled = ('enable' == is_enable)
28
30
  if enabled && !syntax_valid?(b.expr)
29
- return errmsg("Expression \"#{b.expr}\" syntactically incorrect; " \
30
- 'breakpoint remains disabled.')
31
+ return errmsg(pr('toggle.errors.expression', expr: b.expr))
31
32
  end
32
33
 
33
34
  b.enabled = enabled
@@ -35,9 +36,7 @@ module Byebug
35
36
  end
36
37
 
37
38
  def enable_disable_display(is_enable, args)
38
- if 0 == @state.display.size
39
- return errmsg('No display expressions have been set')
40
- end
39
+ return errmsg(pr('toggle.errors.no_display')) if 0 == @state.display.size
41
40
 
42
41
  args.each do |pos|
43
42
  pos, err = get_int(pos, "#{is_enable} display", 1, @state.display.size)
@@ -52,6 +51,8 @@ module Byebug
52
51
  # Enabling or disabling custom display expressions or breakpoints.
53
52
  #
54
53
  class EnableDisableCommand < Command
54
+ include EnableDisableFunctions
55
+
55
56
  Subcommands = [
56
57
  ['breakpoints', 2, 'Enable/disable breakpoints. Give breakpoint ' \
57
58
  'numbers (separated by spaces) as arguments or no ' \
@@ -64,7 +65,7 @@ module Byebug
64
65
  'numbers']
65
66
  ].map do |name, min, help|
66
67
  Subcmd.new(name, min, help)
67
- end unless defined?(Subcommands)
68
+ end
68
69
 
69
70
  def regexp
70
71
  /^\s* (dis|en)(?:able)? (?:\s+(.+))? \s*$/x
@@ -73,8 +74,7 @@ module Byebug
73
74
  def execute
74
75
  cmd = @match[1] == 'dis' ? 'disable' : 'enable'
75
76
 
76
- return errmsg("\"#{cmd}\" must be followed by \"display\", " \
77
- "\"breakpoints\" or breakpoint ids") unless @match[2]
77
+ return errmsg(pr('toggle.errors.syntax', toggle: cmd)) unless @match[2]
78
78
 
79
79
  args = @match[2].split(/[ \t]+/)
80
80
  param = args.shift
@@ -108,22 +108,24 @@ module Byebug
108
108
  end
109
109
 
110
110
  def description
111
- %{(en|dis)[able][[ (breakpoints|display)][ n1[ n2[ ...[ nn]]]]]
111
+ prettify <<-EOD
112
+ (en|dis)[able][[ (breakpoints|display)][ n1[ n2[ ...[ nn]]]]]
112
113
 
113
- Enables or disables breakpoints or displays.
114
+ Enables or disables breakpoints or displays.
114
115
 
115
- "enable" by itself enables all breakpoints, just like
116
- "enable breakpoints". On the other side, "disable" or
117
- "disable breakpoints" disable all breakpoints.
116
+ "enable" by itself enables all breakpoints, just like
117
+ "enable breakpoints". On the other side, "disable" or
118
+ "disable breakpoints" disable all breakpoints.
118
119
 
119
- You can also specify a space separated list of breakpoint numbers to
120
- enable or disable specific breakpoints. You can use either
121
- "enable <id1> ... <idn>" or "enable breakpoints <id1> ... <idn>" and
122
- the same with "disable".
120
+ You can also specify a space separated list of breakpoint numbers to
121
+ enable or disable specific breakpoints. You can use either
122
+ "enable <id1> ... <idn>" or "enable breakpoints <id1> ... <idn>" and
123
+ the same with "disable".
123
124
 
124
- If instead of "breakpoints" you specify "display", the command will
125
- work exactly the same way, but displays will get enabled/disabled
126
- instead of breakpoints.}
125
+ If instead of "breakpoints" you specify "display", the command will
126
+ work exactly the same way, but displays will get enabled/disabled
127
+ instead of breakpoints.
128
+ EOD
127
129
  end
128
130
  end
129
131
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  require 'English'
2
4
  require 'pp'
3
5
 
@@ -6,16 +8,52 @@ module Byebug
6
8
  # Utilities used by the eval command
7
9
  #
8
10
  module EvalFunctions
11
+ #
12
+ # Run block temporarily ignoring all TracePoint events.
13
+ #
14
+ # Used to evaluate stuff within Byebug's prompt. Otherwise, any code
15
+ # creating new threads won't be properly evaluated because new threads will
16
+ # get blocked by byebug's main thread.
17
+ #
18
+ def allowing_other_threads
19
+ Byebug.unlock
20
+ res = yield
21
+ Byebug.lock
22
+ res
23
+ end
24
+
25
+ #
26
+ # Get current binding and yield it to the given block
27
+ #
9
28
  def run_with_binding
10
29
  binding = get_binding
11
30
  yield binding
12
31
  end
32
+
33
+ #
34
+ # Evaluate +expression+ using +binding+
35
+ #
36
+ # @param binding [Binding] Context where to evaluate the expression
37
+ # @param expression [String] Expression to evaluation
38
+ # @param stack_on_error [Boolean] Whether to show a stack trace on error.
39
+ #
40
+ def eval_with_setting(binding, expression, stack_on_error)
41
+ allowing_other_threads do
42
+ if stack_on_error
43
+ bb_eval(expression, binding)
44
+ else
45
+ bb_warning_eval(expression, binding)
46
+ end
47
+ end
48
+ end
13
49
  end
14
50
 
15
51
  #
16
52
  # Evaluation of expressions from byebug's prompt.
17
53
  #
18
54
  class EvalCommand < Command
55
+ include EvalFunctions
56
+
19
57
  self.allow_in_control = true
20
58
 
21
59
  def match(input)
@@ -24,17 +62,15 @@ module Byebug
24
62
  end
25
63
 
26
64
  def regexp
27
- /^\s* (p|e(?:val)?)\s+/x
65
+ /^\s* e(?:val)? \s+/x
28
66
  end
29
67
 
30
68
  def execute
31
69
  expr = @match ? @match.post_match : @input
32
70
  run_with_binding do |b|
33
- if Setting[:stack_on_error]
34
- puts "#{bb_eval(expr, b).inspect}"
35
- else
36
- puts "#{bb_warning_eval(expr, b).inspect}"
37
- end
71
+ res = eval_with_setting(b, expr, Setting[:stack_on_error])
72
+
73
+ print pr('eval.result', expr: expr, result: res.inspect)
38
74
  end
39
75
  rescue
40
76
  puts "#{$ERROR_INFO.class} Exception: #{$ERROR_INFO.message}"
@@ -42,16 +78,18 @@ module Byebug
42
78
 
43
79
  class << self
44
80
  def names
45
- %w(p eval)
81
+ %w(eval)
46
82
  end
47
83
 
48
84
  def description
49
- %{(p|e[val]) <expression>
85
+ prettify <<-EOD
86
+ e[val] <expression>
50
87
 
51
88
  Evaluates <expression> and prints its value.
52
89
 
53
90
  * NOTE - unknown input is automatically evaluated, to turn this off
54
- use 'set noautoeval'.}
91
+ use 'set noautoeval'.
92
+ EOD
55
93
  end
56
94
  end
57
95
  end
@@ -60,6 +98,8 @@ module Byebug
60
98
  # Evaluation and pretty printing from byebug's prompt.
61
99
  #
62
100
  class PPCommand < Command
101
+ include EvalFunctions
102
+
63
103
  self.allow_in_control = true
64
104
 
65
105
  def regexp
@@ -86,9 +126,11 @@ module Byebug
86
126
  end
87
127
 
88
128
  def description
89
- %(pp <expression>
129
+ prettify <<-EOD
130
+ pp <expression>
90
131
 
91
- Evaluates <expression> and pretty-prints its value.)
132
+ Evaluates <expression> and pretty-prints its value.
133
+ EOD
92
134
  end
93
135
  end
94
136
  end
@@ -97,26 +139,24 @@ module Byebug
97
139
  # Evaluation, pretty printing and columnizing from byebug's prompt.
98
140
  #
99
141
  class PutLCommand < Command
142
+ include EvalFunctions
100
143
  include Columnize
144
+
101
145
  self.allow_in_control = true
102
146
 
103
147
  def regexp
104
- /^\s* putl\s+/x
148
+ /^\s* putl \s+/x
105
149
  end
106
150
 
107
151
  def execute
108
152
  out = StringIO.new
109
153
  run_with_binding do |b|
110
- if Setting[:stack_on_error]
111
- vals = bb_eval(@match.post_match, b)
112
- else
113
- vals = bb_warning_eval(@match.post_match, b)
114
- end
115
- if vals.is_a?(Array)
116
- vals = vals.map { |item| item.to_s }
117
- puts "#{columnize(vals, Setting[:width])}"
154
+ res = eval_with_setting(b, @match.post_match, Setting[:stack_on_error])
155
+
156
+ if res.is_a?(Array)
157
+ puts "#{columnize(res.map(&:to_s), Setting[:width])}"
118
158
  else
119
- PP.pp(vals, out)
159
+ PP.pp(res, out)
120
160
  puts out.string
121
161
  end
122
162
  end
@@ -130,9 +170,11 @@ module Byebug
130
170
  end
131
171
 
132
172
  def description
133
- %(putl <expression>
173
+ prettify <<-EOD
174
+ putl <expression>
134
175
 
135
- Evaluates <expression>, an array, and columnize its value.)
176
+ Evaluates <expression>, an array, and columnize its value.
177
+ EOD
136
178
  end
137
179
  end
138
180
  end
@@ -141,26 +183,24 @@ module Byebug
141
183
  # Evaluation, pretty printing, columnizing and sorting from byebug's prompt
142
184
  #
143
185
  class PSCommand < Command
186
+ include EvalFunctions
144
187
  include Columnize
188
+
145
189
  self.allow_in_control = true
146
190
 
147
191
  def regexp
148
- /^\s* ps\s+/x
192
+ /^\s* ps \s+/x
149
193
  end
150
194
 
151
195
  def execute
152
196
  out = StringIO.new
153
197
  run_with_binding do |b|
154
- if Setting[:stack_on_error]
155
- vals = bb_eval(@match.post_match, b)
156
- else
157
- vals = bb_warning_eval(@match.post_match, b)
158
- end
159
- if vals.is_a?(Array)
160
- vals = vals.map { |item| item.to_s }
161
- puts "#{columnize(vals.sort!, Setting[:width])}"
198
+ res = eval_with_setting(b, @match.post_match, Setting[:stack_on_error])
199
+
200
+ if res.is_a?(Array)
201
+ puts "#{columnize(res.map(&:to_s).sort!, Setting[:width])}"
162
202
  else
163
- PP.pp(vals, out)
203
+ PP.pp(res, out)
164
204
  puts out.string
165
205
  end
166
206
  end
@@ -174,9 +214,11 @@ module Byebug
174
214
  end
175
215
 
176
216
  def description
177
- %(ps <expression>
217
+ prettify <<-EOD
218
+ ps <expression>
178
219
 
179
- Evaluates <expression>, an array, sort and columnize its value.)
220
+ Evaluates <expression>, an array, sort and columnize its value.
221
+ EOD
180
222
  end
181
223
  end
182
224
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Implements the finish functionality.
@@ -12,7 +14,7 @@ module Byebug
12
14
  end
13
15
 
14
16
  def execute
15
- max_frames = Context.stack_size - @state.frame_pos
17
+ max_frames = @state.context.stack_size - @state.frame
16
18
  if @match[1]
17
19
  n_frames, err = get_int(@match[1], 'finish', 0, max_frames - 1)
18
20
  return errmsg(err) unless n_frames
@@ -21,8 +23,8 @@ module Byebug
21
23
  end
22
24
 
23
25
  force = n_frames == 0 ? true : false
24
- @state.context.step_out(@state.frame_pos + n_frames, force)
25
- @state.frame_pos = 0
26
+ @state.context.step_out(@state.frame + n_frames, force)
27
+ @state.frame = 0
26
28
  @state.proceed
27
29
  end
28
30
 
@@ -32,11 +34,13 @@ module Byebug
32
34
  end
33
35
 
34
36
  def description
35
- %(fin[ish][ n_frames] Execute until frame returns.
37
+ prettify <<-EOD
38
+ fin[ish][ n_frames] Execute until frame returns.
36
39
 
37
40
  If no number is given, we run until the current frame returns. If a
38
41
  number of frames `n_frames` is given, then we run until `n_frames`
39
- return from the current position.)
42
+ return from the current position.
43
+ EOD
40
44
  end
41
45
  end
42
46
  end
@@ -1,26 +1,28 @@
1
+ require 'byebug/command'
2
+
1
3
  # encoding: utf-8
4
+
5
+ require 'pathname'
6
+
2
7
  module Byebug
3
8
  #
4
9
  # Mixin to assist command parsing
5
10
  #
6
11
  module FrameFunctions
7
- def c_frame?(frame_no)
8
- @state.context.frame_binding(frame_no).nil?
9
- end
10
-
11
12
  def switch_to_frame(frame_no)
12
- frame_no >= 0 ? frame_no : Context.stack_size + frame_no
13
+ frame_no >= 0 ? frame_no : @state.context.stack_size + frame_no
13
14
  end
14
15
 
15
16
  def navigate_to_frame(jump_no)
16
17
  return if jump_no == 0
17
- total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame_pos
18
- step = jump_no / total_jumps
18
+ total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame
19
+ step = jump_no / total_jumps # +1 (up) or -1 (down)
20
+
19
21
  loop do
20
22
  new_pos += step
21
- return new_pos if new_pos < 0 || new_pos >= Context.stack_size
23
+ break if new_pos < 0 || new_pos >= @state.context.stack_size
22
24
 
23
- next if c_frame?(new_pos)
25
+ next if @state.c_frame?(new_pos)
24
26
 
25
27
  current_jumps += 1
26
28
  break if current_jumps == total_jumps
@@ -28,126 +30,36 @@ module Byebug
28
30
  new_pos
29
31
  end
30
32
 
31
- def adjust_frame(frame_pos, absolute)
33
+ def adjust_frame(frame, absolute)
32
34
  if absolute
33
- abs_frame_pos = switch_to_frame(frame_pos)
34
- return errmsg("Can't navigate to c-frame") if c_frame?(abs_frame_pos)
35
+ abs_frame = switch_to_frame(frame)
36
+ return errmsg(pr('frame.errors.c_frame')) if @state.c_frame?(abs_frame)
35
37
  else
36
- abs_frame_pos = navigate_to_frame(frame_pos)
38
+ abs_frame = navigate_to_frame(frame)
37
39
  end
38
40
 
39
- if abs_frame_pos >= Context.stack_size
40
- return errmsg("Can't navigate beyond the oldest frame")
41
- elsif abs_frame_pos < 0
42
- return errmsg("Can't navigate beyond the newest frame")
41
+ if abs_frame >= @state.context.stack_size
42
+ return errmsg(pr('frame.errors.too_low'))
43
+ elsif abs_frame < 0
44
+ return errmsg(pr('frame.errors.too_high'))
43
45
  end
44
46
 
45
- @state.frame_pos = abs_frame_pos
46
- @state.file = @state.context.frame_file @state.frame_pos
47
- @state.line = @state.context.frame_line @state.frame_pos
47
+ @state.frame = abs_frame
48
+ @state.file = @state.context.frame_file(@state.frame)
49
+ @state.line = @state.context.frame_line(@state.frame)
48
50
  @state.prev_line = nil
49
- ListCommand.new(@state).execute
50
- end
51
-
52
- def get_frame_class(style, pos)
53
- frame_class = style == 'short' ? '' : "#{@state.context.frame_class pos}"
54
- frame_class == '' ? '' : "#{frame_class}."
55
- end
56
-
57
- def get_frame_block_and_method(pos)
58
- frame_deco_regexp = /((?:block(?: \(\d+ levels\))?|rescue) in )?(.+)/
59
- frame_deco_method = "#{@state.context.frame_method pos}"
60
- frame_block_and_method = frame_deco_regexp.match(frame_deco_method)[1..2]
61
- frame_block_and_method.map { |x| x.nil? ? '' : x }
62
- end
63
-
64
- def get_frame_args(style, pos)
65
- args = @state.context.frame_args pos
66
- return '' if args.empty?
67
-
68
- locals = @state.context.frame_locals pos if style == 'long'
69
- my_args = args.map do |arg|
70
- case arg[0]
71
- when :block
72
- prefix, default = '&', 'block'
73
- when :rest
74
- prefix, default = '*', 'args'
75
- else
76
- prefix, default = '', nil
77
- end
78
-
79
- klass = style == 'long' && arg[1] ? "##{locals[arg[1]].class}" : ''
80
- "#{prefix}#{arg[1] || default}#{klass}"
81
- end
82
-
83
- "(#{my_args.join(', ')})"
84
- end
85
-
86
- def get_frame_call(prefix, pos)
87
- frame_block, frame_method = get_frame_block_and_method(pos)
88
- frame_class = get_frame_class(Setting[:callstyle], pos)
89
- frame_args = get_frame_args(Setting[:callstyle], pos)
90
-
91
- call_str = frame_block + frame_class + frame_method + frame_args
92
-
93
- max_call_str_size = Setting[:width] - prefix.size
94
- if call_str.size > max_call_str_size
95
- call_str = call_str[0..max_call_str_size - 5] + '...)'
96
- end
97
-
98
- call_str
99
- end
100
-
101
- def print_backtrace
102
- realsize = Context.stack_size
103
- calcedsize = @state.context.calced_stack_size
104
- if calcedsize != realsize
105
- if Byebug.post_mortem?
106
- stacksize = calcedsize
107
- else
108
- errmsg "Byebug's stacksize (#{calcedsize}) should be #{realsize}. " \
109
- "This might be a bug in byebug or ruby's debugging API's\n"
110
- stacksize = realsize
111
- end
112
- else
113
- stacksize = calcedsize
114
- end
115
- (0...stacksize).each do |idx|
116
- print_frame(idx)
117
- end
118
- end
119
-
120
- require 'pathname'
121
-
122
- def shortpath(fullpath)
123
- components = Pathname(fullpath).each_filename.to_a
124
- return File.join(components) if components.size <= 2
125
51
 
126
- File.join('...', components[-3..-1])
52
+ ListCommand.new(@state).execute if Setting[:autolist]
127
53
  end
128
54
 
129
- def print_frame(pos, mark_current = true)
130
- fullpath = @state.context.frame_file(pos)
131
- file = Setting[:fullpath] ? fullpath : shortpath(fullpath)
132
- line = @state.context.frame_line(pos)
133
-
134
- if mark_current
135
- frame_str = (pos == @state.frame_pos) ? '--> ' : ' '
136
- else
137
- frame_str = ''
138
- end
139
- frame_str += c_frame?(pos) ? ' ͱ-- ' : ''
140
-
141
- frame_str += format('#%-2d ', pos)
142
- frame_str += get_frame_call frame_str, pos
143
- file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}"
144
- if frame_str.size + file_line.size + 1 > Setting[:width]
145
- frame_str += "\n #{file_line}"
146
- else
147
- frame_str += " #{file_line}"
148
- end
55
+ def get_pr_arguments(frame_no)
56
+ file = @state.frame_file(frame_no)
57
+ line = @state.frame_line(frame_no)
58
+ call = @state.frame_call(frame_no)
59
+ mark = @state.frame_mark(frame_no)
60
+ pos = @state.frame_pos(frame_no)
149
61
 
150
- puts frame_str
62
+ { mark: mark, pos: pos, call: call, file: file, line: line }
151
63
  end
152
64
  end
153
65
 
@@ -155,6 +67,8 @@ module Byebug
155
67
  # Show current backtrace.
156
68
  #
157
69
  class WhereCommand < Command
70
+ include FrameFunctions
71
+
158
72
  def regexp
159
73
  /^\s* (?:w(?:here)?|bt|backtrace) \s*$/x
160
74
  end
@@ -169,22 +83,36 @@ module Byebug
169
83
  end
170
84
 
171
85
  def description
172
- %(w[here]|bt|backtrace Display stack frames.
86
+ prettify <<-EOD
87
+ w[here]|bt|backtrace Display stack frames.
173
88
 
174
89
  Print the entire stack frame. Each frame is numbered; the most recent
175
90
  frame is 0. A frame number can be referred to in the "frame" command;
176
91
  "up" and "down" add or subtract respectively to frame numbers shown.
177
92
  The position of the current frame is marked with -->. C-frames hang
178
93
  from their most immediate Ruby frame to indicate that they are not
179
- navigable.)
94
+ navigable.
95
+ EOD
180
96
  end
181
97
  end
98
+
99
+ private
100
+
101
+ def print_backtrace
102
+ bt = prc('frame.line', (0...@state.context.stack_size)) do |_, index|
103
+ get_pr_arguments(index)
104
+ end
105
+
106
+ print(bt)
107
+ end
182
108
  end
183
109
 
184
110
  #
185
111
  # Move the current frame up in the backtrace.
186
112
  #
187
113
  class UpCommand < Command
114
+ include FrameFunctions
115
+
188
116
  def regexp
189
117
  /^\s* u(?:p)? (?:\s+(\S+))? \s*$/x
190
118
  end
@@ -202,7 +130,9 @@ module Byebug
202
130
  end
203
131
 
204
132
  def description
205
- %(up[ count] Move to higher frame.)
133
+ prettify <<-EOD
134
+ up[ count] Move to higher frame.
135
+ EOD
206
136
  end
207
137
  end
208
138
  end
@@ -211,6 +141,8 @@ module Byebug
211
141
  # Move the current frame down in the backtrace.
212
142
  #
213
143
  class DownCommand < Command
144
+ include FrameFunctions
145
+
214
146
  def regexp
215
147
  /^\s* down (?:\s+(\S+))? \s*$/x
216
148
  end
@@ -228,7 +160,9 @@ module Byebug
228
160
  end
229
161
 
230
162
  def description
231
- %(down[ count] Move to lower frame.)
163
+ prettify <<-EOD
164
+ down[ count] Move to lower frame.
165
+ EOD
232
166
  end
233
167
  end
234
168
  end
@@ -237,12 +171,17 @@ module Byebug
237
171
  # Move to specific frames in the backtrace.
238
172
  #
239
173
  class FrameCommand < Command
174
+ include FrameFunctions
175
+
240
176
  def regexp
241
177
  /^\s* f(?:rame)? (?:\s+(\S+))? \s*$/x
242
178
  end
243
179
 
244
180
  def execute
245
- return print_frame @state.frame_pos unless @match[1]
181
+ unless @match[1]
182
+ print(pr('frame.line', get_pr_arguments(@state.frame)))
183
+ return
184
+ end
246
185
 
247
186
  pos, err = get_int(@match[1], 'Frame')
248
187
  return errmsg(err) unless pos
@@ -256,7 +195,8 @@ module Byebug
256
195
  end
257
196
 
258
197
  def description
259
- %(f[rame][ frame-number]
198
+ prettify <<-EOD
199
+ f[rame][ frame-number]
260
200
 
261
201
  Move the current frame to the specified frame number, or the 0 if no
262
202
  frame-number has been given.
@@ -267,7 +207,8 @@ module Byebug
267
207
 
268
208
  Without an argument, the command prints the current stack frame. Since
269
209
  the current position is redisplayed, it may trigger a resyncronization
270
- if there is a front end also watching over things.)
210
+ if there is a front end also watching over things.
211
+ EOD
271
212
  end
272
213
  end
273
214
  end