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