mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 08:33:58 +02:00
[Bug #19877] Literals cannot have singleton methods even in blocks
This commit is contained in:
parent
3f492921c8
commit
e8896a31d4
Notes:
git
2023-09-14 17:29:28 +00:00
2 changed files with 33 additions and 7 deletions
15
parse.y
15
parse.y
|
@ -917,6 +917,15 @@ set_embraced_location(NODE *node, const rb_code_location_t *beg, const rb_code_l
|
|||
nd_set_line(node, beg->end_pos.lineno);
|
||||
}
|
||||
|
||||
static NODE *
|
||||
last_expr_node(NODE *expr)
|
||||
{
|
||||
if (nd_type_p(expr, NODE_BLOCK)) {
|
||||
expr = expr->nd_end->nd_head;
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
#define yyparse ruby_yyparse
|
||||
|
||||
static NODE* cond(struct parser_params *p, NODE *node, const YYLTYPE *loc);
|
||||
|
@ -6050,16 +6059,18 @@ singleton : var_ref
|
|||
| '(' {SET_LEX_STATE(EXPR_BEG);} expr rparen
|
||||
{
|
||||
/*%%%*/
|
||||
switch (nd_type($3)) {
|
||||
NODE *expr = last_expr_node($3);
|
||||
switch (nd_type(expr)) {
|
||||
case NODE_STR:
|
||||
case NODE_DSTR:
|
||||
case NODE_XSTR:
|
||||
case NODE_DXSTR:
|
||||
case NODE_DREGX:
|
||||
case NODE_LIT:
|
||||
case NODE_DSYM:
|
||||
case NODE_LIST:
|
||||
case NODE_ZLIST:
|
||||
yyerror1(&@3, "can't define singleton method for literals");
|
||||
yyerror1(&expr->nd_loc, "can't define singleton method for literals");
|
||||
break;
|
||||
default:
|
||||
value_expr($3);
|
||||
|
|
|
@ -453,11 +453,16 @@ class TestParse < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_define_singleton_error
|
||||
assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /singleton method for literals/) do
|
||||
begin;
|
||||
def ("foo").foo; end
|
||||
end;
|
||||
end
|
||||
msg = /singleton method for literals/
|
||||
assert_parse_error(%q[def ("foo").foo; end], msg)
|
||||
assert_parse_error(%q[def (1).foo; end], msg)
|
||||
assert_parse_error(%q[def ((1;1)).foo; end], msg)
|
||||
assert_parse_error(%q[def ((;1)).foo; end], msg)
|
||||
assert_parse_error(%q[def ((1+1;1)).foo; end], msg)
|
||||
assert_parse_error(%q[def ((%s();1)).foo; end], msg)
|
||||
assert_parse_error(%q[def ((%w();1)).foo; end], msg)
|
||||
assert_parse_error(%q[def ("#{42}").foo; end], msg)
|
||||
assert_parse_error(%q[def (:"#{42}").foo; end], msg)
|
||||
end
|
||||
|
||||
def test_op_asgn1_with_block
|
||||
|
@ -1453,4 +1458,14 @@ x = __ENCODING__
|
|||
assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}}
|
||||
end
|
||||
=end
|
||||
|
||||
def assert_parse(code)
|
||||
assert_kind_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.parse(code))
|
||||
end
|
||||
|
||||
def assert_parse_error(code, message)
|
||||
assert_raise_with_message(SyntaxError, message) do
|
||||
RubyVM::AbstractSyntaxTree.parse(code)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue