make method lookup work with id

This commit is contained in:
Bill Currie 2003-07-29 17:38:29 +00:00
parent ef1b68e697
commit 5b9b11241b
4 changed files with 60 additions and 16 deletions

View file

@ -77,6 +77,8 @@ keywordarg_t *copy_keywordargs (const keywordarg_t *kwargs);
struct expr_s *send_message (int super);
method_t *find_method (const char *sel_name);
void selector_name (struct dstring_s *sel_id, keywordarg_t *selector);
void selector_types (struct dstring_s *sel_types, keywordarg_t *selector);
struct def_s *selector_def (const char *sel_id, const char *sel_types);

View file

@ -434,6 +434,14 @@ class_message_response (class_t *class, int class_msg, expr_t *sel)
}
selector = &G_STRUCT (pr_sel_t, POINTER_VAL (sel->e.pointer));
sel_name = G_GETSTR (selector->sel_id);
if (class->type == &type_id) {
m = find_method (sel_name);
if (m)
return m;
warning (sel, "could not find method for %c%s", class_msg ? '+' : '-',
sel_name);
return 0;
} else {
while (c) {
if (c->methods) {
for (cat = c->categories; cat; cat = cat->next) {
@ -451,6 +459,7 @@ class_message_response (class_t *class, int class_msg, expr_t *sel)
}
warning (sel, "%s does not respond to %c%s", class->name,
class_msg ? '+' : '-', sel_name);
}
return 0;
}

View file

@ -2487,11 +2487,11 @@ message_expr (expr_t *receiver, keywordarg_t *message)
return error (receiver, "not a class/object");
class = rec_type->aux_type->class;
}
if (rec_type != &type_id) {
method = class_message_response (class, class_msg, selector);
if (method)
rec_type = method->type->aux_type;
}
for (m = message; m; m = m->next) {
*a = m->expr;
while ((*a))

View file

@ -60,6 +60,24 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "struct.h"
#include "type.h"
static hashtab_t *known_methods;
static const char *
method_get_key (void *meth, void *unused)
{
return ((method_t *) meth)->name;
}
static void
method_free (void *_meth, void *unused)
{
method_t *meth = (method_t *) meth;
free (meth->name);
free (meth->types);
free (meth);
}
method_t *
new_method (type_t *ret_type, param_t *selector, param_t *opt_parms)
{
@ -89,6 +107,11 @@ new_method (type_t *ret_type, param_t *selector, param_t *opt_parms)
//print_type (meth->type); puts ("");
meth->def = 0;
if (!known_methods)
known_methods = Hash_NewTable (1021, method_get_key, method_free, 0);
Hash_Add (known_methods, meth);
return meth;
}
@ -200,6 +223,14 @@ send_message (int super)
st_extern));
}
method_t *
find_method (const char *sel_name)
{
if (!known_methods)
return 0;
return Hash_Find (known_methods, sel_name);
}
void
selector_name (dstring_t *sel_id, keywordarg_t *selector)
{
@ -331,4 +362,6 @@ clear_selectors (void)
{
if (sel_def_hash)
Hash_FlushTable (sel_def_hash);
if (known_methods)
Hash_FlushTable (known_methods);
}