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
34class ModuleDefImpl;
35
37{
38 HeaderInfo(const QCString &fn,const QCString &name,bool sys)
39 : fileName(fn), headerName(name), isSystem(sys) {}
40 QCString fileName; // file containing the import
41 QCString headerName; // name of the imported header
42 bool isSystem; // <...> => true, "..." => false
43};
44
45using HeaderInfoVector = std::vector<HeaderInfo>;
46
47
48class ModuleDefImpl : public DefinitionMixin<ModuleDef>
49{
50 public:
51 ModuleDefImpl(const QCString &fileName,int startLine,int startColom,
52 const QCString &name, Type type, const QCString &partitionName)
53 : DefinitionMixin<ModuleDef>(fileName,startLine,startColom,name,nullptr,nullptr,true),
55
56 // --- Definition
57 DefType definitionType() const override { return TypeModule; }
59 QCString displayName(bool=TRUE) const override { return name(); }
60 QCString getOutputFileBase() const override;
61 QCString anchor() const override { return ""; }
62 bool isLinkableInProject() const override {
63 if (m_primaryInterface) return m_primaryInterface->isLinkableInProject();
64 else return isLinkable() && !isHidden() && !isReference(); }
65 bool isLinkable() const override {
66 if (m_primaryInterface) return m_primaryInterface->isLinkable();
67 else return hasDocumentation(); }
68 QCString qualifiedName() const override;
69 void writeSummaryLinks(OutputList &ol) const override;
70 void writePageNavigation(OutputList &ol) const override;
71
72 // --- ModuleDef
73 Type moduleType() const override { return m_type; }
74 QCString partitionName() const override { return m_partitionName; }
75 void writeDocumentation(OutputList &ol) override;
76 bool isPrimaryInterface() const override { return m_type==Type::Interface && m_partitionName.isEmpty(); }
77 MemberList *getMemberList(MemberListType lt) const override;
78 const MemberLists &getMemberLists() const override { return m_memberLists; }
79 const MemberGroupList &getMemberGroups() const override { return m_memberGroups; }
80 const ClassLinkedRefMap &getClasses() const override { return m_classes; }
81 const ConceptLinkedRefMap &getConcepts() const override { return m_concepts; }
82 int countVisibleMembers() const override;
83 FileDef *getFileDef() const override { return m_fileDef; }
84 const ImportInfoMap &getImports() const override { return m_imports; }
85 const ImportInfoMap &getExports() const override { return m_exportedModules; }
86 const ModuleMap &partitions() const override { return m_partitions; }
87 void writeTagFile(TextStream &t) const override;
88 FileList getUsedFiles() const override;
89
90 void writeExports(OutputList &ol,const QCString &title);
91 void writeClassDeclarations(OutputList &ol,const QCString &title);
92 void writeConcepts(OutputList &ol,const QCString &title);
93 void writeFiles(OutputList &ol,const QCString &title);
98 void writeDetailedDescription(OutputList &ol,const QCString &title);
104 void writeDeclarationLink(OutputList &ol,bool &found,const QCString &header,bool localNames) const;
105
106 void addHeader(int line,const QCString &headerName,bool isSystem);
107 void addImport(int line,const QCString &moduleName,const QCString &partitionName,bool isExported);
108 void addClassToModule(const Entry *root,ClassDef *cd);
109 void addConceptToModule(const Entry *root,ConceptDef *cd);
110 void addMemberToModule(const Entry *root,MemberDef *md);
111 void addPartition(ModuleDefImpl *mod);
113 void setPrimaryInterface(const ModuleDef *mod);
114 void setFileDef(FileDef *fd);
116 void addExportedModule(const QCString &moduleName,const ImportInfo &info);
117 void addListReferences();
121 void sortMemberLists();
122
123 //ModuleMap &partitions() { return m_partitions; }
124 void mergeSymbolsFrom(ModuleDefImpl *other);
125 bool hasDetailedDescription() const;
126 void countMembers();
127
128 private:
140 FileDef *m_fileDef = nullptr; // file holding this module
141};
142
144{
145 return convertNameToFile("module_" + name());
146}
147
149{
150 QCString result=name();
151 if (!m_partitionName.isEmpty())
152 {
153 result+=":"+m_partitionName;
154 }
155 return result;
156}
157
159{
160 std::string qName = mod->qualifiedName().str();
161 if (m_partitions.find(qName)==m_partitions.end())
162 {
163 m_partitions.emplace(qName,mod);
164 }
165}
166
168{
169 if (std::find(m_contributing.begin(),m_contributing.end(),mod)==m_contributing.end())
170 {
171 m_contributing.push_back(mod);
172 }
173}
174
179
181{
182 m_fileDef = fd;
183}
184
185void ModuleDefImpl::addHeader(int line,const QCString &headerName,bool isSystem)
186{
187 AUTO_TRACE("name={}:line={},header={},isSystem={}",name(),line,headerName,isSystem);
188}
189
190void ModuleDefImpl::addImport(int line,const QCString &moduleName,const QCString &partitionName,bool isExported)
191{
192 AUTO_TRACE("name={}:line={},module={},partition={}",name(),line,moduleName,partitionName);
193 m_imports[getDefFileName().str()+":"+std::to_string(line)].push_back(ImportInfo(this,moduleName,line,partitionName,isExported));
194}
195
196void ModuleDefImpl::addExportedModule(const QCString &moduleName,const ImportInfo &info)
197{
198 AUTO_TRACE("name={}:moduleName={},import={}",name(),moduleName,info.importName);
199 m_exportedModules[moduleName.str()].push_back(info);
200}
201
203{
204 QCString className = cd->qualifiedName();
205 AUTO_TRACE("{}:{} class {} of module {} exported={}",
206 root->fileName,root->startLine, className, name(), root->exported);
207 bool isExported = m_classes.find(className)!=nullptr;
208 if (root->exported && !isExported)
209 {
210 m_classes.add(className,cd);
211 }
212 auto cdm = toClassDefMutable(cd);
213 if (cdm && root->exported && !cd->isExported())
214 {
215 cdm->setExported(true);
216 }
217}
218
220{
221 QCString conceptName = cd->qualifiedName();
222 AUTO_TRACE("{}:{} concept {} of module {} exported={}",
223 root->fileName,root->startLine,
224 cd->qualifiedName(),name(),
225 root->exported);
226 bool isExported = m_classes.find(conceptName)!=nullptr;
227 if (root->exported && !isExported)
228 {
229 m_concepts.add(conceptName,cd);
230 }
231 auto cdm = toConceptDefMutable(cd);
232 if (cdm && root->exported && !cd->isExported())
233 {
234 cdm->setExported(true);
235 }
236}
237
239{
240 for (auto &ml : m_memberLists)
241 {
242 if (ml->listType()==lt)
243 {
244 return ml.get();
245 }
246 }
247 return nullptr;
248}
249
251{
252 bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
253 bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
255 ml->setNeedsSorting(
256 (ml->listType().isDeclaration() && sortBriefDocs) ||
257 (ml->listType().isDocumentation() && sortMemberDocs));
258 ml->push_back(md);
259 if (ml->listType().isDeclaration())
260 {
262 if (mdm)
263 {
264 mdm->setSectionList(this,ml.get());
265 }
266 }
267}
268
270{
271 AUTO_TRACE("{}:{} member {} of module {} exported={}",
272 qPrint(root->fileName),root->startLine,
274 root->exported);
275 MemberList *allMemberList = getMemberList(MemberListType::AllMembersList());
276 if (allMemberList==nullptr)
277 {
278 m_memberLists.emplace_back(std::make_unique<MemberList>(MemberListType::AllMembersList(),MemberListContainer::Module));
279 allMemberList = m_memberLists.back().get();
280 }
281 if (allMemberList->contains(md))
282 {
283 return;
284 }
285 allMemberList->push_back(md);
286 switch (md->memberType())
287 {
289 addMemberToList(MemberListType::DecVarMembers(),md);
290 break;
292 addMemberToList(MemberListType::DecFuncMembers(),md);
293 break;
295 addMemberToList(MemberListType::DecTypedefMembers(),md);
296 break;
298 addMemberToList(MemberListType::DecEnumMembers(),md);
299 break;
300 default:
301 break;
302 }
303 auto mdm = toMemberDefMutable(md);
304 if (mdm && root->exported && !md->isExported())
305 {
306 mdm->setExported(true);
307 }
308}
309
311{
312 AUTO_TRACE("{} merging symbols of {} ({}:{})",
313 name(),other->qualifiedName(),other->getDefFileName(),other->getDefLine());
314 for (const auto &cd : other->getClasses())
315 {
316 m_classes.add(cd->qualifiedName(),cd);
317 }
318 for (const auto &cd : other->getConcepts())
319 {
320 m_concepts.add(cd->qualifiedName(),cd);
321 }
322 auto mergeMemberList = [this,other](MemberListType lt)
323 {
324 const auto srcMl = other->getMemberList(lt);
325 if (srcMl)
326 {
327 auto &dstMl = m_memberLists.get(lt,srcMl->container());
328 for (const auto &md : *srcMl)
329 {
330 dstMl->push_back(md);
331 }
332 }
333 };
334 mergeMemberList(MemberListType::DecVarMembers());
335 mergeMemberList(MemberListType::DecFuncMembers());
336 mergeMemberList(MemberListType::DecTypedefMembers());
337 mergeMemberList(MemberListType::DecEnumMembers());
338}
339
341{
342 if (isReference()) return;
343 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
345 AUTO_TRACE("%s file=%s",name(),getDefFileName());
346 SrcLangExt lang = getLanguage();
347 QCString pageTitle;
348 if (Config_getBool(HIDE_COMPOUND_REFERENCE))
349 {
350 pageTitle = displayName();
351 }
352 else
353 {
354 pageTitle = theTranslator->trModuleReference(displayName());
355 }
357
358 // ---- title part
360 bool writeOutlinePanel = generateTreeView && Config_getBool(PAGE_OUTLINE_PANEL);
361 if (!writeOutlinePanel) writeSummaryLinks(ol);
363
366 ol.parseText(pageTitle);
368
369 addGroupListToTitle(ol,this);
370
373 ol.endTitleHead(getOutputFileBase(),pageTitle);
375
379 ol.writeString(" - ");
380 ol.parseText(pageTitle);
382
383 ol.endHeaderSection();
384 ol.startContents();
385
386 //---------------------------------------- start flexible part -------------------------------
387 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
388 {
389 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
390 switch (lde->kind())
391 {
392 case LayoutDocEntry::BriefDesc:
394 break;
395 case LayoutDocEntry::MemberDeclStart:
397 break;
398 case LayoutDocEntry::ModuleClasses:
399 if (ls) writeClassDeclarations(ol,ls->title(lang));
400 break;
401 case LayoutDocEntry::ModuleConcepts:
402 if (ls) writeConcepts(ol,ls->title(lang));
403 break;
404 case LayoutDocEntry::ModuleExports:
405 if (ls) writeExports(ol,ls->title(lang));
406 break;
407 case LayoutDocEntry::ModuleUsedFiles:
408 if (ls) writeFiles(ol,ls->title(lang));
409 break;
410 case LayoutDocEntry::MemberGroups:
412 break;
413 case LayoutDocEntry::MemberDecl:
414 {
415 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
416 if (lmd) writeMemberDeclarations(ol,lmd->type,lmd->title(lang));
417 }
418 break;
419 case LayoutDocEntry::MemberDeclEnd:
421 break;
422 case LayoutDocEntry::DetailedDesc:
423 if (ls) writeDetailedDescription(ol,ls->title(lang));
424 break;
425 case LayoutDocEntry::MemberDefStart:
427 break;
428 case LayoutDocEntry::MemberDef:
429 {
430 const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get());
431 if (lmd) writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
432 }
433 break;
434 case LayoutDocEntry::MemberDefEnd:
436 break;
437 case LayoutDocEntry::AuthorSection:
439 break;
440 case LayoutDocEntry::ClassIncludes:
441 case LayoutDocEntry::ClassInheritanceGraph:
442 case LayoutDocEntry::ClassNestedClasses:
443 case LayoutDocEntry::ClassCollaborationGraph:
444 case LayoutDocEntry::ClassAllMembersLink:
445 case LayoutDocEntry::ClassUsedFiles:
446 case LayoutDocEntry::ClassInlineClasses:
447 case LayoutDocEntry::FileClasses:
448 case LayoutDocEntry::FileConcepts:
449 case LayoutDocEntry::FileInterfaces:
450 case LayoutDocEntry::FileStructs:
451 case LayoutDocEntry::FileExceptions:
452 case LayoutDocEntry::FileNamespaces:
453 case LayoutDocEntry::FileConstantGroups:
454 case LayoutDocEntry::FileIncludes:
455 case LayoutDocEntry::FileIncludeGraph:
456 case LayoutDocEntry::FileIncludedByGraph:
457 case LayoutDocEntry::FileInlineClasses:
458 case LayoutDocEntry::FileSourceLink:
459 case LayoutDocEntry::NamespaceNestedNamespaces:
460 case LayoutDocEntry::NamespaceNestedConstantGroups:
461 case LayoutDocEntry::NamespaceClasses:
462 case LayoutDocEntry::NamespaceConcepts:
463 case LayoutDocEntry::NamespaceInterfaces:
464 case LayoutDocEntry::NamespaceStructs:
465 case LayoutDocEntry::NamespaceExceptions:
466 case LayoutDocEntry::NamespaceInlineClasses:
467 case LayoutDocEntry::ConceptDefinition:
468 case LayoutDocEntry::GroupClasses:
469 case LayoutDocEntry::GroupConcepts:
470 case LayoutDocEntry::GroupModules:
471 case LayoutDocEntry::GroupInlineClasses:
472 case LayoutDocEntry::GroupNamespaces:
473 case LayoutDocEntry::GroupDirs:
474 case LayoutDocEntry::GroupNestedGroups:
475 case LayoutDocEntry::GroupFiles:
476 case LayoutDocEntry::GroupGraph:
477 case LayoutDocEntry::GroupPageDocs:
478 case LayoutDocEntry::DirSubDirs:
479 case LayoutDocEntry::DirFiles:
480 case LayoutDocEntry::DirGraph:
481 err("Internal inconsistency: member '{}' should not be part of "
482 "LayoutDocManager::Module entry list\n",lde->entryToString());
483 break;
484 }
485 }
486
487 //---------------------------------------- end flexible part -------------------------------
488 if (generateTreeView)
489 {
492 ol.endContents();
493 ol.writeString("</div><!-- doc-content -->\n");
495 ol.writeString("</div><!-- container -->\n");
497 }
498 endFile(ol,generateTreeView,true);
499
501}
502
504{
505 m_classes.writeDeclaration(ol,nullptr,title,FALSE);
506}
507
509{
510 m_concepts.writeDeclaration(ol,title,FALSE);
511}
512
517
522
524{
525 if (Config_getBool(SEPARATE_MEMBER_PAGES))
526 {
529 }
530}
531
533{
534 if (Config_getBool(SEPARATE_MEMBER_PAGES))
535 {
538 }
539}
540
542{
544 {
547 ol.writeRuler();
551 ol.writeAnchor(QCString(),"details");
553 ol.startGroupHeader("details");
554 ol.parseText(title);
555 ol.endGroupHeader();
556
557 ol.startTextBlock();
558 if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF))
559 {
561 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
562 }
563 if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) &&
564 !documentation().isEmpty())
565 {
569 ol.enableAll();
572 ol.writeString("\n\n");
574 }
575 if (!documentation().isEmpty())
576 {
577 ol.generateDoc(docFile(),docLine(),this,nullptr,documentation()+"\n",TRUE,FALSE,
578 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
579 }
580 ol.endTextBlock();
581 }
582}
583
585{
587 {
588 auto parser { createDocParser() };
589 auto ast { validatingParseDoc(*parser.get(),
590 briefFile(),briefLine(),this,nullptr,
592 QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) };
593 if (!ast->isEmpty())
594 {
595 ol.startParagraph();
598 ol.writeString(" - ");
600 ol.writeDoc(ast.get(),this,nullptr);
603 ol.writeString(" \n");
605
607 {
609 ol.startTextLink(QCString(),"details");
610 ol.parseText(theTranslator->trMore());
611 ol.endTextLink();
612 }
614 ol.endParagraph();
615 }
616 }
617 ol.writeSynopsis();
618}
619
621{
622 for (const auto &mg : m_memberGroups)
623 {
624 mg->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this);
625 }
626}
627
629{
630 MemberList * ml = getMemberList(lt);
631 if (ml) ml->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this,title,QCString());
632}
633
635{
636 MemberList * ml = getMemberList(lt);
637 if (ml) ml->writeDocumentation(ol,name(),this,title,ml->listType().toLabel());
638}
639
641{
642 // write Author section (Man only)
645 ol.startGroupHeader();
646 ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
647 ol.endGroupHeader();
648 ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString(PROJECT_NAME)));
650}
651
653{
654 bool repeatBrief = Config_getBool(REPEAT_BRIEF);
655 return (!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty();
656}
657
659{
660 for (auto &ml : m_memberLists)
661 {
662 ml->countDecMembers();
663 ml->countDocMembers();
664 }
665 for (const auto &mg : m_memberGroups)
666 {
667 mg->countDecMembers();
668 mg->countDocMembers();
669 }
670}
671
673{
674 const RefItemVector &xrefItems = xrefListItems();
675 addRefItem(xrefItems,
677 getLanguage()==SrcLangExt::Fortran ?
678 theTranslator->trModule(TRUE,TRUE) :
679 theTranslator->trNamespace(TRUE,TRUE),
681 QCString(),
682 this
683 );
684 for (const auto &mg : m_memberGroups)
685 {
686 mg->addListReferences(this);
687 }
688 for (auto &ml : m_memberLists)
689 {
690 if (ml->listType().isDocumentation())
691 {
692 ml->addListReferences(this);
693 }
694 }
695}
696
698{
699 for (auto &ml : m_memberLists)
700 {
701 if (ml->listType().isDeclaration())
702 {
704 }
705 }
706
707 // add members inside sections to their groups
708 for (const auto &mg : m_memberGroups)
709 {
710 if (mg->allMembersInSameSection() && Config_getBool(SUBGROUPING))
711 {
712 //printf("----> addToDeclarationSection(%s)\n",qPrint(mg->header()));
713 mg->addToDeclarationSection();
714 }
715 }
716}
717
719{
720 for (const auto &mg : m_memberGroups)
721 {
722 mg->distributeMemberGroupDocumentation();
723 }
724}
725
727{
731 for (const auto &mg : m_memberGroups)
732 {
733 mg->findSectionsInDocumentation(this);
734 }
735 for (auto &ml : m_memberLists)
736 {
737 if (ml->listType().isDeclaration())
738 {
739 ml->findSectionsInDocumentation(this);
740 }
741 }
742}
743
745{
746 for (auto &ml : m_memberLists)
747 {
748 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
749 }
750
751 if (Config_getBool(SORT_BRIEF_DOCS))
752 {
753 auto classComp = [](const ClassLinkedRefMap::Ptr &c1,const ClassLinkedRefMap::Ptr &c2)
754 {
755 return Config_getBool(SORT_BY_SCOPE_NAME) ?
756 qstricmp_sort(c1->name(), c2->name())<0 :
757 qstricmp_sort(c1->className(), c2->className())<0;
758 };
759 std::stable_sort(m_classes.begin(), m_classes.end(), classComp);
760
761 auto conceptComp = [](const ConceptLinkedRefMap::Ptr &c1,const ConceptLinkedRefMap::Ptr &c2)
762 {
763 return Config_getBool(SORT_BY_SCOPE_NAME) ?
764 qstricmp_sort(c1->qualifiedName(), c2->qualifiedName())<0 :
765 qstricmp_sort(c1->name(), c2->name())<0;
766 };
767 std::stable_sort(m_concepts.begin(), m_concepts.end(), conceptComp);
768 }
769
770 static auto contrComp = [](const ModuleDef *m1, const ModuleDef *m2)
771 {
772 FileDef *f1 = m1->getFileDef();
773 FileDef *f2 = m2->getFileDef();
774 QCString fn1 = f1 ? f1->name() : m1->name();
775 QCString fn2 = f2 ? f2->name() : m2->name();
776 static auto typeRank = [](const ModuleDef *m) -> int
777 {
778 if (m->moduleType()==ModuleDef::Type::Interface)
779 {
780 if (m->partitionName().isEmpty()) return 0; // primary interface unit
781 return 1; // partition interface unit
782 }
783 else
784 {
785 if (!m->partitionName().isEmpty()) return 2; // partition implementation unit
786 return 3; // implementation unit
787 }
788 };
789 auto tr1 = typeRank(m1);
790 auto tr2 = typeRank(m2);
791 int diff = qstricmp_sort(fn1,fn2);
792 return tr1<tr2 || (tr1==tr2 && diff<0);
793 };
794
795 std::stable_sort(m_contributing.begin(), m_contributing.end(), contrComp);
796}
797
799{
802 bool first=TRUE;
803 SrcLangExt lang=getLanguage();
804 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
805 {
806 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
807 if (lde->kind()==LayoutDocEntry::ModuleClasses && m_classes.declVisible() && ls)
808 {
809 QCString label = "classes";
810 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
811 first=FALSE;
812 }
813 else if (lde->kind()==LayoutDocEntry::ModuleConcepts && m_concepts.declVisible() && ls)
814 {
815 QCString label = "concepts";
816 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
817 first=FALSE;
818 }
819 else if (lde->kind()==LayoutDocEntry::ModuleUsedFiles && ls)
820 {
821 QCString label = "files";
822 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
823 first=FALSE;
824 }
825 else if (lde->kind()==LayoutDocEntry::MemberDecl)
826 {
827 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
828 if (lmd)
829 {
830 MemberList * ml = getMemberList(lmd->type);
831 if (ml && ml->declVisible())
832 {
833 ol.writeSummaryLink(QCString(),ml->listType().toLabel(),lmd->title(lang),first);
834 first=FALSE;
835 }
836 }
837 }
838 }
839 if (!first)
840 {
841 ol.writeString(" </div>\n");
842 }
844}
845
850
851void ModuleDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const QCString &header,bool localNames) const
852{
853 if (isLinkable())
854 {
855 if (!found) // first module
856 {
857 ol.startMemberHeader("modules");
858 if (!header.isEmpty())
859 {
860 ol.parseText(header);
861 }
862 else
863 {
864 theTranslator->trModule(true,false);
865 }
866 ol.endMemberHeader();
867 ol.startMemberList();
868 found=TRUE;
869 }
871 QCString cname = displayName(!localNames);
872 QCString anc = anchor();
873 if (anc.isEmpty()) anc=cname; else anc.prepend(cname+"_");
875 ol.writeString("module ");
877 if (isLinkable())
878 {
881 anchor(),
882 cname
883 );
884 }
885 else
886 {
887 ol.startBold();
888 ol.docify(cname);
889 ol.endBold();
890 }
892 // add the brief description if available
893 if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
894 {
895 auto parser { createDocParser() };
896 auto ast { validatingParseDoc(
897 *parser.get(),briefFile(),briefLine(),this,nullptr,
899 QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) };
900 if (!ast->isEmpty())
901 {
903 ol.writeDoc(ast.get(),this,nullptr);
905 }
906 }
908 }
909}
910
911
913{
914 AUTO_TRACE("name={} count={}",name(),m_exportedModules.size());
915 if (!m_exportedModules.empty())
916 {
917 ol.startMemberHeader("exports");
918 ol.parseText(title);
919 ol.endMemberHeader();
920 ol.startMemberList();
921 for (const auto &[moduleName,importInfoList] : m_exportedModules)
922 {
923 for (const auto &importInfo : importInfoList)
924 {
925 ModuleDef *mod = ModuleManager::instance().getPrimaryInterface(importInfo.importName);
928 ol.docify(theTranslator->trModule(FALSE,TRUE)+" ");
930 if (mod && mod->isLinkable())
931 {
933 }
934 else
935 {
936 ol.startBold();
937 ol.docify(importInfo.importName);
938 ol.endBold();
939 }
941 if (mod && !mod->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
942 {
944 ol.generateDoc(briefFile(),briefLine(),mod,nullptr,mod->briefDescription(),FALSE,FALSE,
945 QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
947 }
949 }
950 }
951 ol.endMemberList();
952 }
953}
954
956{
957 AUTO_TRACE("{} count={}",name(),m_contributing.size());
958 if (!m_contributing.empty())
959 {
960 ol.startMemberHeader("files");
961 ol.parseText(title);
962 ol.endMemberHeader();
963 ol.startMemberList();
964 for (const auto &mod : m_contributing)
965 {
966 FileDef *fd = mod->getFileDef();
967 if (fd)
968 {
970 QCString fname = fd->displayName();
971 QCString anc = fd->anchor();
972 if (anc.isEmpty()) anc=fname; else anc.prepend(fname+"_");
974 ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
976 QCString path=fd->getPath();
977 if (Config_getBool(FULL_PATH_NAMES))
978 {
979 ol.docify(stripFromPath(path));
980 }
981 if (fd->isLinkable())
982 {
984 }
985 else
986 {
987 ol.startBold();
988 ol.docify(fd->displayName());
989 ol.endBold();
990 }
992 if (!fd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
993 {
996 QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
998 }
1000 }
1001 }
1002 ol.endMemberList();
1003 }
1004}
1005
1007{
1008 FileList result;
1009 for (const auto &mod : m_contributing)
1010 {
1011 FileDef *fd = mod->getFileDef();
1012 if (fd) result.push_back(fd);
1013 }
1014 return result;
1015}
1016
1018{
1019 int count=0;
1020 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
1021 {
1022 if (lde->kind()==LayoutDocEntry::MemberDecl)
1023 {
1024 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1025 if (lmd)
1026 {
1027 MemberList *ml = getMemberList(lmd->type);
1028 if (ml)
1029 {
1030 for (const auto &md : *ml)
1031 {
1032 if (md->visibleInIndex())
1033 {
1034 count++;
1035 }
1036 }
1037 }
1038 }
1039 }
1040 else if (lde->kind()==LayoutDocEntry::ModuleClasses)
1041 {
1042 for (const auto &cd : getClasses())
1043 {
1044 if (cd->isLinkableInProject())
1045 {
1046 count++;
1047 }
1048 }
1049 }
1050 else if (lde->kind()==LayoutDocEntry::ModuleConcepts)
1051 {
1052 for (const auto &cd : getConcepts())
1053 {
1054 if (cd->isLinkableInProject())
1055 {
1056 count++;
1057 }
1058 }
1059 }
1060 }
1061 return count;
1062}
1063
1065{
1066 if (!isPrimaryInterface() || !isLinkableInProject()) return;
1067 tagFile << " <compound kind=\"module\">\n";
1068 tagFile << " <name>" << convertToXML(name()) << "</name>\n";
1069 const FileDef *fd = getFileDef();
1070 QCString fn = fd ? fd->getOutputFileBase() : getOutputFileBase();
1072 tagFile << " <filename>" << convertToXML(fn) << "</filename>\n";
1073#if 0 // at the moment we do not export the members of a module to a tag file.
1074 // We let the project using a tag file directly link to the implementation of the
1075 // symbols (which have the same scope).
1076 //
1077 // When we support linking to a module's interface instead we need to
1078 // export the module's members as well. Then we probably need a way to
1079 // disambiguate/prioritize a link to a module over a link to the implementation,
1080 // for instance by hiding non-exported symbols from the tag file.
1081 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Group))
1082 {
1083 switch (lde->kind())
1084 {
1085 case LayoutDocEntry::ModuleExports:
1086 {
1087 for (const auto &[modName,importInfo] : m_exportedModules)
1088 {
1089 tagFile << " <export>" << convertToXML(importInfo.importName) << "</export>\n";
1090 }
1091 }
1092 break;
1093 case LayoutDocEntry::ModuleClasses:
1094 {
1095 for (const auto &cd : m_classes)
1096 {
1097 if (cd->isLinkableInProject())
1098 {
1099 tagFile << " <class kind=\"" << cd->compoundTypeString()
1100 << "\">" << convertToXML(cd->name()) << "</class>\n";
1101 }
1102 }
1103 }
1104 break;
1105 case LayoutDocEntry::ModuleConcepts:
1106 {
1107 for (const auto &cd : m_concepts)
1108 {
1109 if (cd->isLinkableInProject())
1110 {
1111 tagFile << " <concept>" << convertToXML(cd->name())
1112 << "</concept>\n";
1113 }
1114 }
1115 }
1116 break;
1117 case LayoutDocEntry::ModuleUsedFiles:
1118 {
1119 for (const auto &usedFd : getUsedFiles())
1120 {
1121 if (usedFd->isLinkableInProject())
1122 {
1123 tagFile << " <file>" << convertToXML(usedFd->name()) << "</file>\n";
1124 }
1125 }
1126 }
1127 break;
1128 case LayoutDocEntry::MemberDecl:
1129 {
1130 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1131 if (lmd && lmd->visible())
1132 {
1133 MemberList * ml = getMemberList(lmd->type);
1134 if (ml)
1135 {
1136 ml->writeTagFile(tagFile,true);
1137 }
1138 }
1139 }
1140 break;
1141 default:
1142 break;
1143 }
1144 }
1145#endif
1146 QCString idStr = id();
1147 if (!idStr.isEmpty())
1148 {
1149 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>\n";
1150 }
1151 writeDocAnchorsToTagFile(tagFile);
1152 tagFile << " </compound>\n";
1153}
1154
1155//------------------------------------------------------------------------------------------------------------
1156
1158{
1159 if (d==nullptr) return nullptr;
1160 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<ModuleDef*>(d) : nullptr;
1161}
1162
1164{
1165 if (d==nullptr) return nullptr;
1166 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<const ModuleDef*>(d) : nullptr;
1167}
1168
1170{ return static_cast<ModuleDefImpl*>(m); }
1171
1172//static inline const ModuleDefImpl *toModuleDefImpl(const ModuleDef *m)
1173//{ return static_cast<const ModuleDefImpl*>(m); }
1174
1175static inline ModuleDefImpl *toModuleDefImpl(const std::unique_ptr<ModuleDef> &m)
1176{ return static_cast<ModuleDefImpl*>(m.get()); }
1177
1178//------------------------------------------------------------------------------------
1179
1181{
1182 bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
1183 for (const auto &mod : *this)
1184 {
1185 bool isLink = mod->isLinkable();
1186 if (isLink || !hideUndocClasses)
1187 {
1188 return true;
1189 }
1190 }
1191 return false;
1192}
1193
1194void ModuleLinkedRefMap::writeDeclaration(OutputList &ol,const QCString &header,bool localNames) const
1195{
1196 bool found=FALSE;
1197 for (const auto &mod : *this)
1198 {
1199 toModuleDefImpl(mod)->writeDeclarationLink(ol,found,header,localNames);
1200 }
1201 if (found) ol.endMemberList();
1202}
1203
1204//------------------------------------------------------------------------------------------------------------
1205
1207{
1208 ModuleLinkedMap moduleFileMap; // file->module mapping
1209 std::unordered_map<std::string,ModuleList> moduleNameMap; // name->module mapping
1212 std::mutex mutex;
1213};
1214
1216{
1217 static ModuleManager m;
1218 return m;
1219}
1220
1222{
1223}
1224
1225void ModuleManager::createModuleDef(const QCString &fileName,int line,int column,bool exported,
1226 const QCString &moduleName,const QCString &partitionName)
1227{
1228 AUTO_TRACE("{}:{}: Found module name='{}' partition='{}' exported='{}'",
1229 fileName,line,moduleName,partitionName,exported);
1230 std::lock_guard lock(p->mutex);
1232 std::unique_ptr<ModuleDef> modDef = std::make_unique<ModuleDefImpl>(fileName,line,column,moduleName,mt,partitionName);
1233 auto mod = p->moduleFileMap.add(fileName,std::move(modDef));
1234 auto it = p->moduleNameMap.find(moduleName.str());
1235 if (it == p->moduleNameMap.end())
1236 {
1237 ModuleList ml;
1238 ml.push_back(mod);
1239 p->moduleNameMap.emplace(moduleName.str(),ml);
1240 }
1241 else
1242 {
1243 it->second.push_back(mod);
1244 }
1245}
1246
1248{
1249 std::lock_guard lock(p->mutex);
1250 p->headers.clear();
1251 p->externalImports.clear();
1252 p->moduleNameMap.clear();
1253 p->moduleFileMap.clear();
1254}
1255
1256void ModuleManager::addHeader(const QCString &moduleFile,int line,const QCString &headerName,bool isSystem)
1257{
1258 AUTO_TRACE("{}:{} headerName={} isSystem={}",moduleFile,line,headerName,isSystem);
1259 std::lock_guard lock(p->mutex);
1260 auto mod = p->moduleFileMap.find(moduleFile);
1261 if (mod)
1262 {
1263 toModuleDefImpl(mod)->addHeader(line,headerName,isSystem);
1264 }
1265 else
1266 {
1267 AUTO_TRACE_ADD("imported header '{}' found in file '{}' that is not a module",headerName,moduleFile);
1268 }
1269 p->headers.emplace_back(moduleFile,headerName,isSystem);
1270}
1271
1272void ModuleManager::addImport(const QCString &moduleFile,int line,const QCString &importName,
1273 bool isExported,const QCString &partitionName)
1274{
1275 AUTO_TRACE("{}:{} importName={},isExported={},partitionName={}",
1276 moduleFile,line,importName,isExported,partitionName);
1277 std::lock_guard lock(p->mutex);
1278 auto mod = p->moduleFileMap.find(moduleFile);
1279 if (mod) // import inside a module
1280 {
1281 AUTO_TRACE_ADD("in module");
1282 toModuleDefImpl(mod)->addImport(line,importName.isEmpty()?mod->name():importName,partitionName,isExported);
1283 }
1284 else // import outside of a module
1285 {
1286 AUTO_TRACE_ADD("outside module");
1287 p->externalImports[moduleFile.str()].emplace_back(nullptr,importName,line,partitionName);
1288 }
1289}
1290
1292{
1293 std::lock_guard lock(p->mutex);
1294 auto mod = p->moduleFileMap.find(root->fileName);
1295 if (mod)
1296 {
1297 toModuleDefImpl(mod)->addClassToModule(root,cd);
1298 auto cdm = toClassDefMutable(cd);
1299 if (cdm) cdm->setModuleDef(mod);
1300 }
1301}
1302
1304{
1305 std::lock_guard lock(p->mutex);
1306 auto mod = p->moduleFileMap.find(root->fileName);
1307 if (mod)
1308 {
1309 toModuleDefImpl(mod)->addConceptToModule(root,cd);
1310 auto cdm = toConceptDefMutable(cd);
1311 if (cdm) cdm->setModuleDef(mod);
1312 }
1313}
1314
1316{
1317 std::lock_guard lock(p->mutex);
1318 auto mod = p->moduleFileMap.find(root->fileName);
1319 if (mod && root->exported)
1320 {
1321 toModuleDefImpl(mod)->addMemberToModule(root,md);
1322 auto mdm = toMemberDefMutable(md);
1323 if (mdm) mdm->setModuleDef(mod);
1324 }
1325}
1326
1327void ModuleManager::addTagInfo(const QCString &fileName,const QCString &tagFile,const QCString &clangId)
1328{
1329 std::lock_guard lock(p->mutex);
1330 auto mod = p->moduleFileMap.find(fileName);
1331 if (mod)
1332 {
1333 ModuleDefImpl *modi = toModuleDefImpl(mod);
1334 modi->setReference(tagFile);
1335 modi->setId(clangId);
1336 }
1337}
1338
1340{
1341 AUTO_TRACE();
1342 for (auto &[partitionFileName,importInfoList] : mod->getImports()) // foreach import
1343 {
1344 for (auto &importInfo : importInfoList)
1345 {
1346 AUTO_TRACE_ADD("partitionFileName={} importName={} partitionName={}",
1347 partitionFileName,importInfo.importName,importInfo.partitionName);
1348 if (importInfo.importName==intfMod->name() && !importInfo.partitionName.isEmpty() &&
1349 importInfo.exported) // that is an exported partition of this module
1350 {
1351 auto it = p->moduleNameMap.find(importInfo.importName.str());
1352 if (it != p->moduleNameMap.end())
1353 {
1354 for (auto importedMod : it->second)
1355 {
1356 if (importedMod->qualifiedName()==importInfo.importName+":"+importInfo.partitionName)
1357 {
1358 AUTO_TRACE_ADD("Interface module {} exports partition {}:{}",
1359 mod->name(),importedMod->name(),importedMod->partitionName());
1360 toModuleDefImpl(intfMod)->addPartition(toModuleDefImpl(importedMod));
1361 toModuleDefImpl(importedMod)->setPrimaryInterface(intfMod);
1362 for (const auto &[partitionFileName_,partitionImportInfoList] : importedMod->getImports())
1363 {
1364 for (const auto &partitionImportInfo : partitionImportInfoList)
1365 {
1366 if (partitionImportInfo.exported && intfMod->name()!=partitionImportInfo.importName)
1367 {
1368 toModuleDefImpl(intfMod)->addExportedModule(partitionImportInfo.importName,partitionImportInfo);
1369 }
1370 }
1371 }
1372 resolvePartitionsRecursively(intfMod,importedMod);
1373 }
1374 }
1375 }
1376 }
1377 }
1378 }
1379}
1380
1382{
1383 AUTO_TRACE();
1384 for (auto &mod : p->moduleFileMap) // foreach module
1385 {
1386 if (mod->moduleType()==ModuleDef::Type::Interface && mod->partitionName().isEmpty())
1387 { // that is a primary interface
1388 resolvePartitionsRecursively(mod.get(),mod.get());
1389 }
1390
1391 // copy exported imports to m_exportedModules
1392 for (const auto &[fileName,importInfoList] : mod->getImports())
1393 {
1394 for (const auto &importInfo : importInfoList)
1395 {
1396 if (importInfo.exported && mod->name()!=importInfo.importName)
1397 {
1398 toModuleDefImpl(mod)->addExportedModule(importInfo.importName,importInfo);
1399 }
1400 }
1401 }
1402
1403 // also link the ModuleDef and FileDef together
1404 bool ambig = false;
1405 FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,mod->getDefFileName(),ambig);
1406 if (fd)
1407 {
1408 fd->setModuleDef(mod.get());
1409 toModuleDefImpl(mod)->setFileDef(fd);
1410 }
1411 }
1412}
1413
1415{
1416 AUTO_TRACE();
1417 for (auto &mod : p->moduleFileMap)
1418 {
1419 FileDef *fd = mod->getFileDef();
1420 if (fd)
1421 {
1422 for (const auto &[fileName,importInfoList] : mod->getImports())
1423 {
1424 for (const auto &importInfo : importInfoList)
1425 {
1426 ModuleDef *importedModule = getPrimaryInterface(importInfo.importName);
1427 const FileDef *importedFd = importedModule ? importedModule->getFileDef() : nullptr;
1428 AUTO_TRACE_ADD("module: addIncludeDependency {}->{}:{} fd={}",
1429 mod->qualifiedName(), importInfo.qualifiedName(), importInfo.line, fd?fd->absFilePath():"");
1431 }
1432 }
1433 }
1434 }
1435 for (const auto &[fileName,importInfoList] : p->externalImports)
1436 {
1437 for (const auto &importInfo : importInfoList)
1438 {
1439 bool ambig = false;
1441 AUTO_TRACE_ADD("externalImport name={} fd={}",fileName,(void*)fd);
1442 if (fd)
1443 {
1444 ModuleDef *mod = getPrimaryInterface(importInfo.importName);
1445 FileDef *importedFd = mod ? mod->getFileDef() : nullptr;
1446 fd->addIncludeDependency(importedFd,importInfo.importName,IncludeKind::ImportModule);
1447 if (importedFd)
1448 {
1450 }
1451 }
1452 }
1453 }
1454 for (const auto &headerInfo : p->headers)
1455 {
1456 bool ambig = false;
1457 FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,headerInfo.fileName,ambig);
1458 AUTO_TRACE_ADD("header name={} fd={}",headerInfo.fileName,(void*)fd);
1459 if (fd)
1460 {
1461 QCString resolvedHeader = determineAbsoluteIncludeName(headerInfo.fileName,headerInfo.headerName);
1462 FileDef *importFd = findFileDef(Doxygen::inputNameLinkedMap,resolvedHeader,ambig);
1463 fd->addIncludeDependency(importFd, headerInfo.headerName,
1464 headerInfo.isSystem ? IncludeKind::ImportSystem : IncludeKind::ImportLocal);
1465 if (importFd)
1466 {
1468 }
1469 }
1470 }
1471}
1472
1474{
1475 AUTO_TRACE("{}: collecting symbols for partition {}",intfMod->qualifiedName(),partitionMod->qualifiedName());
1476 auto intfModImpl = toModuleDefImpl(intfMod);
1477 auto partitionModImpl = toModuleDefImpl(partitionMod);
1478 intfModImpl->mergeSymbolsFrom(partitionModImpl);
1479}
1480
1482{
1483 AUTO_TRACE();
1484 for (auto &mod : p->moduleFileMap) // foreach module
1485 {
1486 if (mod->isPrimaryInterface()) // that is a primary interface
1487 {
1488 for (auto &[partitionName,partitionMod] : mod->partitions())
1489 {
1490 collectExportedSymbolsRecursively(mod.get(),partitionMod);
1491 }
1492
1493 // collect all files that contribute to this module (e.g. implementation/partition modules)
1494 auto it = p->moduleNameMap.find(mod->name().str());
1495 if (it != p->moduleNameMap.end())
1496 {
1497 for (auto contributingMod : it->second)
1498 {
1499 AUTO_TRACE_ADD(" adding contributing module {} to interface module {} type={} partition={} isPrimaryIntf={}",
1500 contributingMod->qualifiedName(),
1501 mod->name(),
1502 contributingMod->moduleType()==ModuleDef::Type::Interface ? "Interface" : "Implementation",
1503 contributingMod->partitionName(),
1504 contributingMod->isPrimaryInterface());
1506 }
1507 }
1508 }
1509 }
1510}
1511
1513{
1514 for (auto &mod : p->moduleFileMap) // foreach module
1515 {
1517 }
1518}
1519
1521{
1522 for (auto &mod : p->moduleFileMap) // foreach module
1523 {
1524 if (mod->isPrimaryInterface())
1525 {
1526 mod->writeDocumentation(ol);
1527 }
1528 }
1529}
1530
1532{
1533 int count=0;
1534 for (const auto &mod : p->moduleFileMap) // foreach module
1535 {
1536 if (mod->isPrimaryInterface()) count++;
1537 }
1538 return count;
1539}
1540
1542{
1543 return p->moduleFileMap;
1544}
1545
1547{
1548 return p->moduleFileMap;
1549}
1550
1552{
1553 AUTO_TRACE("file={} module={}",root->fileName,root->name);
1554 if (root->doc.isEmpty() && root->brief.isEmpty()) return;
1555 if (root->name.find(':')!=-1)
1556 {
1557 warn(root->fileName,root->startLine,"Ignoring documentation for module partition {}. Please place documentation at the primary module name",
1558 root->name);
1559 }
1560 else
1561 {
1562 auto it = p->moduleNameMap.find(root->name.str());
1563 if (it != p->moduleNameMap.end())
1564 {
1565 ModuleDef *mod = getPrimaryInterface(root->name);
1566 if (mod)
1567 {
1568 mod->setDocumentation(root->doc,root->docFile,root->docLine);
1569 mod->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1570 mod->setId(root->id);
1571 mod->setHidden(root->hidden);
1572 mod->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1573 mod->setRefItems(root->sli);
1574 //mod->addSectionsToDefinition(root->anchors);
1575 addModuleToGroups(root,mod);
1576 }
1577 else
1578 {
1579 warn(root->fileName,root->startLine,"Found documentation for module {} but it has no primary interface unit.",root->name);
1580 }
1581 }
1582 else
1583 {
1584 warn(root->fileName,root->startLine,"Found documentation for unknown module {}.",root->name);
1585 }
1586 }
1587}
1588
1590{
1591 auto it = p->moduleNameMap.find(moduleName.str());
1592 if (it != p->moduleNameMap.end())
1593 {
1594 for (const auto &mod : it->second)
1595 {
1596 if (mod->isPrimaryInterface())
1597 {
1598 return mod;
1599 }
1600 }
1601 }
1602 return nullptr;
1603}
1604
1606{
1607 for (const auto &mod : p->moduleFileMap) // foreach module
1608 {
1609 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addListReferences();
1610 }
1611}
1612
1614{
1615 for (const auto &mod : p->moduleFileMap) // foreach module
1616 {
1617 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addMembersToMemberGroup();
1618 }
1619}
1620
1622{
1623 for (const auto &mod : p->moduleFileMap) // foreach module
1624 {
1625 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->distributeMemberGroupDocumentation();
1626 }
1627}
1628
1630{
1631 for (auto &mod : p->moduleFileMap) // foreach module
1632 {
1633 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->findSectionsInDocumentation();
1634 }
1635}
1636
1638{
1639 for (auto &mod : p->moduleFileMap) // foreach module
1640 {
1641 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->sortMemberLists();
1642 }
1643}
1644
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual QCString className() const =0
Returns the name of the class including outer classes, but not including namespaces.
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual bool isLinkable() const =0
virtual QCString anchor() const =0
virtual bool isExported() const =0
virtual QCString briefDescription(bool abbreviate=FALSE) const =0
virtual QCString getReference() const =0
virtual QCString qualifiedName() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
virtual QCString getOutputFileBase() const =0
virtual const QCString & name() const =0
int getDefLine() const override
bool isReference() const override
const QCString & name() const override
QCString getDefFileName() const override
bool isExported() const override
bool hasBriefDescription() const override
void setId(const QCString &name) override
QCString docFile() const override
QCString briefFile() const override
QCString id() const override
void setReference(const QCString &r) override
const RefItemVector & xrefListItems() const override
QCString briefDescription(bool abbreviate=FALSE) const override
QCString getReference() const override
DefinitionMixin(const QCString &defFileName, int defLine, int defColumn, const QCString &name, const char *b=nullptr, const char *d=nullptr, bool isSymbol=TRUE)
bool isHidden() const override
QCString inbodyDocumentation() const override
int docLine() const override
int briefLine() const override
QCString documentation() 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 QCString &d, const QCString &docFile, int docLine, bool stripWhiteSpace=TRUE)=0
virtual void setId(const QCString &name)=0
virtual void setBriefDescription(const QCString &b, const QCString &briefFile, int briefLine)=0
virtual void setRefItems(const RefItemVector &sli)=0
static bool suppressDocWarnings
Definition doxygen.h:132
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:116
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:189
QCString id
libclang id
Definition entry.h:231
QCString fileName
file this entry was extracted from
Definition entry.h:223
int startLine
start line of entry in the source
Definition entry.h:224
QCString name
member name
Definition entry.h:174
QCString briefFile
file in which the brief desc. was found
Definition entry.h:205
int bodyLine
line number of the body in the source
Definition entry.h:216
QCString doc
documentation block (partly parsed)
Definition entry.h:200
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:226
QCString docFile
file in which the documentation was found
Definition entry.h:202
bool hidden
does this represent an entity that is hidden from the output
Definition entry.h:228
QCString brief
brief description (doc block)
Definition entry.h:203
int briefLine
line number at which the brief desc. was found
Definition entry.h:204
A model of a file symbol.
Definition filedef.h:99
virtual void setModuleDef(ModuleDef *mod)=0
virtual void addIncludedByDependency(const FileDef *fd, const QCString &incName, IncludeKind kind)=0
virtual QCString getPath() const =0
virtual QCString absFilePath() const =0
virtual QCString fileName() const =0
virtual void addIncludeDependency(const FileDef *fd, const QCString &incName, IncludeKind kind)=0
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1435
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
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:109
void writeDeclarations(OutputList &ol, const ClassDef *cd, const NamespaceDef *nd, const FileDef *fd, const GroupDef *gd, const ModuleDef *mod, const QCString &title, const QCString &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 writeTagFile(TextStream &, bool useQualifiedName=false, bool showNamespaceMembers=true)
MemberListType listType() const
Definition memberlist.h:114
void writeDocumentation(OutputList &ol, const QCString &scopeName, const Definition *container, const QCString &title, const QCString &anchor, bool showEnumValues=FALSE, bool showInline=FALSE) const
bool declVisible() const
Wrapper class for the MemberListType type.
Definition types.h:346
constexpr const char * toLabel() const
Definition types.h:402
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()
void addPartition(ModuleDefImpl *mod)
void distributeMemberGroupDocumentation()
QCString anchor() const override
Definition moduledef.cpp:61
void startMemberDeclarations(OutputList &ol)
DefType definitionType() const override
Definition moduledef.cpp:57
void sortMemberLists()
QCString getOutputFileBase() const override
void endMemberDeclarations(OutputList &ol)
MemberList * getMemberList(MemberListType lt) const override
void writeDocumentation(OutputList &ol) override
FileList getUsedFiles() const override
void writeMemberDocumentation(OutputList &ol, MemberListType lt, const QCString &title)
ModuleList m_contributing
void addMemberToModule(const Entry *root, MemberDef *md)
bool isPrimaryInterface() const override
Definition moduledef.cpp:76
QCString qualifiedName() const override
void addConceptToModule(const Entry *root, ConceptDef *cd)
FileDef * getFileDef() const override
Definition moduledef.cpp:83
QCString partitionName() const override
Definition moduledef.cpp:74
void addClassToModule(const Entry *root, ClassDef *cd)
bool isLinkableInProject() const override
Definition moduledef.cpp:62
FileDef * m_fileDef
void writeTagFile(TextStream &t) const override
void writeMemberGroups(OutputList &ol)
const ModuleDef * m_primaryInterface
void startMemberDocumentation(OutputList &ol)
void writeAuthorSection(OutputList &ol)
const ImportInfoMap & getImports() const override
Definition moduledef.cpp:84
MemberLists m_memberLists
int countVisibleMembers() const override
void setPrimaryInterface(const ModuleDef *mod)
void writeClassDeclarations(OutputList &ol, const QCString &title)
void mergeSymbolsFrom(ModuleDefImpl *other)
void writeExports(OutputList &ol, const QCString &title)
const ClassLinkedRefMap & getClasses() const override
Definition moduledef.cpp:80
void addMembersToMemberGroup()
void writeFiles(OutputList &ol, const QCString &title)
void addExportedModule(const QCString &moduleName, const ImportInfo &info)
void endMemberDocumentation(OutputList &ol)
void setFileDef(FileDef *fd)
QCString m_partitionName
ConceptLinkedRefMap m_concepts
void addMemberToList(MemberListType lt, MemberDef *md)
void writeDetailedDescription(OutputList &ol, const QCString &title)
CodeSymbolType codeSymbolType() const override
Definition moduledef.cpp:58
const ImportInfoMap & getExports() const override
Definition moduledef.cpp:85
void writeBriefDescription(OutputList &ol)
ModuleDefImpl(const QCString &fileName, int startLine, int startColom, const QCString &name, Type type, const QCString &partitionName)
Definition moduledef.cpp:51
void writeMemberDeclarations(OutputList &ol, MemberListType lt, const QCString &title)
ClassLinkedRefMap m_classes
const MemberGroupList & getMemberGroups() const override
Definition moduledef.cpp:79
void findSectionsInDocumentation()
ImportInfoMap m_exportedModules
ModuleMap m_partitions
void addImport(int line, const QCString &moduleName, const QCString &partitionName, bool isExported)
bool isLinkable() const override
Definition moduledef.cpp:65
QCString displayName(bool=TRUE) const override
Definition moduledef.cpp:59
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:73
const ModuleMap & partitions() const override
Definition moduledef.cpp:86
const MemberLists & getMemberLists() const override
Definition moduledef.cpp:78
void writeDeclarationLink(OutputList &ol, bool &found, const QCString &header, bool localNames) const
MemberGroupList m_memberGroups
void writeConcepts(OutputList &ol, const QCString &title)
void addListReferences()
const ConceptLinkedRefMap & getConcepts() const override
Definition moduledef.cpp:81
void addHeader(int line, const QCString &headerName, bool isSystem)
bool declVisible() const
void writeDeclaration(OutputList &ol, const QCString &header, bool localNames) const
void addListReferences()
int numDocumentedModules() const
void sortMemberLists()
void resolveImports()
static ModuleManager & instance()
void addDocs(const Entry *root)
void collectExportedSymbolsRecursively(ModuleDef *intfMod, ModuleDef *mod)
void addHeader(const QCString &moduleFile, int line, const QCString &headerName, bool isSystem)
void countMembers()
void addConceptToModule(const Entry *root, ConceptDef *cd)
ModuleLinkedMap & modules()
void addTagInfo(const QCString &moduleFile, const QCString &tagName, const QCString &clangId)
void addClassToModule(const Entry *root, ClassDef *cd)
void createModuleDef(const QCString &fileName, int line, int column, bool exported, const QCString &moduleName, const QCString &partitionName=QCString())
ModuleDef * getPrimaryInterface(const QCString &moduleName) const
void addMemberToModule(const Entry *root, MemberDef *md)
void writeDocumentation(OutputList &ol)
void addMembersToMemberGroup()
void resolvePartitions()
std::unique_ptr< Private > p
Definition moduledef.h:147
void findSectionsInDocumentation()
void collectExportedSymbols()
void resolvePartitionsRecursively(ModuleDef *intfMod, ModuleDef *mod)
void addImport(const QCString &moduleFile, int line, const QCString &importName, bool isExported, const QCString &partitionName=QCString())
void distributeMemberGroupDocumentation()
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:314
void endTextBlock(bool paraBreak=FALSE)
Definition outputlist.h:673
void writeString(const QCString &text)
Definition outputlist.h:412
void startMemberDeclaration()
Definition outputlist.h:570
void endTitleHead(const QCString &fileName, const QCString &name)
Definition outputlist.h:406
void disable(OutputType o)
void startTitleHead(const QCString &fileName)
Definition outputlist.h:404
void writeRuler()
Definition outputlist.h:522
void startGroupHeader(const QCString &id=QCString(), int extraLevels=0)
Definition outputlist.h:454
void enable(OutputType o)
void endContents()
Definition outputlist.h:621
void endHeaderSection()
Definition outputlist.h:468
void endMemberDescription()
Definition outputlist.h:568
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:440
void writeDoc(const IDocNodeAST *ast, const Definition *ctx, const MemberDef *md)
Definition outputlist.h:384
void startMemberDescription(const QCString &anchor, const QCString &inheritId=QCString(), bool typ=false)
Definition outputlist.h:566
void startHeaderSection()
Definition outputlist.h:466
void docify(const QCString &s)
Definition outputlist.h:438
void startParagraph(const QCString &classDef=QCString())
Definition outputlist.h:408
void startTextBlock(bool dense=FALSE)
Definition outputlist.h:671
void endParagraph()
Definition outputlist.h:410
void startMemberSections()
Definition outputlist.h:462
void startMemberList()
Definition outputlist.h:482
void endTextLink()
Definition outputlist.h:445
void startBold()
Definition outputlist.h:562
void endMemberItem(OutputGenerator::MemberItemType type)
Definition outputlist.h:496
void endMemberList()
Definition outputlist.h:484
void writeSynopsis()
Definition outputlist.h:593
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
void pushGeneratorState()
void insertMemberAlign(bool templ=FALSE)
Definition outputlist.h:518
void disableAllBut(OutputType o)
void popGeneratorState()
void writeSummaryLink(const QCString &file, const QCString &anchor, const QCString &title, bool first)
Definition outputlist.h:615
void writeAnchor(const QCString &fileName, const QCString &name)
Definition outputlist.h:524
void endBold()
Definition outputlist.h:564
void endGroupHeader(int extraLevels=0)
Definition outputlist.h:456
void writePageOutline()
Definition outputlist.h:617
void startContents()
Definition outputlist.h:619
void endMemberDeclaration(const QCString &anchor, const QCString &inheritId)
Definition outputlist.h:572
void enableAll()
void endMemberHeader()
Definition outputlist.h:472
void startMemberItem(const QCString &anchor, OutputGenerator::MemberItemType type, const QCString &id=QCString())
Definition outputlist.h:494
void parseText(const QCString &textStr)
void startTextLink(const QCString &file, const QCString &anchor)
Definition outputlist.h:443
void startMemberHeader(const QCString &anchor, int typ=2)
Definition outputlist.h:470
void endMemberSections()
Definition outputlist.h:464
This is an alternative implementation of QCString.
Definition qcstring.h:101
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString & prepend(const char *s)
Definition qcstring.h:407
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const std::string & str() const
Definition qcstring.h:537
Text streaming class that buffers data.
Definition textstream.h:36
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:47
#define AUTO_TRACE(...)
Definition docnode.cpp:46
void docFindSections(const QCString &input, const Definition *d, const QCString &fileName)
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:55
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
static void writeTagFile()
@ 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 QCString &navPath)
Definition index.cpp:427
void startFile(OutputList &ol, const QCString &name, const QCString &manName, const QCString &title, HighlightedItem hli, bool additionalIndices, const QCString &altSidebarName, int hierarchyLevel, const QCString &allMembersFile)
Definition index.cpp:401
Translator * theTranslator
Definition language.cpp:71
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:45
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
int qstricmp_sort(const char *str1, const char *str2)
Definition qcstring.h:86
const char * qPrint(const char *s)
Definition qcstring.h:672
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
std::vector< RefItem * > RefItemVector
Definition reflist.h:133
QCString headerName
Definition moduledef.cpp:41
bool isSystem
Definition moduledef.cpp:42
HeaderInfo(const QCString &fn, const QCString &name, bool sys)
Definition moduledef.cpp:38
QCString fileName
Definition moduledef.cpp:40
QCString importName
Definition moduledef.h:44
Represents of a member declaration list with configurable title and subtitle.
Definition layout.h:112
QCString title(SrcLangExt lang) const
Definition layout.cpp:1786
MemberListType type
Definition layout.h:118
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
QCString title(SrcLangExt lang) const
Definition layout.cpp:1798
Definition layout.h:102
QCString 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
@ Enumeration
Definition types.h:557
@ Variable
Definition types.h:555
@ Typedef
Definition types.h:556
@ Function
Definition types.h:554
SrcLangExt
Definition types.h:207
void addRefItem(const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
Definition util.cpp:5318
void addGroupListToTitle(OutputList &ol, const Definition *d)
Definition util.cpp:5405
bool found
Definition util.cpp:984
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:309
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:4020
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:4428
QCString determineAbsoluteIncludeName(const QCString &curFile, const QCString &incFileName)
Definition util.cpp:4116
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:3415
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5415
A bunch of utility functions.