Feature #14056 ยป 0001-Add-Module-deprecate_public-for-deprecation-of-publi.patch
method.h | ||
---|---|---|
#define METHOD_ENTRY_VISI(me) (rb_method_visibility_t)(((me)->flags & (IMEMO_FL_USER0 | IMEMO_FL_USER1)) >> (IMEMO_FL_USHIFT+0))
|
||
#define METHOD_ENTRY_BASIC(me) (int) (((me)->flags & (IMEMO_FL_USER2 )) >> (IMEMO_FL_USHIFT+2))
|
||
#define METHOD_ENTRY_DEPRECATED(me) (int) (((me)->flags & (IMEMO_FL_USER4 )) >> (IMEMO_FL_USHIFT+4))
|
||
#define METHOD_ENTRY_COMPLEMENTED(me) ((me)->flags & IMEMO_FL_USER3)
|
||
#define METHOD_ENTRY_COMPLEMENTED_SET(me) ((me)->flags = (me)->flags | IMEMO_FL_USER3)
|
||
... | ... | |
me->flags = (me->flags & ~(IMEMO_FL_USER2 )) | (basic << (IMEMO_FL_USHIFT+2));
|
||
}
|
||
static inline void
|
||
METHOD_ENTRY_DEPRECATED_SET(rb_method_entry_t *me, unsigned int deprecated)
|
||
{
|
||
VM_ASSERT(deprecated <= 1);
|
||
me->flags = (me->flags & ~(IMEMO_FL_USER4 )) | (deprecated << (IMEMO_FL_USHIFT+4));
|
||
}
|
||
static inline void
|
||
METHOD_ENTRY_FLAGS_SET(rb_method_entry_t *me, rb_method_visibility_t visi, unsigned int basic)
|
||
{
|
||
VM_ASSERT((int)visi >= 0 && visi <= 3);
|
||
... | ... | |
METHOD_ENTRY_FLAGS_COPY(rb_method_entry_t *dst, const rb_method_entry_t *src)
|
||
{
|
||
dst->flags =
|
||
(dst->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2)) |
|
||
(src->flags & (IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2));
|
||
(dst->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2|IMEMO_FL_USER4)) |
|
||
(src->flags & (IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2|IMEMO_FL_USER4));
|
||
}
|
||
typedef enum {
|
test/ruby/test_method.rb | ||
---|---|---|
assert_equal(:m1, c2.new.m.call, 'see [Bug #4881] and [Bug #3136]')
|
||
end
|
||
def test_deprecate_public
|
||
c1 = Class.new do
|
||
def dp
|
||
:dp
|
||
end
|
||
deprecate_public :dp
|
||
end
|
||
refute_includes c1.instance_methods, :dp
|
||
assert_includes c1.private_instance_methods, :dp
|
||
assert_equal false, c1.public_method_defined?(:dp)
|
||
assert_equal true, c1.private_method_defined?(:dp)
|
||
o = c1.new
|
||
assert_equal :dp, o.dp
|
||
assert_equal :dp, o.public_send(:dp)
|
||
refute_includes o.public_methods, :dp
|
||
assert_includes o.private_methods, :dp
|
||
assert_equal false, o.respond_to?(:dp)
|
||
assert_equal true, o.respond_to?(:dp, true)
|
||
end
|
||
def test_deprecate_public_module
|
||
m1 = Module.new do
|
||
def dp
|
||
:dp
|
||
end
|
||
end
|
||
c1 = Class.new
|
||
c1.include m1
|
||
m1.send :deprecate_public, :dp
|
||
refute_includes c1.instance_methods, :dp
|
||
assert_includes c1.private_instance_methods, :dp
|
||
assert_equal false, c1.public_method_defined?(:dp)
|
||
assert_equal true, c1.private_method_defined?(:dp)
|
||
o = c1.new
|
||
assert_equal :dp, o.dp
|
||
assert_equal :dp, o.public_send(:dp)
|
||
refute_includes o.public_methods, :dp
|
||
assert_includes o.private_methods, :dp
|
||
assert_equal false, o.respond_to?(:dp)
|
||
assert_equal true, o.respond_to?(:dp, true)
|
||
end
|
||
def test_clone
|
||
o = Object.new
|
||
def o.foo; :foo; end
|
test/ruby/test_object.rb | ||
---|---|---|
public_send(m)
|
||
end
|
||
def dep_pub
|
||
:ok
|
||
end
|
||
deprecate_public :dep_pub
|
||
protected
|
||
def prot
|
||
:ng
|
||
... | ... | |
assert_equal(:ok, c.public_send(:pub))
|
||
assert_raise(NoMethodError) {c.public_send(:priv)}
|
||
assert_raise(NoMethodError) {c.public_send(:prot)}
|
||
assert_equal(:ok, c.public_send(:dep_pub))
|
||
assert_raise(NoMethodError) {c.invoke(:priv)}
|
||
bug7499 = '[ruby-core:50489]'
|
||
assert_raise(NoMethodError, bug7499) {c.invoke(:prot)}
|
vm_eval.c | ||
---|---|---|
/* receiver specified form for private method */
|
||
if (UNLIKELY(visi != METHOD_VISI_PUBLIC)) {
|
||
if (visi == METHOD_VISI_PRIVATE && scope == CALL_PUBLIC) {
|
||
return MISSING_PRIVATE;
|
||
if (METHOD_ENTRY_DEPRECATED(me)) {
|
||
if (RB_TYPE_P(klass, T_ICLASS)) {
|
||
klass = RBASIC(klass)->klass;
|
||
}
|
||
VALUE calling_str = rb_inspect(klass);
|
||
rb_warn("calling private method %s on %s via deprecated public interface",
|
||
rb_id2name(me->called_id),
|
||
rb_string_value_ptr(&calling_str));
|
||
return MISSING_NONE;
|
||
}
|
||
else {
|
||
return MISSING_PRIVATE;
|
||
}
|
||
}
|
||
/* self must be kind of a specified form for protected method */
|
vm_insnhelper.c | ||
---|---|---|
case METHOD_VISI_PRIVATE:
|
||
if (!(ci->flag & VM_CALL_FCALL)) {
|
||
enum method_missing_reason stat = MISSING_PRIVATE;
|
||
if (ci->flag & VM_CALL_VCALL) stat |= MISSING_VCALL;
|
||
cc->aux.method_missing_reason = stat;
|
||
CI_SET_FASTPATH(cc, vm_call_method_missing, 1);
|
||
return vm_call_method_missing(th, cfp, calling, ci, cc);
|
||
if (METHOD_ENTRY_DEPRECATED(cc->me)) {
|
||
VALUE calling_str = rb_inspect(calling->recv);
|
||
rb_warn("calling private method %s on %s via deprecated public interface",
|
||
rb_id2name(cc->me->called_id),
|
||
rb_string_value_ptr(&calling_str));
|
||
} else {
|
||
enum method_missing_reason stat = MISSING_PRIVATE;
|
||
if (ci->flag & VM_CALL_VCALL) stat |= MISSING_VCALL;
|
||
cc->aux.method_missing_reason = stat;
|
||
CI_SET_FASTPATH(cc, vm_call_method_missing, 1);
|
||
return vm_call_method_missing(th, cfp, calling, ci, cc);
|
||
}
|
||
}
|
||
return vm_call_method_each_type(th, cfp, calling, ci, cc);
|
||
vm_method.c | ||
---|---|---|
return module;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* deprecate_public(symbol, ...) -> self
|
||
* deprecate_public(string, ...) -> self
|
||
*
|
||
* Sets the named methods to be private but be
|
||
* callable as public methods, issuing a deprecation warning
|
||
* when they are called in a non-private context.
|
||
* String arguments are converted to symbols.
|
||
*/
|
||
static VALUE
|
||
rb_mod_deprecate_public(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
int i;
|
||
|
||
if (argc == 0) {
|
||
return self;
|
||
}
|
||
for (i = 0; i < argc; i++) {
|
||
VALUE v = argv[i];
|
||
ID id = rb_check_id(&v);
|
||
rb_method_entry_t *meth;
|
||
if (!id) {
|
||
rb_print_undef_str(self, v);
|
||
}
|
||
rb_export_method(self, id, METHOD_VISI_PUBLIC);
|
||
rb_export_method(self, id, METHOD_VISI_PRIVATE);
|
||
meth = search_method(self, id, 0);
|
||
METHOD_ENTRY_DEPRECATED_SET(meth, 1);
|
||
}
|
||
rb_clear_method_cache_by_class(self);
|
||
return self;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* public -> self
|
||
... | ... | |
rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
|
||
rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
|
||
rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
|
||
rb_define_private_method(rb_cModule, "deprecate_public", rb_mod_deprecate_public, -1);
|
||
rb_define_private_method(rb_cModule, "public", rb_mod_public, -1);
|
||
rb_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
|
||
rb_define_private_method(rb_cModule, "private", rb_mod_private, -1);
|