Skip to content

Add Adopted protocol parsing (for classes, categories and protocols). #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 130 additions & 39 deletions SCKClangSourceFile.m
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ static BOOL isIBOutletFromPropertyOrIvar(CXCursor cursor)
- (void) setLocation: (SCKSourceLocation*)aLocation
forClass: (NSString*)aClassName
withSuperclass: (NSString*)aSuperclassName
adoptedProtocols: (NSArray*)adoptedProtocolNames
isDefinition: (BOOL)isDefinition
isForwardDeclaration: (BOOL)isForwardDeclaration
{
Expand All @@ -274,6 +275,13 @@ - (void) setLocation: (SCKSourceLocation*)aLocation
[class setSuperclass: [[self collection] classForName: aSuperclassName]];
}

if (nil != adoptedProtocolNames)
{
[self addAdoptedProtocolWithNames: adoptedProtocolNames
toProgramComponent: class
category: nil];
}

if (isDefinition)
{
[class setDefinition: aLocation];
Expand All @@ -286,6 +294,7 @@ - (void) setLocation: (SCKSourceLocation*)aLocation

- (void)setLocation: (SCKSourceLocation*)aLocation
forCategory: (NSString*)aCategoryName
adoptedProtocols: (NSArray*)adoptedProtocolNames
isDefinition: (BOOL)isDefinition
ofClass: (NSString*)aClassName
{
Expand All @@ -301,6 +310,13 @@ - (void)setLocation: (SCKSourceLocation*)aLocation
[[class categories] setObject: category forKey: aCategoryName];
}

if (nil != adoptedProtocolNames)
{
[self addAdoptedProtocolWithNames: adoptedProtocolNames
toProgramComponent: class
category: category];
}

if (isDefinition)
{
[category setDefinition: aLocation];
Expand Down Expand Up @@ -490,6 +506,7 @@ - (void)setLocation: (SCKSourceLocation*)sourceLocation

- (void) setLocation: (SCKSourceLocation*)sourceLocation
forProtocol: (NSString*)protocolName
adoptedProtocols: (NSArray*)adoptedProtocolNames
isForwardDeclaration: (BOOL)isForwardDeclaration
{
SCKProtocol *protocol = [[self collection] protocolForName: protocolName];
Expand All @@ -498,6 +515,14 @@ - (void) setLocation: (SCKSourceLocation*)sourceLocation
{
return;
}

if (nil != adoptedProtocolNames)
{
[self addAdoptedProtocolWithNames: adoptedProtocolNames
toProgramComponent: nil
category: nil];
}

[protocol setDeclaration: sourceLocation];
[protocol setDefinition: sourceLocation];
}
Expand Down Expand Up @@ -631,6 +656,61 @@ - (void)setLocation: (SCKSourceLocation*)sourceLocation
}
}

- (void)addAdoptedProtocolWithName: (NSString*)adoptedProtocolName
toClass: (SCKClass*)class
toProtocol: (SCKProtocol*)protocol
toCategory: (SCKCategory*)category
{
SCKProtocol *adoptedProtocol = nil;

if (nil != class)
{
adoptedProtocol = [[class adoptedProtocols] objectForKey: adoptedProtocolName];

if (nil == adoptedProtocol)
{
adoptedProtocol = [[self collection] protocolForName: adoptedProtocolName];
[[class adoptedProtocols] setObject: adoptedProtocol forKey: adoptedProtocolName];
}

if (nil != category)
{
[[category adoptedProtocols] setObject: adoptedProtocol forKey: adoptedProtocolName];
}
}

if (nil != protocol)
{
adoptedProtocol = [[protocol adoptedProtocols] objectForKey: adoptedProtocolName];

if (nil == adoptedProtocol)
{
adoptedProtocol = [[self collection] protocolForName: adoptedProtocolName];
[[protocol adoptedProtocols] setObject: adoptedProtocol forKey: adoptedProtocolName];
}
}
}

- (void)addAdoptedProtocolWithNames: (NSArray *)adoptedProtocolNames
toProgramComponent: (SCKProgramComponent *)component
category: (SCKCategory *)category
{
if (nil == adoptedProtocolNames)
{
return;
}

for (NSString *adoptedProtocolName in adoptedProtocolNames)
{
SCKProtocol *protocol = [[self collection] protocolForName: adoptedProtocolName];

[[(id)component adoptedProtocols] setObject: protocol forKey: adoptedProtocolName];

[[category adoptedProtocols] setObject: protocol forKey: adoptedProtocolName];
}
}


