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
data/README.md CHANGED
@@ -2,19 +2,16 @@
2
2
 
3
3
  [![Ver][gem]][gem_url]
4
4
  [![Gpa][gpa]][gpa_url]
5
- [![Dep][dep]][dep_url]
6
5
  [![Cov][cov]][cov_url]
7
6
  [![Git][tip]][tip_url]
8
7
 
9
8
  [gem]: https://img.shields.io/gem/v/byebug.svg
10
9
  [gpa]: https://img.shields.io/codeclimate/github/deivid-rodriguez/byebug.svg
11
- [dep]: https://img.shields.io/gemnasium/deivid-rodriguez/byebug.svg
12
10
  [cov]: https://img.shields.io/codeclimate/coverage/github/deivid-rodriguez/byebug.svg
13
11
  [tip]: https://img.shields.io/gittip/deivid-rodriguez.svg
14
12
 
15
13
  [gem_url]: https://rubygems.org/gems/byebug
16
14
  [gpa_url]: https://codeclimate.com/github/deivid-rodriguez/byebug
17
- [dep_url]: https://gemnasium.com/deivid-rodriguez/byebug
18
15
  [cov_url]: https://codeclimate.com/github/deivid-rodriguez/byebug
19
16
  [tip_url]: https://www.gittip.com/deivid-rodriguez
20
17
 
@@ -92,7 +89,6 @@ are debugging rails, start the server and once the execution gets to your
92
89
  `down` | |
93
90
  `edit` | |
94
91
  `enable` | | `breakpoints` `display`
95
- `eval` | |
96
92
  `finish` | |
97
93
  `frame` | |
98
94
  `help` | |
@@ -103,15 +99,13 @@ are debugging rails, start the server and once the execution gets to your
103
99
  `list` | |
104
100
  `method` | | `instance`
105
101
  `next` | |
106
- `pp` | |
107
102
  `pry` | |
108
103
  `ps` | |
109
- `putl` | |
110
- `quit` | `exit` |
104
+ `quit` | |
111
105
  `restart` | |
112
106
  `save` | |
113
- `set` | | `autoeval` `autoirb` `autolist` `autosave` `basename` `callstyle` `fullpath` `histfile` `histsize` `linetrace` `listsize` `post_mortem` `savefile` `stack_on_error` `verbose` `width`
114
- `show` | | `autoeval` `autoirb` `autolist` `autosave` `basename` `callstyle` `fullpath` `histfile` `histsize` `linetrace` `listsize` `post_mortem` `savefile` `stack_on_error` `verbose` `width`
107
+ `set` | | `autoirb` `autolist` `autosave` `basename` `callstyle` `fullpath` `histfile` `histsize` `linetrace` `listsize` `post_mortem` `savefile` `stack_on_error` `width`
108
+ `show` | | `autoirb` `autolist` `autosave` `basename` `callstyle` `fullpath` `histfile` `histsize` `linetrace` `listsize` `post_mortem` `savefile` `stack_on_error` `width`
115
109
  `source` | |
116
110
  `step` | |
117
111
  `thread` | | `current` `list` `resume` `stop` `switch`
@@ -154,10 +148,10 @@ See [Getting Started with Development](CONTRIBUTING.md).
154
148
  ## Credits
155
149
 
156
150
  Everybody who has ever contributed to this forked and reforked piece of
157
- software, specially:
151
+ software, especially:
158
152
 
159
153
  * @ko1, author of the awesome TracePoint API for Ruby.
160
- * @cldwalker, [debugger][]'s mantainer.
154
+ * @cldwalker, [debugger][]'s maintainer.
161
155
  * @denofevil, author of [debase][], the starting point of this.
162
156
  * @kevjames3 for testing, bug reports and the interest in the project.
163
157
  * @FooBarWidget for working and helping with remote debugging.
@@ -357,8 +357,7 @@ raw_return_event(VALUE trace_point, void *data)
357
357
  static void
358
358
  raise_event(VALUE trace_point, void *data)
