byebug 5.0.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/CONTRIBUTING.md +35 -13
  4. data/GUIDE.md +256 -198
  5. data/README.md +5 -11
  6. data/ext/byebug/byebug.c +5 -43
  7. data/ext/byebug/byebug.h +6 -1
  8. data/ext/byebug/context.c +4 -5
  9. data/lib/byebug/command.rb +64 -64
  10. data/lib/byebug/command_list.rb +32 -0
  11. data/lib/byebug/commands.rb +37 -0
  12. data/lib/byebug/commands/break.rb +45 -37
  13. data/lib/byebug/commands/catch.rb +52 -28
  14. data/lib/byebug/commands/condition.rb +19 -13
  15. data/lib/byebug/commands/continue.rb +15 -11
  16. data/lib/byebug/commands/delete.rb +18 -12
  17. data/lib/byebug/commands/disable.rb +9 -10
  18. data/lib/byebug/commands/disable/breakpoints.rb +13 -11
  19. data/lib/byebug/commands/disable/display.rb +13 -11
  20. data/lib/byebug/commands/display.rb +32 -24
  21. data/lib/byebug/commands/down.rb +18 -14
  22. data/lib/byebug/commands/edit.rb +42 -26
  23. data/lib/byebug/commands/enable.rb +9 -3
  24. data/lib/byebug/commands/enable/breakpoints.rb +13 -11
  25. data/lib/byebug/commands/enable/display.rb +13 -11
  26. data/lib/byebug/commands/finish.rb +23 -14
  27. data/lib/byebug/commands/frame.rb +21 -18
  28. data/lib/byebug/commands/help.rb +39 -16
  29. data/lib/byebug/commands/history.rb +16 -10
  30. data/lib/byebug/commands/info.rb +8 -5
  31. data/lib/byebug/commands/info/breakpoints.rb +16 -14
  32. data/lib/byebug/commands/info/display.rb +18 -18
  33. data/lib/byebug/commands/info/file.rb +22 -22
  34. data/lib/byebug/commands/info/line.rb +13 -11
  35. data/lib/byebug/commands/info/program.rb +13 -17
  36. data/lib/byebug/commands/interrupt.rb +13 -11
  37. data/lib/byebug/commands/irb.rb +16 -10
  38. data/lib/byebug/commands/kill.rb +19 -13
  39. data/lib/byebug/commands/list.rb +35 -24
  40. data/lib/byebug/commands/method.rb +25 -15
  41. data/lib/byebug/commands/next.rb +15 -13
  42. data/lib/byebug/commands/pry.rb +18 -11
  43. data/lib/byebug/commands/ps.rb +21 -23
  44. data/lib/byebug/commands/quit.rb +17 -11
  45. data/lib/byebug/commands/restart.rb +28 -24
  46. data/lib/byebug/commands/save.rb +23 -15
  47. data/lib/byebug/commands/set.rb +26 -19
  48. data/lib/byebug/commands/show.rb +20 -14
  49. data/lib/byebug/commands/source.rb +15 -14
  50. data/lib/byebug/commands/step.rb +15 -13
  51. data/lib/byebug/commands/thread.rb +8 -4
  52. data/lib/byebug/commands/thread/current.rb +11 -11
  53. data/lib/byebug/commands/thread/list.rb +14 -14
  54. data/lib/byebug/commands/thread/resume.rb +14 -14
  55. data/lib/byebug/commands/thread/stop.rb +14 -14
  56. data/lib/byebug/commands/thread/switch.rb +15 -14
  57. data/lib/byebug/commands/tracevar.rb +20 -16
  58. data/lib/byebug/commands/undisplay.rb +22 -18
  59. data/lib/byebug/commands/untracevar.rb +13 -11
  60. data/lib/byebug/commands/up.rb +18 -14
  61. data/lib/byebug/commands/var.rb +10 -3
  62. data/lib/byebug/commands/var/all.rb +15 -13
  63. data/lib/byebug/commands/var/args.rb +37 -0
  64. data/lib/byebug/commands/var/const.rb +25 -14
  65. data/lib/byebug/commands/var/global.rb +13 -11
  66. data/lib/byebug/commands/var/instance.rb +13 -11
  67. data/lib/byebug/commands/var/local.rb +13 -11
  68. data/lib/byebug/commands/where.rb +15 -11
  69. data/lib/byebug/context.rb +71 -73
  70. data/lib/byebug/core.rb +45 -26
  71. data/lib/byebug/errors.rb +27 -0
  72. data/lib/byebug/frame.rb +181 -0
  73. data/lib/byebug/helpers/eval.rb +67 -26
  74. data/lib/byebug/helpers/file.rb +18 -3
  75. data/lib/byebug/helpers/frame.rb +36 -39
  76. data/lib/byebug/helpers/parse.rb +15 -13
  77. data/lib/byebug/helpers/path.rb +21 -0
  78. data/lib/byebug/helpers/reflection.rb +17 -0
  79. data/lib/byebug/helpers/thread.rb +20 -14
  80. data/lib/byebug/helpers/toggle.rb +10 -5
  81. data/lib/byebug/helpers/var.rb +36 -15
  82. data/lib/byebug/interface.rb +27 -9
  83. data/lib/byebug/option_setter.rb +93 -0
  84. data/lib/byebug/printers/base.rb +3 -0
  85. data/lib/byebug/printers/plain.rb +4 -14
  86. data/lib/byebug/printers/texts/base.yml +2 -7
  87. data/lib/byebug/processors/command_processor.rb +101 -102
  88. data/lib/byebug/processors/control_processor.rb +20 -0
  89. data/lib/byebug/processors/post_mortem_processor.rb +16 -0
  90. data/lib/byebug/processors/script_processor.rb +49 -0
  91. data/lib/byebug/remote.rb +13 -7
  92. data/lib/byebug/runner.rb +39 -65
  93. data/lib/byebug/setting.rb +4 -1
  94. data/lib/byebug/settings/post_mortem.rb +0 -16
  95. data/lib/byebug/settings/savefile.rb +1 -4
  96. data/lib/byebug/subcommands.rb +27 -29
  97. data/lib/byebug/version.rb +4 -1
  98. metadata +14 -29
  99. data/lib/byebug/commands/eval.rb +0 -43
  100. data/lib/byebug/commands/info/args.rb +0 -39
  101. data/lib/byebug/commands/info/catch.rb +0 -39
  102. data/lib/byebug/commands/pp.rb +0 -41
  103. data/lib/byebug/commands/putl.rb +0 -43
  104. data/lib/byebug/processor.rb +0 -43
  105. data/lib/byebug/processors/control_command_processor.rb +0 -48
  106. data/lib/byebug/settings/verbose.rb +0 -20
  107. data/lib/byebug/state.rb +0 -12
  108. data/lib/byebug/states/control_state.rb +0 -26
  109. data/lib/byebug/states/regular_state.rb +0 -187
  110. data/lib/byebug/subcommand_list.rb +0 -33
