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

ruby-changes:36905

From: nobu <ko1@a...>
Date: Thu, 25 Dec 2014 12:47:57 +0900 (JST)
Subject: [ruby-changes:36905] nobu:r48986 (trunk): parse.y: warn past scope variable

nobu	2014-12-25 12:47:46 +0900 (Thu, 25 Dec 2014)

  New Revision: 48986

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48986

  Log:
    parse.y: warn past scope variable
    
    * parse.y (gettable_gen): warn possible reference to a local
      variable defined in a past scope.

  Modified files:
    trunk/ChangeLog
    trunk/parse.y
    trunk/test/ruby/test_parse.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 48985)
+++ ChangeLog	(revision 48986)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Dec 25 12:47:44 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* parse.y (gettable_gen): warn possible reference to a local
+	  variable defined in a past scope.
+
 Thu Dec 25 10:09:14 2014  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/io/console/console.c (console_dev): id_console is not a
Index: parse.y
===================================================================
--- parse.y	(revision 48985)
+++ parse.y	(revision 48986)
@@ -113,6 +113,7 @@ struct local_vars { https://github.com/ruby/ruby/blob/trunk/parse.y#L113
     struct vtable *args;
     struct vtable *vars;
     struct vtable *used;
+    struct vtable *past;
     struct local_vars *prev;
     stack_type cmdargs;
 };
@@ -8827,6 +8828,17 @@ match_op_gen(struct parser_params *parse https://github.com/ruby/ruby/blob/trunk/parse.y#L8828
     return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
 }
 
+static int
+past_dvar_p(struct parser_params *parser, ID id)
+{
+    struct vtable *past = lvtbl->past;
+    while (past) {
+	if (vtable_included(past, id)) return 1;
+	past = past->prev;
+    }
+    return 0;
+}
+
 static NODE*
 gettable_gen(struct parser_params *parser, ID id)
 {
@@ -8860,6 +8872,9 @@ gettable_gen(struct parser_params *parse https://github.com/ruby/ruby/blob/trunk/parse.y#L8872
 	    }
 	    return NEW_LVAR(id);
 	}
+	if (!in_defined && RTEST(ruby_verbose) && past_dvar_p(parser, id)) {
+	    rb_warningV("possible reference to past scope - %"PRIsVALUE, rb_id2str(id));
+	}
 	/* method call without arguments */
 	return NEW_VCALL(id);
       case ID_GLOBAL:
@@ -9978,6 +9993,7 @@ local_push_gen(struct parser_params *par https://github.com/ruby/ruby/blob/trunk/parse.y#L9993
     local->used = !(inherit_dvars &&
 		    (ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
 	RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
+    local->past = 0;
     local->cmdargs = cmdarg_stack;
     cmdarg_stack = 0;
     lvtbl = local;
@@ -9991,6 +10007,11 @@ local_pop_gen(struct parser_params *pars https://github.com/ruby/ruby/blob/trunk/parse.y#L10007
 	warn_unused_var(parser, lvtbl);
 	vtable_free(lvtbl->used);
     }
+    while (lvtbl->past) {
+	struct vtable *past = lvtbl->past;
+	lvtbl->past = past->prev;
+	vtable_free(past);
+    }
     vtable_free(lvtbl->args);
     vtable_free(lvtbl->vars);
     cmdarg_stack = lvtbl->cmdargs;
@@ -10090,10 +10111,12 @@ dyna_pop_1(struct parser_params *parser) https://github.com/ruby/ruby/blob/trunk/parse.y#L10111
     }
     tmp = lvtbl->args;
     lvtbl->args = lvtbl->args->prev;
-    vtable_free(tmp);
+    tmp->prev = lvtbl->past;
+    lvtbl->past = tmp;
     tmp = lvtbl->vars;
     lvtbl->vars = lvtbl->vars->prev;
-    vtable_free(tmp);
+    tmp->prev = lvtbl->past;
+    lvtbl->past = tmp;
 }
 
 static void
Index: test/ruby/test_parse.rb
===================================================================
--- test/ruby/test_parse.rb	(revision 48985)
+++ test/ruby/test_parse.rb	(revision 48986)
@@ -873,4 +873,8 @@ x = __ENCODING__ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_parse.rb#L873
     a = "\u{3042}"
     assert_warning(/#{a}/) {eval("#{a} = 1; /(?<#{a}>)/ =~ ''")}
   end
+
+  def test_past_scope_variable
+    assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}}
+  end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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