359
359
  {
360
- VALUE expn_class, ancestors;
361
- VALUE path, lineno, binding, post_mortem_context;
360
+ VALUE expn_class, ancestors, path, lineno, pm_context;
362
361
  int i;
363
362
  debug_context_t *new_dc;
364
363
 
@@ -366,19 +365,14 @@ raise_event(VALUE trace_point, void *data)
366
365
 
367
366
  path = rb_tracearg_path(trace_arg);
368
367
  lineno = rb_tracearg_lineno(trace_arg);
369
- binding = rb_tracearg_binding(trace_arg);
370
368
  raised_exception = rb_tracearg_raised_exception(trace_arg);
371
369
 
372
370
  if (post_mortem == Qtrue)
373
371
  {
374
- post_mortem_context = context_dup(dc);
375
- rb_ivar_set(raised_exception, rb_intern("@__bb_file"), path);
376
- rb_ivar_set(raised_exception, rb_intern("@__bb_line"), lineno);
377
- rb_ivar_set(raised_exception, rb_intern("@__bb_binding"), binding);
378
- rb_ivar_set(raised_exception, rb_intern("@__bb_context"),
379
- post_mortem_context);
380
-
381
- Data_Get_Struct(post_mortem_context, debug_context_t, new_dc);
372
+ pm_context = context_dup(dc);
373
+ rb_ivar_set(raised_exception, rb_intern("@__bb_context"), pm_context);
374
+
375
+ Data_Get_Struct(pm_context, debug_context_t, new_dc);
382
376
  rb_debug_inspector_open(context_backtrace_set, (void *)new_dc);
383
377
  }
384
378
 
@@ -655,36 +649,6 @@ Debug_load(int argc, VALUE * argv, VALUE self)
655
649
  return status;
656
650
  }
657
651
 
658
- /*
659
- * call-seq:
660
- * Byebug.verbose? -> bool
661
- *
662
- * Returns +true+ if verbose output of TracePoint API events is enabled.
663
- */
664
- static VALUE
665
- Verbose(VALUE self)
666
- {
667
- UNUSED(self);
668
-
669
- return verbose;
670
- }
671
-
672
- /*
673
- * call-seq:
674
- * Byebug.verbose = bool
675
- *
676
- * Enable verbose output of every TracePoint API events, useful for debugging
677
- * byebug.
678
- */
679
- static VALUE
680
- Set_verbose(VALUE self, VALUE value)
681
- {
682
- UNUSED(self);
683
-
684
- verbose = RTEST(value) ? Qtrue : Qfalse;
685
- return value;
686
- }
687
-
688
652
  /*
689
653
  * call-seq:
690
654
  * Byebug.tracing? -> bool
@@ -789,8 +753,6 @@ Init_byebug()
789
753
  rb_define_module_function(mByebug, "thread_context", Thread_context, 1);
790
754
  rb_define_module_function(mByebug, "tracing?", Tracing, 0);
791
755
  rb_define_module_function(mByebug, "tracing=", Set_tracing, 1);
792
- rb_define_module_function(mByebug, "verbose?", Verbose, 0);
793
- rb_define_module_function(mByebug, "verbose=", Set_verbose, 1);
794
756
 
795
757
  Init_threads_table(mByebug);
796
758
  Init_context(mByebug);
@@ -45,7 +45,12 @@ typedef struct {
45
45
  VALUE backtrace; /* [[loc, self, klass, binding], ...] */
46
46
  } debug_context_t;
47
47
 
48
- enum frame_component { LOCATION, SELF, CLASS, BINDING };
48
+ typedef enum {
49
+ LOCATION,
50
+ SELF,
51
+ CLASS,
52
+ BINDING
53
+ } frame_part;
49
54
 
