Doxygen
Loading...
Searching...
No Matches
groupdef.cpp File Reference
#include <algorithm>
#include <vector>
#include <ctype.h>
#include "groupdef.h"
#include "classdef.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 QCString &fileName, int line, const QCString &name, const QCString &title, const QCString &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 1444 of file groupdef.cpp.

1445{
1446 for (const Grouping &g : root->groups)
1447 {
1448 GroupDef *gd=nullptr;
1449 if (!g.groupname.isEmpty()) gd=Doxygen::groupLinkedMap->find(g.groupname);
1450 if (gd && gd->addClass(cd))
1451 {
1453 if (cdm)
1454 {
1455 cdm->makePartOfGroup(gd);
1456 }
1457 //printf("Compound %s: in group %s\n",qPrint(cd->name()),gd->groupTitle());
1458 }
1459 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1460 {
1461 warn(root->fileName, root->startLine,
1462 "Found non-existing group '{}' for the command '{}', ignoring command",
1464 );
1465 }
1466 }
1467}
virtual void makePartOfGroup(GroupDef *gd)=0
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
QCString 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:52
virtual bool addClass(ClassDef *def)=0
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
ClassDefMutable * toClassDefMutable(Definition *d)
#define warn(file, line, fmt,...)
Definition message.h:97
Grouping info.
Definition types.h:227
QCString groupname
name of the group
Definition types.h:257
@ GROUPING_INGROUP
membership in group was defined by @ingroup
Definition types.h:236
static const char * getGroupPriName(GroupPri_t priority)
Definition types.h:240
GroupPri_t pri
priority of this definition
Definition types.h:258

References GroupDef::addClass(), Entry::fileName, Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, QCString::isEmpty(), DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, toClassDefMutable(), and warn.

Referenced by addClassToContext().

◆ addConceptToGroups()

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

Definition at line 1469 of file groupdef.cpp.

1470{
1471 for (const Grouping &g : root->groups)
1472 {
1474 if (gd && gd->addConcept(cd))
1475 {
1477 if (cdm)
1478 {
1479 cdm->makePartOfGroup(gd);
1480 }
1481 //printf("Compound %s: in group %s\n",qPrint(cd->name()),gd->groupTitle());
1482 }
1483 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1484 {
1485 warn(root->fileName, root->startLine,
1486 "Found non-existing group '{}' for the command '{}', ignoring command",
1488 );
1489 }
1490 }
1491}
virtual bool addConcept(ConceptDef *def)=0
ConceptDefMutable * toConceptDefMutable(Definition *d)

References GroupDef::addConcept(), Entry::fileName, Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, toConceptDefMutable(), and warn.

Referenced by addConceptToContext().

◆ addDirToGroups()

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

Definition at line 1541 of file groupdef.cpp.

1542{
1543 //printf("*** root->groups.size()=%d\n",root->groups.size());
1544 for (const Grouping &g : root->groups)
1545 {
1547 //printf("group '%s'\n",qPrint(g->groupname));
1548 if (gd)
1549 {
1550 gd->addDir(dd);
1551 dd->makePartOfGroup(gd);
1552 //printf("Dir %s: in group %s\n",qPrint(dd->name()),qPrint(g->groupname));
1553 }
1554 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1555 {
1556 warn(root->fileName, root->startLine,
1557 "Found non-existing group '{}' for the command '{}', ignoring command",
1559 );
1560 }
1561 }
1562}
virtual void addDir(DirDef *dd)=0

References GroupDef::addDir(), Entry::fileName, Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, and warn.

Referenced by findDirDocumentation().

◆ addExampleToGroups()

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

Definition at line 1724 of file groupdef.cpp.

1725{
1726 for (const Grouping &g : root->groups)
1727 {
1729 if (gd)
1730 {
1731 gd->addExample(eg);
1732 eg->makePartOfGroup(gd);
1733 //printf("Example %s: in group %s\n",qPrint(eg->name()),s->data());
1734 }
1735 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1736 {
1737 warn(root->fileName, root->startLine,
1738 "Found non-existing group '{}' for the command '{}', ignoring command",
1740 );
1741 }
1742 }
1743}
virtual void addExample(PageDef *def)=0

References GroupDef::addExample(), Entry::fileName, Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, and warn.

◆ addGroupToGroups()

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

Definition at line 1564 of file groupdef.cpp.

1565{
1566 //printf("addGroupToGroups for %s groups=%d\n",qPrint(root->name),root->groups.size());
1567 for (const Grouping &g : root->groups)
1568 {
1570 if (gd)
1571 {
1572 if (gd==subGroup)
1573 {
1574 warn(root->fileName,root->startLine,"Refusing to add group {} to itself",
1575 gd->name());
1576 }
1577 else if (subGroup->findGroup(gd))
1578 {
1579 warn(root->fileName,root->startLine,"Refusing to add group {} to group {}, since the latter is already a "
1580 "subgroup of the former", subGroup->name(),gd->name());
1581 }
1582 else if (!gd->findGroup(subGroup))
1583 {
1584 gd->addGroup(subGroup);
1585 subGroup->makePartOfGroup(gd);
1586 }
1587 }
1588 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1589 {
1590 warn(root->fileName, root->startLine,
1591 "Found non-existing group '{}' for the command '{}', ignoring command",
1593 );
1594 }
1595 }
1596}
virtual const QCString & name() const =0
virtual void addGroup(GroupDef *def)=0
virtual bool findGroup(const GroupDef *def) const =0

References GroupDef::addGroup(), Entry::fileName, 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 organizeSubGroupsFiltered().

◆ addMemberToGroups()

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

Add a member to the group with the highest priority

Definition at line 1599 of file groupdef.cpp.

1600{
1601 //printf("addMemberToGroups: Root %p = %s, md %p=%s groups=%zu\n",
1602 // root, qPrint(root->name), md, qPrint(md->name()), root->groups.size() );
1603
1604 // Search entry's group list for group with highest pri.
1606 GroupDef *fgd=nullptr;
1607 for (const Grouping &g : root->groups)
1608 {
1609 GroupDef *gd=nullptr;
1610 if (!g.groupname.isEmpty()) gd=Doxygen::groupLinkedMap->find(g.groupname);
1611 if (gd && g.pri >= pri)
1612 {
1613 if (fgd && gd!=fgd && g.pri==pri)
1614 {
1615 warn(root->fileName, root->startLine,
1616 "Member {} found in multiple {} groups! "
1617 "The member will be put in group {}, and not in group {}",
1618 md->name(), Grouping::getGroupPriName( pri ),
1619 gd->name(), fgd->name()
1620 );
1621 }
1622
1623 fgd = gd;
1624 pri = g.pri;
1625 }
1626 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1627 {
1628 warn(root->fileName, root->startLine,
1629 "Found non-existing group '{}' for the command '{}', ignoring command",
1631 );
1632 }
1633 }
1634 //printf("fgd=%p\n",fgd);
1635
1636 // put member into group defined by this entry?
1637 if (fgd)
1638 {
1639 GroupDef *mgd = md->getGroupDef();
1640 //printf("mgd=%p\n",mgd);
1641 bool insertit = FALSE;
1642 if (mgd==nullptr)
1643 {
1644 insertit = TRUE;
1645 }
1646 else if (mgd!=fgd)
1647 {
1648 bool moveit = FALSE;
1649
1650 // move member from one group to another if
1651 // - the new one has a higher priority
1652 // - the new entry has the same priority, but with docs where the old one had no docs
1653 if (md->getGroupPri()<pri)
1654 {
1655 moveit = TRUE;
1656 }
1657 else
1658 {
1659 if (md->getGroupPri()==pri)
1660 {
1661 if (!root->doc.isEmpty() && !md->getGroupHasDocs())
1662 {
1663 moveit = TRUE;
1664 }
1665 else if (!root->doc.isEmpty() && md->getGroupHasDocs())
1666 {
1668 "Member documentation for {} found several times in {} groups!\n"
1669 "{}:{}: The member will remain in group {}, and won't be put into group {}",
1670 md->name(), Grouping::getGroupPriName( pri ),
1671 root->fileName, root->startLine,
1672 mgd->name(), fgd->name()
1673 );
1674 }
1675 }
1676 }
1677
1678 if (moveit)
1679 {
1680 //printf("removeMember\n");
1681 mgd->removeMember(md);
1682 insertit = TRUE;
1683 }
1684 }
1685
1686 if (insertit)
1687 {
1688 //printf("insertMember found at %s line %d: %s: related %s\n",
1689 // qPrint(md->getDefFileName()),md->getDefLine(),
1690 // qPrint(md->name()),qPrint(root->relates));
1691 bool success = fgd->insertMember(md);
1692 if (success)
1693 {
1695 if (mdm)
1696 {
1697 //printf("insertMember successful\n");
1698 mdm->setGroupDef(fgd,pri,root->fileName,root->startLine,!root->doc.isEmpty());
1700 if (cdm)
1701 {
1702 cdm->setGroupDefForAllMembers(fgd,pri,root->fileName,root->startLine,root->doc.length() != 0);
1703 }
1704 if (mdm->isEnumerate() && mdm->getGroupDef() && md->isStrong())
1705 {
1706 for (const auto &emd : mdm->enumFieldList())
1707 {
1709 if (emdm && emdm->getGroupDef()==nullptr)
1710 {
1711 emdm->setGroupDef(mdm->getGroupDef(),mdm->getGroupPri(),
1712 mdm->getGroupFileName(),mdm->getGroupStartLine(),
1713 mdm->getGroupHasDocs());
1714 }
1715 }
1716 }
1717 }
1718 }
1719 }
1720 }
1721}
virtual void setGroupDefForAllMembers(GroupDef *g, Grouping::GroupPri_t pri, const QCString &fileName, int startLine, bool hasDocs)=0
QCString 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 ClassDef * getClassDefOfAnonymousType() const =0
virtual Grouping::GroupPri_t getGroupPri() const =0
virtual bool isEnumerate() const =0
virtual QCString getGroupFileName() const =0
virtual bool isStrong() const =0
virtual void setGroupDef(GroupDef *gd, Grouping::GroupPri_t pri, const QCString &fileName, int startLine, bool hasDocs, MemberDef *member=nullptr)=0
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
MemberDefMutable * toMemberDefMutable(Definition *d)
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
GroupPri_t
Grouping priority.
Definition types.h:230
@ GROUPING_LOWEST
Definition types.h:231

