Skip to content

Commit

Permalink
Fix defined_expr compilation of method call with parenthesized receiver
Browse files Browse the repository at this point in the history
  • Loading branch information
tompng committed Jan 6, 2025
1 parent 31905d9 commit 67ae57c
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 7 deletions.
14 changes: 7 additions & 7 deletions prism_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -3755,7 +3755,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
const pm_node_list_t *arguments = &cast->arguments;
for (size_t idx = 0; idx < arguments->size; idx++) {
const pm_node_t *argument = arguments->nodes[idx];
pm_compile_defined_expr0(iseq, argument, node_location, ret, popped, scope_node, in_condition, lfinish, explicit_receiver);
pm_compile_defined_expr0(iseq, argument, node_location, ret, popped, scope_node, in_condition, lfinish, false);

if (!lfinish[1]) {
lfinish[1] = NEW_LABEL(location.line);
Expand All @@ -3778,7 +3778,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
else if (PM_NODE_TYPE_P(cast->body, PM_STATEMENTS_NODE) && ((const pm_statements_node_t *) cast->body)->body.size == 1) {
// If we have a parentheses node that is wrapping a single statement
// then we want to recurse down to that statement and compile it.
pm_compile_defined_expr0(iseq, ((const pm_statements_node_t *) cast->body)->body.nodes[0], node_location, ret, popped, scope_node, in_condition, lfinish, explicit_receiver);
pm_compile_defined_expr0(iseq, ((const pm_statements_node_t *) cast->body)->body.nodes[0], node_location, ret, popped, scope_node, in_condition, lfinish, false);
return;
}
else {
Expand Down Expand Up @@ -3874,7 +3874,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
}
case PM_IMPLICIT_NODE: {
const pm_implicit_node_t *cast = (const pm_implicit_node_t *) node;
pm_compile_defined_expr0(iseq, cast->value, node_location, ret, popped, scope_node, in_condition, lfinish, explicit_receiver);
pm_compile_defined_expr0(iseq, cast->value, node_location, ret, popped, scope_node, in_condition, lfinish, false);
return;
}
case PM_AND_NODE:
Expand Down Expand Up @@ -4018,16 +4018,16 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
}

if (cast->receiver) {
pm_compile_defined_expr0(iseq, cast->receiver, node_location, ret, popped, scope_node, true, lfinish, true);

if (PM_NODE_TYPE_P(cast->receiver, PM_CALL_NODE) && !BLOCK_P((const pm_call_node_t *) cast->receiver)) {
pm_compile_defined_expr0(iseq, cast->receiver, node_location, ret, popped, scope_node, true, lfinish, true);
PUSH_INSNL(ret, location, branchunless, lfinish[2]);

const pm_call_node_t *receiver = (const pm_call_node_t *) cast->receiver;
ID method_id = pm_constant_id_lookup(scope_node, receiver->name);
pm_compile_call(iseq, receiver, ret, popped, scope_node, method_id, NULL);
}
else {
pm_compile_defined_expr0(iseq, cast->receiver, node_location, ret, popped, scope_node, true, lfinish, false);
PUSH_INSNL(ret, location, branchunless, lfinish[1]);
PM_COMPILE(cast->receiver);
}
Expand Down Expand Up @@ -4106,7 +4106,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
}

static void
pm_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_location_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, bool in_condition, LABEL **lfinish, bool explicit_receiver)
pm_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_location_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, bool in_condition, LABEL **lfinish)
{
LINK_ELEMENT *lcur = ret->last;
pm_compile_defined_expr0(iseq, node, node_location, ret, popped, scope_node, in_condition, lfinish, false);
Expand Down Expand Up @@ -4147,7 +4147,7 @@ pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_lo
lfinish[2] = 0;

if (!popped) {
pm_defined_expr(iseq, node, node_location, ret, popped, scope_node, in_condition, lfinish, false);
pm_defined_expr(iseq, node, node_location, ret, popped, scope_node, in_condition, lfinish);
}

if (lfinish[1]) {
Expand Down
3 changes: 3 additions & 0 deletions test/ruby/test_compile_prism.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ def test_DefinedNode
# method chain with a block on the inside
assert_prism_eval("defined?(itself { 1 }.itself)")

# method chain with parenthesized receiver
assert_prism_eval("defined?((itself).itself)")

# Method chain on a constant
assert_prism_eval(<<~RUBY)
class PrismDefinedNode
Expand Down

0 comments on commit 67ae57c

Please sign in to comment.