diff options
author | ydah <[email protected]> | 2024-09-24 14:49:00 +0900 |
---|---|---|
committer | Yuichiro Kaneko <[email protected]> | 2024-09-25 09:15:43 +0900 |
commit | 509b577e0126d92f37ae45d83863c449f8666be1 (patch) | |
tree | 6c4082c676a086f8818717ec19f078772f75ad9c | |
parent | 31a88d1554550a7c70fd63991051890c4fd71ac7 (diff) |
Implement BLOCK_PASS NODE keyword locations
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/11663
-rw-r--r-- | ast.c | 5 | ||||
-rw-r--r-- | node_dump.c | 3 | ||||
-rw-r--r-- | parse.y | 13 | ||||
-rw-r--r-- | rubyparser.h | 1 | ||||
-rw-r--r-- | test/ruby/test_ast.rb | 8 |
5 files changed, 23 insertions, 7 deletions
@@ -783,6 +783,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_AND(node)->operator_loc)); + case NODE_BLOCK_PASS: + return rb_ary_new_from_args(2, + location_new(nd_code_loc(node)), + location_new(&RNODE_BLOCK_PASS(node)->operator_loc)); + case NODE_BREAK: return rb_ary_new_from_args(2, location_new(nd_code_loc(node)), diff --git a/node_dump.c b/node_dump.c index 0555d11cdc..ad248aea74 100644 --- a/node_dump.c +++ b/node_dump.c @@ -910,8 +910,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) } } F_NODE(nd_head, RNODE_BLOCK_PASS, "other arguments"); - LAST_NODE; F_NODE(nd_body, RNODE_BLOCK_PASS, "block argument"); + LAST_NODE; + F_LOC(operator_loc, RNODE_BLOCK_PASS); return; case NODE_DEFN: @@ -1135,7 +1135,7 @@ static rb_node_postarg_t *rb_node_postarg_new(struct parser_params *p, NODE *nd_ static rb_node_argscat_t *rb_node_argscat_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc); static rb_node_argspush_t *rb_node_argspush_new(struct parser_params *p, NODE *nd_head, NODE *nd_body, const YYLTYPE *loc); static rb_node_splat_t *rb_node_splat_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc); -static rb_node_block_pass_t *rb_node_block_pass_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc); +static rb_node_block_pass_t *rb_node_block_pass_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *operator_loc); static rb_node_defn_t *rb_node_defn_new(struct parser_params *p, ID nd_mid, NODE *nd_defn, const YYLTYPE *loc); static rb_node_defs_t *rb_node_defs_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_defn, const YYLTYPE *loc); static rb_node_alias_t *rb_node_alias_new(struct parser_params *p, NODE *nd_1st, NODE *nd_2nd, const YYLTYPE *loc, const YYLTYPE *keyword_loc); @@ -1243,7 +1243,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE #define NEW_ARGSCAT(a,b,loc) (NODE *)rb_node_argscat_new(p,a,b,loc) #define NEW_ARGSPUSH(a,b,loc) (NODE *)rb_node_argspush_new(p,a,b,loc) #define NEW_SPLAT(a,loc) (NODE *)rb_node_splat_new(p,a,loc) -#define NEW_BLOCK_PASS(b,loc) rb_node_block_pass_new(p,b,loc) +#define NEW_BLOCK_PASS(b,loc,o_loc) rb_node_block_pass_new(p,b,loc,o_loc) #define NEW_DEFN(i,s,loc) (NODE *)rb_node_defn_new(p,i,s,loc) #define NEW_DEFS(r,i,s,loc) (NODE *)rb_node_defs_new(p,r,i,s,loc) #define NEW_ALIAS(n,o,loc,k_loc) (NODE *)rb_node_alias_new(p,n,o,loc,k_loc) @@ -4311,13 +4311,13 @@ command_args : { block_arg : tAMPER arg_value { - $$ = NEW_BLOCK_PASS($2, &@$); + $$ = NEW_BLOCK_PASS($2, &@$, &@1); /*% ripper: $:2 %*/ } | tAMPER { forwarding_arg_check(p, idFWD_BLOCK, idFWD_ALL, "block"); - $$ = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, &@1), &@$); + $$ = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, &@1), &@$, &@1); /*% ripper: Qnil %*/ } ; @@ -12301,12 +12301,13 @@ rb_node_splat_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc) } static rb_node_block_pass_t * -rb_node_block_pass_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc) +rb_node_block_pass_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *operator_loc) { rb_node_block_pass_t *n = NODE_NEWNODE(NODE_BLOCK_PASS, rb_node_block_pass_t, loc); n->forwarding = 0; n->nd_head = 0; n->nd_body = nd_body; + n->operator_loc = *operator_loc; return n; } @@ -15139,7 +15140,7 @@ new_args_forward_call(struct parser_params *p, NODE *leading, const YYLTYPE *loc #ifndef FORWARD_ARGS_WITH_RUBY2_KEYWORDS NODE *kwrest = list_append(p, NEW_LIST(0, loc), NEW_LVAR(idFWD_KWREST, loc)); #endif - rb_node_block_pass_t *block = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, loc), argsloc); + rb_node_block_pass_t *block = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, loc), argsloc, &NULL_LOC); NODE *args = leading ? rest_arg_append(p, leading, rest, argsloc) : NEW_SPLAT(rest, loc); block->forwarding = TRUE; #ifndef FORWARD_ARGS_WITH_RUBY2_KEYWORDS diff --git a/rubyparser.h b/rubyparser.h index cfa881ac41..e856f69a5f 100644 --- a/rubyparser.h +++ b/rubyparser.h @@ -811,6 +811,7 @@ typedef struct RNode_BLOCK_PASS { struct RNode *nd_head; struct RNode *nd_body; unsigned int forwarding: 1; + rb_code_location_t operator_loc; } rb_node_block_pass_t; typedef struct RNode_DEFN { diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb index 38c0d56a0f..940c4de9d7 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -1348,6 +1348,14 @@ dummy assert_locations(node.children[-1].locations, [[1, 0, 1, 6], [1, 2, 1, 4]]) end + def test_block_pass_locations + node = ast_parse("foo(&bar)") + assert_locations(node.children[-1].children[-1].locations, [[1, 4, 1, 8], [1, 4, 1, 5]]) + + node = ast_parse("def a(&); b(&) end") + assert_locations(node.children[-1].children[-1].children[-1].children[-1].children[-1].locations, [[1, 12, 1, 13], [1, 12, 1, 13]]) + end + def test_break_locations node = ast_parse("loop { break 1 }") assert_locations(node.children[-1].children[-1].children[-1].locations, [[1, 7, 1, 14], [1, 7, 1, 12]]) |