[PRISM] Fix keywords arguments in IndexAndWriteNode
Fixes ruby/prism#2233.
This commit is contained in:
parent
5906ce42fe
commit
a7af34fa8b
@ -932,10 +932,10 @@ pm_compile_call_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pm_compile_index_write_nodes_add_send(bool popped, LINK_ANCHOR *const ret, rb_iseq_t *iseq, NODE dummy_line_node, VALUE argc, int flag, int block_offset)
|
pm_compile_index_write_nodes_add_send(bool popped, LINK_ANCHOR *const ret, rb_iseq_t *iseq, NODE dummy_line_node, VALUE argc, int flag, int block_offset, struct rb_callinfo_kwarg *keywords)
|
||||||
{
|
{
|
||||||
if (!popped) {
|
if (!popped) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, FIXNUM_INC(argc, 2 + block_offset));
|
ADD_INSN1(ret, &dummy_line_node, setn, FIXNUM_INC(argc, 2 + block_offset + (keywords ? keywords->keyword_len : 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag & VM_CALL_ARGS_SPLAT) {
|
if (flag & VM_CALL_ARGS_SPLAT) {
|
||||||
@ -952,6 +952,11 @@ pm_compile_index_write_nodes_add_send(bool popped, LINK_ANCHOR *const ret, rb_is
|
|||||||
}
|
}
|
||||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, argc, INT2FIX(flag));
|
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, argc, INT2FIX(flag));
|
||||||
}
|
}
|
||||||
|
else if (keywords && keywords->keyword_len) {
|
||||||
|
ADD_INSN1(ret, &dummy_line_node, opt_reverse, INT2FIX(keywords->keyword_len + block_offset + 1));
|
||||||
|
ADD_INSN1(ret, &dummy_line_node, opt_reverse, INT2FIX(keywords->keyword_len + block_offset + 0));
|
||||||
|
ADD_SEND_R(ret, &dummy_line_node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), keywords);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (block_offset > 0) {
|
if (block_offset > 0) {
|
||||||
PM_SWAP;
|
PM_SWAP;
|
||||||
@ -1241,9 +1246,10 @@ pm_compile_index_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t
|
|||||||
int flag = 0;
|
int flag = 0;
|
||||||
int argc_int = 0;
|
int argc_int = 0;
|
||||||
|
|
||||||
|
struct rb_callinfo_kwarg *keywords = NULL;
|
||||||
if (arguments) {
|
if (arguments) {
|
||||||
// Get any arguments, and set the appropriate values for flag
|
// Get any arguments, and set the appropriate values for flag
|
||||||
argc_int = pm_setup_args(arguments, &flag, NULL, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
|
argc_int = pm_setup_args(arguments, &flag, &keywords, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE argc = INT2FIX(argc_int);
|
VALUE argc = INT2FIX(argc_int);
|
||||||
@ -1255,9 +1261,9 @@ pm_compile_index_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t
|
|||||||
block_offset = 1;
|
block_offset = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_INSN1(ret, &dummy_line_node, dupn, FIXNUM_INC(argc, 1 + block_offset));
|
ADD_INSN1(ret, &dummy_line_node, dupn, FIXNUM_INC(argc, 1 + block_offset + (keywords ? keywords->keyword_len : 0)));
|
||||||
|
|
||||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idAREF, argc, INT2FIX(flag));
|
ADD_SEND_R(ret, &dummy_line_node, idAREF, argc, NULL, INT2FIX(flag), keywords);
|
||||||
|
|
||||||
LABEL *label = NEW_LABEL(lineno);
|
LABEL *label = NEW_LABEL(lineno);
|
||||||
LABEL *lfin = NEW_LABEL(lineno);
|
LABEL *lfin = NEW_LABEL(lineno);
|
||||||
@ -1276,7 +1282,7 @@ pm_compile_index_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t
|
|||||||
|
|
||||||
PM_COMPILE_NOT_POPPED(value);
|
PM_COMPILE_NOT_POPPED(value);
|
||||||
|
|
||||||
pm_compile_index_write_nodes_add_send(popped, ret, iseq, dummy_line_node, argc, flag, block_offset);
|
pm_compile_index_write_nodes_add_send(popped, ret, iseq, dummy_line_node, argc, flag, block_offset, keywords);
|
||||||
|
|
||||||
ADD_INSNL(ret, &dummy_line_node, jump, lfin);
|
ADD_INSNL(ret, &dummy_line_node, jump, lfin);
|
||||||
ADD_LABEL(ret, label);
|
ADD_LABEL(ret, label);
|
||||||
@ -5028,7 +5034,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||||||
ID method_id = pm_constant_id_lookup(scope_node, index_operator_write_node->operator);
|
ID method_id = pm_constant_id_lookup(scope_node, index_operator_write_node->operator);
|
||||||
ADD_SEND(ret, &dummy_line_node, method_id, INT2FIX(1));
|
ADD_SEND(ret, &dummy_line_node, method_id, INT2FIX(1));
|
||||||
|
|
||||||
pm_compile_index_write_nodes_add_send(popped, ret, iseq, dummy_line_node, argc, flag, block_offset);
|
pm_compile_index_write_nodes_add_send(popped, ret, iseq, dummy_line_node, argc, flag, block_offset, NULL);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -385,6 +385,15 @@ module Prism
|
|||||||
hash["key", &(Proc.new { _1.upcase })] &&= "value"
|
hash["key", &(Proc.new { _1.upcase })] &&= "value"
|
||||||
hash
|
hash
|
||||||
CODE
|
CODE
|
||||||
|
|
||||||
|
# Test with keyword arguments
|
||||||
|
assert_prism_eval(<<~RUBY)
|
||||||
|
h = Object.new
|
||||||
|
def h.[](**b) = 0
|
||||||
|
def h.[]=(*a, **b); end
|
||||||
|
|
||||||
|
h[foo: 1] &&= 2
|
||||||
|
RUBY
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_IndexOrWriteNode
|
def test_IndexOrWriteNode
|
||||||
|
Loading…
x
Reference in New Issue
Block a user