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