From 397cb4564c6a38e0a96dafa90c52bcf59213b32d Mon Sep 17 00:00:00 2001 From: Andrew Richardson Date: Sun, 5 Jan 2014 18:58:49 -0800 Subject: [PATCH] -Correctly handle object types with both a class name and a protocol (ie. NSObject *) referenced in methods and ivars -Add imports for protocols referenced in types --- Source/CDMultiFileVisitor.m | 5 +++++ Source/CDType.h | 1 + Source/CDType.m | 26 +++++++++++++++++++++----- Source/CDTypeController.h | 2 ++ Source/CDTypeController.m | 6 ++++++ Source/CDTypeFormatter.h | 1 + Source/CDTypeFormatter.m | 5 +++++ Source/CDTypeParser.m | 18 +++++++++++++++--- 8 files changed, 56 insertions(+), 8 deletions(-) diff --git a/Source/CDMultiFileVisitor.m b/Source/CDMultiFileVisitor.m index 8469dce4..5884b622 100644 --- a/Source/CDMultiFileVisitor.m +++ b/Source/CDMultiFileVisitor.m @@ -192,6 +192,11 @@ - (void)typeController:(CDTypeController *)typeController didReferenceClassName: [self addReferenceToClassName:name]; } +- (void)typeController:(CDTypeController *)typeController didReferenceProtocolNames:(NSArray *)names +{ + [self addReferencesToProtocolNamesInArray:names]; +} + #pragma mark - - (NSString *)frameworkForClassName:(NSString *)name; diff --git a/Source/CDType.h b/Source/CDType.h index 6ef74a1a..f4a3d434 100644 --- a/Source/CDType.h +++ b/Source/CDType.h @@ -10,6 +10,7 @@ - (id)init; - (id)initSimpleType:(int)type; - (id)initIDType:(CDTypeName *)name; +- (id)initIDType:(CDTypeName *)name withProtocols:(NSArray *)protocols; - (id)initIDTypeWithProtocols:(NSArray *)protocols; - (id)initStructType:(CDTypeName *)name members:(NSArray *)members; - (id)initUnionType:(CDTypeName *)name members:(NSArray *)members; diff --git a/Source/CDType.m b/Source/CDType.m index 1ac4d8d2..28f68cee 100644 --- a/Source/CDType.m +++ b/Source/CDType.m @@ -108,6 +108,11 @@ - (id)initSimpleType:(int)type; } - (id)initIDType:(CDTypeName *)name; +{ + return [self initIDType:name withProtocols:nil]; +} + +- (id)initIDType:(CDTypeName *)name withProtocols:(NSArray *)protocols { if ((self = [self init])) { if (name != nil) { @@ -116,8 +121,9 @@ - (id)initIDType:(CDTypeName *)name; } else { _primitiveType = '@'; } + _protocols = protocols; } - + return self; } @@ -315,17 +321,27 @@ - (NSString *)formattedString:(NSString *)previousName formatter:(CDTypeFormatte currentName = self.variableName; else currentName = previousName; + + if ([_protocols count]) + [typeFormatter formattingDidReferenceProtocolNames:_protocols]; switch (self.primitiveType) { - case T_NAMED_OBJECT: + case T_NAMED_OBJECT: { assert(self.typeName != nil); [typeFormatter formattingDidReferenceClassName:self.typeName.name]; + + NSString *typeName = nil; + if (_protocols == nil) + typeName = [NSString stringWithFormat:@"%@", self.typeName]; + else + typeName = [NSString stringWithFormat:@"%@ <%@>", self.typeName, [_protocols componentsJoinedByString:@", "]]; + if (currentName == nil) - result = [NSString stringWithFormat:@"%@ *", self.typeName]; + result = [NSString stringWithFormat:@"%@ *", typeName]; else - result = [NSString stringWithFormat:@"%@ *%@", self.typeName, currentName]; + result = [NSString stringWithFormat:@"%@ *%@", typeName, currentName]; break; - + } case '@': if (currentName == nil) { if (_protocols == nil) diff --git a/Source/CDTypeController.h b/Source/CDTypeController.h index 27fd0fe9..c325c1a5 100644 --- a/Source/CDTypeController.h +++ b/Source/CDTypeController.h @@ -28,6 +28,7 @@ - (CDType *)typeFormatter:(CDTypeFormatter *)typeFormatter replacementForType:(CDType *)type; - (NSString *)typeFormatter:(CDTypeFormatter *)typeFormatter typedefNameForStructure:(CDType *)structureType level:(NSUInteger)level; - (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceClassName:(NSString *)name; +- (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceProtocolNames:(NSArray *)names; - (void)appendStructuresToString:(NSMutableString *)resultString; @@ -58,4 +59,5 @@ @protocol CDTypeControllerDelegate @optional - (void)typeController:(CDTypeController *)typeController didReferenceClassName:(NSString *)name; +- (void)typeController:(CDTypeController *)typeController didReferenceProtocolNames:(NSArray *)names; @end diff --git a/Source/CDTypeController.m b/Source/CDTypeController.m index 6ef999d6..119c93f6 100644 --- a/Source/CDTypeController.m +++ b/Source/CDTypeController.m @@ -133,6 +133,12 @@ - (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceClassName:(NS [self.delegate typeController:self didReferenceClassName:name]; } +- (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceProtocolNames:(NSArray *)names +{ + if ([self.delegate respondsToSelector:@selector(typeController:didReferenceProtocolNames:)]) + [self.delegate typeController:self didReferenceProtocolNames:names]; +} + #pragma mark - - (void)appendStructuresToString:(NSMutableString *)resultString; diff --git a/Source/CDTypeFormatter.h b/Source/CDTypeFormatter.h index 053d8d92..c138a5d6 100644 --- a/Source/CDTypeFormatter.h +++ b/Source/CDTypeFormatter.h @@ -20,5 +20,6 @@ - (NSString *)typedefNameForStructure:(CDType *)structureType level:(NSUInteger)level; - (void)formattingDidReferenceClassName:(NSString *)name; +- (void)formattingDidReferenceProtocolNames:(NSArray *)names; @end diff --git a/Source/CDTypeFormatter.m b/Source/CDTypeFormatter.m index 623b978d..366b81e3 100644 --- a/Source/CDTypeFormatter.m +++ b/Source/CDTypeFormatter.m @@ -272,4 +272,9 @@ - (void)formattingDidReferenceClassName:(NSString *)name; [self.typeController typeFormatter:self didReferenceClassName:name]; } +- (void)formattingDidReferenceProtocolNames:(NSArray *)names +{ + [self.typeController typeFormatter:self didReferenceProtocolNames:names]; +} + @end diff --git a/Source/CDTypeParser.m b/Source/CDTypeParser.m index e548ba59..d36dc733 100644 --- a/Source/CDTypeParser.m +++ b/Source/CDTypeParser.m @@ -245,9 +245,21 @@ - (CDType *)_parseTypeInStruct:(BOOL)isInStruct; #endif if (_lookahead == TK_QUOTED_STRING && (isInStruct == NO || [self.lexer.lexText isFirstLetterUppercase] || [self isTokenInTypeStartSet:self.lexer.peekChar] == NO)) { NSString *str = self.lexer.lexText; - if ([str hasPrefix:@"<"] && [str hasSuffix:@">"]) { - str = [str substringWithRange:NSMakeRange(1, [str length] - 2)]; - result = [[CDType alloc] initIDTypeWithProtocols:[str componentsSeparatedByString:@","]]; + + NSUInteger protocolOpenIdx = NSMaxRange([str rangeOfString:@"<"]); + NSUInteger protocolCloseIdx = [str rangeOfString:@">" options:NSBackwardsSearch].location; + if (protocolOpenIdx != NSNotFound && protocolCloseIdx != NSNotFound) { + NSRange protocolRange = NSMakeRange(protocolOpenIdx, protocolCloseIdx - protocolOpenIdx); + NSArray *protocols = [[str substringWithRange:protocolRange] componentsSeparatedByString:@","]; + + NSString *typeNameStr = [[str substringToIndex:(protocolOpenIdx - 1)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + CDTypeName *typeName = nil; + if (![typeNameStr isEqualToString:@"id"]) { + typeName = [[CDTypeName alloc] init]; + typeName.name = typeNameStr; + } + + result = [[CDType alloc] initIDType:typeName withProtocols:protocols]; } else { CDTypeName *typeName = [[CDTypeName alloc] init]; typeName.name = str;