clang 20.0.0git
SymbolGraphSerializer.h
Go to the documentation of this file.
1//===- ExtractAPI/Serialization/SymbolGraphSerializer.h ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines the SymbolGraphSerializer class.
11///
12/// Implement an APISetVisitor to serialize the APISet into the Symbol Graph
13/// format for ExtractAPI. See https://github.com/apple/swift-docc-symbolkit.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
18#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
19
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/SmallString.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/StringMap.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/ADT/StringSet.h"
29#include "llvm/ADT/Twine.h"
30#include "llvm/Support/JSON.h"
31#include "llvm/Support/VersionTuple.h"
32#include "llvm/Support/raw_ostream.h"
33#include <optional>
34
35namespace clang {
36namespace extractapi {
37
38using namespace llvm::json;
39
40/// Common options to customize the visitor output.
42 /// Do not include unnecessary whitespaces to save space.
43 bool Compact = true;
45};
46
47/// A representation of the contents of a given module symbol graph
49 ExtendedModule() = default;
52 // Copies are expensive so disable them.
53 ExtendedModule(const ExtendedModule &EM) = delete;
55
56 /// Add a symbol to the module, do not store the resulting pointer or use it
57 /// across insertions.
58 Object *addSymbol(Object &&Symbol);
59
60 void addRelationship(Object &&Relationship);
61
62 /// A JSON array of formatted symbols from an \c APISet.
63 Array Symbols;
64
65 /// A JSON array of formatted symbol relationships from an \c APISet.
67};
68
69/// The visitor that organizes API information in the Symbol Graph format.
70///
71/// The Symbol Graph format (https://github.com/apple/swift-docc-symbolkit)
72/// models an API set as a directed graph, where nodes are symbol declarations,
73/// and edges are relationships between the connected symbols.
74class SymbolGraphSerializer : public APISetVisitor<SymbolGraphSerializer> {
75private:
77 /// The main symbol graph that contains symbols that are either top-level or a
78 /// are related to symbols defined in this product/module.
79 ExtendedModule MainModule;
80
81 /// Additional symbol graphs that contain symbols that are related to symbols
82 /// defined in another product/module. The key of this map is the module name
83 /// of the extended module.
84 llvm::StringMap<ExtendedModule> ExtendedModules;
85
86 /// The Symbol Graph format version used by this serializer.
87 static const VersionTuple FormatVersion;
88
89 /// Indicates whether to take into account the extended module. This is only
90 /// useful for \c serializeSingleSymbolSGF.
91 bool ForceEmitToMainModule;
92
93 // Stores the references required to construct path components for the
94 // currently visited APIRecord.
96
97 /// The list of symbols to ignore.
98 ///
99 /// Note: This should be consulted before emitting a symbol.
100 const APIIgnoresList &IgnoresList;
101
102 const bool EmitSymbolLabelsForTesting = false;
103
104 const bool SkipSymbolsInCategoriesToExternalTypes = false;
105
106 /// The object instantiated by the last call to serializeAPIRecord.
107 Object *CurrentSymbol = nullptr;
108
109 /// The module to which \p CurrentSymbol belongs too.
110 ExtendedModule *ModuleForCurrentSymbol = nullptr;
111
112public:
113 static void
114 serializeMainSymbolGraph(raw_ostream &OS, const APISet &API,
115 const APIIgnoresList &IgnoresList,
116 SymbolGraphSerializerOption Options = {});
117
119 raw_ostream &MainOutput, const APISet &API,
120 const APIIgnoresList &IgnoresList,
121 llvm::function_ref<
122 std::unique_ptr<llvm::raw_pwrite_stream>(llvm::Twine BaseFileName)>
123 CreateOutputStream,
124 SymbolGraphSerializerOption Options = {});
125
126 /// Serialize a single symbol SGF. This is primarily used for libclang.
127 ///
128 /// \returns an optional JSON Object representing the payload that libclang
129 /// expects for providing symbol information for a single symbol. If this is
130 /// not a known symbol returns \c std::nullopt.
131 static std::optional<Object> serializeSingleSymbolSGF(StringRef USR,
132 const APISet &API);
133
134private:
135 /// The kind of a relationship between two symbols.
136 enum RelationshipKind {
137 /// The source symbol is a member of the target symbol.
138 /// For example enum constants are members of the enum, class/instance
139 /// methods are members of the class, etc.
140 MemberOf,
141
142 /// The source symbol is inherited from the target symbol.
143 InheritsFrom,
144
145 /// The source symbol conforms to the target symbol.
146 /// For example Objective-C protocol conformances.
147 ConformsTo,
148
149 /// The source symbol is an extension to the target symbol.
150 /// For example Objective-C categories extending an external type.
151 ExtensionTo,
152 };
153
154 /// Serialize a single record.
155 void serializeSingleRecord(const APIRecord *Record);
156
157 /// Get the string representation of the relationship kind.
158 static StringRef getRelationshipString(RelationshipKind Kind);
159
160 void serializeRelationship(RelationshipKind Kind,
161 const SymbolReference &Source,
162 const SymbolReference &Target,
163 ExtendedModule &Into);
164
165 enum ConstraintKind { Conformance, ConditionalConformance };
166
167 static StringRef getConstraintString(ConstraintKind Kind);
168
169 /// Serialize the APIs in \c ExtendedModule.
170 ///
171 /// \returns a JSON object that contains the root of the formatted
172 /// Symbol Graph.
173 Object serializeGraph(StringRef ModuleName, ExtendedModule &&EM);
174
175 /// Serialize the APIs in \c ExtendedModule in the Symbol Graph format and
176 /// write them to the provide stream.
177 void serializeGraphToStream(raw_ostream &OS,
179 StringRef ModuleName, ExtendedModule &&EM);
180
181 /// Synthesize the metadata section of the Symbol Graph format.
182 ///
183 /// The metadata section describes information about the Symbol Graph itself,
184 /// including the format version and the generator information.
185 Object serializeMetadata() const;
186
187 /// Synthesize the module section of the Symbol Graph format.
188 ///
189 /// The module section contains information about the product that is defined
190 /// by the given API set.
191 /// Note that "module" here is not to be confused with the Clang/C++ module
192 /// concept.
193 Object serializeModuleObject(StringRef ModuleName) const;
194
195 Array serializePathComponents(const APIRecord *Record) const;
196
197 /// Determine if the given \p Record should be skipped during serialization.
198 bool shouldSkip(const APIRecord *Record) const;
199
200 ExtendedModule &getModuleForCurrentSymbol();
201
202 /// Format the common API information for \p Record.
203 ///
204 /// This handles the shared information of all kinds of API records,
205 /// for example identifier, source location and path components. The resulting
206 /// object is then augmented with kind-specific symbol information in
207 /// subsequent visit* methods by accessing the \p State member variable. This
208 /// method also checks if the given \p Record should be skipped during
209 /// serialization. This should be called only once per concrete APIRecord
210 /// instance and the first visit* method to be called is responsible for
211 /// calling this. This is normally visitAPIRecord unless a walkUpFromFoo
212 /// method is implemented along the inheritance hierarchy in which case the
213 /// visitFoo method needs to call this.
214 ///
215 /// \returns \c nullptr if this \p Record should be skipped, or a pointer to
216 /// JSON object containing common symbol information of \p Record. Do not
217 /// store the returned pointer only use it to augment the object with record
218 /// specific information as it directly points to the object in the
219 /// \p ExtendedModule, the pointer won't be valid as soon as another object is
220 /// inserted into the module.
221 void serializeAPIRecord(const APIRecord *Record);
222
223public:
224 // Handle if records should be skipped at this level of the traversal to
225 // ensure that children of skipped records aren't serialized.
227
228 bool visitAPIRecord(const APIRecord *Record);
229
230 /// Visit a global function record.
232
234
236
239
241
243
245
247
248 bool
250
253
254 bool
256
258
260
264
266
267 bool
269
272
273 SymbolGraphSerializer(const APISet &API, const APIIgnoresList &IgnoresList,
274 bool EmitSymbolLabelsForTesting = false,
275 bool ForceEmitToMainModule = false,
276 bool SkipSymbolsInCategoriesToExternalTypes = false)
277 : Base(API), ForceEmitToMainModule(ForceEmitToMainModule),
278 IgnoresList(IgnoresList),
279 EmitSymbolLabelsForTesting(EmitSymbolLabelsForTesting),
280 SkipSymbolsInCategoriesToExternalTypes(
281 SkipSymbolsInCategoriesToExternalTypes) {}
282};
283
284} // namespace extractapi
285} // namespace clang
286
287#endif // LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
This file defines the ExtractAPI APISetVisitor interface.
This file defines the APIRecord-based structs and the APISet class.
enum clang::sema::@1712::IndirectLocalPathEntry::EntryKind Kind
llvm::MachO::Target Target
Definition: MachO.h:51
llvm::MachO::Record Record
Definition: MachO.h:31
The base interface of visitors for API information, the interface and usage is almost identical to Re...
Definition: APISetVisitor.h:76
APISet holds the set of API records collected from given inputs.
Definition: API.h:1427
The visitor that organizes API information in the Symbol Graph format.
SymbolGraphSerializer(const APISet &API, const APIIgnoresList &IgnoresList, bool EmitSymbolLabelsForTesting=false, bool ForceEmitToMainModule=false, bool SkipSymbolsInCategoriesToExternalTypes=false)
bool visitCXXFieldTemplateRecord(const CXXFieldTemplateRecord *Record)
bool traverseObjCCategoryRecord(const ObjCCategoryRecord *Record)
bool visitGlobalVariableTemplatePartialSpecializationRecord(const GlobalVariableTemplatePartialSpecializationRecord *Record)
bool visitClassTemplateRecord(const ClassTemplateRecord *Record)
bool visitCXXClassRecord(const CXXClassRecord *Record)
bool visitGlobalFunctionTemplateRecord(const GlobalFunctionTemplateRecord *Record)
bool visitCXXMethodRecord(const CXXMethodRecord *Record)
bool visitObjCInstanceVariableRecord(const ObjCInstanceVariableRecord *Record)
bool visitObjCInterfaceRecord(const ObjCInterfaceRecord *Record)
bool walkUpFromTypedefRecord(const TypedefRecord *Record)
bool visitCXXMethodTemplateRecord(const CXXMethodTemplateRecord *Record)
bool visitClassTemplatePartialSpecializationRecord(const ClassTemplatePartialSpecializationRecord *Record)
bool walkUpFromObjCCategoryRecord(const ObjCCategoryRecord *Record)
bool visitConceptRecord(const ConceptRecord *Record)
bool visitGlobalVariableTemplateRecord(const GlobalVariableTemplateRecord *Record)
bool traverseAPIRecord(const APIRecord *Record)
static void serializeWithExtensionGraphs(raw_ostream &MainOutput, const APISet &API, const APIIgnoresList &IgnoresList, llvm::function_ref< std::unique_ptr< llvm::raw_pwrite_stream >(llvm::Twine BaseFileName)> CreateOutputStream, SymbolGraphSerializerOption Options={})
bool visitGlobalFunctionRecord(const GlobalFunctionRecord *Record)
Visit a global function record.
bool visitTypedefRecord(const TypedefRecord *Record)
static std::optional< Object > serializeSingleSymbolSGF(StringRef USR, const APISet &API)
Serialize a single symbol SGF.
bool visitObjCCategoryRecord(const ObjCCategoryRecord *Record)
bool visitObjCMethodRecord(const ObjCMethodRecord *Record)
bool visitObjCContainerRecord(const ObjCContainerRecord *Record)
static void serializeMainSymbolGraph(raw_ostream &OS, const APISet &API, const APIIgnoresList &IgnoresList, SymbolGraphSerializerOption Options={})
The JSON file list parser is used to communicate input to InstallAPI.
A type that provides access to a new line separated list of symbol names to ignore when extracting AP...
The base representation of an API record. Holds common symbol information.
Definition: API.h:185
A representation of the contents of a given module symbol graph.
ExtendedModule(ExtendedModule &&EM)=default
void addRelationship(Object &&Relationship)
Object * addSymbol(Object &&Symbol)
Add a symbol to the module, do not store the resulting pointer or use it across insertions.
ExtendedModule & operator=(ExtendedModule &&EM)=default
ExtendedModule(const ExtendedModule &EM)=delete
ExtendedModule & operator=(const ExtendedModule &EM)=delete
Array Symbols
A JSON array of formatted symbols from an APISet.
Array Relationships
A JSON array of formatted symbol relationships from an APISet.
This holds information associated with global functions.
Definition: API.h:400
This holds information associated with Objective-C categories.
Definition: API.h:1303
The base representation of an Objective-C container record.
Definition: API.h:1179
This holds information associated with Objective-C instance variables.
Definition: API.h:1079
This holds information associated with Objective-C interfaces/classes.
Definition: API.h:1336
This holds information associated with Objective-C methods.
Definition: API.h:1101
Common options to customize the visitor output.
bool Compact
Do not include unnecessary whitespaces to save space.
This holds information associated with typedefs.
Definition: API.h:1404