mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Refined warnings against literal in flip-flop
This commit is contained in:
parent
79117d4a9b
commit
01b723ba6d
2 changed files with 48 additions and 62 deletions
86
parse.y
86
parse.y
|
@ -10824,19 +10824,20 @@ assign_in_cond(struct parser_params *p, NODE *node)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
enum cond_type {
|
||||||
warn_unless_e_option(struct parser_params *p, NODE *node, const char *str)
|
COND_IN_OP,
|
||||||
{
|
COND_IN_COND,
|
||||||
if (!e_option_supplied(p)) parser_warn(p, node, str);
|
COND_IN_FF
|
||||||
}
|
};
|
||||||
|
|
||||||
static void
|
#define SWITCH_BY_COND_TYPE(t, w, arg) \
|
||||||
warning_unless_e_option(struct parser_params *p, NODE *node, const char *str)
|
switch (t) { \
|
||||||
{
|
case COND_IN_OP: break; \
|
||||||
if (!e_option_supplied(p)) parser_warning(p, node, str);
|
case COND_IN_COND: rb_##w##0(arg "literal in condition"); break; \
|
||||||
}
|
case COND_IN_FF: rb_##w##0(arg "literal in flip-flop"); break; \
|
||||||
|
}
|
||||||
|
|
||||||
static NODE *cond0(struct parser_params*,NODE*,int,const YYLTYPE*);
|
static NODE *cond0(struct parser_params*,NODE*,enum cond_type,const YYLTYPE*);
|
||||||
|
|
||||||
static NODE*
|
static NODE*
|
||||||
range_op(struct parser_params *p, NODE *node, const YYLTYPE *loc)
|
range_op(struct parser_params *p, NODE *node, const YYLTYPE *loc)
|
||||||
|
@ -10848,35 +10849,14 @@ range_op(struct parser_params *p, NODE *node, const YYLTYPE *loc)
|
||||||
type = nd_type(node);
|
type = nd_type(node);
|
||||||
value_expr(node);
|
value_expr(node);
|
||||||
if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
|
if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
|
||||||
warn_unless_e_option(p, node, "integer literal in conditional range");
|
if (!e_option_supplied(p)) parser_warn(p, node, "integer literal in flip-flop");
|
||||||
return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."), loc), loc), loc);
|
return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."), loc), loc), loc);
|
||||||
}
|
}
|
||||||
return cond0(p, node, FALSE, loc);
|
return cond0(p, node, COND_IN_FF, loc);
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
literal_node(NODE *node)
|
|
||||||
{
|
|
||||||
if (!node) return 1; /* same as NODE_NIL */
|
|
||||||
if (!(node = nd_once_body(node))) return 1;
|
|
||||||
switch (nd_type(node)) {
|
|
||||||
case NODE_LIT:
|
|
||||||
case NODE_STR:
|
|
||||||
case NODE_DSTR:
|
|
||||||
case NODE_EVSTR:
|
|
||||||
case NODE_DREGX:
|
|
||||||
case NODE_DSYM:
|
|
||||||
return 2;
|
|
||||||
case NODE_TRUE:
|
|
||||||
case NODE_FALSE:
|
|
||||||
case NODE_NIL:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NODE*
|
static NODE*
|
||||||
cond0(struct parser_params *p, NODE *node, int method_op, const YYLTYPE *loc)
|
cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
if (node == 0) return 0;
|
if (node == 0) return 0;
|
||||||
if (!(node = nd_once_body(node))) return 0;
|
if (!(node = nd_once_body(node))) return 0;
|
||||||
|
@ -10886,21 +10866,18 @@ cond0(struct parser_params *p, NODE *node, int method_op, const YYLTYPE *loc)
|
||||||
case NODE_DSTR:
|
case NODE_DSTR:
|
||||||
case NODE_EVSTR:
|
case NODE_EVSTR:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
if (!method_op) rb_warn0("string literal in condition");
|
SWITCH_BY_COND_TYPE(type, warn, "string ")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_DREGX:
|
case NODE_DREGX:
|
||||||
{
|
if (!e_option_supplied(p)) SWITCH_BY_COND_TYPE(type, warning, "regex ")
|
||||||
if (!method_op)
|
|
||||||
warning_unless_e_option(p, node, "regex literal in condition");
|
|
||||||
|
|
||||||
return NEW_MATCH2(node, NEW_GVAR(idLASTLINE, loc), loc);
|
return NEW_MATCH2(node, NEW_GVAR(idLASTLINE, loc), loc);
|
||||||
}
|
|
||||||
|
|
||||||
case NODE_AND:
|
case NODE_AND:
|
||||||
case NODE_OR:
|
case NODE_OR:
|
||||||
node->nd_1st = cond0(p, node->nd_1st, FALSE, loc);
|
node->nd_1st = cond0(p, node->nd_1st, COND_IN_COND, loc);
|
||||||
node->nd_2nd = cond0(p, node->nd_2nd, FALSE, loc);
|
node->nd_2nd = cond0(p, node->nd_2nd, COND_IN_COND, loc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_DOT2:
|
case NODE_DOT2:
|
||||||
|
@ -10909,23 +10886,15 @@ cond0(struct parser_params *p, NODE *node, int method_op, const YYLTYPE *loc)
|
||||||
node->nd_end = range_op(p, node->nd_end, loc);
|
node->nd_end = range_op(p, node->nd_end, loc);
|
||||||
if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
|
if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
|
||||||
else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
|
else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
|
||||||
if (!method_op && !e_option_supplied(p)) {
|
|
||||||
int b = literal_node(node->nd_beg);
|
|
||||||
int e = literal_node(node->nd_end);
|
|
||||||
if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
|
|
||||||
parser_warn(p, node, "range literal in condition");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_DSYM:
|
case NODE_DSYM:
|
||||||
if (!method_op) parser_warning(p, node, "literal in condition");
|
SWITCH_BY_COND_TYPE(type, warning, "string ")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
|
if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
|
||||||
if (!method_op)
|
if (!e_option_supplied(p)) SWITCH_BY_COND_TYPE(type, warn, "regex ")
|
||||||
warn_unless_e_option(p, node, "regex literal in condition");
|
|
||||||
nd_set_type(node, NODE_MATCH);
|
nd_set_type(node, NODE_MATCH);
|
||||||
}
|
}
|
||||||
else if (node->nd_lit == Qtrue ||
|
else if (node->nd_lit == Qtrue ||
|
||||||
|
@ -10933,8 +10902,7 @@ cond0(struct parser_params *p, NODE *node, int method_op, const YYLTYPE *loc)
|
||||||
/* booleans are OK, e.g., while true */
|
/* booleans are OK, e.g., while true */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!method_op)
|
SWITCH_BY_COND_TYPE(type, warning, "")
|
||||||
parser_warning(p, node, "literal in condition");
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -10946,21 +10914,21 @@ static NODE*
|
||||||
cond(struct parser_params *p, NODE *node, const YYLTYPE *loc)
|
cond(struct parser_params *p, NODE *node, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
if (node == 0) return 0;
|
if (node == 0) return 0;
|
||||||
return cond0(p, node, FALSE, loc);
|
return cond0(p, node, COND_IN_COND, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NODE*
|
static NODE*
|
||||||
method_cond(struct parser_params *p, NODE *node, const YYLTYPE *loc)
|
method_cond(struct parser_params *p, NODE *node, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
if (node == 0) return 0;
|
if (node == 0) return 0;
|
||||||
return cond0(p, node, TRUE, loc);
|
return cond0(p, node, COND_IN_OP, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NODE*
|
static NODE*
|
||||||
new_if(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYLTYPE *loc)
|
new_if(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
if (!cc) return right;
|
if (!cc) return right;
|
||||||
cc = cond0(p, cc, FALSE, loc);
|
cc = cond0(p, cc, COND_IN_COND, loc);
|
||||||
return newline_node(NEW_IF(cc, left, right, loc));
|
return newline_node(NEW_IF(cc, left, right, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10968,7 +10936,7 @@ static NODE*
|
||||||
new_unless(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYLTYPE *loc)
|
new_unless(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
if (!cc) return right;
|
if (!cc) return right;
|
||||||
cc = cond0(p, cc, FALSE, loc);
|
cc = cond0(p, cc, COND_IN_COND, loc);
|
||||||
return newline_node(NEW_UNLESS(cc, left, right, loc));
|
return newline_node(NEW_UNLESS(cc, left, right, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1007,9 +1007,6 @@ eom
|
||||||
assert_warn(/literal in condition/) do
|
assert_warn(/literal in condition/) do
|
||||||
eval('1 if //')
|
eval('1 if //')
|
||||||
end
|
end
|
||||||
assert_warn(/literal in condition/) do
|
|
||||||
eval('1 if true..false')
|
|
||||||
end
|
|
||||||
assert_warning(/literal in condition/) do
|
assert_warning(/literal in condition/) do
|
||||||
eval('1 if 1')
|
eval('1 if 1')
|
||||||
end
|
end
|
||||||
|
@ -1040,6 +1037,27 @@ eom
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_warning_literal_in_flip_flop
|
||||||
|
assert_warn(/literal in flip-flop/) do
|
||||||
|
eval('1 if ""..false')
|
||||||
|
end
|
||||||
|
assert_warning(/literal in flip-flop/) do
|
||||||
|
eval('1 if :foo..false')
|
||||||
|
end
|
||||||
|
assert_warning(/literal in flip-flop/) do
|
||||||
|
eval('1 if :"#{"foo".upcase}"..false')
|
||||||
|
end
|
||||||
|
assert_warn(/literal in flip-flop/) do
|
||||||
|
eval('1 if ""...false')
|
||||||
|
end
|
||||||
|
assert_warning(/literal in flip-flop/) do
|
||||||
|
eval('1 if :foo...false')
|
||||||
|
end
|
||||||
|
assert_warning(/literal in flip-flop/) do
|
||||||
|
eval('1 if :"#{"foo".upcase}"...false')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_alias_symbol
|
def test_alias_symbol
|
||||||
bug8851 = '[ruby-dev:47681] [Bug #8851]'
|
bug8851 = '[ruby-dev:47681] [Bug #8851]'
|
||||||
formats = ['%s', ":'%s'", ':"%s"', '%%s(%s)']
|
formats = ['%s', ":'%s'", ':"%s"', '%%s(%s)']
|
||||||
|
|
Loading…
Reference in a new issue