blob: 3c1130b2438cd650b5b5566d6a8061563605ffb6 [file] [log] [blame]
// This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
// Copyright (C) 1997-1998, 2000-2001, 2004-2006 Steve Nygard
#import "CDOCProtocol.h"
#import <Foundation/Foundation.h>
#import "NSArray-Extensions.h"
#import "CDClassDump.h"
#import "CDOCMethod.h"
#import "CDOCSymtab.h"
#import "CDSymbolReferences.h"
#import "CDTypeParser.h"
@implementation CDOCProtocol
- (id)init;
{
if ([super init] == nil)
return nil;
name = nil;
protocols = [[NSMutableArray alloc] init];
classMethods = nil;
instanceMethods = nil;
adoptedProtocolNames = [[NSMutableSet alloc] init];
return self;
}
- (void)dealloc;
{
[name release];
[protocols release];
[classMethods release];
[instanceMethods release];
[adoptedProtocolNames release];
[super dealloc];
}
- (NSString *)name;
{
return name;
}
- (void)setName:(NSString *)newName;
{
if (newName == name)
return;
[name release];
name = [newName retain];
}
- (NSArray *)protocols;
{
return protocols;
}
// This assumes that the protocol name doesn't change after it's been added to this.
- (void)addProtocol:(CDOCProtocol *)aProtocol;
{
if ([adoptedProtocolNames containsObject:[aProtocol name]] == NO) {
[protocols addObject:aProtocol];
[adoptedProtocolNames addObject:[aProtocol name]];
}
}
- (void)removeProtocol:(CDOCProtocol *)aProtocol;
{
[adoptedProtocolNames removeObject:[aProtocol name]];
[protocols removeObject:aProtocol];
}
- (void)addProtocolsFromArray:(NSArray *)newProtocols;
{
int count, index;
count = [newProtocols count];
for (index = 0; index < count; index++)
[self addProtocol:[newProtocols objectAtIndex:index]];
}
- (NSArray *)classMethods;
{
return classMethods;
}
- (void)setClassMethods:(NSArray *)newClassMethods;
{
if (newClassMethods == classMethods)
return;
[classMethods release];
classMethods = [newClassMethods retain];
}
- (NSArray *)instanceMethods;
{
return instanceMethods;
}
- (void)setInstanceMethods:(NSArray *)newInstanceMethods;
{
if (newInstanceMethods == instanceMethods)
return;
[instanceMethods release];
instanceMethods = [newInstanceMethods retain];
}
- (NSString *)description;
{
return [NSString stringWithFormat:@"[%@] name: %@, protocols: %d, class methods: %d, instance methods: %d",
NSStringFromClass([self class]), name, [protocols count], [classMethods count], [instanceMethods count]];
}
- (void)appendToString:(NSMutableString *)resultString classDump:(CDClassDump *)aClassDump symbolReferences:(CDSymbolReferences *)symbolReferences;
{
if ([aClassDump shouldMatchRegex] == YES && [aClassDump regexMatchesString:[self name]] == NO)
return;
[resultString appendFormat:@"@protocol %@", name];
if ([protocols count] > 0) {
[resultString appendFormat:@" <%@>", [[protocols arrayByMappingSelector:@selector(name)] componentsJoinedByString:@", "]];
[symbolReferences addProtocolNamesFromArray:[protocols arrayByMappingSelector:@selector(name)]];
}
[resultString appendString:@"\n"];
[self appendMethodsToString:resultString classDump:aClassDump symbolReferences:symbolReferences];
[resultString appendString:@"@end\n\n"];
}
- (void)appendMethodsToString:(NSMutableString *)resultString classDump:(CDClassDump *)aClassDump symbolReferences:(CDSymbolReferences *)symbolReferences;
{
int count, index;
NSArray *methods;
if ([aClassDump shouldSortMethods] == YES)
methods = [classMethods sortedArrayUsingSelector:@selector(ascendingCompareByName:)];
else
methods = classMethods;
count = [methods count];
if (count > 0) {
for (index = 0; index < count; index++) {
[resultString appendString:@"+ "];
[[methods objectAtIndex:index] appendToString:resultString classDump:aClassDump symbolReferences:symbolReferences];
[resultString appendString:@"\n"];
}
}
if ([aClassDump shouldSortMethods] == YES)
methods = [instanceMethods sortedArrayUsingSelector:@selector(ascendingCompareByName:)];
else
methods = instanceMethods;
count = [methods count];
if (count > 0) {
for (index = 0; index < count; index++) {
[resultString appendString:@"- "];
[[methods objectAtIndex:index] appendToString:resultString classDump:aClassDump symbolReferences:symbolReferences];
[resultString appendString:@"\n"];
}
}
}
- (void)registerStructuresWithObject:(id <CDStructureRegistration>)anObject phase:(int)phase;
{
[self registerStructuresFromMethods:classMethods withObject:anObject phase:phase];
[self registerStructuresFromMethods:instanceMethods withObject:anObject phase:phase];
}
- (void)registerStructuresFromMethods:(NSArray *)methods withObject:(id <CDStructureRegistration>)anObject phase:(int)phase;
{
int count, index;
CDTypeParser *parser;
NSArray *methodTypes;
count = [methods count];
for (index = 0; index < count; index++) {
parser = [[CDTypeParser alloc] initWithType:[(CDOCMethod *)[methods objectAtIndex:index] type]];
methodTypes = [parser parseMethodType];
if (methodTypes == nil)
NSLog(@"Warning: Parsing method types failed, %@", [(CDOCMethod *)[methods objectAtIndex:index] name]);
[self registerStructuresFromMethodTypes:methodTypes withObject:anObject phase:phase];
[parser release];
}
}
- (void)registerStructuresFromMethodTypes:(NSArray *)methodTypes withObject:(id <CDStructureRegistration>)anObject phase:(int)phase;
{
int count, index;
count = [methodTypes count];
for (index = 0; index < count; index++) {
[[methodTypes objectAtIndex:index] registerStructuresWithObject:anObject phase:phase];
}
}
- (NSString *)sortableName;
{
return name;
}
- (NSComparisonResult)ascendingCompareByName:(CDOCProtocol *)otherProtocol;
{
return [[self sortableName] compare:[otherProtocol sortableName]];
}
@end