Doxygen
Loading...
Searching...
No Matches
groupdef.cpp File Reference
#include <algorithm>
#include <vector>
#include <ctype.h>
#include "groupdef.h"
#include "classdef.h"
#include "conceptdef.h"
#include "filedef.h"
#include "classlist.h"
#include "outputlist.h"
#include "namespacedef.h"
#include "language.h"
#include "util.h"
#include "memberlist.h"
#include "message.h"
#include "membergroup.h"
#include "doxygen.h"
#include "pagedef.h"
#include "docparser.h"
#include "searchindex.h"
#include "dot.h"
#include "dotgroupcollaboration.h"
#include "vhdldocgen.h"
#include "layout.h"
#include "arguments.h"
#include "entry.h"
#include "membername.h"
#include "dirdef.h"
#include "config.h"
#include "definitionimpl.h"
#include "regex.h"
#include "moduledef.h"
Include dependency graph for groupdef.cpp:

Go to the source code of this file.

Classes

class  GroupDefImpl

Functions

std::unique_ptr< GroupDefcreateGroupDef (const DString &fileName, int line, const DString &name, const DString &title, const DString &refFileName)
void addClassToGroups (const Entry *root, ClassDef *cd)
void addConceptToGroups (const Entry *root, ConceptDef *cd)
void addModuleToGroups (const Entry *root, ModuleDef *mod)
void addNamespaceToGroups (const Entry *root, NamespaceDef *nd)
void addDirToGroups (const Entry *root, DirDef *dd)
void addGroupToGroups (const Entry *root, GroupDef *subGroup)
void addMemberToGroups (const Entry *root, MemberDef *md)
void addExampleToGroups (const Entry *root, PageDef *eg)
template<class Vec>
static void groupClassesWithSameScope (Vec &vec)
static bool hasNonReferenceNestedGroupRec (const GroupDef *gd, int level)
GroupDeftoGroupDef (Definition *d)
const GroupDeftoGroupDef (const Definition *d)

Function Documentation

◆ addClassToGroups()

void addClassToGroups ( const Entry * root,
ClassDef * cd )

Definition at line 1500 of file groupdef.cpp.

1501{
1502 for (const Grouping &g : root->groups)
1503 {
1504 GroupDef *gd=nullptr;
1506 if (gd && gd->addClass(cd))
1507 {
1509 if (cdm)
1510 {
1511 cdm->makePartOfGroup(gd);
1512 }
1513 //printf("Compound %s: in group %s\n",qPrint(cd->name()),gd->groupTitle());
1514 }
1515 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1516 {
1517 warn(root->fileName, root->startLine,
1518 "Found non-existing group '{}' for the command '{}', ignoring command",
1520 );
1521 }
1522 }
1523}
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:152
virtual void makePartOfGroup(GroupDef *gd)=0
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:107
DString fileName
file this entry was extracted from
Definition entry.h:223
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:221
int startLine
start line of entry in the source
Definition entry.h:224
A model of a group of symbols.
Definition groupdef.h:48
virtual bool addClass(ClassDef *def)=0
const T * find(const std::string &key) const
Definition linkedmap.h:47
ClassDefMutable * toClassDefMutable(Definition *d)
#define warn(file, line, fmt,...)
Definition message.h:97
Grouping info.
Definition types.h:227
DString groupname
name of the group
Definition types.h:257
static constexpr const char * getGroupPriName(GroupPri_t priority) noexcept
Definition types.h:240
@ GROUPING_INGROUP
membership in group was defined by @ingroup
Definition types.h:236
GroupPri_t pri
priority of this definition
Definition types.h:258

