forked from OSchip/llvm-project
[index] Add a SymbolSubKind for an ObjC unit test.
llvm-svn: 267117
This commit is contained in:
parent
f2142cbca8
commit
f30c8c621f
|
@ -63,8 +63,9 @@ enum class SymbolSubKind : uint8_t {
|
||||||
Generic = 1 << 0,
|
Generic = 1 << 0,
|
||||||
TemplatePartialSpecialization = 1 << 1,
|
TemplatePartialSpecialization = 1 << 1,
|
||||||
TemplateSpecialization = 1 << 2,
|
TemplateSpecialization = 1 << 2,
|
||||||
|
UnitTest = 1 << 3,
|
||||||
};
|
};
|
||||||
static const unsigned SymbolSubKindBitNum = 3;
|
static const unsigned SymbolSubKindBitNum = 4;
|
||||||
typedef unsigned SymbolSubKindSet;
|
typedef unsigned SymbolSubKindSet;
|
||||||
|
|
||||||
/// Set of roles that are attributed to symbol occurrences.
|
/// Set of roles that are attributed to symbol occurrences.
|
||||||
|
|
|
@ -16,6 +16,30 @@
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
using namespace clang::index;
|
using namespace clang::index;
|
||||||
|
|
||||||
|
/// \returns true if \c D is a subclass of 'XCTestCase'.
|
||||||
|
static bool isUnitTestCase(const ObjCInterfaceDecl *D) {
|
||||||
|
if (!D)
|
||||||
|
return false;
|
||||||
|
while (const ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
|
||||||
|
if (SuperD->getName() == "XCTestCase")
|
||||||
|
return true;
|
||||||
|
D = SuperD;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \returns true if \c D is in a subclass of 'XCTestCase', returns void, has
|
||||||
|
/// no parameters, and its name starts with 'test'.
|
||||||
|
static bool isUnitTest(const ObjCMethodDecl *D) {
|
||||||
|
if (!D->parameters().empty())
|
||||||
|
return false;
|
||||||
|
if (!D->getReturnType()->isVoidType())
|
||||||
|
return false;
|
||||||
|
if (!D->getSelector().getNameForSlot(0).startswith("test"))
|
||||||
|
return false;
|
||||||
|
return isUnitTestCase(D->getClassInterface());
|
||||||
|
}
|
||||||
|
|
||||||
SymbolInfo index::getSymbolInfo(const Decl *D) {
|
SymbolInfo index::getSymbolInfo(const Decl *D) {
|
||||||
assert(D);
|
assert(D);
|
||||||
SymbolInfo Info;
|
SymbolInfo Info;
|
||||||
|
@ -84,10 +108,16 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
|
||||||
case Decl::EnumConstant:
|
case Decl::EnumConstant:
|
||||||
Info.Kind = SymbolKind::EnumConstant; break;
|
Info.Kind = SymbolKind::EnumConstant; break;
|
||||||
case Decl::ObjCInterface:
|
case Decl::ObjCInterface:
|
||||||
case Decl::ObjCImplementation:
|
case Decl::ObjCImplementation: {
|
||||||
Info.Kind = SymbolKind::Class;
|
Info.Kind = SymbolKind::Class;
|
||||||
Info.Lang = SymbolLanguage::ObjC;
|
Info.Lang = SymbolLanguage::ObjC;
|
||||||
|
const ObjCInterfaceDecl *ClsD = dyn_cast<ObjCInterfaceDecl>(D);
|
||||||
|
if (!ClsD)
|
||||||
|
ClsD = cast<ObjCImplementationDecl>(D)->getClassInterface();
|
||||||
|
if (isUnitTestCase(ClsD))
|
||||||
|
Info.SubKinds |= (unsigned)SymbolSubKind::UnitTest;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Decl::ObjCProtocol:
|
case Decl::ObjCProtocol:
|
||||||
Info.Kind = SymbolKind::Protocol;
|
Info.Kind = SymbolKind::Protocol;
|
||||||
Info.Lang = SymbolLanguage::ObjC;
|
Info.Lang = SymbolLanguage::ObjC;
|
||||||
|
@ -103,6 +133,8 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
|
||||||
else
|
else
|
||||||
Info.Kind = SymbolKind::ClassMethod;
|
Info.Kind = SymbolKind::ClassMethod;
|
||||||
Info.Lang = SymbolLanguage::ObjC;
|
Info.Lang = SymbolLanguage::ObjC;
|
||||||
|
if (isUnitTest(cast<ObjCMethodDecl>(D)))
|
||||||
|
Info.SubKinds |= (unsigned)SymbolSubKind::UnitTest;
|
||||||
break;
|
break;
|
||||||
case Decl::ObjCProperty:
|
case Decl::ObjCProperty:
|
||||||
Info.Kind = SymbolKind::InstanceProperty;
|
Info.Kind = SymbolKind::InstanceProperty;
|
||||||
|
@ -314,6 +346,7 @@ void index::applyForEachSymbolSubKind(SymbolSubKindSet SubKinds,
|
||||||
APPLY_FOR_SUBKIND(Generic);
|
APPLY_FOR_SUBKIND(Generic);
|
||||||
APPLY_FOR_SUBKIND(TemplatePartialSpecialization);
|
APPLY_FOR_SUBKIND(TemplatePartialSpecialization);
|
||||||
APPLY_FOR_SUBKIND(TemplateSpecialization);
|
APPLY_FOR_SUBKIND(TemplateSpecialization);
|
||||||
|
APPLY_FOR_SUBKIND(UnitTest);
|
||||||
|
|
||||||
#undef APPLY_FOR_SUBKIND
|
#undef APPLY_FOR_SUBKIND
|
||||||
}
|
}
|
||||||
|
@ -329,6 +362,7 @@ void index::printSymbolSubKinds(SymbolSubKindSet SubKinds, raw_ostream &OS) {
|
||||||
case SymbolSubKind::Generic: OS << "Gen"; break;
|
case SymbolSubKind::Generic: OS << "Gen"; break;
|
||||||
case SymbolSubKind::TemplatePartialSpecialization: OS << "TPS"; break;
|
case SymbolSubKind::TemplatePartialSpecialization: OS << "TPS"; break;
|
||||||
case SymbolSubKind::TemplateSpecialization: OS << "TS"; break;
|
case SymbolSubKind::TemplateSpecialization: OS << "TS"; break;
|
||||||
|
case SymbolSubKind::UnitTest: OS << "test"; break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
// RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s
|
||||||
|
|
||||||
|
// CHECK: [[@LINE+1]]:12 | class/ObjC | XCTestCase | c:objc(cs)XCTestCase | _OBJC_CLASS_$_XCTestCase | Decl | rel: 0
|
||||||
|
@interface XCTestCase
|
||||||
|
@end
|
||||||
|
|
||||||
|
// CHECK: [[@LINE+1]]:12 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Decl | rel: 0
|
||||||
|
@interface MyTestCase : XCTestCase
|
||||||
|
@end
|
||||||
|
// CHECK: [[@LINE+1]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | <no-cgname> | Def | rel: 0
|
||||||
|
@implementation MyTestCase
|
||||||
|
// CHECK: [[@LINE+1]]:1 | instance-method(test)/ObjC | testMe | c:objc(cs)MyTestCase(im)testMe | -[MyTestCase testMe] | Def,Dyn,RelChild | rel: 1
|
||||||
|
-(void)testMe {}
|
||||||
|
// CHECK: [[@LINE+1]]:1 | instance-method/ObjC | testResult | c:objc(cs)MyTestCase(im)testResult | -[MyTestCase testResult] | Def,Dyn,RelChild | rel: 1
|
||||||
|
-(id)testResult { return 0; }
|
||||||
|
// CHECK: [[@LINE+1]]:1 | instance-method/ObjC | testWithInt: | c:objc(cs)MyTestCase(im)testWithInt: | -[MyTestCase testWithInt:] | Def,Dyn,RelChild | rel: 1
|
||||||
|
-(void)testWithInt:(int)i {}
|
||||||
|
@end
|
||||||
|
|
||||||
|
// CHECK: [[@LINE+1]]:12 | class(test)/ObjC | SubTestCase | c:objc(cs)SubTestCase | _OBJC_CLASS_$_SubTestCase | Decl | rel: 0
|
||||||
|
@interface SubTestCase : MyTestCase
|
||||||
|
@end
|
||||||
|
// CHECK: [[@LINE+1]]:17 | class(test)/ObjC | SubTestCase | c:objc(cs)SubTestCase | <no-cgname> | Def | rel: 0
|
||||||
|
@implementation SubTestCase
|
||||||
|
// CHECK: [[@LINE+1]]:1 | instance-method(test)/ObjC | testIt2 | c:objc(cs)SubTestCase(im)testIt2 | -[SubTestCase testIt2] | Def,Dyn,RelChild | rel: 1
|
||||||
|
-(void)testIt2 {}
|
||||||
|
@end
|
||||||
|
|
||||||
|
// CHECK: [[@LINE+1]]:12 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Decl | rel: 0
|
||||||
|
@interface MyTestCase(cat)
|
||||||
|
@end
|
||||||
|
// CHECK: [[@LINE+1]]:17 | extension/ObjC | MyTestCase | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
|
||||||
|
@implementation MyTestCase(cat)
|
||||||
|
// CHECK: [[@LINE+1]]:1 | instance-method(test)/ObjC | testInCat | c:objc(cs)MyTestCase(im)testInCat | -[MyTestCase(cat) testInCat] | Def,Dyn,RelChild | rel: 1
|
||||||
|
- (void)testInCat {}
|
||||||
|
@end
|
|
@ -169,8 +169,9 @@ static bool printSourceSymbols(ArrayRef<const char *> Args) {
|
||||||
static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) {
|
static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) {
|
||||||
OS << getSymbolKindString(SymInfo.Kind);
|
OS << getSymbolKindString(SymInfo.Kind);
|
||||||
if (SymInfo.SubKinds) {
|
if (SymInfo.SubKinds) {
|
||||||
OS << '-';
|
OS << '(';
|
||||||
printSymbolSubKinds(SymInfo.SubKinds, OS);
|
printSymbolSubKinds(SymInfo.SubKinds, OS);
|
||||||
|
OS << ')';
|
||||||
}
|
}
|
||||||
OS << '/' << getSymbolLanguageString(SymInfo.Lang);
|
OS << '/' << getSymbolLanguageString(SymInfo.Lang);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue