diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-05-14 17:27:48 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-05-14 19:58:44 +0900 |
commit | d7d0d01401a8082e514eb2cb3cec5410e7acba7d (patch) | |
tree | a40aa20206bb3603d683bec7cbe5d45e0e91e0be | |
parent | 634eeb4353ca92a94b4642bd05837868f630eda1 (diff) | |
download | ruby-d7d0d01401a8082e514eb2cb3cec5410e7acba7d.tar.gz |
Endless method definition including `rescue` modifier
-rw-r--r-- | parse.y | 36 | ||||
-rw-r--r-- | test/ruby/test_syntax.rb | 6 |
2 files changed, 40 insertions, 2 deletions
@@ -920,6 +920,17 @@ set_defun_body(struct parser_params *p, NODE *n, NODE *args, NODE *body, const Y set_line_body(body, loc->beg_pos.lineno); return n; } + +static NODE * +rescued_expr(struct parser_params *p, NODE *arg, NODE *rescue, + const YYLTYPE *arg_loc, const YYLTYPE *mod_loc, const YYLTYPE *res_loc) +{ + YYLTYPE loc = code_loc_gen(mod_loc, res_loc); + rescue = NEW_RESBODY(0, remove_begin(rescue), 0, &loc); + loc.beg_pos = arg_loc->beg_pos; + return NEW_RESCUE(arg, rescue, 0, &loc); +} + #endif /* RIPPER */ static void @@ -2455,6 +2466,16 @@ arg : lhs '=' arg_rhs /*% ripper: def!(get_value($1), $2, $4) %*/ local_pop(p); } + | defn_head f_paren_args '=' arg modifier_rescue arg + { + restore_defun(p, $<node>1->nd_defn); + /*%%%*/ + $4 = rescued_expr(p, $4, $6, &@4, &@5, &@6); + $$ = set_defun_body(p, $1, $2, $4, &@$); + /*% %*/ + /*% ripper: def!(get_value($1), $2, rescue_mod!($4, $6)) %*/ + local_pop(p); + } | defs_head f_paren_args '=' arg { restore_defun(p, $<node>1->nd_defn); @@ -2466,6 +2487,18 @@ arg : lhs '=' arg_rhs /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/ local_pop(p); } + | defs_head f_paren_args '=' arg modifier_rescue arg + { + restore_defun(p, $<node>1->nd_defn); + /*%%%*/ + $4 = rescued_expr(p, $4, $6, &@4, &@5, &@6); + $$ = set_defun_body(p, $1, $2, $4, &@$); + /*% + $1 = get_value($1); + %*/ + /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, rescue_mod!($4, $6)) %*/ + local_pop(p); + } | primary { $$ = $1; @@ -2525,9 +2558,8 @@ arg_rhs : arg %prec tOP_ASGN | arg modifier_rescue arg { /*%%%*/ - YYLTYPE loc = code_loc_gen(&@2, &@3); value_expr($1); - $$ = NEW_RESCUE($1, NEW_RESBODY(0, remove_begin($3), 0, &loc), 0, &@$); + $$ = rescued_expr(p, $1, $3, &@1, &@2, &@3); /*% %*/ /*% ripper: rescue_mod!($1, $3) %*/ } diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index df6c2e383f..23061e364b 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -1423,6 +1423,12 @@ eom assert_valid_syntax('private def obj.inc(x) = x + 1') eval('def self.inc(x) = x + 1 => @x') assert_equal(:inc, @x) + k = Class.new do + class_eval('def rescued(x) = raise("to be caught") rescue "instance #{x}"') + class_eval('def self.rescued(x) = raise("to be caught") rescue "class #{x}"') + end + assert_equal("class ok", k.rescued("ok")) + assert_equal("instance ok", k.new.rescued("ok")) end def test_methoddef_in_cond |