Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/ExtractAPI/DeclarationFragments.h
Line
Count
Source
1
//===- ExtractAPI/DeclarationFragments.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 Declaration Fragments related classes.
11
///
12
/// Declaration Fragments represent parts of a symbol declaration tagged with
13
/// syntactic/semantic information.
14
/// See https://github.com/apple/swift-docc-symbolkit
15
///
16
//===----------------------------------------------------------------------===//
17
18
#ifndef LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
19
#define LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
20
21
#include "clang/AST/ASTContext.h"
22
#include "clang/AST/Decl.h"
23
#include "clang/AST/DeclCXX.h"
24
#include "clang/AST/DeclObjC.h"
25
#include "clang/Lex/MacroInfo.h"
26
#include "llvm/ADT/StringRef.h"
27
#include <vector>
28
29
namespace clang {
30
namespace extractapi {
31
32
/// DeclarationFragments is a vector of tagged important parts of a symbol's
33
/// declaration.
34
///
35
/// The fragments sequence can be joined to form spans of declaration text, with
36
/// attached information useful for purposes like syntax-highlighting etc.
37
/// For example:
38
/// \code
39
///   const -> keyword    "const"
40
///   int   -> type       "int"
41
///   pi;   -> identifier "pi"
42
/// \endcode
43
class DeclarationFragments {
44
public:
45
493
  DeclarationFragments() = default;
46
47
  /// The kind of a fragment.
48
  enum class FragmentKind {
49
    /// Unknown fragment kind.
50
    None,
51
52
    Keyword,
53
    Attribute,
54
    NumberLiteral,
55
    StringLiteral,
56
    Identifier,
57
58
    /// Identifier that refers to a type in the context.
59
    TypeIdentifier,
60
61
    /// Parameter that's used as generics in the context. For example template
62
    /// parameters.
63
    GenericParameter,
64
65
    /// External parameters in Objective-C methods.
66
    /// For example, \c forKey in
67
    /// \code{.m}
68
    ///   - (void) setValue:(Value)value forKey(Key)key
69
    /// \endcode
70
    ExternalParam,
71
72
    /// Internal/local parameters in Objective-C methods.
73
    /// For example, \c key in
74
    /// \code{.m}
75
    ///   - (void) setValue:(Value)value forKey(Key)key
76
    /// \endcode
77
    InternalParam,
78
79
    Text,
80
  };
81
82
  /// Fragment holds information of a single fragment.
83
  struct Fragment {
84
    std::string Spelling;
85
    FragmentKind Kind;
86
87
    /// The USR of the fragment symbol, if applicable.
88
    std::string PreciseIdentifier;
89
90
    Fragment(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier)
91
534
        : Spelling(Spelling), Kind(Kind), PreciseIdentifier(PreciseIdentifier) {
92
534
    }
93
  };
94
95
511
  const std::vector<Fragment> &getFragments() const { return Fragments; }
96
97
  /// Append a new Fragment to the end of the Fragments.
98
  ///
99
  /// \returns a reference to the DeclarationFragments object itself after
100
  /// appending to chain up consecutive appends.
101
  DeclarationFragments &append(StringRef Spelling, FragmentKind Kind,
102
543
                               StringRef PreciseIdentifier = "") {
103
543
    if (Kind == FragmentKind::Text && 
!Fragments.empty()175
&&
104
543
        
Fragments.back().Kind == FragmentKind::Text159
) {
105
      // If appending a text fragment, and the last fragment is also text,
106
      // merge into the last fragment.
107
9
      Fragments.back().Spelling.append(Spelling.data(), Spelling.size());
108
534
    } else {
109
534
      Fragments.emplace_back(Spelling, Kind, PreciseIdentifier);
110
534
    }
111
543
    return *this;
112
543
  }
113
114
  /// Append another DeclarationFragments to the end.
115
  ///
116
  /// Note: \p Other is moved from and cannot be used after a call to this
117
  /// method.
118
  ///
119
  /// \returns a reference to the DeclarationFragments object itself after
120
  /// appending to chain up consecutive appends.
121
176
  DeclarationFragments &append(DeclarationFragments &&Other) {
122
176
    Fragments.insert(Fragments.end(),
123
176
                     std::make_move_iterator(Other.Fragments.begin()),
124
176
                     std::make_move_iterator(Other.Fragments.end()));
125
176
    Other.Fragments.clear();
126
176
    return *this;
127
176
  }
128
129
  /// Append a text Fragment of a space character.
130
  ///
131
  /// \returns a reference to the DeclarationFragments object itself after
132
  /// appending to chain up consecutive appends.
133
  DeclarationFragments &appendSpace();
134
135
  /// Get the string description of a FragmentKind \p Kind.
136
  static StringRef getFragmentKindString(FragmentKind Kind);
137
138
  /// Get the corresponding FragmentKind from string \p S.
139
  static FragmentKind parseFragmentKindFromString(StringRef S);
140
141
private:
142
  std::vector<Fragment> Fragments;
143
};
144
145
/// Store function signature information with DeclarationFragments of the
146
/// return type and parameters.
147
class FunctionSignature {
148
public:
149
9
  FunctionSignature() = default;
150
151
  /// Parameter holds the name and DeclarationFragments of a single parameter.
152
  struct Parameter {
153
    std::string Name;
154
    DeclarationFragments Fragments;
155
156
    Parameter(StringRef Name, DeclarationFragments Fragments)
157
11
        : Name(Name), Fragments(Fragments) {}
158
  };
159
160
9
  const std::vector<Parameter> &getParameters() const { return Parameters; }
161
9
  const DeclarationFragments &getReturnType() const { return ReturnType; }
162
163
  FunctionSignature &addParameter(StringRef Name,
164
11
                                  DeclarationFragments Fragments) {
165
11
    Parameters.emplace_back(Name, Fragments);
166
11
    return *this;
167
11
  }
168
169
9
  void setReturnType(DeclarationFragments RT) { ReturnType = RT; }
170
171
  /// Determine if the FunctionSignature is empty.
172
  ///
173
  /// \returns true if the return type DeclarationFragments is empty and there
174
  /// is no parameter, otherwise false.
175
9
  bool empty() const {
176
9
    return Parameters.empty() && 
ReturnType.getFragments().empty()4
;
177
9
  }
178
179
private:
180
  std::vector<Parameter> Parameters;
181
  DeclarationFragments ReturnType;
182
};
183
184
/// A factory class to build DeclarationFragments for different kinds of Decl.
185
class DeclarationFragmentsBuilder {
186
public:
187
  /// Build DeclarationFragments for a variable declaration VarDecl.
188
  static DeclarationFragments getFragmentsForVar(const VarDecl *);
189
190
  /// Build DeclarationFragments for a function declaration FunctionDecl.
191
  static DeclarationFragments getFragmentsForFunction(const FunctionDecl *);
192
193
  /// Build DeclarationFragments for an enum constant declaration
194
  /// EnumConstantDecl.
195
  static DeclarationFragments
196
  getFragmentsForEnumConstant(const EnumConstantDecl *);
197
198
  /// Build DeclarationFragments for an enum declaration EnumDecl.
199
  static DeclarationFragments getFragmentsForEnum(const EnumDecl *);
200
201
  /// Build DeclarationFragments for a field declaration FieldDecl.
202
  static DeclarationFragments getFragmentsForField(const FieldDecl *);
203
204
  /// Build DeclarationFragments for a struct record declaration RecordDecl.
205
  static DeclarationFragments getFragmentsForStruct(const RecordDecl *);
206
207
  /// Build DeclarationFragments for an Objective-C category declaration
208
  /// ObjCCategoryDecl.
209
  static DeclarationFragments
210
  getFragmentsForObjCCategory(const ObjCCategoryDecl *);
211
212
  /// Build DeclarationFragments for an Objective-C interface declaration
213
  /// ObjCInterfaceDecl.
214
  static DeclarationFragments
215
  getFragmentsForObjCInterface(const ObjCInterfaceDecl *);
216
217
  /// Build DeclarationFragments for an Objective-C method declaration
218
  /// ObjCMethodDecl.
219
  static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *);
220
221
  /// Build DeclarationFragments for an Objective-C property declaration
222
  /// ObjCPropertyDecl.
223
  static DeclarationFragments
224
  getFragmentsForObjCProperty(const ObjCPropertyDecl *);
225
226
  /// Build DeclarationFragments for an Objective-C protocol declaration
227
  /// ObjCProtocolDecl.
228
  static DeclarationFragments
229
  getFragmentsForObjCProtocol(const ObjCProtocolDecl *);
230
231
  /// Build DeclarationFragments for a macro.
232
  ///
233
  /// \param Name name of the macro.
234
  /// \param MD the associated MacroDirective.
235
  static DeclarationFragments getFragmentsForMacro(StringRef Name,
236
                                                   const MacroDirective *MD);
237
238
  /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
239
  static DeclarationFragments
240
  getFragmentsForTypedef(const TypedefNameDecl *Decl);
241
242
  /// Build sub-heading fragments for a NamedDecl.
243
  static DeclarationFragments getSubHeading(const NamedDecl *);
244
245
  /// Build sub-heading fragments for an Objective-C method.
246
  static DeclarationFragments getSubHeading(const ObjCMethodDecl *);
247
248
  /// Build a sub-heading for macro \p Name.
249
  static DeclarationFragments getSubHeadingForMacro(StringRef Name);
250
251
  /// Build FunctionSignature for a function-like declaration \c FunctionT like
252
  /// FunctionDecl or ObjCMethodDecl.
253
  ///
254
  /// The logic and implementation of building a signature for a FunctionDecl
255
  /// and an ObjCMethodDecl are exactly the same, but they do not share a common
256
  /// base. This template helps reuse the code.
257
  template <typename FunctionT>
258
  static FunctionSignature getFunctionSignature(const FunctionT *);
259
260
private:
261
  DeclarationFragmentsBuilder() = delete;
262
263
  /// Build DeclarationFragments for a QualType.
264
  static DeclarationFragments getFragmentsForType(const QualType, ASTContext &,
265
                                                  DeclarationFragments &);
266
267
  /// Build DeclarationFragments for a Type.
268
  static DeclarationFragments getFragmentsForType(const Type *, ASTContext &,
269
                                                  DeclarationFragments &);
270
271
  /// Build DeclarationFragments for a NestedNameSpecifier.
272
  static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
273
                                                 ASTContext &,
274
                                                 DeclarationFragments &);
275
276
  /// Build DeclarationFragments for Qualifiers.
277
  static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);
278
279
  /// Build DeclarationFragments for a parameter variable declaration
280
  /// ParmVarDecl.
281
  static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
282
};
283
284
} // namespace extractapi
285
} // namespace clang
286
287
#endif // LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H