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