Skip to content

Commit

Permalink
endless_stmt
Browse files Browse the repository at this point in the history
`def test = puts("foo") or puts("bar")` is interrupted as
`def test = (puts("foo") or puts("bar"))`
  • Loading branch information
yui-knk committed Jul 9, 2023
1 parent acd9c20 commit f91fff6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
19 changes: 15 additions & 4 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -1588,7 +1588,7 @@ static int looking_at_eol_p(struct parser_params *p);
%type <node> string_contents xstring_contents regexp_contents string_content
%type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
%type <node> literal numeric simple_numeric ssym dsym symbol cpath def_name defn_head defs_head
%type <node> top_compstmt top_stmts top_stmt begin_block endless_arg endless_command
%type <node> top_compstmt top_stmts top_stmt begin_block endless_stmt endless_arg endless_command
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
%type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr
%type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
Expand Down Expand Up @@ -2973,7 +2973,7 @@ arg : lhs '=' lex_ctxt arg_rhs
/*% %*/
/*% ripper: ifop!($1, $3, $6) %*/
}
| defn_head f_opt_paren_args '=' endless_arg
| defn_head f_opt_paren_args '=' endless_stmt
{
endless_method_name(p, $<node>1, &@1);
restore_defun(p, $<node>1->nd_defn);
Expand All @@ -2983,7 +2983,7 @@ arg : lhs '=' lex_ctxt arg_rhs
/*% ripper: def!(get_value($1), $2, bodystmt!($4, Qnil, Qnil, Qnil)) %*/
local_pop(p);
}
| defs_head f_opt_paren_args '=' endless_arg
| defs_head f_opt_paren_args '=' endless_stmt
{
endless_method_name(p, $<node>1, &@1);
restore_defun(p, $<node>1->nd_defn);
Expand All @@ -3001,18 +3001,29 @@ arg : lhs '=' lex_ctxt arg_rhs
}
;

endless_arg : arg %prec modifier_rescue
endless_stmt : endless_arg %prec tLOWEST
| endless_arg modifier_rescue arg
{
/*%%%*/
$$ = rescued_expr(p, $1, $3, &@1, &@2, &@3);
/*% %*/
/*% ripper: rescue_mod!($1, $3) %*/
}
;

endless_arg : arg %prec modifier_rescue
| keyword_not opt_nl endless_arg
{
$$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
}
| endless_arg keyword_and endless_arg
{
$$ = logop(p, idAND, $1, $3, &@2, &@$);
}
| endless_arg keyword_or endless_arg
{
$$ = logop(p, idOR, $1, $3, &@2, &@$);
}
;

relop : '>' {$$ = '>';}
Expand Down
6 changes: 6 additions & 0 deletions test/ruby/test_syntax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,12 @@ def test_methoddef_endless
end
assert_equal("class ok", k.rescued("ok"))
assert_equal("instance ok", k.new.rescued("ok"))
k2 = Class.new do
class_eval('def and(x) = "ng" and x')
class_eval('def or(x) = x or raise("ng")')
end
assert_equal("ok", k2.new.and("ok"))
assert_equal("ok", k2.new.or("ok"))

error = /setter method cannot be defined in an endless method definition/
assert_syntax_error('def foo=() = 42', error)
Expand Down

0 comments on commit f91fff6

Please sign in to comment.