Doxygen
Loading...
Searching...
No Matches
moduledef.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2023 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16// own headers
17#include "moduledef.h"
18
19// other includes
20#include "classdef.h"
21#include "classlist.h"
22#include "conceptdef.h"
23#include "config.h"
24#include "definitionimpl.h"
25#include "doxygen.h"
26#include "entry.h"
27#include "filedef.h"
28#include "filename.h"
29#include "groupdef.h"
30#include "language.h"
31#include "layout.h"
32#include "memberdef.h"
33#include "membergroup.h"
34#include "message.h"
35#include "namespacedef.h"
36#include "outputlist.h"
37#include "textstream.h"
38#include "trace.h"
39#include "util.h"
40
41class ModuleDefImpl;
42
44{
45 HeaderInfo(const DString &fn,const DString &name,bool sys)
46 : fileName(fn), headerName(name), isSystem(sys) {}
47 DString fileName; // file containing the import
48 DString headerName; // name of the imported header
49 bool isSystem; // <...> => true, "..." => false
50};
51
52using HeaderInfoVector = std::vector<HeaderInfo>;
53
54
55class ModuleDefImpl final : public DefinitionMixin<ModuleDef>
56{
57 public:
58 ModuleDefImpl(const DString &fileName,int startLine,size_t startColumn,
59 const DString &name, Type type, const DString &partitionName)
60 : DefinitionMixin<ModuleDef>(fileName,startLine,startColumn,name,nullptr,nullptr,true),
62
63 // --- Definition
64 DefType definitionType() const override { return TypeModule; }
66 DString displayName(bool=true) const override { return name(); }
67 DString getOutputFileBase() const override;
68 DString anchor() const override { return ""; }
69 bool isLinkableInProject() const override {
71 else return isLinkable() && !isHidden() && !isReference(); }
72 bool isLinkable() const override {
74 else return hasDocumentation(); }
75 DString qualifiedName() const override;
76 void writeSummaryLinks(OutputList &ol) const override;
77 void writePageNavigation(OutputList &ol) const override;
78
79 // --- ModuleDef
80 Type moduleType() const override { return m_type; }
81 DString partitionName() const override { return m_partitionName; }
82 void writeDocumentation(OutputList &ol) override;
83 bool isPrimaryInterface() const override { return m_type==Type::Interface && m_partitionName.empty(); }
84 MemberList *getMemberList(MemberListType lt) const override;
85 const MemberLists &getMemberLists() const override { return m_memberLists; }
86 const MemberGroupList &getMemberGroups() const override { return m_memberGroups; }
87 const ClassLinkedRefMap &getClasses() const override { return m_classes; }
88 const ConceptLinkedRefMap &getConcepts() const override { return m_concepts; }
89 int countVisibleMembers() const override;
90 FileDef *getFileDef() const override { return m_fileDef; }
91 const ImportInfoMap &getImports() const override { return m_imports; }
92 const ImportInfoMap &getExports() const override { return m_exportedModules; }
93 const ModuleMap &partitions() const override { return m_partitions; }
94 void writeTagFile(TextStream &t) const override;
95 FileList getUsedFiles() const override;
96
97 void writeExports(OutputList &ol,const DString &title);
98 void writeClassDeclarations(OutputList &ol,const DString &title);
99 void writeConcepts(OutputList &ol,const DString &title);
100 void writeFiles(OutputList &ol,const DString &title);
105 void writeDetailedDescription(OutputList &ol,const DString &title);
111 void writeDeclarationLink(OutputList &ol,bool &found,const DString &header,bool localNames) const;
112
113 void addHeader(int line,const DString &headerName,bool isSystem);
114 void addImport(int line,const DString &moduleName,const DString &partitionName,bool isExported);
115 void addClassToModule(const Entry *root,ClassDef *cd);
116 void addConceptToModule(const Entry *root,ConceptDef *cd);
117 void addMemberToModule(const Entry *root,MemberDef *md);
118 void addPartition(ModuleDefImpl *mod);
120 void setPrimaryInterface(const ModuleDef *mod);
121 void setFileDef(FileDef *fd);
123 void addExportedModule(const DString &moduleName,const ImportInfo &info);
124 void addListReferences();
129 void sortMemberLists();
130
131 void mergeSymbolsFrom(ModuleDefImpl *other);
132 bool hasDetailedDescription() const;
133 void countMembers();
134
135 private:
147 FileDef *m_fileDef = nullptr; // file holding this module
148};
149
151{
152 return convertNameToFile("module_" + name());
153}
154
156{
157 DString result=name();
158 if (!m_partitionName.empty())
159 {
160 result+=":"+m_partitionName;
161 }
162 return result;
163}
164
166{
167 std::string qName = mod->qualifiedName().str();
168 if (m_partitions.find(qName)==m_partitions.end())
169 {
170 m_partitions.emplace(qName,mod);
171 }
172}
173
175{
176 if (std::find(m_contributing.begin(),m_contributing.end(),mod)==m_contributing.end())
177 {
178 m_contributing.push_back(mod);
179 }
180}
181
186
188{
189 m_fileDef = fd;
190}
191
192void ModuleDefImpl::addHeader(int line,const DString &headerName,bool isSystem)
193{
194 AUTO_TRACE("name={}:line={},header={},isSystem={}",name(),line,headerName,isSystem);
195}
196
197void ModuleDefImpl::addImport(int line,const DString &moduleName,const DString &partitionName,bool isExported)
198{
199 AUTO_TRACE("name={}:line={},module={},partition={}",name(),line,moduleName,partitionName);
200 m_imports[getDefFileName().str()+":"+std::to_string(line)].push_back(ImportInfo(this,moduleName,line,partitionName,isExported));
201}
202
203void ModuleDefImpl::addExportedModule(const DString &moduleName,const ImportInfo &info)
204{
205 AUTO_TRACE("name={}:moduleName={},import={}",name(),moduleName,info.importName);
206 m_exportedModules[moduleName.str()].push_back(info);
207}
208
210{
211 DString className = cd->qualifiedName();
212 AUTO_TRACE("{}:{} class {} of module {} exported={}",
213 root->fileName,root->startLine, className, name(), root->exported);
214 bool isExported = m_classes.find(className)!=nullptr;
215 if (root->exported && !isExported)
216 {
217 m_classes.add(className,cd);
218 }
219 auto cdm = toClassDefMutable(cd);
220 if (cdm && root->exported && !cd->isExported())
221 {
222 cdm->setExported(true);
223 }
224}
225
227{
228 DString conceptName = cd->qualifiedName();
229 AUTO_TRACE("{}:{} concept {} of module {} exported={}",
230 root->fileName,root->startLine,
231 cd->qualifiedName(),name(),
232 root->exported);
233 bool isExported = m_classes.find(conceptName)!=nullptr;
234 if (root->exported && !isExported)
235 {
236 m_concepts.add(conceptName,cd);
237 }
238 auto cdm = toConceptDefMutable(cd);
239 if (cdm && root->exported && !cd->isExported())
240 {
241 cdm->setExported(true);
242 }
243}
244
246{
247 for (auto &ml : m_memberLists)
248 {
249 if (ml->listType()==lt)
250 {
251 return ml.get();
252 }
253 }
254 return nullptr;
255}
256
258{
259 bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
260 bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
262 ml->setNeedsSorting(
263 (ml->listType().isDeclaration() && sortBriefDocs) ||
264 (ml->listType().isDocumentation() && sortMemberDocs));
265 ml->push_back(md);
266 if (ml->listType().isDeclaration())
267 {
269 if (mdm)
270 {
271 mdm->setSectionList(this,ml.get());
272 }
273 }
274}
275
277{
278 AUTO_TRACE("{}:{} member {} of module {} exported={}",
279 qPrint(root->fileName),root->startLine,
281 root->exported);
282 MemberList *allMemberList = getMemberList(MemberListType::AllMembersList());
283 if (allMemberList==nullptr)
284 {
285 m_memberLists.emplace_back(std::make_unique<MemberList>(MemberListType::AllMembersList(),MemberListContainer::Module));
286 allMemberList = m_memberLists.back().get();
287 }
288 if (allMemberList->contains(md))
289 {
290 return;
291 }
292 allMemberList->push_back(md);
293 switch (md->memberType())
294 {
295 case MemberType::Variable:
296 addMemberToList(MemberListType::DecVarMembers(),md);
297 break;
298 case MemberType::Function:
299 addMemberToList(MemberListType::DecFuncMembers(),md);
300 break;
301 case MemberType::Typedef:
302 addMemberToList(MemberListType::DecTypedefMembers(),md);
303 break;
304 case MemberType::Enumeration:
305 addMemberToList(MemberListType::DecEnumMembers(),md);
306 break;
307 default:
308 break;
309 }
310 auto mdm = toMemberDefMutable(md);
311 if (mdm && root->exported && !md->isExported())
312 {
313 mdm->setExported(true);
314 }
315}
316
318{
319 AUTO_TRACE("{} merging symbols of {} ({}:{})",
320 name(),other->qualifiedName(),other->getDefFileName(),other->getDefLine());
321 for (const auto &cd : other->getClasses())
322 {
323 m_classes.add(cd->qualifiedName(),cd);
324 }
325 for (const auto &cd : other->getConcepts())
326 {
327 m_concepts.add(cd->qualifiedName(),cd);
328 }
329 auto mergeMemberList = [this,other](MemberListType lt)
330 {
331 const auto &srcMl = other->getMemberList(lt);
332 if (srcMl)
333 {
334 auto &dstMl = m_memberLists.get(lt,srcMl->container());
335 for (const auto &md : *srcMl)
336 {
337 dstMl->push_back(md);
338 }
339 }
340 };
341 mergeMemberList(MemberListType::DecVarMembers());
342 mergeMemberList(MemberListType::DecFuncMembers());
343 mergeMemberList(MemberListType::DecTypedefMembers());
344 mergeMemberList(MemberListType::DecEnumMembers());
345}
346
348{
349 if (isReference()) return;
350 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
352 AUTO_TRACE("%s file=%s",name(),getDefFileName());
353 SrcLangExt lang = getLanguage();
354 DString pageTitle;
355 if (Config_getBool(HIDE_COMPOUND_REFERENCE))
356 {
357 pageTitle = displayName();
358 }
359 else
360 {
362 }
364
365 // ---- title part
367 bool writeOutlinePanel = generateTreeView && Config_getBool(PAGE_OUTLINE_PANEL);
368 if (!writeOutlinePanel) writeSummaryLinks(ol);
370
373 ol.parseText(pageTitle);
375
376 addGroupListToTitle(ol,this);
377
380 ol.endTitleHead(getOutputFileBase(),pageTitle);
382
386 ol.writeString(" - ");
387 ol.parseText(pageTitle);
389
390 ol.endHeaderSection();
391 ol.startContents();
392
393 //---------------------------------------- start flexible part -------------------------------
394 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
395 {
396 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
397 switch (lde->kind())
398 {
399 case LayoutDocEntry::BriefDesc:
401 break;
402 case LayoutDocEntry::MemberDeclStart:
404 break;
405 case LayoutDocEntry::ModuleClasses:
406 if (ls) writeClassDeclarations(ol,ls->title(lang));
407 break;
408 case LayoutDocEntry::ModuleConcepts:
409 if (ls) writeConcepts(ol,ls->title(lang));
410 break;
411 case LayoutDocEntry::ModuleExports:
412 if (ls) writeExports(ol,ls->title(lang));
413 break;
414 case LayoutDocEntry::ModuleUsedFiles:
415 if (ls) writeFiles(ol,ls->title(lang));
416 break;
417 case LayoutDocEntry::MemberGroups:
419 break;
420 case LayoutDocEntry::MemberDecl:
421 {
422 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
423 if (lmd) writeMemberDeclarations(ol,lmd->type,lmd->title(lang));
424 }
425 break;
426 case LayoutDocEntry::MemberDeclEnd:
428 break;
429 case LayoutDocEntry::DetailedDesc:
430 if (ls) writeDetailedDescription(ol,ls->title(lang));
431 break;
432 case LayoutDocEntry::MemberDefStart:
434 break;
435 case LayoutDocEntry::MemberDef:
436 {
437 const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get());
438 if (lmd) writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
439 }
440 break;
441 case LayoutDocEntry::MemberDefEnd:
443 break;
444 case LayoutDocEntry::AuthorSection:
446 break;
447 case LayoutDocEntry::Includes:
448 case LayoutDocEntry::ClassInheritanceGraph:
449 case LayoutDocEntry::ClassNestedClasses:
450 case LayoutDocEntry::ClassCollaborationGraph:
451 case LayoutDocEntry::ClassAllMembersLink:
452 case LayoutDocEntry::ClassUsedFiles:
453 case LayoutDocEntry::ClassInlineClasses:
454 case LayoutDocEntry::FileClasses:
455 case LayoutDocEntry::FileConcepts:
456 case LayoutDocEntry::FileInterfaces:
457 case LayoutDocEntry::FileStructs:
458 case LayoutDocEntry::FileExceptions:
459 case LayoutDocEntry::FileNamespaces:
460 case LayoutDocEntry::FileConstantGroups:
461 case LayoutDocEntry::FileIncludeGraph:
462 case LayoutDocEntry::FileIncludedByGraph:
463 case LayoutDocEntry::FileInlineClasses:
464 case LayoutDocEntry::FileSourceLink:
465 case LayoutDocEntry::NamespaceNestedNamespaces:
466 case LayoutDocEntry::NamespaceNestedConstantGroups:
467 case LayoutDocEntry::NamespaceClasses:
468 case LayoutDocEntry::NamespaceConcepts:
469 case LayoutDocEntry::NamespaceInterfaces:
470 case LayoutDocEntry::NamespaceStructs:
471 case LayoutDocEntry::NamespaceExceptions:
472 case LayoutDocEntry::NamespaceInlineClasses:
473 case LayoutDocEntry::ConceptDefinition:
474 case LayoutDocEntry::GroupClasses:
475 case LayoutDocEntry::GroupConcepts:
476 case LayoutDocEntry::GroupModules:
477 case LayoutDocEntry::GroupInlineClasses:
478 case LayoutDocEntry::GroupNamespaces:
479 case LayoutDocEntry::GroupDirs:
480 case LayoutDocEntry::GroupNestedGroups:
481 case LayoutDocEntry::GroupFiles:
482 case LayoutDocEntry::GroupGraph:
483 case LayoutDocEntry::GroupPageDocs:
484 case LayoutDocEntry::DirSubDirs:
485 case LayoutDocEntry::DirFiles:
486 case LayoutDocEntry::DirGraph:
487 err("Internal inconsistency: member '{}' should not be part of "
488 "LayoutDocManager::Module entry list\n",lde->entryToString());
489 break;
490 }
491 }
492
493 //---------------------------------------- end flexible part -------------------------------
494 if (generateTreeView)
495 {
498 ol.endContents();
499 ol.writeString("</div><!-- doc-content -->\n");
501 ol.writeString("</div><!-- container -->\n");
503 }
504 endFile(ol,generateTreeView,true);
505
507}
508
510{
511 m_classes.writeDeclaration(ol,nullptr,title,false);
512}
513
515{
516 m_concepts.writeDeclaration(ol,title,false);
517}
518
523
528
530{
531 if (Config_getBool(SEPARATE_MEMBER_PAGES))
532 {
535 }
536}
537
539{
540 if (Config_getBool(SEPARATE_MEMBER_PAGES))
541 {
544 }
545}
546
548{
550 {
553 ol.writeRuler();
557 ol.writeAnchor(DString(),"details");
559 ol.startGroupHeader("details");
560 ol.parseText(title);
561 ol.endGroupHeader();
562
563 ol.startTextBlock();
564 if (!briefDescription().empty() && Config_getBool(REPEAT_BRIEF))
565 {
567 briefLine(),
568 this,
569 nullptr,
571 DocOptions());
572 }
573 if (!briefDescription().empty() && Config_getBool(REPEAT_BRIEF) &&
574 !documentation().empty())
575 {
579 ol.enableAll();
582 ol.writeString("\n\n");
584 }
585 if (!documentation().empty())
586 {
587 ol.generateDoc(docFile(),
588 docLine(),
589 this,
590 nullptr,
591 documentation()+"\n",
592 DocOptions()
593 .setIndexWords(true));
594 }
595 ol.endTextBlock();
596 }
597}
598
600{
602 {
603 auto parser { createDocParser() };
604 auto ast { validatingParseDoc(*parser.get(),
605 briefFile(),
606 briefLine(),
607 this,
608 nullptr,
610 DocOptions()
611 .setIndexWords(true)
612 .setSingleLine(true))
613 };
614 if (!ast->empty())
615 {
616 ol.startParagraph();
619 ol.writeString(" - ");
621 ol.writeDoc(ast.get(),this,nullptr);
624 ol.writeString(" \n");
626
628 {
630 ol.startTextLink(DString(),"details");
632 ol.endTextLink();
633 }
635 ol.endParagraph();
636 }
637 }
638 ol.writeSynopsis();
639}
640
642{
643 for (const auto &mg : m_memberGroups)
644 {
645 mg->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this);
646 }
647}
648
650{
651 MemberList * ml = getMemberList(lt);
652 if (ml) ml->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this,title,DString());
653}
654
656{
657 MemberList * ml = getMemberList(lt);
658 if (ml) ml->writeDocumentation(ol,name(),this,title,ml->listType().toLabel());
659}
660
662{
663 // write Author section (Man only)
666 ol.startGroupHeader();
667 ol.parseText(theTranslator->trAuthor(true,true));
668 ol.endGroupHeader();
671}
672
674{
675 bool repeatBrief = Config_getBool(REPEAT_BRIEF);
676 return (!briefDescription().empty() && repeatBrief) || !documentation().empty();
677}
678
680{
681 for (auto &ml : m_memberLists)
682 {
683 ml->countDecMembers();
684 ml->countDocMembers();
685 }
686 for (const auto &mg : m_memberGroups)
687 {
688 mg->countDecMembers();
689 mg->countDocMembers();
690 }
691}
692
694{
697 getLanguage()==SrcLangExt::Fortran ?
698 theTranslator->trModule(true,true) :
699 theTranslator->trNamespace(true,true),
701 DString(),
702 this
703 );
704 for (const auto &mg : m_memberGroups)
705 {
706 mg->addListReferences(this);
707 }
708 for (auto &ml : m_memberLists)
709 {
710 if (ml->listType().isDocumentation())
711 {
712 ml->addListReferences(this);
713 }
714 }
715}
716
718{
720 for (const auto &mg : m_memberGroups)
721 {
722 mg->addRequirementReferences(this);
723 }
724 for (auto &ml : m_memberLists)
725 {
726 if (ml->listType().isDocumentation())
727 {
728 ml->addRequirementReferences(this);
729 }
730 }
731}
732
734{
735 for (auto &ml : m_memberLists)
736 {
737 if (ml->listType().isDeclaration())
738 {
740 }
741 }
742
743 // add members inside sections to their groups
744 for (const auto &mg : m_memberGroups)
745 {
746 if (mg->allMembersInSameSection() && Config_getBool(SUBGROUPING))
747 {
748 //printf("----> addToDeclarationSection(%s)\n",qPrint(mg->header()));
749 mg->addToDeclarationSection();
750 }
751 }
752}
753
755{
756 for (const auto &mg : m_memberGroups)
757 {
758 mg->distributeMemberGroupDocumentation();
759 }
760}
761
763{
767 for (const auto &mg : m_memberGroups)
768 {
769 mg->findSectionsInDocumentation(this);
770 }
771 for (auto &ml : m_memberLists)
772 {
773 if (ml->listType().isDeclaration())
774 {
775 ml->findSectionsInDocumentation(this);
776 }
777 }
778}
779
781{
782 for (auto &ml : m_memberLists)
783 {
784 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(false); }
785 }
786
787 if (Config_getBool(SORT_BRIEF_DOCS))
788 {
789 auto classComp = [](const ClassLinkedRefMap::Ptr &c1,const ClassLinkedRefMap::Ptr &c2)
790 {
791 return Config_getBool(SORT_BY_SCOPE_NAME) ?
792 dstricmp_sort(c1->name(), c2->name())<0 :
793 dstricmp_sort(c1->className(), c2->className())<0;
794 };
795 std::stable_sort(m_classes.begin(), m_classes.end(), classComp);
796
797 auto conceptComp = [](const ConceptLinkedRefMap::Ptr &c1,const ConceptLinkedRefMap::Ptr &c2)
798 {
799 return Config_getBool(SORT_BY_SCOPE_NAME) ?
800 dstricmp_sort(c1->qualifiedName(), c2->qualifiedName())<0 :
801 dstricmp_sort(c1->name(), c2->name())<0;
802 };
803 std::stable_sort(m_concepts.begin(), m_concepts.end(), conceptComp);
804 }
805
806 static auto contrComp = [](const ModuleDef *m1, const ModuleDef *m2)
807 {
808 FileDef *f1 = m1->getFileDef();
809 FileDef *f2 = m2->getFileDef();
810 DString fn1 = f1 ? f1->name() : m1->name();
811 DString fn2 = f2 ? f2->name() : m2->name();
812 static auto typeRank = [](const ModuleDef *m) -> int
813 {
814 if (m->moduleType()==ModuleDef::Type::Interface)
815 {
816 if (m->partitionName().empty()) return 0; // primary interface unit
817 return 1; // partition interface unit
818 }
819 else
820 {
821 if (!m->partitionName().empty()) return 2; // partition implementation unit
822 return 3; // implementation unit
823 }
824 };
825 auto tr1 = typeRank(m1);
826 auto tr2 = typeRank(m2);
827 int diff = dstricmp_sort(fn1,fn2);
828 return tr1<tr2 || (tr1==tr2 && diff<0);
829 };
830
831 std::stable_sort(m_contributing.begin(), m_contributing.end(), contrComp);
832}
833
835{
838 bool first=true;
839 SrcLangExt lang=getLanguage();
840 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
841 {
842 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
843 if (lde->kind()==LayoutDocEntry::ModuleClasses && m_classes.declVisible() && ls)
844 {
845 DString label = "classes";
846 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
847 first=false;
848 }
849 else if (lde->kind()==LayoutDocEntry::ModuleConcepts && m_concepts.declVisible() && ls)
850 {
851 DString label = "concepts";
852 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
853 first=false;
854 }
855 else if (lde->kind()==LayoutDocEntry::ModuleUsedFiles && ls)
856 {
857 DString label = "files";
858 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
859 first=false;
860 }
861 else if (lde->kind()==LayoutDocEntry::MemberDecl)
862 {
863 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
864 if (lmd)
865 {
866 MemberList * ml = getMemberList(lmd->type);
867 if (ml && ml->declVisible())
868 {
869 ol.writeSummaryLink(DString(),ml->listType().toLabel(),lmd->title(lang),first);
870 first=false;
871 }
872 }
873 }
874 }
875 if (!first)
876 {
877 ol.writeString(" </div>\n");
878 }
880}
881
886
887void ModuleDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const DString &header,bool localNames) const
888{
889 if (isLinkable())
890 {
891 if (!found) // first module
892 {
893 ol.startMemberHeader("modules");
894 if (!header.empty())
895 {
896 ol.parseText(header);
897 }
898 else
899 {
900 theTranslator->trModule(true,false);
901 }
902 ol.endMemberHeader();
903 ol.startMemberList();
904 found=true;
905 }
907 DString cname = displayName(!localNames);
908 DString anc = anchor();
909 if (anc.empty()) anc=cname; else anc.prepend(cname+"_");
911 ol.writeString("module ");
913 if (isLinkable())
914 {
917 anchor(),
918 cname
919 );
920 }
921 else
922 {
923 ol.startBold();
924 ol.docify(cname);
925 ol.endBold();
926 }
928 // add the brief description if available
929 if (!briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
930 {
931 auto parser { createDocParser() };
932 auto ast { validatingParseDoc(*parser.get(),
933 briefFile(),
934 briefLine(),
935 this,
936 nullptr,
938 DocOptions()
939 .setSingleLine(true))
940 };
941 if (!ast->empty())
942 {
944 ol.writeDoc(ast.get(),this,nullptr);
946 }
947 }
949 }
950}
951
952
954{
955 AUTO_TRACE("name={} count={}",name(),m_exportedModules.size());
956 if (!m_exportedModules.empty())
957 {
958 ol.startMemberHeader("exports");
959 ol.parseText(title);
960 ol.endMemberHeader();
961 ol.startMemberList();
962 for (const auto &[moduleName,importInfoList] : m_exportedModules)
963 {
964 for (const auto &importInfo : importInfoList)
965 {
966 ModuleDef *mod = ModuleManager::instance().getPrimaryInterface(importInfo.importName);
969 ol.docify(theTranslator->trModule(false,true)+" ");
971 if (mod && mod->isLinkable())
972 {
974 }
975 else
976 {
977 ol.startBold();
978 ol.docify(importInfo.importName);
979 ol.endBold();
980 }
982 if (mod && !mod->briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
983 {
986 briefLine(),
987 mod,
988 nullptr,
989 mod->briefDescription(),
990 DocOptions()
991 .setSingleLine(true));
993 }
995 }
996 }
997 ol.endMemberList();
998 }
999}
1000
1002{
1003 AUTO_TRACE("{} count={}",name(),m_contributing.size());
1004 if (!m_contributing.empty())
1005 {
1006 ol.startMemberHeader("files");
1007 ol.parseText(title);
1008 ol.endMemberHeader();
1009 ol.startMemberList();
1010 for (const auto &mod : m_contributing)
1011 {
1012 FileDef *fd = mod->getFileDef();
1013 if (fd)
1014 {
1016 DString fname = fd->displayName();
1017 DString anc = fd->anchor();
1018 if (anc.empty()) anc=fname; else anc.prepend(fname+"_");
1020 ol.docify(theTranslator->trFile(false,true)+" ");
1021 ol.insertMemberAlign();
1022 DString path=fd->getPath();
1023 if (Config_getBool(FULL_PATH_NAMES))
1024 {
1025 ol.docify(stripFromPath(path));
1026 }
1027 if (fd->isLinkable())
1028 {
1029 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),DString(),fname);
1030 }
1031 else
1032 {
1033 ol.startBold();
1034 ol.docify(fd->displayName());
1035 ol.endBold();
1036 }
1038 if (!fd->briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
1039 {
1042 briefLine(),
1043 fd,
1044 nullptr,
1045 fd->briefDescription(),
1046 DocOptions()
1047 .setSingleLine(true));
1049 }
1051 }
1052 }
1053 ol.endMemberList();
1054 }
1055}
1056
1058{
1059 FileList result;
1060 for (const auto &mod : m_contributing)
1061 {
1062 FileDef *fd = mod->getFileDef();
1063 if (fd) result.push_back(fd);
1064 }
1065 return result;
1066}
1067
1069{
1070 int count=0;
1071 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
1072 {
1073 if (lde->kind()==LayoutDocEntry::MemberDecl)
1074 {
1075 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1076 if (lmd)
1077 {
1078 MemberList *ml = getMemberList(lmd->type);
1079 if (ml)
1080 {
1081 for (const auto &md : *ml)
1082 {
1083 if (md->visibleInIndex())
1084 {
1085 count++;
1086 }
1087 }
1088 }
1089 }
1090 }
1091 else if (lde->kind()==LayoutDocEntry::ModuleClasses)
1092 {
1093 for (const auto &cd : getClasses())
1094 {
1095 if (cd->isLinkableInProject())
1096 {
1097 count++;
1098 }
1099 }
1100 }
1101 else if (lde->kind()==LayoutDocEntry::ModuleConcepts)
1102 {
1103 for (const auto &cd : getConcepts())
1104 {
1105 if (cd->isLinkableInProject())
1106 {
1107 count++;
1108 }
1109 }
1110 }
1111 }
1112 return count;
1113}
1114
1116{
1117 if (!isPrimaryInterface() || !isLinkableInProject()) return;
1118 tagFile << " <compound kind=\"module\">\n";
1119 tagFile << " <name>" << convertToXML(name()) << "</name>\n";
1120 const FileDef *fd = getFileDef();
1121 DString fn = fd ? fd->getOutputFileBase() : getOutputFileBase();
1123 tagFile << " <filename>" << convertToXML(fn) << "</filename>\n";
1124#if 0 // at the moment we do not export the members of a module to a tag file.
1125 // We let the project using a tag file directly link to the implementation of the
1126 // symbols (which have the same scope).
1127 //
1128 // When we support linking to a module's interface instead we need to
1129 // export the module's members as well. Then we probably need a way to
1130 // disambiguate/prioritize a link to a module over a link to the implementation,
1131 // for instance by hiding non-exported symbols from the tag file.
1132 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Group))
1133 {
1134 switch (lde->kind())
1135 {
1136 case LayoutDocEntry::ModuleExports:
1137 {
1138 for (const auto &[modName,importInfo] : m_exportedModules)
1139 {
1140 tagFile << " <export>" << convertToXML(importInfo.importName) << "</export>\n";
1141 }
1142 }
1143 break;
1144 case LayoutDocEntry::ModuleClasses:
1145 {
1146 for (const auto &cd : m_classes)
1147 {
1148 if (cd->isLinkableInProject())
1149 {
1150 tagFile << " <class kind=\"" << cd->compoundTypeString()
1151 << "\">" << convertToXML(cd->name()) << "</class>\n";
1152 }
1153 }
1154 }
1155 break;
1156 case LayoutDocEntry::ModuleConcepts:
1157 {
1158 for (const auto &cd : m_concepts)
1159 {
1160 if (cd->isLinkableInProject())
1161 {
1162 tagFile << " <concept>" << convertToXML(cd->name())
1163 << "</concept>\n";
1164 }
1165 }
1166 }
1167 break;
1168 case LayoutDocEntry::ModuleUsedFiles:
1169 {
1170 for (const auto &usedFd : getUsedFiles())
1171 {
1172 if (usedFd->isLinkableInProject())
1173 {
1174 tagFile << " <file>" << convertToXML(usedFd->name()) << "</file>\n";
1175 }
1176 }
1177 }
1178 break;
1179 case LayoutDocEntry::MemberDecl:
1180 {
1181 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1182 if (lmd && lmd->visible())
1183 {
1184 MemberList * ml = getMemberList(lmd->type);
1185 if (ml)
1186 {
1187 ml->writeTagFile(tagFile,true);
1188 }
1189 }
1190 }
1191 break;
1192 default:
1193 break;
1194 }
1195 }
1196#endif
1197 DString idStr = id();
1198 if (!idStr.empty())
1199 {
1200 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>\n";
1201 }
1202 writeDocAnchorsToTagFile(tagFile);
1203 tagFile << " </compound>\n";
1204}
1205
1206//------------------------------------------------------------------------------------------------------------
1207
1209{
1210 if (d==nullptr) return nullptr;
1211 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<ModuleDef*>(d) : nullptr;
1212}
1213
1215{
1216 if (d==nullptr) return nullptr;
1217 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<const ModuleDef*>(d) : nullptr;
1218}
1219
1221{ return static_cast<ModuleDefImpl*>(m); }
1222
1223//static inline const ModuleDefImpl *toModuleDefImpl(const ModuleDef *m)
1224//{ return static_cast<const ModuleDefImpl*>(m); }
1225
1226static inline ModuleDefImpl *toModuleDefImpl(const std::unique_ptr<ModuleDef> &m)
1227{ return static_cast<ModuleDefImpl*>(m.get()); }
1228
1229//------------------------------------------------------------------------------------
1230
1232{
1233 bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
1234 for (const auto &mod : *this)
1235 {
1236 bool isLink = mod->isLinkable();
1237 if (isLink || !hideUndocClasses)
1238 {
1239 return true;
1240 }
1241 }
1242 return false;
1243}
1244
1245void ModuleLinkedRefMap::writeDeclaration(OutputList &ol,const DString &header,bool localNames) const
1246{
1247 bool found=false;
1248 for (const auto &mod : *this)
1249 {
1250 toModuleDefImpl(mod)->writeDeclarationLink(ol,found,header,localNames);
1251 }
1252 if (found) ol.endMemberList();
1253}
1254
1255//------------------------------------------------------------------------------------------------------------
1256
1258{
1259 ModuleLinkedMap moduleFileMap; // file->module mapping
1260 std::unordered_map<std::string,ModuleList> moduleNameMap; // name->module mapping
1263 std::mutex mutex;
1264};
1265
1267{
1268 static ModuleManager m;
1269 return m;
1270}
1271
1273{
1274}
1275
1276void ModuleManager::createModuleDef(const DString &fileName,int line,size_t column,bool exported,
1277 const DString &moduleName,const DString &partitionName)
1278{
1279 AUTO_TRACE("{}:{}: Found module name='{}' partition='{}' exported='{}'",
1280 fileName,line,moduleName,partitionName,exported);
1281 std::lock_guard lock(p->mutex);
1283 std::unique_ptr<ModuleDef> modDef = std::make_unique<ModuleDefImpl>(fileName,line,column,moduleName,mt,partitionName);
1284 auto mod = p->moduleFileMap.add(fileName,std::move(modDef));
1285 auto it = p->moduleNameMap.find(moduleName.str());
1286 if (it == p->moduleNameMap.end())
1287 {
1288 ModuleList ml;
1289 ml.push_back(mod);
1290 p->moduleNameMap.emplace(moduleName.str(),ml);
1291 }
1292 else
1293 {
1294 it->second.push_back(mod);
1295 }
1296}
1297
1299{
1300 std::lock_guard lock(p->mutex);
1301 p->headers.clear();
1302 p->externalImports.clear();
1303 p->moduleNameMap.clear();
1304 p->moduleFileMap.clear();
1305}
1306
1307void ModuleManager::addHeader(const DString &moduleFile,int line,const DString &headerName,bool isSystem)
1308{
1309 AUTO_TRACE("{}:{} headerName={} isSystem={}",moduleFile,line,headerName,isSystem);
1310 std::lock_guard lock(p->mutex);
1311 auto mod = p->moduleFileMap.find(moduleFile);
1312 if (mod)
1313 {
1314 toModuleDefImpl(mod)->addHeader(line,headerName,isSystem);
1315 }
1316 else
1317 {
1318 AUTO_TRACE_ADD("imported header '{}' found in file '{}' that is not a module",headerName,moduleFile);
1319 }
1320 p->headers.emplace_back(moduleFile,headerName,isSystem);
1321}
1322
1323void ModuleManager::addImport(const DString &moduleFile,int line,const DString &importName,
1324 bool isExported,const DString &partitionName)
1325{
1326 AUTO_TRACE("{}:{} importName={},isExported={},partitionName={}",
1327 moduleFile,line,importName,isExported,partitionName);
1328 std::lock_guard lock(p->mutex);
1329 auto mod = p->moduleFileMap.find(moduleFile);
1330 if (mod) // import inside a module
1331 {
1332 AUTO_TRACE_ADD("in module");
1333 toModuleDefImpl(mod)->addImport(line,importName.empty()?mod->name():importName,partitionName,isExported);
1334 }
1335 else // import outside of a module
1336 {
1337 AUTO_TRACE_ADD("outside module");
1338 p->externalImports[moduleFile.str()].emplace_back(nullptr,importName,line,partitionName);
1339 }
1340}
1341
1343{
1344 std::lock_guard lock(p->mutex);
1345 auto mod = p->moduleFileMap.find(root->fileName);
1346 if (mod)
1347 {
1348 toModuleDefImpl(mod)->addClassToModule(root,cd);
1349 auto cdm = toClassDefMutable(cd);
1350 if (cdm) cdm->setModuleDef(mod);
1351 }
1352}
1353
1355{
1356 std::lock_guard lock(p->mutex);
1357 auto mod = p->moduleFileMap.find(root->fileName);
1358 if (mod)
1359 {
1360 toModuleDefImpl(mod)->addConceptToModule(root,cd);
1361 auto cdm = toConceptDefMutable(cd);
1362 if (cdm) cdm->setModuleDef(mod);
1363 }
1364}
1365
1367{
1368 std::lock_guard lock(p->mutex);
1369 auto mod = p->moduleFileMap.find(root->fileName);
1370 if (mod && root->exported && md->getClassDef()==nullptr)
1371 {
1372 toModuleDefImpl(mod)->addMemberToModule(root,md);
1373 auto mdm = toMemberDefMutable(md);
1374 if (mdm) mdm->setModuleDef(mod);
1375 }
1376}
1377
1378void ModuleManager::addTagInfo(const DString &fileName,const DString &tagFile,const DString &clangId)
1379{
1380 std::lock_guard lock(p->mutex);
1381 auto mod = p->moduleFileMap.find(fileName);
1382 if (mod)
1383 {
1384 ModuleDefImpl *modi = toModuleDefImpl(mod);
1385 modi->setReference(tagFile);
1386 modi->setId(clangId);
1387 }
1388}
1389
1391{
1392 AUTO_TRACE();
1393 for (auto &[partitionFileName,importInfoList] : mod->getImports()) // foreach import
1394 {
1395 for (auto &importInfo : importInfoList)
1396 {
1397 AUTO_TRACE_ADD("partitionFileName={} importName={} partitionName={}",
1398 partitionFileName,importInfo.importName,importInfo.partitionName);
1399 if (importInfo.importName==intfMod->name() && !importInfo.partitionName.empty() &&
1400 importInfo.exported) // that is an exported partition of this module
1401 {
1402 auto it = p->moduleNameMap.find(importInfo.importName.str());
1403 if (it != p->moduleNameMap.end())
1404 {
1405 for (auto importedMod : it->second)
1406 {
1407 if (importedMod->qualifiedName()==importInfo.importName+":"+importInfo.partitionName)
1408 {
1409 AUTO_TRACE_ADD("Interface module {} exports partition {}:{}",
1410 mod->name(),importedMod->name(),importedMod->partitionName());
1411 toModuleDefImpl(intfMod)->addPartition(toModuleDefImpl(importedMod));
1412 toModuleDefImpl(importedMod)->setPrimaryInterface(intfMod);
1413 for (const auto &[partitionFileName_,partitionImportInfoList] : importedMod->getImports())
1414 {
1415 for (const auto &partitionImportInfo : partitionImportInfoList)
1416 {
1417 if (partitionImportInfo.exported && intfMod->name()!=partitionImportInfo.importName)
1418 {
1419 toModuleDefImpl(intfMod)->addExportedModule(partitionImportInfo.importName,partitionImportInfo);
1420 }
1421 }
1422 }
1423 resolvePartitionsRecursively(intfMod,importedMod);
1424 }
1425 }
1426 }
1427 }
1428 }
1429 }
1430}
1431
1433{
1434 AUTO_TRACE();
1435 for (auto &mod : p->moduleFileMap) // foreach module
1436 {
1437 if (mod->moduleType()==ModuleDef::Type::Interface && mod->partitionName().empty())
1438 { // that is a primary interface
1439 resolvePartitionsRecursively(mod.get(),mod.get());
1440 }
1441
1442 // copy exported imports to m_exportedModules
1443 for (const auto &[fileName,importInfoList] : mod->getImports())
1444 {
1445 for (const auto &importInfo : importInfoList)
1446 {
1447 if (importInfo.exported && mod->name()!=importInfo.importName)
1448 {
1449 toModuleDefImpl(mod)->addExportedModule(importInfo.importName,importInfo);
1450 }
1451 }
1452 }
1453
1454 // also link the ModuleDef and FileDef together
1455 bool ambig = false;
1456 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(mod->getDefFileName(),ambig);
1457 if (fd)
1458 {
1459 fd->setModuleDef(mod.get());
1460 toModuleDefImpl(mod)->setFileDef(fd);
1461 }
1462 }
1463}
1464
1466{
1467 AUTO_TRACE();
1468 for (auto &mod : p->moduleFileMap)
1469 {
1470 FileDef *fd = mod->getFileDef();
1471 if (fd)
1472 {
1473 for (const auto &[fileName,importInfoList] : mod->getImports())
1474 {
1475 for (const auto &importInfo : importInfoList)
1476 {
1477 ModuleDef *importedModule = getPrimaryInterface(importInfo.importName);
1478 const FileDef *importedFd = importedModule ? importedModule->getFileDef() : nullptr;
1479 AUTO_TRACE_ADD("module: addIncludeDependency {}->{}:{} fd={}",
1480 mod->qualifiedName(), importInfo.qualifiedName(), importInfo.line, fd?fd->absFilePath():"");
1482 }
1483 }
1484 }
1485 }
1486 for (const auto &[fileName,importInfoList] : p->externalImports)
1487 {
1488 for (const auto &importInfo : importInfoList)
1489 {
1490 bool ambig = false;
1491 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(fileName,ambig);
1492 AUTO_TRACE_ADD("externalImport name={} fd={}",fileName,(void*)fd);
1493 if (fd)
1494 {
1495 ModuleDef *mod = getPrimaryInterface(importInfo.importName);
1496 FileDef *importedFd = mod ? mod->getFileDef() : nullptr;
1497 fd->addIncludeDependency(importedFd,importInfo.importName,IncludeKind::ImportModule);
1498 if (importedFd)
1499 {
1501 }
1502 }
1503 }
1504 }
1505 for (const auto &headerInfo : p->headers)
1506 {
1507 bool ambig = false;
1508 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(headerInfo.fileName,ambig);
1509 AUTO_TRACE_ADD("header name={} fd={}",headerInfo.fileName,(void*)fd);
1510 if (fd)
1511 {
1512 DString resolvedHeader = determineAbsoluteIncludeName(headerInfo.fileName,headerInfo.headerName);
1513 FileDef *importFd = Doxygen::inputNameLinkedMap->findFileDef(resolvedHeader,ambig);
1514 fd->addIncludeDependency(importFd, headerInfo.headerName,
1515 headerInfo.isSystem ? IncludeKind::ImportSystem : IncludeKind::ImportLocal);
1516 if (importFd)
1517 {
1519 }
1520 }
1521 }
1522}
1523
1525{
1526 AUTO_TRACE("{}: collecting symbols for partition {}",intfMod->qualifiedName(),partitionMod->qualifiedName());
1527 auto intfModImpl = toModuleDefImpl(intfMod);
1528 auto partitionModImpl = toModuleDefImpl(partitionMod);
1529 intfModImpl->mergeSymbolsFrom(partitionModImpl);
1530}
1531
1533{
1534 AUTO_TRACE();
1535 for (auto &mod : p->moduleFileMap) // foreach module
1536 {
1537 if (mod->isPrimaryInterface()) // that is a primary interface
1538 {
1539 for (auto &[partitionName,partitionMod] : mod->partitions())
1540 {
1541 collectExportedSymbolsRecursively(mod.get(),partitionMod);
1542 }
1543
1544 // collect all files that contribute to this module (e.g. implementation/partition modules)
1545 auto it = p->moduleNameMap.find(mod->name().str());
1546 if (it != p->moduleNameMap.end())
1547 {
1548 for (auto contributingMod : it->second)
1549 {
1550 AUTO_TRACE_ADD(" adding contributing module {} to interface module {} type={} partition={} isPrimaryIntf={}",
1551 contributingMod->qualifiedName(),
1552 mod->name(),
1553 contributingMod->moduleType()==ModuleDef::Type::Interface ? "Interface" : "Implementation",
1554 contributingMod->partitionName(),
1555 contributingMod->isPrimaryInterface());
1557 }
1558 }
1559 }
1560 }
1561}
1562
1564{
1565 for (auto &mod : p->moduleFileMap) // foreach module
1566 {
1568 }
1569}
1570
1572{
1573 for (auto &mod : p->moduleFileMap) // foreach module
1574 {
1575 if (mod->isPrimaryInterface())
1576 {
1577 mod->writeDocumentation(ol);
1578 }
1579 }
1580}
1581
1583{
1584 int count=0;
1585 for (const auto &mod : p->moduleFileMap) // foreach module
1586 {
1587 if (mod->isPrimaryInterface()) count++;
1588 }
1589 return count;
1590}
1591
1593{
1594 return p->moduleFileMap;
1595}
1596
1598{
1599 return p->moduleFileMap;
1600}
1601
1603{
1604 AUTO_TRACE("file={} module={}",root->fileName,root->name);
1605 if (root->doc.empty() && root->brief.empty()) return;
1606 if (root->name.find(':')!=DString::npos)
1607 {
1608 warn(root->fileName,root->startLine,"Ignoring documentation for module partition {}. Please place documentation at the primary module name",
1609 root->name);
1610 }
1611 else
1612 {
1613 auto it = p->moduleNameMap.find(root->name.str());
1614 if (it != p->moduleNameMap.end())
1615 {
1616 ModuleDef *mod = getPrimaryInterface(root->name);
1617 if (mod)
1618 {
1619 mod->setDocumentation(root->doc,root->docFile,root->docLine);
1620 mod->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1621 mod->setId(root->id);
1622 mod->setHidden(root->hidden);
1623 mod->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1624 mod->setRefItems(root->sli);
1625 mod->setRequirementReferences(root->rqli);
1626 //mod->addSectionsToDefinition(root->anchors);
1627 addModuleToGroups(root,mod);
1628 }
1629 else
1630 {
1631 warn(root->fileName,root->startLine,"Found documentation for module {} but it has no primary interface unit.",root->name);
1632 }
1633 }
1634 else
1635 {
1636 warn(root->fileName,root->startLine,"Found documentation for unknown module {}.",root->name);
1637 }
1638 }
1639}
1640
1642{
1643 auto it = p->moduleNameMap.find(moduleName.str());
1644 if (it != p->moduleNameMap.end())
1645 {
1646 for (const auto &mod : it->second)
1647 {
1648 if (mod->isPrimaryInterface())
1649 {
1650 return mod;
1651 }
1652 }
1653 }
1654 return nullptr;
1655}
1656
1658{
1659 for (const auto &mod : p->moduleFileMap) // foreach module
1660 {
1661 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addListReferences();
1662 }
1663}
1664
1666{
1667 for (const auto &mod : p->moduleFileMap) // foreach module
1668 {
1669 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addRequirementReferences();
1670 }
1671}
1672
1674{
1675 for (const auto &mod : p->moduleFileMap) // foreach module
1676 {
1677 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addMembersToMemberGroup();
1678 }
1679}
1680
1682{
1683 for (const auto &mod : p->moduleFileMap) // foreach module
1684 {
1685 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->distributeMemberGroupDocumentation();
1686 }
1687}
1688
1690{
1691 for (auto &mod : p->moduleFileMap) // foreach module
1692 {
1693 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->findSectionsInDocumentation();
1694 }
1695}
1696
1698{
1699 for (auto &mod : p->moduleFileMap) // foreach module
1700 {
1701 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->sortMemberLists();
1702 }
1703}
1704
A abstract class representing of a compound symbol.
Definition classdef.h:100
virtual DString className() const =0
Returns the name of the class including outer classes, but not including namespaces.
bool declVisible(const ClassDef::CompoundType *filter=nullptr) const
Definition classlist.cpp:27
void writeDeclaration(OutputList &ol, const ClassDef::CompoundType *filter, const DString &header, bool localNames) const
Definition classlist.cpp:51
bool declVisible() const
void writeDeclaration(OutputList &ol, const DString &header, bool localNames) const
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:178
DString & prepend(const char *s)
Definition dstring.h:515
size_t find(char c, size_t pos=0) const
Definition dstring.h:239
const std::string & str() const
Definition dstring.h:645
The common base class of all entity definitions found in the sources.
Definition definition.h:77
virtual DString briefDescription(bool abbreviate=false) const =0
virtual bool isLinkable() const =0
virtual const DString & name() const =0
virtual bool isLinkableInProject() const =0
virtual bool isExported() const =0
virtual DString displayName(bool includeScope=true) const =0
virtual DString qualifiedName() const =0
virtual DString anchor() const =0
virtual DString getReference() const =0
virtual DString getOutputFileBase() const =0
int getDefLine() const override
bool isReference() const override
DString docFile() const override
void setId(const DString &name) override
bool isExported() const override
bool hasBriefDescription() const override
DString id() const override
DString briefFile() const override
DString briefDescription(bool abbreviate=false) const override
const DString & name() const override
DString getReference() const override
const RefItemVector & xrefListItems() const override
void setReference(const DString &r) override
bool isHidden() const override
DString getDefFileName() const override
DString documentation() const override
DefinitionMixin(const DString &defFileName, int defLine, size_t defColumn, const DString &name, const char *b=nullptr, const char *d=nullptr, bool isSymbol=true)
DString inbodyDocumentation() const override
int docLine() const override
int briefLine() const override
void writeDocAnchorsToTagFile(TextStream &fs) const override
bool hasDocumentation() const override
SrcLangExt getLanguage() const override
virtual void setBodySegment(int defLine, int bls, int ble)=0
virtual void setHidden(bool b)=0
virtual void setDocumentation(const DString &d, const DString &docFile, int docLine, bool stripWhiteSpace=true)=0
virtual void setBriefDescription(const DString &b, const DString &briefFile, int briefLine)=0
virtual void setRequirementReferences(const RequirementRefs &rqli)=0
virtual void setId(const DString &name)=0
virtual void setRefItems(const RefItemVector &sli)=0
static bool suppressDocWarnings
Definition doxygen.h:123
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:97
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:115
RequirementRefs rqli
references to requirements
Definition entry.h:227
int docLine
line number at which the documentation was found
Definition entry.h:201
int endBodyLine
line number where the definition ends
Definition entry.h:218
bool exported
is the symbol exported from a C++20 module
Definition entry.h:188
DString fileName
file this entry was extracted from
Definition entry.h:223
DString docFile
file in which the documentation was found
Definition entry.h:202
DString doc
documentation block (partly parsed)
Definition entry.h:200
DString brief
brief description (doc block)
Definition entry.h:203
int startLine
start line of entry in the source
Definition entry.h:224
int bodyLine
line number of the body in the source
Definition entry.h:216
DString name
member name
Definition entry.h:173
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:226
bool hidden
does this represent an entity that is hidden from the output
Definition entry.h:229
int briefLine
line number at which the brief desc. was found
Definition entry.h:204
DString id
libclang id
Definition entry.h:232
DString briefFile
file in which the brief desc. was found
Definition entry.h:205
A model of a file symbol.
Definition filedef.h:97
virtual void setModuleDef(ModuleDef *mod)=0
virtual DString fileName() const =0
virtual DString getPath() const =0
virtual void addIncludeDependency(const FileDef *fd, const DString &incName, IncludeKind kind)=0
virtual DString absFilePath() const =0
virtual void addIncludedByDependency(const FileDef *fd, const DString &incName, IncludeKind kind)=0
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
Definition filename.cpp:38
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1439
bool add(const char *k, T *obj)
Definition linkedmap.h:284
iterator end()
Definition linkedmap.h:367
const T * find(const std::string &key) const
Definition linkedmap.h:243
iterator begin()
Definition linkedmap.h:366
A model of a class/file/namespace member symbol.
Definition memberdef.h:45
virtual const ClassDef * getClassDef() const =0
virtual MemberType memberType() const =0
virtual void setSectionList(const Definition *container, const MemberList *sl)=0
A list of MemberDef objects as shown in documentation sections.
Definition memberlist.h:126
void writeTagFile(TextStream &, bool useQualifiedName=false, bool showNamespaceMembers=true)
void writeDeclarations(OutputList &ol, const ClassDef *cd, const NamespaceDef *nd, const FileDef *fd, const GroupDef *gd, const ModuleDef *mod, const DString &title, const DString &subtitle, bool showEnumValues=false, bool showInline=false, const ClassDef *inheritedFrom=nullptr, MemberListType lt=MemberListType::PubMethods(), bool showSectionTitle=true) const
Writes the list of members to the output.
void writeDocumentation(OutputList &ol, const DString &scopeName, const Definition *container, const DString &title, const DString &anchor, bool showEnumValues=false, bool showInline=false) const
MemberListType listType() const
Definition memberlist.h:131
bool declVisible() const
Wrapper class for the MemberListType type.
Definition types.h:346
constexpr const char * toLabel() const noexcept
Definition types.h:402
const std::unique_ptr< MemberList > & get(MemberListType lt, MemberListContainer con)
Definition memberlist.h:192
bool contains(const MemberDef *md) const
Definition memberlist.h:90
void push_back(const T &value)
Definition memberlist.h:49
virtual const ImportInfoMap & getImports() const =0
virtual FileDef * getFileDef() const =0
void countMembers()
ModuleDefImpl(const DString &fileName, int startLine, size_t startColumn, const DString &name, Type type, const DString &partitionName)
Definition moduledef.cpp:58
void writeConcepts(OutputList &ol, const DString &title)
void addPartition(ModuleDefImpl *mod)
void distributeMemberGroupDocumentation()
void startMemberDeclarations(OutputList &ol)
DefType definitionType() const override
Definition moduledef.cpp:64
void sortMemberLists()
void writeDeclarationLink(OutputList &ol, bool &found, const DString &header, bool localNames) const
void endMemberDeclarations(OutputList &ol)
void addHeader(int line, const DString &headerName, bool isSystem)
void writeMemberDocumentation(OutputList &ol, MemberListType lt, const DString &title)
MemberList * getMemberList(MemberListType lt) const override
void writeDocumentation(OutputList &ol) override
FileList getUsedFiles() const override
DString partitionName() const override
Definition moduledef.cpp:81
ModuleList m_contributing
void addMemberToModule(const Entry *root, MemberDef *md)
bool isPrimaryInterface() const override
Definition moduledef.cpp:83
void addConceptToModule(const Entry *root, ConceptDef *cd)
FileDef * getFileDef() const override
Definition moduledef.cpp:90
void addClassToModule(const Entry *root, ClassDef *cd)
bool isLinkableInProject() const override
Definition moduledef.cpp:69
DString anchor() const override
Definition moduledef.cpp:68
DString getOutputFileBase() const override
FileDef * m_fileDef
void writeTagFile(TextStream &t) const override
DString displayName(bool=true) const override
Definition moduledef.cpp:66
void writeMemberGroups(OutputList &ol)
DString m_partitionName
const ModuleDef * m_primaryInterface
void startMemberDocumentation(OutputList &ol)
void addImport(int line, const DString &moduleName, const DString &partitionName, bool isExported)
void writeAuthorSection(OutputList &ol)
const ImportInfoMap & getImports() const override
Definition moduledef.cpp:91
MemberLists m_memberLists
int countVisibleMembers() const override
void setPrimaryInterface(const ModuleDef *mod)
void mergeSymbolsFrom(ModuleDefImpl *other)
void writeClassDeclarations(OutputList &ol, const DString &title)
const ClassLinkedRefMap & getClasses() const override
Definition moduledef.cpp:87
void addMembersToMemberGroup()
void writeExports(OutputList &ol, const DString &title)
void endMemberDocumentation(OutputList &ol)
void writeMemberDeclarations(OutputList &ol, MemberListType lt, const DString &title)
void setFileDef(FileDef *fd)
ConceptLinkedRefMap m_concepts
void addMemberToList(MemberListType lt, MemberDef *md)
CodeSymbolType codeSymbolType() const override
Definition moduledef.cpp:65
const ImportInfoMap & getExports() const override
Definition moduledef.cpp:92
void writeBriefDescription(OutputList &ol)
void addRequirementReferences()
ClassLinkedRefMap m_classes
const MemberGroupList & getMemberGroups() const override
Definition moduledef.cpp:86
void findSectionsInDocumentation()
ImportInfoMap m_exportedModules
ModuleMap m_partitions
bool isLinkable() const override
Definition moduledef.cpp:72
ImportInfoMap m_imports
bool hasDetailedDescription() const
void addContributingModule(ModuleDefImpl *mod)
void writeSummaryLinks(OutputList &ol) const override
void writePageNavigation(OutputList &ol) const override
Type moduleType() const override
Definition moduledef.cpp:80
void writeFiles(OutputList &ol, const DString &title)
DString qualifiedName() const override
const ModuleMap & partitions() const override
Definition moduledef.cpp:93
const MemberLists & getMemberLists() const override
Definition moduledef.cpp:85
void addExportedModule(const DString &moduleName, const ImportInfo &info)
void writeDetailedDescription(OutputList &ol, const DString &title)
MemberGroupList m_memberGroups
void addListReferences()
const ConceptLinkedRefMap & getConcepts() const override
Definition moduledef.cpp:88
bool declVisible() const
void writeDeclaration(OutputList &ol, const DString &header, bool localNames) const
void addListReferences()
int numDocumentedModules() const
void sortMemberLists()
void createModuleDef(const DString &fileName, int line, size_t column, bool exported, const DString &moduleName, const DString &partitionName=DString())
void resolveImports()
static ModuleManager & instance()
void addDocs(const Entry *root)
void collectExportedSymbolsRecursively(ModuleDef *intfMod, ModuleDef *mod)
void countMembers()
void addConceptToModule(const Entry *root, ConceptDef *cd)
ModuleLinkedMap & modules()
void addClassToModule(const Entry *root, ClassDef *cd)
void addMemberToModule(const Entry *root, MemberDef *md)
void writeDocumentation(OutputList &ol)
void addMembersToMemberGroup()
void resolvePartitions()
std::unique_ptr< Private > p
Definition moduledef.h:148
void addImport(const DString &moduleFile, int line, const DString &importName, bool isExported, const DString &partitionName=DString())
void addRequirementReferences()
void addHeader(const DString &moduleFile, int line, const DString &headerName, bool isSystem)
void findSectionsInDocumentation()
void collectExportedSymbols()
void resolvePartitionsRecursively(ModuleDef *intfMod, ModuleDef *mod)
ModuleDef * getPrimaryInterface(const DString &moduleName) const
void addTagInfo(const DString &moduleFile, const DString &tagName, const DString &clangId)
void distributeMemberGroupDocumentation()
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:311
void writeDoc(const IDocNodeAST *ast, const Definition *ctx, const MemberDef *md, int sectionLevel=-1)
Definition outputlist.h:379
void startTitleHead(const DString &fileName)
Definition outputlist.h:399
void startMemberDeclaration()
Definition outputlist.h:565
void parseText(const DString &textStr)
void endTitleHead(const DString &fileName, const DString &name)
Definition outputlist.h:401
void disable(OutputType o)
void startParagraph(const DString &classDef=DString())
Definition outputlist.h:403
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name)
Definition outputlist.h:435
void writeRuler()
Definition outputlist.h:517
void enable(OutputType o)
void endContents()
Definition outputlist.h:616
void endHeaderSection()
Definition outputlist.h:463
void endMemberDescription()
Definition outputlist.h:563
void endTextBlock(bool paraBreak=false)
Definition outputlist.h:668
void endMemberDeclaration(const DString &anchor, const DString &inheritId)
Definition outputlist.h:567
void docify(const DString &s)
Definition outputlist.h:433
void startMemberHeader(const DString &anchor, int typ=2)
Definition outputlist.h:465
void writeAnchor(const DString &fileName, const DString &name)
Definition outputlist.h:519
void startHeaderSection()
Definition outputlist.h:461
void insertMemberAlign(bool templ=false)
Definition outputlist.h:513
void writeString(const DString &text)
Definition outputlist.h:407
void endParagraph()
Definition outputlist.h:405
void startMemberSections()
Definition outputlist.h:457
void startMemberList()
Definition outputlist.h:477
void endTextLink()
Definition outputlist.h:440
void startBold()
Definition outputlist.h:557
void endMemberItem(OutputGenerator::MemberItemType type)
Definition outputlist.h:491
void endMemberList()
Definition outputlist.h:479
void writeSynopsis()
Definition outputlist.h:588
void pushGeneratorState()
void writeSummaryLink(const DString &file, const DString &anchor, const DString &title, bool first)
Definition outputlist.h:610
void disableAllBut(OutputType o)
void startTextBlock(bool dense=false)
Definition outputlist.h:666
void popGeneratorState()
void startTextLink(const DString &file, const DString &anchor)
Definition outputlist.h:438
void endBold()
Definition outputlist.h:559
void endGroupHeader(int extraLevels=0)
Definition outputlist.h:451
void startMemberItem(const DString &anchor, OutputGenerator::MemberItemType type, const DString &id=DString())
Definition outputlist.h:489
void startMemberDescription(const DString &anchor, const DString &inheritId=DString(), bool typ=false)
Definition outputlist.h:561
void writePageOutline()
Definition outputlist.h:612
void generateDoc(const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &docStr, const DocOptions &options)
void startContents()
Definition outputlist.h:614
void startGroupHeader(const DString &id=DString(), int extraLevels=0)
Definition outputlist.h:449
void enableAll()
void endMemberHeader()
Definition outputlist.h:467
void endMemberSections()
Definition outputlist.h:459
static RequirementManager & instance()
void addRequirementRefsForSymbol(const Definition *symbol)
Text streaming class that buffers data.
Definition textstream.h:36
virtual DString trNamespace(bool first_capital, bool singular)=0
virtual DString trAuthor(bool first_capital, bool singular)=0
virtual DString trMore()=0
virtual DString trModule(bool first_capital, bool singular)=0
virtual DString trModuleReference(const DString &namespaceName)=0
virtual DString trGeneratedAutomatically(const DString &s)=0
virtual DString trFile(bool first_capital, bool singular)=0
ClassDefMutable * toClassDefMutable(Definition *d)
ConceptDefMutable * toConceptDefMutable(Definition *d)
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:54
#define AUTO_TRACE(...)
Definition docnode.cpp:53
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:59
void docFindSections(const DString &input, const Definition *d, const DString &fileName)
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &input, const DocOptions &options)
int dstricmp_sort(const char *str1, const char *str2)
Definition dstring.h:67
const char * qPrint(const char *s)
Definition dstring.h:783
@ ImportLocal
Definition filedef.h:51
@ ImportModule
Definition filedef.h:52
@ ImportSystem
Definition filedef.h:50
void addModuleToGroups(const Entry *root, ModuleDef *mod)
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const DString &navPath)
Definition index.cpp:431
void startFile(OutputList &ol, const DString &name, bool isSource, const DString &manName, const DString &title, HighlightedItem hli, bool additionalIndices, const DString &altSidebarName, int hierarchyLevel, const DString &allMembersFile)
Definition index.cpp:405
Translator * theTranslator
Definition language.cpp:76
MemberDefMutable * toMemberDefMutable(Definition *d)
#define warn(file, line, fmt,...)
Definition message.h:97
#define err(fmt,...)
Definition message.h:127
std::vector< HeaderInfo > HeaderInfoVector
Definition moduledef.cpp:52
static ModuleDefImpl * toModuleDefImpl(ModuleDef *m)
ModuleDef * toModuleDef(Definition *d)
std::unordered_map< std::string, ModuleDef * > ModuleMap
Definition moduledef.h:60
std::unordered_map< std::string, ImportInfoList > ImportInfoMap
Definition moduledef.h:61
Definition dstring.h:913
void addRefItem(const RefItemVector &sli, const DString &key, const DString &prefix, const DString &name, const DString &title, const DString &args, const Definition *scope)
Definition reflist.h:136
Helper class to pass options when calling OutputList::generateDoc().
Definition docoptions.h:24
DString fileName
Definition moduledef.cpp:47
HeaderInfo(const DString &fn, const DString &name, bool sys)
Definition moduledef.cpp:45
bool isSystem
Definition moduledef.cpp:49
DString headerName
Definition moduledef.cpp:48
DString importName
Definition moduledef.h:44
Represents of a member declaration list with configurable title and subtitle.
Definition layout.h:111
MemberListType type
Definition layout.h:117
DString title(SrcLangExt lang) const
Definition layout.cpp:1790
bool visible() const override
Definition layout.h:120
Represents of a member definition list with configurable title.
Definition layout.h:131
MemberListType type
Definition layout.h:136
DString title(SrcLangExt lang) const
Definition layout.cpp:1802
Definition layout.h:101
DString title(SrcLangExt lang) const
Definition layout.cpp:1783
ModuleLinkedMap moduleFileMap
ImportInfoMap externalImports
HeaderInfoVector headers
std::unordered_map< std::string, ModuleList > moduleNameMap
CodeSymbolType
Definition types.h:481
SrcLangExt
Definition types.h:207
DString convertNameToFile(const DString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:2864
void addGroupListToTitle(OutputList &ol, const Definition *d)
Definition util.cpp:3922
void addHtmlExtensionIfMissing(DString &fName)
Definition util.cpp:3932
DString convertToXML(const DString &s, bool keepEntities, const bool citeEntry)
Definition util.cpp:3233
DString determineAbsoluteIncludeName(const DString &curFile, const DString &incFileName)
Definition util.cpp:2930
DString stripFromPath(const DString &path)
Definition util.cpp:219
A bunch of utility functions.