Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added support for termination macros for method declaration and properties declaration #143

Closed
wants to merge 2 commits into from

2 participants

@groue

Hi,

appledoc was not able to properly parse custom termination macros, such as the following declaration:

- (NSString *)foo:(id)bar MACRO;
@property (nonatomic, readonly) int p1 MACRO;
@property (nonatomic, readonly) void(^p2)(void) MACRO;

This pull request adds the following method to the GBTokenizer class:

- (void)lookaheadTo:(NSString *)end usingBlock:(void (^)(PKToken *token, BOOL *stop))block;

This method allows [GBObjectiveCParser matchMethodDataForProvider:from:to:required:] to look ahead an argument name for further colons :. If there is none, remaining tokens are handled as termination macros.

Also, [GBMethodData propertyDataWithAttributes:components:] has been enhanced in order to set the property name apart from the return type, without help from [GBObjectiveCParser matchPropertyDefinitionForProvider:required:] in the specific case of block properties.

@groue

Forget about this one. It does not handle well methods without any argument, but with a termination macro.

@groue groue closed this
@tomaz
Owner

Cool, will wait for fix if you implement one. These things tend to be tricky and GHUnit stopped working on me... Time to change to SenTest I guess - with Xcode 4 it's working quite well...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
42 Model/GBMethodData.m
@@ -9,6 +9,7 @@
#import "GRMustache.h"
#import "GBMethodArgument.h"
#import "GBMethodData.h"
+#import "RegexKitLite.h"
@interface GBMethodData ()
@@ -40,9 +41,44 @@ + (id)methodDataWithType:(GBMethodType)type result:(NSArray *)result arguments:(
+ (id)propertyDataWithAttributes:(NSArray *)attributes components:(NSArray *)components {
NSParameterAssert([components count] >= 2); // At least one return and the name!
- NSMutableArray *results = [NSMutableArray arrayWithArray:components];
- [results removeLastObject]; // Remove ;
- GBMethodArgument *argument = [GBMethodArgument methodArgumentWithName:[components lastObject]];
+
+ // extract return type and property name
+ NSString *propertyName = nil;
+ NSMutableArray *results = [NSMutableArray array];
+ BOOL nextComponentIsBlockPropertyName = NO;
+ BOOL nextComponentIsBlockReturnComponent = NO;
+ NSUInteger parenthesisLevel = 0;
+ for (NSString *component in components) {
+ if ([component isEqualToString:@"^"]) {
+ [results addObject:component];
+ nextComponentIsBlockPropertyName = YES;
+ } else if (nextComponentIsBlockPropertyName) {
+ propertyName = component;
+ nextComponentIsBlockPropertyName = NO;
+ nextComponentIsBlockReturnComponent = YES;
+ } else if (nextComponentIsBlockReturnComponent) {
+ if (parenthesisLevel > 0 || [component isEqualToString:@"("]) {
+ [results addObject:component];
+ }
+ } else if ([component isMatchedByRegex:@"^[_a-zA-Z][_a-zA-Z0-9]*$"]) {
+ if (results.count == 0) {
+ [results addObject:component];
+ } else if (propertyName == nil) {
+ propertyName = component;
+ } else {
+ // ignore termination macro
+ }
+ } else if (propertyName == nil) {
+ [results addObject:component];
+ }
+ if ([component isEqualToString:@"("]) {
+ ++parenthesisLevel;
+ } else if ([component isEqualToString:@")"]) {
+ --parenthesisLevel;
+ }
+ }
+
+ GBMethodArgument *argument = [GBMethodArgument methodArgumentWithName:propertyName];
return [[[self alloc] initWithType:GBMethodTypeProperty attributes:attributes result:results arguments:[NSArray arrayWithObject:argument]] autorelease];
}
View
23 Parsing/GBObjectiveCParser.m
@@ -261,8 +261,6 @@ - (BOOL)matchPropertyDefinitionForProvider:(GBMethodsProvider *)provider require
NSMutableArray *propertyComponents = [NSMutableArray array];
__block BOOL parseAttribute = NO;
__block NSUInteger parenthesisDepth = 0;
- __block BOOL parseBlockName = NO;
- __block NSString *blockName = nil;
[self.tokenizer consumeTo:@";" usingBlock:^(PKToken *token, BOOL *consume, BOOL *stop) {
if ([token matches:@"__attribute__"]) {
parseAttribute = YES;
@@ -276,14 +274,8 @@ - (BOOL)matchPropertyDefinitionForProvider:(GBMethodsProvider *)provider require
}
} else {
[propertyComponents addObject:[token stringValue]];
- if (parseBlockName) {
- blockName = [token stringValue];
- parseBlockName = NO;
- }
- if ([token matches:@"^"]) parseBlockName = YES;
}
}];
- if (blockName) [propertyComponents addObject:blockName];
// Register property.
GBMethodData *propertyData = [GBMethodData propertyDataWithAttributes:propertyAttributes components:propertyComponents];
@@ -531,6 +523,21 @@ - (BOOL)matchMethodDataForProvider:(GBMethodsProvider *)provider from:(NSString
}];
*stop = YES; // Ignore the rest of parameters as vararg is the last and above block consumed end token which would confuse above block!
}
+
+ // If we have no more colon before end, consume the rest of the tokens to get optional termination macros.
+ __block BOOL hasColon = NO;
+ [self.tokenizer lookaheadTo:end usingBlock:^(PKToken *token, BOOL *stop) {
+ if ([token matches:@":"]) {
+ hasColon = YES;
+ *stop = YES;
+ }
+ }];
+ if (!hasColon) {
+ [self.tokenizer consumeTo:end usingBlock:^(PKToken *token, BOOL *consume, BOOL *stop) {
+ [terminationMacros addObject:[token stringValue]];
+ }];
+ *stop = YES; // Ignore the rest of parameters as vararg is the last and above block consumed end token which would confuse above block!
+ }
}
GBMethodArgument *argument = nil;
View
10 Parsing/GBTokenizer.h
@@ -88,9 +88,19 @@
@param offset The offset from the current position.
@return Returns the token at the given offset or EOF token if offset point after EOF.
@see consume:
+ @see lookaheadTo:usingBlock:
*/
- (PKToken *)lookahead:(NSUInteger)offset;
+/** Enumerates but does not consume all tokens starting at current token up until the given end token is detected.
+
+ For each token, the given block is called which gives client a chance to inspect and handle tokens. End token is not reported. Note that this method automatically skips any comment tokens and only enumerates actual language tokens.
+
+ @param end Ending token.
+ @see lookahead:
+ */
+- (void)lookaheadTo:(NSString *)end usingBlock:(void (^)(PKToken *token, BOOL *stop))block;
+
/** Consumes the given ammoun of tokens, starting at the current position.
This effectively "moves" `currentToken` to the new position. If EOF is reached before consuming the given ammount of tokens, consuming stops at the end of stream and `currentToken` returns EOF token. If comment tokens are detected while consuming, they are not counted and consuming count continues with actual language tokens. However if there is a comment just before the next current token (i.e. after the last consumed token), the comment data is saved and is available through `lastCommentString`. Otherwise last comment data is cleared, even if a comment was detected in between.
View
17 Parsing/GBTokenizer.m
@@ -87,6 +87,23 @@ - (PKToken *)lookahead:(NSUInteger)offset {
return [self.tokens objectAtIndex:self.tokenIndex + delta - 1];
}
+- (void)lookaheadTo:(NSString *)end usingBlock:(void (^)(PKToken *token, BOOL *stop))block {
+ NSUInteger tokenCount = [self.tokens count];
+ BOOL quit = NO;
+ for (NSUInteger index = self.tokenIndex; index < tokenCount; ++index) {
+ PKToken *token = [self.tokens objectAtIndex:index];
+ if ([token isComment]) {
+ index++;
+ continue;
+ }
+ if ([token matches:end]) {
+ break;
+ }
+ block(token, &quit);
+ if (quit) break;
+ }
+}
+
- (PKToken *)currentToken {
if ([self eof]) return [PKToken EOFToken];
return [self.tokens objectAtIndex:self.tokenIndex];
View
0  install-appledoc.sh 100644 → 100755
File mode changed
Something went wrong with that request. Please try again.