mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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]
This commit is contained in:
parent
4f24f3ea94
commit
4bfdf6d06d
Notes:
git
2022-10-08 17:59:34 +09:00
7 changed files with 41 additions and 30 deletions
2
ast.c
2
ast.c
|
@ -648,6 +648,8 @@ node_children(rb_ast_t *ast, const NODE *node)
|
||||||
NEW_CHILD(ast, node->nd_pkwargs),
|
NEW_CHILD(ast, node->nd_pkwargs),
|
||||||
kwrest);
|
kwrest);
|
||||||
}
|
}
|
||||||
|
case NODE_ERROR:
|
||||||
|
return rb_ary_new_from_node_args(ast, 0);
|
||||||
case NODE_ARGS_AUX:
|
case NODE_ARGS_AUX:
|
||||||
case NODE_LAST:
|
case NODE_LAST:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -493,6 +493,7 @@ count_nodes(int argc, VALUE *argv, VALUE os)
|
||||||
COUNT_NODE(NODE_ARYPTN);
|
COUNT_NODE(NODE_ARYPTN);
|
||||||
COUNT_NODE(NODE_FNDPTN);
|
COUNT_NODE(NODE_FNDPTN);
|
||||||
COUNT_NODE(NODE_HSHPTN);
|
COUNT_NODE(NODE_HSHPTN);
|
||||||
|
COUNT_NODE(NODE_ERROR);
|
||||||
#undef COUNT_NODE
|
#undef COUNT_NODE
|
||||||
case NODE_LAST: break;
|
case NODE_LAST: break;
|
||||||
}
|
}
|
||||||
|
|
3
node.c
3
node.c
|
@ -1098,6 +1098,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
||||||
F_NODE(nd_pkwrestarg, "keyword rest argument");
|
F_NODE(nd_pkwrestarg, "keyword rest argument");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case NODE_ERROR:
|
||||||
|
ANN("Broken input recovered by Error Tolerant mode");
|
||||||
|
return;
|
||||||
|
|
||||||
case NODE_ARGS_AUX:
|
case NODE_ARGS_AUX:
|
||||||
case NODE_LAST:
|
case NODE_LAST:
|
||||||
|
|
2
node.h
2
node.h
|
@ -125,6 +125,7 @@ enum node_type {
|
||||||
NODE_ARYPTN,
|
NODE_ARYPTN,
|
||||||
NODE_HSHPTN,
|
NODE_HSHPTN,
|
||||||
NODE_FNDPTN,
|
NODE_FNDPTN,
|
||||||
|
NODE_ERROR,
|
||||||
NODE_LAST
|
NODE_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -386,6 +387,7 @@ typedef struct RNode {
|
||||||
#define NEW_PREEXE(b,loc) NEW_SCOPE(b,loc)
|
#define NEW_PREEXE(b,loc) NEW_SCOPE(b,loc)
|
||||||
#define NEW_POSTEXE(b,loc) NEW_NODE(NODE_POSTEXE,0,b,0,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_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_SPECIAL_REQUIRED_KEYWORD ((NODE *)-1)
|
||||||
#define NODE_REQUIRED_KEYWORD_P(node) ((node)->nd_value == NODE_SPECIAL_REQUIRED_KEYWORD)
|
#define NODE_REQUIRED_KEYWORD_P(node) ((node)->nd_value == NODE_SPECIAL_REQUIRED_KEYWORD)
|
||||||
|
|
14
parse.y
14
parse.y
|
@ -1430,10 +1430,6 @@ top_stmts : none
|
||||||
/*% %*/
|
/*% %*/
|
||||||
/*% ripper: stmts_add!($1, $3) %*/
|
/*% ripper: stmts_add!($1, $3) %*/
|
||||||
}
|
}
|
||||||
| error top_stmt
|
|
||||||
{
|
|
||||||
$$ = remove_begin($2);
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
top_stmt : stmt
|
top_stmt : stmt
|
||||||
|
@ -1503,10 +1499,6 @@ stmts : none
|
||||||
/*% %*/
|
/*% %*/
|
||||||
/*% ripper: stmts_add!($1, $3) %*/
|
/*% ripper: stmts_add!($1, $3) %*/
|
||||||
}
|
}
|
||||||
| error stmt
|
|
||||||
{
|
|
||||||
$$ = remove_begin($2);
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
stmt_or_begin : stmt
|
stmt_or_begin : stmt
|
||||||
|
@ -1659,6 +1651,12 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
|
||||||
/*% ripper: massign!($1, $4) %*/
|
/*% ripper: massign!($1, $4) %*/
|
||||||
}
|
}
|
||||||
| expr
|
| expr
|
||||||
|
| error
|
||||||
|
{
|
||||||
|
/*%%%*/
|
||||||
|
$$ = NEW_ERROR(&@$);
|
||||||
|
/*% %*/
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
command_asgn : lhs '=' lex_ctxt command_rhs
|
command_asgn : lhs '=' lex_ctxt command_rhs
|
||||||
|
|
|
@ -114,6 +114,11 @@ module TestIRB
|
||||||
"class bad; end" => "#{GREEN}class#{CLEAR} #{RED}#{REVERSE}bad#{CLEAR}; #{GREEN}end#{CLEAR}",
|
"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}",
|
"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
|
else
|
||||||
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
|
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
|
||||||
tests.merge!({
|
tests.merge!({
|
||||||
|
|
|
@ -981,12 +981,12 @@ dummy
|
||||||
tbl: []
|
tbl: []
|
||||||
args: nil
|
args: nil
|
||||||
body:
|
body:
|
||||||
(BLOCK@1:8-8:3 (BEGIN@1:8-1:8 nil)
|
(BLOCK@1:8-7:5 (BEGIN@1:8-1:8 nil)
|
||||||
(CLASS@2:2-8:3 (COLON2@2:8-2:11 nil :Foo) nil
|
(CLASS@2:2-4:5 (COLON2@2:8-2:11 nil :Foo) nil
|
||||||
(SCOPE@2:2-8:3
|
(SCOPE@2:2-4:5
|
||||||
tbl: []
|
tbl: []
|
||||||
args: nil
|
args: nil
|
||||||
body:
|
body: (BLOCK@2:11-4:5 (BEGIN@2:11-2:11 nil) (ERROR@3:4-4:5))))
|
||||||
(DEFN@6:2-7:5
|
(DEFN@6:2-7:5
|
||||||
mid: :bar
|
mid: :bar
|
||||||
body:
|
body:
|
||||||
|
@ -1004,7 +1004,7 @@ dummy
|
||||||
kw: nil
|
kw: nil
|
||||||
kwrest: nil
|
kwrest: nil
|
||||||
block: nil)
|
block: nil)
|
||||||
body: nil))))))))
|
body: nil))))))
|
||||||
EXP
|
EXP
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue