General improvements in responsetoSelector and methodSig code

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@9923 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2001-05-12 06:25:46 +00:00
parent ac7eae4414
commit 9609221f1b
3 changed files with 93 additions and 21 deletions

View file

@ -1,3 +1,12 @@
2001-05-12 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSObject.m: Removed some unused obsolete code.
* Source/NSProxy.m: Modified ([methodSignatureForSelector:]) and
([respondsToSelector:]) to work for existing methods and raise
exception for non-existant methods. The MacOS-X docs says they raise
exceptions, but I think it makes sense for them to work for methods
that are actually implemented in the proxy.
2001-05-11 Adam Fedor <fedor@gnu.org> 2001-05-11 Adam Fedor <fedor@gnu.org>
* Source/NSArchiver.m ([NSArchiver -encodeValueOfObjCType:at:]): Use * Source/NSArchiver.m ([NSArchiver -encodeValueOfObjCType:at:]): Use

View file

@ -1101,14 +1101,7 @@ static BOOL deallocNotifications = NO;
- (BOOL) respondsToSelector: (SEL)aSelector - (BOOL) respondsToSelector: (SEL)aSelector
{ {
#if 0
if (GSObjCIsInstance(self))
return (class_get_instance_method(GSObjCClass(self), aSelector)!=METHOD_NULL);
else
return (class_get_class_method(GSObjCClass(self), aSelector)!=METHOD_NULL);
#else
return __objc_responds_to(self, aSelector); return __objc_responds_to(self, aSelector);
#endif
} }
- (id) retain - (id) retain

View file

@ -30,6 +30,7 @@
#include <Foundation/NSObjCRuntime.h> #include <Foundation/NSObjCRuntime.h>
#include "limits.h" #include "limits.h"
extern BOOL __objc_responds_to(id, SEL);
@implementation NSProxy @implementation NSProxy
@ -54,19 +55,35 @@
return self; return self;
} }
+ (void) load
{
/* Do nothing */
}
+ (NSString*) description + (NSString*) description
{ {
return [NSString stringWithFormat: @"<%s>", object_get_class_name(self)]; return [NSString stringWithFormat: @"<%s>", object_get_class_name(self)];
} }
+ (BOOL) respondsToSelector: (SEL)aSelector + (void) load
{ {
return (class_get_class_method(self, aSelector) != METHOD_NULL); /* Do nothing */
}
+ (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
{
struct objc_method *mth;
if (aSelector == 0)
{
return nil;
}
mth = class_get_class_method(GSObjCClass(self), aSelector);
if (mth != 0)
{
const char *types = mth->method_types;
if (types != 0)
{
return [NSMethodSignature signatureWithObjCTypes: types];
}
}
return nil;
} }
+ (void) release + (void) release
@ -74,6 +91,14 @@
/* Do nothing */ /* Do nothing */
} }
+ (BOOL) respondsToSelector: (SEL)aSelector
{
if (__objc_responds_to(self, aSelector))
return YES;
else
return NO;
}
+ (id) retain + (id) retain
{ {
return self; return self;
@ -121,8 +146,8 @@
NSInvocation *inv; NSInvocation *inv;
inv = AUTORELEASE([[NSInvocation alloc] initWithArgframe: argFrame inv = AUTORELEASE([[NSInvocation alloc] initWithArgframe: argFrame
selector: aSel]); selector: aSel]);
[self forwardInvocation:inv]; [self forwardInvocation: inv];
return [inv returnFrame: argFrame]; return [inv returnFrame: argFrame];
} }
@ -140,6 +165,9 @@
- (id) init - (id) init
{ {
[NSException raise: NSGenericException
format: @"subclass %s should override %s", object_get_class_name(self),
sel_get_name(_cmd)];
return self; return self;
} }
@ -190,10 +218,30 @@
return self; return self;
} }
/*
* If we respond to the method directly, create and return a method
* signature. Otherwise raise an exception.
*/
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector - (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
{ {
struct objc_method *mth;
if (aSelector == 0)
{
return nil;
}
mth = class_get_instance_method(GSObjCClass(self), aSelector);
if (mth != 0)
{
const char *types = mth->method_types;
if (types != 0)
{
return [NSMethodSignature signatureWithObjCTypes: types];
}
}
[NSException raise: NSInvalidArgumentException format: [NSException raise: NSInvalidArgumentException format:
@"NSProxy should not implement 'methodSignatureForSelector:'"]; @"NSProxy should not implement 'methodSignatureForSelector:'"];
return nil; return nil;
} }
@ -252,12 +300,34 @@
#endif #endif
} }
/*
* If we respond to the method directly, return YES, otherwise
* forward this request to the object we are acting as a proxy for.
*/
- (BOOL) respondsToSelector: (SEL)aSelector - (BOOL) respondsToSelector: (SEL)aSelector
{ {
[NSException raise: NSGenericException if (aSelector == 0)
format: @"subclass %s should override %s", object_get_class_name(self), {
sel_get_name(_cmd)]; return NO;
return NO; }
if (__objc_responds_to(self, aSelector))
{
return YES;
}
else
{
NSMethodSignature *sig;
NSInvocation *inv;
BOOL ret;
sig = [self methodSignatureForSelector: _cmd];
inv = [NSInvocation invocationWithMethodSignature: sig];
[inv setSelector: _cmd];
[inv setArgument: &aSelector atIndex: 2];
[self forwardInvocation: inv];
[inv getReturnValue: &ret];
return ret;
}
} }
- (id) retain - (id) retain