byebug 5.0.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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