From ca5b4580442eac3ee8ad3f98b692d204d7b92f03 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Mon, 20 May 2024 10:44:13 -0400 Subject: [PATCH] [PRISM] Match CRuby line semantics for evstr --- prism/prism.c | 7 +++++++ prism_compile.c | 17 +++++++++++------ test/.excludes-prism/TestCoverage.rb | 1 - 3 files changed, 18 insertions(+), 7 deletions(-) delete mode 100644 test/.excludes-prism/TestCoverage.rb diff --git a/prism/prism.c b/prism/prism.c index 22c19f56b5..bad6c7ff2b 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -15460,6 +15460,13 @@ parse_string_part(pm_parser_t *parser) { expect1(parser, PM_TOKEN_EMBEXPR_END, PM_ERR_EMBEXPR_END); pm_token_t closing = parser->previous; + // If this set of embedded statements only contains a single + // statement, then Ruby does not consider it as a possible statement + // that could emit a line event. + if (statements != NULL && statements->body.size == 1) { + pm_node_flag_unset(statements->body.nodes[0], PM_NODE_FLAG_NEWLINE); + } + return (pm_node_t *) pm_embedded_statements_node_create(parser, &opening, statements, &closing); } diff --git a/prism_compile.c b/prism_compile.c index 675b4cf86a..c9f2fed9ca 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -570,6 +570,7 @@ pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const if (parts_size > 0) { VALUE current_string = Qnil; + pm_line_column_t current_location = *node_location; for (size_t index = 0; index < parts_size; index++) { const pm_node_t *part = parts->nodes[index]; @@ -590,6 +591,7 @@ pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const } else { current_string = string_value; + if (index != 0) current_location = PM_NODE_END_LINE_COLUMN(scope_node->parser, part); } } else { @@ -616,6 +618,7 @@ pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const } else { current_string = string_value; + current_location = PM_NODE_START_LINE_COLUMN(scope_node->parser, part); } } else { @@ -640,11 +643,13 @@ pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const current_string = rb_enc_str_new(NULL, 0, encoding); } - PUSH_INSN1(ret, *node_location, putobject, rb_fstring(current_string)); + PUSH_INSN1(ret, current_location, putobject, rb_fstring(current_string)); PM_COMPILE_NOT_POPPED(part); - PUSH_INSN(ret, *node_location, dup); - PUSH_INSN1(ret, *node_location, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE)); - PUSH_INSN(ret, *node_location, anytostring); + + const pm_line_column_t current_location = PM_NODE_START_LINE_COLUMN(scope_node->parser, part); + PUSH_INSN(ret, current_location, dup); + PUSH_INSN1(ret, current_location, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE, NULL, FALSE)); + PUSH_INSN(ret, current_location, anytostring); current_string = Qnil; stack_size += 2; @@ -656,10 +661,10 @@ pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const current_string = rb_fstring(current_string); if (stack_size == 0 && interpolated) { - PUSH_INSN1(ret, *node_location, putstring, current_string); + PUSH_INSN1(ret, current_location, putstring, current_string); } else { - PUSH_INSN1(ret, *node_location, putobject, current_string); + PUSH_INSN1(ret, current_location, putobject, current_string); } current_string = Qnil; diff --git a/test/.excludes-prism/TestCoverage.rb b/test/.excludes-prism/TestCoverage.rb deleted file mode 100644 index f122d6edbc..0000000000 --- a/test/.excludes-prism/TestCoverage.rb +++ /dev/null @@ -1 +0,0 @@ -exclude(:test_eval, "respect eval coverage setting")