References Entry::doc, MemberDef::enumFieldList(), FALSE, Entry::fileName, 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(), QCString::isEmpty(), MemberDef::isEnumerate(), MemberDef::isStrong(), QCString::length(), Definition::name(), Grouping::pri, GroupDef::removeMember(), MemberDefMutable::setGroupDef(), ClassDefMutable::setGroupDefForAllMembers(), Entry::startLine, toClassDefMutable(), toMemberDefMutable(), TRUE, and warn.

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

◆ addModuleToGroups()

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

Definition at line 1493 of file groupdef.cpp.

1494{
1495 for (const Grouping &g : root->groups)
1496 {
1498 if (gd && gd->addModule(mod))
1499 {
1500 mod->makePartOfGroup(gd);
1501 //printf("Module %s: in group %s\n",qPrint(mod->name()),gd->groupTitle());
1502 }
1503 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1504 {
1505 warn(root->fileName, root->startLine,
1506 "Found non-existing group '{}' for the command '{}', ignoring command",
1508 );
1509 }
1510 }
1511}
virtual bool addModule(ModuleDef *def)=0

References GroupDef::addModule(), Entry::fileName, Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, and warn.

Referenced by ModuleManager::addDocs().

◆ addNamespaceToGroups()

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

Definition at line 1514 of file groupdef.cpp.

1515{
1516 //printf("root->groups.size()=%zu\n",root->groups.size());
1517 for (const Grouping &g : root->groups)
1518 {
1519 GroupDef *gd=nullptr;
1520 if (!g.groupname.isEmpty()) gd=Doxygen::groupLinkedMap->find(g.groupname);
1521 //printf("group '%s' gd=%p\n",qPrint(g.groupname),(void*)gd);
1522 if (gd && gd->addNamespace(nd))
1523 {
1525 if (ndm)
1526 {
1527 ndm->makePartOfGroup(gd);
1528 }
1529 //printf("Namespace %s: in group %s\n",qPrint(nd->name()),qPrint(gd->name()));
1530 }
1531 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
1532 {
1533 warn(root->fileName, root->startLine,
1534 "Found non-existing group '{}' for the command '{}', ignoring command",
1536 );
1537 }
1538 }
1539}
virtual bool addNamespace(NamespaceDef *def)=0
NamespaceDefMutable * toNamespaceDefMutable(Definition *d)

