diff --git a/test/snapshots/heredoc_with_escaped_newline_at_start.txt b/test/snapshots/heredoc_with_escaped_newline_at_start.txt new file mode 100644 index 00000000000000..43fa751526de80 --- /dev/null +++ b/test/snapshots/heredoc_with_escaped_newline_at_start.txt @@ -0,0 +1,45 @@ +ProgramNode(0...62)( + [], + StatementsNode(0...62)( + [CallNode(0...25)( + InterpolatedStringNode(0...9)((0...9), [], (27...34)), + (9...10), + (10...14), + nil, + ArgumentsNode(15...25)( + [RegularExpressionNode(15...21)( + (15...16), + (16...20), + (20...21), + "^ {", + 0 + ), + StringNode(23...25)((23...24), (24...24), (24...25), "")] + ), + nil, + nil, + 0, + "gsub" + ), + CallNode(37...62)( + InterpolatedStringNode(37...46)((37...46), [], (65...73)), + (46...47), + (47...51), + nil, + ArgumentsNode(52...62)( + [RegularExpressionNode(52...58)( + (52...53), + (53...57), + (57...58), + "^ {", + 0 + ), + StringNode(60...62)((60...61), (61...61), (61...62), "")] + ), + nil, + nil, + 0, + "gsub" + )] + ) +) diff --git a/yarp/yarp.c b/yarp/yarp.c index ed777a45203b4f..715c2819491d62 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -5653,13 +5653,23 @@ parser_lex(yp_parser_t *parser) { break; case '\\': if (peek_at(parser, 1) == '\n') { - yp_newline_list_append(&parser->newline_list, parser->current.end + 1); - parser->current.end += 2; - space_seen = true; - } else if (parser->current.end + 2 < parser->end && peek_at(parser, 1) == '\r' && peek_at(parser, 2) == '\n') { - yp_newline_list_append(&parser->newline_list, parser->current.end + 2); - parser->current.end += 3; - space_seen = true; + if (parser->heredoc_end) { + parser->current.end = parser->heredoc_end; + parser->heredoc_end = NULL; + } else { + yp_newline_list_append(&parser->newline_list, parser->current.end + 1); + parser->current.end += 2; + space_seen = true; + } + } else if (peek_at(parser, 1) == '\r' && peek_at(parser, 2) == '\n') { + if (parser->heredoc_end) { + parser->current.end = parser->heredoc_end; + parser->heredoc_end = NULL; + } else { + yp_newline_list_append(&parser->newline_list, parser->current.end + 2); + parser->current.end += 3; + space_seen = true; + } } else if (yp_char_is_inline_whitespace(*parser->current.end)) { parser->current.end += 2; } else {