From 9b87518ea0eff0c30c22db9c2394bb61db913646 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 27 Aug 2023 16:43:27 -0400 Subject: [PATCH] [ruby/yarp] fix: %I list spanning a heredoc Similar to the previous %W fix, we accept a symbol node and concatenate it onto an interpolated symbol. https://github.com/ruby/yarp/commit/6b5911b95e --- test/yarp/fixtures/spanning_heredoc.txt | 7 ++++++ test/yarp/snapshots/spanning_heredoc.txt | 31 ++++++++++++++++++++++-- yarp/yarp.c | 13 ++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/test/yarp/fixtures/spanning_heredoc.txt b/test/yarp/fixtures/spanning_heredoc.txt index c1852e377a..a52a4c3c27 100644 --- a/test/yarp/fixtures/spanning_heredoc.txt +++ b/test/yarp/fixtures/spanning_heredoc.txt @@ -42,3 +42,10 @@ pp <<-A, %i[n\ m A n] + +# ripper gets this one wrong in the same way that YARP does ... +# TODO: yarp does not include the "\n" in "p\np" in the AST like ruby does +pp <<-A, %I[p\ +o +A +p] diff --git a/test/yarp/snapshots/spanning_heredoc.txt b/test/yarp/snapshots/spanning_heredoc.txt index 3d223e5e4d..301c70adf2 100644 --- a/test/yarp/snapshots/spanning_heredoc.txt +++ b/test/yarp/snapshots/spanning_heredoc.txt @@ -1,6 +1,6 @@ -ProgramNode(164...802)( +ProgramNode(164...964)( [], - StatementsNode(164...802)( + StatementsNode(164...964)( [CallNode(164...192)( nil, nil, @@ -183,6 +183,33 @@ ProgramNode(164...802)( nil, 0, "pp" + ), + CallNode(943...964)( + nil, + nil, + (943...945), + nil, + ArgumentsNode(946...964)( + [InterpolatedStringNode(946...950)( + (946...950), + [StringNode(958...960)(nil, (958...960), nil, "o\n")], + (960...962) + ), + ArrayNode(952...964)( + [InterpolatedSymbolNode(955...963)( + nil, + [SymbolNode(955...958)(nil, (955...958), nil, "p"), + StringNode(962...963)(nil, (962...963), nil, "p")], + nil + )], + (952...955), + (963...964) + )] + ), + nil, + nil, + 0, + "pp" )] ) ) diff --git a/yarp/yarp.c b/yarp/yarp.c index 1f707696bb..6f66affd78 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -12001,6 +12001,19 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { // to the list of child nodes. yp_node_t *part = parse_string_part(parser); yp_interpolated_symbol_node_append((yp_interpolated_symbol_node_t *) current, part); + } else if (YP_NODE_TYPE_P(current, YP_NODE_SYMBOL_NODE)) { + // If we hit string content and the current node is a string node, + // then we need to convert the current node into an interpolated + // string and add the string content to the list of child nodes. + yp_token_t opening = not_provided(parser); + yp_token_t closing = not_provided(parser); + yp_interpolated_symbol_node_t *interpolated = + yp_interpolated_symbol_node_create(parser, &opening, NULL, &closing); + yp_interpolated_symbol_node_append(interpolated, current); + + yp_node_t *part = parse_string_part(parser); + yp_interpolated_symbol_node_append(interpolated, part); + current = (yp_node_t *) interpolated; } else { assert(false && "unreachable"); }