我试图将一个参数的类名提取到objective-C中的方法调用中。我正在解析的代码是:
- (void)testAddConcreteDataModel:(DFDemoDataModelOne*)helpmeh {
[self.dataModels addObject:helpmeh];
}
我需要的结果是helpmeh类的类型,即“DFDemoDataModelOne”。
到目前为止,我有以下代码,输出:"[(DFDataModelContainer).dataModels addObject:helpmeh]"
if (cursor.kind == CXCursor_ObjCMessageExpr) {
__block NSString* memberName = nil;
__block NSString* ownerClassName = nil;
__block NSString* methodName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))];
clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) {
if (cursor.kind == CXCursor_MemberRefExpr) {
memberName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))];
ownerClassName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(clang_getCursorSemanticParent(clang_getCursorReferenced(cursor))))];
} else {
if (memberName) {
NSString* param = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))];
NSLog(@"[(%@).%@ %@%@]", ownerClassName, memberName, methodName, param);
clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) {
// test
if ([param isEqualToString:@"helpmeh"] && cursor.kind == CXCursor_DeclRefExpr) {
// found the interesting part.. what now?
}
return CXChildVisit_Recurse;
}
}
}
return CXChildVisit_Continue;
}
}
关于如何从游标中提取信息,我有点迷失 - 当我转储我的课程时,我可以看到我需要的信息(见最后一行):
|-ObjCMethodDecl 0x112790f90 <line:32:1, line:34:1> - testAddConcreteDataModel: 'void'
| |-ImplicitParamDecl 0x112791960 <<invalid sloc>> self 'DFDataModelContainer *const __strong'
| |-ImplicitParamDecl 0x1127919c0 <<invalid sloc>> _cmd 'SEL':'SEL *'
| |-ParmVarDecl 0x112791040 <line:32:35, col:55> helpmeh 'DFDemoDataModelOne *__strong'
| `-CompoundStmt 0x112791bf0 <col:63, line:34:1>
| `-ExprWithCleanups 0x112791bd8 <line:33:5, col:39> 'void'
| `-ObjCMessageExpr 0x112791ba0 <col:5, col:39> 'void' selector=addObject:
| |-PseudoObjectExpr 0x112791b48 <col:6, col:11> 'NSMutableArray *'
| | |-ObjCPropertyRefExpr 0x112791ad0 <col:6, col:11> '<pseudo-object type>' lvalue objcproperty Kind=PropertyRef Property="dataModels" Messaging=Getter
| | | `-OpaqueValueExpr 0x112791ab0 <col:6> 'DFDataModelContainer *'
| | | `-ImplicitCastExpr 0x112791a40 <col:6> 'DFDataModelContainer *' <LValueToRValue>
| | | `-DeclRefExpr 0x112791a18 <col:6> 'DFDataModelContainer *const __strong' lvalue ImplicitParam 0x112791960 'self' 'DFDataModelContainer *const __strong'
| | |-OpaqueValueExpr 0x112791ab0 <col:6> 'DFDataModelContainer *'
| | | `-ImplicitCastExpr 0x112791a40 <col:6> 'DFDataModelContainer *' <LValueToRValue>
| | | `-DeclRefExpr 0x112791a18 <col:6> 'DFDataModelContainer *const __strong' lvalue ImplicitParam 0x112791960 'self' 'DFDataModelContainer *const __strong'
| | `-ImplicitCastExpr 0x112791b30 <col:11> 'NSMutableArray *' <ARCReclaimReturnedObject>
| | `-ObjCMessageExpr 0x112791b00 <col:11> 'NSMutableArray *' selector=dataModels
| | `-OpaqueValueExpr 0x112791ab0 <col:6> 'DFDataModelContainer *'
| | `-ImplicitCastExpr 0x112791a40 <col:6> 'DFDataModelContainer *' <LValueToRValue>
| | `-DeclRefExpr 0x112791a18 <col:6> 'DFDataModelContainer *const __strong' lvalue ImplicitParam 0x112791960 'self' 'DFDataModelContainer *const __strong'
| `-ImplicitCastExpr 0x112791b88 <col:32> 'id':'id' <BitCast>
| `-ImplicitCastExpr 0x112791b70 <col:32> 'DFDemoDataModelOne *' <LValueToRValue>
| `-DeclRefExpr 0x112791a88 <col:32> 'DFDemoDataModelOne *__strong' lvalue ParmVar 0x112791040 'helpmeh' 'DFDemoDataModelOne *__strong'
任何指针都非常感谢!
答案 0 :(得分:3)
您是否尝试过查看clang_getCursorSemanticParent功能?
我无法帮助您使用ObjC代码,但总体思路应该是:
clang_getCursorSemanticParent
获取类声明的游标clang_getCursorSpelling
或clang_getCursorDisplayName
以获取类名答案 1 :(得分:0)
我想我找到了一个解决方案 -
CXCursor_ParmDecl
,但它可以是任何内容,例如CXCursor_VarDecl
等。这是我更新的代码 - 它很hacky,需要一些清理/澄清,但是在这里张贴后代。
- (void)processMethodDeclaration:(const CXIdxDeclInfo *)declaration {
clang_visitChildrenWithBlock(declaration->cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) {
if (cursor.kind == CXCursor_ObjCMessageExpr) {
__block NSString* memberName = nil;
__block NSString* referencedObjectName = nil;
clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) {
if (cursor.kind == CXCursor_MemberRefExpr) {
memberName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))];
referencedObjectName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(clang_getCursorSemanticParent(clang_getCursorReferenced(cursor))))];
} else {
if (memberName) {
__block NSString* passedClassName = nil;
clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) {
if (cursor.kind == CXCursor_DeclRefExpr) {
CXCursor def = clang_getCursorDefinition(cursor);
clang_visitChildrenWithBlock(def, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) {
passedClassName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))];
return CXChildVisit_Break;
});
}
return CXChildVisit_Recurse;
});
return CXChildVisit_Break;
}
}
return CXChildVisit_Continue;
});
}
return CXChildVisit_Recurse;
});
}