/****************************************************************************** * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */ #include #include #include "context.h" #include "config.h" #include "index.h" #include "classlist.h" #include "doxygen.h" #include "namespacedef.h" #include "filedef.h" #include "pagedef.h" #include "groupdef.h" #include "util.h" #include "version.h" #include "language.h" #include "message.h" #include "vhdldocgen.h" #include "filename.h" #include "dirdef.h" #include "docparser.h" #include "htmlgen.h" #include "htmldocvisitor.h" #include "htmlhelp.h" #include "latexgen.h" #include "latexdocvisitor.h" #include "dot.h" #include "dotcallgraph.h" #include "dotclassgraph.h" #include "dotdirdeps.h" #include "dotgfxhierarchytable.h" #include "dotgroupcollaboration.h" #include "dotincldepgraph.h" #include "diagram.h" #include "example.h" #include "membername.h" #include "parserintf.h" #include "portable.h" #include "arguments.h" #include "groupdef.h" #include "searchindex.h" #include "resourcemgr.h" #include "dir.h" // TODO: pass the current file to Dot*::writeGraph, so the user can put dot graphs in other // files as well enum ContextOutputFormat { ContextOutputFormat_Unspecified=0, ContextOutputFormat_Html, ContextOutputFormat_Latex, ContextOutputFormat_Rtf, ContextOutputFormat_ManPage, ContextOutputFormat_DocBook, ContextOutputFormat_Xml, ContextOutputFormat_TagFile }; struct ContextGlobals { int dynSectionId; QCString outputDir; ContextOutputFormat outputFormat; } g_globals; /** @brief Scoped smart pointer */ template class ScopedPtr { private: T *m_ptr; ScopedPtr(const ScopedPtr &); ScopedPtr &operator=(const ScopedPtr &); void operator==(const ScopedPtr &) const; void operator!=(const ScopedPtr &) const; public: typedef T Type; explicit ScopedPtr(T *p=0) : m_ptr(p) {} ~ScopedPtr() { delete m_ptr; }; T &operator*() const { return *m_ptr; } T *operator->() const { return m_ptr; } T *get() const { return m_ptr; } operator bool() const { return m_ptr!=0; } void reset(T *p=0) { if (p!=m_ptr) { delete m_ptr; m_ptr = p; } } }; /** @brief Reference counting smart pointer */ template class SharedPtr { private: T *m_ptr; SharedPtr(const SharedPtr &); SharedPtr &operator=(const SharedPtr &p); void operator==(const SharedPtr &) const; void operator!=(const SharedPtr &) const; public: typedef T Type; explicit SharedPtr(T *p=0) : m_ptr(p) { if (m_ptr) m_ptr->addRef(); } ~SharedPtr() { if (m_ptr) m_ptr->release(); }; T &operator*() const { return *m_ptr; } T *operator->() const { return m_ptr; } T *get() const { return m_ptr; } operator bool() const { return m_ptr!=0; } void reset(T *p=0) { if (p) p->addRef(); if (m_ptr) m_ptr->release(); m_ptr = p; } }; /** @brief Template List iterator support */ class GenericConstIterator : public TemplateListIntf::ConstIterator { public: GenericConstIterator(const std::vector &list) : m_list(list) {} virtual ~GenericConstIterator() {} void toFirst() { m_index=0; } void toLast() { m_index=static_cast(m_list.size())-1; } void toNext() { if (m_index < static_cast(m_list.size())) ++m_index; } void toPrev() { if (m_index>=0) --m_index; } bool current(TemplateVariant &v) const { if (m_index>=0 && m_index < static_cast(m_list.size())) { v = m_list[m_index]; return true; } else { v = TemplateVariant(); return false; } } private: const std::vector &m_list; int m_index=0; }; //------------------------------------------------------------------------ /** @brief standard template list implementation */ class GenericNodeListContext : public TemplateListIntf { public: GenericNodeListContext() : m_refCount(0) { } static GenericNodeListContext *alloc() { return new GenericNodeListContext; } // TemplateListIntf methods uint count() const { return static_cast(m_children.size()); } TemplateVariant at(uint index) const { TemplateVariant result; if (index m_children; int m_refCount; }; //------------------------------------------------------------------------ /** @brief Helper class to map a property name to a handler member function */ template class PropertyMapper { private: struct PropertyFuncIntf { virtual ~PropertyFuncIntf() {} virtual TemplateVariant operator()(const T *obj) const = 0; }; struct PropertyFunc : public PropertyFuncIntf { typedef TemplateVariant (T::*Handler)() const; PropertyFunc(Handler h) : handler(h) {} TemplateVariant operator()(const T *obj) const { return (obj->*handler)(); } Handler handler; }; public: /** Add a property to the map * @param[in] name The name of the property to add. * @param[in] handle The method to call when the property is accessed. */ void addProperty(const char *name,typename PropertyFunc::Handler handle) { auto it = m_map.find(name); if (it!=m_map.end()) { err("adding property '%s' more than once\n",name); } else { m_map.insert(std::make_pair(name,std::make_unique(handle))); } } /** Gets the value of a property. * @param[in] obj The object handling access to the property. * @param[in] name The name of the property. * @returns A variant representing the properties value or an * invalid variant if it was not found. */ TemplateVariant get(const T *obj,const char *name) const { //printf("PropertyMapper::get(%s)\n",name); TemplateVariant result; auto it = m_map.find(name); return it!=m_map.end() ? (*it->second)(obj) : TemplateVariant(); } private: std::unordered_map> m_map; }; //------------------------------------------------------------------------ //%% struct Config : configuration options //%% { class ConfigContext::Private { public: Private() { } virtual ~Private() { } TemplateVariant fetchList(const QCString &name,const StringVector &list) { auto it = m_cachedLists.find(name.str()); if (it==m_cachedLists.end()) { TemplateList *tlist = TemplateList::alloc(); m_cachedLists.insert(std::make_pair(name.str(),TemplateVariant(tlist))); for (const auto &s : list) { tlist->append(s.c_str()); } return tlist; } else { return it->second; } } private: std::unordered_map m_cachedLists; }; //%% } ConfigContext::ConfigContext() : RefCountedContext("ConfigContext") { p = new Private; } ConfigContext::~ConfigContext() { delete p; } TemplateVariant ConfigContext::get(const char *name) const { TemplateVariant result; if (name) { const ConfigValues::Info *option = ConfigValues::instance().get(name); if (option) { switch (option->type) { case ConfigValues::Info::Bool: { bool b = ConfigValues::instance().*(option->value.b); return TemplateVariant(b); } case ConfigValues::Info::Int: { int i = ConfigValues::instance().*(option->value.i); return TemplateVariant(i); } case ConfigValues::Info::String: { QCString s = ConfigValues::instance().*(option->value.s); return TemplateVariant(s); } case ConfigValues::Info::List: { const StringVector &l = ConfigValues::instance().*(option->value.l); return p->fetchList(name,l); } default: break; } } } return result; } //------------------------------------------------------------------------ //%% struct Doxygen: global information //%% { class DoxygenContext::Private { public: TemplateVariant version() const { return getDoxygenVersion(); } TemplateVariant date() const { return dateToString(TRUE); } TemplateVariant maxJaxCodeFile() const { return m_cache.maxJaxCodeFile; } Private() { static bool init=FALSE; if (!init) { //%% string version s_inst.addProperty("version", &Private::version); //%% string date s_inst.addProperty("date", &Private::date); //%% string maxJaxCodeFile s_inst.addProperty("mathJaxCodeFile", &Private::maxJaxCodeFile); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } private: struct Cachable { Cachable() { maxJaxCodeFile=fileToString(Config_getString(MATHJAX_CODEFILE)); } QCString maxJaxCodeFile; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper DoxygenContext::Private::s_inst; // (PropertyMapper::instance()); DoxygenContext::DoxygenContext() : RefCountedContext("DoxygenContext") { p = new Private; } DoxygenContext::~DoxygenContext() { delete p; } TemplateVariant DoxygenContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Translator: translation methods //%% { class TranslateContext::Private { public: TemplateVariant handleGeneratedAt(const std::vector &args) const { if (args.size()==2) { return theTranslator->trGeneratedAt(args[0].toString(),args[1].toString()); } else { err("tr.generateAt should take two arguments, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleInheritanceDiagramFor(const std::vector &args) const { if (args.size()==1) { return theTranslator->trClassDiagram(args[0].toString()); } else { err("tr.inheritanceDiagramFor should take one argument, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleCollaborationDiagramFor(const std::vector &args) const { if (args.size()==1) { return theTranslator->trCollaborationDiagram(args[0].toString()); } else { err("tr.collaborationDiagramFor should take one argument, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleDirDependencyGraphFor(const std::vector &args) const { if (args.size()==1) { return theTranslator->trDirDepGraph(args[0].toString()); } else { err("tr.dirDependencyGraphFor should take one argument, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleInheritsList(const std::vector &args) const { if (args.size()==1) { return theTranslator->trInheritsList(args[0].toInt()); } else { err("tr.inheritsList should take one integer argument, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleInheritedByList(const std::vector &args) const { if (args.size()==1) { return theTranslator->trInheritedByList(args[0].toInt()); } else { err("tr.inheritedByList should take one integer argument, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleWriteList(const std::vector &args) const { if (args.size()==1) { return theTranslator->trWriteList(args[0].toInt()); } else { err("tr.*List should take one integer argument, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleImplementedBy(const std::vector &args) const { if (args.size()==1) { return theTranslator->trImplementedInList(args[0].toInt()); } else { err("tr.implementedBy should take one integer argument, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleReimplementedBy(const std::vector &args) const { if (args.size()==1) { return theTranslator->trReimplementedInList(args[0].toInt()); } else { err("tr.reimplementedBy should take one integer argument, got %zu!\n",args.size()); } return TemplateVariant(); } TemplateVariant handleSourceRefs(const std::vector &args) const { if (args.size()==1) { return theTranslator->trReferences()+" "+theTranslator->trWriteList(args[0].toInt())+"."; } else { err("tr.sourceRefs should take one integer argument, got %zu\n",args.size()); } return TemplateVariant(); } TemplateVariant handleSourceRefBys(const std::vector &args) const { if (args.size()==1) { return theTranslator->trReferencedBy()+" "+theTranslator->trWriteList(args[0].toInt())+"."; } else { err("tr.sourceRefBys should take one integer argument, got %zu\n",args.size()); } return TemplateVariant(); } TemplateVariant handleIncludeDependencyGraph(const std::vector &args) const { if (args.size()==1) { return theTranslator->trInclDepGraph(args[0].toString()); } else { err("tr.includeDependencyGraph should take one string argument, got %zu\n",args.size()); } return TemplateVariant(); } TemplateVariant generatedBy() const { return theTranslator->trGeneratedBy(); } TemplateVariant generatedAt() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant inheritanceDiagramFor() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant collaborationDiagramFor() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant dirDependencyGraphFor() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant search() const { return theTranslator->trSearch(); } TemplateVariant mainPage() const { return theTranslator->trMainPage(); } TemplateVariant classes() const { return theTranslator->trClasses(); // TODO: VHDL: theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE) // TODO: Fortran: trDataTypes() } TemplateVariant classList() const { return theTranslator->trCompoundList(); } TemplateVariant classListDescription() const { return theTranslator->trCompoundListDescription(); } TemplateVariant classIndex() const { return theTranslator->trCompoundIndex(); } TemplateVariant namespaceIndex() const { return theTranslator->trNamespaceIndex(); } TemplateVariant classHierarchy() const { return theTranslator->trClassHierarchy(); } TemplateVariant classMembers() const { return theTranslator->trCompoundMembers(); } TemplateVariant modules() const { return theTranslator->trModules(); } TemplateVariant moduleIndex() const { return theTranslator->trModuleIndex(); } TemplateVariant namespaces() const { if (m_javaOpt || m_vhdlOpt) { return theTranslator->trPackages(); } else if (m_fortranOpt || m_sliceOpt) { return theTranslator->trModules(); } else { return theTranslator->trNamespaces(); } } TemplateVariant files() const { return theTranslator->trFile(TRUE,FALSE); } TemplateVariant fileIndex() const { return theTranslator->trFileIndex(); } TemplateVariant pages() const { return theTranslator->trRelatedPages(); } TemplateVariant examples() const { return theTranslator->trExamples(); } TemplateVariant namespaceList() const { if (m_javaOpt || m_vhdlOpt) { return theTranslator->trPackages(); } else if (m_fortranOpt || m_sliceOpt) { return theTranslator->trModulesList(); } else { return theTranslator->trNamespaceList(); } } TemplateVariant namespaceMembers() const { if (m_javaOpt || m_vhdlOpt) { return theTranslator->trPackageMembers(); } else if (m_fortranOpt || m_sliceOpt) { return theTranslator->trModulesMembers(); } else { return theTranslator->trNamespaceMembers(); } } TemplateVariant moduleDocumentation() const { return theTranslator->trModuleDocumentation(); } TemplateVariant fileDocumentation() const { return theTranslator->trFileDocumentation(); } TemplateVariant fileList() const { return theTranslator->trFileList(); } TemplateVariant fileMembers() const { return theTranslator->trFileMembers(); } TemplateVariant fileMembersDescription() const { static bool extractAll = Config_getBool(EXTRACT_ALL); return theTranslator->trFileMembersDescription(extractAll); } TemplateVariant namespaceMembersDescription() const { static bool extractAll = Config_getBool(EXTRACT_ALL); return theTranslator->trNamespaceMemberDescription(extractAll); } TemplateVariant classHierarchyDescription() const { return theTranslator->trClassHierarchyDescription(); } TemplateVariant gotoGraphicalHierarchy() const { return theTranslator->trGotoGraphicalHierarchy(); } TemplateVariant gotoTextualHierarchy() const { return theTranslator->trGotoTextualHierarchy(); } TemplateVariant classMembersDescription() const { static bool extractAll = Config_getBool(EXTRACT_ALL); static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); if (fortranOpt) { return theTranslator->trCompoundMembersDescriptionFortran(extractAll); } else { return theTranslator->trCompoundMembersDescription(extractAll); } } TemplateVariant relatedPagesDesc() const { return theTranslator->trRelatedPagesDescription(); } TemplateVariant more() const { return theTranslator->trMore(); } TemplateVariant detailedDesc() const { return theTranslator->trDetailedDescription(); } TemplateVariant inheritsList() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant inheritedByList() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant definedAtLineInSourceFile() const { return theTranslator->trDefinedAtLineInSourceFile(); } TemplateVariant typeConstraints() const { return theTranslator->trTypeConstraints(); } TemplateVariant exampleList() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant listOfAllMembers() const { return theTranslator->trListOfAllMembers(); } TemplateVariant memberList() const { return theTranslator->trMemberList(); } TemplateVariant theListOfAllMembers() const { return theTranslator->trThisIsTheListOfAllMembers(); } TemplateVariant incInheritedMembers() const { 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(this); } TemplateVariant reimplementedBy() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant sourceRefs() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant sourceRefBys() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant callGraph() const { return theTranslator->trCallGraph(); } TemplateVariant callerGraph() const { return theTranslator->trCallerGraph(); } TemplateVariant referencedByRelation() const { return theTranslator->trReferencedBy(); } TemplateVariant referencesRelation() const { return theTranslator->trReferences(); } TemplateVariant inheritedFrom() const { return theTranslator->trInheritedFrom("@0","@1"); } TemplateVariant additionalInheritedMembers() const { return theTranslator->trAdditionalInheritedMembers(); } TemplateVariant includeDependencyGraph() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant includedByDependencyGraph() const { return theTranslator->trInclByDepGraph(); } TemplateVariant gotoSourceCode() const { return theTranslator->trGotoSourceCode(); } TemplateVariant gotoDocumentation() const { return theTranslator->trGotoDocumentation(); } TemplateVariant constantgroups() const { return theTranslator->trConstantGroups(); } TemplateVariant classDocumentation() const { return theTranslator->trClassDocumentation(); } TemplateVariant namespaceDocumentation() const { return theTranslator->trNamespaceDocumentation(); } TemplateVariant compoundMembers() const { return theTranslator->trCompoundMembers(); } TemplateVariant detailLevel() const { return theTranslator->trDetailLevel(); } TemplateVariant fileListDescription() const { bool extractAll = Config_getBool(EXTRACT_ALL); return theTranslator->trFileListDescription(extractAll); } TemplateVariant modulesDescription() const { bool extractAll = Config_getBool(EXTRACT_ALL); return theTranslator->trModulesListDescription(extractAll); } TemplateVariant namespaceListDescription() const { bool extractAll = Config_getBool(EXTRACT_ALL); return theTranslator->trNamespaceListDescription(extractAll); } TemplateVariant directories() const { return theTranslator->trDirectories(); } TemplateVariant all() const { return theTranslator->trAll(); } TemplateVariant functions() const { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); return fortranOpt ? theTranslator->trSubprograms() : vhdlOpt ? theTranslator->trFunctionAndProc() : theTranslator->trFunctions(); } TemplateVariant variables() const { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables(); } TemplateVariant typedefs() const { return theTranslator->trTypedefs(); } TemplateVariant enums() const { return theTranslator->trEnumerations(); } TemplateVariant properties() const { return theTranslator->trProperties(); } TemplateVariant events() const { return theTranslator->trEvents(); } TemplateVariant related() const { return theTranslator->trRelatedFunctions(); } TemplateVariant macros() const { return theTranslator->trDefines(); } TemplateVariant loading() const { return theTranslator->trLoading(); } TemplateVariant searching() const { return theTranslator->trSearching(); } TemplateVariant noMatches() const { return theTranslator->trNoMatches(); } TemplateVariant enumName() const { return theTranslator->trEnumName(); } TemplateVariant enumValue() const { return theTranslator->trEnumValue(); } TemplateVariant referenceManual() const { return theTranslator->trReferenceManual(); } TemplateVariant index() const { return theTranslator->trRTFGeneralIndex(); } TemplateVariant panelSyncOn() const { return theTranslator->trPanelSynchronisationTooltip(FALSE); } TemplateVariant panelSyncOff() const { return theTranslator->trPanelSynchronisationTooltip(TRUE); } TemplateVariant providedByCategory() const { return theTranslator->trProvidedByCategory(); } TemplateVariant extendsClass() const { return theTranslator->trExtendsClass(); } TemplateVariant examplesDescription() const { return theTranslator->trExamplesDescription(); } TemplateVariant langString() const { return HtmlHelp::getLanguageString(); } Private() { static bool init=FALSE; if (!init) { //%% string generatedBy s_inst.addProperty("generatedBy", &Private::generatedBy); //%% string generatedAt s_inst.addProperty("generatedAt", &Private::generatedAt); //%% string search s_inst.addProperty("search", &Private::search); //%% string mainPage s_inst.addProperty("mainPage", &Private::mainPage); //%% string classes s_inst.addProperty("classes", &Private::classes); //%% string classList s_inst.addProperty("classList", &Private::classList); //%% string classListDescription s_inst.addProperty("classListDescription", &Private::classListDescription); //%% string classIndex s_inst.addProperty("classIndex", &Private::classIndex); //%% string namespaceIndex s_inst.addProperty("namespaceIndex", &Private::namespaceIndex); //%% string classHierarchy s_inst.addProperty("classHierarchy", &Private::classHierarchy); //%% string classMembers s_inst.addProperty("classMembers", &Private::classMembers); //%% string classMembersDescription s_inst.addProperty("classMembersDescription",&Private::classMembersDescription); //%% string modules s_inst.addProperty("modules", &Private::modules); //%% string moduleIndex s_inst.addProperty("moduleIndex", &Private::moduleIndex); //%% string namespaces s_inst.addProperty("namespaces", &Private::namespaces); //%% string fileIndex s_inst.addProperty("fileIndex", &Private::fileIndex); //%% string files s_inst.addProperty("files", &Private::files); //%% string pages s_inst.addProperty("pages", &Private::pages); //%% string examples s_inst.addProperty("examples", &Private::examples); //%% string namespaceList s_inst.addProperty("namespaceList", &Private::namespaceList); //%% string namespaceMembers s_inst.addProperty("namespaceMembers", &Private::namespaceMembers); //%% string fileList s_inst.addProperty("fileList", &Private::fileList); //%% string fileMembers s_inst.addProperty("fileMembers", &Private::fileMembers); //%% string fileMembersDescription s_inst.addProperty("fileMembersDescription", &Private::fileMembersDescription); //%% string relatedPagesDescription s_inst.addProperty("relatedPagesDesc", &Private::relatedPagesDesc); //%% string more s_inst.addProperty("more", &Private::more); //%% string detailedDescription s_inst.addProperty("detailedDesc", &Private::detailedDesc); //%% string inheritanceDiagramFor s_inst.addProperty("inheritanceDiagramFor", &Private::inheritanceDiagramFor); //%% string collaborationDiagramFor s_inst.addProperty("collaborationDiagramFor", &Private::collaborationDiagramFor); //%% markerstring inheritsList s_inst.addProperty("inheritsList", &Private::inheritsList); //%% markerstring inheritedByList s_inst.addProperty("inheritedByList", &Private::inheritedByList); //%% markerstring definedAtLineInSourceFile s_inst.addProperty("definedAtLineInSourceFile", &Private::definedAtLineInSourceFile); //%% string typeConstraints s_inst.addProperty("typeConstraints", &Private::typeConstraints); //%% string exampleList s_inst.addProperty("exampleList", &Private::exampleList); //%% string listOfAllMembers s_inst.addProperty("listOfAllMembers", &Private::listOfAllMembers); //%% string memberList s_inst.addProperty("memberList", &Private::memberList); //%% string theListOfAllMembers s_inst.addProperty("theListOfAllMembers",&Private::theListOfAllMembers); //%% string incInheritedMembers s_inst.addProperty("incInheritedMembers",&Private::incInheritedMembers); //%% string defineValue s_inst.addProperty("defineValue", &Private::defineValue); //%% string initialValue s_inst.addProperty("initialValue", &Private::initialValue); //%% markerstring implements s_inst.addProperty("implements", &Private::implements); //%% markerstring reimplements s_inst.addProperty("reimplements", &Private::reimplements); //%% markerstring implementedBy s_inst.addProperty("implementedBy", &Private::implementedBy); //%% markerstring reimplementedBy s_inst.addProperty("reimplementedBy", &Private::reimplementedBy); //%% markerstring sourceRefs s_inst.addProperty("sourceRefs", &Private::sourceRefs); //%% markerstring sourceRefBys s_inst.addProperty("sourceRefBys", &Private::sourceRefBys); //%% string callGraph s_inst.addProperty("callGraph", &Private::callGraph); //%% string callerGraph s_inst.addProperty("callerGraph", &Private::callerGraph); //%% string referencedByRelation s_inst.addProperty("referencedByRelation", &Private::referencedByRelation); //%% string referencesRelation s_inst.addProperty("referencesRelation", &Private::referencesRelation); //%% markerstring inheritedFrom s_inst.addProperty("inheritedFrom", &Private::inheritedFrom); //%% string additionalInheritedMembers s_inst.addProperty("additionalInheritedMembers",&Private::additionalInheritedMembers); //%% string includeDependencyGraph:container_name s_inst.addProperty("includeDependencyGraph",&Private::includeDependencyGraph); //%% string includedByDependencyGraph s_inst.addProperty("includedByDependencyGraph",&Private::includedByDependencyGraph); //%% string gotoSourceCode s_inst.addProperty("gotoSourceCode", &Private::gotoSourceCode); //%% string gotoDocumentation s_inst.addProperty("gotoDocumentation", &Private::gotoDocumentation); //%% string constantgroups s_inst.addProperty("constantgroups", &Private::constantgroups); //%% string classDocumentation s_inst.addProperty("classDocumentation", &Private::classDocumentation); //%% string namespaceDocumentation s_inst.addProperty("namespaceDocumentation", &Private::namespaceDocumentation); //%% string moduleDocumentation s_inst.addProperty("moduleDocumentation",&Private::moduleDocumentation); //%% string fileDocumentation s_inst.addProperty("fileDocumentation", &Private::fileDocumentation); //%% string compoundMembers s_inst.addProperty("compoundMembers", &Private::compoundMembers); //%% string detailLevel s_inst.addProperty("detailLevel", &Private::detailLevel); //%% string fileListDescription s_inst.addProperty("fileListDescription",&Private::fileListDescription); //%% string namespaceListDescription s_inst.addProperty("namespaceListDescription",&Private::namespaceListDescription); //%% string directories s_inst.addProperty("directories", &Private::directories); //%% string moduleDescription s_inst.addProperty("modulesDescription", &Private::modulesDescription); //%% string all s_inst.addProperty("all", &Private::all); //%% string functions s_inst.addProperty("functions", &Private::functions); //%% string variables s_inst.addProperty("variables", &Private::variables); //%% string typedefs s_inst.addProperty("typedefs", &Private::typedefs); //%% string enums s_inst.addProperty("enums", &Private::enums); //%% string enumValues s_inst.addProperty("enumValues", &Private::enumerationValues); //%% string properties s_inst.addProperty("properties", &Private::properties); //%% string events s_inst.addProperty("events", &Private::events); //%% string related s_inst.addProperty("related", &Private::related); //%% string macros s_inst.addProperty("macros", &Private::macros); //%% string namespaceMembersDescription s_inst.addProperty("namespaceMembersDescription",&Private::namespaceMembersDescription); //%% string classHierarchyDescription s_inst.addProperty("classHierarchyDescription",&Private::classHierarchyDescription); //%% string gotoGraphicalHierarchy s_inst.addProperty("gotoGraphicalHierarchy",&Private::gotoGraphicalHierarchy); //%% string gotoTextualHierarchy s_inst.addProperty("gotoTextualHierarchy",&Private::gotoTextualHierarchy); //%% string loading s_inst.addProperty("loading", &Private::loading); //%% string searching s_inst.addProperty("searching", &Private::searching); //%% string noMatches s_inst.addProperty("noMatches", &Private::noMatches); //%% string enumValue s_inst.addProperty("enumValue", &Private::enumValue); //%% string enumName s_inst.addProperty("enumName", &Private::enumName); //%% string referenceManual s_inst.addProperty("referenceManual", &Private::referenceManual); //%% string index s_inst.addProperty("index", &Private::index); //%% string panelSyncOn s_inst.addProperty("panelSyncOn", &Private::panelSyncOn); //%% string panelSyncOff s_inst.addProperty("panelSyncOff", &Private::panelSyncOff); //%% string dirDependencyGraph s_inst.addProperty("dirDependencyGraphFor", &Private::dirDependencyGraphFor); //%% string providedByCategory s_inst.addProperty("providedByCategory", &Private::providedByCategory); //%% string extendsClass s_inst.addProperty("extendsClass", &Private::extendsClass); //%% string examplesDescription s_inst.addProperty("examplesDescription",&Private::examplesDescription); //%% string langstring s_inst.addProperty("langString", &Private::langString); init=TRUE; } m_javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA); m_fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); m_vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); m_sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } private: bool m_javaOpt; bool m_fortranOpt; bool m_vhdlOpt; bool m_sliceOpt; static PropertyMapper s_inst; }; //%% } PropertyMapper TranslateContext::Private::s_inst; TranslateContext::TranslateContext() : RefCountedContext("TranslateContext") { p = new Private; } TranslateContext::~TranslateContext() { delete p; } TemplateVariant TranslateContext::get(const char *n) const { return p->get(n); } static TemplateVariant parseDoc(const Definition *def,const QCString &file,int line, const QCString &relPath,const QCString &docStr,bool isBrief) { TemplateVariant result; DocRoot *root = validatingParseDoc(file,line,def,0,docStr,TRUE,FALSE, 0,isBrief,FALSE,Config_getBool(MARKDOWN_SUPPORT)); std::ostringstream ts(std::ios_base::ate); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { HtmlCodeGenerator codeGen(ts,relPath); HtmlDocVisitor visitor(ts,codeGen,def); root->accept(&visitor); } break; case ContextOutputFormat_Latex: { LatexCodeGenerator codeGen(ts,relPath,file); LatexDocVisitor visitor(ts,codeGen,def->getDefFileExtension(),FALSE); root->accept(&visitor); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } std::string docs = ts.str(); bool isEmpty = root->isEmpty(); if (isEmpty) result = ""; else result = TemplateVariant(docs.c_str(),TRUE); delete root; 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) { auto intf = Doxygen::parserManager->getCodeParser(md->getDefFileExtension()); intf->resetCodeParserState(); std::ostringstream t(std::ios_base::ate); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { HtmlCodeGenerator codeGen(t,relPath); intf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), startLine,endLine,TRUE,md,showLineNumbers,md); } break; case ContextOutputFormat_Latex: { LatexCodeGenerator codeGen(t,relPath,md->docFile()); intf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), startLine,endLine,TRUE,md,showLineNumbers,md); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } QCString s = t.str(); return TemplateVariant(s.data(),TRUE); } static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) { static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); auto intf = Doxygen::parserManager->getCodeParser(fd->getDefFileExtension()); intf->resetCodeParserState(); std::ostringstream t(std::ios_base::ate); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { HtmlCodeGenerator codeGen(t,relPath); intf->parseCode(codeGen,0, fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources fd->getLanguage(), // lang FALSE, // isExampleBlock 0, // exampleName const_cast(fd), // fileDef, TODO: should be const -1, // startLine -1, // endLine FALSE, // inlineFragment 0, // memberDef TRUE, // showLineNumbers 0, // searchCtx TRUE // collectXRefs, TODO: should become FALSE ); } break; case ContextOutputFormat_Latex: { LatexCodeGenerator codeGen(t,relPath,fd->docFile()); intf->parseCode(codeGen,0, fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources fd->getLanguage(), // lang FALSE, // isExampleBlock 0, // exampleName const_cast(fd), // fileDef, TODO: should be const -1, // startLine -1, // endLine FALSE, // inlineFragment 0, // memberDef TRUE, // showLineNumbers 0, // searchCtx TRUE // collectXRefs, TODO: should become FALSE ); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } QCString s = t.str(); return TemplateVariant(s.data(),TRUE); } //------------------------------------------------------------------------ //%% struct Symbol: shared info for all symbols //%% { template class DefinitionContext { public: DefinitionContext(const Definition *d) : m_def(d) { assert(d!=0); } virtual ~DefinitionContext() {} void addBaseProperties(PropertyMapper &inst) { //%% string name: the name of the symbol inst.addProperty("name",&DefinitionContext::name); //%% string bareName: the bare name of the symbol with scope info inst.addProperty("bareName",&DefinitionContext::bareName); //%% string relPath: the relative path to the root of the output (CREATE_SUBDIRS) inst.addProperty("relPath",&DefinitionContext::relPath); //%% string fileName: the file name of the output file associated with the symbol (without extension) inst.addProperty("fileName",&DefinitionContext::fileName); //%% string anchor: anchor within the page inst.addProperty("anchor",&DefinitionContext::anchor); //%% string details: the detailed documentation for this symbol inst.addProperty("details",&DefinitionContext::details); //%% string brief: the brief description for this symbol inst.addProperty("brief",&DefinitionContext::brief); //%% string inbodyDocs: the documentation found in the body inst.addProperty("inbodyDocs",&DefinitionContext::inbodyDocs); //%% string sourceFileName: the file name of the source file (without extension) inst.addProperty("sourceFileName",&DefinitionContext::sourceFileName); //%% bool isLinkable: can the symbol be linked to? inst.addProperty("isLinkable",&DefinitionContext::isLinkable); //%% bool isLinkableInProject: can the symbol be linked within this project? inst.addProperty("isLinkableInProject",&DefinitionContext::isLinkableInProject); //%% int dynSectionId: identifier that can be used for collapsible sections inst.addProperty("dynSectionId",&DefinitionContext::dynSectionId); //%% string language: the programming language in which the symbol is written inst.addProperty("language",&DefinitionContext::language); //%% string sourceDef: A link to the source definition inst.addProperty("sourceDef",&DefinitionContext::sourceDef); //%% list[Definition] navigationPath: Breadcrumb navigation path to this item inst.addProperty("navigationPath",&DefinitionContext::navigationPath); //%% string kind: Kind of compound object: class, namespace, module, package, page, dir inst.addProperty("compoundKind",&DefinitionContext::compoundKind); //%% bool isReference: is this definition imported via a tag file inst.addProperty("isReference",&DefinitionContext::isReference); //%% string externalReference: the link to the element in the remote documentation inst.addProperty("externalReference",&DefinitionContext::externalReference); } TemplateVariant fileName() const { return m_def->getOutputFileBase(); } TemplateVariant anchor() const { return m_def->anchor(); } TemplateVariant sourceFileName() const { return m_def->getSourceFileBase(); } TemplateVariant isLinkable() const { return m_def->isLinkable(); } TemplateVariant isLinkableInProject() const { return m_def->isLinkableInProject(); } TemplateVariant name() const { return m_def->displayName(TRUE); } TemplateVariant bareName() const { return m_def->displayName(FALSE); } QCString relPathAsString() const { static bool createSubdirs = Config_getBool(CREATE_SUBDIRS); return createSubdirs ? QCString("../../") : QCString(""); } virtual TemplateVariant relPath() const { return relPathAsString(); } TemplateVariant details() const { Cachable &cache = getCache(); if (!cache.details || g_globals.outputFormat!=cache.detailsOutputFormat) { cache.details.reset(new TemplateVariant(parseDoc(m_def,m_def->docFile(),m_def->docLine(), relPathAsString(),m_def->documentation(),FALSE))); cache.detailsOutputFormat = g_globals.outputFormat; } return *cache.details; } TemplateVariant brief() const { Cachable &cache = getCache(); if (!cache.brief || g_globals.outputFormat!=cache.briefOutputFormat) { if (m_def->hasBriefDescription()) { cache.brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(), relPathAsString(),m_def->briefDescription(),TRUE))); cache.briefOutputFormat = g_globals.outputFormat; } else { cache.brief.reset(new TemplateVariant("")); } } return *cache.brief; } TemplateVariant inbodyDocs() const { Cachable &cache = getCache(); if (!cache.inbodyDocs || g_globals.outputFormat!=cache.inbodyDocsOutputFormat) { if (!m_def->inbodyDocumentation().isEmpty()) { cache.inbodyDocs.reset(new TemplateVariant(parseDoc(m_def,m_def->inbodyFile(),m_def->inbodyLine(), relPathAsString(),m_def->inbodyDocumentation(),FALSE))); cache.inbodyDocsOutputFormat = g_globals.outputFormat; } else { cache.inbodyDocs.reset(new TemplateVariant("")); } } return *cache.inbodyDocs; } TemplateVariant dynSectionId() const { return g_globals.dynSectionId; } TemplateVariant language() const { SrcLangExt lang = m_def->getLanguage(); QCString result = "unknown"; switch (lang) { case SrcLangExt_Unknown: break; case SrcLangExt_IDL: result="idl"; break; case SrcLangExt_Java: result="java"; break; case SrcLangExt_CSharp: result="csharp"; break; case SrcLangExt_D: result="d"; break; case SrcLangExt_PHP: result="php"; break; case SrcLangExt_ObjC: result="objc"; break; case SrcLangExt_Cpp: result="cpp"; break; case SrcLangExt_JS: result="js"; break; case SrcLangExt_Python: result="python"; break; case SrcLangExt_Fortran: result="fortran"; break; case SrcLangExt_VHDL: result="vhdl"; break; case SrcLangExt_XML: result="xml"; break; case SrcLangExt_SQL: result="sql"; break; case SrcLangExt_Markdown: result="markdown"; break; case SrcLangExt_Slice: result="slice"; break; case SrcLangExt_Lex: result="lex"; break; } return result; } TemplateVariant compoundKind() const { QCString result = "unspecified"; switch (m_def->definitionType()) { case Definition::TypeClass: result="class"; break; case Definition::TypeFile: result="file"; break; case Definition::TypeNamespace: result="namespace"; break; case Definition::TypeGroup: result="module"; break; case Definition::TypePackage: result="package"; break; case Definition::TypePage: result="page"; break; case Definition::TypeDir: result="dir"; break; case Definition::TypeMember: break; } return result; } TemplateVariant sourceDef() const { Cachable &cache = getCache(); if (cache.sourceDef->count()==2) { return cache.sourceDef.get(); } else { return FALSE; } } void fillPath(const Definition *def,TemplateList *list) const { const Definition *outerScope = def->getOuterScope(); Definition::DefType type = def->definitionType(); if (outerScope && outerScope!=Doxygen::globalScope) { fillPath(outerScope,list); } else if (type==Definition::TypeFile && (toFileDef(def))->getDirDef()) { fillPath((toFileDef(def))->getDirDef(),list); } list->append(NavPathElemContext::alloc(def)); } TemplateVariant navigationPath() const { Cachable &cache = getCache(); if (!cache.navPath) { TemplateList *list = TemplateList::alloc(); if (m_def->getOuterScope() && m_def->getOuterScope()!=Doxygen::globalScope) { fillPath(m_def->getOuterScope(),list); } else if (m_def->definitionType()==Definition::TypeFile && (toFileDef(m_def))->getDirDef()) { fillPath((toFileDef(m_def))->getDirDef(),list); } cache.navPath.reset(list); } return cache.navPath.get(); } TemplateVariant isReference() const { return m_def->isReference(); } TemplateVariant externalReference() const { return m_def->externalReference(relPathAsString()); } protected: struct Cachable : public Definition::Cookie { Cachable(const Definition *def) : detailsOutputFormat(ContextOutputFormat_Unspecified), briefOutputFormat(ContextOutputFormat_Unspecified), inbodyDocsOutputFormat(ContextOutputFormat_Unspecified) { sourceDef.reset(TemplateList::alloc()); lineLink.reset(TemplateStruct::alloc()); fileLink.reset(TemplateStruct::alloc()); if (def && !def->getSourceFileBase().isEmpty()) { lineLink->set("text",def->getStartBodyLine()); lineLink->set("isLinkable",TRUE); lineLink->set("fileName",def->getSourceFileBase()); lineLink->set("anchor",def->getSourceAnchor()); lineLink->set("isReference",FALSE); lineLink->set("externalReference",""); if (def->definitionType()==Definition::TypeFile) { fileLink->set("text",def->name()); } else if (def->getBodyDef()) { fileLink->set("text",def->getBodyDef()->name()); } else { fileLink->set("text",def->displayName(TRUE)); } fileLink->set("isLinkable",TRUE); fileLink->set("fileName",def->getSourceFileBase()); fileLink->set("anchor",QCString()); fileLink->set("isReference",FALSE); fileLink->set("externalReference",""); sourceDef->append(lineLink.get()); sourceDef->append(fileLink.get()); } } ScopedPtr details; ContextOutputFormat detailsOutputFormat; ScopedPtr brief; ContextOutputFormat briefOutputFormat; ScopedPtr inbodyDocs; ContextOutputFormat inbodyDocsOutputFormat; SharedPtr navPath; SharedPtr sourceDef; SharedPtr fileLink; SharedPtr lineLink; }; private: Cachable &getCache() const { Cachable *c = static_cast(m_def->cookie()); assert(c!=0); return *c; } const Definition *m_def; }; //%% } //------------------------------------------------------------------------ //%% struct IncludeInfo: include file information //%% { class IncludeInfoContext::Private { public: Private(const IncludeInfo *info,SrcLangExt lang) : m_info(info), m_lang(lang) { static bool init=FALSE; if (!init) { s_inst.addProperty("file",&Private::file); s_inst.addProperty("name",&Private::name); s_inst.addProperty("isImport",&Private::isImport); s_inst.addProperty("isLocal",&Private::isLocal); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant isLocal() const { bool isIDLorJava = m_lang==SrcLangExt_IDL || m_lang==SrcLangExt_Java; return m_info->local || isIDLorJava; } TemplateVariant isImport() const { return m_info->imported || m_lang==SrcLangExt_ObjC; } TemplateVariant file() const { if (!m_fileContext && m_info && m_info->fileDef) { m_fileContext.reset(FileContext::alloc(m_info->fileDef)); } if (m_fileContext) { return m_fileContext.get(); } else { return FALSE; } } TemplateVariant name() const { return m_info->includeName; } private: const IncludeInfo *m_info; mutable SharedPtr m_fileContext; SrcLangExt m_lang; static PropertyMapper s_inst; }; PropertyMapper IncludeInfoContext::Private::s_inst; IncludeInfoContext::IncludeInfoContext(const IncludeInfo *info,SrcLangExt lang) : RefCountedContext("IncludeContext") { p = new Private(info,lang); } IncludeInfoContext::~IncludeInfoContext() { delete p; } TemplateVariant IncludeInfoContext::get(const char *n) const { return p->get(n); } //%% } //------------------------------------------------------------------------ //%% list IncludeInfoList[Class] : list of nested classes class IncludeInfoListContext::Private : public GenericNodeListContext { public: Private(const IncludeInfoList &list,SrcLangExt lang) { for (const auto &ii : list) { append(IncludeInfoContext::alloc(&ii,lang)); } } }; IncludeInfoListContext::IncludeInfoListContext(const IncludeInfoList &list,SrcLangExt lang) : RefCountedContext("IncludeListContext") { p = new Private(list,lang); } IncludeInfoListContext::~IncludeInfoListContext() { delete p; } // TemplateListIntf uint IncludeInfoListContext::count() const { return p->count(); } TemplateVariant IncludeInfoListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *IncludeInfoListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct Class(Symbol): class information //%% { class ClassContext::Private : public DefinitionContext { public: Private(const ClassDef *cd) : DefinitionContext(cd), m_classDef(cd) { static bool init=FALSE; if (!init) { addBaseProperties(s_inst); s_inst.addProperty("title", &Private::title); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subHighlight); s_inst.addProperty("hasDetails", &Private::hasDetails); s_inst.addProperty("generatedFromFiles", &Private::generatedFromFiles); s_inst.addProperty("usedFiles", &Private::usedFiles); s_inst.addProperty("hasInheritanceDiagram", &Private::hasInheritanceDiagram); s_inst.addProperty("inheritanceDiagram", &Private::inheritanceDiagram); s_inst.addProperty("hasCollaborationDiagram", &Private::hasCollaborationDiagram); s_inst.addProperty("collaborationDiagram", &Private::collaborationDiagram); s_inst.addProperty("includeInfo", &Private::includeInfo); s_inst.addProperty("inherits", &Private::inherits); s_inst.addProperty("inheritedBy", &Private::inheritedBy); s_inst.addProperty("unoIDLServices", &Private::unoIDLServices); s_inst.addProperty("unoIDLInterfaces", &Private::unoIDLInterfaces); s_inst.addProperty("signals", &Private::signals); s_inst.addProperty("publicTypes", &Private::publicTypes); s_inst.addProperty("publicMethods", &Private::publicMethods); s_inst.addProperty("publicStaticMethods", &Private::publicStaticMethods); s_inst.addProperty("publicAttributes", &Private::publicAttributes); s_inst.addProperty("publicStaticAttributes", &Private::publicStaticAttributes); s_inst.addProperty("publicSlots", &Private::publicSlots); s_inst.addProperty("protectedTypes", &Private::protectedTypes); s_inst.addProperty("protectedMethods", &Private::protectedMethods); s_inst.addProperty("protectedStaticMethods", &Private::protectedStaticMethods); s_inst.addProperty("protectedAttributes", &Private::protectedAttributes); s_inst.addProperty("protectedStaticAttributes", &Private::protectedStaticAttributes); s_inst.addProperty("protectedSlots", &Private::protectedSlots); s_inst.addProperty("privateTypes", &Private::privateTypes); s_inst.addProperty("privateMethods", &Private::privateMethods); s_inst.addProperty("privateStaticMethods", &Private::privateStaticMethods); s_inst.addProperty("privateAttributes", &Private::privateAttributes); s_inst.addProperty("privateStaticAttributes", &Private::privateStaticAttributes); s_inst.addProperty("privateSlots", &Private::privateSlots); s_inst.addProperty("packageTypes", &Private::packageTypes); s_inst.addProperty("packageMethods", &Private::packageMethods); s_inst.addProperty("packageStaticMethods", &Private::packageStaticMethods); s_inst.addProperty("packageAttributes", &Private::packageAttributes); s_inst.addProperty("packageStaticAttributes", &Private::packageStaticAttributes); s_inst.addProperty("properties", &Private::properties); s_inst.addProperty("events", &Private::events); s_inst.addProperty("friends", &Private::friends); s_inst.addProperty("related", &Private::related); s_inst.addProperty("detailedTypedefs", &Private::detailedTypedefs); s_inst.addProperty("detailedEnums", &Private::detailedEnums); s_inst.addProperty("detailedServices", &Private::detailedServices); s_inst.addProperty("detailedInterfaces", &Private::detailedInterfaces); s_inst.addProperty("detailedConstructors", &Private::detailedConstructors); s_inst.addProperty("detailedMethods", &Private::detailedMethods); s_inst.addProperty("detailedRelated", &Private::detailedRelated); s_inst.addProperty("detailedVariables", &Private::detailedVariables); s_inst.addProperty("detailedProperties", &Private::detailedProperties); s_inst.addProperty("detailedEvents", &Private::detailedEvents); s_inst.addProperty("classes", &Private::classes); s_inst.addProperty("innerClasses", &Private::innerClasses); s_inst.addProperty("compoundType", &Private::compoundType); s_inst.addProperty("templateDecls", &Private::templateDecls); s_inst.addProperty("typeConstraints", &Private::typeConstraints); s_inst.addProperty("examples", &Private::examples); s_inst.addProperty("members", &Private::members); s_inst.addProperty("allMembersList", &Private::allMembersList); s_inst.addProperty("allMembersFileName", &Private::allMembersFileName); s_inst.addProperty("memberGroups", &Private::memberGroups); s_inst.addProperty("additionalInheritedMembers",&Private::additionalInheritedMembers); s_inst.addProperty("isSimple", &Private::isSimple); s_inst.addProperty("categoryOf", &Private::categoryOf); init=TRUE; } if (!cd->cookie()) { cd->setCookie(new ClassContext::Private::Cachable(cd)); } } virtual ~Private() {} TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant title() const { return TemplateVariant(m_classDef->title()); } TemplateVariant highlight() const { return TemplateVariant("classes"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } TemplateVariant hasDetails() const { return m_classDef->hasDetailedDescription(); } TemplateVariant generatedFromFiles() const { return m_classDef->generatedFromFiles(); } TemplateVariant usedFiles() const { Cachable &cache = getCache(); if (!cache.usedFiles) { cache.usedFiles.reset(UsedFilesContext::alloc(m_classDef)); } return cache.usedFiles.get(); } DotClassGraph *getClassGraph() const { Cachable &cache = getCache(); if (!cache.classGraph) { cache.classGraph.reset(new DotClassGraph(m_classDef,Inheritance)); } return cache.classGraph.get(); } int numInheritanceNodes() const { Cachable &cache = getCache(); if (cache.inheritanceNodes==-1) { cache.inheritanceNodes=m_classDef->countInheritanceNodes(); } return cache.inheritanceNodes>0; } TemplateVariant hasInheritanceDiagram() const { bool result=FALSE; static bool haveDot = Config_getBool(HAVE_DOT); static bool classDiagrams = Config_getBool(CLASS_DIAGRAMS); static bool classGraph = Config_getBool(CLASS_GRAPH); if (haveDot && (classDiagrams || classGraph)) { DotClassGraph *cg = getClassGraph(); result = !cg->isTrivial() && !cg->isTooBig(); } else if (classDiagrams) { result = numInheritanceNodes()>0; } return result; } TemplateVariant inheritanceDiagram() const { std::ostringstream t(std::ios_base::ate); static bool haveDot = Config_getBool(HAVE_DOT); static bool classDiagrams = Config_getBool(CLASS_DIAGRAMS); static bool classGraph = Config_getBool(CLASS_GRAPH); if (haveDot && (classDiagrams || classGraph)) { DotClassGraph *cg = getClassGraph(); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { cg->writeGraph(t,GOF_BITMAP,EOF_Html, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,TRUE,g_globals.dynSectionId ); } break; case ContextOutputFormat_Latex: { cg->writeGraph(t,GOF_EPS,EOF_LaTeX, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_classDef->getOutputFileBase()+".tex", relPathAsString(),TRUE,TRUE,g_globals.dynSectionId ); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; } else if (classDiagrams) { ClassDiagram d(m_classDef); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { std::ostringstream tt(std::ios_base::ate); QCString name = convertToHtml(m_classDef->displayName()); d.writeImage(tt,g_globals.outputDir, relPathAsString(), m_classDef->getOutputFileBase()); if (tt.tellp()>0) { t << "
\n"; t << " getOutputFileBase(); t << ".png\" usemap=\"#" << convertToId(name) << "_map\" alt=\"\"/>\n"; t << " \n"; t << tt.str(); t << " \n"; t << "
"; } else { t << "
\n"; t << " getOutputFileBase(); t << ".png\" alt=\"\"/>\n"; t << "
"; } } break; case ContextOutputFormat_Latex: { d.writeFigure(t,g_globals.outputDir,m_classDef->getOutputFileBase()); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; } QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } DotClassGraph *getCollaborationGraph() const { Cachable &cache = getCache(); if (!cache.collaborationGraph) { cache.collaborationGraph.reset(new DotClassGraph(m_classDef,Collaboration)); } return cache.collaborationGraph.get(); } TemplateVariant hasCollaborationDiagram() const { static bool haveDot = Config_getBool(HAVE_DOT); return haveDot && !getCollaborationGraph()->isTrivial(); } TemplateVariant collaborationDiagram() const { static bool haveDot = Config_getBool(HAVE_DOT); std::ostringstream t(std::ios_base::ate); if (haveDot) { DotClassGraph *cg = getCollaborationGraph(); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { cg->writeGraph(t,GOF_BITMAP,EOF_Html, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,TRUE,g_globals.dynSectionId ); } break; case ContextOutputFormat_Latex: { cg->writeGraph(t,GOF_EPS,EOF_LaTeX, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_classDef->getOutputFileBase()+".tex", relPathAsString(),TRUE,TRUE,g_globals.dynSectionId ); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; } QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } TemplateVariant includeInfo() const { Cachable &cache = getCache(); if (!cache.includeInfo && m_classDef->includeInfo()) { cache.includeInfo.reset(IncludeInfoContext::alloc(m_classDef->includeInfo(),m_classDef->getLanguage())); } if (cache.includeInfo) { return cache.includeInfo.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant inherits() const { Cachable &cache = getCache(); if (!cache.inheritsList) { cache.inheritsList.reset(InheritanceListContext::alloc(m_classDef->baseClasses(),TRUE)); } return cache.inheritsList.get(); } TemplateVariant inheritedBy() const { Cachable &cache = getCache(); if (!cache.inheritedByList) { cache.inheritedByList.reset(InheritanceListContext::alloc(m_classDef->subClasses(),FALSE)); } return cache.inheritedByList.get(); } TemplateVariant getMemberList(SharedPtr &list, MemberListType type,const char *title,bool=FALSE) const { if (!list) { const MemberList *ml = m_classDef->getMemberList(type); if (ml) { list.reset(MemberListInfoContext::alloc(m_classDef,relPathAsString(),ml,title,"")); } } if (list) { return list.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant unoIDLServices() const { return getMemberList(getCache().unoIDLServices,MemberListType_services,theTranslator->trServices()); } TemplateVariant unoIDLInterfaces() const { return getMemberList(getCache().unoIDLInterfaces,MemberListType_interfaces,theTranslator->trInterfaces()); } TemplateVariant signals() const { return getMemberList(getCache().signals,MemberListType_signals,theTranslator->trSignals()); } TemplateVariant publicTypes() const { return getMemberList(getCache().publicTypes,MemberListType_pubTypes,theTranslator->trPublicTypes()); } TemplateVariant publicMethods() const { return getMemberList(getCache().publicMethods,MemberListType_pubMethods, m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trInstanceMethods() : theTranslator->trPublicMembers()); } TemplateVariant publicStaticMethods() const { return getMemberList(getCache().publicStaticMethods,MemberListType_pubStaticMethods, m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trClassMethods() : theTranslator->trStaticPublicMembers()); } TemplateVariant publicAttributes() const { return getMemberList(getCache().publicAttributes,MemberListType_pubAttribs,theTranslator->trPublicAttribs()); } TemplateVariant publicStaticAttributes() const { return getMemberList(getCache().publicStaticAttributes,MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs()); } TemplateVariant publicSlots() const { return getMemberList(getCache().publicSlots,MemberListType_pubSlots,theTranslator->trPublicSlots()); } TemplateVariant protectedTypes() const { return getMemberList(getCache().protectedTypes,MemberListType_proTypes,theTranslator->trProtectedTypes()); } TemplateVariant protectedMethods() const { return getMemberList(getCache().protectedMethods,MemberListType_proMethods,theTranslator->trProtectedMembers()); } TemplateVariant protectedStaticMethods() const { return getMemberList(getCache().protectedStaticMethods,MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers()); } TemplateVariant protectedAttributes() const { return getMemberList(getCache().protectedAttributes,MemberListType_proAttribs,theTranslator->trProtectedAttribs()); } TemplateVariant protectedStaticAttributes() const { return getMemberList(getCache().protectedStaticAttributes,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs()); } TemplateVariant protectedSlots() const { return getMemberList(getCache().protectedSlots,MemberListType_proSlots,theTranslator->trProtectedSlots()); } TemplateVariant privateTypes() const { return getMemberList(getCache().privateTypes,MemberListType_priTypes,theTranslator->trPrivateTypes()); } TemplateVariant privateSlots() const { return getMemberList(getCache().privateSlots,MemberListType_priSlots,theTranslator->trPrivateSlots()); } TemplateVariant privateMethods() const { return getMemberList(getCache().privateMethods,MemberListType_priMethods,theTranslator->trPrivateMembers()); } TemplateVariant privateStaticMethods() const { return getMemberList(getCache().privateStaticMethods,MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers()); } TemplateVariant privateAttributes() const { return getMemberList(getCache().privateAttributes,MemberListType_priAttribs,theTranslator->trPrivateAttribs()); } TemplateVariant privateStaticAttributes() const { return getMemberList(getCache().privateStaticAttributes,MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs()); } TemplateVariant packageTypes() const { return getMemberList(getCache().packageTypes,MemberListType_pacTypes,theTranslator->trPackageTypes()); } TemplateVariant packageMethods() const { return getMemberList(getCache().packageMethods,MemberListType_pacMethods,theTranslator->trPackageMembers()); } TemplateVariant packageStaticMethods() const { return getMemberList(getCache().packageStaticMethods,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers()); } TemplateVariant packageAttributes() const { return getMemberList(getCache().packageAttributes,MemberListType_pacAttribs,theTranslator->trPackageAttribs()); } TemplateVariant packageStaticAttributes() const { return getMemberList(getCache().packageStaticAttributes,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs()); } TemplateVariant properties() const { return getMemberList(getCache().properties,MemberListType_properties,theTranslator->trProperties()); } TemplateVariant events() const { return getMemberList(getCache().events,MemberListType_events,theTranslator->trEvents()); } TemplateVariant friends() const { return getMemberList(getCache().friends,MemberListType_friends,theTranslator->trFriends()); } TemplateVariant related() const { return getMemberList(getCache().related,MemberListType_related,theTranslator->trRelatedFunctions()); } TemplateVariant detailedTypedefs() const { return getMemberList(getCache().detailedTypedefs,MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation(),TRUE); } TemplateVariant detailedEnums() const { return getMemberList(getCache().detailedEnums,MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation(),TRUE); } TemplateVariant detailedServices() const { return getMemberList(getCache().detailedServices,MemberListType_serviceMembers,theTranslator->trServices(),TRUE); } TemplateVariant detailedInterfaces() const { return getMemberList(getCache().detailedInterfaces,MemberListType_interfaceMembers,theTranslator->trInterfaces(),TRUE); } TemplateVariant detailedConstructors() const { return getMemberList(getCache().detailedConstructors,MemberListType_constructors,theTranslator->trConstructorDocumentation(),TRUE); } TemplateVariant detailedMethods() const { return getMemberList(getCache().detailedMethods,MemberListType_functionMembers,theTranslator->trMemberFunctionDocumentation(),TRUE); } TemplateVariant detailedRelated() const { return getMemberList(getCache().detailedRelated,MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation(),TRUE); } TemplateVariant detailedVariables() const { return getMemberList(getCache().detailedVariables,MemberListType_variableMembers,theTranslator->trMemberDataDocumentation(),TRUE); } TemplateVariant detailedProperties() const { return getMemberList(getCache().detailedProperties,MemberListType_propertyMembers,theTranslator->trPropertyDocumentation(),TRUE); } TemplateVariant detailedEvents() const { return getMemberList(getCache().detailedEvents,MemberListType_eventMembers,theTranslator->trEventDocumentation(),TRUE); } TemplateVariant classes() const { Cachable &cache = getCache(); if (!cache.classes) { TemplateList *classList = TemplateList::alloc(); for (const auto &cd : m_classDef->getClasses()) { if (cd->visibleInParentsDeclList()) { classList->append(ClassContext::alloc(cd)); } } cache.classes.reset(classList); } return cache.classes.get(); } TemplateVariant innerClasses() const { Cachable &cache = getCache(); if (!cache.innerClasses) { TemplateList *classList = TemplateList::alloc(); for (const auto &cd : m_classDef->getClasses()) { if (!cd->isAnonymous() && cd->isLinkableInProject() && cd->isEmbeddedInOuterScope() && cd->partOfGroups().empty() ) { classList->append(ClassContext::alloc(cd)); } } cache.innerClasses.reset(classList); } return cache.innerClasses.get(); } TemplateVariant compoundType() const { return m_classDef->compoundTypeString(); } void addTemplateDecls(const Definition *d,TemplateList *tl) const { if (d->definitionType()==Definition::TypeClass) { const Definition *parent = d->getOuterScope(); if (parent) { addTemplateDecls(parent,tl); } const ClassDef *cd=toClassDef(d); if (!cd->templateArguments().empty()) { ArgumentListContext *al = ArgumentListContext::alloc(cd->templateArguments(),cd,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 tl->append(al); } } } void addExamples(TemplateList *list) const { if (m_classDef->hasExamples()) { for (const auto &ex : m_classDef->getExamples()) { TemplateStruct *s = TemplateStruct::alloc(); s->set("text",ex.name); s->set("isLinkable",TRUE); s->set("anchor",ex.anchor); s->set("fileName",ex.file); s->set("isReference",FALSE); s->set("externalReference",""); list->append(s); } } } TemplateVariant templateDecls() const { Cachable &cache = getCache(); if (!cache.templateDecls) { TemplateList *tl = TemplateList::alloc(); addTemplateDecls(m_classDef,tl); cache.templateDecls.reset(tl); } return cache.templateDecls.get(); } TemplateVariant typeConstraints() const { if (!m_classDef->typeConstraints().empty()) { Cachable &cache = getCache(); if (!cache.typeConstraints && !m_classDef->typeConstraints().empty()) { cache.typeConstraints.reset(ArgumentListContext::alloc(m_classDef->typeConstraints(),m_classDef,relPathAsString())); } return cache.typeConstraints.get(); } return FALSE; } TemplateVariant examples() const { Cachable &cache = getCache(); if (!cache.examples) { TemplateList *exampleList = TemplateList::alloc(); addExamples(exampleList); cache.examples.reset(exampleList); } return cache.examples.get(); } void addMembers(const ClassDef *cd,MemberListType lt) const { const MemberList *ml = cd->getMemberList(lt); if (ml) { Cachable &cache = getCache(); for (const auto &md : *ml) { if (md->isBriefSectionVisible()) { cache.allMembers.push_back(md); } } } } TemplateVariant members() const { Cachable &cache = getCache(); if (!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); cache.members.reset(MemberListContext::alloc(&cache.allMembers)); } return cache.members.get(); } TemplateVariant allMembersList() const { Cachable &cache = getCache(); if (!cache.allMembersList) { AllMembersListContext *ml = AllMembersListContext::alloc(m_classDef->memberNameInfoLinkedMap()); cache.allMembersList.reset(ml); } return cache.allMembersList.get(); } TemplateVariant allMembersFileName() const { return m_classDef->getMemberListFileName(); } TemplateVariant memberGroups() const { Cachable &cache = getCache(); if (!cache.memberGroups) { if (!m_classDef->getMemberGroups().empty()) { cache.memberGroups.reset(MemberGroupListContext::alloc(m_classDef,relPathAsString(),m_classDef->getMemberGroups(),m_classDef->subGrouping())); } else { cache.memberGroups.reset(MemberGroupListContext::alloc()); } } return cache.memberGroups.get(); } TemplateVariant additionalInheritedMembers() const { Cachable &cache = getCache(); if (!cache.additionalInheritedMembers) { InheritedMemberInfoListContext *ctx = InheritedMemberInfoListContext::alloc(); 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()); cache.additionalInheritedMembers.reset(ctx); } return cache.additionalInheritedMembers.get(); } TemplateVariant isSimple() const { return m_classDef->isSimple(); } TemplateVariant categoryOf() const { Cachable &cache = getCache(); if (!cache.categoryOf && m_classDef->categoryOf()) { cache.categoryOf.reset(ClassContext::alloc(m_classDef->categoryOf())); } if (cache.categoryOf) { return cache.categoryOf.get(); } else { return TemplateVariant(FALSE); } } private: const ClassDef *m_classDef; struct Cachable : public DefinitionContext::Cachable { Cachable(const ClassDef *cd) : DefinitionContext::Cachable(cd), inheritanceNodes(-1) { } SharedPtr includeInfo; SharedPtr inheritsList; SharedPtr inheritedByList; ScopedPtr classGraph; ScopedPtr collaborationGraph; SharedPtr classes; SharedPtr innerClasses; SharedPtr publicTypes; SharedPtr publicMethods; SharedPtr publicStaticMethods; SharedPtr publicAttributes; SharedPtr publicStaticAttributes; SharedPtr publicSlots; SharedPtr protectedTypes; SharedPtr protectedMethods; SharedPtr protectedStaticMethods; SharedPtr protectedAttributes; SharedPtr protectedStaticAttributes; SharedPtr protectedSlots; SharedPtr privateTypes; SharedPtr privateMethods; SharedPtr privateStaticMethods; SharedPtr privateAttributes; SharedPtr privateStaticAttributes; SharedPtr privateSlots; SharedPtr packageTypes; SharedPtr packageMethods; SharedPtr packageStaticMethods; SharedPtr packageAttributes; SharedPtr packageStaticAttributes; SharedPtr unoIDLServices; SharedPtr unoIDLInterfaces; SharedPtr signals; SharedPtr properties; SharedPtr events; SharedPtr friends; SharedPtr related; SharedPtr detailedTypedefs; SharedPtr detailedEnums; SharedPtr detailedServices; SharedPtr detailedInterfaces; SharedPtr detailedConstructors; SharedPtr detailedMethods; SharedPtr detailedRelated; SharedPtr detailedVariables; SharedPtr detailedProperties; SharedPtr detailedEvents; SharedPtr memberGroups; SharedPtr allMembersList; SharedPtr typeConstraints; SharedPtr examples; SharedPtr templateDecls; SharedPtr additionalInheritedMembers; SharedPtr members; SharedPtr usedFiles; SharedPtr exampleList; SharedPtr categoryOf; int inheritanceNodes; MemberList allMembers; }; Cachable &getCache() const { Cachable *c = static_cast(m_classDef->cookie()); assert(c!=0); return *c; } static PropertyMapper s_inst; }; //%% } PropertyMapper ClassContext::Private::s_inst; ClassContext::ClassContext(const ClassDef *cd) : RefCountedContext("ClassContext") { //printf("ClassContext::ClassContext(%s)\n",cd?cd->name().data():""); p = new Private(cd); } ClassContext::~ClassContext() { delete p; } TemplateVariant ClassContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Namespace(Symbol): namespace information //%% { class NamespaceContext::Private : public DefinitionContext { public: Private(const NamespaceDef *nd) : DefinitionContext(nd), m_namespaceDef(nd) { static bool init=FALSE; if (!init) { addBaseProperties(s_inst); s_inst.addProperty("title", &Private::title); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subHighlight); s_inst.addProperty("compoundType", &Private::compoundType); s_inst.addProperty("hasDetails", &Private::hasDetails); s_inst.addProperty("classes", &Private::classes); //s_inst.addProperty("interfaces", &Private::interfaces); s_inst.addProperty("namespaces", &Private::namespaces); s_inst.addProperty("constantgroups", &Private::constantgroups); s_inst.addProperty("typedefs", &Private::typedefs); s_inst.addProperty("sequences", &Private::sequences); s_inst.addProperty("dictionaries", &Private::dictionaries); s_inst.addProperty("enums", &Private::enums); s_inst.addProperty("functions", &Private::functions); s_inst.addProperty("variables", &Private::variables); s_inst.addProperty("memberGroups", &Private::memberGroups); s_inst.addProperty("detailedTypedefs", &Private::detailedTypedefs); s_inst.addProperty("detailedSequences", &Private::detailedSequences); s_inst.addProperty("detailedDictionaries", &Private::detailedDictionaries); s_inst.addProperty("detailedEnums", &Private::detailedEnums); s_inst.addProperty("detailedFunctions", &Private::detailedFunctions); s_inst.addProperty("detailedVariables", &Private::detailedVariables); s_inst.addProperty("inlineClasses", &Private::inlineClasses); init=TRUE; } if (!nd->cookie()) { nd->setCookie(new NamespaceContext::Private::Cachable(nd)); } } virtual ~Private() {} TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant title() const { return TemplateVariant(m_namespaceDef->title()); } TemplateVariant highlight() const { return TemplateVariant("namespaces"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } TemplateVariant compoundType() const { return m_namespaceDef->compoundTypeString(); } TemplateVariant hasDetails() const { return m_namespaceDef->hasDetailedDescription(); } TemplateVariant classes() const { Cachable &cache = getCache(); if (!cache.classes) { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); TemplateList *classList = TemplateList::alloc(); for (const auto &cd : m_namespaceDef->getClasses()) { if (sliceOpt && (cd->compoundType()==ClassDef::Struct || cd->compoundType()==ClassDef::Interface || cd->compoundType()==ClassDef::Exception)) { continue; // These types appear in their own sections. } if (cd->visibleInParentsDeclList()) { classList->append(ClassContext::alloc(cd)); } } cache.classes.reset(classList); } return cache.classes.get(); } TemplateVariant namespaces() const { Cachable &cache = getCache(); if (!cache.namespaces) { TemplateList *namespaceList = TemplateList::alloc(); for (const auto &nd : m_namespaceDef->getNamespaces()) { if (nd->isLinkable() && !nd->isConstantGroup()) { namespaceList->append(NamespaceContext::alloc(nd)); } } cache.namespaces.reset(namespaceList); } return cache.namespaces.get(); } TemplateVariant constantgroups() const { Cachable &cache = getCache(); if (!cache.constantgroups) { TemplateList *namespaceList = TemplateList::alloc(); for (const auto &nd : m_namespaceDef->getNamespaces()) { if (nd->isLinkable() && nd->isConstantGroup()) { namespaceList->append(NamespaceContext::alloc(nd)); } } cache.constantgroups.reset(namespaceList); } return cache.constantgroups.get(); } TemplateVariant getMemberList(SharedPtr &list, MemberListType type,const char *title,bool=FALSE) const { if (!list) { const MemberList *ml = m_namespaceDef->getMemberList(type); if (ml) { list.reset(MemberListInfoContext::alloc(m_namespaceDef,relPathAsString(),ml,title,"")); } } if (list) { return list.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant typedefs() const { return getMemberList(getCache().typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs()); } TemplateVariant sequences() const { return getMemberList(getCache().sequences,MemberListType_decSequenceMembers,theTranslator->trSequences()); } TemplateVariant dictionaries() const { return getMemberList(getCache().dictionaries,MemberListType_decDictionaryMembers,theTranslator->trDictionaries()); } TemplateVariant enums() const { return getMemberList(getCache().enums,MemberListType_decEnumMembers,theTranslator->trEnumerations()); } TemplateVariant functions() const { QCString title = theTranslator->trFunctions(); SrcLangExt lang = m_namespaceDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms(); else if (lang==SrcLangExt_VHDL) title=theTranslator->trFunctionAndProc(); return getMemberList(getCache().functions,MemberListType_decFuncMembers,title); } TemplateVariant variables() const { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return getMemberList(getCache().variables,MemberListType_decVarMembers, sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } TemplateVariant memberGroups() const { Cachable &cache = getCache(); if (!cache.memberGroups) { if (!m_namespaceDef->getMemberGroups().empty()) { cache.memberGroups.reset(MemberGroupListContext::alloc(m_namespaceDef,relPathAsString(),m_namespaceDef->getMemberGroups(),m_namespaceDef->subGrouping())); } else { cache.memberGroups.reset(MemberGroupListContext::alloc()); } } return cache.memberGroups.get(); } TemplateVariant detailedTypedefs() const { return getMemberList(getCache().detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()); } TemplateVariant detailedSequences() const { return getMemberList(getCache().detailedSequences,MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation()); } TemplateVariant detailedDictionaries() const { return getMemberList(getCache().detailedDictionaries,MemberListType_docDictionaryMembers,theTranslator->trDictionaryDocumentation()); } TemplateVariant detailedEnums() const { return getMemberList(getCache().detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()); } TemplateVariant detailedFunctions() const { QCString title = theTranslator->trFunctionDocumentation(); SrcLangExt lang = m_namespaceDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation(); return getMemberList(getCache().detailedFunctions,MemberListType_docFuncMembers,title); } TemplateVariant detailedVariables() const { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return getMemberList(getCache().detailedVariables,MemberListType_docVarMembers, sliceOpt ? theTranslator->trConstantDocumentation() : theTranslator->trVariableDocumentation()); } TemplateVariant inlineClasses() const { Cachable &cache = getCache(); if (!cache.inlineClasses) { TemplateList *classList = TemplateList::alloc(); for (const auto &cd : m_namespaceDef->getClasses()) { if (!cd->isAnonymous() && cd->isLinkableInProject() && cd->isEmbeddedInOuterScope() && cd->partOfGroups().empty()) { classList->append(ClassContext::alloc(cd)); } } cache.inlineClasses.reset(classList); } return cache.inlineClasses.get(); } private: const NamespaceDef *m_namespaceDef; struct Cachable : public DefinitionContext::Cachable { Cachable(const NamespaceDef *nd) : DefinitionContext::Cachable(nd) {} SharedPtr classes; SharedPtr interfaces; SharedPtr namespaces; SharedPtr constantgroups; SharedPtr typedefs; SharedPtr sequences; SharedPtr dictionaries; SharedPtr enums; SharedPtr functions; SharedPtr variables; SharedPtr memberGroups; SharedPtr detailedTypedefs; SharedPtr detailedSequences; SharedPtr detailedDictionaries; SharedPtr detailedEnums; SharedPtr detailedFunctions; SharedPtr detailedVariables; SharedPtr inlineClasses; }; Cachable &getCache() const { Cachable *c = static_cast(m_namespaceDef->cookie()); assert(c!=0); return *c; } static PropertyMapper s_inst; }; //%% } PropertyMapper NamespaceContext::Private::s_inst; NamespaceContext::NamespaceContext(const NamespaceDef *nd) : RefCountedContext("NamespaceContext") { p = new Private(nd); } NamespaceContext::~NamespaceContext() { delete p; } TemplateVariant NamespaceContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct File(Symbol): file information //%% { class FileContext::Private : public DefinitionContext { public: Private(const FileDef *fd) : DefinitionContext(fd) , m_fileDef(fd) { if (fd==0) abort(); static bool init=FALSE; if (!init) { addBaseProperties(s_inst); s_inst.addProperty("title", &Private::title); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subHighlight); s_inst.addProperty("versionInfo", &Private::versionInfo); s_inst.addProperty("includeList", &Private::includeList); s_inst.addProperty("hasIncludeGraph", &Private::hasIncludeGraph); s_inst.addProperty("hasIncludedByGraph", &Private::hasIncludedByGraph); s_inst.addProperty("includeGraph", &Private::includeGraph); s_inst.addProperty("includedByGraph", &Private::includedByGraph); s_inst.addProperty("hasDetails", &Private::hasDetails); s_inst.addProperty("hasSourceFile", &Private::hasSourceFile); s_inst.addProperty("sources", &Private::sources); s_inst.addProperty("version", &Private::version); s_inst.addProperty("classes", &Private::classes); s_inst.addProperty("namespaces", &Private::namespaces); s_inst.addProperty("constantgroups", &Private::constantgroups); s_inst.addProperty("macros", &Private::macros); s_inst.addProperty("typedefs", &Private::typedefs); s_inst.addProperty("sequences", &Private::sequences); s_inst.addProperty("dictionaries", &Private::dictionaries); s_inst.addProperty("enums", &Private::enums); s_inst.addProperty("functions", &Private::functions); s_inst.addProperty("variables", &Private::variables); s_inst.addProperty("memberGroups", &Private::memberGroups); s_inst.addProperty("detailedMacros", &Private::detailedMacros); s_inst.addProperty("detailedTypedefs", &Private::detailedTypedefs); s_inst.addProperty("detailedSequences", &Private::detailedSequences); s_inst.addProperty("detailedDictionaries", &Private::detailedDictionaries); s_inst.addProperty("detailedEnums", &Private::detailedEnums); s_inst.addProperty("detailedFunctions", &Private::detailedFunctions); s_inst.addProperty("detailedVariables", &Private::detailedVariables); s_inst.addProperty("inlineClasses", &Private::inlineClasses); s_inst.addProperty("compoundType", &Private::compoundType); init=TRUE; } if (!fd->cookie()) { fd->setCookie(new FileContext::Private::Cachable(fd)); } } virtual ~Private() {} TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant title() const { return m_fileDef->title(); } TemplateVariant highlight() const { return TemplateVariant("files"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } TemplateVariant versionInfo() const { return m_fileDef->getVersion(); } TemplateVariant includeList() const { Cachable &cache = getCache(); if (!cache.includeInfoList && !m_fileDef->includeFileList().empty()) { cache.includeInfoList.reset(IncludeInfoListContext::alloc( m_fileDef->includeFileList(),m_fileDef->getLanguage())); } if (cache.includeInfoList) { return cache.includeInfoList.get(); } else { return TemplateVariant(FALSE); } } DotInclDepGraph *getIncludeGraph() const { Cachable &cache = getCache(); if (!cache.includeGraph) { cache.includeGraph.reset(new DotInclDepGraph(m_fileDef,FALSE)); } return cache.includeGraph.get(); } TemplateVariant hasIncludeGraph() const { static bool haveDot = Config_getBool(HAVE_DOT); DotInclDepGraph *incGraph = getIncludeGraph(); return (haveDot && !incGraph->isTooBig() && !incGraph->isTrivial()); } TemplateVariant includeGraph() const { static bool haveDot = Config_getBool(HAVE_DOT); std::ostringstream t(std::ios_base::ate); if (haveDot) { DotInclDepGraph *cg = getIncludeGraph(); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { cg->writeGraph(t,GOF_BITMAP,EOF_Html, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,g_globals.dynSectionId ); } break; case ContextOutputFormat_Latex: { cg->writeGraph(t,GOF_EPS,EOF_LaTeX, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_fileDef->getOutputFileBase()+".tex", relPathAsString(),TRUE,g_globals.dynSectionId ); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; } QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } DotInclDepGraph *getIncludedByGraph() const { Cachable &cache = getCache(); if (!cache.includedByGraph) { cache.includedByGraph.reset(new DotInclDepGraph(m_fileDef,TRUE)); } return cache.includedByGraph.get(); } TemplateVariant hasIncludedByGraph() const { static bool haveDot = Config_getBool(HAVE_DOT); DotInclDepGraph *incGraph = getIncludedByGraph(); return (haveDot && !incGraph->isTooBig() && !incGraph->isTrivial()); } TemplateVariant includedByGraph() const { static bool haveDot = Config_getBool(HAVE_DOT); std::ostringstream t(std::ios_base::ate); if (haveDot) { DotInclDepGraph *cg = getIncludedByGraph(); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { cg->writeGraph(t,GOF_BITMAP,EOF_Html, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,g_globals.dynSectionId ); } break; case ContextOutputFormat_Latex: { cg->writeGraph(t,GOF_EPS,EOF_LaTeX, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_fileDef->getOutputFileBase()+".tex", relPathAsString(),TRUE,g_globals.dynSectionId ); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; } QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } TemplateVariant hasDetails() const { return m_fileDef->hasDetailedDescription(); } TemplateVariant hasSourceFile() const { return m_fileDef->generateSourceFile(); } TemplateVariant sources() const { Cachable &cache = getCache(); if (!cache.sources) { if (m_fileDef->generateSourceFile()) { cache.sources.reset(new TemplateVariant(parseCode(m_fileDef,relPathAsString()))); } else { cache.sources.reset(new TemplateVariant("")); } } return *cache.sources; } TemplateVariant version() const { return m_fileDef->fileVersion(); } TemplateVariant classes() const { Cachable &cache = getCache(); if (!cache.classes) { TemplateList *classList = TemplateList::alloc(); for (const auto &cd : m_fileDef->getClasses()) { if (cd->visibleInParentsDeclList()) { classList->append(ClassContext::alloc(cd)); } } cache.classes.reset(classList); } return cache.classes.get(); } TemplateVariant namespaces() const { Cachable &cache = getCache(); if (!cache.namespaces) { TemplateList *namespaceList = TemplateList::alloc(); for (const auto &nd : m_fileDef->getNamespaces()) { if (nd->isLinkable() && !nd->isConstantGroup()) { namespaceList->append(NamespaceContext::alloc(nd)); } } cache.namespaces.reset(namespaceList); } return cache.namespaces.get(); } TemplateVariant constantgroups() const { Cachable &cache = getCache(); if (!cache.constantgroups) { TemplateList *namespaceList = TemplateList::alloc(); for (const auto &nd : m_fileDef->getNamespaces()) { if (nd->isLinkable() && nd->isConstantGroup()) { namespaceList->append(NamespaceContext::alloc(nd)); } } cache.constantgroups.reset(namespaceList); } return cache.constantgroups.get(); } TemplateVariant getMemberList(SharedPtr &list, MemberListType type,const char *title,bool=FALSE) const { if (!list) { const MemberList *ml = m_fileDef->getMemberList(type); if (ml) { list.reset(MemberListInfoContext::alloc(m_fileDef,relPathAsString(),ml,title,"")); } } if (list) { return list.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant macros() const { return getMemberList(getCache().macros,MemberListType_decDefineMembers,theTranslator->trDefines()); } TemplateVariant typedefs() const { return getMemberList(getCache().typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs()); } TemplateVariant sequences() const { return getMemberList(getCache().sequences,MemberListType_decSequenceMembers,theTranslator->trSequences()); } TemplateVariant dictionaries() const { return getMemberList(getCache().dictionaries,MemberListType_decDictionaryMembers,theTranslator->trDictionaries()); } TemplateVariant enums() const { return getMemberList(getCache().enums,MemberListType_decEnumMembers,theTranslator->trEnumerations()); } TemplateVariant functions() const { QCString title = theTranslator->trFunctions(); SrcLangExt lang = m_fileDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms(); else if (lang==SrcLangExt_VHDL) title=theTranslator->trFunctionAndProc(); return getMemberList(getCache().functions,MemberListType_decFuncMembers,title); } TemplateVariant variables() const { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return getMemberList(getCache().variables,MemberListType_decVarMembers, sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } TemplateVariant memberGroups() const { Cachable &cache = getCache(); if (!cache.memberGroups) { if (!m_fileDef->getMemberGroups().empty()) { cache.memberGroups.reset(MemberGroupListContext::alloc(m_fileDef,relPathAsString(),m_fileDef->getMemberGroups(),m_fileDef->subGrouping())); } else { cache.memberGroups.reset(MemberGroupListContext::alloc()); } } return cache.memberGroups.get(); } TemplateVariant detailedMacros() const { return getMemberList(getCache().detailedMacros,MemberListType_docDefineMembers,theTranslator->trDefineDocumentation()); } TemplateVariant detailedTypedefs() const { return getMemberList(getCache().detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()); } TemplateVariant detailedSequences() const { return getMemberList(getCache().detailedSequences,MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation()); } TemplateVariant detailedDictionaries() const { return getMemberList(getCache().detailedDictionaries,MemberListType_docDictionaryMembers,theTranslator->trDictionaryDocumentation()); } TemplateVariant detailedEnums() const { return getMemberList(getCache().detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()); } TemplateVariant detailedFunctions() const { QCString title = theTranslator->trFunctionDocumentation(); SrcLangExt lang = m_fileDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation(); return getMemberList(getCache().detailedFunctions,MemberListType_docFuncMembers,title); } TemplateVariant detailedVariables() const { return getMemberList(getCache().detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation()); } TemplateVariant inlineClasses() const { Cachable &cache = getCache(); if (!cache.inlineClasses) { TemplateList *classList = TemplateList::alloc(); for (const auto &cd : m_fileDef->getClasses()) { if (!cd->isAnonymous() && cd->isLinkableInProject() && cd->isEmbeddedInOuterScope() && cd->partOfGroups().empty()) { classList->append(ClassContext::alloc(cd)); } } cache.inlineClasses.reset(classList); } return cache.inlineClasses.get(); } TemplateVariant compoundType() const { return theTranslator->trFile(FALSE,TRUE); } private: const FileDef *m_fileDef; struct Cachable : public DefinitionContext::Cachable { Cachable(const FileDef *fd) : DefinitionContext::Cachable(fd) {} SharedPtr includeInfoList; ScopedPtr includeGraph; ScopedPtr includedByGraph; ScopedPtr sources; SharedPtr classes; SharedPtr namespaces; SharedPtr constantgroups; SharedPtr macros; SharedPtr typedefs; SharedPtr sequences; SharedPtr dictionaries; SharedPtr enums; SharedPtr functions; SharedPtr variables; SharedPtr memberGroups; SharedPtr detailedMacros; SharedPtr detailedTypedefs; SharedPtr detailedSequences; SharedPtr detailedDictionaries; SharedPtr detailedEnums; SharedPtr detailedFunctions; SharedPtr detailedVariables; SharedPtr inlineClasses; }; Cachable &getCache() const { Cachable *c = static_cast(m_fileDef->cookie()); assert(c!=0); return *c; } static PropertyMapper s_inst; }; //%% } PropertyMapper FileContext::Private::s_inst; FileContext::FileContext(const FileDef *fd) : RefCountedContext("FileContext") { p = new Private(fd); } FileContext::~FileContext() { delete p; } TemplateVariant FileContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Dir(Symbol): directory information //%% { class DirContext::Private : public DefinitionContext { public: Private(const DirDef *dd) : DefinitionContext(dd) , m_dirDef(dd) { static bool init=FALSE; if (!init) { addBaseProperties(s_inst); s_inst.addProperty("title", &Private::title); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subHighlight); s_inst.addProperty("dirName", &Private::dirName); s_inst.addProperty("dirs", &Private::dirs); s_inst.addProperty("files", &Private::files); s_inst.addProperty("hasDetails", &Private::hasDetails); s_inst.addProperty("hasDirGraph", &Private::hasDirGraph); s_inst.addProperty("dirGraph", &Private::dirGraph); s_inst.addProperty("compoundType", &Private::compoundType); init=TRUE; } if (!dd->cookie()) { dd->setCookie(new DirContext::Private::Cachable(dd)); } } virtual ~Private() {} TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant title() const { return TemplateVariant(m_dirDef->shortTitle()); } TemplateVariant highlight() const { return TemplateVariant("files"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } TemplateVariant dirName() const { return TemplateVariant(m_dirDef->shortName()); } TemplateVariant dirs() const { Cachable &cache = getCache(); if (!cache.dirs) { cache.dirs.reset(TemplateList::alloc()); for(const auto dd : m_dirDef->subDirs()) { DirContext *dc = new DirContext(dd); cache.dirs->append(dc); } } return cache.dirs.get(); } TemplateVariant files() const { Cachable &cache = getCache(); if (!cache.files) { cache.files.reset(TemplateList::alloc()); for (const auto &fd : m_dirDef->getFiles()) { FileContext *fc = FileContext::alloc(fd); cache.files->append(fc); } } return cache.files.get(); } TemplateVariant hasDetails() const { return m_dirDef->hasDetailedDescription(); } TemplateVariant compoundType() const { return theTranslator->trDir(FALSE,TRUE); } TemplateVariant relPath() const { return ""; } DotDirDeps *getDirDepsGraph() const { Cachable &cache = getCache(); if (!cache.dirDepsGraph) { cache.dirDepsGraph.reset(new DotDirDeps(m_dirDef)); } return cache.dirDepsGraph.get(); } TemplateVariant hasDirGraph() const { bool result=FALSE; static bool haveDot = Config_getBool(HAVE_DOT); static bool dirGraph = Config_getBool(DIRECTORY_GRAPH); if (haveDot && dirGraph) { DotDirDeps *graph = getDirDepsGraph(); result = !graph->isTrivial(); } return result; } TemplateVariant dirGraph() const { std::ostringstream t(std::ios_base::ate); static bool haveDot = Config_getBool(HAVE_DOT); static bool dirGraph = Config_getBool(DIRECTORY_GRAPH); if (haveDot && dirGraph) { DotDirDeps *graph = getDirDepsGraph(); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { graph->writeGraph(t,GOF_BITMAP, EOF_Html, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_dirDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(), TRUE, g_globals.dynSectionId, FALSE); } break; case ContextOutputFormat_Latex: { graph->writeGraph(t,GOF_EPS, EOF_LaTeX, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_dirDef->getOutputFileBase()+".tex", relPathAsString(), TRUE, g_globals.dynSectionId, FALSE); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; } QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } private: const DirDef *m_dirDef; struct Cachable : public DefinitionContext::Cachable { Cachable(const DirDef *dd) : DefinitionContext::Cachable(dd) {} SharedPtr dirs; SharedPtr files; ScopedPtr dirDepsGraph; }; Cachable &getCache() const { Cachable *c = static_cast(m_dirDef->cookie()); assert(c!=0); return *c; } static PropertyMapper s_inst; }; //%% } PropertyMapper DirContext::Private::s_inst; DirContext::DirContext(const DirDef *fd) : RefCountedContext("DirContext") { p = new Private(fd); } DirContext::~DirContext() { delete p; } TemplateVariant DirContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Page(Symbol): page information //%% { class PageContext::Private : public DefinitionContext { public: Private(const PageDef *pd,bool isMainPage,bool isExample) : DefinitionContext(pd) , m_pageDef(pd), m_isMainPage(isMainPage), m_isExample(isExample) { static bool init=FALSE; if (!init) { addBaseProperties(s_inst); s_inst.addProperty("title", &Private::title); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight",&Private::subHighlight); s_inst.addProperty("example", &Private::example); init=TRUE; } if (!pd->cookie()) { pd->setCookie(new PageContext::Private::Cachable(pd)); } } virtual ~Private() {} TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant title() const { if (m_isMainPage) { if (mainPageHasTitle()) { return m_pageDef->title(); } else { return theTranslator->trMainPage(); } } else if (m_isExample) { return m_pageDef->name(); } else { return m_pageDef->title(); } } TemplateVariant relPath() const { if (m_isMainPage) { return ""; } else { return DefinitionContext::relPath(); } } TemplateVariant highlight() const { if (m_isMainPage) { return "main"; } else { return "pages"; } } TemplateVariant subHighlight() const { return ""; } TemplateVariant example() const { if (m_isExample) { Cachable &cache = getCache(); if (!cache.example || g_globals.outputFormat!=cache.exampleOutputFormat) { cache.example.reset(new TemplateVariant( parseDoc(m_pageDef,m_pageDef->docFile(),m_pageDef->docLine(), relPathAsString(),"\\include "+m_pageDef->name(),FALSE))); cache.exampleOutputFormat = g_globals.outputFormat; } return *cache.example; } else { return TemplateVariant(""); } } private: const PageDef *m_pageDef; struct Cachable : public DefinitionContext::Cachable { Cachable(const PageDef *pd) : DefinitionContext::Cachable(pd), exampleOutputFormat(ContextOutputFormat_Unspecified) { } ScopedPtr example; ContextOutputFormat exampleOutputFormat; }; Cachable &getCache() const { Cachable *c = static_cast(m_pageDef->cookie()); assert(c!=0); return *c; } bool m_isMainPage; bool m_isExample; static PropertyMapper s_inst; }; //%% } PropertyMapper PageContext::Private::s_inst; PageContext::PageContext(const PageDef *pd,bool isMainPage,bool isExample) : RefCountedContext("PageContext") { p = new Private(pd,isMainPage,isExample); } PageContext::~PageContext() { delete p; } TemplateVariant PageContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ class TextGeneratorHtml : public TextGeneratorIntf { public: TextGeneratorHtml(std::ostream &ts,const QCString &relPath) : m_ts(ts), m_relPath(relPath) {} void writeString(const char *s,bool keepSpaces) const { static const char *hex="0123456789ABCDEF"; if (s==0) return; if (keepSpaces) { const char *p=s; char c; while ((c=*p++)) { switch(c) { case '<': m_ts << "<"; break; case '>': m_ts << ">"; break; case '\'': m_ts << "'"; break; case '"': m_ts << """; break; case '&': m_ts << "&"; break; case ' ': m_ts << " "; break; default: { uchar uc = static_cast(c); if (uc<32 && !isspace(c)) // non-printable control characters { m_ts << "$" << hex[uc>>4] << hex[uc&0xF] << ";"; } else { m_ts << c; } } break; } } } else { m_ts << convertToHtml(s); } } void writeBreak(int indent) const { m_ts << "
"; for (int i=0;i"; m_ts << convertToHtml(name); m_ts << ""; } private: std::ostream &m_ts; QCString m_relPath; }; //------------------------------------------------------------------------ class TextGeneratorLatex : public TextGeneratorIntf { public: TextGeneratorLatex(std::ostream &ts) : m_ts(ts) {} void writeString(const char *s,bool keepSpaces) const { if (s==0) return; m_ts << convertToLaTeX(s,FALSE,keepSpaces); } void writeBreak(int indent) const { m_ts << "\\\\*\n"; for (int i=0;icreate(ts,relPath); if (tg) { linkifyText(*tg,def->getOuterScope(),def->getBodyDef(),def,text); delete tg; return TemplateVariant(ts.str().c_str(),true); } else { return text; } } //%% struct Member(Symbol): member information //%% { class MemberContext::Private : public DefinitionContext { public: Private(const MemberDef *md) : DefinitionContext(md) , m_memberDef(md) { static bool init=FALSE; if (!init) { addBaseProperties(s_inst); s_inst.addProperty("isSignal", &Private::isSignal); s_inst.addProperty("isSlot", &Private::isSlot); s_inst.addProperty("isVariable", &Private::isVariable); s_inst.addProperty("isEnumeration", &Private::isEnumeration); s_inst.addProperty("isEnumValue", &Private::isEnumValue); s_inst.addProperty("isTypedef", &Private::isTypedef); s_inst.addProperty("isFunction", &Private::isFunction); s_inst.addProperty("isFunctionPtr", &Private::isFunctionPtr); s_inst.addProperty("isDefine", &Private::isDefine); s_inst.addProperty("isFriend", &Private::isFriend); s_inst.addProperty("isProperty", &Private::isProperty); s_inst.addProperty("isEvent", &Private::isEvent); s_inst.addProperty("isRelated", &Private::isRelated); s_inst.addProperty("isForeign", &Private::isForeign); s_inst.addProperty("isStatic", &Private::isStatic); s_inst.addProperty("isInline", &Private::isInline); s_inst.addProperty("isExplicit", &Private::isExplicit); s_inst.addProperty("isMutable", &Private::isMutable); s_inst.addProperty("isGettable", &Private::isGettable); s_inst.addProperty("isPrivateGettable", &Private::isPrivateGettable); s_inst.addProperty("isProtectedGettable", &Private::isProtectedGettable); s_inst.addProperty("isSettable", &Private::isSettable); s_inst.addProperty("isPrivateSettable", &Private::isPrivateSettable); s_inst.addProperty("isProtectedSettable", &Private::isProtectedSettable); s_inst.addProperty("isReadable", &Private::isReadable); s_inst.addProperty("isWritable", &Private::isWritable); s_inst.addProperty("isAddable", &Private::isAddable); s_inst.addProperty("isRemovable", &Private::isRemovable); s_inst.addProperty("isRaisable", &Private::isRaisable); s_inst.addProperty("isFinal", &Private::isFinal); s_inst.addProperty("isAbstract", &Private::isAbstract); s_inst.addProperty("isOverride", &Private::isOverride); s_inst.addProperty("isInitonly", &Private::isInitonly); s_inst.addProperty("isOptional", &Private::isOptional); s_inst.addProperty("isRequired", &Private::isRequired); s_inst.addProperty("isNonAtomic", &Private::isNonAtomic); s_inst.addProperty("isCopy", &Private::isCopy); s_inst.addProperty("isAssign", &Private::isAssign); s_inst.addProperty("isRetain", &Private::isRetain); s_inst.addProperty("isWeak", &Private::isWeak); s_inst.addProperty("isStrong", &Private::isStrong); s_inst.addProperty("isUnretained", &Private::isUnretained); s_inst.addProperty("isNew", &Private::isNew); s_inst.addProperty("isSealed", &Private::isSealed); s_inst.addProperty("isImplementation", &Private::isImplementation); s_inst.addProperty("isExternal", &Private::isExternal); s_inst.addProperty("isTypeAlias", &Private::isTypeAlias); s_inst.addProperty("isDefault", &Private::isDefault); s_inst.addProperty("isDelete", &Private::isDelete); s_inst.addProperty("isNoExcept", &Private::isNoExcept); s_inst.addProperty("isAttribute", &Private::isAttribute); s_inst.addProperty("isUNOProperty", &Private::isUNOProperty); s_inst.addProperty("isReadonly", &Private::isReadonly); s_inst.addProperty("isBound", &Private::isBound); s_inst.addProperty("isConstrained", &Private::isConstrained); s_inst.addProperty("isTransient", &Private::isTransient); s_inst.addProperty("isMaybeVoid", &Private::isMaybeVoid); s_inst.addProperty("isMaybeDefault", &Private::isMaybeDefault); s_inst.addProperty("isMaybeAmbiguous", &Private::isMaybeAmbiguous); s_inst.addProperty("isPublished", &Private::isPublished); s_inst.addProperty("isTemplateSpecialization",&Private::isTemplateSpecialization); s_inst.addProperty("isObjCMethod", &Private::isObjCMethod); s_inst.addProperty("isObjCProperty", &Private::isObjCProperty); s_inst.addProperty("isAnonymous", &Private::isAnonymous); s_inst.addProperty("hasParameters", &Private::hasParameters); s_inst.addProperty("declType", &Private::declType); s_inst.addProperty("declArgs", &Private::declArgs); s_inst.addProperty("anonymousType", &Private::anonymousType); s_inst.addProperty("anonymousMember", &Private::anonymousMember); s_inst.addProperty("hasDetails", &Private::hasDetails); s_inst.addProperty("exception", &Private::exception); s_inst.addProperty("bitfields", &Private::bitfields); s_inst.addProperty("initializer", &Private::initializer); s_inst.addProperty("initializerAsCode", &Private::initializerAsCode); s_inst.addProperty("hasOneLineInitializer", &Private::hasOneLineInitializer); s_inst.addProperty("hasMultiLineInitializer", &Private::hasMultiLineInitializer); s_inst.addProperty("templateArgs", &Private::templateArgs); s_inst.addProperty("templateAlias", &Private::templateAlias); s_inst.addProperty("propertyAttrs", &Private::propertyAttrs); s_inst.addProperty("eventAttrs", &Private::eventAttrs); s_inst.addProperty("category", &Private::category); s_inst.addProperty("categoryRelation", &Private::categoryRelation); s_inst.addProperty("class", &Private::getClass); s_inst.addProperty("file", &Private::getFile); s_inst.addProperty("namespace", &Private::getNamespace); s_inst.addProperty("definition", &Private::definition); s_inst.addProperty("parameters", &Private::parameters); s_inst.addProperty("hasConstQualifier", &Private::hasConstQualifier); s_inst.addProperty("hasVolatileQualifier",&Private::hasVolatileQualifier); s_inst.addProperty("hasRefQualifierLValue", &Private::hasRefQualifierLValue); s_inst.addProperty("hasRefQualifierRValue", &Private::hasRefQualifierRValue); s_inst.addProperty("trailingReturnType", &Private::trailingReturnType); s_inst.addProperty("extraTypeChars", &Private::extraTypeChars); s_inst.addProperty("templateDecls", &Private::templateDecls); s_inst.addProperty("labels", &Private::labels); s_inst.addProperty("enumBaseType", &Private::enumBaseType); s_inst.addProperty("enumValues", &Private::enumValues); s_inst.addProperty("paramDocs", &Private::paramDocs); s_inst.addProperty("reimplements", &Private::reimplements); s_inst.addProperty("implements", &Private::implements); s_inst.addProperty("reimplementedBy", &Private::reimplementedBy); s_inst.addProperty("implementedBy", &Private::implementedBy); s_inst.addProperty("examples", &Private::examples); s_inst.addProperty("typeConstraints", &Private::typeConstraints); s_inst.addProperty("functionQualifier", &Private::functionQualifier); s_inst.addProperty("sourceRefs", &Private::sourceRefs); s_inst.addProperty("sourceRefBys", &Private::sourceRefBys); s_inst.addProperty("hasSources", &Private::hasSources); s_inst.addProperty("sourceCode", &Private::sourceCode); s_inst.addProperty("hasCallGraph", &Private::hasCallGraph); s_inst.addProperty("callGraph", &Private::callGraph); s_inst.addProperty("hasCallerGraph", &Private::hasCallerGraph); s_inst.addProperty("callerGraph", &Private::callerGraph); s_inst.addProperty("hasReferencedByRelation", &Private::hasReferencedByRelation); s_inst.addProperty("referencedByRelation", &Private::referencedByRelation); s_inst.addProperty("hasReferencesRelation", &Private::hasReferencesRelation); s_inst.addProperty("referencesRelation", &Private::referencesRelation); s_inst.addProperty("fieldType", &Private::fieldType); s_inst.addProperty("type", &Private::type); s_inst.addProperty("detailsVisibleFor", &Private::detailsVisibleFor); s_inst.addProperty("nameWithContextFor", &Private::nameWithContextFor); init=TRUE; } if (!md->cookie()) { md->setCookie(new MemberContext::Private::Cachable(md)); } Cachable &cache = getCache(); cache.propertyAttrs.reset(TemplateList::alloc()); if (md->isProperty()) { if (md->isGettable()) cache.propertyAttrs->append("get"); if (md->isPrivateGettable()) cache.propertyAttrs->append("private get"); if (md->isProtectedGettable()) cache.propertyAttrs->append("protected get"); if (md->isSettable()) cache.propertyAttrs->append("set"); if (md->isPrivateSettable()) cache.propertyAttrs->append("private set"); if (md->isProtectedSettable()) cache.propertyAttrs->append("protected set"); } cache.eventAttrs.reset(TemplateList::alloc()); if (md->isEvent()) { if (md->isAddable()) cache.eventAttrs->append("add"); if (md->isRemovable()) cache.eventAttrs->append("remove"); if (md->isRaisable()) cache.eventAttrs->append("raise"); } } virtual ~Private() {} TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant fieldType() const { return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->fieldType()); } TemplateVariant declType() const { Cachable &cache = getCache(); if (!cache.declTypeParsed) { cache.declType=createLinkedText(m_memberDef,relPathAsString(),m_memberDef->getDeclType()); cache.declTypeParsed = TRUE; return cache.declType; } else { return cache.declType; } } TemplateVariant declArgs() const { Cachable &cache = getCache(); if (!cache.declArgsParsed) { cache.declArgs=createLinkedText(m_memberDef,relPathAsString(),m_memberDef->argsString()); cache.declArgsParsed = TRUE; return cache.declArgs; } else { return cache.declArgs; } } TemplateVariant exception() const { return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->excpString()); } TemplateVariant bitfields() const { return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->bitfieldString()); } TemplateVariant isStatic() const { return m_memberDef->isStatic(); } TemplateVariant isObjCMethod() const { return m_memberDef->isObjCMethod(); } TemplateVariant isObjCProperty() const { return m_memberDef->isObjCProperty(); } TemplateVariant isImplementation() const { return m_memberDef->isImplementation(); } TemplateVariant isSignal() const { return m_memberDef->isSignal(); } TemplateVariant isSlot() const { return m_memberDef->isSlot(); } TemplateVariant isTypedef() const { return m_memberDef->isTypedef(); } TemplateVariant isFunction() const { return m_memberDef->isFunction(); } TemplateVariant isFunctionPtr() const { return m_memberDef->isFunctionPtr(); } TemplateVariant isFriend() const { return m_memberDef->isFriend(); } TemplateVariant isForeign() const { return m_memberDef->isForeign(); } TemplateVariant isEvent() const { return m_memberDef->isEvent(); } TemplateVariant isInline() const { return m_memberDef->isInline(); } TemplateVariant isExplicit() const { return m_memberDef->isExplicit(); } TemplateVariant isMutable() const { return m_memberDef->isMutable(); } TemplateVariant isGettable() const { return m_memberDef->isGettable(); } TemplateVariant isPrivateGettable() const { return m_memberDef->isPrivateGettable(); } TemplateVariant isProtectedGettable() const { return m_memberDef->isProtectedGettable(); } TemplateVariant isSettable() const { return m_memberDef->isSettable(); } TemplateVariant isPrivateSettable() const { return m_memberDef->isPrivateSettable(); } TemplateVariant isProtectedSettable() const { return m_memberDef->isProtectedSettable(); } TemplateVariant isReadable() const { return m_memberDef->isReadable(); } TemplateVariant isWritable() const { return m_memberDef->isWritable(); } TemplateVariant isAddable() const { return m_memberDef->isAddable(); } TemplateVariant isRemovable() const { return m_memberDef->isRemovable(); } TemplateVariant isRaisable() const { return m_memberDef->isRaisable(); } TemplateVariant isFinal() const { return m_memberDef->isFinal(); } TemplateVariant isAbstract() const { return m_memberDef->isAbstract(); } TemplateVariant isOverride() const { return m_memberDef->isOverride(); } TemplateVariant isInitonly() const { return m_memberDef->isInitonly(); } TemplateVariant isOptional() const { return m_memberDef->isOptional(); } TemplateVariant isRequired() const { return m_memberDef->isRequired(); } TemplateVariant isNonAtomic() const { return m_memberDef->isNonAtomic(); } TemplateVariant isCopy() const { return m_memberDef->isCopy(); } TemplateVariant isAssign() const { return m_memberDef->isAssign(); } TemplateVariant isRetain() const { return m_memberDef->isRetain(); } TemplateVariant isWeak() const { return m_memberDef->isWeak(); } TemplateVariant isStrong() const { return m_memberDef->isStrong(); } TemplateVariant isUnretained() const { return m_memberDef->isUnretained(); } TemplateVariant isNew() const { return m_memberDef->isNew(); } TemplateVariant isSealed() const { return m_memberDef->isSealed(); } TemplateVariant isExternal() const { return m_memberDef->isExternal(); } TemplateVariant isTypeAlias() const { return m_memberDef->isTypeAlias(); } TemplateVariant isDefault() const { return m_memberDef->isDefault(); } TemplateVariant isDelete() const { return m_memberDef->isDelete(); } TemplateVariant isNoExcept() const { return m_memberDef->isNoExcept(); } TemplateVariant isAttribute() const { return m_memberDef->isAttribute(); } TemplateVariant isUNOProperty() const { return m_memberDef->isUNOProperty(); } TemplateVariant isReadonly() const { return m_memberDef->isReadonly(); } TemplateVariant isBound() const { return m_memberDef->isBound(); } TemplateVariant isConstrained() const { return m_memberDef->isConstrained(); } TemplateVariant isTransient() const { return m_memberDef->isTransient(); } TemplateVariant isMaybeVoid() const { return m_memberDef->isMaybeVoid(); } TemplateVariant isMaybeDefault() const { return m_memberDef->isMaybeDefault(); } TemplateVariant isMaybeAmbiguous() const { return m_memberDef->isMaybeAmbiguous(); } TemplateVariant isPublished() const { return m_memberDef->isPublished(); } TemplateVariant isTemplateSpecialization() const { return m_memberDef->isTemplateSpecialization(); } TemplateVariant isProperty() const { return m_memberDef->isProperty(); } TemplateVariant isEnumValue() const { return m_memberDef->isEnumValue(); } TemplateVariant isVariable() const { return m_memberDef->isVariable(); } TemplateVariant isEnumeration() const { return m_memberDef->isEnumerate(); } TemplateVariant hasDetails() const { return m_memberDef->isDetailedSectionLinkable(); } TemplateVariant initializer() const { return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->initializer()); } TemplateVariant initializerAsCode() const { Cachable &cache = getCache(); if (!cache.initializerParsed) { QCString scopeName; if (m_memberDef->getClassDef()) { scopeName = m_memberDef->getClassDef()->name(); } else if (m_memberDef->getNamespaceDef()) { scopeName = m_memberDef->getNamespaceDef()->name(); } cache.initializer = parseCode(const_cast(m_memberDef), scopeName,relPathAsString(), m_memberDef->initializer()); cache.initializerParsed = TRUE; } return cache.initializer; } TemplateVariant isDefine() const { return m_memberDef->isDefine(); } TemplateVariant isAnonymous() const { return m_memberDef->isAnonymous(); } TemplateVariant anonymousType() const { Cachable &cache = getCache(); if (!cache.anonymousType) { const ClassDef *cd = m_memberDef->getClassDefOfAnonymousType(); if (cd) { cache.anonymousType.reset(ClassContext::alloc(cd)); } } if (cache.anonymousType) { return cache.anonymousType.get(); } else { return FALSE; } } TemplateVariant anonymousMember() const { Cachable &cache = getCache(); if (!cache.anonymousMember) { MemberDef *md = m_memberDef->fromAnonymousMember(); if (md) { cache.anonymousMember.reset(MemberContext::alloc(md)); } } if (cache.anonymousMember) { return cache.anonymousMember.get(); } else { return FALSE; } } TemplateVariant isRelated() const { return m_memberDef->isRelated(); } TemplateVariant enumBaseType() const { return m_memberDef->enumBaseType(); } TemplateVariant hasOneLineInitializer() const { return m_memberDef->hasOneLineInitializer(); } TemplateVariant hasMultiLineInitializer() const { return m_memberDef->hasMultiLineInitializer(); } TemplateVariant enumValues() const { Cachable &cache = getCache(); if (!cache.enumValues) { cache.enumValues.reset(MemberListContext::alloc(&m_memberDef->enumFieldList())); } return cache.enumValues.get(); } TemplateVariant templateArgs() const { Cachable &cache = getCache(); if (!cache.templateArgs && !m_memberDef->templateArguments().empty()) { cache.templateArgs.reset(ArgumentListContext::alloc(m_memberDef->templateArguments(),m_memberDef,relPathAsString())); } if (cache.templateArgs) { return cache.templateArgs.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant templateAlias() const { if (m_memberDef->isTypeAlias()) { return createLinkedText(m_memberDef,relPathAsString(), QCString(" = ")+m_memberDef->typeString()); } return ""; } TemplateVariant propertyAttrs() const { return getCache().propertyAttrs.get(); } TemplateVariant eventAttrs() const { return getCache().eventAttrs.get(); } TemplateVariant getClass() const { Cachable &cache = getCache(); if (!cache.classDef && m_memberDef->getClassDef()) { cache.classDef.reset(ClassContext::alloc(m_memberDef->getClassDef())); } if (cache.classDef) { return cache.classDef.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant category() const { Cachable &cache = getCache(); if (!cache.category && m_memberDef->category()) { cache.category.reset(ClassContext::alloc(m_memberDef->category())); } if (cache.category) { return cache.category.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant categoryRelation() const { Cachable &cache = getCache(); if (!cache.categoryRelation && m_memberDef->categoryRelation()) { cache.categoryRelation.reset(MemberContext::alloc(m_memberDef->categoryRelation())); } if (cache.categoryRelation) { return cache.categoryRelation.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant getFile() const { Cachable &cache = getCache(); if (!cache.fileDef && m_memberDef->getFileDef()) { cache.fileDef.reset(FileContext::alloc(m_memberDef->getFileDef())); } if (cache.fileDef) { return cache.fileDef.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant getNamespace() const { Cachable &cache = getCache(); if (!cache.namespaceDef && m_memberDef->getNamespaceDef()) { cache.namespaceDef.reset(NamespaceContext::alloc(m_memberDef->getNamespaceDef())); } if (cache.namespaceDef) { return cache.namespaceDef.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant definition() const { return createLinkedText(m_memberDef,relPathAsString(), m_memberDef->displayDefinition()); } const ArgumentList &getDefArgList() const { return (m_memberDef->isDocsForDefinition()) ? m_memberDef->argumentList() : m_memberDef->declArgumentList(); } TemplateVariant parameters() const { Cachable &cache = getCache(); if (!cache.arguments) { const ArgumentList &defArgList = getDefArgList(); if (!m_memberDef->isProperty()) { cache.arguments.reset(ArgumentListContext::alloc(defArgList,m_memberDef,relPathAsString())); } else { cache.arguments.reset(ArgumentListContext::alloc()); } } return cache.arguments.get(); } TemplateVariant hasParameters() const { return !getDefArgList().empty(); } TemplateVariant hasConstQualifier() const { return getDefArgList().constSpecifier(); } TemplateVariant hasVolatileQualifier() const { return getDefArgList().volatileSpecifier(); } TemplateVariant hasRefQualifierLValue() const { return getDefArgList().refQualifier()==RefQualifierLValue; } TemplateVariant hasRefQualifierRValue() const { return getDefArgList().refQualifier()==RefQualifierRValue; } TemplateVariant trailingReturnType() const { const ArgumentList &al = getDefArgList(); if (!al.trailingReturnType().isEmpty()) { return createLinkedText(m_memberDef,relPathAsString(), al.trailingReturnType()); } else { return ""; } } TemplateVariant extraTypeChars() const { return m_memberDef->extraTypeChars(); } void addTemplateDecls(TemplateList *tl) const { const ClassDef *cd=m_memberDef->getClassDef(); if (!m_memberDef->definitionTemplateParameterLists().empty()) { for (const ArgumentList &tal : m_memberDef->definitionTemplateParameterLists()) { if (!tal.empty()) { ArgumentListContext *al = ArgumentListContext::alloc(tal,m_memberDef,relPathAsString()); tl->append(al); } } } else { if (cd && !m_memberDef->isRelated() && !m_memberDef->isTemplateSpecialization()) { for (const ArgumentList &tal : cd->getTemplateParameterLists()) { if (!tal.empty()) { ArgumentListContext *al = ArgumentListContext::alloc(tal,m_memberDef,relPathAsString()); tl->append(al); } } } if (!m_memberDef->templateArguments().empty()) // function template prefix { ArgumentListContext *al = ArgumentListContext::alloc( m_memberDef->templateArguments(),m_memberDef,relPathAsString()); tl->append(al); } } } TemplateVariant templateDecls() const { Cachable &cache = getCache(); if (!cache.templateDecls) { TemplateList *tl = TemplateList::alloc(); addTemplateDecls(tl); cache.templateDecls.reset(tl); } return cache.templateDecls.get(); } TemplateVariant labels() const { Cachable &cache = getCache(); if (!cache.labels) { StringVector sl = m_memberDef->getLabels(m_memberDef->getOuterScope()); TemplateList *tl = TemplateList::alloc(); for (const auto &s : sl) { tl->append(s.c_str()); } cache.labels.reset(tl); } return cache.labels.get(); } TemplateVariant paramDocs() const { Cachable &cache = getCache(); if (!cache.paramDocs) { if (m_memberDef->argumentList().hasDocumentation()) { QCString paramDocs; for (const Argument &a : m_memberDef->argumentList()) { if (a.hasDocumentation()) { QCString docs = a.docs; QCString direction = extractDirection(docs); paramDocs+="@param"+direction+" "+a.name+" "+docs; } } cache.paramDocs.reset(new TemplateVariant(parseDoc(m_memberDef, m_memberDef->docFile(),m_memberDef->docLine(), relPathAsString(),paramDocs,FALSE))); } else { cache.paramDocs.reset(new TemplateVariant("")); } } return *cache.paramDocs; } TemplateVariant implements() const { Cachable &cache = getCache(); if (!cache.implements) { const MemberDef *md = m_memberDef->reimplements(); cache.implements.reset(TemplateList::alloc()); if (md) { const ClassDef *cd = md->getClassDef(); // filter on pure virtual/interface methods if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface)) { MemberContext *mc = MemberContext::alloc(md); cache.implements->append(mc); } } } return cache.implements.get(); } TemplateVariant reimplements() const { Cachable &cache = getCache(); if (!cache.reimplements) { const MemberDef *md = m_memberDef->reimplements(); cache.reimplements.reset(TemplateList::alloc()); if (md) { const ClassDef *cd = md->getClassDef(); // filter on non-pure virtual & non interface methods if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface) { MemberContext *mc = MemberContext::alloc(md); cache.reimplements->append(mc); } } } return cache.reimplements.get(); } TemplateVariant implementedBy() const { Cachable &cache = getCache(); if (!cache.implementedBy) { cache.implementedBy.reset(TemplateList::alloc()); for (const auto &md : m_memberDef->reimplementedBy()) { const ClassDef *cd = md->getClassDef(); // filter on pure virtual/interface methods if (cd && md->virtualness()==Pure && cd->compoundType()==ClassDef::Interface) { MemberContext *mc = new MemberContext(md); cache.implementedBy->append(mc); } } } return cache.implementedBy.get(); } TemplateVariant reimplementedBy() const { Cachable &cache = getCache(); if (!cache.reimplementedBy) { cache.reimplementedBy.reset(TemplateList::alloc()); for (const auto &md : m_memberDef->reimplementedBy()) { const ClassDef *cd = md->getClassDef(); // filter on non-pure virtual & non interface methods if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface) { MemberContext *mc = new MemberContext(md); cache.reimplementedBy->append(mc); } } } return cache.reimplementedBy.get(); } void addExamples(TemplateList *list) const { if (m_memberDef->hasExamples()) { for (const auto &ex : m_memberDef->getExamples()) { TemplateStruct *s = TemplateStruct::alloc(); s->set("text",ex.name); s->set("isLinkable",TRUE); s->set("anchor",ex.anchor); s->set("fileName",ex.file); s->set("isReference",FALSE); s->set("externalReference",""); list->append(s); } } } TemplateVariant examples() const { Cachable &cache = getCache(); if (!cache.examples) { TemplateList *exampleList = TemplateList::alloc(); addExamples(exampleList); cache.examples.reset(exampleList); } return cache.examples.get(); } TemplateVariant typeConstraints() const { Cachable &cache = getCache(); if (cache.typeConstraints && !m_memberDef->typeConstraints().empty()) { cache.typeConstraints.reset(ArgumentListContext::alloc(m_memberDef->typeConstraints(),m_memberDef,relPathAsString())); } else { cache.typeConstraints.reset(ArgumentListContext::alloc()); } return cache.typeConstraints.get(); } 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 { Cachable &cache = getCache(); if (!cache.sourceRefs) { cache.sourceRefs.reset(MemberListContext::alloc(m_memberDef->getReferencesMembers())); } return cache.sourceRefs.get(); } TemplateVariant sourceRefBys() const { Cachable &cache = getCache(); if (!cache.sourceRefBys) { cache.sourceRefBys.reset(MemberListContext::alloc(m_memberDef->getReferencedByMembers())); } return cache.sourceRefBys.get(); } TemplateVariant hasSources() const { return TemplateVariant(m_memberDef->hasSources()); } TemplateVariant sourceCode() const { Cachable &cache = getCache(); if (!cache.sourceCodeParsed) { QCString codeFragment; const 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(); } cache.sourceCode = parseCode(const_cast(m_memberDef), scopeName,relPathAsString(), codeFragment,startLine,endLine,TRUE); cache.sourceCodeParsed = TRUE; } } return cache.sourceCode; } DotCallGraph *getCallGraph() const { Cachable &cache = getCache(); if (!cache.callGraph) { cache.callGraph.reset(new DotCallGraph(m_memberDef,FALSE)); } return cache.callGraph.get(); } TemplateVariant hasCallGraph() const { static bool haveDot = Config_getBool(HAVE_DOT); if (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 hasReferencedByRelation() const { return TemplateVariant(m_memberDef->hasReferencedByRelation()); } TemplateVariant callGraph() const { if (hasCallGraph().toBool()) { DotCallGraph *cg = getCallGraph(); std::ostringstream t(std::ios_base::ate); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { cg->writeGraph(t,GOF_BITMAP,EOF_Html, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,g_globals.dynSectionId ); } break; case ContextOutputFormat_Latex: { cg->writeGraph(t,GOF_EPS,EOF_LaTeX, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_memberDef->getOutputFileBase()+".tex", relPathAsString(),TRUE,g_globals.dynSectionId ); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } else { return TemplateVariant(""); } } TemplateVariant referencedByRelation() const { if (hasReferencedByRelation().toBool()) { err("context.cpp: output format not yet supported\n"); } return TemplateVariant(""); } DotCallGraph *getCallerGraph() const { Cachable &cache = getCache(); if (!cache.callerGraph) { cache.callerGraph.reset(new DotCallGraph(m_memberDef,TRUE)); } return cache.callerGraph.get(); } TemplateVariant hasCallerGraph() const { static bool haveDot = Config_getBool(HAVE_DOT); if (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 hasReferencesRelation() const { return TemplateVariant(m_memberDef->hasReferencesRelation()); } TemplateVariant callerGraph() const { if (hasCallerGraph().toBool()) { DotCallGraph *cg = getCallerGraph(); std::ostringstream t(std::ios_base::ate); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { cg->writeGraph(t,GOF_BITMAP,EOF_Html, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,g_globals.dynSectionId ); } break; case ContextOutputFormat_Latex: { cg->writeGraph(t,GOF_EPS,EOF_LaTeX, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_memberDef->getOutputFileBase()+".tex", relPathAsString(),TRUE,g_globals.dynSectionId ); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } else { return TemplateVariant(""); } } TemplateVariant referencesRelation() const { if (hasReferencesRelation().toBool()) { err("context.cpp: output format not yet supported\n"); } return TemplateVariant(""); } TemplateVariant type() const { return m_memberDef->typeString(); } TemplateVariant handleDetailsVisibleFor(const std::vector &args) const { if (args.size()==1) { return m_memberDef->isDetailedSectionVisible(args[0].toString()=="module",args[0].toString()=="file"); } else { err(".detailsVisibleFor should take one string argument, got %zu\n",args.size()); } return TemplateVariant(); } TemplateVariant detailsVisibleFor() const { return TemplateVariant::Delegate::fromMethod(this); } TemplateVariant handleNameWithContextFor(const std::vector &args) const { if (args.size()==1) { SrcLangExt lang = m_memberDef->getLanguage(); QCString n = m_memberDef->name(); QCString ctx = args[0].toString(); QCString sep = getLanguageSpecificSeparator(lang,TRUE); if (m_memberDef->getEnumScope() && m_memberDef->livesInsideEnum()) { n.prepend(m_memberDef->getEnumScope()->displayName()+sep); } if (ctx=="module" && m_memberDef->getClassDef() && !m_memberDef->isRelated()) { n.prepend(m_memberDef->getClassDef()->displayName()+sep); } else if ((ctx=="module" || ctx=="file") && m_memberDef->getNamespaceDef()) { n.prepend(m_memberDef->getNamespaceDef()->displayName()+sep); } return n; } else { err(".nameWithContextFor should take one string argument, got %zu\n",args.size()); } return TemplateVariant(); } TemplateVariant nameWithContextFor() const { return TemplateVariant::Delegate::fromMethod(this); } private: const MemberDef *m_memberDef; struct Cachable : public DefinitionContext::Cachable { Cachable(const MemberDef *md) : DefinitionContext::Cachable(md), initializerParsed(FALSE), sourceCodeParsed(FALSE), declArgsParsed(FALSE), declTypeParsed(FALSE) { } SharedPtr templateArgs; SharedPtr arguments; SharedPtr enumValues; SharedPtr fileDef; SharedPtr namespaceDef; SharedPtr category; SharedPtr categoryRelation; SharedPtr classDef; SharedPtr anonymousType; SharedPtr templateDecls; ScopedPtr paramDocs; SharedPtr implements; SharedPtr reimplements; SharedPtr implementedBy; SharedPtr sourceRefs; SharedPtr sourceRefBys; ScopedPtr callGraph; ScopedPtr callerGraph; SharedPtr anonymousMember; SharedPtr reimplementedBy; SharedPtr labels; TemplateVariant initializer; bool initializerParsed; TemplateVariant sourceCode; bool sourceCodeParsed; TemplateVariant declArgs; bool declArgsParsed; TemplateVariant declType; bool declTypeParsed; SharedPtr examples; SharedPtr exampleList; SharedPtr typeConstraints; SharedPtr propertyAttrs; SharedPtr eventAttrs; }; Cachable &getCache() const { Cachable *c = static_cast(m_memberDef->cookie()); assert(c!=0); return *c; } static PropertyMapper s_inst; }; //%% } PropertyMapper MemberContext::Private::s_inst; MemberContext::MemberContext(const MemberDef *md) : RefCountedContext("MemberContext") { p = new Private(md); } MemberContext::~MemberContext() { delete p; } TemplateVariant MemberContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Module(Symbol): group information //%% { class ModuleContext::Private : public DefinitionContext { public: Private(const GroupDef *gd) : DefinitionContext(gd) , m_groupDef(gd) { static bool init=FALSE; if (!init) { addBaseProperties(s_inst); s_inst.addProperty("title", &Private::title); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subHighlight); s_inst.addProperty("hasGroupGraph", &Private::hasGroupGraph); s_inst.addProperty("groupGraph", &Private::groupGraph); s_inst.addProperty("hasDetails", &Private::hasDetails); s_inst.addProperty("modules", &Private::modules); s_inst.addProperty("dirs", &Private::dirs); s_inst.addProperty("files", &Private::files); s_inst.addProperty("namespaces", &Private::namespaces); s_inst.addProperty("classes", &Private::classes); s_inst.addProperty("constantgroups", &Private::constantgroups); s_inst.addProperty("examples", &Private::examples); s_inst.addProperty("macros", &Private::macros); s_inst.addProperty("typedefs", &Private::typedefs); s_inst.addProperty("enums", &Private::enums); s_inst.addProperty("enumvalues", &Private::enumValues); s_inst.addProperty("functions", &Private::functions); s_inst.addProperty("variables", &Private::variables); s_inst.addProperty("signals", &Private::signals); s_inst.addProperty("publicSlots", &Private::publicSlots); s_inst.addProperty("protectedSlots", &Private::protectedSlots); s_inst.addProperty("privateSlots", &Private::privateSlots); s_inst.addProperty("events", &Private::events); s_inst.addProperty("properties", &Private::properties); s_inst.addProperty("friends", &Private::friends); s_inst.addProperty("memberGroups", &Private::memberGroups); s_inst.addProperty("detailedMacros", &Private::detailedMacros); s_inst.addProperty("detailedTypedefs", &Private::detailedTypedefs); s_inst.addProperty("detailedEnums", &Private::detailedEnums); s_inst.addProperty("detailedEnumValues", &Private::detailedEnumValues); s_inst.addProperty("detailedFunctions", &Private::detailedFunctions); s_inst.addProperty("detailedVariables", &Private::detailedVariables); s_inst.addProperty("detailedSignals", &Private::detailedSignals); s_inst.addProperty("detailedPublicSlots", &Private::detailedPublicSlots); s_inst.addProperty("detailedProtectedSlots", &Private::detailedProtectedSlots); s_inst.addProperty("detailedPrivateSlots", &Private::detailedPrivateSlots); s_inst.addProperty("detailedEvents", &Private::detailedEvents); s_inst.addProperty("detailedProperties", &Private::detailedProperties); s_inst.addProperty("detailedFriends", &Private::detailedFriends); s_inst.addProperty("inlineClasses", &Private::inlineClasses); s_inst.addProperty("compoundType", &Private::compoundType); init=TRUE; } if (!gd->cookie()) { gd->setCookie(new ModuleContext::Private::Cachable(gd)); } } virtual ~Private() {} TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant title() const { return TemplateVariant(m_groupDef->groupTitle()); } TemplateVariant highlight() const { return TemplateVariant("modules"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } DotGroupCollaboration *getGroupGraph() const { Cachable &cache = getCache(); if (!cache.groupGraph) { cache.groupGraph.reset(new DotGroupCollaboration(m_groupDef)); } return cache.groupGraph.get(); } TemplateVariant hasGroupGraph() const { bool result=FALSE; static bool haveDot = Config_getBool(HAVE_DOT); static bool groupGraphs = Config_getBool(GROUP_GRAPHS); if (haveDot && groupGraphs) { DotGroupCollaboration *graph = getGroupGraph(); result = !graph->isTrivial(); } return result; } TemplateVariant groupGraph() const { std::ostringstream t(std::ios_base::ate); static bool haveDot = Config_getBool(HAVE_DOT); static bool groupGraphs = Config_getBool(GROUP_GRAPHS); if (haveDot && groupGraphs) { DotGroupCollaboration *graph = getGroupGraph(); switch (g_globals.outputFormat) { case ContextOutputFormat_Html: { graph->writeGraph(t,GOF_BITMAP, EOF_Html, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_groupDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(), TRUE, g_globals.dynSectionId); } break; case ContextOutputFormat_Latex: { graph->writeGraph(t,GOF_EPS, EOF_LaTeX, g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+m_groupDef->getOutputFileBase()+".tex", relPathAsString(), TRUE, g_globals.dynSectionId); } break; // TODO: support other generators default: err("context.cpp: output format not yet supported\n"); break; } g_globals.dynSectionId++; } QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } TemplateVariant hasDetails() const { return m_groupDef->hasDetailedDescription(); } TemplateVariant modules() const { Cachable &cache = getCache(); if (!cache.modules) { TemplateList *moduleList = TemplateList::alloc(); for (const auto &gd : m_groupDef->getSubGroups()) { if (gd->isVisible()) { moduleList->append(ModuleContext::alloc(gd)); } } cache.modules.reset(moduleList); } return cache.modules.get(); } TemplateVariant examples() const { Cachable &cache = getCache(); if (!cache.examples) { TemplateList *exampleList = TemplateList::alloc(); for (const auto &ex : m_groupDef->getExamples()) { exampleList->append(PageContext::alloc(ex,FALSE,TRUE)); } cache.examples.reset(exampleList); } return cache.examples.get(); } TemplateVariant pages() const { Cachable &cache = getCache(); if (!cache.pages) { TemplateList *pageList = TemplateList::alloc(); for (const auto &ex : m_groupDef->getPages()) { pageList->append(PageContext::alloc(ex,FALSE,TRUE)); } cache.pages.reset(pageList); } return cache.pages.get(); } TemplateVariant dirs() const { Cachable &cache = getCache(); if (!cache.dirs) { TemplateList *dirList = TemplateList::alloc(); for(const auto dd : m_groupDef->getDirs()) { dirList->append(DirContext::alloc(dd)); } cache.dirs.reset(dirList); } return cache.dirs.get(); } TemplateVariant files() const { Cachable &cache = getCache(); if (!cache.files) { TemplateList *fileList = TemplateList::alloc(); for (const auto &fd : m_groupDef->getFiles()) { fileList->append(FileContext::alloc(fd)); } cache.files.reset(fileList); } return cache.files.get(); } TemplateVariant classes() const { Cachable &cache = getCache(); if (!cache.classes) { TemplateList *classList = TemplateList::alloc(); for (const auto &cd : m_groupDef->getClasses()) { if (cd->visibleInParentsDeclList()) { classList->append(ClassContext::alloc(cd)); } } cache.classes.reset(classList); } return cache.classes.get(); } TemplateVariant namespaces() const { Cachable &cache = getCache(); if (!cache.namespaces) { TemplateList *namespaceList = TemplateList::alloc(); for (const auto &nd : m_groupDef->getNamespaces()) { if (nd->isLinkable() && !nd->isConstantGroup()) { namespaceList->append(NamespaceContext::alloc(nd)); } } cache.namespaces.reset(namespaceList); } return cache.namespaces.get(); } TemplateVariant constantgroups() const { Cachable &cache = getCache(); if (!cache.constantgroups) { TemplateList *namespaceList = TemplateList::alloc(); for (const auto &nd : m_groupDef->getNamespaces()) { if (nd->isLinkable() && nd->isConstantGroup()) { namespaceList->append(NamespaceContext::alloc(nd)); } } cache.constantgroups.reset(namespaceList); } return cache.constantgroups.get(); } TemplateVariant getMemberList(SharedPtr &list, MemberListType type,const char *title,bool=FALSE) const { if (!list) { MemberList *ml = m_groupDef->getMemberList(type); if (ml) { list.reset(MemberListInfoContext::alloc(m_groupDef,relPathAsString(),ml,title,"")); } } if (list) { return list.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant macros() const { return getMemberList(getCache().macros,MemberListType_decDefineMembers,theTranslator->trDefines()); } TemplateVariant typedefs() const { return getMemberList(getCache().typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs()); } TemplateVariant enums() const { return getMemberList(getCache().enums,MemberListType_decEnumMembers,theTranslator->trEnumerations()); } TemplateVariant enumValues() const { return getMemberList(getCache().enums,MemberListType_decEnumValMembers,theTranslator->trEnumerationValues()); } TemplateVariant functions() const { QCString title = theTranslator->trFunctions(); SrcLangExt lang = m_groupDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms(); else if (lang==SrcLangExt_VHDL) title=theTranslator->trFunctionAndProc(); return getMemberList(getCache().functions,MemberListType_decFuncMembers,title); } TemplateVariant variables() const { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); return getMemberList(getCache().variables,MemberListType_decVarMembers, sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()); } TemplateVariant signals() const { return getMemberList(getCache().signals,MemberListType_signals,theTranslator->trSignals()); } TemplateVariant publicSlots() const { return getMemberList(getCache().publicSlots,MemberListType_pubSlots,theTranslator->trPublicSlots()); } TemplateVariant protectedSlots() const { return getMemberList(getCache().protectedSlots,MemberListType_proSlots,theTranslator->trProtectedSlots()); } TemplateVariant privateSlots() const { return getMemberList(getCache().privateSlots,MemberListType_priSlots,theTranslator->trPrivateSlots()); } TemplateVariant events() const { return getMemberList(getCache().events,MemberListType_events,theTranslator->trEvents()); } TemplateVariant properties() const { return getMemberList(getCache().properties,MemberListType_properties,theTranslator->trProperties()); } TemplateVariant friends() const { return getMemberList(getCache().friends,MemberListType_friends,theTranslator->trFriends()); } TemplateVariant memberGroups() const { Cachable &cache = getCache(); if (!cache.memberGroups) { if (!m_groupDef->getMemberGroups().empty()) { cache.memberGroups.reset(MemberGroupListContext::alloc(m_groupDef,relPathAsString(),m_groupDef->getMemberGroups(),m_groupDef->subGrouping())); } else { cache.memberGroups.reset(MemberGroupListContext::alloc()); } } return cache.memberGroups.get(); } TemplateVariant detailedMacros() const { return getMemberList(getCache().detailedMacros,MemberListType_docDefineMembers,theTranslator->trDefineDocumentation()); } TemplateVariant detailedTypedefs() const { return getMemberList(getCache().detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()); } TemplateVariant detailedEnums() const { return getMemberList(getCache().detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()); } TemplateVariant detailedEnumValues() const { return getMemberList(getCache().detailedEnumValues,MemberListType_docEnumValMembers,theTranslator->trEnumerationValueDocumentation()); } TemplateVariant detailedFunctions() const { QCString title = theTranslator->trFunctionDocumentation(); SrcLangExt lang = m_groupDef->getLanguage(); if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation(); return getMemberList(getCache().detailedFunctions,MemberListType_docFuncMembers,title); } TemplateVariant detailedVariables() const { return getMemberList(getCache().detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation()); } TemplateVariant detailedSignals() const { return getMemberList(getCache().detailedSignals,MemberListType_docSignalMembers,theTranslator->trSignals()); } TemplateVariant detailedPublicSlots() const { return getMemberList(getCache().detailedPublicSlots,MemberListType_docPubSlotMembers,theTranslator->trPublicSlots()); } TemplateVariant detailedProtectedSlots() const { return getMemberList(getCache().detailedProtectedSlots,MemberListType_docProSlotMembers,theTranslator->trProtectedSlots()); } TemplateVariant detailedPrivateSlots() const { return getMemberList(getCache().detailedPrivateSlots,MemberListType_docPriSlotMembers,theTranslator->trPrivateSlots()); } TemplateVariant detailedEvents() const { return getMemberList(getCache().detailedEvents,MemberListType_docEventMembers,theTranslator->trEventDocumentation(),TRUE); } TemplateVariant detailedProperties() const { return getMemberList(getCache().detailedProperties,MemberListType_docPropMembers,theTranslator->trPropertyDocumentation(),TRUE); } TemplateVariant detailedFriends() const { return getMemberList(getCache().detailedFriends,MemberListType_docFriendMembers,theTranslator->trFriends(),TRUE); } TemplateVariant inlineClasses() const { Cachable &cache = getCache(); if (!cache.inlineClasses) { TemplateList *classList = TemplateList::alloc(); for (const auto &cd : m_groupDef->getClasses()) { if (!cd->isAnonymous() && cd->isLinkableInProject() && cd->isEmbeddedInOuterScope() && cd->partOfGroups().empty()) { classList->append(ClassContext::alloc(cd)); } } cache.inlineClasses.reset(classList); } return cache.inlineClasses.get(); } TemplateVariant compoundType() const { return "module"; //theTranslator->trGroup(FALSE,TRUE); } private: const GroupDef *m_groupDef; struct Cachable : public DefinitionContext::Cachable { Cachable(const GroupDef *gd) : DefinitionContext::Cachable(gd) {} SharedPtr modules; SharedPtr dirs; SharedPtr files; SharedPtr classes; SharedPtr namespaces; SharedPtr constantgroups; SharedPtr examples; SharedPtr pages; SharedPtr macros; SharedPtr typedefs; SharedPtr enums; SharedPtr enumValues; SharedPtr functions; SharedPtr variables; SharedPtr signals; SharedPtr publicSlots; SharedPtr protectedSlots; SharedPtr privateSlots; SharedPtr events; SharedPtr properties; SharedPtr friends; SharedPtr memberGroups; SharedPtr detailedMacros; SharedPtr detailedTypedefs; SharedPtr detailedEnums; SharedPtr detailedEnumValues; SharedPtr detailedFunctions; SharedPtr detailedVariables; SharedPtr detailedSignals; SharedPtr detailedPublicSlots; SharedPtr detailedProtectedSlots; SharedPtr detailedPrivateSlots; SharedPtr detailedEvents; SharedPtr detailedProperties; SharedPtr detailedFriends; SharedPtr inlineClasses; ScopedPtr groupGraph; }; Cachable &getCache() const { Cachable *c = static_cast(m_groupDef->cookie()); assert(c!=0); return *c; } static PropertyMapper s_inst; }; //%% } PropertyMapper ModuleContext::Private::s_inst; ModuleContext::ModuleContext(const GroupDef *gd) : RefCountedContext("ModuleContext") { p = new Private(gd); } ModuleContext::~ModuleContext() { delete p; } TemplateVariant ModuleContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% list ClassList[Class] : list of classes class ClassListContext::Private : public GenericNodeListContext { public: void addClasses(const ClassLinkedMap &classLinkedMap) { for (const auto &cd : classLinkedMap) { if (cd->getLanguage()==SrcLangExt_VHDL && ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) ) // no architecture { continue; } if (cd->isLinkableInProject() && cd->templateMaster()==0 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()) { append(ClassContext::alloc(cd.get())); } } } }; ClassListContext::ClassListContext() : RefCountedContext("ClassListContext") { p = new Private; p->addClasses(*Doxygen::classLinkedMap); p->addClasses(*Doxygen::hiddenClassLinkedMap); } ClassListContext::~ClassListContext() { delete p; } // TemplateListIntf uint ClassListContext::count() const { return p->count(); } TemplateVariant ClassListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *ClassListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% list ClassIndex[Class] : list of classes class ClassIndexContext::Private { public: Private() { static bool init=FALSE; if (!init) { s_inst.addProperty("list", &Private::list); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight",&Private::subhighlight); s_inst.addProperty("title", &Private::title); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant list() const { if (!m_cache.classes) { TemplateList *classList = TemplateList::alloc(); if (Doxygen::classLinkedMap) { for (const auto &cd : *Doxygen::classLinkedMap) { if (cd->getLanguage()==SrcLangExt_VHDL && ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) ) // no architecture { continue; } if (cd->isLinkableInProject() && cd->templateMaster()==0) { classList->append(ClassContext::alloc(cd.get())); } } } m_cache.classes.reset(classList); } return m_cache.classes.get(); } TemplateVariant fileName() const { return "classes"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "classes"; } TemplateVariant subhighlight() const { return "classindex"; } TemplateVariant title() const { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); if (fortranOpt) { return theTranslator->trDataTypes(); } else if (vhdlOpt) { return theTranslator->trDesignUnits(); } else { return theTranslator->trCompoundIndex(); } } private: struct Cachable { SharedPtr classes; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; PropertyMapper ClassIndexContext::Private::s_inst; ClassIndexContext::ClassIndexContext() : RefCountedContext("ClassIndexContext") { p = new Private; //p->addClasses(*Doxygen::hiddenClasses); } ClassIndexContext::~ClassIndexContext() { delete p; } // TemplateStructIntf TemplateVariant ClassIndexContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ static int computeMaxDepth(const TemplateListIntf *list) { int maxDepth=0; if (list) { TemplateListIntf::ConstIterator *it = list->createIterator(); TemplateVariant v; for (it->toFirst();it->current(v);it->toNext()) { const TemplateStructIntf *s = v.toStruct(); TemplateVariant child = s->get("children"); int d = computeMaxDepth(child.toList())+1; if (d>maxDepth) maxDepth=d; } delete it; } return maxDepth; } static int computeNumNodesAtLevel(const TemplateStructIntf *s,int level,int maxLevel) { int num=0; if (levelget("children"); if (child.toList()) { TemplateListIntf::ConstIterator *it = child.toList()->createIterator(); TemplateVariant v; for (it->toFirst();it->current(v);it->toNext()) { num+=computeNumNodesAtLevel(v.toStruct(),level+1,maxLevel); } delete it; } } return num; } static int computePreferredDepth(const TemplateListIntf *list,int maxDepth) { int preferredNumEntries = Config_getInt(HTML_INDEX_NUM_ENTRIES); int preferredDepth=1; if (preferredNumEntries>0) { int depth = maxDepth; for (int i=1;i<=depth;i++) { int num=0; TemplateListIntf::ConstIterator *it = list->createIterator(); TemplateVariant v; for (it->toFirst();it->current(v);it->toNext()) { num+=computeNumNodesAtLevel(v.toStruct(),0,i); } delete it; if (num<=preferredNumEntries) { preferredDepth=i; } else { break; } } } return preferredDepth; } //------------------------------------------------------------------------ //%% struct ClassHierarchy: inheritance tree //%% { class ClassHierarchyContext::Private { public: Private() { m_classTree.reset(NestingContext::alloc(0,0)); ClassDefSet visitedClasses; m_classTree->addClassHierarchy(*Doxygen::classLinkedMap,visitedClasses); m_classTree->addClassHierarchy(*Doxygen::hiddenClassLinkedMap,visitedClasses); //%% ClassInheritance tree static bool init=FALSE; if (!init) { s_inst.addProperty("tree", &Private::tree); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subhighlight); s_inst.addProperty("title", &Private::title); s_inst.addProperty("preferredDepth", &Private::preferredDepth); s_inst.addProperty("maxDepth", &Private::maxDepth); s_inst.addProperty("diagrams", &Private::diagrams); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant tree() const { return m_classTree.get(); } TemplateVariant fileName() const { return "hierarchy"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "classes"; } TemplateVariant subhighlight() const { return "classhierarchy"; } DotGfxHierarchyTable *getHierarchy() const { if (!m_cache.hierarchy) { m_cache.hierarchy.reset(new DotGfxHierarchyTable()); } return m_cache.hierarchy.get(); } TemplateVariant diagrams() const { if (!m_cache.diagrams) { TemplateList *diagrams = TemplateList::alloc(); DotGfxHierarchyTable *hierarchy = getHierarchy(); int id=0; for (auto n : hierarchy->subGraphs()) { diagrams->append(InheritanceGraphContext::alloc(hierarchy,n,id++)); } m_cache.diagrams.reset(diagrams); } return m_cache.diagrams.get(); } TemplateVariant title() const { static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); if (vhdlOpt) { return theTranslator->trDesignUnitHierarchy(); } else { return theTranslator->trClassHierarchy(); } } TemplateVariant maxDepth() const { if (!m_cache.maxDepthComputed) { m_cache.maxDepth = computeMaxDepth(m_classTree.get()); m_cache.maxDepthComputed=TRUE; } return m_cache.maxDepth; } TemplateVariant preferredDepth() const { if (!m_cache.preferredDepthComputed) { m_cache.preferredDepth = computePreferredDepth(m_classTree.get(),maxDepth().toInt()); m_cache.preferredDepthComputed=TRUE; } return m_cache.preferredDepth; } private: SharedPtr m_classTree; struct Cachable { Cachable() : maxDepth(0), maxDepthComputed(FALSE), preferredDepth(0), preferredDepthComputed(FALSE), hierarchy(0) {} int maxDepth; bool maxDepthComputed; int preferredDepth; bool preferredDepthComputed; SharedPtr diagrams; ScopedPtr hierarchy; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper ClassHierarchyContext::Private::s_inst; ClassHierarchyContext::ClassHierarchyContext() : RefCountedContext("ClassHierarchyContext") { p = new Private; } ClassHierarchyContext::~ClassHierarchyContext() { delete p; } TemplateVariant ClassHierarchyContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct NestingNode: node is a nesting relation tree //%% { class NestingNodeContext::Private { public: Private(const NestingNodeContext *parent,const NestingNodeContext *thisNode, const Definition *d,int index,int level,bool addCls,bool inherit, bool hideSuper, ClassDefSet &visitedClasses) : m_parent(parent), m_def(d), m_level(level), m_index(index) { m_children.reset(NestingContext::alloc(thisNode,level+1)); static bool init=FALSE; if (!init) { //%% bool is_leaf_node: true if this node does not have any children s_inst.addProperty("is_leaf_node",&Private::isLeafNode); //%% Nesting children: list of nested classes/namespaces s_inst.addProperty("children",&Private::children); //%% [optional] Class class: class info (if this node represents a class) s_inst.addProperty("class",&Private::getClass); //%% [optional] Namespace namespace: namespace info (if this node represents a namespace) s_inst.addProperty("namespace",&Private::getNamespace); //%% [optional] File file: file info (if this node represents a file) s_inst.addProperty("file",&Private::getFile); //%% [optional] Dir dir: directory info (if this node represents a directory) s_inst.addProperty("dir",&Private::getDir); //%% [optional] Page page: page info (if this node represents a page) s_inst.addProperty("page",&Private::getPage); //%% [optional] Module module: module info (if this node represents a module) s_inst.addProperty("module",&Private::getModule); //%% int id s_inst.addProperty("id",&Private::id); //%% string level s_inst.addProperty("level",&Private::level); //%% string name s_inst.addProperty("name",&Private::name); //%% string brief s_inst.addProperty("brief",&Private::brief); //%% bool isLinkable s_inst.addProperty("isLinkable",&Private::isLinkable); s_inst.addProperty("anchor",&Private::anchor); s_inst.addProperty("fileName",&Private::fileName); s_inst.addProperty("isReference",&Private::isReference); s_inst.addProperty("externalReference",&Private::externalReference); init=TRUE; } addNamespaces(addCls,visitedClasses); addClasses(inherit,hideSuper,visitedClasses); addDirFiles(visitedClasses); addPages(visitedClasses); addModules(visitedClasses); } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant isLeafNode() const { return m_children->count()==0; } TemplateVariant children() const { return m_children.get(); } TemplateVariant getClass() const { if (!m_cache.classContext && m_def->definitionType()==Definition::TypeClass) { m_cache.classContext.reset(ClassContext::alloc(toClassDef(m_def))); } if (m_cache.classContext) { return m_cache.classContext.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant getNamespace() const { if (!m_cache.namespaceContext && m_def->definitionType()==Definition::TypeNamespace) { m_cache.namespaceContext.reset(NamespaceContext::alloc(toNamespaceDef(m_def))); } if (m_cache.namespaceContext) { return m_cache.namespaceContext.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant getDir() const { if (!m_cache.dirContext && m_def->definitionType()==Definition::TypeDir) { m_cache.dirContext.reset(DirContext::alloc(toDirDef(m_def))); } if (m_cache.dirContext) { return m_cache.dirContext.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant getFile() const { if (!m_cache.fileContext && m_def->definitionType()==Definition::TypeFile) { m_cache.fileContext.reset(FileContext::alloc(toFileDef(m_def))); } if (m_cache.fileContext) { return m_cache.fileContext.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant getPage() const { if (!m_cache.pageContext && m_def->definitionType()==Definition::TypePage) { m_cache.pageContext.reset(PageContext::alloc(toPageDef(m_def),FALSE,FALSE)); } if (m_cache.pageContext) { return m_cache.pageContext.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant getModule() const { if (!m_cache.moduleContext && m_def->definitionType()==Definition::TypeGroup) { m_cache.moduleContext.reset(ModuleContext::alloc(toGroupDef(m_def))); } if (m_cache.moduleContext) { return m_cache.moduleContext.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant level() const { return m_level; } TemplateVariant id() const { QCString result; if (m_parent) result=m_parent->id(); result+=QCString().setNum(m_index)+"_"; return result; } TemplateVariant name() const { return m_def->displayName(FALSE); } QCString relPathAsString() const { static bool createSubdirs = Config_getBool(CREATE_SUBDIRS); return createSubdirs ? QCString("../../") : QCString(""); } TemplateVariant brief() const { if (!m_cache.brief) { if (m_def->hasBriefDescription()) { m_cache.brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(), "",m_def->briefDescription(),TRUE))); } else { m_cache.brief.reset(new TemplateVariant("")); } } return *m_cache.brief; } TemplateVariant isLinkable() const { return m_def->isLinkable(); } TemplateVariant anchor() const { return m_def->anchor(); } TemplateVariant fileName() const { return m_def->getOutputFileBase(); } TemplateVariant isReference() const { return m_def->isReference(); } TemplateVariant externalReference() const { return m_def->externalReference(relPathAsString()); } //------------------------------------------------------------------ void addClasses(bool inherit, bool hideSuper,ClassDefSet &visitedClasses) { const ClassDef *cd = toClassDef(m_def); if (cd && inherit) { bool hasChildren = visitedClasses.find(cd)==visitedClasses.end() && !hideSuper && classHasVisibleChildren(cd); if (hasChildren) { visitedClasses.insert(cd); if (cd->getLanguage()==SrcLangExt_VHDL) { m_children->addDerivedClasses(cd->baseClasses(),false,visitedClasses); } else { m_children->addDerivedClasses(cd->subClasses(),false,visitedClasses); } } } else { if (cd) { m_children->addClasses(cd->getClasses(),FALSE,visitedClasses); } } } void addNamespaces(bool addClasses,ClassDefSet &visitedClasses) { const NamespaceDef *nd = toNamespaceDef(m_def); if (nd && !nd->getNamespaces().empty()) { m_children->addNamespaces(nd->getNamespaces(),FALSE,addClasses,visitedClasses); } if (addClasses && nd) { m_children->addClasses(nd->getClasses(),FALSE,visitedClasses); } } void addDirFiles(ClassDefSet &visitedClasses) { const DirDef *dd = toDirDef(m_def); if (dd) { m_children->addDirs(dd->subDirs(),visitedClasses); m_children->addFiles(dd->getFiles(),visitedClasses); } } void addPages(ClassDefSet &visitedClasses) { const PageDef *pd = toPageDef(m_def); if (pd && !pd->getSubPages().empty()) { m_children->addPages(pd->getSubPages(),FALSE,visitedClasses); } } void addModules(ClassDefSet &visitedClasses) { const GroupDef *gd = toGroupDef(m_def); if (gd && !gd->getSubGroups().empty()) { m_children->addModules(gd->getSubGroups(),visitedClasses); } } private: const NestingNodeContext *m_parent; const Definition *m_def; SharedPtr m_children; int m_level; int m_index; struct Cachable { SharedPtr classContext; SharedPtr namespaceContext; SharedPtr dirContext; SharedPtr fileContext; SharedPtr pageContext; SharedPtr moduleContext; ScopedPtr brief; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper NestingNodeContext::Private::s_inst; NestingNodeContext::NestingNodeContext(const NestingNodeContext *parent, const Definition *d,int index,int level,bool addClass,bool inherit,bool hideSuper, ClassDefSet &visitedClasses) : RefCountedContext("NestingNodeContext") { p = new Private(parent,this,d,index,level,addClass,inherit,hideSuper,visitedClasses); } NestingNodeContext::~NestingNodeContext() { delete p; } TemplateVariant NestingNodeContext::get(const char *n) const { return p->get(n); } QCString NestingNodeContext::id() const { return p->id().toString(); } //------------------------------------------------------------------------ //%% list Nesting[NestingNode]: namespace and class nesting relations class NestingContext::Private : public GenericNodeListContext { public: Private(const NestingNodeContext *parent,int level) : m_parent(parent), m_level(level), m_index(0) {} void addNamespace(const NamespaceDef *nd,bool rootOnly,bool addClasses,ClassDefSet &visitedClasses) { if (!nd->isAnonymous() && (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { bool hasChildren = namespaceHasNestedNamespace(nd); bool isLinkable = nd->isLinkableInProject(); if (isLinkable || hasChildren) { NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,nd,m_index,m_level,addClasses,FALSE,FALSE,visitedClasses); append(nnc); m_index++; } } } void addNamespaces(const NamespaceLinkedMap &nsLinkedMap,bool rootOnly,bool addClasses,ClassDefSet &visitedClasses) { for (const auto &nd : nsLinkedMap) { addNamespace(nd.get(),rootOnly,addClasses,visitedClasses); } } void addNamespaces(const NamespaceLinkedRefMap &nsLinkedMap,bool rootOnly,bool addClasses,ClassDefSet &visitedClasses) { for (const auto &nd : nsLinkedMap) { addNamespace(nd,rootOnly,addClasses,visitedClasses); } } void addClass(const ClassDef *cd,bool rootOnly,ClassDefSet &visitedClasses) { if (cd->getLanguage()==SrcLangExt_VHDL) { if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS )// no architecture { return; } } if (!rootOnly || cd->getOuterScope()==0 || cd->getOuterScope()==Doxygen::globalScope ) { if (classVisibleInIndex(cd) && cd->templateMaster()==0) { NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,cd,m_index,m_level,TRUE,FALSE,FALSE,visitedClasses); append(nnc); m_index++; } } } void addClasses(const ClassLinkedRefMap &clLinkedMap,bool rootOnly,ClassDefSet &visitedClasses) { for (const auto &cd : clLinkedMap) { addClass(cd,rootOnly,visitedClasses); } } void addClasses(const ClassLinkedMap &clLinkedMap,bool rootOnly,ClassDefSet &visitedClasses) { for (const auto &cd : clLinkedMap) { addClass(cd.get(),rootOnly,visitedClasses); } } void addDirs(const DirLinkedMap &dirLinkedMap,ClassDefSet &visitedClasses) { for (const auto &dd : dirLinkedMap) { if (dd->getOuterScope()==Doxygen::globalScope) { append(NestingNodeContext::alloc(m_parent,dd.get(),m_index,m_level,FALSE,FALSE,FALSE,visitedClasses)); m_index++; } } } void addDirs(const DirList &dirList,ClassDefSet &visitedClasses) { for(const auto dd : dirList) { append(NestingNodeContext::alloc(m_parent,dd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses)); m_index++; } } void addFiles(const FileNameLinkedMap &fnList,ClassDefSet &visitedClasses) { for (const FileNameLinkedMap::Ptr &fn : fnList) { for (const auto &fd : *fn) { if (fd->getDirDef()==0) // top level file { append(NestingNodeContext::alloc(m_parent,fd.get(),m_index,m_level,FALSE,FALSE,FALSE,visitedClasses)); m_index++; } } } } void addFiles(const FileList &fList,ClassDefSet &visitedClasses) { for (const auto &fd : fList) { append(NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses)); m_index++; } } void addPage(const PageDef *pd,bool rootOnly,ClassDefSet &visitedClasses) { if (!rootOnly || pd->getOuterScope()==0 || pd->getOuterScope()->definitionType()!=Definition::TypePage) { append(NestingNodeContext::alloc(m_parent,pd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses)); m_index++; } } void addPages(const PageLinkedMap &pages,bool rootOnly,ClassDefSet &visitedClasses) { for (const auto &pd : pages) { addPage(pd.get(),rootOnly,visitedClasses); } } void addPages(const PageLinkedRefMap &pages,bool rootOnly,ClassDefSet &visitedClasses) { for (const auto &pd : pages) { addPage(pd,rootOnly,visitedClasses); } } void addModules(const GroupLinkedMap &groups,ClassDefSet &visitedClasses) { for (const auto &gd : groups) { bool externalGroups = Config_getBool(EXTERNAL_GROUPS); if (!gd->isASubGroup() && gd->isVisible() && (!gd->isReference() || externalGroups) ) { append(NestingNodeContext::alloc(m_parent,gd.get(),m_index,m_level,FALSE,FALSE,FALSE,visitedClasses)); m_index++; } } } void addModules(const GroupList &groups,ClassDefSet &visitedClasses) { for (const auto &gd : groups) { if (gd->isVisible()) { append(NestingNodeContext::alloc(m_parent,gd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses)); m_index++; } } } void addDerivedClasses(const BaseClassList &bcl,bool hideSuper,ClassDefSet &visitedClasses) { for (const auto &bcd : bcl) { const ClassDef *cd=bcd.classDef; if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) { continue; } bool b; if (cd->getLanguage()==SrcLangExt_VHDL) { b=hasVisibleRoot(cd->subClasses()); } else { b=hasVisibleRoot(cd->baseClasses()); } if (cd->isVisibleInHierarchy() && b) { NestingNodeContext *tnc = NestingNodeContext::alloc(m_parent,cd,m_index,m_level,TRUE,TRUE,hideSuper,visitedClasses); append(tnc); m_index++; } } } void addClassHierarchy(const ClassLinkedMap &classLinkedMap,ClassDefSet &visitedClasses) { for (const auto &cd : classLinkedMap) { bool b; if (cd->getLanguage()==SrcLangExt_VHDL) { if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) { continue; } b=!hasVisibleRoot(cd->subClasses()); } else { b=!hasVisibleRoot(cd->baseClasses()); } if (b) { if (cd->isVisibleInHierarchy()) // should it be visible { // new root level class NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,cd.get(),m_index,m_level,TRUE,TRUE,FALSE,visitedClasses); append(nnc); m_index++; } } } } private: const NestingNodeContext *m_parent; int m_level; int m_index; }; NestingContext::NestingContext(const NestingNodeContext *parent,int level) : RefCountedContext("NestingContext") { p = new Private(parent,level); } NestingContext::~NestingContext() { delete p; } // TemplateListIntf uint NestingContext::count() const { return p->count(); } TemplateVariant NestingContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *NestingContext::createIterator() const { return p->createIterator(); } void NestingContext::addClasses(const ClassLinkedRefMap &clLinkedRefMap,bool rootOnly,ClassDefSet &visitedClasses) { p->addClasses(clLinkedRefMap,rootOnly,visitedClasses); } void NestingContext::addClasses(const ClassLinkedMap &clLinkedMap,bool rootOnly,ClassDefSet &visitedClasses) { p->addClasses(clLinkedMap,rootOnly,visitedClasses); } void NestingContext::addNamespaces(const NamespaceLinkedMap &nsLinkedMap,bool rootOnly,bool addClasses,ClassDefSet &visitedClasses) { p->addNamespaces(nsLinkedMap,rootOnly,addClasses,visitedClasses); } void NestingContext::addNamespaces(const NamespaceLinkedRefMap &nsLinkedRefMap,bool rootOnly,bool addClasses,ClassDefSet &visitedClasses) { p->addNamespaces(nsLinkedRefMap,rootOnly,addClasses,visitedClasses); } void NestingContext::addDirs(const DirLinkedMap &dirs,ClassDefSet &visitedClasses) { p->addDirs(dirs,visitedClasses); } void NestingContext::addDirs(const DirList &dirs,ClassDefSet &visitedClasses) { p->addDirs(dirs,visitedClasses); } void NestingContext::addFiles(const FileNameLinkedMap &files,ClassDefSet &visitedClasses) { p->addFiles(files,visitedClasses); } void NestingContext::addFiles(const FileList &files,ClassDefSet &visitedClasses) { p->addFiles(files,visitedClasses); } void NestingContext::addPages(const PageLinkedMap &pages,bool rootOnly,ClassDefSet &visitedClasses) { p->addPages(pages,rootOnly,visitedClasses); } void NestingContext::addPages(const PageLinkedRefMap &pages,bool rootOnly,ClassDefSet &visitedClasses) { p->addPages(pages,rootOnly,visitedClasses); } void NestingContext::addModules(const GroupLinkedMap &modules,ClassDefSet &visitedClasses) { p->addModules(modules,visitedClasses); } void NestingContext::addModules(const GroupList &modules,ClassDefSet &visitedClasses) { p->addModules(modules,visitedClasses); } void NestingContext::addClassHierarchy(const ClassLinkedMap &classLinkedMap,ClassDefSet &visitedClasses) { p->addClassHierarchy(classLinkedMap,visitedClasses); } void NestingContext::addDerivedClasses(const BaseClassList &bcl,bool hideSuper,ClassDefSet &visitedClasses) { p->addDerivedClasses(bcl,hideSuper,visitedClasses); } //------------------------------------------------------------------------ //%% struct ClassTree: Class nesting relations //%% { class ClassTreeContext::Private { public: Private() { m_classTree.reset(NestingContext::alloc(0,0)); ClassDefSet visitedClasses; m_classTree->addNamespaces(*Doxygen::namespaceLinkedMap,TRUE,TRUE,visitedClasses); m_classTree->addClasses(*Doxygen::classLinkedMap,TRUE,visitedClasses); //%% Nesting tree static bool init=FALSE; if (!init) { s_inst.addProperty("tree", &Private::tree); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subhighlight); s_inst.addProperty("title", &Private::title); s_inst.addProperty("preferredDepth",&Private::preferredDepth); s_inst.addProperty("maxDepth", &Private::maxDepth); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant tree() const { return m_classTree.get(); } TemplateVariant fileName() const { return "annotated"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "classes"; } TemplateVariant subhighlight() const { return "classlist"; } TemplateVariant title() const { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); if (fortranOpt) { return theTranslator->trCompoundListFortran(); } else if (vhdlOpt) { return theTranslator->trDesignUnitList(); } else { return theTranslator->trClasses(); } } TemplateVariant maxDepth() const { if (!m_cache.maxDepthComputed) { m_cache.maxDepth = computeMaxDepth(m_classTree.get()); m_cache.maxDepthComputed=TRUE; } return m_cache.maxDepth; } TemplateVariant preferredDepth() const { if (!m_cache.preferredDepthComputed) { m_cache.preferredDepth = computePreferredDepth(m_classTree.get(),maxDepth().toInt()); m_cache.preferredDepthComputed=TRUE; } return m_cache.preferredDepth; } private: SharedPtr m_classTree; struct Cachable { Cachable() : maxDepth(0), maxDepthComputed(FALSE), preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; bool preferredDepthComputed; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper ClassTreeContext::Private::s_inst; ClassTreeContext::ClassTreeContext() : RefCountedContext("ClassTreeContext") { p = new Private; } ClassTreeContext::~ClassTreeContext() { delete p; } TemplateVariant ClassTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list NamespaceList[Namespace] : list of namespaces class NamespaceListContext::Private : public GenericNodeListContext { public: void addNamespaces(const NamespaceLinkedMap &nsLinkedMap) { for (const auto &nd : nsLinkedMap) { if (nd->isLinkableInProject()) { append(NamespaceContext::alloc(nd.get())); } } } }; NamespaceListContext::NamespaceListContext() : RefCountedContext("NamespaceListContext") { p = new Private; p->addNamespaces(*Doxygen::namespaceLinkedMap); } NamespaceListContext::~NamespaceListContext() { delete p; } // TemplateListIntf uint NamespaceListContext::count() const { return p->count(); } TemplateVariant NamespaceListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *NamespaceListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct NamespaceTree: tree of nested namespace //%% { class NamespaceTreeContext::Private { public: Private() { m_namespaceTree.reset(NestingContext::alloc(0,0)); ClassDefSet visitedClasses; m_namespaceTree->addNamespaces(*Doxygen::namespaceLinkedMap,TRUE,FALSE,visitedClasses); //%% Nesting tree static bool init=FALSE; if (!init) { s_inst.addProperty("tree", &Private::tree); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subhighlight); s_inst.addProperty("title", &Private::title); s_inst.addProperty("preferredDepth",&Private::preferredDepth); s_inst.addProperty("maxDepth", &Private::maxDepth); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant tree() const { return m_namespaceTree.get(); } TemplateVariant fileName() const { return "namespaces"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "namespaces"; } TemplateVariant subhighlight() const { return "namespacelist"; } TemplateVariant title() const { static bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA); static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (javaOpt || vhdlOpt) { return theTranslator->trPackages(); } else if (fortranOpt || sliceOpt) { return theTranslator->trModulesList(); } else { return theTranslator->trNamespaceList(); } } TemplateVariant maxDepth() const { if (!m_cache.maxDepthComputed) { m_cache.maxDepth = computeMaxDepth(m_namespaceTree.get()); m_cache.maxDepthComputed=TRUE; } return m_cache.maxDepth; } TemplateVariant preferredDepth() const { if (!m_cache.preferredDepthComputed) { m_cache.preferredDepth = computePreferredDepth(m_namespaceTree.get(),maxDepth().toInt()); m_cache.preferredDepthComputed=TRUE; } return m_cache.preferredDepth; } private: SharedPtr m_namespaceTree; struct Cachable { Cachable() : maxDepth(0), maxDepthComputed(FALSE), preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; bool preferredDepthComputed; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper NamespaceTreeContext::Private::s_inst; NamespaceTreeContext::NamespaceTreeContext() : RefCountedContext("NamespaceTreeContext") { p = new Private; } NamespaceTreeContext::~NamespaceTreeContext() { delete p; } TemplateVariant NamespaceTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list FileList[File] : list of files class FileListContext::Private : public GenericNodeListContext { public: void addFiles(const FileNameLinkedMap &fnMap) { // TODO: if FULL_PATH_NAMES is enabled, the ordering should be dir+file for (const auto &fn : fnMap) { for (const auto &fd : *fn) { bool doc = fd->isLinkableInProject(); bool src = fd->generateSourceFile(); bool nameOk = !fd->isDocumentationFile(); if (nameOk && (doc || src) && !fd->isReference()) { append(FileContext::alloc(fd.get())); } } } } }; FileListContext::FileListContext() : RefCountedContext("FileListContext") { p = new Private; if (Doxygen::inputNameLinkedMap) p->addFiles(*Doxygen::inputNameLinkedMap); } FileListContext::~FileListContext() { delete p; } // TemplateListIntf uint FileListContext::count() const { return p->count(); } TemplateVariant FileListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *FileListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% list DirList[Dir] : list of files class DirListContext::Private : public GenericNodeListContext { public: Private() { for (const auto &dir : *Doxygen::dirLinkedMap) { append(DirContext::alloc(dir.get())); } } }; DirListContext::DirListContext() : RefCountedContext("DirListContext") { p = new Private; } DirListContext::~DirListContext() { delete p; } // TemplateListIntf uint DirListContext::count() const { return p->count(); } TemplateVariant DirListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *DirListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% list UsedFiles[File] : list of files class UsedFilesContext::Private : public GenericNodeListContext { public: void addFile(const FileDef *fd) { append(FileContext::alloc(fd)); } }; UsedFilesContext::UsedFilesContext(const ClassDef *cd) : RefCountedContext("UsedFilesContext") { p = new Private; if (cd) { for (const auto &fd : cd->usedFiles()) { p->addFile(fd); } } } UsedFilesContext::~UsedFilesContext() { delete p; } // TemplateListIntf uint UsedFilesContext::count() const { return p->count(); } TemplateVariant UsedFilesContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *UsedFilesContext::createIterator() const { return p->createIterator(); } void UsedFilesContext::addFile(const FileDef *fd) { p->addFile(fd); } //------------------------------------------------------------------------ //%% struct FileTree: tree of directories and files //%% { class FileTreeContext::Private { public: Private() { // Add dirs tree m_dirFileTree.reset(NestingContext::alloc(0,0)); ClassDefSet visitedClasses; m_dirFileTree->addDirs(*Doxygen::dirLinkedMap,visitedClasses); if (Doxygen::inputNameLinkedMap) { m_dirFileTree->addFiles(*Doxygen::inputNameLinkedMap,visitedClasses); } //%% DirFile tree: static bool init=FALSE; if (!init) { s_inst.addProperty("tree", &Private::tree); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subhighlight); s_inst.addProperty("title", &Private::title); s_inst.addProperty("preferredDepth",&Private::preferredDepth); s_inst.addProperty("maxDepth", &Private::maxDepth); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant tree() const { return m_dirFileTree.get(); } TemplateVariant fileName() const { return "files"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "files"; } TemplateVariant subhighlight() const { return "filelist"; } TemplateVariant title() const { return theTranslator->trFileList(); } TemplateVariant maxDepth() const { if (!m_cache.maxDepthComputed) { m_cache.maxDepth = computeMaxDepth(m_dirFileTree.get()); m_cache.maxDepthComputed=TRUE; } return m_cache.maxDepth; } TemplateVariant preferredDepth() const { if (!m_cache.preferredDepthComputed) { m_cache.preferredDepth = computePreferredDepth(m_dirFileTree.get(),maxDepth().toInt()); m_cache.preferredDepthComputed=TRUE; } return m_cache.preferredDepth; } private: SharedPtr m_dirFileTree; struct Cachable { Cachable() : maxDepth(0), maxDepthComputed(FALSE), preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; bool preferredDepthComputed; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper FileTreeContext::Private::s_inst; FileTreeContext::FileTreeContext() : RefCountedContext("FileTreeContext") { p = new Private; } FileTreeContext::~FileTreeContext() { delete p; } TemplateVariant FileTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct PageTree: tree of related pages //%% { class PageTreeContext::Private { public: Private(const PageLinkedMap &pages) { m_pageTree.reset(NestingContext::alloc(0,0)); ClassDefSet visitedClasses; // Add pages m_pageTree->addPages(pages,TRUE,visitedClasses); //%% PageNodeList tree: static bool init=FALSE; if (!init) { s_inst.addProperty("tree", &Private::tree); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subhighlight); s_inst.addProperty("title", &Private::title); s_inst.addProperty("preferredDepth",&Private::preferredDepth); s_inst.addProperty("maxDepth", &Private::maxDepth); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant tree() const { return m_pageTree.get(); } TemplateVariant fileName() const { return "pages"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "pages"; } TemplateVariant subhighlight() const { return ""; } TemplateVariant title() const { return theTranslator->trRelatedPages(); } TemplateVariant maxDepth() const { if (!m_cache.maxDepthComputed) { m_cache.maxDepth = computeMaxDepth(m_pageTree.get()); m_cache.maxDepthComputed=TRUE; } return m_cache.maxDepth; } TemplateVariant preferredDepth() const { if (!m_cache.preferredDepthComputed) { m_cache.preferredDepth = computePreferredDepth(m_pageTree.get(),maxDepth().toInt()); m_cache.preferredDepthComputed=TRUE; } return m_cache.preferredDepth; } private: SharedPtr m_pageTree; struct Cachable { Cachable() : maxDepth(0), maxDepthComputed(FALSE), preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; bool preferredDepthComputed; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper PageTreeContext::Private::s_inst; PageTreeContext::PageTreeContext(const PageLinkedMap &pages) : RefCountedContext("PageTreeContext") { p = new Private(pages); } PageTreeContext::~PageTreeContext() { delete p; } TemplateVariant PageTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list PageList[Page]: list of pages class PageListContext::Private : public GenericNodeListContext { public: void addPages(const PageLinkedMap &pages) { for (const auto &pd : pages) { if (!pd->getGroupDef() && !pd->isReference()) { append(PageContext::alloc(pd.get(),FALSE,FALSE)); } } } }; PageListContext::PageListContext(const PageLinkedMap &pages) : RefCountedContext("PageListContext") { p = new Private; p->addPages(pages); } PageListContext::~PageListContext() { delete p; } // TemplateListIntf uint PageListContext::count() const { return p->count(); } TemplateVariant PageListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *PageListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% list ExampleList[Page]: list of pages class ExampleListContext::Private : public GenericNodeListContext { public: Private() { for (const auto &pd : *Doxygen::exampleLinkedMap) { if (!pd->getGroupDef() && !pd->isReference()) { append(PageContext::alloc(pd.get(),FALSE,TRUE)); } } } }; ExampleListContext::ExampleListContext() : RefCountedContext("ExampleListContext") { p = new Private; } ExampleListContext::~ExampleListContext() { delete p; } // TemplateListIntf uint ExampleListContext::count() const { return p->count(); } TemplateVariant ExampleListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *ExampleListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% list ModuleList[ModuleNode]: list of directories and/or files class ModuleListContext::Private : public GenericNodeListContext { public: void addModules() { for (const auto &gd : *Doxygen::groupLinkedMap) { if (!gd->isReference()) { append(ModuleContext::alloc(gd.get())); } } } }; ModuleListContext::ModuleListContext() : RefCountedContext("ModuleListContext") { p = new Private; p->addModules(); } ModuleListContext::~ModuleListContext() { delete p; } // TemplateListIntf uint ModuleListContext::count() const { return p->count(); } TemplateVariant ModuleListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *ModuleListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct ModuleTree: tree of modules //%% { class ModuleTreeContext::Private { public: Private() { m_moduleTree.reset(NestingContext::alloc(0,0)); ClassDefSet visitedClasses; // Add modules m_moduleTree->addModules(*Doxygen::groupLinkedMap,visitedClasses); //%% ModuleList tree: static bool init=FALSE; if (!init) { s_inst.addProperty("tree", &Private::tree); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subhighlight); s_inst.addProperty("title", &Private::title); s_inst.addProperty("preferredDepth",&Private::preferredDepth); s_inst.addProperty("maxDepth", &Private::maxDepth); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant tree() const { return m_moduleTree.get(); } TemplateVariant fileName() const { return "modules"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "modules"; } TemplateVariant subhighlight() const { return ""; } TemplateVariant title() const { return theTranslator->trModules(); } TemplateVariant maxDepth() const { if (!m_cache.maxDepthComputed) { m_cache.maxDepth = computeMaxDepth(m_moduleTree.get()); m_cache.maxDepthComputed=TRUE; } return m_cache.maxDepth; } TemplateVariant preferredDepth() const { if (!m_cache.preferredDepthComputed) { m_cache.preferredDepth = computePreferredDepth(m_moduleTree.get(),maxDepth().toInt()); m_cache.preferredDepthComputed=TRUE; } return m_cache.preferredDepth; } private: SharedPtr m_moduleTree; struct Cachable { Cachable() : maxDepth(0), maxDepthComputed(FALSE), preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; bool preferredDepthComputed; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper ModuleTreeContext::Private::s_inst; ModuleTreeContext::ModuleTreeContext() : RefCountedContext("ModuleTreeContext") { p = new Private; } ModuleTreeContext::~ModuleTreeContext() { delete p; } TemplateVariant ModuleTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct NavPathElem: list of examples page //%% { class NavPathElemContext::Private { public: Private(const Definition *def) : m_def(def) { static bool init=FALSE; if (!init) { s_inst.addProperty("isLinkable", &Private::isLinkable); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("anchor", &Private::anchor); s_inst.addProperty("text", &Private::text); s_inst.addProperty("isReference", &Private::isReference); s_inst.addProperty("externalReference",&Private::externalReference); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } 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 = (toGroupDef(m_def))->groupTitle(); } else if (type==Definition::TypePage && ((toPageDef(m_def))->hasTitle())) { text = (toPageDef(m_def))->title(); } else if (type==Definition::TypeClass) { if (text.right(2)=="-p") { text = text.left(text.length()-2); } } return text; } TemplateVariant isReference() const { return m_def->isReference(); } QCString relPathAsString() const { static bool createSubdirs = Config_getBool(CREATE_SUBDIRS); return createSubdirs ? QCString("../../") : QCString(""); } TemplateVariant externalReference() const { return m_def->externalReference(relPathAsString()); } private: const Definition *m_def; static PropertyMapper s_inst; }; //%% } PropertyMapper NavPathElemContext::Private::s_inst; NavPathElemContext::NavPathElemContext(const Definition *def) : RefCountedContext("NavPathElemContext") { 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 ExampleTreeContext::Private { public: Private() { m_exampleTree.reset(NestingContext::alloc(0,0)); ClassDefSet visitedClasses; // Add pages m_exampleTree->addPages(*Doxygen::exampleLinkedMap,TRUE,visitedClasses); static bool init=FALSE; if (!init) { s_inst.addProperty("tree", &Private::tree); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight", &Private::subhighlight); s_inst.addProperty("title", &Private::title); s_inst.addProperty("preferredDepth",&Private::preferredDepth); s_inst.addProperty("maxDepth", &Private::maxDepth); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant tree() const { return m_exampleTree.get(); } TemplateVariant fileName() const { return "examples"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "examples"; } TemplateVariant subhighlight() const { return ""; } TemplateVariant title() const { return theTranslator->trExamples(); } TemplateVariant maxDepth() const { if (!m_cache.maxDepthComputed) { m_cache.maxDepth = computeMaxDepth(m_exampleTree.get()); m_cache.maxDepthComputed=TRUE; } return m_cache.maxDepth; } TemplateVariant preferredDepth() const { if (!m_cache.preferredDepthComputed) { m_cache.preferredDepth = computePreferredDepth(m_exampleTree.get(),maxDepth().toInt()); m_cache.preferredDepthComputed=TRUE; } return m_cache.preferredDepth; } private: SharedPtr m_exampleTree; struct Cachable { Cachable() : maxDepth(0), maxDepthComputed(FALSE), preferredDepth(0), preferredDepthComputed(FALSE) {} int maxDepth; bool maxDepthComputed; int preferredDepth; bool preferredDepthComputed; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper ExampleTreeContext::Private::s_inst; ExampleTreeContext::ExampleTreeContext() : RefCountedContext("ExampleTreeContext") { p = new Private; } ExampleTreeContext::~ExampleTreeContext() { delete p; } TemplateVariant ExampleTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct GlobalsIndex: list of examples page //%% { class GlobalsIndexContext::Private { public: Private() { static bool init=FALSE; if (!init) { s_inst.addProperty("all", &Private::all); s_inst.addProperty("functions", &Private::functions); s_inst.addProperty("variables", &Private::variables); s_inst.addProperty("typedefs", &Private::typedefs); s_inst.addProperty("enums", &Private::enums); s_inst.addProperty("enumValues", &Private::enumValues); s_inst.addProperty("macros", &Private::macros); s_inst.addProperty("properties", &Private::properties); s_inst.addProperty("events", &Private::events); s_inst.addProperty("related", &Private::related); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight",&Private::subhighlight); s_inst.addProperty("title", &Private::title); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } typedef bool (MemberDef::*MemberFunc)() const; TemplateVariant getMembersFiltered(SharedPtr &listRef,MemberFunc filter) const { if (!listRef) { TemplateList *list = TemplateList::alloc(); for (const auto &mn : *Doxygen::functionNameLinkedMap) { for (const auto &md : *mn) { const FileDef *fd=md->getFileDef(); if (fd && fd->isLinkableInProject() && !md->name().isEmpty() && !md->getNamespaceDef() && md->isLinkableInProject()) { if (filter==0 || (md.get()->*filter)()) { list->append(MemberContext::alloc(md.get())); } } } } listRef.reset(list); } return listRef.get(); } TemplateVariant all() const { return getMembersFiltered(m_cache.all,0); } TemplateVariant functions() const { return getMembersFiltered(m_cache.functions,&MemberDef::isFunction); } TemplateVariant variables() const { return getMembersFiltered(m_cache.variables,&MemberDef::isVariable); } TemplateVariant typedefs() const { return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef); } TemplateVariant enums() const { return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate); } TemplateVariant enumValues() const { return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue); } TemplateVariant macros() const { return getMembersFiltered(m_cache.macros,&MemberDef::isDefine); } TemplateVariant properties() const { return FALSE; } TemplateVariant events() const { return FALSE; } TemplateVariant related() const { return FALSE; } TemplateVariant fileName() const { return "globals"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "files"; } TemplateVariant subhighlight() const { return "filemembers"; } TemplateVariant title() const { return theTranslator->trFileMembers(); } private: struct Cachable { Cachable() {} SharedPtr all; SharedPtr functions; SharedPtr variables; SharedPtr typedefs; SharedPtr enums; SharedPtr enumValues; SharedPtr macros; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper GlobalsIndexContext::Private::s_inst; GlobalsIndexContext::GlobalsIndexContext() : RefCountedContext("GlobalsIndexContext") { p = new Private; } GlobalsIndexContext::~GlobalsIndexContext() { delete p; } TemplateVariant GlobalsIndexContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct ClassMembersIndex: list of examples page //%% { class ClassMembersIndexContext::Private { public: Private() { static bool init=FALSE; if (!init) { s_inst.addProperty("all", &Private::all); s_inst.addProperty("functions", &Private::functions); s_inst.addProperty("variables", &Private::variables); s_inst.addProperty("typedefs", &Private::typedefs); s_inst.addProperty("enums", &Private::enums); s_inst.addProperty("enumValues", &Private::enumValues); s_inst.addProperty("macros", &Private::macros); s_inst.addProperty("properties", &Private::properties); s_inst.addProperty("events", &Private::events); s_inst.addProperty("related", &Private::related); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight",&Private::subhighlight); s_inst.addProperty("title", &Private::title); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } typedef bool (MemberDef::*MemberFunc)() const; TemplateVariant getMembersFiltered(SharedPtr &listRef,MemberFunc filter) const { if (!listRef) { TemplateList *list = TemplateList::alloc(); for (const auto &mn : *Doxygen::memberNameLinkedMap) { for (const auto &md : *mn) { const ClassDef *cd = md->getClassDef(); if (cd && cd->isLinkableInProject() && cd->templateMaster()==0 && md->isLinkableInProject() && !md->name().isEmpty()) { if (filter==0 || (md.get()->*filter)()) { list->append(MemberContext::alloc(md.get())); } } } } listRef.reset(list); } return listRef.get(); } TemplateVariant all() const { return getMembersFiltered(m_cache.all,&MemberDef::isNotFriend); } TemplateVariant functions() const { return getMembersFiltered(m_cache.functions,&MemberDef::isFunctionOrSignalSlot); } TemplateVariant variables() const { return getMembersFiltered(m_cache.variables,&MemberDef::isVariable); } TemplateVariant typedefs() const { return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef); } TemplateVariant enums() const { return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate); } TemplateVariant enumValues() const { return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue); } TemplateVariant macros() const { return FALSE; } TemplateVariant properties() const { return getMembersFiltered(m_cache.properties,&MemberDef::isProperty); } TemplateVariant events() const { return getMembersFiltered(m_cache.events,&MemberDef::isEvent); } TemplateVariant related() const { return getMembersFiltered(m_cache.related,&MemberDef::isRelated); } TemplateVariant fileName() const { return "functions"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "classes"; } TemplateVariant subhighlight() const { return "classmembers"; } TemplateVariant title() const { return theTranslator->trCompoundMembers(); } private: struct Cachable { Cachable() {} SharedPtr all; SharedPtr functions; SharedPtr variables; SharedPtr typedefs; SharedPtr enums; SharedPtr enumValues; SharedPtr properties; SharedPtr events; SharedPtr related; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper ClassMembersIndexContext::Private::s_inst; ClassMembersIndexContext::ClassMembersIndexContext() : RefCountedContext("ClassMembersIndexContext") { p = new Private; } ClassMembersIndexContext::~ClassMembersIndexContext() { delete p; } TemplateVariant ClassMembersIndexContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct NamespaceMembersIndex: list of examples page //%% { class NamespaceMembersIndexContext::Private { public: Private() { static bool init=FALSE; if (!init) { s_inst.addProperty("all", &Private::all); s_inst.addProperty("functions", &Private::functions); s_inst.addProperty("variables", &Private::variables); s_inst.addProperty("typedefs", &Private::typedefs); s_inst.addProperty("enums", &Private::enums); s_inst.addProperty("enumValues", &Private::enumValues); s_inst.addProperty("macros", &Private::macros); s_inst.addProperty("properties", &Private::properties); s_inst.addProperty("events", &Private::events); s_inst.addProperty("related", &Private::related); s_inst.addProperty("fileName", &Private::fileName); s_inst.addProperty("relPath", &Private::relPath); s_inst.addProperty("highlight", &Private::highlight); s_inst.addProperty("subhighlight",&Private::subhighlight); s_inst.addProperty("title", &Private::title); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } typedef bool (MemberDef::*MemberFunc)() const; TemplateVariant getMembersFiltered(SharedPtr &listRef,MemberFunc filter) const { if (!listRef) { TemplateList *list = TemplateList::alloc(); for (const auto &mn : *Doxygen::functionNameLinkedMap) { for (const auto &md : *mn) { const NamespaceDef *nd=md->getNamespaceDef(); if (nd && nd->isLinkableInProject() && !md->name().isEmpty() && md->isLinkableInProject()) { if (filter==0 || (md.get()->*filter)()) { list->append(MemberContext::alloc(md.get())); } } } } listRef.reset(list); } return listRef.get(); } TemplateVariant all() const { return getMembersFiltered(m_cache.all,0); } TemplateVariant functions() const { return getMembersFiltered(m_cache.functions,&MemberDef::isFunction); } TemplateVariant variables() const { return getMembersFiltered(m_cache.variables,&MemberDef::isVariable); } TemplateVariant typedefs() const { return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef); } TemplateVariant enums() const { return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate); } TemplateVariant enumValues() const { return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue); } TemplateVariant macros() const { return FALSE; } TemplateVariant properties() const { return FALSE; } TemplateVariant events() const { return FALSE; } TemplateVariant related() const { return FALSE; } TemplateVariant fileName() const { return "namespacemembers"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "namespaces"; } TemplateVariant subhighlight() const { return "namespacemembers"; } TemplateVariant title() const { return theTranslator->trNamespaceMembers(); } private: struct Cachable { Cachable() {} SharedPtr all; SharedPtr functions; SharedPtr variables; SharedPtr typedefs; SharedPtr enums; SharedPtr enumValues; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper NamespaceMembersIndexContext::Private::s_inst; NamespaceMembersIndexContext::NamespaceMembersIndexContext() : RefCountedContext("NamespaceMembersIndexContext") { p = new Private; } NamespaceMembersIndexContext::~NamespaceMembersIndexContext() { delete p; } TemplateVariant NamespaceMembersIndexContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct InheritanceGraph: a connected graph representing part of the overall inheritance tree //%% { class InheritanceGraphContext::Private { public: Private(DotGfxHierarchyTable *hierarchy,DotNode *n,int id) : m_hierarchy(hierarchy), m_node(n), m_id(id) { static bool init=FALSE; if (!init) { s_inst.addProperty("graph",&Private::graph); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant graph() const { std::ostringstream t(std::ios_base::ate); static bool haveDot = Config_getBool(HAVE_DOT); static bool graphicalHierarchy = Config_getBool(GRAPHICAL_HIERARCHY); if (haveDot && graphicalHierarchy) { m_hierarchy->createGraph(m_node,t, /*GOF_BITMAP, EOF_Html,*/ g_globals.outputDir, g_globals.outputDir+Portable::pathSeparator()+"inherits"+Doxygen::htmlFileExtension, m_id); } QCString result = t.str(); return TemplateVariant(result.data(),TRUE); } private: DotGfxHierarchyTable *m_hierarchy; DotNode *m_node; int m_id; static PropertyMapper s_inst; }; PropertyMapper InheritanceGraphContext::Private::s_inst; InheritanceGraphContext::InheritanceGraphContext(DotGfxHierarchyTable *hierarchy,DotNode *n,int id) : RefCountedContext("InheritanceGraphContext") { p = new Private(hierarchy,n,id); } InheritanceGraphContext::~InheritanceGraphContext() { delete p; } TemplateVariant InheritanceGraphContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct InheritanceNode: a class in the inheritance list //%% { class InheritanceNodeContext::Private { public: Private(const ClassDef *cd,const QCString &name) : m_classDef(cd), m_name(name) { static bool init=FALSE; if (!init) { s_inst.addProperty("class",&Private::getClass); s_inst.addProperty("name", &Private::name); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant getClass() const { if (!m_classContext) { m_classContext.reset(ClassContext::alloc(m_classDef)); } return m_classContext.get(); } TemplateVariant name() const { return m_name; } private: const ClassDef *m_classDef; mutable SharedPtr m_classContext; QCString m_name; static PropertyMapper s_inst; }; //%% } PropertyMapper InheritanceNodeContext::Private::s_inst; InheritanceNodeContext::InheritanceNodeContext(const ClassDef *cd,const QCString &name) : RefCountedContext("InheritanceNodeContext") { p = new Private(cd,name); } InheritanceNodeContext::~InheritanceNodeContext() { delete p; } TemplateVariant InheritanceNodeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list InheritanceList[InheritanceNode] : list of inherited classes class InheritanceListContext::Private : public GenericNodeListContext { public: void addClass(const ClassDef *cd,const QCString &name) { append(InheritanceNodeContext::alloc(cd,name)); } }; InheritanceListContext::InheritanceListContext(const BaseClassList &list, bool baseClasses) : RefCountedContext("InheritanceListContext") { p = new Private; for (const auto &bcd : list) { const ClassDef *cd=bcd.classDef; QCString name; if (baseClasses) { name = insertTemplateSpecifierInScope( cd->displayName(),bcd.templSpecifiers); } else { name = cd->displayName(); } //printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses); p->addClass(cd,name); } } InheritanceListContext::~InheritanceListContext() { delete p; } // TemplateListIntf uint InheritanceListContext::count() const { return p->count(); } TemplateVariant InheritanceListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *InheritanceListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% list MemberList[Member] : list of inherited classes class MemberListContext::Private : public GenericNodeListContext { public: void addMember(const MemberDef *md) { append(MemberContext::alloc(md)); } }; MemberListContext::MemberListContext() : RefCountedContext("MemberListContext") { p = new Private; } MemberListContext::MemberListContext(const MemberList *list) : RefCountedContext("MemberListContext") { p = new Private; if (list) { bool details = list->listType()&MemberListType_detailedLists; for (const auto &md : *list) { if ((md->isBriefSectionVisible() && !details) || (md->isDetailedSectionLinkable() && details) ) { p->addMember(md); } } } } MemberListContext::MemberListContext(std::vector &&ml) : RefCountedContext("MemberListContext") { p = new Private; for (const auto &md : ml) { p->addMember(md); } ml.clear(); } MemberListContext::~MemberListContext() { delete p; } // TemplateListIntf uint MemberListContext::count() const { return p->count(); } TemplateVariant MemberListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *MemberListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct MemberInfo: member information //%% { class MemberInfoContext::Private { public: Private(const MemberInfo *mi) : m_memberInfo(mi) { static bool init=FALSE; if (!init) { //%% string protection s_inst.addProperty("protection", &Private::protection); //%% string virtualness s_inst.addProperty("virtualness", &Private::virtualness); //%% string ambiguityScope s_inst.addProperty("ambiguityScope",&Private::ambiguityScope); //%% Member member s_inst.addProperty("member", &Private::member); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant protection() const { switch (m_memberInfo->prot()) { case ::Public: return "public"; case ::Protected: return "protected"; case ::Private: return "private"; case ::Package: return "package"; } return ""; } TemplateVariant virtualness() const { switch (m_memberInfo->virt()) { case ::Normal: return "normal"; case ::Virtual: return "virtual"; case ::Pure: return "pure"; } return ""; } TemplateVariant ambiguityScope() const { return m_memberInfo->ambiguityResolutionScope(); } TemplateVariant member() const { if (!m_member && m_memberInfo->memberDef()) { m_member.reset(MemberContext::alloc(m_memberInfo->memberDef())); } if (m_member) { return m_member.get(); } else { return TemplateVariant(FALSE); } } private: const MemberInfo *m_memberInfo; mutable SharedPtr m_member; static PropertyMapper s_inst; }; //%% } PropertyMapper MemberInfoContext::Private::s_inst; MemberInfoContext::MemberInfoContext(const MemberInfo *mi) : RefCountedContext("MemberInfoContext") { p = new Private(mi); } MemberInfoContext::~MemberInfoContext() { delete p; } TemplateVariant MemberInfoContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list AllMembersList[MemberList] : list of inherited classes class AllMembersListContext::Private : public GenericNodeListContext { public: Private(const MemberNameInfoLinkedMap &ml) { static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); for (auto &mni : ml) { for (auto &mi : *mni) { const MemberDef *md=mi->memberDef(); const ClassDef *cd=md->getClassDef(); if (cd && !md->isAnonymous()) { if ((cd->isLinkable() && md->isLinkable()) || (!cd->isArtificial() && !hideUndocMembers && (protectionLevelVisible(md->protection()) || md->isFriend()) ) ) { append(MemberInfoContext::alloc(mi.get())); } } } } } }; AllMembersListContext::AllMembersListContext(const MemberNameInfoLinkedMap &ml) : RefCountedContext("AllMembersListContext") { p = new Private(ml); } AllMembersListContext::~AllMembersListContext() { delete p; } // TemplateListIntf uint AllMembersListContext::count() const { return p->count(); } TemplateVariant AllMembersListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *AllMembersListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct MemberGroupInfo: member group information //%% { class MemberGroupInfoContext::Private { public: Private(const Definition *def,const QCString &relPath,const MemberGroup *mg) : m_def(def), m_relPath(relPath), m_memberGroup(mg) { static bool init=FALSE; if (!init) { s_inst.addProperty("members", &Private::members); s_inst.addProperty("title", &Private::groupTitle); s_inst.addProperty("subtitle", &Private::groupSubtitle); s_inst.addProperty("anchor", &Private::groupAnchor); s_inst.addProperty("memberGroups", &Private::memberGroups); s_inst.addProperty("docs", &Private::docs); s_inst.addProperty("inherited", &Private::inherited); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant members() const { if (!m_cache.memberListContext) { m_cache.memberListContext.reset(MemberListContext::alloc(&m_memberGroup->members())); } return m_cache.memberListContext.get(); } TemplateVariant groupTitle() const { return m_memberGroup->header(); } TemplateVariant groupSubtitle() const { return ""; } TemplateVariant groupAnchor() const { return m_memberGroup->anchor(); } TemplateVariant memberGroups() const { if (!m_cache.memberGroups) { m_cache.memberGroups.reset(MemberGroupListContext::alloc()); } return m_cache.memberGroups.get(); } TemplateVariant docs() const { if (!m_cache.docs) { QCString docs = m_memberGroup->documentation(); if (!docs.isEmpty()) { m_cache.docs.reset(new TemplateVariant( parseDoc(m_def,"[@name docs]",-1, // TODO store file & line m_relPath, m_memberGroup->documentation()+"\n",FALSE))); } else { m_cache.docs.reset(new TemplateVariant("")); } } return *m_cache.docs; } TemplateVariant inherited() const { return FALSE; } private: const Definition *m_def; QCString m_relPath; const MemberGroup *m_memberGroup; struct Cachable { SharedPtr memberListContext; SharedPtr memberGroups; ScopedPtr docs; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper MemberGroupInfoContext::Private::s_inst; MemberGroupInfoContext::MemberGroupInfoContext(const Definition *def, const QCString &relPath,const MemberGroup *mg) : RefCountedContext("MemberGroupInfoContext") { p = new Private(def,relPath,mg); } MemberGroupInfoContext::~MemberGroupInfoContext() { delete p; } TemplateVariant MemberGroupInfoContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list MemberGroupList[MemberGroupInfo] : list of member groups class MemberGroupListContext::Private : public GenericNodeListContext { public: void addMemberGroup(const Definition *def,const QCString &relPath,const MemberGroup *mg) { append(MemberGroupInfoContext::alloc(def,relPath,mg)); } }; MemberGroupListContext::MemberGroupListContext() : RefCountedContext("MemberGroupListContext") { p = new Private; } MemberGroupListContext::MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupRefList &list) : RefCountedContext("MemberGroupListContext") { p = new Private; for (const auto &mg : list) { p->addMemberGroup(def,relPath,mg); } } MemberGroupListContext::MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupList &list,bool subGrouping) : RefCountedContext("MemberGroupListContext") { p = new Private; for (const auto &mg : list) { if (!mg->allMembersInSameSection() || !subGrouping) { p->addMemberGroup(def,relPath,mg.get()); } } } MemberGroupListContext::~MemberGroupListContext() { delete p; } // TemplateListIntf uint MemberGroupListContext::count() const { return p->count(); } TemplateVariant MemberGroupListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *MemberGroupListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct MemberListInfo: member list information //%% { class MemberListInfoContext::Private { public: Private(const Definition *def,const QCString &relPath,const MemberList *ml,const QCString &title,const QCString &subtitle) : m_def(def), m_memberList(ml), m_relPath(relPath), m_title(title), m_subtitle(subtitle) { static bool init=FALSE; if (!init) { s_inst.addProperty("members", &Private::members); s_inst.addProperty("title", &Private::title); s_inst.addProperty("subtitle", &Private::subtitle); s_inst.addProperty("anchor", &Private::anchor); s_inst.addProperty("memberGroups", &Private::memberGroups); s_inst.addProperty("inherited", &Private::inherited); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant members() const { if (!m_cache.memberListContext) { m_cache.memberListContext.reset(MemberListContext::alloc(m_memberList)); } return m_cache.memberListContext.get(); } TemplateVariant title() const { return m_title; } TemplateVariant subtitle() const { return m_subtitle; } TemplateVariant anchor() const { return MemberList::listTypeAsString(m_memberList->listType()); } TemplateVariant memberGroups() const { if (!m_cache.memberGroups) { m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_def,m_relPath,m_memberList->getMemberGroupList())); } return m_cache.memberGroups.get(); } TemplateVariant inherited() const { if (!m_cache.inherited && (m_memberList->listType()&MemberListType_detailedLists)==0 && m_def->definitionType()==Definition::TypeClass) { InheritedMemberInfoListContext *ctx = InheritedMemberInfoListContext::alloc(); ctx->addMemberList(toClassDef(m_def),m_memberList->listType(),m_title,FALSE); m_cache.inherited.reset(ctx); } if (m_cache.inherited) { return m_cache.inherited.get(); } else { return TemplateVariant(FALSE); } } private: const Definition *m_def; const MemberList *m_memberList; QCString m_relPath; QCString m_title; QCString m_subtitle; struct Cachable { SharedPtr memberListContext; SharedPtr memberGroups; SharedPtr inherited; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper MemberListInfoContext::Private::s_inst; MemberListInfoContext::MemberListInfoContext( const Definition *def,const QCString &relPath,const MemberList *ml, const QCString &title,const QCString &subtitle) : RefCountedContext("MemberListInfoContext") { p = new Private(def,relPath,ml,title,subtitle); } MemberListInfoContext::~MemberListInfoContext() { delete p; } TemplateVariant MemberListInfoContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct InheritedMemberInfo: inherited member information //%% { class InheritedMemberInfoContext::Private { public: Private(const ClassDef *cd,const MemberList *ml,const QCString &title) : m_class(cd), m_memberList(ml), m_title(title) { static bool init=FALSE; if (!init) { s_inst.addProperty("class", &Private::getClass); s_inst.addProperty("title", &Private::title); s_inst.addProperty("members", &Private::members); s_inst.addProperty("id", &Private::id); s_inst.addProperty("inheritedFrom", &Private::inheritedFrom); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } virtual ~Private() { delete m_memberList; } TemplateVariant getClass() const { if (!m_classCtx) { m_classCtx.reset(ClassContext::alloc(m_class)); } return m_classCtx.get(); } TemplateVariant title() const { return m_title; } TemplateVariant members() const { if (!m_memberListCtx) { m_memberListCtx.reset(MemberListContext::alloc(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) { m_inheritedFrom.reset(TemplateList::alloc()); m_inheritedFrom->append(title()); m_inheritedFrom->append(getClass()); } return m_inheritedFrom.get(); } private: const ClassDef * m_class; const MemberList *m_memberList; QCString m_title; mutable SharedPtr m_classCtx; mutable SharedPtr m_memberListCtx; mutable SharedPtr m_inheritedFrom; static PropertyMapper s_inst; }; //%% } PropertyMapper InheritedMemberInfoContext::Private::s_inst; InheritedMemberInfoContext::InheritedMemberInfoContext(const ClassDef *cd,const MemberList *ml, const QCString &title) : RefCountedContext("InheritedMemberInfoContext") { 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(const ClassDef *inheritedFrom,const MemberList &ml,MemberList *combinedList) { for (const auto &md : ml) { if (md->isBriefSectionVisible() && !md->isReimplementedBy(inheritedFrom)) { combinedList->push_back(md); } } } void addMemberListIncludingGrouped(const ClassDef *inheritedFrom,const MemberList *ml,MemberList *combinedList) { if (ml) { addMemberList(inheritedFrom,*ml,combinedList); for (const auto *mg : ml->getMemberGroupList()) { addMemberList(inheritedFrom,mg->members(),combinedList); } } } void addMemberGroupsOfClass(const ClassDef *inheritedFrom, const ClassDef *cd,MemberListType lt,MemberList *combinedList) { // TODO: why this there no addMemberGroupsOfNamespace, addMembersGroupsOfFile, // addMemberGroupsOfGroup? for (const auto &mg: cd->getMemberGroups()) { if (!mg->members().empty() && (!mg->allMembersInSameSection() || !cd->subGrouping())) // group is in its own section { for (const auto &md : mg->members()) { if (lt==md->getSectionList(mg->container())->listType() && !md->isReimplementedBy(inheritedFrom) && md->isBriefSectionVisible()) { combinedList->push_back(md); } } } } } void addInheritedMembers(const ClassDef *inheritedFrom,const 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) { const MemberList *ml = cd->getMemberList(lt1); const 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(InheritedMemberInfoContext::alloc(cd,combinedList,title)); } } void findInheritedMembers(const ClassDef *inheritedFrom,const ClassDef *cd,MemberListType lt, int lt2, const QCString &title,bool additionalList, ClassDefSet &visitedClasses) { for (const auto &ibcd : cd->baseClasses()) { 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)==visitedClasses.end()) { visitedClasses.insert(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() : RefCountedContext("InheritedMemberInfoListContext") { p = new Private; } void InheritedMemberInfoListContext::addMemberList( const ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList) { ClassDefSet visited; bool memberInSection = cd->countMembersIncludingGrouped(lt,cd,FALSE)>0; 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 uint InheritedMemberInfoListContext::count() const { return p->count(); } TemplateVariant InheritedMemberInfoListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *InheritedMemberInfoListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct Argument: parameter information //%% { class ArgumentContext::Private { public: Private(const Argument &arg,const Definition *def,const QCString &relPath) : m_argument(arg), m_def(def), m_relPath(relPath) { static bool init=FALSE; if (!init) { s_inst.addProperty("type", &Private::type); s_inst.addProperty("name", &Private::name); s_inst.addProperty("defVal", &Private::defVal); s_inst.addProperty("docs", &Private::docs); s_inst.addProperty("attrib", &Private::attrib); s_inst.addProperty("array", &Private::array); s_inst.addProperty("namePart", &Private::namePart); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant type() const { return createLinkedText(m_def,m_relPath,m_argument.type); } TemplateVariant attrib() const { return m_argument.attrib; } TemplateVariant name() const { return m_argument.name; } TemplateVariant defVal() const { return createLinkedText(m_def,m_relPath,m_argument.defval); } TemplateVariant array() const { return m_argument.array; } TemplateVariant docs() const { if (!m_cache.docs && m_def) { if (!m_argument.docs.isEmpty()) { m_cache.docs.reset(new TemplateVariant( parseDoc(m_def,m_def->docFile(),m_def->docLine(), m_relPath,m_argument.docs,TRUE))); } else { m_cache.docs.reset(new TemplateVariant("")); } } return *m_cache.docs; } TemplateVariant namePart() const { QCString result = m_argument.attrib; uint l = result.length(); if (l>2 && result.at(0)=='[' && result.at(l-1)==']') { result = result.mid(1,l-2); if (result!=",") result+=":"; // for normal keywords add colon } return result; } private: Argument m_argument; const Definition *m_def; QCString m_relPath; struct Cachable { ScopedPtr docs; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper ArgumentContext::Private::s_inst; ArgumentContext::ArgumentContext(const Argument &al,const Definition *def,const QCString &relPath) : RefCountedContext("ArgumentContext") { p = new Private(al,def,relPath); } ArgumentContext::~ArgumentContext() { delete p; } TemplateVariant ArgumentContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list ArgumentList[Argument] : list of inherited classes class ArgumentListContext::Private : public GenericNodeListContext { public: void addArgument(const Argument &arg,const Definition *def,const QCString &relPath) { append(ArgumentContext::alloc(arg,def,relPath)); } }; ArgumentListContext::ArgumentListContext() : RefCountedContext("ArgumentListContext") { p = new Private; } ArgumentListContext::ArgumentListContext(const ArgumentList &list, const Definition *def,const QCString &relPath) : RefCountedContext("ArgumentListContext") { p = new Private; for (const Argument &arg : list) { p->addArgument(arg,def,relPath); } } ArgumentListContext::~ArgumentListContext() { delete p; } // TemplateListIntf uint ArgumentListContext::count() const { return p->count(); } TemplateVariant ArgumentListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *ArgumentListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ // SymbolIndex // - name: string // - letter: string // - symbolGroups: SymbolGroupList // SymbolGroupList: list of SymbolGroups // SymbolGroup // - id // - name // - symbols: SymbolList // SymbolList: list of Symbols // Symbol // - obj // - scope // - relPath //------------------------------------------------------------------------ //%% struct SymbolGroup: search group of similar symbols //%% { class SymbolContext::Private { public: Private(const Definition *d,const Definition *prev, const Definition *next) : m_def(d), m_prevDef(prev), m_nextDef(next) { static bool init=FALSE; if (!init) { s_inst.addProperty("fileName",&Private::fileName); s_inst.addProperty("anchor", &Private::anchor); s_inst.addProperty("scope", &Private::scope); s_inst.addProperty("relPath", &Private::relPath); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant fileName() const { return m_def->getOutputFileBase(); } TemplateVariant anchor() const { return m_def->anchor(); } TemplateVariant scope() const { const Definition *scope = m_def->getOuterScope(); const Definition *next = m_nextDef; const Definition *prev = m_prevDef; const Definition *nextScope = next ? next->getOuterScope() : 0; const Definition *prevScope = prev ? prev->getOuterScope() : 0; const MemberDef *md = toMemberDef(m_def); bool isFunctionLike = md && (md->isFunction() || md->isSlot() || md->isSignal()); bool overloadedFunction = isFunctionLike && ((prevScope!=0 && scope==prevScope) || (scope && scope==nextScope)); QCString prefix; if (md) prefix=md->localName(); if (overloadedFunction) // overloaded member function { prefix+=md->argsString(); // show argument list to disambiguate overloaded functions } else if (md && isFunctionLike) // unique member function { prefix+="()"; // only to show it is a function } bool found=FALSE; QCString name; if (m_def->definitionType()==Definition::TypeClass) { name = m_def->displayName(); found = TRUE; } else if (m_def->definitionType()==Definition::TypeNamespace) { name = m_def->displayName(); found = TRUE; } else if (scope==0 || scope==Doxygen::globalScope) // in global scope { if (md) { const FileDef *fd = md->getBodyDef(); if (fd==0) fd = md->getFileDef(); if (fd) { if (!prefix.isEmpty()) prefix+=": "; name = prefix + convertToXML(fd->localName()); found = TRUE; } } } else if (md && (md->getClassDef() || md->getNamespaceDef())) // member in class or namespace scope { SrcLangExt lang = md->getLanguage(); name = m_def->getOuterScope()->qualifiedName() + getLanguageSpecificSeparator(lang) + prefix; found = TRUE; } else if (scope) // some thing else? -> show scope { name = prefix + convertToXML(scope->name()); found = TRUE; } if (!found) // fallback { name = prefix + "("+theTranslator->trGlobalNamespace()+")"; } return name; } TemplateVariant relPath() const { return externalRef("../",m_def->getReference(),TRUE); } private: const Definition *m_def; const Definition *m_prevDef; const Definition *m_nextDef; static PropertyMapper s_inst; }; //%% } PropertyMapper SymbolContext::Private::s_inst; SymbolContext::SymbolContext(const Definition *def,const Definition *prevDef,const Definition *nextDef) : RefCountedContext("SymbolContext") { p = new Private(def,prevDef,nextDef); } SymbolContext::~SymbolContext() { delete p; } TemplateVariant SymbolContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list SymbolList[Symbol] : list of search symbols with the same name class SymbolListContext::Private : public GenericNodeListContext { public: Private(const SearchIndexList::const_iterator &start, const SearchIndexList::const_iterator &end) { const Definition *prev = 0; for (auto it = start; it!=end;) { const Definition *def = *it; ++it; const Definition *next = it!=end ? *it : 0; append(SymbolContext::alloc(def,prev,next)); prev = def; } } }; SymbolListContext::SymbolListContext(const SearchIndexList::const_iterator &start, const SearchIndexList::const_iterator &end) : RefCountedContext("SymbolListContext") { p = new Private(start,end); } SymbolListContext::~SymbolListContext() { delete p; } // TemplateListIntf uint SymbolListContext::count() const { return p->count(); } TemplateVariant SymbolListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *SymbolListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct SymbolGroup: search group of similar symbols //%% { class SymbolGroupContext::Private { public: Private(const SearchIndexList::const_iterator &start, const SearchIndexList::const_iterator &end) : m_start(start), m_end(end) { static bool init=FALSE; if (!init) { s_inst.addProperty("id", &Private::id); s_inst.addProperty("name", &Private::name); s_inst.addProperty("symbols",&Private::symbolList); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant id() const { return searchId(*m_start); } TemplateVariant name() const { return searchName(*m_start); } TemplateVariant symbolList() const { if (!m_cache.symbolList) { m_cache.symbolList.reset(SymbolListContext::alloc(m_start,m_end)); } return m_cache.symbolList.get(); } private: SearchIndexList::const_iterator m_start; SearchIndexList::const_iterator m_end; struct Cachable { SharedPtr symbolList; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper SymbolGroupContext::Private::s_inst; SymbolGroupContext::SymbolGroupContext(const SearchIndexList::const_iterator &start, const SearchIndexList::const_iterator &end) : RefCountedContext("SymbolGroupContext") { p = new Private(start,end); } SymbolGroupContext::~SymbolGroupContext() { delete p; } TemplateVariant SymbolGroupContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list SymbolGroupList[SymbolGroup] : list of search groups one per by name class SymbolGroupListContext::Private : public GenericNodeListContext { public: Private(const SearchIndexList &sil) { QCString lastName; auto it = sil.begin(); auto it_begin = it; while (it!=sil.end()) { QCString name = searchName(*it); if (name!=lastName) { append(SymbolGroupContext::alloc(it_begin,it)); it_begin = it; lastName = name; } ++it; } if (it_begin!=sil.end()) { append(SymbolGroupContext::alloc(it_begin,sil.end())); } } }; SymbolGroupListContext::SymbolGroupListContext(const SearchIndexList &sil) : RefCountedContext("SymbolGroupListContext") { p = new Private(sil); } SymbolGroupListContext::~SymbolGroupListContext() { delete p; } // TemplateListIntf uint SymbolGroupListContext::count() const { return p->count(); } TemplateVariant SymbolGroupListContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *SymbolGroupListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct SymbolIndex: search index //%% { class SymbolIndexContext::Private { public: Private(const std::string &letter, const SearchIndexList &sl, const QCString &name) : m_letter(letter), m_searchList(sl), m_name(name) { static bool init=FALSE; if (!init) { s_inst.addProperty("name", &Private::name); s_inst.addProperty("letter", &Private::letter); s_inst.addProperty("symbolGroups",&Private::symbolGroups); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant name() const { return m_name; } TemplateVariant letter() const { return m_letter; } TemplateVariant symbolGroups() const { if (!m_cache.symbolGroups) { m_cache.symbolGroups.reset(SymbolGroupListContext::alloc(m_searchList)); } return m_cache.symbolGroups.get(); } private: QCString m_letter; const SearchIndexList &m_searchList; QCString m_name; struct Cachable { SharedPtr symbolGroups; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper SymbolIndexContext::Private::s_inst; SymbolIndexContext::SymbolIndexContext(const std::string &letter,const SearchIndexList &sl,const QCString &name) : RefCountedContext("SymbolIndexContext") { p = new Private(letter,sl,name); } SymbolIndexContext::~SymbolIndexContext() { delete p; } TemplateVariant SymbolIndexContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list SymbolIndices[SymbolIndex] : list of search indices one per by type class SymbolIndicesContext::Private : public GenericNodeListContext { public: Private(const SearchIndexInfo &info) { // use info->symbolList to populate the list for (const auto &kv : info.symbolMap) { append(SymbolIndexContext::alloc(kv.first,kv.second,info.name)); } } }; SymbolIndicesContext::SymbolIndicesContext(const SearchIndexInfo &info) : RefCountedContext("SymbolIndicesContext") { p = new Private(info); } SymbolIndicesContext::~SymbolIndicesContext() { delete p; } // TemplateListIntf uint SymbolIndicesContext::count() const { return p->count(); } TemplateVariant SymbolIndicesContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *SymbolIndicesContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct SearchIndex: search index //%% { class SearchIndexContext::Private { public: Private(const SearchIndexInfo &info) : m_info(info) { static bool init=FALSE; if (!init) { s_inst.addProperty("name", &Private::name); s_inst.addProperty("text", &Private::text); s_inst.addProperty("symbolIndices",&Private::symbolIndices); init=TRUE; } } TemplateVariant get(const char *n) const { return s_inst.get(this,n); } TemplateVariant name() const { return m_info.name; } TemplateVariant text() const { return m_info.getText(); } TemplateVariant symbolIndices() const { if (!m_cache.symbolIndices) { m_cache.symbolIndices.reset(SymbolIndicesContext::alloc(m_info)); } return m_cache.symbolIndices.get(); } private: const SearchIndexInfo &m_info; struct Cachable { SharedPtr symbolIndices; }; mutable Cachable m_cache; static PropertyMapper s_inst; }; //%% } PropertyMapper SearchIndexContext::Private::s_inst; SearchIndexContext::SearchIndexContext(const SearchIndexInfo &info) : RefCountedContext("SearchIndexContext") { p = new Private(info); } SearchIndexContext::~SearchIndexContext() { delete p; } TemplateVariant SearchIndexContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list SearchIndices[SearchIndex] : list of search indices one per by type class SearchIndicesContext::Private : public GenericNodeListContext { public: Private() { for (const auto &si : getSearchIndices()) { append(SearchIndexContext::alloc(si)); } } }; SearchIndicesContext::SearchIndicesContext() : RefCountedContext("SearchIndicesContext") { p = new Private; } SearchIndicesContext::~SearchIndicesContext() { delete p; } // TemplateListIntf uint SearchIndicesContext::count() const { return p->count(); } TemplateVariant SearchIndicesContext::at(uint index) const { return p->at(index); } TemplateListIntf::ConstIterator *SearchIndicesContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ class HtmlEscaper : public TemplateEscapeIntf { public: QCString escape(const QCString &s) { return convertToHtml(s,TRUE); } void enableTabbing(bool) {} }; //------------------------------------------------------------------------ class LatexSpaceless : public TemplateSpacelessIntf { public: LatexSpaceless() { reset(); } void reset() { } QCString remove(const QCString &s) { std::ostringstream result(std::ios_base::ate); const char *p = s.data(); char c; while ((c=*p++)) { switch(c) { case '\t': case ' ': case '\n': break; default: result << c; break; } } return result.str(); } private: }; //------------------------------------------------------------------------ class HtmlSpaceless : public TemplateSpacelessIntf { public: HtmlSpaceless() { reset(); } void reset() { m_insideTag = FALSE; m_insideString = '\0'; m_removeSpaces = TRUE; } QCString remove(const QCString &s) { std::ostringstream result(std::ios_base::ate); const char *p = s.data(); char c; while ((c=*p++)) { switch(c) { case '<': // start of a tag if (!m_insideString) m_insideTag=TRUE,m_removeSpaces=FALSE; result << c; break; case '>': // end of a tag if (!m_insideString) m_insideTag=FALSE,m_removeSpaces=TRUE; result << c; break; case '\\': // escaped character in a string result << c; if (m_insideString && *p) result << *p++; break; case '"': case '\'': if (m_insideTag) { if (m_insideString==c) // end of string { m_insideString='\0'; } else if (m_insideString=='\0') // start of string { m_insideString=c; } } result << c; break; case ' ': case '\t': case '\n': // whitespace if (!m_insideTag) // outside tags strip consecutive whitespace { m_removeSpaces=TRUE; } else { result << ' '; } break; default: //if (m_removeSpaces) result+=' '; result << c; m_removeSpaces=FALSE; break; } } //printf("HtmlSpaceless::remove({%s})={%s} m_insideTag=%d m_insideString=%c (%d) removeSpaces=%d\n",s.data(),result.data(), // m_insideTag,m_insideString,m_insideString,m_removeSpaces); return result.str(); } private: bool m_insideTag; char m_insideString; bool m_removeSpaces; }; //------------------------------------------------------------------------ class LatexEscaper : public TemplateEscapeIntf { public: LatexEscaper() : m_tabbing(FALSE) {} QCString escape(const QCString &s) { return convertToLaTeX(s,m_tabbing); } void enableTabbing(bool b) { m_tabbing=b; } private: bool m_tabbing; }; //------------------------------------------------------------------------ #if DEBUG_REF int RefCountedContext::s_totalCount; #endif void generateOutputViaTemplate() { msg("Generating output via template engine...\n"); { TemplateEngine e; TemplateContext *ctx = e.createContext(); if (ctx) { SharedPtr doxygen (DoxygenContext::alloc()); SharedPtr config (ConfigContext::alloc()); SharedPtr tr (TranslateContext::alloc()); SharedPtr classList (ClassListContext::alloc()); SharedPtr classIndex (ClassIndexContext::alloc()); SharedPtr classTree (ClassTreeContext::alloc()); SharedPtr classHierarchy (ClassHierarchyContext::alloc()); SharedPtr namespaceList (NamespaceListContext::alloc()); SharedPtr namespaceTree (NamespaceTreeContext::alloc()); SharedPtr dirList (DirListContext::alloc()); SharedPtr fileList (FileListContext::alloc()); SharedPtr fileTree (FileTreeContext::alloc()); SharedPtr pageTree (PageTreeContext::alloc(*Doxygen::pageLinkedMap)); SharedPtr pageList (PageListContext::alloc(*Doxygen::pageLinkedMap)); SharedPtr exampleTree (ExampleTreeContext::alloc()); SharedPtr exampleList (ExampleListContext::alloc()); SharedPtr moduleTree (ModuleTreeContext::alloc()); SharedPtr moduleList (ModuleListContext::alloc()); SharedPtr globalsIndex (GlobalsIndexContext::alloc()); SharedPtr classMembersIndex (ClassMembersIndexContext::alloc()); SharedPtr namespaceMembersIndex(NamespaceMembersIndexContext::alloc()); SharedPtr searchIndices (SearchIndicesContext::alloc()); //%% Doxygen doxygen: ctx->set("doxygen",doxygen.get()); //%% Translator tr: ctx->set("tr",tr.get()); //%% Config config: ctx->set("config",config.get()); //%% ClassList classList: ctx->set("classList",classList.get()); // not used for standard HTML //%% ClassTree classTree: ctx->set("classTree",classTree.get()); //%% ClassIndex classIndex: ctx->set("classIndex",classIndex.get()); //%% ClassHierarchy classHierarchy: ctx->set("classHierarchy",classHierarchy.get()); //%% NamespaceList namespaceList: ctx->set("namespaceList",namespaceList.get()); //%% NamespaceTree namespaceTree: ctx->set("namespaceTree",namespaceTree.get()); //%% FileList fileList: ctx->set("fileList",fileList.get()); //%% FileTree fileTree: ctx->set("fileTree",fileTree.get()); //%% PageList pageList ctx->set("pageList",pageList.get()); //%% PageTree pageTree ctx->set("pageTree",pageTree.get()); //%% ExampleTree exampleTree ctx->set("exampleTree",exampleTree.get()); //%% ExampleList exampleList ctx->set("exampleList",exampleList.get()); //%% ModuleTree moduleTree ctx->set("moduleTree",moduleTree.get()); //%% ModuleList moduleList ctx->set("moduleList",moduleList.get()); //%% DirList dirList ctx->set("dirList",dirList.get()); //%% Page mainPage if (Doxygen::mainPage) { SharedPtr mainPage(PageContext::alloc(Doxygen::mainPage.get(),TRUE,FALSE)); ctx->set("mainPage",mainPage.get()); } else { // TODO: for LaTeX output index should be main... => solve in template Doxygen::mainPage.reset(createPageDef("[generated]",1,"index","",theTranslator->trMainPage())); Doxygen::mainPage->setFileName("index"); SharedPtr mainPage(PageContext::alloc(Doxygen::mainPage.get(),TRUE,FALSE)); ctx->set("mainPage",mainPage.get()); } //%% GlobalsIndex globalsIndex: ctx->set("globalsIndex",globalsIndex.get()); //%% ClassMembersIndex classMembersIndex: ctx->set("classMembersIndex",classMembersIndex.get()); //%% NamespaceMembersIndex namespaceMembersIndex: ctx->set("namespaceMembersIndex",namespaceMembersIndex.get()); //%% SearchIndices searchIndices ctx->set("searchIndices",searchIndices.get()); //%% string space ctx->set("space"," "); //if (Config_getBool(GENERATE_HTML)) { // render HTML output e.setTemplateDir("templates/html"); // TODO: make template part user configurable Template *tpl = e.loadByName("htmllayout.tpl",1); if (tpl) { g_globals.outputFormat = ContextOutputFormat_Html; g_globals.dynSectionId = 0; g_globals.outputDir = Config_getString(HTML_OUTPUT); Dir dir(g_globals.outputDir.str()); createSubDirs(dir); HtmlEscaper htmlEsc; ctx->setEscapeIntf(Config_getString(HTML_FILE_EXTENSION),&htmlEsc); HtmlSpaceless spl; ctx->setSpacelessIntf(&spl); ctx->setOutputDirectory(g_globals.outputDir); std::ostringstream ts(std::ios_base::ate); tpl->render(ts,ctx); e.unload(tpl); } } // TODO: clean index before each run... //if (Config_getBool(GENERATE_LATEX)) if (0) { // render LaTeX output e.setTemplateDir("templates/latex"); // TODO: make template part user configurable Template *tpl = e.loadByName("latexlayout.tpl",1); if (tpl) { g_globals.outputFormat = ContextOutputFormat_Latex; g_globals.dynSectionId = 0; g_globals.outputDir = Config_getString(LATEX_OUTPUT); Dir dir(g_globals.outputDir.str()); createSubDirs(dir); LatexEscaper latexEsc; ctx->setEscapeIntf(".tex",&latexEsc); LatexSpaceless spl; ctx->setSpacelessIntf(&spl); ctx->setOutputDirectory(g_globals.outputDir); std::ostringstream ts(std::ios_base::ate); tpl->render(ts,ctx); e.unload(tpl); } } // clear all cached data in Definition objects. for (const auto &kv : Doxygen::symbolMap) { kv.second->setCookie(0); } e.destroyContext(ctx); } } #if DEBUG_REF // should be 0, i.e. all objects are deleted printf("==== total ref count %d\n",RefCountedContext::s_totalCount); #endif } void generateTemplateFiles(const char *templateDir) { if (!templateDir) return; Dir thisDir; if (!thisDir.exists(templateDir) && !thisDir.mkdir(templateDir)) { err("Failed to create output directory '%s'\n",templateDir); return; } std::string outDir = std::string(templateDir)+"/html"; if (!thisDir.exists(outDir) && !thisDir.mkdir(outDir)) { err("Failed to create output directory '%s'\n",outDir.c_str()); return; } ResourceMgr::instance().writeCategory("html",outDir.c_str()); }