Skip to content

Commit 6baa2ec

Browse files
committed
fix next/finish/until for duplicate lines
On the code like that: ```ruby foo; bar next_line ``` and breaking at the end of `foo`, `next` command moves to the beggining of `bar`, bit it should be `next_line`. This patch solves this issue.
1 parent f9477c3 commit 6baa2ec

File tree

2 files changed

+79
-25
lines changed

2 files changed

+79
-25
lines changed

lib/debug/thread_client.rb

+35-20
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,7 @@ def wait_next_action_
870870
frame = @target_frames.first
871871
path = frame.location.absolute_path || "!eval:#{frame.path}"
872872
line = frame.location.lineno
873+
label = frame.location.base_label
873874

874875
if frame.iseq
875876
frame.iseq.traceable_lines_norec(lines = {})
@@ -881,23 +882,32 @@ def wait_next_action_
881882

882883
depth = @target_frames.first.frame_depth
883884

884-
step_tp iter do
885+
step_tp iter do |tp|
885886
loc = caller_locations(2, 1).first
886887
loc_path = loc.absolute_path || "!eval:#{loc.path}"
888+
loc_label = loc.base_label
889+
loc_depth = DEBUGGER__.frame_depth - 3
887890

888-
# same stack depth
889-
(DEBUGGER__.frame_depth - 3 <= depth) ||
890-
891-
# different frame
892-
(next_line && loc_path == path &&
893-
(loc_lineno = loc.lineno) > line &&
894-
loc_lineno <= next_line)
891+
case
892+
when loc_depth == depth && loc_label == label
893+
true
894+
when loc_depth < depth
895+
# lower stack depth
896+
true
897+
when (next_line &&
898+
loc_path == path &&
899+
(loc_lineno = loc.lineno) > line &&
900+
loc_lineno <= next_line)
901+
# different frame (maybe block) but the line is before next_line
902+
true
903+
end
895904
end
896905
break
897906

898907
when :finish
899908
finish_frames = (iter || 1) - 1
900-
goal_depth = @target_frames.first.frame_depth - finish_frames
909+
frame = @target_frames.first
910+
goal_depth = frame.frame_depth - finish_frames - (frame.has_return_value ? 1 : 0)
901911

902912
step_tp nil, [:return, :b_return] do
903913
DEBUGGER__.frame_depth - 3 <= goal_depth ? true : false
@@ -907,22 +917,25 @@ def wait_next_action_
907917
when :until
908918
location = iter&.strip
909919
frame = @target_frames.first
910-
depth = frame.frame_depth
920+
depth = frame.frame_depth - (frame.has_return_value ? 1 : 0)
911921
target_location_label = frame.location.base_label
912922

913923
case location
914924
when nil, /\A(?:(.+):)?(\d+)\z/
915-
file = $1
925+
no_loc = !location
926+
file = $1 || frame.location.path
916927
line = ($2 || frame.location.lineno + 1).to_i
917928

918929
step_tp nil, [:line, :return] do |tp|
919930
if tp.event == :line
920-
next true if file && tp.path.end_with?(file)
921-
next true if tp.lineno >= line
931+
next false if no_loc && depth < DEBUGGER__.frame_depth - 3
932+
next false unless tp.path.end_with?(file)
933+
next false unless tp.lineno >= line
934+
true
922935
else
923-
next true if depth >= DEBUGGER__.frame_depth - 3 &&
924-
caller_locations(2, 1).first.label == target_location_label
925-
# TODO: imcomplete condition
936+
true if depth >= DEBUGGER__.frame_depth - 3 &&
937+
caller_locations(2, 1).first.label == target_location_label
938+
# TODO: imcomplete condition
926939
end
927940
end
928941
else
@@ -934,11 +947,11 @@ def wait_next_action_
934947
step_tp nil, [:call, :c_call, :return] do |tp|
935948
case tp.event
936949
when :call, :c_call
937-
next true if pat === tp.callee_id.to_s
950+
true if pat === tp.callee_id.to_s
938951
else # :return, :b_return
939-
next true if depth >= DEBUGGER__.frame_depth - 3 &&
940-
caller_locations(2, 1).first.label == target_location_label
941-
# TODO: imcomplete condition
952+
true if depth >= DEBUGGER__.frame_depth - 3 &&
953+
caller_locations(2, 1).first.label == target_location_label
954+
# TODO: imcomplete condition
942955
end
943956
end
944957
end
@@ -1181,6 +1194,8 @@ def wait_next_action_
11811194
rescue Exception => e
11821195
pp ["DEBUGGER Exception: #{__FILE__}:#{__LINE__}", e, e.backtrace]
11831196
raise
1197+
ensure
1198+
@returning = false
11841199
end
11851200

11861201
def debug_event(ev, args)

test/console/control_flow_commands_test.rb

+44-5
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,19 @@ def test_next_goes_to_the_next_line
8282
end
8383
end
8484

85+
def test_next_skips_method_in_a_same_line
86+
debug_code program do
87+
type 'b 7'
88+
type 'c'
89+
assert_line_num 7
90+
type 'n'
91+
assert_line_num 8
92+
type 'n'
93+
assert_line_num 17
94+
type 'n'
95+
end
96+
end
97+
8598
def test_next_with_number_goes_to_the_next_nth_line
8699
debug_code program do
87100
type 'b 15'
@@ -123,6 +136,17 @@ def test_finish_leaves_the_current_frame
123136
type 'c'
124137
end
125138
end
139+
140+
def test_finish_skips_method_in_a_same_line
141+
debug_code program do
142+
type 'b 7'
143+
type 'c'
144+
assert_line_num 7
145+
type 'fin'
146+
assert_line_num 8
147+
type 'fin'
148+
end
149+
end
126150
end
127151

128152
#
@@ -254,7 +278,6 @@ def test_finish_4
254278
end
255279
end
256280

257-
258281
def program2
259282
<<~RUBY
260283
1| def foo x
@@ -279,7 +302,7 @@ def test_finish_param
279302
type 'finish'
280303
assert_line_num 6
281304
type 'next'
282-
assert_line_num 2
305+
assert_line_num 9
283306
type 'c'
284307
end
285308
end
@@ -417,9 +440,13 @@ def program
417440
4| end
418441
5| c = 3
419442
6| def foo
420-
7| x = 1
443+
7| @x = 1
421444
8| end
422-
9| foo
445+
9| def bar
446+
10| @y = 2
447+
11| end
448+
12| foo; bar
449+
13| [@x, @y].inspect
423450
RUBY
424451
end
425452

@@ -447,11 +474,23 @@ def test_until_method
447474
debug_code program do
448475
type 'u foo'
449476
assert_line_num 7
450-
type 'u bar'
477+
type 'u baz'
451478
assert_line_num 8
452479
type 'c'
453480
end
454481
end
482+
483+
def test_unit_method_in_the_same_line
484+
debug_code program do
485+
type 'u foo'
486+
assert_line_num 7
487+
type 'u'
488+
assert_line_num 8
489+
type 'u'
490+
assert_line_num 13
491+
type 'c'
492+
end
493+
end
455494
end
456495

457496
#

0 commit comments

Comments
 (0)