mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Prohibit setter method names in all kinds of endless methods
Also unwrap NODE_RIPPER to check the method name.
This commit is contained in:
parent
27b48089e2
commit
4ed0c33d13
Notes:
git
2020-10-12 01:54:09 +09:00
3 changed files with 66 additions and 10 deletions
19
parse.y
19
parse.y
|
@ -961,6 +961,18 @@ restore_defun(struct parser_params *p, NODE *name)
|
|||
p->ctxt.in_def = c.ctxt.in_def;
|
||||
}
|
||||
|
||||
static void
|
||||
endless_method_name(struct parser_params *p, NODE *defn, const YYLTYPE *loc)
|
||||
{
|
||||
#ifdef RIPPER
|
||||
defn = defn->nd_defn;
|
||||
#endif
|
||||
ID mid = defn->nd_mid;
|
||||
if (is_attrset_id(mid)) {
|
||||
yyerror1(loc, "setter method cannot be defined in an endless method definition");
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef RIPPER
|
||||
# define Qnone 0
|
||||
# define Qnull 0
|
||||
|
@ -2477,9 +2489,7 @@ arg : lhs '=' arg_rhs
|
|||
}
|
||||
| defn_head f_paren_args '=' arg
|
||||
{
|
||||
if (is_attrset_id($<node>1->nd_mid)) {
|
||||
yyerror1(&@1, "setter method cannot be defined in an endless method definition");
|
||||
}
|
||||
endless_method_name(p, $<node>1, &@1);
|
||||
token_info_drop(p, "def", @1.beg_pos);
|
||||
restore_defun(p, $<node>1->nd_defn);
|
||||
/*%%%*/
|
||||
|
@ -2490,6 +2500,7 @@ arg : lhs '=' arg_rhs
|
|||
}
|
||||
| defn_head f_paren_args '=' arg modifier_rescue arg
|
||||
{
|
||||
endless_method_name(p, $<node>1, &@1);
|
||||
token_info_drop(p, "def", @1.beg_pos);
|
||||
restore_defun(p, $<node>1->nd_defn);
|
||||
/*%%%*/
|
||||
|
@ -2501,6 +2512,7 @@ arg : lhs '=' arg_rhs
|
|||
}
|
||||
| defs_head f_paren_args '=' arg
|
||||
{
|
||||
endless_method_name(p, $<node>1, &@1);
|
||||
restore_defun(p, $<node>1->nd_defn);
|
||||
/*%%%*/
|
||||
$$ = set_defun_body(p, $1, $2, $4, &@$);
|
||||
|
@ -2512,6 +2524,7 @@ arg : lhs '=' arg_rhs
|
|||
}
|
||||
| defs_head f_paren_args '=' arg modifier_rescue arg
|
||||
{
|
||||
endless_method_name(p, $<node>1, &@1);
|
||||
restore_defun(p, $<node>1->nd_defn);
|
||||
/*%%%*/
|
||||
$4 = rescued_expr(p, $4, $6, &@4, &@5, &@6);
|
||||
|
|
|
@ -660,11 +660,30 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
|
|||
}
|
||||
assert_equal true, thru_def
|
||||
assert_equal '[def(foo,[],bodystmt([void()]))]', parse('def foo ;end')
|
||||
end
|
||||
|
||||
thru_def = false
|
||||
tree = parse('def foo() = 42', :on_def) {thru_def = true}
|
||||
assert_equal true, thru_def
|
||||
def test_endless_def
|
||||
events = %i[on_def on_parse_error]
|
||||
thru = nil
|
||||
hook = ->(name, *) {thru[name] = true}
|
||||
|
||||
thru = {}
|
||||
tree = parse('def foo() = 42', events, &hook)
|
||||
assert_equal({on_def: true}, thru)
|
||||
assert_equal '[def(foo,[],42)]', tree
|
||||
|
||||
thru = {}
|
||||
tree = parse('def foo() = 42 rescue 0', events, &hook)
|
||||
assert_equal({on_def: true}, thru)
|
||||
assert_equal '[def(foo,[],rescue_mod(42,0))]', tree
|
||||
|
||||
thru = {}
|
||||
tree = parse('def foo=() = 42', events, &hook)
|
||||
assert_equal({on_def: true, on_parse_error: true}, thru)
|
||||
|
||||
thru = {}
|
||||
tree = parse('def foo=() = 42 rescue 0', events, &hook)
|
||||
assert_equal({on_def: true, on_parse_error: true}, thru)
|
||||
end
|
||||
|
||||
def test_defined
|
||||
|
@ -682,11 +701,30 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
|
|||
thru_parse_error = false
|
||||
tree = parse('def foo&.bar; end', :on_parse_error) {thru_parse_error = true}
|
||||
assert_equal(true, thru_parse_error)
|
||||
end
|
||||
|
||||
thru_defs = false
|
||||
tree = parse('def foo.bar() = 42', :on_defs) {thru_defs = true}
|
||||
assert_equal true, thru_defs
|
||||
def test_endless_defs
|
||||
events = %i[on_defs on_parse_error]
|
||||
thru = nil
|
||||
hook = ->(name, *) {thru[name] = true}
|
||||
|
||||
thru = {}
|
||||
tree = parse('def foo.bar() = 42', events, &hook)
|
||||
assert_equal({on_defs: true}, thru)
|
||||
assert_equal '[defs(vcall(foo),.,bar,[],42)]', tree
|
||||
|
||||
thru = {}
|
||||
tree = parse('def foo.bar() = 42 rescue 0', events, &hook)
|
||||
assert_equal({on_defs: true}, thru)
|
||||
assert_equal '[defs(vcall(foo),.,bar,[],rescue_mod(42,0))]', tree
|
||||
|
||||
thru = {}
|
||||
tree = parse('def foo.bar=() = 42', events, &hook)
|
||||
assert_equal({on_defs: true, on_parse_error: true}, thru)
|
||||
|
||||
thru = {}
|
||||
tree = parse('def foo.bar=() = 42 rescue 0', events, &hook)
|
||||
assert_equal({on_defs: true, on_parse_error: true}, thru)
|
||||
end
|
||||
|
||||
def test_do_block
|
||||
|
|
|
@ -1429,7 +1429,12 @@ eom
|
|||
end
|
||||
assert_equal("class ok", k.rescued("ok"))
|
||||
assert_equal("instance ok", k.new.rescued("ok"))
|
||||
assert_syntax_error('def foo=() = 42', /setter method cannot be defined in an endless method definition/)
|
||||
|
||||
error = /setter method cannot be defined in an endless method definition/
|
||||
assert_syntax_error('def foo=() = 42', error)
|
||||
assert_syntax_error('def obj.foo=() = 42', error)
|
||||
assert_syntax_error('def foo=() = 42 rescue nil', error)
|
||||
assert_syntax_error('def obj.foo=() = 42 rescue nil', error)
|
||||
end
|
||||
|
||||
def test_methoddef_in_cond
|
||||
|
|
Loading…
Add table
Reference in a new issue