From 4d64693c703edbccc5b155072276ce7b8c3becdb Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Wed, 24 Apr 2019 10:34:02 -0700 Subject: Make ripper support **nil syntax The on_params hook will use :nil as the keyword rest argument. There is a new on_nokw_param hook as well. This fixes a type issue in the previous code, where an ID was passed where a VALUE was the declared type. The symbol :nil is passed instead of the id. --- parse.y | 12 +++++++++--- test/ripper/test_parser_events.rb | 10 ++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/parse.y b/parse.y index c7c43e3278..c575dfdded 100644 --- a/parse.y +++ b/parse.y @@ -1034,6 +1034,7 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in %type cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg %type f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon %type p_kwrest +%type f_no_kwarg %token END_OF_INPUT 0 "end-of-input" %token '.' /* escaped chars, should be ignored otherwise */ @@ -3247,7 +3248,7 @@ block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg } | f_no_kwarg opt_f_block_arg { - $$ = new_args_tail(p, Qnone, rb_intern("nil"), $2, &@1); + $$ = new_args_tail(p, Qnone, ID2SYM(rb_intern("nil")), $2, &@1); } | f_block_arg { @@ -4718,7 +4719,7 @@ args_tail : f_kwarg ',' f_kwrest opt_f_block_arg } | f_no_kwarg opt_f_block_arg { - $$ = new_args_tail(p, Qnone, rb_intern("nil"), $2, &@1); + $$ = new_args_tail(p, Qnone, ID2SYM(rb_intern("nil")), $2, &@1); } | f_block_arg { @@ -4977,6 +4978,11 @@ kwrest_mark : tPOW ; f_no_kwarg : kwrest_mark keyword_nil + { + /*%%%*/ + /*% %*/ + /*% ripper: nokw_param!(Qnil) %*/ + } ; f_kwrest : kwrest_mark tIDENTIFIER @@ -11136,7 +11142,7 @@ new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block, args->kw_rest_arg = NEW_DVAR(kw_rest_arg, loc); args->kw_rest_arg->nd_cflag = kw_bits; } - else if (kw_rest_arg == rb_intern("nil")) { + else if (kw_rest_arg == ID2SYM(rb_intern("nil"))) { args->no_kwarg = 1; } else if (kw_rest_arg) { diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb index 59d4ad3987..1bae1e31ad 100644 --- a/test/ripper/test_parser_events.rb +++ b/test/ripper/test_parser_events.rb @@ -944,6 +944,10 @@ class TestRipper::ParserEvents < Test::Unit::TestCase parse('a {|**x|}', :on_params) {|_, *v| thru_params = true; arg = v} assert_equal true, thru_params assert_equal [nil, nil, nil, nil, nil, "**x", nil], arg + thru_params = false + parse('a {|**nil|}', :on_params) {|_, *v| thru_params = true; arg = v} + assert_equal true, thru_params + assert_equal [nil, nil, nil, nil, nil, :nil, nil], arg end def test_params_mlhs @@ -1153,6 +1157,12 @@ class TestRipper::ParserEvents < Test::Unit::TestCase assert_equal "x", thru_kwrest end + def test_nokw_param + thru_nokw = false + parse('def a(**nil) end', :on_nokw_param) {|n, val| thru_nokw = val} + assert_equal nil, thru_nokw + end + def test_retry thru_retry = false parse('retry', :on_retry) {thru_retry = true} -- cgit v1.2.3