summaryrefslogtreecommitdiffstats
path: root/src/memberdef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/memberdef.cpp')
-rw-r--r--src/memberdef.cpp934
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();
}