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