1 /******************************************************************************
5 * Copyright (C) 1997-2014 by Dimitri van Heesch.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
22 #include "classlist.h"
25 #include "membername.h"
33 #include "outputlist.h"
37 #include "docparser.h"
38 #include "searchindex.h"
39 #include "vhdldocgen.h"
41 #include "arguments.h"
42 #include "memberlist.h"
45 #include "namespacedef.h"
46 #include "membergroup.h"
48 //-----------------------------------------------------------------------------
50 /** Private data associated with a ClassDef object. */
56 void init(const char *defFileName, const char *name,
57 const QCString &ctStr, const char *fName);
59 /*! file name that forms the base for the output file containing the
60 * class documentation. For compatibility with Qt (e.g. links via tag
61 * files) this name cannot be derived from the class name directly.
65 /*! Include information about the header file should be included
66 * in the documentation. 0 by default, set by setIncludeFile().
70 /*! List of base class (or super-classes) from which this class derives
73 BaseClassList *inherits;
75 /*! List of sub-classes that directly derive from this class
77 BaseClassList *inheritedBy;
79 /*! Namespace this class is part of
80 * (this is the inner most namespace in case of nested namespaces)
84 /*! File this class is defined in */
87 /*! List of all members (including inherited members) */
88 MemberNameInfoSDict *allMemberNameInfoSDict;
90 /*! Template arguments of this class */
91 ArgumentList *tempArgs;
93 /*! Type constraints for template parameters */
94 ArgumentList *typeConstraints;
96 /*! Files that were used for generating the class documentation. */
99 /*! Examples that use this class */
100 ExampleSDict *exampleSDict;
102 /*! Holds the kind of "class" this is. */
103 ClassDef::CompoundType compType;
105 /*! The protection level in which this class was found.
106 * Typically Public, but for nested classes this can also be Protected
111 /*! The inner classes contained in this class. Will be 0 if there are
114 ClassSDict *innerClasses;
116 /* classes for the collaboration diagram */
117 UsesClassDict *usesImplClassDict;
118 UsesClassDict *usedByImplClassDict;
119 UsesClassDict *usesIntfClassDict;
121 /*! Template instances that exists of this class, the key in the
122 * dictionary is the template argument list.
124 QDict<ClassDef> *templateInstances;
126 /*! Template instances that exists of this class, as defined by variables.
127 * We do NOT want to document these individually. The key in the
128 * dictionary is the template argument list.
130 QDict<ClassDef> *variableInstances;
132 QDict<int> *templBaseClassNames;
134 /*! The class this class is an instance of. */
135 ClassDef *templateMaster;
137 /*! local class name which could be a typedef'ed alias name. */
140 /*! If this class is a Objective-C category, then this points to the
141 * class which is extended.
143 ClassDef *categoryOf;
145 QList<MemberList> memberLists;
147 /* user defined member groups */
148 MemberGroupSDict *memberGroupSDict;
150 /*! Is this an abstact class? */
153 /*! Is the class part of an unnamed namespace? */
156 /*! TRUE if classes members are merged with those of the base classes. */
159 /*! TRUE if the class is defined in a source file rather than a header file. */
164 /*! Does this class group its user-grouped members
165 * as a sub-section of the normal (public/protected/..)
170 /** Reason of existence is a "use" relation */
173 /** List of titles to use for the summary */
174 SDict<QCString> vhdlSummaryTitles;
176 /** Is this a simple (non-nested) C structure? */
179 /** Does this class overloaded the -> operator? */
180 MemberDef *arrowOperator;
182 ClassList *taggedInnerClasses;
183 ClassDef *tagLessRef;
185 /** Does this class represent a Java style enum? */
195 void ClassDefImpl::init(const char *defFileName, const char *name,
196 const QCString &ctStr, const char *fName)
200 fileName=stripExtension(fName);
209 allMemberNameInfoSDict = 0;
217 usedByImplClassDict=0;
219 memberGroupSDict = 0;
221 subGrouping=Config_getBool("SUBGROUPING");
222 templateInstances = 0;
223 variableInstances = 0;
225 templBaseClassNames = 0;
229 membersMerged = FALSE;
232 isSimple = Config_getBool("INLINE_SIMPLE_STRUCTS");
234 taggedInnerClasses = 0;
238 //extractNamespaceName(name,className,ns);
239 //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());
241 // we cannot use getLanguage at this point, as setLanguage has not been called.
242 SrcLangExt lang = getLanguageFromFileName(defFileName);
243 if ((lang==SrcLangExt_Cpp || lang==SrcLangExt_ObjC) &&
244 guessSection(defFileName)==Entry::SOURCE_SEC)
252 isGeneric = (lang==SrcLangExt_CSharp || lang==SrcLangExt_Java) && QCString(name).find('<')!=-1;
253 isAnonymous = QCString(name).find('@')!=-1;
256 ClassDefImpl::ClassDefImpl() : vhdlSummaryTitles(17)
258 vhdlSummaryTitles.setAutoDelete(TRUE);
261 ClassDefImpl::~ClassDefImpl()
265 delete allMemberNameInfoSDict;
267 delete usesImplClassDict;
268 delete usedByImplClassDict;
269 delete usesIntfClassDict;
271 delete memberGroupSDict;
273 delete templateInstances;
274 delete variableInstances;
275 delete templBaseClassNames;
277 delete typeConstraints;
278 delete taggedInnerClasses;
281 // constructs a new class definition
283 const char *defFileName,int defLine,int defColumn,
284 const char *nm,CompoundType ct,
285 const char *lref,const char *fName,
286 bool isSymbol,bool isJavaEnum)
287 : Definition(defFileName,defLine,defColumn,removeRedundantWhiteSpace(nm),0,0,isSymbol)
291 m_impl = new ClassDefImpl;
292 m_impl->compType = ct;
293 m_impl->isJavaEnum = isJavaEnum;
294 m_impl->init(defFileName,name(),compoundTypeString(),fName);
297 // destroy the class definition
298 ClassDef::~ClassDef()
303 QCString ClassDef::getMemberListFileName() const
305 return convertNameToFile(compoundTypeString()+name()+"-members");
308 QCString ClassDef::displayName(bool includeScope) const
310 //static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
311 SrcLangExt lang = getLanguage();
312 //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
314 if (lang==SrcLangExt_VHDL)
316 n = VhdlDocGen::getClassName(this);
322 n=qualifiedNameWithTemplateParameters();
329 QCString sep=getLanguageSpecificSeparator(lang);
332 n=substitute(n,"::",sep);
334 if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p")
336 n="<"+n.left(n.length()-2)+">";
338 //else if (n.right(2)=="-g")
340 // n = n.left(n.length()-2);
342 //printf("ClassDef::displayName()=%s\n",n.data());
345 return removeAnonymousScopes(n);
353 // inserts a base/super class in the inheritance list
354 void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p,
355 Specifier s,const char *t)
357 //printf("*** insert base class %s into %s\n",cd->name().data(),name().data());
358 //inherits->inSort(new BaseClassDef(cd,p,s,t));
359 if (m_impl->inherits==0)
361 m_impl->inherits = new BaseClassList;
362 m_impl->inherits->setAutoDelete(TRUE);
364 m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
365 m_impl->isSimple = FALSE;
368 // inserts a derived/sub class in the inherited-by list
369 void ClassDef::insertSubClass(ClassDef *cd,Protection p,
370 Specifier s,const char *t)
372 //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());
373 static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
374 if (!extractPrivate && cd->protection()==Private) return;
375 if (m_impl->inheritedBy==0)
377 m_impl->inheritedBy = new BaseClassList;
378 m_impl->inheritedBy->setAutoDelete(TRUE);
380 m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));
381 m_impl->isSimple = FALSE;
384 void ClassDef::addMembersToMemberGroup()
386 QListIterator<MemberList> mli(m_impl->memberLists);
388 for (mli.toFirst();(ml=mli.current());++mli)
390 if ((ml->listType()&MemberListType_detailedLists)==0)
392 ::addMembersToMemberGroup(ml,&m_impl->memberGroupSDict,this);
396 // add members inside sections to their groups
397 if (m_impl->memberGroupSDict)
399 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
401 for (;(mg=mgli.current());++mgli)
403 if (mg->allMembersInSameSection() && m_impl->subGrouping)
405 //printf("addToDeclarationSection(%s)\n",mg->header().data());
406 mg->addToDeclarationSection();
412 // adds new member definition to the class
413 void ClassDef::internalInsertMember(MemberDef *md,
418 //printf("insertInternalMember(%s) isHidden()=%d\n",md->name().data(),md->isHidden());
419 if (md->isHidden()) return;
421 if (getLanguage()==SrcLangExt_VHDL)
423 QCString title=VhdlDocGen::trVhdlType(md->getMemberSpecifiers(),FALSE);
424 if (!m_impl->vhdlSummaryTitles.find(title))
426 m_impl->vhdlSummaryTitles.append(title,new QCString(title));
430 if (1 /*!isReference()*/) // changed to 1 for showing members of external
431 // classes when HAVE_DOT and UML_LOOK are enabled.
435 /********************************************/
436 /* insert member in the declaration section */
437 /********************************************/
438 if (md->isRelated() && protectionLevelVisible(prot))
440 addMemberToList(MemberListType_related,md,TRUE);
442 else if (md->isFriend())
444 addMemberToList(MemberListType_friends,md,TRUE);
448 switch (md->memberType())
450 case MemberType_Service: // UNO IDL
451 addMemberToList(MemberListType_services,md,TRUE);
453 case MemberType_Interface: // UNO IDL
454 addMemberToList(MemberListType_interfaces,md,TRUE);
456 case MemberType_Signal: // Qt specific
457 addMemberToList(MemberListType_signals,md,TRUE);
459 case MemberType_DCOP: // KDE2 specific
460 addMemberToList(MemberListType_dcopMethods,md,TRUE);
462 case MemberType_Property:
463 addMemberToList(MemberListType_properties,md,TRUE);
465 case MemberType_Event:
466 addMemberToList(MemberListType_events,md,TRUE);
468 case MemberType_Slot: // Qt specific
472 case Package: // slots in packages are not possible!
473 addMemberToList(MemberListType_proSlots,md,TRUE);
476 addMemberToList(MemberListType_pubSlots,md,TRUE);
479 addMemberToList(MemberListType_priSlots,md,TRUE);
483 default: // any of the other members
486 if (md->isVariable())
491 addMemberToList(MemberListType_proStaticAttribs,md,TRUE);
494 addMemberToList(MemberListType_pacStaticAttribs,md,TRUE);
497 addMemberToList(MemberListType_pubStaticAttribs,md,TRUE);
500 addMemberToList(MemberListType_priStaticAttribs,md,TRUE);
509 addMemberToList(MemberListType_proStaticMethods,md,TRUE);
512 addMemberToList(MemberListType_pacStaticMethods,md,TRUE);
515 addMemberToList(MemberListType_pubStaticMethods,md,TRUE);
518 addMemberToList(MemberListType_priStaticMethods,md,TRUE);
525 if (md->isVariable())
530 addMemberToList(MemberListType_proAttribs,md,TRUE);
533 addMemberToList(MemberListType_pacAttribs,md,TRUE);
536 addMemberToList(MemberListType_pubAttribs,md,TRUE);
537 isSimple=!md->isFunctionPtr();
540 addMemberToList(MemberListType_priAttribs,md,TRUE);
544 else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())
549 addMemberToList(MemberListType_proTypes,md,TRUE);
552 addMemberToList(MemberListType_pacTypes,md,TRUE);
555 addMemberToList(MemberListType_pubTypes,md,TRUE);
556 isSimple=QCString(md->typeString()).find(")(")==-1;
559 addMemberToList(MemberListType_priTypes,md,TRUE);
563 else // member function
568 addMemberToList(MemberListType_proMethods,md,TRUE);
571 addMemberToList(MemberListType_pacMethods,md,TRUE);
574 addMemberToList(MemberListType_pubMethods,md,TRUE);
577 addMemberToList(MemberListType_priMethods,md,TRUE);
585 if (!isSimple) // not a simple field -> not a simple struct
587 m_impl->isSimple = FALSE;
589 //printf("adding %s simple=%d total_simple=%d\n",name().data(),isSimple,m_impl->isSimple);
591 /*******************************************************/
592 /* insert member in the detailed documentation section */
593 /*******************************************************/
594 if ((md->isRelated() && protectionLevelVisible(prot)) || md->isFriend())
596 addMemberToList(MemberListType_relatedMembers,md,FALSE);
600 switch (md->memberType())
602 case MemberType_Service: // UNO IDL
603 addMemberToList(MemberListType_serviceMembers,md,FALSE);
605 case MemberType_Interface: // UNO IDL
606 addMemberToList(MemberListType_interfaceMembers,md,FALSE);
608 case MemberType_Property:
609 addMemberToList(MemberListType_propertyMembers,md,FALSE);
611 case MemberType_Event:
612 addMemberToList(MemberListType_eventMembers,md,FALSE);
614 case MemberType_Signal: // fall through
615 case MemberType_DCOP:
616 addMemberToList(MemberListType_functionMembers,md,FALSE);
618 case MemberType_Slot:
619 if (protectionLevelVisible(prot))
621 addMemberToList(MemberListType_functionMembers,md,FALSE);
624 default: // any of the other members
625 if (protectionLevelVisible(prot))
627 switch (md->memberType())
629 case MemberType_Typedef:
630 addMemberToList(MemberListType_typedefMembers,md,FALSE);
632 case MemberType_Enumeration:
633 addMemberToList(MemberListType_enumMembers,md,FALSE);
635 case MemberType_EnumValue:
636 addMemberToList(MemberListType_enumValMembers,md,FALSE);
638 case MemberType_Function:
639 if (md->isConstructor() || md->isDestructor())
641 MemberList *ml = createMemberList(MemberListType_constructors);
646 addMemberToList(MemberListType_functionMembers,md,FALSE);
649 case MemberType_Variable:
650 addMemberToList(MemberListType_variableMembers,md,FALSE);
653 err("Unexpected member type %d found!\n",md->memberType());
660 /*************************************************/
661 /* insert member in the appropriate member group */
662 /*************************************************/
663 // Note: this must be done AFTER inserting the member in the
665 //addMemberToGroup(md,groupId);
669 if (md->virtualness()==Pure)
671 m_impl->isAbstract=TRUE;
674 if (md->name()=="operator->")
676 m_impl->arrowOperator=md;
679 //::addClassMemberNameToIndex(md);
681 !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
683 (QCString(md->typeString())=="friend class" ||
684 QCString(md->typeString())=="friend struct" ||
685 QCString(md->typeString())=="friend union")))
687 //printf("=======> adding member %s to class %s\n",md->name().data(),name().data());
688 MemberInfo *mi = new MemberInfo((MemberDef *)md,
689 prot,md->virtualness(),FALSE);
690 MemberNameInfo *mni=0;
691 if (m_impl->allMemberNameInfoSDict==0)
693 m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
694 m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
696 if ((mni=m_impl->allMemberNameInfoSDict->find(md->name())))
702 mni = new MemberNameInfo(md->name());
704 m_impl->allMemberNameInfoSDict->append(mni->memberName(),mni);
709 void ClassDef::insertMember(MemberDef *md)
711 internalInsertMember(md,md->protection(),TRUE);
714 // compute the anchors for all members
715 void ClassDef::computeAnchors()
717 //ClassDef *context = Config_getBool("INLINE_INHERITED_MEMB") ? this : 0;
718 //const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";
719 QListIterator<MemberList> mli(m_impl->memberLists);
722 for (mli.toFirst();(ml=mli.current());++mli)
724 if ((ml->listType()&MemberListType_detailedLists)==0)
730 if (m_impl->memberGroupSDict)
732 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
734 for (;(mg=mgli.current());++mgli)
741 void ClassDef::distributeMemberGroupDocumentation()
743 if (m_impl->memberGroupSDict)
745 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
747 for (;(mg=mgli.current());++mgli)
749 mg->distributeMemberGroupDocumentation();
754 void ClassDef::findSectionsInDocumentation()
756 docFindSections(documentation(),this,0,docFile());
757 if (m_impl->memberGroupSDict)
759 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
761 for (;(mg=mgli.current());++mgli)
763 mg->findSectionsInDocumentation();
766 QListIterator<MemberList> mli(m_impl->memberLists);
768 for (mli.toFirst();(ml=mli.current());++mli)
770 if ((ml->listType()&MemberListType_detailedLists)==0)
772 ml->findSectionsInDocumentation();
778 // add a file name to the used files set
779 void ClassDef::insertUsedFile(FileDef *fd)
782 if (m_impl->files.find(fd)==-1) m_impl->files.append(fd);
783 if (m_impl->templateInstances)
785 QDictIterator<ClassDef> qdi(*m_impl->templateInstances);
787 for (qdi.toFirst();(cd=qdi.current());++qdi)
789 cd->insertUsedFile(fd);
794 static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd)
796 if (bcd->prot!=Public || bcd->virt!=Normal)
798 ol.startTypewriter();
801 if (bcd->prot==Protected) sl.append("protected");
802 else if (bcd->prot==Private) sl.append("private");
803 if (bcd->virt==Virtual) sl.append("virtual");
804 const char *s=sl.first();
809 if (s) ol.docify(", ");
816 void ClassDef::setIncludeFile(FileDef *fd,
817 const char *includeName,bool local, bool force)
819 //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);
820 if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo;
821 if ((includeName && m_impl->incInfo->includeName.isEmpty()) ||
822 (fd!=0 && m_impl->incInfo->fileDef==0)
825 //printf("Setting file info\n");
826 m_impl->incInfo->fileDef = fd;
827 m_impl->incInfo->includeName = includeName;
828 m_impl->incInfo->local = local;
830 if (force && includeName)
832 m_impl->incInfo->includeName = includeName;
833 m_impl->incInfo->local = local;
837 // TODO: fix this: a nested template class can have multiple outer templates
838 //ArgumentList *ClassDef::outerTemplateArguments() const
843 // if (m_impl->tempArgs) return m_impl->tempArgs;
844 // // find the outer most class scope
845 // while ((ti=name().find("::",pi))!=-1 &&
846 // (pcd=getClass(name().left(ti)))==0
850 // return pcd->templateArguments();
855 static void searchTemplateSpecs(/*in*/ Definition *d,
856 /*out*/ QList<ArgumentList> &result,
857 /*out*/ QCString &name)
859 if (d->definitionType()==Definition::TypeClass)
861 if (d->getOuterScope())
863 searchTemplateSpecs(d->getOuterScope(),result,name);
865 ClassDef *cd=(ClassDef *)d;
866 if (!name.isEmpty()) name+="::";
867 QCString clName = d->localName();
868 if (/*clName.right(2)=="-g" ||*/ clName.right(2)=="-p")
870 clName = clName.left(clName.length()-2);
873 bool isSpecialization = d->localName().find('<')!=-1;
874 if (cd->templateArguments())
876 result.append(cd->templateArguments());
877 if (!isSpecialization)
879 name+=tempArgListToString(cd->templateArguments());
885 name+=d->qualifiedName();
889 static void writeTemplateSpec(OutputList &ol,Definition *d,
890 const QCString &type)
892 QList<ArgumentList> specs;
894 searchTemplateSpecs(d,specs,name);
895 if (specs.count()>0) // class has template scope specifiers
897 ol.startSubsubsection();
898 QListIterator<ArgumentList> spi(specs);
900 for (spi.toFirst();(al=spi.current());++spi)
902 ol.docify("template<");
903 QListIterator<Argument> ali(*al);
905 while ((a=ali.current()))
908 if (!a->name.isEmpty())
913 if (a->defval.length()!=0)
916 ol.docify(a->defval);
920 if (a) ol.docify(", ");
923 ol.pushGeneratorState();
924 ol.disableAllBut(OutputGenerator::Html);
926 ol.popGeneratorState();
928 ol.docify(type.lower()+" "+name);
929 ol.endSubsubsection();
930 ol.writeString("\n");
934 void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag)
936 if (hasBriefDescription())
939 ol.generateDoc(briefFile(),briefLine(),this,0,
940 briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
941 ol.pushGeneratorState();
942 ol.disable(OutputGenerator::RTF);
943 ol.writeString(" \n");
944 ol.enable(OutputGenerator::RTF);
945 ol.popGeneratorState();
947 if (hasDetailedDescription() || exampleFlag)
949 writeMoreLink(ol,anchor());
957 void ClassDef::writeDetailedDocumentationBody(OutputList &ol)
959 static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
963 if (getLanguage()==SrcLangExt_Cpp)
965 writeTemplateSpec(ol,this,compoundTypeString());
968 // repeat brief description
969 if (!briefDescription().isEmpty() && repeatBrief)
971 ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
973 if (!briefDescription().isEmpty() && repeatBrief &&
974 !documentation().isEmpty())
976 ol.pushGeneratorState();
977 ol.disable(OutputGenerator::Html);
978 ol.writeString("\n\n");
979 ol.popGeneratorState();
981 // write documentation
982 if (!documentation().isEmpty())
984 ol.generateDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);
986 // write type constraints
987 writeTypeConstraints(ol,this,m_impl->typeConstraints);
990 if (hasExamples() && m_impl->exampleSDict)
992 ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
993 ol.startDescForItem();
994 //ol.startParagraph();
995 writeExample(ol,m_impl->exampleSDict);
1000 //ol.newParagraph();
1001 writeSourceDef(ol,name());
1005 bool ClassDef::hasDetailedDescription() const
1007 static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
1008 static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
1009 return ((!briefDescription().isEmpty() && repeatBrief) ||
1010 !documentation().isEmpty() ||
1011 (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef()));
1014 // write the detailed description for this class
1015 void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &/*pageType*/, bool exampleFlag,
1016 const QCString &title,const QCString &anchor)
1018 if (hasDetailedDescription() || exampleFlag)
1020 ol.pushGeneratorState();
1021 ol.disable(OutputGenerator::Html);
1023 ol.popGeneratorState();
1025 ol.pushGeneratorState();
1026 ol.disableAllBut(OutputGenerator::Html);
1027 ol.writeAnchor(0,anchor.isEmpty() ? QCString("details") : anchor);
1028 ol.popGeneratorState();
1030 if (!anchor.isEmpty())
1032 ol.pushGeneratorState();
1033 ol.disable(OutputGenerator::Html);
1034 ol.disable(OutputGenerator::Man);
1035 ol.writeAnchor(getOutputFileBase(),anchor);
1036 ol.popGeneratorState();
1039 ol.startGroupHeader();
1040 ol.parseText(title);
1041 ol.endGroupHeader();
1043 writeDetailedDocumentationBody(ol);
1047 //writeTemplateSpec(ol,this,pageType);
1051 QCString ClassDef::generatedFromFiles() const
1054 SrcLangExt lang = getLanguage();
1055 if (lang==SrcLangExt_Fortran)
1057 result = theTranslator->trGeneratedFromFilesFortran(
1058 getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
1059 m_impl->files.count()==1);
1061 else if (isJavaEnum())
1063 result = theTranslator->trEnumGeneratedFromFiles(m_impl->files.count()==1);
1065 else if (m_impl->compType==Service)
1067 result = theTranslator->trServiceGeneratedFromFiles(m_impl->files.count()==1);
1069 else if (m_impl->compType==Singleton)
1071 result = theTranslator->trSingletonGeneratedFromFiles(m_impl->files.count()==1);
1075 result = theTranslator->trGeneratedFromFiles(
1076 getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
1077 m_impl->files.count()==1);
1082 void ClassDef::showUsedFiles(OutputList &ol)
1084 ol.pushGeneratorState();
1085 ol.disable(OutputGenerator::Man);
1089 ol.parseText(generatedFromFiles());
1092 QListIterator<FileDef> li(m_impl->files);
1094 for (;(fd=li.current());++li)
1102 ol.startItemListItem();
1103 QCString path=fd->getPath();
1104 if (Config_getBool("FULL_PATH_NAMES"))
1106 ol.docify(stripFromPath(path));
1109 QCString fname = fd->name();
1110 if (!fd->getVersion().isEmpty()) // append version if available
1112 fname += " (" + fd->getVersion() + ")";
1116 ol.pushGeneratorState();
1117 ol.disableAllBut(OutputGenerator::Html);
1118 if (fd->generateSourceFile())
1120 ol.writeObjectLink(0,fd->getSourceFileBase(),0,fname);
1122 else if (fd->isLinkable())
1124 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
1131 ol.popGeneratorState();
1133 // for other output formats
1134 ol.pushGeneratorState();
1135 ol.disable(OutputGenerator::Html);
1136 if (fd->isLinkable())
1138 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
1145 ol.popGeneratorState();
1147 ol.endItemListItem();
1149 if (!first) ol.endItemList();
1151 ol.popGeneratorState();
1154 int ClassDef::countInheritanceNodes()
1158 if (m_impl->inheritedBy)
1160 BaseClassListIterator it(*m_impl->inheritedBy);
1161 for (;(ibcd=it.current());++it)
1163 ClassDef *icd=ibcd->classDef;
1164 if ( icd->isVisibleInHierarchy()) count++;
1167 if (m_impl->inherits)
1169 BaseClassListIterator it(*m_impl->inherits);
1170 for (;(ibcd=it.current());++it)
1172 ClassDef *icd=ibcd->classDef;
1173 if ( icd->isVisibleInHierarchy()) count++;
1179 void ClassDef::writeInheritanceGraph(OutputList &ol)
1181 // count direct inheritance relations
1182 int count=countInheritanceNodes();
1184 bool renderDiagram = FALSE;
1185 if (Config_getBool("HAVE_DOT") &&
1186 (Config_getBool("CLASS_DIAGRAMS") || Config_getBool("CLASS_GRAPH")))
1187 // write class diagram using dot
1189 DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
1190 if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig())
1192 ol.pushGeneratorState();
1193 ol.disable(OutputGenerator::Man);
1195 ol.parseText(theTranslator->trClassDiagram(displayName()));
1196 ol.endDotGraph(inheritanceGraph);
1197 ol.popGeneratorState();
1198 renderDiagram = TRUE;
1201 else if (Config_getBool("CLASS_DIAGRAMS") && count>0)
1202 // write class diagram using build-in generator
1204 ClassDiagram diagram(this); // create a diagram of this class.
1205 ol.startClassDiagram();
1206 ol.disable(OutputGenerator::Man);
1207 ol.parseText(theTranslator->trClassDiagram(displayName()));
1208 ol.enable(OutputGenerator::Man);
1209 ol.endClassDiagram(diagram,getOutputFileBase(),displayName());
1210 renderDiagram = TRUE;
1213 if (renderDiagram) // if we already show the inheritance relations graphically,
1214 // then hide the text version
1216 ol.disableAllBut(OutputGenerator::Man);
1219 if (m_impl->inherits && (count=m_impl->inherits->count())>0)
1221 ol.startParagraph();
1222 //parseText(ol,theTranslator->trInherits()+" ");
1224 QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());
1225 QRegExp marker("@[0-9]+");
1226 int index=0,newIndex,matchLen;
1227 // now replace all markers in inheritLine with links to the classes
1228 while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
1230 ol.parseText(inheritLine.mid(index,newIndex-index));
1232 uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1233 BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
1236 ClassDef *cd=bcd->classDef;
1238 // use the class name but with the template arguments as given
1239 // in the inheritance relation
1240 QCString displayName = insertTemplateSpecifierInScope(
1241 cd->displayName(),bcd->templSpecifiers);
1243 if (cd->isLinkable())
1245 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
1247 Doxygen::tagFile << " <base";
1248 if (bcd->prot==Protected)
1250 Doxygen::tagFile << " protection=\"protected\"";
1252 else if (bcd->prot==Private)
1254 Doxygen::tagFile << " protection=\"private\"";
1256 if (bcd->virt==Virtual)
1258 Doxygen::tagFile << " virtualness=\"virtual\"";
1260 Doxygen::tagFile << ">" << convertToXML(cd->name())
1261 << "</base>" << endl;
1263 ol.writeObjectLink(cd->getReference(),
1264 cd->getOutputFileBase(),
1270 ol.docify(displayName);
1275 err("invalid marker %d in inherits list!\n",entryIndex);
1277 index=newIndex+matchLen;
1279 ol.parseText(inheritLine.right(inheritLine.length()-index));
1284 if (m_impl->inheritedBy && (count=m_impl->inheritedBy->count())>0)
1286 ol.startParagraph();
1287 QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());
1288 QRegExp marker("@[0-9]+");
1289 int index=0,newIndex,matchLen;
1290 // now replace all markers in inheritLine with links to the classes
1291 while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
1293 ol.parseText(inheritLine.mid(index,newIndex-index));
1295 uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1296 BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
1299 ClassDef *cd=bcd->classDef;
1300 if (cd->isLinkable())
1302 ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName());
1306 ol.docify(cd->displayName());
1308 writeInheritanceSpecifier(ol,bcd);
1310 index=newIndex+matchLen;
1312 ol.parseText(inheritLine.right(inheritLine.length()-index));
1322 void ClassDef::writeCollaborationGraph(OutputList &ol)
1324 if (Config_getBool("HAVE_DOT") /*&& Config_getBool("COLLABORATION_GRAPH")*/)
1326 DotClassGraph usageImplGraph(this,DotNode::Collaboration);
1327 if (!usageImplGraph.isTrivial())
1329 ol.pushGeneratorState();
1330 ol.disable(OutputGenerator::Man);
1332 ol.parseText(theTranslator->trCollaborationDiagram(displayName()));
1333 ol.endDotGraph(usageImplGraph);
1334 ol.popGeneratorState();
1339 QCString ClassDef::includeStatement() const
1341 SrcLangExt lang = getLanguage();
1342 bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
1347 else if (isObjectiveC())
1357 void ClassDef::writeIncludeFiles(OutputList &ol)
1359 if (m_impl->incInfo /*&& Config_getBool("SHOW_INCLUDE_FILES")*/)
1361 QCString nm=m_impl->incInfo->includeName.isEmpty() ?
1362 (m_impl->incInfo->fileDef ?
1363 m_impl->incInfo->fileDef->docName().data() : ""
1365 m_impl->incInfo->includeName.data();
1368 ol.startParagraph();
1369 ol.startTypewriter();
1370 ol.docify(includeStatement());
1371 SrcLangExt lang = getLanguage();
1372 bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
1373 if (m_impl->incInfo->local || isIDLorJava)
1377 ol.pushGeneratorState();
1378 ol.disable(OutputGenerator::Html);
1380 ol.disableAllBut(OutputGenerator::Html);
1381 ol.enable(OutputGenerator::Html);
1382 if (m_impl->incInfo->fileDef)
1384 ol.writeObjectLink(0,m_impl->incInfo->fileDef->includeName(),0,nm);
1390 ol.popGeneratorState();
1391 if (m_impl->incInfo->local || isIDLorJava)
1404 void ClassDef::writeAllMembersLink(OutputList &ol)
1406 // write link to list of all members (HTML only)
1407 if (m_impl->allMemberNameInfoSDict &&
1408 !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
1411 ol.pushGeneratorState();
1412 ol.disableAllBut(OutputGenerator::Html);
1413 ol.startParagraph();
1414 ol.startTextLink(getMemberListFileName(),0);
1415 ol.parseText(theTranslator->trListOfAllMembers());
1419 ol.popGeneratorState();
1424 void ClassDef::writeMemberGroups(OutputList &ol,bool showInline)
1426 // write user defined member groups
1427 if (m_impl->memberGroupSDict)
1429 m_impl->memberGroupSDict->sort();
1430 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
1432 for (;(mg=mgli.current());++mgli)
1434 if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
1436 mg->writeDeclarations(ol,this,0,0,0,showInline);
1438 else // add this group to the corresponding member section
1440 //printf("addToDeclarationSection(%s)\n",mg->header().data());
1441 //mg->addToDeclarationSection();
1447 void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title)
1450 if (m_impl->innerClasses)
1452 m_impl->innerClasses->writeDeclaration(ol,0,title,TRUE);
1456 void ClassDef::writeInlineClasses(OutputList &ol)
1458 if (m_impl->innerClasses)
1460 m_impl->innerClasses->writeDocumentation(ol,this);
1464 void ClassDef::startMemberDocumentation(OutputList &ol)
1466 //printf("%s: ClassDef::startMemberDocumentation()\n",name().data());
1467 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
1469 ol.disable(OutputGenerator::Html);
1470 Doxygen::suppressDocWarnings = TRUE;
1474 void ClassDef::endMemberDocumentation(OutputList &ol)
1476 //printf("%s: ClassDef::endMemberDocumentation()\n",name().data());
1477 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
1479 ol.enable(OutputGenerator::Html);
1480 Doxygen::suppressDocWarnings = FALSE;
1484 void ClassDef::startMemberDeclarations(OutputList &ol)
1486 //printf("%s: ClassDef::startMemberDeclarations()\n",name().data());
1487 ol.startMemberSections();
1490 void ClassDef::endMemberDeclarations(OutputList &ol)
1492 //printf("%s: ClassDef::endMemberDeclarations()\n",name().data());
1493 static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
1494 if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0)
1496 ol.startMemberHeader("inherited");
1497 ol.parseText(theTranslator->trAdditionalInheritedMembers());
1498 ol.endMemberHeader();
1499 writeAdditionalInheritedMembers(ol);
1501 ol.endMemberSections();
1504 void ClassDef::writeAuthorSection(OutputList &ol)
1506 ol.pushGeneratorState();
1507 ol.disableAllBut(OutputGenerator::Man);
1508 ol.writeString("\n");
1509 ol.startGroupHeader();
1510 ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
1511 ol.endGroupHeader();
1512 ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
1513 ol.popGeneratorState();
1517 void ClassDef::writeSummaryLinks(OutputList &ol)
1519 ol.pushGeneratorState();
1520 ol.disableAllBut(OutputGenerator::Html);
1521 QListIterator<LayoutDocEntry> eli(
1522 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
1523 LayoutDocEntry *lde;
1525 SrcLangExt lang = getLanguage();
1527 if (lang!=SrcLangExt_VHDL)
1529 for (eli.toFirst();(lde=eli.current());++eli)
1531 if (lde->kind()==LayoutDocEntry::ClassNestedClasses &&
1532 m_impl->innerClasses &&
1533 m_impl->innerClasses->declVisible()
1536 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
1537 ol.writeSummaryLink(0,"nested-classes",ls->title(lang),first);
1540 else if (lde->kind()==LayoutDocEntry::ClassAllMembersLink &&
1541 m_impl->allMemberNameInfoSDict &&
1542 !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
1545 ol.writeSummaryLink(getMemberListFileName(),"all-members-list",theTranslator->trListOfAllMembers(),first);
1548 else if (lde->kind()== LayoutDocEntry::MemberDecl)
1550 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
1551 MemberList * ml = getMemberList(lmd->type);
1552 if (ml && ml->declVisible())
1554 ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first);
1562 SDict<QCString>::Iterator li(m_impl->vhdlSummaryTitles);
1563 for (li.toFirst();li.current();++li)
1565 ol.writeSummaryLink(0,li.current()->data(),li.current()->data(),first);
1571 ol.writeString(" </div>\n");
1573 ol.popGeneratorState();
1576 void ClassDef::writeTagFileMarker()
1578 // write section to the tag file
1579 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
1581 Doxygen::tagFile << " <compound kind=\"" << compoundTypeString();
1582 Doxygen::tagFile << "\"";
1583 if (isObjectiveC()) { Doxygen::tagFile << " objc=\"yes\""; }
1584 Doxygen::tagFile << ">" << endl;
1585 Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
1586 Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
1587 if (!anchor().isEmpty())
1589 Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
1591 QCString idStr = id();
1592 if (!idStr.isEmpty())
1594 Doxygen::tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
1596 if (m_impl->tempArgs)
1598 ArgumentListIterator ali(*m_impl->tempArgs);
1600 for (;(a=ali.current());++ali)
1602 Doxygen::tagFile << " <templarg>" << convertToXML(a->name) << "</templarg>" << endl;
1608 /** Write class documentation inside another container (i.e. a group) */
1609 void ClassDef::writeInlineDocumentation(OutputList &ol)
1611 bool isSimple = m_impl->isSimple;
1613 ol.addIndexItem(name(),0);
1614 //printf("ClassDef::writeInlineDocumentation(%s)\n",name().data());
1615 QListIterator<LayoutDocEntry> eli(
1616 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
1617 LayoutDocEntry *lde;
1619 // part 1: anchor and title
1620 QCString s = compoundTypeString()+" "+name();
1623 ol.pushGeneratorState();
1624 ol.disableAllBut(OutputGenerator::Html);
1626 ol.writeAnchor(0,anchor());
1627 ol.startMemberDoc(0,0,0,0,FALSE);
1628 ol.startMemberDocName(FALSE);
1630 ol.endMemberDocName();
1631 ol.endMemberDoc(FALSE);
1632 ol.writeString("</div>");
1635 ol.popGeneratorState();
1638 ol.pushGeneratorState();
1639 ol.disable(OutputGenerator::Html);
1640 ol.disable(OutputGenerator::Man);
1641 { // for LaTeX/RTF only
1642 ol.writeAnchor(getOutputFileBase(),anchor());
1644 ol.popGeneratorState();
1647 ol.pushGeneratorState();
1648 ol.disable(OutputGenerator::Html);
1650 // for LaTeX/RTF/Man
1651 ol.startGroupHeader(1);
1653 ol.endGroupHeader(1);
1655 ol.popGeneratorState();
1657 SrcLangExt lang=getLanguage();
1659 // part 2: the header and detailed description
1660 for (eli.toFirst();(lde=eli.current());++eli)
1662 switch (lde->kind())
1664 case LayoutDocEntry::BriefDesc:
1666 // since we already shown the brief description in the
1667 // declaration part of the container, so we use this to
1668 // show the details on top.
1669 writeDetailedDocumentationBody(ol);
1672 case LayoutDocEntry::ClassInheritanceGraph:
1673 writeInheritanceGraph(ol);
1675 case LayoutDocEntry::ClassCollaborationGraph:
1676 writeCollaborationGraph(ol);
1678 case LayoutDocEntry::MemberDeclStart:
1679 if (!isSimple) startMemberDeclarations(ol);
1681 case LayoutDocEntry::MemberDecl:
1683 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
1684 if (!isSimple) writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang),TRUE);
1687 case LayoutDocEntry::MemberGroups:
1688 if (!isSimple) writeMemberGroups(ol,TRUE);
1690 case LayoutDocEntry::MemberDeclEnd:
1691 if (!isSimple) endMemberDeclarations(ol);
1693 case LayoutDocEntry::MemberDefStart:
1694 if (!isSimple) startMemberDocumentation(ol);
1696 case LayoutDocEntry::MemberDef:
1698 LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
1701 writeSimpleMemberDocumentation(ol,lmd->type);
1705 writeMemberDocumentation(ol,lmd->type,lmd->title(lang),TRUE);
1709 case LayoutDocEntry::MemberDefEnd:
1710 if (!isSimple) endMemberDocumentation(ol);
1717 // part 3: close the block
1718 ol.pushGeneratorState();
1719 ol.disableAllBut(OutputGenerator::Html);
1723 ol.popGeneratorState();
1725 // part 4: write tag file information
1726 writeTagFileMarker();
1729 void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor)
1731 // TODO: clean up this mess by moving it to
1732 // the output generators...
1733 static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1734 static bool rtfHyperlinks = Config_getBool("RTF_HYPERLINKS");
1735 static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
1738 ol.pushGeneratorState();
1739 ol.disableAllBut(OutputGenerator::Html);
1741 ol.startTextLink(getOutputFileBase(),
1742 anchor.isEmpty() ? QCString("details") : anchor);
1743 ol.parseText(theTranslator->trMore());
1745 ol.popGeneratorState();
1747 if (!anchor.isEmpty())
1749 ol.pushGeneratorState();
1751 ol.disable(OutputGenerator::Html);
1752 ol.disable(OutputGenerator::Man);
1753 if (!(usePDFLatex && pdfHyperlinks))
1755 ol.disable(OutputGenerator::Latex);
1759 ol.disable(OutputGenerator::RTF);
1762 ol.startTextLink(getOutputFileBase(), anchor);
1763 ol.parseText(theTranslator->trMore());
1766 ol.disable(OutputGenerator::Latex);
1767 ol.writeString("\\par");
1768 ol.popGeneratorState();
1772 bool ClassDef::visibleInParentsDeclList() const
1774 static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
1775 static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
1776 static bool extractLocalClasses = Config_getBool("EXTRACT_LOCAL_CLASSES");
1777 bool linkable = isLinkable();
1778 return (!isAnonymous() && !isExtension() &&
1779 (protection()!=::Private || extractPrivate) &&
1780 (linkable || (!hideUndocClasses && (!isLocal() || extractLocalClasses)))
1784 void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames)
1786 //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
1787 //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1788 SrcLangExt lang = getLanguage();
1789 if (visibleInParentsDeclList())
1791 if (!found) // first class
1793 ol.startMemberHeader("nested-classes");
1796 ol.parseText(header);
1798 else if (lang==SrcLangExt_VHDL)
1800 ol.parseText(VhdlDocGen::trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE));
1804 ol.parseText(lang==SrcLangExt_Fortran ?
1805 theTranslator->trDataTypes() :
1806 theTranslator->trCompounds());
1808 ol.endMemberHeader();
1809 ol.startMemberList();
1812 if (!Config_getString("GENERATE_TAGFILE").isEmpty() &&
1813 !isReference()) // skip classes found in tag files
1815 Doxygen::tagFile << " <class kind=\"" << compoundTypeString()
1816 << "\">" << convertToXML(name()) << "</class>" << endl;
1818 ol.startMemberDeclaration();
1819 ol.startMemberItem(anchor(),FALSE);
1820 QCString ctype = compoundTypeString();
1821 QCString cname = displayName(!localNames);
1823 if (lang!=SrcLangExt_VHDL) // for VHDL we swap the name and the type
1825 ol.writeString(ctype);
1826 ol.writeString(" ");
1827 ol.insertMemberAlign();
1831 ol.writeObjectLink(getReference(),
1832 getOutputFileBase(),
1843 if (lang==SrcLangExt_VHDL) // now write the type
1845 ol.writeString(" ");
1846 ol.insertMemberAlign();
1847 ol.writeString(VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)protection()));
1851 // add the brief description if available
1852 if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
1854 DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
1855 briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
1856 if (rootNode && !rootNode->isEmpty())
1858 ol.startMemberDescription(anchor());
1859 ol.writeDoc(rootNode,this,0);
1860 if (isLinkableInProject())
1862 writeMoreLink(ol,anchor());
1864 ol.endMemberDescription();
1868 ol.endMemberDeclaration(anchor(),0);
1872 void ClassDef::addClassAttributes(OutputList &ol)
1875 if (isFinal()) sl.append("final");
1876 if (isSealed()) sl.append("sealed");
1877 if (isAbstract()) sl.append("abstract");
1878 if (getLanguage()==SrcLangExt_IDL && isPublished()) sl.append("published");
1880 ol.pushGeneratorState();
1881 ol.disableAllBut(OutputGenerator::Html);
1885 const char *s=sl.first();
1888 const char *ns = sl.next();
1889 ol.writeLabel(s,ns==0);
1894 ol.popGeneratorState();
1897 void ClassDef::writeDocumentationContents(OutputList &ol,const QCString & /*pageTitle*/)
1901 QCString pageType = " ";
1902 pageType += compoundTypeString();
1903 toupper(pageType.at(1));
1905 writeTagFileMarker();
1907 Doxygen::indexList->addIndexItem(this,0);
1909 if (Doxygen::searchIndex)
1911 Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
1912 Doxygen::searchIndex->addWord(localName(),TRUE);
1914 bool exampleFlag=hasExamples();
1916 //---------------------------------------- start flexible part -------------------------------
1918 SrcLangExt lang = getLanguage();
1920 QListIterator<LayoutDocEntry> eli(
1921 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
1922 LayoutDocEntry *lde;
1923 for (eli.toFirst();(lde=eli.current());++eli)
1925 switch (lde->kind())
1927 case LayoutDocEntry::BriefDesc:
1928 writeBriefDescription(ol,exampleFlag);
1930 case LayoutDocEntry::ClassIncludes:
1931 writeIncludeFiles(ol);
1933 case LayoutDocEntry::ClassInheritanceGraph:
1934 writeInheritanceGraph(ol);
1936 case LayoutDocEntry::ClassCollaborationGraph:
1937 writeCollaborationGraph(ol);
1939 case LayoutDocEntry::ClassAllMembersLink:
1940 //writeAllMembersLink(ol); // this is now part of the summary links
1942 case LayoutDocEntry::MemberDeclStart:
1943 startMemberDeclarations(ol);
1945 case LayoutDocEntry::MemberGroups:
1946 writeMemberGroups(ol);
1948 case LayoutDocEntry::MemberDecl:
1950 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
1951 writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang));
1954 case LayoutDocEntry::ClassNestedClasses:
1956 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
1957 writeNestedClasses(ol,ls->title(lang));
1960 case LayoutDocEntry::MemberDeclEnd:
1961 endMemberDeclarations(ol);
1963 case LayoutDocEntry::DetailedDesc:
1965 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
1966 writeDetailedDescription(ol,pageType,exampleFlag,ls->title(lang));
1969 case LayoutDocEntry::MemberDefStart:
1970 startMemberDocumentation(ol);
1972 case LayoutDocEntry::ClassInlineClasses:
1973 writeInlineClasses(ol);
1975 case LayoutDocEntry::MemberDef:
1977 LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
1978 writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
1981 case LayoutDocEntry::MemberDefEnd:
1982 endMemberDocumentation(ol);
1984 case LayoutDocEntry::ClassUsedFiles:
1987 case LayoutDocEntry::AuthorSection:
1988 writeAuthorSection(ol);
1990 case LayoutDocEntry::NamespaceNestedNamespaces:
1991 case LayoutDocEntry::NamespaceNestedConstantGroups:
1992 case LayoutDocEntry::NamespaceClasses:
1993 case LayoutDocEntry::NamespaceInlineClasses:
1994 case LayoutDocEntry::FileClasses:
1995 case LayoutDocEntry::FileNamespaces:
1996 case LayoutDocEntry::FileConstantGroups:
1997 case LayoutDocEntry::FileIncludes:
1998 case LayoutDocEntry::FileIncludeGraph:
1999 case LayoutDocEntry::FileIncludedByGraph:
2000 case LayoutDocEntry::FileSourceLink:
2001 case LayoutDocEntry::FileInlineClasses:
2002 case LayoutDocEntry::GroupClasses:
2003 case LayoutDocEntry::GroupInlineClasses:
2004 case LayoutDocEntry::GroupNamespaces:
2005 case LayoutDocEntry::GroupDirs:
2006 case LayoutDocEntry::GroupNestedGroups:
2007 case LayoutDocEntry::GroupFiles:
2008 case LayoutDocEntry::GroupGraph:
2009 case LayoutDocEntry::GroupPageDocs:
2010 case LayoutDocEntry::DirSubDirs:
2011 case LayoutDocEntry::DirFiles:
2012 case LayoutDocEntry::DirGraph:
2013 err("Internal inconsistency: member %d should not be part of "
2014 "LayoutDocManager::Class entry list\n",lde->kind());
2019 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
2021 writeDocAnchorsToTagFile();
2022 Doxygen::tagFile << " </compound>" << endl;
2027 QCString ClassDef::title() const
2030 SrcLangExt lang = getLanguage();
2032 if (lang==SrcLangExt_Fortran)
2034 pageTitle = theTranslator->trCompoundReferenceFortran(displayName(),
2036 m_impl->tempArgs != 0);
2038 else if (lang==SrcLangExt_VHDL)
2040 pageTitle = VhdlDocGen::getClassTitle(this)+" Reference";
2042 else if (isJavaEnum())
2044 pageTitle = theTranslator->trEnumReference(displayName());
2046 else if (m_impl->compType==Service)
2048 pageTitle = theTranslator->trServiceReference(displayName());
2050 else if (m_impl->compType==Singleton)
2052 pageTitle = theTranslator->trSingletonReference(displayName());
2056 pageTitle = theTranslator->trCompoundReference(displayName(),
2057 m_impl->compType == Interface && getLanguage()==SrcLangExt_ObjC ? Class : m_impl->compType,
2058 m_impl->tempArgs != 0);
2063 // write all documentation for this class
2064 void ClassDef::writeDocumentation(OutputList &ol)
2066 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
2067 //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2068 //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2069 QCString pageTitle = title();
2071 startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible,!generateTreeView);
2072 if (!generateTreeView)
2074 if (getOuterScope()!=Doxygen::globalScope)
2076 writeNavigationPath(ol);
2078 ol.endQuickIndices();
2081 startTitle(ol,getOutputFileBase(),this);
2082 ol.parseText(pageTitle);
2083 addClassAttributes(ol);
2084 addGroupListToTitle(ol,this);
2085 endTitle(ol,getOutputFileBase(),displayName());
2086 writeDocumentationContents(ol,pageTitle);
2088 endFileWithNavPath(this,ol);
2090 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
2092 writeMemberPages(ol);
2096 void ClassDef::writeMemberPages(OutputList &ol)
2098 ///////////////////////////////////////////////////////////////////////////
2099 //// Member definitions on separate pages
2100 ///////////////////////////////////////////////////////////////////////////
2102 ol.pushGeneratorState();
2103 ol.disableAllBut(OutputGenerator::Html);
2105 QListIterator<MemberList> mli(m_impl->memberLists);
2107 for (mli.toFirst();(ml=mli.current());++mli)
2109 ml->countDocMembers();
2110 if (ml->numDocMembers()>0 && (ml->listType()&MemberListType_detailedLists))
2112 ml->writeDocumentationPage(ol,displayName(),this);
2116 ol.popGeneratorState();
2119 void ClassDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
2121 static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
2123 ol.writeString(" <div class=\"navtab\">\n");
2124 ol.writeString(" <table>\n");
2126 if (m_impl->allMemberNameInfoSDict)
2128 MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
2129 MemberNameInfo *mni;
2130 for (;(mni=mnili.current());++mnili)
2132 MemberNameInfoIterator mnii(*mni);
2134 for (mnii.toFirst();(mi=mnii.current());++mnii)
2136 MemberDef *md=mi->memberDef;
2137 if (md->getClassDef()==this && md->isLinkable() && !md->isEnumValue())
2139 ol.writeString(" <tr><td class=\"navtab\">");
2140 if (md->isLinkableInProject())
2142 if (md==currentMd) // selected item => highlight
2144 ol.writeString("<a class=\"qindexHL\" ");
2148 ol.writeString("<a class=\"qindex\" ");
2150 ol.writeString("href=\"");
2151 if (createSubDirs) ol.writeString("../../");
2152 ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
2153 ol.writeString("\">");
2154 ol.writeString(convertToHtml(md->name()));
2155 ol.writeString("</a>");
2157 ol.writeString("</td></tr>\n");
2163 ol.writeString(" </table>\n");
2164 ol.writeString(" </div>\n");
2169 void ClassDef::writeDocumentationForInnerClasses(OutputList &ol)
2171 // write inner classes after the parent, so the tag files contain
2172 // the definition in proper order!
2173 if (m_impl->innerClasses)
2175 ClassSDict::Iterator cli(*m_impl->innerClasses);
2177 for (cli.toFirst();(innerCd=cli.current());++cli)
2179 if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
2180 protectionLevelVisible(innerCd->protection()) &&
2181 !innerCd->isEmbeddedInOuterScope()
2184 msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name()));
2185 innerCd->writeDocumentation(ol);
2186 innerCd->writeMemberList(ol);
2188 innerCd->writeDocumentationForInnerClasses(ol);
2193 // write the list of all (inherited) members for this class
2194 void ClassDef::writeMemberList(OutputList &ol)
2196 static bool cOpt = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
2197 //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2198 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
2199 if (m_impl->allMemberNameInfoSDict==0 || cOpt) return;
2201 ol.pushGeneratorState();
2202 ol.disableAllBut(OutputGenerator::Html);
2204 QCString memListFile = getMemberListFileName();
2205 startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),
2206 HLI_ClassVisible,!generateTreeView,getOutputFileBase());
2207 if (!generateTreeView)
2209 if (getOuterScope()!=Doxygen::globalScope)
2211 writeNavigationPath(ol);
2213 ol.endQuickIndices();
2216 ol.parseText(displayName()+" "+theTranslator->trMemberList());
2219 ol.startParagraph();
2220 ol.parseText(theTranslator->trThisIsTheListOfAllMembers());
2221 ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),displayName());
2222 ol.parseText(theTranslator->trIncludingInheritedMembers());
2225 //ol.startItemList();
2226 ol.writeString("<table class=\"directory\">\n");
2229 //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first();
2230 MemberNameInfoSDict::Iterator mnii(*m_impl->allMemberNameInfoSDict);
2231 MemberNameInfo *mni;
2232 for (mnii.toFirst();(mni=mnii.current());++mnii)
2234 MemberNameInfoIterator it(*mni);
2236 for (;(mi=it.current());++it)
2238 MemberDef *md=mi->memberDef;
2239 ClassDef *cd=md->getClassDef();
2240 Protection prot = mi->prot;
2241 Specifier virt=md->virtualness();
2243 //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
2244 // name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);
2246 if (cd && !md->name().isEmpty() && md->name()[0]!='@')
2248 bool memberWritten=FALSE;
2249 if (cd->isLinkable() && md->isLinkable())
2250 // create a link to the documentation
2252 QCString name=mi->ambiguityResolutionScope+md->name();
2253 //ol.writeListItem();
2254 ol.writeString(" <tr");
2255 if ((idx&1)==0) ol.writeString(" class=\"even\"");
2257 ol.writeString("><td class=\"entry\">");
2258 if (cd->isObjectiveC())
2260 if (md->isObjCMethod())
2263 ol.writeString("+ </td><td>");
2265 ol.writeString("- </td><td>");
2268 ol.writeString("</td><td class=\"entry\">");
2270 if (md->isObjCMethod())
2272 ol.writeObjectLink(md->getReference(),
2273 md->getOutputFileBase(),
2274 md->anchor(),md->name());
2278 //Definition *bd = md->getGroupDef();
2280 ol.writeObjectLink(md->getReference(),
2281 md->getOutputFileBase(),
2284 if ( md->isFunction() || md->isSignal() || md->isSlot() ||
2285 (md->isFriend() && md->argsString()))
2286 ol.docify(md->argsString());
2287 else if (md->isEnumerate())
2288 ol.parseText(" "+theTranslator->trEnumName());
2289 else if (md->isEnumValue())
2290 ol.parseText(" "+theTranslator->trEnumValue());
2291 else if (md->isTypedef())
2292 ol.docify(" typedef");
2293 else if (md->isFriend() && !qstrcmp(md->typeString(),"friend class"))
2294 ol.docify(" class");
2295 //ol.writeString("\n");
2297 ol.writeString("</td>");
2300 else if (!cd->isArtificial() &&
2301 !Config_getBool("HIDE_UNDOC_MEMBERS") &&
2302 (protectionLevelVisible(md->protection()) || md->isFriend())
2303 ) // no documentation,
2304 // generate link to the class instead.
2306 //ol.writeListItem();
2307 ol.writeString(" <tr bgcolor=\"#f0f0f0\"");
2308 if ((idx&1)==0) ol.writeString(" class=\"even\"");
2310 ol.writeString("><td class=\"entry\">");
2311 if (cd->isObjectiveC())
2313 if (md->isObjCMethod())
2316 ol.writeString("+ </td><td class=\"entry\">");
2318 ol.writeString("- </td><td class=\"entry\">");
2321 ol.writeString("</td><td class=\"entry\">");
2324 ol.docify(md->name());
2326 if (!md->isObjCMethod())
2328 if ( md->isFunction() || md->isSignal() || md->isSlot() )
2329 ol.docify(md->argsString());
2330 else if (md->isEnumerate())
2331 ol.parseText(" "+theTranslator->trEnumName());
2332 else if (md->isEnumValue())
2333 ol.parseText(" "+theTranslator->trEnumValue());
2334 else if (md->isTypedef())
2335 ol.docify(" typedef");
2337 ol.writeString(" (");
2338 ol.parseText(theTranslator->trDefinedIn()+" ");
2339 if (cd->isLinkable())
2343 cd->getOutputFileBase(),
2350 ol.docify(cd->displayName());
2353 ol.writeString(")");
2354 ol.writeString("</td>");
2359 ol.writeString("<td class=\"entry\">");
2360 ol.writeObjectLink(cd->getReference(),
2361 cd->getOutputFileBase(),
2364 md->category()->displayName() :
2366 ol.writeString("</td>");
2367 ol.writeString("<td class=\"entry\">");
2369 SrcLangExt lang = md->getLanguage();
2371 (prot!=Public || (virt!=Normal && getLanguage()!=SrcLangExt_ObjC) ||
2372 md->isFriend() || md->isRelated() || md->isExplicit() ||
2373 md->isMutable() || (md->isInline() && Config_getBool("INLINE_INFO")) ||
2374 md->isSignal() || md->isSlot() ||
2375 (getLanguage()==SrcLangExt_IDL &&
2376 (md->isOptional() || md->isAttribute() || md->isUNOProperty())) ||
2377 md->isStatic() || lang==SrcLangExt_VHDL
2381 ol.writeString("<span class=\"mlabel\">");
2383 if (lang==SrcLangExt_VHDL)
2385 sl.append(VhdlDocGen::trVhdlType(md->getMemberSpecifiers())); //append vhdl type
2387 else if (md->isFriend()) sl.append("friend");
2388 else if (md->isRelated()) sl.append("related");
2391 if (Config_getBool("INLINE_INFO") && md->isInline())
2392 sl.append("inline");
2393 if (md->isExplicit()) sl.append("explicit");
2394 if (md->isMutable()) sl.append("mutable");
2395 if (prot==Protected) sl.append("protected");
2396 else if (prot==Private) sl.append("private");
2397 else if (prot==Package) sl.append("package");
2398 if (virt==Virtual && getLanguage()!=SrcLangExt_ObjC)
2399 sl.append("virtual");
2400 else if (virt==Pure) sl.append("pure virtual");
2401 if (md->isStatic()) sl.append("static");
2402 if (md->isSignal()) sl.append("signal");
2403 if (md->isSlot()) sl.append("slot");
2404 // this is the extra member page
2405 if (md->isOptional()) sl.append("optional");
2406 if (md->isAttribute()) sl.append("attribute");
2407 if (md->isUNOProperty()) sl.append("property");
2408 if (md->isReadonly()) sl.append("readonly");
2409 if (md->isBound()) sl.append("bound");
2410 if (md->isRemovable()) sl.append("removable");
2411 if (md->isConstrained()) sl.append("constrained");
2412 if (md->isTransient()) sl.append("transient");
2413 if (md->isMaybeVoid()) sl.append("maybevoid");
2414 if (md->isMaybeDefault()) sl.append("maybedefault");
2415 if (md->isMaybeAmbiguous())sl.append("maybeambiguous");
2417 const char *s=sl.first();
2422 if (s) ol.writeString("</span><span class=\"mlabel\">");
2424 ol.writeString("</span>");
2428 ol.writeString("</td>");
2429 ol.writeString("</tr>\n");
2436 ol.writeString("</table>");
2439 ol.popGeneratorState();
2443 // add a reference to an example
2444 bool ClassDef::addExample(const char *anchor,const char *nameStr,
2447 if (m_impl->exampleSDict==0)
2449 m_impl->exampleSDict = new ExampleSDict;
2450 m_impl->exampleSDict->setAutoDelete(TRUE);
2452 if (!m_impl->exampleSDict->find(nameStr))
2454 Example *e=new Example;
2458 m_impl->exampleSDict->inSort(nameStr,e);
2464 // returns TRUE if this class is used in an example
2465 bool ClassDef::hasExamples() const
2468 if (m_impl->exampleSDict)
2469 result = m_impl->exampleSDict->count()>0;
2474 void ClassDef::setTemplateArguments(ArgumentList *al)
2477 if (!m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed
2478 m_impl->tempArgs=new ArgumentList;
2479 ArgumentListIterator ali(*al);
2481 for (;(a=ali.current());++ali)
2483 m_impl->tempArgs->append(new Argument(*a));
2487 void ClassDef::setTypeConstraints(ArgumentList *al)
2490 if (!m_impl->typeConstraints) delete m_impl->typeConstraints;
2491 m_impl->typeConstraints = new ArgumentList;
2492 ArgumentListIterator ali(*al);
2494 for (;(a=ali.current());++ali)
2496 m_impl->typeConstraints->append(new Argument(*a));
2500 /*! Returns \c TRUE iff this class or a class inheriting from this class
2501 * is \e not defined in an external tag file.
2503 bool ClassDef::hasNonReferenceSuperClass()
2505 bool found=!isReference() && isLinkableInProject() && !isHidden();
2508 return TRUE; // we're done if this class is not a reference
2510 if (m_impl->inheritedBy)
2512 BaseClassListIterator bcli(*m_impl->inheritedBy);
2513 for ( ; bcli.current() && !found ; ++bcli ) // for each super class
2515 ClassDef *bcd=bcli.current()->classDef;
2516 // recurse into the super class branch
2517 found = found || bcd->hasNonReferenceSuperClass();
2520 // look for template instances that might have non-reference super classes
2521 QDict<ClassDef> *cil = bcd->getTemplateInstances();
2524 QDictIterator<ClassDef> tidi(*cil);
2525 for ( ; tidi.current() && !found ; ++tidi) // for each template instance
2527 // recurse into the template instance branch
2528 found = found || tidi.current()->hasNonReferenceSuperClass();
2537 /*! called from MemberDef::writeDeclaration() to (recusively) write the
2538 * definition of an anonymous struct, union or class.
2540 void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup,
2541 ClassDef *inheritedFrom,const char *inheritId)
2543 //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup);
2545 ol.docify(compoundTypeString());
2546 QCString cn = displayName(FALSE);
2550 if (md && isLinkable())
2552 ol.writeObjectLink(0,0,md->anchor(),cn);
2564 // write user defined member groups
2565 if (m_impl->memberGroupSDict)
2567 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
2569 for (;(mg=mgli.current());++mgli)
2571 mg->setInGroup(inGroup);
2572 mg->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
2576 QListIterator<LayoutDocEntry> eli(
2577 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
2578 LayoutDocEntry *lde;
2579 for (eli.toFirst();(lde=eli.current());++eli)
2581 if (lde->kind()==LayoutDocEntry::MemberDecl)
2583 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
2584 writePlainMemberDeclaration(ol,lmd->type,inGroup,inheritedFrom,inheritId);
2589 /*! a link to this class is possible within this project */
2590 bool ClassDef::isLinkableInProject() const
2592 static bool extractLocal = Config_getBool("EXTRACT_LOCAL_CLASSES");
2593 static bool extractStatic = Config_getBool("EXTRACT_STATIC");
2594 static bool hideUndoc = Config_getBool("HIDE_UNDOC_CLASSES");
2595 if (m_impl->templateMaster)
2597 return m_impl->templateMaster->isLinkableInProject();
2601 return !name().isEmpty() && /* has a name */
2602 !isArtificial() && !isHidden() && /* not hidden */
2603 !isAnonymous() && /* not anonymous */
2604 protectionLevelVisible(m_impl->prot) && /* private/internal */
2605 (!m_impl->isLocal || extractLocal) && /* local */
2606 (hasDocumentation() || !hideUndoc) && /* documented */
2607 (!m_impl->isStatic || extractStatic) && /* static */
2608 !isReference(); /* not an external reference */
2612 bool ClassDef::isLinkable() const
2614 if (m_impl->templateMaster)
2616 return m_impl->templateMaster->isLinkable();
2620 return isLinkableInProject() || isReference();
2625 /*! the class is visible in a class diagram, or class hierarchy */
2626 bool ClassDef::isVisibleInHierarchy()
2628 static bool allExternals = Config_getBool("ALLEXTERNALS");
2629 static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
2630 static bool extractStatic = Config_getBool("EXTRACT_STATIC");
2632 return // show all classes or a subclass is visible
2633 (allExternals || hasNonReferenceSuperClass()) &&
2634 // and not an anonymous compound
2636 // not an artificially introduced class
2637 /*!isArtificial() &&*/ // 1.8.2: allowed these to appear
2638 // and not privately inherited
2639 protectionLevelVisible(m_impl->prot) &&
2640 // documented or shown anyway or documentation is external
2641 (hasDocumentation() ||
2642 !hideUndocClasses ||
2643 (m_impl->templateMaster && m_impl->templateMaster->hasDocumentation()) ||
2646 // is not part of an unnamed namespace or shown anyway
2647 (!m_impl->isStatic || extractStatic);
2650 bool ClassDef::hasDocumentation() const
2652 return Definition::hasDocumentation();
2655 //----------------------------------------------------------------------
2656 // recursive function:
2657 // returns TRUE iff class definition `bcd' represents an (in)direct base
2658 // class of class definition `cd'.
2660 bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level)
2663 //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
2666 err("Possible recursive class relation while inside %s and looking for base class %s\n",qPrint(name()),qPrint(bcd->name()));
2671 // Beware: trying to optimise the iterator away using ->first() & ->next()
2672 // causes bug 625531
2673 BaseClassListIterator bcli(*baseClasses());
2674 for ( ; bcli.current() && !found ; ++bcli)
2676 ClassDef *ccd=bcli.current()->classDef;
2677 if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
2678 //printf("isBaseClass() baseclass %s\n",ccd->name().data());
2682 found=ccd->isBaseClass(bcd,followInstances,level+1);
2688 //----------------------------------------------------------------------
2690 bool ClassDef::isSubClass(ClassDef *cd,int level)
2695 err("Possible recursive class relation while inside %s and looking for derived class %s\n",qPrint(name()),qPrint(cd->name()));
2700 BaseClassListIterator bcli(*subClasses());
2701 for ( ; bcli.current() && !found ; ++bcli)
2703 ClassDef *ccd=bcli.current()->classDef;
2707 found=ccd->isSubClass(cd,level+1);
2713 //----------------------------------------------------------------------------
2715 static bool isStandardFunc(MemberDef *md)
2717 return md->name()=="operator=" || // assignment operator
2718 md->isConstructor() || // constructor
2719 md->isDestructor(); // destructor
2723 * recusively merges the `all members' lists of a class base
2724 * with that of this class. Must only be called for classes without
2727 void ClassDef::mergeMembers()
2729 if (m_impl->membersMerged) return;
2731 //static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
2732 //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2733 SrcLangExt lang = getLanguage();
2734 QCString sep=getLanguageSpecificSeparator(lang,TRUE);
2735 int sepLen = sep.length();
2737 m_impl->membersMerged=TRUE;
2738 //printf(" mergeMembers for %s\n",name().data());
2739 bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB" );
2742 //printf(" => has base classes!\n");
2743 BaseClassListIterator bcli(*baseClasses());
2745 for ( ; (bcd=bcli.current()) ; ++bcli )
2747 ClassDef *bClass=bcd->classDef;
2749 // merge the members in the base class of this inheritance branch first
2750 bClass->mergeMembers();
2752 MemberNameInfoSDict *srcMnd = bClass->memberNameInfoSDict();
2753 MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;
2757 MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
2758 MemberNameInfo *srcMni;
2759 for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
2761 //printf(" Base member name %s\n",srcMni->memberName());
2762 MemberNameInfo *dstMni;
2763 if (dstMnd!=0 && (dstMni=dstMnd->find(srcMni->memberName())))
2764 // a member with that name is already in the class.
2765 // the member may hide or reimplement the one in the sub class
2766 // or there may be another path to the base class that is already
2767 // visited via another branch in the class hierarchy.
2769 MemberNameInfoIterator srcMnii(*srcMni);
2771 for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
2773 MemberDef *srcMd = srcMi->memberDef;
2777 MemberNameInfoIterator dstMnii(*dstMni);
2779 ClassDef *srcCd = srcMd->getClassDef();
2780 for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii )
2782 MemberDef *dstMd = dstMi->memberDef;
2783 if (srcMd!=dstMd) // different members
2785 ClassDef *dstCd = dstMd->getClassDef();
2786 //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
2787 if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
2788 // member is in the same or a base class
2790 ArgumentList *srcAl = srcMd->argumentList();
2791 ArgumentList *dstAl = dstMd->argumentList();
2792 found=matchArguments2(
2793 srcMd->getOuterScope(),srcMd->getFileDef(),srcAl,
2794 dstMd->getOuterScope(),dstMd->getFileDef(),dstAl,
2797 //printf(" Yes, matching (%s<->%s): %d\n",
2798 // argListToString(srcMd->argumentList()).data(),
2799 // argListToString(dstMd->argumentList()).data(),
2801 hidden = hidden || !found;
2803 else // member is in a non base class => multiple inheritance
2804 // using the same base class.
2806 //printf("$$ Existing member %s %s add scope %s\n",
2807 // dstMi->ambiguityResolutionScope.data(),
2808 // dstMd->name().data(),
2809 // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
2811 QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
2812 if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
2813 dstMi->ambiguityResolutionScope.prepend(scope);
2817 else // same members
2819 // do not add if base class is virtual or
2820 // if scope paths are equal or
2821 // if base class is an interface (and thus implicitly virtual).
2822 //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
2823 if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||
2824 bClass->name()+sep+srcMi->scopePath == dstMi->scopePath ||
2825 dstMd->getClassDef()->compoundType()==Interface
2830 else // member can be reached via multiple paths in the
2833 //printf("$$ Existing member %s %s add scope %s\n",
2834 // dstMi->ambiguityResolutionScope.data(),
2835 // dstMd->name().data(),
2836 // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
2838 QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
2839 if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
2841 dstMi->ambiguityResolutionScope.prepend(scope);
2847 //printf("member %s::%s hidden %d ambigue %d srcMi->ambigClass=%p\n",
2848 // srcCd->name().data(),srcMd->name().data(),hidden,ambigue,srcMi->ambigClass);
2850 // TODO: fix the case where a member is hidden by inheritance
2851 // of a member with the same name but with another prototype,
2852 // while there is more than one path to the member in the
2853 // base class due to multiple inheritance. In this case
2854 // it seems that the member is not reachable by prefixing a
2855 // scope name either (according to my compiler). Currently,
2856 // this case is shown anyway.
2857 if (!found && srcMd->protection()!=Private && !srcMd->isFriend())
2859 Protection prot=srcMd->protection();
2860 if (bcd->prot==Protected && prot==Public) prot=bcd->prot;
2861 else if (bcd->prot==Private) prot=bcd->prot;
2863 if (inlineInheritedMembers)
2865 if (!isStandardFunc(srcMd))
2867 //printf(" insertMember `%s'\n",srcMd->name().data());
2868 internalInsertMember(srcMd,prot,FALSE);
2872 Specifier virt=srcMi->virt;
2873 if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
2875 MemberInfo *newMi = new MemberInfo(srcMd,prot,virt,TRUE);
2876 newMi->scopePath=bClass->name()+sep+srcMi->scopePath;
2879 //printf("$$ New member %s %s add scope %s::\n",
2880 // srcMi->ambiguityResolutionScope.data(),
2881 // srcMd->name().data(),
2882 // bClass->name().data());
2884 QCString scope=bClass->name()+sep;
2885 if (scope!=srcMi->ambiguityResolutionScope.left(scope.length()))
2887 newMi->ambiguityResolutionScope=
2888 scope+srcMi->ambiguityResolutionScope.copy();
2893 if (srcMi->ambigClass==0)
2895 newMi->ambigClass=bClass;
2896 newMi->ambiguityResolutionScope=bClass->name()+sep;
2900 newMi->ambigClass=srcMi->ambigClass;
2901 newMi->ambiguityResolutionScope=srcMi->ambigClass->name()+sep;
2904 dstMni->append(newMi);
2908 else // base class has a member that is not in the sub class => copy
2910 // create a deep copy of the list (only the MemberInfo's will be
2911 // copied, not the actual MemberDef's)
2912 MemberNameInfo *newMni = 0;
2913 newMni = new MemberNameInfo(srcMni->memberName());
2915 // copy the member(s) from the base to the sub class
2916 MemberNameInfoIterator mnii(*srcMni);
2918 for (;(mi=mnii.current());++mnii)
2920 if (!mi->memberDef->isFriend()) // don't inherit friends
2922 Protection prot = mi->prot;
2923 if (bcd->prot==Protected)
2925 if (prot==Public) prot=Protected;
2927 else if (bcd->prot==Private)
2931 //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",
2932 // name().data(),mi->memberDef->name().data(),mi->prot,
2935 if (mi->prot!=Private)
2937 Specifier virt=mi->virt;
2938 if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
2940 if (inlineInheritedMembers)
2942 if (!isStandardFunc(mi->memberDef))
2944 //printf(" insertMember `%s'\n",mi->memberDef->name().data());
2945 internalInsertMember(mi->memberDef,prot,FALSE);
2948 //printf("Adding!\n");
2949 MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);
2950 newMi->scopePath=bClass->name()+sep+mi->scopePath;
2951 newMi->ambigClass=mi->ambigClass;
2952 newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope.copy();
2953 newMni->append(newMi);
2960 m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
2961 m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
2962 dstMnd = m_impl->allMemberNameInfoSDict;
2964 // add it to the dictionary
2965 dstMnd->append(newMni->memberName(),newMni);
2971 //printf(" end mergeMembers\n");
2974 //----------------------------------------------------------------------------
2976 /*! Merges the members of a Objective-C category into this class.
2978 void ClassDef::mergeCategory(ClassDef *category)
2980 static bool extractLocalMethods = Config_getBool("EXTRACT_LOCAL_METHODS");
2981 bool makePrivate = category->isLocal();
2982 // in case extract local methods is not enabled we don't add the methods
2983 // of the category in case it is defined in the .m file.
2984 if (makePrivate && !extractLocalMethods) return;
2985 bool isExtension = category->isExtension();
2987 category->setCategoryOf(this);
2990 category->setArtificial(TRUE);
2992 // copy base classes/protocols from extension
2993 if (category->baseClasses())
2995 BaseClassListIterator bcli(*category->baseClasses());
2997 for ( ; (bcd=bcli.current()) ; ++bcli )
2999 insertBaseClass(bcd->classDef,bcd->usedName,bcd->prot,bcd->virt,bcd->templSpecifiers);
3000 // correct bcd->classDef so that they do no longer derive from
3001 // category, but from this class!
3002 if (bcd->classDef->subClasses())
3004 BaseClassListIterator scli(*bcd->classDef->subClasses());
3006 for ( ; (scd=scli.current()) ; ++scli )
3008 if (scd->classDef==category)
3018 // make methods private for categories defined in the .m file
3019 //printf("%s::mergeCategory makePrivate=%d\n",name().data(),makePrivate);
3021 MemberNameInfoSDict *srcMnd = category->memberNameInfoSDict();
3022 MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;
3024 if (srcMnd && dstMnd)
3026 MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
3027 MemberNameInfo *srcMni;
3028 for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
3030 MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());
3031 if (dstMni) // method is already defined in the class
3033 //printf("Existing member %s\n",srcMni->memberName());
3034 MemberInfo *dstMi = dstMni->getFirst();
3035 MemberInfo *srcMi = srcMni->getFirst();
3038 // Protection prot = dstMi->prot;
3039 // if (makePrivate || isExtension)
3042 // removeMemberFromLists(dstMi->memberDef);
3043 // internalInsertMember(dstMi->memberDef,prot,FALSE);
3048 combineDeclarationAndDefinition(srcMi->memberDef,dstMi->memberDef);
3049 dstMi->memberDef->setCategory(category);
3050 dstMi->memberDef->setCategoryRelation(srcMi->memberDef);
3051 srcMi->memberDef->setCategoryRelation(dstMi->memberDef);
3054 else // new method name
3056 //printf("New member %s\n",srcMni->memberName());
3057 // create a deep copy of the list
3058 MemberNameInfo *newMni = 0;
3059 newMni = new MemberNameInfo(srcMni->memberName());
3061 // copy the member(s) from the category to this class
3062 MemberNameInfoIterator mnii(*srcMni);
3064 for (;(mi=mnii.current());++mnii)
3066 //printf("Adding '%s'\n",mi->memberDef->name().data());
3067 Protection prot = mi->prot;
3068 //if (makePrivate) prot = Private;
3069 MemberDef *newMd = mi->memberDef->deepCopy();
3070 //printf("Copying member %s\n",mi->memberDef->name().data());
3071 newMd->moveTo(this);
3073 MemberInfo *newMi=new MemberInfo(newMd,prot,mi->virt,mi->inherited);
3074 newMi->scopePath=mi->scopePath;
3075 newMi->ambigClass=mi->ambigClass;
3076 newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope;
3077 newMni->append(newMi);
3079 // also add the newly created member to the global members list
3083 QCString name = newMd->name();
3084 if ((mn=Doxygen::memberNameSDict->find(name)))
3090 mn = new MemberName(newMd->name());
3092 Doxygen::memberNameSDict->append(name,mn);
3096 newMd->setCategory(category);
3097 newMd->setCategoryRelation(mi->memberDef);
3098 mi->memberDef->setCategoryRelation(newMd);
3099 if (makePrivate || isExtension)
3101 newMd->makeImplementationDetail();
3103 internalInsertMember(newMd,prot,FALSE);
3106 // add it to the dictionary
3107 dstMnd->append(newMni->memberName(),newMni);
3113 //----------------------------------------------------------------------------
3115 void ClassDef::addUsedClass(ClassDef *cd,const char *accessName,
3118 static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
3119 static bool umlLook = Config_getBool("UML_LOOK");
3120 if (prot==Private && !extractPrivate) return;
3121 //printf("%s::addUsedClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
3122 if (m_impl->usesImplClassDict==0)
3124 m_impl->usesImplClassDict = new UsesClassDict(17);
3125 m_impl->usesImplClassDict->setAutoDelete(TRUE);
3127 UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
3130 ucd = new UsesClassDef(cd);
3131 m_impl->usesImplClassDict->insert(cd->name(),ucd);
3132 //printf("Adding used class %s to class %s via accessor %s\n",
3133 // cd->name().data(),name().data(),accessName);
3135 QCString acc = accessName;
3140 case Public: acc.prepend("+"); break;
3141 case Private: acc.prepend("-"); break;
3142 case Protected: acc.prepend("#"); break;
3143 case Package: acc.prepend("~"); break;
3146 ucd->addAccessor(acc);
3149 void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName,
3152 static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
3153 static bool umlLook = Config_getBool("UML_LOOK");
3154 if (prot==Private && !extractPrivate) return;
3155 //printf("%s::addUsedByClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
3156 if (m_impl->usedByImplClassDict==0)
3158 m_impl->usedByImplClassDict = new UsesClassDict(17);
3159 m_impl->usedByImplClassDict->setAutoDelete(TRUE);
3161 UsesClassDef *ucd=m_impl->usedByImplClassDict->find(cd->name());
3164 ucd = new UsesClassDef(cd);
3165 m_impl->usedByImplClassDict->insert(cd->name(),ucd);
3166 //printf("Adding used by class %s to class %s\n",
3167 // cd->name().data(),name().data());
3169 QCString acc = accessName;
3174 case Public: acc.prepend("+"); break;
3175 case Private: acc.prepend("-"); break;
3176 case Protected: acc.prepend("#"); break;
3177 case Package: acc.prepend("~"); break;
3180 ucd->addAccessor(acc);
3185 /*! Builds up a dictionary of all classes that are used by the state of this
3186 * class (the "implementation").
3187 * Must be called before mergeMembers() is called!
3190 void ClassDef::determineImplUsageRelation()
3192 MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
3193 MemberNameInfo *mni;
3194 for (;(mni=mnili.current());++mnili)
3196 MemberNameInfoIterator mnii(*mni);
3198 for (mnii.toFirst();(mi=mnii.current());++mnii)
3200 MemberDef *md=mi->memberDef;
3201 if (md->isVariable()) // for each member variable in this class
3203 QCString type=removeRedundantWhiteSpace(md->typeString());
3204 //printf("in class %s found var type=`%s' name=`%s'\n",
3205 // name().data(),type.data(),md->name().data());
3207 QCString usedClassName;
3210 while (extractClassNameFromType(type,pos,usedClassName,templSpec)!=-1 && !found)
3212 //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data());
3213 // check if usedClassName is a template argument of its class
3214 ClassDef *cd=md->getClassDef();
3215 if (cd && cd->templateArguments())
3217 ArgumentListIterator ali(*cd->templateArguments());
3220 for (ali.toFirst();(arg=ali.current());++ali,++count)
3222 if (arg->name==usedClassName) // type is a template argument
3225 if (m_impl->usesImplClassDict==0) m_impl->usesImplClassDict = new UsesClassDict(257);
3226 cd = new ClassDef(cd->getDefFileName(),cd->getDefLine(),
3227 usedClassName,ClassDef::Class);
3228 cd->setIsTemplateBaseClass(count);
3229 UsesClassDef *ucd = new UsesClassDef(cd);
3230 m_impl->usesImplClassDict->insert(cd->name(),ucd);
3231 ucd->templSpecifiers = templSpec;
3232 ucd->addAccessor(md->name());
3233 Doxygen::hiddenClasses.append(cd);
3234 //printf("Adding used template argument %s to class %s\n",
3235 // cd->name().data(),name().data());
3236 //printf("Adding accessor %s to class %s\n",
3237 // md->name().data(),ucd->classDef->name().data());
3245 if (getNamespaceDef()!=0)
3247 cd=getResolvedClass(getNamespaceDef()->name()+"::"+usedClassName,0,&templSpec);
3249 if (cd==0) cd=getResolvedClass(name()+"::"+usedClassName,0,&templSpec);
3250 if (cd==0) cd=getResolvedClass(usedClassName,0,&templSpec); // TODO: also try in-between scopes!
3251 //printf("Search for class %s result=%p\n",usedClassName.data(),cd);
3252 if (cd) // class exists
3255 if (m_impl->usesImplClassDict==0)
3257 m_impl->usesImplClassDict = new UsesClassDict(257);
3258 m_impl->usesImplClassDict->setAutoDelete(TRUE);
3260 UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
3261 if (ucd==0 || ucd->templSpecifiers!=templSpec)
3263 ucd = new UsesClassDef(cd);
3264 m_impl->usesImplClassDict->insert(cd->name(),ucd);
3265 ucd->templSpecifiers = templSpec;
3266 //printf("Adding used class %s to class %s\n",
3267 // cd->name().data(),name().data());
3269 ucd->addAccessor(md->name());
3270 //printf("Adding accessor %s to class %s\n",
3271 // md->name().data(),ucd->classDef->name().data());
3279 if (m_impl->usesClassDict)
3281 msg("Class %s uses the following classes:\n",name().data());
3282 UsesClassDictIterator ucdi(*m_impl->usesClassDict);
3284 for (;(ucd=ucdi.current());++ucdi)
3286 msg(" %s via ",ucd->classDef->name().data());
3287 QDictIterator<void> dvi(*ucd->accessors);
3289 for (;(s=dvi.currentKey());++dvi)
3299 //----------------------------------------------------------------------------
3301 // I have disabled this code because the graphs it renders quickly become
3302 // too large to be of practical use.
3304 void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr)
3306 QCString type = typeStr;
3307 static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
3309 while ((i=re.match(type,p,&l))!=-1) // for each class name in the type
3311 ClassDef *cd=getClass(name()+"::"+type.mid(i,l));
3312 if (cd==0) cd=getClass(type.mid(i,l)); // TODO: also try in-between scopes!
3313 if (cd && cd!=this && !isBaseClass(cd))
3315 if (m_impl->usesIntfClassDict==0)
3317 m_impl->usesIntfClassDict = new UsesClassDict(257);
3319 UsesClassDef *ucd=m_impl->usesIntfClassDict->find(cd->name());
3322 ucd = new UsesClassDef(cd);
3323 m_impl->usesIntfClassDict->insert(cd->name(),ucd);
3324 //printf("in class `%s' adding used intf class `%s'\n",
3325 // name().data(),cd->name().data());
3327 ucd->addAccessor(md->name());
3328 //printf("in class `%s' adding accessor `%s' to class `%s'\n",
3329 // name().data(),md->name().data(),ucd->classDef->name().data());
3335 void ClassDef::determineIntfUsageRelation()
3337 MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoList);
3338 MemberNameInfo *mni;
3339 for (;(mni=mnili.current());++mnili)
3341 MemberNameInfoIterator mnii(*mni);
3343 for (mnii.toFirst();(mi=mnii.current());++mnii)
3345 MemberDef *md=mi->memberDef;
3347 // compute the protection level for this member
3348 Protection protect=md->protection();
3349 if (mi->prot==Protected) // inherited protection
3351 if (protect==Public) protect=Protected;
3352 else if (protect==Protected) protect=Private;
3355 if (!md->name().isEmpty() && md->name()[0]!='@' &&
3356 (mi->prot!=Private && protect!=Private)
3359 // add classes found in the return type
3360 addUsedInterfaceClasses(md,md->typeString());
3361 ArgumentList *al = md->argumentList();
3362 if (al) // member has arguments
3364 // add classes found in the types of the argument list
3365 ArgumentListIterator ali(*al);
3367 for (;(a=ali.current());++ali)
3369 if (!a->type.isEmpty() && a->type.at(0)!='@')
3371 addUsedInterfaceClasses(md,a->type);
3381 QCString ClassDef::compoundTypeString() const
3383 if (getLanguage()==SrcLangExt_Fortran)
3385 switch (m_impl->compType)
3387 case Class: return "module";
3388 case Struct: return "type";
3389 case Union: return "union";
3390 case Interface: return "interface";
3391 case Protocol: return "protocol";
3392 case Category: return "category";
3393 case Exception: return "exception";
3394 default: return "unknown";
3399 switch (m_impl->compType)
3401 case Class: return isJavaEnum() ? "enum" : "class";
3402 case Struct: return "struct";
3403 case Union: return "union";
3404 case Interface: return getLanguage()==SrcLangExt_ObjC ? "class" : "interface";
3405 case Protocol: return "protocol";
3406 case Category: return "category";
3407 case Exception: return "exception";
3408 case Service: return "service";
3409 case Singleton: return "singleton";
3410 default: return "unknown";
3415 QCString ClassDef::getOutputFileBase() const
3417 static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
3418 static bool inlineSimpleClasses = Config_getBool("INLINE_SIMPLE_STRUCTS");
3419 if (!Doxygen::generatingXmlOutput)
3421 Definition *scope=0;
3422 if (inlineGroupedClasses && partOfGroups()!=0)
3424 // point to the group that embeds this class
3425 return partOfGroups()->at(0)->getOutputFileBase();
3427 else if (inlineSimpleClasses && m_impl->isSimple && partOfGroups()!=0)
3429 // point to simple struct inside a group
3430 return partOfGroups()->at(0)->getOutputFileBase();
3432 else if (inlineSimpleClasses && m_impl->isSimple && (scope=getOuterScope()))
3434 if (scope==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) // simple struct embedded in file
3436 return getFileDef()->getOutputFileBase();
3438 else if (scope->isLinkableInProject()) // simple struct embedded in other container (namespace/group/class)
3440 return getOuterScope()->getOutputFileBase();
3444 if (m_impl->templateMaster)
3446 // point to the template of which this class is an instance
3447 return m_impl->templateMaster->getOutputFileBase();
3449 else if (isReference())
3451 // point to the external location
3452 return m_impl->fileName;
3456 // normal locally defined class
3457 return convertNameToFile(m_impl->fileName);
3461 QCString ClassDef::getInstanceOutputFileBase() const
3465 return m_impl->fileName;
3469 return convertNameToFile(m_impl->fileName);
3473 QCString ClassDef::getFileBase() const
3475 if (m_impl->templateMaster)
3477 return m_impl->templateMaster->getFileBase();
3481 return m_impl->fileName;
3485 QCString ClassDef::getSourceFileBase() const
3487 if (m_impl->templateMaster)
3489 return m_impl->templateMaster->getSourceFileBase();
3493 return Definition::getSourceFileBase();
3497 void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
3500 //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data());
3501 if (m_impl->allMemberNameInfoSDict==0) return;
3502 MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
3503 MemberNameInfo *mni;
3504 for (;(mni=mnili.current());++mnili)
3506 MemberNameInfoIterator mnii(*mni);
3508 for (mnii.toFirst();(mi=mnii.current());++mnii)
3510 MemberDef *md=mi->memberDef;
3511 md->setGroupDef(gd,pri,fileName,startLine,hasDocs);
3512 gd->insertMember(md,TRUE);
3513 ClassDef *innerClass = md->getClassDefOfAnonymousType();
3514 if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);
3519 void ClassDef::addInnerCompound(Definition *d)
3521 //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data());
3522 if (d->definitionType()==Definition::TypeClass) // only classes can be
3523 // nested in classes.
3525 if (m_impl->innerClasses==0)
3527 m_impl->innerClasses = new ClassSDict(17);
3529 m_impl->innerClasses->inSort(d->localName(),(ClassDef *)d);
3533 Definition *ClassDef::findInnerCompound(const char *name)
3535 Definition *result=0;
3536 if (name==0) return 0;
3537 if (m_impl->innerClasses)
3539 result = m_impl->innerClasses->find(name);
3544 //void ClassDef::initTemplateMapping()
3546 // m_impl->templateMapping->clear();
3547 // ArgumentList *al = templateArguments();
3550 // ArgumentListIterator ali(*al);
3552 // for (ali.toFirst();(arg=ali.current());++ali)
3554 // setTemplateArgumentMapping(arg->name,arg->defval);
3558 //void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)
3560 // //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);
3561 // if (m_impl->templateMapping && formal)
3563 // if (m_impl->templateMapping->find(formal))
3565 // m_impl->templateMapping->remove(formal);
3567 // m_impl->templateMapping->insert(formal,new QCString(actual));
3571 //QCString ClassDef::getTemplateArgumentMapping(const char *formal) const
3573 // if (m_impl->templateMapping && formal)
3575 // QCString *s = m_impl->templateMapping->find(formal);
3584 ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,
3585 int startLine, int startColumn, const QCString &templSpec,bool &freshInstance)
3587 freshInstance = FALSE;
3588 if (m_impl->templateInstances==0)
3590 m_impl->templateInstances = new QDict<ClassDef>(17);
3592 ClassDef *templateClass=m_impl->templateInstances->find(templSpec);
3593 if (templateClass==0)
3595 Debug::print(Debug::Classes,0," New template instance class `%s'`%s'\n",name().data(),templSpec.data());
3596 QCString tcname = removeRedundantWhiteSpace(localName()+templSpec);
3597 templateClass = new ClassDef(
3598 fileName,startLine,startColumn,tcname,ClassDef::Class);
3599 templateClass->setTemplateMaster(this);
3600 templateClass->setOuterScope(getOuterScope());
3601 templateClass->setHidden(isHidden());
3602 m_impl->templateInstances->insert(templSpec,templateClass);
3605 return templateClass;
3608 ClassDef *ClassDef::getVariableInstance(const char *templSpec)
3610 if (m_impl->variableInstances==0)
3612 m_impl->variableInstances = new QDict<ClassDef>(17);
3613 m_impl->variableInstances->setAutoDelete(TRUE);
3615 ClassDef *templateClass=m_impl->variableInstances->find(templSpec);
3616 if (templateClass==0)
3618 Debug::print(Debug::Classes,0," New template variable instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec));
3619 QCString tcname = removeRedundantWhiteSpace(name()+templSpec);
3620 templateClass = new ClassDef("<code>",1,1,tcname,
3621 ClassDef::Class,0,0,FALSE);
3622 templateClass->addMembersToTemplateInstance( this, templSpec );
3623 templateClass->setTemplateMaster(this);
3624 m_impl->variableInstances->insert(templSpec,templateClass);
3626 return templateClass;
3629 void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames)
3631 if (templateNames==0) return;
3632 if (m_impl->templBaseClassNames==0)
3634 m_impl->templBaseClassNames = new QDict<int>(17);
3635 m_impl->templBaseClassNames->setAutoDelete(TRUE);
3637 // make a deep copy of the dictionary.
3638 QDictIterator<int> qdi(*templateNames);
3639 for (;qdi.current();++qdi)
3641 if (m_impl->templBaseClassNames->find(qdi.currentKey())==0)
3643 m_impl->templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));
3648 QDict<int> *ClassDef::getTemplateBaseClassNames() const
3650 return m_impl->templBaseClassNames;
3653 void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec)
3655 //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);
3656 if (cd->memberNameInfoSDict()==0) return;
3657 MemberNameInfoSDict::Iterator mnili(*cd->memberNameInfoSDict());
3658 MemberNameInfo *mni;
3659 for (;(mni=mnili.current());++mnili)
3661 MemberNameInfoIterator mnii(*mni);
3663 for (mnii.toFirst();(mi=mnii.current());++mnii)
3665 ArgumentList *actualArguments = new ArgumentList;
3666 stringToArgumentList(templSpec,actualArguments);
3667 MemberDef *md = mi->memberDef;
3668 MemberDef *imd = md->createTemplateInstanceMember(
3669 cd->templateArguments(),actualArguments);
3670 delete actualArguments;
3671 //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);
3672 imd->setMemberClass(this);
3673 imd->setTemplateMaster(md);
3674 imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
3675 imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
3676 imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
3677 imd->setMemberSpecifiers(md->getMemberSpecifiers());
3678 imd->setMemberGroupId(md->getMemberGroupId());
3680 //printf("Adding member=%s %s%s to class %s templSpec %s\n",
3681 // imd->typeString(),imd->name().data(),imd->argsString(),
3682 // imd->getClassDef()->name().data(),templSpec);
3683 // insert imd in the list of all members
3684 //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());
3685 MemberName *mn = Doxygen::memberNameSDict->find(imd->name());
3688 mn = new MemberName(imd->name());
3689 Doxygen::memberNameSDict->append(imd->name(),mn);
3696 QCString ClassDef::getReference() const
3698 if (m_impl->templateMaster)
3700 return m_impl->templateMaster->getReference();
3704 return Definition::getReference();
3708 bool ClassDef::isReference() const
3710 if (m_impl->templateMaster)
3712 return m_impl->templateMaster->isReference();
3716 return Definition::isReference();
3720 void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const
3722 Definition *d=getOuterScope();
3725 if (d->definitionType()==Definition::TypeClass)
3727 ClassDef *cd=(ClassDef *)d;
3728 cd->getTemplateParameterLists(lists);
3731 if (templateArguments())
3733 lists.append(templateArguments());
3737 QCString ClassDef::qualifiedNameWithTemplateParameters(
3738 QList<ArgumentList> *actualParams,int *actualParamIndex) const
3740 //static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
3741 static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
3742 //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());
3744 Definition *d=getOuterScope();
3747 if (d->definitionType()==Definition::TypeClass)
3749 ClassDef *cd=(ClassDef *)d;
3750 scName = cd->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex);
3752 else if (!hideScopeNames)
3754 scName = d->qualifiedName();
3758 SrcLangExt lang = getLanguage();
3759 QCString scopeSeparator = getLanguageSpecificSeparator(lang);
3760 if (!scName.isEmpty()) scName+=scopeSeparator;
3762 bool isSpecialization = localName().find('<')!=-1;
3764 QCString clName = className();
3765 //bool isGeneric = getLanguage()==SrcLangExt_CSharp;
3766 //if (isGeneric && clName.right(2)=="-g")
3768 // clName = clName.left(clName.length()-2);
3770 //printf("m_impl->lang=%d clName=%s\n",m_impl->lang,clName.data());
3773 if (templateArguments())
3775 if (actualParams && *actualParamIndex<(int)actualParams->count())
3777 al = actualParams->at(*actualParamIndex);
3778 if (!isSpecialization)
3780 scName+=tempArgListToString(al);
3782 (*actualParamIndex)++;
3786 if (!isSpecialization)
3788 scName+=tempArgListToString(templateArguments());
3792 //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());
3796 QCString ClassDef::className() const
3798 if (m_impl->className.isEmpty())
3804 return m_impl->className;
3808 void ClassDef::setClassName(const char *name)
3810 m_impl->className = name;
3813 void ClassDef::addListReferences()
3815 SrcLangExt lang = getLanguage();
3816 if (!isLinkableInProject()) return;
3817 //printf("ClassDef(%s)::addListReferences()\n",name().data());
3819 QList<ListItemInfo> *xrefItems = xrefListItems();
3820 addRefItem(xrefItems,
3822 lang==SrcLangExt_Fortran ? theTranslator->trType(TRUE,TRUE)
3823 : theTranslator->trClass(TRUE,TRUE),
3824 getOutputFileBase(),
3829 if (m_impl->memberGroupSDict)
3831 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
3833 for (;(mg=mgli.current());++mgli)
3835 mg->addListReferences(this);
3838 QListIterator<MemberList> mli(m_impl->memberLists);
3840 for (mli.toFirst();(ml=mli.current());++mli)
3842 if (ml->listType()&MemberListType_detailedLists)
3844 ml->addListReferences(this);
3849 MemberDef *ClassDef::getMemberByName(const QCString &name) const
3852 if (m_impl->allMemberNameInfoSDict)
3854 MemberNameInfo *mni = m_impl->allMemberNameInfoSDict->find(name);
3857 const int maxInheritanceDepth = 100000;
3858 int mdist=maxInheritanceDepth;
3859 MemberNameInfoIterator mnii(*mni);
3861 for (mnii.toFirst();(mi=mnii.current());++mnii)
3863 ClassDef *mcd=mi->memberDef->getClassDef();
3864 int m=minClassDistance(this,mcd);
3865 //printf("found member in %s linkable=%d m=%d\n",
3866 // mcd->name().data(),mcd->isLinkable(),m);
3867 if (m<mdist && mcd->isLinkable())
3875 //printf("getMemberByName(%s)=%p\n",name.data(),xmd);
3879 bool ClassDef::isAccessibleMember(MemberDef *md)
3881 return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);
3884 MemberList *ClassDef::createMemberList(MemberListType lt)
3886 m_impl->memberLists.setAutoDelete(TRUE);
3887 QListIterator<MemberList> mli(m_impl->memberLists);
3889 for (mli.toFirst();(ml=mli.current());++mli)
3891 if (ml->listType()==lt)
3896 // not found, create a new member list
3897 ml = new MemberList(lt);
3898 m_impl->memberLists.append(ml);
3902 MemberList *ClassDef::getMemberList(MemberListType lt)
3904 QListIterator<MemberList> mli(m_impl->memberLists);
3906 for (;(ml=mli.current());++mli)
3908 if (ml->listType()==lt)
3916 void ClassDef::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief)
3918 static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
3919 static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
3920 MemberList *ml = createMemberList(lt);
3921 ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));
3924 // for members in the declaration lists we set the section, needed for member grouping
3925 if ((ml->listType()&MemberListType_detailedLists)==0) md->setSectionList(this,ml);
3928 void ClassDef::sortMemberLists()
3930 QListIterator<MemberList> mli(m_impl->memberLists);
3932 for (;(ml=mli.current());++mli)
3934 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
3936 if (m_impl->innerClasses)
3938 m_impl->innerClasses->sort();
3942 int ClassDef::countMemberDeclarations(MemberListType lt,ClassDef *inheritedFrom,
3943 int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses)
3945 //printf("%s: countMemberDeclarations for %d and %d\n",name().data(),lt,lt2);
3947 MemberList * ml = getMemberList(lt);
3948 MemberList * ml2 = getMemberList((MemberListType)lt2);
3949 if (getLanguage()!=SrcLangExt_VHDL) // use specific declarations function
3953 ml->countDecMembers();
3954 count+=ml->numDecMembers();
3955 //printf("-> ml=%d\n",ml->numDecMembers());
3959 ml2->countDecMembers();
3960 count+=ml2->numDecMembers();
3961 //printf("-> ml2=%d\n",ml2->numDecMembers());
3963 // also include grouped members that have their own section in the class (see bug 722759)
3964 if (inheritedFrom && m_impl->memberGroupSDict)
3966 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
3968 for (;(mg=mgli.current());++mgli)
3970 count+=mg->countGroupedInheritedMembers(lt);
3971 if (lt2!=1) count+=mg->countGroupedInheritedMembers((MemberListType)lt2);
3974 static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
3975 if (!inlineInheritedMembers) // show inherited members as separate lists
3977 QPtrDict<void> visited(17);
3978 count+=countInheritedDecMembers(lt,inheritedFrom,invert,showAlways,visitedClasses);
3981 //printf("-> %d\n",count);
3986 int ClassDef::countInheritedDecMembers(MemberListType lt,
3987 ClassDef *inheritedFrom,bool invert,bool showAlways,
3988 QPtrDict<void> *visitedClasses)
3991 int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
3992 bool process = count>0;
3993 //printf("%s: countInheritedDecMembers: lt=%d process=%d count=%d invert=%d\n",
3994 // name().data(),lt,process,count,invert);
3995 if ((process^invert) || showAlways)
3997 if (m_impl->inherits)
3999 BaseClassListIterator it(*m_impl->inherits);
4001 for (it.toFirst();(ibcd=it.current());++it)
4003 ClassDef *icd=ibcd->classDef;
4005 if (icd->isLinkable())
4007 convertProtectionLevel(lt,ibcd->prot,<1,<2);
4008 //printf("%s: convert %d->(%d,%d) prot=%d\n",
4009 // icd->name().data(),lt,lt1,lt2,ibcd->prot);
4010 if (visitedClasses->find(icd)==0)
4012 visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
4015 inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
4025 void ClassDef::getTitleForMemberListType(MemberListType type,
4026 QCString &title,QCString &subtitle)
4028 SrcLangExt lang = getLanguage();
4029 QListIterator<LayoutDocEntry> eli(
4030 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
4031 LayoutDocEntry *lde;
4032 for (eli.toFirst();(lde=eli.current());++eli)
4034 if (lde->kind()==LayoutDocEntry::MemberDecl)
4036 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
4037 if (lmd->type==type)
4039 title = lmd->title(lang);
4040 subtitle = lmd->subtitle(lang);
4049 int ClassDef::countAdditionalInheritedMembers()
4052 QListIterator<LayoutDocEntry> eli(
4053 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
4054 LayoutDocEntry *lde;
4055 for (eli.toFirst();(lde=eli.current());++eli)
4057 if (lde->kind()==LayoutDocEntry::MemberDecl)
4059 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
4060 if (lmd->type!=MemberListType_friends) // friendship is not inherited
4062 //MemberList *ml = getMemberList(lmd->type);
4063 //if (ml==0 || ml->numDecMembers()==0)
4065 QPtrDict<void> visited(17);
4066 totalCount+=countInheritedDecMembers(lmd->type,this,TRUE,FALSE,&visited);
4071 //printf("countAdditonalInheritedMembers()=%d\n",totalCount);
4075 void ClassDef::writeAdditionalInheritedMembers(OutputList &ol)
4077 //printf("**** writeAdditionalInheritedMembers()\n");
4078 QListIterator<LayoutDocEntry> eli(
4079 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
4080 LayoutDocEntry *lde;
4081 for (eli.toFirst();(lde=eli.current());++eli)
4083 if (lde->kind()==LayoutDocEntry::MemberDecl)
4085 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
4086 if (lmd->type!=MemberListType_friends)
4088 QPtrDict<void> visited(17);
4089 writeInheritedMemberDeclarations(ol,lmd->type,-1,lmd->title(getLanguage()),this,TRUE,FALSE,&visited);
4095 int ClassDef::countMembersIncludingGrouped(MemberListType lt,
4096 ClassDef *inheritedFrom,bool additional)
4099 MemberList *ml = getMemberList(lt);
4102 count=ml->countInheritableMembers(inheritedFrom);
4104 //printf("%s:countMembersIncludingGrouped: count=%d\n",name().data(),count);
4105 if (m_impl->memberGroupSDict)
4107 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
4109 for (;(mg=mgli.current());++mgli)
4111 bool hasOwnSection = !mg->allMembersInSameSection() ||
4112 !m_impl->subGrouping; // group is in its own section
4113 if ((additional && hasOwnSection) || (!additional && !hasOwnSection))
4115 count+=mg->countGroupedInheritedMembers(lt);
4119 //printf("%s:countMembersIncludingGrouped(lt=%d,%s)=%d\n",
4120 // name().data(),lt,ml?ml->listTypeAsString(ml->listType()).data():"<none>",count);
4124 void ClassDef::writeInheritedMemberDeclarations(OutputList &ol,
4125 MemberListType lt,int lt2,const QCString &title,
4126 ClassDef *inheritedFrom,bool invert,bool showAlways,
4127 QPtrDict<void> *visitedClasses)
4129 ol.pushGeneratorState();
4130 ol.disableAllBut(OutputGenerator::Html);
4131 int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
4132 bool process = count>0;
4133 //printf("%s: writeInheritedMemberDec: lt=%d process=%d invert=%d always=%d\n",
4134 // name().data(),lt,process,invert,showAlways);
4135 if ((process^invert) || showAlways)
4137 if (m_impl->inherits)
4139 BaseClassListIterator it(*m_impl->inherits);
4141 for (it.toFirst();(ibcd=it.current());++it)
4143 ClassDef *icd=ibcd->classDef;
4144 if (icd->isLinkable())
4147 convertProtectionLevel(lt,ibcd->prot,<1,<3);
4148 if (lt2==-1 && lt3!=-1)
4152 //printf("%s:convert %d->(%d,%d) prot=%d\n",icd->name().data(),lt,lt1,lt2,ibcd->prot);
4153 if (visitedClasses->find(icd)==0)
4155 visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
4158 icd->writeMemberDeclarations(ol,(MemberListType)lt1,
4159 title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
4164 //printf("%s: class already visited!\n",icd->name().data());
4170 ol.popGeneratorState();
4173 void ClassDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title,
4174 const char *subTitle,bool showInline,ClassDef *inheritedFrom,int lt2,
4175 bool invert,bool showAlways,QPtrDict<void> *visitedClasses)
4177 //printf("%s: ClassDef::writeMemberDeclarations lt=%d lt2=%d\n",name().data(),lt,lt2);
4178 MemberList * ml = getMemberList(lt);
4179 MemberList * ml2 = getMemberList((MemberListType)lt2);
4180 if (getLanguage()==SrcLangExt_VHDL) // use specific declarations function
4184 VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this,0,0);
4189 //printf("%s::writeMemberDeclarations(%s) ml=%p ml2=%p\n",name().data(),title.data(),ml,ml2);
4190 QCString tt = title, st = subTitle;
4193 //printf(" writeDeclaration type=%d count=%d\n",lt,ml->numDecMembers());
4194 ml->writeDeclarations(ol,this,0,0,0,tt,st,definitionType(),FALSE,showInline,inheritedFrom,lt);
4200 //printf(" writeDeclaration type=%d count=%d\n",lt2,ml2->numDecMembers());
4201 ml2->writeDeclarations(ol,this,0,0,0,tt,st,definitionType(),FALSE,showInline,inheritedFrom,lt);
4203 static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
4204 if (!inlineInheritedMembers) // show inherited members as separate lists
4206 QPtrDict<void> visited(17);
4207 writeInheritedMemberDeclarations(ol,lt,lt2,title,
4208 inheritedFrom ? inheritedFrom : this,
4210 visitedClasses==0 ? &visited: visitedClasses);
4215 void ClassDef::addGroupedInheritedMembers(OutputList &ol,MemberListType lt,
4216 ClassDef *inheritedFrom,const QCString &inheritId)
4218 //printf("** %s::addGroupedInheritedMembers(%p) inheritId=%s\n",name().data(),m_impl->memberGroupSDict,inheritId.data());
4219 if (m_impl->memberGroupSDict)
4221 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
4223 for (;(mg=mgli.current());++mgli)
4225 if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
4227 mg->addGroupedInheritedMembers(ol,this,lt,inheritedFrom,inheritId);
4233 void ClassDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline)
4235 //printf("%s: ClassDef::writeMemberDocumentation()\n",name().data());
4236 MemberList * ml = getMemberList(lt);
4237 if (ml) ml->writeDocumentation(ol,displayName(),this,title,FALSE,showInline);
4240 void ClassDef::writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt)
4242 //printf("%s: ClassDef::writeSimpleMemberDocumentation()\n",name().data());
4243 MemberList * ml = getMemberList(lt);
4244 if (ml) ml->writeSimpleDocumentation(ol,this);
4247 void ClassDef::writePlainMemberDeclaration(OutputList &ol,
4248 MemberListType lt,bool inGroup,
4249 ClassDef *inheritedFrom,const char *inheritId)
4251 //printf("%s: ClassDef::writePlainMemberDeclaration()\n",name().data());
4252 MemberList * ml = getMemberList(lt);
4255 ml->setInGroup(inGroup);
4256 ml->writePlainDeclarations(ol,this,0,0,0,definitionType(),inheritedFrom,inheritId);
4260 bool ClassDef::isLocal() const
4262 return m_impl->isLocal;
4265 ClassSDict *ClassDef::getClassSDict()
4267 return m_impl->innerClasses;
4270 ClassDef::CompoundType ClassDef::compoundType() const
4272 return m_impl->compType;
4275 BaseClassList *ClassDef::baseClasses() const
4277 return m_impl->inherits;
4280 BaseClassList *ClassDef::subClasses() const
4282 return m_impl->inheritedBy;
4285 MemberNameInfoSDict *ClassDef::memberNameInfoSDict() const
4287 return m_impl->allMemberNameInfoSDict;
4290 Protection ClassDef::protection() const
4292 return m_impl->prot;
4295 ArgumentList *ClassDef::templateArguments() const
4297 return m_impl->tempArgs;
4300 NamespaceDef *ClassDef::getNamespaceDef() const
4302 return m_impl->nspace;
4305 FileDef *ClassDef::getFileDef() const
4307 return m_impl->fileDef;
4310 QDict<ClassDef> *ClassDef::getTemplateInstances() const
4312 return m_impl->templateInstances;
4315 ClassDef *ClassDef::templateMaster() const
4317 return m_impl->templateMaster;
4320 bool ClassDef::isTemplate() const
4322 return m_impl->tempArgs!=0;
4325 IncludeInfo *ClassDef::includeInfo() const
4327 return m_impl->incInfo;
4330 UsesClassDict *ClassDef::usedImplementationClasses() const
4332 return m_impl->usesImplClassDict;
4335 UsesClassDict *ClassDef::usedByImplementationClasses() const
4337 return m_impl->usedByImplClassDict;
4340 UsesClassDict *ClassDef::usedInterfaceClasses() const
4342 return m_impl->usesIntfClassDict;
4345 bool ClassDef::isTemplateArgument() const
4347 return m_impl->isTemplArg;
4350 bool ClassDef::isAbstract() const
4352 return m_impl->isAbstract || (m_impl->spec&Entry::Abstract);
4355 bool ClassDef::isFinal() const
4357 return m_impl->spec&Entry::Final;
4360 bool ClassDef::isSealed() const
4362 return m_impl->spec&Entry::Sealed;
4365 bool ClassDef::isPublished() const
4367 return m_impl->spec&Entry::Published;
4370 bool ClassDef::isForwardDeclared() const
4372 return m_impl->spec&Entry::ForwardDecl;
4375 bool ClassDef::isObjectiveC() const
4377 return getLanguage()==SrcLangExt_ObjC;
4380 bool ClassDef::isCSharp() const
4382 return getLanguage()==SrcLangExt_CSharp;
4385 ClassDef *ClassDef::categoryOf() const
4387 return m_impl->categoryOf;
4390 const QList<MemberList> &ClassDef::getMemberLists() const
4392 return m_impl->memberLists;
4395 MemberGroupSDict *ClassDef::getMemberGroupSDict() const
4397 return m_impl->memberGroupSDict;
4400 void ClassDef::setNamespace(NamespaceDef *nd)
4402 m_impl->nspace = nd;
4405 void ClassDef::setFileDef(FileDef *fd)
4410 void ClassDef::setSubGrouping(bool enabled)
4412 m_impl->subGrouping = enabled;
4415 void ClassDef::setProtection(Protection p)
4420 void ClassDef::setIsStatic(bool b)
4425 void ClassDef::setCompoundType(CompoundType t)
4427 m_impl->compType = t;
4430 void ClassDef::setTemplateMaster(ClassDef *tm)
4432 m_impl->templateMaster=tm;
4435 void ClassDef::makeTemplateArgument(bool b)
4437 m_impl->isTemplArg = b;
4440 void ClassDef::setCategoryOf(ClassDef *cd)
4442 m_impl->categoryOf = cd;
4445 void ClassDef::setUsedOnly(bool b)
4447 m_impl->usedOnly = b;
4450 bool ClassDef::isUsedOnly() const
4452 return m_impl->usedOnly;
4455 bool ClassDef::isSimple() const
4457 return m_impl->isSimple;
4460 MemberDef *ClassDef::isSmartPointer() const
4462 return m_impl->arrowOperator;
4465 void ClassDef::reclassifyMember(MemberDef *md,MemberType t)
4467 md->setMemberType(t);
4468 QListIterator<MemberList> mli(m_impl->memberLists);
4470 for (;(ml=mli.current());++mli)
4477 QCString ClassDef::anchor() const
4480 if (isEmbeddedInOuterScope() && !Doxygen::generatingXmlOutput)
4482 if (m_impl->templateMaster)
4484 // point to the template of which this class is an instance
4485 anc = m_impl->templateMaster->getOutputFileBase();
4487 else if (isReference())
4489 // point to the external location
4490 anc = m_impl->fileName;
4494 // normal locally defined class
4495 anc = convertNameToFile(m_impl->fileName);
4501 bool ClassDef::isEmbeddedInOuterScope() const
4503 static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
4504 static bool inlineSimpleClasses = Config_getBool("INLINE_SIMPLE_STRUCTS");
4506 Definition *container = getOuterScope();
4508 bool containerLinkable =
4511 (container==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) || // global class in documented file
4512 container->isLinkableInProject() // class in documented scope
4515 // inline because of INLINE_GROUPED_CLASSES=YES ?
4516 bool b1 = (inlineGroupedClasses && partOfGroups()!=0); // a grouped class
4517 // inline because of INLINE_SIMPLE_STRUCTS=YES ?
4518 bool b2 = (inlineSimpleClasses && m_impl->isSimple && // a simple class
4519 (containerLinkable || // in a documented container
4520 partOfGroups()!=0 // or part of a group
4523 //printf("%s::isEmbeddedInOuterScope(): inlineGroupedClasses=%d "
4524 // "inlineSimpleClasses=%d partOfGroups()=%p m_impl->isSimple=%d "
4525 // "getOuterScope()=%s b1=%d b2=%d\n",
4526 // name().data(),inlineGroupedClasses,inlineSimpleClasses,
4527 // partOfGroups().pointer(),m_impl->isSimple,getOuterScope()?getOuterScope()->name().data():"<none>",b1,b2);
4528 return b1 || b2; // either reason will do
4531 const ClassList *ClassDef::taggedInnerClasses() const
4533 return m_impl->taggedInnerClasses;
4536 void ClassDef::addTaggedInnerClass(ClassDef *cd)
4538 if (m_impl->taggedInnerClasses==0)
4540 m_impl->taggedInnerClasses = new ClassList;
4542 m_impl->taggedInnerClasses->append(cd);
4545 ClassDef *ClassDef::tagLessReference() const
4547 return m_impl->tagLessRef;
4550 void ClassDef::setTagLessReference(ClassDef *cd)
4552 m_impl->tagLessRef = cd;
4555 void ClassDef::removeMemberFromLists(MemberDef *md)
4557 QListIterator<MemberList> mli(m_impl->memberLists);
4559 for (;(ml=mli.current());++mli)
4565 bool ClassDef::isJavaEnum() const
4567 return m_impl->isJavaEnum;
4570 bool ClassDef::isGeneric() const
4572 return m_impl->isGeneric;
4575 void ClassDef::setClassSpecifier(uint64 spec)
4577 m_impl->spec = spec;
4580 bool ClassDef::isExtension() const
4582 QCString n = name();
4583 int si = n.find('(');
4584 int ei = n.find(')');
4585 bool b = ei>si && n.mid(si+1,ei-si-1).stripWhiteSpace().isEmpty();
4589 const ClassSDict *ClassDef::innerClasses() const
4591 return m_impl->innerClasses;
4594 const FileList &ClassDef::usedFiles() const
4596 return m_impl->files;
4599 const ArgumentList *ClassDef::typeConstraints() const
4601 return m_impl->typeConstraints;
4604 const ExampleSDict *ClassDef::exampleList() const
4606 return m_impl->exampleSDict;
4609 bool ClassDef::subGrouping() const
4611 return m_impl->subGrouping;
4614 void ClassDef::setName(const char *name)
4616 m_impl->isAnonymous = QCString(name).find('@')!=-1;
4617 Definition::setName(name);
4620 bool ClassDef::isAnonymous() const
4622 return m_impl->isAnonymous;