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();
122 void sortMemberLists();
123
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 briefLine(),
562 this,
563 nullptr,
565 DocOptions());
566 }
567 if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) &&
568 !documentation().isEmpty())
569 {
573 ol.enableAll();
576 ol.writeString("\n\n");
578 }
579 if (!documentation().isEmpty())
580 {
581 ol.generateDoc(docFile(),
582 docLine(),
583 this,
584 nullptr,
585 documentation()+"\n",
586 DocOptions()
587 .setIndexWords(true));
588 }
589 ol.endTextBlock();
590 }
591}
592
594{
596 {
597 auto parser { createDocParser() };
598 auto ast { validatingParseDoc(*parser.get(),
599 briefFile(),
600 briefLine(),
601 this,
602 nullptr,
604 DocOptions()
605 .setIndexWords(true)
606 .setSingleLine(true))
607 };
608 if (!ast->isEmpty())
609 {
610 ol.startParagraph();
613 ol.writeString(" - ");
615 ol.writeDoc(ast.get(),this,nullptr);
618 ol.writeString(" \n");
620
622 {
624 ol.startTextLink(QCString(),"details");
625 ol.parseText(theTranslator->trMore());
626 ol.endTextLink();
627 }
629 ol.endParagraph();
630 }
631 }
632 ol.writeSynopsis();
633}
634
636{
637 for (const auto &mg : m_memberGroups)
638 {
639 mg->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this);
640 }
641}
642
644{
645 MemberList * ml = getMemberList(lt);
646 if (ml) ml->writeDeclarations(ol,nullptr,nullptr,nullptr,nullptr,this,title,QCString());
647}
648
650{
651 MemberList * ml = getMemberList(lt);
652 if (ml) ml->writeDocumentation(ol,name(),this,title,ml->listType().toLabel());
653}
654
656{
657 // write Author section (Man only)
660 ol.startGroupHeader();
661 ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
662 ol.endGroupHeader();
663 ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString(PROJECT_NAME)));
665}
666
668{
669 bool repeatBrief = Config_getBool(REPEAT_BRIEF);
670 return (!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty();
671}
672
674{
675 for (auto &ml : m_memberLists)
676 {
677 ml->countDecMembers();
678 ml->countDocMembers();
679 }
680 for (const auto &mg : m_memberGroups)
681 {
682 mg->countDecMembers();
683 mg->countDocMembers();
684 }
685}
686
688{
691 getLanguage()==SrcLangExt::Fortran ?
692 theTranslator->trModule(TRUE,TRUE) :
693 theTranslator->trNamespace(TRUE,TRUE),
695 QCString(),
696 this
697 );
698 for (const auto &mg : m_memberGroups)
699 {
700 mg->addListReferences(this);
701 }
702 for (auto &ml : m_memberLists)
703 {
704 if (ml->listType().isDocumentation())
705 {
706 ml->addListReferences(this);
707 }
708 }
709}
710
712{
714 for (const auto &mg : m_memberGroups)
715 {
716 mg->addRequirementReferences(this);
717 }
718 for (auto &ml : m_memberLists)
719 {
720 if (ml->listType().isDocumentation())
721 {
722 ml->addRequirementReferences(this);
723 }
724 }
725}
726
728{
729 for (auto &ml : m_memberLists)
730 {
731 if (ml->listType().isDeclaration())
732 {
734 }
735 }
736
737 // add members inside sections to their groups
738 for (const auto &mg : m_memberGroups)
739 {
740 if (mg->allMembersInSameSection() && Config_getBool(SUBGROUPING))
741 {
742 //printf("----> addToDeclarationSection(%s)\n",qPrint(mg->header()));
743 mg->addToDeclarationSection();
744 }
745 }
746}
747
749{
750 for (const auto &mg : m_memberGroups)
751 {
752 mg->distributeMemberGroupDocumentation();
753 }
754}
755
757{
761 for (const auto &mg : m_memberGroups)
762 {
763 mg->findSectionsInDocumentation(this);
764 }
765 for (auto &ml : m_memberLists)
766 {
767 if (ml->listType().isDeclaration())
768 {
769 ml->findSectionsInDocumentation(this);
770 }
771 }
772}
773
775{
776 for (auto &ml : m_memberLists)
777 {
778 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
779 }
780
781 if (Config_getBool(SORT_BRIEF_DOCS))
782 {
783 auto classComp = [](const ClassLinkedRefMap::Ptr &c1,const ClassLinkedRefMap::Ptr &c2)
784 {
785 return Config_getBool(SORT_BY_SCOPE_NAME) ?
786 qstricmp_sort(c1->name(), c2->name())<0 :
787 qstricmp_sort(c1->className(), c2->className())<0;
788 };
789 std::stable_sort(m_classes.begin(), m_classes.end(), classComp);
790
791 auto conceptComp = [](const ConceptLinkedRefMap::Ptr &c1,const ConceptLinkedRefMap::Ptr &c2)
792 {
793 return Config_getBool(SORT_BY_SCOPE_NAME) ?
794 qstricmp_sort(c1->qualifiedName(), c2->qualifiedName())<0 :
795 qstricmp_sort(c1->name(), c2->name())<0;
796 };
797 std::stable_sort(m_concepts.begin(), m_concepts.end(), conceptComp);
798 }
799
800 static auto contrComp = [](const ModuleDef *m1, const ModuleDef *m2)
801 {
802 FileDef *f1 = m1->getFileDef();
803 FileDef *f2 = m2->getFileDef();
804 QCString fn1 = f1 ? f1->name() : m1->name();
805 QCString fn2 = f2 ? f2->name() : m2->name();
806 static auto typeRank = [](const ModuleDef *m) -> int
807 {
808 if (m->moduleType()==ModuleDef::Type::Interface)
809 {
810 if (m->partitionName().isEmpty()) return 0; // primary interface unit
811 return 1; // partition interface unit
812 }
813 else
814 {
815 if (!m->partitionName().isEmpty()) return 2; // partition implementation unit
816 return 3; // implementation unit
817 }
818 };
819 auto tr1 = typeRank(m1);
820 auto tr2 = typeRank(m2);
821 int diff = qstricmp_sort(fn1,fn2);
822 return tr1<tr2 || (tr1==tr2 && diff<0);
823 };
824
825 std::stable_sort(m_contributing.begin(), m_contributing.end(), contrComp);
826}
827
829{
832 bool first=TRUE;
833 SrcLangExt lang=getLanguage();
834 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
835 {
836 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
837 if (lde->kind()==LayoutDocEntry::ModuleClasses && m_classes.declVisible() && ls)
838 {
839 QCString label = "classes";
840 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
841 first=FALSE;
842 }
843 else if (lde->kind()==LayoutDocEntry::ModuleConcepts && m_concepts.declVisible() && ls)
844 {
845 QCString label = "concepts";
846 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
847 first=FALSE;
848 }
849 else if (lde->kind()==LayoutDocEntry::ModuleUsedFiles && ls)
850 {
851 QCString label = "files";
852 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
853 first=FALSE;
854 }
855 else if (lde->kind()==LayoutDocEntry::MemberDecl)
856 {
857 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
858 if (lmd)
859 {
860 MemberList * ml = getMemberList(lmd->type);
861 if (ml && ml->declVisible())
862 {
863 ol.writeSummaryLink(QCString(),ml->listType().toLabel(),lmd->title(lang),first);
864 first=FALSE;
865 }
866 }
867 }
868 }
869 if (!first)
870 {
871 ol.writeString(" </div>\n");
872 }
874}
875
880
881void ModuleDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const QCString &header,bool localNames) const
882{
883 if (isLinkable())
884 {
885 if (!found) // first module
886 {
887 ol.startMemberHeader("modules");
888 if (!header.isEmpty())
889 {
890 ol.parseText(header);
891 }
892 else
893 {
894 theTranslator->trModule(true,false);
895 }
896 ol.endMemberHeader();
897 ol.startMemberList();
898 found=TRUE;
899 }
901 QCString cname = displayName(!localNames);
902 QCString anc = anchor();
903 if (anc.isEmpty()) anc=cname; else anc.prepend(cname+"_");
905 ol.writeString("module ");
907 if (isLinkable())
908 {
911 anchor(),
912 cname
913 );
914 }
915 else
916 {
917 ol.startBold();
918 ol.docify(cname);
919 ol.endBold();
920 }
922 // add the brief description if available
923 if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
924 {
925 auto parser { createDocParser() };
926 auto ast { validatingParseDoc(*parser.get(),
927 briefFile(),
928 briefLine(),
929 this,
930 nullptr,
932 DocOptions()
933 .setSingleLine(true))
934 };
935 if (!ast->isEmpty())
936 {
938 ol.writeDoc(ast.get(),this,nullptr);
940 }
941 }
943 }
944}
945
946
948{
949 AUTO_TRACE("name={} count={}",name(),m_exportedModules.size());
950 if (!m_exportedModules.empty())
951 {
952 ol.startMemberHeader("exports");
953 ol.parseText(title);
954 ol.endMemberHeader();
955 ol.startMemberList();
956 for (const auto &[moduleName,importInfoList] : m_exportedModules)
957 {
958 for (const auto &importInfo : importInfoList)
959 {
960 ModuleDef *mod = ModuleManager::instance().getPrimaryInterface(importInfo.importName);
963 ol.docify(theTranslator->trModule(FALSE,TRUE)+" ");
965 if (mod && mod->isLinkable())
966 {
968 }
969 else
970 {
971 ol.startBold();
972 ol.docify(importInfo.importName);
973 ol.endBold();
974 }
976 if (mod && !mod->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
977 {
980 briefLine(),
981 mod,
982 nullptr,
983 mod->briefDescription(),
984 DocOptions()
985 .setSingleLine(true));
987 }
989 }
990 }
991 ol.endMemberList();
992 }
993}
994
996{
997 AUTO_TRACE("{} count={}",name(),m_contributing.size());
998 if (!m_contributing.empty())
999 {
1000 ol.startMemberHeader("files");
1001 ol.parseText(title);
1002 ol.endMemberHeader();
1003 ol.startMemberList();
1004 for (const auto &mod : m_contributing)
1005 {
1006 FileDef *fd = mod->getFileDef();
1007 if (fd)
1008 {
1010 QCString fname = fd->displayName();
1011 QCString anc = fd->anchor();
1012 if (anc.isEmpty()) anc=fname; else anc.prepend(fname+"_");
1014 ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
1015 ol.insertMemberAlign();
1016 QCString path=fd->getPath();
1017 if (Config_getBool(FULL_PATH_NAMES))
1018 {
1019 ol.docify(stripFromPath(path));
1020 }
1021 if (fd->isLinkable())
1022 {
1024 }
1025 else
1026 {
1027 ol.startBold();
1028 ol.docify(fd->displayName());
1029 ol.endBold();
1030 }
1032 if (!fd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
1033 {
1036 briefLine(),
1037 fd,
1038 nullptr,
1039 fd->briefDescription(),
1040 DocOptions()
1041 .setSingleLine(true));
1043 }
1045 }
1046 }
1047 ol.endMemberList();
1048 }
1049}
1050
1052{
1053 FileList result;
1054 for (const auto &mod : m_contributing)
1055 {
1056 FileDef *fd = mod->getFileDef();
1057 if (fd) result.push_back(fd);
1058 }
1059 return result;
1060}
1061
1063{
1064 int count=0;
1065 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
1066 {
1067 if (lde->kind()==LayoutDocEntry::MemberDecl)
1068 {
1069 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1070 if (lmd)
1071 {
1072 MemberList *ml = getMemberList(lmd->type);
1073 if (ml)
1074 {
1075 for (const auto &md : *ml)
1076 {
1077 if (md->visibleInIndex())
1078 {
1079 count++;
1080 }
1081 }
1082 }
1083 }
1084 }
1085 else if (lde->kind()==LayoutDocEntry::ModuleClasses)
1086 {
1087 for (const auto &cd : getClasses())
1088 {
1089 if (cd->isLinkableInProject())
1090 {
1091 count++;
1092 }
1093 }
1094 }
1095 else if (lde->kind()==LayoutDocEntry::ModuleConcepts)
1096 {
1097 for (const auto &cd : getConcepts())
1098 {
1099 if (cd->isLinkableInProject())
1100 {
1101 count++;
1102 }
1103 }
1104 }
1105 }
1106 return count;
1107}
1108
1110{
1111 if (!isPrimaryInterface() || !isLinkableInProject()) return;
1112 tagFile << " <compound kind=\"module\">\n";
1113 tagFile << " <name>" << convertToXML(name()) << "</name>\n";
1114 const FileDef *fd = getFileDef();
1115 QCString fn = fd ? fd->getOutputFileBase() : getOutputFileBase();
1117 tagFile << " <filename>" << convertToXML(fn) << "</filename>\n";
1118#if 0 // at the moment we do not export the members of a module to a tag file.
1119 // We let the project using a tag file directly link to the implementation of the
1120 // symbols (which have the same scope).
1121 //
1122 // When we support linking to a module's interface instead we need to
1123 // export the module's members as well. Then we probably need a way to
1124 // disambiguate/prioritize a link to a module over a link to the implementation,
1125 // for instance by hiding non-exported symbols from the tag file.
1126 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Group))
1127 {
1128 switch (lde->kind())
1129 {
1130 case LayoutDocEntry::ModuleExports:
1131 {
1132 for (const auto &[modName,importInfo] : m_exportedModules)
1133 {
1134 tagFile << " <export>" << convertToXML(importInfo.importName) << "</export>\n";
1135 }
1136 }
1137 break;
1138 case LayoutDocEntry::ModuleClasses:
1139 {
1140 for (const auto &cd : m_classes)
1141 {
1142 if (cd->isLinkableInProject())
1143 {
1144 tagFile << " <class kind=\"" << cd->compoundTypeString()
1145 << "\">" << convertToXML(cd->name()) << "</class>\n";
1146 }
1147 }
1148 }
1149 break;
1150 case LayoutDocEntry::ModuleConcepts:
1151 {
1152 for (const auto &cd : m_concepts)
1153 {
1154 if (cd->isLinkableInProject())
1155 {
1156 tagFile << " <concept>" << convertToXML(cd->name())
1157 << "</concept>\n";
1158 }
1159 }
1160 }
1161 break;
1162 case LayoutDocEntry::ModuleUsedFiles:
1163 {
1164 for (const auto &usedFd : getUsedFiles())
1165 {
1166 if (usedFd->isLinkableInProject())
1167 {
1168 tagFile << " <file>" << convertToXML(usedFd->name()) << "</file>\n";
1169 }
1170 }
1171 }
1172 break;
1173 case LayoutDocEntry::MemberDecl:
1174 {
1175 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1176 if (lmd && lmd->visible())
1177 {
1178 MemberList * ml = getMemberList(lmd->type);
1179 if (ml)
1180 {
1181 ml->writeTagFile(tagFile,true);
1182 }
1183 }
1184 }
1185 break;
1186 default:
1187 break;
1188 }
1189 }
1190#endif
1191 QCString idStr = id();
1192 if (!idStr.isEmpty())
1193 {
1194 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>\n";
1195 }
1196 writeDocAnchorsToTagFile(tagFile);
1197 tagFile << " </compound>\n";
1198}
1199
1200//------------------------------------------------------------------------------------------------------------
1201
1203{
1204 if (d==nullptr) return nullptr;
1205 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<ModuleDef*>(d) : nullptr;
1206}
1207
1209{
1210 if (d==nullptr) return nullptr;
1211 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<const ModuleDef*>(d) : nullptr;
1212}
1213
1215{ return static_cast<ModuleDefImpl*>(m); }
1216
1217//static inline const ModuleDefImpl *toModuleDefImpl(const ModuleDef *m)
1218//{ return static_cast<const ModuleDefImpl*>(m); }
1219
1220static inline ModuleDefImpl *toModuleDefImpl(const std::unique_ptr<ModuleDef> &m)
1221{ return static_cast<ModuleDefImpl*>(m.get()); }
1222
1223//------------------------------------------------------------------------------------
1224
1226{
1227 bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
1228 for (const auto &mod : *this)
1229 {
1230 bool isLink = mod->isLinkable();
1231 if (isLink || !hideUndocClasses)
1232 {
1233 return true;
1234 }
1235 }
1236 return false;
1237}
1238
1239void ModuleLinkedRefMap::writeDeclaration(OutputList &ol,const QCString &header,bool localNames) const
1240{
1241 bool found=FALSE;
1242 for (const auto &mod : *this)
1243 {
1244 toModuleDefImpl(mod)->writeDeclarationLink(ol,found,header,localNames);
1245 }
1246 if (found) ol.endMemberList();
1247}
1248
1249//------------------------------------------------------------------------------------------------------------
1250
1252{
1253 ModuleLinkedMap moduleFileMap; // file->module mapping
1254 std::unordered_map<std::string,ModuleList> moduleNameMap; // name->module mapping
1257 std::mutex mutex;
1258};
1259
1261{
1262 static ModuleManager m;
1263 return m;
1264}
1265
1267{
1268}
1269
1270void ModuleManager::createModuleDef(const QCString &fileName,int line,int column,bool exported,
1271 const QCString &moduleName,const QCString &partitionName)
1272{
1273 AUTO_TRACE("{}:{}: Found module name='{}' partition='{}' exported='{}'",
1274 fileName,line,moduleName,partitionName,exported);
1275 std::lock_guard lock(p->mutex);
1277 std::unique_ptr<ModuleDef> modDef = std::make_unique<ModuleDefImpl>(fileName,line,column,moduleName,mt,partitionName);
1278 auto mod = p->moduleFileMap.add(fileName,std::move(modDef));
1279 auto it = p->moduleNameMap.find(moduleName.str());
1280 if (it == p->moduleNameMap.end())
1281 {
1282 ModuleList ml;
1283 ml.push_back(mod);
1284 p->moduleNameMap.emplace(moduleName.str(),ml);
1285 }
1286 else
1287 {
1288 it->second.push_back(mod);
1289 }
1290}
1291
1293{
1294 std::lock_guard lock(p->mutex);
1295 p->headers.clear();
1296 p->externalImports.clear();
1297 p->moduleNameMap.clear();
1298 p->moduleFileMap.clear();
1299}
1300
1301void ModuleManager::addHeader(const QCString &moduleFile,int line,const QCString &headerName,bool isSystem)
1302{
1303 AUTO_TRACE("{}:{} headerName={} isSystem={}",moduleFile,line,headerName,isSystem);
1304 std::lock_guard lock(p->mutex);
1305 auto mod = p->moduleFileMap.find(moduleFile);
1306 if (mod)
1307 {
1308 toModuleDefImpl(mod)->addHeader(line,headerName,isSystem);
1309 }
1310 else
1311 {
1312 AUTO_TRACE_ADD("imported header '{}' found in file '{}' that is not a module",headerName,moduleFile);
1313 }
1314 p->headers.emplace_back(moduleFile,headerName,isSystem);
1315}
1316
1317void ModuleManager::addImport(const QCString &moduleFile,int line,const QCString &importName,
1318 bool isExported,const QCString &partitionName)
1319{
1320 AUTO_TRACE("{}:{} importName={},isExported={},partitionName={}",
1321 moduleFile,line,importName,isExported,partitionName);
1322 std::lock_guard lock(p->mutex);
1323 auto mod = p->moduleFileMap.find(moduleFile);
1324 if (mod) // import inside a module
1325 {
1326 AUTO_TRACE_ADD("in module");
1327 toModuleDefImpl(mod)->addImport(line,importName.isEmpty()?mod->name():importName,partitionName,isExported);
1328 }
1329 else // import outside of a module
1330 {
1331 AUTO_TRACE_ADD("outside module");
1332 p->externalImports[moduleFile.str()].emplace_back(nullptr,importName,line,partitionName);
1333 }
1334}
1335
1337{
1338 std::lock_guard lock(p->mutex);
1339 auto mod = p->moduleFileMap.find(root->fileName);
1340 if (mod)
1341 {
1342 toModuleDefImpl(mod)->addClassToModule(root,cd);
1343 auto cdm = toClassDefMutable(cd);
1344 if (cdm) cdm->setModuleDef(mod);
1345 }
1346}
1347
1349{
1350 std::lock_guard lock(p->mutex);
1351 auto mod = p->moduleFileMap.find(root->fileName);
1352 if (mod)
1353 {
1354 toModuleDefImpl(mod)->addConceptToModule(root,cd);
1355 auto cdm = toConceptDefMutable(cd);
1356 if (cdm) cdm->setModuleDef(mod);
1357 }
1358}
1359
1361{
1362 std::lock_guard lock(p->mutex);
1363 auto mod = p->moduleFileMap.find(root->fileName);
1364 if (mod && root->exported && md->getClassDef()==nullptr)
1365 {
1366 toModuleDefImpl(mod)->addMemberToModule(root,md);
1367 auto mdm = toMemberDefMutable(md);
1368 if (mdm) mdm->setModuleDef(mod);
1369 }
1370}
1371
1372void ModuleManager::addTagInfo(const QCString &fileName,const QCString &tagFile,const QCString &clangId)
1373{
1374 std::lock_guard lock(p->mutex);
1375 auto mod = p->moduleFileMap.find(fileName);
1376 if (mod)
1377 {
1378 ModuleDefImpl *modi = toModuleDefImpl(mod);
1379 modi->setReference(tagFile);
1380 modi->setId(clangId);
1381 }
1382}
1383
1385{
1386 AUTO_TRACE();
1387 for (auto &[partitionFileName,importInfoList] : mod->getImports()) // foreach import
1388 {
1389 for (auto &importInfo : importInfoList)
1390 {
1391 AUTO_TRACE_ADD("partitionFileName={} importName={} partitionName={}",
1392 partitionFileName,importInfo.importName,importInfo.partitionName);
1393 if (importInfo.importName==intfMod->name() && !importInfo.partitionName.isEmpty() &&
1394 importInfo.exported) // that is an exported partition of this module
1395 {
1396 auto it = p->moduleNameMap.find(importInfo.importName.str());
1397 if (it != p->moduleNameMap.end())
1398 {
1399 for (auto importedMod : it->second)
1400 {
1401 if (importedMod->qualifiedName()==importInfo.importName+":"+importInfo.partitionName)
1402 {
1403 AUTO_TRACE_ADD("Interface module {} exports partition {}:{}",
1404 mod->name(),importedMod->name(),importedMod->partitionName());
1405 toModuleDefImpl(intfMod)->addPartition(toModuleDefImpl(importedMod));
1406 toModuleDefImpl(importedMod)->setPrimaryInterface(intfMod);
1407 for (const auto &[partitionFileName_,partitionImportInfoList] : importedMod->getImports())
1408 {
1409 for (const auto &partitionImportInfo : partitionImportInfoList)
1410 {
1411 if (partitionImportInfo.exported && intfMod->name()!=partitionImportInfo.importName)
1412 {
1413 toModuleDefImpl(intfMod)->addExportedModule(partitionImportInfo.importName,partitionImportInfo);
1414 }
1415 }
1416 }
1417 resolvePartitionsRecursively(intfMod,importedMod);
1418 }
1419 }
1420 }
1421 }
1422 }
1423 }
1424}
1425
1427{
1428 AUTO_TRACE();
1429 for (auto &mod : p->moduleFileMap) // foreach module
1430 {
1431 if (mod->moduleType()==ModuleDef::Type::Interface && mod->partitionName().isEmpty())
1432 { // that is a primary interface
1433 resolvePartitionsRecursively(mod.get(),mod.get());
1434 }
1435
1436 // copy exported imports to m_exportedModules
1437 for (const auto &[fileName,importInfoList] : mod->getImports())
1438 {
1439 for (const auto &importInfo : importInfoList)
1440 {
1441 if (importInfo.exported && mod->name()!=importInfo.importName)
1442 {
1443 toModuleDefImpl(mod)->addExportedModule(importInfo.importName,importInfo);
1444 }
1445 }
1446 }
1447
1448 // also link the ModuleDef and FileDef together
1449 bool ambig = false;
1450 FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,mod->getDefFileName(),ambig);
1451 if (fd)
1452 {
1453 fd->setModuleDef(mod.get());
1454 toModuleDefImpl(mod)->setFileDef(fd);
1455 }
1456 }
1457}
1458
1460{
1461 AUTO_TRACE();
1462 for (auto &mod : p->moduleFileMap)
1463 {
1464 FileDef *fd = mod->getFileDef();
1465 if (fd)
1466 {
1467 for (const auto &[fileName,importInfoList] : mod->getImports())
1468 {
1469 for (const auto &importInfo : importInfoList)
1470 {
1471 ModuleDef *importedModule = getPrimaryInterface(importInfo.importName);
1472 const FileDef *importedFd = importedModule ? importedModule->getFileDef() : nullptr;
1473 AUTO_TRACE_ADD("module: addIncludeDependency {}->{}:{} fd={}",
1474 mod->qualifiedName(), importInfo.qualifiedName(), importInfo.line, fd?fd->absFilePath():"");
1476 }
1477 }
1478 }
1479 }
1480 for (const auto &[fileName,importInfoList] : p->externalImports)
1481 {
1482 for (const auto &importInfo : importInfoList)
1483 {
1484 bool ambig = false;
1485 FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,fileName,ambig);
1486 AUTO_TRACE_ADD("externalImport name={} fd={}",fileName,(void*)fd);
1487 if (fd)
1488 {
1489 ModuleDef *mod = getPrimaryInterface(importInfo.importName);
1490 FileDef *importedFd = mod ? mod->getFileDef() : nullptr;
1491 fd->addIncludeDependency(importedFd,importInfo.importName,IncludeKind::ImportModule);
1492 if (importedFd)
1493 {
1495 }
1496 }
1497 }
1498 }
1499 for (const auto &headerInfo : p->headers)
1500 {
1501 bool ambig = false;
1502 FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,headerInfo.fileName,ambig);
1503 AUTO_TRACE_ADD("header name={} fd={}",headerInfo.fileName,(void*)fd);
1504 if (fd)
1505 {
1506 QCString resolvedHeader = determineAbsoluteIncludeName(headerInfo.fileName,headerInfo.headerName);
1507 FileDef *importFd = findFileDef(Doxygen::inputNameLinkedMap,resolvedHeader,ambig);
1508 fd->addIncludeDependency(importFd, headerInfo.headerName,
1509 headerInfo.isSystem ? IncludeKind::ImportSystem : IncludeKind::ImportLocal);
1510 if (importFd)
1511 {
1513 }
1514 }
1515 }
1516}
1517
1519{
1520 AUTO_TRACE("{}: collecting symbols for partition {}",intfMod->qualifiedName(),partitionMod->qualifiedName());
1521 auto intfModImpl = toModuleDefImpl(intfMod);
1522 auto partitionModImpl = toModuleDefImpl(partitionMod);
1523 intfModImpl->mergeSymbolsFrom(partitionModImpl);
1524}
1525
1527{
1528 AUTO_TRACE();
1529 for (auto &mod : p->moduleFileMap) // foreach module
1530 {
1531 if (mod->isPrimaryInterface()) // that is a primary interface
1532 {
1533 for (auto &[partitionName,partitionMod] : mod->partitions())
1534 {
1535 collectExportedSymbolsRecursively(mod.get(),partitionMod);
1536 }
1537
1538 // collect all files that contribute to this module (e.g. implementation/partition modules)
1539 auto it = p->moduleNameMap.find(mod->name().str());
1540 if (it != p->moduleNameMap.end())
1541 {
1542 for (auto contributingMod : it->second)
1543 {
1544 AUTO_TRACE_ADD(" adding contributing module {} to interface module {} type={} partition={} isPrimaryIntf={}",
1545 contributingMod->qualifiedName(),
1546 mod->name(),
1547 contributingMod->moduleType()==ModuleDef::Type::Interface ? "Interface" : "Implementation",
1548 contributingMod->partitionName(),
1549 contributingMod->isPrimaryInterface());
1551 }
1552 }
1553 }
1554 }
1555}
1556
1558{
1559 for (auto &mod : p->moduleFileMap) // foreach module
1560 {
1562 }
1563}
1564
1566{
1567 for (auto &mod : p->moduleFileMap) // foreach module
1568 {
1569 if (mod->isPrimaryInterface())
1570 {
1571 mod->writeDocumentation(ol);
1572 }
1573 }
1574}
1575
1577{
1578 int count=0;
1579 for (const auto &mod : p->moduleFileMap) // foreach module
1580 {
1581 if (mod->isPrimaryInterface()) count++;
1582 }
1583 return count;
1584}
1585
1587{
1588 return p->moduleFileMap;
1589}
1590
1592{
1593 return p->moduleFileMap;
1594}
1595
1597{
1598 AUTO_TRACE("file={} module={}",root->fileName,root->name);
1599 if (root->doc.isEmpty() && root->brief.isEmpty()) return;
1600 if (root->name.find(':')!=-1)
1601 {
1602 warn(root->fileName,root->startLine,"Ignoring documentation for module partition {}. Please place documentation at the primary module name",
1603 root->name);
1604 }
1605 else
1606 {
1607 auto it = p->moduleNameMap.find(root->name.str());
1608 if (it != p->moduleNameMap.end())
1609 {
1610 ModuleDef *mod = getPrimaryInterface(root->name);
1611 if (mod)
1612 {
1613 mod->setDocumentation(root->doc,root->docFile,root->docLine);
1614 mod->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1615 mod->setId(root->id);
1616 mod->setHidden(root->hidden);
1617 mod->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1618 mod->setRefItems(root->sli);
1619 mod->setRequirementReferences(root->rqli);
1620 //mod->addSectionsToDefinition(root->anchors);
1621 addModuleToGroups(root,mod);
1622 }
1623 else
1624 {
1625 warn(root->fileName,root->startLine,"Found documentation for module {} but it has no primary interface unit.",root->name);
1626 }
1627 }
1628 else
1629 {
1630 warn(root->fileName,root->startLine,"Found documentation for unknown module {}.",root->name);
1631 }
1632 }
1633}
1634
1636{
1637 auto it = p->moduleNameMap.find(moduleName.str());
1638 if (it != p->moduleNameMap.end())
1639 {
1640 for (const auto &mod : it->second)
1641 {
1642 if (mod->isPrimaryInterface())
1643 {
1644 return mod;
1645 }
1646 }
1647 }
1648 return nullptr;
1649}
1650
1652{
1653 for (const auto &mod : p->moduleFileMap) // foreach module
1654 {
1655 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addListReferences();
1656 }
1657}
1658
1660{
1661 for (const auto &mod : p->moduleFileMap) // foreach module
1662 {
1663 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addRequirementReferences();
1664 }
1665}
1666
1668{
1669 for (const auto &mod : p->moduleFileMap) // foreach module
1670 {
1671 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addMembersToMemberGroup();
1672 }
1673}
1674
1676{
1677 for (const auto &mod : p->moduleFileMap) // foreach module
1678 {
1679 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->distributeMemberGroupDocumentation();
1680 }
1681}
1682
1684{
1685 for (auto &mod : p->moduleFileMap) // foreach module
1686 {
1687 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->findSectionsInDocumentation();
1688 }
1689}
1690
1692{
1693 for (auto &mod : p->moduleFileMap) // foreach module
1694 {
1695 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->sortMemberLists();
1696 }
1697}
1698
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:77
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 setRequirementReferences(const RequirementRefs &rqli)=0
virtual void setRefItems(const RefItemVector &sli)=0
static bool suppressDocWarnings
Definition doxygen.h:131
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:104
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:117
RequirementRefs rqli
references to requirements
Definition entry.h:228
int docLine
line number at which the documentation was found
Definition entry.h:202
int endBodyLine
line number where the definition ends
Definition entry.h:219
bool exported
is the symbol exported from a C++20 module
Definition entry.h:190
QCString id
libclang id
Definition entry.h:233
QCString fileName
file this entry was extracted from
Definition entry.h:224
int startLine
start line of entry in the source
Definition entry.h:225
QCString name
member name
Definition entry.h:175
QCString briefFile
file in which the brief desc. was found
Definition entry.h:206
int bodyLine
line number of the body in the source
Definition entry.h:217
QCString doc
documentation block (partly parsed)
Definition entry.h:201
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:227
QCString docFile
file in which the documentation was found
Definition entry.h:203
bool hidden
does this represent an entity that is hidden from the output
Definition entry.h:230
QCString brief
brief description (doc block)
Definition entry.h:204
int briefLine
line number at which the brief desc. was found
Definition entry.h:205
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:1437
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
virtual const ClassDef * getClassDef() const =0
virtual MemberType memberType() const =0
virtual void setSectionList(const Definition *container, const MemberList *sl)=0
A list of MemberDef objects as shown in documentation sections.
Definition memberlist.h:125
void 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:130
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 noexcept
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 addRequirementReferences()
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:148
void addRequirementReferences()
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:315
void writeDoc(const IDocNodeAST *ast, const Definition *ctx, const MemberDef *md, int sectionLevel=-1)
Definition outputlist.h:383
void endTextBlock(bool paraBreak=FALSE)
Definition outputlist.h:672
void writeString(const QCString &text)
Definition outputlist.h:411
void startMemberDeclaration()
Definition outputlist.h:569
void endTitleHead(const QCString &fileName, const QCString &name)
Definition outputlist.h:405
void disable(OutputType o)
void startTitleHead(const QCString &fileName)
Definition outputlist.h:403
void writeRuler()
Definition outputlist.h:521
void startGroupHeader(const QCString &id=QCString(), int extraLevels=0)
Definition outputlist.h:453
void enable(OutputType o)
void endContents()
Definition outputlist.h:620
void endHeaderSection()
Definition outputlist.h:467
void endMemberDescription()
Definition outputlist.h:567
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:439
void startMemberDescription(const QCString &anchor, const QCString &inheritId=QCString(), bool typ=false)
Definition outputlist.h:565
void startHeaderSection()
Definition outputlist.h:465
void docify(const QCString &s)
Definition outputlist.h:437
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, const DocOptions &options)
void startParagraph(const QCString &classDef=QCString())
Definition outputlist.h:407
void startTextBlock(bool dense=FALSE)
Definition outputlist.h:670
void endParagraph()
Definition outputlist.h:409
void startMemberSections()
Definition outputlist.h:461
void startMemberList()
Definition outputlist.h:481
void endTextLink()
Definition outputlist.h:444
void startBold()
Definition outputlist.h:561
void endMemberItem(OutputGenerator::MemberItemType type)
Definition outputlist.h:495
void endMemberList()
Definition outputlist.h:483
void writeSynopsis()
Definition outputlist.h:592
void pushGeneratorState()
void insertMemberAlign(bool templ=FALSE)
Definition outputlist.h:517
void disableAllBut(OutputType o)
void popGeneratorState()
void writeSummaryLink(const QCString &file, const QCString &anchor, const QCString &title, bool first)
Definition outputlist.h:614
void writeAnchor(const QCString &fileName, const QCString &name)
Definition outputlist.h:523
void endBold()
Definition outputlist.h:563
void endGroupHeader(int extraLevels=0)
Definition outputlist.h:455
void writePageOutline()
Definition outputlist.h:616
void startContents()
Definition outputlist.h:618
void endMemberDeclaration(const QCString &anchor, const QCString &inheritId)
Definition outputlist.h:571
void enableAll()
void endMemberHeader()
Definition outputlist.h:471
void startMemberItem(const QCString &anchor, OutputGenerator::MemberItemType type, const QCString &id=QCString())
Definition outputlist.h:493
void parseText(const QCString &textStr)
void startTextLink(const QCString &file, const QCString &anchor)
Definition outputlist.h:442
void startMemberHeader(const QCString &anchor, int typ=2)
Definition outputlist.h:469
void endMemberSections()
Definition outputlist.h:463
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:422
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
const std::string & str() const
Definition qcstring.h:552
static RequirementManager & instance()
void addRequirementRefsForSymbol(const Definition *symbol)
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:48
#define AUTO_TRACE(...)
Definition docnode.cpp:47
void docFindSections(const QCString &input, const Definition *d, const QCString &fileName)
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, const DocOptions &options)
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:55
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, bool isSource, 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:687
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
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:1788
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:1800
Definition layout.h:102
QCString 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
@ 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:4805
void addGroupListToTitle(OutputList &ol, const Definition *d)
Definition util.cpp:4892
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:299
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3485
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:3893
QCString determineAbsoluteIncludeName(const QCString &curFile, const QCString &incFileName)
Definition util.cpp:3581
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2871
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4902
A bunch of utility functions.