Skip to content

Commit aae2df9

Browse files
committed
Make RubyVM::AST.of return a parent node of NODE_SCOPE
This change makes `RubyVM::AST.of` and `.node_id_for_backtrace_location` return a parent node of NODE_SCOPE (such as NODE_DEFN) instead of the NODE_SCOPE node itself. (In future, we may remove NODE_SCOPE, which is a bit hacky AST node.) This is preparation for [Feature #21543].
1 parent b5c8c97 commit aae2df9

File tree

6 files changed

+47
-23
lines changed

6 files changed

+47
-23
lines changed

compile.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9242,6 +9242,7 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
92429242
rb_node_init(RNODE(&scope_node), NODE_SCOPE);
92439243
scope_node.nd_tbl = tbl;
92449244
scope_node.nd_body = mandatory_node(iseq, node);
9245+
scope_node.nd_parent = NULL;
92459246
scope_node.nd_args = &args_node;
92469247

92479248
VALUE ast_value = rb_ruby_ast_new(RNODE(&scope_node));

iseq.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,18 @@ new_arena(void)
634634
return new_arena;
635635
}
636636

637+
static int
638+
prepare_node_id(const NODE *node)
639+
{
640+
if (!node) return -1;
641+
642+
if (nd_type(node) == NODE_SCOPE && RNODE_SCOPE(node)->nd_parent) {
643+
return nd_node_id(RNODE_SCOPE(node)->nd_parent);
644+
}
645+
646+
return nd_node_id(node);
647+
}
648+
637649
static VALUE
638650
prepare_iseq_build(rb_iseq_t *iseq,
639651
VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_code_location_t *code_location, const int node_id,
@@ -1031,7 +1043,7 @@ rb_iseq_new_with_opt(VALUE ast_value, VALUE name, VALUE path, VALUE realpath,
10311043
script_lines = ISEQ_BODY(parent)->variable.script_lines;
10321044
}
10331045

1034-
prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, node ? nd_node_id(node) : -1,
1046+
prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, prepare_node_id(node),
10351047
parent, isolated_depth, type, script_lines, option);
10361048

10371049
rb_iseq_compile_node(iseq, node);

parse.y

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,8 +1061,8 @@ rb_discard_node(struct parser_params *p, NODE *n)
10611061
rb_ast_delete_node(p->ast, n);
10621062
}
10631063

1064-
static rb_node_scope_t *rb_node_scope_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc);
1065-
static rb_node_scope_t *rb_node_scope_new2(struct parser_params *p, rb_ast_id_table_t *nd_tbl, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc);
1064+
static rb_node_scope_t *rb_node_scope_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, NODE *nd_parent, const YYLTYPE *loc);
1065+
static rb_node_scope_t *rb_node_scope_new2(struct parser_params *p, rb_ast_id_table_t *nd_tbl, rb_node_args_t *nd_args, NODE *nd_body, NODE *nd_parent, const YYLTYPE *loc);
10661066
static rb_node_block_t *rb_node_block_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc);
10671067
static rb_node_if_t *rb_node_if_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, NODE *nd_else, const YYLTYPE *loc, const YYLTYPE* if_keyword_loc, const YYLTYPE* then_keyword_loc, const YYLTYPE* end_keyword_loc);
10681068
static rb_node_unless_t *rb_node_unless_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, NODE *nd_else, const YYLTYPE *loc, const YYLTYPE *keyword_loc, const YYLTYPE *then_keyword_loc, const YYLTYPE *end_keyword_loc);
@@ -1169,8 +1169,8 @@ static rb_node_line_t *rb_node_line_new(struct parser_params *p, const YYLTYPE *
11691169
static rb_node_file_t *rb_node_file_new(struct parser_params *p, VALUE str, const YYLTYPE *loc);
11701170
static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE *loc);
11711171

1172-
#define NEW_SCOPE(a,b,loc) (NODE *)rb_node_scope_new(p,a,b,loc)
1173-
#define NEW_SCOPE2(t,a,b,loc) (NODE *)rb_node_scope_new2(p,t,a,b,loc)
1172+
#define NEW_SCOPE(a,b,c,loc) (NODE *)rb_node_scope_new(p,a,b,c,loc)
1173+
#define NEW_SCOPE2(t,a,b,c,loc) (NODE *)rb_node_scope_new2(p,t,a,b,c,loc)
11741174
#define NEW_BLOCK(a,loc) (NODE *)rb_node_block_new(p,a,loc)
11751175
#define NEW_IF(c,t,e,loc,ik_loc,tk_loc,ek_loc) (NODE *)rb_node_if_new(p,c,t,e,loc,ik_loc,tk_loc,ek_loc)
11761176
#define NEW_UNLESS(c,t,e,loc,k_loc,t_loc,e_loc) (NODE *)rb_node_unless_new(p,c,t,e,loc,k_loc,t_loc,e_loc)
@@ -1634,11 +1634,11 @@ aryptn_pre_args(struct parser_params *p, VALUE pre_arg, VALUE pre_args)
16341634
#define KWD2EID(t, v) keyword_##t
16351635

