зеркало из https://github.com/github/ruby.git
[PRISM] Fix keywords arguments in IndexAndWriteNode
Fixes ruby/prism#2233.
This commit is contained in:
Родитель
5906ce42fe
Коммит
a7af34fa8b
|
@ -932,10 +932,10 @@ pm_compile_call_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t
|
|||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
|
@ -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));
|
||||
}
|
||||
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 {
|
||||
if (block_offset > 0) {
|
||||
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 argc_int = 0;
|
||||
|
||||
struct rb_callinfo_kwarg *keywords = NULL;
|
||||
if (arguments) {
|
||||
// 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);
|
||||
|
@ -1255,9 +1261,9 @@ pm_compile_index_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t
|
|||
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 *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_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_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);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -385,6 +385,15 @@ module Prism
|
|||
hash["key", &(Proc.new { _1.upcase })] &&= "value"
|
||||
hash
|
||||
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
|
||||
|
||||
def test_IndexOrWriteNode
|
||||
|
|
Загрузка…
Ссылка в новой задаче