diff options
Diffstat (limited to 'src/memberdef.cpp')
-rw-r--r-- | src/memberdef.cpp | 934 |
1 files changed, 909 insertions, 25 deletions
diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 1321692..34061f0 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -21,6 +21,165 @@ #include "doxygen.h" #include "util.h" #include "message.h" +#include "htmlhelp.h" +#include "language.h" + +//----------------------------------------------------------------------------- + +static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t) +{ + QCString result; + QCString clRealName=n; + int p=0,i; + if ((i=clRealName.find('<'))!=-1) + { + clRealName=clRealName.left(i); // strip template specialization + } + if ((i=clRealName.findRev("::"))!=-1) + { + clRealName=clRealName.right(clRealName.length()-i-2); + } + while ((i=s.find(clRealName,p))!=-1) + { + result+=s.mid(p,i-p); + uint j=clRealName.length()+i; + if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j)))) + { // add template names + //printf("Adding %s+%s\n",clRealName.data(),t.data()); + result+=clRealName+t; + } + else + { // template names already present + //printf("Adding %s\n",clRealName.data()); + result+=clRealName; + } + p=i+clRealName.length(); + } + result+=s.right(s.length()-p); + //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data()); + return result; +} + +static void writeDefArgumentList(OutputList &ol,ClassDef *cd, + const QCString &scopeName,MemberDef *md) +{ + ArgumentList *argList=md->argumentList(); + if (argList==0) return; // member has no function like argument list + ol.docify(" ("); // start argument list + Argument *a=argList->first(); + QCString cName; + if (md->scopeDefTemplateArguments()) + { + cName=tempArgListToString(md->scopeDefTemplateArguments()); + } + if (cd) + { + cName=cd->name(); + int il=cName.find('<'); + int ir=cName.findRev('>'); + if (il!=-1 && ir!=-1 && ir>il) + { + cName=cName.mid(il,ir-il+1); + //printf("1. cName=%s\n",cName.data()); + } + else if (cd->templateArguments()) + { + cName=tempArgListToString(cd->templateArguments()); + //printf("2. cName=%s\n",cName.data()); + } + else // no template specifier + { + cName.resize(0); + } + } + //printf("~~~ %s cName=%s\n",md->name().data(),cName.data()); + while (a) + { + QRegExp re(")("); + int vp; + if (!a->attrib.isEmpty()) + { + ol.docify(a->attrib+" "); + } + if ((vp=a->type.find(re))!=-1) // argument type is a function pointer + { + QCString n=a->type.left(vp); + if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName); + linkifyText(ol,scopeName,md->name(),n); + } + else // non-function pointer type + { + QCString n=a->type; + if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName); + linkifyText(ol,scopeName,md->name(),n); + } + if (a->name.length()>0) // argument has a name + { + ol.docify(" "); + ol.disable(OutputGenerator::Man); + ol.startEmphasis(); + ol.enable(OutputGenerator::Man); + ol.docify(a->name); + ol.disable(OutputGenerator::Man); + ol.endEmphasis(); + ol.enable(OutputGenerator::Man); + } + if (vp!=-1) // write the part of the argument type + // that comes after the name + { + linkifyText(ol,scopeName,md->name(),a->type.right(a->type.length()-vp)); + } + if (a->defval.length()>0) // write the default value + { + QCString n=a->defval; + if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName); + ol.docify(" = "); + linkifyText(ol,scopeName,md->name(),n); + } + a=argList->next(); + if (a) ol.docify(", "); // there are more arguments + } + ol.docify(")"); // end argument list + if (argList->constSpecifier) + { + ol.docify(" const"); + } + if (argList->volatileSpecifier) + { + ol.docify(" volatile"); + } +} + +static void writeTemplatePrefix(OutputList &ol,ArgumentList *al,bool br=TRUE) +{ + ol.docify("template<"); + Argument *a=al->first(); + while (a) + { + ol.docify(a->type); + ol.docify(a->name); + if (a->defval.length()!=0) + { + ol.docify(" = "); + ol.docify(a->defval); + } + a=al->next(); + if (a) ol.docify(", "); + } + ol.docify("> "); + if (br) + { + bool latexEnabled = ol.isEnabled(OutputGenerator::Latex); + bool manEnabled = ol.isEnabled(OutputGenerator::Man); + if (latexEnabled) ol.disable(OutputGenerator::Latex); + if (manEnabled) ol.disable(OutputGenerator::Man); + ol.lineBreak(); + if (latexEnabled) ol.enable(OutputGenerator::Latex); + if (manEnabled) ol.enable(OutputGenerator::Man); + } +} + +//----------------------------------------------------------------------------- /*! Creates a new member definition. * Members can be function/variables/enums/etc. inside a class or inside a @@ -59,11 +218,14 @@ MemberDef::MemberDef(const char *t,const char *na,const char *a,const char *e, enumScope=0; enumDeclList=0; scopeTAL=0; + membTAL=0; type=substituteClassNames(t); args=substituteClassNames(a); if (type.isNull()) decl=name()+args; else decl=type+" "+name()+args; declLine=0; defLine=0; + grpId=-1; + memberGroup=0; virt=v; prot=p; related=r; @@ -72,6 +234,10 @@ MemberDef::MemberDef(const char *t,const char *na,const char *a,const char *e, exception=e; eUsed=FALSE; proto=FALSE; + annScope=FALSE; + annMemb=0; + annUsed=FALSE; + indDepth=0; docEnumValues=FALSE; // copy function template arguments (if any) if (tal) @@ -203,49 +369,767 @@ QCString MemberDef::getOutputFileBase() const return "dummy"; } -void MemberDef::setScopeTemplateArguments(ArgumentList *tal) +static void copyArgumentList(const ArgumentList *src,ArgumentList *dst) +{ + ArgumentListIterator tali(*src); + Argument *a; + for (;(a=tali.current());++tali) + { + dst->append(new Argument(*a)); + } + dst->constSpecifier = src->constSpecifier; + dst->volatileSpecifier = src->volatileSpecifier; + dst->pureSpecifier = src->pureSpecifier; +} + +void MemberDef::setScopeDefTemplateArguments(ArgumentList *tal) { // copy function arguments (if any) if (tal) { scopeTAL = new ArgumentList; scopeTAL->setAutoDelete(TRUE); - ArgumentListIterator tali(*tal); - Argument *a; - for (;(a=tali.current());++tali) + copyArgumentList(tal,scopeTAL); + } +} + +void MemberDef::setMemberDefTemplateArguments(ArgumentList *tal) +{ + // copy function arguments (if any) + if (tal) + { + membTAL = new ArgumentList; + membTAL->setAutoDelete(TRUE); + copyArgumentList(tal,membTAL); + } +} + + + +void MemberDef::setGroupId(int groupId) +{ + grpId=groupId; + if (grpId!=-1) + { + memberGroup=memberGroupDict[grpId]; + memberGroup->insertMember(this); + } +} + +void MemberDef::writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd, + FileDef *fd,MemberGroup *mg) +{ + if (mg) + ol.writeObjectLink(0,mg->getOutputFileBase(), + anchor(),name()); + else if (nd) + ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(), + anchor(),name()); + else if (fd) + ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(), + anchor(),name()); + else + ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(), + anchor(),name()); +} + +void MemberDef::writeDeclaration(OutputList &ol,ClassDef *cd,NamespaceDef *nd,FileDef *fd, + int prevGroupId,bool inGroup) +{ + int i,l; + bool hasDocs=hasDocumentation(); + //if (cd) printf("MemberDef: %s in class %s annScope=%d annMemb=%p\n", + // name().data(),cd->name().data(),annScope,annMemb); + if (annScope) return; + if (!hasDocs && Config::hideMemberFlag) return; + if (Config::hideMemberFlag && documentation().isEmpty() && + !Config::briefMemDescFlag && !Config::repeatBriefFlag + ) return; + QCString type=typeString(); + // strip `static' keyword from type + if (type.left(7)=="static ") type=type.right(type.length()-7); + // strip `friend' keyword from type + if (type.left(7)=="friend ") type=type.right(type.length()-7); + QRegExp r("@[0-9]+"); + if ((i=r.match(type,0,&l))==-1 || !enumUsed()) + { + + if (Config::genTagFile.length()>0) + { + tagFile << name() << " " << anchor() << " \"" + << argsString() << "\"\n"; + } + + Definition *d=0; + if (cd) d=cd; else if (nd) d=nd; else d=fd; + QCString cname = d->name(); + QCString cfname = d->getOutputFileBase(); + + int gId = inGroup ? -1 : groupId(); + MemberGroup *mg = (gId!=prevGroupId && gId!=-1) ? memberGroupDict[gId] : 0; + const char *gHeader = 0; + const char *gFile = 0; + if (mg) + { + gHeader=mg->header(); + gFile=mg->getOutputFileBase(); + } + + if (!inGroup) + { + if (prevGroupId==-1 && gId!=-1) + { + ol.memberGroupSpacing(FALSE); + ol.memberGroupSeparator(); + } + else if (prevGroupId!=-1 && gId==-1) + { + ol.memberGroupSpacing(TRUE); + ol.memberGroupSeparator(); + } + else if (prevGroupId!=-1 && gId!=-1 && prevGroupId!=gId) + { + ol.memberGroupSpacing(TRUE); + ol.memberGroupSeparator(); + } + } + + HtmlHelp *htmlHelp=0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance(); + + // search for the last annonymous scope in the member type + ClassDef *annoClassDef=0; + while (i!=-1 && cname.find(type.mid(i,l))!=-1) + { + i=r.match(type,i+l,&l); + } + if (i!=-1) + { + // get the definition of the annonymous class that is + // the type of this member + annoClassDef=getClass(cname+"::"+type.mid(i,l)); + } + + // start a new member declaration + ol.startMemberItem(gId!=-1,((i!=-1) || annMemb) ? 1 : 0); + + // If there is no detailed description we need to write the anchor here. + bool detailsVisible = detailsAreVisible(); + if (!detailsVisible && !Config::extractAllFlag && !annMemb) + { + QCString doxyName=name().copy(); + if (!cname.isEmpty()) doxyName.prepend(cname+"::"); + ol.writeDoxyAnchor(cname,anchor(),doxyName); + ol.addToIndex(name(),cname); + ol.addToIndex(cname,name()); + if (hasHtmlHelp) + { + htmlHelp->addIndexItem(cname,name(),cfname,anchor()); + } + ol.docify("\n"); + } + //else if (!detailsVisible) // when extractAll it true we have to write + // // a index reference and label in LaTeX because + // // detailed section not shown in LaTeX + //{ + // ol.addToIndex(name(),cname); + // ol.addToIndex(cname,name()); + // ol.writeLatexLabel(cname,anchor()); + //} + + if (tArgList) + { + writeTemplatePrefix(ol,tArgList,FALSE); + } + + if (i!=-1 || annMemb) + { + int j; + for (j=0;j<indDepth;j++) + { + ol.writeNonBreakableSpace(); + } + } + + if (i!=-1) + { + //printf("scopeName=`%s' annonymous=`%s'\n", + // cname.data(),type.mid(i,l).data()); + + if (annoClassDef) + { + //printf("class found!\n"); + annoClassDef->writeDeclaration(ol); + ol.startMemberItem(gId!=-1,2); + int j; + for (j=0;j<indDepth;j++) + { + ol.writeNonBreakableSpace(); + } + ol.docify("}"); + ol.docify(type.right(type.length()-i-l).stripWhiteSpace()); + } + else + { + type = type.left(i) + " { ... } " + type.right(type.length()-i-l); + linkifyText(ol,cname,name(),type); + } + } + else + { + linkifyText(ol,cname,name(),type); + } + bool htmlOn = ol.isEnabled(OutputGenerator::Html); + if (htmlOn && Config::htmlAlignMemberFlag && type.length()>0) + { + ol.disable(OutputGenerator::Html); + } + if (!type.isEmpty()) ol.docify(" "); + if (htmlOn) + { + ol.enable(OutputGenerator::Html); + } + + if (annMemb) + { + bool latexOn = ol.isEnabled(OutputGenerator::Latex); + bool manOn = ol.isEnabled(OutputGenerator::Latex); + if (latexOn) ol.disable(OutputGenerator::Latex); + if (manOn) ol.disable(OutputGenerator::Man); + ol.writeNonBreakableSpace(); + if (latexOn) ol.enable(OutputGenerator::Latex); + if (manOn) ol.enable(OutputGenerator::Man); + } + else + ol.insertMemberAlign(); + + // write name + if (grpId!=-1) + { + if (annMemb) + { + //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor()); + annMemb->writeLink(ol,cd,nd,fd,inGroup ? memberGroup : 0); + annMemb->annUsed=annUsed=TRUE; + } + else + writeLink(ol,0,0,0,memberGroup); + //ol.writeBoldString(name()); + } + else if (isLinkable()) + { + if (annMemb) + { + //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor()); + annMemb->writeLink(ol,annMemb->memberClass(),nd,fd,inGroup ? memberGroup : 0); + annMemb->annUsed=annUsed=TRUE; + } + else + //printf("writeLink %s->%d\n",name.data(),hasDocumentation()); + writeLink(ol,cd,nd,fd,inGroup ? memberGroup : 0); + } + else // there is a brief member description and brief member + // descriptions are enabled or there is no detailed description. { - scopeTAL->append(new Argument(*a)); + if (annMemb) annMemb->annUsed=annUsed=TRUE; + ol.writeBoldString(name()); + } + + // if member template specifiers are not part of the name, but they are + // present, we add them + if (tArgList && !(name().find('<')!=-1 && name().find('>')!=-1) + && cd && cd->templateArguments()) + { + ol.docify(tempArgListToString(tArgList)); + } + + if (argsString()) + { + ol.writeString(" "); + //ol.docify(argsString()); + linkifyText(ol,cname,name(),argsString()); + } + + if (excpString()) + { + ol.writeString(" "); + ol.docify(excpString()); + } + + ol.endMemberItem(gId!=-1,gFile,gHeader,annoClassDef!=0 && indDepth==0); + + // write brief description + if (!briefDescription().isEmpty() && Config::briefMemDescFlag && + gId==-1 && !inGroup && !annMemb) + { + ol.startMemberDescription(); + parseDoc(ol,cname,name(),briefDescription()); + if (!documentation().isEmpty()) + { + ol.disableAllBut(OutputGenerator::Html); + ol.endEmphasis(); + ol.docify(" "); + ol.startTextLink(0,anchor()); + parseText(ol,theTranslator->trMore()); + ol.endTextLink(); + ol.startEmphasis(); + ol.enableAll(); + } + ol.endMemberDescription(); + ol.newParagraph(); } - scopeTAL->constSpecifier = tal->constSpecifier; - scopeTAL->volatileSpecifier = tal->volatileSpecifier; - scopeTAL->pureSpecifier = tal->pureSpecifier; } + warnIfUndocumented(); } -QCString MemberDef::getScopeTemplateNameString() + +void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,const char *scopeName, + MemberType m) { - QCString result; - if (!scopeTAL || scopeTAL->count()==0) return result; - result="<"; - Argument *a=scopeTAL->first(); - while (a) + bool hasDocs = detailsAreVisible(); + if ( + (memberType()==m && // filter member type + (Config::extractAllFlag || hasDocs) && + groupId()==-1 + ) || /* member is part of an annonymous scope that is the type of + * another member in the list. + */ + (!hasDocs && !briefDescription().isEmpty() && annUsed) + ) { - if (a->name.length()>0) // add template argument name + //printf("************* Writing docs for member %s\n",name().data()); + //if (Config::extractAllFlag && !hasDocs) + //{ + // ol.disable(OutputGenerator::Latex); // Latex cannot insert a pagebreak + // // if there are a lot of empty sections, + // // so we disable LaTeX for all empty + // // sections even if Config::extractAllFlag is enabled + //} + NamespaceDef *nd=getNamespace(); + ClassDef *cd=memberClass(); + FileDef *fd=getFileDef(); + Definition *d = 0; + if (cd) d=cd; else if (nd) d=nd; else d=fd; + QCString cname = d->name(); + QCString cfname = d->getOutputFileBase(); + + // get member name + QCString doxyName=name().copy(); + // prepend scope if there is any + if (scopeName) doxyName.prepend((QCString)scopeName+"::"); + + QCString def = definition(); + if (isEnumerate()) def.prepend("enum "); + MemberDef *smd; + if (isEnumValue() && def[0]=='@') def = def.right(def.length()-2); + int i=0,l,dummy; + QRegExp r("@[0-9]+"); + if (isEnumerate() && r.match(def,0,&l)!=-1) return; + if (isEnumValue() && (smd = getEnumScope()) + && r.match(smd->name(),0,&dummy)==-1) return; + + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + HtmlHelp *htmlHelp = 0; + if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance(); + + if ((isVariable() || isTypedef()) && (i=r.match(def,0,&l))!=-1) { - result+=a->name; + // find enum type an insert it in the definition + MemberListIterator vmli(*ml); + MemberDef *vmd; + bool found=FALSE; + for ( ; (vmd=vmli.current()) && !found ; ++vmli) + { + if (vmd->isEnumerate() && def.mid(i,l)==vmd->name()) + { + ol.startMemberDoc(cname,name(),anchor()); + if (hasHtmlHelp) + { + htmlHelp->addIndexItem(cname,name(),cfname,anchor()); + } + ol.writeDoxyAnchor(cname,anchor(),doxyName); + linkifyText(ol,scopeName,name(),def.left(i)); + ol+=*vmd->enumDecl(); + linkifyText(ol,scopeName,name(),def.right(def.length()-i-l)); + found=TRUE; + } + } + if (!found) // anonymous compound + { + //printf("Annonymous compound `%s'\n",cname.data()); + ol.startMemberDoc(cname,name(),anchor()); + if (hasHtmlHelp) + { + htmlHelp->addIndexItem(cname,name(),cfname,anchor()); + } + ol.writeDoxyAnchor(cname,anchor(),doxyName); + // strip annonymous compound names from definition + int si=def.find(' '),pi,ei=i+l; + if (si==-1) si=0; + while ((pi=r.match(def,i+l,&l))!=-1) ei=i=pi+l; + // first si characters of def contain compound type name + ol.docify(def.left(si)); + ol.docify(" { ... } "); + // last ei characters of def contain pointer/reference specifiers + linkifyText(ol,scopeName,name(),def.right(def.length()-ei)); + } } - else // extract name from type + else { - int i=a->type.length()-1; - while (i>=0 && isId(a->type.at(i))) i--; - if (i>0) + ol.startMemberDoc(cname,name(),anchor()); + if (hasHtmlHelp) + { + htmlHelp->addIndexItem(cname,name(),cfname,anchor()); + } + ol.writeDoxyAnchor(cname,anchor(),doxyName); + + ArgumentList *scopeAl=scopeDefTemplateArguments(); + if (scopeAl==0 && cd) scopeAl=cd->templateArguments(); + + ArgumentList *membAl=memberDefTemplateArguments(); + if (membAl==0) membAl=templateArguments(); + + //if (cd && (!isRelated() || templateArguments()!=0) && + // ((al=scopeDefTemplateArguments()) || (al=cd->templateArguments())) + // ) + if (scopeAl) // class template prefix + { + writeTemplatePrefix(ol,scopeAl); + } + if (scopeAl && membAl) ol.docify(" "); + + if (membAl) // function template prefix { - result+=a->type.right(a->type.length()-i-1); + writeTemplatePrefix(ol,membAl); } + if (cd) + { + QCString cName=cd->name(); + //printf("cName=%s\n",cName.data()); + int il=cName.find('<'); + int ir=cName.findRev('>'); + if (il!=-1 && ir!=-1 && ir>il) + { + def=addTemplateNames(def, + cName.left(il), /* class without template spec */ + cName.mid(il,ir-il+1) /* templ spec */ + ); + } + else if (scopeAl) + { + def=addTemplateNames(def,cName,tempArgListToString(scopeAl)); + } + } + linkifyText(ol,scopeName,name(),def); + writeDefArgumentList(ol,cd,scopeName,this); + if (excpString()) + { + ol.docify(" "); + linkifyText(ol,scopeName,name(),excpString()); + } + } + + Specifier virt=virtualness(); + MemberDef *rmd=reimplements(); + while (rmd && virt==Normal) + { + virt = rmd->virtualness()==Normal ? Normal : Virtual; + rmd = rmd->reimplements(); + } + + if (isStatic() || protection()!=Public || + virt!=Normal || isSignal() || isFriend() || + isRelated() || isSlot() + ) + { + // write the member specifier list + ol.writeLatexSpacing(); + ol.startTypewriter(); + ol.docify(" ["); + QStrList sl; + if (isFriend()) sl.append("friend"); + else if (isRelated()) sl.append("related"); + else + { + if (isStatic()) sl.append("static"); + if (protection()==Protected) sl.append("protected"); + else if (protection()==Private) sl.append("private"); + if (virt==Virtual) sl.append("virtual"); + else if (virt==Pure) sl.append("pure virtual"); + if (isSignal()) sl.append("signal"); + if (isSlot()) sl.append("slot"); + } + const char *s=sl.first(); + while (s) + { + ol.docify(s); + s=sl.next(); + if (s) ol.docify(", "); + } + ol.docify("]"); + ol.endTypewriter(); + } + ol.endMemberDoc(); + ol.startIndent(); + ol.newParagraph(); + + if (!briefDescription().isEmpty() && + (Config::repeatBriefFlag || + (!Config::briefMemDescFlag && documentation().isEmpty()) + ) || !annMemb + ) + { + parseDoc(ol,scopeName,name(),briefDescription()); + ol.newParagraph(); + } + if (!documentation().isEmpty()) + { + parseDoc(ol,scopeName,name(),documentation()+"\n"); + } + if (!bodyCode().isEmpty()) + { + ol.startCodeFragment(); + parseCode(ol,scopeName,bodyCode(),FALSE,0); + ol.endCodeFragment(); + } + + if (isEnumerate()) + { + bool first=TRUE; + MemberList *fmdl=enumFieldList(); + if (fmdl) + { + MemberDef *fmd=fmdl->first(); + while (fmd) + { + if (fmd->isLinkable()) + { + if (first) + { + ol.newParagraph(); + ol.startBold(); + parseText(ol,theTranslator->trEnumerationValues()); + //ol.writeBoldString("Enumeration values:"); + ol.docify(":"); + ol.endBold(); + ol.startItemList(); + } + ol.writeDoxyAnchor(cname,fmd->anchor(),fmd->name()); + ol.addToIndex(fmd->name(),cname); + ol.addToIndex(cname,fmd->name()); + if (Config::generateHtml && Config::htmlHelpFlag) + { + HtmlHelp::getInstance()->addIndexItem(cname,fmd->name(),cfname,fmd->anchor()); + } + ol.writeListItem(); + first=FALSE; + ol.startBold(); + ol.docify(fmd->name()); + ol.endBold(); + ol.newParagraph(); + + if (!fmd->briefDescription().isEmpty()) + { + parseDoc(ol,scopeName,fmd->name(),fmd->briefDescription()); + ol.newParagraph(); + } + if (!fmd->documentation().isEmpty()) + { + parseDoc(ol,scopeName,fmd->name(),fmd->documentation()+"\n"); + } + ol.disable(OutputGenerator::Man); + ol.newParagraph(); + ol.enable(OutputGenerator::Man); + } + fmd=fmdl->next(); + } + } + if (!first) { ol.endItemList(); ol.writeChar('\n'); } + } + + MemberDef *bmd=reimplements(); + ClassDef *bcd=0; + if (bmd && (bcd=bmd->memberClass())) + { + if (virt!=Normal) // search for virtual member of the deepest base class + { + MemberDef *lastBmd=bmd; + while (lastBmd) + { + ClassDef *lastBcd = lastBmd->memberClass(); + if (lastBmd->virtualness()!=Normal && + lastBmd->isLinkable() && + lastBcd->isLinkable() + ) { bmd=lastBmd; bcd=lastBcd; } + lastBmd=lastBmd->reimplements(); + } + } + // write class that contains a member that is reimplemented by this one + if (bcd->isLinkable()) + { + ol.newParagraph(); + + QCString reimplFromLine = theTranslator->trReimplementedFromList(1); + int markerPos = reimplFromLine.find("@0"); + if (markerPos!=-1) // should always pass this. + { + parseText(ol,reimplFromLine.left(markerPos)); //text left from marker + if (bmd->isLinkable()) // replace marker with link + { + ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(), + bmd->anchor(),bcd->name()); + if ( bcd->isLinkableInProject()) + { + ol.writePageRef(bcd->name(),bmd->anchor()); + } + } + else + { + ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(), + 0,bcd->name()); + if (bcd->isLinkableInProject()) + { + ol.writePageRef(bcd->name(),0); + } + } + parseText(ol,reimplFromLine.right( + reimplFromLine.length()-markerPos-2)); // text right from marker + + } + else + { + err("Error: translation error: no marker in trReimplementsFromList()\n"); + } + } + + //ol.writeString("."); } - a=scopeTAL->next(); - if (a) result+=", "; + MemberList *bml=reimplementedBy(); + if (bml) + { + MemberListIterator mli(*bml); + MemberDef *bmd=0; + uint count=0; + ClassDef *bcd=0; + for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->memberClass());++mli) + { + // count the members that directly inherit from md and for + // which the member and class are visible in the docs. + if ( bmd->isLinkable() && bcd->isLinkable() ) count++; + } + if (count>0) + { + mli.toFirst(); + // write the list of classes that overwrite this member + ol.newParagraph(); + //parseText(ol,theTranslator->trReimplementedIn()); + //ol.writeString("Reimplemented in "); + //ol.docify(" "); + + QCString reimplInLine = + theTranslator->trReimplementedInList(count); + QRegExp marker("@[0-9]+"); + int index=0,newIndex,matchLen; + // now replace all markers in reimplInLine with links to the classes + while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1) + { + parseText(ol,reimplInLine.mid(index,newIndex-index)); + bool ok; + uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok); + //bmd=bml->at(entryIndex); + + count=0; + // find the entryIndex-th documented entry in the inheritance list. + for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->memberClass());++mli) + { + if ( bmd->isLinkable() && bcd->isLinkable()) + { + if (count==entryIndex) break; + count++; + } + } + + if (ok && bcd && bmd) // write link for marker + { + //if (bmd->hasDocumentation() && + // (bmd->protection()!=Private || Config::extractPrivateFlag) + // ) + //{ + ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(), + bmd->anchor(),bcd->name()); + if (bcd->isLinkableInProject()) + { + ol.writePageRef(bcd->name(),bmd->anchor()); + } + //} + //else + //{ + // ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(), + // 0,bcd->name()); + // if (!bcd->isReference() && bcd->isVisible()) + // ol.writePageRef(bcd->name(),0); + //} + } + ++mli; + index=newIndex+matchLen; + } + parseText(ol,reimplInLine.right(reimplInLine.length()-index)); + + } + } + // write the list of examples that use this member + if (hasExamples()) + { + ol.startDescList(); + ol.startBold(); + parseText(ol,theTranslator->trExamples()+": "); + //ol.writeBoldString("Examples: "); + ol.endBold(); + ol.endDescTitle(); + ol.writeDescItem(); + writeExample(ol,getExampleList()); + //ol.endDescItem(); + ol.endDescList(); + } + ol.endIndent(); + // enable LaTeX again + //if (Config::extractAllFlag && !hasDocs) ol.enable(OutputGenerator::Latex); + } - result+=">"; - return result; +} + +void MemberDef::warnIfUndocumented() +{ + if (memberGroup) return; + ClassDef *cd = memberClass(); + NamespaceDef *nd = getNamespace(); + FileDef *fd = getFileDef(); + Definition *d=0; + const char *t=0; + if (cd) + t="class", d=cd; + else if (nd) + t="namespace", d=nd; + else + t="file", d=fd; + + if (d && d->isLinkable() && !isLinkable() && name().find('@')==-1) + warn("Warning: Member %s of %s %s is not documented\n", + name().data(),t,d->name().data()); +} + + +bool MemberDef::isLinkableInProject() +{ + return !name().isEmpty() && name().at(0)!='@' && + ((hasDocumentation() && !isReference()) || + (memberGroup && memberGroup->isLinkableInProject()) + ) && + (prot!=Private || Config::extractPrivateFlag || isFriend()); +} + +bool MemberDef::isLinkable() +{ + return isLinkableInProject() || isReference(); } |