diff --git a/ast.c b/ast.c index e5565ae00a..4936ccc91d 100644 --- a/ast.c +++ b/ast.c @@ -792,6 +792,11 @@ node_locations(VALUE ast_value, const NODE *node) location_new(nd_code_loc(node)), location_new(&RNODE_CASE(node)->case_keyword_loc), location_new(&RNODE_CASE(node)->end_keyword_loc)); + case NODE_CASE2: + return rb_ary_new_from_args(3, + location_new(nd_code_loc(node)), + location_new(&RNODE_CASE2(node)->case_keyword_loc), + location_new(&RNODE_CASE2(node)->end_keyword_loc)); case NODE_NEXT: return rb_ary_new_from_args(2, location_new(nd_code_loc(node)), diff --git a/node_dump.c b/node_dump.c index 3e92c87bf0..9a92762e10 100644 --- a/node_dump.c +++ b/node_dump.c @@ -271,8 +271,10 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: case; [nd_body]; end"); ANN("example: case; when 1; foo; when 2; bar; else baz; end"); F_NODE(nd_head, RNODE_CASE2, "case expr"); - LAST_NODE; F_NODE(nd_body, RNODE_CASE2, "when clauses"); + F_LOC(case_keyword_loc, RNODE_CASE2); + LAST_NODE; + F_LOC(end_keyword_loc, RNODE_CASE2); return; case NODE_CASE3: ANN("case statement (pattern matching)"); diff --git a/parse.y b/parse.y index 550f00d56b..cd5c76f469 100644 --- a/parse.y +++ b/parse.y @@ -1064,7 +1064,7 @@ static rb_node_block_t *rb_node_block_new(struct parser_params *p, NODE *nd_head 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, 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_case2_t *rb_node_case2_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *case_keyword_loc, const YYLTYPE *end_keyword_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); static rb_node_in_t *rb_node_in_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, NODE *nd_next, const YYLTYPE *loc); @@ -1172,7 +1172,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE #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,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_CASE2(b,loc,ck_loc,ek_loc) (NODE *)rb_node_case2_new(p,b,loc,ck_loc,ek_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) #define NEW_IN(c,t,e,loc) (NODE *)rb_node_in_new(p,c,t,e,loc) @@ -4564,7 +4564,7 @@ primary : literal { if (p->case_labels) st_free_table(p->case_labels); p->case_labels = $3; - $$ = NEW_CASE2($4, &@$); + $$ = NEW_CASE2($4, &@$, &@1, &@5); /*% ripper: case!(Qnil, $:4) %*/ } | k_case expr_value terms? @@ -11625,11 +11625,13 @@ rb_node_case_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YY } static rb_node_case2_t * -rb_node_case2_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc) +rb_node_case2_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *case_keyword_loc, const YYLTYPE *end_keyword_loc) { rb_node_case2_t *n = NODE_NEWNODE(NODE_CASE2, rb_node_case2_t, loc); n->nd_head = 0; n->nd_body = nd_body; + n->case_keyword_loc = *case_keyword_loc; + n->end_keyword_loc = *end_keyword_loc; return n; } diff --git a/rubyparser.h b/rubyparser.h index 81f45386fc..dbef455998 100644 --- a/rubyparser.h +++ b/rubyparser.h @@ -292,6 +292,8 @@ typedef struct RNode_CASE2 { struct RNode *nd_head; struct RNode *nd_body; + rb_code_location_t case_keyword_loc; + rb_code_location_t end_keyword_loc; } rb_node_case2_t; typedef struct RNode_CASE3 { diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb index 068b372ff9..f2024b2900 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -1358,6 +1358,11 @@ dummy assert_locations(node.children[-1].locations, [[1, 0, 1, 19], [1, 0, 1, 4], [1, 16, 1, 19]]) end + def test_case2_locations + node = ast_parse("case; when 1; end") + assert_locations(node.children[-1].locations, [[1, 0, 1, 17], [1, 0, 1, 4], [1, 14, 1, 17]]) + 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]])