Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implemented `--search-comments` cmd line switch for enabling or disab…

…ling searching for missing comments.
  • Loading branch information...
commit 91d6dc3351b5ceeaea73921f28575ab2bd09c16e 1 parent 661fa8e
tomaz authored
12 AppledocTests/Common/SettingsTests.mm
View
@@ -62,8 +62,10 @@ static void runWithSettings(void(^handler)(GBSettings *settings)) {
it(@"should work for comment related settings", ^{
runWithSettings(^(GBSettings *settings) {
// execute
+ [settings setBool:YES forKey:GBOptions.searchMissingComments];
[settings setObject:@"crossrefs" forKey:GBOptions.crossRefsFormat];
// verify
+ settings.searchForMissingComments should equal(YES);
settings.crossRefsFormat should equal(@"crossrefs");
});
});
@@ -73,19 +75,9 @@ static void runWithSettings(void(^handler)(GBSettings *settings)) {
// execute
[settings setInteger:2 forKey:GBOptions.loggingFormat];
[settings setInteger:3 forKey:GBOptions.loggingLevel];
- [settings setBool:YES forKey:GBOptions.loggingInternalEnabled];
- [settings setBool:YES forKey:GBOptions.loggingCommonEnabled];
- [settings setBool:YES forKey:GBOptions.loggingStoreEnabled];
- [settings setBool:YES forKey:GBOptions.loggingParsingEnabled];
- [settings setBool:YES forKey:GBOptions.loggingProcessingEnabled];
// verify
settings.loggingFormat should equal(2);
settings.loggingLevel should equal(3);
- settings.loggingInternalEnabled should equal(YES);
- settings.loggingCommonEnabled should equal(YES);
- settings.loggingStoreEnabled should equal(YES);
- settings.loggingParsingEnabled should equal(YES);
- settings.loggingProcessingEnabled should equal(YES);
});
});
281 AppledocTests/Processing/FetchDocumentationTaskTests.mm
View
@@ -14,130 +14,253 @@
#pragma mark -
-static void runWithTask(void(^handler)(FetchDocumentationTask *task, id store)) {
+static void runWithTask(id store, id settings, void(^handler)(FetchDocumentationTask *task, id store, id settings)) {
FetchDocumentationTask *task = [[FetchDocumentationTask alloc] init];
- task.store = mock([Store class]);
- handler(task, task.store);
+ task.settings = settings ? settings : mock([GBSettings class]);
+ task.store = store ? store : mock([Store class]);
+ handler(task, task.store, task.settings);
[task release];
}
+static void runWithTask(void(^handler)(FetchDocumentationTask *task, id store, id settings)) {
+ runWithTask(nil, nil, handler);
+}
+
+static id createBaseClass() {
+ return [StoreMocks mockClass:@"BaseClass" block:^(id object) { }];
+}
+
+static id createDerivedClass(id baseClass) {
+ return [StoreMocks mockClass:@"DerivedClass" block:^(id object) {
+ [StoreMocks add:object asDerivedClassFrom:baseClass];
+ }];
+}
+
+static id createAdoptedProtocol(NSString *name, id adoptedInObject) {
+ return [StoreMocks mockProtocol:name block:^(id object) {
+ [StoreMocks add:adoptedInObject asAdopting:object];
+ }];
+}
+
+static id createMethod(NSString *selector, id parent) {
+ BOOL isClassMethod = [selector hasPrefix:@"+"];
+ return [StoreMocks createMethod:selector block:^(MethodInfo *object) {
+ if (isClassMethod)
+ [StoreMocks add:object asClassMethodOf:parent];
+ else
+ [StoreMocks add:object asInstanceMethodOf:parent];
+ }];
+}
+
+static id createCommentedMethod(NSString *selector, id parent) {
+ id result = createMethod(selector, parent);
+ [StoreMocks addMockCommentTo:result];
+ return result;
+}
+
+static id createProperty(NSString *name, id parent) {
+ return [StoreMocks createProperty:name block:^(PropertyInfo *object) {
+ [StoreMocks add:object asPropertyOf:parent];
+ }];
+}
+
+static id createCommentedProperty(NSString *name, id parent) {
+ id result = createProperty(name, parent);
+ [StoreMocks addMockCommentTo:result];
+ return result;
+}
+
+#define GBSearch [info[@"search"] boolValue]
+#define GBVerify(d,b) if (GBSearch) d.comment should equal(b.comment); else d.comment should be_nil()
+
#pragma mark -
TEST_BEGIN(FetchDocumentationTaskTests)
-describe(@"adopted protocols:", ^{
+describe(@"copy documentation from super classes:", ^{
sharedExamplesFor(@"examples", ^(NSDictionary *info) {
- __block id protocol;
- __block id object;
- __block id realStore;
+ __block id settings;
beforeEach(^{
- // get objects from info dictionary
- realStore = info[@"store"];
- object = info[@"object"];
- // setup protocol and assign it to store; note that we need to append our protocol to existing ones!
- protocol = [StoreMocks mockProtocol:@"Protocol"];
- NSMutableArray *actualProtocols = [NSMutableArray arrayWithArray:[realStore storeProtocols]];
- [actualProtocols addObject:protocol];
- [given([realStore storeProtocols]) willReturn:actualProtocols];
- // adopt the protocol
- [given([object interfaceAdoptedProtocols]) willReturn:@[ [StoreMocks link:protocol] ]];
+ settings = mock([GBSettings class]);
+ [given([settings searchForMissingComments]) willReturnBool:GBSearch];
});
-
- it(@"should fetch for class methods", ^{
- runWithTask(^(FetchDocumentationTask *task, id store) {
- // setup class methods in protocol
- ObjectInfoBase *protocolClassMethod = [StoreMocks mockCommentedMethod:@"+method"];
- [given([protocol interfaceClassMethods]) willReturn:@[ protocolClassMethod ]];
- // setup class methods in object
- MethodInfo *objectClassMethod = [StoreMocks createMethod:@"+method"];
- [given([object interfaceClassMethods]) willReturn:@[ objectClassMethod ]];
- // setup task
- task.store = realStore;
+
+ it(@"should handle class method", ^{
+ runWithTask(nil, settings, ^(FetchDocumentationTask *task, id store, id settings) {
+ // setup
+ id baseClass = createBaseClass();
+ id derivedClass = createDerivedClass(baseClass);
+ MethodInfo *baseMethod = createCommentedMethod(@"+method", baseClass);
+ MethodInfo *derivedMethod = createMethod(@"+method", derivedClass);
+ [given([store storeClasses]) willReturn:@[ baseClass, derivedClass ]];
// execute
[task runTask];
// verify
- objectClassMethod.comment should equal(protocolClassMethod.comment);
+ GBVerify(derivedMethod, baseMethod);
});
});
- it(@"should fetch for instance methods", ^{
- runWithTask(^(FetchDocumentationTask *task, id store) {
- // setup instance methods in protocol
- ObjectInfoBase *protocolInstanceMethod = [StoreMocks mockCommentedMethod:@"+method"];
- [given([protocol interfaceInstanceMethods]) willReturn:@[ protocolInstanceMethod ]];
- // setup instance methods in object
- MethodInfo *objectInstanceMethod = [StoreMocks createMethod:@"+method"];
- [given([object interfaceInstanceMethods]) willReturn:@[ objectInstanceMethod ]];
- // setup task
- task.store = realStore;
+ it(@"should handle instance method", ^{
+ runWithTask(nil, settings, ^(FetchDocumentationTask *task, id store, id settings) {
+ // setup
+ id baseClass = createBaseClass();
+ id derivedClass = createDerivedClass(baseClass);
+ MethodInfo *baseMethod = createCommentedMethod(@"-method", baseClass);
+ MethodInfo *derivedMethod = createMethod(@"-method", derivedClass);
+ [given([store storeClasses]) willReturn:@[ baseClass, derivedClass ]];
// execute
[task runTask];
// verify
- objectInstanceMethod.comment should equal(protocolInstanceMethod.comment);
+ GBVerify(derivedMethod, baseMethod);
});
});
-
- it(@"should fetch for properties", ^{
- runWithTask(^(FetchDocumentationTask *task, id store) {
- // setup properties in protocol
- ObjectInfoBase *protocolProperty = [StoreMocks mockCommentedProperty:@"property"];
- [given([protocol interfaceProperties]) willReturn:@[ protocolProperty ]];
- // setup properties in object
- PropertyInfo *objectProperty = [StoreMocks createProperty:@"property"];
- [given([object interfaceProperties]) willReturn:@[ objectProperty ]];
- // setup task
- task.store = realStore;
+
+ it(@"should copy property from base class", ^{
+ runWithTask(nil, settings, ^(FetchDocumentationTask *task, id store, id settings) {
+ // setup
+ id baseClass = createBaseClass();
+ id derivedClass = createDerivedClass(baseClass);
+ PropertyInfo *baseProperty = createCommentedProperty(@"property", baseClass);
+ PropertyInfo *derivedProperty = createProperty(@"property", derivedClass);
+ [given([store storeClasses]) willReturn:@[ baseClass, derivedClass ]];
// execute
[task runTask];
// verify
- objectProperty.comment should equal(protocolProperty.comment);
+ GBVerify(derivedProperty, baseProperty);
});
});
});
- describe(@"classes:", ^{
+ describe(@"search enabled:", ^{
beforeEach(^{
- id store = mock([Store class]);
- id object = mock([ClassInfo class]);
- [given([store storeClasses]) willReturn:@[ object ]];
- [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
- [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
+ [[SpecHelper specHelper] sharedExampleContext][@"search"] = @(YES);
});
itShouldBehaveLike(@"examples");
});
- describe(@"extensions:", ^{
+ describe(@"search disabled:", ^{
beforeEach(^{
- id store = mock([Store class]);
- id object = mock([CategoryInfo class]);
- [given([store storeExtensions]) willReturn:@[ object ]];
- [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
- [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
+ [[SpecHelper specHelper] sharedExampleContext][@"search"] = @(NO);
});
itShouldBehaveLike(@"examples");
});
-
- describe(@"categories:", ^{
+});
+
+describe(@"adopted protocols:", ^{
+ // This block describes actual unit tests.
+ sharedExamplesFor(@"examples", ^(NSDictionary *info) {
+ __block id store;
+ __block id settings;
+
beforeEach(^{
- id store = mock([Store class]);
- id object = mock([CategoryInfo class]);
- [given([store storeCategories]) willReturn:@[ object ]];
- [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
- [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
+ store = info[@"store"];
+ settings = mock([GBSettings class]);
+ [given([settings searchForMissingComments]) willReturnBool:GBSearch];
+ });
+
+ it(@"should fetch for class methods", ^{
+ runWithTask(store, settings, ^(FetchDocumentationTask *task, id store, id settings) {
+ // setup
+ id object = info[@"object"];
+ id protocol = createAdoptedProtocol(@"Protocol", object);
+ MethodInfo *objectClassMethod = createMethod(@"+method", object);
+ ObjectInfoBase *protocolClassMethod = createCommentedMethod(@"+method", protocol);
+ // execute
+ [task runTask];
+ // verify
+ GBVerify(objectClassMethod, protocolClassMethod);
+ });
+ });
+
+ it(@"should fetch for instance methods", ^{
+ runWithTask(store, settings, ^(FetchDocumentationTask *task, id store, id settings) {
+ // setup
+ id object = info[@"object"];
+ id protocol = createAdoptedProtocol(@"Protocol", object);
+ MethodInfo *objectInstanceMethod = createMethod(@"-method", object);
+ ObjectInfoBase *protocolInstanceMethod = createCommentedMethod(@"-method", protocol);
+ // execute
+ [task runTask];
+ // verify
+ GBVerify(objectInstanceMethod, protocolInstanceMethod);
+ });
+ });
+
+ it(@"should fetch for properties", ^{
+ runWithTask(store, settings, ^(FetchDocumentationTask *task, id store, id settings) {
+ // setup
+ id object = info[@"object"];
+ id protocol = createAdoptedProtocol(@"Protocol", object);
+ PropertyInfo *objectProperty = createProperty(@"property", object);
+ ObjectInfoBase *protocolProperty = createCommentedProperty(@"property", protocol);
+ // execute
+ [task runTask];
+ // verify
+ GBVerify(objectProperty, protocolProperty);
+ });
});
- itShouldBehaveLike(@"examples");
});
- describe(@"protocols:", ^{
+ // This block described variants for above tests (repeats the tests for different types of objects).
+ sharedExamplesFor(@"variants", ^(NSDictionary *info) {
+ describe(@"classes:", ^{
+ beforeEach(^{
+ id store = mock([Store class]);
+ id object = mock([ClassInfo class]);
+ [given([store storeClasses]) willReturn:@[ object ]];
+ [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
+ [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
+ });
+ itShouldBehaveLike(@"examples");
+ });
+
+ describe(@"extensions:", ^{
+ beforeEach(^{
+ id store = mock([Store class]);
+ id object = mock([CategoryInfo class]);
+ [given([store storeExtensions]) willReturn:@[ object ]];
+ [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
+ [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
+ });
+ itShouldBehaveLike(@"examples");
+ });
+
+ describe(@"categories:", ^{
+ beforeEach(^{
+ id store = mock([Store class]);
+ id object = mock([CategoryInfo class]);
+ [given([store storeCategories]) willReturn:@[ object ]];
+ [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
+ [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
+ });
+ itShouldBehaveLike(@"examples");
+ });
+
+ describe(@"protocols:", ^{
+ beforeEach(^{
+ id store = mock([Store class]);
+ id object = mock([ProtocolInfo class]);
+ [given([store storeProtocols]) willReturn:@[ object ]];
+ [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
+ [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
+ });
+ itShouldBehaveLike(@"examples");
+ });
+ });
+
+ // These two blocks repeat all the variants, for all the examples, for search enabled or disabled.
+ describe(@"search enabled:", ^{
beforeEach(^{
- id store = mock([Store class]);
- id object = mock([ProtocolInfo class]);
- [given([store storeProtocols]) willReturn:@[ object ]];
- [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
- [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
+ [[SpecHelper specHelper] sharedExampleContext][@"search"] = @(YES);
});
- itShouldBehaveLike(@"examples");
+ itShouldBehaveLike(@"variants");
+ });
+ describe(@"search disabled:", ^{
+ beforeEach(^{
+ [[SpecHelper specHelper] sharedExampleContext][@"search"] = @(NO);
+ });
+ itShouldBehaveLike(@"variants");
});
});
3  AppledocTests/TestingBase/StoreMocks.h
View
@@ -33,7 +33,8 @@ typedef void(^GBCreateObjectBlock)(id object);
+ (id)mockProperty:(NSString *)uniqueID block:(GBCreateObjectBlock)handler;
+ (void)addMockCommentTo:(id)objectOrMock;
-+ (void)add:(id)classOrMock asBaseClassOf:(id)baseOrMock;
++ (void)add:(id)classOrMock asDerivedClassFrom:(id)baseOrMock;
++ (void)add:(id)objectOrMock asAdopting:(id)protocolOrMock;
+ (void)add:(id)methodOrMock asClassMethodOf:(id)interfaceOrMock;
+ (void)add:(id)methodOrMock asInstanceMethodOf:(id)interfaceOrMock;
+ (void)add:(id)propertyOrMock asPropertyOf:(id)interfaceOrMock;
12 AppledocTests/TestingBase/StoreMocks.m
View
@@ -141,14 +141,22 @@ + (void)addMockCommentTo:(id)objectOrMock {
[objectOrMock setComment:comment];
}
-+ (void)add:(id)classOrMock asBaseClassOf:(id)baseOrMock {
- ObjectLinkInfo *link = [StoreMocks link:baseOrMock];
++ (void)add:(id)classOrMock asDerivedClassFrom:(id)baseOrMock {
+ ObjectLinkInfo *link = [self link:baseOrMock];
if ([self isMock:classOrMock])
[given([classOrMock classSuperClass]) willReturn:link];
else
[classOrMock setClassSuperClass:link];
}
++ (void)add:(id)objectOrMock asAdopting:(id)protocolOrMock {
+ ObjectLinkInfo *link = [self link:protocolOrMock];
+ if ([self isMock:objectOrMock])
+ [given([objectOrMock interfaceAdoptedProtocols]) willReturn:@[ link ]];
+ else
+ [[objectOrMock interfaceAdoptedProtocols] addObject:link];
+}
+
+ (void)add:(id)methodOrMock asClassMethodOf:(id)interfaceOrMock {
if ([self isMock:interfaceOrMock])
[given([interfaceOrMock interfaceClassMethods]) willReturn:@[ methodOrMock ]];
12 appledoc/Common/GBSettings+Appledoc.h
View
@@ -37,6 +37,7 @@
#pragma mark - Comments
+@property (nonatomic, assign) BOOL searchForMissingComments;
@property (nonatomic, copy) NSString *crossRefsFormat;
#pragma mark - Debugging aid
@@ -47,11 +48,6 @@
@property (nonatomic, assign) NSUInteger loggingLevel;
@property (nonatomic, assign) NSUInteger loggingFormat;
-@property (nonatomic, assign) BOOL loggingInternalEnabled;
-@property (nonatomic, assign) BOOL loggingCommonEnabled;
-@property (nonatomic, assign) BOOL loggingStoreEnabled;
-@property (nonatomic, assign) BOOL loggingParsingEnabled;
-@property (nonatomic, assign) BOOL loggingProcessingEnabled;
@end
@@ -67,6 +63,7 @@ extern const struct GBOptions {
__unsafe_unretained NSString *ignoredPaths;
__unsafe_unretained NSString *templatesPath;
+ __unsafe_unretained NSString *searchMissingComments;
__unsafe_unretained NSString *crossRefsFormat;
__unsafe_unretained NSString *printSettings;
@@ -75,9 +72,4 @@ extern const struct GBOptions {
__unsafe_unretained NSString *loggingLevel;
__unsafe_unretained NSString *loggingFormat;
- __unsafe_unretained NSString *loggingInternalEnabled;
- __unsafe_unretained NSString *loggingCommonEnabled;
- __unsafe_unretained NSString *loggingStoreEnabled;
- __unsafe_unretained NSString *loggingParsingEnabled;
- __unsafe_unretained NSString *loggingProcessingEnabled;
} GBOptions;
12 appledoc/Common/GBSettings+Appledoc.m
View
@@ -36,6 +36,7 @@ + (id)appledocSettingsWithName:(NSString *)name parent:(GBSettings *)parent {
#pragma mark - Comments
+GB_SYNTHESIZE_BOOL(searchForMissingComments, setSearchForMissingComments, GBOptions.searchMissingComments);
GB_SYNTHESIZE_COPY(NSString *, crossRefsFormat, setCrossRefsFormat, GBOptions.crossRefsFormat)
#pragma mark - Debugging aid
@@ -46,11 +47,6 @@ + (id)appledocSettingsWithName:(NSString *)name parent:(GBSettings *)parent {
GB_SYNTHESIZE_UINT(loggingFormat, setLoggingFormat, GBOptions.loggingFormat)
GB_SYNTHESIZE_UINT(loggingLevel, setLoggingLevel, GBOptions.loggingLevel)
-GB_SYNTHESIZE_BOOL(loggingInternalEnabled, setLoggingInternalEnabled, GBOptions.loggingInternalEnabled)
-GB_SYNTHESIZE_BOOL(loggingCommonEnabled, setLoggingCommonEnabled, GBOptions.loggingCommonEnabled)
-GB_SYNTHESIZE_BOOL(loggingStoreEnabled, setLoggingStoreEnabled, GBOptions.loggingStoreEnabled)
-GB_SYNTHESIZE_BOOL(loggingParsingEnabled, setLoggingParsingEnabled, GBOptions.loggingParsingEnabled)
-GB_SYNTHESIZE_BOOL(loggingProcessingEnabled, setLoggingProcessingEnabled, GBOptions.loggingProcessingEnabled)
@end
@@ -66,6 +62,7 @@ + (id)appledocSettingsWithName:(NSString *)name parent:(GBSettings *)parent {
.templatesPath = @"templates",
.ignoredPaths = @"ignore",
+ .searchMissingComments = @"search-comments",
.crossRefsFormat = @"crossrefs",
.printSettings = @"print-settings",
@@ -74,9 +71,4 @@ + (id)appledocSettingsWithName:(NSString *)name parent:(GBSettings *)parent {
.loggingLevel = @"verbose",
.loggingFormat = @"log-format",
- .loggingInternalEnabled = @"log-internal",
- .loggingCommonEnabled = @"log-common",
- .loggingStoreEnabled = @"log-store",
- .loggingParsingEnabled = @"log-parsing",
- .loggingProcessingEnabled = @"log-processing",
};
4 appledoc/Common/GBSettings+Helpers.m
View
@@ -28,10 +28,8 @@ @implementation GBSettings (Helpers)
- (void)applyFactoryDefaults {
self.projectVersion = @"1.0";
self.crossRefsFormat = @"plain";
+ self.searchForMissingComments = YES;
self.loggingFormat = 0;
- self.loggingCommonEnabled = YES;
- self.loggingStoreEnabled = NO;
- self.loggingParsingEnabled = NO;
}
- (BOOL)applyGlobalSettingsFromCmdLineSettings:(GBSettings *)settings {
93 appledoc/Processing/FetchDocumentationTask.m
View
@@ -15,6 +15,7 @@
@implementation FetchDocumentationTask
- (GBResult)runTask {
+ if (!self.settings.searchForMissingComments) return GBResultOk;
LogDebug(@"Fetching documentation from related objects...");
[self handleClassesFromStore:self.store];
[self handleExtensionsFromStore:self.store];
@@ -30,49 +31,51 @@ - (void)handleClassesFromStore:(Store *)store {
__weak FetchDocumentationTask *bself = self;
[store.storeClasses enumerateObjectsUsingBlock:^(ClassInfo *class, NSUInteger idx, BOOL *stop) {
LogDebug(@"Handling %@...", class);
- [bself fetchDocumentationForMembersOf:class block:^(id member) {
-
+ [bself fetchDocumentationFromAdoptedProtocolsOf:class missingBlock:^(id member) {
+ // Note that we want to log undocumented members; users may disable warnings but if they turn verbosity to debug, they should still see what's going on.
+ LogDebug(@"Documentation for %@ not found in adopted protocols, checking superclasses...", member);
+ [bself fetchDocumentationFromSuperClassesOf:class forMember:member];
}];
}];
}
- (void)handleExtensionsFromStore:(Store *)store {
LogDebug(@"Handling extensions...");
- __weak FetchDocumentationTask *bself = self;
- [store.storeExtensions enumerateObjectsUsingBlock:^(CategoryInfo *extension, NSUInteger idx, BOOL *stop) {
- LogDebug(@"Handling %@...", extension);
- [bself fetchDocumentationForMembersOf:extension block:^(id member) { }];
- }];
+ [self fetchDocumentationFromAdoptedProtocolsForInterfaces:store.storeExtensions];
}
- (void)handleCategoriesFromStore:(Store *)store {
LogDebug(@"Handling categories...");
- __weak FetchDocumentationTask *bself = self;
- [store.storeCategories enumerateObjectsUsingBlock:^(CategoryInfo *category, NSUInteger idx, BOOL *stop) {
- LogDebug(@"Handling %@...", category);
- [bself fetchDocumentationForMembersOf:category block:^(id member) { }];
- }];
+ [self fetchDocumentationFromAdoptedProtocolsForInterfaces:store.storeCategories];
}
- (void)handleProtocolsFromStore:(Store *)store {
LogDebug(@"Handling protocols...");
+ [self fetchDocumentationFromAdoptedProtocolsForInterfaces:store.storeProtocols];
+}
+
+#pragma mark - Adopted protocols handling
+
+- (void)fetchDocumentationFromAdoptedProtocolsForInterfaces:(NSArray *)interfaces {
__weak FetchDocumentationTask *bself = self;
- [store.storeProtocols enumerateObjectsUsingBlock:^(ProtocolInfo *protocol, NSUInteger idx, BOOL *stop) {
- LogDebug(@"Handling %@...", protocol);
- [bself fetchDocumentationForMembersOf:protocol block:^(id member) { }];
+ [interfaces enumerateObjectsUsingBlock:^(InterfaceInfoBase *interface, NSUInteger idx, BOOL *stop) {
+ LogDebug(@"Handling %@...", interface);
+ [bself fetchDocumentationFromAdoptedProtocolsOf:interface missingBlock:^(id member) {
+ // Similar to handleClassesFromStore: we want to always log undocumented members as debug messages...
+ LogDebug(@"Member %@ is undocumented!", member);
+ [bself reportUndocumentedMember:member];
+ }];
}];
}
-#pragma mark - Members handling
-
-- (void)fetchDocumentationForMembersOf:(InterfaceInfoBase *)interface block:(GBFetchBlock)handler {
- if (interface.interfaceAdoptedProtocols.count == 0) return;
- [self fetchDocumentationForMembersOf:interface members:@selector(interfaceClassMethods) block:handler];
- [self fetchDocumentationForMembersOf:interface members:@selector(interfaceInstanceMethods) block:handler];
- [self fetchDocumentationForMembersOf:interface members:@selector(interfaceProperties) block:handler];
+- (void)fetchDocumentationFromAdoptedProtocolsOf:(InterfaceInfoBase *)interface missingBlock:(GBFetchBlock)handler {
+ [self fetchDocumentationFromAdoptedProtocolsOf:interface members:@selector(interfaceClassMethods) missingBlock:handler];
+ [self fetchDocumentationFromAdoptedProtocolsOf:interface members:@selector(interfaceInstanceMethods) missingBlock:handler];
+ [self fetchDocumentationFromAdoptedProtocolsOf:interface members:@selector(interfaceProperties) missingBlock:handler];
}
-- (void)fetchDocumentationForMembersOf:(InterfaceInfoBase *)interface members:(SEL)selector block:(GBFetchBlock)handler {
+- (void)fetchDocumentationFromAdoptedProtocolsOf:(InterfaceInfoBase *)interface members:(SEL)selector missingBlock:(GBFetchBlock)handler {
+ __weak FetchDocumentationTask *bself = self;
NSArray *interfaceMembers = [interface performSelector:selector];
[interfaceMembers enumerateObjectsUsingBlock:^(ObjectInfoBase *member, NSUInteger idx, BOOL *stop) {
if (member.comment) return;
@@ -81,10 +84,9 @@ - (void)fetchDocumentationForMembersOf:(InterfaceInfoBase *)interface members:(S
if (!adoptedProtocol) return;
NSArray *adoptedMembers = [adoptedProtocol performSelector:selector];
[adoptedMembers enumerateObjectsUsingBlock:^(ObjectInfoBase *adoptedMember, NSUInteger j, BOOL *jstop) {
- if (![adoptedMember.uniqueObjectID isEqualToString:member.uniqueObjectID]) return;
if (!adoptedMember.comment) return;
- LogVerbose(@"Fetching documentation for %@ from %@.", [(id)member descriptionWithInterface:interface], [(id)adoptedMember descriptionWithInterface:adoptedProtocol]);
- member.comment = adoptedMember.comment;
+ if (![adoptedMember.uniqueObjectID isEqualToString:member.uniqueObjectID]) return;
+ [bself copyDocumentationFrom:adoptedMember to:member];
*jstop = YES;
*istop = YES;
}];
@@ -93,4 +95,43 @@ - (void)fetchDocumentationForMembersOf:(InterfaceInfoBase *)interface members:(S
}];
}
+#pragma mark - Super classes handling
+
+- (void)fetchDocumentationFromSuperClassesOf:(ClassInfo *)class forMember:(id)member {
+ ClassInfo *superClass = class.classSuperClass.linkToObject;
+ while (superClass) {
+ LogDebug(@"Checking super class %@...", superClass);
+ if ([self fetchDocumentationFromSuperClassMembers:superClass.interfaceClassMethods forMember:member]) break;
+ if ([self fetchDocumentationFromSuperClassMembers:superClass.interfaceInstanceMethods forMember:member]) break;
+ if ([self fetchDocumentationFromSuperClassMembers:superClass.interfaceProperties forMember:member]) break;
+ superClass = superClass.classSuperClass.linkToObject;
+ }
+ if (![member comment]) {
+ LogDebug(@"Member %@ is undocumented!", [member descriptionWithParent]);
+ [self reportUndocumentedMember:member];
+ }
+}
+
+- (BOOL)fetchDocumentationFromSuperClassMembers:(NSArray *)superMembers forMember:(ObjectInfoBase *)member {
+ __weak FetchDocumentationTask *bself = self;
+ [superMembers enumerateObjectsUsingBlock:^(ObjectInfoBase *superMember, NSUInteger idx, BOOL *stop) {
+ if (!superMember.comment) return;
+ if (![superMember.uniqueObjectID isEqualToString:member.uniqueObjectID]) return;
+ [bself copyDocumentationFrom:superMember to:member];
+ }];
+}
+
+#pragma mark - Copying documentation
+
+- (void)copyDocumentationFrom:(MemberInfoBase *)source to:(MemberInfoBase *)dest {
+ LogVerbose(@"Fetching documentation for %@ from %@.", [dest descriptionWithParent], [source descriptionWithParent]);
+ dest.comment = source.comment;
+}
+
+#pragma mark - Undocumented objects handling
+
+- (void)reportUndocumentedMember:(id)object {
+ LogWarn(@"%@ is undocumented!", [object descriptionWithParent]);
+}
+
@end
10 appledoc/main.m
View
@@ -25,20 +25,16 @@ static void registerOptionDefinitions(GBOptionsHelper *options) {
{ 0, nil, @"PATHS", GBOptionSeparator },
{ 0, GBOptions.inputPaths, @"[a] Array of input paths for global and project settings", GBValueRequired|GBOptionNoCmdLine|GBOptionInvisible },
- { 't', GBOptions.templatesPath, @"Template files path", GBValueRequired },
{ 'i', GBOptions.ignoredPaths, @"[a] Ignore given path", GBValueRequired },
+ { 't', GBOptions.templatesPath, @"Template files path", GBValueRequired },
{ 0, nil, @"COMMENTS", GBOptionSeparator },
+ { 0, GBOptions.searchMissingComments, @"[b] Search for missing comments", GBValueNone },
{ 0, GBOptions.crossRefsFormat, @"Cross references format", GBValueRequired },
{ 0, nil, @"LOGGING", GBOptionSeparator },
- { 0, GBOptions.loggingLevel, @"Log verbosity", GBValueOptional },
+ { 0, GBOptions.loggingLevel, @"Log verbosity (1-2)", GBValueOptional },
{ 0, GBOptions.loggingFormat, @"Log format (0-3)", GBValueRequired },
- { 0, GBOptions.loggingCommonEnabled, @"[b] Enable common logging", GBValueNone|GBOptionNoHelp },
- { 0, GBOptions.loggingStoreEnabled, @"[b] Enable store logging", GBValueNone|GBOptionNoHelp },
- { 0, GBOptions.loggingParsingEnabled, @"[b] Enable parser logging", GBValueNone|GBOptionNoHelp },
- { 0, GBOptions.loggingProcessingEnabled, @"[b] Enable processing logging", GBValueNone|GBOptionNoHelp },
- { 0, GBOptions.loggingInternalEnabled, @"[b] Enable internal logging", GBValueNone|GBOptionNoHelp },
{ 0, nil, @"MISCELLANEOUS", GBOptionSeparator },
{ 0, GBOptions.printSettings, @"[b] Print settings for current run", GBValueNone },
Please sign in to comment.
Something went wrong with that request. Please try again.