diff options
author | Zixu Wang <zixu_wang@apple.com> | 2022-03-30 17:21:33 -0700 |
---|---|---|
committer | Zixu Wang <zixu_wang@apple.com> | 2022-04-06 12:00:12 -0700 |
commit | 178aad9b946e3c5abe9df162e5c482fb4acae99c (patch) | |
tree | 7791542c16161e68d1b9b27d7eb9251faabdaa7f /clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | |
parent | 6b306233f78876a1d197ed6e1f05785505de7c63 (diff) | |
download | llvm-178aad9b946e3c5abe9df162e5c482fb4acae99c.zip llvm-178aad9b946e3c5abe9df162e5c482fb4acae99c.tar.gz llvm-178aad9b946e3c5abe9df162e5c482fb4acae99c.tar.bz2 |
[clang][extract-api] Add Objective-C Category support
Add (partial) support for Objective-C category records in ExtractAPI.
The current ExtractAPI collects everything for an Objective-C category,
but not fully serialized in the SymbolGraphSerializer. Categories
extending external interfaces are disgarded during serialization, and
categories extending known interfaces are merged (all members surfaced)
into the interfaces.
Differential Revision: https://reviews.llvm.org/D122774
Diffstat (limited to 'clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp')
-rw-r--r-- | clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | 99 |
1 files changed, 39 insertions, 60 deletions
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index f38a5bb..efe3c27 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -401,6 +401,11 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) { Kind["identifier"] = AddLangPrefix("class"); Kind["displayName"] = "Class"; break; + case APIRecord::RK_ObjCCategory: + // We don't serialize out standalone Objective-C category symbols yet. + llvm_unreachable("Serializing standalone Objective-C category symbols is " + "not supported."); + break; case APIRecord::RK_ObjCProtocol: Kind["identifier"] = AddLangPrefix("protocol"); Kind["displayName"] = "Protocol"; @@ -476,6 +481,21 @@ SymbolGraphSerializer::serializeAPIRecord(const APIRecord &Record) const { return Obj; } +template <typename MemberTy> +void SymbolGraphSerializer::serializeMembers( + const APIRecord &Record, + const SmallVector<std::unique_ptr<MemberTy>> &Members) { + for (const auto &Member : Members) { + auto MemberPathComponentGuard = makePathComponentGuard(Member->Name); + auto MemberRecord = serializeAPIRecord(*Member); + if (!MemberRecord) + continue; + + Symbols.emplace_back(std::move(*MemberRecord)); + serializeRelationship(RelationshipKind::MemberOf, *Member, Record); + } +} + StringRef SymbolGraphSerializer::getRelationshipString(RelationshipKind Kind) { switch (Kind) { case RelationshipKind::MemberOf: @@ -520,18 +540,7 @@ void SymbolGraphSerializer::serializeEnumRecord(const EnumRecord &Record) { return; Symbols.emplace_back(std::move(*Enum)); - - for (const auto &Constant : Record.Constants) { - auto EnumConstantPathComponentGuard = - makePathComponentGuard(Constant->Name); - auto EnumConstant = serializeAPIRecord(*Constant); - - if (!EnumConstant) - continue; - - Symbols.emplace_back(std::move(*EnumConstant)); - serializeRelationship(RelationshipKind::MemberOf, *Constant, Record); - } + serializeMembers(Record, Record.Constants); } void SymbolGraphSerializer::serializeStructRecord(const StructRecord &Record) { @@ -541,17 +550,7 @@ void SymbolGraphSerializer::serializeStructRecord(const StructRecord &Record) { return; Symbols.emplace_back(std::move(*Struct)); - - for (const auto &Field : Record.Fields) { - auto StructFieldPathComponentGuard = makePathComponentGuard(Field->Name); - auto StructField = serializeAPIRecord(*Field); - - if (!StructField) - continue; - - Symbols.emplace_back(std::move(*StructField)); - serializeRelationship(RelationshipKind::MemberOf, *Field, Record); - } + serializeMembers(Record, Record.Fields); } void SymbolGraphSerializer::serializeObjCContainerRecord( @@ -563,53 +562,33 @@ void SymbolGraphSerializer::serializeObjCContainerRecord( Symbols.emplace_back(std::move(*ObjCContainer)); - // Record instance variables and that the instance variables are members of - // the container. - for (const auto &Ivar : Record.Ivars) { - auto IvarPathComponentGuard = makePathComponentGuard(Ivar->Name); - auto ObjCIvar = serializeAPIRecord(*Ivar); - - if (!ObjCIvar) - continue; - - Symbols.emplace_back(std::move(*ObjCIvar)); - serializeRelationship(RelationshipKind::MemberOf, *Ivar, Record); - } - - // Record methods and that the methods are members of the container. - for (const auto &Method : Record.Methods) { - auto MethodPathComponentGuard = makePathComponentGuard(Method->Name); - auto ObjCMethod = serializeAPIRecord(*Method); - - if (!ObjCMethod) - continue; - - Symbols.emplace_back(std::move(*ObjCMethod)); - serializeRelationship(RelationshipKind::MemberOf, *Method, Record); - } - - // Record properties and that the properties are members of the container. - for (const auto &Property : Record.Properties) { - auto PropertyPathComponentGuard = makePathComponentGuard(Property->Name); - auto ObjCProperty = serializeAPIRecord(*Property); - - if (!ObjCProperty) - continue; - - Symbols.emplace_back(std::move(*ObjCProperty)); - serializeRelationship(RelationshipKind::MemberOf, *Property, Record); - } + serializeMembers(Record, Record.Ivars); + serializeMembers(Record, Record.Methods); + serializeMembers(Record, Record.Properties); for (const auto &Protocol : Record.Protocols) // Record that Record conforms to Protocol. serializeRelationship(RelationshipKind::ConformsTo, Record, Protocol); - if (auto *ObjCInterface = dyn_cast<ObjCInterfaceRecord>(&Record)) + if (auto *ObjCInterface = dyn_cast<ObjCInterfaceRecord>(&Record)) { if (!ObjCInterface->SuperClass.empty()) // If Record is an Objective-C interface record and it has a super class, // record that Record is inherited from SuperClass. serializeRelationship(RelationshipKind::InheritsFrom, Record, ObjCInterface->SuperClass); + + // Members of categories extending an interface are serialized as members of + // the interface. + for (const auto *Category : ObjCInterface->Categories) { + serializeMembers(Record, Category->Ivars); + serializeMembers(Record, Category->Methods); + serializeMembers(Record, Category->Properties); + + // Surface the protocols of the the category to the interface. + for (const auto &Protocol : Category->Protocols) + serializeRelationship(RelationshipKind::ConformsTo, Record, Protocol); + } + } } void SymbolGraphSerializer::serializeMacroDefinitionRecord( |