Implement FOR NODE locations
The following Location information has been added This is the information required for parse.y to be a universal parser: ``` ❯ ruby --parser=prism --dump=parsetree -e "for a in b do end" @ ProgramNode (location: (1,0)-(1,17)) +-- locals: [:a] +-- statements: @ StatementsNode (location: (1,0)-(1,17)) +-- body: (length: 1) +-- @ ForNode (location: (1,0)-(1,17)) +-- index: | @ LocalVariableTargetNode (location: (1,4)-(1,5)) | +-- name: :a | +-- depth: 0 +-- collection: | @ CallNode (location: (1,9)-(1,10)) | +-- CallNodeFlags: variable_call, ignore_visibility | +-- receiver: nil | +-- call_operator_loc: nil | +-- name: :b | +-- message_loc: (1,9)-(1,10) = "b" | +-- opening_loc: nil | +-- arguments: nil | +-- closing_loc: nil | +-- block: nil +-- statements: nil +-- for_keyword_loc: (1,0)-(1,3) = "for" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-- in_keyword_loc: (1,6)-(1,8) = "in" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-- do_keyword_loc: (1,11)-(1,13) = "do" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-- end_keyword_loc: (1,14)-(1,17) = "end" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ```
This commit is contained in:
parent
841555245d
commit
c721301132
7
ast.c
7
ast.c
@ -828,6 +828,13 @@ node_locations(VALUE ast_value, const NODE *node)
|
||||
return rb_ary_new_from_args(2,
|
||||
location_new(nd_code_loc(node)),
|
||||
location_new(&RNODE_FLIP3(node)->operator_loc));
|
||||
case NODE_FOR:
|
||||
return rb_ary_new_from_args(5,
|
||||
location_new(nd_code_loc(node)),
|
||||
location_new(&RNODE_FOR(node)->for_keyword_loc),
|
||||
location_new(&RNODE_FOR(node)->in_keyword_loc),
|
||||
location_new(&RNODE_FOR(node)->do_keyword_loc),
|
||||
location_new(&RNODE_FOR(node)->end_keyword_loc));
|
||||
case NODE_LAMBDA:
|
||||
return rb_ary_new_from_args(4,
|
||||
location_new(nd_code_loc(node)),
|
||||
|
15
node_dump.c
15
node_dump.c
@ -338,15 +338,22 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
||||
ANN("method call with block");
|
||||
ANN("format: [nd_iter] { [nd_body] }");
|
||||
ANN("example: 3.times { foo }");
|
||||
goto iter;
|
||||
F_NODE(nd_iter, RNODE_ITER, "iteration receiver");
|
||||
LAST_NODE;
|
||||
F_NODE(nd_body, RNODE_ITER, "body");
|
||||
return;
|
||||
|
||||
case NODE_FOR:
|
||||
ANN("for statement");
|
||||
ANN("format: for * in [nd_iter] do [nd_body] end");
|
||||
ANN("example: for i in 1..3 do foo end");
|
||||
iter:
|
||||
F_NODE(nd_iter, RNODE_ITER, "iteration receiver");
|
||||
F_NODE(nd_iter, RNODE_FOR, "iteration receiver");
|
||||
F_NODE(nd_body, RNODE_FOR, "body");
|
||||
F_LOC(for_keyword_loc, RNODE_FOR);
|
||||
F_LOC(in_keyword_loc, RNODE_FOR);
|
||||
F_LOC(do_keyword_loc, RNODE_FOR);
|
||||
LAST_NODE;
|
||||
F_NODE(nd_body, RNODE_ITER, "body");
|
||||
F_LOC(end_keyword_loc, RNODE_FOR);
|
||||
return;
|
||||
|
||||
case NODE_FOR_MASGN:
|
||||
|
27
parse.y
27
parse.y
@ -1073,7 +1073,7 @@ static rb_node_in_t *rb_node_in_new(struct parser_params *p, NODE *nd_head, NODE
|
||||
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_t *rb_node_for_new(struct parser_params *p, NODE *nd_iter, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *for_keyword_loc, const YYLTYPE *in_keyword_loc, const YYLTYPE *do_keyword_loc, const YYLTYPE *end_keyword_loc);
|
||||
static rb_node_for_masgn_t *rb_node_for_masgn_new(struct parser_params *p, NODE *nd_var, const YYLTYPE *loc);
|
||||
static rb_node_retry_t *rb_node_retry_new(struct parser_params *p, const YYLTYPE *loc);
|
||||
static rb_node_begin_t *rb_node_begin_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc);
|
||||
@ -1181,7 +1181,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE
|
||||
#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(i,b,loc,f_loc,i_loc,d_loc,e_loc) (NODE *)rb_node_for_new(p,i,b,loc,f_loc,i_loc,d_loc,e_loc)
|
||||
#define NEW_FOR_MASGN(v,loc) (NODE *)rb_node_for_masgn_new(p,v,loc)
|
||||
#define NEW_RETRY(loc) (NODE *)rb_node_retry_new(p,loc)
|
||||
#define NEW_BEGIN(b,loc) (NODE *)rb_node_begin_new(p,b,loc)
|
||||
@ -2783,7 +2783,7 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
|
||||
%type <node_masgn> f_margs
|
||||
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
|
||||
%type <node_args> block_param opt_block_param block_param_def
|
||||
%type <id> bv_decls opt_bv_decl bvar
|
||||
%type <id> do bv_decls opt_bv_decl bvar
|
||||
%type <node> lambda brace_body do_body
|
||||
%type <locations_lambda_body> lambda_body
|
||||
%type <node_args> f_larglist
|
||||
@ -4502,7 +4502,8 @@ primary : inline_primary
|
||||
$$ = NEW_CASE3($2, $4, &@$, &@1, &@5);
|
||||
/*% ripper: case!($:2, $:4) %*/
|
||||
}
|
||||
| k_for for_var keyword_in expr_value_do
|
||||
| k_for for_var keyword_in
|
||||
{COND_PUSH(1);} expr_value do {COND_POP();}
|
||||
compstmt(stmts)
|
||||
k_end
|
||||
{
|
||||
@ -4539,10 +4540,14 @@ primary : inline_primary
|
||||
}
|
||||
/* {|*internal_id| <m> = internal_id; ... } */
|
||||
args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@2), &@2);
|
||||
scope = NEW_SCOPE2(tbl, args, $5, &@$);
|
||||
$$ = NEW_FOR($4, scope, &@$);
|
||||
scope = NEW_SCOPE2(tbl, args, $8, &@$);
|
||||
if ($6 == keyword_do_cond) {
|
||||
$$ = NEW_FOR($5, scope, &@$, &@1, &@3, &@6, &@9);
|
||||
} else {
|
||||
$$ = NEW_FOR($5, scope, &@$, &@1, &@3, &NULL_LOC, &@9);
|
||||
}
|
||||
fixpos($$, $2);
|
||||
/*% ripper: for!($:2, $:4, $:5) %*/
|
||||
/*% ripper: for!($:2, $:5, $:8) %*/
|
||||
}
|
||||
| k_class cpath superclass
|
||||
{
|
||||
@ -4837,7 +4842,7 @@ then : term
|
||||
;
|
||||
|
||||
do : term
|
||||
| keyword_do_cond
|
||||
| keyword_do_cond { $$ = keyword_do_cond; }
|
||||
;
|
||||
|
||||
if_tail : opt_else
|
||||
@ -11314,11 +11319,15 @@ rb_node_block_new(struct parser_params *p, NODE *nd_head, 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)
|
||||
rb_node_for_new(struct parser_params *p, NODE *nd_iter, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *for_keyword_loc, const YYLTYPE *in_keyword_loc, const YYLTYPE *do_keyword_loc, const YYLTYPE *end_keyword_loc)
|
||||
{
|
||||
rb_node_for_t *n = NODE_NEWNODE(NODE_FOR, rb_node_for_t, loc);
|
||||
n->nd_body = nd_body;
|
||||
n->nd_iter = nd_iter;
|
||||
n->for_keyword_loc = *for_keyword_loc;
|
||||
n->in_keyword_loc = *in_keyword_loc;
|
||||
n->do_keyword_loc = *do_keyword_loc;
|
||||
n->end_keyword_loc = *end_keyword_loc;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
13
rubyparser.h
13
rubyparser.h
@ -341,7 +341,18 @@ typedef struct RNode_ITER {
|
||||
|
||||
struct RNode *nd_body;
|
||||
struct RNode *nd_iter;
|
||||
} rb_node_iter_t, rb_node_for_t;
|
||||
} rb_node_iter_t;
|
||||
|
||||
typedef struct RNode_FOR {
|
||||
NODE node;
|
||||
|
||||
struct RNode *nd_body;
|
||||
struct RNode *nd_iter;
|
||||
rb_code_location_t for_keyword_loc;
|
||||
rb_code_location_t in_keyword_loc;
|
||||
rb_code_location_t do_keyword_loc;
|
||||
rb_code_location_t end_keyword_loc;
|
||||
} rb_node_for_t;
|
||||
|
||||
typedef struct RNode_FOR_MASGN {
|
||||
NODE node;
|
||||
|
@ -1428,6 +1428,14 @@ dummy
|
||||
assert_locations(node.children[-1].children[0].locations, [[1, 3, 1, 8], [1, 4, 1, 7]])
|
||||
end
|
||||
|
||||
def test_for_locations
|
||||
node = ast_parse("for a in b; end")
|
||||
assert_locations(node.children[-1].locations, [[1, 0, 1, 15], [1, 0, 1, 3], [1, 6, 1, 8], nil, [1, 12, 1, 15]])
|
||||
|
||||
node = ast_parse("for a in b do; end")
|
||||
assert_locations(node.children[-1].locations, [[1, 0, 1, 18], [1, 0, 1, 3], [1, 6, 1, 8], [1, 11, 1, 13], [1, 15, 1, 18]])
|
||||
end
|
||||
|
||||
def test_lambda_locations
|
||||
node = ast_parse("-> (a, b) { foo }")
|
||||
assert_locations(node.children[-1].locations, [[1, 0, 1, 17], [1, 0, 1, 2], [1, 10, 1, 11], [1, 16, 1, 17]])
|
||||
|
Loading…
x
Reference in New Issue
Block a user