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

ruby-changes:73930

From: yui-knk <ko1@a...>
Date: Sat, 8 Oct 2022 17:59:34 +0900 (JST)
Subject: [ruby-changes:73930] 4bfdf6d06d (master): Move `error` from top_stmts and top_stmt to stmt

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

From 4bfdf6d06ddbcf21345461038f2a9e3012f77268 Mon Sep 17 00:00:00 2001
From: yui-knk <spiketeika@g...>
Date: Sat, 1 Oct 2022 17:44:28 +0900
Subject: Move `error` from top_stmts and top_stmt to stmt

By this change, syntax error is recovered smaller units.
In the case below, "DEFN :bar" is same level with "CLASS :Foo"
now.

```
module Z
  class Foo
    foo.
  end

  def bar
  end
end
```

[Feature #19013]
---
 ast.c                   |  2 ++
 ext/objspace/objspace.c |  1 +
 node.c                  |  3 +++
 node.h                  |  2 ++
 parse.y                 | 14 ++++++--------
 test/irb/test_color.rb  |  5 +++++
 test/ruby/test_ast.rb   | 44 ++++++++++++++++++++++----------------------
 7 files changed, 41 insertions(+), 30 deletions(-)

diff --git a/ast.c b/ast.c
index 67275c47b3..c9d0b41fac 100644
--- a/ast.c
+++ b/ast.c
@@ -648,6 +648,8 @@ node_children(rb_ast_t *ast, const NODE *node) https://github.com/ruby/ruby/blob/trunk/ast.c#L648
                                         NEW_CHILD(ast, node->nd_pkwargs),
                                         kwrest);
         }
+      case NODE_ERROR:
+        return rb_ary_new_from_node_args(ast, 0);
       case NODE_ARGS_AUX:
       case NODE_LAST:
         break;
diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c
index 0b1b094325..ca08604c95 100644
--- a/ext/objspace/objspace.c
+++ b/ext/objspace/objspace.c
@@ -493,6 +493,7 @@ count_nodes(int argc, VALUE *argv, VALUE os) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L493
                 COUNT_NODE(NODE_ARYPTN);
                 COUNT_NODE(NODE_FNDPTN);
                 COUNT_NODE(NODE_HSHPTN);
+                COUNT_NODE(NODE_ERROR);
 #undef COUNT_NODE
               case NODE_LAST: break;
             }
diff --git a/node.c b/node.c
index 483e7fa8fb..c7469151ec 100644
--- a/node.c
+++ b/node.c
@@ -1098,6 +1098,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) https://github.com/ruby/ruby/blob/trunk/node.c#L1098
             F_NODE(nd_pkwrestarg, "keyword rest argument");
         }
         return;
+      case NODE_ERROR:
+        ANN("Broken input recovered by Error Tolerant mode");
+        return;
 
       case NODE_ARGS_AUX:
       case NODE_LAST:
diff --git a/node.h b/node.h
index d97c333ab5..2a27988ff5 100644
--- a/node.h
+++ b/node.h
@@ -125,6 +125,7 @@ enum node_type { https://github.com/ruby/ruby/blob/trunk/node.h#L125
     NODE_ARYPTN,
     NODE_HSHPTN,
     NODE_FNDPTN,
+    NODE_ERROR,
     NODE_LAST
 };
 
@@ -386,6 +387,7 @@ typedef struct RNode { https://github.com/ruby/ruby/blob/trunk/node.h#L387
 #define NEW_PREEXE(b,loc) NEW_SCOPE(b,loc)
 #define NEW_POSTEXE(b,loc) NEW_NODE(NODE_POSTEXE,0,b,0,loc)
 #define NEW_ATTRASGN(r,m,a,loc) NEW_NODE(NODE_ATTRASGN,r,m,a,loc)
+#define NEW_ERROR(loc) NEW_NODE(NODE_ERROR,0,0,0,loc)
 
 #define NODE_SPECIAL_REQUIRED_KEYWORD ((NODE *)-1)
 #define NODE_REQUIRED_KEYWORD_P(node) ((node)->nd_value == NODE_SPECIAL_REQUIRED_KEYWORD)
diff --git a/parse.y b/parse.y
index c0959a5e81..a8eadfebd3 100644
--- a/parse.y
+++ b/parse.y
@@ -1430,10 +1430,6 @@ top_stmts	: none https://github.com/ruby/ruby/blob/trunk/parse.y#L1430
 		    /*% %*/
 		    /*% ripper: stmts_add!($1, $3) %*/
 		    }
