Skip to content

Commit 4009b71

Browse files
authored
[Bug #21974] Fix RubyVM::AST inspection for ::Foo = 1 (ruby#16642)
* Fix AST CDECL children for top-level constants * Simplify cdecl AST regression test
1 parent 3319be0 commit 4009b71

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

ast.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,19 @@ rest_arg(VALUE ast_value, const NODE *rest_arg)
404404
return NODE_NAMED_REST_P(rest_arg) ? NEW_CHILD(ast_value, rest_arg) : no_name_rest();
405405
}
406406

407+
static ID
408+
node_colon_name(const NODE *node)
409+
{
410+
switch (nd_type(node)) {
411+
case NODE_COLON2:
412+
return RNODE_COLON2(node)->nd_mid;
413+
case NODE_COLON3:
414+
return RNODE_COLON3(node)->nd_mid;
415+
default:
416+
rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
417+
}
418+
}
419+
407420
static VALUE
408421
node_children(VALUE ast_value, const NODE *node)
409422
{
@@ -497,7 +510,7 @@ node_children(VALUE ast_value, const NODE *node)
497510
if (RNODE_CDECL(node)->nd_vid) {
498511
return rb_ary_new_from_args(2, ID2SYM(RNODE_CDECL(node)->nd_vid), NEW_CHILD(ast_value, RNODE_CDECL(node)->nd_value));
499512
}
500-
return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_CDECL(node)->nd_else), ID2SYM(RNODE_COLON2(RNODE_CDECL(node)->nd_else)->nd_mid), NEW_CHILD(ast_value, RNODE_CDECL(node)->nd_value));
513+
return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_CDECL(node)->nd_else), ID2SYM(node_colon_name(RNODE_CDECL(node)->nd_else)), NEW_CHILD(ast_value, RNODE_CDECL(node)->nd_value));
501514
case NODE_OP_ASGN1:
502515
return rb_ary_new_from_args(4, NEW_CHILD(ast_value, RNODE_OP_ASGN1(node)->nd_recv),
503516
ID2SYM(RNODE_OP_ASGN1(node)->nd_mid),

test/ruby/test_ast.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,17 @@ def test_parse_file_raises_syntax_error
215215
end
216216
end
217217

218+
def test_cdecl_children_with_toplevel_constant_path
219+
# [Bug #21974]
220+
children = parse("::Foo = 1").children[2].children
221+
222+
assert_equal(:COLON3, children[0].type)
223+
assert_equal([:Foo], children[0].children)
224+
assert_equal(:Foo, children[1])
225+
assert_equal(:INTEGER, children[2].type)
226+
assert_equal([1], children[2].children)
227+
end
228+
218229
def assert_parse(code, warning: '')
219230
node = assert_warning(warning) {RubyVM::AbstractSyntaxTree.parse(code)}
220231
assert_kind_of(RubyVM::AbstractSyntaxTree::Node, node, code)

0 commit comments

Comments
 (0)