From fa66569afa0614ab27d941a68fb99e7adc1d2d48 Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 19 Mar 2019 06:01:21 +0000 Subject: parse.y: fix var_ref of numbered param in ripper * parse.y (string_dvar, user_variable): register numbered parameter in ripper for var_ref. [ruby-core:91867] [Bug #15673] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67306 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- parse.y | 51 ++++++++++++++++++++++++--------------- test/ripper/test_parser_events.rb | 1 + 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/parse.y b/parse.y index b78d878b91..bb4160194d 100644 --- a/parse.y +++ b/parse.y @@ -419,7 +419,6 @@ static NODE *new_args(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*,const YYL static NODE *new_args_tail(struct parser_params*,NODE*,ID,ID,const YYLTYPE*); static NODE *new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc); static NODE *args_with_numbered(struct parser_params*,NODE*,int); -static ID numparam_id(struct parser_params*,int); static VALUE negate_lit(struct parser_params*, VALUE); static NODE *ret_args(struct parser_params*,NODE*); @@ -472,6 +471,7 @@ static int literal_concat0(struct parser_params *p, VALUE head, VALUE tail); static NODE *heredoc_dedent(struct parser_params*,NODE*); #define get_id(id) (id) #define get_value(val) (val) +#define get_num(num) (num) #else /* RIPPER */ #define NODE_RIPPER NODE_CDECL @@ -498,6 +498,7 @@ static ID ripper_get_id(VALUE); #define get_id(id) ripper_get_id(id) static VALUE ripper_get_value(VALUE); #define get_value(val) ripper_get_value(val) +#define get_num(num) (int)get_id(num) static VALUE assignable(struct parser_params*,VALUE); static int id_is_var(struct parser_params *p, ID id); @@ -533,8 +534,11 @@ PRINTF_ARGS(void rb_parser_fatal(struct parser_params *p, const char *fmt, ...), YYLTYPE *rb_parser_set_location_from_strterm_heredoc(struct parser_params *p, rb_strterm_heredoc_t *here, YYLTYPE *yylloc); YYLTYPE *rb_parser_set_location_of_none(struct parser_params *p, YYLTYPE *yylloc); YYLTYPE *rb_parser_set_location(struct parser_params *p, YYLTYPE *yylloc); +ID rb_parser_numparam_id(struct parser_params *p, int num); RUBY_SYMBOL_EXPORT_END +#define numparam_id rb_parser_numparam_id + static void parser_token_value_print(struct parser_params *p, enum yytokentype type, const YYSTYPE *valp); static ID formal_argument(struct parser_params*, ID); static ID shadowing_lvar(struct parser_params*,ID); @@ -3816,9 +3820,11 @@ string_dvar : tGVAR } | tNUMPARAM { + ID id = numparam_id(p, get_num($1)); /*%%%*/ - $$ = NEW_DVAR(numparam_id(p, $1), &@1); + $$ = NEW_DVAR(id, &@1); /*% %*/ + (void)id; /*% ripper: var_ref!(number_arg!($1)) %*/ } | backref @@ -3878,10 +3884,13 @@ user_variable : tIDENTIFIER | tCVAR | tNUMPARAM { - /*%%%*/ - $$ = numparam_id(p, $1); - /*% %*/ + ID id = numparam_id(p, get_num($1)); /*% ripper: number_arg!($1) %*/ + /*%%%*/ + $$ = id; + /*% + $$ = ripper_new_yylval(p, id, $$, 0); + %*/ } ; @@ -9162,6 +9171,8 @@ id_is_var(struct parser_params *p, ID id) switch (id & ID_SCOPE_MASK) { case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS: return 1; + case ID_INTERNAL: + return vtable_included(p->lvtbl->args, id); case ID_LOCAL: if (dyna_in_block(p) && dvar_defined(p, id)) return 1; if (local_id(p, id)) return 1; @@ -9463,21 +9474,6 @@ assignable(struct parser_params *p, ID id, NODE *val, const YYLTYPE *loc) if (err) yyerror1(loc, err); return NEW_BEGIN(0, loc); } - -static ID -numparam_id(struct parser_params *p, int idx) -{ - struct vtable *args; - if (idx <= 0) return (ID)0; - if (p->max_numparam < idx) { - p->max_numparam = idx; - } - args = p->lvtbl->args; - while (idx > args->pos) { - vtable_add(args, internal_id(p)); - } - return args->tbl[idx-1]; -} #else static VALUE assignable(struct parser_params *p, VALUE lhs) @@ -10373,6 +10369,21 @@ args_with_numbered(struct parser_params *p, NODE *args, int max_numparam) return args; } +ID +rb_parser_numparam_id(struct parser_params *p, int idx) +{ + struct vtable *args; + if (idx <= 0) return (ID)0; + if (p->max_numparam < idx) { + p->max_numparam = idx; + } + args = p->lvtbl->args; + while (idx > args->pos) { + vtable_add(args, internal_id(p)); + } + return args->tbl[idx-1]; +} + static NODE* dsym_node(struct parser_params *p, NODE *node, const YYLTYPE *loc) { diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb index e4860ef533..fd01427af5 100644 --- a/test/ripper/test_parser_events.rb +++ b/test/ripper/test_parser_events.rb @@ -58,6 +58,7 @@ class TestRipper::ParserEvents < Test::Unit::TestCase assert_equal '[assign(var_field(a),ref(a))]', parse('a=a') assert_equal '[ref(nil)]', parse('nil') assert_equal '[ref(true)]', parse('true') + assert_include parse('proc{@1}'), '[ref(number_arg(@1))]' end def test_vcall -- cgit v1.2.3