From 3df677f15f784fc30e913175b1e946f7449cf934 Mon Sep 17 00:00:00 2001 From: robvdveer Date: Thu, 25 Jul 2013 12:01:04 +0200 Subject: [PATCH] Implemented crude parsing of typedef enum definitions with comments --- Model/GBDataObjects.h | 1 + Model/GBEnumConstantData.h | 19 ++++++++++ Model/GBEnumConstantData.m | 28 +++++++++++++++ Model/GBEnumConstantProvider.h | 24 +++++++++++++ Model/GBEnumConstantProvider.m | 30 ++++++++++++++++ Model/GBStore.h | 7 +++- Model/GBStore.m | 16 +++++++++ Model/GBTypedefEnumData.h | 24 +++++++++++++ Model/GBTypedefEnumData.m | 42 ++++++++++++++++++++++ Parsing/GBObjectiveCParser.m | 58 ++++++++++++++++++++++++++++++ appledoc.xcodeproj/project.pbxproj | 18 ++++++++++ 11 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 Model/GBEnumConstantData.h create mode 100644 Model/GBEnumConstantData.m create mode 100644 Model/GBEnumConstantProvider.h create mode 100644 Model/GBEnumConstantProvider.m create mode 100644 Model/GBTypedefEnumData.h create mode 100644 Model/GBTypedefEnumData.m diff --git a/Model/GBDataObjects.h b/Model/GBDataObjects.h index 46e6413c..da465ee5 100644 --- a/Model/GBDataObjects.h +++ b/Model/GBDataObjects.h @@ -16,6 +16,7 @@ #import "GBProtocolData.h" #import "GBDocumentData.h" +#import "GBTypedefEnumData.h" #import "GBIvarData.h" #import "GBMethodData.h" #import "GBMethodArgument.h" diff --git a/Model/GBEnumConstantData.h b/Model/GBEnumConstantData.h new file mode 100644 index 00000000..916b5261 --- /dev/null +++ b/Model/GBEnumConstantData.h @@ -0,0 +1,19 @@ +// +// GBEnumConstantData.h +// appledoc +// +// Created by Rob van der Veer on 25/7/13. +// Copyright (c) 2013 Gentle Bytes. All rights reserved. +// + +#import "GBModelBase.h" + +@interface GBEnumConstantData : GBModelBase +{ + @private + NSString *_name; +} ++(id)constantWithName:(NSString *)name; + +@property (readonly) NSString *name; +@end diff --git a/Model/GBEnumConstantData.m b/Model/GBEnumConstantData.m new file mode 100644 index 00000000..7507de56 --- /dev/null +++ b/Model/GBEnumConstantData.m @@ -0,0 +1,28 @@ +// +// GBEnumConstantData.m +// appledoc +// +// Created by Rob van der Veer on 25/7/13. +// Copyright (c) 2013 Gentle Bytes. All rights reserved. +// + +#import "GBEnumConstantData.h" + +@implementation GBEnumConstantData ++(id)constantWithName:(NSString *)name +{ + return [[[GBEnumConstantData alloc] initWithName:name] retain]; +} + +-(id)initWithName:(NSString *)name +{ + self = [super init]; + if(self) + { + _name = name; + } + return self; +} + +@synthesize name = _name; +@end diff --git a/Model/GBEnumConstantProvider.h b/Model/GBEnumConstantProvider.h new file mode 100644 index 00000000..0d781060 --- /dev/null +++ b/Model/GBEnumConstantProvider.h @@ -0,0 +1,24 @@ +// +// GBEnumConstantProvider.h +// appledoc +// +// Created by Rob van der Veer on 25/7/13. +// Copyright (c) 2013 Gentle Bytes. All rights reserved. +// + +#import +#import "GBEnumConstantData.h" + +@interface GBEnumConstantProvider : NSObject +{ + @private + NSMutableArray *_constants; + id _parent; + BOOL _useAlphabeticalOrder; +} + +- (id)initWithParentObject:(id)parent; +- (void)registerConstant:(GBEnumConstantData *)constant; + +@property (readonly) NSArray *constants; +@end diff --git a/Model/GBEnumConstantProvider.m b/Model/GBEnumConstantProvider.m new file mode 100644 index 00000000..436a7fb0 --- /dev/null +++ b/Model/GBEnumConstantProvider.m @@ -0,0 +1,30 @@ +// +// GBEnumConstantProvider.m +// appledoc +// +// Created by Rob van der Veer on 25/7/13. +// Copyright (c) 2013 Gentle Bytes. All rights reserved. +// + +#import "GBEnumConstantProvider.h" + +@implementation GBEnumConstantProvider + +- (id)initWithParentObject:(id)parent { + NSParameterAssert(parent != nil); + GBLogDebug(@"Initializing enumConstant provider for %@...", parent); + self = [super init]; + if (self) { + _parent = [parent retain]; + _constants = [[NSMutableArray alloc] init]; + _useAlphabeticalOrder = YES; + } + return self; +} + +-(void)registerConstant:(GBEnumConstantData *)constant { + +} + +@synthesize constants = _constants; +@end diff --git a/Model/GBStore.h b/Model/GBStore.h index 0df7e4a0..0b27a13c 100644 --- a/Model/GBStore.h +++ b/Model/GBStore.h @@ -12,6 +12,7 @@ @class GBCategoryData; @class GBProtocolData; @class GBDocumentData; +@class GBTypedefEnumData; /** Implements the application's in-memory objects data store. @@ -27,7 +28,9 @@ NSMutableDictionary *_protocolsByName; NSMutableSet *_documents; NSMutableDictionary *_documentsByName; - NSMutableSet *_customDocuments; + NSMutableSet *_typedefEnums; + NSMutableDictionary *_typedefEnumsByName; + NSMutableSet *_customDocuments; NSMutableDictionary *_customDocumentsByKey; } @@ -118,6 +121,8 @@ */ - (void)unregisterTopLevelObject:(id)object; +-(void)registerTypedefEnum:(GBTypedefEnumData *)typedefEnum; + ///--------------------------------------------------------------------------------------- /// @name Data handling ///--------------------------------------------------------------------------------------- diff --git a/Model/GBStore.m b/Model/GBStore.m index 93bb6a0c..aeb7f82e 100644 --- a/Model/GBStore.m +++ b/Model/GBStore.m @@ -24,6 +24,8 @@ - (id)init { _protocolsByName = [[NSMutableDictionary alloc] init]; _documents = [[NSMutableSet alloc] init]; _documentsByName = [[NSMutableDictionary alloc] init]; + _typedefEnums = [[NSMutableSet alloc] init]; + _typedefEnumsByName = [[NSMutableDictionary alloc] init]; _customDocuments = [[NSMutableSet alloc] init]; _customDocumentsByKey = [[NSMutableDictionary alloc] init]; } @@ -102,6 +104,20 @@ - (void)registerProtocol:(GBProtocolData *)protocol { [_protocolsByName setObject:protocol forKey:protocol.nameOfProtocol]; } +-(void)registerTypedefEnum:(GBTypedefEnumData *)typedefEnum +{ + NSParameterAssert(typedefEnum != nil); + GBLogDebug(@"Registering typedef enum %@...", typedefEnum); + if ([_typedefEnums containsObject:typedefEnum]) return; + GBProtocolData *existingTypedef = [_typedefEnumsByName objectForKey:typedefEnum.nameOfEnum]; + if (existingTypedef) { + [NSException raise:@"Typedef with name %@ is already registered!", typedefEnum.nameOfEnum]; + return; + } + [_typedefEnums addObject:typedefEnum]; + [_typedefEnumsByName setObject:typedefEnum forKey:typedefEnum.nameOfEnum]; +} + - (void)registerDocument:(GBDocumentData *)document { NSParameterAssert(document != nil); GBLogDebug(@"Registering document %@...", document); diff --git a/Model/GBTypedefEnumData.h b/Model/GBTypedefEnumData.h new file mode 100644 index 00000000..21840bfc --- /dev/null +++ b/Model/GBTypedefEnumData.h @@ -0,0 +1,24 @@ +// +// GBTypedefEnumData.h +// appledoc +// +// Created by Rob van der Veer on 25/7/13. +// Copyright (c) 2013 Gentle Bytes. All rights reserved. +// + +#import "GBModelBase.h" +#import "GBObjectDataProviding.h" +#import "GBEnumConstantProvider.h" + +@interface GBTypedefEnumData : GBModelBase +{ + @private + NSString *_typedefName; + GBEnumConstantProvider *_constants; +} + ++(id)typedefEnumWithName:(NSString *)name; + +@property (readonly) NSString *nameOfEnum; +@property (readonly) GBEnumConstantProvider *constants; +@end diff --git a/Model/GBTypedefEnumData.m b/Model/GBTypedefEnumData.m new file mode 100644 index 00000000..a80d582a --- /dev/null +++ b/Model/GBTypedefEnumData.m @@ -0,0 +1,42 @@ +// +// GBTypedefEnumData.m +// appledoc +// +// Created by Rob van der Veer on 25/7/13. +// Copyright (c) 2013 Gentle Bytes. All rights reserved. +// + +#import "GBTypedefEnumData.h" + +@implementation GBTypedefEnumData ++(id)typedefEnumWithName:(NSString *)name +{ + return [[[self alloc] initWithName:name] autorelease]; +} + +-(id)initWithName:(NSString *)name +{ + self = [super init]; + if(self) + { + _typedefName = name; + _constants = [[GBEnumConstantProvider alloc] initWithParentObject:self]; + } + return self; +} + +- (NSString *)description { + return self.nameOfEnum; +} + +- (NSString *)debugDescription { + return [NSString stringWithFormat:@"enum %@\n%@", self.nameOfEnum, self.constants.debugDescription]; +} + +- (BOOL)isTopLevelObject { + return YES; +} + +@synthesize nameOfEnum = _typedefName; +@synthesize constants = _constants; +@end diff --git a/Parsing/GBObjectiveCParser.m b/Parsing/GBObjectiveCParser.m index 514fa30f..2887b5ee 100644 --- a/Parsing/GBObjectiveCParser.m +++ b/Parsing/GBObjectiveCParser.m @@ -57,6 +57,7 @@ @interface GBObjectiveCParser (CommonParsing) - (BOOL)matchNextObject; - (BOOL)matchObjectDefinition; - (BOOL)matchObjectDeclaration; +- (BOOL)matchTypedefEnumDefinition; - (BOOL)matchMethodDataForProvider:(GBMethodsProvider *)provider from:(NSString *)start to:(NSString *)end required:(BOOL)required; - (void)registerComment:(GBComment *)comment toObject:(GBModelBase *)object; - (void)registerLastCommentToObject:(GBModelBase *)object; @@ -414,9 +415,66 @@ @implementation GBObjectiveCParser (CommonParsing) - (BOOL)matchNextObject { if ([self matchObjectDefinition]) return YES; if ([self matchObjectDeclaration]) return YES; + if ([self matchTypedefEnumDefinition]) return YES; return NO; } +- (BOOL)matchTypedefEnumDefinition { + BOOL isTypeDef = [[self.tokenizer currentToken] matches:@"typedef"]; + BOOL isTypeDefEnum = [[self.tokenizer lookahead:1] matches:@"enum"]; + + if(isTypeDef && isTypeDefEnum) + { + NSMutableArray *constants = [[NSMutableArray alloc] init]; + + //TODO: remember the current comments, we need them later. + __block GBComment *typeDefComment; + __block GBComment *sectionComment; + __block NSString *sectionName; + [self updateLastComment:&typeDefComment sectionComment:§ionComment sectionName:§ionName]; + + GBSourceInfo *startInfo = [tokenizer sourceInfoForCurrentToken]; + + [self.tokenizer consume:2]; + [self.tokenizer consumeFrom:@"{" to:@"}" usingBlock:^(PKToken *token, BOOL *consume, BOOL *stop) { + + if([token matches:@","]) + { + //skip + } + else + { + GBEnumConstantData *newConstant = [GBEnumConstantData constantWithName:[token stringValue]]; + [constants addObject:newConstant]; + + [self registerLastCommentToObject:newConstant]; + } + }]; + + NSString *typedefName = [[self.tokenizer currentToken] stringValue]; + [self.tokenizer consume:1]; // consume typedef name; + + GBLogVerbose(@"Matched %@ typedef enum definition at line %lu.", typedefName, startInfo.lineNumber); + + GBTypedefEnumData *newEnum = [GBTypedefEnumData typedefEnumWithName:typedefName]; + newEnum.includeInOutput = self.includeInOutput; + [self registerSourceInfoFromCurrentTokenToObject:newEnum]; + [self registerComment:typeDefComment toObject:newEnum]; + + for(GBEnumConstantData *constant in constants) + { + [newEnum.constants registerConstant:constant]; + } + + //consume ; + [self.tokenizer consume:1]; + + [self.store registerTypedefEnum:newEnum]; + return YES; + } + return NO; +} + - (BOOL)matchObjectDefinition { // Get data needed for distinguishing between class, category and extension definition. BOOL isInterface = [[self.tokenizer currentToken] matches:@"@interface"]; diff --git a/appledoc.xcodeproj/project.pbxproj b/appledoc.xcodeproj/project.pbxproj index 588a93e8..b8c1843f 100644 --- a/appledoc.xcodeproj/project.pbxproj +++ b/appledoc.xcodeproj/project.pbxproj @@ -230,6 +230,9 @@ B4D1FFE615FF5F05009736E2 /* DDXcodeProjectFile.m in Sources */ = {isa = PBXBuildFile; fileRef = B4D1FFD415FF5F05009736E2 /* DDXcodeProjectFile.m */; }; B4D1FFF315FF633F009736E2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B4D1FFF215FF633F009736E2 /* libz.dylib */; }; B4D1FFF415FF634F009736E2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B4D1FFF215FF633F009736E2 /* libz.dylib */; }; + D4B844EC17A121040012C1DC /* GBTypedefEnumData.m in Sources */ = {isa = PBXBuildFile; fileRef = D4B844EB17A121030012C1DC /* GBTypedefEnumData.m */; }; + D4B844EF17A122670012C1DC /* GBEnumConstantData.m in Sources */ = {isa = PBXBuildFile; fileRef = D4B844EE17A122650012C1DC /* GBEnumConstantData.m */; }; + D4B844F217A122A60012C1DC /* GBEnumConstantProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = D4B844F117A122A50012C1DC /* GBEnumConstantProvider.m */; }; D818BAC0152039DC00B26451 /* GHUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 733EA0F1122BDC5B0060CBDE /* GHUnit.framework */; }; D818BACE15203AA700B26451 /* GHUnit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 733EA0F1122BDC5B0060CBDE /* GHUnit.framework */; }; D818BACF15203AA700B26451 /* OCMock.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 73FC6EDF11FCE01E00AAD0B9 /* OCMock.framework */; }; @@ -550,6 +553,12 @@ B4D1FFD415FF5F05009736E2 /* DDXcodeProjectFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDXcodeProjectFile.m; sourceTree = ""; }; B4D1FFF215FF633F009736E2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; B4D1FFF615FF643D009736E2 /* install-appledoc.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "install-appledoc.sh"; sourceTree = ""; }; + D4B844EA17A121000012C1DC /* GBTypedefEnumData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBTypedefEnumData.h; sourceTree = ""; }; + D4B844EB17A121030012C1DC /* GBTypedefEnumData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GBTypedefEnumData.m; sourceTree = ""; }; + D4B844ED17A122640012C1DC /* GBEnumConstantData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBEnumConstantData.h; sourceTree = ""; }; + D4B844EE17A122650012C1DC /* GBEnumConstantData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GBEnumConstantData.m; sourceTree = ""; }; + D4B844F017A122A40012C1DC /* GBEnumConstantProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBEnumConstantProvider.h; sourceTree = ""; }; + D4B844F117A122A50012C1DC /* GBEnumConstantProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GBEnumConstantProvider.m; sourceTree = ""; }; F59056EC16C1C6DC00391620 /* publish */ = {isa = PBXFileReference; lastKnownFileType = folder; path = publish; sourceTree = ""; }; /* End PBXFileReference section */ @@ -921,6 +930,10 @@ 73FC742C11FE274300AAD0B9 /* GBMethodArgument.m */, 735B237F1304024600704844 /* GBDocumentData.h */, 735B23801304024600704844 /* GBDocumentData.m */, + D4B844EA17A121000012C1DC /* GBTypedefEnumData.h */, + D4B844EB17A121030012C1DC /* GBTypedefEnumData.m */, + D4B844ED17A122640012C1DC /* GBEnumConstantData.h */, + D4B844EE17A122650012C1DC /* GBEnumConstantData.m */, ); name = Store; sourceTree = ""; @@ -1123,6 +1136,8 @@ 736B2BF5124BCBB6009145B1 /* GBSourceInfo.m */, 7307B318124A1C2E007EC6B8 /* GBMethodSectionData.h */, 7307B319124A1C2E007EC6B8 /* GBMethodSectionData.m */, + D4B844F017A122A40012C1DC /* GBEnumConstantProvider.h */, + D4B844F117A122A50012C1DC /* GBEnumConstantProvider.m */, ); name = Helpers; sourceTree = ""; @@ -1516,6 +1531,9 @@ B4D1FFE115FF5F05009736E2 /* DDZipWriter.m in Sources */, B4D1FFE315FF5F05009736E2 /* DDEmbeddedDataReader.m in Sources */, B4D1FFE515FF5F05009736E2 /* DDXcodeProjectFile.m in Sources */, + D4B844EC17A121040012C1DC /* GBTypedefEnumData.m in Sources */, + D4B844EF17A122670012C1DC /* GBEnumConstantData.m in Sources */, + D4B844F217A122A60012C1DC /* GBEnumConstantProvider.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };