summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorydah <t.yudai92@gmail.com>2024-09-05 18:41:10 +0900
committerYuichiro Kaneko <spiketeika@gmail.com>2024-09-09 10:34:02 +0900
commitd52e599538fb67535c95d86aec89fd7e53c61818 (patch)
treefcb0fd4bbd8a9db6a598a135a0f0a62f2178ed5d
parentb5f12910151f93f5f14057c52ffffa2b2ef09caa (diff)
Implement WHEN NODE locations
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/11553
-rw-r--r--ast.c5
-rw-r--r--node_dump.c3
-rw-r--r--parse.y10
-rw-r--r--rubyparser.h2
-rw-r--r--test/ruby/test_ast.rb5
5 files changed, 21 insertions, 4 deletions
diff --git a/ast.c b/ast.c
index 67d121e1ce..031031af95 100644
--- a/ast.c
+++ b/ast.c
@@ -801,6 +801,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_VALIAS(node)->keyword_loc));
+ case NODE_WHEN:
+ return rb_ary_new_from_args(3,
+ location_new(nd_code_loc(node)),
+ location_new(&RNODE_WHEN(node)->keyword_loc),
+ location_new(&RNODE_WHEN(node)->then_keyword_loc));
case NODE_ARGS_AUX:
case NODE_LAST:
break;
diff --git a/node_dump.c b/node_dump.c
index ae948eb66e..d97a400a97 100644
--- a/node_dump.c
+++ b/node_dump.c
@@ -289,6 +289,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
F_NODE(nd_body, RNODE_WHEN, "when body");
LAST_NODE;
F_NODE(nd_next, RNODE_WHEN, "next when clause");
+ F_LOC(keyword_loc, RNODE_WHEN);
+ LAST_NODE;
+ F_LOC(then_keyword_loc, RNODE_WHEN);
return;
case NODE_IN:
diff --git a/parse.y b/parse.y
index 42396094be..d78d4586f8 100644
--- a/parse.y
+++ b/parse.y
@@ -1066,7 +1066,7 @@ static rb_node_unless_t *rb_node_unless_new(struct parser_params *p, NODE *nd_co
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_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);
+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);
static rb_node_while_t *rb_node_while_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd_state, const YYLTYPE *loc);
static rb_node_until_t *rb_node_until_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd_state, const YYLTYPE *loc);
@@ -1174,7 +1174,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE
#define NEW_CASE(h,b,loc) (NODE *)rb_node_case_new(p,h,b,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) (NODE *)rb_node_when_new(p,c,t,e,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)
#define NEW_WHILE(c,b,n,loc) (NODE *)rb_node_while_new(p,c,b,n,loc)
#define NEW_UNTIL(c,b,n,loc) (NODE *)rb_node_until_new(p,c,b,n,loc)
@@ -5443,7 +5443,7 @@ case_body : k_when case_args then
compstmt
cases
{
- $$ = NEW_WHEN($2, $4, $5, &@$);
+ $$ = NEW_WHEN($2, $4, $5, &@$, &@1, &@3);
fixpos($$, $2);
/*% ripper: when!($:2, $:4, $:5) %*/
}
@@ -11643,12 +11643,14 @@ rb_node_case3_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const Y
}
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)
+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)
{
rb_node_when_t *n = NODE_NEWNODE(NODE_WHEN, rb_node_when_t, loc);
n->nd_head = nd_head;
n->nd_body = nd_body;
n->nd_next = nd_next;
+ n->keyword_loc = *keyword_loc;
+ n->then_keyword_loc = *then_keyword_loc;
return n;
}
diff --git a/rubyparser.h b/rubyparser.h
index 1a1a1d2b07..5728844827 100644
--- a/rubyparser.h
+++ b/rubyparser.h
@@ -305,6 +305,8 @@ typedef struct RNode_WHEN {
struct RNode *nd_head;
struct RNode *nd_body;
struct RNode *nd_next;
+ rb_code_location_t keyword_loc;
+ rb_code_location_t then_keyword_loc;
} rb_node_when_t;
typedef struct RNode_IN {
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index f03a323ccf..8ecd384d58 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -1375,6 +1375,11 @@ dummy
assert_locations(node.children[-1].locations, [[1, 0, 1, 13], [1, 0, 1, 5]])
end
+ def test_when_locations
+ node = RubyVM::AbstractSyntaxTree.parse("case a; when 1 then 2; end")
+ assert_locations(node.children[-1].children[1].locations, [[1, 8, 1, 22], [1, 8, 1, 12], [1, 15, 1, 19]])
+ end
+
private
def assert_locations(locations, expected)
ary = locations.map {|loc| loc && [loc.first_lineno, loc.first_column, loc.last_lineno, loc.last_column] }