@@ -1,4 +1,5 @@
1
1
  require 'byebug/command'
2
+ require 'byebug/helpers/eval'
2
3
 
3
4
  module Byebug
4
5
  #
@@ -7,50 +8,73 @@ module Byebug
7
8
  # Enables the user to catch unhandled assertion when they happen.
8
9
  #
9
10
  class CatchCommand < Command
10
- def regexp
11
+ include Helpers::EvalHelper
12
+
13
+ self.allow_in_post_mortem = true
14
+
15
+ def self.regexp
11
16
  /^\s* cat(?:ch)? (?:\s+(\S+))? (?:\s+(off))? \s*$/x
12
17
  end
13
18
 
19
+ def self.description
20
+ <<-EOD
21
+ cat[ch][ (off|<exception>[ off])]
22
+
23
+ #{short_description}
24
+
25
+ catch -- lists catchpoints
26
+ catch off -- deletes all catchpoints
27
+ catch <exception> -- enables handling <exception>
28
+ catch <exception> off -- disables handling <exception>
29
+ EOD
30
+ end
31
+
32
+ def self.short_description
33
+ 'Handles exception catchpoints'
34
+ end
35
+
14
36
  def execute
15
- ex = @match[1]
16
- return info_catch unless ex
37
+ return info unless @match[1]
17
38
 
18
- cmd = @match[2]
19
- unless cmd
20
- if 'off' == ex
21
- Byebug.catchpoints.clear if
22
- confirm(pr('catch.confirmations.delete_all'))
39
+ return 'off' == @match[1] ? clear : add(@match[1]) unless @match[2]
23
40
 
24
- return
25
- end
41
+ return errmsg pr('catch.errors.off', off: cmd) unless @match[2] == 'off'
42
+
43
+ remove(@match[1])
44
+ end
26
45
 
27
- is_class = bb_eval("#{ex.is_a?(Class)}")
28
- puts pr('catch.errors.not_class', class: ex) unless is_class
46
+ private
29
47
 
