[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]