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,
|
return rb_ary_new_from_args(2,
|
||||||
location_new(nd_code_loc(node)),
|
location_new(nd_code_loc(node)),
|
||||||
location_new(&RNODE_FLIP3(node)->operator_loc));
|
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:
|
case NODE_LAMBDA:
|
||||||
return rb_ary_new_from_args(4,
|
return rb_ary_new_from_args(4,
|
||||||
location_new(nd_code_loc(node)),
|
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("method call with block");
|
||||||
ANN("format: [nd_iter] { [nd_body] }");
|
ANN("format: [nd_iter] { [nd_body] }");
|
||||||
ANN("example: 3.times { foo }");
|
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:
|
case NODE_FOR:
|
||||||
ANN("for statement");
|
ANN("for statement");
|
||||||
ANN("format: for * in [nd_iter] do [nd_body] end");
|
ANN("format: for * in [nd_iter] do [nd_body] end");
|
||||||
ANN("example: for i in 1..3 do foo end");
|
ANN("example: for i in 1..3 do foo end");
|
||||||
iter:
|
F_NODE(nd_iter, RNODE_FOR, "iteration receiver");
|
||||||
F_NODE(nd_iter, RNODE_ITER, "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;
|
LAST_NODE;
|
||||||
F_NODE(nd_body, RNODE_ITER, "body");
|
F_LOC(end_keyword_loc, RNODE_FOR);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case NODE_FOR_MASGN:
|
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_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_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_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_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_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);
|
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_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_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_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_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_RETRY(loc) (NODE *)rb_node_retry_new(p,loc)
|
||||||
#define NEW_BEGIN(b,loc) (NODE *)rb_node_begin_new(p,b,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_masgn> f_margs
|
||||||
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
|
%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 <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 <node> lambda brace_body do_body
|
||||||
%type <locations_lambda_body> lambda_body
|
%type <locations_lambda_body> lambda_body
|
||||||
%type <node_args> f_larglist
|
%type <node_args> f_larglist
|
||||||
@ -4502,7 +4502,8 @@ primary : inline_primary
|
|||||||
$$ = NEW_CASE3($2, $4, &@$, &@1, &@5);
|
$$ = NEW_CASE3($2, $4, &@$, &@1, &@5);
|
||||||
/*% ripper: case!($:2, $:4) %*/
|
/*% 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)
|
compstmt(stmts)
|
||||||
k_end
|
k_end
|
||||||
{
|
{
|
||||||
@ -4539,10 +4540,14 @@ primary : inline_primary
|
|||||||
}
|
}
|
||||||
/* {|*internal_id| <m> = internal_id; ... } */
|
/* {|*internal_id| <m> = internal_id; ... } */
|
||||||
args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@2), &@2);
|
args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@2), &@2);
|
||||||
scope = NEW_SCOPE2(tbl, args, $5, &@$);
|
scope = NEW_SCOPE2(tbl, args, $8, &@$);
|
||||||
$$ = NEW_FOR($4, scope, &@$);
|
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);
|
fixpos($$, $2);
|
||||||
/*% ripper: for!($:2, $:4, $:5) %*/
|
/*% ripper: for!($:2, $:5, $:8) %*/
|
||||||
}
|
}
|
||||||
| k_class cpath superclass
|
| k_class cpath superclass
|
||||||
{
|
{
|
||||||
@ -4837,7 +4842,7 @@ then : term
|
|||||||
;
|
;
|
||||||
|
|
||||||
do : term
|
do : term
|
||||||
| keyword_do_cond
|
| keyword_do_cond { $$ = keyword_do_cond; }
|
||||||
;
|
;
|
||||||
|
|
||||||
if_tail : opt_else
|
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 *
|
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);
|
rb_node_for_t *n = NODE_NEWNODE(NODE_FOR, rb_node_for_t, loc);
|
||||||
n->nd_body = nd_body;
|
n->nd_body = nd_body;
|
||||||
n->nd_iter = nd_iter;
|
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;
|
return n;
|
||||||
}
|
}
|
||||||
|
13
rubyparser.h
13
rubyparser.h
@ -341,7 +341,18 @@ typedef struct RNode_ITER {
|
|||||||
|
|
||||||
struct RNode *nd_body;
|
struct RNode *nd_body;
|
||||||
struct RNode *nd_iter;
|
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 {
|
typedef struct RNode_FOR_MASGN {
|
||||||
NODE node;
|
NODE node;
|
||||||
|
@ -1428,6 +1428,14 @@ dummy
|
|||||||
assert_locations(node.children[-1].children[0].locations, [[1, 3, 1, 8], [1, 4, 1, 7]])
|
assert_locations(node.children[-1].children[0].locations, [[1, 3, 1, 8], [1, 4, 1, 7]])
|
||||||
end
|
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
|
def test_lambda_locations
|
||||||
node = ast_parse("-> (a, b) { foo }")
|
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]])
|
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