diff options
author | Zixu Wang <zixu_wang@apple.com> | 2022-03-25 15:15:08 -0700 |
---|---|---|
committer | Zixu Wang <zixu_wang@apple.com> | 2022-03-29 14:44:49 -0700 |
commit | d1d34bafef56b732b461e12032eaf030e609f55a (patch) | |
tree | 8360785bdf0fa068133c2916679cbb5550af3b8c /clang/lib/ExtractAPI | |
parent | 122638d97d913edcdfa8ccf921eb5929498166c7 (diff) | |
download | llvm-d1d34bafef56b732b461e12032eaf030e609f55a.zip llvm-d1d34bafef56b732b461e12032eaf030e609f55a.tar.gz llvm-d1d34bafef56b732b461e12032eaf030e609f55a.tar.bz2 |
[clang][extract-api] Add Objective-C protocol support
Add support for Objective-C protocol declarations in ExtractAPI.
Depends on D122446
Differential Revision: https://reviews.llvm.org/D122511
Diffstat (limited to 'clang/lib/ExtractAPI')
-rw-r--r-- | clang/lib/ExtractAPI/API.cpp | 15 | ||||
-rw-r--r-- | clang/lib/ExtractAPI/DeclarationFragments.cpp | 29 | ||||
-rw-r--r-- | clang/lib/ExtractAPI/ExtractAPIConsumer.cpp | 32 | ||||
-rw-r--r-- | clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | 8 |
4 files changed, 84 insertions, 0 deletions
diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 2456022..1c9314c 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -161,6 +161,20 @@ ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable( return Container->Ivars.emplace_back(std::move(Record)).get(); } +ObjCProtocolRecord *APISet::addObjCProtocol( + StringRef Name, StringRef USR, PresumedLoc Loc, + const AvailabilityInfo &Availability, const DocComment &Comment, + DeclarationFragments Declaration, DeclarationFragments SubHeading) { + auto Result = ObjCProtocols.insert({Name, nullptr}); + if (Result.second) { + // Create the record if it does not already exist. + auto Record = std::make_unique<ObjCProtocolRecord>( + Name, USR, Loc, Availability, Comment, Declaration, SubHeading); + Result.first->second = std::move(Record); + } + return Result.first->second.get(); +} + StringRef APISet::recordUSR(const Decl *D) { SmallString<128> USR; index::generateUSRForDecl(D, USR); @@ -193,3 +207,4 @@ void ObjCPropertyRecord::anchor() {} void ObjCInstanceVariableRecord::anchor() {} void ObjCMethodRecord::anchor() {} void ObjCInterfaceRecord::anchor() {} +void ObjCProtocolRecord::anchor() {} diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index b35388e..7c6c9dc 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -621,6 +621,35 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty( .append(std::move(After)); } +DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol( + const ObjCProtocolDecl *Protocol) { + DeclarationFragments Fragments; + // Build basic protocol declaration. + Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() + .append(Protocol->getName(), + DeclarationFragments::FragmentKind::Identifier); + + // If this protocol conforms to other protocols, build the conformance list. + if (!Protocol->protocols().empty()) { + Fragments.append(" <", DeclarationFragments::FragmentKind::Text); + for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin(); + It != Protocol->protocol_end(); It++) { + // Add a leading comma if this is not the first protocol rendered. + if (It != Protocol->protocol_begin()) + Fragments.append(", ", DeclarationFragments::FragmentKind::Text); + + SmallString<128> USR; + index::generateUSRForDecl(*It, USR); + Fragments.append((*It)->getName(), + DeclarationFragments::FragmentKind::TypeIdentifier, USR); + } + Fragments.append(">", DeclarationFragments::FragmentKind::Text); + } + + return Fragments; +} + template <typename FunctionT> FunctionSignature DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) { diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index f8b1c9b..bcc01db 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -260,6 +260,38 @@ public: return true; } + bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl) { + // Skip forward declaration for protocols (@protocol). + if (!Decl->isThisDeclarationADefinition()) + return true; + + // Collect symbol information. + StringRef Name = Decl->getName(); + StringRef USR = API.recordUSR(Decl); + PresumedLoc Loc = + Context.getSourceManager().getPresumedLoc(Decl->getLocation()); + AvailabilityInfo Availability = getAvailability(Decl); + DocComment Comment; + if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl)) + Comment = RawComment->getFormattedLines(Context.getSourceManager(), + Context.getDiagnostics()); + + // Build declaration fragments and sub-heading for the protocol. + DeclarationFragments Declaration = + DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(Decl); + DeclarationFragments SubHeading = + DeclarationFragmentsBuilder::getSubHeading(Decl); + + ObjCProtocolRecord *ObjCProtocolRecord = API.addObjCProtocol( + Name, USR, Loc, Availability, Comment, Declaration, SubHeading); + + recordObjCMethods(ObjCProtocolRecord, Decl->methods()); + recordObjCProperties(ObjCProtocolRecord, Decl->properties()); + recordObjCProtocols(ObjCProtocolRecord, Decl->protocols()); + + return true; + } + private: /// Get availability information of the declaration \p D. AvailabilityInfo getAvailability(const Decl *D) const { diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 3faf9cd..1acb67a 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -393,6 +393,10 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) { Kind["identifier"] = AddLangPrefix("class"); Kind["displayName"] = "Class"; break; + case APIRecord::RK_ObjCProtocol: + Kind["identifier"] = AddLangPrefix("protocol"); + Kind["displayName"] = "Protocol"; + break; } return Kind; @@ -593,6 +597,10 @@ Object SymbolGraphSerializer::serialize() { for (const auto &ObjCInterface : API.getObjCInterfaces()) serializeObjCContainerRecord(*ObjCInterface.second); + // Serialize Objective-C protocol records in the API set. + for (const auto &ObjCProtocol : API.getObjCProtocols()) + serializeObjCContainerRecord(*ObjCProtocol.second); + Root["symbols"] = std::move(Symbols); Root["relationhips"] = std::move(Relationships); |