зеркало из https://github.com/github/ruby.git
Implement WHILE and UNTIL NODE locations
This commit is contained in:
Родитель
1adcc41b94
Коммит
4e6091ce09
10
ast.c
10
ast.c
|
@ -806,6 +806,16 @@ node_locations(VALUE ast_value, const NODE *node)
|
|||
location_new(nd_code_loc(node)),
|
||||
location_new(&RNODE_WHEN(node)->keyword_loc),
|
||||
location_new(&RNODE_WHEN(node)->then_keyword_loc));
|
||||
case NODE_WHILE:
|
||||
return rb_ary_new_from_args(3,
|
||||
location_new(nd_code_loc(node)),
|
||||
location_new(&RNODE_WHILE(node)->keyword_loc),
|
||||
location_new(&RNODE_WHILE(node)->closing_loc));
|
||||
case NODE_UNTIL:
|
||||
return rb_ary_new_from_args(3,
|
||||
location_new(nd_code_loc(node)),
|
||||
location_new(&RNODE_UNTIL(node)->keyword_loc),
|
||||
location_new(&RNODE_UNTIL(node)->closing_loc));
|
||||
case NODE_ARGS_AUX:
|
||||
case NODE_LAST:
|
||||
break;
|
||||
|
|
|
@ -319,8 +319,10 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
|||
A((RNODE_WHILE(node)->nd_state == 1) ? " (while-end)" : " (begin-end-while)");
|
||||
}
|
||||
F_NODE(nd_cond, RNODE_WHILE, "condition");
|
||||
LAST_NODE;
|
||||
F_NODE(nd_body, RNODE_WHILE, "body");
|
||||
F_LOC(keyword_loc, RNODE_WHILE);
|
||||
LAST_NODE;
|
||||
F_LOC(closing_loc, RNODE_WHILE);
|
||||
return;
|
||||
|
||||
case NODE_ITER:
|
||||
|
|
30
parse.y
30
parse.y
|
@ -1068,8 +1068,8 @@ static rb_node_case2_t *rb_node_case2_new(struct parser_params *p, NODE *nd_body
|
|||
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);
|
||||
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);
|
||||
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, const YYLTYPE *keyword_loc, const YYLTYPE *closing_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, const YYLTYPE *keyword_loc, const YYLTYPE *closing_loc);
|
||||
static rb_node_iter_t *rb_node_iter_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc);
|
||||
static rb_node_for_t *rb_node_for_new(struct parser_params *p, NODE *nd_iter, NODE *nd_body, const YYLTYPE *loc);
|
||||
static rb_node_for_masgn_t *rb_node_for_masgn_new(struct parser_params *p, NODE *nd_var, const YYLTYPE *loc);
|
||||
|
@ -1176,8 +1176,8 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE
|
|||
#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)
|
||||
#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)
|
||||
#define NEW_WHILE(c,b,n,loc,k_loc,c_loc) (NODE *)rb_node_while_new(p,c,b,n,loc,k_loc,c_loc)
|
||||
#define NEW_UNTIL(c,b,n,loc,k_loc,c_loc) (NODE *)rb_node_until_new(p,c,b,n,loc,k_loc,c_loc)
|
||||
#define NEW_ITER(a,b,loc) (NODE *)rb_node_iter_new(p,a,b,loc)
|
||||
#define NEW_FOR(i,b,loc) (NODE *)rb_node_for_new(p,i,b,loc)
|
||||
#define NEW_FOR_MASGN(v,loc) (NODE *)rb_node_for_masgn_new(p,v,loc)
|
||||
|
@ -3176,10 +3176,10 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
|
|||
{
|
||||
clear_block_exit(p, false);
|
||||
if ($1 && nd_type_p($1, NODE_BEGIN)) {
|
||||
$$ = NEW_WHILE(cond(p, $3, &@3), RNODE_BEGIN($1)->nd_body, 0, &@$);
|
||||
$$ = NEW_WHILE(cond(p, $3, &@3), RNODE_BEGIN($1)->nd_body, 0, &@$, &@2, &NULL_LOC);
|
||||
}
|
||||
else {
|
||||
$$ = NEW_WHILE(cond(p, $3, &@3), $1, 1, &@$);
|
||||
$$ = NEW_WHILE(cond(p, $3, &@3), $1, 1, &@$, &@2, &NULL_LOC);
|
||||
}
|
||||
/*% ripper: while_mod!($:3, $:1) %*/
|
||||
}
|
||||
|
@ -3187,10 +3187,10 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
|
|||
{
|
||||
clear_block_exit(p, false);
|
||||
if ($1 && nd_type_p($1, NODE_BEGIN)) {
|
||||
$$ = NEW_UNTIL(cond(p, $3, &@3), RNODE_BEGIN($1)->nd_body, 0, &@$);
|
||||
$$ = NEW_UNTIL(cond(p, $3, &@3), RNODE_BEGIN($1)->nd_body, 0, &@$, &@2, &NULL_LOC);
|
||||
}
|
||||
else {
|
||||
$$ = NEW_UNTIL(cond(p, $3, &@3), $1, 1, &@$);
|
||||
$$ = NEW_UNTIL(cond(p, $3, &@3), $1, 1, &@$, &@2, &NULL_LOC);
|
||||
}
|
||||
/*% ripper: until_mod!($:3, $:1) %*/
|
||||
}
|
||||
|
@ -4527,7 +4527,7 @@ primary : literal
|
|||
k_end
|
||||
{
|
||||
restore_block_exit(p, $1);
|
||||
$$ = NEW_WHILE(cond(p, $2, &@2), $3, 1, &@$);
|
||||
$$ = NEW_WHILE(cond(p, $2, &@2), $3, 1, &@$, &@1, &@4);
|
||||
fixpos($$, $2);
|
||||
/*% ripper: while!($:2, $:3) %*/
|
||||
}
|
||||
|
@ -4536,7 +4536,7 @@ primary : literal
|
|||
k_end
|
||||
{
|
||||
restore_block_exit(p, $1);
|
||||
$$ = NEW_UNTIL(cond(p, $2, &@2), $3, 1, &@$);
|
||||
$$ = NEW_UNTIL(cond(p, $2, &@2), $3, 1, &@$, &@1, &@4);
|
||||
fixpos($$, $2);
|
||||
/*% ripper: until!($:2, $:3) %*/
|
||||
}
|
||||
|
@ -11667,23 +11667,27 @@ rb_node_in_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, NODE *nd_n
|
|||
}
|
||||
|
||||
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)
|
||||
rb_node_while_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd_state, const YYLTYPE *loc, const YYLTYPE *keyword_loc, const YYLTYPE *closing_loc)
|
||||
{
|
||||
rb_node_while_t *n = NODE_NEWNODE(NODE_WHILE, rb_node_while_t, loc);
|
||||
n->nd_cond = nd_cond;
|
||||
n->nd_body = nd_body;
|
||||
n->nd_state = nd_state;
|
||||
n->keyword_loc = *keyword_loc;
|
||||
n->closing_loc = *closing_loc;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
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)
|
||||
rb_node_until_new(struct parser_params *p, NODE *nd_cond, NODE *nd_body, long nd_state, const YYLTYPE *loc, const YYLTYPE *keyword_loc, const YYLTYPE *closing_loc)
|
||||
{
|
||||
rb_node_until_t *n = NODE_NEWNODE(NODE_UNTIL, rb_node_until_t, loc);
|
||||
n->nd_cond = nd_cond;
|
||||
n->nd_body = nd_body;
|
||||
n->nd_state = nd_state;
|
||||
n->keyword_loc = *keyword_loc;
|
||||
n->closing_loc = *closing_loc;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -15528,7 +15532,7 @@ parser_append_options(struct parser_params *p, NODE *node)
|
|||
irs = list_append(p, irs, NEW_HASH(chomp, LOC));
|
||||
}
|
||||
|
||||
node = NEW_WHILE((NODE *)NEW_FCALL(idGets, irs, LOC), node, 1, LOC);
|
||||
node = NEW_WHILE((NODE *)NEW_FCALL(idGets, irs, LOC), node, 1, LOC, &NULL_LOC, &NULL_LOC);
|
||||
}
|
||||
|
||||
return node;
|
||||
|
|
|
@ -323,6 +323,8 @@ typedef struct RNode_LOOP {
|
|||
struct RNode *nd_cond;
|
||||
struct RNode *nd_body;
|
||||
long nd_state;
|
||||
rb_code_location_t keyword_loc;
|
||||
rb_code_location_t closing_loc;
|
||||
} rb_node_while_t, rb_node_until_t;
|
||||
|
||||
typedef struct RNode_ITER {
|
||||
|
|
|
@ -1380,6 +1380,22 @@ dummy
|
|||
assert_locations(node.children[-1].children[1].locations, [[1, 8, 1, 22], [1, 8, 1, 12], [1, 15, 1, 19]])
|
||||
end
|
||||
|
||||
def test_while_locations
|
||||
node = RubyVM::AbstractSyntaxTree.parse("while cond do 1 end")
|
||||
assert_locations(node.children[-1].locations, [[1, 0, 1, 19], [1, 0, 1, 5], [1, 16, 1, 19]])
|
||||
|
||||
node = RubyVM::AbstractSyntaxTree.parse("1 while 2")
|
||||
assert_locations(node.children[-1].locations, [[1, 0, 1, 9], [1, 2, 1, 7], nil])
|
||||
end
|
||||
|
||||
def test_until_locations
|
||||
node = RubyVM::AbstractSyntaxTree.parse("until cond do 1 end")
|
||||
assert_locations(node.children[-1].locations, [[1, 0, 1, 19], [1, 0, 1, 5], [1, 16, 1, 19]])
|
||||
|
||||
node = RubyVM::AbstractSyntaxTree.parse("1 until 2")
|
||||
assert_locations(node.children[-1].locations, [[1, 0, 1, 9], [1, 2, 1, 7], nil])
|
||||
end
|
||||
|
||||
private
|
||||
def assert_locations(locations, expected)
|
||||
ary = locations.map {|loc| loc && [loc.first_lineno, loc.first_column, loc.last_lineno, loc.last_column] }
|
||||
|
|
Загрузка…
Ссылка в новой задаче