mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
parse.y: warn past scope variable
* parse.y (gettable_gen): warn possible reference to a local variable defined in a past scope. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48986 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ce59e249a5
commit
f5f6218a23
3 changed files with 34 additions and 2 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Thu Dec 25 12:47:44 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* parse.y (gettable_gen): warn possible reference to a local
|
||||||
|
variable defined in a past scope.
|
||||||
|
|
||||||
Thu Dec 25 10:09:14 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Dec 25 10:09:14 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* ext/io/console/console.c (console_dev): id_console is not a
|
* ext/io/console/console.c (console_dev): id_console is not a
|
||||||
|
|
27
parse.y
27
parse.y
|
@ -113,6 +113,7 @@ struct local_vars {
|
||||||
struct vtable *args;
|
struct vtable *args;
|
||||||
struct vtable *vars;
|
struct vtable *vars;
|
||||||
struct vtable *used;
|
struct vtable *used;
|
||||||
|
struct vtable *past;
|
||||||
struct local_vars *prev;
|
struct local_vars *prev;
|
||||||
stack_type cmdargs;
|
stack_type cmdargs;
|
||||||
};
|
};
|
||||||
|
@ -8827,6 +8828,17 @@ match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
|
||||||
return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
|
return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
past_dvar_p(struct parser_params *parser, ID id)
|
||||||
|
{
|
||||||
|
struct vtable *past = lvtbl->past;
|
||||||
|
while (past) {
|
||||||
|
if (vtable_included(past, id)) return 1;
|
||||||
|
past = past->prev;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static NODE*
|
static NODE*
|
||||||
gettable_gen(struct parser_params *parser, ID id)
|
gettable_gen(struct parser_params *parser, ID id)
|
||||||
{
|
{
|
||||||
|
@ -8860,6 +8872,9 @@ gettable_gen(struct parser_params *parser, ID id)
|
||||||
}
|
}
|
||||||
return NEW_LVAR(id);
|
return NEW_LVAR(id);
|
||||||
}
|
}
|
||||||
|
if (!in_defined && RTEST(ruby_verbose) && past_dvar_p(parser, id)) {
|
||||||
|
rb_warningV("possible reference to past scope - %"PRIsVALUE, rb_id2str(id));
|
||||||
|
}
|
||||||
/* method call without arguments */
|
/* method call without arguments */
|
||||||
return NEW_VCALL(id);
|
return NEW_VCALL(id);
|
||||||
case ID_GLOBAL:
|
case ID_GLOBAL:
|
||||||
|
@ -9978,6 +9993,7 @@ local_push_gen(struct parser_params *parser, int inherit_dvars)
|
||||||
local->used = !(inherit_dvars &&
|
local->used = !(inherit_dvars &&
|
||||||
(ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
|
(ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
|
||||||
RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
|
RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
|
||||||
|
local->past = 0;
|
||||||
local->cmdargs = cmdarg_stack;
|
local->cmdargs = cmdarg_stack;
|
||||||
cmdarg_stack = 0;
|
cmdarg_stack = 0;
|
||||||
lvtbl = local;
|
lvtbl = local;
|
||||||
|
@ -9991,6 +10007,11 @@ local_pop_gen(struct parser_params *parser)
|
||||||
warn_unused_var(parser, lvtbl);
|
warn_unused_var(parser, lvtbl);
|
||||||
vtable_free(lvtbl->used);
|
vtable_free(lvtbl->used);
|
||||||
}
|
}
|
||||||
|
while (lvtbl->past) {
|
||||||
|
struct vtable *past = lvtbl->past;
|
||||||
|
lvtbl->past = past->prev;
|
||||||
|
vtable_free(past);
|
||||||
|
}
|
||||||
vtable_free(lvtbl->args);
|
vtable_free(lvtbl->args);
|
||||||
vtable_free(lvtbl->vars);
|
vtable_free(lvtbl->vars);
|
||||||
cmdarg_stack = lvtbl->cmdargs;
|
cmdarg_stack = lvtbl->cmdargs;
|
||||||
|
@ -10090,10 +10111,12 @@ dyna_pop_1(struct parser_params *parser)
|
||||||
}
|
}
|
||||||
tmp = lvtbl->args;
|
tmp = lvtbl->args;
|
||||||
lvtbl->args = lvtbl->args->prev;
|
lvtbl->args = lvtbl->args->prev;
|
||||||
vtable_free(tmp);
|
tmp->prev = lvtbl->past;
|
||||||
|
lvtbl->past = tmp;
|
||||||
tmp = lvtbl->vars;
|
tmp = lvtbl->vars;
|
||||||
lvtbl->vars = lvtbl->vars->prev;
|
lvtbl->vars = lvtbl->vars->prev;
|
||||||
vtable_free(tmp);
|
tmp->prev = lvtbl->past;
|
||||||
|
lvtbl->past = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -873,4 +873,8 @@ x = __ENCODING__
|
||||||
a = "\u{3042}"
|
a = "\u{3042}"
|
||||||
assert_warning(/#{a}/) {eval("#{a} = 1; /(?<#{a}>)/ =~ ''")}
|
assert_warning(/#{a}/) {eval("#{a} = 1; /(?<#{a}>)/ =~ ''")}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_past_scope_variable
|
||||||
|
assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue