<commit_before>#import "CDRFake.h"
#import "CDRProtocolFake.h"
#import "StubbedMethod.h"
#import <objc/runtime.h>

static bool protocol_hasSelector(Protocol *protocol, SEL selector, BOOL is_required_method, BOOL is_instance_method) {
    objc_method_description method_description = protocol_getMethodDescription(protocol, selector, is_required_method, is_instance_method);
    return method_description.name && method_description.types;
}

static bool CDR_protocol_hasSelector(Protocol *protocol, SEL selector) {
    return (protocol_hasSelector(protocol, selector, true, true)
            || protocol_hasSelector(protocol, selector, true, false)
            || protocol_hasSelector(protocol, selector, false, true)
            || protocol_hasSelector(protocol, selector, false, false));
}

@interface CDRProtocolFake ()
@property (retain, nonatomic) NSArray *protocols;
@end

@implementation CDRProtocolFake

@synthesize protocols = protocols_;

- (id)initWithClass:(Class)klass forProtocols:(NSArray *)protocols requireExplicitStubs:(BOOL)requireExplicitStubs; {
    if (self = [super initWithClass:klass requireExplicitStubs:requireExplicitStubs]) {
        self.protocols = protocols;
    }
    return self;
}

- (void)dealloc {
    self.protocols = nil;
    [super dealloc];
}

- (BOOL)can_stub:(SEL)selector {
    if (class_respondsToSelector(self.klass, selector)) {
        return YES;
    }
    for (Protocol *protocol in self.protocols) {
        if (CDR_protocol_hasSelector(protocol, selector)) {
            return YES;
        }
    }
    return NO;
}

- (BOOL)respondsToSelector:(SEL)selector {
    if (class_respondsToSelector(self.klass, selector)) {
        return YES;
    }

    for (Protocol *protocol in self.protocols) {
        if ([self respondsToSelector:selector fromProtocol:protocol]) {
            return YES;
        }
    }
    return NO;
}

- (void)doesNotRecognizeSelector:(SEL)selector {
    if ([self has_rejected_method_for:selector]) {
        NSString *reason = [NSString stringWithFormat:@"Received message with explicitly rejected selector <%@>", NSStringFromSelector(selector)];
        [[NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil] raise];
    }
    else {
        [super doesNotRecognizeSelector:selector];
    }
}

- (BOOL)conformsToProtocol:(Protocol *)aProtocol {
    for (Protocol *protocol in self.protocols) {
        if (protocol_conformsToProtocol(protocol, aProtocol)) {
            return YES;
        }
    }
    return NO;
}

- (NSString *)description {
    NSMutableString *mutableDescription = [NSMutableString stringWithFormat:@"Fake implementation of %s", protocol_getName([self.protocols objectAtIndex:0])];
    NSUInteger protocolCount = [self.protocols count];
    for (int i = 1; i < protocolCount; i++) {
        [mutableDescription appendFormat:@", %s", protocol_getName([self.protocols objectAtIndex:i])];
    }
    [mutableDescription appendString:@" protocol(s)"];
    return [NSString stringWithString:mutableDescription];
}

- (BOOL)respondsToSelector:(SEL)selector fromProtocol:(Protocol *)protocol {
    if (protocol_hasSelector(protocol, selector, true, true) || protocol_hasSelector(protocol, selector, true, false)) {
        return YES;
    }
    if (self.requiresExplicitStubs) {
        return [self has_stubbed_method_for:selector];
    }
    if (!self.requiresExplicitStubs) {
        if ([self has_rejected_method_for:selector]) {
            return NO;
        }
    }
    return protocol_hasSelector(protocol, selector, false, true);
}

@end