-		| error top_stmt
-		    {
-			$$ = remove_begin($2);
-		    }
 		;
 
 top_stmt	: stmt
@@ -1503,10 +1499,6 @@ stmts		: none https://github.com/ruby/ruby/blob/trunk/parse.y#L1499
 		    /*% %*/
 		    /*% ripper: stmts_add!($1, $3) %*/
 		    }
-		| error stmt
-		    {
-			$$ = remove_begin($2);
-		    }
 		;
 
 stmt_or_begin	: stmt
@@ -1659,6 +1651,12 @@ stmt		: keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem https://github.com/ruby/ruby/blob/trunk/parse.y#L1651
 		    /*% ripper: massign!($1, $4) %*/
 		    }
 		| expr
+		| error
+		    {
+		    /*%%%*/
+			$$ = NEW_ERROR(&@$);
+		    /*% %*/
+		    }
 		;
 
 command_asgn	: lhs '=' lex_ctxt command_rhs
diff --git a/test/irb/test_color.rb b/test/irb/test_color.rb
index dc394f9d68..8de03a5e8e 100644
--- a/test/irb/test_color.rb
+++ b/test/irb/test_color.rb
@@ -114,6 +114,11 @@ module TestIRB https://github.com/ruby/ruby/blob/trunk/test/irb/test_color.rb#L114
           "class bad; end" => "#{GREEN}class#{CLEAR} #{RED}#{REVERSE}bad#{CLEAR}; #{GREEN}end#{CLEAR}",
           "def req(@a) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}@a#{CLEAR}) #{GREEN}end#{CLEAR}",
         })
+        if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0')
+          tests.merge!({
+            "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}true#{CLEAR}#{RED}#{REVERSE})#{CLEAR} #{RED}#{REVERSE}end#{CLEAR}",
+          })
+        end
       else
         if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
           tests.merge!({
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index 033a09b4c0..cda325c1fd 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -981,30 +981,30 @@ dummy https://github.com/ruby/ruby/blob/trunk/test/ruby/test_ast.rb#L981
              tbl: []
              args: nil
              body:
-               (BLOCK@1:8-8:3 (BEGIN@1:8-1:8 nil)
-                  (CLASS@2:2-8:3 (COLON2@2:8-2:11 nil :Foo) nil
-                     (SCOPE@2:2-8:3
+               (BLOCK@1:8-7:5 (BEGIN@1:8-1:8 nil)
+                  (CLASS@2:2-4:5 (COLON2@2:8-2:11 nil :Foo) nil
+                     (SCOPE@2:2-4:5
                       tbl: []
                       args: nil
-                      body:
-                        (DEFN@6:2-7:5
-                         mid: :bar
-                         body:
-                           (SCOPE@6:2-7:5
-                            tbl: []
-                            args:
-                              (ARGS@6:9-6:9
-                               pre_num: 0
-                               pre_init: nil
-                               opt: nil
-                               first_post: nil
-                               post_num: 0
-                               post_init: nil
-                               rest: nil
-                               kw: nil
-                               kwrest: nil
-                               block: nil)
-                            body: nil))))))))
+                      body: (BLOCK@2:11-4:5 (BEGIN@2:11-2:11 nil) (ERROR@3:4-4:5))))
+                  (DEFN@6:2-7:5
+                   mid: :bar
+                   body:
+                     (SCOPE@6:2-7:5
+                      tbl: []
+                      args:
+                        (ARGS@6:9-6:9
+                         pre_num: 0
+                         pre_init: nil
+                         opt: nil
+                         first_post: nil
+                         post_num: 0
+                         post_init: nil
+                         rest: nil
+                         kw: nil
+                         kwrest: nil
+                         block: nil)
+                      body: nil))))))
     EXP
   end
 end
-- 
cgit v1.2.1


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

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