@@ -152,15 +152,266 @@ Error MustacheHTMLGenerator::generateDocs(
152
152
return Error::success ();
153
153
}
154
154
155
+ static json::Value
156
+ extractValue (const Location &L,
157
+ std::optional<StringRef> RepositoryUrl = std::nullopt) {
158
+ Object Obj = Object ();
159
+ // Should there be Start/End line numbers?
160
+ Obj.insert ({" LineNumber" , L.StartLineNumber });
161
+ Obj.insert ({" Filename" , L.Filename });
162
+
163
+ if (!L.IsFileInRootDir || !RepositoryUrl) {
164
+ return Obj;
165
+ }
166
+ SmallString<128 > FileURL (*RepositoryUrl);
167
+ sys::path::append (FileURL, sys::path::Style ::posix, L.Filename );
168
+ FileURL += " #" + std::to_string (L.StartLineNumber );
169
+ Obj.insert ({" FileURL" , FileURL});
170
+
171
+ return Obj;
172
+ }
173
+
174
+ static json::Value extractValue (const Reference &I,
175
+ StringRef CurrentDirectory) {
176
+ SmallString<64 > Path = I.getRelativeFilePath (CurrentDirectory);
177
+ sys::path::append (Path, I.getFileBaseName () + " .html" );
178
+ sys::path::native (Path, sys::path::Style ::posix);
179
+ Object Obj = Object ();
180
+ Obj.insert ({" Link" , Path});
181
+ Obj.insert ({" Name" , I.Name });
182
+ Obj.insert ({" QualName" , I.QualName });
183
+ Obj.insert ({" ID" , toHex (toStringRef (I.USR ))});
184
+ return Obj;
185
+ }
186
+
187
+ static json::Value extractValue (const TypedefInfo &I) {
188
+ // Not Supported
189
+ return nullptr ;
190
+ }
191
+
192
+ static json::Value extractValue (const CommentInfo &I) {
193
+ assert ((I.Kind == " BlockCommandComment" || I.Kind == " FullComment" ||
194
+ I.Kind == " ParagraphComment" || I.Kind == " TextComment" ) &&
195
+ " Unknown Comment type in CommentInfo." );
196
+
197
+ Object Obj = Object ();
198
+ json::Value Child = Object ();
199
+
200
+ // TextComment has no children, so return it.
201
+ if (I.Kind == " TextComment" ) {
202
+ Obj.insert ({" TextComment" , I.Text });
203
+ return Obj;
204
+ }
205
+
206
+ // BlockCommandComment needs to generate a Command key.
207
+ if (I.Kind == " BlockCommandComment" ) {
208
+ Child.getAsObject ()->insert ({" Command" , I.Name });
209
+ }
210
+
211
+ // Use the same handling for everything else.
212
+ // Only valid for:
213
+ // - BlockCommandComment
214
+ // - FullComment
215
+ // - ParagraphComment
216
+ json::Value ChildArr = Array ();
217
+ auto &CARef = *ChildArr.getAsArray ();
218
+ CARef.reserve (I.Children .size ());
219
+ for (const auto &C : I.Children )
220
+ CARef.emplace_back (extractValue (*C));
221
+ Child.getAsObject ()->insert ({" Children" , ChildArr});
222
+ Obj.insert ({I.Kind , Child});
223
+
224
+ return Obj;
225
+ }
226
+
227
+ static void maybeInsertLocation (std::optional<Location> Loc,
228
+ const ClangDocContext &CDCtx, Object &Obj) {
229
+ if (!Loc)
230
+ return ;
231
+ Location L = *Loc;
232
+ Obj.insert ({" Location" , extractValue (L, CDCtx.RepositoryUrl )});
233
+ }
234
+
235
+ static void extractDescriptionFromInfo (ArrayRef<CommentInfo> Descriptions,
236
+ json::Object &EnumValObj) {
237
+ if (Descriptions.empty ())
238
+ return ;
239
+ json::Value ArrDesc = Array ();
240
+ json::Array &ADescRef = *ArrDesc.getAsArray ();
241
+ for (const CommentInfo &Child : Descriptions)
242
+ ADescRef.emplace_back (extractValue (Child));
243
+ EnumValObj.insert ({" EnumValueComments" , ArrDesc});
244
+ }
245
+
246
+ static json::Value extractValue (const FunctionInfo &I, StringRef ParentInfoDir,
247
+ const ClangDocContext &CDCtx) {
248
+ Object Obj = Object ();
249
+ Obj.insert ({" Name" , I.Name });
250
+ Obj.insert ({" ID" , toHex (toStringRef (I.USR ))});
251
+ Obj.insert ({" Access" , getAccessSpelling (I.Access ).str ()});
252
+ Obj.insert ({" ReturnType" , extractValue (I.ReturnType .Type , ParentInfoDir)});
253
+
254
+ json::Value ParamArr = Array ();
255
+ for (const auto Val : enumerate(I.Params )) {
256
+ json::Value V = Object ();
257
+ auto &VRef = *V.getAsObject ();
258
+ VRef.insert ({" Name" , Val.value ().Name });
259
+ VRef.insert ({" Type" , Val.value ().Type .Name });
260
+ VRef.insert ({" End" , Val.index () + 1 == I.Params .size ()});
261
+ ParamArr.getAsArray ()->emplace_back (V);
262
+ }
263
+ Obj.insert ({" Params" , ParamArr});
264
+
265
+ maybeInsertLocation (I.DefLoc , CDCtx, Obj);
266
+ return Obj;
267
+ }
268
+
269
+ static json::Value extractValue (const EnumInfo &I,
270
+ const ClangDocContext &CDCtx) {
271
+ Object Obj = Object ();
272
+ std::string EnumType = I.Scoped ? " enum class " : " enum " ;
273
+ EnumType += I.Name ;
274
+ bool HasComment = std::any_of (
275
+ I.Members .begin (), I.Members .end (),
276
+ [](const EnumValueInfo &M) { return !M.Description .empty (); });
277
+ Obj.insert ({" EnumName" , EnumType});
278
+ Obj.insert ({" HasComment" , HasComment});
279
+ Obj.insert ({" ID" , toHex (toStringRef (I.USR ))});
280
+ json::Value Arr = Array ();
281
+ json::Array &ARef = *Arr.getAsArray ();
282
+ for (const EnumValueInfo &M : I.Members ) {
283
+ json::Value EnumValue = Object ();
284
+ auto &EnumValObj = *EnumValue.getAsObject ();
285
+ EnumValObj.insert ({" Name" , M.Name });
286
+ if (!M.ValueExpr .empty ())
287
+ EnumValObj.insert ({" ValueExpr" , M.ValueExpr });
288
+ else
289
+ EnumValObj.insert ({" Value" , M.Value });
290
+
291
+ extractDescriptionFromInfo (M.Description , EnumValObj);
292
+ ARef.emplace_back (EnumValue);
293
+ }
294
+ Obj.insert ({" EnumValues" , Arr});
295
+
296
+ extractDescriptionFromInfo (I.Description , Obj);
297
+ maybeInsertLocation (I.DefLoc , CDCtx, Obj);
298
+
299
+ return Obj;
300
+ }
301
+
302
+ static void extractScopeChildren (const ScopeChildren &S, Object &Obj,
303
+ StringRef ParentInfoDir,
304
+ const ClangDocContext &CDCtx) {
305
+ json::Value ArrNamespace = Array ();
306
+ for (const Reference &Child : S.Namespaces )
307
+ ArrNamespace.getAsArray ()->emplace_back (extractValue (Child, ParentInfoDir));
308
+
309
+ if (!ArrNamespace.getAsArray ()->empty ())
310
+ Obj.insert ({" Namespace" , Object{{" Links" , ArrNamespace}}});
311
+
312
+ json::Value ArrRecord = Array ();
313
+ for (const Reference &Child : S.Records )
314
+ ArrRecord.getAsArray ()->emplace_back (extractValue (Child, ParentInfoDir));
315
+
316
+ if (!ArrRecord.getAsArray ()->empty ())
317
+ Obj.insert ({" Record" , Object{{" Links" , ArrRecord}}});
318
+
319
+ json::Value ArrFunction = Array ();
320
+ json::Value PublicFunction = Array ();
321
+ json::Value ProtectedFunction = Array ();
322
+ json::Value PrivateFunction = Array ();
323
+
324
+ for (const FunctionInfo &Child : S.Functions ) {
325
+ json::Value F = extractValue (Child, ParentInfoDir, CDCtx);
326
+ AccessSpecifier Access = Child.Access ;
327
+ if (Access == AccessSpecifier::AS_public)
328
+ PublicFunction.getAsArray ()->emplace_back (F);
329
+ else if (Access == AccessSpecifier::AS_protected)
330
+ ProtectedFunction.getAsArray ()->emplace_back (F);
331
+ else
332
+ ArrFunction.getAsArray ()->emplace_back (F);
333
+ }
334
+
335
+ if (!ArrFunction.getAsArray ()->empty ())
336
+ Obj.insert ({" Function" , Object{{" Obj" , ArrFunction}}});
337
+
338
+ if (!PublicFunction.getAsArray ()->empty ())
339
+ Obj.insert ({" PublicFunction" , Object{{" Obj" , PublicFunction}}});
340
+
341
+ if (!ProtectedFunction.getAsArray ()->empty ())
342
+ Obj.insert ({" ProtectedFunction" , Object{{" Obj" , ProtectedFunction}}});
343
+
344
+ json::Value ArrEnum = Array ();
345
+ auto &ArrEnumRef = *ArrEnum.getAsArray ();
346
+ for (const EnumInfo &Child : S.Enums )
347
+ ArrEnumRef.emplace_back (extractValue (Child, CDCtx));
348
+
349
+ if (!ArrEnumRef.empty ())
350
+ Obj.insert ({" Enums" , Object{{" Obj" , ArrEnum}}});
351
+
352
+ json::Value ArrTypedefs = Array ();
353
+ auto &ArrTypedefsRef = *ArrTypedefs.getAsArray ();
354
+ for (const TypedefInfo &Child : S.Typedefs )
355
+ ArrTypedefsRef.emplace_back (extractValue (Child));
356
+
357
+ if (!ArrTypedefsRef.empty ())
358
+ Obj.insert ({" Typedefs" , Object{{" Obj" , ArrTypedefs}}});
359
+ }
360
+
155
361
static json::Value extractValue (const NamespaceInfo &I,
156
362
const ClangDocContext &CDCtx) {
157
363
Object NamespaceValue = Object ();
364
+ std::string InfoTitle = I.Name .empty () ? " Global Namespace"
365
+ : (Twine (" namespace " ) + I.Name ).str ();
366
+
367
+ SmallString<64 > BasePath = I.getRelativeFilePath (" " );
368
+ NamespaceValue.insert ({" NamespaceTitle" , InfoTitle});
369
+ NamespaceValue.insert ({" NamespacePath" , BasePath});
370
+
371
+ extractDescriptionFromInfo (I.Description , NamespaceValue);
372
+ extractScopeChildren (I.Children , NamespaceValue, BasePath, CDCtx);
158
373
return NamespaceValue;
159
374
}
160
375
161
376
static json::Value extractValue (const RecordInfo &I,
162
377
const ClangDocContext &CDCtx) {
163
378
Object RecordValue = Object ();
379
+ extractDescriptionFromInfo (I.Description , RecordValue);
380
+ RecordValue.insert ({" Name" , I.Name });
381
+ RecordValue.insert ({" FullName" , I.FullName });
382
+ RecordValue.insert ({" RecordType" , getTagType (I.TagType )});
383
+
384
+ maybeInsertLocation (I.DefLoc , CDCtx, RecordValue);
385
+
386
+ StringRef BasePath = I.getRelativeFilePath (" " );
387
+ extractScopeChildren (I.Children , RecordValue, BasePath, CDCtx);
388
+ json::Value PublicMembers = Array ();
389
+ json::Array &PubMemberRef = *PublicMembers.getAsArray ();
390
+ json::Value ProtectedMembers = Array ();
391
+ json::Array &ProtMemberRef = *ProtectedMembers.getAsArray ();
392
+ json::Value PrivateMembers = Array ();
393
+ json::Array &PrivMemberRef = *PrivateMembers.getAsArray ();
394
+ for (const MemberTypeInfo &Member : I.Members ) {
395
+ json::Value MemberValue = Object ();
396
+ auto &MVRef = *MemberValue.getAsObject ();
397
+ MVRef.insert ({" Name" , Member.Name });
398
+ MVRef.insert ({" Type" , Member.Type .Name });
399
+ extractDescriptionFromInfo (Member.Description , MVRef);
400
+
401
+ if (Member.Access == AccessSpecifier::AS_public)
402
+ PubMemberRef.emplace_back (MemberValue);
403
+ else if (Member.Access == AccessSpecifier::AS_protected)
404
+ ProtMemberRef.emplace_back (MemberValue);
405
+ else if (Member.Access == AccessSpecifier::AS_private)
406
+ ProtMemberRef.emplace_back (MemberValue);
407
+ }
408
+ if (!PubMemberRef.empty ())
409
+ RecordValue.insert ({" PublicMembers" , Object{{" Obj" , PublicMembers}}});
410
+ if (!ProtMemberRef.empty ())
411
+ RecordValue.insert ({" ProtectedMembers" , Object{{" Obj" , ProtectedMembers}}});
412
+ if (!PrivMemberRef.empty ())
413
+ RecordValue.insert ({" PrivateMembers" , Object{{" Obj" , PrivateMembers}}});
414
+
164
415
return RecordValue;
165
416
}
166
417
0 commit comments