diff options
author | Daniel Grumberg <dgrumberg@apple.com> | 2022-04-07 13:50:28 +0100 |
---|---|---|
committer | Daniel Grumberg <dgrumberg@apple.com> | 2022-04-11 19:05:24 +0100 |
commit | 236b6a0eb41a163510e65664e2160f599287326b (patch) | |
tree | 287e71d587ccc098c9d5cf5a2485920136ae7b08 /clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | |
parent | 2d0475e37169bee3d969c4e4b445e86c08539769 (diff) | |
download | llvm-236b6a0eb41a163510e65664e2160f599287326b.zip llvm-236b6a0eb41a163510e65664e2160f599287326b.tar.gz llvm-236b6a0eb41a163510e65664e2160f599287326b.tar.bz2 |
[clang][extract-api] Emit "functionSignature" in SGF for ObjC methods.
- Split GlobalRecord into two distinct types to be able to introduce
has_function_signature type trait.
- Add has_function_signature type trait.
- Serialize function signatures as part of serializeAPIRecord for
records that are known to have a function signature.
Differential Revision: https://reviews.llvm.org/D123304
Diffstat (limited to 'clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp')
-rw-r--r-- | clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | 136 |
1 files changed, 79 insertions, 57 deletions
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 2a3818e..045d5d6 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/JSON.h" #include "llvm/Support/Path.h" #include "llvm/Support/VersionTuple.h" +#include <type_traits> using namespace clang; using namespace clang::extractapi; @@ -285,39 +286,6 @@ Optional<Array> serializeDeclarationFragments(const DeclarationFragments &DF) { return Fragments; } -/// Serialize the function signature field of a function, as specified by the -/// Symbol Graph format. -/// -/// The Symbol Graph function signature property contains two arrays. -/// - The \c returns array is the declaration fragments of the return type; -/// - The \c parameters array contains names and declaration fragments of the -/// parameters. -/// -/// \returns \c None if \p FS is empty, or an \c Object containing the -/// formatted function signature. -Optional<Object> serializeFunctionSignature(const FunctionSignature &FS) { - if (FS.empty()) - return None; - - Object Signature; - serializeArray(Signature, "returns", - serializeDeclarationFragments(FS.getReturnType())); - - Array Parameters; - for (const auto &P : FS.getParameters()) { - Object Parameter; - Parameter["name"] = P.Name; - serializeArray(Parameter, "declarationFragments", - serializeDeclarationFragments(P.Fragments)); - Parameters.emplace_back(std::move(Parameter)); - } - - if (!Parameters.empty()) - Signature["parameters"] = std::move(Parameters); - - return Signature; -} - /// Serialize the \c names field of a symbol as specified by the Symbol Graph /// format. /// @@ -354,23 +322,14 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) { Object Kind; switch (Record.getKind()) { - case APIRecord::RK_Global: { - auto *GR = dyn_cast<GlobalRecord>(&Record); - switch (GR->GlobalKind) { - case GVKind::Function: - Kind["identifier"] = AddLangPrefix("func"); - Kind["displayName"] = "Function"; - break; - case GVKind::Variable: - Kind["identifier"] = AddLangPrefix("var"); - Kind["displayName"] = "Global Variable"; - break; - case GVKind::Unknown: - // Unknown global kind - break; - } + case APIRecord::RK_GlobalFunction: + Kind["identifier"] = AddLangPrefix("func"); + Kind["displayName"] = "Function"; + break; + case APIRecord::RK_GlobalVariable: + Kind["identifier"] = AddLangPrefix("var"); + Kind["displayName"] = "Global Variable"; break; - } case APIRecord::RK_EnumConstant: Kind["identifier"] = AddLangPrefix("enum.case"); Kind["displayName"] = "Enumeration Case"; @@ -430,6 +389,55 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) { return Kind; } +template <typename RecordTy> +Optional<Object> serializeFunctionSignatureMixinImpl(const RecordTy &Record, + std::true_type) { + const auto &FS = Record.Signature; + if (FS.empty()) + return None; + + Object Signature; + serializeArray(Signature, "returns", + serializeDeclarationFragments(FS.getReturnType())); + + Array Parameters; + for (const auto &P : FS.getParameters()) { + Object Parameter; + Parameter["name"] = P.Name; + serializeArray(Parameter, "declarationFragments", + serializeDeclarationFragments(P.Fragments)); + Parameters.emplace_back(std::move(Parameter)); + } + + if (!Parameters.empty()) + Signature["parameters"] = std::move(Parameters); + + return Signature; +} + +template <typename RecordTy> +Optional<Object> serializeFunctionSignatureMixinImpl(const RecordTy &Record, + std::false_type) { + return None; +} + +/// Serialize the function signature field, as specified by the +/// Symbol Graph format. +/// +/// The Symbol Graph function signature property contains two arrays. +/// - The \c returns array is the declaration fragments of the return type; +/// - The \c parameters array contains names and declaration fragments of the +/// parameters. +/// +/// \returns \c None if \p FS is empty, or an \c Object containing the +/// formatted function signature. +template <typename RecordTy> +void serializeFunctionSignatureMixin(Object &Paren, const RecordTy &Record) { + serializeObject(Paren, "functionSignature", + serializeFunctionSignatureMixinImpl( + Record, has_function_signature<RecordTy>())); +} + } // namespace void SymbolGraphSerializer::anchor() {} @@ -462,8 +470,9 @@ bool SymbolGraphSerializer::shouldSkip(const APIRecord &Record) const { return false; } +template <typename RecordTy> Optional<Object> -SymbolGraphSerializer::serializeAPIRecord(const APIRecord &Record) const { +SymbolGraphSerializer::serializeAPIRecord(const RecordTy &Record) const { if (shouldSkip(Record)) return None; @@ -485,6 +494,8 @@ SymbolGraphSerializer::serializeAPIRecord(const APIRecord &Record) const { Obj["accessLevel"] = "public"; serializeArray(Obj, "pathComponents", Array(PathComponents)); + serializeFunctionSignatureMixin(Obj, Record); + return Obj; } @@ -526,16 +537,24 @@ void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind, Relationships.emplace_back(std::move(Relationship)); } -void SymbolGraphSerializer::serializeGlobalRecord(const GlobalRecord &Record) { +void SymbolGraphSerializer::serializeGlobalFunctionRecord( + const GlobalFunctionRecord &Record) { auto GlobalPathComponentGuard = makePathComponentGuard(Record.Name); auto Obj = serializeAPIRecord(Record); if (!Obj) return; - if (Record.GlobalKind == GVKind::Function) - serializeObject(*Obj, "functionSignature", - serializeFunctionSignature(Record.Signature)); + Symbols.emplace_back(std::move(*Obj)); +} + +void SymbolGraphSerializer::serializeGlobalVariableRecord( + const GlobalVariableRecord &Record) { + auto GlobalPathComponentGuard = makePathComponentGuard(Record.Name); + + auto Obj = serializeAPIRecord(Record); + if (!Obj) + return; Symbols.emplace_back(std::move(*Obj)); } @@ -640,9 +659,12 @@ Object SymbolGraphSerializer::serialize() { serializeObject(Root, "metadata", serializeMetadata()); serializeObject(Root, "module", serializeModule()); - // Serialize global records in the API set. - for (const auto &Global : API.getGlobals()) - serializeGlobalRecord(*Global.second); + // Serialize global variables in the API set. + for (const auto &GlobalVar : API.getGlobalVariables()) + serializeGlobalVariableRecord(*GlobalVar.second); + + for (const auto &GlobalFunction : API.getGlobalFunctions()) + serializeGlobalFunctionRecord(*GlobalFunction.second); // Serialize enum records in the API set. for (const auto &Enum : API.getEnums()) |