30
- Byebug.add_catchpoint(ex)
31
- return puts pr('catch.catching', exception: ex)
48
+ def remove(exception)
49
+ unless Byebug.catchpoints.member?(exception)
50
+ return errmsg pr('catch.errors.not_found', exception: exception)
32
51
  end
33
52
 
34
- if cmd == 'off'
35
- exists = Byebug.catchpoints.member?(ex)
36
- return errmsg pr('catch.errors.not_found', exception: ex) unless exists
53
+ puts pr('catch.removed', exception: exception)
54
+ Byebug.catchpoints.delete(exception)
55
+ end
37
56
 
38
- Byebug.catchpoints.delete(ex)
39
- return errmsg pr('catch.errors.removed', exception: ex)
57
+ def add(exception)
58
+ if single_thread_eval("#{exception.is_a?(Class)}")
59
+ errmsg pr('catch.errors.not_class', class: exception)
40
60
  end
41
61
 
42
- errmsg pr('catch.errors.off', off: cmd)
62
+ puts pr('catch.added', exception: exception)
63
+ Byebug.add_catchpoint(exception)
43
64
  end
44
65
 
45
- def description
46
- <<-EOD
47
- cat[ch][ (off|<exception>[ off])]
66
+ def clear
67
+ Byebug.catchpoints.clear if confirm(pr('catch.confirmations.delete_all'))
68
+ end
48
69
 
49
- "catch" lists catchpoints.
50
- "catch off" deletes all catchpoints.
51
- "catch <exception>" enables handling <exception>.
52
- "catch <exception> off" disables handling <exception>.
53
- EOD
70
+ def info
71
+ if Byebug.catchpoints && !Byebug.catchpoints.empty?
72
+ Byebug.catchpoints.each do |exception, _hits|
73
+ puts("#{exception}: #{exception.is_a?(Class)}")
74
+ end
75
+ else
76
+ puts 'No exceptions set to be caught.'
77
+ end
54
78
  end
55
79
  end
56
80
  end
@@ -10,12 +10,29 @@ module Byebug
10
10
  class ConditionCommand < Command
11
11
  include Helpers::ParseHelper
12
12
 
13
- self.allow_in_post_mortem = false
13
+ self.allow_in_post_mortem = true
14
14
 
15
- def regexp
15
+ def self.regexp
16
16
  /^\s* cond(?:ition)? (?:\s+(\d+)(?:\s+(.*))?)? \s*$/x
17
17
  end
18
18
 
19
+ def self.description
20
+ <<-EOD
21
+ cond[ition] <n>[ expr]
22
+
23
+ #{short_description}
24
+
25
+ Specify breakpoint number <n> to break only if <expr> is true. <n> is
26
+ an integer and <expr> is an expression to be evaluated whenever
27
+ breakpoint <n> is reached. If no expression is specified, the condition
28
+ is removed.
29
+ EOD
30
+ end
31
+
32
+ def self.short_description
33
+ 'Sets conditions on breakpoints'
34
+ end
35
+
19
36
  def execute
20
37
  return puts(help) unless @match[1]
21
38
 
@@ -34,16 +51,5 @@ module Byebug
34
51
 
35
52
  breakpoint.expr = @match[2]
36
53
  end
37
-
38
- def description
39
- <<-EOD
40
- cond[ition] <n>[ expr]
41
-
42
- Specify breakpoint number <n> to break only if <expr> is true. <n> is
43
- an integer and <expr> is an expression to be evaluated whenever
44
- breakpoint <n> is reached. If no expression is specified, the condition
45
- is removed.
46
- EOD
47
- end
48
54
  end
49
55
  end
@@ -11,16 +11,28 @@ module Byebug
11
11
  class ContinueCommand < Command
12
12
  include Helpers::ParseHelper
13
13
 
14
- def regexp
14
+ def self.regexp
15
15
  /^\s* c(?:ont(?:inue)?)? (?:\s+(\S+))? \s*$/x
16
16
  end
17
17
 
18
+ def self.description
19
+ <<-EOD
20
+ c[ont[inue]][ <line_number>]
21
+
22
+ #{short_description}
23
+ EOD
24
+ end
25
+
26
+ def self.short_description
27
+ 'Runs until program ends, hits a breakpoint or reaches a line'
28
+ end
29
+
18
30
  def execute
19
31
  if @match[1]
