mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Make anonymous rest arg (*) and block arg (&) accessible from ARGS node
This commit is contained in:
parent
ddd62fadaf
commit
f0ce118662
Notes:
git
2022-11-18 09:26:01 +00:00
3 changed files with 32 additions and 4 deletions
1
node.h
1
node.h
|
@ -461,6 +461,7 @@ struct rb_args_info {
|
|||
NODE *opt_args;
|
||||
unsigned int no_kwarg: 1;
|
||||
unsigned int ruby2_keywords: 1;
|
||||
unsigned int forwarding: 1;
|
||||
|
||||
VALUE imemo;
|
||||
};
|
||||
|
|
11
parse.y
11
parse.y
|
@ -5322,6 +5322,9 @@ args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
|
|||
{
|
||||
add_forwarding_args(p);
|
||||
$$ = new_args_tail(p, Qnone, $1, ID2VAL(idFWD_BLOCK), &@1);
|
||||
/*%%%*/
|
||||
($$->nd_ainfo)->forwarding = 1;
|
||||
/*% %*/
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -5688,7 +5691,7 @@ f_rest_arg : restarg_mark tIDENTIFIER
|
|||
{
|
||||
arg_var(p, ANON_REST_ID);
|
||||
/*%%%*/
|
||||
$$ = internal_id(p);
|
||||
$$ = ANON_REST_ID;
|
||||
/*% %*/
|
||||
/*% ripper: rest_param!(Qnil) %*/
|
||||
}
|
||||
|
@ -5710,7 +5713,7 @@ f_block_arg : blkarg_mark tIDENTIFIER
|
|||
{
|
||||
arg_var(p, ANON_BLOCK_ID);
|
||||
/*%%%*/
|
||||
$$ = internal_id(p);
|
||||
$$ = ANON_BLOCK_ID;
|
||||
/*% %*/
|
||||
/*% ripper: blockarg!(Qnil) %*/
|
||||
}
|
||||
|
@ -12204,7 +12207,7 @@ new_args(struct parser_params *p, NODE *pre_args, NODE *opt_args, ID rest_arg, N
|
|||
int saved_line = p->ruby_sourceline;
|
||||
struct rb_args_info *args = tail->nd_ainfo;
|
||||
|
||||
if (args->block_arg == idFWD_BLOCK) {
|
||||
if (args->forwarding) {
|
||||
if (rest_arg) {
|
||||
yyerror1(&tail->nd_loc, "... after rest argument");
|
||||
return tail;
|
||||
|
@ -12223,7 +12226,7 @@ new_args(struct parser_params *p, NODE *pre_args, NODE *opt_args, ID rest_arg, N
|
|||
|
||||
args->opt_args = opt_args;
|
||||
|
||||
args->ruby2_keywords = rest_arg == idFWD_REST;
|
||||
args->ruby2_keywords = args->forwarding;
|
||||
|
||||
p->ruby_sourceline = saved_line;
|
||||
nd_set_loc(tail, loc);
|
||||
|
|
|
@ -461,6 +461,30 @@ class TestAst < Test::Unit::TestCase
|
|||
assert_not_equal(type1, type2)
|
||||
end
|
||||
|
||||
def test_rest_arg
|
||||
rest_arg = lambda do |arg_str|
|
||||
node = RubyVM::AbstractSyntaxTree.parse("def a(#{arg_str}) end")
|
||||
node = node.children.last.children.last.children[1].children[-4]
|
||||
end
|
||||
|
||||
assert_equal(nil, rest_arg.call(''))
|
||||
assert_equal(:r, rest_arg.call('*r'))
|
||||
assert_equal(:r, rest_arg.call('a, *r'))
|
||||
assert_equal(:*, rest_arg.call('*'))
|
||||
assert_equal(:*, rest_arg.call('a, *'))
|
||||
end
|
||||
|
||||
def test_block_arg
|
||||
block_arg = lambda do |arg_str|
|
||||
node = RubyVM::AbstractSyntaxTree.parse("def a(#{arg_str}) end")
|
||||
node = node.children.last.children.last.children[1].children[-1]
|
||||
end
|
||||
|
||||
assert_equal(nil, block_arg.call(''))
|
||||
assert_equal(:block, block_arg.call('&block'))
|
||||
assert_equal(:&, block_arg.call('&'))
|
||||
end
|
||||
|
||||
def test_keyword_rest
|
||||
kwrest = lambda do |arg_str|
|
||||
node = RubyVM::AbstractSyntaxTree.parse("def a(#{arg_str}) end")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue