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>
|
Fri May 2 09:38:06 2003 Warren Brown <wkb@airmail.net>
|
||||||
|
|
||||||
* string.c (rb_str_ljust): now takes optional argument to specify
|
* 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;
|
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
|
static int
|
||||||
ins_methods_i(key, body, ary)
|
ins_methods_push(name, type, ary, visi)
|
||||||
ID key;
|
ID name;
|
||||||
NODE *body;
|
long type;
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
|
long visi;
|
||||||
{
|
{
|
||||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
if (type == -1) return ST_CONTINUE;
|
||||||
if (!body->nd_body) {
|
switch (visi) {
|
||||||
rb_ary_push(ary, Qnil);
|
case NOEX_PRIVATE:
|
||||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
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)) {
|
if (visi) {
|
||||||
VALUE name = rb_str_new2(rb_id2name(key));
|
rb_ary_push(ary, rb_str_new2(rb_id2name(name)));
|
||||||
|
|
||||||
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 ST_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ins_methods_prot_i(key, body, ary)
|
ins_methods_i(name, type, ary)
|
||||||
ID key;
|
ID name;
|
||||||
NODE *body;
|
long type;
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
{
|
{
|
||||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
return ins_methods_push(name, type, ary, -1); /* everything but private */
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ins_methods_priv_i(key, body, ary)
|
ins_methods_prot_i(name, type, ary)
|
||||||
ID key;
|
ID name;
|
||||||
NODE *body;
|
long type;
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
{
|
{
|
||||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
return ins_methods_push(name, type, ary, NOEX_PROTECTED);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ins_methods_pub_i(key, body, ary)
|
ins_methods_priv_i(name, type, ary)
|
||||||
ID key;
|
ID name;
|
||||||
NODE *body;
|
long type;
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
{
|
{
|
||||||
if (key == ID_ALLOCATOR) return ST_CONTINUE;
|
return ins_methods_push(name, type, ary, NOEX_PRIVATE);
|
||||||
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));
|
|
||||||
|
|
||||||
if (!rb_ary_includes(ary, name)) {
|
static int
|
||||||
rb_ary_push(ary, name);
|
ins_methods_pub_i(name, type, ary)
|
||||||
}
|
ID name;
|
||||||
}
|
long type;
|
||||||
else if (nd_type(body->nd_body) == NODE_ZSUPER) {
|
VALUE ary;
|
||||||
rb_ary_push(ary, Qnil);
|
{
|
||||||
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
|
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;
|
return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
method_list(mod, option, func)
|
method_list(mod, recur, func)
|
||||||
VALUE mod;
|
VALUE mod;
|
||||||
int option;
|
int recur;
|
||||||
int (*func)();
|
int (*func)();
|
||||||
{
|
{
|
||||||
VALUE ary;
|
st_table *list;
|
||||||
VALUE klass;
|
VALUE klass, ary;
|
||||||
VALUE *p, *q, *pend;
|
|
||||||
|
|
||||||
ary = rb_ary_new();
|
list = st_init_numtable();
|
||||||
for (klass = mod; klass; klass = RCLASS(klass)->super) {
|
for (klass = mod; klass; klass = RCLASS(klass)->super) {
|
||||||
st_foreach(RCLASS(klass)->m_tbl, func, ary);
|
st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
|
||||||
if (!option) break;
|
if (!recur) break;
|
||||||
}
|
}
|
||||||
p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
|
ary = rb_ary_new();
|
||||||
while (p < pend) {
|
st_foreach(list, func, ary);
|
||||||
if (*p == Qnil) {
|
st_free_table(list);
|
||||||
p+=2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*q++ = *p++;
|
|
||||||
}
|
|
||||||
RARRAY(ary)->len = q - RARRAY(ary)->ptr;
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,10 +560,11 @@ rb_class_instance_methods(argc, argv, mod)
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE mod;
|
VALUE mod;
|
||||||
{
|
{
|
||||||
VALUE option;
|
VALUE recur;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "01", &option);
|
rb_scan_args(argc, argv, "01", &recur);
|
||||||
return method_list(mod, RTEST(option), ins_methods_i);
|
if (argc == 0) recur = Qtrue;
|
||||||
|
return method_list(mod, RTEST(recur), ins_methods_i);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -600,10 +573,11 @@ rb_class_protected_instance_methods(argc, argv, mod)
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE mod;
|
VALUE mod;
|
||||||
{
|
{
|
||||||
VALUE option;
|
VALUE recur;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "01", &option);
|
rb_scan_args(argc, argv, "01", &recur);
|
||||||
return method_list(mod, RTEST(option), ins_methods_prot_i);
|
if (argc == 0) recur = Qtrue;
|
||||||
|
return method_list(mod, RTEST(recur), ins_methods_prot_i);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -612,10 +586,11 @@ rb_class_private_instance_methods(argc, argv, mod)
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE mod;
|
VALUE mod;
|
||||||
{
|
{
|
||||||
VALUE option;
|
VALUE recur;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "01", &option);
|
rb_scan_args(argc, argv, "01", &recur);
|
||||||
return method_list(mod, RTEST(option), ins_methods_priv_i);
|
if (argc == 0) recur = Qtrue;
|
||||||
|
return method_list(mod, RTEST(recur), ins_methods_priv_i);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -624,10 +599,11 @@ rb_class_public_instance_methods(argc, argv, mod)
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE mod;
|
VALUE mod;
|
||||||
{
|
{
|
||||||
VALUE option;
|
VALUE recur;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "01", &option);
|
rb_scan_args(argc, argv, "01", &recur);
|
||||||
return method_list(mod, RTEST(option), ins_methods_pub_i);
|
if (argc == 0) recur = Qtrue;
|
||||||
|
return method_list(mod, RTEST(recur), ins_methods_pub_i);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -636,33 +612,26 @@ rb_obj_singleton_methods(argc, argv, obj)
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
{
|
{
|
||||||
VALUE all;
|
VALUE all, ary, klass;
|
||||||
VALUE ary;
|
st_table *list;
|
||||||
VALUE klass;
|
|
||||||
VALUE *p, *q, *pend;
|
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "01", &all);
|
rb_scan_args(argc, argv, "01", &all);
|
||||||
ary = rb_ary_new();
|
if (argc == 0) all = Qtrue;
|
||||||
klass = CLASS_OF(obj);
|
klass = CLASS_OF(obj);
|
||||||
|
list = st_init_numtable();
|
||||||
while (klass && FL_TEST(klass, FL_SINGLETON)) {
|
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;
|
klass = RCLASS(klass)->super;
|
||||||
}
|
}
|
||||||
if (RTEST(all)) {
|
if (RTEST(all)) {
|
||||||
while (klass && TYPE(klass) == T_ICLASS) {
|
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;
|
klass = RCLASS(klass)->super;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
|
ary = rb_ary_new();
|
||||||
while (p < pend) {
|
st_foreach(list, ins_methods_i, ary);
|
||||||
if (*p == Qnil) {
|
st_free_table(list);
|
||||||
p+=2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*q++ = *p++;
|
|
||||||
}
|
|
||||||
RARRAY(ary)->len = q - RARRAY(ary)->ptr;
|
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue