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::ClassIncludes:
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::FileIncludes:
462 case LayoutDocEntry::FileIncludeGraph:
463 case LayoutDocEntry::FileIncludedByGraph:
464 case LayoutDocEntry::FileInlineClasses:
465 case LayoutDocEntry::FileSourceLink:
466 case LayoutDocEntry::NamespaceNestedNamespaces:
467 case LayoutDocEntry::NamespaceNestedConstantGroups:
468 case LayoutDocEntry::NamespaceClasses:
469 case LayoutDocEntry::NamespaceConcepts:
470 case LayoutDocEntry::NamespaceInterfaces:
471 case LayoutDocEntry::NamespaceStructs:
472 case LayoutDocEntry::NamespaceExceptions:
473 case LayoutDocEntry::NamespaceInlineClasses:
474 case LayoutDocEntry::ConceptDefinition:
475 case LayoutDocEntry::GroupClasses:
476 case LayoutDocEntry::GroupConcepts:
477 case LayoutDocEntry::GroupModules:
478 case LayoutDocEntry::GroupInlineClasses:
479 case LayoutDocEntry::GroupNamespaces:
480 case LayoutDocEntry::GroupDirs:
481 case LayoutDocEntry::GroupNestedGroups:
482 case LayoutDocEntry::GroupFiles:
483 case LayoutDocEntry::GroupGraph:
484 case LayoutDocEntry::GroupPageDocs:
485 case LayoutDocEntry::DirSubDirs:
486 case LayoutDocEntry::DirFiles:
487 case LayoutDocEntry::DirGraph:
488 err("Internal inconsistency: member '{}' should not be part of "
489 "LayoutDocManager::Module entry list\n",lde->entryToString());
490 break;
491 }
492 }
493
494 //---------------------------------------- end flexible part -------------------------------
495 if (generateTreeView)
496 {
499 ol.endContents();
500 ol.writeString("</div><!-- doc-content -->\n");
502 ol.writeString("</div><!-- container -->\n");
504 }
505 endFile(ol,generateTreeView,true);
506
508}
509
511{
512 m_classes.writeDeclaration(ol,nullptr,title,false);
513}
514
516{
517 m_concepts.writeDeclaration(ol,title,false);
518}
519
524
529
531{
532 if (Config_getBool(SEPARATE_MEMBER_PAGES))
533 {
536 }
537}
538
540{
541 if (Config_getBool(SEPARATE_MEMBER_PAGES))
542 {
545 }
546}
547
549{
551 {
554 ol.writeRuler();
558 ol.writeAnchor(DString(),"details");
560 ol.startGroupHeader("details");
561 ol.parseText(title);
562 ol.endGroupHeader();
563
564 ol.startTextBlock();
565 if (!briefDescription().empty() && Config_getBool(REPEAT_BRIEF))
566 {
568 briefLine(),
569 this,
570 nullptr,
572 DocOptions());
573 }
574 if (!briefDescription().empty() && Config_getBool(REPEAT_BRIEF) &&
575 !documentation().empty())
576 {
580 ol.enableAll();
583 ol.writeString("\n\n");
585 }
586 if (!documentation().empty())
587 {
588 ol.generateDoc(docFile(),
589 docLine(),
590 this,
591 nullptr,
592 documentation()+"\n",
593 DocOptions()
594 .setIndexWords(true));
595 }
596 ol.endTextBlock();
597 }
598}
599
601{
603 {
604 auto parser { createDocParser() };
605 auto ast { validatingParseDoc(*parser.get(),
606 briefFile(),
607 briefLine(),
608 this,
609 nullptr,
611 DocOptions()
612 .setIndexWords(true)
613 .setSingleLine(true))
614 };
615 if (!ast->empty())
616 {
617 ol.startParagraph();
620 ol.writeString(" - ");
622 ol.writeDoc(ast.get(),this,nullptr);
625 ol.writeString(" \n");
627
629 {
631 ol.startTextLink(DString(),"details");
633 ol.endTextLink();
634 }
636 ol.endParagraph();
637 }
638 }
639 ol.writeSynopsis();
640}
641
643{
644 for (const auto &mg : m_memberGroups)
645 {
646 mg->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this);
647 }
648}
649
651{
652 MemberList * ml = getMemberList(lt);
653 if (ml) ml->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this,title,DString());
654}
655
657{
658 MemberList * ml = getMemberList(lt);
659 if (ml) ml->writeDocumentation(ol,name(),this,title,ml->listType().toLabel());
660}
661
663{
664 // write Author section (Man only)
667 ol.startGroupHeader();
668 ol.parseText(theTranslator->trAuthor(true,true));
669 ol.endGroupHeader();
672}
673
675{
676 bool repeatBrief = Config_getBool(REPEAT_BRIEF);
677 return (!briefDescription().empty() && repeatBrief) || !documentation().empty();
678}
679
681{
682 for (auto &ml : m_memberLists)
683 {
684 ml->countDecMembers();
685 ml->countDocMembers();
686 }
687 for (const auto &mg : m_memberGroups)
688 {
689 mg->countDecMembers();
690 mg->countDocMembers();
691 }
692}
693
695{
698 getLanguage()==SrcLangExt::Fortran ?
699 theTranslator->trModule(true,true) :
700 theTranslator->trNamespace(true,true),
702 DString(),
703 this
704 );
705 for (const auto &mg : m_memberGroups)
706 {
707 mg->addListReferences(this);
708 }
709 for (auto &ml : m_memberLists)
710 {
711 if (ml->listType().isDocumentation())
712 {
713 ml->addListReferences(this);
714 }
715 }
716}
717
719{
721 for (const auto &mg : m_memberGroups)
722 {
723 mg->addRequirementReferences(this);
724 }
725 for (auto &ml : m_memberLists)
726 {
727 if (ml->listType().isDocumentation())
728 {
729 ml->addRequirementReferences(this);
730 }
731 }
732}
733
735{
736 for (auto &ml : m_memberLists)
737 {
738 if (ml->listType().isDeclaration())
739 {
741 }
742 }
743
744 // add members inside sections to their groups
745 for (const auto &mg : m_memberGroups)
746 {
747 if (mg->allMembersInSameSection() && Config_getBool(SUBGROUPING))
748 {
749 //printf("----> addToDeclarationSection(%s)\n",qPrint(mg->header()));
750 mg->addToDeclarationSection();
751 }
752 }
753}
754
756{
757 for (const auto &mg : m_memberGroups)
758 {
759 mg->distributeMemberGroupDocumentation();
760 }
761}
762
764{
768 for (const auto &mg : m_memberGroups)
769 {
770 mg->findSectionsInDocumentation(this);
771 }
772 for (auto &ml : m_memberLists)
773 {
774 if (ml->listType().isDeclaration())
775 {
776 ml->findSectionsInDocumentation(this);
777 }
778 }
779}
780
782{
783 for (auto &ml : m_memberLists)
784 {
785 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(false); }
786 }
787
788 if (Config_getBool(SORT_BRIEF_DOCS))
789 {
790 auto classComp = [](const ClassLinkedRefMap::Ptr &c1,const ClassLinkedRefMap::Ptr &c2)
791 {
792 return Config_getBool(SORT_BY_SCOPE_NAME) ?
793 dstricmp_sort(c1->name(), c2->name())<0 :
794 dstricmp_sort(c1->className(), c2->className())<0;
795 };
796 std::stable_sort(m_classes.begin(), m_classes.end(), classComp);
797
798 auto conceptComp = [](const ConceptLinkedRefMap::Ptr &c1,const ConceptLinkedRefMap::Ptr &c2)
799 {
800 return Config_getBool(SORT_BY_SCOPE_NAME) ?
801 dstricmp_sort(c1->qualifiedName(), c2->qualifiedName())<0 :
802 dstricmp_sort(c1->name(), c2->name())<0;
803 };
804 std::stable_sort(m_concepts.begin(), m_concepts.end(), conceptComp);
805 }
806
807 static auto contrComp = [](const ModuleDef *m1, const ModuleDef *m2)
808 {
809 FileDef *f1 = m1->getFileDef();
810 FileDef *f2 = m2->getFileDef();
811 DString fn1 = f1 ? f1->name() : m1->name();
812 DString fn2 = f2 ? f2->name() : m2->name();
813 static auto typeRank = [](const ModuleDef *m) -> int
814 {
815 if (m->moduleType()==ModuleDef::Type::Interface)
816 {
817 if (m->partitionName().empty()) return 0; // primary interface unit
818 return 1; // partition interface unit
819 }
820 else
821 {
822 if (!m->partitionName().empty()) return 2; // partition implementation unit
823 return 3; // implementation unit
824 }
825 };
826 auto tr1 = typeRank(m1);
827 auto tr2 = typeRank(m2);
828 int diff = dstricmp_sort(fn1,fn2);
829 return tr1<tr2 || (tr1==tr2 && diff<0);
830 };
831
832 std::stable_sort(m_contributing.begin(), m_contributing.end(), contrComp);
833}
834
836{
839 bool first=true;
840 SrcLangExt lang=getLanguage();
841 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
842 {
843 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
844 if (lde->kind()==LayoutDocEntry::ModuleClasses && m_classes.declVisible() && ls)
845 {
846 DString label = "classes";
847 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
848 first=false;
849 }
850 else if (lde->kind()==LayoutDocEntry::ModuleConcepts && m_concepts.declVisible() && ls)
851 {
852 DString label = "concepts";
853 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
854 first=false;
855 }
856 else if (lde->kind()==LayoutDocEntry::ModuleUsedFiles && ls)
857 {
858 DString label = "files";
859 ol.writeSummaryLink(DString(),label,ls->title(lang),first);
860 first=false;
861 }
862 else if (lde->kind()==LayoutDocEntry::MemberDecl)
863 {
864 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
865 if (lmd)
866 {
867 MemberList * ml = getMemberList(lmd->type);
868 if (ml && ml->declVisible())
869 {
870 ol.writeSummaryLink(DString(),ml->listType().toLabel(),lmd->title(lang),first);
871 first=false;
872 }
873 }
874 }
875 }
876 if (!first)
877 {
878 ol.writeString(" </div>\n");
879 }
881}
882
887
888void ModuleDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const DString &header,bool localNames) const
889{
890 if (isLinkable())
891 {
892 if (!found) // first module
893 {
894 ol.startMemberHeader("modules");
895 if (!header.empty())
896 {
897 ol.parseText(header);
898 }
899 else
900 {
901 theTranslator->trModule(true,false);
902 }
903 ol.endMemberHeader();
904 ol.startMemberList();
905 found=true;
906 }
908 DString cname = displayName(!localNames);
909 DString anc = anchor();
910 if (anc.empty()) anc=cname; else anc.prepend(cname+"_");
912 ol.writeString("module ");
914 if (isLinkable())
915 {
918 anchor(),
919 cname
920 );
921 }
922 else
923 {
924 ol.startBold();
925 ol.docify(cname);
926 ol.endBold();
927 }
929 // add the brief description if available
930 if (!briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
931 {
932 auto parser { createDocParser() };
933 auto ast { validatingParseDoc(*parser.get(),
934 briefFile(),
935 briefLine(),
936 this,
937 nullptr,
939 DocOptions()
940 .setSingleLine(true))
941 };
942 if (!ast->empty())
943 {
945 ol.writeDoc(ast.get(),this,nullptr);
947 }
948 }
950 }
951}
952
953
955{
956 AUTO_TRACE("name={} count={}",name(),m_exportedModules.size());
957 if (!m_exportedModules.empty())
958 {
959 ol.startMemberHeader("exports");
960 ol.parseText(title);
961 ol.endMemberHeader();
962 ol.startMemberList();
963 for (const auto &[moduleName,importInfoList] : m_exportedModules)
964 {
965 for (const auto &importInfo : importInfoList)
966 {
967 ModuleDef *mod = ModuleManager::instance().getPrimaryInterface(importInfo.importName);
970 ol.docify(theTranslator->trModule(false,true)+" ");
972 if (mod && mod->isLinkable())
973 {
975 }
976 else
977 {
978 ol.startBold();
979 ol.docify(importInfo.importName);
980 ol.endBold();
981 }
983 if (mod && !mod->briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
984 {
987 briefLine(),
988 mod,
989 nullptr,
990 mod->briefDescription(),
991 DocOptions()
992 .setSingleLine(true));
994 }
996 }
997 }
998 ol.endMemberList();
999 }
1000}
1001
1003{
1004 AUTO_TRACE("{} count={}",name(),m_contributing.size());
1005 if (!m_contributing.empty())
1006 {
1007 ol.startMemberHeader("files");
1008 ol.parseText(title);
1009 ol.endMemberHeader();
1010 ol.startMemberList();
1011 for (const auto &mod : m_contributing)
1012 {
1013 FileDef *fd = mod->getFileDef();
1014 if (fd)
1015 {
1017 DString fname = fd->displayName();
1018 DString anc = fd->anchor();
1019 if (anc.empty()) anc=fname; else anc.prepend(fname+"_");
1021 ol.docify(theTranslator->trFile(false,true)+" ");
1022 ol.insertMemberAlign();
1023 DString path=fd->getPath();
1024 if (Config_getBool(FULL_PATH_NAMES))
1025 {
1026 ol.docify(stripFromPath(path));
1027 }
1028 if (fd->isLinkable())
1029 {
1030 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),DString(),fname);
1031 }
1032 else
1033 {
1034 ol.startBold();
1035 ol.docify(fd->displayName());
1036 ol.endBold();
1037 }
1039 if (!fd->briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC))
1040 {
1043 briefLine(),
1044 fd,
1045 nullptr,
1046 fd->briefDescription(),
1047 DocOptions()
1048 .setSingleLine(true));
1050 }
1052 }
1053 }
1054 ol.endMemberList();
1055 }
1056}
1057
1059{
1060 FileList result;
1061 for (const auto &mod : m_contributing)
1062 {
1063 FileDef *fd = mod->getFileDef();
1064 if (fd) result.push_back(fd);
1065 }
1066 return result;
1067}
1068
1070{
1071 int count=0;
1072 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
1073 {
1074 if (lde->kind()==LayoutDocEntry::MemberDecl)
1075 {
1076 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1077 if (lmd)
1078 {
1079 MemberList *ml = getMemberList(lmd->type);
1080 if (ml)
1081 {
1082 for (const auto &md : *ml)
1083 {
1084 if (md->visibleInIndex())
1085 {
1086 count++;
1087 }
1088 }
1089 }
1090 }
1091 }
1092 else if (lde->kind()==LayoutDocEntry::ModuleClasses)
1093 {
1094 for (const auto &cd : getClasses())
1095 {
1096 if (cd->isLinkableInProject())
1097 {
1098 count++;
1099 }
1100 }
1101 }
1102 else if (lde->kind()==LayoutDocEntry::ModuleConcepts)
1103 {
1104 for (const auto &cd : getConcepts())
1105 {
1106 if (cd->isLinkableInProject())
1107 {
1108 count++;
1109 }
1110 }
1111 }
1112 }
1113 return count;
1114}
1115
1117{
1118 if (!isPrimaryInterface() || !isLinkableInProject()) return;
1119 tagFile << " <compound kind=\"module\">\n";
1120 tagFile << " <name>" << convertToXML(name()) << "</name>\n";
1121 const FileDef *fd = getFileDef();
1122 DString fn = fd ? fd->getOutputFileBase() : getOutputFileBase();
1124 tagFile << " <filename>" << convertToXML(fn) << "</filename>\n";
1125#if 0 // at the moment we do not export the members of a module to a tag file.
1126 // We let the project using a tag file directly link to the implementation of the
1127 // symbols (which have the same scope).
1128 //
1129 // When we support linking to a module's interface instead we need to
1130 // export the module's members as well. Then we probably need a way to
1131 // disambiguate/prioritize a link to a module over a link to the implementation,
1132 // for instance by hiding non-exported symbols from the tag file.
1133 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Group))
1134 {
1135 switch (lde->kind())
1136 {
1137 case LayoutDocEntry::ModuleExports:
1138 {
1139 for (const auto &[modName,importInfo] : m_exportedModules)
1140 {
1141 tagFile << " <export>" << convertToXML(importInfo.importName) << "</export>\n";
1142 }
1143 }
1144 break;
1145 case LayoutDocEntry::ModuleClasses:
1146 {
1147 for (const auto &cd : m_classes)
1148 {
1149 if (cd->isLinkableInProject())
1150 {
1151 tagFile << " <class kind=\"" << cd->compoundTypeString()
1152 << "\">" << convertToXML(cd->name()) << "</class>\n";
1153 }
1154 }
1155 }
1156 break;
1157 case LayoutDocEntry::ModuleConcepts:
1158 {
1159 for (const auto &cd : m_concepts)
1160 {
1161 if (cd->isLinkableInProject())
1162 {
1163 tagFile << " <concept>" << convertToXML(cd->name())
1164 << "</concept>\n";
1165 }
1166 }
1167 }
1168 break;
1169 case LayoutDocEntry::ModuleUsedFiles:
1170 {
1171 for (const auto &usedFd : getUsedFiles())
1172 {
1173 if (usedFd->isLinkableInProject())
1174 {
1175 tagFile << " <file>" << convertToXML(usedFd->name()) << "</file>\n";
1176 }
1177 }
1178 }
1179 break;
1180 case LayoutDocEntry::MemberDecl:
1181 {
1182 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1183 if (lmd && lmd->visible())
1184 {
1185 MemberList * ml = getMemberList(lmd->type);
1186 if (ml)
1187 {
1188 ml->writeTagFile(tagFile,true);
1189 }
1190 }
1191 }
1192 break;
1193 default:
1194 break;
1195 }
1196 }
1197#endif
1198 DString idStr = id();
1199 if (!idStr.empty())
1200 {
1201 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>\n";
1202 }
1203 writeDocAnchorsToTagFile(tagFile);
1204 tagFile << " </compound>\n";
1205}
1206
1207//------------------------------------------------------------------------------------------------------------
1208
1210{
1211 if (d==nullptr) return nullptr;
1212 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<ModuleDef*>(d) : nullptr;
1213}
1214
1216{
1217 if (d==nullptr) return nullptr;
1218 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<const ModuleDef*>(d) : nullptr;
1219}
1220
1222{ return static_cast<ModuleDefImpl*>(m); }
1223
1224//static inline const ModuleDefImpl *toModuleDefImpl(const ModuleDef *m)
1225//{ return static_cast<const ModuleDefImpl*>(m); }
1226
1227static inline ModuleDefImpl *toModuleDefImpl(const std::unique_ptr<ModuleDef> &m)
1228{ return static_cast<ModuleDefImpl*>(m.get()); }
1229
1230//------------------------------------------------------------------------------------
1231
1233{
1234 bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
1235 for (const auto &mod : *this)
1236 {
1237 bool isLink = mod->isLinkable();
1238 if (isLink || !hideUndocClasses)
1239 {
1240 return true;
1241 }
1242 }
1243 return false;
1244}
1245
1246void ModuleLinkedRefMap::writeDeclaration(OutputList &ol,const DString &header,bool localNames) const
1247{
1248 bool found=false;
1249 for (const auto &mod : *this)
1250 {
1251 toModuleDefImpl(mod)->writeDeclarationLink(ol,found,header,localNames);
1252 }
1253 if (found) ol.endMemberList();
1254}
1255
1256//------------------------------------------------------------------------------------------------------------
1257
1259{
1260 ModuleLinkedMap moduleFileMap; // file->module mapping
1261 std::unordered_map<std::string,ModuleList> moduleNameMap; // name->module mapping
1264 std::mutex mutex;
1265};
1266
1268{
1269 static ModuleManager m;
1270 return m;
1271}
1272
1274{
1275}
1276
1277void ModuleManager::createModuleDef(const DString &fileName,int line,size_t column,bool exported,
1278 const DString &moduleName,const DString &partitionName)
1279{
1280 AUTO_TRACE("{}:{}: Found module name='{}' partition='{}' exported='{}'",
1281 fileName,line,moduleName,partitionName,exported);
1282 std::lock_guard lock(p->mutex);
1284 std::unique_ptr<ModuleDef> modDef = std::make_unique<ModuleDefImpl>(fileName,line,column,moduleName,mt,partitionName);
1285 auto mod = p->moduleFileMap.add(fileName,std::move(modDef));
1286 auto it = p->moduleNameMap.find(moduleName.str());
1287 if (it == p->moduleNameMap.end())
1288 {
1289 ModuleList ml;
1290 ml.push_back(mod);
1291 p->moduleNameMap.emplace(moduleName.str(),ml);
1292 }
1293 else
1294 {
1295 it->second.push_back(mod);
1296 }
1297}
1298
1300{
1301 std::lock_guard lock(p->mutex);
1302 p->headers.clear();
1303 p->externalImports.clear();
1304 p->moduleNameMap.clear();
1305 p->moduleFileMap.clear();
1306}
1307
1308void ModuleManager::addHeader(const DString &moduleFile,int line,const DString &headerName,bool isSystem)
1309{
1310 AUTO_TRACE("{}:{} headerName={} isSystem={}",moduleFile,line,headerName,isSystem);
1311 std::lock_guard lock(p->mutex);
1312 auto mod = p->moduleFileMap.find(moduleFile);
1313 if (mod)
1314 {
1315 toModuleDefImpl(mod)->addHeader(line,headerName,isSystem);
1316 }
1317 else
1318 {
1319 AUTO_TRACE_ADD("imported header '{}' found in file '{}' that is not a module",headerName,moduleFile);
1320 }
1321 p->headers.emplace_back(moduleFile,headerName,isSystem);
1322}
1323
1324void ModuleManager::addImport(const DString &moduleFile,int line,const DString &importName,
1325 bool isExported,const DString &partitionName)
1326{
1327 AUTO_TRACE("{}:{} importName={},isExported={},partitionName={}",
1328 moduleFile,line,importName,isExported,partitionName);
1329 std::lock_guard lock(p->mutex);
1330 auto mod = p->moduleFileMap.find(moduleFile);
1331 if (mod) // import inside a module
1332 {
1333 AUTO_TRACE_ADD("in module");
1334 toModuleDefImpl(mod)->addImport(line,importName.empty()?mod->name():importName,partitionName,isExported);
1335 }
1336 else // import outside of a module
1337 {
1338 AUTO_TRACE_ADD("outside module");
1339 p->externalImports[moduleFile.str()].emplace_back(nullptr,importName,line,partitionName);
1340 }
1341}
1342
1344{
1345 std::lock_guard lock(p->mutex);
1346 auto mod = p->moduleFileMap.find(root->fileName);
1347 if (mod)
1348 {
1349 toModuleDefImpl(mod)->addClassToModule(root,cd);
1350 auto cdm = toClassDefMutable(cd);
1351 if (cdm) cdm->setModuleDef(mod);
1352 }
1353}
1354
1356{
1357 std::lock_guard lock(p->mutex);
1358 auto mod = p->moduleFileMap.find(root->fileName);
1359 if (mod)
1360 {
1361 toModuleDefImpl(mod)->addConceptToModule(root,cd);
1362 auto cdm = toConceptDefMutable(cd);
1363 if (cdm) cdm->setModuleDef(mod);
1364 }
1365}
1366
1368{
1369 std::lock_guard lock(p->mutex);
1370 auto mod = p->moduleFileMap.find(root->fileName);
1371 if (mod && root->exported && md->getClassDef()==nullptr)
1372 {
1373 toModuleDefImpl(mod)->addMemberToModule(root,md);
1374 auto mdm = toMemberDefMutable(md);
1375 if (mdm) mdm->setModuleDef(mod);
1376 }
1377}
1378
1379void ModuleManager::addTagInfo(const DString &fileName,const DString &tagFile,const DString &clangId)
1380{
1381 std::lock_guard lock(p->mutex);
1382 auto mod = p->moduleFileMap.find(fileName);
1383 if (mod)
1384 {
1385 ModuleDefImpl *modi = toModuleDefImpl(mod);
1386 modi->setReference(tagFile);
1387 modi->setId(clangId);
1388 }
1389}
1390
1392{
1393 AUTO_TRACE();
1394 for (auto &[partitionFileName,importInfoList] : mod->getImports()) // foreach import
1395 {
1396 for (auto &importInfo : importInfoList)
1397 {
1398 AUTO_TRACE_ADD("partitionFileName={} importName={} partitionName={}",
1399 partitionFileName,importInfo.importName,importInfo.partitionName);
1400 if (importInfo.importName==intfMod->name() && !importInfo.partitionName.empty() &&
1401 importInfo.exported) // that is an exported partition of this module
1402 {
1403 auto it = p->moduleNameMap.find(importInfo.importName.str());
1404 if (it != p->moduleNameMap.end())
1405 {
1406 for (auto importedMod : it->second)
1407 {
1408 if (importedMod->qualifiedName()==importInfo.importName+":"+importInfo.partitionName)
1409 {
1410 AUTO_TRACE_ADD("Interface module {} exports partition {}:{}",
1411 mod->name(),importedMod->name(),importedMod->partitionName());
1412 toModuleDefImpl(intfMod)->addPartition(toModuleDefImpl(importedMod));
1413 toModuleDefImpl(importedMod)->setPrimaryInterface(intfMod);
1414 for (const auto &[partitionFileName_,partitionImportInfoList] : importedMod->getImports())
1415 {
1416 for (const auto &partitionImportInfo : partitionImportInfoList)
1417 {
1418 if (partitionImportInfo.exported && intfMod->name()!=partitionImportInfo.importName)
1419 {
1420 toModuleDefImpl(intfMod)->addExportedModule(partitionImportInfo.importName,partitionImportInfo);
1421 }
1422 }
1423 }
1424 resolvePartitionsRecursively(intfMod,importedMod);
1425 }
1426 }
1427 }
1428 }
1429 }
1430 }
1431}
1432
1434{
1435 AUTO_TRACE();
1436 for (auto &mod : p->moduleFileMap) // foreach module
1437 {
1438 if (mod->moduleType()==ModuleDef::Type::Interface && mod->partitionName().empty())
1439 { // that is a primary interface
1440 resolvePartitionsRecursively(mod.get(),mod.get());
1441 }
1442
1443 // copy exported imports to m_exportedModules
1444 for (const auto &[fileName,importInfoList] : mod->getImports())
1445 {
1446 for (const auto &importInfo : importInfoList)
1447 {
1448 if (importInfo.exported && mod->name()!=importInfo.importName)
1449 {
1450 toModuleDefImpl(mod)->addExportedModule(importInfo.importName,importInfo);
1451 }
1452 }
1453 }
1454
1455 // also link the ModuleDef and FileDef together
1456 bool ambig = false;
1457 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(mod->getDefFileName(),ambig);
1458 if (fd)
1459 {
1460 fd->setModuleDef(mod.get());
1461 toModuleDefImpl(mod)->setFileDef(fd);
1462 }
1463 }
1464}
1465
1467{
1468 AUTO_TRACE();
1469 for (auto &mod : p->moduleFileMap)
1470 {
1471 FileDef *fd = mod->getFileDef();
1472 if (fd)
1473 {
1474 for (const auto &[fileName,importInfoList] : mod->getImports())
1475 {
1476 for (const auto &importInfo : importInfoList)
1477 {
1478 ModuleDef *importedModule = getPrimaryInterface(importInfo.importName);
1479 const FileDef *importedFd = importedModule ? importedModule->getFileDef() : nullptr;
1480 AUTO_TRACE_ADD("module: addIncludeDependency {}->{}:{} fd={}",
1481 mod->qualifiedName(), importInfo.qualifiedName(), importInfo.line, fd?fd->absFilePath():"");
1483 }
1484 }
1485 }
1486 }
1487 for (const auto &[fileName,importInfoList] : p->externalImports)
1488 {
1489 for (const auto &importInfo : importInfoList)
1490 {
1491 bool ambig = false;
1492 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(fileName,ambig);
1493 AUTO_TRACE_ADD("externalImport name={} fd={}",fileName,(void*)fd);
1494 if (fd)
1495 {
1496 ModuleDef *mod = getPrimaryInterface(importInfo.importName);
1497 FileDef *importedFd = mod ? mod->getFileDef() : nullptr;
1498 fd->addIncludeDependency(importedFd,importInfo.importName,IncludeKind::ImportModule);
1499 if (importedFd)
1500 {
1502 }
1503 }
1504 }
1505 }
1506 for (const auto &headerInfo : p->headers)
1507 {
1508 bool ambig = false;
1509 FileDef *fd = Doxygen::inputNameLinkedMap->findFileDef(headerInfo.fileName,ambig);
1510 AUTO_TRACE_ADD("header name={} fd={}",headerInfo.fileName,(void*)fd);
1511 if (fd)
1512 {
1513 DString resolvedHeader = determineAbsoluteIncludeName(headerInfo.fileName,headerInfo.headerName);
1514 FileDef *importFd = Doxygen::inputNameLinkedMap->findFileDef(resolvedHeader,ambig);
1515 fd->addIncludeDependency(importFd, headerInfo.headerName,
1516 headerInfo.isSystem ? IncludeKind::ImportSystem : IncludeKind::ImportLocal);
1517 if (importFd)
1518 {
1520 }
1521 }
1522 }
1523}
1524
1526{
1527 AUTO_TRACE("{}: collecting symbols for partition {}",intfMod->qualifiedName(),partitionMod->qualifiedName());
1528 auto intfModImpl = toModuleDefImpl(intfMod);
1529 auto partitionModImpl = toModuleDefImpl(partitionMod);
1530 intfModImpl->mergeSymbolsFrom(partitionModImpl);
1531}
1532
1534{
1535 AUTO_TRACE();
1536 for (auto &mod : p->moduleFileMap) // foreach module
1537 {
1538 if (mod->isPrimaryInterface()) // that is a primary interface
1539 {
1540 for (auto &[partitionName,partitionMod] : mod->partitions())
1541 {
1542 collectExportedSymbolsRecursively(mod.get(),partitionMod);
1543 }
1544
1545 // collect all files that contribute to this module (e.g. implementation/partition modules)
1546 auto it = p->moduleNameMap.find(mod->name().str());
1547 if (it != p->moduleNameMap.end())
1548 {
1549 for (auto contributingMod : it->second)
1550 {
1551 AUTO_TRACE_ADD(" adding contributing module {} to interface module {} type={} partition={} isPrimaryIntf={}",
1552 contributingMod->qualifiedName(),
1553 mod->name(),
1554 contributingMod->moduleType()==ModuleDef::Type::Interface ? "Interface" : "Implementation",
1555 contributingMod->partitionName(),
1556 contributingMod->isPrimaryInterface());
1558 }
1559 }
1560 }
1561 }
1562}
1563
1565{
1566 for (auto &mod : p->moduleFileMap) // foreach module
1567 {
1569 }
1570}
1571
1573{
1574 for (auto &mod : p->moduleFileMap) // foreach module
1575 {
1576 if (mod->isPrimaryInterface())
1577 {
1578 mod->writeDocumentation(ol);
1579 }
1580 }
1581}
1582
1584{
1585 int count=0;
1586 for (const auto &mod : p->moduleFileMap) // foreach module
1587 {
1588 if (mod->isPrimaryInterface()) count++;
1589 }
1590 return count;
1591}
1592
1594{
1595 return p->moduleFileMap;
1596}
1597
1599{
1600 return p->moduleFileMap;
1601}
1602
1604{
1605 AUTO_TRACE("file={} module={}",root->fileName,root->name);
1606 if (root->doc.empty() && root->brief.empty()) return;
1607 if (root->name.find(':')!=DString::npos)
1608 {
1609 warn(root->fileName,root->startLine,"Ignoring documentation for module partition {}. Please place documentation at the primary module name",
1610 root->name);
1611 }
1612 else
1613 {
1614 auto it = p->moduleNameMap.find(root->name.str());
1615 if (it != p->moduleNameMap.end())
1616 {
1617 ModuleDef *mod = getPrimaryInterface(root->name);
1618 if (mod)
1619 {
1620 mod->setDocumentation(root->doc,root->docFile,root->docLine);
1621 mod->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1622 mod->setId(root->id);
1623 mod->setHidden(root->hidden);
1624 mod->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1625 mod->setRefItems(root->sli);
1626 mod->setRequirementReferences(root->rqli);
1627 //mod->addSectionsToDefinition(root->anchors);
1628 addModuleToGroups(root,mod);
1629 }
1630 else
1631 {
1632 warn(root->fileName,root->startLine,"Found documentation for module {} but it has no primary interface unit.",root->name);
1633 }
1634 }
1635 else
1636 {
1637 warn(root->fileName,root->startLine,"Found documentation for unknown module {}.",root->name);
1638 }
1639 }
1640}
1641
1643{
1644 auto it = p->moduleNameMap.find(moduleName.str());
1645 if (it != p->moduleNameMap.end())
1646 {
1647 for (const auto &mod : it->second)
1648 {
1649 if (mod->isPrimaryInterface())
1650 {
1651 return mod;
1652 }
1653 }
1654 }
1655 return nullptr;
1656}
1657
1659{
1660 for (const auto &mod : p->moduleFileMap) // foreach module
1661 {
1662 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addListReferences();
1663 }
1664}
1665
1667{
1668 for (const auto &mod : p->moduleFileMap) // foreach module
1669 {
1670 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addRequirementReferences();
1671 }
1672}
1673
1675{
1676 for (const auto &mod : p->moduleFileMap) // foreach module
1677 {
1678 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addMembersToMemberGroup();
1679 }
1680}
1681
1683{
1684 for (const auto &mod : p->moduleFileMap) // foreach module
1685 {
1686 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->distributeMemberGroupDocumentation();
1687 }
1688}
1689
1691{
1692 for (auto &mod : p->moduleFileMap) // foreach module
1693 {
1694 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->findSectionsInDocumentation();
1695 }
1696}
1697
1699{
1700 for (auto &mod : p->moduleFileMap) // foreach module
1701 {
1702 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->sortMemberLists();
1703 }
1704}
1705
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:1437
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:134
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:1788
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:1800
Definition layout.h:101
DString title(SrcLangExt lang) const
Definition layout.cpp:1781
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:2863
void addGroupListToTitle(OutputList &ol, const Definition *d)
Definition util.cpp:3921
void addHtmlExtensionIfMissing(DString &fName)
Definition util.cpp:3931
DString convertToXML(const DString &s, bool keepEntities, const bool citeEntry)
Definition util.cpp:3232
DString determineAbsoluteIncludeName(const DString &curFile, const DString &incFileName)
Definition util.cpp:2929
DString stripFromPath(const DString &path)
Definition util.cpp:219
A bunch of utility functions.