@@ -403,6 +403,7 @@ class ClassDefImpl : public DefinitionMixin<ClassDefMutable>
403403 void writeTemplateSpec (OutputList &ol,const Definition *d,
404404 const QCString &type,SrcLangExt lang) const ;
405405 void mergeMembersFromBaseClasses (bool mergeVirtualBaseClass);
406+ void hideDerivedVariablesInPython (ClassDefMutable *cls);
406407
407408 // PIMPL idiom
408409 class IMPL ;
@@ -3739,7 +3740,7 @@ void ClassDefImpl::mergeMembersFromBaseClasses(bool mergeVirtualBaseClass)
37393740 found=matchArguments2 (
37403741 srcMd->getOuterScope (),srcMd->getFileDef (),&srcAl,
37413742 dstMd->getOuterScope (),dstMd->getFileDef (),&dstAl,
3742- TRUE ,getLanguage ()
3743+ TRUE ,lang
37433744 );
37443745 // printf(" Yes, matching (%s<->%s): %d\n",
37453746 // qPrint(argListToString(srcMd->argumentList())),
@@ -3805,7 +3806,8 @@ void ClassDefImpl::mergeMembersFromBaseClasses(bool mergeVirtualBaseClass)
38053806 // it seems that the member is not reachable by prefixing a
38063807 // scope name either (according to my compiler). Currently,
38073808 // this case is shown anyway.
3808- if (!found && srcMd->protection ()!=Protection::Private && !srcMd->isFriend () && srcMi->virtualBaseClass ()==mergeVirtualBaseClass)
3809+ if (!found && srcMd->protection ()!=Protection::Private && !srcMd->isFriend () &&
3810+ srcMi->virtualBaseClass ()==mergeVirtualBaseClass && lang!=SrcLangExt::Python)
38093811 {
38103812 Protection prot = srcMd->protection ();
38113813 if (bcd.prot ==Protection::Protected && prot==Protection::Public)
@@ -3830,7 +3832,7 @@ void ClassDefImpl::mergeMembersFromBaseClasses(bool mergeVirtualBaseClass)
38303832 if (virt==Specifier::Normal && bcd.virt !=Specifier::Normal) virt=bcd.virt ;
38313833 bool virtualBaseClass = bcd.virt !=Specifier::Normal;
38323834
3833- std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE ,virtualBaseClass);
3835+ auto newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE ,virtualBaseClass);
38343836 newMi->setScopePath (bClass->name ()+sep+srcMi->scopePath ());
38353837 if (ambiguous)
38363838 {
@@ -3919,6 +3921,56 @@ void ClassDefImpl::mergeMembersFromBaseClasses(bool mergeVirtualBaseClass)
39193921 }
39203922}
39213923
3924+ // See issue11260, referring to a variable in a base class will make doxygen
3925+ // add it as a member to the derived class, but this is not correct for non-private variables
3926+ // so we correct this here, now we know the inheritance hierarchy
3927+ void ClassDefImpl::hideDerivedVariablesInPython (ClassDefMutable *bClass)
3928+ {
3929+ // printf("hideDerivedVariableInPython()\n");
3930+ if (bClass)
3931+ {
3932+ const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap ();
3933+ MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap ;
3934+
3935+ // recurse up the inheritance hierarchy
3936+ for (const auto &bcd : bClass->baseClasses ())
3937+ {
3938+ hideDerivedVariablesInPython (toClassDefMutable (bcd.classDef ));
3939+ }
3940+
3941+ for (auto &srcMni : srcMnd) // for each member in a base class
3942+ {
3943+ // printf(" candidate(%s)\n",qPrint(srcMni->memberName()));
3944+ MemberNameInfo *dstMni=dstMnd.find (srcMni->memberName ());
3945+ if (dstMni) // that is also in this class
3946+ {
3947+ MemberNameInfo::iterator it;
3948+ // printf("%s member in %s and %s\n",qPrint(name()),qPrint(bClass->name()),qPrint(name()));
3949+ for (it=dstMni->begin ();it!=dstMni->end ();)
3950+ {
3951+ MemberDefMutable *dstMd = toMemberDefMutable ((*it)->memberDef ());
3952+ if (dstMd && dstMd->isVariable () && !dstMd->name ().startsWith (" __" ))
3953+ {
3954+ // printf(" hiding member %s\n",qPrint(dstMd->name()));
3955+ // hide a member variable if it is already defined in a base class, unless
3956+ // it is a __private variable
3957+ removeMemberFromLists (dstMd);
3958+ it = dstMni->erase (it);
3959+ }
3960+ else
3961+ {
3962+ ++it;
3963+ }
3964+ }
3965+ if (dstMni->empty ()) // if the list has become empty, remove the entry from the dictionary
3966+ {
3967+ dstMnd.del (srcMni->memberName ());
3968+ }
3969+ }
3970+ }
3971+ }
3972+ }
3973+
39223974/* !
39233975 * recursively merges the 'all members' lists of a class base
39243976 * with that of this class. Must only be called for classes without
@@ -3927,7 +3979,14 @@ void ClassDefImpl::mergeMembersFromBaseClasses(bool mergeVirtualBaseClass)
39273979void ClassDefImpl::mergeMembers ()
39283980{
39293981 if (m_impl->membersMerged ) return ;
3930- if (getLanguage ()==SrcLangExt::Python) return ; // python does not have member overloading, see issue 8480
3982+ if (getLanguage ()==SrcLangExt::Python)
3983+ {
3984+ for (const auto &bcd : baseClasses ())
3985+ {
3986+ ClassDefMutable *bClass=toClassDefMutable (bcd.classDef );
3987+ hideDerivedVariablesInPython (bClass);
3988+ }
3989+ }
39313990
39323991 // printf("> %s::mergeMembers()\n",qPrint(name()));
39333992
@@ -4519,20 +4578,20 @@ void ClassDefImpl::sortMemberLists()
45194578int ClassDefImpl::countMemberDeclarations (MemberListType lt,const ClassDef *inheritedFrom,
45204579 MemberListType lt2,bool invert,bool showAlways,ClassDefSet &visitedClasses) const
45214580{
4522- // printf("%s: countMemberDeclarations for %d and %d \n",qPrint(name()),lt.to_int (),lt2.to_int ());
4581+ // printf("%s: countMemberDeclarations for %s and %s \n",qPrint(name()),lt.to_string (),lt2.to_string ());
45234582 int count=0 ;
45244583 MemberList * ml = getMemberList (lt);
45254584 MemberList * ml2 = getMemberList (lt2);
45264585 if (getLanguage ()!=SrcLangExt::VHDL ) // use specific declarations function
45274586 {
45284587 if (ml)
45294588 {
4530- count+=ml->numDecMembers ();
4589+ count+=ml->numDecMembers (inheritedFrom );
45314590 // printf("-> ml=%d\n",ml->numDecMembers());
45324591 }
45334592 if (ml2)
45344593 {
4535- count+=ml2->numDecMembers ();
4594+ count+=ml2->numDecMembers (inheritedFrom );
45364595 // printf("-> ml2=%d\n",ml2->numDecMembers());
45374596 }
45384597 // also include grouped members that have their own section in the class (see bug 722759)
@@ -4601,8 +4660,8 @@ int ClassDefImpl::countInheritedDecMembers(MemberListType lt,
46014660 int inhCount = 0 ;
46024661 int count = countMembersIncludingGrouped (lt,inheritedFrom,FALSE );
46034662 bool process = count>0 ;
4604- // printf("%s: countInheritedDecMembers: lt=%d process=%d count=%d invert=%d\n",
4605- // qPrint(name()),lt.to_int (),process,count,invert);
4663+ // printf("%s: countInheritedDecMembers: lt=%s process=%d count=%d invert=%d\n",
4664+ // qPrint(name()),lt.to_string (),process,count,invert);
46064665 if ((process^invert) || showAlways)
46074666 {
46084667 for (const auto &ibcd : m_impl->inherits )
@@ -4613,8 +4672,8 @@ int ClassDefImpl::countInheritedDecMembers(MemberListType lt,
46134672 if (icd && icd->isLinkable ())
46144673 {
46154674 convertProtectionLevel (lt,ibcd.prot ,<1,<2);
4616- // printf("%s: convert %d ->(%d,%d ) prot=%d\n",
4617- // qPrint(icd->name()),lt.to_int (),lt1.to_int (),lt2.to_int (),ibcd.prot);
4675+ // printf("%s: convert %s ->(%s,%s ) prot=%d\n",
4676+ // qPrint(icd->name()),lt.to_string (),lt1.to_string (),lt2.to_string (),ibcd.prot);
46184677 if (visitedClasses.find (icd)==visitedClasses.end ())
46194678 {
46204679 visitedClasses.insert (icd); // guard for multiple virtual inheritance
@@ -4626,6 +4685,7 @@ int ClassDefImpl::countInheritedDecMembers(MemberListType lt,
46264685 }
46274686 }
46284687 }
4688+ // printf("%s: count=%d\n",qPrint(name()),inhCount);
46294689 return inhCount;
46304690}
46314691
@@ -4706,7 +4766,7 @@ int ClassDefImpl::countMembersIncludingGrouped(MemberListType lt,
47064766 }
47074767 }
47084768 // printf("%s:countMembersIncludingGrouped(lt=%s,%s)=%d\n",
4709- // qPrint(name()),qPrint(lt.to_string()),ml?qPrint(ml->listType().toLabel ()):"<none>",count);
4769+ // qPrint(name()),qPrint(lt.to_string()),ml?qPrint(ml->listType().to_string ()):"<none>",count);
47104770 return count;
47114771}
47124772
@@ -4777,18 +4837,18 @@ void ClassDefImpl::writeMemberDeclarations(OutputList &ol,ClassDefSet &visitedCl
47774837 }
47784838 else
47794839 {
4780- // printf("%s::writeMemberDeclarations(%s) ml=%p ml2=%p\n",qPrint(name()),qPrint(title),ml,ml2);
4840+ // printf("%s::writeMemberDeclarations(%s) ml=%p ml2=%p\n",qPrint(name()),qPrint(title),(void*) ml,(void*) ml2);
47814841 QCString tt = title, st = subTitle;
47824842 if (ml)
47834843 {
4784- // printf(" writeDeclarations type=%s count=%d\n",qPrint(lt.to_string()),ml->numDecMembers());
4844+ // printf(" writeDeclarations ml type=%s count=%d\n",qPrint(lt.to_string()),ml->numDecMembers(inheritedFrom ));
47854845 ml->writeDeclarations (ol,this ,nullptr ,nullptr ,nullptr ,nullptr ,tt,st,FALSE ,showInline,inheritedFrom,lt,true );
47864846 tt.clear ();
47874847 st.clear ();
47884848 }
47894849 if (ml2)
47904850 {
4791- // printf(" writeDeclarations type=%s count=%d\n",qPrint(lt2.to_string()),ml2->numDecMembers());
4851+ // printf(" writeDeclarations ml2 type=%s count=%d\n",qPrint(lt2.to_string()),ml2->numDecMembers(inheritedFrom ));
47924852 ml2->writeDeclarations (ol,this ,nullptr ,nullptr ,nullptr ,nullptr ,tt,st,FALSE ,showInline,inheritedFrom,lt,ml==nullptr );
47934853 }
47944854 bool inlineInheritedMembers = Config_getBool (INLINE_INHERITED_MEMB );
0 commit comments