mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
make method lookup work with id
This commit is contained in:
parent
ef1b68e697
commit
5b9b11241b
4 changed files with 60 additions and 16 deletions
|
@ -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);
|
||||
|
|
|
@ -434,23 +434,32 @@ 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);
|
||||
while (c) {
|
||||
if (c->methods) {
|
||||
for (cat = c->categories; cat; cat = cat->next) {
|
||||
for (m = cat->methods->head; m; m = m->next) {
|
||||
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) {
|
||||
for (m = cat->methods->head; m; m = m->next) {
|
||||
if (strcmp (sel_name, m->name) == 0)
|
||||
return m;
|
||||
}
|
||||
}
|
||||
for (m = c->methods->head; m; m = m->next) {
|
||||
if (strcmp (sel_name, m->name) == 0)
|
||||
return m;
|
||||
}
|
||||
}
|
||||
for (m = c->methods->head; m; m = m->next) {
|
||||
if (strcmp (sel_name, m->name) == 0)
|
||||
return m;
|
||||
}
|
||||
c = c->super_class;
|
||||
}
|
||||
c = c->super_class;
|
||||
warning (sel, "%s does not respond to %c%s", class->name,
|
||||
class_msg ? '+' : '-', sel_name);
|
||||
}
|
||||
warning (sel, "%s does not respond to %c%s", class->name,
|
||||
class_msg ? '+' : '-', sel_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue