Implement CASE NODE keyword locations

This commit is contained in:
ydah 2024-09-22 00:13:16 +09:00 коммит произвёл Yuichiro Kaneko
Родитель 02b36f7572
Коммит feac2b4b77
5 изменённых файлов: 21 добавлений и 5 удалений

5
ast.c
Просмотреть файл

@ -787,6 +787,11 @@ node_locations(VALUE ast_value, const NODE *node)
return rb_ary_new_from_args(2,
location_new(nd_code_loc(node)),
location_new(&RNODE_BREAK(node)->keyword_loc));
case NODE_CASE:
return rb_ary_new_from_args(3,
location_new(nd_code_loc(node)),
location_new(&RNODE_CASE(node)->case_keyword_loc),
location_new(&RNODE_CASE(node)->end_keyword_loc));
case NODE_NEXT:
return rb_ary_new_from_args(2,
location_new(nd_code_loc(node)),

Просмотреть файл

@ -261,8 +261,10 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
ANN("format: case [nd_head]; [nd_body]; end");
ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
F_NODE(nd_head, RNODE_CASE, "case expr");
LAST_NODE;
F_NODE(nd_body, RNODE_CASE, "when clauses");
F_LOC(case_keyword_loc, RNODE_CASE);
LAST_NODE;
F_LOC(end_keyword_loc, RNODE_CASE);
return;
case NODE_CASE2:
ANN("case statement with no head");

10
parse.y
Просмотреть файл

@ -1063,7 +1063,7 @@ static rb_node_scope_t *rb_node_scope_new2(struct parser_params *p, rb_ast_id_ta
static rb_node_block_t *rb_node_block_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc);
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);
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);
static rb_node_case_t *rb_node_case_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc);
static rb_node_case_t *rb_node_case_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *case_keyword_loc, const YYLTYPE *end_keyword_loc);
static rb_node_case2_t *rb_node_case2_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
static rb_node_case3_t *rb_node_case3_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc);
static rb_node_when_t *rb_node_when_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, NODE *nd_next, const YYLTYPE *loc, const YYLTYPE *keyword_loc, const YYLTYPE *then_keyword_loc);
@ -1171,7 +1171,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE
#define NEW_BLOCK(a,loc) (NODE *)rb_node_block_new(p,a,loc)
#define NEW_IF(c,t,e,loc) (NODE *)rb_node_if_new(p,c,t,e,loc)
#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)
#define NEW_CASE(h,b,loc) (NODE *)rb_node_case_new(p,h,b,loc)
#define NEW_CASE(h,b,loc,ck_loc,ek_loc) (NODE *)rb_node_case_new(p,h,b,loc,ck_loc,ek_loc)
#define NEW_CASE2(b,loc) (NODE *)rb_node_case2_new(p,b,loc)
#define NEW_CASE3(h,b,loc) (NODE *)rb_node_case3_new(p,h,b,loc)
#define NEW_WHEN(c,t,e,loc,k_loc,t_loc) (NODE *)rb_node_when_new(p,c,t,e,loc,k_loc,t_loc)
@ -4550,7 +4550,7 @@ primary : literal
{
if (CASE_LABELS_ENABLED_P(p->case_labels)) st_free_table(p->case_labels);
p->case_labels = $4;
$$ = NEW_CASE($2, $5, &@$);
$$ = NEW_CASE($2, $5, &@$, &@1, &@6);
fixpos($$, $2);
/*% ripper: case!($:2, $:5) %*/
}
@ -11613,11 +11613,13 @@ rb_node_lambda_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_bo
}
static rb_node_case_t *
rb_node_case_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc)
rb_node_case_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *case_keyword_loc, const YYLTYPE *end_keyword_loc)
{
rb_node_case_t *n = NODE_NEWNODE(NODE_CASE, rb_node_case_t, loc);
n->nd_head = nd_head;
n->nd_body = nd_body;
n->case_keyword_loc = *case_keyword_loc;
n->end_keyword_loc = *end_keyword_loc;
return n;
}

Просмотреть файл

@ -283,6 +283,8 @@ typedef struct RNode_CASE {
struct RNode *nd_head;
struct RNode *nd_body;
rb_code_location_t case_keyword_loc;
rb_code_location_t end_keyword_loc;
} rb_node_case_t;
typedef struct RNode_CASE2 {

Просмотреть файл

@ -1353,6 +1353,11 @@ dummy
assert_locations(node.children[-1].children[-1].children[-1].locations, [[1, 7, 1, 14], [1, 7, 1, 12]])
end
def test_case_locations
node = ast_parse("case a; when 1; end")
assert_locations(node.children[-1].locations, [[1, 0, 1, 19], [1, 0, 1, 4], [1, 16, 1, 19]])
end
def test_next_locations
node = ast_parse("loop { next 1 }")
assert_locations(node.children[-1].children[-1].children[-1].locations, [[1, 7, 1, 13], [1, 7, 1, 11]])