| Index: class-dump/src/CDOCProperty.m
|
| ===================================================================
|
| --- class-dump/src/CDOCProperty.m (revision 0)
|
| +++ class-dump/src/CDOCProperty.m (revision 0)
|
| @@ -0,0 +1,223 @@
|
| +// -*- mode: ObjC -*-
|
| +
|
| +// 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-2010 Steve Nygard.
|
| +
|
| +#import "CDOCProperty.h"
|
| +
|
| +#import "NSString-Extensions.h"
|
| +#import "CDTypeParser.h"
|
| +#import "CDTypeLexer.h"
|
| +
|
| +// http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
|
| +
|
| +static BOOL debug = NO;
|
| +
|
| +@implementation CDOCProperty
|
| +
|
| +- (id)initWithName:(NSString *)aName attributes:(NSString *)someAttributes;
|
| +{
|
| + if ([super init] == nil)
|
| + return nil;
|
| +
|
| + name = [aName retain];
|
| + attributeString = [someAttributes retain];
|
| + type = nil;
|
| + attributes = [[NSMutableArray alloc] init];
|
| +
|
| + hasParsedAttributes = NO;
|
| + attributeStringAfterType = nil;
|
| + customGetter = nil;
|
| + customSetter = nil;
|
| +
|
| + flags.isReadOnly = NO;
|
| + flags.isDynamic = NO;
|
| +
|
| + [self _parseAttributes];
|
| +
|
| + return self;
|
| +}
|
| +
|
| +- (void)dealloc;
|
| +{
|
| + [name release];
|
| + [attributeString release];
|
| + [type release];
|
| + [attributes release];
|
| +
|
| + [attributeStringAfterType release];
|
| + [customGetter release];
|
| + [customSetter release];
|
| +
|
| + [super dealloc];
|
| +}
|
| +
|
| +- (NSString *)name;
|
| +{
|
| + return name;
|
| +}
|
| +
|
| +- (NSString *)attributeString;
|
| +{
|
| + return attributeString;
|
| +}
|
| +
|
| +- (CDType *)type;
|
| +{
|
| + return type;
|
| +}
|
| +
|
| +- (NSArray *)attributes;
|
| +{
|
| + return attributes;
|
| +}
|
| +
|
| +- (NSString *)attributeStringAfterType;
|
| +{
|
| + return attributeStringAfterType;
|
| +}
|
| +
|
| +- (void)_setAttributeStringAfterType:(NSString *)newValue;
|
| +{
|
| + if (newValue == attributeStringAfterType)
|
| + return;
|
| +
|
| + [attributeStringAfterType release];
|
| + attributeStringAfterType = [newValue retain];
|
| +}
|
| +
|
| +- (NSString *)defaultGetter;
|
| +{
|
| + return name;
|
| +}
|
| +
|
| +- (NSString *)defaultSetter;
|
| +{
|
| + return [NSString stringWithFormat:@"set%@:", [name capitalizeFirstCharacter]];
|
| +}
|
| +
|
| +- (NSString *)customGetter;
|
| +{
|
| + return customGetter;
|
| +}
|
| +
|
| +- (void)_setCustomGetter:(NSString *)newStr;
|
| +{
|
| + if (newStr == customGetter)
|
| + return;
|
| +
|
| + [customGetter release];
|
| + customGetter = [newStr retain];
|
| +}
|
| +
|
| +- (NSString *)customSetter;
|
| +{
|
| + return customSetter;
|
| +}
|
| +
|
| +- (void)_setCustomSetter:(NSString *)newStr;
|
| +{
|
| + if (newStr == customSetter)
|
| + return;
|
| +
|
| + [customSetter release];
|
| + customSetter = [newStr retain];
|
| +}
|
| +
|
| +- (NSString *)getter;
|
| +{
|
| + if (customGetter != nil)
|
| + return customGetter;
|
| +
|
| + return [self defaultGetter];
|
| +}
|
| +
|
| +- (NSString *)setter;
|
| +{
|
| + if (customSetter != nil)
|
| + return customSetter;
|
| +
|
| + return [self defaultSetter];
|
| +}
|
| +
|
| +- (BOOL)isReadOnly;
|
| +{
|
| + return flags.isReadOnly;
|
| +}
|
| +
|
| +- (BOOL)isDynamic;
|
| +{
|
| + return flags.isDynamic;
|
| +}
|
| +
|
| +- (NSString *)description;
|
| +{
|
| + return [NSString stringWithFormat:@"<%@:%p> name: %@, attributeString: %@",
|
| + NSStringFromClass([self class]), self,
|
| + name, attributeString];
|
| +}
|
| +
|
| +- (NSComparisonResult)ascendingCompareByName:(CDOCProperty *)otherProperty;
|
| +{
|
| + return [name compare:[otherProperty name]];
|
| +}
|
| +
|
| +// TODO (2009-07-09): Really, I don't need to require the "T" at the start.
|
| +- (void)_parseAttributes;
|
| +{
|
| + NSScanner *scanner;
|
| +
|
| + // On 10.6, Finder's TTaskErrorViewController class has a property with a nasty C++ type. I just knew someone would make this difficult.
|
| + scanner = [[NSScanner alloc] initWithString:attributeString];
|
| +
|
| + if ([scanner scanString:@"T" intoString:NULL]) {
|
| + NSError *error;
|
| + NSRange typeRange;
|
| + CDTypeParser *parser;
|
| +
|
| + typeRange.location = [scanner scanLocation];
|
| + parser = [[CDTypeParser alloc] initWithType:[[scanner string] substringFromIndex:[scanner scanLocation]]];
|
| + type = [[parser parseType:&error] retain];
|
| + if (type != nil) {
|
| + NSString *str;
|
| +
|
| + typeRange.length = [[[parser lexer] scanner] scanLocation];
|
| +
|
| + str = [attributeString substringFromIndex:NSMaxRange(typeRange)];
|
| +
|
| + // Filter out so we don't get an empty string as an attribute.
|
| + if ([str hasPrefix:@","])
|
| + str = [str substringFromIndex:1];
|
| +
|
| + [self _setAttributeStringAfterType:str];
|
| + if ([attributeStringAfterType length] > 0) {
|
| + [attributes addObjectsFromArray:[attributeStringAfterType componentsSeparatedByString:@","]];
|
| + } else {
|
| + // For a simple case like "Ti", we'd get the empty string.
|
| + // Then, using componentsSeparatedByString:, since it has no separator we'd get back an array containing the (empty) string
|
| + }
|
| + }
|
| +
|
| + [parser release];
|
| + } else {
|
| + if (debug) NSLog(@"Error: Property attributes should begin with the type ('T') attribute, property name: %@", name);
|
| + }
|
| +
|
| + [scanner release];
|
| +
|
| + for (NSString *attr in attributes) {
|
| + if ([attr hasPrefix:@"R"])
|
| + flags.isReadOnly = YES;
|
| + else if ([attr hasPrefix:@"D"])
|
| + flags.isDynamic = YES;
|
| + else if ([attr hasPrefix:@"G"])
|
| + [self _setCustomGetter:[attr substringFromIndex:1]];
|
| + else if ([attr hasPrefix:@"S"])
|
| + [self _setCustomSetter:[attr substringFromIndex:1]];
|
| + }
|
| +
|
| + hasParsedAttributes = YES;
|
| + // And then if parsedType is nil, we know we couldn't parse the type.
|
| +}
|
| +
|
| +@end
|
|
|
| Property changes on: class-dump/src/CDOCProperty.m
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|