@@ -163,15 +163,264 @@ Error MustacheHTMLGenerator::generateDocs(
163163 return Error::success ();
164164}
165165
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+
166370static json::Value extractValue (const NamespaceInfo &I,
167371 const ClangDocContext &CDCtx) {
168372 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);
169382 return NamespaceValue;
170383}
171384
172385static json::Value extractValue (const RecordInfo &I,
173386 const ClangDocContext &CDCtx) {
174387 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+
175424 return RecordValue;
176425}
177426
0 commit comments