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