diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2016-04-22 07:21:10 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2016-04-22 07:21:10 +0000 |
commit | f30c8c621f4aa5b6b00364d0706feed227cfa047 (patch) | |
tree | eae4ad1357c50d8932a0c26c4dd3d85d457d6600 /clang/lib/Index/IndexSymbol.cpp | |
parent | f2142cbca8fee48ed61e25e1f1e7f460494670c2 (diff) | |
download | bcm5719-llvm-f30c8c621f4aa5b6b00364d0706feed227cfa047.tar.gz bcm5719-llvm-f30c8c621f4aa5b6b00364d0706feed227cfa047.zip |
[index] Add a SymbolSubKind for an ObjC unit test.
llvm-svn: 267117
Diffstat (limited to 'clang/lib/Index/IndexSymbol.cpp')
-rw-r--r-- | clang/lib/Index/IndexSymbol.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp index 097aaf0721f..ba83d0cdef6 100644 --- a/clang/lib/Index/IndexSymbol.cpp +++ b/clang/lib/Index/IndexSymbol.cpp @@ -16,6 +16,30 @@ using namespace clang; 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) { assert(D); SymbolInfo Info; @@ -84,10 +108,16 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { case Decl::EnumConstant: Info.Kind = SymbolKind::EnumConstant; break; case Decl::ObjCInterface: - case Decl::ObjCImplementation: + case Decl::ObjCImplementation: { Info.Kind = SymbolKind::Class; 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; + } case Decl::ObjCProtocol: Info.Kind = SymbolKind::Protocol; Info.Lang = SymbolLanguage::ObjC; @@ -103,6 +133,8 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { else Info.Kind = SymbolKind::ClassMethod; Info.Lang = SymbolLanguage::ObjC; + if (isUnitTest(cast<ObjCMethodDecl>(D))) + Info.SubKinds |= (unsigned)SymbolSubKind::UnitTest; break; case Decl::ObjCProperty: Info.Kind = SymbolKind::InstanceProperty; @@ -314,6 +346,7 @@ void index::applyForEachSymbolSubKind(SymbolSubKindSet SubKinds, APPLY_FOR_SUBKIND(Generic); APPLY_FOR_SUBKIND(TemplatePartialSpecialization); APPLY_FOR_SUBKIND(TemplateSpecialization); + APPLY_FOR_SUBKIND(UnitTest); #undef APPLY_FOR_SUBKIND } @@ -329,6 +362,7 @@ void index::printSymbolSubKinds(SymbolSubKindSet SubKinds, raw_ostream &OS) { case SymbolSubKind::Generic: OS << "Gen"; break; case SymbolSubKind::TemplatePartialSpecialization: OS << "TPS"; break; case SymbolSubKind::TemplateSpecialization: OS << "TS"; break; + case SymbolSubKind::UnitTest: OS << "test"; break; } }); } |