parse.y: warning for locations
* parse.y (gettable_gen): warn for __FILE__/__LINE__ when eval with binding only. promote use of Binding#source_location instead. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61483 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
62a3e7a33b
commit
3802fb92ff
18
parse.y
18
parse.y
@ -261,6 +261,7 @@ struct parser_params {
|
|||||||
unsigned int do_loop: 1;
|
unsigned int do_loop: 1;
|
||||||
unsigned int do_chomp: 1;
|
unsigned int do_chomp: 1;
|
||||||
unsigned int do_split: 1;
|
unsigned int do_split: 1;
|
||||||
|
unsigned int warn_location: 1;
|
||||||
|
|
||||||
NODE *eval_tree_begin;
|
NODE *eval_tree_begin;
|
||||||
NODE *eval_tree;
|
NODE *eval_tree;
|
||||||
@ -9347,6 +9348,13 @@ past_dvar_p(struct parser_params *parser, ID id)
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
#define WARN_LOCATION(type) do { \
|
||||||
|
if (parser->warn_location) { \
|
||||||
|
rb_warning0(type" in eval may not return location in binding;" \
|
||||||
|
" use Binding#source_location instead"); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static NODE*
|
static NODE*
|
||||||
gettable_gen(struct parser_params *parser, ID id, const YYLTYPE *location)
|
gettable_gen(struct parser_params *parser, ID id, const YYLTYPE *location)
|
||||||
{
|
{
|
||||||
@ -9370,9 +9378,11 @@ gettable_gen(struct parser_params *parser, ID id, const YYLTYPE *location)
|
|||||||
nd_set_loc(node, location);
|
nd_set_loc(node, location);
|
||||||
return node;
|
return node;
|
||||||
case keyword__FILE__:
|
case keyword__FILE__:
|
||||||
|
WARN_LOCATION("__FILE__");
|
||||||
node = new_str(rb_str_dup(ruby_sourcefile_string), location);
|
node = new_str(rb_str_dup(ruby_sourcefile_string), location);
|
||||||
return node;
|
return node;
|
||||||
case keyword__LINE__:
|
case keyword__LINE__:
|
||||||
|
WARN_LOCATION("__LINE__");
|
||||||
return new_lit(INT2FIX(tokline), location);
|
return new_lit(INT2FIX(tokline), location);
|
||||||
case keyword__ENCODING__:
|
case keyword__ENCODING__:
|
||||||
return new_lit(rb_enc_from_encoding(current_enc), location);
|
return new_lit(rb_enc_from_encoding(current_enc), location);
|
||||||
@ -11527,6 +11537,14 @@ rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split)
|
|||||||
parser->do_split = split;
|
parser->do_split = split;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_parser_warn_location(VALUE vparser, int warn)
|
||||||
|
{
|
||||||
|
struct parser_params *parser;
|
||||||
|
TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
|
||||||
|
parser->warn_location = warn;
|
||||||
|
}
|
||||||
|
|
||||||
static NODE *
|
static NODE *
|
||||||
parser_append_options(struct parser_params *parser, NODE *node)
|
parser_append_options(struct parser_params *parser, NODE *node)
|
||||||
{
|
{
|
||||||
|
@ -503,6 +503,12 @@ class TestEval < Test::Unit::TestCase
|
|||||||
assert_same a, b
|
assert_same a, b
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_eval_location_binding
|
||||||
|
assert_warning(/__FILE__ in eval/) do
|
||||||
|
assert_equal(__FILE__, eval("__FILE__", binding))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_fstring_instance_eval
|
def test_fstring_instance_eval
|
||||||
bug = "[ruby-core:78116] [Bug #12930]".freeze
|
bug = "[ruby-core:78116] [Bug #12930]".freeze
|
||||||
assert_same bug, (bug.instance_eval {self})
|
assert_same bug, (bug.instance_eval {self})
|
||||||
|
32
vm_eval.c
32
vm_eval.c
@ -1242,6 +1242,28 @@ rb_each(VALUE obj)
|
|||||||
return rb_call(obj, idEach, 0, 0, CALL_FCALL);
|
return rb_call(obj, idEach, 0, 0, CALL_FCALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rb_parser_warn_location(VALUE, int);
|
||||||
|
static const rb_iseq_t *
|
||||||
|
eval_make_iseq(VALUE fname, VALUE realpath, VALUE src, int line, const struct rb_block *base_block, int warn_location)
|
||||||
|
{
|
||||||
|
const VALUE parser = rb_parser_new();
|
||||||
|
const rb_iseq_t *const parent = vm_block_iseq(base_block);
|
||||||
|
rb_iseq_t *iseq = 0;
|
||||||
|
rb_ast_t *ast;
|
||||||
|
|
||||||
|
rb_parser_set_context(parser, base_block, FALSE);
|
||||||
|
rb_parser_warn_location(parser, warn_location);
|
||||||
|
ast = rb_parser_compile_string_path(parser, fname, src, line);
|
||||||
|
if (ast->root) {
|
||||||
|
iseq = rb_iseq_new_with_opt(ast->root,
|
||||||
|
parent->body->location.label,
|
||||||
|
fname, realpath, INT2FIX(line),
|
||||||
|
parent, ISEQ_TYPE_EVAL, NULL);
|
||||||
|
}
|
||||||
|
rb_ast_dispose(ast);
|
||||||
|
return iseq;
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_arg,
|
eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_arg,
|
||||||
VALUE filename, int lineno)
|
VALUE filename, int lineno)
|
||||||
@ -1251,8 +1273,11 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
|||||||
const struct rb_block *base_block;
|
const struct rb_block *base_block;
|
||||||
VALUE file;
|
VALUE file;
|
||||||
int line;
|
int line;
|
||||||
|
int warn_location = FALSE;
|
||||||
|
|
||||||
file = filename ? filename : rb_source_location(&lineno);
|
if (!(file = filename)) {
|
||||||
|
file = rb_source_location(&lineno);
|
||||||
|
}
|
||||||
line = lineno;
|
line = lineno;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1269,6 +1294,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
|||||||
if (!NIL_P(scope)) {
|
if (!NIL_P(scope)) {
|
||||||
bind = Check_TypedStruct(scope, &ruby_binding_data_type);
|
bind = Check_TypedStruct(scope, &ruby_binding_data_type);
|
||||||
|
|
||||||
|
warn_location = !filename || filename == Qundef;
|
||||||
if (NIL_P(realpath)) {
|
if (NIL_P(realpath)) {
|
||||||
file = pathobj_path(bind->pathobj);
|
file = pathobj_path(bind->pathobj);
|
||||||
realpath = pathobj_realpath(bind->pathobj);
|
realpath = pathobj_realpath(bind->pathobj);
|
||||||
@ -1295,9 +1321,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_
|
|||||||
fname = rb_usascii_str_new_cstr("(eval)");
|
fname = rb_usascii_str_new_cstr("(eval)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make eval iseq */
|
iseq = eval_make_iseq(fname, realpath, src, line, base_block, warn_location);
|
||||||
iseq = rb_iseq_compile_with_option(src, fname, realpath, INT2FIX(line), base_block, Qnil);
|
|
||||||
|
|
||||||
if (!iseq) {
|
if (!iseq) {
|
||||||
rb_exc_raise(ec->errinfo);
|
rb_exc_raise(ec->errinfo);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user