parse.y: set used flag in gettable
* parse.y (dvar_defined_ref, dvar_defined): rename macros. only gettable uses the former. assignable should not set LVAR_USED flag. * parse.y (gettable_gen): set used flag on local/dynamic variables instead of setting in lexer. [ruby-core:82368] [Bug #13809] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59585 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2bbc30520f
commit
29b114a1ea
36
parse.y
36
parse.y
@ -586,8 +586,9 @@ static void local_var_gen(struct parser_params*, ID);
|
|||||||
#define local_var(id) local_var_gen(parser, (id))
|
#define local_var(id) local_var_gen(parser, (id))
|
||||||
static void arg_var_gen(struct parser_params*, ID);
|
static void arg_var_gen(struct parser_params*, ID);
|
||||||
#define arg_var(id) arg_var_gen(parser, (id))
|
#define arg_var(id) arg_var_gen(parser, (id))
|
||||||
static int local_id_gen(struct parser_params*, ID);
|
static int local_id_gen(struct parser_params*, ID, ID **);
|
||||||
#define local_id(id) local_id_gen(parser, (id))
|
#define local_id_ref(id, vidp) local_id_gen(parser, (id), &(vidp))
|
||||||
|
#define local_id(id) local_id_gen(parser, (id), NULL)
|
||||||
static ID internal_id_gen(struct parser_params*);
|
static ID internal_id_gen(struct parser_params*);
|
||||||
#define internal_id() internal_id_gen(parser)
|
#define internal_id() internal_id_gen(parser)
|
||||||
|
|
||||||
@ -598,9 +599,9 @@ static void dyna_pop_gen(struct parser_params*, const struct vtable *);
|
|||||||
static int dyna_in_block_gen(struct parser_params*);
|
static int dyna_in_block_gen(struct parser_params*);
|
||||||
#define dyna_in_block() dyna_in_block_gen(parser)
|
#define dyna_in_block() dyna_in_block_gen(parser)
|
||||||
#define dyna_var(id) local_var(id)
|
#define dyna_var(id) local_var(id)
|
||||||
static int dvar_defined_gen(struct parser_params*,ID,int);
|
static int dvar_defined_gen(struct parser_params*, ID, ID**);
|
||||||
#define dvar_defined(id) dvar_defined_gen(parser, (id), 0)
|
#define dvar_defined_ref(id, vidp) dvar_defined_gen(parser, (id), &(vidp))
|
||||||
#define dvar_defined_get(id) dvar_defined_gen(parser, (id), 1)
|
#define dvar_defined(id) dvar_defined_gen(parser, (id), NULL)
|
||||||
static int dvar_curr_gen(struct parser_params*,ID);
|
static int dvar_curr_gen(struct parser_params*,ID);
|
||||||
#define dvar_curr(id) dvar_curr_gen(parser, (id))
|
#define dvar_curr(id) dvar_curr_gen(parser, (id))
|
||||||
|
|
||||||
@ -6791,7 +6792,7 @@ formal_argument_gen(struct parser_params *parser, ID lhs)
|
|||||||
static int
|
static int
|
||||||
lvar_defined_gen(struct parser_params *parser, ID id)
|
lvar_defined_gen(struct parser_params *parser, ID id)
|
||||||
{
|
{
|
||||||
return (dyna_in_block() && dvar_defined_get(id)) || local_id(id);
|
return (dyna_in_block() && dvar_defined(id)) || local_id(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* emacsen -*- hack */
|
/* emacsen -*- hack */
|
||||||
@ -8578,6 +8579,8 @@ yylex(YYSTYPE *lval, struct parser_params *parser)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
|
||||||
|
|
||||||
#ifndef RIPPER
|
#ifndef RIPPER
|
||||||
static NODE*
|
static NODE*
|
||||||
node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
|
node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
|
||||||
@ -8932,6 +8935,7 @@ past_dvar_p(struct parser_params *parser, ID id)
|
|||||||
static NODE*
|
static NODE*
|
||||||
gettable_gen(struct parser_params *parser, ID id)
|
gettable_gen(struct parser_params *parser, ID id)
|
||||||
{
|
{
|
||||||
|
ID *vidp = NULL;
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case keyword_self:
|
case keyword_self:
|
||||||
return NEW_SELF();
|
return NEW_SELF();
|
||||||
@ -8950,16 +8954,18 @@ gettable_gen(struct parser_params *parser, ID id)
|
|||||||
}
|
}
|
||||||
switch (id_type(id)) {
|
switch (id_type(id)) {
|
||||||
case ID_LOCAL:
|
case ID_LOCAL:
|
||||||
if (dyna_in_block() && dvar_defined(id)) {
|
if (dyna_in_block() && dvar_defined_ref(id, vidp)) {
|
||||||
if (id == current_arg) {
|
if (id == current_arg) {
|
||||||
rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
|
rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
|
||||||
}
|
}
|
||||||
|
if (vidp) *vidp |= LVAR_USED;
|
||||||
return NEW_DVAR(id);
|
return NEW_DVAR(id);
|
||||||
}
|
}
|
||||||
if (local_id(id)) {
|
if (local_id_ref(id, vidp)) {
|
||||||
if (id == current_arg) {
|
if (id == current_arg) {
|
||||||
rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
|
rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
|
||||||
}
|
}
|
||||||
|
if (vidp) *vidp |= LVAR_USED;
|
||||||
return NEW_LVAR(id);
|
return NEW_LVAR(id);
|
||||||
}
|
}
|
||||||
# if WARN_PAST_SCOPE
|
# if WARN_PAST_SCOPE
|
||||||
@ -9325,8 +9331,6 @@ is_private_local_id(ID name)
|
|||||||
return RSTRING_PTR(s)[0] == '_';
|
return RSTRING_PTR(s)[0] == '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
shadowing_lvar_0(struct parser_params *parser, ID name)
|
shadowing_lvar_0(struct parser_params *parser, ID name)
|
||||||
{
|
{
|
||||||
@ -9335,7 +9339,7 @@ shadowing_lvar_0(struct parser_params *parser, ID name)
|
|||||||
if (dvar_curr(name)) {
|
if (dvar_curr(name)) {
|
||||||
yyerror("duplicated argument name");
|
yyerror("duplicated argument name");
|
||||||
}
|
}
|
||||||
else if (dvar_defined_get(name) || local_id(name)) {
|
else if (dvar_defined(name) || local_id(name)) {
|
||||||
rb_warning1("shadowing outer local variable - %"PRIsWARN, rb_id2str(name));
|
rb_warning1("shadowing outer local variable - %"PRIsWARN, rb_id2str(name));
|
||||||
vtable_add(lvtbl->vars, name);
|
vtable_add(lvtbl->vars, name);
|
||||||
if (lvtbl->used) {
|
if (lvtbl->used) {
|
||||||
@ -10389,7 +10393,7 @@ local_var_gen(struct parser_params *parser, ID id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
local_id_gen(struct parser_params *parser, ID id)
|
local_id_gen(struct parser_params *parser, ID id, ID **vidrefp)
|
||||||
{
|
{
|
||||||
struct vtable *vars, *args, *used;
|
struct vtable *vars, *args, *used;
|
||||||
|
|
||||||
@ -10411,7 +10415,7 @@ local_id_gen(struct parser_params *parser, ID id)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int i = vtable_included(vars, id);
|
int i = vtable_included(vars, id);
|
||||||
if (i && used) used->tbl[i-1] |= LVAR_USED;
|
if (i && used && vidrefp) *vidrefp = &used->tbl[i-1];
|
||||||
return i != 0;
|
return i != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10477,7 +10481,7 @@ dyna_in_block_gen(struct parser_params *parser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dvar_defined_gen(struct parser_params *parser, ID id, int get)
|
dvar_defined_gen(struct parser_params *parser, ID id, ID **vidrefp)
|
||||||
{
|
{
|
||||||
struct vtable *vars, *args, *used;
|
struct vtable *vars, *args, *used;
|
||||||
int i;
|
int i;
|
||||||
@ -10491,12 +10495,12 @@ dvar_defined_gen(struct parser_params *parser, ID id, int get)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ((i = vtable_included(vars, id)) != 0) {
|
if ((i = vtable_included(vars, id)) != 0) {
|
||||||
if (used) used->tbl[i-1] |= LVAR_USED;
|
if (used && vidrefp) *vidrefp = &used->tbl[i-1];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
args = args->prev;
|
args = args->prev;
|
||||||
vars = vars->prev;
|
vars = vars->prev;
|
||||||
if (get) used = 0;
|
if (!vidrefp) used = 0;
|
||||||
if (used) used = used->prev;
|
if (used) used = used->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,8 +881,11 @@ x = __ENCODING__
|
|||||||
def test_unused_variable
|
def test_unused_variable
|
||||||
o = Object.new
|
o = Object.new
|
||||||
assert_warning(/assigned but unused variable/) {o.instance_eval("def foo; a=1; nil; end")}
|
assert_warning(/assigned but unused variable/) {o.instance_eval("def foo; a=1; nil; end")}
|
||||||
|
assert_warning(/assigned but unused variable/) {o.instance_eval("def bar; a=1; a(); end")}
|
||||||
a = "\u{3042}"
|
a = "\u{3042}"
|
||||||
assert_warning(/#{a}/) {o.instance_eval("def foo; #{a}=1; nil; end")}
|
assert_warning(/#{a}/) {o.instance_eval("def foo; #{a}=1; nil; end")}
|
||||||
|
o = Object.new
|
||||||
|
assert_warning(/assigned but unused variable/) {o.instance_eval("def foo; tap {a=1; a()}; end")}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_named_capture_conflict
|
def test_named_capture_conflict
|
||||||
|
Loading…
x
Reference in New Issue
Block a user