mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Merge pull request #2418 from jeremyevans/array-empty-kwsplat
Ignore empty keyword splats in arrays
This commit is contained in:
parent
be86591458
commit
f560609d66
Notes:
git
2019-09-03 00:21:53 +09:00
Merged: https://github.com/ruby/ruby/pull/2418 Merged-By: jeremyevans <code@jeremyevans.net>
3 changed files with 63 additions and 2 deletions
18
compile.c
18
compile.c
|
@ -4025,8 +4025,21 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_ro
|
|||
else {
|
||||
if (!popped || kw) {
|
||||
switch (type) {
|
||||
case COMPILE_ARRAY_TYPE_ARRAY:
|
||||
ADD_INSN1(anchor, line, newarray, INT2FIX(i));
|
||||
case COMPILE_ARRAY_TYPE_ARRAY: {
|
||||
const NODE *check_node = node_root;
|
||||
|
||||
/* Find last node in array, and if it is a keyword argument, then set
|
||||
flag to check and remove empty keyword arguments hash from array */
|
||||
while(check_node->nd_next) {
|
||||
check_node = check_node->nd_next;
|
||||
}
|
||||
if (nd_type(check_node->nd_head) == NODE_HASH && check_node->nd_head->nd_brace == 0) {
|
||||
ADD_INSN1(anchor, line, newarraykwsplat, INT2FIX(i));
|
||||
}
|
||||
else {
|
||||
ADD_INSN1(anchor, line, newarray, INT2FIX(i));
|
||||
}
|
||||
|
||||
|
||||
if (first) {
|
||||
first = 0;
|
||||
|
@ -4037,6 +4050,7 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_ro
|
|||
|
||||
APPEND_LIST(ret, anchor);
|
||||
break;
|
||||
}
|
||||
case COMPILE_ARRAY_TYPE_HASH:
|
||||
if (i > 0) {
|
||||
if (first) {
|
||||
|
|
20
insns.def
20
insns.def
|
@ -441,6 +441,26 @@ newarray
|
|||
val = rb_ary_new4(num, STACK_ADDR_FROM_TOP(num));
|
||||
}
|
||||
|
||||
/* put new array initialized with num values on the stack. There
|
||||
should be at least one element on the stack, and the top element
|
||||
should be a hash. If the top element is empty, it is not
|
||||
included in the array.
|
||||
*/
|
||||
DEFINE_INSN
|
||||
newarraykwsplat
|
||||
(rb_num_t num)
|
||||
(...)
|
||||
(VALUE val)
|
||||
// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
|
||||
{
|
||||
if (RHASH_EMPTY_P(*STACK_ADDR_FROM_TOP(1))) {
|
||||
val = rb_ary_new4(num-1, STACK_ADDR_FROM_TOP(num));
|
||||
}
|
||||
else {
|
||||
val = rb_ary_new4(num, STACK_ADDR_FROM_TOP(num));
|
||||
}
|
||||
}
|
||||
|
||||
/* dup array */
|
||||
DEFINE_INSN
|
||||
duparray
|
||||
|
|
|
@ -100,6 +100,33 @@ class TestSyntax < Test::Unit::TestCase
|
|||
EOS
|
||||
end
|
||||
|
||||
def test_array_kwsplat_hash
|
||||
kw = {}
|
||||
h = {a: 1}
|
||||
assert_equal([], [**{}])
|
||||
assert_equal([], [**kw])
|
||||
assert_equal([h], [**h])
|
||||
assert_equal([{}], [{}])
|
||||
assert_equal([kw], [kw])
|
||||
assert_equal([h], [h])
|
||||
|
||||
assert_equal([1], [1, **{}])
|
||||
assert_equal([1], [1, **kw])
|
||||
assert_equal([1, h], [1, **h])
|
||||
assert_equal([1, {}], [1, {}])
|
||||
assert_equal([1, kw], [1, kw])
|
||||
assert_equal([1, h], [1, h])
|
||||
|
||||
assert_equal([], [**kw, **kw])
|
||||
assert_equal([], [**kw, **{}, **kw])
|
||||
assert_equal([1], [1, **kw, **{}, **kw])
|
||||
|
||||
assert_equal([{}], [{}, **kw, **kw])
|
||||
assert_equal([kw], [kw, **kw, **kw])
|
||||
assert_equal([h], [h, **kw, **kw])
|
||||
assert_equal([h, h], [h, **kw, **kw, **h])
|
||||
end
|
||||
|
||||
def test_normal_argument
|
||||
assert_valid_syntax('def foo(x) end')
|
||||
assert_syntax_error('def foo(X) end', /constant/)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue