Commit 6dbf32d5 authored by Dimitri van Heesch's avatar Dimitri van Heesch

More template and context enhancements

parent 4d5ddf77
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "diagram.h" #include "diagram.h"
#include "example.h" #include "example.h"
#include "membername.h" #include "membername.h"
#include "parserintf.h"
struct ContextGlobals struct ContextGlobals
{ {
...@@ -328,31 +329,7 @@ class TranslateContext::Private : public PropertyMapper ...@@ -328,31 +329,7 @@ class TranslateContext::Private : public PropertyMapper
{ {
public: public:
static TemplateVariant generatedAtFunc(const void *obj,const QValueList<TemplateVariant> &args) TemplateVariant handleGeneratedAt(const QValueList<TemplateVariant> &args) const
{
return ((TranslateContext::Private*)obj)->generatedAt(args);
}
static TemplateVariant inheritanceDiagramForFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->inheritanceDiagramFor(args);
}
static TemplateVariant inheritsListFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->inheritsList(args);
}
static TemplateVariant inheritedByListFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->inheritedByList(args);
}
static TemplateVariant collaborationDiagramForFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->collaborationDiagramFor(args);
}
static TemplateVariant writeListFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->writeList(args);
}
TemplateVariant generatedAt(const QValueList<TemplateVariant> &args) const
{ {
if (args.count()==2) if (args.count()==2)
{ {
...@@ -364,7 +341,7 @@ class TranslateContext::Private : public PropertyMapper ...@@ -364,7 +341,7 @@ class TranslateContext::Private : public PropertyMapper
} }
return TemplateVariant(); return TemplateVariant();
} }
TemplateVariant inheritanceDiagramFor(const QValueList<TemplateVariant> &args) const TemplateVariant handleInheritanceDiagramFor(const QValueList<TemplateVariant> &args) const
{ {
if (args.count()==1) if (args.count()==1)
{ {
...@@ -376,7 +353,7 @@ class TranslateContext::Private : public PropertyMapper ...@@ -376,7 +353,7 @@ class TranslateContext::Private : public PropertyMapper
} }
return TemplateVariant(); return TemplateVariant();
} }
TemplateVariant collaborationDiagramFor(const QValueList<TemplateVariant> &args) const TemplateVariant handleCollaborationDiagramFor(const QValueList<TemplateVariant> &args) const
{ {
if (args.count()==1) if (args.count()==1)
{ {
...@@ -388,7 +365,7 @@ class TranslateContext::Private : public PropertyMapper ...@@ -388,7 +365,7 @@ class TranslateContext::Private : public PropertyMapper
} }
return TemplateVariant(); return TemplateVariant();
} }
TemplateVariant inheritsList(const QValueList<TemplateVariant> &args) const TemplateVariant handleInheritsList(const QValueList<TemplateVariant> &args) const
{ {
if (args.count()==1) if (args.count()==1)
{ {
...@@ -400,7 +377,7 @@ class TranslateContext::Private : public PropertyMapper ...@@ -400,7 +377,7 @@ class TranslateContext::Private : public PropertyMapper
} }
return TemplateVariant(); return TemplateVariant();
} }
QCString inheritedByList(const QValueList<TemplateVariant> &args) const TemplateVariant handleInheritedByList(const QValueList<TemplateVariant> &args) const
{ {
if (args.count()==1) if (args.count()==1)
{ {
...@@ -410,9 +387,9 @@ class TranslateContext::Private : public PropertyMapper ...@@ -410,9 +387,9 @@ class TranslateContext::Private : public PropertyMapper
{ {
err("tr.inheritedByList should take one integer parameter, got %d!\n",args.count()); err("tr.inheritedByList should take one integer parameter, got %d!\n",args.count());
} }
return QCString(); return TemplateVariant();
} }
QCString writeList(const QValueList<TemplateVariant> &args) const TemplateVariant handleWriteList(const QValueList<TemplateVariant> &args) const
{ {
if (args.count()==1) if (args.count()==1)
{ {
...@@ -422,7 +399,55 @@ class TranslateContext::Private : public PropertyMapper ...@@ -422,7 +399,55 @@ class TranslateContext::Private : public PropertyMapper
{ {
err("tr.*List should take one integer parameter, got %d!\n",args.count()); err("tr.*List should take one integer parameter, got %d!\n",args.count());
} }
return QCString(); return TemplateVariant();
}
TemplateVariant handleImplementedBy(const QValueList<TemplateVariant> &args) const
{
if (args.count()==1)
{
return theTranslator->trImplementedInList(args[0].toInt());
}
else
{
err("tr.implementedBy should take one integer parameter, got %d!\n",args.count());
}
return TemplateVariant();
}
TemplateVariant handleReimplementedBy(const QValueList<TemplateVariant> &args) const
{
if (args.count()==1)
{
return theTranslator->trReimplementedInList(args[0].toInt());
}
else
{
err("tr.reimplementedBy should take one integer parameter, got %d!\n",args.count());
}
return TemplateVariant();
}
TemplateVariant handleSourceRefs(const QValueList<TemplateVariant> &args) const
{
if (args.count()==1)
{
return theTranslator->trReferences()+" "+theTranslator->trWriteList(args[0].toInt())+".";
}
else
{
err("tr.sourceRefs should take one integer parameter, got %d\n",args.count());
}
return TemplateVariant();
}
TemplateVariant handleSourceRefBys(const QValueList<TemplateVariant> &args) const
{
if (args.count()==1)
{
return theTranslator->trReferencedBy()+" "+theTranslator->trWriteList(args[0].toInt())+".";
}
else
{
err("tr.sourceRefBys should take one integer parameter, got %d\n",args.count());
}
return TemplateVariant();
} }
...@@ -433,15 +458,15 @@ class TranslateContext::Private : public PropertyMapper ...@@ -433,15 +458,15 @@ class TranslateContext::Private : public PropertyMapper
} }
TemplateVariant generatedAt() const TemplateVariant generatedAt() const
{ {
return TemplateVariant(this,&Private::generatedAtFunc); return TemplateVariant::Delegate::fromMethod<Private,&Private::handleGeneratedAt>(this);
} }
TemplateVariant inheritanceDiagramFor() const TemplateVariant inheritanceDiagramFor() const
{ {
return TemplateVariant(this,&Private::inheritanceDiagramForFunc); return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritanceDiagramFor>(this);
} }
TemplateVariant collaborationDiagramFor() const TemplateVariant collaborationDiagramFor() const
{ {
return TemplateVariant(this,&Private::collaborationDiagramForFunc); return TemplateVariant::Delegate::fromMethod<Private,&Private::handleCollaborationDiagramFor>(this);
} }
TemplateVariant search() const TemplateVariant search() const
{ {
...@@ -554,11 +579,11 @@ class TranslateContext::Private : public PropertyMapper ...@@ -554,11 +579,11 @@ class TranslateContext::Private : public PropertyMapper
} }
TemplateVariant inheritsList() const TemplateVariant inheritsList() const
{ {
return TemplateVariant(this,&Private::inheritsListFunc); return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritsList>(this);
} }
TemplateVariant inheritedByList() const TemplateVariant inheritedByList() const
{ {
return TemplateVariant(this,&Private::inheritedByListFunc); return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritedByList>(this);
} }
TemplateVariant definedAtLineInSourceFile() const TemplateVariant definedAtLineInSourceFile() const
{ {
...@@ -570,7 +595,7 @@ class TranslateContext::Private : public PropertyMapper ...@@ -570,7 +595,7 @@ class TranslateContext::Private : public PropertyMapper
} }
TemplateVariant exampleList() const TemplateVariant exampleList() const
{ {
return TemplateVariant(this,&Private::writeListFunc); return TemplateVariant::Delegate::fromMethod<Private,&Private::handleWriteList>(this);
} }
TemplateVariant listOfAllMembers() const TemplateVariant listOfAllMembers() const
{ {
...@@ -588,6 +613,50 @@ class TranslateContext::Private : public PropertyMapper ...@@ -588,6 +613,50 @@ class TranslateContext::Private : public PropertyMapper
{ {
return theTranslator->trIncludingInheritedMembers(); return theTranslator->trIncludingInheritedMembers();
} }
TemplateVariant defineValue() const
{
return theTranslator->trDefineValue();
}
TemplateVariant initialValue() const
{
return theTranslator->trInitialValue();
}
TemplateVariant enumerationValues() const
{
return theTranslator->trEnumerationValues();
}
TemplateVariant implements() const
{
return theTranslator->trImplementedFromList(1);
}
TemplateVariant reimplements() const
{
return theTranslator->trReimplementedFromList(1);
}
TemplateVariant implementedBy() const
{
return TemplateVariant::Delegate::fromMethod<Private,&Private::handleImplementedBy>(this);
}
TemplateVariant reimplementedBy() const
{
return TemplateVariant::Delegate::fromMethod<Private,&Private::handleReimplementedBy>(this);
}
TemplateVariant sourceRefs() const
{
return TemplateVariant::Delegate::fromMethod<Private,&Private::handleSourceRefs>(this);
}
TemplateVariant sourceRefBys() const
{
return TemplateVariant::Delegate::fromMethod<Private,&Private::handleSourceRefBys>(this);
}
TemplateVariant callGraph() const
{
return theTranslator->trCallGraph();
}
TemplateVariant callerGraph() const
{
return theTranslator->trCallerGraph();
}
Private() Private()
{ {
//%% string generatedBy //%% string generatedBy
...@@ -654,6 +723,28 @@ class TranslateContext::Private : public PropertyMapper ...@@ -654,6 +723,28 @@ class TranslateContext::Private : public PropertyMapper
addProperty("theListOfAllMembers",this,&Private::theListOfAllMembers); addProperty("theListOfAllMembers",this,&Private::theListOfAllMembers);
//%% string incInheritedMembers //%% string incInheritedMembers
addProperty("incInheritedMembers",this,&Private::incInheritedMembers); addProperty("incInheritedMembers",this,&Private::incInheritedMembers);
//%% string defineValue
addProperty("defineValue", this,&Private::defineValue);
//%% string initialValue
addProperty("initialValue", this,&Private::initialValue);
//%% string enumerationValues
addProperty("enumerationValues", this,&Private::enumerationValues);
//%% markerstring implements
addProperty("implements", this,&Private::implements);
//%% markerstring reimplements
addProperty("reimplements", this,&Private::reimplements);
//%% markerstring implementedBy
addProperty("implementedBy", this,&Private::implementedBy);
//%% markerstring reimplementedBy
addProperty("reimplementedBy", this,&Private::reimplementedBy);
//%% markerstring sourceRefs
addProperty("sourceRefs", this,&Private::sourceRefs);
//%% markerstring sourceRefBys
addProperty("sourceRefBys", this,&Private::sourceRefBys);
//%% string callGraph
addProperty("callGraph", this,&Private::callGraph);
//%% string callerGraph
addProperty("callerGraph", this,&Private::callerGraph);
m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
...@@ -703,6 +794,19 @@ static TemplateVariant parseDoc(Definition *def,const QCString &file,int line, ...@@ -703,6 +794,19 @@ static TemplateVariant parseDoc(Definition *def,const QCString &file,int line,
return result; return result;
} }
static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const QCString &relPath,
const QCString &code,int startLine=-1,int endLine=-1,bool showLineNumbers=FALSE)
{
ParserInterface *pIntf = Doxygen::parserManager->getParser(md->getDefFileExtension());
pIntf->resetCodeParserState();
QGString s;
FTextStream t(&s);
HtmlCodeGenerator codeGen(t,relPath);
pIntf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(),
startLine,endLine,TRUE,md,showLineNumbers,md);
return TemplateVariant(s.data(),TRUE);
}
//------------------------------------------------------------------------ //------------------------------------------------------------------------
//%% struct Symbol: shared info for all symbols //%% struct Symbol: shared info for all symbols
...@@ -727,6 +831,8 @@ class DefinitionContext : public PropertyMapper ...@@ -727,6 +831,8 @@ class DefinitionContext : public PropertyMapper
addProperty("details",this,&DefinitionContext::details); addProperty("details",this,&DefinitionContext::details);
//%% string brief: the brief description for this symbol //%% string brief: the brief description for this symbol
addProperty("brief",this,&DefinitionContext::brief); addProperty("brief",this,&DefinitionContext::brief);
//%% string inbodyDocs: the documentation found in the body
addProperty("inbodyDocs",this,&DefinitionContext::inbodyDocs);
//%% string sourceFileName: the file name of the source file (without extension) //%% string sourceFileName: the file name of the source file (without extension)
addProperty("sourceFileName",this,&DefinitionContext::sourceFileName); addProperty("sourceFileName",this,&DefinitionContext::sourceFileName);
//%% bool isLinkable: can the symbol be linked to? //%% bool isLinkable: can the symbol be linked to?
...@@ -745,7 +851,7 @@ class DefinitionContext : public PropertyMapper ...@@ -745,7 +851,7 @@ class DefinitionContext : public PropertyMapper
m_sourceDef.append(&m_lineLink); m_sourceDef.append(&m_lineLink);
m_sourceDef.append(&m_fileLink); m_sourceDef.append(&m_fileLink);
m_lineLink.set("text",m_def->getStartBodyLine()); m_lineLink.set("text",m_def->getStartBodyLine());
m_lineLink.set("isLinkable",m_def->isLinkable()); m_lineLink.set("isLinkable",TRUE);
m_lineLink.set("fileName",m_def->getSourceFileBase()); m_lineLink.set("fileName",m_def->getSourceFileBase());
m_lineLink.set("anchor",m_def->getSourceAnchor()); m_lineLink.set("anchor",m_def->getSourceAnchor());
if (m_def->definitionType()==Definition::TypeFile) if (m_def->definitionType()==Definition::TypeFile)
...@@ -760,7 +866,7 @@ class DefinitionContext : public PropertyMapper ...@@ -760,7 +866,7 @@ class DefinitionContext : public PropertyMapper
{ {
m_fileLink.set("text",name()); m_fileLink.set("text",name());
} }
m_fileLink.set("isLinkable",m_def->isLinkable()); m_fileLink.set("isLinkable",TRUE);
m_fileLink.set("fileName",m_def->getSourceFileBase()); m_fileLink.set("fileName",m_def->getSourceFileBase());
m_fileLink.set("anchor",QCString()); m_fileLink.set("anchor",QCString());
} }
...@@ -827,6 +933,22 @@ class DefinitionContext : public PropertyMapper ...@@ -827,6 +933,22 @@ class DefinitionContext : public PropertyMapper
} }
return *m_cache.brief; return *m_cache.brief;
} }
TemplateVariant inbodyDocs() const
{
if (!m_cache.inbodyDocs)
{
if (!m_def->inbodyDocumentation().isEmpty())
{
m_cache.inbodyDocs.reset(new TemplateVariant(parseDoc(m_def,m_def->inbodyFile(),m_def->inbodyLine(),
relPathAsString(),m_def->inbodyDocumentation(),FALSE)));
}
else
{
m_cache.inbodyDocs.reset(new TemplateVariant(""));
}
}
return *m_cache.inbodyDocs;
}
TemplateVariant dynSectionId() const TemplateVariant dynSectionId() const
{ {
return g_globals.dynSectionId; return g_globals.dynSectionId;
...@@ -873,6 +995,7 @@ class DefinitionContext : public PropertyMapper ...@@ -873,6 +995,7 @@ class DefinitionContext : public PropertyMapper
{ {
ScopedPtr<TemplateVariant> details; ScopedPtr<TemplateVariant> details;
ScopedPtr<TemplateVariant> brief; ScopedPtr<TemplateVariant> brief;
ScopedPtr<TemplateVariant> inbodyDocs;
}; };
mutable Cachable m_cache; mutable Cachable m_cache;
TemplateList m_sourceDef; TemplateList m_sourceDef;
...@@ -1002,11 +1125,10 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> ...@@ -1002,11 +1125,10 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
addProperty("events", this,&Private::events); addProperty("events", this,&Private::events);
addProperty("friends", this,&Private::friends); addProperty("friends", this,&Private::friends);
addProperty("relatedDecls", this,&Private::relatedDecls); addProperty("relatedDecls", this,&Private::relatedDecls);
addProperty("typedefs", this,&Private::typedefs); addProperty("typedefs", this,&Private::typedefs);
addProperty("enums", this,&Private::enums);
addProperty("methods", this,&Private::methods); addProperty("methods", this,&Private::methods);
addProperty("relatedDefs", this,&Private::relatedDefs); addProperty("relatedDefs", this,&Private::relatedDefs);
addProperty("nestedClasses", this,&Private::nestedClasses); addProperty("nestedClasses", this,&Private::nestedClasses);
addProperty("compoundType", this,&Private::compoundType); addProperty("compoundType", this,&Private::compoundType);
addProperty("templateDecls", this,&Private::templateDecls); addProperty("templateDecls", this,&Private::templateDecls);
...@@ -1316,6 +1438,10 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> ...@@ -1316,6 +1438,10 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
{ {
return getMemberList(m_cache.typedefs,MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation()); return getMemberList(m_cache.typedefs,MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation());
} }
TemplateVariant enums() const
{
return getMemberList(m_cache.enums,MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation());
}
TemplateVariant methods() const TemplateVariant methods() const
{ {
return getMemberList(m_cache.methods,MemberListType_functionMembers,theTranslator->trMemberFunctionDocumentation()); return getMemberList(m_cache.methods,MemberListType_functionMembers,theTranslator->trMemberFunctionDocumentation());
...@@ -1519,6 +1645,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> ...@@ -1519,6 +1645,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
ScopedPtr<MemberListInfoContext> friends; ScopedPtr<MemberListInfoContext> friends;
ScopedPtr<MemberListInfoContext> relatedDecls; ScopedPtr<MemberListInfoContext> relatedDecls;
ScopedPtr<MemberListInfoContext> typedefs; ScopedPtr<MemberListInfoContext> typedefs;
ScopedPtr<MemberListInfoContext> enums;
ScopedPtr<MemberListInfoContext> methods; ScopedPtr<MemberListInfoContext> methods;
ScopedPtr<MemberListInfoContext> relatedDefs; ScopedPtr<MemberListInfoContext> relatedDefs;
ScopedPtr<AllMembersListContext> allMembersList; ScopedPtr<AllMembersListContext> allMembersList;
...@@ -1871,11 +1998,14 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -1871,11 +1998,14 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
addProperty("isEnumeration", this,&Private::isEnumeration); addProperty("isEnumeration", this,&Private::isEnumeration);
addProperty("isEnumValue", this,&Private::isEnumValue); addProperty("isEnumValue", this,&Private::isEnumValue);
addProperty("isAnonymous", this,&Private::isAnonymous); addProperty("isAnonymous", this,&Private::isAnonymous);
addProperty("isRelated", this,&Private::isRelated);
addProperty("hasDetails", this,&Private::hasDetails); addProperty("hasDetails", this,&Private::hasDetails);
addProperty("exception", this,&Private::exception); addProperty("exception", this,&Private::exception);
addProperty("bitfields", this,&Private::bitfields); addProperty("bitfields", this,&Private::bitfields);
addProperty("initializer", this,&Private::initializer); addProperty("initializer", this,&Private::initializer);
addProperty("oneLineInitializer", this,&Private::oneLineInitializer); addProperty("initializerAsCode", this,&Private::initializerAsCode);
addProperty("hasOneLineInitializer", this,&Private::hasOneLineInitializer);
addProperty("hasMultiLineInitializer", this,&Private::hasMultiLineInitializer);
addProperty("templateArgs", this,&Private::templateArgs); addProperty("templateArgs", this,&Private::templateArgs);
addProperty("templateAlias", this,&Private::templateAlias); addProperty("templateAlias", this,&Private::templateAlias);
addProperty("propertyAttrs", this,&Private::propertyAttrs); addProperty("propertyAttrs", this,&Private::propertyAttrs);
...@@ -1892,6 +2022,22 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -1892,6 +2022,22 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
addProperty("labels", this,&Private::labels); addProperty("labels", this,&Private::labels);
addProperty("enumBaseType", this,&Private::enumBaseType); addProperty("enumBaseType", this,&Private::enumBaseType);
addProperty("enumValues", this,&Private::enumValues); addProperty("enumValues", this,&Private::enumValues);
addProperty("paramDocs", this,&Private::paramDocs);
addProperty("reimplements", this,&Private::reimplements);
addProperty("implements", this,&Private::implements);
addProperty("reimplementedBy", this,&Private::reimplementedBy);
addProperty("implementedBy", this,&Private::implementedBy);
addProperty("examples", this,&Private::examples);
addProperty("typeConstraints", this,&Private::typeConstraints);
addProperty("functionQualifier", this,&Private::functionQualifier);
addProperty("sourceRefs", this,&Private::sourceRefs);
addProperty("sourceRefBys", this,&Private::sourceRefBys);
addProperty("hasSources", this,&Private::hasSources);
addProperty("sourceCode", this,&Private::sourceCode);
addProperty("hasCallGraph", this,&Private::hasCallGraph);
addProperty("callGraph", this,&Private::callGraph);
addProperty("hasCallerGraph", this,&Private::hasCallerGraph);
addProperty("callerGraph", this,&Private::callerGraph);
if (md && md->isProperty()) if (md && md->isProperty())
{ {
...@@ -1961,6 +2107,25 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -1961,6 +2107,25 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
{ {
return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->initializer()); return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->initializer());
} }
TemplateVariant initializerAsCode() const
{
if (!m_cache.initializerParsed)
{
QCString scopeName;
if (m_memberDef->getClassDef())
{
scopeName = m_memberDef->getClassDef()->name();
}
else if (m_memberDef->getNamespaceDef())
{
scopeName = m_memberDef->getNamespaceDef()->name();
}
m_cache.initializer = parseCode(m_memberDef,scopeName,relPathAsString(),
m_memberDef->initializer());
m_cache.initializerParsed = TRUE;
}
return m_cache.initializer;
}
TemplateVariant isDefine() const TemplateVariant isDefine() const
{ {
return m_memberDef->isDefine(); return m_memberDef->isDefine();
...@@ -1970,14 +2135,22 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -1970,14 +2135,22 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
QCString name = m_memberDef->name(); QCString name = m_memberDef->name();
return !name.isEmpty() && name.at(0)=='@'; return !name.isEmpty() && name.at(0)=='@';
} }
TemplateVariant isRelated() const
{
return m_memberDef->isRelated();
}
TemplateVariant enumBaseType() const TemplateVariant enumBaseType() const
{ {
return m_memberDef->enumBaseType(); return m_memberDef->enumBaseType();
} }
TemplateVariant oneLineInitializer() const TemplateVariant hasOneLineInitializer() const
{ {
return m_memberDef->hasOneLineInitializer(); return m_memberDef->hasOneLineInitializer();
} }
TemplateVariant hasMultiLineInitializer() const
{
return m_memberDef->hasMultiLineInitializer();
}
TemplateVariant enumValues() const TemplateVariant enumValues() const
{ {
if (!m_cache.enumValues) if (!m_cache.enumValues)
...@@ -2109,8 +2282,6 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -2109,8 +2282,6 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
if (tal->count()>0) if (tal->count()>0)
{ {
ArgumentListContext *al = new ArgumentListContext(tal,m_memberDef,relPathAsString()); ArgumentListContext *al = new ArgumentListContext(tal,m_memberDef,relPathAsString());
// since a TemplateVariant does take ownership of the object, we add it
// a separate list just to be able to delete it and avoid a memory leak
m_cache.templateArgList.append(al); m_cache.templateArgList.append(al);
tl->append(al); tl->append(al);
} }
...@@ -2118,7 +2289,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -2118,7 +2289,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
} }
else else
{ {
if (cd && !m_memberDef->isTemplateSpecialization()) if (cd && !m_memberDef->isRelated() && !m_memberDef->isTemplateSpecialization())
{ {
QList<ArgumentList> tempParamLists; QList<ArgumentList> tempParamLists;
cd->getTemplateParameterLists(tempParamLists); cd->getTemplateParameterLists(tempParamLists);
...@@ -2130,8 +2301,6 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -2130,8 +2301,6 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
if (tal->count()>0) if (tal->count()>0)
{ {
ArgumentListContext *al = new ArgumentListContext(tal,m_memberDef,relPathAsString()); ArgumentListContext *al = new ArgumentListContext(tal,m_memberDef,relPathAsString());
// since a TemplateVariant does take ownership of the object, we add it
// a separate list just to be able to delete it and avoid a memory leak
m_cache.templateArgList.append(al); m_cache.templateArgList.append(al);
tl->append(al); tl->append(al);
} }
...@@ -2141,8 +2310,6 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -2141,8 +2310,6 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
{ {
ArgumentListContext *al = new ArgumentListContext( ArgumentListContext *al = new ArgumentListContext(
m_memberDef->templateArguments(),m_memberDef,relPathAsString()); m_memberDef->templateArguments(),m_memberDef,relPathAsString());
// since a TemplateVariant does take ownership of the object, we add it
// a separate list just to be able to delete it and avoid a memory leak
m_cache.templateArgList.append(al); m_cache.templateArgList.append(al);
tl->append(al); tl->append(al);
} }
...@@ -2191,17 +2358,379 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> ...@@ -2191,17 +2358,379 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
return TemplateVariant(FALSE); return TemplateVariant(FALSE);
} }
} }
TemplateVariant paramDocs() const
{
if (!m_cache.paramDocs)
{
if (m_memberDef->argumentList() && m_memberDef->argumentList()->hasDocumentation())
{
QCString paramDocs;
ArgumentListIterator ali(*m_memberDef->argumentList());
Argument *a;
// convert the parameter documentation into a list of @param commands
for (ali.toFirst();(a=ali.current());++ali)
{
if (a->hasDocumentation())
{
QCString direction = extractDirection(a->docs);
paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
}
}
m_cache.paramDocs.reset(new TemplateVariant(parseDoc(m_memberDef,
m_memberDef->docFile(),m_memberDef->docLine(),
relPathAsString(),paramDocs,FALSE)));
}
else
{
m_cache.paramDocs.reset(new TemplateVariant(""));
}
}
return *m_cache.paramDocs;
}
TemplateVariant implements() const
{
if (!m_cache.implements)
{
MemberDef *md = m_memberDef->reimplements();
if (md)
{
ClassDef *cd = md->getClassDef();
if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface))
{
m_cache.implements.reset(new TemplateList);
MemberContext *mc = new MemberContext(md);
m_cache.implementsMember.reset(mc);
m_cache.implements->append(mc);
}
}
}
if (m_cache.implements)
{
return m_cache.implements.get();
}
else
{
return TemplateVariant(FALSE);
}
}
TemplateVariant reimplements() const
{
if (!m_cache.reimplements)
{
MemberDef *md = m_memberDef->reimplements();
if (md)
{
ClassDef *cd = md->getClassDef();
if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface)
{
m_cache.reimplements.reset(new TemplateList);
MemberContext *mc = new MemberContext(md);
m_cache.reimplementsMember.reset(mc);
m_cache.reimplements->append(mc);
}
}
}
if (m_cache.reimplements)
{
return m_cache.reimplements.get();
}
else
{
return TemplateVariant(FALSE);
}
}
TemplateVariant implementedBy() const
{
if (!m_cache.implementedBy)
{
MemberList *ml = m_memberDef->reimplementedBy();
if (ml)
{
MemberListIterator mli(*ml);
MemberDef *md=0;
m_cache.implementedBy.reset(new TemplateList);
for (mli.toFirst();(md=mli.current());++mli)
{
ClassDef *cd = md->getClassDef();
if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface))
{
MemberContext *mc = new MemberContext(md);
m_cache.implementedByMembers.append(mc);
m_cache.implementedBy->append(mc);
}
}
}
}
if (m_cache.implementedBy)
{
return m_cache.implementedBy.get();
}
else
{
return TemplateVariant(FALSE);
}
}
TemplateVariant reimplementedBy() const
{
if (!m_cache.reimplementedBy)
{
MemberList *ml = m_memberDef->reimplementedBy();
if (ml)
{
MemberListIterator mli(*ml);
MemberDef *md=0;
m_cache.reimplementedBy.reset(new TemplateList);
for (mli.toFirst();(md=mli.current());++mli)
{
ClassDef *cd = md->getClassDef();
if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface)
{
MemberContext *mc = new MemberContext(md);
m_cache.reimplementedByMembers.append(mc);
m_cache.reimplementedBy->append(mc);
}
}
}
}
if (m_cache.reimplementedBy)
{
return m_cache.reimplementedBy.get();
}
else
{
return TemplateVariant(FALSE);
}
}
void addExamples(TemplateList *list) const
{
if (m_memberDef->hasExamples())
{
ExampleSDict::Iterator it(*m_memberDef->getExamples());
Example *ex;
for (it.toFirst();(ex=it.current());++it)
{
TemplateStruct *s = new TemplateStruct;
m_cache.exampleList.append(s);
s->set("text",ex->name);
s->set("isLinkable",TRUE);
s->set("anchor",ex->anchor);
s->set("fileName",ex->file);
list->append(s);
}
}
}
TemplateVariant examples() const
{
if (!m_cache.examples)
{
TemplateList *exampleList = new TemplateList;
addExamples(exampleList);
m_cache.examples.reset(exampleList);
}
if (m_cache.examples)
{
return m_cache.examples.get();
}
else
{
return TemplateVariant(FALSE);
}
}
TemplateVariant typeConstraints() const
{
if (!m_cache.typeConstraints && m_memberDef->typeConstraints())
{
m_cache.typeConstraints.reset(new ArgumentListContext(m_memberDef->typeConstraints(),m_memberDef,relPathAsString()));
}
if (m_cache.typeConstraints)
{
return m_cache.typeConstraints.get();
}
else
{
return TemplateVariant(FALSE);
}
}
TemplateVariant functionQualifier() const
{
if (!m_memberDef->isObjCMethod() &&
(m_memberDef->isFunction() || m_memberDef->isSlot() ||
m_memberDef->isPrototype() || m_memberDef->isSignal()
)
)
{
return "()";
}
else
{
return "";
}
}
TemplateVariant sourceRefs() const
{
if (!m_cache.sourceRefs)
{
m_cache.sourceRefs.reset(new MemberListContext(m_memberDef->getReferencesMembers(),TRUE));
}
return m_cache.sourceRefs.get();
}
TemplateVariant sourceRefBys() const
{
if (!m_cache.sourceRefBys)
{
m_cache.sourceRefBys.reset(new MemberListContext(m_memberDef->getReferencedByMembers(),TRUE));
}
return m_cache.sourceRefBys.get();
}
TemplateVariant hasSources() const
{
return TemplateVariant(m_memberDef->hasSources());
}
TemplateVariant sourceCode() const
{
if (!m_cache.sourceCodeParsed)
{
QCString codeFragment;
FileDef *fd = m_memberDef->getBodyDef();
int startLine = m_memberDef->getStartBodyLine();
int endLine = m_memberDef->getEndBodyLine();
if (fd && readCodeFragment(fd->absFilePath(),
startLine,endLine,codeFragment)
)
{
QCString scopeName;
if (m_memberDef->getClassDef())
{
scopeName = m_memberDef->getClassDef()->name();
}
else if (m_memberDef->getNamespaceDef())
{
scopeName = m_memberDef->getNamespaceDef()->name();
}
m_cache.sourceCode = parseCode(m_memberDef,scopeName,relPathAsString(),codeFragment,startLine,endLine,TRUE);
m_cache.sourceCodeParsed = TRUE;
}
}
return m_cache.sourceCode;
}
DotCallGraph *getCallGraph() const
{
if (!m_cache.callGraph)
{
m_cache.callGraph.reset(new DotCallGraph(m_memberDef,FALSE));
}
return m_cache.callGraph.get();
}
TemplateVariant hasCallGraph() const
{
static bool haveDot = Config_getBool("HAVE_DOT");
static bool callGraph = Config_getBool("CALL_GRAPH");
if ((callGraph || m_memberDef->hasCallGraph()) && haveDot &&
(m_memberDef->isFunction() || m_memberDef->isSlot() || m_memberDef->isSignal()))
{
DotCallGraph *cg = getCallGraph();
return !cg->isTooBig() && !cg->isTrivial();
}
return TemplateVariant(FALSE);
}
TemplateVariant callGraph() const
{
if (hasCallGraph().toBool())
{
DotCallGraph *cg = getCallGraph();
QGString result;
FTextStream t(&result);
cg->writeGraph(t,BITMAP,
g_globals.outputDir,
m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension,
relPathAsString(),TRUE,g_globals.dynSectionId
);
g_globals.dynSectionId++;
return TemplateVariant(result.data(),TRUE);
}
else
{
return TemplateVariant("");
}
}
DotCallGraph *getCallerGraph() const
{
if (!m_cache.callerGraph)
{
m_cache.callerGraph.reset(new DotCallGraph(m_memberDef,TRUE));
}
return m_cache.callerGraph.get();
}
TemplateVariant hasCallerGraph() const
{
static bool haveDot = Config_getBool("HAVE_DOT");
static bool callerGraph = Config_getBool("CALLER_GRAPH");
if ((callerGraph || m_memberDef->hasCallerGraph()) && haveDot &&
(m_memberDef->isFunction() || m_memberDef->isSlot() || m_memberDef->isSignal()))
{
DotCallGraph *cg = getCallerGraph();
return !cg->isTooBig() && !cg->isTrivial();
}
return TemplateVariant(FALSE);
}
TemplateVariant callerGraph() const
{
if (hasCallerGraph().toBool())
{
DotCallGraph *cg = getCallerGraph();
QGString result;
FTextStream t(&result);
cg->writeGraph(t,BITMAP,
g_globals.outputDir,
m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension,
relPathAsString(),TRUE,g_globals.dynSectionId
);
g_globals.dynSectionId++;
return TemplateVariant(result.data(),TRUE);
}
else
{
return TemplateVariant("");
}
}
private: private:
MemberDef *m_memberDef; MemberDef *m_memberDef;
struct Cachable struct Cachable
{ {
Cachable() : initializerParsed(FALSE), sourceCodeParsed(FALSE)
{
implementedByMembers.setAutoDelete(TRUE);
reimplementedByMembers.setAutoDelete(TRUE);
templateArgList.setAutoDelete(TRUE);
exampleList.setAutoDelete(TRUE);
}
ScopedPtr<ArgumentListContext> templateArgs; ScopedPtr<ArgumentListContext> templateArgs;
ScopedPtr<ArgumentListContext> arguments; ScopedPtr<ArgumentListContext> arguments;
ScopedPtr<MemberListContext> enumValues; ScopedPtr<MemberListContext> enumValues;
ScopedPtr<ClassContext> classDef; ScopedPtr<ClassContext> classDef;
ScopedPtr<TemplateList> templateDecls; ScopedPtr<TemplateList> templateDecls;
ScopedPtr<TemplateVariant> paramDocs;
ScopedPtr<TemplateList> implements;
ScopedPtr<MemberContext> implementsMember;
ScopedPtr<TemplateList> reimplements;
ScopedPtr<MemberContext> reimplementsMember;
ScopedPtr<TemplateList> implementedBy;
ScopedPtr<MemberListContext> sourceRefs;
ScopedPtr<MemberListContext> sourceRefBys;
ScopedPtr<DotCallGraph> callGraph;
ScopedPtr<DotCallGraph> callerGraph;
QList<MemberContext> implementedByMembers;
ScopedPtr<TemplateList> reimplementedBy;
QList<MemberContext> reimplementedByMembers;
QList<ArgumentListContext> templateArgList; QList<ArgumentListContext> templateArgList;
ScopedPtr<TemplateList> labels; ScopedPtr<TemplateList> labels;
TemplateVariant initializer;
bool initializerParsed;
TemplateVariant sourceCode;
bool sourceCodeParsed;
ScopedPtr<TemplateList> examples;
QList<TemplateStruct> exampleList;
ScopedPtr<ArgumentListContext> typeConstraints;
}; };
mutable Cachable m_cache; mutable Cachable m_cache;
TemplateList m_propertyAttrs; TemplateList m_propertyAttrs;
...@@ -4021,6 +4550,24 @@ MemberListContext::MemberListContext(const MemberList *list) ...@@ -4021,6 +4550,24 @@ MemberListContext::MemberListContext(const MemberList *list)
} }
} }
MemberListContext::MemberListContext(MemberSDict *list,bool doSort)
{
p = new Private;
if (list)
{
if (doSort)
{
list->sort();
}
MemberSDict::Iterator it(*list);
MemberDef *md;
for (it.toFirst();(md=it.current());++it)
{
p->addMember(md);
}
}
}
MemberListContext::~MemberListContext() MemberListContext::~MemberListContext()
{ {
delete p; delete p;
......
...@@ -25,6 +25,7 @@ class GroupDef; ...@@ -25,6 +25,7 @@ class GroupDef;
class GroupList; class GroupList;
struct IncludeInfo; struct IncludeInfo;
class MemberList; class MemberList;
class MemberSDict;
class MemberDef; class MemberDef;
struct Argument; struct Argument;
class ArgumentList; class ArgumentList;
...@@ -650,6 +651,7 @@ class MemberListContext : public TemplateListIntf ...@@ -650,6 +651,7 @@ class MemberListContext : public TemplateListIntf
{ {
public: public:
MemberListContext(const MemberList *ml); MemberListContext(const MemberList *ml);
MemberListContext(MemberSDict *ml,bool doSort);
~MemberListContext(); ~MemberListContext();
// TemplateListIntf // TemplateListIntf
......
...@@ -1050,6 +1050,13 @@ void Definition::setBodyDef(FileDef *fd) ...@@ -1050,6 +1050,13 @@ void Definition::setBodyDef(FileDef *fd)
m_impl->body->fileDef=fd; m_impl->body->fileDef=fd;
} }
bool Definition::hasSources() const
{
return m_impl->body && m_impl->body->startLine!=-1 &&
m_impl->body->endLine>=m_impl->body->startLine &&
m_impl->body->fileDef;
}
/*! Write code of this definition into the documentation */ /*! Write code of this definition into the documentation */
void Definition::writeInlineCode(OutputList &ol,const char *scopeName) void Definition::writeInlineCode(OutputList &ol,const char *scopeName)
{ {
...@@ -1057,9 +1064,7 @@ void Definition::writeInlineCode(OutputList &ol,const char *scopeName) ...@@ -1057,9 +1064,7 @@ void Definition::writeInlineCode(OutputList &ol,const char *scopeName)
ol.pushGeneratorState(); ol.pushGeneratorState();
//printf("Source Fragment %s: %d-%d bodyDef=%p\n",name().data(), //printf("Source Fragment %s: %d-%d bodyDef=%p\n",name().data(),
// m_startBodyLine,m_endBodyLine,m_bodyDef); // m_startBodyLine,m_endBodyLine,m_bodyDef);
if (inlineSources && if (inlineSources && hasSources())
m_impl->body && m_impl->body->startLine!=-1 &&
m_impl->body->endLine>=m_impl->body->startLine && m_impl->body->fileDef)
{ {
QCString codeFragment; QCString codeFragment;
int actualStart=m_impl->body->startLine,actualEnd=m_impl->body->endLine; int actualStart=m_impl->body->startLine,actualEnd=m_impl->body->endLine;
......
...@@ -137,7 +137,7 @@ class Definition : public DefinitionIntf ...@@ -137,7 +137,7 @@ class Definition : public DefinitionIntf
virtual QCString getSourceAnchor() const; virtual QCString getSourceAnchor() const;
/*! Returns the detailed description of this definition */ /*! Returns the detailed description of this definition */
QCString documentation() const; virtual QCString documentation() const;
/*! Returns the line number at which the detailed documentation was found. */ /*! Returns the line number at which the detailed documentation was found. */
int docLine() const; int docLine() const;
...@@ -148,7 +148,7 @@ class Definition : public DefinitionIntf ...@@ -148,7 +148,7 @@ class Definition : public DefinitionIntf
QCString docFile() const; QCString docFile() const;
/*! Returns the brief description of this definition. This can include commands. */ /*! Returns the brief description of this definition. This can include commands. */
QCString briefDescription(bool abbreviate=FALSE) const; virtual QCString briefDescription(bool abbreviate=FALSE) const;
/*! Returns a plain text version of the brief description suitable for use /*! Returns a plain text version of the brief description suitable for use
* as a tool tip. * as a tool tip.
...@@ -259,6 +259,7 @@ class Definition : public DefinitionIntf ...@@ -259,6 +259,7 @@ class Definition : public DefinitionIntf
MemberSDict *getReferencedByMembers() const; MemberSDict *getReferencedByMembers() const;
bool hasSections() const; bool hasSections() const;
bool hasSources() const;
/** returns TRUE if this class has a brief description */ /** returns TRUE if this class has a brief description */
bool hasBriefDescription() const; bool hasBriefDescription() const;
......
...@@ -282,7 +282,7 @@ class HtmlGenerator : public OutputGenerator ...@@ -282,7 +282,7 @@ class HtmlGenerator : public OutputGenerator
//{ t << "<tr><td valign=\"top\"><em>"; } //{ t << "<tr><td valign=\"top\"><em>"; }
{ t << "<tr><td class=\"fieldname\"><em>"; } { t << "<tr><td class=\"fieldname\"><em>"; }
void endDescTableTitle() void endDescTableTitle()
{ t << "</em>&nbsp;</td>"; } { t << "</em>&#160;</td>"; }
void startDescTableData() void startDescTableData()
//{ t << "<td>" << endl; } //{ t << "<td>" << endl; }
{ t << "<td class=\"fielddoc\">" << endl; } { t << "<td class=\"fielddoc\">" << endl; }
......
...@@ -449,27 +449,6 @@ static void writeTemplatePrefix(OutputList &ol,ArgumentList *al) ...@@ -449,27 +449,6 @@ static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
ol.docify("> "); ol.docify("> ");
} }
QCString extractDirection(QCString &docs)
{
QRegExp re("\\[[^\\]]+\\]"); // [...]
int l=0;
if (re.match(docs,0,&l)==0)
{
int inPos = docs.find("in", 1,FALSE);
int outPos = docs.find("out",1,FALSE);
bool input = inPos!=-1 && inPos<l;
bool output = outPos!=-1 && outPos<l;
if (input || output) // in,out attributes
{
docs = docs.mid(l); // strip attributes
if (input && output) return "[in,out]";
else if (input) return "[in]";
else if (output) return "[out]";
}
}
return QCString();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -4985,3 +4964,33 @@ void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef) ...@@ -4985,3 +4964,33 @@ void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef)
} }
} }
QCString MemberDef::briefDescription(bool abbr) const
{
if (m_impl->templateMaster)
{
return m_impl->templateMaster->briefDescription(abbr);
}
else
{
return Definition::briefDescription(abbr);
}
}
QCString MemberDef::documentation() const
{
if (m_impl->templateMaster)
{
return m_impl->templateMaster->documentation();
}
else
{
return Definition::documentation();
}
}
const ArgumentList *MemberDef::typeConstraints() const
{
return m_impl->typeConstraints;
}
...@@ -245,6 +245,14 @@ class MemberDef : public Definition ...@@ -245,6 +245,14 @@ class MemberDef : public Definition
QCString getDeclType() const; QCString getDeclType() const;
void getLabels(QStrList &sl,Definition *container) const; void getLabels(QStrList &sl,Definition *container) const;
const ArgumentList *typeConstraints() const;
// overrules
QCString documentation() const;
QCString briefDescription(bool abbr=FALSE) const;
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// ---- setters ----- // ---- setters -----
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
......
...@@ -104,8 +104,7 @@ class TemplateVariant::Private ...@@ -104,8 +104,7 @@ class TemplateVariant::Private
bool boolVal; bool boolVal;
const TemplateStructIntf *strukt; const TemplateStructIntf *strukt;
const TemplateListIntf *list; const TemplateListIntf *list;
FuncType func; Delegate delegate;
const void *obj;
bool raw; bool raw;
}; };
...@@ -158,12 +157,11 @@ TemplateVariant::TemplateVariant(const TemplateListIntf *l) ...@@ -158,12 +157,11 @@ TemplateVariant::TemplateVariant(const TemplateListIntf *l)
p->list = l; p->list = l;
} }
TemplateVariant::TemplateVariant(const void *obj,FuncType f) TemplateVariant::TemplateVariant(const TemplateVariant::Delegate &delegate)
{ {
p = new Private; p = new Private;
p->type = Function; p->type = Function;
p->func = f; p->delegate = delegate;
p->obj = obj;
} }
TemplateVariant::~TemplateVariant() TemplateVariant::~TemplateVariant()
...@@ -184,8 +182,7 @@ TemplateVariant::TemplateVariant(const TemplateVariant &v) ...@@ -184,8 +182,7 @@ TemplateVariant::TemplateVariant(const TemplateVariant &v)
case String: p->strVal = v.p->strVal; break; case String: p->strVal = v.p->strVal; break;
case Struct: p->strukt = v.p->strukt; break; case Struct: p->strukt = v.p->strukt; break;
case List: p->list = v.p->list; break; case List: p->list = v.p->list; break;
case Function: p->func = v.p->func; case Function: p->delegate= v.p->delegate;break;
p->obj = v.p->obj; break;
} }
} }
...@@ -201,8 +198,7 @@ TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v) ...@@ -201,8 +198,7 @@ TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v)
case String: p->strVal = v.p->strVal; break; case String: p->strVal = v.p->strVal; break;
case Struct: p->strukt = v.p->strukt; break; case Struct: p->strukt = v.p->strukt; break;
case List: p->list = v.p->list; break; case List: p->list = v.p->list; break;
case Function: p->func = v.p->func; case Function: p->delegate= v.p->delegate;break;
p->obj = v.p->obj; break;
} }
return *this; return *this;
} }
...@@ -305,7 +301,7 @@ const TemplateListIntf *TemplateVariant::toList() const ...@@ -305,7 +301,7 @@ const TemplateListIntf *TemplateVariant::toList() const
TemplateVariant TemplateVariant::call(const QValueList<TemplateVariant> &args) TemplateVariant TemplateVariant::call(const QValueList<TemplateVariant> &args)
{ {
if (p->type==Function) return p->func(p->obj,args); if (p->type==Function) return p->delegate(args);
return TemplateVariant(); return TemplateVariant();
} }
...@@ -766,14 +762,12 @@ class FilterDivisibleBy ...@@ -766,14 +762,12 @@ class FilterDivisibleBy
public: public:
static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &n) static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &n)
{ {
printf("FilterDivisibleBy::apply()\n");
if (!v.isValid() || !n.isValid()) if (!v.isValid() || !n.isValid())
{ {
return TemplateVariant(); return TemplateVariant();
} }
if (v.type()==TemplateVariant::Integer && n.type()==TemplateVariant::Integer) if (v.type()==TemplateVariant::Integer && n.type()==TemplateVariant::Integer)
{ {
printf("FilterDivisibleBy(%d,%d)=%d",v.toInt(),n.toInt(),(v.toInt()%n.toInt())==0);
return TemplateVariant((v.toInt()%n.toInt())==0); return TemplateVariant((v.toInt()%n.toInt())==0);
} }
else else
...@@ -2045,10 +2039,13 @@ class TemplateNodeMsg : public TemplateNodeCreator<TemplateNodeMsg> ...@@ -2045,10 +2039,13 @@ class TemplateNodeMsg : public TemplateNodeCreator<TemplateNodeMsg>
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c); TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
TemplateEscapeIntf *escIntf = ci->escapeIntf(); TemplateEscapeIntf *escIntf = ci->escapeIntf();
ci->setEscapeIntf(0); // avoid escaping things we send to standard out ci->setEscapeIntf(0); // avoid escaping things we send to standard out
bool enable = ci->spacelessEnabled();
ci->enableSpaceless(FALSE);
FTextStream ts(stdout); FTextStream ts(stdout);
m_nodes.render(ts,c); m_nodes.render(ts,c);
ts << endl; ts << endl;
ci->setEscapeIntf(escIntf); ci->setEscapeIntf(escIntf);
ci->enableSpaceless(enable);
} }
private: private:
TemplateNodeList m_nodes; TemplateNodeList m_nodes;
...@@ -2423,7 +2420,8 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree> ...@@ -2423,7 +2420,8 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
if (list && list->count()>0) // non-empty list if (list && list->count()>0) // non-empty list
{ {
TreeContext childCtx(this,list,ctx->templateCtx); TreeContext childCtx(this,list,ctx->templateCtx);
TemplateVariant children(&childCtx,renderChildrenStub); // TemplateVariant children(&childCtx,renderChildrenStub);
TemplateVariant children(TemplateVariant::Delegate::fromFunction(&childCtx,renderChildrenStub));
children.setRaw(TRUE); children.setRaw(TRUE);
c->set("children",children); c->set("children",children);
m_treeNodes.render(ss,c); m_treeNodes.render(ss,c);
......
...@@ -26,7 +26,7 @@ class TemplateEngine; ...@@ -26,7 +26,7 @@ class TemplateEngine;
* When the template engine encounters a variable, it evaluates that variable and * When the template engine encounters a variable, it evaluates that variable and
* replaces it with the result. Variable names consist of any combination of * replaces it with the result. Variable names consist of any combination of
* alphanumeric characters and the underscore ("_"). * alphanumeric characters and the underscore ("_").
* Use a dot (.) to access attributes of a variable. * Use a dot (.) to access attributes of a structured variable.
* *
* One can modify variables for display by using \b filters, for example: * One can modify variables for display by using \b filters, for example:
* `{{ value|default:"nothing" }}` * `{{ value|default:"nothing" }}`
...@@ -46,22 +46,27 @@ class TemplateEngine; ...@@ -46,22 +46,27 @@ class TemplateEngine;
* - `include` * - `include`
* - `with ... endwith` * - `with ... endwith`
* - `spaceless ... endspaceless` * - `spaceless ... endspaceless`
* * - `cycle`
* Supported Django filters:
* - `default`
* - `length`
* - `add`
* *
* Extension tags: * Extension tags:
* - `create` which instantiates a template and writes the result to a file. * - `create` which instantiates a template and writes the result to a file.
* The syntax is `{% create 'filename' from 'template' %}`. * The syntax is `{% create 'filename' from 'template' %}`.
* - `recursetree` * - `recursetree`
* - `markers` * - `markers`
* - `msg` ... `endmsg`
* - `set`
*
* Supported Django filters:
* - `default`
* - `length`
* - `add`
* - `divisibleby`
* *
* Extension filters: * Extension filters:
* - `stripPath` * - `stripPath`
* - `nowrap` * - `nowrap`
* - `prepend` * - `prepend`
* - `append`
* *
* @{ * @{
*/ */
...@@ -70,8 +75,50 @@ class TemplateEngine; ...@@ -70,8 +75,50 @@ class TemplateEngine;
class TemplateVariant class TemplateVariant
{ {
public: public:
/** Signature of the callback function, used for function type variants */ /** @brief Helper class to create a delegate that can store a function/method call. */
typedef TemplateVariant (*FuncType)(const void *obj, const QValueList<TemplateVariant> &args); class Delegate
{
public:
/** Callback type to use when creating a delegate from a function. */
typedef TemplateVariant (*StubType)(const void *obj, const QValueList<TemplateVariant> &args);
Delegate() : m_objectPtr(0) , m_stubPtr(0) {}
/** Creates a delegate given an object. The method to call is passed as a template parameter */
template <class T, TemplateVariant (T::*TMethod)(const QValueList<TemplateVariant> &) const>
static Delegate fromMethod(const T* objectPtr)
{
Delegate d;
d.m_objectPtr = objectPtr;
d.m_stubPtr = &methodStub<T, TMethod>;
return d;
}
/** Creates a delegate given an object, and a plain function. */
static Delegate fromFunction(const void *obj,StubType func)
{
Delegate d;
d.m_objectPtr = obj;
d.m_stubPtr = func;
return d;
}
/** Invokes the function/method stored in the delegate */
TemplateVariant operator()(const QValueList<TemplateVariant> &args) const
{
return (*m_stubPtr)(m_objectPtr, args);
}
private:
const void* m_objectPtr;
StubType m_stubPtr;
template <class T, TemplateVariant (T::*TMethod)(const QValueList<TemplateVariant> &) const>
static TemplateVariant methodStub(const void* objectPtr, const QValueList<TemplateVariant> &args)
{
T* p = (T*)(objectPtr);
return (p->*TMethod)(args);
}
};
/** Types of data that can be stored in a TemplateVariant */ /** Types of data that can be stored in a TemplateVariant */
enum Type { None, Bool, Integer, String, Struct, List, Function }; enum Type { None, Bool, Integer, String, Struct, List, Function };
...@@ -109,13 +156,14 @@ class TemplateVariant ...@@ -109,13 +156,14 @@ class TemplateVariant
*/ */
TemplateVariant(const TemplateListIntf *l); TemplateVariant(const TemplateListIntf *l);
/** Constructs a new variant which represents a function /** Constructs a new variant which represents a method call
* @param[in] obj Opaque user defined pointer, which * @param[in] delegate Delegate object to invoke when
* is passed back when call() is invoked.
* @param[in] func Callback function to invoke when
* calling call() on this variant. * calling call() on this variant.
* @note Use TemplateVariant::Delegate::fromMethod() and
* TemplateVariant::Delegate::fromFunction() to create
* Delegate objects.
*/ */
TemplateVariant(const void *obj,FuncType func); TemplateVariant(const Delegate &delegate);
/** Destroys the Variant object */ /** Destroys the Variant object */
~TemplateVariant(); ~TemplateVariant();
......
...@@ -8057,3 +8057,26 @@ bool classVisibleInIndex(ClassDef *cd) ...@@ -8057,3 +8057,26 @@ bool classVisibleInIndex(ClassDef *cd)
return (allExternals && cd->isLinkable()) || cd->isLinkableInProject(); return (allExternals && cd->isLinkable()) || cd->isLinkableInProject();
} }
//----------------------------------------------------------------------------
QCString extractDirection(QCString &docs)
{
QRegExp re("\\[[^\\]]+\\]"); // [...]
int l=0;
if (re.match(docs,0,&l)==0)
{
int inPos = docs.find("in", 1,FALSE);
int outPos = docs.find("out",1,FALSE);
bool input = inPos!=-1 && inPos<l;
bool output = outPos!=-1 && outPos<l;
if (input || output) // in,out attributes
{
docs = docs.mid(l); // strip attributes
if (input && output) return "[in,out]";
else if (input) return "[in]";
else if (output) return "[out]";
}
}
return QCString();
}
...@@ -446,7 +446,7 @@ uint getUtf8Code( const QCString& s, int idx ); ...@@ -446,7 +446,7 @@ uint getUtf8Code( const QCString& s, int idx );
uint getUtf8CodeToLower( const QCString& s, int idx ); uint getUtf8CodeToLower( const QCString& s, int idx );
uint getUtf8CodeToUpper( const QCString& s, int idx ); uint getUtf8CodeToUpper( const QCString& s, int idx );
QCString extractDirection(QCString &docs);
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment