diff options
-rw-r--r-- | prism/prism.c | 21 | ||||
-rw-r--r-- | test/prism/errors_test.rb | 9 |
2 files changed, 23 insertions, 7 deletions
diff --git a/prism/prism.c b/prism/prism.c index bc758b49f2..4aeef976c9 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -8658,7 +8658,7 @@ parser_lex(pm_parser_t *parser) { // this is not a valid heredoc declaration. In this case we // will add an error, but we will still return a heredoc // start. - pm_parser_err_current(parser, PM_ERR_EMBDOC_TERM); + pm_parser_err_current(parser, PM_ERR_HEREDOC_TERM); body_start = parser->end; } else { // Otherwise, we want to indicate that the body of the @@ -9911,15 +9911,22 @@ parser_lex(pm_parser_t *parser) { parser->next_start = NULL; } - // We'll check if we're at the end of the file. If we are, then we need to - // return the EOF token. + // Now let's grab the information about the identifier off of the + // current lex mode. + pm_lex_mode_t *lex_mode = parser->lex_modes.current; + + // We'll check if we're at the end of the file. If we are, then we + // will add an error (because we weren't able to find the + // terminator) but still continue parsing so that content after the + // declaration of the heredoc can be parsed. if (parser->current.end >= parser->end) { - LEX(PM_TOKEN_EOF); + pm_parser_err_current(parser, PM_ERR_HEREDOC_TERM); + parser->next_start = lex_mode->as.heredoc.next_start; + parser->heredoc_end = parser->current.end; + lex_state_set(parser, PM_LEX_STATE_END); + LEX(PM_TOKEN_HEREDOC_END); } - // Now let's grab the information about the identifier off of the current - // lex mode. - pm_lex_mode_t *lex_mode = parser->lex_modes.current; const uint8_t *ident_start = lex_mode->as.heredoc.ident_start; size_t ident_length = lex_mode->as.heredoc.ident_length; diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb index 9e7bb10762..7ce6d17be5 100644 --- a/test/prism/errors_test.rb +++ b/test/prism/errors_test.rb @@ -1248,6 +1248,15 @@ module Prism assert_errors expected, "def foo(a = 1,b,*c);end", [["unexpected parameter `*`", 16..17]] end + def test_content_after_unterminated_heredoc + receiver = StringNode(0, Location(), Location(), Location(), "") + expected = CallNode(0, receiver, Location(), :foo, Location(), nil, nil, nil, nil) + + assert_errors expected, "<<~FOO.foo\n", [ + ["could not find a terminator for the heredoc", 11..11] + ] + end + def test_invalid_message_name result = Prism.parse("+.@foo,+=foo") assert_equal :"", result.value.statements.body.first.write_name |