8000 Implement COLON2 and COLON3 NODE locations by ydah · Pull Request #11987 · ruby/ruby · GitHub
[go: up one dir, main page]

Skip to content

Implement COLON2 and COLON3 NODE locations #11987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,16 @@ node_locations(VALUE ast_value, const NODE *node)
location_new(&RNODE_CLASS(node)->class_keyword_loc),
location_new(&RNODE_CLASS(node)->inheritance_operator_loc),
location_new(&RNODE_CLASS(node)->end_keyword_loc));
case NODE_COLON2:
return rb_ary_new_from_args(3,
location_new(nd_code_loc(node)),
location_new(&RNODE_COLON2(node)->delimiter_loc),
location_new(&RNODE_COLON2(node)->name_loc));
case NODE_COLON3:
return rb_ary_new_from_args(3,
location_new(nd_code_loc(node)),
location_new(&RNODE_COLON3(node)->delimiter_loc),
location_new(&RNODE_COLON3(node)->name_loc));
case NODE_DOT2:
return rb_ary_new_from_args(2,
location_new(nd_code_loc(node)),
Expand Down
6 changes: 5 additions & 1 deletion node_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -1027,15 +1027,19 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
ANN("format: [nd_head]::[nd_mid]");
ANN("example: M::C");
F_ID(nd_mid, RNODE_COLON2, "constant name");
LAST_NODE;
F_NODE(nd_head, RNODE_COLON2, "receiver");
F_LOC(delimiter_loc, RNODE_COLON2);
LAST_NODE;
F_LOC(name_loc, RNODE_COLON2);
return;

case NODE_COLON3:
ANN("top-level constant reference");
ANN("format: ::[nd_mid]");
ANN("example: ::Object");
F_ID(nd_mid, RNODE_COLON3, "constant name");
F_LOC(delimiter_loc, RNODE_COLON3);
F_LOC(name_loc, RNODE_COLON3);
return;

case NODE_DOT2:
Expand Down
42 changes: 23 additions & 19 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -1146,8 +1146,8 @@ static rb_node_undef_t *rb_node_undef_new(struct parser_params *p, NODE *nd_unde
static rb_node_class_t *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);
static rb_node_module_t *rb_node_module_new(struct parser_params *p, NODE *nd_cpath, NODE *nd_body, const YYLTYPE *loc);
static rb_node_sclass_t *rb_node_sclass_new(struct parser_params *p, NODE *nd_recv, NODE *nd_body, const YYLTYPE *loc);
static rb_node_colon2_t *rb_node_colon2_new(struct parser_params *p, NODE *nd_head, ID nd_mid, const YYLTYPE *loc);
static rb_node_colon3_t *rb_node_colon3_new(struct parser_params *p, ID nd_mid, const YYLTYPE *loc);
static rb_node_colon2_t *rb_node_colon2_new(struct parser_params *p, NODE *nd_head, ID nd_mid, const YYLTYPE *loc, const YYLTYPE *delimiter_loc, const YYLTYPE *name_loc);
static rb_node_colon3_t *rb_node_colon3_new(struct parser_params *p, ID nd_mid, const YYLTYPE *loc, const YYLTYPE *delimiter_loc, const YYLTYPE *name_loc);
static rb_node_dot2_t *rb_node_dot2_new(struct parser_params *p, NODE *nd_beg, NODE *nd_end, const YYLTYPE *loc, const YYLTYPE *operator_loc);
static rb_node_dot3_t *rb_node_dot3_new(struct parser_params *p, NODE *nd_beg, NODE *nd_end, const YYLTYPE *loc, const YYLTYPE *operator_loc);
static rb_node_self_t *rb_node_self_new(struct parser_params *p, const YYLTYPE *loc);
Expand Down Expand Up @@ -1254,8 +1254,8 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE
#define NEW_CLASS(n,b,s,loc,ck_loc,io_loc,ek_loc) (NODE *)rb_node_class_new(p,n,b,s,loc,ck_loc,io_loc,ek_loc)
#define NEW_MODULE(n,b,loc) (NODE *)rb_node_module_new(p,n,b,loc)
#define NEW_SCLASS(r,b,loc) (NODE *)rb_node_sclass_new(p,r,b,loc)
#define NEW_COLON2(c,i,loc) (NODE *)rb_node_colon2_new(p,c,i,loc)
#define NEW_COLON3(i,loc) (NODE *)rb_node_colon3_new(p,i,loc)
#define NEW_COLON2(c,i,loc,d_loc,n_loc) (NODE *)rb_node_colon2_new(p,c,i,loc,d_loc,n_loc)
#define NEW_COLON3(i,loc,d_loc,n_loc) (NODE *)rb_node_colon3_new(p,i,loc,d_loc,n_loc)
#define NEW_DOT2(b,e,loc,op_loc) (NODE *)rb_node_dot2_new(p,b,e,loc,op_loc)
#define NEW_DOT3(b,e,loc,op_loc) (NODE *)rb_node_dot3_new(p,b,e,loc,op_loc)
#define NEW_SELF(loc) (NODE *)rb_node_self_new(p,loc)
Expand Down Expand Up @@ -3067,13 +3067,13 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
| primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt rhs
{
YYLTYPE loc = code_loc_gen(&@primary_value, &@tCONSTANT);
$$ = new_const_op_assign(p, NEW_COLON2($primary_value, $tCONSTANT, &loc), $tOP_ASGN, $rhs, $lex_ctxt, &@$);
$$ = new_const_op_assign(p, NEW_COLON2($primary_value, $tCONSTANT, &loc, &@tCOLON2, &@tCONSTANT), $tOP_ASGN, $rhs, $lex_ctxt, &@$);
/*% ripper: opassign!(const_path_field!($:1, $:3), $:4, $:6) %*/
}
| tCOLON3 tCONSTANT tOP_ASGN lex_ctxt rhs
{
YYLTYPE loc = code_loc_gen(&@tCOLON3, &@tCONSTANT);
$$ = new_const_op_assign(p, NEW_COLON3($tCONSTANT, &loc), $tOP_ASGN, $rhs, $lex_ctxt, &@$);
$$ = new_const_op_assign(p, NEW_COLON3($tCONSTANT, &loc, &@tCOLON3, &@tCONSTANT), $tOP_ASGN, $rhs, $lex_ctxt, &@$);
/*% ripper: opassign!(top_const_field!($:2), $:3, $:5) %*/
}
| backref tOP_ASGN lex_ctxt rhs
Expand Down Expand Up @@ -3756,12 +3756,12 @@ mlhs_node : user_or_keyword_variable
| primary_value tCOLON2 tCONSTANT
{
/*% ripper: const_path_field!($:1, $:3) %*/
$$ = const_decl(p, NEW_COLON2($1, $3, &@$), &@$);
$$ = const_decl(p, NEW_COLON2($1, $3, &@$, &@2, &@3), &@$);
}
| tCOLON3 tCONSTANT
{
/*% ripper: top_const_field!($:2) %*/
$$ = const_decl(p, NEW_COLON3($2, &@$), &@$);
$$ = const_decl(p, NEW_COLON3($2, &@$, &@1, &@2), &@$);
}
| backref
{
Expand Down Expand Up @@ -3794,12 +3794,12 @@ lhs : user_or_keyword_variable
| primary_value tCOLON2 tCONSTANT
{
/*% ripper: const_path_field!($:1, $:3) %*/
$$ = const_decl(p, NEW_COLON2($1, $3, &@$), &@$);
$$ = const_decl(p, NEW_COLON2($1, $3, &@$, &@2, &@3), &@$);
}
| tCOLON3 tCONSTANT
{
/*% ripper: top_const_field!($:2) %*/
$$ = const_decl(p, NEW_COLON3($2, &@$), &@$);
$$ = const_decl(p, NEW_COLON3($2, &@$, &@1, &@2), &@$);
}
| backref
{
Expand All @@ -3822,17 +3822,17 @@ cname : tIDENTIFIER

cpath : tCOLON3 cname
{
$$ = NEW_COLON3($2, &@$);
$$ = NEW_COLON3($2, &@$, &@1, &@2);
/*% ripper: top_const_ref!($:2) %*/
}
| cname
{
$$ = NEW_COLON2(0, $1, &@$);
$$ = NEW_COLON2(0, $1, &@$, &NULL_LOC, &@1);
/*% ripper: const_ref!($:1) %*/
}
| primary_value tCOLON2 cname
{
$$ = NEW_COLON2($1, $3, &@$);
$$ = NEW_COLON2($1, $3, &@$, &@2, &@3);
/*% ripper: const_path_ref!($:1, $:3) %*/
}
;
Expand Down Expand Up @@ -4385,12 +4385,12 @@ primary : inline_primary
}
| primary_value tCOLON2 tCONSTANT
{
$$ = NEW_COLON2($1, $3, &@$);
$$ = NEW_COLON2($1, $3, &@$, &@2, &@3);
/*% ripper: const_path_ref!($:1, $:3) %*/
}
| tCOLON3 tCONSTANT
{
$$ = NEW_COLON3($2, &@$);
$$ = NEW_COLON3($2, &@$, &@1, &@2);
/*% ripper: top_const_ref!($:2) %*/
}
| tLBRACK aref_args ']'
Expand Down Expand Up @@ -5810,12 +5810,12 @@ p_expr_ref : '^' tLPAREN expr_value rparen

p_const : tCOLON3 cname
{
$$ = NEW_COLON3($2, &@$);
$$ = NEW_COLON3($2, &@$, &@1, &@2);
/*% ripper: top_const_ref!($:2) %*/
}
| p_const tCOLON2 cname
{
$$ = NEW_COLON2($1, $3, &@$);
$$ = NEW_COLON2($1, $3, &@$, &@2, &@3);
/*% ripper: const_path_ref!($:1, $:3) %*/
}
| tCONSTANT
Expand Down Expand Up @@ -11553,20 +11553,24 @@ rb_node_until_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd
}

static rb_node_colon2_t *
rb_node_colon2_new(struct parser_params *p, NODE *nd_head, ID nd_mid, const YYLTYPE *loc)
rb_node_colon2_new(struct parser_params *p, NODE *nd_head, ID nd_mid, const YYLTYPE *loc, const YYLTYPE *delimiter_loc, const YYLTYPE *name_loc)
{
rb_node_colon2_t *n = NODE_NEWNODE(NODE_COLON2, rb_node_colon2_t, loc);
n->nd_head = nd_head;
n->nd_mid = nd_mid;
n->delimiter_loc = *delimiter_loc;
n->name_loc = *name_loc;

return n;
}

static rb_node_colon3_t *
rb_node_colon3_new(struct parser_params *p, ID nd_mid, const YYLTYPE *loc)
rb_node_colon3_new(struct parser_params *p, ID nd_mid, const YYLTYPE *loc, const YYLTYPE *delimiter_loc, const YYLTYPE *name_loc)
{
rb_node_colon3_t *n = NODE_NEWNODE(NODE_COLON3, rb_node_colon3_t, loc);
n->nd_mid = nd_mid;
n->delimiter_loc = *delimiter_loc;
n->name_loc = *name_loc;

return n;
}
Expand Down
4 changes: 4 additions & 0 deletions rubyparser.h
28BE
Original file line number Diff line number Diff line change
Expand Up @@ -915,12 +915,16 @@ typedef struct RNode_COLON2 {

struct RNode *nd_head;
ID nd_mid;
rb_code_location_t delimiter_loc;
rb_code_location_t name_loc;
} rb_node_colon2_t;

typedef struct RNode_COLON3 {
NODE node;

ID nd_mid;
rb_code_location_t delimiter_loc;
rb_code_location_t name_loc;
} rb_node_colon3_t;

/* NODE_DOT2, NODE_DOT3, NODE_FLIP2, NODE_FLIP3 */
Expand Down
18 changes: 18 additions & 0 deletions test/ruby/test_ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,24 @@ def test_class_locations
assert_locations(node.children[-1].locations, [[1, 0, 1, 16], [1, 0, 1, 5], [1, 8, 1, 9], [1, 13, 1, 16]])
end

def test_colon2_locations
node = ast_parse("A::B")
assert_locations(node.children[-1].locations, [[1, 0, 1, 4], [1, 1, 1, 3], [1, 3, 1, 4]])

node = ast_parse("A::B::C")
assert_locations(node.children[-1].locations, [[1, 0, 1, 7], [1, 4, 1, 6], [1, 6, 1, 7]])
assert_locations(node.children[-1].children[0].locations, [[1, 0, 1, 4], [1, 1, 1, 3], [1, 3, 1, 4]])
end

def test_colon3_locations
node = ast_parse("::A")
assert_locations(node.children[-1].locations, [[1, 0, 1, 3], [1, 0, 1, 2], [1, 2, 1, 3]])

node = ast_parse("::A::B")
assert_locations(node.children[-1].locations, [[1, 0, 1, 6], [1, 3, 1, 5], [1, 5, 1, 6]])
assert_locations(node.children[-1].children[0].locations, [[1, 0, 1, 3], [1, 0, 1, 2], [1, 2, 1, 3]])
end

def test_dot2_locations
node = ast_parse("1..2")
assert_locations(node.children[-1].locations, [[1, 0, 1, 4], [1, 1, 1, 3]])
Expand Down
Loading
0