References GroupDef::addNamespace(), Entry::fileName, Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, QCString::isEmpty(), DefinitionMutable::makePartOfGroup(), Grouping::pri, Entry::startLine, toNamespaceDefMutable(), and warn.

Referenced by buildNamespaceList().

◆ createGroupDef()

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

Definition at line 175 of file groupdef.cpp.

177{
178 return std::make_unique<GroupDefImpl>(fileName,line,name,title,refFileName);
179}

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

◆ groupClassesWithSameScope()

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

Definition at line 1788 of file groupdef.cpp.

1789{
1790 bool done=false;
1791 while (!done) // for each iteration
1792 {
1793 done=true;
1794 for (size_t i=0; i<vec.size(); i++) // go through all items
1795 {
1796 std::string qni = vec[i]->name().str();
1797 size_t posi = qni.rfind("::");
1798 if (posi!=std::string::npos)
1799 {
1800 std::string scope = qni.substr(0,posi);
1801 auto it = std::find_if( vec.begin(), vec.end(),
1802 [&](typename Vec::Ptr &cd)
1803 { return cd->name().str()==scope; });
1804 if (it!=vec.end())
1805 {
1806 size_t idx = std::distance(vec.begin(),it);
1807 if (i<idx) // parent scope located after child scope
1808 {
1809 // to avoid reordering elements with the same parent
1810 // we skip to the last one with the same scope
1811 size_t k = idx;
1812 while (k<vec.size() && vec[k]->name().str().substr(0,posi)==scope)
1813 {
1814 idx = k;
1815 k++;
1816 }
1817 // swap the items such that i is inserted after idx
1818 for (size_t j=i; j<idx; j++)
1819 {
1820 std::swap(vec[j],vec[j+1]);
1821 }
1822 done=false;
1823 }
1824 else if (idx<i && vec[i-1]->name().str().substr(0,posi)!=scope)
1825 {
1826 // parent scope is found before the item, and the item
1827 // has some other item with a different scope in front of it
1828 // move idx to the end of range with the same scope
1829 while (idx<i && vec[idx]->name().str().substr(0,posi)==scope)
1830 {
1831 idx++;
1832 }
1833 // swap the items such that i is just after idx
1834 for (size_t j=idx; j<i; j++)
1835 {
1836 std::swap(vec[j],vec[j+1]);
1837 }
1838 done=false;
1839 }
1840 }
1841 }
1842 }
1843 }
1844}

Referenced by GroupDefImpl::sortMemberLists().

◆ hasNonReferenceNestedGroupRec()

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

Definition at line 1926 of file groupdef.cpp.

1927{
1928 if (level>30)
1929 {
1930 err("Possible recursive group relation while inside {}\n",gd->name());
1931 return false;
1932 }
1933 bool found=gd->isLinkableInProject();
1934 if (found)
1935 {
1936 return true;
1937 }
1938 else
1939 {
1940 for (const auto &igd : gd->getSubGroups())
1941 {
1942 found = found || hasNonReferenceNestedGroupRec(igd,level+1);
1943 if (found) break;
1944 }
1945 }
1946 return found;
1947}
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 2009 of file groupdef.cpp.

2010{
2011 if (d==nullptr) return nullptr;
2012 if (d && typeid(*d)==typeid(GroupDefImpl))
2013 {
2014 return static_cast<const GroupDef*>(d);
2015 }
2016 else
2017 {
2018 return nullptr;
2019 }
2020}

◆ toGroupDef() [2/2]

GroupDef * toGroupDef ( Definition * d)

Definition at line 1996 of file groupdef.cpp.

1997{
1998 if (d==nullptr) return nullptr;
1999 if (d && typeid(*d)==typeid(GroupDefImpl))
2000 {
2001 return static_cast<GroupDef*>(d);
2002 }
2003 else
2004 {
2005 return nullptr;
2006 }
2007}

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