Permalink
Browse files

Added support for availability comment.

Using @since or @available comment in a method description will generate a new section in the method doc. called "Availability". The content of that section will be the text following the @since or @available tag.
  • Loading branch information...
1 parent e379f33 commit a50bb8e506831ac53d6a8c5e82f3b7339c00ea91 @zittix zittix committed Jul 11, 2011
@@ -74,6 +74,7 @@ - (NSDictionary *)objectMethods {
[result setObject:@"Properties" forKey:@"propertiesTitle"];
[result setObject:@"Parameters" forKey:@"parametersTitle"];
[result setObject:@"Return Value" forKey:@"resultTitle"];
+ [result setObject:@"Availability" forKey:@"availability"];
[result setObject:@"Discussion" forKey:@"discussionTitle"];
[result setObject:@"Exceptions" forKey:@"exceptionsTitle"];
[result setObject:@"See Also" forKey:@"seeAlsoTitle"];
@@ -70,6 +70,9 @@
/** Returns the regex used for matching cross reference directive with capture 1 containing directive, capture 3 link. */
@property (readonly) NSString *relatedSymbolRegex;
+/** Returns the regex used for matching cross reference directive with capture 1 containing directive, capture 2 description text. */
+@property (readonly) NSString *availabilityRegex;
+
///---------------------------------------------------------------------------------------
/// @name Markdown specific definitions
///---------------------------------------------------------------------------------------
@@ -74,6 +74,10 @@ - (NSString *)relatedSymbolRegex {
GBRETURN_ON_DEMAND([self descriptionCaptureRegexForKeyword:@"(?:sa|see)"]);
}
+- (NSString *)availabilityRegex {
+ GBRETURN_ON_DEMAND([self descriptionCaptureRegexForKeyword:@"(?:available|since)"]);
+}
+
#pragma mark Markdown detection
- (NSString *)markdownInlineLinkRegex {
@@ -293,6 +293,10 @@ - (void)addTokensXmlModelObjectDataForObject:(GBModelBase *)object toData:(NSMut
NSDictionary *resultData = [NSDictionary dictionaryWithObject:method.comment.methodResult forKey:@"abstract"];
[data setObject:resultData forKey:@"returnValue"];
}
+ if (method.comment.hasAvailability) {
+ NSDictionary *resultData = [NSDictionary dictionaryWithObject:method.comment.availability forKey:@"abstract"];
+ [data setObject:resultData forKey:@"availability"];
+ }
}
}
}
View
@@ -21,6 +21,7 @@
- `methodParameters`: The list of all method parameters. Only used for methods.
- `methodResult`: Description of method result. Only used for methods.
- `methodExceptions`: The list of all possible exceptions. Only used for methods.
+ - `availability`: A text representing the version at which this method / property is available. Can also be applied to other entities
- `relatedItems`: The list of all related items. Used for cross referencing other entities.
All lists must be provided in the desired order of output - i.e. output formatters don't apply any sorting, they simply emit the values in the given order.
@@ -105,6 +106,11 @@
*/
@property (retain) GBCommentComponentsList *methodResult;
+/** Entity availability description.
+
+ */
+@property (retain) GBCommentComponentsList *availability;
+
///---------------------------------------------------------------------------------------
/// @name Output generator helpers
///---------------------------------------------------------------------------------------
@@ -171,6 +177,12 @@
*/
@property (readonly) BOOL hasMethodResult;
+/** Specifies whether the `availability` contains at least one object or not.
+
+ @see availability
+ */
+@property (readonly) BOOL hasAvailability;
+
/** Specifies whether the `relatedItems` contains at least one object or not.
*/
@property (readonly) BOOL hasRelatedItems;
View
@@ -32,6 +32,7 @@ - (id)init {
self.methodParameters = [NSMutableArray array];
self.methodExceptions = [NSMutableArray array];
self.methodResult = [GBCommentComponentsList componentsList];
+ self.availability = [GBCommentComponentsList componentsList];
}
return self;
}
@@ -72,6 +73,10 @@ - (BOOL)hasRelatedItems {
return [self.relatedItems.components count] > 0;
}
+- (BOOL)hasAvailability {
+ return [self.availability.components count] > 0;
+}
+
- (BOOL)isCopied {
return (self.originalContext != nil);
}
@@ -88,5 +93,6 @@ - (BOOL)isCopied {
@synthesize methodParameters;
@synthesize methodExceptions;
@synthesize methodResult;
+@synthesize availability;
@end
@@ -69,6 +69,7 @@ - (BOOL)processParamBlockInString:(NSString *)string lines:(NSArray *)lines bloc
- (BOOL)processExceptionBlockInString:(NSString *)string lines:(NSArray *)lines blockRange:(NSRange)blockRange shortRange:(NSRange)shortRange;
- (BOOL)processReturnBlockInString:(NSString *)string lines:(NSArray *)lines blockRange:(NSRange)blockRange shortRange:(NSRange)shortRange;
- (BOOL)processRelatedBlockInString:(NSString *)string lines:(NSArray *)lines blockRange:(NSRange)blockRange shortRange:(NSRange)shortRange;
+- (BOOL)processAvailabilityBlockInString:(NSString *)string lines:(NSArray *)lines blockRange:(NSRange)blockRange shortRange:(NSRange)shortRange;
- (BOOL)isLineMatchingDirectiveStatement:(NSString *)string;
- (GBCommentComponent *)commentComponentByPreprocessingString:(NSString *)string withFlags:(GBProcessingFlag)flags;
@@ -195,7 +196,10 @@ - (void)processCommentBlockInLines:(NSArray *)lines blockRange:(NSRange)blockRan
if ([self processParamBlockInString:string lines:lines blockRange:blockRange shortRange:shortRange]) return;
if ([self processExceptionBlockInString:string lines:lines blockRange:blockRange shortRange:shortRange]) return;
if ([self processReturnBlockInString:string lines:lines blockRange:blockRange shortRange:shortRange]) return;
+ if ([self processAvailabilityBlockInString:string lines:lines blockRange:blockRange shortRange:shortRange]) return;
if ([self processRelatedBlockInString:string lines:lines blockRange:blockRange shortRange:shortRange]) return;
+
+
GBLogXWarn(self.currentSourceInfo, @"Unknown directive block %@ encountered at %@, processing as standard text!", [[lines firstObject] normalizedDescription], self.currentSourceInfo);
}
@@ -332,6 +336,22 @@ - (BOOL)processExceptionBlockInString:(NSString *)string lines:(NSArray *)lines
return YES;
}
+- (BOOL)processAvailabilityBlockInString:(NSString *)string lines:(NSArray *)lines blockRange:(NSRange)blockRange shortRange:(NSRange)shortRange {
+ NSArray *components = [string captureComponentsMatchedByRegex:self.components.availabilityRegex];
+ if ([components count] == 0) return NO;
+
+ // Get data from captures. Index 1 is directive, index 2 description text.
+ NSString *description = [components objectAtIndex:2];
+ NSString *prefix = [string substringToIndex:[string rangeOfString:description].location];
+ GBLogDebug(@"- Registering availability description %@ at %@...", [description normalizedDescription], self.currentSourceInfo);
+ [self reserveShortDescriptionFromLines:lines range:shortRange removePrefix:prefix];
+
+ // Prepare object representation from the description and register the result to the comment.
+ GBCommentComponent *component = [self commentComponentByPreprocessingString:description withFlags:0];
+ [self.currentComment.availability registerComponent:component];
+ return YES;
+}
+
- (BOOL)processReturnBlockInString:(NSString *)string lines:(NSArray *)lines blockRange:(NSRange)blockRange shortRange:(NSRange)shortRange {
NSArray *components = [string captureComponentsMatchedByRegex:self.components.returnDescriptionRegex];
if ([components count] == 0) return NO;
@@ -379,6 +399,7 @@ - (BOOL)isLineMatchingDirectiveStatement:(NSString *)string {
if ([string isMatchedByRegex:self.components.parameterDescriptionRegex]) return YES;
if ([string isMatchedByRegex:self.components.exceptionDescriptionRegex]) return YES;
if ([string isMatchedByRegex:self.components.returnDescriptionRegex]) return YES;
+ if ([string isMatchedByRegex:self.components.availabilityRegex]) return YES;
if ([string isMatchedByRegex:self.components.relatedSymbolRegex]) return YES;
return NO;
}
@@ -238,6 +238,13 @@ <h4 class="method-subtitle parameter-title">{{strings/objectMethods/resultTitle}
</div>
{{/hasMethodResult}}
+ {{#hasAvailability}}
+ <div class="method-subsection availability">
+ <h4 class="method-subtitle parameter-title">{{strings/objectMethods/availability}}</h4>
+ {{#availability}}{{>GBCommentComponentsList}}{{/availability}}
+ </div>
+ {{/hasAvailability}}
+
{{#hasLongDescription}}
<div class="method-subsection discussion-section">
<h4 class="method-subtitle">{{strings/objectMethods/discussionTitle}}</h4>
@@ -25,6 +25,7 @@ - (void)testInit_shouldSetupDefaultComponents {
assertThat(comment.methodParameters, isNot(nil));
assertThat(comment.methodExceptions, isNot(nil));
assertThat(comment.methodResult, isNot(nil));
+ assertThat(comment.availability, isNot(nil));
}
#pragma mark Comment components testing
@@ -196,7 +196,8 @@ - (void)testProcessCommentWithContextStore_descriptions_shouldAssignSettingsToAl
@"@param name Desc\n"
@"@exception name Desc\n"
@"@return Desc"
- @"@see Class"];
+ @"@see Class"
+ @"@since Version 1.0"];
// execute
[processor processComment:comment withContext:nil store:store];
// verify
@@ -226,6 +227,10 @@ - (void)testProcessCommentWithContextStore_descriptions_shouldAssignSettingsToAl
assertThat(c.settings, is(settings));
assertThat(c.sourceInfo, isNot(nil));
}
+ for (GBCommentComponent *c in comment.availability.components) {
+ assertThat(c.settings, is(settings));
+ assertThat(c.sourceInfo, isNot(nil));
+ }
}
#pragma mark Method data testing
@@ -283,6 +288,20 @@ - (void)testProcessCommentWithContextStore_methods_shouldRegisterResultDescripti
[self assertCommentComponents:comment2.methodResult matchesStringValues:@"Description1\nLine2\n\nParagraph2", nil];
}
+- (void)testProcessCommentWithContextStore_methods_shouldRegisterAvailabilityDescriptionProperly {
+ // setup
+ GBStore *store = [GBTestObjectsRegistry store];
+ GBCommentsProcessor *processor = [GBCommentsProcessor processorWithSettingsProvider:[GBTestObjectsRegistry realSettingsProvider]];
+ GBComment *comment1 = [GBComment commentWithStringValue:@"@since Description"];
+ GBComment *comment2 = [GBComment commentWithStringValue:@"@available Description1\nLine2\n\nParagraph2"];
+ // execute
+ [processor processComment:comment1 withContext:nil store:store];
+ [processor processComment:comment2 withContext:nil store:store];
+ // verify - we only use parameter description if there is nothing else found in the comment.
+ [self assertCommentComponents:comment1.availability matchesStringValues:@"Description", nil];
+ [self assertCommentComponents:comment2.availability matchesStringValues:@"Description1\nLine2\n\nParagraph2", nil];
+}
+
#pragma mark Common directives testing
- (void)testProcessCommentWithContextStore_directives_shouldRegisterRelatedItemsForKnownTopLevelObjects {
@@ -371,7 +390,8 @@ - (void)testProcessCommentWithContextStore_combinations_shouldRegisterMethodDesc
@"@exception exc Exception\n"
@"@param name2 Description2\n"
@"@return Return\n"
- @"@param name3 Description3\n"];
+ @"@param name3 Description3\n"
+ @"@since Version 1.0\n"];
// execute
[processor processComment:comment withContext:nil store:store];
// verify - we only use parameter description if there is nothing else found in the comment.
@@ -381,6 +401,7 @@ - (void)testProcessCommentWithContextStore_combinations_shouldRegisterMethodDesc
@"name3", @"Description3", GBEND, nil];
[self assertMethodArguments:comment.methodExceptions matches:@"exc", @"Exception", GBEND, nil];
[self assertCommentComponents:comment.methodResult matchesStringValues:@"Return", nil];
+ [self assertCommentComponents:comment.availability matchesStringValues:@"Version 1.0", nil];
}
- (void)testProcessCommentWithContextStore_combinations_shouldRegisterWarningAfterMethodBlockAsMainDescription {
@@ -390,17 +411,21 @@ - (void)testProcessCommentWithContextStore_combinations_shouldRegisterWarningAft
GBComment *comment1 = [GBComment commentWithStringValue:@"@param name Description\n@warning Warning"];
GBComment *comment2 = [GBComment commentWithStringValue:@"@exception name Description\n@warning Warning"];
GBComment *comment3 = [GBComment commentWithStringValue:@"@return Description\n@warning Warning"];
+ GBComment *comment4 = [GBComment commentWithStringValue:@"@since Description\n@warning Warning"];
// execute
[processor processComment:comment1 withContext:nil store:store];
[processor processComment:comment2 withContext:nil store:store];
[processor processComment:comment3 withContext:nil store:store];
+ [processor processComment:comment4 withContext:nil store:store];
// verify - we only use parameter description if there is nothing else found in the comment.
[self assertMethodArguments:comment1.methodParameters matches:@"name", @"Description", GBEND, nil];
[self assertMethodArguments:comment2.methodExceptions matches:@"name", @"Description", GBEND, nil];
[self assertCommentComponents:comment3.methodResult matchesStringValues:@"Description", nil];
+ [self assertCommentComponents:comment4.availability matchesStringValues:@"Description", nil];
[self assertComment:comment1 matchesShortDesc:@"Warning" longDesc:@"@warning Warning", nil];
[self assertComment:comment2 matchesShortDesc:@"Warning" longDesc:@"@warning Warning", nil];
[self assertComment:comment3 matchesShortDesc:@"Warning" longDesc:@"@warning Warning", nil];
+ [self assertComment:comment4 matchesShortDesc:@"Warning" longDesc:@"@warning Warning", nil];
}
#pragma mark Miscellaneous handling

0 comments on commit a50bb8e

Please sign in to comment.