20
32
  num, err = get_int(@match[1], 'Continue', 0, nil)
21
33
  return errmsg(err) unless num
22
34
 
23
- filename = File.expand_path(@state.file)
35
+ filename = File.expand_path(frame.file)
24
36
  unless Breakpoint.potential_line?(filename, num)
25
37
  return errmsg(pr('continue.errors.unstopped_line', line: num))
26
38
  end
@@ -28,15 +40,7 @@ module Byebug
28
40
  Breakpoint.add(filename, num)
29
41
  end
30
42
 
31
- @state.proceed
32
- end
33
-
34
- def description
35
- <<-EOD
36
- c[ont[inue]][ <n>]
37
-
38
- Run until program ends, hits a breakpoint or reaches line <n>.
39
- EOD
43
+ processor.proceed!
40
44
  end
41
45
  end
42
46
  end
@@ -8,20 +8,35 @@ module Byebug
8
8
  class DeleteCommand < Command
9
9
  include Helpers::ParseHelper
10
10
 
11
- self.allow_in_post_mortem = false
12
11
  self.allow_in_control = true
12
+ self.allow_in_post_mortem = true
13
13
 
14
- def regexp
14
+ def self.regexp
15
15
  /^\s* del(?:ete)? (?:\s+(.*))?$/x
16
16
  end
17
17
 
18
+ def self.description
19
+ <<-EOD
20
+ del[ete][ nnn...]
21
+
22
+ #{short_description}
23
+
24
+ Without and argument, deletes all breakpoints. With integer arguments,
25
+ it deletes specific breakpoints.
26
+ EOD
27
+ end
28
+
29
+ def self.short_description
30
+ 'Deletes breakpoints'
31
+ end
32
+
18
33
  def execute
19
34
  unless @match[1]
20
35
  if confirm(pr('break.confirmations.delete_all'))
21
36
  Byebug.breakpoints.clear
22
37
  end
23
38
 
24
- return nil
39
+ return
25
40
  end
26
41
 
27
42
  @match[1].split(/ +/).each do |number|
@@ -34,14 +49,5 @@ module Byebug
34
49
  end
35
50
  end
36
51
  end
37
-
38
- def description
39
- <<-EOD
40
- del[ete][ nnn...]
41
-
42
- Without and argument, deletes all breakpoints. With integer arguments,
43
- it deletes specific breakpoints.
44
- EOD
45
- end
46
52
  end
47
53
  end
@@ -10,23 +10,22 @@ module Byebug
10
10
  class DisableCommand < Command
11
11
  include Subcommands
12
12
 
13
- def regexp
13
+ self.allow_in_post_mortem = true
14
+
15
+ def self.regexp
14
16
  /^\s* dis(?:able)? (?:\s+ (.+))? \s*$/x
15
17
  end
16
18
 
17
- def description
19
+ def self.description
18
20
  <<-EOD
19
21
  dis[able][[ breakpoints| display)][ n1[ n2[ ...[ nn]]]]]
20
22
 
21
- Disables breakpoints or displays.
22
-
23
- "disable" by itself shows this help
24
- "disable breakpoints" disables all breakpoints.
25
- "disable displays" disables all displays.
26
-
27
- You can also specify a space separated list of breakpoint or display
28
- numbers to disable only specific breakpoints or displays.
23
+ #{short_description}
29
24
  EOD
30
25
  end
26
+
27
+ def self.short_description
28
+ 'Disables breakpoints or displays'
29
+ end
31
30
  end
32
31
  end
@@ -8,22 +8,16 @@ module Byebug
8
8
  #
9
9
  # Disables all or specific breakpoints
10
10
  #
11
- class BreakpointsSubcommand < Command
11
+ class BreakpointsCommand < Command
12
12
  include Helpers::ToggleHelper
13
13
 
14
- def regexp
15
- /^\s* b(?:reakpoints)? (?:\s+ (.+))? \s*$/x
16
- end
17
-
18
- def execute
19
- enable_disable_breakpoints('disable', @match[1])
20
- end
14
+ self.allow_in_post_mortem = true
21
15
 
22
- def short_description
23
- 'Disable all or specific breakpoints.'
16
+ def self.regexp
17
+ /^\s* b(?:reakpoints)? (?:\s+ (.+))? \s*$/x
24
18
  end
25
19
 
26
- def description
20
+ def self.description
27
21
  <<-EOD
28
22
  dis[able] b[reakpoints][ <id1> <id2> .. <idn>]
29
23
 
@@ -33,6 +27,14 @@ module Byebug
33
27
  argument at all if you want to disable every breakpoint.
34
28
  EOD
35
29
  end
30
+
31
+ def self.short_description
32
+ 'Disable all or specific breakpoints.'
33
+ end
34
+
35
+ def execute
36
+ enable_disable_breakpoints('disable', @match[1])
37
+ end
36
38
  end
37
39
  end
38
40
  end
@@ -8,22 +8,16 @@ module Byebug
8
8
  #
9
9
  # Enables all or specific displays
10
10
  #
11
- class DisplaySubcommand < Command
11
+ class DisplayCommand < Command
12
12
  include Helpers::ToggleHelper
13
13
 
14
- def regexp
15
- /^\s* d(?:isplay)? (?:\s+ (.+))? \s*$/x
16
- end
17
-
18
- def execute
19
- enable_disable_display('disable', @match[1])
20
- end
14
+ self.allow_in_post_mortem = true
21
15
 
22
- def short_description
23
- 'Disables expressions to be displayed when program stops.'
16
+ def self.regexp
17
+ /^\s* d(?:isplay)? (?:\s+ (.+))? \s*$/x
24
18
  end
25
19
 
26
- def description
20
+ def self.description
27
21
  <<-EOD
28
22
  dis[able] d[isplay][ <id1> <id2> .. <idn>]
29
23
 
@@ -34,6 +28,14 @@ module Byebug
34
28
  specified, all displays are disabled.
35
29
  EOD
36
30
  end
31
+
32
+ def self.short_description
33
+ 'Disables expressions to be displayed when program stops.'
34
+ end
35
+
36
+ def execute
37
+ enable_disable_display('disable', @match[1])
38
+ end
37
39
  end
38
40
  end
39
41
  end
@@ -1,56 +1,64 @@
1
1
  require 'byebug/command'
2
+ require 'byebug/helpers/eval'
2
3
 
3
4
  module Byebug
4
5
  #
5
6
  # Custom expressions to be displayed every time the debugger stops.
6
7
  #
7
8
  class DisplayCommand < Command
8
- self.allow_in_post_mortem = false
9
+ include Helpers::EvalHelper
9
10
 
10
- def self.always_run
11
- 2
12
- end
11
+ self.allow_in_post_mortem = false
12
+ self.always_run = 2
13
13
 
14
- def regexp
14
+ def self.regexp
15
15
  /^\s* disp(?:lay)? (?:\s+ (.+))? \s*$/x
16
16
  end
17
17
 
18
- def execute
19
- return print_display_expressions unless @match && @match[1]
20
-
21
- @state.display.push [true, @match[1]]
22
- display_expression(@match[1])
23
- end
24
-
25
- def description
18
+ def self.description
26
19
  <<-EOD
27
20
  disp[lay][ <expression>]
28
21
 
22
+ #{short_descripton}
23
+
29
24
  If <expression> specified, adds <expression> into display expression
30
25
  list. Otherwise, it lists all expressions.
31
26
  EOD
32
27
  end
33
28
 
29
+ def self.short_description
30
+ 'Evaluates expressions every time the debugger stops'
31
+ end
32
+
33
+ def execute
34
+ return print_display_expressions unless @match && @match[1]
35
+
36
+ Byebug.displays.push [true, @match[1]]
37
+ display_expression(@match[1])
38
+ end
39
+
34
40
  private
35
41
 
36
42
  def display_expression(exp)
37
- print pr('display.result',
38
- n: @state.display.size,
39
- exp: exp,
40
- result: bb_warning_eval(exp).inspect)
43
+ print pr('display.result', n: Byebug.displays.size,
44
+ exp: exp,
45
+ result: eval_expr(exp))
41
46
  end
42
47
 
43
48
  def print_display_expressions
44
- result = prc('display.result', @state.display) do |item, index|
45
- is_active, expression = item
46
- if is_active
47
- { n: index + 1,
48
- exp: expression,
49
- result: bb_warning_eval(expression).inspect }
50
- end
49
+ result = prc('display.result', Byebug.displays) do |item, index|
50
+ active, exp = item
51
+
52
+ { n: index + 1, exp: exp, result: eval_expr(exp) } if active
51
53
  end
52
54
 
53
55
  print result
54
56
  end
57
+
58
+ def eval_expr(expression)
59
+ thread_safe_eval(expression).inspect
60
+ rescue
61
+ '(undefined)'
62
+ end
55
63
  end
56
64
  end