summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorydah <[email protected]>2024-09-24 14:49:00 +0900
committerYuichiro Kaneko <[email protected]>2024-09-25 09:15:43 +0900
commit509b577e0126d92f37ae45d83863c449f8666be1 (patch)
tree6c4082c676a086f8818717ec19f078772f75ad9c
parent31a88d1554550a7c70fd63991051890c4fd71ac7 (diff)
Implement BLOCK_PASS NODE keyword locations
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/11663
-rw-r--r--ast.c5
-rw-r--r--node_dump.c3
-rw-r--r--parse.y13
-rw-r--r--rubyparser.h1
-rw-r--r--test/ruby/test_ast.rb8
5 files changed, 23 insertions, 7 deletions
diff --git a/ast.c b/ast.c
index a3490823ae..d2bc60c3e1 100644
--- a/ast.c
+++ b/ast.c
@@ -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:
diff --git a/parse.y b/parse.y
index aa87d16a09..4fad1cd812 100644
--- a/parse.y
+++ b/parse.y
@@ -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]])