This repository has been archived by the owner on Jan 18, 2023. It is now read-only.
/
PXSourceListRuntimeAdditions.m
67 lines (52 loc) · 2.42 KB
/
PXSourceListRuntimeAdditions.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//
// PXSourceListRuntimeAdditions.m
// PXSourceList
//
// Created by Alex Rozanski on 25/12/2013.
// Copyright 2009-14 Alex Rozanski http://alexrozanski.com and other contributors.
// This software is licensed under the New BSD License. Full details can be found in the README.
//
#import "PXSourceListRuntimeAdditions.h"
NSString * const px_protocolMethodNameKey = @"methodName";
NSString * const px_protocolMethodArgumentTypesKey = @"types";
NSString * const px_protocolIsRequiredMethodKey = @"isRequired";
NSArray *px_allProtocolMethods(Protocol *protocol)
{
NSMutableArray *methodList = [[NSMutableArray alloc] init];
// We have 4 permutations as protocol_copyMethodDescriptionList() takes two BOOL arguments for the types of methods to return.
for (NSUInteger i = 0; i < 4; ++i) {
BOOL isRequiredMethod = (i / 2) % 2;
unsigned int numberOfMethodDescriptions = 0;
struct objc_method_description *methodDescriptions = protocol_copyMethodDescriptionList(protocol, isRequiredMethod, i % 2, &numberOfMethodDescriptions);
for (unsigned int j = 0; j < numberOfMethodDescriptions; ++j) {
struct objc_method_description methodDescription = methodDescriptions[j];
[methodList addObject:@{px_protocolMethodNameKey: px_methodNameForSelector(methodDescription.name),
px_protocolMethodArgumentTypesKey: [NSString stringWithUTF8String:methodDescription.types],
px_protocolIsRequiredMethodKey: @(isRequiredMethod)}];
}
free(methodDescriptions);
}
return methodList;
}
NSArray *px_methodNamesForProtocol(Protocol *protocol)
{
NSMutableArray *methodNames = [[NSMutableArray alloc] init];
for (NSDictionary *methodInfo in px_allProtocolMethods(protocol))
[methodNames addObject:methodInfo[px_protocolMethodNameKey]];
return methodNames;
}
id px_methodNameForSelector(SEL selector)
{
return NSStringFromSelector(selector);
}
struct objc_method_description px_methodDescriptionForProtocolMethod(Protocol *protocol, SEL selector)
{
struct objc_method_description description = {NULL, NULL};
// We have 4 permutations to check for.
for (NSUInteger i = 0; i < 4; ++i) {
description = protocol_getMethodDescription(protocol, selector, (i / 2) % 2, i % 2);
if (description.types != NULL && description.name != NULL)
break;
}
return description;
}