16361636
static NODE *
1637-
new_scope_body(struct parser_params *p, rb_node_args_t *args, NODE *body, const YYLTYPE *loc)
1637+
new_scope_body(struct parser_params *p, rb_node_args_t *args, NODE *body, NODE *parent, const YYLTYPE *loc)
16381638
{
16391639
body = remove_begin(body);
16401640
reduce_nodes(p, &body);
1641-
NODE *n = NEW_SCOPE(args, body, loc);
1641+
NODE *n = NEW_SCOPE(args, body, parent, loc);
16421642
nd_set_line(n, loc->end_pos.lineno);
16431643
set_line_body(body, loc->beg_pos.lineno);
16441644
return n;
@@ -2949,8 +2949,8 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
29492949
{
29502950
endless_method_name(p, $head->nd_mid, &@head);
29512951
restore_defun(p, $head);
2952-
$bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
29532952
($$ = $head->nd_def)->nd_loc = @$;
2953+
$bodystmt = new_scope_body(p, $args, $bodystmt, $$, &@$);
29542954
RNODE_DEFN($$)->nd_defn = $bodystmt;
29552955
/*% ripper: bodystmt!($:bodystmt, Qnil, Qnil, Qnil) %*/
29562956
/*% ripper: def!($:head, $:args, $:$) %*/
@@ -2960,8 +2960,8 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
29602960
{
29612961
endless_method_name(p, $head->nd_mid, &@head);
29622962
restore_defun(p, $head);
2963-
$bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
29642963
($$ = $head->nd_def)->nd_loc = @$;
2964+
$bodystmt = new_scope_body(p, $args, $bodystmt, $$, &@$);
29652965
RNODE_DEFS($$)->nd_defn = $bodystmt;
29662966
/*% ripper: bodystmt!($:bodystmt, Qnil, Qnil, Qnil) %*/
29672967
/*% ripper: defs!(*$:head[0..2], $:args, $:$) %*/
@@ -3176,7 +3176,7 @@ program : {
31763176
node = remove_begin(node);
31773177
void_expr(p, node);
31783178
}
3179-
p->eval_tree = NEW_SCOPE(0, block_append(p, p->eval_tree, $2), &@$);
3179+
p->eval_tree = NEW_SCOPE(0, block_append(p, p->eval_tree, $2), NULL, &@$);
31803180
/*% ripper[final]: program!($:2) %*/
31813181
local_pop(p);
31823182
}
@@ -3375,8 +3375,9 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
33753375
restore_block_exit(p, $allow_exits);
33763376
p->ctxt = $k_END;
33773377
{
3378-
NODE *scope = NEW_SCOPE2(0 /* tbl */, 0 /* args */, $compstmt /* body */, &@$);
3378+
NODE *scope = NEW_SCOPE2(0 /* tbl */, 0 /* args */, $compstmt /* body */, NULL /* parent */, &@$);
33793379
$$ = NEW_POSTEXE(scope, &@$, &@1, &@3, &@5);
3380+
RNODE_SCOPE(scope)->nd_parent = $$;
33803381
}
33813382
/*% ripper: END!($:compstmt) %*/
33823383
}
@@ -4567,9 +4568,10 @@ primary : inline_primary
45674568
}
45684569
/* {|*internal_id| <m> = internal_id; ... } */
45694570
args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@for_var), &@for_var);
4570-
scope = NEW_SCOPE2(tbl, args, $compstmt, &@$);
4571+
scope = NEW_SCOPE2(tbl, args, $compstmt, NULL, &@$);
45714572
YYLTYPE do_keyword_loc = $do == keyword_do_cond ? @do : NULL_LOC;
45724573
$$ = NEW_FOR($5, scope, &@$, &@k_for, &@keyword_in, &do_keyword_loc, &@k_end);
4574+
RNODE_SCOPE(scope)->nd_parent = $$;
45734575
fixpos($$, $for_var);
45744576
/*% ripper: for!($:for_var, $:expr_value, $:compstmt) %*/
45754577
}
@@ -4640,8 +4642,8 @@ primary : inline_primary
46404642
k_end
46414643
{
46424644
restore_defun(p, $head);
4643-
$bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
46444645
($$ = $head->nd_def)->nd_loc = @$;
4646+
$bodystmt = new_scope_body(p, $args, $bodystmt, $$, &@$);
46454647
RNODE_DEFN($$)->nd_defn = $bodystmt;
46464648
/*% ripper: def!($:head, $:args, $:bodystmt) %*/
46474649
local_pop(p);
@@ -4655,8 +4657,8 @@ primary : inline_primary
46554657
k_end
46564658
{
46574659
restore_defun(p, $head);
4658-
$bodystmt = new_scope_body(p, $args, $bodystmt, &@$);
46594660
($$ = $head->nd_def)->nd_loc = @$;
4661+
$bodystmt = new_scope_body(p, $args, $bodystmt, $$, &@$);
46604662
RNODE_DEFS($$)->nd_defn = $bodystmt;
46614663
/*% ripper: defs!(*$:head[0..2], $:args, $:bodystmt) %*/
46624664
local_pop(p);
@@ -11208,24 +11210,26 @@ node_newnode(struct parser_params *p, enum node_type type, size_t size, size_t a
1120811210
#define NODE_NEWNODE(node_type, type, loc) (type *)(node_newnode(p, node_type, sizeof(type), RUBY_ALIGNOF(type), loc))
1120911211

1121011212
static rb_node_scope_t *
11211-
rb_node_scope_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc)
11213+
rb_node_scope_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, NODE *nd_parent, const YYLTYPE *loc)
1121211214
{
1121311215
rb_ast_id_table_t *nd_tbl;
1121411216
nd_tbl = local_tbl(p);
1121511217
rb_node_scope_t *n = NODE_NEWNODE(NODE_SCOPE, rb_node_scope_t, loc);
1121611218
n->nd_tbl = nd_tbl;
1121711219
n->nd_body = nd_body;
11220+
n->nd_parent = nd_parent;
1121811221
n->nd_args = nd_args;
1121911222

1122011223
return n;
1122111224
}
1122211225

1122311226
static rb_node_scope_t *
11224-
rb_node_scope_new2(struct parser_params *p, rb_ast_id_table_t *nd_tbl, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc)
11227+
rb_node_scope_new2(struct parser_params *p, rb_ast_id_table_t *nd_tbl, rb_node_args_t *nd_args, NODE *nd_body, NODE *nd_parent, const YYLTYPE *loc)
1122511228
{
1122611229
rb_node_scope_t *n = NODE_NEWNODE(NODE_SCOPE, rb_node_scope_t, loc);
1122711230
n->nd_tbl = nd_tbl;
1122811231
n->nd_body = nd_body;
11232+
n->nd_parent = nd_parent;
1122911233
n->nd_args = nd_args;
1123011234

1123111235
return n;
@@ -11413,8 +11417,9 @@ static rb_node_class_t *
1141311417
rb_node_class_new(struct parser_params *p, NODE *nd_cpath, NODE *nd_body, NODE *nd_super, const YYLTYPE *loc, const YYLTYPE *class_keyword_loc, const YYLTYPE *inheritance_operator_loc, const YYLTYPE *end_keyword_loc)
1141411418
{
1141511419
/* Keep the order of node creation */
11416-
NODE *scope = NEW_SCOPE(0, nd_body, loc);
11420+
NODE *scope = NEW_SCOPE(0, nd_body, NULL, loc);
1141711421
rb_node_class_t *n = NODE_NEWNODE(NODE_CLASS, rb_node_class_t, loc);
11422+
RNODE_SCOPE(scope)->nd_parent = &n->node;
1141811423
n->nd_cpath = nd_cpath;
1141911424
n->nd_body = scope;
1142011425
n->nd_super = nd_super;
@@ -11429,8 +11434,9 @@ static rb_node_sclass_t *
1142911434
rb_node_sclass_new(struct parser_params *p, NODE *nd_recv, NODE *nd_body, const YYLTYPE *loc)
1143011435
{
1143111436
/* Keep the order of node creation */
11432-
NODE *scope = NEW_SCOPE(0, nd_body, loc);
11437+
NODE *scope = NEW_SCOPE(0, nd_body, NULL, loc);
1143311438
rb_node_sclass_t *n = NODE_NEWNODE(NODE_SCLASS, rb_node_sclass_t, loc);
11439+
RNODE_SCOPE(scope)->nd_parent = &n->node;
1143411440
n->nd_recv = nd_recv;
1143511441
n->nd_body = scope;
1143611442

@@ -11441,8 +11447,9 @@ static rb_node_module_t *
1144111447
rb_node_module_new(struct parser_params *p, NODE *nd_cpath, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *module_keyword_loc, const YYLTYPE *end_keyword_loc)
1144211448
{
1144311449
/* Keep the order of node creation */
11444-
NODE *scope = NEW_SCOPE(0, nd_body, loc);
11450+
NODE *scope = NEW_SCOPE(0, nd_body, NULL, loc);
1144511451
rb_node_module_t *n = NODE_NEWNODE(NODE_MODULE, rb_node_module_t, loc);
11452+
RNODE_SCOPE(scope)->nd_parent = &n->node;
1144611453
n->nd_cpath = nd_cpath;
1144711454
n->nd_body = scope;
1144811455
n->module_keyword_loc = *module_keyword_loc;
@@ -11455,8 +11462,9 @@ static rb_node_iter_t *
1145511462
rb_node_iter_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc)
1145611463
{
1145711464
/* Keep the order of node creation */
11458-
NODE *scope = NEW_SCOPE(nd_args, nd_body, loc);
11465+
NODE *scope = NEW_SCOPE(nd_args, nd_body, NULL, loc);
1145911466
rb_node_iter_t *n = NODE_NEWNODE(NODE_ITER, rb_node_iter_t, loc);
11467+
RNODE_SCOPE(scope)->nd_parent = &n->node;
1146011468
n->nd_body = scope;
1146111469
n->nd_iter = 0;
1146211470

@@ -11467,9 +11475,10 @@ static rb_node_lambda_t *
1146711475
rb_node_lambda_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *operator_loc, const YYLTYPE *opening_loc, const YYLTYPE *closing_loc)
1146811476
{
1146911477
/* Keep the order of node creation */
11470-
NODE *scope = NEW_SCOPE(nd_args, nd_body, loc);
11478+
NODE *scope = NEW_SCOPE(nd_args, nd_body, NULL, loc);
1147111479
YYLTYPE lambda_loc = code_loc_gen(operator_loc, closing_loc);
1147211480
rb_node_lambda_t *n = NODE_NEWNODE(NODE_LAMBDA, rb_node_lambda_t, &lambda_loc);
11481+
RNODE_SCOPE(scope)->nd_parent = &n->node;
1147311482
n->nd_body = scope;
1147411483
n->operator_loc = *operator_loc;
1147511484
n->opening_loc = *opening_loc;

rubyparser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ typedef struct RNode_SCOPE {
248248

249249
rb_ast_id_table_t *nd_tbl;
250250
struct RNode *nd_body;
251+
struct RNode *nd_parent;
251252
struct RNode_ARGS *nd_args;
252253
} rb_node_scope_t;
253254

test/ruby/test_ast.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ def test_keep_script_lines_for_of
801801
node_proc = RubyVM::AbstractSyntaxTree.of(proc, keep_script_lines: true)
802802
node_method = RubyVM::AbstractSyntaxTree.of(method, keep_script_lines: true)
803803

804-
assert_equal("{ 1 + 2 }", node_proc.source)
804+
assert_equal("Proc.new { 1 + 2 }", node_proc.source)
805805
assert_equal("def test_keep_script_lines_for_of\n", node_method.source.lines.first)
806806
end
807807

@@ -878,7 +878,7 @@ def test_e_option
878878
omit if ParserSupport.prism_enabled? || ParserSupport.prism_enabled_in_subprocess?
879879

880880
assert_in_out_err(["-e", "def foo; end; pp RubyVM::AbstractSyntaxTree.of(method(:foo)).type"],
881-
"", [":SCOPE"], [])
881+
"", [":DEFN"], [])
882882
end
883883

884884
def test_error_tolerant

vm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,6 +1541,7 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
15411541
rb_node_init(RNODE(&tmp_node), NODE_SCOPE);
15421542
tmp_node.nd_tbl = dyns;
15431543
tmp_node.nd_body = 0;
1544+
tmp_node.nd_parent = NULL;
15441545
tmp_node.nd_args = 0;
15451546

15461547
VALUE ast_value = rb_ruby_ast_new(RNODE(&tmp_node));

0 commit comments

Comments
 (0)