| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- //
- // FLEXProtocol.m
- // FLEX
- //
- // Derived from MirrorKit.
- // Created by Tanner on 6/30/15.
- // Copyright (c) 2015 Tanner Bennett. All rights reserved.
- //
- #import "FLEXProtocol.h"
- #import "FLEXProperty.h"
- #import <objc/runtime.h>
- @implementation FLEXProtocol
- - (id)init {
- [NSException
- raise:NSInternalInconsistencyException
- format:@"Class instance should not be created with -init"
- ];
- return nil;
- }
- #pragma mark Initializers
- + (NSArray *)allProtocols {
- unsigned int prcount;
- Protocol *__unsafe_unretained*protocols = objc_copyProtocolList(&prcount);
-
- NSMutableArray *all = [NSMutableArray new];
- for(NSUInteger i = 0; i < prcount; i++)
- [all addObject:[self protocol:protocols[i]]];
-
- free(protocols);
- return all;
- }
- + (instancetype)protocol:(Protocol *)protocol {
- return [[self alloc] initWithProtocol:protocol];
- }
- - (id)initWithProtocol:(Protocol *)protocol {
- NSParameterAssert(protocol);
-
- self = [super init];
- if (self) {
- _objc_protocol = protocol;
- [self examine];
- }
-
- return self;
- }
- #pragma mark Other
- - (NSString *)description {
- return self.name;
- }
- - (NSString *)debugDescription {
- return [NSString stringWithFormat:@"<%@ name=%@, %lu properties, %lu required methods, %lu optional methods, %lu protocols>",
- NSStringFromClass(self.class), self.name, (unsigned long)self.properties.count,
- (unsigned long)self.requiredMethods.count, (unsigned long)self.optionalMethods.count, (unsigned long)self.protocols.count];
- }
- - (void)examine {
- _name = @(protocol_getName(self.objc_protocol));
- unsigned int prcount, pccount, mdrcount, mdocount;
-
- objc_property_t *objcproperties = protocol_copyPropertyList(self.objc_protocol, &prcount);
- Protocol * __unsafe_unretained *objcprotocols = protocol_copyProtocolList(self.objc_protocol, &pccount);
- struct objc_method_description *objcrmethods = protocol_copyMethodDescriptionList(self.objc_protocol, YES, YES, &mdrcount);
- struct objc_method_description *objcomethods = protocol_copyMethodDescriptionList(self.objc_protocol, NO, YES, &mdocount);
-
- NSMutableArray *properties = [NSMutableArray new];
- for (int i = 0; i < prcount; i++)
- [properties addObject:[FLEXProperty property:objcproperties[i]]];
- _properties = properties;
-
- NSMutableArray *protocols = [NSMutableArray new];
- for (int i = 0; i < pccount; i++)
- [protocols addObject:[FLEXProtocol protocol:objcprotocols[i]]];
- _protocols = protocols;
-
- NSMutableArray *requiredMethods = [NSMutableArray new];
- for (int i = 0; i < mdrcount; i++)
- [requiredMethods addObject:[FLEXMethodDescription description:objcrmethods[i]]];
- _requiredMethods = requiredMethods;
-
- NSMutableArray *optionalMethods = [NSMutableArray new];
- for (int i = 0; i < mdocount; i++)
- [optionalMethods addObject:[FLEXMethodDescription description:objcomethods[i]]];
- _optionalMethods = optionalMethods;
-
- free(objcproperties);
- free(objcprotocols);
- free(objcrmethods);
- free(objcomethods);
- }
- - (BOOL)conformsTo:(Protocol *)protocol {
- return protocol_conformsToProtocol(self.objc_protocol, protocol);
- }
- @end
- #pragma mark FLEXMethodDescription
- @implementation FLEXMethodDescription
- - (id)init {
- [NSException
- raise:NSInternalInconsistencyException
- format:@"Class instance should not be created with -init"
- ];
- return nil;
- }
- + (instancetype)description:(struct objc_method_description)methodDescription {
- return [[self alloc] initWithDescription:methodDescription];
- }
- - (id)initWithDescription:(struct objc_method_description)md {
- NSParameterAssert(md.name != NULL);
-
- self = [super init];
- if (self) {
- _objc_description = md;
- _selector = md.name;
- _typeEncoding = @(md.types);
- _returnType = (FLEXTypeEncoding)[self.typeEncoding characterAtIndex:0];
- }
-
- return self;
- }
- - (NSString *)description {
- return NSStringFromSelector(self.selector);
- }
- - (NSString *)debugDescription {
- return [NSString stringWithFormat:@"<%@ name=%@, type=%@>",
- NSStringFromClass(self.class), NSStringFromSelector(self.selector), self.typeEncoding];
- }
- @end
|