blob: 402429124755b234cc12e4e89cea4a95673fbd70 [file] [log] [blame]
// -*- mode: ObjC -*-
// This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
// Copyright (C) 1997-2019 Steve Nygard.
#import "CDFindMethodVisitor.h"
#import "CDClassDump.h"
#import "CDObjectiveC1Processor.h"
#import "CDMachOFile.h"
#import "CDOCProtocol.h"
#import "CDLCDylib.h"
#import "CDOCClass.h"
#import "CDOCCategory.h"
#import "CDOCMethod.h"
//#import "CDTypeController.h"
@interface CDFindMethodVisitor ()
@property (readonly) NSMutableString *resultString;
@property (nonatomic, strong) CDOCProtocol *context;
@property (assign) BOOL hasShownContext;
@end
#pragma mark -
@implementation CDFindMethodVisitor
{
NSString *_searchString;
NSMutableString *_resultString;
CDOCProtocol *_context;
BOOL _hasShownContext;
}
- (id)init;
{
if ((self = [super init])) {
_searchString = nil;
_resultString = [[NSMutableString alloc] init];
_context = nil;
_hasShownContext = NO;
}
return self;
}
#pragma mark -
- (void)willBeginVisiting;
{
[self.classDump appendHeaderToString:self.resultString];
if (self.classDump.hasObjectiveCRuntimeInfo) {
//[[classDump typeController] appendStructuresToString:resultString symbolReferences:nil];
//[resultString appendString:@"// [structures go here]\n"];
}
}
- (void)visitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
{
if (!self.classDump.hasObjectiveCRuntimeInfo) {
[self.resultString appendString:@"//\n"];
[self.resultString appendString:@"// This file does not contain any Objective-C runtime information.\n"];
[self.resultString appendString:@"//\n"];
}
}
- (void)didEndVisiting;
{
[self writeResultToStandardOutput];
}
- (void)writeResultToStandardOutput;
{
NSData *data = [self.resultString dataUsingEncoding:NSUTF8StringEncoding];
[(NSFileHandle *)[NSFileHandle fileHandleWithStandardOutput] writeData:data];
}
- (void)willVisitProtocol:(CDOCProtocol *)protocol;
{
[self setContext:protocol];
}
- (void)didVisitProtocol:(CDOCProtocol *)protocol;
{
if (self.hasShownContext)
[self.resultString appendString:@"\n"];
}
- (void)willVisitClass:(CDOCClass *)aClass;
{
[self setContext:aClass];
}
- (void)didVisitClass:(CDOCClass *)aClass;
{
if (self.hasShownContext)
[self.resultString appendString:@"\n"];
}
- (void)willVisitIvarsOfClass:(CDOCClass *)aClass;
{
}
- (void)didVisitIvarsOfClass:(CDOCClass *)aClass;
{
}
- (void)willVisitCategory:(CDOCCategory *)category;
{
[self setContext:category];
}
- (void)didVisitCategory:(CDOCCategory *)category;
{
if (self.hasShownContext)
[self.resultString appendString:@"\n"];
}
- (void)visitClassMethod:(CDOCMethod *)method;
{
NSRange range = [method.name rangeOfString:self.searchString];
if (range.length > 0) {
[self showContextIfNecessary];
[self.resultString appendString:@"+ "];
[method appendToString:self.resultString typeController:self.classDump.typeController];
[self.resultString appendString:@"\n"];
}
}
- (void)visitInstanceMethod:(CDOCMethod *)method propertyState:(CDVisitorPropertyState *)propertyState;
{
NSRange range = [method.name rangeOfString:self.searchString];
if (range.length > 0) {
[self showContextIfNecessary];
[self.resultString appendString:@"- "];
[method appendToString:self.resultString typeController:self.classDump.typeController];
[self.resultString appendString:@"\n"];
}
}
- (void)visitIvar:(CDOCInstanceVariable *)ivar;
{
}
#pragma mark -
- (void)setContext:(CDOCProtocol *)newContext;
{
if (newContext != _context) {
_context = newContext;
self.hasShownContext = NO;
}
}
- (void)showContextIfNecessary;
{
if (self.hasShownContext == NO) {
[self.resultString appendString:[self.context methodSearchContext]];
[self.resultString appendString:@"\n"];
self.hasShownContext = YES;
}
}
@end