From 5b9b11241b97aea2d41fdb3e803997a8fc69228b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 29 Jul 2003 17:38:29 +0000 Subject: [PATCH] make method lookup work with id --- tools/qfcc/include/method.h | 2 ++ tools/qfcc/source/class.c | 31 ++++++++++++++++++++----------- tools/qfcc/source/expr.c | 10 +++++----- tools/qfcc/source/method.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/tools/qfcc/include/method.h b/tools/qfcc/include/method.h index 518bb79d4..ea35fa5f9 100644 --- a/tools/qfcc/include/method.h +++ b/tools/qfcc/include/method.h @@ -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); diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index e71936cc7..75473f15e 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -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; } diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index a0bbeba3b..9de72d44b 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -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)) diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index 1e19a6a02..c363b98b3 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -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); }