From 77d02d075ba3bfb85ac2d642f2e620a216280d3e Mon Sep 17 00:00:00 2001 From: theraven Date: Tue, 7 Sep 2010 20:55:26 +0000 Subject: [PATCH] Add some missing protocol introspection functions. --- objc/runtime.h | 13 ++++++++++++ protocol.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/objc/runtime.h b/objc/runtime.h index ec5287f..56d4b35 100644 --- a/objc/runtime.h +++ b/objc/runtime.h @@ -81,6 +81,19 @@ typedef void *objc_property_t; typedef struct objc_protocol Protocol; #endif +struct objc_method_description +{ + /** + * The name of this method. + */ + SEL name; + /** + * The types of this method. + */ + const char *types; +}; + + #ifndef YES #define YES ((BOOL)1) #endif diff --git a/protocol.c b/protocol.c index ea00a60..2ef9a3e 100644 --- a/protocol.c +++ b/protocol.c @@ -267,13 +267,68 @@ BOOL class_conformsToProtocol(Class cls, Protocol *protocol) struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *count) { + static id protocol2 = NULL; + + if (NULL == protocol2) + { + protocol2 = objc_getClass("Protocol2"); + } + + struct objc_method_description_list *list; *count = 0; - return NULL; + if (isRequiredMethod) + { + if (isInstanceMethod) + { + list = p->instance_methods; + } + else + { + list = p->class_methods; + } + } + else + { + if (p->isa != protocol2) { return NULL; } + + + if (isInstanceMethod) + { + list = ((Protocol2*)p)->optional_instance_methods; + } + else + { + list = ((Protocol2*)p)->optional_class_methods; + } + } + if (NULL == list || list->count == 0) { return NULL; } + + *count = list->count; + struct objc_method_description *out = + calloc(sizeof(struct objc_method_description_list), list->count); + + for (int i=0 ; icount ; i++) + { + out[i].name = sel_registerTypedName_np(list->methods[i].name, + list->methods[i].types); + out[i].types = list->methods[i].types; + } + return out; } Protocol **protocol_copyProtocolList(Protocol *p, unsigned int *count) { *count = 0; + if (p->protocol_list == NULL || p->protocol_list->count ==0) + { + return NULL; + } + + Protocol **out = calloc(sizeof(Protocol*), p->protocol_list->count); + for (int i=0 ; iprotocol_list->count ; i++) + { + out[i] = (Protocol*)p->protocol_list->list[i]; + } return NULL; }