diff options
author | Vladimír Vondruš <mosra@centrum.cz> | 2019-01-01 17:01:22 (GMT) |
---|---|---|
committer | Vladimír Vondruš <mosra@centrum.cz> | 2019-01-03 10:32:17 (GMT) |
commit | d18b3eaf3486e224fa9de7e77b536883952b40b9 (patch) | |
tree | 045620bc9c59d68e2fb32bf035f0147e164a360b /src | |
parent | 3b2198babbaf8edafe03e5298e7c194763a1f9fa (diff) | |
download | Doxygen-d18b3eaf3486e224fa9de7e77b536883952b40b9.zip Doxygen-d18b3eaf3486e224fa9de7e77b536883952b40b9.tar.gz Doxygen-d18b3eaf3486e224fa9de7e77b536883952b40b9.tar.bz2 |
Implement a new EXTRACT_PRIVATE_VIRTUAL option.
The classic article about virtuality from Herb Sutter [1] suggests that
virtual functions are always private and public class interface is never
virtual. Until now, it was not really possible to document these
functions in Doxygen:
* Enabling EXTRACT_PRIVATE would show all internals, not just virtual
functions, which is not wanted.
* Enabling HIDE_UNDOC_MEMBERS and HIDE_UNDOC_CLASSES would effectively
disable warnings about *all* undocumented members, which is not wanted.
The usual workaround was to put the members into protected scope just
for Doxygen:
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @brief Documented private virtual function */
virtual doStuff();
The new EXTRACT_PRIVATE_VIRTUAL option makes these visible (and able to
be linked to), but shows them *only* if they are documented.
[1] http://www.gotw.ca/publications/mill18.htm
Diffstat (limited to 'src')
-rw-r--r-- | src/classdef.cpp | 4 | ||||
-rw-r--r-- | src/config.xml | 8 | ||||
-rw-r--r-- | src/memberdef.cpp | 17 |
3 files changed, 24 insertions, 5 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index e9d39d5..f275d1d 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -620,6 +620,10 @@ void ClassDef::internalInsertMember(MemberDef *md, { addMemberToList(MemberListType_relatedMembers,md,FALSE); } + else if (md->isFunction() && md->protection()==Private && md->virtualness()!=Normal && Config_getBool(EXTRACT_PRIVATE_VIRTUAL)) + { + addMemberToList(MemberListType_functionMembers,md,FALSE); + } else { switch (md->memberType()) diff --git a/src/config.xml b/src/config.xml index fdc562d..8bf45bb 100644 --- a/src/config.xml +++ b/src/config.xml @@ -838,6 +838,14 @@ Go to the <a href="commands.html">next</a> section or return to the ]]> </docs> </option> + <option type='bool' id='EXTRACT_PRIVATE_VIRTUAL' defval='0'> + <docs> +<![CDATA[ + If the \c EXTRACT_PRIVATE_VIRTUAL tag is set to \c YES, documented private + virtual methods of a class will be included in the documentation. +]]> + </docs> + </option> <option type='bool' id='EXTRACT_PACKAGE' defval='0'> <docs> <![CDATA[ diff --git a/src/memberdef.cpp b/src/memberdef.cpp index a2fcf69..58a2b12 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -1080,6 +1080,7 @@ QCString MemberDef::anchor() const void MemberDef::_computeLinkableInProject() { static bool extractStatic = Config_getBool(EXTRACT_STATIC); + static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIVATE_VIRTUAL); m_isLinkableCached = 2; // linkable //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data()); if (isHidden()) @@ -1133,7 +1134,7 @@ void MemberDef::_computeLinkableInProject() m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable return; } - if (!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend) + if ((!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend) && !(m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual)) { //printf("private and invisible!\n"); m_isLinkableCached = 1; // hidden due to protection @@ -1315,6 +1316,7 @@ ClassDef *MemberDef::getClassDefOfAnonymousType() bool MemberDef::isBriefSectionVisible() const { static bool extractStatic = Config_getBool(EXTRACT_STATIC); + static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIVATE_VIRTUAL); static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); static bool repeatBrief = Config_getBool(REPEAT_BRIEF); @@ -1365,9 +1367,12 @@ bool MemberDef::isBriefSectionVisible() const ); // only include members that are non-private unless EXTRACT_PRIVATE is - // set to YES or the member is part of a group + // set to YES or the member is part of a group. And as a special case, + // private *documented* virtual members are shown if EXTRACT_PRIVATE_VIRTUAL + // is set to YES bool visibleIfPrivate = (protectionLevelVisible(protection()) || - m_impl->mtype==MemberType_Friend + m_impl->mtype==MemberType_Friend || + (m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual && hasDocs) ); // hide member if it overrides a member in a superclass and has no @@ -1639,11 +1644,12 @@ void MemberDef::writeDeclaration(OutputList &ol, if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff { static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIVATE_VIRTUAL); static bool extractStatic = Config_getBool(EXTRACT_STATIC); //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation()); if (!(name().isEmpty() || name().at(0)=='@') && // name valid (hasDocumentation() || isReference()) && // has docs - !(m_impl->prot==Private && !extractPrivate && m_impl->mtype!=MemberType_Friend) && // hidden due to protection + !(m_impl->prot==Private && !extractPrivate && (m_impl->virt==Normal || !extractPrivateVirtual) && m_impl->mtype!=MemberType_Friend) && // hidden due to protection !(isStatic() && m_impl->classDef==0 && !extractStatic) // hidden due to static-ness ) { @@ -1896,6 +1902,7 @@ bool MemberDef::isDetailedSectionLinkable() const static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); static bool extractStatic = Config_getBool(EXTRACT_STATIC); + static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIVATE_VIRTUAL); // the member has details documentation for any of the following reasons bool docFilter = @@ -1933,7 +1940,7 @@ bool MemberDef::isDetailedSectionLinkable() const // only include members that are non-private unless EXTRACT_PRIVATE is // set to YES or the member is part of a group - bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend; + bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend || (m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual); // member is part of an anonymous scope that is the type of // another member in the list. |