Skip to content

Commit ae9b60f

Browse files
committed
[Feature #19107] parse.y: Allow trailing comma in method signature
1 parent 5b83468 commit ae9b60f

2 files changed

Lines changed: 40 additions & 30 deletions

File tree

parse.y

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,7 +2773,7 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
27732773
%type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
27742774
%type <node> args arg_splat call_args opt_call_args
27752775
%type <node> paren_args opt_paren_args
2776-
%type <node_args> args_tail block_args_tail block_args-opt_tail
2776+
%type <node_args> args_tail block_args_tail
27772777
%type <node> command_args aref_args
27782778
%type <node_block_pass> opt_block_arg block_arg
27792779
%type <node> var_ref var_lhs
@@ -2798,7 +2798,7 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
27982798
%type <node> p_value p_primitive p_variable p_var_ref p_expr_ref p_const
27992799
%type <node> p_kwargs p_kwarg p_kw
28002800
%type <id> keyword_variable user_variable sym operation2 operation3
2801-
%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
2801+
%type <id> cname fname op f_rest_arg f_block_arg opt_comma f_norm_arg f_bad_arg
28022802
%type <id> f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon
28032803
%type <id> p_kwrest p_kwnorest p_any_kwrest p_kw_label
28042804
%type <id> f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var def_name
@@ -2923,18 +2923,18 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
29232923
}
29242924
;
29252925

2926-
%rule args_tail_basic(value) <node_args>
2927-
: f_kwarg(value) ',' f_kwrest opt_f_block_arg
2926+
%rule args_tail_basic(value, trailing) <node_args>
2927+
: f_kwarg(value) ',' f_kwrest opt_f_block_arg(trailing)
29282928
{
29292929
$$ = new_args_tail(p, $1, $3, $4, &@3);
29302930
/*% ripper: [$:1, $:3, $:4] %*/
29312931
}
2932-
| f_kwarg(value) opt_f_block_arg
2932+
| f_kwarg(value) opt_f_block_arg(trailing)
29332933
{
29342934
$$ = new_args_tail(p, $1, 0, $2, &@1);
29352935
/*% ripper: [$:1, Qnil, $:2] %*/
29362936
}
2937-
| f_any_kwrest opt_f_block_arg
2937+
| f_any_kwrest opt_f_block_arg(trailing)
29382938
{
29392939
$$ = new_args_tail(p, 0, $1, $2, &@1);
29402940
/*% ripper: [Qnil, $:1, $:2] %*/
@@ -2946,6 +2946,15 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
29462946
}
29472947
;
29482948

2949+
%rule opt_f_block_arg(trailing) <id>
2950+
: ',' f_block_arg
2951+
{
2952+
$$ = $2;
2953+
/*% ripper: $:2 %*/
2954+
}
2955+
| trailing
2956+
;
2957+
29492958
%rule def_endless_method(bodystmt) <node>
29502959
: defn_head[head] f_opt_paren_args[args] '=' bodystmt
29512960
{
@@ -3087,13 +3096,13 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
30873096
}
30883097
;
30893098

3090-
%rule opt_args_tail(tail) <node_args>
3099+
%rule opt_args_tail(tail, trailing) <node_args>
30913100
: ',' tail
30923101
{
30933102
$$ = $tail;
30943103
/*% ripper: $:tail %*/
30953104
}
3096-
| /* none */
3105+
| trailing
30973106
{
30983107
$$ = new_empty_args_tail(p, &@$);
30993108
/*% ripper: [Qnil, Qnil, Qnil] %*/
@@ -4973,10 +4982,7 @@ f_any_kwrest : f_kwrest
49734982

49744983
f_eq : {p->ctxt.in_argdef = 0;} '=';
49754984

4976-
block_args_tail : args_tail_basic(primary_value)
4977-
;
4978-
4979-
block_args-opt_tail : opt_args_tail(block_args_tail)
4985+
block_args_tail : args_tail_basic(primary_value, none)
49804986
;
49814987

49824988
excessed_comma : ','
@@ -4987,14 +4993,14 @@ excessed_comma : ','
49874993
}
49884994
;
49894995

