[前][次][番号順一覧][スレッド一覧]

ruby-changes:63324

From: Nobuyoshi <ko1@a...>
Date: Mon, 12 Oct 2020 01:53:57 +0900 (JST)
Subject: [ruby-changes:63324] 4ed0c33d13 (master): Prohibit setter method names in all kinds of endless methods

https://git.ruby-lang.org/ruby.git/commit/?id=4ed0c33d13

From 4ed0c33d13ff0d2544aaf36e8e4f071b900d10cd Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Mon, 12 Oct 2020 00:26:39 +0900
Subject: Prohibit setter method names in all kinds of endless methods

Also unwrap NODE_RIPPER to check the method name.

diff --git a/parse.y b/parse.y
index 1a6887e..f8d05ad 100644
--- a/parse.y
+++ b/parse.y
@@ -961,6 +961,18 @@ restore_defun(struct parser_params *p, NODE *name) https://github.com/ruby/ruby/blob/trunk/parse.y#L961
     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 https://github.com/ruby/ruby/blob/trunk/parse.y#L2489
 		    }
 		| 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 https://github.com/ruby/ruby/blob/trunk/parse.y#L2500
 		    }
 		| 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 https://github.com/ruby/ruby/blob/trunk/parse.y#L2512
 		    }
 		| 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 https://github.com/ruby/ruby/blob/trunk/parse.y#L2524
 		    }
 		| 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);
diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb
index 13064c2..4e1d233 100644
--- a/test/ripper/test_parser_events.rb
+++ b/test/ripper/test_parser_events.rb
@@ -660,11 +660,30 @@ class TestRipper::ParserEvents < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ripper/test_parser_events.rb#L660
     }
     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 https://github.com/ruby/ruby/blob/trunk/test/ripper/test_parser_events.rb#L701
     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
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index fb982e8..0542d4f 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -1429,7 +1429,12 @@ eom https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L1429
     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
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]