/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 |