main
 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
 9#import "KWGenericMatchEvaluator.h"
10#import "KWStringUtilities.h"
11#import "KWObjCUtilities.h"
12#import <objc/runtime.h>
13
14@implementation KWGenericMatchEvaluator
15
16// Returns true only if the object has a method with the signature "- (void)matches:(id)object"
17+ (BOOL)isGenericMatcher:(id)object
18{
19    Class theClass = object_getClass(object);
20
21    if (theClass == NULL) {
22        return NO;
23    }
24
25    Method method = class_getInstanceMethod(theClass, @selector(matches:));
26
27    if (method == NULL) {
28        return NO;
29    }
30
31    const char *cEncoding = method_getTypeEncoding(method);
32
33    if (cEncoding == NULL) {
34        return NO;
35    }
36
37    NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:cEncoding];
38
39    if (!KWObjCTypeEqualToObjCType(@encode(BOOL), [signature methodReturnType])) {
40        return NO;
41    }
42
43    if ([signature numberOfArguments] != 3) {
44        return NO;
45    }
46
47    if (!KWObjCTypeEqualToObjCType(@encode(id), [signature getArgumentTypeAtIndex:2])) {
48        return NO;
49    }
50
51    return YES;
52}
53
54+ (BOOL)genericMatcher:(id)matcher matches:(id)object
55{
56    NSString *targetEncoding = KWEncodingWithObjCTypes(@encode(BOOL), @encode(id), @encode(SEL), @encode(id), nil);
57    NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:[targetEncoding UTF8String]];
58    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
59    [invocation setSelector:@selector(matches:)];
60    [invocation setArgument:&object atIndex:2];
61    [invocation invokeWithTarget:matcher];
62    BOOL result = NO;
63    [invocation getReturnValue:&result];
64    return result;
65}
66
67@end