4990-
block_param : args-list(primary_value, block_args-opt_tail)
4996+
block_param : args-list(primary_value, opt_args_tail(block_args_tail, none))
49914997
| f_arg[pre] excessed_comma
49924998
{
49934999
$$ = new_empty_args_tail(p, &@excessed_comma);
49945000
$$ = new_args(p, $pre, 0, $excessed_comma, 0, $$, &@$);
49955001
/*% ripper: params!($:pre, Qnil, $:excessed_comma, Qnil, Qnil, Qnil, Qnil) %*/
49965002
}
4997-
| f_arg[pre] opt_args_tail(block_args_tail)[tail]
5003+
| f_arg[pre] opt_args_tail(block_args_tail, none)[tail]
49985004
{
49995005
$$ = new_args(p, $pre, 0, 0, 0, $tail, &@$);
50005006
/*% ripper: params!($:pre, Qnil, Qnil, Qnil, *$:tail[0..2]) %*/
@@ -6240,7 +6246,7 @@ f_arglist : f_paren_args
62406246
}
62416247
;
62426248

6243-
args_tail : args_tail_basic(arg_value)
6249+
args_tail : args_tail_basic(arg_value, opt_comma)
62446250
| args_forward
62456251
{
62466252
add_forwarding_args(p);
@@ -6250,7 +6256,7 @@ args_tail : args_tail_basic(arg_value)
62506256
}
62516257
;
62526258

6253-
largs_tail : args_tail_basic(arg_value)
6259+
largs_tail : args_tail_basic(arg_value, none)
62546260
| args_forward
62556261
{
62566262
yyerror1(&@args_forward, "unexpected ... in lambda argument");
@@ -6331,14 +6337,9 @@ largs_tail : args_tail_basic(arg_value)
63316337
}
63326338
;
63336339

6334-
%rule f_args-opt_tail(tail) <node_args>
6335-
: opt_args_tail(tail)
6336-
;
6337-
6338-
6339-
%rule f_args-list(tail) <node_args>
6340-
: args-list(arg_value, f_args-opt_tail(tail))
6341-
| f_arg[pre] opt_args_tail(tail)[tail]
6340+
%rule f_args-list(tail, trailing) <node_args>
6341+
: args-list(arg_value, opt_args_tail(tail, trailing))
6342+
| f_arg[pre] opt_args_tail(tail, trailing)[tail]
63426343
{
63436344
$$ = new_args(p, $pre, 0, 0, 0, $tail, &@$);
63446345
/*% ripper: params!($:pre, Qnil, Qnil, Qnil, *$:tail[0..2]) %*/
@@ -6347,10 +6348,10 @@ largs_tail : args_tail_basic(arg_value)
63476348
| f_empty_arg
63486349
;
63496350

6350-
f_args : f_args-list(args_tail)
6351+
f_args : f_args-list(args_tail, opt_comma)
63516352
;
63526353

6353-
f_largs : f_args-list(largs_tail)
6354+
f_largs : f_args-list(largs_tail, none)
63546355
;
63556356

63566357
args_forward : tBDOT3
@@ -6538,12 +6539,11 @@ f_block_arg : blkarg_mark tIDENTIFIER
65386539
}
65396540
;
65406541

6541-
opt_f_block_arg : ',' f_block_arg
6542+
opt_comma : ','?
65426543
{
6543-
$$ = $2;
6544-
/*% ripper: $:2 %*/
6544+
$$ = 0;
6545+
/*% ripper: Qnil %*/
65456546
}
6546-
| none
65476547
;
65486548

65496549

test/ruby/test_syntax.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,16 @@ def test_no_block_argument_in_method
222222
assert_raise_with_message(ArgumentError, /block accepted/) {obj.f(&proc {})}
223223
end
224224

225+
def test_trailing_comma_in_method_parameters
226+
assert_valid_syntax("def f(a,b,c,); end")
227+
assert_valid_syntax("def f(a,b,*c,); end")
228+
assert_valid_syntax("def f(a,b,*,); end")
229+
assert_valid_syntax("def f(a,b,**c,); end")
230+
assert_valid_syntax("def f(a,b,**,); end")
231+
assert_syntax_error("def f(a,b,&block,); end", /unexpected/)
232+
assert_syntax_error("def f(a,b,...,); end", /unexpected/)
233+
end
234+
225235
def test_no_block_argument_in_block
226236
assert_valid_syntax("proc do |&nil| end")
227237
assert_valid_syntax("proc do |a, &nil| end")

0 commit comments

Comments
 (0)