References GroupDef::addClass(), addClassToGroups(), DString::empty(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, toClassDefMutable(), and warn.

Referenced by addClassToContext(), and addClassToGroups().

◆ addConceptToGroups()

void addConceptToGroups ( const Entry * root,
ConceptDef * cd )

Definition at line 1525 of file groupdef.cpp.

1526{
1527 for (const Grouping &g : root->groups)
1528 {
1530 if (gd && gd->addConcept(cd))
1531 {
1533 if (cdm)
1534 {
1535 cdm->makePartOfGroup(gd);
1536 }
1537 //printf("Compound %s: in group %s\n",qPrint(cd->name()),gd->groupTitle());
1538 }
1539 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1540 {
1541 warn(root->fileName, root->startLine,
1542 "Found non-existing group '{}' for the command '{}', ignoring command",
1544 );
1545 }
1546 }
1547}
virtual bool addConcept(ConceptDef *def)=0
ConceptDefMutable * toConceptDefMutable(Definition *d)

References GroupDef::addConcept(), addConceptToGroups(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, toConceptDefMutable(), and warn.

Referenced by addConceptToContext(), and addConceptToGroups().

◆ addDirToGroups()

void addDirToGroups ( const Entry * root,
DirDef * dd )

Definition at line 1597 of file groupdef.cpp.

1598{
1599 //printf("*** root->groups.size()=%d\n",root->groups.size());
1600 for (const Grouping &g : root->groups)
1601 {
1603 //printf("group '%s'\n",qPrint(g->groupname));
1604 if (gd)
1605 {
1606 gd->addDir(dd);
1607 dd->makePartOfGroup(gd);
1608 //printf("Dir %s: in group %s\n",qPrint(dd->name()),qPrint(g->groupname));
1609 }
1610 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1611 {
1612 warn(root->fileName, root->startLine,
1613 "Found non-existing group '{}' for the command '{}', ignoring command",
1615 );
1616 }
1617 }
1618}
virtual void addDir(DirDef *dd)=0

References GroupDef::addDir(), addDirToGroups(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, and warn.

Referenced by addDirToGroups(), addPageToGroups(), and findDirDocumentation().

◆ addExampleToGroups()

void addExampleToGroups ( const Entry * root,
PageDef * eg )

Definition at line 1780 of file groupdef.cpp.

1781{
1782 for (const Grouping &g : root->groups)
1783 {
1785 if (gd)
1786 {
1787 gd->addExample(eg);
1788 eg->makePartOfGroup(gd);
1789 //printf("Example %s: in group %s\n",qPrint(eg->name()),s->data());
1790 }
1791 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1792 {
1793 warn(root->fileName, root->startLine,
1794 "Found non-existing group '{}' for the command '{}', ignoring command",
1796 );
1797 }
1798 }
1799}
virtual void addExample(PageDef *def)=0

References GroupDef::addExample(), addExampleToGroups(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, and warn.

Referenced by addExampleToGroups(), and addPageToGroups().

◆ addGroupToGroups()

void addGroupToGroups ( const Entry * root,
GroupDef * subGroup )

Definition at line 1620 of file groupdef.cpp.

1621{
1622 //printf("addGroupToGroups for %s groups=%d\n",qPrint(root->name),root->groups.size());
1623 for (const Grouping &g : root->groups)
1624 {
1626 if (gd)
1627 {
1628 if (gd==subGroup)
1629 {
1630 warn(root->fileName,root->startLine,"Refusing to add group {} to itself",
1631 gd->name());
1632 }
1633 else if (subGroup->findGroup(gd))
1634 {
1635 warn(root->fileName,root->startLine,"Refusing to add group {} to group {}, since the latter is already a "
1636 "subgroup of the former", subGroup->name(),gd->name());
1637 }
1638 else if (!gd->findGroup(subGroup))
1639 {
1640 gd->addGroup(subGroup);
1641 subGroup->makePartOfGroup(gd);
1642 }
1643 }
1644 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1645 {
1646 warn(root->fileName, root->startLine,
1647 "Found non-existing group '{}' for the command '{}', ignoring command",
1649 );
1650 }
1651 }
1652}
virtual const DString & name() const =0
virtual void addGroup(GroupDef *def)=0
virtual bool findGroup(const GroupDef *def) const =0

References GroupDef::addGroup(), addGroupToGroups(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), GroupDef::findGroup(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Definition::name(), Grouping::pri, Entry::startLine, and warn.

Referenced by addGroupToGroups(), and organizeSubGroupsFiltered().

◆ addMemberToGroups()

void addMemberToGroups ( const Entry * root,
MemberDef * md )

Add a member to the group with the highest priority

Definition at line 1655 of file groupdef.cpp.

1656{
1657 //printf("addMemberToGroups: Root %p = %s, md %p=%s groups=%zu\n",
1658 // root, qPrint(root->name), md, qPrint(md->name()), root->groups.size() );
1659
1660 // Search entry's group list for group with highest pri.
1662 GroupDef *fgd=nullptr;
1663 for (const Grouping &g : root->groups)
1664 {
1665 GroupDef *gd=nullptr;
1667 if (gd && g.pri >= pri)
1668 {
1669 if (fgd && gd!=fgd && g.pri==pri)
1670 {
1671 warn(root->fileName, root->startLine,
1672 "Member {} found in multiple {} groups! "
1673 "The member will be put in group {}, and not in group {}",
1674 md->name(), Grouping::getGroupPriName( pri ),
1675 gd->name(), fgd->name()
1676 );
1677 }
1678
1679 fgd = gd;
1680 pri = g.pri;
1681 }
1682 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1683 {
1684 warn(root->fileName, root->startLine,
1685 "Found non-existing group '{}' for the command '{}', ignoring command",
1687 );
1688 }
1689 }
1690 //printf("fgd=%p\n",fgd);
1691
1692 // put member into group defined by this entry?
1693 if (fgd)
1694 {
1695 GroupDef *mgd = md->getGroupDef();
1696 //printf("mgd=%p\n",mgd);
1697 bool insertit = false;
1698 if (mgd==nullptr)
1699 {
1700 insertit = true;
1701 }
1702 else if (mgd!=fgd)
1703 {
1704 bool moveit = false;
1705
1706 // move member from one group to another if
1707 // - the new one has a higher priority
1708 // - the new entry has the same priority, but with docs where the old one had no docs
1709 if (md->getGroupPri()<pri)
1710 {
1711 moveit = true;
1712 }
1713 else
1714 {
1715 if (md->getGroupPri()==pri)
1716 {
1717 if (!root->doc.empty() && !md->getGroupHasDocs())
1718 {
1719 moveit = true;
1720 }
1721 else if (!root->doc.empty() && md->getGroupHasDocs())
1722 {
1724 "Member documentation for {} found several times in {} groups!\n"
1725 "{}:{}: The member will remain in group {}, and won't be put into group {}",
1726 md->name(), Grouping::getGroupPriName( pri ),
1727 root->fileName, root->startLine,
1728 mgd->name(), fgd->name()
1729 );
1730 }
1731 }
1732 }
1733
1734 if (moveit)
1735 {
1736 //printf("removeMember\n");
1737 mgd->removeMember(md);
1738 insertit = true;
1739 }
1740 }
1741
1742 if (insertit)
1743 {
1744 //printf("insertMember found at %s line %d: %s: related %s\n",
1745 // qPrint(md->getDefFileName()),md->getDefLine(),
1746 // qPrint(md->name()),qPrint(root->relates));
1747 bool success = fgd->insertMember(md);
1748 if (success)
1749 {
1751 if (mdm)
1752 {
1753 //printf("insertMember successful\n");
1754 mdm->setGroupDef(fgd,pri,root->fileName,root->startLine,!root->doc.empty());
1756 if (cdm)
1757 {
1758 cdm->setGroupDefForAllMembers(fgd,pri,root->fileName,root->startLine,root->doc.length() != 0);
1759 }
1760 if (mdm->isEnumerate() && mdm->getGroupDef() && md->isStrong())
1761 {
1762 for (const auto &emd : mdm->enumFieldList())
1763 {
1765 if (emdm && emdm->getGroupDef()==nullptr)
1766 {
1767 emdm->setGroupDef(mdm->getGroupDef(),mdm->getGroupPri(),
1768 mdm->getGroupFileName(),mdm->getGroupStartLine(),
1769 mdm->getGroupHasDocs());
1770 }
1771 }
1772 }
1773 }
1774 }
1775 }
1776 }
1777}
A abstract class representing of a compound symbol.
Definition classdef.h:100
virtual void setGroupDefForAllMembers(GroupDef *g, Grouping::GroupPri_t pri, const DString &fileName, int startLine, bool hasDocs)=0
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:155
DString doc
documentation block (partly parsed)
Definition entry.h:200
virtual void removeMember(MemberDef *md)=0
virtual bool insertMember(MemberDef *def, bool docOnly=false)=0
virtual bool getGroupHasDocs() const =0
virtual GroupDef * getGroupDef()=0
virtual const MemberVector & enumFieldList() const =0
virtual int getGroupStartLine() const =0
virtual Grouping::GroupPri_t getGroupPri() const =0
virtual const ClassDef * getClassDefOfAnonymousType() const =0
virtual bool isEnumerate() const =0
virtual DString getGroupFileName() const =0
virtual bool isStrong() const =0
virtual void setGroupDef(GroupDef *gd, Grouping::GroupPri_t pri, const DString &fileName, int startLine, bool hasDocs, MemberDef *member=nullptr)=0
MemberDefMutable * toMemberDefMutable(Definition *d)
GroupPri_t
Grouping priority.
Definition types.h:230
@ GROUPING_LOWEST
Definition types.h:231

References addMemberToGroups(), Entry::doc, DString::empty(), MemberDef::enumFieldList(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), MemberDef::getClassDefOfAnonymousType(), MemberDef::getGroupDef(), MemberDef::getGroupFileName(), MemberDef::getGroupHasDocs(), MemberDef::getGroupPri(), Grouping::getGroupPriName(), MemberDef::getGroupStartLine(), Grouping::GROUPING_INGROUP, Grouping::GROUPING_LOWEST, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, GroupDef::insertMember(), MemberDef::isEnumerate(), MemberDef::isStrong(), DString::length(), Definition::name(), Grouping::pri, GroupDef::removeMember(), MemberDefMutable::setGroupDef(), ClassDefMutable::setGroupDefForAllMembers(), Entry::startLine, toClassDefMutable(), toMemberDefMutable(), and warn.

Referenced by addDefineDoc(), addEnumDocs(), addGlobalFunction(), addInterfaceOrServiceToServiceOrSingleton(), addMemberDocs(), addMemberToGroups(), addMethodToClass(), addVariableToClass(), addVariableToFile(), buildFunctionList(), buildTypedefList(), findEnums(), and findMember().

◆ addModuleToGroups()

void addModuleToGroups ( const Entry * root,
ModuleDef * mod )

Definition at line 1549 of file groupdef.cpp.

1550{
1551 for (const Grouping &g : root->groups)
1552 {
1554 if (gd && gd->addModule(mod))
1555 {
1556 mod->makePartOfGroup(gd);
1557 //printf("Module %s: in group %s\n",qPrint(mod->name()),gd->groupTitle());
1558 }
1559 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1560 {
1561 warn(root->fileName, root->startLine,
1562 "Found non-existing group '{}' for the command '{}', ignoring command",
1564 );
1565 }
1566 }
1567}
virtual bool addModule(ModuleDef *def)=0

References GroupDef::addModule(), addModuleToGroups(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, and warn.

Referenced by ModuleManager::addDocs(), and addModuleToGroups().

◆ addNamespaceToGroups()

void addNamespaceToGroups ( const Entry * root,
NamespaceDef * nd )

Definition at line 1570 of file groupdef.cpp.

1571{
1572 //printf("root->groups.size()=%zu\n",root->groups.size());
1573 for (const Grouping &g : root->groups)
1574 {
1575 GroupDef *gd=nullptr;
1577 //printf("group '%s' gd=%p\n",qPrint(g.groupname),(void*)gd);
1578 if (gd && gd->addNamespace(nd))
1579 {
1581 if (ndm)
1582 {
1583 ndm->makePartOfGroup(gd);
1584 }
1585 //printf("Namespace %s: in group %s\n",qPrint(nd->name()),qPrint(gd->name()));
1586 }
1587 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1588 {
1589 warn(root->fileName, root->startLine,
1590 "Found non-existing group '{}' for the command '{}', ignoring command",
1592 );
1593 }
1594 }
1595}
virtual bool addNamespace(NamespaceDef *def)=0
NamespaceDefMutable * toNamespaceDefMutable(Definition *d)

References GroupDef::addNamespace(), addNamespaceToGroups(), DString::empty(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, toNamespaceDefMutable(), and warn.

Referenced by addNamespaceToGroups(), and buildNamespaceList().

◆ createGroupDef()

std::unique_ptr< GroupDef > createGroupDef ( const DString & fileName,
int line,
const DString & name,
const DString & title,
const DString & refFileName )

Definition at line 179 of file groupdef.cpp.

181{
182 return std::make_unique<GroupDefImpl>(fileName,line,name,title,refFileName);
183}

References createGroupDef().

Referenced by buildGroupListFiltered(), createGroupDef(), and GroupDef::overrideGroupGraph().

◆ groupClassesWithSameScope()

template<class Vec>
void groupClassesWithSameScope ( Vec & vec)
static

Definition at line 1857 of file groupdef.cpp.

1858{
1859 bool done=false;
1860 while (!done) // for each iteration
1861 {
1862 done=true;
1863 for (size_t i=0; i<vec.size(); i++) // go through all items
1864 {
1865 std::string qni = vec[i]->name().str();
1866 size_t posi = qni.rfind("::");
1867 if (posi!=std::string::npos)
1868 {
1869 std::string scope = qni.substr(0,posi);
1870 auto it = std::find_if( vec.begin(), vec.end(),
1871 [&](typename Vec::Ptr &cd)
1872 { return cd->name().str()==scope; });
1873 if (it!=vec.end())
1874 {
1875 size_t idx = std::distance(vec.begin(),it);
1876 if (i<idx) // parent scope located after child scope
1877 {
1878 // to avoid reordering elements with the same parent
1879 // we skip to the last one with the same scope
1880 size_t k = idx;
1881 while (k<vec.size() && vec[k]->name().str().substr(0,posi)==scope)
1882 {
1883 idx = k;
1884 k++;
1885 }
1886 // swap the items such that i is inserted after idx
1887 for (size_t j=i; j<idx; j++)
1888 {
1889 std::swap(vec[j],vec[j+1]);
1890 }
1891 done=false;
1892 }
1893 else if (idx<i && vec[i-1]->name().str().substr(0,posi)!=scope)
1894 {
1895 // parent scope is found before the item, and the item
1896 // has some other item with a different scope in front of it
1897 // move idx to the end of range with the same scope
1898 while (idx<i && vec[idx]->name().str().substr(0,posi)==scope)
1899 {
1900 idx++;
1901 }
1902 // swap the items such that i is just after idx
1903 for (size_t j=idx; j<i; j++)
1904 {
1905 std::swap(vec[j],vec[j+1]);
1906 }
1907 done=false;
1908 }
1909 }
1910 }
1911 }
1912 }
1913}

References groupClassesWithSameScope().

Referenced by groupClassesWithSameScope(), and GroupDefImpl::sortMemberLists().

◆ hasNonReferenceNestedGroupRec()

bool hasNonReferenceNestedGroupRec ( const GroupDef * gd,
int level )
static

Definition at line 2013 of file groupdef.cpp.

2014{
2015 if (level>30)
2016 {
2017 err("Possible recursive group relation while inside {}\n",gd->name());
2018 return false;
2019 }
2020 bool found=gd->isLinkableInProject();
2021 if (found)
2022 {
2023 return true;
2024 }
2025 else
2026 {
2027 for (const auto &igd : gd->getSubGroups())
2028 {
2029 found = found || hasNonReferenceNestedGroupRec(igd,level+1);
2030 if (found) break;
2031 }
2032 }
2033 return found;
2034}
virtual bool isLinkableInProject() const =0
virtual const GroupList & getSubGroups() const =0
static bool hasNonReferenceNestedGroupRec(const GroupDef *gd, int level)
#define err(fmt,...)
Definition message.h:127

References err, GroupDef::getSubGroups(), hasNonReferenceNestedGroupRec(), Definition::isLinkableInProject(), and Definition::name().

Referenced by hasNonReferenceNestedGroupRec(), and GroupDefImpl::isVisibleInHierarchy().

◆ toGroupDef() [1/2]

const GroupDef * toGroupDef ( const Definition * d)

Definition at line 2096 of file groupdef.cpp.

2097{
2098 if (d==nullptr) return nullptr;
2099 if (d && typeid(*d)==typeid(GroupDefImpl))
2100 {
2101 return static_cast<const GroupDef*>(d);
2102 }
2103 else
2104 {
2105 return nullptr;
2106 }
2107}

References toGroupDef().

◆ toGroupDef() [2/2]

GroupDef * toGroupDef ( Definition * d)

Definition at line 2083 of file groupdef.cpp.

2084{
2085 if (d==nullptr) return nullptr;
2086 if (d && typeid(*d)==typeid(GroupDefImpl))
2087 {
2088 return static_cast<GroupDef*>(d);
2089 }
2090 else
2091 {
2092 return nullptr;
2093 }
2094}

References toGroupDef().

Referenced by DocRef::DocRef(), DocParser::handleLinkedWord(), SearchTerm::makeTitle(), DefinitionImpl::navigationPathAsString(), GroupDef::overrideGroupGraph(), DefinitionImpl::pathFragment(), SearchIndex::setCurrentDoc(), SearchIndexExternal::setCurrentDoc(), toGroupDef(), toGroupDef(), validatingParseDoc(), MemberDefImpl::writeDocumentation(), and writeJavasScriptSearchDataPage().