ruby-changes:72158
From: Nobuyoshi <ko1@a...>
Date: Tue, 14 Jun 2022 20:42:11 +0900 (JST)
Subject: [ruby-changes:72158] 1a70973f75 (master): ripper: Check if anonymous parameters defined [Bug #18828]
https://git.ruby-lang.org/ruby.git/commit/?id=1a70973f75 From 1a70973f7557af33bfca6e2edc5cd302937425a4 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Tue, 14 Jun 2022 18:28:22 +0900 Subject: ripper: Check if anonymous parameters defined [Bug #18828] --- parse.y | 24 +++++++++++------------- test/ripper/test_parser_events.rb | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/parse.y b/parse.y index 141c4a6739..167f064b31 100644 --- a/parse.y +++ b/parse.y @@ -2856,14 +2856,13 @@ block_arg : tAMPER arg_value https://github.com/ruby/ruby/blob/trunk/parse.y#L2856 } | tAMPER { - /*%%%*/ if (!local_id(p, ANON_BLOCK_ID)) { compile_error(p, "no anonymous block parameter"); } + /*%%%*/ $$ = NEW_BLOCK_PASS(NEW_LVAR(ANON_BLOCK_ID, &@1), &@$); - /*% - $$ = Qnil; - %*/ + /*% %*/ + /*% ripper: Qnil %*/ } ; @@ -2894,10 +2893,10 @@ args : arg_value https://github.com/ruby/ruby/blob/trunk/parse.y#L2893 } | tSTAR { - /*%%%*/ if (!local_id(p, ANON_REST_ID)) { compile_error(p, "no anonymous rest parameter"); } + /*%%%*/ $$ = NEW_SPLAT(NEW_LVAR(ANON_REST_ID, &@1), &@$); /*% %*/ /*% ripper: args_add_star!(args_new!, Qnil) %*/ @@ -2918,10 +2917,10 @@ args : arg_value https://github.com/ruby/ruby/blob/trunk/parse.y#L2917 } | args ',' tSTAR { - /*%%%*/ if (!local_id(p, ANON_REST_ID)) { compile_error(p, "no anonymous rest parameter"); } + /*%%%*/ $$ = rest_arg_append(p, $1, NEW_LVAR(ANON_REST_ID, &@3), &@$); /*% %*/ /*% ripper: args_add_star!($1, Qnil) %*/ @@ -5489,8 +5488,8 @@ f_kwrest : kwrest_mark tIDENTIFIER https://github.com/ruby/ruby/blob/trunk/parse.y#L5488 } | kwrest_mark { + arg_var(p, ANON_KEYWORD_REST_ID); /*%%%*/ - arg_var(p, shadowing_lvar(p, get_id(ANON_KEYWORD_REST_ID))); /*% %*/ /*% ripper: kwrest_param!(Qnil) %*/ } @@ -5564,8 +5563,8 @@ f_rest_arg : restarg_mark tIDENTIFIER https://github.com/ruby/ruby/blob/trunk/parse.y#L5563 } | restarg_mark { + arg_var(p, ANON_REST_ID); /*%%%*/ - arg_var(p, shadowing_lvar(p, get_id(ANON_REST_ID))); /*% %*/ /*% ripper: rest_param!(Qnil) %*/ } @@ -5585,11 +5584,10 @@ f_block_arg : blkarg_mark tIDENTIFIER https://github.com/ruby/ruby/blob/trunk/parse.y#L5584 } | blkarg_mark { + arg_var(p, ANON_BLOCK_ID); /*%%%*/ - arg_var(p, shadowing_lvar(p, get_id(ANON_BLOCK_ID))); - /*% - $$ = dispatch1(blockarg, Qnil); - %*/ + /*% %*/ + /*% ripper: blockarg!(Qnil) %*/ } ; @@ -5721,10 +5719,10 @@ assoc : arg_value tASSOC arg_value https://github.com/ruby/ruby/blob/trunk/parse.y#L5719 } | tDSTAR { - /*%%%*/ if (!local_id(p, ANON_KEYWORD_REST_ID)) { compile_error(p, "no anonymous keyword rest parameter"); } + /*%%%*/ $$ = list_append(p, NEW_LIST(0, &@$), NEW_LVAR(ANON_KEYWORD_REST_ID, &@$)); /*% %*/ diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb index 5bb8f120f2..1ea8d23378 100644 --- a/test/ripper/test_parser_events.rb +++ b/test/ripper/test_parser_events.rb @@ -155,6 +155,44 @@ class TestRipper::ParserEvents < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ripper/test_parser_events.rb#L155 end end + def test_anonymous_block_forwarding + thru_args_add_block = false + parse('def b(&); c(&); end', :on_args_add_block) {thru_args_add_block = true} + assert_equal true, thru_args_add_block + assert_match "no anonymous block parameter", compile_error('def b; c(&); end') + end + + def test_anonymous_rest_forwarding + [ + 'c(*)', + 'c(*, *)', + ].each do |code| + thru_args_add_star = false + src = "def b(*); #{code} end" + parse(src, :on_args_add_star) {thru_args_add_star = true} + assert_equal true, thru_args_add_star, src + + src = "def b; #{code} end" + assert_match "no anonymous rest parameter", compile_error(src), src + end + end + + def test_anonymous_keyword_rest_forwarding + [ + 'c(**)', + 'c(k: 1, **)', + 'c(**, k: 1)', + ].each do |code| + thru_assoc_splat = false + src = "def b(**); #{code} end" + parse(src, :on_assoc_splat) {thru_assoc_splat = true} + assert_equal true, thru_assoc_splat, src + + src = "def b; #{code} end" + assert_match "no anonymous keyword rest parameter", compile_error(src), src + end + end + def test_arg_paren # FIXME end -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/