mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* class.c (method_list): classify methods based on nearest
visibility. [ruby-dev:20127] * class.c (rb_class_instance_methods): recurse by default. other method listing methods as well. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3744 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
7c08de46cd
commit
954ba9bab2
2 changed files with 97 additions and 120 deletions
|
@ -1,3 +1,11 @@
|
|||
Fri May 2 17:21:02 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* class.c (method_list): classify methods based on nearest
|
||||
visibility. [ruby-dev:20127]
|
||||
|
||||
* class.c (rb_class_instance_methods): recurse by default. other
|
||||
method listing methods as well.
|
||||
|
||||
Fri May 2 09:38:06 2003 Warren Brown <wkb@airmail.net>
|
||||
|
||||
* string.c (rb_str_ljust): now takes optional argument to specify
|
||||
|
|
209
class.c
209
class.c
|
@ -453,132 +453,104 @@ rb_mod_ancestors(mod)
|
|||
return ary;
|
||||
}
|
||||
|
||||
#define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
|
||||
#define VISI(x) ((x)&NOEX_MASK)
|
||||
#define VISI_CHECK(x,f) (VISI(x) == (f))
|
||||
|
||||
static int
|
||||
ins_methods_i(key, body, ary)
|
||||
ID key;
|
||||
NODE *body;
|
||||
ins_methods_push(name, type, ary, visi)
|
||||
ID name;
|
||||
long type;
|
||||
VALUE ary;
|
||||
long visi;
|
||||
{
|
||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
||||
if (!body->nd_body) {
|
||||
rb_ary_push(ary, Qnil);
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
||||
if (type == -1) return ST_CONTINUE;
|
||||
switch (visi) {
|
||||
case NOEX_PRIVATE:
|
||||
case NOEX_PROTECTED:
|
||||
case NOEX_PUBLIC:
|
||||
visi = (type == visi);
|
||||
break;
|
||||
default:
|
||||
visi = (type != NOEX_PRIVATE);
|
||||
break;
|
||||
}
|
||||
else if (!VISI_CHECK(body->nd_noex, NOEX_PRIVATE)) {
|
||||
VALUE name = rb_str_new2(rb_id2name(key));
|
||||
|
||||
if (!rb_ary_includes(ary, name)) {
|
||||
rb_ary_push(ary, name);
|
||||
}
|
||||
}
|
||||
else if (nd_type(body->nd_body) == NODE_ZSUPER) {
|
||||
rb_ary_push(ary, Qnil);
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
||||
if (visi) {
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(name)));
|
||||
}
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
ins_methods_prot_i(key, body, ary)
|
||||
ID key;
|
||||
NODE *body;
|
||||
ins_methods_i(name, type, ary)
|
||||
ID name;
|
||||
long type;
|
||||
VALUE ary;
|
||||
{
|
||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
||||
if (!body->nd_body) {
|
||||
rb_ary_push(ary, Qnil);
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
||||
}
|
||||
else if (VISI_CHECK(body->nd_noex, NOEX_PROTECTED)) {
|
||||
VALUE name = rb_str_new2(rb_id2name(key));
|
||||
|
||||
if (!rb_ary_includes(ary, name)) {
|
||||
rb_ary_push(ary, name);
|
||||
}
|
||||
}
|
||||
else if (nd_type(body->nd_body) == NODE_ZSUPER) {
|
||||
rb_ary_push(ary, Qnil);
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
||||
}
|
||||
return ST_CONTINUE;
|
||||
return ins_methods_push(name, type, ary, -1); /* everything but private */
|
||||
}
|
||||
|
||||
static int
|
||||
ins_methods_priv_i(key, body, ary)
|
||||
ID key;
|
||||
NODE *body;
|
||||
ins_methods_prot_i(name, type, ary)
|
||||
ID name;
|
||||
long type;
|
||||
VALUE ary;
|
||||
{
|
||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
||||
if (!body->nd_body) {
|
||||
rb_ary_push(ary, Qnil);
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
||||
}
|
||||
else if (VISI_CHECK(body->nd_noex, NOEX_PRIVATE)) {
|
||||
VALUE name = rb_str_new2(rb_id2name(key));
|
||||
|
||||
if (!rb_ary_includes(ary, name)) {
|
||||
rb_ary_push(ary, name);
|
||||
}
|
||||
}
|
||||
else if (nd_type(body->nd_body) == NODE_ZSUPER) {
|
||||
rb_ary_push(ary, Qnil);
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
||||
}
|
||||
return ST_CONTINUE;
|
||||
return ins_methods_push(name, type, ary, NOEX_PROTECTED);
|
||||
}
|
||||
|
||||
static int
|
||||
ins_methods_pub_i(key, body, ary)
|
||||
ID key;
|
||||
NODE *body;
|
||||
ins_methods_priv_i(name, type, ary)
|
||||
ID name;
|
||||
long type;
|
||||
VALUE ary;
|
||||
{
|
||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
||||
if (!body->nd_body) {
|
||||
rb_ary_push(ary, Qnil);
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
||||
}
|
||||
else if (VISI_CHECK(body->nd_noex, NOEX_PUBLIC)) {
|
||||
VALUE name = rb_str_new2(rb_id2name(key));
|
||||
return ins_methods_push(name, type, ary, NOEX_PRIVATE);
|
||||
}
|
||||
|
||||
if (!rb_ary_includes(ary, name)) {
|
||||
rb_ary_push(ary, name);
|
||||
}
|
||||
}
|
||||
else if (nd_type(body->nd_body) == NODE_ZSUPER) {
|
||||
rb_ary_push(ary, Qnil);
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
||||
static int
|
||||
ins_methods_pub_i(name, type, ary)
|
||||
ID name;
|
||||
long type;
|
||||
VALUE ary;
|
||||
{
|
||||
return ins_methods_push(name, type, ary, NOEX_PUBLIC);
|
||||
}
|
||||
|
||||
static int
|
||||
method_entry(key, body, list)
|
||||
ID key;
|
||||
NODE *body;
|
||||
st_table *list;
|
||||
{
|
||||
long type;
|
||||
|
||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
||||
if (!st_lookup(list, key, 0)) {
|
||||
if (!body->nd_body) type = -1; /* none */
|
||||
else type = VISI(body->nd_noex);
|
||||
st_add_direct(list, key, type);
|
||||
}
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
method_list(mod, option, func)
|
||||
method_list(mod, recur, func)
|
||||
VALUE mod;
|
||||
int option;
|
||||
int recur;
|
||||
int (*func)();
|
||||
{
|
||||
VALUE ary;
|
||||
VALUE klass;
|
||||
VALUE *p, *q, *pend;
|
||||
st_table *list;
|
||||
VALUE klass, ary;
|
||||
|
||||
ary = rb_ary_new();
|
||||
list = st_init_numtable();
|
||||
for (klass = mod; klass; klass = RCLASS(klass)->super) {
|
||||
st_foreach(RCLASS(klass)->m_tbl, func, ary);
|
||||
if (!option) break;
|
||||
st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
|
||||
if (!recur) break;
|
||||
}
|
||||
p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
|
||||
while (p < pend) {
|
||||
if (*p == Qnil) {
|
||||
p+=2;
|
||||
continue;
|
||||
}
|
||||
*q++ = *p++;
|
||||
}
|
||||
RARRAY(ary)->len = q - RARRAY(ary)->ptr;
|
||||
ary = rb_ary_new();
|
||||
st_foreach(list, func, ary);
|
||||
st_free_table(list);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
||||
|
@ -588,10 +560,11 @@ rb_class_instance_methods(argc, argv, mod)
|
|||
VALUE *argv;
|
||||
VALUE mod;
|
||||
{
|
||||
VALUE option;
|
||||
VALUE recur;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &option);
|
||||
return method_list(mod, RTEST(option), ins_methods_i);
|
||||
rb_scan_args(argc, argv, "01", &recur);
|
||||
if (argc == 0) recur = Qtrue;
|
||||
return method_list(mod, RTEST(recur), ins_methods_i);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -600,10 +573,11 @@ rb_class_protected_instance_methods(argc, argv, mod)
|
|||
VALUE *argv;
|
||||
VALUE mod;
|
||||
{
|
||||
VALUE option;
|
||||
VALUE recur;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &option);
|
||||
return method_list(mod, RTEST(option), ins_methods_prot_i);
|
||||
rb_scan_args(argc, argv, "01", &recur);
|
||||
if (argc == 0) recur = Qtrue;
|
||||
return method_list(mod, RTEST(recur), ins_methods_prot_i);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -612,10 +586,11 @@ rb_class_private_instance_methods(argc, argv, mod)
|
|||
VALUE *argv;
|
||||
VALUE mod;
|
||||
{
|
||||
VALUE option;
|
||||
VALUE recur;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &option);
|
||||
return method_list(mod, RTEST(option), ins_methods_priv_i);
|
||||
rb_scan_args(argc, argv, "01", &recur);
|
||||
if (argc == 0) recur = Qtrue;
|
||||
return method_list(mod, RTEST(recur), ins_methods_priv_i);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -624,10 +599,11 @@ rb_class_public_instance_methods(argc, argv, mod)
|
|||
VALUE *argv;
|
||||
VALUE mod;
|
||||
{
|
||||
VALUE option;
|
||||
VALUE recur;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &option);
|
||||
return method_list(mod, RTEST(option), ins_methods_pub_i);
|
||||
rb_scan_args(argc, argv, "01", &recur);
|
||||
if (argc == 0) recur = Qtrue;
|
||||
return method_list(mod, RTEST(recur), ins_methods_pub_i);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -636,33 +612,26 @@ rb_obj_singleton_methods(argc, argv, obj)
|
|||
VALUE *argv;
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE all;
|
||||
VALUE ary;
|
||||
VALUE klass;
|
||||
VALUE *p, *q, *pend;
|
||||
VALUE all, ary, klass;
|
||||
st_table *list;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &all);
|
||||
ary = rb_ary_new();
|
||||
if (argc == 0) all = Qtrue;
|
||||
klass = CLASS_OF(obj);
|
||||
list = st_init_numtable();
|
||||
while (klass && FL_TEST(klass, FL_SINGLETON)) {
|
||||
st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
|
||||
st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
|
||||
klass = RCLASS(klass)->super;
|
||||
}
|
||||
if (RTEST(all)) {
|
||||
while (klass && TYPE(klass) == T_ICLASS) {
|
||||
st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
|
||||
st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
|
||||
klass = RCLASS(klass)->super;
|
||||
}
|
||||
}
|
||||
p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
|
||||
while (p < pend) {
|
||||
if (*p == Qnil) {
|
||||
p+=2;
|
||||
continue;
|
||||
}
|
||||
*q++ = *p++;
|
||||
}
|
||||
RARRAY(ary)->len = q - RARRAY(ary)->ptr;
|
||||
ary = rb_ary_new();
|
||||
st_foreach(list, ins_methods_i, ary);
|
||||
st_free_table(list);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue