Skip to content

Commit b1ced67

Browse files
committed
Fix behaviour of locations for comments
1 parent d813c30 commit b1ced67

File tree

3 files changed

+47
-24
lines changed

3 files changed

+47
-24
lines changed

src/yarp.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6068,17 +6068,18 @@ parser_lex(yp_parser_t *parser) {
60686068

60696069
case '#': { // comments
60706070
const uint8_t *ending = next_newline(parser->current.end, parser->end - parser->current.end);
6071-
6072-
parser->current.end = ending == NULL ? parser->end : ending + 1;
6073-
parser->current.type = YP_TOKEN_COMMENT;
6074-
parser_lex_callback(parser);
6071+
parser->current.end = ending == NULL ? parser->end : ending;
60756072

60766073
// If we found a comment while lexing, then we're going to
60776074
// add it to the list of comments in the file and keep
60786075
// lexing.
60796076
yp_comment_t *comment = parser_comment(parser, YP_COMMENT_INLINE);
60806077
yp_list_append(&parser->comment_list, (yp_list_node_t *) comment);
60816078

6079+
if (ending) parser->current.end++;
6080+
parser->current.type = YP_TOKEN_COMMENT;
6081+
parser_lex_callback(parser);
6082+
60826083
if (parser->current.start == parser->encoding_comment_start) {
60836084
parser_lex_encoding_comment(parser);
60846085
}
@@ -7067,6 +7068,14 @@ parser_lex(yp_parser_t *parser) {
70677068
(parser->current.end == parser->end || match_eol(parser))
70687069
)
70697070
{
7071+
// Since we know we're about to add an __END__ comment, we know we
7072+
// need at add all of the newlines to get the correct column
7073+
// information for it.
7074+
const uint8_t *cursor = parser->current.end;
7075+
while ((cursor = next_newline(cursor, parser->end - cursor)) != NULL) {
7076+
yp_newline_list_append(&parser->newline_list, cursor++);
7077+
}
7078+
70707079
parser->current.end = parser->end;
70717080
parser->current.type = YP_TOKEN___END__;
70727081
parser_lex_callback(parser);

test/yarp/comments_test.rb

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class CommentsTest < TestCase
77
def test_comment_inline
88
source = "# comment"
99

10-
assert_comment source, :inline, 0..9
10+
assert_comment source, :inline, [0, 9, 1, 1, 0, 9]
1111
assert_equal [0], Debug.newlines(source)
1212
end
1313

@@ -18,7 +18,7 @@ def foo
1818
end
1919
RUBY
2020

21-
assert_comment source, :inline, 10..22
21+
assert_comment source, :inline, [10, 21, 2, 2, 2, 13]
2222
end
2323

2424
def test_comment___END__
@@ -27,13 +27,13 @@ def test_comment___END__
2727
comment
2828
RUBY
2929

30-
assert_comment source, :__END__, 0..16
30+
assert_comment source, :__END__, [0, 16, 1, 2, 0, 0]
3131
end
3232

3333
def test_comment___END__crlf
3434
source = "__END__\r\ncomment\r\n"
3535

36-
assert_comment source, :__END__, 0..18
36+
assert_comment source, :__END__, [0, 18, 1, 2, 0, 0]
3737
end
3838

3939
def test_comment_embedded_document
@@ -43,7 +43,7 @@ def test_comment_embedded_document
4343
=end
4444
RUBY
4545

46-
assert_comment source, :embdoc, 0..20
46+
assert_comment source, :embdoc, [0, 20, 1, 3, 0, 0]
4747
end
4848

4949
def test_comment_embedded_document_with_content_on_same_line
@@ -52,7 +52,7 @@ def test_comment_embedded_document_with_content_on_same_line
5252
=end
5353
RUBY
5454

55-
assert_comment source, :embdoc, 0..24
55+
assert_comment source, :embdoc, [0, 24, 1, 2, 0, 0]
5656
end
5757

5858
def test_attaching_comments
@@ -74,19 +74,40 @@ def bar
7474
method_node = class_node.body.body.first
7575
call_node = method_node.body.body.first
7676

77-
assert_equal("# Foo class\n# Foo end\n", class_node.location.comments.map { |c| c.location.slice }.join)
78-
assert_equal("# bar method\n# bar end\n", method_node.location.comments.map { |c| c.location.slice }.join)
79-
assert_equal("# baz invocation\n", call_node.location.comments.map { |c| c.location.slice }.join)
77+
assert_equal("# Foo class\n# Foo end", class_node.location.comments.map { |c| c.location.slice }.join("\n"))
78+
assert_equal("# bar method\n# bar end", method_node.location.comments.map { |c| c.location.slice }.join("\n"))
79+
assert_equal("# baz invocation", call_node.location.comments.map { |c| c.location.slice }.join("\n"))
8080
end
8181

8282
private
8383

84-
def assert_comment(source, type, location)
84+
def assert_comment(source, type, locations)
85+
start_offset, end_offset, start_line, end_line, start_column, end_column = locations
86+
expected = {
87+
start_offset: start_offset,
88+
end_offset: end_offset,
89+
start_line: start_line,
90+
end_line: end_line,
91+
start_column: start_column,
92+
end_column: end_column
93+
}
94+
8595
result = YARP.parse(source)
8696
assert result.errors.empty?, result.errors.map(&:message).join("\n")
87-
assert_equal result.comments.first.type, type
88-
assert_equal result.comments.first.location.start_offset, location.begin
89-
assert_equal result.comments.first.location.end_offset, location.end
97+
assert_equal type, result.comments.first.type
98+
99+
first_comment_location = result.comments.first.location
100+
101+
actual = {
102+
start_offset: first_comment_location.start_offset,
103+
end_offset: first_comment_location.end_offset,
104+
start_line: first_comment_location.start_line,
105+
end_line: first_comment_location.end_line,
106+
start_column: first_comment_location.start_column,
107+
end_column: first_comment_location.end_column
108+
}
109+
110+
assert_equal expected, actual
90111
end
91112
end
92113
end

test/yarp/parse_test.rb

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,6 @@ def test_parse_lex_file
126126
# Next, assert that the newlines are in the expected places.
127127
expected_newlines = [0]
128128
source.b.scan("\n") { expected_newlines << $~.offset(0)[0] + 1 }
129-
130-
# If there's a __END__, then we should trip out those newlines because we
131-
# don't actually scan them during parsing (because we don't need to).
132-
if found = result.comments.find { |comment| comment.type == :__END__ }
133-
expected_newlines = expected_newlines[...found.location.start_line]
134-
end
135-
136129
assert_equal expected_newlines, Debug.newlines(source)
137130

138131
if ripper_should_parse && ripper_should_match

0 commit comments

Comments
 (0)