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#include "moduledef.h"
17#include "definitionimpl.h"
18#include "entry.h"
19#include "memberdef.h"
20#include "classlist.h"
21#include "namespacedef.h"
22#include "conceptdef.h"
23#include "config.h"
24#include "outputlist.h"
25#include "language.h"
26#include "util.h"
27#include "groupdef.h"
28#include "message.h"
29#include "membergroup.h"
30#include "classdef.h"
31#include "textstream.h"
32#include "trace.h"
33#include "filename.h"
34
35class ModuleDefImpl;
36
38{
39 HeaderInfo(const DString &fn,const DString &name,bool sys)
40 : fileName(fn), headerName(name), isSystem(sys) {}
41 DString fileName; // file containing the import
42 DString headerName; // name of the imported header
43 bool isSystem; // <...> => true, "..." => false
44};
45
46using HeaderInfoVector = std::vector<HeaderInfo>;
47
48
49class ModuleDefImpl final : public DefinitionMixin<ModuleDef>
50{
51 public:
52 ModuleDefImpl(const DString &fileName,int startLine,size_t startColumn,
53 const DString &name, Type type, const DString &partitionName)
54 : DefinitionMixin<ModuleDef>(fileName,startLine,startColumn,name,nullptr,nullptr,true),
56
57 // --- Definition
58 DefType definitionType() const override { return TypeModule; }
60 DString displayName(bool=true) const override { return name(); }
61 DString getOutputFileBase() const override;
62 DString anchor() const override { return ""; }
63 bool isLinkableInProject() const override {
65 else return isLinkable() && !isHidden() && !isReference(); }
66 bool isLinkable() const override {
68 else return hasDocumentation(); }
69 DString qualifiedName() const override;
70 void writeSummaryLinks(OutputList &ol) const override;
71 void writePageNavigation(OutputList &ol) const override;
72
73 // --- ModuleDef
74 Type moduleType() const override { return m_type; }
75 DString partitionName() const override { return m_partitionName; }
76 void writeDocumentation(OutputList &ol) override;
77 bool isPrimaryInterface() const override { return m_type==Type::Interface && m_partitionName.empty(); }
78 MemberList *getMemberList(MemberListType lt) const override;
79 const MemberLists &getMemberLists() const override { return m_memberLists; }
80 const MemberGroupList &getMemberGroups() const override { return m_memberGroups; }
81 const ClassLinkedRefMap &getClasses() const override { return m_classes; }
82 const ConceptLinkedRefMap &getConcepts() const override { return m_concepts; }
83 int countVisibleMembers() const override;
84 FileDef *getFileDef() const override { return m_fileDef; }
85 const ImportInfoMap &getImports() const override { return m_imports; }
86 const ImportInfoMap &getExports() const override { return m_exportedModules; }
87 const ModuleMap &partitions() const override { return m_partitions; }
88 void writeTagFile(TextStream &t) const override;
89 FileList getUsedFiles() const override;
90
91 void writeExports(OutputList &ol,const DString &title);
92 void writeClassDeclarations(OutputList &ol,const DString &title);
93 void writeConcepts(OutputList &ol,const DString &title);
94 void writeFiles(OutputList &ol,const DString &title);
99 void writeDetailedDescription(OutputList &ol,const DString &title);
105 void writeDeclarationLink(OutputList &ol,bool &found,const DString &header,bool localNames) const;
106
107 void addHeader(int line,const DString &headerName,bool isSystem);
108 void addImport(int line,const DString &moduleName,const DString &partitionName,bool isExported);
109 void addClassToModule(const Entry *root,ClassDef *cd);
110 void addConceptToModule(const Entry *root,ConceptDef *cd);
111 void addMemberToModule(const Entry *root,MemberDef *md);
112 void addPartition(ModuleDefImpl *mod);
114 void setPrimaryInterface(const ModuleDef *mod);
115 void setFileDef(FileDef *fd);
117 void addExportedModule(const DString &moduleName,const ImportInfo &info);
118 void addListReferences();
123 void sortMemberLists();
124
125 void mergeSymbolsFrom(ModuleDefImpl *other);
126 bool hasDetailedDescription() const;
127 void countMembers();
128
129 private:
141 FileDef *m_fileDef = nullptr; // file holding this module
142};
143
145{
146 return convertNameToFile("module_" + name());
147}
148
150{
151 DString result=name();
152 if (!m_partitionName.empty())
153 {
154 result+=":"+m_partitionName;
155 }
156 return result;
157}
158
160{
161 std::string qName = mod->qualifiedName().str();
162 if (m_partitions.find(qName)==m_partitions.end())
163 {
164 m_partitions.emplace(qName,mod);
165 }
166}
167
169{
170 if (std::find(m_contributing.begin(),m_contributing.end(),mod)==m_contributing.end())
171 {
172 m_contributing.push_back(mod);
173 }
174}
175
180
182{
183 m_fileDef = fd;
184}
185
186void ModuleDefImpl::addHeader(int line,const DString &headerName,bool isSystem)
187{
188 AUTO_TRACE("name={}:line={},header={},isSystem={}",name(),line,headerName,isSystem);
189}
190
191void ModuleDefImpl::addImport(int line,const DString &moduleName,const DString &partitionName,bool isExported)
192{
193 AUTO_TRACE("name={}:line={},module={},partition={}",name(),line,moduleName,partitionName);
194 m_imports[getDefFileName().str()+":"+std::to_string(line)].push_back(ImportInfo(this,moduleName,line,partitionName,isExported));
195}
196
197void ModuleDefImpl::addExportedModule(const DString &moduleName,const ImportInfo &info)
198{
199 AUTO_TRACE("name={}:moduleName={},import={}",name(),moduleName,info.importName);
200 m_exportedModules[moduleName.str()].push_back(info);
201}
202
204{
205 DString className = cd->qualifiedName();
206 AUTO_TRACE("{}:{} class {} of module {} exported={}",
207 root->fileName,root->startLine, className, name(), root->exported);
208 bool isExported = m_classes.find(className)!=nullptr;
209 if (root->exported && !isExported)
210 {
211 m_classes.add(className,cd);
212 }
213 auto cdm = toClassDefMutable(cd);
214 if (cdm && root->exported && !cd->isExported())
215 {
216 cdm->setExported(true);
217 }
218}
219
221{
222 DString conceptName = cd->qualifiedName();
223 AUTO_TRACE("{}:{} concept {} of module {} exported={}",
224 root->fileName,root->startLine,
225 cd->qualifiedName(),name(),
226 root->exported);
227 bool isExported = m_classes.find(conceptName)!=nullptr;
228 if (root->exported && !isExported)
229 {
230 m_concepts.add(conceptName,cd);
231 }
232 auto cdm = toConceptDefMutable(cd);
233 if (cdm && root->exported && !cd->isExported())
234 {
235 cdm->setExported(true);
236 }
237}
238
240{
241 for (auto &ml : m_memberLists)
242 {
243 if (ml->listType()==lt)
244 {
245 return ml.get();
246 }
247 }
248 return nullptr;
249}
250
252{
253 bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
254 bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
256 ml->setNeedsSorting(
257 (ml->listType().isDeclaration() && sortBriefDocs) ||
258 (ml->listType().isDocumentation() && sortMemberDocs));
259 ml->push_back(md);
260 if (ml->listType().isDeclaration())
261 {
263 if (mdm)
264 {
265 mdm->setSectionList(this,ml.get());
266 }
267 }
268}
269
271{
272 AUTO_TRACE("{}:{} member {} of module {} exported={}",
273 qPrint(root->fileName),root->startLine,
275 root->exported);
276 MemberList *allMemberList = getMemberList(MemberListType::AllMembersList());
277 if (allMemberList==nullptr)
278 {
279 m_memberLists.emplace_back(std::make_unique<MemberList>(MemberListType::AllMembersList(),MemberListContainer::Module));
280 allMemberList = m_memberLists.back().get();
281 }
282 if (allMemberList->contains(md))
283 {
284 return;
285 }
286 allMemberList->push_back(md);
287 switch (md->memberType())
288 {
289 case MemberType::Variable:
290 addMemberToList(MemberListType::DecVarMembers(),md);
291 break;
292 case MemberType::Function:
293 addMemberToList(MemberListType::DecFuncMembers(),md);
294 break;
295 case MemberType::Typedef:
296 addMemberToList(MemberListType::DecTypedefMembers(),md);
297 break;
298 case MemberType::Enumeration:
299 addMemberToList(MemberListType::DecEnumMembers(),md);
300 break;
301 default:
302 break;
303 }
304 auto mdm = toMemberDefMutable(md);
305 if (mdm && root->exported && !md->isExported())
306 {
307 mdm->setExported(true);
308 }
309}
310
312{
313 AUTO_TRACE("{} merging symbols of {} ({}:{})",
314 name(),other->qualifiedName(),other->getDefFileName(),other->getDefLine());
315 for (const auto &cd : other->getClasses())
316 {
317 m_classes.add(cd->qualifiedName(),cd);
318 }
319 for (const auto &cd : other->getConcepts())
320 {
321 m_concepts.add(cd->qualifiedName(),cd);
322 }
323 auto mergeMemberList = [this,other](MemberListType lt)
324 {
325 const auto srcMl = other->getMemberList(lt);
326 if (srcMl)
327 {
328 auto &dstMl = m_memberLists.get(lt,srcMl->container());
329 for (const auto &md : *srcMl)
330 {
331 dstMl->push_back(md);
332 }
333 }
334 };
335 mergeMemberList(MemberListType::DecVarMembers());
336 mergeMemberList(MemberListType::DecFuncMembers());
337 mergeMemberList(MemberListType::DecTypedefMembers());
338 mergeMemberList(MemberListType::DecEnumMembers());
339}
340
342{
343 if (isReference()) return;
344 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
346 AUTO_TRACE("%s file=%s",name(),getDefFileName());
347 SrcLangExt lang = getLanguage();
348 DString pageTitle;
349 if (Config_getBool(HIDE_COMPOUND_REFERENCE))
350 {
351 pageTitle = displayName();
352 }
353 else
354 {
356 }
358
359 // ---- title part
361 bool writeOutlinePanel = generateTreeView && Config_getBool(PAGE_OUTLINE_PANEL);
362 if (!writeOutlinePanel) writeSummaryLinks(ol);
364
367 ol.parseText(pageTitle);
369
370 addGroupListToTitle(ol,this);
371
374 ol.endTitleHead(getOutputFileBase(),pageTitle);
376
380 ol.writeString(" - ");
381 ol.parseText(pageTitle);
383
384 ol.endHeaderSection();
385 ol.startContents();
386
387 //---------------------------------------- start flexible part -------------------------------
388 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
389 {
390 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
391 switch (lde->kind())
392 {
393 case LayoutDocEntry::BriefDesc:
395 break;
396 case LayoutDocEntry::MemberDeclStart:
398 break;
399 case LayoutDocEntry::ModuleClasses:
400 if (ls) writeClassDeclarations(ol,ls->title(lang));
401 break;
402 case LayoutDocEntry::ModuleConcepts:
403 if (ls) writeConcepts(ol,ls->title(lang));
404 break;
405 case LayoutDocEntry::ModuleExports:
406 if (ls) writeExports(ol,ls->title(lang));
407 break;
408 case LayoutDocEntry::ModuleUsedFiles:
409 if (ls) writeFiles(ol,ls->title(lang));
410 break;
411 case LayoutDocEntry::MemberGroups:
413 break;
414 case LayoutDocEntry::MemberDecl:
415 {
416 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
417 if (lmd) writeMemberDeclarations(ol,lmd->type,lmd->title(lang));
418 }
419 break;
420 case LayoutDocEntry::MemberDeclEnd:
422 break;
423 case LayoutDocEntry::DetailedDesc:
424 if (ls) writeDetailedDescription(ol,ls->title(lang));
425 break;
426 case LayoutDocEntry::MemberDefStart:
428 break;
429 case LayoutDocEntry::MemberDef:
430 {
431 const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get());
432 if (lmd) writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
433 }
434 break;
435 case LayoutDocEntry::MemberDefEnd:
437 break;
438 case LayoutDocEntry::AuthorSection:
440 break;
441 case LayoutDocEntry::ClassIncludes:
442 case LayoutDocEntry::ClassInheritanceGraph:
443 case LayoutDocEntry::ClassNestedClasses:
444 case LayoutDocEntry::ClassCollaborationGraph:
445 case LayoutDocEntry::ClassAllMembersLink:
446 case LayoutDocEntry::ClassUsedFiles:
447 case LayoutDocEntry::ClassInlineClasses:
448 case LayoutDocEntry::FileClasses:
449 case LayoutDocEntry::FileConcepts:
450 case LayoutDocEntry::FileInterfaces:
451 case LayoutDocEntry::FileStructs:
452 case LayoutDocEntry::FileExceptions:
453 case LayoutDocEntry::FileNamespaces:
454 case LayoutDocEntry::FileConstantGroups:
455 case LayoutDocEntry::FileIncludes:
456 case LayoutDocEntry::FileIncludeGraph:
457 case LayoutDocEntry::FileIncludedByGraph:
458 case LayoutDocEntry::FileInlineClasses:
459 case LayoutDocEntry::FileSourceLink:
460 case LayoutDocEntry::NamespaceNestedNamespaces:
461 case LayoutDocEntry::NamespaceNestedConstantGroups:
462 case LayoutDocEntry::NamespaceClasses:
463 case LayoutDocEntry::NamespaceConcepts:
464 case LayoutDocEntry::NamespaceInterfaces:
465 case LayoutDocEntry::NamespaceStructs:
466 case LayoutDocEntry::NamespaceExceptions:
467 case LayoutDocEntry::NamespaceInlineClasses:
468 case LayoutDocEntry::ConceptDefinition:
469 case LayoutDocEntry::GroupClasses:
470 case LayoutDocEntry::GroupConcepts:
471 case LayoutDocEntry::GroupModules:
472 case LayoutDocEntry::GroupInlineClasses:
473 case LayoutDocEntry::GroupNamespaces:
474 case LayoutDocEntry::GroupDirs:
475 case LayoutDocEntry::GroupNestedGroups:
476 case LayoutDocEntry::GroupFiles:
477 case LayoutDocEntry::GroupGraph:
478 case LayoutDocEntry::GroupPageDocs:
479 case LayoutDocEntry::DirSubDirs:
480 case LayoutDocEntry::DirFiles:
481 case LayoutDocEntry::DirGraph:
482 err("Internal inconsistency: member '{}' should not be part of "
483 "LayoutDocManager::Module entry list\n",lde->entryToString());
484 break;
485 }
486 }
487
488 //---------------------------------------- end flexible part -------------------------------
489 if (generateTreeView)
490 {
493 ol.endContents();
494 ol.writeString("</div><!-- doc-content -->\n");
496 ol.writeString("</div><!-- container -->\n");
498 }
499 endFile(ol,generateTreeView,true);
500
502}
503
505{
506 m_classes.writeDeclaration(ol,nullptr,title,false);
507}
508
510{
511 m_concepts.writeDeclaration(ol,title,false);
512}
513
518
523
525{
526 if (Config_getBool(SEPARATE_MEMBER_PAGES))
527 {
530 }
531}
532
534{
535 if (Config_getBool(SEPARATE_MEMBER_PAGES))
536 {
539 }
540}
541
543{
545 {
548 ol.writeRuler();
552 ol.writeAnchor(DString(),"details");
554 ol.startGroupHeader("details");
555 ol.parseText(title);
556 ol.endGroupHeader();
557
558 ol.startTextBlock();
559 if (!briefDescription().empty() && Config_getBool(REPEAT_BRIEF))
560 {
562 briefLine(),
563 this,
564 nullptr,
566 DocOptions());
567 }
568 if (!briefDescription().empty() && Config_getBool(REPEAT_BRIEF) &&
569 !documentation().empty())
570 {
574 ol.enableAll();
577 ol.writeString("\n\n");
579 }
580 if (!documentation().empty())
581 {
582 ol.generateDoc(docFile(),
583 docLine(),
584 this,
585 nullptr,
586 documentation()+"\n",
587 DocOptions()
588 .setIndexWords(true));
589 }
590 ol.endTextBlock();
591 }
592}
593
595{
597 {
598 auto parser { createDocParser() };
599 auto ast { validatingParseDoc(*parser.get(),
600 briefFile(),
601 briefLine(),
602 this,
603 nullptr,
605 DocOptions()
606 .setIndexWords(true)
607 .setSingleLine(true))
608 };
609 if (!ast->empty())
610 {
611 ol.startParagraph();
614 ol.writeString(" - ");
616 ol.writeDoc(ast.get(),this,nullptr);
619 ol.writeString(" \n");
621
623 {
625 ol.startTextLink(DString(),"details");
627 ol.endTextLink();
628 }
630 ol.endParagraph();
631 }
632 }
633 ol.writeSynopsis();
634}
635
637{
638 for (const auto &mg : m_memberGroups)
639 {
640 mg->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this);
641 }
642}
643
645{
646 MemberList * ml = getMemberList(lt);
647 if (ml) ml->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this,title,DString());
648}
649
651{
652 MemberList * ml = getMemberList(lt);
653 if (ml) ml->writeDocumentation(ol,name(),this,title,ml->listType().toLabel());
654}
655
657{
658 // write Author section (Man only)
661 ol.startGroupHeader();
662 ol.parseText(theTranslator->trAuthor(true,true));
663 ol.endGroupHeader();
666}
667
669{
670 bool repeatBrief = Config_getBool(REPEAT_BRIEF);
671 return (!briefDescription().empty() && repeatBrief) || !documentation().empty();
672}
673
675{
676 for (auto &ml : m_memberLists)
677 {
678 ml->countDecMembers();
679 ml->countDocMembers();
680 }
681 for (const auto &mg : m_memberGroups)
682 {
683 mg->countDecMembers();
684 mg->countDocMembers();
685 }
686}
687
689{
692 getLanguage()==SrcLangExt::Fortran ?
693 theTranslator->trModule(true,true) :
694 theTranslator->trNamespace(true,true),
696 DString(),
697 this
698 );
699 for (const auto &mg : m_memberGroups)
700 {
701 mg->addListReferences(this);
702 }
703 for (auto &ml : m_memberLists)
704 {
705 if (ml->listType().isDocumentation())
706 {
707 ml->addListReferences(this);
708 }
709 }
710}
711
713{
715 for (const auto &mg : m_memberGroups)
716 {
717 mg->addRequirementReferences(this);
718 }
719 for (auto &ml : m_memberLists)
720 {
721 if (ml->listType().isDocumentation())
722 {
723 ml->addRequirementReferences(this);
724 }
725 }
726}
727
729{
730 for (auto &ml : m_memberLists)
731 {
732 if (ml->listType().isDeclaration())
733 {
735 }
736 }
737
738 // add members inside sections to their groups
739 for (const auto &mg : m_memberGroups)
740 {
741 if (mg->allMembersInSameSection() && Config_getBool(SUBGROUPING))
742 {
743 //printf("----> addToDeclarationSection(%s)\n",qPrint(mg->header()));
744 mg->addToDeclarationSection();
745 }
746 }
747}
748
750{
751 for (const auto &mg : m_memberGroups)
752 {
753 mg->distributeMemberGroupDocumentation();
754 }
755}
756
758{
762 for (const auto &mg : m_memberGroups)
763 {
764 mg->findSectionsInDocumentation(this);
765 }
766 for (auto &ml : m_memberLists)
767 {
768 if (ml->listType().isDeclaration())
769 {
770 ml->findSectionsInDocumentation(this);
771 }
772 }
773}
774
776{
777 for (auto &ml : m_memberLists)
778 {
779 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(false); }
780 }
781
782 if (Config_getBool(SORT_BRIEF_DOCS))
783 {
784 auto classComp = [](const ClassLinkedRefMap::Ptr &c1,const ClassLinkedRefMap::Ptr &c2)
785 {
786 return Config_getBool(SORT_BY_SCOPE_NAME) ?
787 dstricmp_sort(c1->name(), c2->name())<0 :
788 dstricmp_sort(c1->className(), c2->className())<0;
789 };
790 std::stable_sort(m_classes.begin(), m_classes.end(), classComp);
791
792 auto conceptComp = [](const ConceptLinkedRefMap::Ptr &c1,const ConceptLinkedRefMap::Ptr &c2)
793 {
794 return Config_getBool(SORT_BY_SCOPE_NAME) ?
795 dstricmp_sort(c1->qualifiedName(), c2->qualifiedName())<0 :
796 dstricmp_sort(c1->name(), c2->name())<0;
797 };
798 std::stable_sort(m_concepts.begin(), m_concepts.end(), conceptComp);
799 }
800
801 static auto contrComp = [](const ModuleDef *m1, const ModuleDef *m2)
802 {
803 FileDef *f1 = m1->getFileDef();
804 FileDef *f2 = m2->getFileDef();
805 DString fn1 = f1 ? f1->name() : m1->name();
806 DString fn2 = f2 ? f2->name() : m2->name();
807 static auto typeRank = [](const ModuleDef *m) -> int
808 {
809 if (m->moduleType()==ModuleDef::Type::Interface)
810 {
811 if (m->partitionName().empty()) return 0; // primary interface unit
812 return 1; // partition interface unit
813 }
814 else
815 {
816 if (!m->partitionName().empty()) return 2; // partition implementation unit
817 return 3; // implementation unit
818 }
819 };
820 auto tr1 = typeRank(m1);
821 auto tr2 = typeRank(m2);
822 int diff = dstricmp_sort(fn1,fn2);
823 return tr1<tr2 || (tr1==tr2 && diff<0);
824 };
825
826 std::stable_sort(m_contributing.begin(), m_contributing.end(), contrComp);
827}
828
830{
833 bool first=true;
834 SrcLangExt lang=getLanguage();
835 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
836 {
837 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
838 if (lde->kind()==LayoutDocEntry::ModuleClasses && m_classes.declVisible() && ls)
839 {
840 DString label = "classes";
841 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
842 first=false;
843 }
844 else if (lde->kind()==LayoutDocEntry::ModuleConcepts && m_concepts.declVisible() && ls)
845 {
846 DString label = "concepts";
847 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
848 first=false;
849 }
850 else if (lde->kind()==LayoutDocEntry::ModuleUsedFiles && ls)
851 {
852 DString label = "files";
853 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
854 first=false;
855 }
856 else if (lde->kind()==LayoutDocEntry::MemberDecl)
857 {
858 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
859 if (lmd)
860 {
861 MemberList * ml = getMemberList(lmd->type);
862 if (ml && ml->declVisible())
863 {
864 ol.writeSummaryLink(DString(),ml->listType().toLabel(),lmd->title(lang),first);
865 first=false;
866 }
867 }
868 }
869 }
870 if (!first)
871 {
872 ol.writeString(" </div>\n");
873 }
875}
876
881
882void ModuleDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const DString &header,bool localNames) const
883{
884 if (isLinkable())
885 {
886 if (!found) // first module
887 {
888 ol.startMemberHeader("modules");
889 if (!header.empty())
890 {
891 ol.parseText(header);
892 }
893 else
894 {
895 theTranslator->trModule(true,false);
896 }
897 ol.endMemberHeader();
898 ol.startMemberList();
899 found=true;
900 }
902 DString cname = displayName(!localNames);
903 DString anc = anchor();
904 if (anc.empty()) anc=cname; else anc.prepend(cname+"_");
906 ol.writeString("module ");
908 if (isLinkable())
909 {
912 anchor(),
913 cname
914 );
915 }
916 else
917 {
918 ol.startBold();
919 ol.docify(cname);
920 ol.endBold();
921 }
923 // add the brief description if available
924 if (!briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
925 {
926 auto parser { createDocParser() };
927 auto ast { validatingParseDoc(*parser.get(),
928 briefFile(),
929 briefLine(),
930 this,
931 nullptr,
933 DocOptions()
934 .setSingleLine(true))
935 };
936 if (!ast->empty())
937 {
939 ol.writeDoc(ast.get(),this,nullptr);
941 }
942 }
944 }
945}
946
947
949{
950 AUTO_TRACE("name={} count={}",name(),m_exportedModules.size());
951 if (!m_exportedModules.empty())
952 {
953 ol.startMemberHeader("exports");
954 ol.parseText(title);
955 ol.endMemberHeader();
956 ol.startMemberList();
957 for (const auto &[moduleName,importInfoList] : m_exportedModules)
958 {
959 for (const auto &importInfo : importInfoList)
960 {
961 ModuleDef *mod = ModuleManager::instance().getPrimaryInterface(importInfo.importName);
964 ol.docify(theTranslator->trModule(false,true)+" ");
966 if (mod && mod->isLinkable())
967 {
969 }
970 else
971 {
972 ol.startBold();
973 ol.docify(importInfo.importName);
974 ol.endBold();
975 }
977 if (mod && !mod->briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
978 {
981 briefLine(),
982 mod,
983 nullptr,
984 mod->briefDescription(),
985 DocOptions()
986 .setSingleLine(true));
988 }
990 }
991 }
992 ol.endMemberList();
993 }
994}
995
997{
998 AUTO_TRACE("{} count={}",name(),m_contributing.size());
999 if (!m_contributing.empty())
1000 {
1001 ol.startMemberHeader("files");
1002 ol.parseText(title);
1003 ol.endMemberHeader();
1004 ol.startMemberList();
1005 for (const auto &mod : m_contributing)
1006 {
1007 FileDef *fd = mod->getFileDef();
1008 if (fd)
1009 {
1011 DString fname = fd->displayName();
1012 DString anc = fd->anchor();
1013 if (anc.empty()) anc=fname; else anc.prepend(fname+"_");
1015 ol.docify(theTranslator->trFile(false,true)+" ");
1016 ol.insertMemberAlign();
1017 DString path=fd->getPath();
1018 if (Config_getBool(FULL_PATH_NAMES))
1019 {
1020 ol.docify(stripFromPath(path));
1021 }
1022 if (fd->isLinkable())
1023 {
1024 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),DString(),fname);
1025 }
1026 else
1027 {
1028 ol.startBold();
1029 ol.docify(fd->displayName());
1030 ol.endBold();
1031 }
1033 if (!fd->briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
1034 {
1037 briefLine(),
1038 fd,
1039 nullptr,
1040 fd->briefDescription(),
1041 DocOptions()
1042 .setSingleLine(true));
1044 }
1046 }
1047 }
1048 ol.endMemberList();
1049 }
1050}
1051
1053{
1054 FileList result;
1055 for (const auto &mod : m_contributing)
1056 {
1057 FileDef *fd = mod->getFileDef();
1058 if (fd) result.push_back(fd);
1059 }
1060 return result;
1061}
1062
1064{
1065 int count=0;
1066 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
1067 {
1068 if (lde->kind()==LayoutDocEntry::MemberDecl)
1069 {
1070 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1071 if (lmd)
1072 {
1073 MemberList *ml = getMemberList(lmd->type);
1074 if (ml)
1075 {
1076 for (const auto &md : *ml)
1077 {
1078 if (md->visibleInIndex())
1079 {
1080 count++;
1081 }
1082 }
1083 }
1084 }
1085 }
1086 else if (lde->kind()==LayoutDocEntry::ModuleClasses)
1087 {
1088 for (const auto &cd : getClasses())
1089 {
1090 if (cd->isLinkableInProject())
1091 {
1092 count++;
1093 }
1094 }
1095 }
1096 else if (lde->kind()==LayoutDocEntry::ModuleConcepts)
1097 {
1098 for (const auto &cd : getConcepts())
1099 {
1100 if (cd->isLinkableInProject())
1101 {
1102 count++;
1103 }
1104 }
1105 }
1106 }
1107 return count;
1108}
1109
1111{
1112 if (!isPrimaryInterface() || !isLinkableInProject()) return;
1113 tagFile << " <compound kind=\"module\">\n";
1114 tagFile << " <name>" << convertToXML(name()) << "</name>\n";
1115 const FileDef *fd = getFileDef();
1116 DString fn = fd ? fd->getOutputFileBase() : getOutputFileBase();
1118 tagFile << " <filename>" << convertToXML(fn) << "</filename>\n";
1119#if 0 // at the moment we do not export the members of a module to a tag file.
1120 // We let the project using a tag file directly link to the implementation of the
1121 // symbols (which have the same scope).
1122 //
1123 // When we support linking to a module's interface instead we need to
1124 // export the module's members as well. Then we probably need a way to
1125 // disambiguate/prioritize a link to a module over a link to the implementation,
1126 // for instance by hiding non-exported symbols from the tag file.
1127 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Group))
1128 {
1129 switch (lde->kind())
1130 {
1131 case LayoutDocEntry::ModuleExports:
1132 {
1133 for (const auto &[modName,importInfo] : m_exportedModules)
1134 {
1135 tagFile << " <export>" << convertToXML(importInfo.importName) << "</export>\n";
1136 }
1137 }
1138 break;
1139 case LayoutDocEntry::ModuleClasses:
1140 {
1141 for (const auto &cd : m_classes)
1142 {
1143 if (cd->isLinkableInProject())
1144 {
1145 tagFile << " <class kind=\"" << cd->compoundTypeString()
1146 << "\">" << convertToXML(cd->name()) << "</class>\n";
1147 }
1148 }
1149 }
1150 break;
1151 case LayoutDocEntry::ModuleConcepts:
1152 {
1153 for (const auto &cd : m_concepts)
1154 {
1155 if (cd->isLinkableInProject())
1156 {
1157 tagFile << " <concept>" << convertToXML(cd->name())
1158 << "</concept>\n";
1159 }
1160 }
1161 }
1162 break;
1163 case LayoutDocEntry::ModuleUsedFiles:
1164 {
1165 for (const auto &usedFd : getUsedFiles())
1166 {
1167 if (usedFd->isLinkableInProject())
1168 {
1169 tagFile << " <file>" << convertToXML(usedFd->name()) << "</file>\n";
1170 }
1171 }
1172 }
1173 break;
1174 case LayoutDocEntry::MemberDecl:
1175 {
1176 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1177 if (lmd && lmd->visible())
1178 {
1179 MemberList * ml = getMemberList(lmd->type);
1180 if (ml)
1181 {
1182 ml->writeTagFile(tagFile,true);
1183 }
1184 }
1185 }
1186 break;
1187 default:
1188 break;
1189 }
1190 }
1191#endif
1192 DString idStr = id();
1193 if (!idStr.empty())
1194 {
1195 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>\n";
1196 }
1197 writeDocAnchorsToTagFile(tagFile);
1198 tagFile << " </compound>\n";
1199}
1200
1201//------------------------------------------------------------------------------------------------------------
1202
1204{
1205 if (d==nullptr) return nullptr;
1206 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<ModuleDef*>(d) : nullptr;
1207}
1208
1210{
1211 if (d==nullptr) return nullptr;
1212 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<const ModuleDef*>(d) : nullptr;
1213}
1214
1216{ return static_cast<ModuleDefImpl*>(m); }
1217
1218//static inline const ModuleDefImpl *toModuleDefImpl(const ModuleDef *m)
1219//{ return static_cast<const ModuleDefImpl*>(m); }
1220
1221static inline ModuleDefImpl *toModuleDefImpl(const std::unique_ptr<ModuleDef> &m)
1222{ return static_cast<ModuleDefImpl*>(m.get()); }
1223
1224//------------------------------------------------------------------------------------
1225
1227{
1228 bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
1229 for (const auto &mod : *this)
1230 {
1231 bool isLink = mod->isLinkable();
1232 if (isLink || !hideUndocClasses)
1233 {
1234 return true;
1235 }
1236 }
1237 return false;
1238}
1239
1240void ModuleLinkedRefMap::writeDeclaration(OutputList &ol,const DString &header,bool localNames) const
1241{
1242 bool found=false;
1243 for (const auto &mod : *this)
1244 {
1245 toModuleDefImpl(mod)->writeDeclarationLink(ol,found,header,localNames);
1246 }
1247 if (found) ol.endMemberList();
1248}
1249
1250//------------------------------------------------------------------------------------------------------------
1251
1253{
1254 ModuleLinkedMap moduleFileMap; // file->module mapping
1255 std::unordered_map<std::string,ModuleList> moduleNameMap; // name->module mapping
1258 std::mutex mutex;
1259};
1260
1262{
1263 static ModuleManager m;
1264 return m;
1265}
1266
1268{
1269}
1270
1271void ModuleManager::createModuleDef(const DString &fileName,int line,size_t column,bool exported,
1272 const DString &moduleName,const DString &partitionName)
1273{
1274 AUTO_TRACE("{}:{}: Found module name='{}' partition='{}' exported='{}'",
1275 fileName,line,moduleName,partitionName,exported);
1276 std::lock_guard lock(p->mutex);
1278 std::unique_ptr<ModuleDef> modDef = std::make_unique<ModuleDefImpl>(fileName,line,column,moduleName,mt,partitionName);
1279 auto mod = p->moduleFileMap.add(fileName,std::move(modDef));
1280 auto it = p->moduleNameMap.find(moduleName.str());
1281 if (it == p->moduleNameMap.end())
1282 {
1283 ModuleList ml;
1284 ml.push_back(mod);
1285 p->moduleNameMap.emplace(moduleName.str(),ml);
1286 }
1287 else
1288 {
1289 it->second.push_back(mod);
1290 }
1291}
1292
1294{
1295 std::lock_guard lock(p->mutex);
1296 p->headers.clear();
1297 p->externalImports.clear();
1298 p->moduleNameMap.clear();
1299 p->moduleFileMap.clear();
1300}
1301
1302void ModuleManager::addHeader(const DString &moduleFile,int line,const DString &headerName,bool isSystem)
1303{
1304 AUTO_TRACE("{}:{} headerName={} isSystem={}",moduleFile,line,headerName,isSystem);
1305 std::lock_guard lock(p->mutex);
1306 auto mod = p->moduleFileMap.find(moduleFile);
1307 if (mod)
1308 {
1309 toModuleDefImpl(mod)->addHeader(line,headerName,isSystem);
1310 }
1311 else
1312 {
1313 AUTO_TRACE_ADD("imported header '{}' found in file '{}' that is not a module",headerName,moduleFile);
1314 }
1315 p->headers.emplace_back(moduleFile,headerName,isSystem);
1316}
1317
1318void ModuleManager::addImport(const DString &moduleFile,int line,const DString &importName,
1319 bool isExported,const DString &partitionName)
1320{
1321 AUTO_TRACE("{}:{} importName={},isExported={},partitionName={}",
1322 moduleFile,line,importName,isExported,partitionName);
1323 std::lock_guard lock(p->mutex);
1324 auto mod = p->moduleFileMap.find(moduleFile);
1325 if (mod) // import inside a module
1326 {
1327 AUTO_TRACE_ADD("in module");
1328 toModuleDefImpl(mod)->addImport(line,importName.empty()?mod->name():importName,partitionName,isExported);
1329 }
1330 else // import outside of a module
1331 {
1332 AUTO_TRACE_ADD("outside module");
1333 p->externalImports[moduleFile.str()].emplace_back(nullptr,importName,line,partitionName);
1334 }
1335}
1336
1338{
1339 std::lock_guard lock(p->mutex);
1340 auto mod = p->moduleFileMap.find(root->fileName);
1341 if (mod)
1342 {
1343 toModuleDefImpl(mod)->addClassToModule(root,cd);
1344 auto cdm = toClassDefMutable(cd);
1345 if (cdm) cdm->setModuleDef(mod);
1346 }
1347}
1348
1350{
1351 std::lock_guard lock(p->mutex);
1352 auto mod = p->moduleFileMap.find(root->fileName);
1353 if (mod)
1354 {
1355 toModuleDefImpl(mod)->addConceptToModule(root,cd);
1356 auto cdm = toConceptDefMutable(cd);
1357 if (cdm) cdm->setModuleDef(mod);
1358 }
1359}
1360
1362{
1363 std::lock_guard lock(p->mutex);
1364 auto mod = p->moduleFileMap.find(root->fileName);
1365 if (mod && root->exported && md->getClassDef()==nullptr)
1366 {
1367 toModuleDefImpl(mod)->addMemberToModule(root,md);
1368 auto mdm = toMemberDefMutable(md);
1369 if (mdm) mdm->setModuleDef(mod);
1370 }
1371}
1372
1373void ModuleManager::addTagInfo(const DString &fileName,const DString &tagFile,const DString &clangId)
1374{
1375 std::lock_guard lock(p->mutex);
1376 auto mod = p->moduleFileMap.find(fileName);
1377 if (mod)
1378 {
1379 ModuleDefImpl *modi = toModuleDefImpl(mod);
1380 modi->setReference(tagFile);
1381 modi->setId(clangId);
1382 }
1383}
1384
1386{
1387 AUTO_TRACE();
1388 for (auto &[partitionFileName,importInfoList] : mod->getImports()) // foreach import
1389 {
1390 for (auto &importInfo : importInfoList)
1391 {
1392 AUTO_TRACE_ADD("partitionFileName={} importName={} partitionName={}",
1393 partitionFileName,importInfo.importName,importInfo.partitionName);
1394 if (importInfo.importName==intfMod->name() && !importInfo.partitionName.empty() &&
1395 importInfo.exported) // that is an exported partition of this module
1396 {
1397 auto it = p->moduleNameMap.find(importInfo.importName.str());
1398 if (it != p->moduleNameMap.end())
1399 {
1400 for (auto importedMod : it->second)
1401 {
1402 if (importedMod->qualifiedName()==importInfo.importName+":"+importInfo.partitionName)
1403 {
1404 AUTO_TRACE_ADD("Interface module {} exports partition {}:{}",
1405 mod->name(),importedMod->name(),importedMod->partitionName());
1406 toModuleDefImpl(intfMod)->addPartition(toModuleDefImpl(importedMod));
1407 toModuleDefImpl(importedMod)->setPrimaryInterface(intfMod);
1408 for (const auto &[partitionFileName_,partitionImportInfoList] : importedMod->getImports())
1409 {
1410 for (const auto &partitionImportInfo : partitionImportInfoList)
1411 {
1412 if (partitionImportInfo.exported && intfMod->name()!=partitionImportInfo.importName)
1413 {
1414 toModuleDefImpl(intfMod)->addExportedModule(partitionImportInfo.importName,partitionImportInfo);
1415 }
1416 }
1417 }
1418 resolvePartitionsRecursively(intfMod,importedMod);
1419 }
1420 }
1421 }
1422 }
1423 }
1424 }
1425}
1426
1428{
1429 AUTO_TRACE();
1430 for (auto &mod : p->moduleFileMap) // foreach module
1431 {
1432 if (mod->moduleType()==ModuleDef::Type::Interface && mod->partitionName().empty())
1433 { // that is a primary interface
1434 resolvePartitionsRecursively(mod.get(),mod.get());
1435 }
1436
1437 // copy exported imports to m_exportedModules
1438 for (const auto &[fileName,importInfoList] : mod->getImports())
1439 {
1440 for (const auto &importInfo : importInfoList)
1441 {
1442 if (importInfo.exported && mod->name()!=importInfo.importName)
1443 {
1444 toModuleDefImpl(mod)->addExportedModule(importInfo.importName,importInfo);
1445 }
1446 }
1447 }
1448
1449 // also link the ModuleDef and FileDef together
1450 bool ambig = false;
1451 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(mod->getDefFileName(),ambig);
1452 if (fd)
1453 {
1454 fd->setModuleDef(mod.get());
1455 toModuleDefImpl(mod)->setFileDef(fd);
1456 }
1457 }
1458}
1459
1461{
1462 AUTO_TRACE();
1463 for (auto &mod : p->moduleFileMap)
1464 {
1465 FileDef *fd = mod->getFileDef();
1466 if (fd)
1467 {
1468 for (const auto &[fileName,importInfoList] : mod->getImports())
1469 {
1470 for (const auto &importInfo : importInfoList)
1471 {
1472 ModuleDef *importedModule = getPrimaryInterface(importInfo.importName);
1473 const FileDef *importedFd = importedModule ? importedModule->getFileDef() : nullptr;
1474 AUTO_TRACE_ADD("module: addIncludeDependency {}->{}:{} fd={}",
1475 mod->qualifiedName(), importInfo.qualifiedName(), importInfo.line, fd?fd->absFilePath():"");
1477 }
1478 }
1479 }
1480 }
1481 for (const auto &[fileName,importInfoList] : p->externalImports)
1482 {
1483 for (const auto &importInfo : importInfoList)
1484 {
1485 bool ambig = false;
1486 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(fileName,ambig);
1487 AUTO_TRACE_ADD("externalImport name={} fd={}",fileName,(void*)fd);
1488 if (fd)
1489 {
1490 ModuleDef *mod = getPrimaryInterface(importInfo.importName);
1491 FileDef *importedFd = mod ? mod->getFileDef() : nullptr;
1492 fd->addIncludeDependency(importedFd,importInfo.importName,IncludeKind::ImportModule);
1493 if (importedFd)
1494 {
1496 }
1497 }
1498 }
1499 }
1500 for (const auto &headerInfo : p->headers)
1501 {
1502 bool ambig = false;
1503 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(headerInfo.fileName,ambig);
1504 AUTO_TRACE_ADD("header name={} fd={}",headerInfo.fileName,(void*)fd);
1505 if (fd)
1506 {
1507 DString resolvedHeader = determineAbsoluteIncludeName(headerInfo.fileName,headerInfo.headerName);
1508 FileDef *importFd = Doxygen::inputNameLinkedMap->findFileDef(resolvedHeader,ambig);
1509 fd->addIncludeDependency(importFd, headerInfo.headerName,
1510 headerInfo.isSystem ? IncludeKind::ImportSystem : IncludeKind::ImportLocal);
1511 if (importFd)
1512 {
1514 }
1515 }
1516 }
1517}
1518
1520{
1521 AUTO_TRACE("{}: collecting symbols for partition {}",intfMod->qualifiedName(),partitionMod->qualifiedName());
1522 auto intfModImpl = toModuleDefImpl(intfMod);
1523 auto partitionModImpl = toModuleDefImpl(partitionMod);
1524 intfModImpl->mergeSymbolsFrom(partitionModImpl);
1525}
1526
1528{
1529 AUTO_TRACE();
1530 for (auto &mod : p->moduleFileMap) // foreach module
1531 {
1532 if (mod->isPrimaryInterface()) // that is a primary interface
1533 {
1534 for (auto &[partitionName,partitionMod] : mod->partitions())
1535 {
1536 collectExportedSymbolsRecursively(mod.get(),partitionMod);
1537 }
1538
1539 // collect all files that contribute to this module (e.g. implementation/partition modules)
1540 auto it = p->moduleNameMap.find(mod->name().str());
1541 if (it != p->moduleNameMap.end())
1542 {
1543 for (auto contributingMod : it->second)
1544 {
1545 AUTO_TRACE_ADD(" adding contributing module {} to interface module {} type={} partition={} isPrimaryIntf={}",
1546 contributingMod->qualifiedName(),
1547 mod->name(),
1548 contributingMod->moduleType()==ModuleDef::Type::Interface ? "Interface" : "Implementation",
1549 contributingMod->partitionName(),
1550 contributingMod->isPrimaryInterface());
1552 }
1553 }
1554 }
1555 }
1556}
1557
1559{
1560 for (auto &mod : p->moduleFileMap) // foreach module
1561 {
1563 }
1564}
1565
1567{
1568 for (auto &mod : p->moduleFileMap) // foreach module
1569 {
1570 if (mod->isPrimaryInterface())
1571 {
1572 mod->writeDocumentation(ol);
1573 }
1574 }
1575}
1576
1578{
1579 int count=0;
1580 for (const auto &mod : p->moduleFileMap) // foreach module
1581 {
1582 if (mod->isPrimaryInterface()) count++;
1583 }
1584 return count;
1585}
1586
1588{
1589 return p->moduleFileMap;
1590}
1591
1593{
1594 return p->moduleFileMap;
1595}
1596
1598{
1599 AUTO_TRACE("file={} module={}",root->fileName,root->name);
1600 if (root->doc.empty() && root->brief.empty()) return;
1601 if (root->name.find(':')!=DString::npos)
1602 {
1603 warn(root->fileName,root->startLine,"Ignoring documentation for module partition {}. Please place documentation at the primary module name",
1604 root->name);
1605 }
1606 else
1607 {
1608 auto it = p->moduleNameMap.find(root->name.str());
1609 if (it != p->moduleNameMap.end())
1610 {
1611 ModuleDef *mod = getPrimaryInterface(root->name);
1612 if (mod)
1613 {
1614 mod->setDocumentation(root->doc,root->docFile,root->docLine);
1615 mod->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1616 mod->setId(root->id);
1617 mod->setHidden(root->hidden);
1618 mod->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1619 mod->setRefItems(root->sli);
1620 mod->setRequirementReferences(root->rqli);
1621 //mod->addSectionsToDefinition(root->anchors);
1622 addModuleToGroups(root,mod);
1623 }
1624 else
1625 {
1626 warn(root->fileName,root->startLine,"Found documentation for module {} but it has no primary interface unit.",root->name);
1627 }
1628 }
1629 else
1630 {
1631 warn(root->fileName,root->startLine,"Found documentation for unknown module {}.",root->name);
1632 }
1633 }
1634}
1635
1637{
1638 auto it = p->moduleNameMap.find(moduleName.str());
1639 if (it != p->moduleNameMap.end())
1640 {
1641 for (const auto &mod : it->second)
1642 {
1643 if (mod->isPrimaryInterface())
1644 {
1645 return mod;
1646 }
1647 }
1648 }
1649 return nullptr;
1650}
1651
1653{
1654 for (const auto &mod : p->moduleFileMap) // foreach module
1655 {
1656 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addListReferences();
1657 }
1658}
1659
1661{
1662 for (const auto &mod : p->moduleFileMap) // foreach module
1663 {
1664 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addRequirementReferences();
1665 }
1666}
1667
1669{
1670 for (const auto &mod : p->moduleFileMap) // foreach module
1671 {
1672 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addMembersToMemberGroup();
1673 }
1674}
1675
1677{
1678 for (const auto &mod : p->moduleFileMap) // foreach module
1679 {
1680 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->distributeMemberGroupDocumentation();
1681 }
1682}
1683
1685{
1686 for (auto &mod : p->moduleFileMap) // foreach module
1687 {
1688 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->findSectionsInDocumentation();
1689 }
1690}
1691
1693{
1694 for (auto &mod : p->moduleFileMap) // foreach module
1695 {
1696 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->sortMemberLists();
1697 }
1698}
1699
A abstract class representing of a compound symbol.
Definition classdef.h:104
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:29
void writeDeclaration(OutputList &ol, const ClassDef::CompoundType *filter, const DString &header, bool localNames) const
Definition classlist.cpp:53
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:89
DString()=default
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:153
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:183
DString & prepend(const char *s)
Definition dstring.h:504
size_t find(char c, size_t pos=0) const
Definition dstring.h:244
const std::string & str() const
Definition dstring.h:634
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:130
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:104
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:117
RequirementRefs rqli
references to requirements
Definition entry.h:229
int docLine
line number at which the documentation was found
Definition entry.h:203
int endBodyLine
line number where the definition ends
Definition entry.h:220
bool exported
is the symbol exported from a C++20 module
Definition entry.h:190
DString fileName
file this entry was extracted from
Definition entry.h:225
DString docFile
file in which the documentation was found
Definition entry.h:204
DString doc
documentation block (partly parsed)
Definition entry.h:202
DString brief
brief description (doc block)
Definition entry.h:205
int startLine
start line of entry in the source
Definition entry.h:226
int bodyLine
line number of the body in the source
Definition entry.h:218
DString name
member name
Definition entry.h:175
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:228
bool hidden
does this represent an entity that is hidden from the output
Definition entry.h:231
int briefLine
line number at which the brief desc. was found
Definition entry.h:206
DString id
libclang id
Definition entry.h:234
DString briefFile
file in which the brief desc. was found
Definition entry.h:207
A model of a file symbol.
Definition filedef.h:99
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:36
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1435
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:48
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:125
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:130
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:191
bool contains(const MemberDef *md) const
Definition memberlist.h:89
void push_back(const T &value)
Definition memberlist.h:48
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:52
void writeConcepts(OutputList &ol, const DString &title)
void addPartition(ModuleDefImpl *mod)
void distributeMemberGroupDocumentation()
void startMemberDeclarations(OutputList &ol)
DefType definitionType() const override
Definition moduledef.cpp:58
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:75
ModuleList m_contributing
void addMemberToModule(const Entry *root, MemberDef *md)
bool isPrimaryInterface() const override
Definition moduledef.cpp:77
void addConceptToModule(const Entry *root, ConceptDef *cd)
FileDef * getFileDef() const override
Definition moduledef.cpp:84
void addClassToModule(const Entry *root, ClassDef *cd)
bool isLinkableInProject() const override
Definition moduledef.cpp:63
DString anchor() const override
Definition moduledef.cpp:62
DString getOutputFileBase() const override
FileDef * m_fileDef
void writeTagFile(TextStream &t) const override
DString displayName(bool=true) const override
Definition moduledef.cpp:60
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:85
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:81
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:59
const ImportInfoMap & getExports() const override
Definition moduledef.cpp:86
void writeBriefDescription(OutputList &ol)
void addRequirementReferences()
ClassLinkedRefMap m_classes
const MemberGroupList & getMemberGroups() const override
Definition moduledef.cpp:80
void findSectionsInDocumentation()
ImportInfoMap m_exportedModules
ModuleMap m_partitions
bool isLinkable() const override
Definition moduledef.cpp:66
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:74
void writeFiles(OutputList &ol, const DString &title)
DString qualifiedName() const override
const ModuleMap & partitions() const override
Definition moduledef.cpp:87
const MemberLists & getMemberLists() const override
Definition moduledef.cpp:79
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:82
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:315
void writeDoc(const IDocNodeAST *ast, const Definition *ctx, const MemberDef *md, int sectionLevel=-1)
Definition outputlist.h:383
void startTitleHead(const DString &fileName)
Definition outputlist.h:403
void startMemberDeclaration()
Definition outputlist.h:569
void parseText(const DString &textStr)
void endTitleHead(const DString &fileName, const DString &name)
Definition outputlist.h:405
void disable(OutputType o)
void startParagraph(const DString &classDef=DString())
Definition outputlist.h:407
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name)
Definition outputlist.h:439
void writeRuler()
Definition outputlist.h:521
void enable(OutputType o)
void endContents()
Definition outputlist.h:620
void endHeaderSection()
Definition outputlist.h:467
void endMemberDescription()
Definition outputlist.h:567
void endTextBlock(bool paraBreak=false)
Definition outputlist.h:672
void endMemberDeclaration(const DString &anchor, const DString &inheritId)
Definition outputlist.h:571
void docify(const DString &s)
Definition outputlist.h:437
void startMemberHeader(const DString &anchor, int typ=2)
Definition outputlist.h:469
void writeAnchor(const DString &fileName, const DString &name)
Definition outputlist.h:523
void startHeaderSection()
Definition outputlist.h:465
void insertMemberAlign(bool templ=false)
Definition outputlist.h:517
void writeString(const DString &text)
Definition outputlist.h:411
void endParagraph()
Definition outputlist.h:409
void startMemberSections()
Definition outputlist.h:461
void startMemberList()
Definition outputlist.h:481
void endTextLink()
Definition outputlist.h:444
void startBold()
Definition outputlist.h:561
void endMemberItem(OutputGenerator::MemberItemType type)
Definition outputlist.h:495
void endMemberList()
Definition outputlist.h:483
void writeSynopsis()
Definition outputlist.h:592
void pushGeneratorState()
void writeSummaryLink(const DString &file, const DString &anchor, const DString &title, bool first)
Definition outputlist.h:614
void disableAllBut(OutputType o)
void startTextBlock(bool dense=false)
Definition outputlist.h:670
void popGeneratorState()
void startTextLink(const DString &file, const DString &anchor)
Definition outputlist.h:442
void endBold()
Definition outputlist.h:563
void endGroupHeader(int extraLevels=0)
Definition outputlist.h:455
void startMemberItem(const DString &anchor, OutputGenerator::MemberItemType type, const DString &id=DString())
Definition outputlist.h:493
void startMemberDescription(const DString &anchor, const DString &inheritId=DString(), bool typ=false)
Definition outputlist.h:565
void writePageOutline()
Definition outputlist.h:616
void generateDoc(const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &docStr, const DocOptions &options)
void startContents()
Definition outputlist.h:618
void startGroupHeader(const DString &id=DString(), int extraLevels=0)
Definition outputlist.h:453
void enableAll()
void endMemberHeader()
Definition outputlist.h:471
void endMemberSections()
Definition outputlist.h:463
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:51
#define AUTO_TRACE(...)
Definition docnode.cpp:50
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:56
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:72
const char * qPrint(const char *s)
Definition dstring.h:772
@ ImportLocal
Definition filedef.h:54
@ ImportModule
Definition filedef.h:55
@ ImportSystem
Definition filedef.h:53
void addModuleToGroups(const Entry *root, ModuleDef *mod)
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const DString &navPath)
Definition index.cpp:429
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:403
Translator * theTranslator
Definition language.cpp:71
MemberDefMutable * toMemberDefMutable(Definition *d)
void addMembersToMemberGroup(MemberList *ml, MemberGroupList *pMemberGroups, const Definition *context)
#define warn(file, line, fmt,...)
Definition message.h:97
#define err(fmt,...)
Definition message.h:127
std::vector< HeaderInfo > HeaderInfoVector
Definition moduledef.cpp:46
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:902
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:135
Helper class to pass options when calling OutputList::generateDoc().
Definition docoptions.h:24
DString fileName
Definition moduledef.cpp:41
HeaderInfo(const DString &fn, const DString &name, bool sys)
Definition moduledef.cpp:39
bool isSystem
Definition moduledef.cpp:43
DString headerName
Definition moduledef.cpp:42
ImportInfo(ModuleDef *def, const DString &name, int l, const DString &pName, bool isExported=false)
Definition moduledef.h:40
DString importName
Definition moduledef.h:44
Represents of a member declaration list with configurable title and subtitle.
Definition layout.h:112
MemberListType type
Definition layout.h:118
DString title(SrcLangExt lang) const
Definition layout.cpp:1786
bool visible() const override
Definition layout.h:121
Represents of a member definition list with configurable title.
Definition layout.h:132
MemberListType type
Definition layout.h:137
DString title(SrcLangExt lang) const
Definition layout.cpp:1798
Definition layout.h:102
DString title(SrcLangExt lang) const
Definition layout.cpp:1779
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:2930
void addGroupListToTitle(OutputList &ol, const Definition *d)
Definition util.cpp:4118
void addHtmlExtensionIfMissing(DString &fName)
Definition util.cpp:4128
DString convertToXML(const DString &s, bool keepEntities, const bool citeEntry)
Definition util.cpp:3299
DString determineAbsoluteIncludeName(const DString &curFile, const DString &incFileName)
Definition util.cpp:2996
DString stripFromPath(const DString &path)
Definition util.cpp:251
A bunch of utility functions.