Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions include/ruby/internal/scan_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@
/** Same behaviour as rb_scan_args(). */
#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS 0

/** The final argument should be a hash treated as keywords.*/
/** The final argument must be a hash, which will be treated as keywords. */
#define RB_SCAN_ARGS_KEYWORDS 1

/**
* Treat a final argument as keywords if it is a hash, and not as keywords
* Treat a final argument as keywords if it is a hash, and not as keywords
* otherwise.
*/
#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS 3
Expand All @@ -68,7 +68,7 @@
/** Do not pass keywords. */
#define RB_NO_KEYWORDS 0

/** Pass keywords, final argument should be a hash of keywords. */
/** Pass keywords, final argument must be a hash of keywords. */
#define RB_PASS_KEYWORDS 1

/**
Expand Down
24 changes: 1 addition & 23 deletions prism/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -22282,28 +22282,6 @@ pm_parse_stream_read(pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t
#undef LINE_SIZE
}

/**
* Determine if there was an unterminated heredoc at the end of the input, which
* would mean the stream isn't finished and we should keep reading.
*
* For the other lex modes we can check if the lex mode has been closed, but for
* heredocs when we hit EOF we close the lex mode and then go back to parse the
* rest of the line after the heredoc declaration so that we get more of the
* syntax tree.
*/
static bool
pm_parse_stream_unterminated_heredoc_p(pm_parser_t *parser) {
pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) parser->error_list.head;

for (; diagnostic != NULL; diagnostic = (pm_diagnostic_t *) diagnostic->node.next) {
if (diagnostic->diag_id == PM_ERR_HEREDOC_TERM) {
return true;
}
}

return false;
}

/**
* Parse a stream of Ruby source and return the tree.
*
Expand All @@ -22319,7 +22297,7 @@ pm_parse_stream(pm_parser_t *parser, pm_buffer_t *buffer, void *stream, pm_parse
pm_parser_init(parser, (const uint8_t *) pm_buffer_value(buffer), pm_buffer_length(buffer), options);
pm_node_t *node = pm_parse(parser);

while (!eof && parser->error_list.size > 0 && (parser->lex_modes.index > 0 || pm_parse_stream_unterminated_heredoc_p(parser))) {
while (!eof && parser->error_list.size > 0) {
pm_node_destroy(parser, node);
eof = pm_parse_stream_read(buffer, stream, stream_fgets, stream_feof);

Expand Down
51 changes: 44 additions & 7 deletions test/prism/api/parse_stream_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,48 +30,85 @@ def test_multi_read
end

def test___END__
io = StringIO.new("1 + 2\n3 + 4\n__END__\n5 + 6")
io = StringIO.new(<<~RUBY)
1 + 2
3 + 4
__END__
5 + 6
RUBY
result = Prism.parse_stream(io)

assert result.success?
assert_equal 2, result.value.statements.body.length
assert_equal "5 + 6", io.read
assert_equal "5 + 6\n", io.read
end

def test_false___END___in_string
io = StringIO.new("1 + 2\n3 + 4\n\"\n__END__\n\"\n5 + 6")
io = StringIO.new(<<~RUBY)
1 + 2
3 + 4
"
__END__
"
5 + 6
RUBY
result = Prism.parse_stream(io)

assert result.success?
assert_equal 4, result.value.statements.body.length
end

def test_false___END___in_regexp
io = StringIO.new("1 + 2\n3 + 4\n/\n__END__\n/\n5 + 6")
io = StringIO.new(<<~RUBY)
1 + 2
3 + 4
/
__END__
/
5 + 6
RUBY
result = Prism.parse_stream(io)

assert result.success?
assert_equal 4, result.value.statements.body.length
end

def test_false___END___in_list
io = StringIO.new("1 + 2\n3 + 4\n%w[\n__END__\n]\n5 + 6")
io = StringIO.new(<<~RUBY)
1 + 2
3 + 4
%w[
__END__
]
5 + 6
RUBY
result = Prism.parse_stream(io)

assert result.success?
assert_equal 4, result.value.statements.body.length
end

def test_false___END___in_heredoc
io = StringIO.new("1 + 2\n3 + 4\n<<-EOF\n__END__\nEOF\n5 + 6")
io = StringIO.new(<<~RUBY)
1 + 2
3 + 4
<<-EOF
__END__
EOF
5 + 6
RUBY
result = Prism.parse_stream(io)

assert result.success?
assert_equal 4, result.value.statements.body.length
end

def test_nul_bytes
io = StringIO.new("1 # \0\0\0 \n2 # \0\0\0\n3")
io = StringIO.new(<<~RUBY)
1 # \0\0\0\t
2 # \0\0\0
3
RUBY
result = Prism.parse_stream(io)

assert result.success?
Expand Down