From c5ec90d1780c95cd699225ff16627e96f993b179 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Tue, 17 Dec 2013 21:15:27 +0100 Subject: Template and context enhancements --- src/classdef.cpp | 220 ++----------------- src/context.cpp | 597 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/context.h | 52 +++++ src/doxygen.cpp | 3 +- src/filedef.cpp | 2 +- src/groupdef.cpp | 2 +- src/memberdef.cpp | 63 ++++-- src/memberdef.h | 1 + src/memberlist.cpp | 2 +- src/memberlist.h | 2 +- src/namespacedef.cpp | 2 +- src/template.cpp | 137 +++++++++--- src/template.h | 7 - src/util.cpp | 190 ++++++++++++++++ src/util.h | 7 + 15 files changed, 978 insertions(+), 309 deletions(-) diff --git a/src/classdef.cpp b/src/classdef.cpp index 53eabc2..6404431 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -337,7 +337,14 @@ QCString ClassDef::displayName(bool includeScope) const // n = n.left(n.length()-2); //} //printf("ClassDef::displayName()=%s\n",n.data()); - return n; + if (n.find('@')!=-1) + { + return removeAnonymousScopes(n); + } + else + { + return n; + } } // inserts a base/super class in the inheritance list @@ -1542,7 +1549,7 @@ void ClassDef::writeSummaryLinks(OutputList &ol) MemberList * ml = getMemberList(lmd->type); if (ml && ml->declVisible()) { - ol.writeSummaryLink(0,ml->listTypeAsString(ml->listType()),lmd->title(lang),first); + ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); first=FALSE; } } @@ -2526,23 +2533,14 @@ bool ClassDef::hasNonReferenceSuperClass() void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup, ClassDef *inheritedFrom,const char *inheritId) { - //ol.insertMemberAlign(); //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup); - //if (inGroup && md && md->getClassDef()==this) return; - ol.docify(compoundTypeString()); - int ri=name().findRev("::"); - if (ri==-1) ri=name().length(); - QCString cn=name().right(name().length()-ri-2); - if (!cn.isEmpty() && cn.at(0)!='@' && md) + QCString cn = displayName(FALSE); + if (!cn.isEmpty()) { - if (cn.right(2)=="-p" /*|| cn.right(2)=="-g"*/) - { - cn = cn.left(cn.length()-2); - } ol.docify(" "); - if (isLinkable()) + if (md && isLinkable()) { ol.writeObjectLink(0,0,md->anchor(),cn); } @@ -3929,196 +3927,6 @@ void ClassDef::sortMemberLists() } } - -/** Computes for a given list type \a inListType, which are the - * the corresponding list type(s) in the base class that are to be - * added to this list. - * - * So for public inheritance, the mapping is 1-1, so outListType1=inListType - * Private members are to be hidden completely. - * - * For protected inheritance, both protected and public members of the - * base class should be joined in the protected member section. - * - * For private inheritance, both protected and public members of the - * base class should be joined in the private member section. - */ -static void convertProtectionLevel( - MemberListType inListType, - Protection inProt, - int *outListType1, - int *outListType2 - ) -{ - static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE"); - // default representing 1-1 mapping - *outListType1=inListType; - *outListType2=-1; - if (inProt==Public) - { - switch (inListType) // in the private section of the derived class, - // the private section of the base class should not - // be visible - { - case MemberListType_priMethods: - case MemberListType_priStaticMethods: - case MemberListType_priSlots: - case MemberListType_priAttribs: - case MemberListType_priStaticAttribs: - case MemberListType_priTypes: - *outListType1=-1; - *outListType2=-1; - break; - default: - break; - } - } - else if (inProt==Protected) // Protected inheritance - { - switch (inListType) // in the protected section of the derived class, - // both the public and protected members are shown - // as protected - { - case MemberListType_pubMethods: - case MemberListType_pubStaticMethods: - case MemberListType_pubSlots: - case MemberListType_pubAttribs: - case MemberListType_pubStaticAttribs: - case MemberListType_pubTypes: - case MemberListType_priMethods: - case MemberListType_priStaticMethods: - case MemberListType_priSlots: - case MemberListType_priAttribs: - case MemberListType_priStaticAttribs: - case MemberListType_priTypes: - *outListType1=-1; - *outListType2=-1; - break; - - case MemberListType_proMethods: - *outListType2=MemberListType_pubMethods; - break; - case MemberListType_proStaticMethods: - *outListType2=MemberListType_pubStaticMethods; - break; - case MemberListType_proSlots: - *outListType2=MemberListType_pubSlots; - break; - case MemberListType_proAttribs: - *outListType2=MemberListType_pubAttribs; - break; - case MemberListType_proStaticAttribs: - *outListType2=MemberListType_pubStaticAttribs; - break; - case MemberListType_proTypes: - *outListType2=MemberListType_pubTypes; - break; - default: - break; - } - } - else if (inProt==Private) - { - switch (inListType) // in the private section of the derived class, - // both the public and protected members are shown - // as private - { - case MemberListType_pubMethods: - case MemberListType_pubStaticMethods: - case MemberListType_pubSlots: - case MemberListType_pubAttribs: - case MemberListType_pubStaticAttribs: - case MemberListType_pubTypes: - case MemberListType_proMethods: - case MemberListType_proStaticMethods: - case MemberListType_proSlots: - case MemberListType_proAttribs: - case MemberListType_proStaticAttribs: - case MemberListType_proTypes: - *outListType1=-1; - *outListType2=-1; - break; - - case MemberListType_priMethods: - if (extractPrivate) - { - *outListType1=MemberListType_pubMethods; - *outListType2=MemberListType_proMethods; - } - else - { - *outListType1=-1; - *outListType2=-1; - } - break; - case MemberListType_priStaticMethods: - if (extractPrivate) - { - *outListType1=MemberListType_pubStaticMethods; - *outListType2=MemberListType_proStaticMethods; - } - else - { - *outListType1=-1; - *outListType2=-1; - } - break; - case MemberListType_priSlots: - if (extractPrivate) - { - *outListType1=MemberListType_pubSlots; - *outListType1=MemberListType_proSlots; - } - else - { - *outListType1=-1; - *outListType2=-1; - } - break; - case MemberListType_priAttribs: - if (extractPrivate) - { - *outListType1=MemberListType_pubAttribs; - *outListType2=MemberListType_proAttribs; - } - else - { - *outListType1=-1; - *outListType2=-1; - } - break; - case MemberListType_priStaticAttribs: - if (extractPrivate) - { - *outListType1=MemberListType_pubStaticAttribs; - *outListType2=MemberListType_proStaticAttribs; - } - else - { - *outListType1=-1; - *outListType2=-1; - } - break; - case MemberListType_priTypes: - if (extractPrivate) - { - *outListType1=MemberListType_pubTypes; - *outListType2=MemberListType_proTypes; - } - else - { - *outListType1=-1; - *outListType2=-1; - } - break; - default: - break; - } - } - //printf("convertProtectionLevel(type=%d prot=%d): %d,%d\n", - // inListType,inProt,*outListType1,*outListType2); -} - int ClassDef::countMemberDeclarations(MemberListType lt,ClassDef *inheritedFrom, int lt2,bool invert,bool showAlways,QPtrDict *visitedClasses) { @@ -4157,7 +3965,7 @@ int ClassDef::countInheritedDecMembers(MemberListType lt, QPtrDict *visitedClasses) { int inhCount = 0; - int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE)>0; + int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE); bool process = count>0; //printf("%s: countInheritedDecMembers: lt=%d process=%d count=%d invert=%d\n", // name().data(),lt,process,count,invert); @@ -4297,7 +4105,7 @@ void ClassDef::writeInheritedMemberDeclarations(OutputList &ol, { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); - int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE)>0; + int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE); bool process = count>0; //printf("%s: writeInheritedMemberDec: lt=%d process=%d invert=%d always=%d\n", // name().data(),lt,process,invert,showAlways); diff --git a/src/context.cpp b/src/context.cpp index 7e14c8b..e573dde 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -22,6 +22,10 @@ #include "example.h" #include "membername.h" #include "parserintf.h" +#include "portable.h" + +// TODO: pass the current file to Dot*::writeGraph, so the user can put dot graphs in other +// files as well struct ContextGlobals { @@ -61,7 +65,7 @@ template class ScopedPtr void reset(T *p=0) { if (p!=m_ptr) { delete m_ptr; m_ptr = p; } } }; -// iterator support +/** @brief Template List iterator support */ template class GenericConstIterator : public TemplateListIntf::ConstIterator { @@ -104,7 +108,7 @@ class GenericConstIterator : public TemplateListIntf::ConstIterator //------------------------------------------------------------------------ -// standard list implementation +/** @brief standard template list implementation */ template class GenericNodeListContext : public TemplateListIntf { @@ -337,7 +341,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.generateAt should take two parameters, got %d!\n",args.count()); + err("tr.generateAt should take two arguments, got %d!\n",args.count()); } return TemplateVariant(); } @@ -349,7 +353,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.inheritanceDiagramFor should take one parameter, got %d!\n",args.count()); + err("tr.inheritanceDiagramFor should take one argument, got %d!\n",args.count()); } return TemplateVariant(); } @@ -361,7 +365,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.collaborationDiagramFor should take one parameter, got %d!\n",args.count()); + err("tr.collaborationDiagramFor should take one argument, got %d!\n",args.count()); } return TemplateVariant(); } @@ -373,7 +377,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.inheritsList should take one integer parameter, got %d!\n",args.count()); + err("tr.inheritsList should take one integer argument, got %d!\n",args.count()); } return TemplateVariant(); } @@ -385,7 +389,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.inheritedByList should take one integer parameter, got %d!\n",args.count()); + err("tr.inheritedByList should take one integer argument, got %d!\n",args.count()); } return TemplateVariant(); } @@ -397,7 +401,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.*List should take one integer parameter, got %d!\n",args.count()); + err("tr.*List should take one integer argument, got %d!\n",args.count()); } return TemplateVariant(); } @@ -409,7 +413,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.implementedBy should take one integer parameter, got %d!\n",args.count()); + err("tr.implementedBy should take one integer argument, got %d!\n",args.count()); } return TemplateVariant(); } @@ -421,7 +425,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.reimplementedBy should take one integer parameter, got %d!\n",args.count()); + err("tr.reimplementedBy should take one integer argument, got %d!\n",args.count()); } return TemplateVariant(); } @@ -433,7 +437,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.sourceRefs should take one integer parameter, got %d\n",args.count()); + err("tr.sourceRefs should take one integer argument, got %d\n",args.count()); } return TemplateVariant(); } @@ -445,7 +449,7 @@ class TranslateContext::Private : public PropertyMapper } else { - err("tr.sourceRefBys should take one integer parameter, got %d\n",args.count()); + err("tr.sourceRefBys should take one integer argument, got %d\n",args.count()); } return TemplateVariant(); } @@ -657,6 +661,14 @@ class TranslateContext::Private : public PropertyMapper { return theTranslator->trCallerGraph(); } + TemplateVariant inheritedFrom() const + { + return theTranslator->trInheritedFrom("@0","@1"); + } + TemplateVariant additionalInheritedMembers() const + { + return theTranslator->trAdditionalInheritedMembers(); + } Private() { //%% string generatedBy @@ -745,6 +757,10 @@ class TranslateContext::Private : public PropertyMapper addProperty("callGraph", this,&Private::callGraph); //%% string callerGraph addProperty("callerGraph", this,&Private::callerGraph); + //%% markerstring inheritedFrom + addProperty("inheritedFrom", this,&Private::inheritedFrom); + //%% string addtionalInheritedMembers + addProperty("additionalInheritedMembers",this,&Private::additionalInheritedMembers); m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); @@ -845,6 +861,8 @@ class DefinitionContext : public PropertyMapper addProperty("language",this,&DefinitionContext::language); //%% string sourceDef: A link to the source definition addProperty("sourceDef",this,&DefinitionContext::sourceDef); + //%% list[Definition] navigationPath: Breadcrumb navigation path to this item + addProperty("navigationPath",this,&DefinitionContext::navigationPath); if (m_def && !m_def->getSourceFileBase().isEmpty()) { @@ -988,14 +1006,43 @@ class DefinitionContext : public PropertyMapper return FALSE; } } + void fillPath(Definition *def,TemplateList *list) const + { + Definition *outerScope = def->getOuterScope(); + Definition::DefType type = def->definitionType(); + if (outerScope && outerScope!=Doxygen::globalScope) + { + fillPath(outerScope,list); + } + else if (type==Definition::TypeFile && ((const FileDef*)def)->getDirDef()) + { + fillPath(((const FileDef*)def)->getDirDef(),list); + } + NavPathElemContext *elem = new NavPathElemContext(def); + list->append(elem); + m_cache.navPathElems.append(elem); + } + TemplateVariant navigationPath() const + { + if (!m_cache.navPath) + { + TemplateList *list = new TemplateList; + fillPath(m_def,list); + m_cache.navPath.reset(list); + } + return m_cache.navPath.get(); + } private: Definition *m_def; struct Cachable { + Cachable() { navPathElems.setAutoDelete(TRUE); } ScopedPtr details; ScopedPtr brief; ScopedPtr inbodyDocs; + ScopedPtr navPath; + QList navPathElems; }; mutable Cachable m_cache; TemplateList m_sourceDef; @@ -1140,9 +1187,11 @@ class ClassContext::Private : public DefinitionContext addProperty("templateDecls", this,&Private::templateDecls); addProperty("typeConstraints", this,&Private::typeConstraints); addProperty("examples", this,&Private::examples); + addProperty("members", this,&Private::members); addProperty("allMembersList", this,&Private::allMembersList); addProperty("allMembersFileName", this,&Private::allMembersFileName); addProperty("memberGroups", this,&Private::memberGroups); + addProperty("additionalInheritedMembers",this,&Private::additionalInheritedMembers); } TemplateVariant title() const { @@ -1213,7 +1262,7 @@ class ClassContext::Private : public DefinitionContext FTextStream t(&result); cg->writeGraph(t,BITMAP, g_globals.outputDir, - m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, + g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,TRUE,g_globals.dynSectionId ); } @@ -1258,7 +1307,7 @@ class ClassContext::Private : public DefinitionContext FTextStream t(&result); cg->writeGraph(t,BITMAP, g_globals.outputDir, - m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, + g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,TRUE,g_globals.dynSectionId ); } @@ -1298,14 +1347,14 @@ class ClassContext::Private : public DefinitionContext return m_cache.inheritedByList.get(); } TemplateVariant getMemberList(ScopedPtr &list, - MemberListType type,const char *title) const + MemberListType type,const char *title,bool detailed=FALSE) const { if (!list) { MemberList *ml = m_classDef->getMemberList(type); if (ml) { - list.reset(new MemberListInfoContext(m_classDef,relPathAsString(),ml,title)); + list.reset(new MemberListInfoContext(m_classDef,relPathAsString(),ml,title,detailed)); } } if (list) @@ -1443,43 +1492,43 @@ class ClassContext::Private : public DefinitionContext } TemplateVariant detailedTypedefs() const { - return getMemberList(m_cache.detailedTypedefs,MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation()); + return getMemberList(m_cache.detailedTypedefs,MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation(),TRUE); } TemplateVariant detailedEnums() const { - return getMemberList(m_cache.detailedEnums,MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation()); + return getMemberList(m_cache.detailedEnums,MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation(),TRUE); } TemplateVariant detailedServices() const { - return getMemberList(m_cache.detailedServices,MemberListType_serviceMembers,theTranslator->trServices()); + return getMemberList(m_cache.detailedServices,MemberListType_serviceMembers,theTranslator->trServices(),TRUE); } TemplateVariant detailedInterfaces() const { - return getMemberList(m_cache.detailedInterfaces,MemberListType_interfaceMembers,theTranslator->trInterfaces()); + return getMemberList(m_cache.detailedInterfaces,MemberListType_interfaceMembers,theTranslator->trInterfaces(),TRUE); } TemplateVariant detailedConstructors() const { - return getMemberList(m_cache.detailedConstructors,MemberListType_constructors,theTranslator->trConstructorDocumentation()); + return getMemberList(m_cache.detailedConstructors,MemberListType_constructors,theTranslator->trConstructorDocumentation(),TRUE); } TemplateVariant detailedMethods() const { - return getMemberList(m_cache.detailedMethods,MemberListType_functionMembers,theTranslator->trMemberFunctionDocumentation()); + return getMemberList(m_cache.detailedMethods,MemberListType_functionMembers,theTranslator->trMemberFunctionDocumentation(),TRUE); } TemplateVariant detailedRelated() const { - return getMemberList(m_cache.detailedRelated,MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation()); + return getMemberList(m_cache.detailedRelated,MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation(),TRUE); } TemplateVariant detailedVariables() const { - return getMemberList(m_cache.detailedVariables,MemberListType_variableMembers,theTranslator->trMemberDataDocumentation()); + return getMemberList(m_cache.detailedVariables,MemberListType_variableMembers,theTranslator->trMemberDataDocumentation(),TRUE); } TemplateVariant detailedProperties() const { - return getMemberList(m_cache.detailedProperties,MemberListType_propertyMembers,theTranslator->trPropertyDocumentation()); + return getMemberList(m_cache.detailedProperties,MemberListType_propertyMembers,theTranslator->trPropertyDocumentation(),TRUE); } TemplateVariant detailedEvents() const { - return getMemberList(m_cache.detailedEvents,MemberListType_eventMembers,theTranslator->trEventDocumentation()); + return getMemberList(m_cache.detailedEvents,MemberListType_eventMembers,theTranslator->trEventDocumentation(),TRUE); } TemplateVariant nestedClasses() const { @@ -1584,6 +1633,59 @@ class ClassContext::Private : public DefinitionContext } return m_cache.examples.get(); } + void addMembers(ClassDef *cd,MemberListType lt) const + { + MemberList *ml = cd->getMemberList(lt); + if (ml) + { + MemberListIterator li(*ml); + const MemberDef *md; + for (li.toFirst();(md=li.current());++li) + { + if (md->isBriefSectionVisible()) + { + m_cache.allMembers.append(md); + } + } + } + } + TemplateVariant members() const + { + if (!m_cache.members) + { + addMembers(m_classDef,MemberListType_pubTypes); + addMembers(m_classDef,MemberListType_services); + addMembers(m_classDef,MemberListType_interfaces); + addMembers(m_classDef,MemberListType_pubSlots); + addMembers(m_classDef,MemberListType_signals); + addMembers(m_classDef,MemberListType_pubMethods); + addMembers(m_classDef,MemberListType_pubStaticMethods); + addMembers(m_classDef,MemberListType_pubAttribs); + addMembers(m_classDef,MemberListType_pubStaticAttribs); + addMembers(m_classDef,MemberListType_proTypes); + addMembers(m_classDef,MemberListType_proSlots); + addMembers(m_classDef,MemberListType_proMethods); + addMembers(m_classDef,MemberListType_proStaticMethods); + addMembers(m_classDef,MemberListType_proAttribs); + addMembers(m_classDef,MemberListType_proStaticAttribs); + addMembers(m_classDef,MemberListType_pacTypes); + addMembers(m_classDef,MemberListType_pacMethods); + addMembers(m_classDef,MemberListType_pacStaticMethods); + addMembers(m_classDef,MemberListType_pacAttribs); + addMembers(m_classDef,MemberListType_pacStaticAttribs); + addMembers(m_classDef,MemberListType_properties); + addMembers(m_classDef,MemberListType_events); + addMembers(m_classDef,MemberListType_priTypes); + addMembers(m_classDef,MemberListType_priSlots); + addMembers(m_classDef,MemberListType_priMethods); + addMembers(m_classDef,MemberListType_priStaticMethods); + addMembers(m_classDef,MemberListType_priAttribs); + addMembers(m_classDef,MemberListType_priStaticAttribs); + addMembers(m_classDef,MemberListType_related); + m_cache.members.reset(new MemberListContext(&m_cache.allMembers)); + } + return m_cache.members.get(); + } TemplateVariant allMembersList() const { if (!m_cache.allMembersList && m_classDef->memberNameInfoSDict()) @@ -1616,6 +1718,48 @@ class ClassContext::Private : public DefinitionContext } return m_cache.memberGroups.get(); } + TemplateVariant additionalInheritedMembers() const + { + if (!m_cache.additionalInheritedMembers) + { + InheritedMemberInfoListContext *ctx = new InheritedMemberInfoListContext; + ctx->addMemberList(m_classDef,MemberListType_pubTypes,theTranslator->trPublicTypes()); + ctx->addMemberList(m_classDef,MemberListType_services,theTranslator->trServices()); + ctx->addMemberList(m_classDef,MemberListType_interfaces,theTranslator->trInterfaces()); + ctx->addMemberList(m_classDef,MemberListType_pubSlots,theTranslator->trPublicSlots()); + ctx->addMemberList(m_classDef,MemberListType_signals,theTranslator->trSignals()); + ctx->addMemberList(m_classDef,MemberListType_pubMethods, + m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trInstanceMethods() + : theTranslator->trPublicMembers()); + ctx->addMemberList(m_classDef,MemberListType_pubStaticMethods, + m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trClassMethods() + : theTranslator->trStaticPublicMembers()); + ctx->addMemberList(m_classDef,MemberListType_pubAttribs,theTranslator->trPublicAttribs()); + ctx->addMemberList(m_classDef,MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs()); + ctx->addMemberList(m_classDef,MemberListType_proTypes,theTranslator->trProtectedTypes()); + ctx->addMemberList(m_classDef,MemberListType_proSlots,theTranslator->trProtectedSlots()); + ctx->addMemberList(m_classDef,MemberListType_proMethods,theTranslator->trProtectedMembers()); + ctx->addMemberList(m_classDef,MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers()); + ctx->addMemberList(m_classDef,MemberListType_proAttribs,theTranslator->trProtectedAttribs()); + ctx->addMemberList(m_classDef,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs()); + ctx->addMemberList(m_classDef,MemberListType_pacTypes,theTranslator->trPackageTypes()); + ctx->addMemberList(m_classDef,MemberListType_pacMethods,theTranslator->trPackageMembers()); + ctx->addMemberList(m_classDef,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers()); + ctx->addMemberList(m_classDef,MemberListType_pacAttribs,theTranslator->trPackageAttribs()); + ctx->addMemberList(m_classDef,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs()); + ctx->addMemberList(m_classDef,MemberListType_properties,theTranslator->trProperties()); + ctx->addMemberList(m_classDef,MemberListType_events,theTranslator->trEvents()); + ctx->addMemberList(m_classDef,MemberListType_priTypes,theTranslator->trPrivateTypes()); + ctx->addMemberList(m_classDef,MemberListType_priSlots,theTranslator->trPrivateSlots()); + ctx->addMemberList(m_classDef,MemberListType_priMethods,theTranslator->trPrivateMembers()); + ctx->addMemberList(m_classDef,MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers()); + ctx->addMemberList(m_classDef,MemberListType_priAttribs,theTranslator->trPrivateAttribs()); + ctx->addMemberList(m_classDef,MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs()); + ctx->addMemberList(m_classDef,MemberListType_related,theTranslator->trRelatedFunctions()); + m_cache.additionalInheritedMembers.reset(ctx); + } + return m_cache.additionalInheritedMembers.get(); + } private: ClassDef *m_classDef; @@ -1627,11 +1771,12 @@ class ClassContext::Private : public DefinitionContext { templateArgList.setAutoDelete(TRUE); exampleList.setAutoDelete(TRUE); + allMembers.setAutoDelete(TRUE); } ScopedPtr inheritsList; ScopedPtr inheritedByList; - ScopedPtr classGraph; - ScopedPtr collaborationGraph; + ScopedPtr classGraph; + ScopedPtr collaborationGraph; ScopedPtr nestedClasses; ScopedPtr publicTypes; ScopedPtr publicMethods; @@ -1678,9 +1823,12 @@ class ClassContext::Private : public DefinitionContext ScopedPtr typeConstraints; ScopedPtr examples; ScopedPtr templateDecls; - QList templateArgList; - int inheritanceNodes; - QList exampleList; + ScopedPtr additionalInheritedMembers; + ScopedPtr members; + QList templateArgList; + int inheritanceNodes; + QList exampleList; + MemberList allMembers; }; mutable Cachable m_cache; }; @@ -2024,6 +2172,8 @@ class MemberContext::Private : public DefinitionContext addProperty("isEnumeration", this,&Private::isEnumeration); addProperty("isEnumValue", this,&Private::isEnumValue); addProperty("isAnonymous", this,&Private::isAnonymous); + addProperty("anonymousType", this,&Private::anonymousType); + addProperty("anonymousMember", this,&Private::anonymousMember); addProperty("isRelated", this,&Private::isRelated); addProperty("hasDetails", this,&Private::hasDetails); addProperty("exception", this,&Private::exception); @@ -2161,6 +2311,44 @@ class MemberContext::Private : public DefinitionContext QCString name = m_memberDef->name(); return !name.isEmpty() && name.at(0)=='@'; } + TemplateVariant anonymousType() const + { + if (!m_cache.anonymousType) + { + ClassDef *cd = m_memberDef->getClassDefOfAnonymousType(); + if (cd) + { + m_cache.anonymousType.reset(new ClassContext(cd)); + } + } + if (m_cache.anonymousType) + { + return m_cache.anonymousType.get(); + } + else + { + return FALSE; + } + } + TemplateVariant anonymousMember() const + { + if (!m_cache.anonymousMember) + { + MemberDef *md = m_memberDef->fromAnonymousMember(); + if (md) + { + m_cache.anonymousMember.reset(new MemberContext(md)); + } + } + if (m_cache.anonymousMember) + { + return m_cache.anonymousMember.get(); + } + else + { + return FALSE; + } + } TemplateVariant isRelated() const { return m_memberDef->isRelated(); @@ -2617,7 +2805,7 @@ class MemberContext::Private : public DefinitionContext FTextStream t(&result); cg->writeGraph(t,BITMAP, g_globals.outputDir, - m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, + g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,g_globals.dynSectionId ); g_globals.dynSectionId++; @@ -2657,7 +2845,7 @@ class MemberContext::Private : public DefinitionContext FTextStream t(&result); cg->writeGraph(t,BITMAP, g_globals.outputDir, - m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, + g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,g_globals.dynSectionId ); g_globals.dynSectionId++; @@ -2683,6 +2871,7 @@ class MemberContext::Private : public DefinitionContext ScopedPtr arguments; ScopedPtr enumValues; ScopedPtr classDef; + ScopedPtr anonymousType; ScopedPtr templateDecls; ScopedPtr paramDocs; ScopedPtr implements; @@ -2694,6 +2883,7 @@ class MemberContext::Private : public DefinitionContext ScopedPtr sourceRefBys; ScopedPtr callGraph; ScopedPtr callerGraph; + ScopedPtr anonymousMember; QList implementedByMembers; ScopedPtr reimplementedBy; QList reimplementedByMembers; @@ -4330,6 +4520,74 @@ TemplateVariant ModuleTreeContext::get(const char *name) const //------------------------------------------------------------------------ +//%% struct NavPathElem: list of examples page +//%% { +class NavPathElemContext::Private : public PropertyMapper +{ + public: + Private(Definition *def) : m_def(def) + { + addProperty("isLinkable",this,&Private::isLinkable); + addProperty("fileName",this,&Private::fileName); + addProperty("anchor",this,&Private::anchor); + addProperty("text",this,&Private::text); + } + TemplateVariant isLinkable() const + { + return m_def->isLinkable(); + } + TemplateVariant anchor() const + { + return m_def->anchor(); + } + TemplateVariant fileName() const + { + return m_def->getOutputFileBase(); + } + TemplateVariant text() const + { + Definition::DefType type = m_def->definitionType(); + QCString text = m_def->localName(); + if (type==Definition::TypeGroup) + { + text = ((const GroupDef*)m_def)->groupTitle(); + } + else if (type==Definition::TypePage && !(((const PageDef*)this)->title().isEmpty())) + { + text = ((const PageDef*)m_def)->title(); + } + else if (type==Definition::TypeClass) + { + if (text.right(2)=="-p") + { + text = text.left(text.length()-2); + } + } + return text; + } + private: + Definition *m_def; +}; +//%% } + +NavPathElemContext::NavPathElemContext(Definition *def) +{ + p = new Private(def); +} + +NavPathElemContext::~NavPathElemContext() +{ + delete p; +} + +TemplateVariant NavPathElemContext::get(const char *name) const +{ + return p->get(name); +} + + +//------------------------------------------------------------------------ + //%% struct ExampleList: list of examples page //%% { class ExampleListContext::Private : public PropertyMapper @@ -4518,11 +4776,14 @@ MemberListContext::MemberListContext(const MemberList *list) p = new Private; if (list) { + bool details = list->listType()&MemberListType_detailedLists; MemberListIterator mli(*list); MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { - if (md->isBriefSectionVisible()) + if ((md->isBriefSectionVisible() && !details) || + (md->isDetailedSectionLinkable() && details) + ) { p->addMember(md); } @@ -4596,6 +4857,7 @@ class MemberInfoContext::Private : public PropertyMapper case ::Private: return "private"; case ::Package: return "package"; } + return ""; } TemplateVariant virtualness() const { @@ -4605,6 +4867,7 @@ class MemberInfoContext::Private : public PropertyMapper case ::Virtual: return "virtual"; case ::Pure: return "pure"; } + return ""; } TemplateVariant ambiguityScope() const { @@ -4735,6 +4998,7 @@ class MemberGroupInfoContext::Private : public PropertyMapper addProperty("anchor", this,&Private::groupAnchor); addProperty("memberGroups", this,&Private::memberGroups); addProperty("docs", this,&Private::docs); + addProperty("inherited", this,&Private::inherited); } TemplateVariant members() const { @@ -4775,6 +5039,10 @@ class MemberGroupInfoContext::Private : public PropertyMapper } return *m_docs; } + TemplateVariant inherited() const + { + return FALSE; + } private: Definition *m_def; QCString m_relPath; @@ -4879,6 +5147,7 @@ class MemberListInfoContext::Private : public PropertyMapper { public: Private(Definition *def,const QCString &relPath,const MemberList *ml,const QCString &title,const QCString &subtitle) : + m_def(def), m_memberListContext(ml), m_memberGroups(def,relPath,ml ? ml->getMemberGroupList() : 0), m_memberList(ml), @@ -4890,6 +5159,7 @@ class MemberListInfoContext::Private : public PropertyMapper addProperty("subtitle", this,&Private::subtitle); addProperty("anchor", this,&Private::anchor); addProperty("memberGroups", this,&Private::memberGroups); + addProperty("inherited", this,&Private::inherited); } TemplateVariant members() const { @@ -4905,18 +5175,38 @@ class MemberListInfoContext::Private : public PropertyMapper } TemplateVariant anchor() const { - return m_memberList->listTypeAsString(m_memberList->listType()); + return MemberList::listTypeAsString(m_memberList->listType()); } TemplateVariant memberGroups() const { return &m_memberGroups; } + TemplateVariant inherited() const + { + if (!m_inherited && (m_memberList->listType()&MemberListType_detailedLists)==0 && + m_def->definitionType()==Definition::TypeClass) + { + InheritedMemberInfoListContext *ctx = new InheritedMemberInfoListContext; + ctx->addMemberList((ClassDef*)m_def,m_memberList->listType(),m_title,FALSE); + m_inherited.reset(ctx); + } + if (m_inherited) + { + return m_inherited.get(); + } + else + { + return TemplateVariant(FALSE); + } + } private: + Definition *m_def; MemberListContext m_memberListContext; MemberGroupListContext m_memberGroups; const MemberList *m_memberList; QCString m_title; QCString m_subtitle; + mutable ScopedPtr m_inherited; }; //%% } @@ -4939,6 +5229,243 @@ TemplateVariant MemberListInfoContext::get(const char *name) const //------------------------------------------------------------------------ +//%% struct InheritedMemberInfo: inherited member information +//%% { +class InheritedMemberInfoContext::Private : public PropertyMapper +{ + public: + Private(ClassDef *cd,MemberList *ml,const QCString &title) + : m_class(cd), m_memberList(ml), m_title(title) + { + addProperty("class", this,&Private::getClass); + addProperty("title", this,&Private::title); + addProperty("members", this,&Private::members); + addProperty("id", this,&Private::id); + addProperty("inheritedFrom", this,&Private::inheritedFrom); + } + ~Private() + { + delete m_memberList; + } + TemplateVariant getClass() const + { + if (!m_classCtx) + { + m_classCtx.reset(new ClassContext(m_class)); + } + return m_classCtx.get(); + } + TemplateVariant title() const + { + return m_title; + } + TemplateVariant members() const + { + if (!m_memberListCtx) + { + m_memberListCtx.reset(new MemberListContext(m_memberList)); + } + return m_memberListCtx.get(); + } + TemplateVariant id() const + { + return substitute(MemberList::listTypeAsString(m_memberList->listType()),"-","_")+"_"+ + stripPath(m_class->getOutputFileBase()); + } + TemplateVariant inheritedFrom() const + { + if (m_inheritedFrom.count()==0) + { + m_inheritedFrom.append(title()); + m_inheritedFrom.append(getClass()); + } + return &m_inheritedFrom; + } + + private: + ClassDef * m_class; + MemberList *m_memberList; + QCString m_title; + mutable ScopedPtr m_classCtx; + mutable ScopedPtr m_memberListCtx; + mutable TemplateList m_inheritedFrom; +}; +//%% } + +InheritedMemberInfoContext::InheritedMemberInfoContext(ClassDef *cd,MemberList *ml, + const QCString &title) +{ + p = new Private(cd,ml,title); +} + +InheritedMemberInfoContext::~InheritedMemberInfoContext() +{ + delete p; +} + +TemplateVariant InheritedMemberInfoContext::get(const char *name) const +{ + return p->get(name); +} + +//------------------------------------------------------------------------ + +//%% list InheritedMemberList[InheritedMemberInfo] : list of inherited classes +class InheritedMemberInfoListContext::Private : public GenericNodeListContext +{ + public: + void addMemberList(ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList) + { + if (ml) + { + MemberListIterator li(*ml); + MemberDef *md; + for (li.toFirst();(md=li.current());++li) + { + if (md->isBriefSectionVisible() && !md->isReimplementedBy(inheritedFrom)) + { + combinedList->append(md); + } + } + } + } + void addMemberListIncludingGrouped(ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList) + { + if (ml) + { + addMemberList(inheritedFrom,ml,combinedList); + if (ml->getMemberGroupList()) + { + MemberGroupListIterator mgli(*ml->getMemberGroupList()); + MemberGroup *mg; + for (mgli.toFirst();(mg=mgli.current());++mgli) + { + addMemberList(inheritedFrom,mg->members(),combinedList); + } + } + } + } + void addMemberGroupsOfClass(ClassDef *inheritedFrom, + ClassDef *cd,MemberListType lt,MemberList *combinedList) + { + if (cd->getMemberGroupSDict()) + { + MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict()); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + if (mg->members() && (!mg->allMembersInSameSection() || !cd->subGrouping())) // group is in its own section + { + MemberListIterator li(*mg->members()); + MemberDef *md; + for (li.toFirst();(md=li.current());++li) + { + if (lt==md->getSectionList(mg->parent())->listType() && + !md->isReimplementedBy(inheritedFrom) && + md->isBriefSectionVisible()) + { + combinedList->append(md); + } + } + } + } + } + } + void addInheritedMembers(ClassDef *inheritedFrom,ClassDef *cd,MemberListType lt, + MemberListType lt1,int lt2,const QCString &title,bool additionalList) + { + int count = cd->countMembersIncludingGrouped(lt1,inheritedFrom,additionalList); + if (lt2!=-1) count += cd->countMembersIncludingGrouped((MemberListType)lt2,inheritedFrom,additionalList); + if (count>0) + { + MemberList *ml = cd->getMemberList(lt1); + MemberList *ml2 = lt2!=-1 ? cd->getMemberList((MemberListType)lt2) : 0; + MemberList *combinedList = new MemberList(lt); + addMemberListIncludingGrouped(inheritedFrom,ml,combinedList); + addMemberListIncludingGrouped(inheritedFrom,ml2,combinedList); + addMemberGroupsOfClass(inheritedFrom,cd,lt,combinedList); + if (lt2!=-1) addMemberGroupsOfClass(inheritedFrom,cd,(MemberListType)lt2,combinedList); + append(new InheritedMemberInfoContext(cd,combinedList,title)); + } + } + void findInheritedMembers(ClassDef *inheritedFrom,ClassDef *cd,MemberListType lt, + int lt2, const QCString &title,bool additionalList, + QPtrDict *visitedClasses) + { + if (cd->baseClasses()) + { + BaseClassListIterator it(*cd->baseClasses()); + BaseClassDef *ibcd; + for (it.toFirst();(ibcd=it.current());++it) + { + ClassDef *icd=ibcd->classDef; + if (icd->isLinkable()) + { + int lt1,lt3; + convertProtectionLevel(lt,ibcd->prot,<1,<3); + if (lt2==-1 && lt3!=-1) + { + lt2=lt3; + } + if (visitedClasses->find(icd)==0) + { + visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance + if (lt1!=-1) + { + // add member info for members of cd with list type lt + addInheritedMembers(inheritedFrom,icd,lt,(MemberListType)lt1,lt2,title,additionalList); + // recurse down the inheritance tree + findInheritedMembers(inheritedFrom,icd,(MemberListType)lt1,lt2,title,additionalList,visitedClasses); + } + } + } + } + } + } +}; + +InheritedMemberInfoListContext::InheritedMemberInfoListContext() +{ + p = new Private; +} + +void InheritedMemberInfoListContext::addMemberList( + ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList) +{ + QPtrDict visited(17); + bool memberInSection = cd->countMembersIncludingGrouped(lt,cd,FALSE); + bool show = (additionalList && !memberInSection) || // inherited member to show in the additional inherited members list + (!additionalList && memberInSection); // inherited member to show in a member list of the class + //printf("%s:%s show=%d\n",cd->name().data(),MemberList::listTypeAsString(lt).data(),show); + if (show) + { + p->findInheritedMembers(cd,cd,lt,-1,title,additionalList,&visited); + } +} + +InheritedMemberInfoListContext::~InheritedMemberInfoListContext() +{ + delete p; +} + +// TemplateListIntf +int InheritedMemberInfoListContext::count() const +{ + return p->count(); +} + +TemplateVariant InheritedMemberInfoListContext::at(int index) const +{ + return p->at(index); +} + +TemplateListIntf::ConstIterator *InheritedMemberInfoListContext::createIterator() const +{ + return p->createIterator(); +} + +//------------------------------------------------------------------------ + //%% struct Argument: parameter information //%% { class ArgumentContext::Private : public PropertyMapper diff --git a/src/context.h b/src/context.h index 6ae2c28..f027749 100644 --- a/src/context.h +++ b/src/context.h @@ -616,6 +616,23 @@ class ExampleListContext : public TemplateStructIntf //---------------------------------------------------- +class NavPathElemContext : public TemplateStructIntf +{ + public: + NavPathElemContext(Definition *def); + ~NavPathElemContext(); + + // TemplateStructIntf methods + virtual TemplateVariant get(const char *name) const; + + private: + class Private; + Private *p; +}; + + +//---------------------------------------------------- + class InheritanceNodeContext : public TemplateStructIntf { public: @@ -741,6 +758,41 @@ class MemberInfoContext : public TemplateStructIntf //---------------------------------------------------- +class InheritedMemberInfoContext : public TemplateStructIntf +{ + public: + InheritedMemberInfoContext(ClassDef *cd,MemberList *ml,const QCString &title); + ~InheritedMemberInfoContext(); + + // TemplateStructIntf methods + virtual TemplateVariant get(const char *name) const; + + private: + class Private; + Private *p; +}; + +//---------------------------------------------------- + +class InheritedMemberInfoListContext : public TemplateListIntf +{ + public: + InheritedMemberInfoListContext(); + void addMemberList(ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList=TRUE); + ~InheritedMemberInfoListContext(); + + // TemplateListIntf + virtual int count() const; + virtual TemplateVariant at(int index) const; + virtual TemplateListIntf::ConstIterator *createIterator() const; + + private: + class Private; + Private *p; +}; + +//---------------------------------------------------- + class AllMembersListContext : public TemplateListIntf { public: diff --git a/src/doxygen.cpp b/src/doxygen.cpp index ba1212a..1d8bfac 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -11427,6 +11427,8 @@ void generateOutput() g_s.end(); } + if (g_useOutputTemplate) generateOutputViaTemplate(); + if (generateRtf) { g_s.begin("Combining RTF output...\n"); @@ -11506,7 +11508,6 @@ void generateOutput() msg("finished...\n"); } - if (g_useOutputTemplate) generateOutputViaTemplate(); /************************************************************************** * Start cleaning up * diff --git a/src/filedef.cpp b/src/filedef.cpp index e75c7b0..e286284 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -514,7 +514,7 @@ void FileDef::writeSummaryLinks(OutputList &ol) MemberList * ml = getMemberList(lmd->type); if (ml && ml->declVisible()) { - ol.writeSummaryLink(0,ml->listTypeAsString(ml->listType()),lmd->title(lang),first); + ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); first=FALSE; } } diff --git a/src/groupdef.cpp b/src/groupdef.cpp index f9b47ae..9426c24 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -913,7 +913,7 @@ void GroupDef::writeSummaryLinks(OutputList &ol) MemberList * ml = getMemberList(lmd->type); if (ml && ml->declVisible()) { - ol.writeSummaryLink(0,ml->listTypeAsString(ml->listType()),lmd->title(lang),first); + ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); first=FALSE; } } diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 5d88d4a..4d7ea9f 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -1409,9 +1409,6 @@ void MemberDef::writeDeclaration(OutputList &ol, // are explicitly grouped. if (!inGroup && m_impl->mtype==MemberType_EnumValue) return; - // hide members whose brief section should not be visible - //if (!isBriefSectionVisible()) return; - Definition *d=0; ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd; @@ -1421,14 +1418,6 @@ void MemberDef::writeDeclaration(OutputList &ol, QCString cname = d->name(); QCString cdname = d->displayName(); QCString cfname = getOutputFileBase(); - //QCString osname = cname; - // in case of class members that are put in a group the name of the outerscope - // differs from the cname. - //if (getOuterScope()) osname=getOuterScope()->name(); - - //HtmlHelp *htmlHelp=0; - //bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP"); - //if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance(); // search for the last anonymous scope in the member type ClassDef *annoClassDef=getClassDefOfAnonymousType(); @@ -1445,15 +1434,27 @@ void MemberDef::writeDeclaration(OutputList &ol, // If there is no detailed description we need to write the anchor here. bool detailsVisible = isDetailedSectionLinkable(); - if (!detailsVisible && !m_impl->annMemb) + if (!detailsVisible) { - QCString doxyName=name().copy(); - if (!cname.isEmpty()) + QCString doxyArgs=argsString(); + if (m_impl->annMemb) { - doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage())); + QCString doxyName=m_impl->annMemb->name(); + if (!cname.isEmpty()) + { + doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage())); + } + ol.startDoxyAnchor(cfname,cname,m_impl->annMemb->anchor(),doxyName,doxyArgs); + } + else + { + QCString doxyName=name(); + if (!cname.isEmpty()) + { + doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage())); + } + ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs); } - QCString doxyArgs=argsString(); - ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs); ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); @@ -2388,6 +2389,21 @@ QCString MemberDef::displayDefinition() const ldef=ldef.mid(2); } } + static QRegExp r("@[0-9]+"); + int l,i=r.match(ldef,0,&l); + if (i!=-1) // replace anonymous parts with { ... } + { + int si=ldef.find(' '),pi,ei=i+l; + if (si==-1) si=0; + while ((pi=r.match(ldef,i+l,&l))!=-1) + { + i=pi; + ei=i+l; + } + int ni=ldef.find("::",si); + if (ni>=ei) ei=ni+2; + ldef = ldef.left(si) + " { ... } " + ldef.right(ldef.length()-ei); + } ClassDef *cd=getClassDef(); if (cd && cd->isObjectiveC()) { @@ -2407,9 +2423,9 @@ QCString MemberDef::displayDefinition() const { ldef=ldef.left(dp+1); } - int l=ldef.length(); + l=ldef.length(); //printf("start >%s<\n",ldef.data()); - int i=l-1; + i=l-1; while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--; while (i>=0 && isspace((uchar)ldef.at(i))) i--; if (i>0) @@ -2483,8 +2499,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, bool inFile = container->definitionType()==Definition::TypeFile; bool hasDocs = isDetailedSectionVisible(inGroup,inFile); - //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d\n", - // name().data(),hasDocs,container->definitionType(),inGroup); + //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d sectionLinkable=%d\n", + // name().data(),hasDocs,container->definitionType(),inGroup,isDetailedSectionLinkable()); if ( !hasDocs ) return; if (isEnumValue() && !showEnumValues) return; @@ -4656,6 +4672,11 @@ void MemberDef::setFromAnonymousMember(MemberDef *m) m_impl->annMemb=m; } +MemberDef *MemberDef::fromAnonymousMember() const +{ + return m_impl->annMemb; +} + void MemberDef::setTemplateMaster(MemberDef *mt) { m_impl->templateMaster=mt; diff --git a/src/memberdef.h b/src/memberdef.h index 926906c..47912b8 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -217,6 +217,7 @@ class MemberDef : public Definition bool fromAnonymousScope() const; bool anonymousDeclShown() const; + MemberDef *fromAnonymousMember() const; // callgraph related members bool hasCallGraph() const; diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 68edabc..feff3b4 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -878,7 +878,7 @@ void MemberList::setNeedsSorting(bool b) m_needsSorting = b; } -QCString MemberList::listTypeAsString(MemberListType type) const +QCString MemberList::listTypeAsString(MemberListType type) { switch(type) { diff --git a/src/memberlist.h b/src/memberlist.h index 7241258..9dfa104 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -36,7 +36,7 @@ class MemberList : public QList MemberList(MemberListType lt); ~MemberList(); MemberListType listType() const { return m_listType; } - QCString listTypeAsString(MemberListType type) const; + static QCString listTypeAsString(MemberListType type); bool insert(uint index,const MemberDef *md); void inSort(const MemberDef *md); void append(const MemberDef *md); diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index c0915b3..d00d845 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -430,7 +430,7 @@ void NamespaceDef::writeSummaryLinks(OutputList &ol) MemberList * ml = getMemberList(lmd->type); if (ml && ml->declVisible()) { - ol.writeSummaryLink(0,ml->listTypeAsString(ml->listType()),lmd->title(lang),first); + ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first); first=FALSE; } } diff --git a/src/template.cpp b/src/template.cpp index 75596f2..8144afd 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -1558,6 +1558,7 @@ class TemplateImpl : public TemplateNode, public Template { public: TemplateImpl(TemplateEngine *e,const QCString &name,const QCString &data); + ~TemplateImpl() {} void render(FTextStream &ts, TemplateContext *c); TemplateEngine *engine() const { return m_engine; } @@ -1868,6 +1869,58 @@ class TemplateNodeIf : public TemplateNodeCreator }; //---------------------------------------------------------- +/** @brief Class representing a 'for' tag in a template */ +class TemplateNodeRepeat : public TemplateNodeCreator +{ + public: + TemplateNodeRepeat(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data) + : TemplateNodeCreator(parser,parent,line) + { + TRACE(("{TemplateNodeRepeat(%s)\n",data.data())); + ExpressionParser expParser(parser->templateName(),line); + m_expr = expParser.parseVariable(data); + QStrList stopAt; + stopAt.append("endrepeat"); + parser->parse(this,line,stopAt,m_repeatNodes); + parser->removeNextToken(); // skip over endrepeat + TRACE(("}TemplateNodeRepeat(%s)\n",data.data())); + } + ~TemplateNodeRepeat() + { + delete m_expr; + } + void render(FTextStream &ts, TemplateContext *c) + { + dynamic_cast(c)->setLocation(m_templateName,m_line); + TemplateVariant v; + if (m_expr && (v=m_expr->resolve(c)).type()==TemplateVariant::Integer) + { + int i, n = v.toInt(); + for (i=0;iset("repeatloop",&s); + // render all items for this iteration of the loop + m_repeatNodes.render(ts,c); + } + } + else // simple type... + { + warn(m_templateName,m_line,"for requires a variable of list type!"); + } + } + private: + TemplateNodeList m_repeatNodes; + ExprAst *m_expr; +}; + +//---------------------------------------------------------- /** @brief Class representing a 'for' tag in a template */ class TemplateNodeFor : public TemplateNodeCreator @@ -2165,7 +2218,8 @@ class TemplateNodeExtend : public TemplateNodeCreator TemplateImpl *t = getTemplate(); if (t) { - TemplateImpl *baseTemplate = dynamic_cast(t->engine()->loadByName(extendFile)); + Template *bt = t->engine()->loadByName(extendFile); + TemplateImpl *baseTemplate = bt ? dynamic_cast(bt) : 0; if (baseTemplate) { // fill block context @@ -2194,7 +2248,7 @@ class TemplateNodeExtend : public TemplateNodeCreator // clean up bc->clear(); - delete baseTemplate; + //delete baseTemplate; } else { @@ -2242,7 +2296,8 @@ class TemplateNodeInclude : public TemplateNodeCreator TemplateImpl *t = getTemplate(); if (t) { - TemplateImpl *incTemplate = dynamic_cast(t->engine()->loadByName(includeFile)); + Template *it = t->engine()->loadByName(includeFile); + TemplateImpl *incTemplate = it ? dynamic_cast(it) : 0; if (incTemplate) { incTemplate->render(ts,c); @@ -2324,7 +2379,8 @@ class TemplateNodeCreate : public TemplateNodeCreator TemplateImpl *t = getTemplate(); if (t) { - TemplateImpl *createTemplate = dynamic_cast(t->engine()->loadByName(templateFile)); + Template *ct = t->engine()->loadByName(templateFile); + TemplateImpl *createTemplate = ct ? dynamic_cast(ct) : 0; if (createTemplate) { if (!ci->outputDirectory().isEmpty()) @@ -2336,7 +2392,7 @@ class TemplateNodeCreate : public TemplateNodeCreator { FTextStream ts(&f); createTemplate->render(ts,c); - delete createTemplate; + //delete createTemplate; } else { @@ -2729,6 +2785,9 @@ class TemplateNodeMarkers : public TemplateNodeCreator for (it->toFirst(); (it->current(var)) && itoNext(),i++) {} if (ok && i==entryIndex) // found element { + TemplateStruct s; + s.set("id",(int)i); + c->set("markers",&s); c->set(m_var,var); // define local variable to hold element of list type bool wasSpaceless = ci->spacelessEnabled(); ci->enableSpaceless(TRUE); @@ -2824,6 +2883,7 @@ static TemplateNodeFactory::AutoRegister autoRefBlock("bl static TemplateNodeFactory::AutoRegister autoRefCycle("cycle"); static TemplateNodeFactory::AutoRegister autoRefExtend("extend"); static TemplateNodeFactory::AutoRegister autoRefCreate("create"); +static TemplateNodeFactory::AutoRegister autoRefRepeat("repeat"); static TemplateNodeFactory::AutoRegister autoRefInclude("include"); static TemplateNodeFactory::AutoRegister autoRefMarkers("markers"); static TemplateNodeFactory::AutoRegister autoRefSpaceless("spaceless"); @@ -3186,7 +3246,8 @@ void TemplateParser::parse( command=="endif" || command=="endfor" || command=="endblock" || command=="endwith" || command=="endrecursetree" || command=="endspaceless" || - command=="endmarkers" || command=="endmsg") + command=="endmarkers" || command=="endmsg" || + command=="endrepeat") { warn(m_templateName,tok->line,"Found tag '%s' without matching start tag",command.data()); } @@ -3288,13 +3349,45 @@ void TemplateImpl::render(FTextStream &ts, TemplateContext *c) class TemplateEngine::Private { public: - Private() { templates.setAutoDelete(TRUE); } - QList