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 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{
689 const RefItemVector &xrefItems = xrefListItems();
690 addRefItem(xrefItems,
692 getLanguage()==SrcLangExt::Fortran ?
693 theTranslator->trModule(TRUE,TRUE) :
694 theTranslator->trNamespace(TRUE,TRUE),
696 QCString(),
697 this
698 );
699 for (const auto &mg : m_memberGroups)
700 {
701 mg->addListReferences(this);
702 }
703 for (auto &ml : m_memberLists)
704 {
705 if (ml->listType().isDocumentation())
706 {
707 ml->addListReferences(this);
708 }
709 }
710}
711
713{
714 for (auto &ml : m_memberLists)
715 {
716 if (ml->listType().isDeclaration())
717 {
719 }
720 }
721
722 // add members inside sections to their groups
723 for (const auto &mg : m_memberGroups)
724 {
725 if (mg->allMembersInSameSection() && Config_getBool(SUBGROUPING))
726 {
727 //printf("----> addToDeclarationSection(%s)\n",qPrint(mg->header()));
728 mg->addToDeclarationSection();
729 }
730 }
731}
732
734{
735 for (const auto &mg : m_memberGroups)
736 {
737 mg->distributeMemberGroupDocumentation();
738 }
739}
740
742{
746 for (const auto &mg : m_memberGroups)
747 {
748 mg->findSectionsInDocumentation(this);
749 }
750 for (auto &ml : m_memberLists)
751 {
752 if (ml->listType().isDeclaration())
753 {
754 ml->findSectionsInDocumentation(this);
755 }
756 }
757}
758
760{
761 for (auto &ml : m_memberLists)
762 {
763 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
764 }
765
766 if (Config_getBool(SORT_BRIEF_DOCS))
767 {
768 auto classComp = [](const ClassLinkedRefMap::Ptr &c1,const ClassLinkedRefMap::Ptr &c2)
769 {
770 return Config_getBool(SORT_BY_SCOPE_NAME) ?
771 qstricmp_sort(c1->name(), c2->name())<0 :
772 qstricmp_sort(c1->className(), c2->className())<0;
773 };
774 std::stable_sort(m_classes.begin(), m_classes.end(), classComp);
775
776 auto conceptComp = [](const ConceptLinkedRefMap::Ptr &c1,const ConceptLinkedRefMap::Ptr &c2)
777 {
778 return Config_getBool(SORT_BY_SCOPE_NAME) ?
779 qstricmp_sort(c1->qualifiedName(), c2->qualifiedName())<0 :
780 qstricmp_sort(c1->name(), c2->name())<0;
781 };
782 std::stable_sort(m_concepts.begin(), m_concepts.end(), conceptComp);
783 }
784
785 static auto contrComp = [](const ModuleDef *m1, const ModuleDef *m2)
786 {
787 FileDef *f1 = m1->getFileDef();
788 FileDef *f2 = m2->getFileDef();
789 QCString fn1 = f1 ? f1->name() : m1->name();
790 QCString fn2 = f2 ? f2->name() : m2->name();
791 static auto typeRank = [](const ModuleDef *m) -> int
792 {
793 if (m->moduleType()==ModuleDef::Type::Interface)
794 {
795 if (m->partitionName().isEmpty()) return 0; // primary interface unit
796 return 1; // partition interface unit
797 }
798 else
799 {
800 if (!m->partitionName().isEmpty()) return 2; // partition implementation unit
801 return 3; // implementation unit
802 }
803 };
804 auto tr1 = typeRank(m1);
805 auto tr2 = typeRank(m2);
806 int diff = qstricmp_sort(fn1,fn2);
807 return tr1<tr2 || (tr1==tr2 && diff<0);
808 };
809
810 std::stable_sort(m_contributing.begin(), m_contributing.end(), contrComp);
811}
812
814{
817 bool first=TRUE;
818 SrcLangExt lang=getLanguage();
819 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
820 {
821 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
822 if (lde->kind()==LayoutDocEntry::ModuleClasses && m_classes.declVisible() && ls)
823 {
824 QCString label = "classes";
825 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
826 first=FALSE;
827 }
828 else if (lde->kind()==LayoutDocEntry::ModuleConcepts && m_concepts.declVisible() && ls)
829 {
830 QCString label = "concepts";
831 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
832 first=FALSE;
833 }
834 else if (lde->kind()==LayoutDocEntry::ModuleUsedFiles && ls)
835 {
836 QCString label = "files";
837 ol.writeSummaryLink(QCString(),label,ls->title(lang),first);
838 first=FALSE;
839 }
840 else if (lde->kind()==LayoutDocEntry::MemberDecl)
841 {
842 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
843 if (lmd)
844 {
845 MemberList * ml = getMemberList(lmd->type);
846 if (ml && ml->declVisible())
847 {
848 ol.writeSummaryLink(QCString(),ml->listType().toLabel(),lmd->title(lang),first);
849 first=FALSE;
850 }
851 }
852 }
853 }
854 if (!first)
855 {
856 ol.writeString(" </div>\n");
857 }
859}
860
865
866void ModuleDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const QCString &header,bool localNames) const
867{
868 if (isLinkable())
869 {
870 if (!found) // first module
871 {
872 ol.startMemberHeader("modules");
873 if (!header.isEmpty())
874 {
875 ol.parseText(header);
876 }
877 else
878 {
879 theTranslator->trModule(true,false);
880 }
881 ol.endMemberHeader();
882 ol.startMemberList();
883 found=TRUE;
884 }
886 QCString cname = displayName(!localNames);
887 QCString anc = anchor();
888 if (anc.isEmpty()) anc=cname; else anc.prepend(cname+"_");
890 ol.writeString("module ");
892 if (isLinkable())
893 {
896 anchor(),
897 cname
898 );
899 }
900 else
901 {
902 ol.startBold();
903 ol.docify(cname);
904 ol.endBold();
905 }
907 // add the brief description if available
908 if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
909 {
910 auto parser { createDocParser() };
911 auto ast { validatingParseDoc(*parser.get(),
912 briefFile(),
913 briefLine(),
914 this,
915 nullptr,
917 DocOptions()
918 .setSingleLine(true))
919 };
920 if (!ast->isEmpty())
921 {
923 ol.writeDoc(ast.get(),this,nullptr);
925 }
926 }
928 }
929}
930
931
933{
934 AUTO_TRACE("name={} count={}",name(),m_exportedModules.size());
935 if (!m_exportedModules.empty())
936 {
937 ol.startMemberHeader("exports");
938 ol.parseText(title);
939 ol.endMemberHeader();
940 ol.startMemberList();
941 for (const auto &[moduleName,importInfoList] : m_exportedModules)
942 {
943 for (const auto &importInfo : importInfoList)
944 {
945 ModuleDef *mod = ModuleManager::instance().getPrimaryInterface(importInfo.importName);
948 ol.docify(theTranslator->trModule(FALSE,TRUE)+" ");
950 if (mod && mod->isLinkable())
951 {
953 }
954 else
955 {
956 ol.startBold();
957 ol.docify(importInfo.importName);
958 ol.endBold();
959 }
961 if (mod && !mod->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
962 {
965 briefLine(),
966 mod,
967 nullptr,
968 mod->briefDescription(),
969 DocOptions()
970 .setSingleLine(true));
972 }
974 }
975 }
976 ol.endMemberList();
977 }
978}
979
981{
982 AUTO_TRACE("{} count={}",name(),m_contributing.size());
983 if (!m_contributing.empty())
984 {
985 ol.startMemberHeader("files");
986 ol.parseText(title);
987 ol.endMemberHeader();
988 ol.startMemberList();
989 for (const auto &mod : m_contributing)
990 {
991 FileDef *fd = mod->getFileDef();
992 if (fd)
993 {
995 QCString fname = fd->displayName();
996 QCString anc = fd->anchor();
997 if (anc.isEmpty()) anc=fname; else anc.prepend(fname+"_");
999 ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
1000 ol.insertMemberAlign();
1001 QCString path=fd->getPath();
1002 if (Config_getBool(FULL_PATH_NAMES))
1003 {
1004 ol.docify(stripFromPath(path));
1005 }
1006 if (fd->isLinkable())
1007 {
1009 }
1010 else
1011 {
1012 ol.startBold();
1013 ol.docify(fd->displayName());
1014 ol.endBold();
1015 }
1017 if (!fd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
1018 {
1021 briefLine(),
1022 fd,
1023 nullptr,
1024 fd->briefDescription(),
1025 DocOptions()
1026 .setSingleLine(true));
1028 }
1030 }
1031 }
1032 ol.endMemberList();
1033 }
1034}
1035
1037{
1038 FileList result;
1039 for (const auto &mod : m_contributing)
1040 {
1041 FileDef *fd = mod->getFileDef();
1042 if (fd) result.push_back(fd);
1043 }
1044 return result;
1045}
1046
1048{
1049 int count=0;
1050 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Module))
1051 {
1052 if (lde->kind()==LayoutDocEntry::MemberDecl)
1053 {
1054 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1055 if (lmd)
1056 {
1057 MemberList *ml = getMemberList(lmd->type);
1058 if (ml)
1059 {
1060 for (const auto &md : *ml)
1061 {
1062 if (md->visibleInIndex())
1063 {
1064 count++;
1065 }
1066 }
1067 }
1068 }
1069 }
1070 else if (lde->kind()==LayoutDocEntry::ModuleClasses)
1071 {
1072 for (const auto &cd : getClasses())
1073 {
1074 if (cd->isLinkableInProject())
1075 {
1076 count++;
1077 }
1078 }
1079 }
1080 else if (lde->kind()==LayoutDocEntry::ModuleConcepts)
1081 {
1082 for (const auto &cd : getConcepts())
1083 {
1084 if (cd->isLinkableInProject())
1085 {
1086 count++;
1087 }
1088 }
1089 }
1090 }
1091 return count;
1092}
1093
1095{
1096 if (!isPrimaryInterface() || !isLinkableInProject()) return;
1097 tagFile << " <compound kind=\"module\">\n";
1098 tagFile << " <name>" << convertToXML(name()) << "</name>\n";
1099 const FileDef *fd = getFileDef();
1100 QCString fn = fd ? fd->getOutputFileBase() : getOutputFileBase();
1102 tagFile << " <filename>" << convertToXML(fn) << "</filename>\n";
1103#if 0 // at the moment we do not export the members of a module to a tag file.
1104 // We let the project using a tag file directly link to the implementation of the
1105 // symbols (which have the same scope).
1106 //
1107 // When we support linking to a module's interface instead we need to
1108 // export the module's members as well. Then we probably need a way to
1109 // disambiguate/prioritize a link to a module over a link to the implementation,
1110 // for instance by hiding non-exported symbols from the tag file.
1111 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Group))
1112 {
1113 switch (lde->kind())
1114 {
1115 case LayoutDocEntry::ModuleExports:
1116 {
1117 for (const auto &[modName,importInfo] : m_exportedModules)
1118 {
1119 tagFile << " <export>" << convertToXML(importInfo.importName) << "</export>\n";
1120 }
1121 }
1122 break;
1123 case LayoutDocEntry::ModuleClasses:
1124 {
1125 for (const auto &cd : m_classes)
1126 {
1127 if (cd->isLinkableInProject())
1128 {
1129 tagFile << " <class kind=\"" << cd->compoundTypeString()
1130 << "\">" << convertToXML(cd->name()) << "</class>\n";
1131 }
1132 }
1133 }
1134 break;
1135 case LayoutDocEntry::ModuleConcepts:
1136 {
1137 for (const auto &cd : m_concepts)
1138 {
1139 if (cd->isLinkableInProject())
1140 {
1141 tagFile << " <concept>" << convertToXML(cd->name())
1142 << "</concept>\n";
1143 }
1144 }
1145 }
1146 break;
1147 case LayoutDocEntry::ModuleUsedFiles:
1148 {
1149 for (const auto &usedFd : getUsedFiles())
1150 {
1151 if (usedFd->isLinkableInProject())
1152 {
1153 tagFile << " <file>" << convertToXML(usedFd->name()) << "</file>\n";
1154 }
1155 }
1156 }
1157 break;
1158 case LayoutDocEntry::MemberDecl:
1159 {
1160 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
1161 if (lmd && lmd->visible())
1162 {
1163 MemberList * ml = getMemberList(lmd->type);
1164 if (ml)
1165 {
1166 ml->writeTagFile(tagFile,true);
1167 }
1168 }
1169 }
1170 break;
1171 default:
1172 break;
1173 }
1174 }
1175#endif
1176 QCString idStr = id();
1177 if (!idStr.isEmpty())
1178 {
1179 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>\n";
1180 }
1181 writeDocAnchorsToTagFile(tagFile);
1182 tagFile << " </compound>\n";
1183}
1184
1185//------------------------------------------------------------------------------------------------------------
1186
1188{
1189 if (d==nullptr) return nullptr;
1190 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<ModuleDef*>(d) : nullptr;
1191}
1192
1194{
1195 if (d==nullptr) return nullptr;
1196 return (typeid(*d)==typeid(ModuleDefImpl)) ? static_cast<const ModuleDef*>(d) : nullptr;
1197}
1198
1200{ return static_cast<ModuleDefImpl*>(m); }
1201
1202//static inline const ModuleDefImpl *toModuleDefImpl(const ModuleDef *m)
1203//{ return static_cast<const ModuleDefImpl*>(m); }
1204
1205static inline ModuleDefImpl *toModuleDefImpl(const std::unique_ptr<ModuleDef> &m)
1206{ return static_cast<ModuleDefImpl*>(m.get()); }
1207
1208//------------------------------------------------------------------------------------
1209
1211{
1212 bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
1213 for (const auto &mod : *this)
1214 {
1215 bool isLink = mod->isLinkable();
1216 if (isLink || !hideUndocClasses)
1217 {
1218 return true;
1219 }
1220 }
1221 return false;
1222}
1223
1224void ModuleLinkedRefMap::writeDeclaration(OutputList &ol,const QCString &header,bool localNames) const
1225{
1226 bool found=FALSE;
1227 for (const auto &mod : *this)
1228 {
1229 toModuleDefImpl(mod)->writeDeclarationLink(ol,found,header,localNames);
1230 }
1231 if (found) ol.endMemberList();
1232}
1233
1234//------------------------------------------------------------------------------------------------------------
1235
1237{
1238 ModuleLinkedMap moduleFileMap; // file->module mapping
1239 std::unordered_map<std::string,ModuleList> moduleNameMap; // name->module mapping
1242 std::mutex mutex;
1243};
1244
1246{
1247 static ModuleManager m;
1248 return m;
1249}
1250
1252{
1253}
1254
1255void ModuleManager::createModuleDef(const QCString &fileName,int line,int column,bool exported,
1256 const QCString &moduleName,const QCString &partitionName)
1257{
1258 AUTO_TRACE("{}:{}: Found module name='{}' partition='{}' exported='{}'",
1259 fileName,line,moduleName,partitionName,exported);
1260 std::lock_guard lock(p->mutex);
1262 std::unique_ptr<ModuleDef> modDef = std::make_unique<ModuleDefImpl>(fileName,line,column,moduleName,mt,partitionName);
1263 auto mod = p->moduleFileMap.add(fileName,std::move(modDef));
1264 auto it = p->moduleNameMap.find(moduleName.str());
1265 if (it == p->moduleNameMap.end())
1266 {
1267 ModuleList ml;
1268 ml.push_back(mod);
1269 p->moduleNameMap.emplace(moduleName.str(),ml);
1270 }
1271 else
1272 {
1273 it->second.push_back(mod);
1274 }
1275}
1276
1278{
1279 std::lock_guard lock(p->mutex);
1280 p->headers.clear();
1281 p->externalImports.clear();
1282 p->moduleNameMap.clear();
1283 p->moduleFileMap.clear();
1284}
1285
1286void ModuleManager::addHeader(const QCString &moduleFile,int line,const QCString &headerName,bool isSystem)
1287{
1288 AUTO_TRACE("{}:{} headerName={} isSystem={}",moduleFile,line,headerName,isSystem);
1289 std::lock_guard lock(p->mutex);
1290 auto mod = p->moduleFileMap.find(moduleFile);
1291 if (mod)
1292 {
1293 toModuleDefImpl(mod)->addHeader(line,headerName,isSystem);
1294 }
1295 else
1296 {
1297 AUTO_TRACE_ADD("imported header '{}' found in file '{}' that is not a module",headerName,moduleFile);
1298 }
1299 p->headers.emplace_back(moduleFile,headerName,isSystem);
1300}
1301
1302void ModuleManager::addImport(const QCString &moduleFile,int line,const QCString &importName,
1303 bool isExported,const QCString &partitionName)
1304{
1305 AUTO_TRACE("{}:{} importName={},isExported={},partitionName={}",
1306 moduleFile,line,importName,isExported,partitionName);
1307 std::lock_guard lock(p->mutex);
1308 auto mod = p->moduleFileMap.find(moduleFile);
1309 if (mod) // import inside a module
1310 {
1311 AUTO_TRACE_ADD("in module");
1312 toModuleDefImpl(mod)->addImport(line,importName.isEmpty()?mod->name():importName,partitionName,isExported);
1313 }
1314 else // import outside of a module
1315 {
1316 AUTO_TRACE_ADD("outside module");
1317 p->externalImports[moduleFile.str()].emplace_back(nullptr,importName,line,partitionName);
1318 }
1319}
1320
1322{
1323 std::lock_guard lock(p->mutex);
1324 auto mod = p->moduleFileMap.find(root->fileName);
1325 if (mod)
1326 {
1327 toModuleDefImpl(mod)->addClassToModule(root,cd);
1328 auto cdm = toClassDefMutable(cd);
1329 if (cdm) cdm->setModuleDef(mod);
1330 }
1331}
1332
1334{
1335 std::lock_guard lock(p->mutex);
1336 auto mod = p->moduleFileMap.find(root->fileName);
1337 if (mod)
1338 {
1339 toModuleDefImpl(mod)->addConceptToModule(root,cd);
1340 auto cdm = toConceptDefMutable(cd);
1341 if (cdm) cdm->setModuleDef(mod);
1342 }
1343}
1344
1346{
1347 std::lock_guard lock(p->mutex);
1348 auto mod = p->moduleFileMap.find(root->fileName);
1349 if (mod && root->exported)
1350 {
1351 toModuleDefImpl(mod)->addMemberToModule(root,md);
1352 auto mdm = toMemberDefMutable(md);
1353 if (mdm) mdm->setModuleDef(mod);
1354 }
1355}
1356
1357void ModuleManager::addTagInfo(const QCString &fileName,const QCString &tagFile,const QCString &clangId)
1358{
1359 std::lock_guard lock(p->mutex);
1360 auto mod = p->moduleFileMap.find(fileName);
1361 if (mod)
1362 {
1363 ModuleDefImpl *modi = toModuleDefImpl(mod);
1364 modi->setReference(tagFile);
1365 modi->setId(clangId);
1366 }
1367}
1368
1370{
1371 AUTO_TRACE();
1372 for (auto &[partitionFileName,importInfoList] : mod->getImports()) // foreach import
1373 {
1374 for (auto &importInfo : importInfoList)
1375 {
1376 AUTO_TRACE_ADD("partitionFileName={} importName={} partitionName={}",
1377 partitionFileName,importInfo.importName,importInfo.partitionName);
1378 if (importInfo.importName==intfMod->name() && !importInfo.partitionName.isEmpty() &&
1379 importInfo.exported) // that is an exported partition of this module
1380 {
1381 auto it = p->moduleNameMap.find(importInfo.importName.str());
1382 if (it != p->moduleNameMap.end())
1383 {
1384 for (auto importedMod : it->second)
1385 {
1386 if (importedMod->qualifiedName()==importInfo.importName+":"+importInfo.partitionName)
1387 {
1388 AUTO_TRACE_ADD("Interface module {} exports partition {}:{}",
1389 mod->name(),importedMod->name(),importedMod->partitionName());
1390 toModuleDefImpl(intfMod)->addPartition(toModuleDefImpl(importedMod));
1391 toModuleDefImpl(importedMod)->setPrimaryInterface(intfMod);
1392 for (const auto &[partitionFileName_,partitionImportInfoList] : importedMod->getImports())
1393 {
1394 for (const auto &partitionImportInfo : partitionImportInfoList)
1395 {
1396 if (partitionImportInfo.exported && intfMod->name()!=partitionImportInfo.importName)
1397 {
1398 toModuleDefImpl(intfMod)->addExportedModule(partitionImportInfo.importName,partitionImportInfo);
1399 }
1400 }
1401 }
1402 resolvePartitionsRecursively(intfMod,importedMod);
1403 }
1404 }
1405 }
1406 }
1407 }
1408 }
1409}
1410
1412{
1413 AUTO_TRACE();
1414 for (auto &mod : p->moduleFileMap) // foreach module
1415 {
1416 if (mod->moduleType()==ModuleDef::Type::Interface && mod->partitionName().isEmpty())
1417 { // that is a primary interface
1418 resolvePartitionsRecursively(mod.get(),mod.get());
1419 }
1420
1421 // copy exported imports to m_exportedModules
1422 for (const auto &[fileName,importInfoList] : mod->getImports())
1423 {
1424 for (const auto &importInfo : importInfoList)
1425 {
1426 if (importInfo.exported && mod->name()!=importInfo.importName)
1427 {
1428 toModuleDefImpl(mod)->addExportedModule(importInfo.importName,importInfo);
1429 }
1430 }
1431 }
1432
1433 // also link the ModuleDef and FileDef together
1434 bool ambig = false;
1435 FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,mod->getDefFileName(),ambig);
1436 if (fd)
1437 {
1438 fd->setModuleDef(mod.get());
1439 toModuleDefImpl(mod)->setFileDef(fd);
1440 }
1441 }
1442}
1443
1445{
1446 AUTO_TRACE();
1447 for (auto &mod : p->moduleFileMap)
1448 {
1449 FileDef *fd = mod->getFileDef();
1450 if (fd)
1451 {
1452 for (const auto &[fileName,importInfoList] : mod->getImports())
1453 {
1454 for (const auto &importInfo : importInfoList)
1455 {
1456 ModuleDef *importedModule = getPrimaryInterface(importInfo.importName);
1457 const FileDef *importedFd = importedModule ? importedModule->getFileDef() : nullptr;
1458 AUTO_TRACE_ADD("module: addIncludeDependency {}->{}:{} fd={}",
1459 mod->qualifiedName(), importInfo.qualifiedName(), importInfo.line, fd?fd->absFilePath():"");
1461 }
1462 }
1463 }
1464 }
1465 for (const auto &[fileName,importInfoList] : p->externalImports)
1466 {
1467 for (const auto &importInfo : importInfoList)
1468 {
1469 bool ambig = false;
1470 FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,fileName,ambig);
1471 AUTO_TRACE_ADD("externalImport name={} fd={}",fileName,(void*)fd);
1472 if (fd)
1473 {
1474 ModuleDef *mod = getPrimaryInterface(importInfo.importName);
1475 FileDef *importedFd = mod ? mod->getFileDef() : nullptr;
1476 fd->addIncludeDependency(importedFd,importInfo.importName,IncludeKind::ImportModule);
1477 if (importedFd)
1478 {
1480 }
1481 }
1482 }
1483 }
1484 for (const auto &headerInfo : p->headers)
1485 {
1486 bool ambig = false;
1487 FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,headerInfo.fileName,ambig);
1488 AUTO_TRACE_ADD("header name={} fd={}",headerInfo.fileName,(void*)fd);
1489 if (fd)
1490 {
1491 QCString resolvedHeader = determineAbsoluteIncludeName(headerInfo.fileName,headerInfo.headerName);
1492 FileDef *importFd = findFileDef(Doxygen::inputNameLinkedMap,resolvedHeader,ambig);
1493 fd->addIncludeDependency(importFd, headerInfo.headerName,
1494 headerInfo.isSystem ? IncludeKind::ImportSystem : IncludeKind::ImportLocal);
1495 if (importFd)
1496 {
1498 }
1499 }
1500 }
1501}
1502
1504{
1505 AUTO_TRACE("{}: collecting symbols for partition {}",intfMod->qualifiedName(),partitionMod->qualifiedName());
1506 auto intfModImpl = toModuleDefImpl(intfMod);
1507 auto partitionModImpl = toModuleDefImpl(partitionMod);
1508 intfModImpl->mergeSymbolsFrom(partitionModImpl);
1509}
1510
1512{
1513 AUTO_TRACE();
1514 for (auto &mod : p->moduleFileMap) // foreach module
1515 {
1516 if (mod->isPrimaryInterface()) // that is a primary interface
1517 {
1518 for (auto &[partitionName,partitionMod] : mod->partitions())
1519 {
1520 collectExportedSymbolsRecursively(mod.get(),partitionMod);
1521 }
1522
1523 // collect all files that contribute to this module (e.g. implementation/partition modules)
1524 auto it = p->moduleNameMap.find(mod->name().str());
1525 if (it != p->moduleNameMap.end())
1526 {
1527 for (auto contributingMod : it->second)
1528 {
1529 AUTO_TRACE_ADD(" adding contributing module {} to interface module {} type={} partition={} isPrimaryIntf={}",
1530 contributingMod->qualifiedName(),
1531 mod->name(),
1532 contributingMod->moduleType()==ModuleDef::Type::Interface ? "Interface" : "Implementation",
1533 contributingMod->partitionName(),
1534 contributingMod->isPrimaryInterface());
1536 }
1537 }
1538 }
1539 }
1540}
1541
1543{
1544 for (auto &mod : p->moduleFileMap) // foreach module
1545 {
1547 }
1548}
1549
1551{
1552 for (auto &mod : p->moduleFileMap) // foreach module
1553 {
1554 if (mod->isPrimaryInterface())
1555 {
1556 mod->writeDocumentation(ol);
1557 }
1558 }
1559}
1560
1562{
1563 int count=0;
1564 for (const auto &mod : p->moduleFileMap) // foreach module
1565 {
1566 if (mod->isPrimaryInterface()) count++;
1567 }
1568 return count;
1569}
1570
1572{
1573 return p->moduleFileMap;
1574}
1575
1577{
1578 return p->moduleFileMap;
1579}
1580
1582{
1583 AUTO_TRACE("file={} module={}",root->fileName,root->name);
1584 if (root->doc.isEmpty() && root->brief.isEmpty()) return;
1585 if (root->name.find(':')!=-1)
1586 {
1587 warn(root->fileName,root->startLine,"Ignoring documentation for module partition {}. Please place documentation at the primary module name",
1588 root->name);
1589 }
1590 else
1591 {
1592 auto it = p->moduleNameMap.find(root->name.str());
1593 if (it != p->moduleNameMap.end())
1594 {
1595 ModuleDef *mod = getPrimaryInterface(root->name);
1596 if (mod)
1597 {
1598 mod->setDocumentation(root->doc,root->docFile,root->docLine);
1599 mod->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1600 mod->setId(root->id);
1601 mod->setHidden(root->hidden);
1602 mod->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1603 mod->setRefItems(root->sli);
1604 //mod->addSectionsToDefinition(root->anchors);
1605 addModuleToGroups(root,mod);
1606 }
1607 else
1608 {
1609 warn(root->fileName,root->startLine,"Found documentation for module {} but it has no primary interface unit.",root->name);
1610 }
1611 }
1612 else
1613 {
1614 warn(root->fileName,root->startLine,"Found documentation for unknown module {}.",root->name);
1615 }
1616 }
1617}
1618
1620{
1621 auto it = p->moduleNameMap.find(moduleName.str());
1622 if (it != p->moduleNameMap.end())
1623 {
1624 for (const auto &mod : it->second)
1625 {
1626 if (mod->isPrimaryInterface())
1627 {
1628 return mod;
1629 }
1630 }
1631 }
1632 return nullptr;
1633}
1634
1636{
1637 for (const auto &mod : p->moduleFileMap) // foreach module
1638 {
1639 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addListReferences();
1640 }
1641}
1642
1644{
1645 for (const auto &mod : p->moduleFileMap) // foreach module
1646 {
1647 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->addMembersToMemberGroup();
1648 }
1649}
1650
1652{
1653 for (const auto &mod : p->moduleFileMap) // foreach module
1654 {
1655 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->distributeMemberGroupDocumentation();
1656 }
1657}
1658
1660{
1661 for (auto &mod : p->moduleFileMap) // foreach module
1662 {
1663 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->findSectionsInDocumentation();
1664 }
1665}
1666
1668{
1669 for (auto &mod : p->moduleFileMap) // foreach module
1670 {
1671 if (mod->isPrimaryInterface()) toModuleDefImpl(mod)->sortMemberLists();
1672 }
1673}
1674
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: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
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: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
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)
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
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:4726
void addGroupListToTitle(OutputList &ol, const Definition *d)
Definition util.cpp:4813
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:307
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3425
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:3833
QCString determineAbsoluteIncludeName(const QCString &curFile, const QCString &incFileName)
Definition util.cpp:3521
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2823
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4823
A bunch of utility functions.