[Bug #21006] Fix defined_expr compilation of method call with parenthesized receiver
This commit is contained in:
parent
5698f4f2e1
commit
8fb17f86d7
@ -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;
|
const pm_node_list_t *arguments = &cast->arguments;
|
||||||
for (size_t idx = 0; idx < arguments->size; idx++) {
|
for (size_t idx = 0; idx < arguments->size; idx++) {
|
||||||
const pm_node_t *argument = arguments->nodes[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]) {
|
if (!lfinish[1]) {
|
||||||
lfinish[1] = NEW_LABEL(location.line);
|
lfinish[1] = NEW_LABEL(location.line);
|
||||||
@ -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) {
|
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
|
// If we have a parentheses node that is wrapping a single statement
|
||||||
// then we want to recurse down to that statement and compile it.
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -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: {
|
case PM_IMPLICIT_NODE: {
|
||||||
const pm_implicit_node_t *cast = (const pm_implicit_node_t *) 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;
|
return;
|
||||||
}
|
}
|
||||||
case PM_AND_NODE:
|
case PM_AND_NODE:
|
||||||
@ -4018,9 +4018,8 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cast->receiver) {
|
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)) {
|
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]);
|
PUSH_INSNL(ret, location, branchunless, lfinish[2]);
|
||||||
|
|
||||||
const pm_call_node_t *receiver = (const pm_call_node_t *) cast->receiver;
|
const pm_call_node_t *receiver = (const pm_call_node_t *) cast->receiver;
|
||||||
@ -4028,6 +4027,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
|
|||||||
pm_compile_call(iseq, receiver, ret, popped, scope_node, method_id, NULL);
|
pm_compile_call(iseq, receiver, ret, popped, scope_node, method_id, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
pm_compile_defined_expr0(iseq, cast->receiver, node_location, ret, popped, scope_node, true, lfinish, false);
|
||||||
PUSH_INSNL(ret, location, branchunless, lfinish[1]);
|
PUSH_INSNL(ret, location, branchunless, lfinish[1]);
|
||||||
PM_COMPILE(cast->receiver);
|
PM_COMPILE(cast->receiver);
|
||||||
}
|
}
|
||||||
@ -4106,7 +4106,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
LINK_ELEMENT *lcur = ret->last;
|
||||||
pm_compile_defined_expr0(iseq, node, node_location, ret, popped, scope_node, in_condition, lfinish, false);
|
pm_compile_defined_expr0(iseq, node, node_location, ret, popped, scope_node, in_condition, lfinish, false);
|
||||||
@ -4147,7 +4147,7 @@ pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_lo
|
|||||||
lfinish[2] = 0;
|
lfinish[2] = 0;
|
||||||
|
|
||||||
if (!popped) {
|
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]) {
|
if (lfinish[1]) {
|
||||||
|
@ -210,6 +210,9 @@ module Prism
|
|||||||
# method chain with a block on the inside
|
# method chain with a block on the inside
|
||||||
assert_prism_eval("defined?(itself { 1 }.itself)")
|
assert_prism_eval("defined?(itself { 1 }.itself)")
|
||||||
|
|
||||||
|
# method chain with parenthesized receiver
|
||||||
|
assert_prism_eval("defined?((itself).itself)")
|
||||||
|
|
||||||
# Method chain on a constant
|
# Method chain on a constant
|
||||||
assert_prism_eval(<<~RUBY)
|
assert_prism_eval(<<~RUBY)
|
||||||
class PrismDefinedNode
|
class PrismDefinedNode
|
||||||
|
Loading…
x
Reference in New Issue
Block a user