aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/clang16/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
blob: 040bbcb649e9060fbc24b084731abd81d7b27d3a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

//===- ExtractAPI/Serialization/SymbolGraphSerializer.h ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines the SymbolGraphSerializer class.
///
/// Implement an APISerializer for 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"
#include "llvm/Support/JSON.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>

namespace clang {
namespace extractapi {

using namespace llvm::json;

/// The serializer 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 APISerializer {
  virtual void anchor();

  /// A JSON array of formatted symbols in \c APISet.
  Array Symbols;

  /// A JSON array of formatted symbol relationships in \c APISet.
  Array Relationships;

  /// The Symbol Graph format version used by this serializer.
  static const VersionTuple FormatVersion;

  /// Indicates whether child symbols should be serialized. This is mainly
  /// useful for \c serializeSingleSymbolSGF.
  bool ShouldRecurse;

public:
  /// Serialize the APIs in \c APISet in the Symbol Graph format.
  ///
  /// \returns a JSON object that contains the root of the formatted
  /// Symbol Graph.
  Object serialize();

  /// Implement the APISerializer::serialize interface. Wrap serialize(void) and
  /// write out the serialized JSON object to \p os.
  void serialize(raw_ostream &os) override;

  /// Serialize a single symbol SGF. This is primarily used for libclang.
  ///
  /// \returns an optional JSON Object representing the payload that libclang
  /// expects for providing symbol information for a single symbol. If this is
  /// not a known symbol returns \c None.
  static std::optional<Object> serializeSingleSymbolSGF(StringRef USR,
                                                        const APISet &API);

  /// The kind of a relationship between two symbols.
  enum RelationshipKind {
    /// The source symbol is a member of the target symbol.
    /// For example enum constants are members of the enum, class/instance
    /// methods are members of the class, etc.
    MemberOf,

    /// The source symbol is inherited from the target symbol.
    InheritsFrom,

    /// The source symbol conforms to the target symbol.
    /// For example Objective-C protocol conformances.
    ConformsTo,
  };

  /// Get the string representation of the relationship kind.
  static StringRef getRelationshipString(RelationshipKind Kind);

private:
  /// Just serialize the currently recorded objects in Symbol Graph format.
  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 serializeMetadata() const;

  /// Synthesize the module section of the Symbol Graph format.
  ///
  /// The module section contains information about the product that is defined
  /// by the given API set.
  /// Note that "module" here is not to be confused with the Clang/C++ module
  /// concept.
  Object serializeModule() const;

  /// Determine if the given \p Record should be skipped during serialization.
  bool shouldSkip(const APIRecord &Record) const;

  /// Format the common API information for \p Record.
  ///
  /// This handles the shared information of all kinds of API records,
  /// for example identifier and source location. The resulting object is then
  /// augmented with kind-specific symbol information by the caller.
  /// This method also checks if the given \p Record should be skipped during
  /// serialization.
  ///
  /// \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> 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 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 serializeRelationship(RelationshipKind Kind, SymbolReference Source,
                             SymbolReference Target);

  /// Serialize a global function record.
  void serializeGlobalFunctionRecord(const GlobalFunctionRecord &Record);

  /// Serialize a global variable record.
  void serializeGlobalVariableRecord(const GlobalVariableRecord &Record);

  /// Serialize an enum record.
  void serializeEnumRecord(const EnumRecord &Record);

  /// Serialize a struct record.
  void serializeStructRecord(const StructRecord &Record);

  /// Serialize an Objective-C container record.
  void serializeObjCContainerRecord(const ObjCContainerRecord &Record);

  /// Serialize a macro definition record.
  void serializeMacroDefinitionRecord(const MacroDefinitionRecord &Record);

  /// Serialize a typedef record.
  void serializeTypedefRecord(const TypedefRecord &Record);

  void serializeSingleRecord(const APIRecord *Record);

public:
  SymbolGraphSerializer(const APISet &API, const APIIgnoresList &IgnoresList,
                        APISerializerOption Options = {},
                        bool ShouldRecurse = true)
      : APISerializer(API, IgnoresList, Options), ShouldRecurse(ShouldRecurse) {
  }
};

} // namespace extractapi
} // namespace clang

#endif // LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif