Feature #1374

location of already initialized constant

Added by nobu (Nobuyoshi Nakada) about 3 years ago. Updated 3 months ago.

[ruby-dev:38301]
Status:Closed Start date:
Priority:Normal Due date:
Assignee:nobu (Nobuyoshi Nakada) % Done:

0%

Category:core
Target version:2.0.0

Description

なかだです。

初期化済み定数の警告で、定義された場所を表示するのはどうでしょうか。

$ ./ruby -e X=1 -e X=2
-e:2: warning: already initialized constant X at -e:1


Index: class.c
===================================================================
--- class.c	(revision 23168)
+++ class.c	(working copy)
@@ -26,4 +26,5 @@ class_alloc(VALUE flags, VALUE klass)
     RCLASS_IV_TBL(obj) = 0;
     RCLASS_M_TBL(obj) = 0;
+    RCLASS_LOC_TBL(obj) = 0;
     RCLASS_SUPER(obj) = 0;
     RCLASS_IV_INDEX_TBL(obj) = 0;
Index: gc.c
===================================================================
--- gc.c	(revision 23168)
+++ gc.c	(working copy)
@@ -1552,4 +1552,5 @@ gc_mark_children(rb_objspace_t *objspace
 	mark_tbl(objspace, RCLASS_M_TBL(obj), lev);
 	mark_tbl(objspace, RCLASS_IV_TBL(obj), lev);
+	mark_tbl(objspace, RCLASS_LOC_TBL(obj), lev);
 	ptr = RCLASS_SUPER(obj);
 	goto again;
Index: variable.c
===================================================================
--- variable.c	(revision 23168)
+++ variable.c	(working copy)
@@ -1512,4 +1512,12 @@
 {
     return rb_const_get_0(klass, id, Qtrue, Qfalse);
+}
+
+static void
+remove_loc(VALUE mod, ID id)
+{
+    if (RCLASS_LOC_TBL(mod)) {
+	st_delete(RCLASS_LOC_TBL(mod), &id, 0);
+    }
 }

@@ -1545,4 +1553,5 @@ rb_mod_remove_const(VALUE mod, VALUE nam
 	    val = Qnil;
 	}
+	remove_loc(mod, id);
 	return val;
     }
@@ -1712,11 +1721,28 @@ mod_av_set(VALUE klass, ID id, VALUE val
     }
     else if (isconst) {
-	VALUE value = Qfalse;
+	st_data_t value = Qfalse;

 	if (st_lookup(RCLASS_IV_TBL(klass), id, &value)) {
-	    if (value == Qundef)
-	      autoload_delete(klass, id);
-	    else
-	      rb_warn("already initialized %s %s", dest, rb_id2name(id));
+	    if ((VALUE)value == Qundef)
+		autoload_delete(klass, id);
+	    else {
+		VALUE file = Qnil;
+		long line = 0;
+		if (st_lookup(RCLASS_LOC_TBL(klass), id, &value)) {
+		    file = RNODE(value)->nd_lit;
+		    line = RNODE(value)->nd_cnt;
+		}
+		if (!RTEST(file)) {
+		    rb_warn("already initialized %s %s", dest, rb_id2name(id));
+		}
+		else if (!line) {
+		    rb_warn("already initialized %s %s in %s", dest, rb_id2name(id),
+			    RSTRING_PTR(file));
+		}
+		else {
+		    rb_warn("already initialized %s %s at %s:%ld", dest, rb_id2name(id),
+			    RSTRING_PTR(file), line);
+		}
+	    }
 	}
     }
@@ -1726,4 +1752,12 @@ mod_av_set(VALUE klass, ID id, VALUE val
     }
     st_insert(RCLASS_IV_TBL(klass), id, val);
+    if (!NIL_P(ruby_verbose)) {
+	NODE *loc = NEW_LIT(rb_sourcefile_str());
+	loc->nd_cnt = rb_sourceline();
+	if (!RCLASS_LOC_TBL(klass)) {
+	    RCLASS_LOC_TBL(klass) = st_init_numtable();
+	}
+	st_insert(RCLASS_LOC_TBL(klass), id, (st_data_t)loc);
+    }
 }

@@ -1958,4 +1992,5 @@ rb_mod_remove_cvar(VALUE mod, VALUE name

     if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), &n, &val)) {
+	remove_loc(mod, id);
 	return (VALUE)val;
     }
Index: vm.c
===================================================================
--- vm.c	(revision 23168)
+++ vm.c	(working copy)
@@ -749,9 +749,17 @@ const char *
 rb_sourcefile(void)
 {
+    VALUE file = rb_sourcefile_str();
+    if (file) return RSTRING_PTR(file);
+    return 0;
+}
+
+VALUE
+rb_sourcefile_str(void)
+{
     rb_thread_t *th = GET_THREAD();
     rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);

     if (cfp) {
-	return RSTRING_PTR(cfp->iseq->filename);
+	return cfp->iseq->filename;
     }
     else {
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 23168)
+++ include/ruby/intern.h	(working copy)
@@ -200,4 +200,5 @@ void rb_check_frozen(VALUE);
 int rb_sourceline(void);
 const char *rb_sourcefile(void);
+VALUE rb_sourcefile_str(void);

 #if defined(NFDBITS) && defined(HAVE_RB_FD_INIT)
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 23168)
+++ include/ruby/ruby.h	(working copy)
@@ -581,4 +581,5 @@ typedef struct {
     VALUE super;
     struct st_table *iv_tbl;
+    struct st_table *loc_tbl;
 } rb_classext_t;

@@ -591,4 +592,5 @@ struct RClass {
 #define RCLASS_IV_TBL(c) (RCLASS(c)->ptr->iv_tbl)
 #define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
+#define RCLASS_LOC_TBL(c) (RCLASS(c)->ptr->loc_tbl)
 #define RCLASS_SUPER(c) (RCLASS(c)->ptr->super)
 #define RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl)


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

History

Updated by marcandre (Marc-Andre Lafortune) over 2 years ago

  • Category set to core
  • Assignee set to matz (Yukihiro Matsumoto)

Updated by mame (Yusuke Endoh) about 2 years ago

  • Target version set to 2.0.0
遠藤です。

このパッチは rb_classext_t をいじるので、private constant とともに
1.9.3 を目指しましょう。

ということで target を 1.9.x にします。

-- 
Yusuke Endoh <mame@tsg.ne.jp>

Updated by shyouhei (Shyouhei Urabe) over 1 year ago

  • Status changed from Open to Assigned

Updated by ko1 (Koichi Sasada) 12 months ago

まつもとさん? 中田さん? これ,どうなってますでしょう.

Updated by matz (Yukihiro Matsumoto) 12 months ago

まつもと ゆきひろです In message "Re: [ruby-dev:43707] [Ruby 1.9 - Feature #1374] location of already initialized constant" on Sat, 11 Jun 2011 14:27:28 +0900, Koichi Sasada <redmine@ruby-lang.org> writes: |Issue #1374 has been updated by Koichi Sasada. | |まつもとさん? 中田さん? |これ,どうなってますでしょう. 導入に反対はしません。いつ入れるかはメンテナにお任せします。

Updated by matz (Yukihiro Matsumoto) 12 months ago

まつもと ゆきひろです In message "Re: [ruby-dev:43707] [Ruby 1.9 - Feature #1374] location of already initialized constant" on Sat, 11 Jun 2011 14:27:28 +0900, Koichi Sasada <redmine@ruby-lang.org> writes: |Issue #1374 has been updated by Koichi Sasada. | |まつもとさん? 中田さん? |これ,どうなってますでしょう. 導入に反対はしません。いつ入れるかはメンテナにお任せします。

Updated by mame (Yusuke Endoh) 3 months ago

  • Assignee changed from matz (Yukihiro Matsumoto) to nobu (Nobuyoshi Nakada)
  • Priority changed from Low to Normal
遠藤です。 trunk に入れましょう。なかださんお願いします。 -- Yusuke Endoh <mame@tsg.ne.jp>

Updated by nobu (Nobuyoshi Nakada) 3 months ago

  • Status changed from Assigned to Closed
r33175でrb_const_entry_tを使うようにしてコミット済みです。

Also available in: Atom PDF