Skip to content

Commit

Permalink
Self references don't form links. Closes #190.
Browse files Browse the repository at this point in the history
This covers the following cases:

- Cross reference to "current" class, category or protocol.
- Cross reference to "current" method or property.
  • Loading branch information
tomaz committed Feb 25, 2012
1 parent 121333b commit 1cff516
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 3 deletions.
2 changes: 1 addition & 1 deletion AppledocTests-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>771</string>
<string>774</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion Application/GBApplicationStringsProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ - (NSDictionary *)appledocData {
result = [[NSMutableDictionary alloc] init];
[result setObject:@"appledoc" forKey:@"tool"];
[result setObject:@"2.0.5" forKey:@"version"];
[result setObject:@"771" forKey:@"build"];
[result setObject:@"774" forKey:@"build"];
[result setObject:@"http://appledoc.gentlebytes.com" forKey:@"homepage"];
}
return result;
Expand Down
14 changes: 14 additions & 0 deletions Processing/GBCommentsProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@
/// @name Processing handling
///---------------------------------------------------------------------------------------

/** Processes the comment of the given object using the given context and store.
This method processes the given comment's string value and prepares all derives values. It uses the given store for dependent values such as links and similar, so make sure the store has all possible objects already registered. In order to properly handle "local" links, the method also takes `context` parameter which identifies top-level object to which the object which's comment we're processing belongs to. You can pass `nil` however this prevents any local links being processed!
@warning **Important:** Note that this method is similar to `processComment:withContext:store:`, in fact, the only difference is that it stores the given object to internal property and then sends `processComment:withContext:store:` to receiver. The big difference is that this method prevents forming cross references to current member, while `processComment:withContext:store:` doesn't. Therefore, this is preffered method for processing comments. The only reasong for keeping two methods is due to unit tests relying on `processComment:withContext:store:` - as that was previously the entry point for processing, all unit tests use it and I don't want to update all of them. So the quick fix was to introduce another method, make sure it gets called from other parts of the tool and keep it as simple as possible.
@param comment The comment to process.
@param context The object identifying current context for handling links or `nil`.
@param store The store to process against.
@exception NSException Thrown if any of the given parameters is invalid or processing encounters unexpected error.
@see alwaysRepeatFirstParagraph
*/
- (void)processCommentForObject:(GBModelBase *)object withContext:(id)context store:(id)store;

