Skip to content

Commit 065c48c

Browse files
committed
Revert "[Feature ruby#6012] Extend source_location for end position
and columns" This reverts commit 073c4e1. https://bugs.ruby-lang.org/issues/6012#note-31 > we will cancel this feature in 4.0 because of design ambiguities > such as whether to return column positions in bytes or characters as > in [#21783]. [#21783]: https://bugs.ruby-lang.org/issues/21783
1 parent 5b0fefe commit 065c48c

File tree

7 files changed

+48
-93
lines changed

7 files changed

+48
-93
lines changed

NEWS.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,6 @@ Note: We're only listing outstanding class updates.
116116
117117
* `Math.log1p` and `Math.expm1` are added. [[Feature #21527]]
118118
119-
* Method
120-
121-
* `Method#source_location`, `Proc#source_location`, and
122-
`UnboundMethod#source_location` now return extended location
123-
information with 5 elements: `[path, start_line, start_column,
124-
end_line, end_column]`. The previous 2-element format `[path,
125-
line]` can still be obtained by calling `.take(2)` on the result.
126-
[[Feature #6012]]
127-
128119
* Proc
129120
130121
* `Proc#parameters` now shows anonymous optional parameters as `[:opt]`
@@ -443,7 +434,6 @@ A lot of work has gone into making Ractors more stable, performant, and usable.
443434
* `--rjit` is removed. We will move the implementation of the third-party JIT API
444435
to the [ruby/rjit](https://github.com/ruby/rjit) repository.
445436
446-
[Feature #6012]: https://bugs.ruby-lang.org/issues/6012
447437
[Feature #15408]: https://bugs.ruby-lang.org/issues/15408
448438
[Feature #17473]: https://bugs.ruby-lang.org/issues/17473
449439
[Feature #18455]: https://bugs.ruby-lang.org/issues/18455

proc.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,20 +1511,14 @@ proc_eq(VALUE self, VALUE other)
15111511
static VALUE
15121512
iseq_location(const rb_iseq_t *iseq)
15131513
{
1514-
VALUE loc[5];
1515-
int i = 0;
1514+
VALUE loc[2];
15161515

15171516
if (!iseq) return Qnil;
15181517
rb_iseq_check(iseq);
1519-
loc[i++] = rb_iseq_path(iseq);
1520-
const rb_code_location_t *cl = &ISEQ_BODY(iseq)->location.code_location;
1521-
loc[i++] = RB_INT2NUM(cl->beg_pos.lineno);
1522-
loc[i++] = RB_INT2NUM(cl->beg_pos.column);
1523-
loc[i++] = RB_INT2NUM(cl->end_pos.lineno);
1524-
loc[i++] = RB_INT2NUM(cl->end_pos.column);
1525-
RUBY_ASSERT_ALWAYS(i == numberof(loc));
1526-
1527-
return rb_ary_new_from_values(i, loc);
1518+
loc[0] = rb_iseq_path(iseq);
1519+
loc[1] = RB_INT2NUM(ISEQ_BODY(iseq)->location.first_lineno);
1520+
1521+
return rb_ary_new4(2, loc);
15281522
}
15291523

15301524
VALUE

spec/ruby/core/method/source_location_spec.rb

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@
1111
end
1212

1313
it "sets the first value to the path of the file in which the method was defined" do
14-
file = @method.source_location[0]
14+
file = @method.source_location.first
1515
file.should be_an_instance_of(String)
1616
file.should == File.realpath('fixtures/classes.rb', __dir__)
1717
end
1818

1919
it "sets the last value to an Integer representing the line on which the method was defined" do
20-
line = @method.source_location[1]
20+
line = @method.source_location.last
2121
line.should be_an_instance_of(Integer)
2222
line.should == 5
2323
end
2424

2525
it "returns the last place the method was defined" do
26-
MethodSpecs::SourceLocation.method(:redefined).source_location[1].should == 13
26+
MethodSpecs::SourceLocation.method(:redefined).source_location.last.should == 13
2727
end
2828

2929
it "returns the location of the original method even if it was aliased" do
30-
MethodSpecs::SourceLocation.new.method(:aka).source_location[1].should == 17
30+
MethodSpecs::SourceLocation.new.method(:aka).source_location.last.should == 17
3131
end
3232

3333
it "works for methods defined with a block" do
@@ -108,13 +108,7 @@ def f
108108
c = Class.new do
109109
eval('def self.m; end', nil, "foo", 100)
110110
end
111-
location = c.method(:m).source_location
112-
ruby_version_is(""..."4.0") do
113-
location.should == ["foo", 100]
114-
end
115-
ruby_version_is("4.0") do
116-
location.should == ["foo", 100, 0, 100, 15]
117-
end
111+
c.method(:m).source_location.should == ["foo", 100]
118112
end
119113

120114
describe "for a Method generated by respond_to_missing?" do

spec/ruby/core/proc/source_location_spec.rb

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,64 +17,57 @@
1717
end
1818

1919
it "sets the first value to the path of the file in which the proc was defined" do
20-
file = @proc.source_location[0]
20+
file = @proc.source_location.first
2121
file.should be_an_instance_of(String)
2222
file.should == File.realpath('fixtures/source_location.rb', __dir__)
2323

24-
file = @proc_new.source_location[0]
24+
file = @proc_new.source_location.first
2525
file.should be_an_instance_of(String)
2626
file.should == File.realpath('fixtures/source_location.rb', __dir__)
2727

28-
file = @lambda.source_location[0]
28+
file = @lambda.source_location.first
2929
file.should be_an_instance_of(String)
3030
file.should == File.realpath('fixtures/source_location.rb', __dir__)
3131

32-
file = @method.source_location[0]
32+
file = @method.source_location.first
3333
file.should be_an_instance_of(String)
3434
file.should == File.realpath('fixtures/source_location.rb', __dir__)
3535
end
3636

37-
it "sets the second value to an Integer representing the line on which the proc was defined" do
38-
line = @proc.source_location[1]
37+
it "sets the last value to an Integer representing the line on which the proc was defined" do
38+
line = @proc.source_location.last
3939
line.should be_an_instance_of(Integer)
4040
line.should == 4
4141

42-
line = @proc_new.source_location[1]
42+
line = @proc_new.source_location.last
4343
line.should be_an_instance_of(Integer)
4444
line.should == 12
4545

46-
line = @lambda.source_location[1]
46+
line = @lambda.source_location.last
4747
line.should be_an_instance_of(Integer)
4848
line.should == 8
4949

50-
line = @method.source_location[1]
50+
line = @method.source_location.last
5151
line.should be_an_instance_of(Integer)
5252
line.should == 15
5353
end
5454

5555
it "works even if the proc was created on the same line" do
56-
ruby_version_is(""..."4.0") do
57-
proc { true }.source_location.should == [__FILE__, __LINE__]
58-
Proc.new { true }.source_location.should == [__FILE__, __LINE__]
59-
-> { true }.source_location.should == [__FILE__, __LINE__]
60-
end
61-
ruby_version_is("4.0") do
62-
proc { true }.source_location.should == [__FILE__, __LINE__, 11, __LINE__, 19]
63-
Proc.new { true }.source_location.should == [__FILE__, __LINE__, 15, __LINE__, 23]
64-
-> { true }.source_location.should == [__FILE__, __LINE__, 8, __LINE__, 17]
65-
end
56+
proc { true }.source_location.should == [__FILE__, __LINE__]
57+
Proc.new { true }.source_location.should == [__FILE__, __LINE__]
58+
-> { true }.source_location.should == [__FILE__, __LINE__]
6659
end
6760

6861
it "returns the first line of a multi-line proc (i.e. the line containing 'proc do')" do
69-
ProcSpecs::SourceLocation.my_multiline_proc.source_location[1].should == 20
70-
ProcSpecs::SourceLocation.my_multiline_proc_new.source_location[1].should == 34
71-
ProcSpecs::SourceLocation.my_multiline_lambda.source_location[1].should == 27
62+
ProcSpecs::SourceLocation.my_multiline_proc.source_location.last.should == 20
63+
ProcSpecs::SourceLocation.my_multiline_proc_new.source_location.last.should == 34
64+
ProcSpecs::SourceLocation.my_multiline_lambda.source_location.last.should == 27
7265
end
7366

7467
it "returns the location of the proc's body; not necessarily the proc itself" do
75-
ProcSpecs::SourceLocation.my_detached_proc.source_location[1].should == 41
76-
ProcSpecs::SourceLocation.my_detached_proc_new.source_location[1].should == 51
77-
ProcSpecs::SourceLocation.my_detached_lambda.source_location[1].should == 46
68+
ProcSpecs::SourceLocation.my_detached_proc.source_location.last.should == 41
69+
ProcSpecs::SourceLocation.my_detached_proc_new.source_location.last.should == 51
70+
ProcSpecs::SourceLocation.my_detached_lambda.source_location.last.should == 46
7871
end
7972

8073
it "returns the same value for a proc-ified method as the method reports" do
@@ -93,12 +86,6 @@
9386

9487
it "works for eval with a given line" do
9588
proc = eval('-> {}', nil, "foo", 100)
96-
location = proc.source_location
97-
ruby_version_is(""..."4.0") do
98-
location.should == ["foo", 100]
99-
end
100-
ruby_version_is("4.0") do
101-
location.should == ["foo", 100, 2, 100, 5]
102-
end
89+
proc.source_location.should == ["foo", 100]
10390
end
10491
end

spec/ruby/core/unboundmethod/source_location_spec.rb

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@
77
end
88

99
it "sets the first value to the path of the file in which the method was defined" do
10-
file = @method.source_location[0]
10+
file = @method.source_location.first
1111
file.should be_an_instance_of(String)
1212
file.should == File.realpath('fixtures/classes.rb', __dir__)
1313
end
1414

15-
it "sets the second value to an Integer representing the line on which the method was defined" do
16-
line = @method.source_location[1]
15+
it "sets the last value to an Integer representing the line on which the method was defined" do
16+
line = @method.source_location.last
1717
line.should be_an_instance_of(Integer)
1818
line.should == 5
1919
end
2020

2121
it "returns the last place the method was defined" do
22-
UnboundMethodSpecs::SourceLocation.method(:redefined).unbind.source_location[1].should == 13
22+
UnboundMethodSpecs::SourceLocation.method(:redefined).unbind.source_location.last.should == 13
2323
end
2424

2525
it "returns the location of the original method even if it was aliased" do
26-
UnboundMethodSpecs::SourceLocation.instance_method(:aka).source_location[1].should == 17
26+
UnboundMethodSpecs::SourceLocation.instance_method(:aka).source_location.last.should == 17
2727
end
2828

2929
it "works for define_method methods" do
@@ -54,12 +54,6 @@
5454
c = Class.new do
5555
eval('def m; end', nil, "foo", 100)
5656
end
57-
location = c.instance_method(:m).source_location
58-
ruby_version_is(""..."4.0") do
59-
location.should == ["foo", 100]
60-
end
61-
ruby_version_is("4.0") do
62-
location.should == ["foo", 100, 0, 100, 10]
63-
end
57+
c.instance_method(:m).source_location.should == ["foo", 100]
6458
end
6559
end

test/ruby/test_lambda.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,27 +276,27 @@ def test_break
276276
end
277277

278278
def test_do_lambda_source_location
279-
exp = [__LINE__ + 1, 12, __LINE__ + 5, 7]
279+
exp_lineno = __LINE__ + 3
280280
lmd = ->(x,
281281
y,
282282
z) do
283283
#
284284
end
285-
file, *loc = lmd.source_location
285+
file, lineno = lmd.source_location
286286
assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
287-
assert_equal(exp, loc)
287+
assert_equal(exp_lineno, lineno, "must be at the beginning of the block")
288288
end
289289

290290
def test_brace_lambda_source_location
291-
exp = [__LINE__ + 1, 12, __LINE__ + 5, 5]
291+
exp_lineno = __LINE__ + 3
292292
lmd = ->(x,
293293
y,
294294
z) {
295295
#
296296
}
297-
file, *loc = lmd.source_location
297+
file, lineno = lmd.source_location
298298
assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
299-
assert_equal(exp, loc)
299+
assert_equal(exp_lineno, lineno, "must be at the beginning of the block")
300300
end
301301

302302
def test_not_orphan_return

test/ruby/test_proc.rb

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ def test_binding_source_location
513513

514514
file, lineno = method(:source_location_test).to_proc.binding.source_location
515515
assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
516-
assert_equal(@@line_of_source_location_test[0], lineno, 'Bug #2427')
516+
assert_equal(@@line_of_source_location_test, lineno, 'Bug #2427')
517517
end
518518

519519
def test_binding_error_unless_ruby_frame
@@ -1499,19 +1499,15 @@ def test_to_s
14991499
assert_include(EnvUtil.labeled_class(name, Proc).new {}.to_s, name)
15001500
end
15011501

1502-
@@line_of_source_location_test = [__LINE__ + 1, 2, __LINE__ + 3, 5]
1502+
@@line_of_source_location_test = __LINE__ + 1
15031503
def source_location_test a=1,
15041504
b=2
15051505
end
15061506

15071507
def test_source_location
1508-
file, *loc = method(:source_location_test).source_location
1508+
file, lineno = method(:source_location_test).source_location
15091509
assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
1510-
assert_equal(@@line_of_source_location_test, loc, 'Bug #2427')
1511-
1512-
file, *loc = self.class.instance_method(:source_location_test).source_location
1513-
assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
1514-
assert_equal(@@line_of_source_location_test, loc, 'Bug #2427')
1510+
assert_equal(@@line_of_source_location_test, lineno, 'Bug #2427')
15151511
end
15161512

15171513
@@line_of_attr_reader_source_location_test = __LINE__ + 3
@@ -1544,13 +1540,13 @@ def block_source_location_test(*args, &block)
15441540
end
15451541

15461542
def test_block_source_location
1547-
exp_loc = [__LINE__ + 3, 49, __LINE__ + 4, 49]
1548-
file, *loc = block_source_location_test(1,
1543+
exp_lineno = __LINE__ + 3
1544+
file, lineno = block_source_location_test(1,
15491545
2,
15501546
3) do
15511547
end
15521548
assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
1553-
assert_equal(exp_loc, loc)
1549+
assert_equal(exp_lineno, lineno)
15541550
end
15551551

15561552
def test_splat_without_respond_to

0 commit comments

Comments
 (0)