50
55
  struct call_with_inspection_data {
51
56
  debug_context_t *dc;
@@ -90,8 +90,7 @@ context_dup(debug_context_t * context)
90
90
 
91
91
 
92
92
  static VALUE
93
- dc_frame_get(const debug_context_t * context, int frame_index,
94
- enum frame_component type)
93
+ dc_frame_get(const debug_context_t * context, int frame_index, frame_part type)
95
94
  {
96
95
  VALUE frame;
97
96
 
@@ -257,7 +256,7 @@ Context_frame_file(int argc, VALUE * argv, VALUE self)
257
256
  * call-seq:
258
257
  * context.frame_line(frame_position = 0) -> int
259
258
  *
260
- * Returns the line number in the file.
259
+ * Returns the line number in the file in the frame.
261
260
  */
262
261
  static VALUE
263
262
  Context_frame_line(int argc, VALUE * argv, VALUE self)
@@ -275,7 +274,7 @@ Context_frame_line(int argc, VALUE * argv, VALUE self)
275
274
  * call-seq:
276
275
  * context.frame_method(frame_position = 0) -> sym
277
276
  *
278
- * Returns the sym of the called method.
277
+ * Returns the sym of the method in the frame.
279
278
  */
280
279
  static VALUE
281
280
  Context_frame_method(int argc, VALUE * argv, VALUE self)
@@ -640,7 +639,7 @@ dt_inherited(VALUE klass)
640
639
  *
641
640
  * == Summary
642
641
  *
643
- * Byebug keeps a single instance of this class.
642
+ * Byebug keeps a single instance of this class per thread.
644
643
  */
645
644
  void
646
645
  Init_context(VALUE mByebug)
@@ -1,4 +1,3 @@
1
- require 'columnize'
2
1
  require 'forwardable'
3
2
  require 'byebug/helpers/string'
4
3
 
@@ -6,78 +5,68 @@ module Byebug
6
5
  #
7
6
  # Parent class of all byebug commands.
8
7
  #
9
- # Subclasses need to implement a `regexp` method and an `execute` method.
8
+ # Subclass it and name the subclass ending with the word Command to implement
9
+ # your own custom command.
10
+ #
11
+ # @example
12
+ #
13
+ # class MyCustomCommand < Command
14
+ # def self.regexp
15
+ # /custom_regexp/
16
+ # end
17
+ #
18
+ # def self.description
19
+ # 'Custom long desc'
20
+ # end
21
+ #
22
+ # def.short_description
23
+ # 'Custom short desc'
24
+ # end
25
+ #
26
+ # def execute
27
+ # # My command's implementation
28
+ # end
29
+ # end
10
30
  #
11
31
  class Command
12
32
  extend Forwardable
13
33
 
14
- include Helpers::StringHelper
34
+ attr_reader :processor
15
35
 
16
- def initialize(state)
17
- @match = nil
18
- @state = state
36
+ def initialize(processor, input = self.class.to_s)
37
+ @processor = processor
38
+ @match = match(input)
19
39
  end
20
40
 
21
- def match(input)
22
- @match = regexp.match(input)
41
+ def context
42
+ @context ||= processor.context
23
43
  end
24
44
 
25
- def_delegators :'self.class', :to_name, :description
26
-
27
- #
28
- # Default help text for a command.
29
- #
30
- def help
31
- prettify(description)
45
+ def frame
46
+ @frame ||= context.frame
32
47
  end
33
48
 
34
- def_delegator :"Byebug.printer", :print, :pr
35
- def_delegator :"Byebug.printer", :print_collection, :prc
36
- def_delegator :"Byebug.printer", :print_variables, :prv
37
-
38
- protected
39
-
40
- def_delegators :@state, :errmsg, :puts, :print, :confirm
41
-
42
- #
43
- # Evaluates a string containing Ruby code, using binding +b+. In case of
44
- # error full stack trace and error are printed.
45
- #
46
- def bb_eval(str, b = get_binding)
47
- b.eval(str)
48
- rescue StandardError, ScriptError => e
49
- at = e.backtrace
50
- locations = []
51
- locations << "#{at.shift}: #{e.class} Exception(#{e.message})"
52
- locations += at.map { |path| "\tfrom #{path}" }
53
-
54
- errmsg(pr('eval.exception', text_message: locations.join("\n")))
55
- nil
49
+ def arguments
50
+ @match[0].split(' ').drop(1).join(' ')
56
51
  end
57
52
 
58
- #
59
- # Evaluates a string containing Ruby code, using binding +b+. In case of
60
- # error, an error message with the exception is printed.
61
- #
62
- def bb_warning_eval(str, b = get_binding)
63
- b.eval(str)
64
- rescue StandardError, ScriptError => e
65
- text_message = "#{e.class} Exception: #{e.message}"
66
- errmsg(pr('eval.exception', text_message: text_message))
67
- nil
68
- end
53
+ def_delegators :'self.class', :help, :match
69
54
 
70
- def get_binding(pos = @state.frame)
71
- @state.context ? @state.context.frame_binding(pos) : TOPLEVEL_BINDING
72
- end
55
+ def_delegator :'processor.printer', :print, :pr
56
+ def_delegator :'processor.printer', :print_collection, :prc
57
+ def_delegator :'processor.printer', :print_variables, :prv
58
+
59
+ def_delegators :'processor.interface', :errmsg, :puts, :print, :confirm
73
60
 
74
61
  class << self
75
- attr_accessor :allow_in_control
76
- attr_writer :allow_in_post_mortem, :always_run
62
+ include Helpers::StringHelper
77
63
 
78
- def allow_in_post_mortem
79
- !defined?(@allow_in_post_mortem) ? true : false
80
- end
64
+ #
65
+ # Special methods to allow command filtering in processors
66
+ #
67
+ attr_accessor :allow_in_control, :allow_in_post_mortem
68
+
69
+ attr_writer :always_run
81
70
 
82
71
  def always_run
83
72
  @always_run ||= 0
@@ -86,19 +75,30 @@ module Byebug
86
75
  #
87
76
  # Name of the command, as executed by the user.
88
77
  #
89
- def to_name
90
- name.gsub(/^Byebug::/, '').gsub(/Command$/, '').downcase
78
+ def to_s
79
+ name
80
+ .split('::')
81
+ .map { |n| n.gsub(/Command$/, '').downcase if n =~ /Command$/ }
82
+ .compact
83
+ .join(' ')
84
+ end
85
+
86
+ def columnize(width)
87
+ format(" %-#{width}s -- %s\n", to_s, short_description)
91
88
  end
92
89
 
93
90
  #
94
- # Available subcommands for the current command
95
- #
96
- # A subcommand is any class defined inside the parent's command class
91
+ # Default help text for a command.
97
92
  #
98
- def subcommands
99
- const_list = constants(false).map { |const| const_get(const, false) }
93
+ def help
94
+ prettify(description)
95
+ end
100
96
 
101
- const_list.select { |c| c.is_a?(Class) }
97
+ #
98
+ # Command's regexp match against an input
99
+ #
100
+ def match(input)
101
+ regexp.match(input)
102
102
  end
103
103
  end
104
104
  end
@@ -0,0 +1,32 @@
1
+ require 'byebug/errors'
2
+
3
+ module Byebug
4
+ #
5
+ # Holds an array of subcommands for a command
6
+ #
7
+ class CommandList
8
+ include Enumerable
9
+
10
+ def initialize(commands)
11
+ @commands = commands.sort_by(&:to_s)
12
+ end
13
+
14
+ def match(input)
15
+ find { |cmd| cmd.match(input) }
16
+ end
17
+
18
+ def each
19
+ @commands.each { |cmd| yield(cmd) }
20
+ end
21
+
22
+ def to_s
23
+ "\n" + map { |cmd| cmd.columnize(width) }.join + "\n"
24
+ end
25
+
26
+ private
27
+
28
+ def width
29
+ @width ||= map(&:to_s).max_by(&:size).size
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ require 'byebug/commands/break'
2
+ require 'byebug/commands/catch'
3
+ require 'byebug/commands/condition'
4
+ require 'byebug/commands/continue'
5
+ require 'byebug/commands/delete'
6
+ require 'byebug/commands/disable'
7
+ require 'byebug/commands/display'
8
+ require 'byebug/commands/down'
9
+ require 'byebug/commands/edit'
10
+ require 'byebug/commands/enable'
11
+ require 'byebug/commands/finish'
12
+ require 'byebug/commands/frame'
13
+ require 'byebug/commands/help'
14
+ require 'byebug/commands/history'
15
+ require 'byebug/commands/info'
16
+ require 'byebug/commands/interrupt'
17
+ require 'byebug/commands/irb'
18
+ require 'byebug/commands/kill'
19
+ require 'byebug/commands/list'
20
+ require 'byebug/commands/method'
21
+ require 'byebug/commands/next'
22
+ require 'byebug/commands/pry'
23
+ require 'byebug/commands/ps'
24
+ require 'byebug/commands/quit'
25
+ require 'byebug/commands/restart'
26
+ require 'byebug/commands/save'
27
+ require 'byebug/commands/set'
28
+ require 'byebug/commands/show'
29
+ require 'byebug/commands/source'
30
+ require 'byebug/commands/step'
31
+ require 'byebug/commands/thread'
32
+ require 'byebug/commands/tracevar'
33
+ require 'byebug/commands/undisplay'
34
+ require 'byebug/commands/untracevar'
35
+ require 'byebug/commands/up'
36
+ require 'byebug/commands/var'
37
+ require 'byebug/commands/where'
@@ -1,4 +1,5 @@
1
1
  require 'byebug/command'
2
+ require 'byebug/helpers/eval'
2
3
  require 'byebug/helpers/file'
3
4
  require 'byebug/helpers/parse'
4
5
 
@@ -7,16 +8,32 @@ module Byebug
7
8
  # Implements breakpoint functionality
8
9
  #
9
10
  class BreakCommand < Command
11
+ include Helpers::EvalHelper
10
12
  include Helpers::FileHelper
11
13
  include Helpers::ParseHelper
12
14
 
13
- self.allow_in_post_mortem = false
14
15
  self.allow_in_control = true
15
16
 
16
- def regexp
17
+ def self.regexp
17
18
  /^\s* b(?:reak)? (?:\s+ (\S+))? (?:\s+ if \s+(.+))? \s*$/x
18
19
  end
19
20
 
21
+ def self.description
22
+ <<-EOD
23
+ b[reak] [file:]line [if expr]
24
+ b[reak] [module::...]class(.|#)method [if expr]
25
+
26
+ They can be specified by line or method and an expression can be added
27
+ for conditionally enabled breakpoints.
28
+
29
+ #{short_description}
30
+ EOD
31
+ end
32
+
33
+ def self.short_description
34
+ 'Sets breakpoints in the source code'
35
+ end
36
+
20
37
  def execute
21
38
  return puts(help) unless @match[1]
22
39
 
@@ -28,62 +45,53 @@ module Byebug
28
45
 
29
46
  errmsg(pr('break.errors.expression', expr: @match[2]))
30
47
  b.enabled = false
31
- rescue => e
32
- errmsg(e.message)
33
- end
34
-
35
- def short_description
36
- 'Set breakpoint to some position, (optionally) if expr == true'
37
- end
38
-
39
- def description
40
- <<-EOD
41
- b[reak] [file:]line [if expr]
42
- b[reak] [module::...]class(.|#)method [if expr]
43
-
44
- #{short_description}
45
- EOD
46
48
  end
47
49
 
48
50
  private
49
51
 
50
- def line_breakpoint(loc)
51
- line = loc.match(/^(\d+)$/)
52
- file_line = loc.match(/^([^:]+):(\d+)$/)
53
- return nil unless line || file_line
52
+ def line_breakpoint(location)
53
+ line_match = location.match(/^(\d+)$/)
54
+ file_line_match = location.match(/^([^:]+):(\d+)$/)
55
+ return unless line_match || file_line_match
54
56
 
55
- f, l = line ? [@state.file, line[1]] : [file_line[1], file_line[2]]
57
+ file = line_match ? frame.file : file_line_match[1]
58
+ line = line_match ? line_match[1].to_i : file_line_match[2].to_i
56
59
 
57
- check_errors(f, l.to_i)
58
-
59
- Breakpoint.add(File.expand_path(f), l.to_i, @match[2])
60
+ add_line_breakpoint(file, line)
60
61
  end
61
62
 
62
63
  def method_breakpoint(location)
63
64
  location.match(/([^.#]+)[.#](.+)/) do |match|
64
- k = bb_warning_eval(match[1])
65
- m = match[2]
66
-
67
- klass = k && k.is_a?(Module) ? k.name : match[1]
68
- method = m.intern
65
+ klass = target_object(match[1])
66
+ method = match[2].intern
69
67
 
70
68
  Breakpoint.add(klass, method, @match[2])
71
69
  end
72
70
  end
73
71
 
74
- def check_errors(file, line)
75
- path = File.expand_path(file)
76
- deco_path = normalize(file)
72
+ def target_object(str)
73
+ k = warning_eval(str)
74
+
75
+ k && k.is_a?(Module) ? k.name : str
76
+ rescue
77
+ errmsg('Warning: breakpoint source is not yet defined')
78
+ str
79
+ end
80
+
81
+ def add_line_breakpoint(file, line)
82
+ fail(pr('break.errors.source', file: file)) unless File.exist?(file)
77
83
 
78
- fail(pr('break.errors.source', file: deco_path)) unless File.exist?(path)
84
+ fullpath = File.realpath(file)
79
85
 
80
86
  if line > n_lines(file)
81
- fail(pr('break.errors.far_line', lines: n_lines(file), file: deco_path))
87
+ fail(pr('break.errors.far_line', lines: n_lines(file), file: fullpath))
82
88
  end
83
89
 
84
- return if Breakpoint.potential_line?(path, line)
90
+ unless Breakpoint.potential_line?(fullpath, line)
91
+ fail(pr('break.errors.line', file: fullpath, line: line))
92
+ end
85
93
 
86
- fail(pr('break.errors.line', file: deco_path, line: line))
94
+ Breakpoint.add(fullpath, line, @match[2])
87
95
  end
88
96
  end
89
97
  end