/** Processes the given `GBComment` using the given context and store.
This method processes the given comment's string value and prepares all derives values. It uses the given store for dependent values such as links and similar, so make sure the store has all possible objects already registered. In order to properly handle "local" links, the method also takes `context` parameter which identifies top-level object to which the object which's comment we're processing belongs to. You can pass `nil` however this prevents any local links being processed!
Expand Down
29 changes: 29 additions & 0 deletions Processing/GBCommentsProcessor.m
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ - (NSString *)stringByPreprocessingString:(NSString *)string withFlags:(GBProces
- (NSString *)stringByConvertingCrossReferencesInString:(NSString *)string withFlags:(GBProcessingFlag)flags;
- (NSString *)stringByConvertingSimpleCrossReferencesInString:(NSString *)string searchRange:(NSRange)searchRange flags:(GBProcessingFlag)flags;
- (NSString *)markdownLinkWithDescription:(NSString *)description address:(NSString *)address flags:(GBProcessingFlag)flags;
- (BOOL)isCrossReference:(GBCrossRefData *)data matchingObject:(id)object;

- (GBCrossRefData)dataForClassOrProtocolLinkInString:(NSString *)string searchRange:(NSRange)searchRange flags:(GBProcessingFlag)flags;
- (GBCrossRefData)dataForCategoryLinkInString:(NSString *)string searchRange:(NSRange)searchRange flags:(GBProcessingFlag)flags;
Expand All @@ -92,6 +93,7 @@ - (NSString *)stringByConvertingLinesToBlockquoteFromString:(NSString *)string c
- (NSString *)stringByCombiningTrimmedLines:(NSArray *)lines;

@property (retain) id currentContext;
@property (retain) id currentObject;
@property (retain) GBComment *currentComment;
@property (retain) GBStore *store;
@property (retain) GBApplicationSettingsProvider *settings;
Expand Down Expand Up @@ -125,6 +127,13 @@ - (id)initWithSettingsProvider:(id)settingsProvider {

#pragma mark Processing handling

- (void)processCommentForObject:(GBModelBase *)object withContext:(id)context store:(id)aStore {
NSParameterAssert(object != nil);
self.currentObject = object;
[self processComment:object.comment withContext:context store:aStore];
self.currentObject = nil;
}

- (void)processComment:(GBComment *)comment withContext:(id)context store:(id)aStore {
NSParameterAssert(comment != nil);
NSParameterAssert(aStore != nil);
Expand Down Expand Up @@ -576,6 +585,11 @@ - (NSString *)stringByConvertingSimpleCrossReferencesInString:(NSString *)string
if (GBIsCrossRefInside(objectData, remoteMemberData)) objectData = GBEmptyCrossRefData();
if (GBIsCrossRefInside(categoryData, remoteMemberData)) categoryData = GBEmptyCrossRefData();

// Prevent forming cross reference to current top-level object. Also prevent forming cross reference to current member.
if (GBIsCrossRefValid(objectData) && [self isCrossReference:&objectData matchingObject:self.currentContext]) objectData = GBEmptyCrossRefData();
if (GBIsCrossRefValid(categoryData) && [self isCrossReference:&categoryData matchingObject:self.currentContext]) categoryData = GBEmptyCrossRefData();
if (GBIsCrossRefValid(localMemberData) && [self isCrossReference:&localMemberData matchingObject:self.currentObject]) localMemberData = GBEmptyCrossRefData();

// Add objects to handler array. Note that we don't add class/protocol if category is found on the same index! If no link was found, proceed with next char. If there's no other word, exit (we'll deal with remaining text later on).
[links setCount:0];
if (GBIsCrossRefValid(urlData)) [links addPointer:&urlData];
Expand Down Expand Up @@ -638,6 +652,20 @@ - (NSString *)stringByConvertingSimpleCrossReferencesInString:(NSString *)string
return result;
}

- (BOOL)isCrossReference:(GBCrossRefData *)data matchingObject:(id)object {
if ([object isTopLevelObject]) {
if ([object isKindOfClass:[GBClassData class]])
if ([data->description isEqualToString:[object nameOfClass]]) return YES;
else if ([object isKindOfClass:[GBCategoryData class]])
if ([data->description isEqualToString:[object idOfCategory]]) return YES;
else if ([object isKindOfClass:[GBProtocolData class]])
if ([data->description isEqualToString:[object nameOfProtocol]]) return YES;
} else {
if ([data->description isEqualToString:[object methodSelector]]) return YES;
}
return NO;
}

- (NSString *)markdownLinkWithDescription:(NSString *)description address:(NSString *)address flags:(GBProcessingFlag)flags {
// Creates Markdown inline style link using the given components. This should be used when converting text to Markdown links as it will prepare special format so that we can later properly format links embedded in code spans!
NSString *result = nil;
Expand Down Expand Up @@ -907,6 +935,7 @@ - (GBCommentComponentsProvider *)components {
@synthesize alwaysRepeatFirstParagraph;
@synthesize currentSourceInfo;
@synthesize currentComment;
@synthesize currentObject;
@synthesize currentContext;
@synthesize settings;
@synthesize store;
Expand Down
2 changes: 1 addition & 1 deletion Processing/GBProcessor.m
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ - (void)processCommentForObject:(GBModelBase *)object {

// Let comments processor parse comment string value into object representation.
self.commentsProcessor.alwaysRepeatFirstParagraph = object.isTopLevelObject || object.isStaticDocument;
[self.commentsProcessor processComment:object.comment withContext:self.currentContext store:self.store];
[self.commentsProcessor processCommentForObject:object withContext:self.currentContext store:self.store];
}

- (void)processParametersFromComment:(GBComment *)comment matchingMethod:(GBMethodData *)method {
Expand Down

0 comments on commit 1cff516

Please sign in to comment.