summaryrefslogtreecommitdiff
path: root/class.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-05-02 08:24:43 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-05-02 08:24:43 +0000
commit954ba9bab249a3492c70b583aa47a3f7656a3afd (patch)
tree1d9910eaa8a4d74b56ffb0ad22b0436e58fb41fe /class.c
parent7c08de46cde52513e54edc893346c5bb4958b00c (diff)
* 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
Diffstat (limited to 'class.c')
-rw-r--r--class.c207
1 files changed, 88 insertions, 119 deletions
diff --git a/class.c b/class.c
index f2122a3..833f96c 100644
--- a/class.c
+++ b/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;
-{
- 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)));
+ long visi;
+{
+ 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;
+ }
+ 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));
+ return ins_methods_push(name, type, ary, -1); /* everything but 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)));
- }
- return ST_CONTINUE;
+static int
+ins_methods_prot_i(name, type, ary)
+ ID name;
+ long type;
+ VALUE ary;
+{
+ return ins_methods_push(name, type, ary, NOEX_PROTECTED);
}
static int
-ins_methods_priv_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_PRIVATE)) {
- 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)));
- }
- return ST_CONTINUE;
+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
-ins_methods_pub_i(key, body, ary)
+method_entry(key, body, list)
ID key;
NODE *body;
- VALUE ary;
+ st_table *list;
{
- 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));
+ long type;
- 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 (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;
}