summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--NEWS3
-rw-r--r--constant.h11
-rw-r--r--lib/timeout.rb3
-rw-r--r--object.c1
-rw-r--r--test/ruby/test_module.rb7
-rw-r--r--variable.c25
7 files changed, 51 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 461311f380..b01f096349 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Jul 30 13:19:54 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * variable.c (rb_const_get_0): warn deprecated constant reference.
+
+ * variable.c (rb_mod_deprecate_constant): mark constants to be
+ warned as deprecated. [Feature #11398]
+
Thu Jul 30 11:53:54 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* thread.c (rb_thread_s_handle_interrupt): make identical hash,
diff --git a/NEWS b/NEWS
index b6c4c8c498..aada4521c4 100644
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,9 @@ with all sufficient information, see the ChangeLog file.
this parameter is bitwise-ORed to oflags generated by normal mode argument.
[Feature #11253]
+* Module
+ * Module#deprecate_constant [Feature #11398]
+
* NameError
* NameError#receiver is added to take the receiver object. [Feature #10881]
diff --git a/constant.h b/constant.h
index c7de5da533..23d17ac24c 100644
--- a/constant.h
+++ b/constant.h
@@ -12,15 +12,21 @@
#define CONSTANT_H
typedef enum {
+ CONST_DEPRECATED = 0x100,
+
+ CONST_VISIBILITY_MASK = 0xff,
CONST_PUBLIC = 0x00,
CONST_PRIVATE,
CONST_VISIBILITY_MAX
} rb_const_flag_t;
#define RB_CONST_PRIVATE_P(ce) \
- ((ce)->flag == CONST_PRIVATE)
+ (((ce)->flag & CONST_VISIBILITY_MASK) == CONST_PRIVATE)
#define RB_CONST_PUBLIC_P(ce) \
- ((ce)->flag == CONST_PUBLIC)
+ (((ce)->flag & CONST_VISIBILITY_MASK) == CONST_PUBLIC)
+
+#define RB_CONST_DEPRECATED_P(ce) \
+ ((ce)->flag & CONST_DEPRECATED)
typedef struct rb_const_entry_struct {
rb_const_flag_t flag;
@@ -31,6 +37,7 @@ typedef struct rb_const_entry_struct {
VALUE rb_mod_private_constant(int argc, const VALUE *argv, VALUE obj);
VALUE rb_mod_public_constant(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj);
void rb_free_const_table(st_table *tbl);
VALUE rb_public_const_get(VALUE klass, ID id);
VALUE rb_public_const_get_at(VALUE klass, ID id);
diff --git a/lib/timeout.rb b/lib/timeout.rb
index 54b93e9716..20a594898f 100644
--- a/lib/timeout.rb
+++ b/lib/timeout.rb
@@ -120,3 +120,6 @@ end
# Another name for Timeout::Error, defined for backwards compatibility with
# earlier versions of timeout.rb.
TimeoutError = Timeout::Error
+class Object
+ deprecate_constant :TimeoutError
+end
diff --git a/object.c b/object.c
index f6f764af7f..99c2fb61e1 100644
--- a/object.c
+++ b/object.c
@@ -3414,6 +3414,7 @@ Init_Object(void)
rb_define_method(rb_cModule, "class_variable_defined?", rb_mod_cvar_defined, 1);
rb_define_method(rb_cModule, "public_constant", rb_mod_public_constant, -1); /* in variable.c */
rb_define_method(rb_cModule, "private_constant", rb_mod_private_constant, -1); /* in variable.c */
+ rb_define_method(rb_cModule, "deprecate_constant", rb_mod_deprecate_constant, -1); /* in variable.c */
rb_define_method(rb_cModule, "singleton_class?", rb_mod_singleton_p, 0);
rb_define_method(rb_cClass, "allocate", rb_obj_alloc, 0);
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 5fc3d4a541..812b7f6a31 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -1360,6 +1360,13 @@ class TestModule < Test::Unit::TestCase
assert_equal("foo", c::FOO)
end
+ def test_deprecate_constant
+ c = Class.new
+ c.const_set(:FOO, "foo")
+ c.deprecate_constant(:FOO)
+ assert_warn(/deprecated/) {c::FOO}
+ end
+
def test_constants_with_private_constant
assert_not_include(::TestModule.constants, :PrivateClass)
end
diff --git a/variable.c b/variable.c
index bb8b6dbbb8..baa6fb600b 100644
--- a/variable.c
+++ b/variable.c
@@ -2149,6 +2149,15 @@ rb_const_get_0(VALUE klass, ID id, int exclude, int recurse, int visibility)
rb_name_error(id, "private constant %"PRIsVALUE"::%"PRIsVALUE" referenced",
rb_class_name(klass), QUOTE_ID(id));
}
+ if (RB_CONST_DEPRECATED_P(ce)) {
+ if (klass == rb_cObject) {
+ rb_warn("constant ::%"PRIsVALUE" is deprecated", QUOTE_ID(id));
+ }
+ else {
+ rb_warn("constant %"PRIsVALUE"::%"PRIsVALUE" is deprecated",
+ rb_class_name(klass), QUOTE_ID(id));
+ }
+ }
value = ce->value;
if (value == Qundef) {
if (am == tmp) break;
@@ -2576,7 +2585,7 @@ rb_define_global_const(const char *name, VALUE val)
}
static void
-set_const_visibility(VALUE mod, int argc, const VALUE *argv, rb_const_flag_t flag)
+set_const_visibility(VALUE mod, int argc, const VALUE *argv, rb_const_flag_t flag, rb_const_flag_t mask)
{
int i;
rb_const_entry_t *ce;
@@ -2600,7 +2609,8 @@ set_const_visibility(VALUE mod, int argc, const VALUE *argv, rb_const_flag_t fla
rb_class_name(mod), QUOTE(val));
}
if ((ce = rb_const_lookup(mod, id))) {
- ce->flag = flag;
+ ce->flag &= ~mask;
+ ce->flag |= flag;
}
else {
if (i > 0) {
@@ -2623,7 +2633,7 @@ set_const_visibility(VALUE mod, int argc, const VALUE *argv, rb_const_flag_t fla
VALUE
rb_mod_private_constant(int argc, const VALUE *argv, VALUE obj)
{
- set_const_visibility(obj, argc, argv, CONST_PRIVATE);
+ set_const_visibility(obj, argc, argv, CONST_PRIVATE, CONST_VISIBILITY_MASK);
return obj;
}
@@ -2637,7 +2647,14 @@ rb_mod_private_constant(int argc, const VALUE *argv, VALUE obj)
VALUE
rb_mod_public_constant(int argc, const VALUE *argv, VALUE obj)
{
- set_const_visibility(obj, argc, argv, CONST_PUBLIC);
+ set_const_visibility(obj, argc, argv, CONST_PUBLIC, CONST_VISIBILITY_MASK);
+ return obj;
+}
+
+VALUE
+rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj)
+{
+ set_const_visibility(obj, argc, argv, CONST_DEPRECATED, CONST_DEPRECATED);
return obj;
}