Refactor NODE_DEF_TEMP

Use `NODE_DEF_TEMP` as the wrapper of `NODE_DEFS` in ripper, not only
of `NODE_DEFN`, so that `endless_method_name` works consistently.
This commit is contained in:
Nobuyoshi Nakada 2023-10-09 17:32:44 +09:00
parent ceec988f2e
commit 4c00ab7fd6

171
parse.y
View File

@ -1104,11 +1104,22 @@ parser_node_name(int node)
typedef struct RNode_DEF_TEMP { typedef struct RNode_DEF_TEMP {
NODE node; NODE node;
ID nd_vid; /* for NODE_DEFN/NODE_DEFS */
#ifndef RIPPER
struct RNode *nd_recv;
ID nd_mid; ID nd_mid;
struct RNode *nd_head; #else
long nd_nth; VALUE nd_recv;
struct lex_context ctxt; VALUE nd_mid;
VALUE dot_or_colon;
#endif
struct {
ID cur_arg;
int max_numparam;
NODE *numparam_save;
struct lex_context ctxt;
} save;
} rb_node_def_temp_t; } rb_node_def_temp_t;
#define RNODE_DEF_TEMP(node) ((struct RNode_DEF_TEMP *)(node)) #define RNODE_DEF_TEMP(node) ((struct RNode_DEF_TEMP *)(node))
@ -1116,12 +1127,12 @@ typedef struct RNode_DEF_TEMP {
static rb_node_break_t *rb_node_break_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc); static rb_node_break_t *rb_node_break_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc);
static rb_node_next_t *rb_node_next_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc); static rb_node_next_t *rb_node_next_new(struct parser_params *p, NODE *nd_stts, const YYLTYPE *loc);
static rb_node_redo_t *rb_node_redo_new(struct parser_params *p, const YYLTYPE *loc); static rb_node_redo_t *rb_node_redo_new(struct parser_params *p, const YYLTYPE *loc);
static rb_node_def_temp_t *rb_node_def_temp_new(struct parser_params *p, ID nd_vid, ID nd_mid, NODE *nd_head, long nd_nth, struct lex_context ctxt, const YYLTYPE *loc); static rb_node_def_temp_t *rb_node_def_temp_new(struct parser_params *p, const YYLTYPE *loc);
#define NEW_BREAK(s,loc) (NODE *)rb_node_break_new(p,s,loc) #define NEW_BREAK(s,loc) (NODE *)rb_node_break_new(p,s,loc)
#define NEW_NEXT(s,loc) (NODE *)rb_node_next_new(p,s,loc) #define NEW_NEXT(s,loc) (NODE *)rb_node_next_new(p,s,loc)
#define NEW_REDO(loc) (NODE *)rb_node_redo_new(p,loc) #define NEW_REDO(loc) (NODE *)rb_node_redo_new(p,loc)
#define NEW_DEF_TEMP(v,m,h,n,c,loc) (NODE *)rb_node_def_temp_new(p,v,m,h,n,c,loc) #define NEW_DEF_TEMP(loc) rb_node_def_temp_new(p,loc)
/* Make a new internal node, which should not be appeared in the /* Make a new internal node, which should not be appeared in the
* result AST and does not have node_id and location. */ * result AST and does not have node_id and location. */
@ -1563,13 +1574,12 @@ static VALUE heredoc_dedent(struct parser_params*,VALUE);
#define KWD2EID(t, v) keyword_##t #define KWD2EID(t, v) keyword_##t
static NODE * static NODE *
set_defun_body(struct parser_params *p, NODE *n, rb_node_args_t *args, NODE *body, const YYLTYPE *loc) new_scope_body(struct parser_params *p, rb_node_args_t *args, NODE *body, const YYLTYPE *loc)
{ {
body = remove_begin(body); body = remove_begin(body);
reduce_nodes(p, &body); reduce_nodes(p, &body);
RNODE_DEFN(n)->nd_defn = NEW_SCOPE(args, body, loc); NODE *n = NEW_SCOPE(args, body, loc);
n->nd_loc = *loc; nd_set_line(n, loc->end_pos.lineno);
nd_set_line(RNODE_DEFN(n)->nd_defn, loc->end_pos.lineno);
set_line_body(body, loc->beg_pos.lineno); set_line_body(body, loc->beg_pos.lineno);
return n; return n;
} }
@ -1599,27 +1609,22 @@ next_rescue_context(struct lex_context *next, const struct lex_context *outer, e
} }
static void static void
restore_defun(struct parser_params *p, NODE *name) restore_defun(struct parser_params *p, rb_node_def_temp_t *temp)
{ {
/* See: def_name action */ /* See: def_name action */
rb_node_def_temp_t *temp = RNODE_DEF_TEMP(name); struct lex_context ctxt = temp->save.ctxt;
struct lex_context ctxt = temp->ctxt; p->cur_arg = temp->save.cur_arg;
p->cur_arg = temp->nd_vid;
p->ctxt.in_def = ctxt.in_def; p->ctxt.in_def = ctxt.in_def;
p->ctxt.shareable_constant_value = ctxt.shareable_constant_value; p->ctxt.shareable_constant_value = ctxt.shareable_constant_value;
p->ctxt.in_rescue = ctxt.in_rescue; p->ctxt.in_rescue = ctxt.in_rescue;
p->max_numparam = (int)temp->nd_nth; p->max_numparam = temp->save.max_numparam;
numparam_pop(p, temp->nd_head); numparam_pop(p, temp->save.numparam_save);
clear_block_exit(p, true); clear_block_exit(p, true);
} }
static void static void
endless_method_name(struct parser_params *p, NODE *defn, const YYLTYPE *loc) endless_method_name(struct parser_params *p, ID mid, const YYLTYPE *loc)
{ {
#ifdef RIPPER
defn = RNODE_DEFN(defn)->nd_defn;
#endif
ID mid = RNODE_DEFN(defn)->nd_mid;
if (is_attrset_id(mid)) { if (is_attrset_id(mid)) {
yyerror1(loc, "setter method cannot be defined in an endless method definition"); yyerror1(loc, "setter method cannot be defined in an endless method definition");
} }
@ -1972,6 +1977,7 @@ get_nd_args(struct parser_params *p, NODE *node)
rb_node_kw_arg_t *node_kw_arg; rb_node_kw_arg_t *node_kw_arg;
rb_node_block_pass_t *node_block_pass; rb_node_block_pass_t *node_block_pass;
rb_node_masgn_t *node_masgn; rb_node_masgn_t *node_masgn;
struct RNode_DEF_TEMP *node_def_temp;
ID id; ID id;
int num; int num;
st_table *tbl; st_table *tbl;
@ -2052,7 +2058,8 @@ get_nd_args(struct parser_params *p, NODE *node)
%type <node> singleton strings string string1 xstring regexp %type <node> singleton strings string string1 xstring regexp
%type <node> string_contents xstring_contents regexp_contents string_content %type <node> string_contents xstring_contents regexp_contents string_content
%type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word %type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
%type <node> literal numeric simple_numeric ssym dsym symbol cpath def_name defn_head defs_head %type <node> literal numeric simple_numeric ssym dsym symbol cpath
/*ripper*/ %type <node_def_temp> defn_head defs_head k_def
%type <node> top_compstmt top_stmts top_stmt begin_block endless_arg endless_command %type <node> top_compstmt top_stmts top_stmt begin_block endless_arg endless_command
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
%type <node> expr_value expr_value_do arg_value primary_value rel_expr %type <node> expr_value expr_value_do arg_value primary_value rel_expr
@ -2091,7 +2098,7 @@ get_nd_args(struct parser_params *p, NODE *node)
%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg %type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
%type <id> f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon %type <id> f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon
%type <id> p_kwrest p_kwnorest p_any_kwrest p_kw_label %type <id> p_kwrest p_kwnorest p_any_kwrest p_kw_label
%type <id> f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var %type <id> f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var def_name
%type <ctxt> lex_ctxt begin_defined k_class k_module k_END k_rescue k_ensure after_rescue %type <ctxt> lex_ctxt begin_defined k_class k_module k_END k_rescue k_ensure after_rescue
%type <tbl> p_lparen p_lbracket %type <tbl> p_lparen p_lbracket
%token END_OF_INPUT 0 "end-of-input" %token END_OF_INPUT 0 "end-of-input"
@ -2561,26 +2568,26 @@ command_asgn : lhs '=' lex_ctxt command_rhs
} }
| defn_head[head] f_opt_paren_args[args] '=' endless_command[bodystmt] | defn_head[head] f_opt_paren_args[args] '=' endless_command[bodystmt]
{ {
endless_method_name(p, $<node>head, &@head); endless_method_name(p, get_id($head->nd_mid), &@head);
restore_defun(p, RNODE_DEFN($head)->nd_defn); restore_defun(p, $head);
/*%%%*/ /*%%%*/
$$ = set_defun_body(p, $head, $args, $bodystmt, &@$); $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
$$ = NEW_DEFN($head->nd_mid, $bodystmt, &@$);
/*% %*/ /*% %*/
/*% ripper: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/ /*% ripper[$bodystmt]: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/
/*% ripper: def!($head, $args, $$) %*/ /*% ripper: def!($head->nd_mid, $args, $bodystmt) %*/
local_pop(p); local_pop(p);
} }
| defs_head[head] f_opt_paren_args[args] '=' endless_command[bodystmt] | defs_head[head] f_opt_paren_args[args] '=' endless_command[bodystmt]
{ {
endless_method_name(p, $<node>head, &@head); endless_method_name(p, get_id($head->nd_mid), &@head);
restore_defun(p, RNODE_DEFS($head)->nd_defn); restore_defun(p, $head);
/*%%%*/ /*%%%*/
$$ = set_defun_body(p, $head, $args, $bodystmt, &@$); $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
/*% $$ = NEW_DEFS($head->nd_recv, $head->nd_mid, $bodystmt, &@$);
$head = get_value($head); /*% %*/
%*/ /*% ripper[$bodystmt]: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/
/*% ripper: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/ /*% ripper: defs!($head->nd_recv, $head->dot_or_colon, $head->nd_mid, $args, $bodystmt) %*/
/*% ripper: defs!(AREF($head, 0), AREF($head, 1), AREF($head, 2), $args, $$) %*/
local_pop(p); local_pop(p);
} }
| backref tOP_ASGN lex_ctxt command_rhs | backref tOP_ASGN lex_ctxt command_rhs
@ -2693,28 +2700,23 @@ expr : command_call
def_name : fname def_name : fname
{ {
ID fname = get_id($1); ID fname = get_id($1);
ID cur_arg = p->cur_arg;
struct lex_context ctxt = p->ctxt;
numparam_name(p, fname); numparam_name(p, fname);
NODE *save = numparam_push(p);
local_push(p, 0); local_push(p, 0);
p->cur_arg = 0; p->cur_arg = 0;
p->ctxt.in_def = 1; p->ctxt.in_def = 1;
p->ctxt.in_rescue = before_rescue; p->ctxt.in_rescue = before_rescue;
$<node>$ = NEW_DEF_TEMP(cur_arg, fname, save, p->max_numparam, ctxt, &@$); $$ = $1;
/*%%%*/
/*%
$$ = NEW_RIPPER(fname, get_value($1), $$, &NULL_LOC);
%*/
} }
; ;
defn_head : k_def def_name defn_head : k_def def_name
{ {
$$ = $2; $$ = $k_def;
$$->nd_mid = $def_name;
/*%%%*/ /*%%%*/
$$ = NEW_DEFN(RNODE_DEF_TEMP($$)->nd_mid, $$, &@$); /*%
/*% %*/ add_mark_object(p, $def_name);
%*/
} }
; ;
@ -2726,13 +2728,14 @@ defs_head : k_def singleton dot_or_colon
def_name def_name
{ {
SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); /* force for args */ SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); /* force for args */
$$ = $def_name; $$ = $k_def;
$$->nd_recv = $singleton;
$$->nd_mid = $def_name;
/*%%%*/ /*%%%*/
$$ = NEW_DEFS($singleton, RNODE_DEF_TEMP($$)->nd_mid, $$, &@$);
/*% /*%
VALUE ary = rb_ary_new_from_args(3, $singleton, $dot_or_colon, get_value($$)); add_mark_object(p, $singleton);
add_mark_object(p, ary); add_mark_object(p, $def_name);
RNODE_RIPPER($$)->nd_rval = ary; $$->dot_or_colon = add_mark_object(p, $dot_or_colon);
%*/ %*/
} }
; ;
@ -3502,26 +3505,26 @@ arg : lhs '=' lex_ctxt arg_rhs
} }
| defn_head[head] f_opt_paren_args[args] '=' endless_arg[bodystmt] | defn_head[head] f_opt_paren_args[args] '=' endless_arg[bodystmt]
{ {
endless_method_name(p, $<node>head, &@head); endless_method_name(p, get_id($head->nd_mid), &@head);
restore_defun(p, RNODE_DEFN($head)->nd_defn); restore_defun(p, $head);
/*%%%*/ /*%%%*/
$$ = set_defun_body(p, $head, $2, $bodystmt, &@$); $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
$$ = NEW_DEFN($head->nd_mid, $bodystmt, &@$);
/*% %*/ /*% %*/
/*% ripper: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/ /*% ripper[$bodystmt]: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/
/*% ripper: def!($head, $2, $$) %*/ /*% ripper: def!($head->nd_mid, $args, $bodystmt) %*/
local_pop(p); local_pop(p);
} }
| defs_head[head] f_opt_paren_args[args] '=' endless_arg[bodystmt] | defs_head[head] f_opt_paren_args[args] '=' endless_arg[bodystmt]
{ {
endless_method_name(p, $<node>head, &@head); endless_method_name(p, get_id($head->nd_mid), &@head);
restore_defun(p, RNODE_DEFS($head)->nd_defn); restore_defun(p, $head);
/*%%%*/ /*%%%*/
$$ = set_defun_body(p, $head, $args, $bodystmt, &@$); $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
/*% $$ = NEW_DEFS($head->nd_recv, $head->nd_mid, $bodystmt, &@$);
$head = get_value($head); /*% %*/
%*/ /*% ripper[$bodystmt]: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/
/*% ripper: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/ /*% ripper: defs!($head->nd_recv, $head->dot_or_colon, $head->nd_mid, $args, $bodystmt) %*/
/*% ripper: defs!(AREF($head, 0), AREF($head, 1), AREF($head, 2), $args, $$) %*/
local_pop(p); local_pop(p);
} }
| primary | primary
@ -4197,11 +4200,12 @@ primary : literal
bodystmt bodystmt
k_end k_end
{ {
restore_defun(p, RNODE_DEFN($head)->nd_defn); restore_defun(p, $head);
/*%%%*/ /*%%%*/
$$ = set_defun_body(p, $head, $args, $bodystmt, &@$); $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
$$ = NEW_DEFN($head->nd_mid, $bodystmt, &@$);
/*% %*/ /*% %*/
/*% ripper: def!($head, $args, $bodystmt) %*/ /*% ripper: def!($head->nd_mid, $args, $bodystmt) %*/
local_pop(p); local_pop(p);
} }
| defs_head[head] | defs_head[head]
@ -4214,13 +4218,12 @@ primary : literal
bodystmt bodystmt
k_end k_end
{ {
restore_defun(p, RNODE_DEFS($head)->nd_defn); restore_defun(p, $head);
/*%%%*/ /*%%%*/
$$ = set_defun_body(p, $head, $args, $bodystmt, &@$); $bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
/*% $$ = NEW_DEFS($head->nd_recv, $head->nd_mid, $bodystmt, &@$);
$head = get_value($head); /*% %*/
%*/ /*% ripper: defs!($head->nd_recv, $head->dot_or_colon, $head->nd_mid, $args, $bodystmt) %*/
/*% ripper: defs!(AREF($head, 0), AREF($head, 1), AREF($head, 2), $args, $bodystmt) %*/
local_pop(p); local_pop(p);
} }
| keyword_break | keyword_break
@ -4364,6 +4367,7 @@ k_module : keyword_module
k_def : keyword_def k_def : keyword_def
{ {
token_info_push(p, "def", &@$); token_info_push(p, "def", &@$);
$$ = NEW_DEF_TEMP(&@$);
p->ctxt.in_argdef = 1; p->ctxt.in_argdef = 1;
} }
; ;
@ -12234,14 +12238,21 @@ rb_node_redo_new(struct parser_params *p, const YYLTYPE *loc)
} }
static rb_node_def_temp_t * static rb_node_def_temp_t *
rb_node_def_temp_new(struct parser_params *p, ID nd_vid, ID nd_mid, NODE *nd_head, long nd_nth, struct lex_context ctxt, const YYLTYPE *loc) rb_node_def_temp_new(struct parser_params *p, const YYLTYPE *loc)
{ {
rb_node_def_temp_t *n = NODE_NEWNODE((enum node_type)NODE_DEF_TEMP, rb_node_def_temp_t, loc); rb_node_def_temp_t *n = NODE_NEWNODE((enum node_type)NODE_DEF_TEMP, rb_node_def_temp_t, loc);
n->nd_vid = nd_vid; n->save.cur_arg = p->cur_arg;
n->nd_mid = nd_mid; n->save.numparam_save = numparam_push(p);
n->nd_head = nd_head; n->save.max_numparam = p->max_numparam;
n->nd_nth = nd_nth; n->save.ctxt = p->ctxt;
n->ctxt = ctxt; #ifdef RIPPER
n->nd_recv = Qnil;
n->nd_mid = Qnil;
n->dot_or_colon = Qnil;
#else
n->nd_recv = 0;
n->nd_mid = 0;
#endif
return n; return n;
} }