ruby-changes:49368
From: nobu <ko1@a...>
Date: Tue, 26 Dec 2017 19:10:50 +0900 (JST)
Subject: [ruby-changes:49368] nobu:r61483 (trunk): parse.y: warning for locations
nobu 2017-12-26 19:10:41 +0900 (Tue, 26 Dec 2017) New Revision: 61483 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61483 Log: 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. Modified files: trunk/parse.y trunk/test/ruby/test_eval.rb trunk/vm_eval.c Index: parse.y =================================================================== --- parse.y (revision 61482) +++ parse.y (revision 61483) @@ -261,6 +261,7 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L261 unsigned int do_loop: 1; unsigned int do_chomp: 1; unsigned int do_split: 1; + unsigned int warn_location: 1; NODE *eval_tree_begin; NODE *eval_tree; @@ -9347,6 +9348,13 @@ past_dvar_p(struct parser_params *parser https://github.com/ruby/ruby/blob/trunk/parse.y#L9348 } # 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* gettable_gen(struct parser_params *parser, ID id, const YYLTYPE *location) { @@ -9370,9 +9378,11 @@ gettable_gen(struct parser_params *parse https://github.com/ruby/ruby/blob/trunk/parse.y#L9378 nd_set_loc(node, location); return node; case keyword__FILE__: + WARN_LOCATION("__FILE__"); node = new_str(rb_str_dup(ruby_sourcefile_string), location); return node; case keyword__LINE__: + WARN_LOCATION("__LINE__"); return new_lit(INT2FIX(tokline), location); case keyword__ENCODING__: return new_lit(rb_enc_from_encoding(current_enc), location); @@ -11527,6 +11537,14 @@ rb_parser_set_options(VALUE vparser, int https://github.com/ruby/ruby/blob/trunk/parse.y#L11537 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 * parser_append_options(struct parser_params *parser, NODE *node) { Index: vm_eval.c =================================================================== --- vm_eval.c (revision 61482) +++ vm_eval.c (revision 61483) @@ -1242,6 +1242,28 @@ rb_each(VALUE obj) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1242 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 eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_arg, VALUE filename, int lineno) @@ -1251,8 +1273,11 @@ eval_string_with_cref(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1273 const struct rb_block *base_block; VALUE file; int line; + int warn_location = FALSE; - file = filename ? filename : rb_source_location(&lineno); + if (!(file = filename)) { + file = rb_source_location(&lineno); + } line = lineno; { @@ -1269,6 +1294,7 @@ eval_string_with_cref(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1294 if (!NIL_P(scope)) { bind = Check_TypedStruct(scope, &ruby_binding_data_type); + warn_location = !filename || filename == Qundef; if (NIL_P(realpath)) { file = pathobj_path(bind->pathobj); realpath = pathobj_realpath(bind->pathobj); @@ -1295,9 +1321,7 @@ eval_string_with_cref(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1321 fname = rb_usascii_str_new_cstr("(eval)"); } - /* make eval iseq */ - iseq = rb_iseq_compile_with_option(src, fname, realpath, INT2FIX(line), base_block, Qnil); - + iseq = eval_make_iseq(fname, realpath, src, line, base_block, warn_location); if (!iseq) { rb_exc_raise(ec->errinfo); } Index: test/ruby/test_eval.rb =================================================================== --- test/ruby/test_eval.rb (revision 61482) +++ test/ruby/test_eval.rb (revision 61483) @@ -503,6 +503,12 @@ class TestEval < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_eval.rb#L503 assert_same a, b 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 bug = "[ruby-core:78116] [Bug #12930]".freeze assert_same bug, (bug.instance_eval {self}) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/