- (void)rebuildIndex
{
if (0 == translationUnit) { return; }
Expand All @@ -655,10 +735,16 @@ - (void)rebuildIndex
SCOPED_STR(className, clang_getCursorSpelling(cursor));
NSString __block *superclassName = nil;
BOOL __block isForwardDeclaration = NO;

NSMutableArray __block *adoptedProtocols = [NSMutableArray array];

clang_visitChildrenWithBlock(cursor,
^ enum CXChildVisitResult (CXCursor classCursor, CXCursor parent)
{
SCOPED_STR(name, clang_getCursorSpelling(classCursor));
SCOPED_STR(typeEncoding, clang_getDeclObjCTypeEncoding(classCursor));
SCKSourceLocation *sourceLocation = [[SCKSourceLocation alloc]
initWithClangSourceLocation: clang_getCursorLocation(classCursor)];

switch (classCursor.kind)
{
case CXCursor_ObjCClassRef:
Expand All @@ -672,13 +758,14 @@ - (void)rebuildIndex
superclassName = [NSString stringWithUTF8String: name];
break;
}
case CXCursor_ObjCIvarDecl:
case CXCursor_ObjCProtocolRef:
{
SCOPED_STR(name, clang_getCursorSpelling(classCursor));
SCOPED_STR(typeEncoding, clang_getDeclObjCTypeEncoding(classCursor));
SCKSourceLocation *sourceLocation = [[SCKSourceLocation alloc]
initWithClangSourceLocation: clang_getCursorLocation(classCursor)];

[adoptedProtocols addObject: [NSString stringWithUTF8String: name]];

break;
}
case CXCursor_ObjCIvarDecl:
{
[self setLocation: sourceLocation
forIvar: [NSString stringWithUTF8String: name]
withTypeEncoding: [NSString stringWithUTF8String: typeEncoding]
Expand All @@ -688,34 +775,25 @@ - (void)rebuildIndex
}
case CXCursor_ObjCPropertyDecl:
{
SCOPED_STR(name, clang_getCursorSpelling(classCursor));
SCOPED_STR(type, clang_getDeclObjCTypeEncoding(classCursor));
SCKSourceLocation *sourceLocation = [[SCKSourceLocation alloc]
initWithClangSourceLocation: clang_getCursorLocation(classCursor)];
CXObjCPropertyAttrKind attributes = 0;
#if CINDEX_VERSION >= 21
attributes = clang_Cursor_getObjCPropertyAttributes(classCursor, 0);
#endif

[self setLocation: sourceLocation
forProperty: [NSString stringWithUTF8String: name]
withTypeEncoding: [NSString stringWithUTF8String: type]
withTypeEncoding: [NSString stringWithUTF8String: typeEncoding]
attributes: attributes
isIBOutlet: isIBOutletFromPropertyOrIvar(classCursor)
inClass: [NSString stringWithUTF8String: className]];
break;
}
case CXCursor_ObjCInstanceMethodDecl:
case CXCursor_ObjCClassMethodDecl:
{
SCOPED_STR(name, clang_getCursorSpelling(classCursor));
SCOPED_STR(type, clang_getDeclObjCTypeEncoding(classCursor));
SCKSourceLocation *sourceLocation = [[SCKSourceLocation alloc]
initWithClangSourceLocation: clang_getCursorLocation(classCursor)];

{
[self setLocation: sourceLocation
forMethod: [NSString stringWithUTF8String: name]
withTypeEncoding: [NSString stringWithUTF8String: type]
withTypeEncoding: [NSString stringWithUTF8String: typeEncoding]
isClassMethod: (classCursor.kind == CXCursor_ObjCClassMethodDecl)
isDefinition: clang_isCursorDefinition(classCursor)
inClass: [NSString stringWithUTF8String: className]
Expand All @@ -735,6 +813,7 @@ - (void)rebuildIndex
[self setLocation: classLoc
forClass: [NSString stringWithUTF8String: className]
withSuperclass: superclassName
adoptedProtocols: adoptedProtocols
isDefinition: clang_isCursorDefinition(cursor)
isForwardDeclaration: isForwardDeclaration];
break;
Expand All @@ -748,6 +827,7 @@ - (void)rebuildIndex
[self setLocation: classLoc
forClass: [NSString stringWithUTF8String: className]
withSuperclass: nil
adoptedProtocols: nil
isDefinition: clang_isCursorDefinition(cursor)
isForwardDeclaration: NO];

Expand Down Expand Up @@ -784,25 +864,27 @@ - (void)rebuildIndex
initWithClangSourceLocation: clang_getCursorLocation(cursor)];
SCOPED_STR(categoryName, clang_getCursorSpelling(cursor));
NSString *className = classNameFromCategory(cursor);

[self setLocation: categoryLoc
forCategory: [NSString stringWithUTF8String: categoryName]
isDefinition: clang_isCursorDefinition(cursor)
ofClass: className];
NSMutableArray __block *adoptedProtocols = [NSMutableArray array];

clang_visitChildrenWithBlock(cursor,
^ enum CXChildVisitResult (CXCursor categoryCursor, CXCursor parent)
{
SCOPED_STR(name, clang_getCursorSpelling(categoryCursor));
SCOPED_STR(type, clang_getDeclObjCTypeEncoding(categoryCursor));
SCKSourceLocation *sourceLocation = [[SCKSourceLocation alloc]
initWithClangSourceLocation: clang_getCursorLocation(categoryCursor)];

switch (categoryCursor.kind)
{
case CXCursor_ObjCProtocolRef:
{
[adoptedProtocols addObject: [NSString stringWithUTF8String: name]];

break;
}
case CXCursor_ObjCInstanceMethodDecl:
case CXCursor_ObjCClassMethodDecl:
{
SCKSourceLocation *sourceLocation = [[SCKSourceLocation alloc]
initWithClangSourceLocation: clang_getCursorLocation(categoryCursor)];
SCOPED_STR(name, clang_getCursorSpelling(categoryCursor));
SCOPED_STR(type, clang_getDeclObjCTypeEncoding(categoryCursor));

[self setLocation: sourceLocation
forMethod: [NSString stringWithUTF8String: name]
withTypeEncoding: [NSString stringWithUTF8String: type]
Expand All @@ -816,10 +898,6 @@ - (void)rebuildIndex
case CXCursor_ObjCDynamicDecl:
case CXCursor_ObjCPropertyDecl:
{
SCKSourceLocation *sourceLocation = [[SCKSourceLocation alloc]
initWithClangSourceLocation: clang_getCursorLocation(categoryCursor)];
SCOPED_STR(name, clang_getCursorSpelling(categoryCursor));
SCOPED_STR(type, clang_getDeclObjCTypeEncoding(categoryCursor));
CXObjCPropertyAttrKind attributes = 0;
#if CINDEX_VERSION >= 21
attributes = clang_Cursor_getObjCPropertyAttributes(categoryCursor, 0);
Expand All @@ -839,6 +917,12 @@ - (void)rebuildIndex
}
return CXChildVisit_Continue;
});

[self setLocation: categoryLoc
forCategory: [NSString stringWithUTF8String: categoryName]
adoptedProtocols: adoptedProtocols
isDefinition: clang_isCursorDefinition(cursor)
ofClass: className];
break;
}
case CXCursor_ObjCProtocolDecl:
Expand All @@ -847,12 +931,7 @@ - (void)rebuildIndex
SCOPED_STR(protocolName, clang_getCursorSpelling(cursor));
SCKSourceLocation *sourceLocation = [[SCKSourceLocation alloc]
initWithClangSourceLocation: clang_getCursorLocation(cursor)];

// NOTE: We could use CXCursor_ObjCProtocolDecl to parse protocol
// forward declarations as we do with CXCursor_ObjCClassDecl
[self setLocation: sourceLocation
forProtocol: [NSString stringWithUTF8String: protocolName]
isForwardDeclaration: (clang_isCursorDefinition(cursor) == NO)];
NSMutableArray __block *adoptedProtocols = [NSMutableArray array];

clang_visitChildrenWithBlock(cursor,
^enum CXChildVisitResult(CXCursor protocolCursor, CXCursor parent)
Expand All @@ -865,6 +944,12 @@ - (void)rebuildIndex

switch (protocolCursor.kind)
{
case CXCursor_ObjCProtocolRef:
{
[adoptedProtocols addObject: [NSString stringWithUTF8String: name]];

break;
}
case CXCursor_ObjCPropertyDecl:
{
CXObjCPropertyAttrKind attributes = 0;
Expand Down Expand Up @@ -907,6 +992,12 @@ - (void)rebuildIndex
}
return CXChildVisit_Recurse;
});
// NOTE: We could use CXCursor_ObjCProtocolDecl to parse protocol
// forward declarations as we do with CXCursor_ObjCClassDecl
[self setLocation: sourceLocation
forProtocol: [NSString stringWithUTF8String: protocolName]
adoptedProtocols: adoptedProtocols
isForwardDeclaration: (clang_isCursorDefinition(cursor) == NO)];
break;
}
case CXCursor_FunctionDecl:
Expand Down
3 changes: 3 additions & 0 deletions SCKIntrospection.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
@property (nonatomic, readonly, retain) NSMutableArray *subclasses;
@property (nonatomic, readonly, retain) NSMutableDictionary *categories;
@property (nonatomic, readonly, retain) NSMutableDictionary *methods;
@property (nonatomic, readonly, retain) NSMutableDictionary *adoptedProtocols;
@property (nonatomic, readonly, retain) NSMutableArray *ivars;
@property (nonatomic, readonly, retain) NSMutableArray *properties;
- (SCKIvar*)ivarForName: (NSString *)name;
Expand All @@ -78,13 +79,15 @@
@property (nonatomic, readonly, retain) NSMutableDictionary *optionalMethods;
@property (nonatomic, readonly, retain) NSMutableArray *requiredProperties;
@property (nonatomic, readonly, retain) NSMutableArray *optionalProperties;
@property (nonatomic, readonly, retain) NSMutableDictionary *adoptedProtocols;
- (SCKProperty*)requiredPropertyForName: (NSString *)aProperty;
- (SCKProperty*)optionalPropertyForName: (NSString *)aProperty;
@end

@interface SCKCategory : SCKProgramComponent
@property (nonatomic, readonly, retain) NSMutableDictionary *methods;
@property (nonatomic, readonly, retain) NSMutableArray *properties;
@property (nonatomic, readonly, retain) NSMutableDictionary *adoptedProtocols;
- (SCKProperty*)propertyForName: (NSString *)aProperty;
@end

Expand Down
Loading