KWGenericMatchEvaluator.m 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. //
  2. // KWGenericMatcher.m
  3. // Kiwi
  4. //
  5. // Created by Allen Ding on 1/31/13.
  6. // Copyright (c) 2013 Allen Ding. All rights reserved.
  7. //
  8. #import "KWGenericMatchEvaluator.h"
  9. #import "KWStringUtilities.h"
  10. #import "KWObjCUtilities.h"
  11. #import <objc/runtime.h>
  12. #import "KWGenericMatcher.h"
  13. @implementation KWGenericMatchEvaluator
  14. // Returns true only if the object has a method with the signature "- (BOOL)matches:(id)object"
  15. + (BOOL)isGenericMatcher:(id)object {
  16. Class theClass = object_getClass(object);
  17. if (theClass == NULL) {
  18. return NO;
  19. }
  20. Method method = class_getInstanceMethod(theClass, @selector(matches:));
  21. if (method == NULL) {
  22. return NO;
  23. }
  24. const char *cEncoding = method_getTypeEncoding(method);
  25. if (cEncoding == NULL) {
  26. return NO;
  27. }
  28. NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:cEncoding];
  29. if (!KWObjCTypeEqualToObjCType(@encode(BOOL), [signature methodReturnType])) {
  30. return NO;
  31. }
  32. if ([signature numberOfArguments] != 3) {
  33. return NO;
  34. }
  35. if (!KWObjCTypeEqualToObjCType(@encode(id), [signature getArgumentTypeAtIndex:2])) {
  36. return NO;
  37. }
  38. return YES;
  39. }
  40. + (BOOL)genericMatcher:(id)matcher matches:(id)object {
  41. NSString *targetEncoding = KWEncodingWithObjCTypes(@encode(BOOL), @encode(id), @encode(SEL), @encode(id), nil);
  42. NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:[targetEncoding UTF8String]];
  43. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  44. [invocation setSelector:@selector(matches:)];
  45. [invocation setArgument:&object atIndex:2];
  46. [invocation invokeWithTarget:matcher];
  47. BOOL result = NO;
  48. [invocation getReturnValue:&result];
  49. return result;
  50. }
  51. @end