1
0
Fork 0
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:
Jeremy Evans 2019-09-02 08:21:30 -07:00 committed by GitHub
parent be86591458
commit f560609d66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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

View file

@ -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) {

View file

@ -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

View file

@ -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/)