evelez7 created this revision. Herald added a reviewer: ributzka. Herald added a project: All. evelez7 requested review of this revision. Herald added a reviewer: dang. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Delete unnecessary includes, revert SymbolGraphSerializer hidden namespace function names, move IgnoresList, Options to SGS Depends on D151293 <https://reviews.llvm.org/D151293> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D151402 Files: clang/include/clang/ExtractAPI/Serialization/SerializerBase.h clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
Index: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp =================================================================== --- clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -14,16 +14,11 @@ #include "clang/ExtractAPI/Serialization/SymbolGraphSerializer.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Version.h" -#include "clang/ExtractAPI/API.h" -#include "clang/ExtractAPI/APIIgnoresList.h" #include "clang/ExtractAPI/DeclarationFragments.h" -#include "clang/ExtractAPI/Serialization/SerializerBase.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLFunctionalExtras.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/JSON.h" #include "llvm/Support/Path.h" #include "llvm/Support/VersionTuple.h" #include <optional> @@ -38,14 +33,14 @@ /// Helper function to inject a JSON object \p Obj into another object \p Paren /// at position \p Key. -void visitObject(Object &Paren, StringRef Key, std::optional<Object> Obj) { +void serializeObject(Object &Paren, StringRef Key, std::optional<Object> Obj) { if (Obj) Paren[Key] = std::move(*Obj); } /// Helper function to inject a JSON array \p Array into object \p Paren at /// position \p Key. -void visitArray(Object &Paren, StringRef Key, std::optional<Array> Array) { +void serializeArray(Object &Paren, StringRef Key, std::optional<Array> Array) { if (Array) Paren[Key] = std::move(*Array); } @@ -66,7 +61,7 @@ /// /// \returns \c std::nullopt if the version \p V is empty, or an \c Object /// containing the semantic version representation of \p V. -std::optional<Object> visitSemanticVersion(const VersionTuple &V) { +std::optional<Object> serializeSemanticVersion(const VersionTuple &V) { if (V.empty()) return std::nullopt; @@ -81,11 +76,11 @@ /// /// The OS information in Symbol Graph contains the \c name of the OS, and an /// optional \c minimumVersion semantic version field. -Object visitOperatingSystem(const Triple &T) { +Object serializeOperatingSystem(const Triple &T) { Object OS; OS["name"] = T.getOSTypeName(T.getOS()); - visitObject(OS, "minimumVersion", - visitSemanticVersion(T.getMinimumSupportedOSVersion())); + serializeObject(OS, "minimumVersion", + serializeSemanticVersion(T.getMinimumSupportedOSVersion())); return OS; } @@ -93,16 +88,16 @@ /// /// The platform object describes a target platform triple in corresponding /// three fields: \c architecture, \c vendor, and \c operatingSystem. -Object visitPlatform(const Triple &T) { +Object serializePlatform(const Triple &T) { Object Platform; Platform["architecture"] = T.getArchName(); Platform["vendor"] = T.getVendorName(); - Platform["operatingSystem"] = visitOperatingSystem(T); + Platform["operatingSystem"] = serializeOperatingSystem(T); return Platform; } /// Serialize a source position. -Object visitSourcePosition(const PresumedLoc &Loc) { +Object serializeSourcePosition(const PresumedLoc &Loc) { assert(Loc.isValid() && "invalid source position"); Object SourcePosition; @@ -117,10 +112,10 @@ /// \param Loc The presumed location to serialize. /// \param IncludeFileURI If true, include the file path of \p Loc as a URI. /// Defaults to false. -Object visitSourceLocation(const PresumedLoc &Loc, - bool IncludeFileURI = false) { +Object serializeSourceLocation(const PresumedLoc &Loc, + bool IncludeFileURI = false) { Object SourceLocation; - visitObject(SourceLocation, "position", visitSourcePosition(Loc)); + serializeObject(SourceLocation, "position", serializeSourcePosition(Loc)); if (IncludeFileURI) { std::string FileURI = "file://"; @@ -133,11 +128,11 @@ } /// Serialize a source range with begin and end locations. -Object visitSourceRange(const PresumedLoc &BeginLoc, - const PresumedLoc &EndLoc) { +Object serializeSourceRange(const PresumedLoc &BeginLoc, + const PresumedLoc &EndLoc) { Object SourceRange; - visitObject(SourceRange, "start", visitSourcePosition(BeginLoc)); - visitObject(SourceRange, "end", visitSourcePosition(EndLoc)); + serializeObject(SourceRange, "start", serializeSourcePosition(BeginLoc)); + serializeObject(SourceRange, "end", serializeSourcePosition(EndLoc)); return SourceRange; } @@ -152,7 +147,8 @@ /// /// \returns \c std::nullopt if the symbol has default availability attributes, /// or an \c Array containing the formatted availability information. -std::optional<Array> visitAvailability(const AvailabilitySet &Availabilities) { +std::optional<Array> +serializeAvailability(const AvailabilitySet &Availabilities) { if (Availabilities.isDefault()) return std::nullopt; @@ -173,12 +169,12 @@ if (AvailInfo.Unavailable) Availability["isUnconditionallyUnavailable"] = true; else { - visitObject(Availability, "introducedVersion", - visitSemanticVersion(AvailInfo.Introduced)); - visitObject(Availability, "deprecatedVersion", - visitSemanticVersion(AvailInfo.Deprecated)); - visitObject(Availability, "obsoletedVersion", - visitSemanticVersion(AvailInfo.Obsoleted)); + serializeObject(Availability, "introducedVersion", + serializeSemanticVersion(AvailInfo.Introduced)); + serializeObject(Availability, "deprecatedVersion", + serializeSemanticVersion(AvailInfo.Deprecated)); + serializeObject(Availability, "obsoletedVersion", + serializeSemanticVersion(AvailInfo.Obsoleted)); } AvailabilityArray.emplace_back(std::move(Availability)); } @@ -218,7 +214,7 @@ /// /// The identifier property of a symbol contains the USR for precise and unique /// references, and the interface language name. -Object visitIdentifier(const APIRecord &Record, Language Lang) { +Object serializeIdentifier(const APIRecord &Record, Language Lang) { Object Identifier; Identifier["precise"] = Record.USR; Identifier["interfaceLanguage"] = getLanguageName(Lang); @@ -242,7 +238,7 @@ /// /// \returns \c std::nullopt if \p Comment is empty, or an \c Object containing /// the formatted lines. -std::optional<Object> visitDocComment(const DocComment &Comment) { +std::optional<Object> serializeDocComment(const DocComment &Comment) { if (Comment.empty()) return std::nullopt; @@ -251,11 +247,11 @@ for (const auto &CommentLine : Comment) { Object Line; Line["text"] = CommentLine.Text; - visitObject(Line, "range", - visitSourceRange(CommentLine.Begin, CommentLine.End)); + serializeObject(Line, "range", + serializeSourceRange(CommentLine.Begin, CommentLine.End)); LinesArray.emplace_back(std::move(Line)); } - visitArray(DocComment, "lines", LinesArray); + serializeArray(DocComment, "lines", LinesArray); return DocComment; } @@ -294,7 +290,8 @@ /// /// \returns \c std::nullopt if \p DF is empty, or an \c Array containing the /// formatted declaration fragments array. -std::optional<Array> visitDeclarationFragments(const DeclarationFragments &DF) { +std::optional<Array> +serializeDeclarationFragments(const DeclarationFragments &DF) { if (DF.getFragments().empty()) return std::nullopt; @@ -320,20 +317,22 @@ /// - \c subHeading : An array of declaration fragments that provides tags, /// and potentially more tokens (for example the \c +/- symbol for /// Objective-C methods). Can be used as sub-headings for documentation. -Object visitNames(const APIRecord &Record) { +Object serializeNames(const APIRecord &Record) { Object Names; Names["title"] = Record.Name; - visitArray(Names, "subHeading", visitDeclarationFragments(Record.SubHeading)); + serializeArray(Names, "subHeading", + serializeDeclarationFragments(Record.SubHeading)); DeclarationFragments NavigatorFragments; NavigatorFragments.append(Record.Name, DeclarationFragments::FragmentKind::Identifier, /*PreciseIdentifier*/ ""); - visitArray(Names, "navigator", visitDeclarationFragments(NavigatorFragments)); + serializeArray(Names, "navigator", + serializeDeclarationFragments(NavigatorFragments)); return Names; } -Object visitSymbolKind(APIRecord::RecordKind RK, Language Lang) { +Object serializeSymbolKind(APIRecord::RecordKind RK, Language Lang) { auto AddLangPrefix = [&Lang](StringRef S) -> std::string { return (getLanguageName(Lang) + "." + S).str(); }; @@ -418,27 +417,27 @@ /// The Symbol Graph symbol kind property contains a shorthand \c identifier /// which is prefixed by the source language name, useful for tooling to parse /// the kind, and a \c displayName for rendering human-readable names. -Object visitSymbolKind(const APIRecord &Record, Language Lang) { - return visitSymbolKind(Record.getKind(), Lang); +Object serializeSymbolKind(const APIRecord &Record, Language Lang) { + return serializeSymbolKind(Record.getKind(), Lang); } template <typename RecordTy> -std::optional<Object> visitFunctionSignatureMixinImpl(const RecordTy &Record, - std::true_type) { +std::optional<Object> +serializeFunctionSignatureMixinImpl(const RecordTy &Record, std::true_type) { const auto &FS = Record.Signature; if (FS.empty()) return std::nullopt; Object Signature; - visitArray(Signature, "returns", - visitDeclarationFragments(FS.getReturnType())); + serializeArray(Signature, "returns", + serializeDeclarationFragments(FS.getReturnType())); Array Parameters; for (const auto &P : FS.getParameters()) { Object Parameter; Parameter["name"] = P.Name; - visitArray(Parameter, "declarationFragments", - visitDeclarationFragments(P.Fragments)); + serializeArray(Parameter, "declarationFragments", + serializeDeclarationFragments(P.Fragments)); Parameters.emplace_back(std::move(Parameter)); } @@ -449,8 +448,8 @@ } template <typename RecordTy> -std::optional<Object> visitFunctionSignatureMixinImpl(const RecordTy &Record, - std::false_type) { +std::optional<Object> +serializeFunctionSignatureMixinImpl(const RecordTy &Record, std::false_type) { return std::nullopt; } @@ -465,10 +464,10 @@ /// \returns \c std::nullopt if \p FS is empty, or an \c Object containing the /// formatted function signature. template <typename RecordTy> -void visitFunctionSignatureMixin(Object &Paren, const RecordTy &Record) { - visitObject(Paren, "functionSignature", - visitFunctionSignatureMixinImpl( - Record, has_function_signature<RecordTy>())); +void serializeFunctionSignatureMixin(Object &Paren, const RecordTy &Record) { + serializeObject(Paren, "functionSignature", + serializeFunctionSignatureMixinImpl( + Record, has_function_signature<RecordTy>())); } struct PathComponent { @@ -525,11 +524,11 @@ return FailedToFindParent; } -Object visitParentContext(const PathComponent &PC, Language Lang) { +Object serializeParentContext(const PathComponent &PC, Language Lang) { Object ParentContextElem; ParentContextElem["usr"] = PC.USR; ParentContextElem["name"] = PC.Name; - ParentContextElem["kind"] = visitSymbolKind(PC.Kind, Lang)["identifier"]; + ParentContextElem["kind"] = serializeSymbolKind(PC.Kind, Lang)["identifier"]; return ParentContextElem; } @@ -539,7 +538,7 @@ Array ParentContexts; generatePathComponents( Record, API, [Lang, &ParentContexts](const PathComponent &PC) { - ParentContexts.push_back(visitParentContext(PC, Lang)); + ParentContexts.push_back(serializeParentContext(PC, Lang)); }); return ParentContexts; @@ -547,24 +546,23 @@ } // namespace -void SymbolGraphSerializer::anchor() {} - /// Defines the format version emitted by SymbolGraphSerializer. const VersionTuple SymbolGraphSerializer::FormatVersion{0, 5, 3}; -Object SymbolGraphSerializer::visitMetadata() const { +Object SymbolGraphSerializer::serializeMetadata() const { Object Metadata; - visitObject(Metadata, "formatVersion", visitSemanticVersion(FormatVersion)); + serializeObject(Metadata, "formatVersion", + serializeSemanticVersion(FormatVersion)); Metadata["generator"] = clang::getClangFullVersion(); return Metadata; } -Object SymbolGraphSerializer::visitModule() const { +Object SymbolGraphSerializer::serializeModule() const { Object Module; // The user is expected to always pass `--product-name=` on the command line // to populate this field. Module["name"] = API.ProductName; - visitObject(Module, "platform", visitPlatform(API.getTarget())); + serializeObject(Module, "platform", serializePlatform(API.getTarget())); return Module; } @@ -587,20 +585,23 @@ template <typename RecordTy> std::optional<Object> -SymbolGraphSerializer::visitAPIRecord(const RecordTy &Record) const { +SymbolGraphSerializer::serializeAPIRecord(const RecordTy &Record) const { if (shouldSkip(Record)) return std::nullopt; Object Obj; - visitObject(Obj, "identifier", visitIdentifier(Record, API.getLanguage())); - visitObject(Obj, "kind", visitSymbolKind(Record, API.getLanguage())); - visitObject(Obj, "names", visitNames(Record)); - visitObject(Obj, "location", - visitSourceLocation(Record.Location, /*IncludeFileURI=*/true)); - visitArray(Obj, "availability", visitAvailability(Record.Availabilities)); - visitObject(Obj, "docComment", visitDocComment(Record.Comment)); - visitArray(Obj, "declarationFragments", - visitDeclarationFragments(Record.Declaration)); + serializeObject(Obj, "identifier", + serializeIdentifier(Record, API.getLanguage())); + serializeObject(Obj, "kind", serializeSymbolKind(Record, API.getLanguage())); + serializeObject(Obj, "names", serializeNames(Record)); + serializeObject( + Obj, "location", + serializeSourceLocation(Record.Location, /*IncludeFileURI=*/true)); + serializeArray(Obj, "availability", + serializeAvailability(Record.Availabilities)); + serializeObject(Obj, "docComment", serializeDocComment(Record.Comment)); + serializeArray(Obj, "declarationFragments", + serializeDeclarationFragments(Record.Declaration)); // TODO: Once we keep track of symbol access information serialize it // correctly here. Obj["accessLevel"] = "public"; @@ -613,27 +614,27 @@ })) return {}; - visitArray(Obj, "pathComponents", Array(PathComponentsNames)); + serializeArray(Obj, "pathComponents", Array(PathComponentsNames)); - visitFunctionSignatureMixin(Obj, Record); + serializeFunctionSignatureMixin(Obj, Record); return Obj; } template <typename MemberTy> -void SymbolGraphSerializer::visitMembers( +void SymbolGraphSerializer::serializeMembers( const APIRecord &Record, const SmallVector<std::unique_ptr<MemberTy>> &Members) { // Members should not be serialized if we aren't recursing. if (!ShouldRecurse) return; for (const auto &Member : Members) { - auto MemberRecord = visitAPIRecord(*Member); + auto MemberRecord = serializeAPIRecord(*Member); if (!MemberRecord) continue; Symbols.emplace_back(std::move(*MemberRecord)); - visitRelationship(RelationshipKind::MemberOf, *Member, Record); + serializeRelationship(RelationshipKind::MemberOf, *Member, Record); } } @@ -649,9 +650,9 @@ llvm_unreachable("Unhandled relationship kind"); } -void SymbolGraphSerializer::visitRelationship(RelationshipKind Kind, - SymbolReference Source, - SymbolReference Target) { +void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind, + SymbolReference Source, + SymbolReference Target) { Object Relationship; Relationship["source"] = Source.USR; Relationship["target"] = Target.USR; @@ -663,7 +664,7 @@ void SymbolGraphSerializer::visitGlobalFunctionRecord( const GlobalFunctionRecord &Record) { - auto Obj = visitAPIRecord(Record); + auto Obj = serializeAPIRecord(Record); if (!Obj) return; @@ -672,7 +673,7 @@ void SymbolGraphSerializer::visitGlobalVariableRecord( const GlobalVariableRecord &Record) { - auto Obj = visitAPIRecord(Record); + auto Obj = serializeAPIRecord(Record); if (!Obj) return; @@ -680,63 +681,63 @@ } void SymbolGraphSerializer::visitEnumRecord(const EnumRecord &Record) { - auto Enum = visitAPIRecord(Record); + auto Enum = serializeAPIRecord(Record); if (!Enum) return; Symbols.emplace_back(std::move(*Enum)); - visitMembers(Record, Record.Constants); + serializeMembers(Record, Record.Constants); } void SymbolGraphSerializer::visitStructRecord(const StructRecord &Record) { - auto Struct = visitAPIRecord(Record); + auto Struct = serializeAPIRecord(Record); if (!Struct) return; Symbols.emplace_back(std::move(*Struct)); - visitMembers(Record, Record.Fields); + serializeMembers(Record, Record.Fields); } void SymbolGraphSerializer::visitObjCContainerRecord( const ObjCContainerRecord &Record) { - auto ObjCContainer = visitAPIRecord(Record); + auto ObjCContainer = serializeAPIRecord(Record); if (!ObjCContainer) return; Symbols.emplace_back(std::move(*ObjCContainer)); - visitMembers(Record, Record.Ivars); - visitMembers(Record, Record.Methods); - visitMembers(Record, Record.Properties); + serializeMembers(Record, Record.Ivars); + serializeMembers(Record, Record.Methods); + serializeMembers(Record, Record.Properties); for (const auto &Protocol : Record.Protocols) // Record that Record conforms to Protocol. - visitRelationship(RelationshipKind::ConformsTo, Record, Protocol); + serializeRelationship(RelationshipKind::ConformsTo, Record, Protocol); 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. - visitRelationship(RelationshipKind::InheritsFrom, Record, - ObjCInterface->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) { - visitMembers(Record, Category->Ivars); - visitMembers(Record, Category->Methods); - visitMembers(Record, Category->Properties); + serializeMembers(Record, Category->Ivars); + serializeMembers(Record, Category->Methods); + serializeMembers(Record, Category->Properties); // Surface the protocols of the category to the interface. for (const auto &Protocol : Category->Protocols) - visitRelationship(RelationshipKind::ConformsTo, Record, Protocol); + serializeRelationship(RelationshipKind::ConformsTo, Record, Protocol); } } } void SymbolGraphSerializer::visitMacroDefinitionRecord( const MacroDefinitionRecord &Record) { - auto Macro = visitAPIRecord(Record); + auto Macro = serializeAPIRecord(Record); if (!Macro) return; @@ -773,12 +774,12 @@ visitTypedefRecord(*cast<TypedefRecord>(Record)); break; default: - if (auto Obj = visitAPIRecord(*Record)) { + if (auto Obj = serializeAPIRecord(*Record)) { Symbols.emplace_back(std::move(*Obj)); auto &ParentInformation = Record->ParentInformation; if (!ParentInformation.empty()) - visitRelationship(RelationshipKind::MemberOf, *Record, - *ParentInformation.ParentRecord); + serializeRelationship(RelationshipKind::MemberOf, *Record, + *ParentInformation.ParentRecord); } break; } @@ -794,7 +795,7 @@ if (ShouldDrop) return; - auto Typedef = visitAPIRecord(Record); + auto Typedef = serializeAPIRecord(Record); if (!Typedef) return; @@ -803,15 +804,15 @@ Symbols.emplace_back(std::move(*Typedef)); } -Object SymbolGraphSerializer::traverse() { +Object SymbolGraphSerializer::serialize() { APISetVisitor::traverseAPISet(); - return visitCurrentGraph(); + return serializeCurrentGraph(); } -Object SymbolGraphSerializer::visitCurrentGraph() { +Object SymbolGraphSerializer::serializeCurrentGraph() { Object Root; - visitObject(Root, "metadata", visitMetadata()); - visitObject(Root, "module", visitModule()); + serializeObject(Root, "metadata", serializeMetadata()); + serializeObject(Root, "module", serializeModule()); Root["symbols"] = std::move(Symbols); Root["relationships"] = std::move(Relationships); @@ -819,8 +820,8 @@ return Root; } -void SymbolGraphSerializer::traverseAPISet(raw_ostream &os) { - Object root = traverse(); +void SymbolGraphSerializer::serialize(raw_ostream &os) { + Object root = serialize(); if (Options.Compact) os << formatv("{0}", Value(std::move(root))) << "\n"; else @@ -843,11 +844,11 @@ /*Options.Compact*/ {true}, /*ShouldRecurse*/ false); Serializer.visitSingleRecord(Record); - visitObject(Root, "symbolGraph", Serializer.visitCurrentGraph()); + serializeObject(Root, "symbolGraph", Serializer.serializeCurrentGraph()); Language Lang = API.getLanguage(); - visitArray(Root, "parentContexts", - generateParentContexts(*Record, API, Lang)); + serializeArray(Root, "parentContexts", + generateParentContexts(*Record, API, Lang)); Array RelatedSymbols; @@ -871,11 +872,11 @@ RelatedSymbol["moduleName"] = API.ProductName; RelatedSymbol["isSystem"] = RelatedRecord->IsFromSystemHeader; - visitArray(RelatedSymbol, "parentContexts", - generateParentContexts(*RelatedRecord, API, Lang)); + serializeArray(RelatedSymbol, "parentContexts", + generateParentContexts(*RelatedRecord, API, Lang)); RelatedSymbols.push_back(std::move(RelatedSymbol)); } - visitArray(Root, "relatedSymbols", RelatedSymbols); + serializeArray(Root, "relatedSymbols", RelatedSymbols); return Root; } Index: clang/lib/ExtractAPI/ExtractAPIConsumer.cpp =================================================================== --- clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -446,7 +446,7 @@ // the Symbol Graph format. // FIXME: Make the kind of APISerializer configurable. SymbolGraphSerializer SGSerializer(*API, IgnoresList); - SGSerializer.traverseAPISet(*OS); + SGSerializer.serialize(*OS); OS.reset(); } Index: clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h =================================================================== --- clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h +++ clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h @@ -9,15 +9,14 @@ /// \file /// This file defines the SymbolGraphSerializer class. /// -/// Implement an APISetVisitor for the Symbol Graph format for ExtractAPI. -/// See https://github.com/apple/swift-docc-symbolkit. +/// Implement an APISetVisitor to serialize the APISet into the Symbol Graph +/// format for ExtractAPI. See https://github.com/apple/swift-docc-symbolkit. /// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H #define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H -#include "clang/ExtractAPI/API.h" #include "clang/ExtractAPI/APIIgnoresList.h" #include "clang/ExtractAPI/Serialization/SerializerBase.h" #include "llvm/ADT/SmallVector.h" @@ -31,14 +30,18 @@ using namespace llvm::json; +/// Common options to customize the visitor output. +struct SymbolGraphSerializerOption { + /// Do not include unnecessary whitespaces to save space. + bool Compact; +}; + /// The visitor that organizes API information in the Symbol Graph format. /// /// The Symbol Graph format (https://github.com/apple/swift-docc-symbolkit) /// models an API set as a directed graph, where nodes are symbol declarations, /// and edges are relationships between the connected symbols. class SymbolGraphSerializer : public APISetVisitor<SymbolGraphSerializer> { - virtual void anchor(); - /// A JSON array of formatted symbols in \c APISet. Array Symbols; @@ -57,11 +60,10 @@ /// /// \returns a JSON object that contains the root of the formatted /// Symbol Graph. - Object traverse(); + Object serialize(); - /// Implement the APISetVisitor::traverseAPISet interface. Wrap - /// serialize(void) and write out the serialized JSON object to \p os. - void traverseAPISet(raw_ostream &os); + /// Wrap serialize(void) and write out the serialized JSON object to \p os. + void serialize(raw_ostream &os); /// Serialize a single symbol SGF. This is primarily used for libclang. /// @@ -91,13 +93,13 @@ private: /// Just serialize the currently recorded objects in Symbol Graph format. - Object visitCurrentGraph(); + Object serializeCurrentGraph(); /// Synthesize the metadata section of the Symbol Graph format. /// /// The metadata section describes information about the Symbol Graph itself, /// including the format version and the generator information. - Object visitMetadata() const; + Object serializeMetadata() const; /// Synthesize the module section of the Symbol Graph format. /// @@ -105,7 +107,7 @@ /// by the given API set. /// Note that "module" here is not to be confused with the Clang/C++ module /// concept. - Object visitModule() const; + Object serializeModule() const; /// Determine if the given \p Record should be skipped during serialization. bool shouldSkip(const APIRecord &Record) const; @@ -121,20 +123,28 @@ /// \returns \c std::nullopt if this \p Record should be skipped, or a JSON /// object containing common symbol information of \p Record. template <typename RecordTy> - std::optional<Object> visitAPIRecord(const RecordTy &Record) const; + std::optional<Object> serializeAPIRecord(const RecordTy &Record) const; /// Helper method to serialize second-level member records of \p Record and /// the member-of relationships. template <typename MemberTy> - void visitMembers(const APIRecord &Record, - const SmallVector<std::unique_ptr<MemberTy>> &Members); + void serializeMembers(const APIRecord &Record, + const SmallVector<std::unique_ptr<MemberTy>> &Members); /// Serialize the \p Kind relationship between \p Source and \p Target. /// /// Record the relationship between the two symbols in /// SymbolGraphSerializer::Relationships. - void visitRelationship(RelationshipKind Kind, SymbolReference Source, - SymbolReference Target); + void serializeRelationship(RelationshipKind Kind, SymbolReference Source, + SymbolReference Target); + +protected: + /// The list of symbols to ignore. + /// + /// Note: This should be consulted before emitting a symbol. + const APIIgnoresList &IgnoresList; + + SymbolGraphSerializerOption Options; public: /// Visit a global function record. @@ -162,10 +172,10 @@ void visitSingleRecord(const APIRecord *Record); SymbolGraphSerializer(const APISet &API, const APIIgnoresList &IgnoresList, - APISetVisitorOption Options = {}, + SymbolGraphSerializerOption Options = {}, bool ShouldRecurse = true) - : APISetVisitor(API, IgnoresList, Options), ShouldRecurse(ShouldRecurse) { - } + : APISetVisitor(API), ShouldRecurse(ShouldRecurse), + IgnoresList(IgnoresList), Options(Options) {} }; } // namespace extractapi Index: clang/include/clang/ExtractAPI/Serialization/SerializerBase.h =================================================================== --- clang/include/clang/ExtractAPI/Serialization/SerializerBase.h +++ clang/include/clang/ExtractAPI/Serialization/SerializerBase.h @@ -15,27 +15,13 @@ #define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H #include "clang/ExtractAPI/API.h" -#include "clang/ExtractAPI/APIIgnoresList.h" -#include "llvm/Support/JSON.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm::json; namespace clang { namespace extractapi { -/// Common options to customize the visitor output. -struct APISetVisitorOption { - /// Do not include unnecessary whitespaces to save space. - bool Compact; -}; - /// The base interface of visitors for API information. template <typename Derived> class APISetVisitor { public: - /// Traverse the API information to output to \p os. - void traverseAPISet(raw_ostream &os){}; - void traverseAPISet() { getDerived()->traverseGlobalVariableRecords(); @@ -93,11 +79,12 @@ for (const auto &Typedef : API.getTypedefs()) getDerived()->visitTypedefRecord(*Typedef.second); } + /// Visit a global function record. void visitGlobalFunctionRecord(const GlobalFunctionRecord &Record){}; /// Visit a global variable record. - void visitGlobalVariableRecord(const GlobalVariableRecord &Record); + void visitGlobalVariableRecord(const GlobalVariableRecord &Record){}; /// Visit an enum record. void visitEnumRecord(const EnumRecord &Record){}; @@ -120,13 +107,6 @@ protected: const APISet &API; - /// The list of symbols to ignore. - /// - /// Note: This should be consulted before emitting a symbol. - const APIIgnoresList &IgnoresList; - - APISetVisitorOption Options; - public: APISetVisitor() = delete; APISetVisitor(const APISetVisitor &) = delete; @@ -135,11 +115,8 @@ APISetVisitor &operator=(APISetVisitor &&) = delete; protected: - APISetVisitor(const APISet &API, const APIIgnoresList &IgnoresList, - APISetVisitorOption Options = {}) - : API(API), IgnoresList(IgnoresList), Options(Options) {} + APISetVisitor(const APISet &API) : API(API) {} - virtual ~APISetVisitor() = default; Derived *getDerived() { return static_cast<Derived *>(this); }; };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits