diff --git a/ast.c b/ast.c index 3544aa3b69..fc524d7c46 100644 --- a/ast.c +++ b/ast.c @@ -807,6 +807,11 @@ node_locations(VALUE ast_value, const NODE *node) location_new(nd_code_loc(node)), location_new(&RNODE_CASE3(node)->case_keyword_loc), location_new(&RNODE_CASE3(node)->end_keyword_loc)); + case NODE_EVSTR: + return rb_ary_new_from_args(3, + location_new(nd_code_loc(node)), + location_new(&RNODE_EVSTR(node)->opening_loc), + location_new(&RNODE_EVSTR(node)->closing_loc)); case NODE_IF: return rb_ary_new_from_args(4, location_new(nd_code_loc(node)), diff --git a/node_dump.c b/node_dump.c index ec9a516453..0153296806 100644 --- a/node_dump.c +++ b/node_dump.c @@ -882,8 +882,10 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("interpolation expression"); ANN("format: \"..#{ [nd_body] }..\""); ANN("example: \"foo#{ bar }baz\""); - LAST_NODE; F_NODE(nd_body, RNODE_EVSTR, "body"); + F_LOC(opening_loc, RNODE_EVSTR); + LAST_NODE; + F_LOC(closing_loc, RNODE_EVSTR); return; case NODE_ARGSCAT: diff --git a/parse.y b/parse.y index d103dd028a..f215c62437 100644 --- a/parse.y +++ b/parse.y @@ -1121,7 +1121,7 @@ static rb_node_dstr_t *rb_node_dstr_new0(struct parser_params *p, rb_parser_stri static rb_node_dstr_t *rb_node_dstr_new(struct parser_params *p, rb_parser_string_t *string, const YYLTYPE *loc); static rb_node_xstr_t *rb_node_xstr_new(struct parser_params *p, rb_parser_string_t *string, const YYLTYPE *loc); static rb_node_dxstr_t *rb_node_dxstr_new(struct parser_params *p, rb_parser_string_t *string, long nd_alen, NODE *nd_next, const YYLTYPE *loc); -static rb_node_evstr_t *rb_node_evstr_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc); +static rb_node_evstr_t *rb_node_evstr_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *opening_loc, const YYLTYPE *closing_loc); static rb_node_regx_t *rb_node_regx_new(struct parser_params *p, rb_parser_string_t *string, int options, const YYLTYPE *loc); static rb_node_once_t *rb_node_once_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc); static rb_node_args_t *rb_node_args_new(struct parser_params *p, const YYLTYPE *loc); @@ -1229,7 +1229,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE #define NEW_DSTR(s,loc) (NODE *)rb_node_dstr_new(p,s,loc) #define NEW_XSTR(s,loc) (NODE *)rb_node_xstr_new(p,s,loc) #define NEW_DXSTR(s,l,n,loc) (NODE *)rb_node_dxstr_new(p,s,l,n,loc) -#define NEW_EVSTR(n,loc) (NODE *)rb_node_evstr_new(p,n,loc) +#define NEW_EVSTR(n,loc,o_loc,c_loc) (NODE *)rb_node_evstr_new(p,n,loc,o_loc,c_loc) #define NEW_REGX(str,opts,loc) (NODE *)rb_node_regx_new(p,str,opts,loc) #define NEW_ONCE(b,loc) (NODE *)rb_node_once_new(p,b,loc) #define NEW_ARGS(loc) rb_node_args_new(p,loc) @@ -1409,7 +1409,7 @@ static NODE *arg_append(struct parser_params*,NODE*,NODE*,const YYLTYPE*); static NODE *last_arg_append(struct parser_params *p, NODE *args, NODE *last_arg, const YYLTYPE *loc); static NODE *rest_arg_append(struct parser_params *p, NODE *args, NODE *rest_arg, const YYLTYPE *loc); static NODE *literal_concat(struct parser_params*,NODE*,NODE*,const YYLTYPE*); -static NODE *new_evstr(struct parser_params*,NODE*,const YYLTYPE*); +static NODE *new_evstr(struct parser_params*,NODE*,const YYLTYPE*,const YYLTYPE*,const YYLTYPE*); static NODE *new_dstr(struct parser_params*,NODE*,const YYLTYPE*); static NODE *str2dstr(struct parser_params*,NODE*); static NODE *evstr2dstr(struct parser_params*,NODE*); @@ -6167,7 +6167,7 @@ string_content : tSTRING_CONTENT string_dvar { p->lex.strterm = $2; - $$ = NEW_EVSTR($3, &@$); + $$ = NEW_EVSTR($3, &@$, &@1, &NULL_LOC); nd_set_line($$, @3.end_pos.lineno); /*% ripper: string_dvar!($:3) %*/ } @@ -6198,7 +6198,7 @@ string_content : tSTRING_CONTENT p->heredoc_indent = $indent; p->heredoc_line_indent = -1; if ($compstmt) nd_unset_fl_newline($compstmt); - $$ = new_evstr(p, $compstmt, &@$); + $$ = new_evstr(p, $compstmt, &@$, &@state, &@string_dend); /*% ripper: string_embexpr!($:compstmt) %*/ } ; @@ -12135,10 +12135,12 @@ rb_node_dsym_new(struct parser_params *p, rb_parser_string_t *string, long nd_al } static rb_node_evstr_t * -rb_node_evstr_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc) +rb_node_evstr_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc, const YYLTYPE *opening_loc, const YYLTYPE *closing_loc) { rb_node_evstr_t *n = NODE_NEWNODE(NODE_EVSTR, rb_node_evstr_t, loc); n->nd_body = nd_body; + n->opening_loc = *opening_loc; + n->closing_loc = *closing_loc; return n; } @@ -12824,7 +12826,7 @@ evstr2dstr(struct parser_params *p, NODE *node) } static NODE * -new_evstr(struct parser_params *p, NODE *node, const YYLTYPE *loc) +new_evstr(struct parser_params *p, NODE *node, const YYLTYPE *loc, const YYLTYPE *opening_loc, const YYLTYPE *closing_loc) { NODE *head = node; @@ -12838,7 +12840,7 @@ new_evstr(struct parser_params *p, NODE *node, const YYLTYPE *loc) return node; } } - return NEW_EVSTR(head, loc); + return NEW_EVSTR(head, loc, opening_loc, closing_loc); } static NODE * diff --git a/rubyparser.h b/rubyparser.h index fa2e2af264..e3c7eae05a 100644 --- a/rubyparser.h +++ b/rubyparser.h @@ -725,6 +725,8 @@ typedef struct RNode_EVSTR { NODE node; struct RNode *nd_body; + rb_code_location_t opening_loc; + rb_code_location_t closing_loc; } rb_node_evstr_t; typedef struct RNode_REGX { /* also RNode_MATCH */ diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb index 58d22149b7..4e449410f1 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -1376,6 +1376,14 @@ dummy assert_locations(node.children[-1].locations, [[1, 0, 1, 17], [1, 0, 1, 4], [1, 14, 1, 17]]) end + def test_evstr_locations + node = ast_parse('"#{foo}"') + assert_locations(node.children[-1].children[1].locations, [[1, 0, 1, 8], [1, 1, 1, 3], [1, 6, 1, 7]]) + + node = ast_parse('"#$1"') + assert_locations(node.children[-1].children[1].locations, [[1, 0, 1, 5], [1, 1, 1, 2], nil]) + end + def test_if_locations node = ast_parse("if cond then 1 else 2 end") assert_locations(node.children[-1].locations, [[1, 0, 1, 25], [1, 0, 1, 2], [1, 8, 1, 12], [1, 22, 1, 25]])