id CDR_fake_for(BOOL require_explicit_stubs, Protocol *protocol, ...) {
    static size_t protocol_dummy_class_id = 0;

    NSMutableArray *protocolArray = [NSMutableArray arrayWithObject:protocol];

    va_list args;
    va_start(args, protocol);
    Protocol *p = nil;
    while ((p = va_arg(args, Protocol *))) {
        [protocolArray addObject:p];
    }
    va_end(args);<commit_msg>Simplify logic in -respondsToSelector:<commit_after>#import "CDRFake.h"
#import "CDRProtocolFake.h"
#import "StubbedMethod.h"
#import <objc/runtime.h>

static bool protocol_hasSelector(Protocol *protocol, SEL selector, BOOL is_required_method, BOOL is_instance_method) {
    objc_method_description method_description = protocol_getMethodDescription(protocol, selector, is_required_method, is_instance_method);
    return method_description.name && method_description.types;
}

static bool CDR_protocol_hasSelector(Protocol *protocol, SEL selector) {
    return (protocol_hasSelector(protocol, selector, true, true)
            || protocol_hasSelector(protocol, selector, true, false)
            || protocol_hasSelector(protocol, selector, false, true)
            || protocol_hasSelector(protocol, selector, false, false));
}

@interface CDRProtocolFake ()
@property (retain, nonatomic) NSArray *protocols;
@end

@implementation CDRProtocolFake

@synthesize protocols = protocols_;

- (id)initWithClass:(Class)klass forProtocols:(NSArray *)protocols requireExplicitStubs:(BOOL)requireExplicitStubs; {
    if (self = [super initWithClass:klass requireExplicitStubs:requireExplicitStubs]) {
        self.protocols = protocols;
    }
    return self;
}

- (void)dealloc {
    self.protocols = nil;
    [super dealloc];
}

- (BOOL)can_stub:(SEL)selector {
    if (class_respondsToSelector(self.klass, selector)) {
        return YES;
    }
    for (Protocol *protocol in self.protocols) {
        if (CDR_protocol_hasSelector(protocol, selector)) {
            return YES;
        }
    }
    return NO;
}

- (BOOL)respondsToSelector:(SEL)selector {
    if (class_respondsToSelector(self.klass, selector)) {
        return YES;
    }

    for (Protocol *protocol in self.protocols) {
        if ([self respondsToSelector:selector fromProtocol:protocol]) {
            return YES;
        }
    }
    return NO;
}

- (void)doesNotRecognizeSelector:(SEL)selector {
    if ([self has_rejected_method_for:selector]) {
        NSString *reason = [NSString stringWithFormat:@"Received message with explicitly rejected selector <%@>", NSStringFromSelector(selector)];
        [[NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil] raise];
    }
    else {
        [super doesNotRecognizeSelector:selector];
    }
}

- (BOOL)conformsToProtocol:(Protocol *)aProtocol {
    for (Protocol *protocol in self.protocols) {
        if (protocol_conformsToProtocol(protocol, aProtocol)) {
            return YES;
        }
    }
    return NO;
}

- (NSString *)description {
    NSMutableString *mutableDescription = [NSMutableString stringWithFormat:@"Fake implementation of %s", protocol_getName([self.protocols objectAtIndex:0])];
    NSUInteger protocolCount = [self.protocols count];
    for (int i = 1; i < protocolCount; i++) {
        [mutableDescription appendFormat:@", %s", protocol_getName([self.protocols objectAtIndex:i])];
    }
    [mutableDescription appendString:@" protocol(s)"];
    return [NSString stringWithString:mutableDescription];
}

- (BOOL)respondsToSelector:(SEL)selector fromProtocol:(Protocol *)protocol {
    if (protocol_hasSelector(protocol, selector, true, true) || protocol_hasSelector(protocol, selector, true, false)) {
        return YES;
    }
    if (self.requiresExplicitStubs) {
        return [self has_stubbed_method_for:selector];
    }
    else if ([self has_rejected_method_for:selector]) {
        return NO;
    }
    return protocol_hasSelector(protocol, selector, false, true);
}

@end


id CDR_fake_for(BOOL require_explicit_stubs, Protocol *protocol, ...) {
    static size_t protocol_dummy_class_id = 0;

    NSMutableArray *protocolArray = [NSMutableArray arrayWithObject:protocol];

    va_list args;
    va_start(args, protocol);
    Protocol *p = nil;
    while ((p = va_arg(args, Protocol *))) {
        [protocolArray addObject:p];
    }
    va_end(args);
{'fraction_non_alphanumeric': 0.1090125491190265, 'fraction_numerical': 0.0007605526682722779, 'mean_word_length': 4.041533546325879, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2993450', 'n_tokens_mistral': 2385, 'n_tokens_neox': 2285, 'n_words': 493}