@@ -8482,6 +8482,7 @@ parser_lex(pm_parser_t *parser) {
8482
8482
8483
8483
const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
8484
8484
pm_token_buffer_t token_buffer = { 0 };
8485
+ bool was_escaped_newline = false;
8485
8486
8486
8487
while (breakpoint != NULL) {
8487
8488
switch (*breakpoint) {
@@ -8509,6 +8510,7 @@ parser_lex(pm_parser_t *parser) {
8509
8510
// content. Then, the next time a token is lexed, it will match
8510
8511
// again and return the end of the heredoc.
8511
8512
if (
8513
+ !was_escaped_newline &&
8512
8514
(start + ident_length <= parser->end) &&
8513
8515
(memcmp(start, ident_start, ident_length) == 0)
8514
8516
) {
@@ -8550,6 +8552,9 @@ parser_lex(pm_parser_t *parser) {
8550
8552
case '\r':
8551
8553
parser->current.end++;
8552
8554
if (peek(parser) != '\n') {
8555
+ if (quote == PM_HEREDOC_QUOTE_SINGLE) {
8556
+ pm_token_buffer_push(&token_buffer, '\\');
8557
+ }
8553
8558
pm_token_buffer_push(&token_buffer, '\r');
8554
8559
break;
8555
8560
}
@@ -8559,25 +8564,19 @@ parser_lex(pm_parser_t *parser) {
8559
8564
// to leave the escaped newline in place so that
8560
8565
// it can be removed later when we dedent the
8561
8566
// heredoc.
8562
- if (lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE) {
8567
+ if (quote == PM_HEREDOC_QUOTE_SINGLE || lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE) {
8563
8568
pm_token_buffer_push(&token_buffer, '\\');
8564
8569
pm_token_buffer_push(&token_buffer, '\n');
8565
8570
}
8566
8571
8567
- if (parser->heredoc_end) {
8568
- // ... if we are on the same line as a heredoc,
8569
- // flush the heredoc and continue parsing after
8570
- // heredoc_end.
8571
- parser_flush_heredoc_end(parser);
8572
- pm_token_buffer_copy(parser, &token_buffer);
8573
- LEX(PM_TOKEN_STRING_CONTENT);
8574
- } else {
8575
- // ... else track the newline.
8576
- pm_newline_list_append(&parser->newline_list, parser->current.end);
8572
+ token_buffer.cursor = parser->current.end + 1;
8573
+ breakpoint = parser->current.end;
8574
+
8575
+ if (quote != PM_HEREDOC_QUOTE_SINGLE) {
8576
+ was_escaped_newline = true;
8577
8577
}
8578
8578
8579
- parser->current.end++;
8580
- break;
8579
+ continue;
8581
8580
default:
8582
8581
if (quote == PM_HEREDOC_QUOTE_SINGLE) {
8583
8582
pm_token_buffer_push(&token_buffer, '\\');
@@ -8616,6 +8615,8 @@ parser_lex(pm_parser_t *parser) {
8616
8615
default:
8617
8616
assert(false && "unreachable");
8618
8617
}
8618
+
8619
+ was_escaped_newline = false;
8619
8620
}
8620
8621
8621
8622
// If we've hit the end of the string, then this is an unterminated
0 commit comments