Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | /******************************************************************************␊ |
2 | *␊ |
3 | * $Id: classdef.cpp,v 1.54 2001/03/19 19:27:39 root Exp $␊ |
4 | *␊ |
5 | * Copyright (C) 1997-2011 by Dimitri van Heesch.␊ |
6 | *␊ |
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.␊ |
12 | *␊ |
13 | * Documents produced by Doxygen are derivative works derived from the␊ |
14 | * input used in their production; they are not affected by this license.␊ |
15 | *␊ |
16 | */␊ |
17 | ␊ |
18 | #include <stdio.h>␊ |
19 | #include <qfile.h>␊ |
20 | #include <qregexp.h>␊ |
21 | #include "classdef.h"␊ |
22 | #include "classlist.h"␊ |
23 | #include "entry.h"␊ |
24 | #include "doxygen.h"␊ |
25 | #include "membername.h"␊ |
26 | #include "message.h"␊ |
27 | #include "config.h"␊ |
28 | #include "util.h"␊ |
29 | #include "diagram.h"␊ |
30 | #include "language.h"␊ |
31 | #include "htmlhelp.h"␊ |
32 | #include "example.h"␊ |
33 | #include "outputlist.h"␊ |
34 | #include "dot.h"␊ |
35 | #include "defargs.h"␊ |
36 | #include "debug.h"␊ |
37 | #include "docparser.h"␊ |
38 | #include "searchindex.h"␊ |
39 | #include "vhdldocgen.h"␊ |
40 | #include "layout.h"␊ |
41 | ␊ |
42 | //-----------------------------------------------------------------------------␊ |
43 | ␊ |
44 | //static inline MemberList *createNewMemberList(MemberList::ListType lt)␊ |
45 | //{␊ |
46 | // MemberList *result = new MemberList(lt);␊ |
47 | // return result;␊ |
48 | //}␊ |
49 | ␊ |
50 | class ClassDefImpl␊ |
51 | {␊ |
52 | public:␊ |
53 | ClassDefImpl();␊ |
54 | ~ClassDefImpl();␊ |
55 | void init(const char *defFileName, const char *name,␊ |
56 | const QCString &ctStr, const char *fName);␊ |
57 | ␊ |
58 | /*! file name that forms the base for the output file containing the␊ |
59 | * class documentation. For compatibility with Qt (e.g. links via tag ␊ |
60 | * files) this name cannot be derived from the class name directly.␊ |
61 | */␊ |
62 | QCString fileName; ␊ |
63 | ␊ |
64 | /*! Include information about the header file should be included␊ |
65 | * in the documentation. 0 by default, set by setIncludeFile().␊ |
66 | */␊ |
67 | IncludeInfo *incInfo; ␊ |
68 | ␊ |
69 | /*! List of base class (or super-classes) from which this class derives␊ |
70 | * directly. ␊ |
71 | */␊ |
72 | BaseClassList *inherits;␊ |
73 | ␊ |
74 | /*! List of sub-classes that directly derive from this class ␊ |
75 | */␊ |
76 | BaseClassList *inheritedBy;␊ |
77 | ␊ |
78 | /*! Namespace this class is part of ␊ |
79 | * (this is the inner most namespace in case of nested namespaces)␊ |
80 | */␊ |
81 | NamespaceDef *nspace; ␊ |
82 | ␊ |
83 | /*! File this class is defined in */␊ |
84 | FileDef *fileDef;␊ |
85 | ␊ |
86 | /*! List of all members (including inherited members) */␊ |
87 | MemberNameInfoSDict *allMemberNameInfoSDict;␊ |
88 | ␊ |
89 | /*! Template arguments of this class */␊ |
90 | ArgumentList *tempArgs;␊ |
91 | ␊ |
92 | /*! Type constraints for template parameters */␊ |
93 | ArgumentList *typeConstraints;␊ |
94 | ␊ |
95 | /*! Files that were used for generating the class documentation. */␊ |
96 | QStrList files;␊ |
97 | ␊ |
98 | /*! Examples that use this class */␊ |
99 | ExampleSDict *exampleSDict;␊ |
100 | ␊ |
101 | /*! Holds the kind of "class" this is. */␊ |
102 | ClassDef::CompoundType compType;␊ |
103 | ␊ |
104 | /*! The protection level in which this class was found. ␊ |
105 | * Typically Public, but for nested classes this can also be Protected␊ |
106 | * or Private.␊ |
107 | */ ␊ |
108 | Protection prot;␊ |
109 | ␊ |
110 | /*! The inner classes contained in this class. Will be 0 if there are␊ |
111 | * no inner classes.␊ |
112 | */␊ |
113 | ClassSDict *innerClasses;␊ |
114 | ␊ |
115 | /* classes for the collaboration diagram */␊ |
116 | UsesClassDict *usesImplClassDict;␊ |
117 | UsesClassDict *usedByImplClassDict;␊ |
118 | UsesClassDict *usesIntfClassDict;␊ |
119 | ␊ |
120 | /*! Template instances that exists of this class, the key in the␊ |
121 | * dictionary is the template argument list.␊ |
122 | */ ␊ |
123 | QDict<ClassDef> *templateInstances;␊ |
124 | ␊ |
125 | /*! Template instances that exists of this class, as defined by variables.␊ |
126 | * We do NOT want to document these individually. The key in the␊ |
127 | * dictionary is the template argument list.␊ |
128 | */ ␊ |
129 | QDict<ClassDef> *variableInstances;␊ |
130 | ␊ |
131 | QDict<int> *templBaseClassNames;␊ |
132 | ␊ |
133 | /*! The class this class is an instance of. */␊ |
134 | ClassDef *templateMaster;␊ |
135 | ␊ |
136 | /*! local class name which could be a typedef'ed alias name. */␊ |
137 | QCString className;␊ |
138 | ␊ |
139 | /*! If this class is a Objective-C category, then this points to the␊ |
140 | * class which is extended.␊ |
141 | */␊ |
142 | ClassDef *categoryOf;␊ |
143 | ␊ |
144 | QList<MemberList> memberLists;␊ |
145 | ␊ |
146 | /* user defined member groups */␊ |
147 | MemberGroupSDict *memberGroupSDict;␊ |
148 | ␊ |
149 | /*! Is this an abstact class? */␊ |
150 | bool isAbstract;␊ |
151 | ␊ |
152 | /*! Is the class part of an unnamed namespace? */␊ |
153 | bool isStatic;␊ |
154 | ␊ |
155 | /*! Language used for this class */␊ |
156 | SrcLangExt lang;␊ |
157 | ␊ |
158 | /*! TRUE if classes members are merged with those of the base classes. */␊ |
159 | bool membersMerged;␊ |
160 | ␊ |
161 | /*! TRUE if the class is defined in a source file rather than a header file. */␊ |
162 | bool isLocal;␊ |
163 | ␊ |
164 | bool isTemplArg;␊ |
165 | ␊ |
166 | /*! Does this class group its user-grouped members␊ |
167 | * as a sub-section of the normal (public/protected/..) ␊ |
168 | * groups?␊ |
169 | */␊ |
170 | bool subGrouping; ␊ |
171 | ␊ |
172 | /** Reason of existance is a "use" relation */␊ |
173 | bool usedOnly;␊ |
174 | ␊ |
175 | /** List of titles to use for the summary */␊ |
176 | SDict<QCString> vhdlSummaryTitles;␊ |
177 | };␊ |
178 | ␊ |
179 | void ClassDefImpl::init(const char *defFileName, const char *name,␊ |
180 | const QCString &ctStr, const char *fName)␊ |
181 | {␊ |
182 | if (fName)␊ |
183 | {␊ |
184 | fileName=stripExtension(fName);␊ |
185 | }␊ |
186 | else␊ |
187 | {␊ |
188 | fileName=ctStr+name;␊ |
189 | }␊ |
190 | exampleSDict = 0;␊ |
191 | inherits = 0;␊ |
192 | inheritedBy = 0;␊ |
193 | allMemberNameInfoSDict = 0;␊ |
194 | incInfo=0;␊ |
195 | tempArgs=0;␊ |
196 | typeConstraints=0;␊ |
197 | prot=Public;␊ |
198 | nspace=0;␊ |
199 | fileDef=0;␊ |
200 | usesImplClassDict=0;␊ |
201 | usedByImplClassDict=0;␊ |
202 | usesIntfClassDict=0;␊ |
203 | memberGroupSDict = 0;␊ |
204 | innerClasses = 0;␊ |
205 | subGrouping=Config_getBool("SUBGROUPING");␊ |
206 | templateInstances = 0;␊ |
207 | variableInstances = 0;␊ |
208 | templateMaster =0;␊ |
209 | templBaseClassNames = 0;␊ |
210 | isAbstract = FALSE;␊ |
211 | isStatic = FALSE;␊ |
212 | isTemplArg = FALSE;␊ |
213 | membersMerged = FALSE;␊ |
214 | categoryOf = 0;␊ |
215 | usedOnly = FALSE;␊ |
216 | //QCString ns;␊ |
217 | //extractNamespaceName(name,className,ns);␊ |
218 | //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());␊ |
219 | ␊ |
220 | if (getLanguageFromFileName(defFileName)!=SrcLangExt_Java && ␊ |
221 | guessSection(defFileName)==Entry::SOURCE_SEC)␊ |
222 | {␊ |
223 | isLocal=TRUE;␊ |
224 | }␊ |
225 | else␊ |
226 | {␊ |
227 | isLocal=FALSE;␊ |
228 | }␊ |
229 | }␊ |
230 | ␊ |
231 | ClassDefImpl::ClassDefImpl() : vhdlSummaryTitles(17)␊ |
232 | {␊ |
233 | vhdlSummaryTitles.setAutoDelete(TRUE);␊ |
234 | }␊ |
235 | ␊ |
236 | ClassDefImpl::~ClassDefImpl()␊ |
237 | {␊ |
238 | delete inherits;␊ |
239 | delete inheritedBy;␊ |
240 | delete allMemberNameInfoSDict;␊ |
241 | delete exampleSDict;␊ |
242 | delete usesImplClassDict;␊ |
243 | delete usedByImplClassDict;␊ |
244 | delete usesIntfClassDict;␊ |
245 | delete incInfo;␊ |
246 | delete memberGroupSDict;␊ |
247 | delete innerClasses;␊ |
248 | delete templateInstances;␊ |
249 | delete variableInstances;␊ |
250 | delete templBaseClassNames;␊ |
251 | delete tempArgs;␊ |
252 | delete typeConstraints;␊ |
253 | }␊ |
254 | ␊ |
255 | // constructs a new class definition␊ |
256 | ClassDef::ClassDef(␊ |
257 | const char *defFileName,int defLine,␊ |
258 | const char *nm,CompoundType ct,␊ |
259 | const char *lref,const char *fName,␊ |
260 | bool isSymbol) ␊ |
261 | : Definition(defFileName,defLine,removeRedundantWhiteSpace(nm),0,0,isSymbol) ␊ |
262 | {␊ |
263 | visited=FALSE;␊ |
264 | setReference(lref);␊ |
265 | m_impl = new ClassDefImpl;␊ |
266 | m_impl->compType = ct;␊ |
267 | m_impl->lang = SrcLangExt_Unknown;␊ |
268 | m_impl->init(defFileName,name(),compoundTypeString(),fName);␊ |
269 | ␊ |
270 | }␊ |
271 | ␊ |
272 | // destroy the class definition␊ |
273 | ClassDef::~ClassDef()␊ |
274 | {␊ |
275 | delete m_impl;␊ |
276 | }␊ |
277 | ␊ |
278 | QCString ClassDef::getMemberListFileName() const␊ |
279 | {␊ |
280 | return convertNameToFile(compoundTypeString()+name()+"-members");␊ |
281 | }␊ |
282 | ␊ |
283 | QCString ClassDef::displayName() const␊ |
284 | {␊ |
285 | static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");␊ |
286 | static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");␊ |
287 | QCString n;␊ |
288 | if (vhdlOpt)␊ |
289 | {␊ |
290 | n = VhdlDocGen::getClassName(this);␊ |
291 | }␊ |
292 | else ␊ |
293 | {␊ |
294 | n=qualifiedNameWithTemplateParameters();␊ |
295 | }␊ |
296 | if (optimizeOutputForJava)␊ |
297 | {␊ |
298 | n=substitute(n,"::",".");␊ |
299 | }␊ |
300 | if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p")␊ |
301 | {␊ |
302 | n="<"+n.left(n.length()-2)+">";␊ |
303 | }␊ |
304 | //printf("ClassDef::displayName()=%s\n",n.data());␊ |
305 | return n;␊ |
306 | }␊ |
307 | ␊ |
308 | // inserts a base class in the inheritance list␊ |
309 | void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p,␊ |
310 | Specifier s,const char *t)␊ |
311 | {␊ |
312 | //printf("*** insert base class %s into %s\n",cd->name().data(),name().data());␊ |
313 | //inherits->inSort(new BaseClassDef(cd,p,s,t));␊ |
314 | if (m_impl->inherits==0)␊ |
315 | {␊ |
316 | m_impl->inherits = new BaseClassList;␊ |
317 | m_impl->inherits->setAutoDelete(TRUE);␊ |
318 | }␊ |
319 | m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));␊ |
320 | }␊ |
321 | ␊ |
322 | // inserts a sub class in the inherited list␊ |
323 | void ClassDef::insertSubClass(ClassDef *cd,Protection p,␊ |
324 | Specifier s,const char *t)␊ |
325 | {␊ |
326 | //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());␊ |
327 | if (m_impl->inheritedBy==0)␊ |
328 | {␊ |
329 | m_impl->inheritedBy = new BaseClassList;␊ |
330 | m_impl->inheritedBy->setAutoDelete(TRUE);␊ |
331 | }␊ |
332 | m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));␊ |
333 | }␊ |
334 | ␊ |
335 | void ClassDef::addMembersToMemberGroup()␊ |
336 | {␊ |
337 | QListIterator<MemberList> mli(m_impl->memberLists);␊ |
338 | MemberList *ml;␊ |
339 | for (mli.toFirst();(ml=mli.current());++mli)␊ |
340 | {␊ |
341 | if ((ml->listType()&MemberList::detailedLists)==0)␊ |
342 | {␊ |
343 | ::addMembersToMemberGroup(ml,&m_impl->memberGroupSDict,this);␊ |
344 | }␊ |
345 | }␊ |
346 | ␊ |
347 | // add members inside sections to their groups␊ |
348 | if (m_impl->memberGroupSDict)␊ |
349 | {␊ |
350 | MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);␊ |
351 | MemberGroup *mg;␊ |
352 | for (;(mg=mgli.current());++mgli)␊ |
353 | {␊ |
354 | if (mg->allMembersInSameSection() && m_impl->subGrouping) ␊ |
355 | {␊ |
356 | //printf("addToDeclarationSection(%s)\n",mg->header().data());␊ |
357 | mg->addToDeclarationSection();␊ |
358 | }␊ |
359 | }␊ |
360 | }␊ |
361 | }␊ |
362 | ␊ |
363 | // adds new member definition to the class␊ |
364 | void ClassDef::internalInsertMember(MemberDef *md,␊ |
365 | Protection prot,␊ |
366 | bool addToAllList␊ |
367 | )␊ |
368 | {␊ |
369 | //printf("insertInternalMember(%s) isHidden()=%d\n",md->name().data(),md->isHidden());␊ |
370 | if (md->isHidden()) return;␊ |
371 | ␊ |
372 | static bool optVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");␊ |
373 | if (optVhdl)␊ |
374 | {␊ |
375 | QCString title=VhdlDocGen::trVhdlType(md->getMemberSpecifiers(),FALSE);␊ |
376 | if (!m_impl->vhdlSummaryTitles.find(title))␊ |
377 | {␊ |
378 | m_impl->vhdlSummaryTitles.append(title,new QCString(title));␊ |
379 | }␊ |
380 | }␊ |
381 | ␊ |
382 | if (!isReference())␊ |
383 | {␊ |
384 | static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");␊ |
385 | ␊ |
386 | /********************************************/␊ |
387 | /* insert member in the declaration section */␊ |
388 | /********************************************/␊ |
389 | if (md->isRelated() && (extractPrivate || prot!=Private))␊ |
390 | {␊ |
391 | addMemberToList(MemberList::related,md,TRUE);␊ |
392 | }␊ |
393 | else if (md->isFriend())␊ |
394 | {␊ |
395 | addMemberToList(MemberList::friends,md,TRUE);␊ |
396 | }␊ |
397 | else␊ |
398 | {␊ |
399 | switch (md->memberType())␊ |
400 | {␊ |
401 | case MemberDef::Signal: // Qt specific␊ |
402 | addMemberToList(MemberList::signals,md,TRUE);␊ |
403 | break;␊ |
404 | case MemberDef::DCOP: // KDE2 specific␊ |
405 | addMemberToList(MemberList::dcopMethods,md,TRUE);␊ |
406 | break;␊ |
407 | case MemberDef::Property:␊ |
408 | addMemberToList(MemberList::properties,md,TRUE);␊ |
409 | break;␊ |
410 | case MemberDef::Event:␊ |
411 | addMemberToList(MemberList::events,md,TRUE);␊ |
412 | break;␊ |
413 | case MemberDef::Slot: // Qt specific␊ |
414 | switch (prot)␊ |
415 | {␊ |
416 | case Protected: ␊ |
417 | case Package: // slots in packages are not possible!␊ |
418 | addMemberToList(MemberList::proSlots,md,TRUE);␊ |
419 | break;␊ |
420 | case Public: ␊ |
421 | addMemberToList(MemberList::pubSlots,md,TRUE);␊ |
422 | break;␊ |
423 | case Private: ␊ |
424 | addMemberToList(MemberList::priSlots,md,TRUE);␊ |
425 | break;␊ |
426 | }␊ |
427 | break;␊ |
428 | default: // any of the other members␊ |
429 | if (md->isStatic())␊ |
430 | {␊ |
431 | if (md->isVariable())␊ |
432 | {␊ |
433 | switch (prot)␊ |
434 | {␊ |
435 | case Protected: ␊ |
436 | addMemberToList(MemberList::proStaticAttribs,md,TRUE);␊ |
437 | break;␊ |
438 | case Package: ␊ |
439 | addMemberToList(MemberList::pacStaticAttribs,md,TRUE);␊ |
440 | break;␊ |
441 | case Public: ␊ |
442 | addMemberToList(MemberList::pubStaticAttribs,md,TRUE);␊ |
443 | break;␊ |
444 | case Private: ␊ |
445 | addMemberToList(MemberList::priStaticAttribs,md,TRUE);␊ |
446 | break;␊ |
447 | }␊ |
448 | }␊ |
449 | else // function␊ |
450 | {␊ |
451 | switch (prot)␊ |
452 | {␊ |
453 | case Protected: ␊ |
454 | addMemberToList(MemberList::proStaticMethods,md,TRUE);␊ |
455 | break;␊ |
456 | case Package: ␊ |
457 | addMemberToList(MemberList::pacStaticMethods,md,TRUE);␊ |
458 | break;␊ |
459 | case Public: ␊ |
460 | addMemberToList(MemberList::pubStaticMethods,md,TRUE);␊ |
461 | break;␊ |
462 | case Private: ␊ |
463 | addMemberToList(MemberList::priStaticMethods,md,TRUE);␊ |
464 | break;␊ |
465 | }␊ |
466 | }␊ |
467 | }␊ |
468 | else // not static␊ |
469 | {␊ |
470 | if (md->isVariable())␊ |
471 | {␊ |
472 | switch (prot)␊ |
473 | {␊ |
474 | case Protected: ␊ |
475 | addMemberToList(MemberList::proAttribs,md,TRUE);␊ |
476 | break;␊ |
477 | case Package:␊ |
478 | addMemberToList(MemberList::pacAttribs,md,TRUE);␊ |
479 | break;␊ |
480 | case Public: ␊ |
481 | addMemberToList(MemberList::pubAttribs,md,TRUE);␊ |
482 | break;␊ |
483 | case Private: ␊ |
484 | addMemberToList(MemberList::priAttribs,md,TRUE);␊ |
485 | break;␊ |
486 | }␊ |
487 | }␊ |
488 | else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())␊ |
489 | {␊ |
490 | switch (prot)␊ |
491 | {␊ |
492 | case Protected: ␊ |
493 | addMemberToList(MemberList::proTypes,md,TRUE);␊ |
494 | break;␊ |
495 | case Package: ␊ |
496 | addMemberToList(MemberList::pacTypes,md,TRUE);␊ |
497 | break;␊ |
498 | case Public: ␊ |
499 | addMemberToList(MemberList::pubTypes,md,TRUE);␊ |
500 | break;␊ |
501 | case Private: ␊ |
502 | addMemberToList(MemberList::priTypes,md,TRUE);␊ |
503 | break;␊ |
504 | }␊ |
505 | }␊ |
506 | else // member function␊ |
507 | {␊ |
508 | switch (prot)␊ |
509 | {␊ |
510 | case Protected: ␊ |
511 | addMemberToList(MemberList::proMethods,md,TRUE);␊ |
512 | break;␊ |
513 | case Package: ␊ |
514 | addMemberToList(MemberList::pacMethods,md,TRUE);␊ |
515 | break;␊ |
516 | case Public: ␊ |
517 | addMemberToList(MemberList::pubMethods,md,TRUE);␊ |
518 | break;␊ |
519 | case Private: ␊ |
520 | addMemberToList(MemberList::priMethods,md,TRUE);␊ |
521 | break;␊ |
522 | }␊ |
523 | }␊ |
524 | }␊ |
525 | break; ␊ |
526 | }␊ |
527 | }␊ |
528 | ␊ |
529 | /*******************************************************/␊ |
530 | /* insert member in the detailed documentation section */␊ |
531 | /*******************************************************/␊ |
532 | if ((md->isRelated() && (extractPrivate || prot!=Private)) || md->isFriend())␊ |
533 | {␊ |
534 | addMemberToList(MemberList::relatedMembers,md,FALSE);␊ |
535 | }␊ |
536 | else␊ |
537 | {␊ |
538 | switch (md->memberType())␊ |
539 | {␊ |
540 | case MemberDef::Property:␊ |
541 | addMemberToList(MemberList::propertyMembers,md,FALSE);␊ |
542 | break;␊ |
543 | case MemberDef::Event:␊ |
544 | addMemberToList(MemberList::eventMembers,md,FALSE);␊ |
545 | break;␊ |
546 | case MemberDef::Signal: // fall through␊ |
547 | case MemberDef::DCOP:␊ |
548 | addMemberToList(MemberList::functionMembers,md,FALSE);␊ |
549 | break;␊ |
550 | case MemberDef::Slot:␊ |
551 | switch (prot)␊ |
552 | {␊ |
553 | case Protected: ␊ |
554 | case Package: ␊ |
555 | case Public: ␊ |
556 | addMemberToList(MemberList::functionMembers,md,FALSE);␊ |
557 | break;␊ |
558 | case Private: ␊ |
559 | if (extractPrivate)␊ |
560 | {␊ |
561 | addMemberToList(MemberList::functionMembers,md,FALSE);␊ |
562 | }␊ |
563 | break;␊ |
564 | }␊ |
565 | break;␊ |
566 | default: // any of the other members␊ |
567 | if (prot!=Private || extractPrivate)␊ |
568 | {␊ |
569 | switch (md->memberType())␊ |
570 | {␊ |
571 | case MemberDef::Typedef:␊ |
572 | addMemberToList(MemberList::typedefMembers,md,FALSE);␊ |
573 | break;␊ |
574 | case MemberDef::Enumeration:␊ |
575 | addMemberToList(MemberList::enumMembers,md,FALSE);␊ |
576 | break;␊ |
577 | case MemberDef::EnumValue:␊ |
578 | addMemberToList(MemberList::enumValMembers,md,FALSE);␊ |
579 | break;␊ |
580 | case MemberDef::Function:␊ |
581 | if (md->isConstructor() || md->isDestructor())␊ |
582 | {␊ |
583 | MemberList *ml = createMemberList(MemberList::constructors);␊ |
584 | ml->append(md);␊ |
585 | }␊ |
586 | else␊ |
587 | {␊ |
588 | addMemberToList(MemberList::functionMembers,md,FALSE);␊ |
589 | }␊ |
590 | break;␊ |
591 | case MemberDef::Variable:␊ |
592 | addMemberToList(MemberList::variableMembers,md,FALSE);␊ |
593 | break;␊ |
594 | default:␊ |
595 | err("Unexpected member type %d found!\n",md->memberType());␊ |
596 | }␊ |
597 | }␊ |
598 | break; ␊ |
599 | }␊ |
600 | }␊ |
601 | ␊ |
602 | /*************************************************/␊ |
603 | /* insert member in the appropriate member group */␊ |
604 | /*************************************************/␊ |
605 | // Note: this must be done AFTER inserting the member in the ␊ |
606 | // regular groups␊ |
607 | //addMemberToGroup(md,groupId);␊ |
608 | ␊ |
609 | }␊ |
610 | ␊ |
611 | if (md->virtualness()==Pure)␊ |
612 | {␊ |
613 | m_impl->isAbstract=TRUE;␊ |
614 | }␊ |
615 | ␊ |
616 | //::addClassMemberNameToIndex(md);␊ |
617 | if (addToAllList && ␊ |
618 | !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&␊ |
619 | md->isFriend() &&␊ |
620 | (QCString(md->typeString())=="friend class" || ␊ |
621 | QCString(md->typeString())=="friend struct" ||␊ |
622 | QCString(md->typeString())=="friend union")))␊ |
623 | {␊ |
624 | //printf("=======> adding member %s to class %s\n",md->name().data(),name().data());␊ |
625 | MemberInfo *mi = new MemberInfo((MemberDef *)md,␊ |
626 | prot,md->virtualness(),FALSE);␊ |
627 | MemberNameInfo *mni=0;␊ |
628 | if (m_impl->allMemberNameInfoSDict==0)␊ |
629 | {␊ |
630 | m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);␊ |
631 | m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);␊ |
632 | }␊ |
633 | if ((mni=m_impl->allMemberNameInfoSDict->find(md->name())))␊ |
634 | {␊ |
635 | mni->append(mi);␊ |
636 | }␊ |
637 | else␊ |
638 | {␊ |
639 | mni = new MemberNameInfo(md->name());␊ |
640 | mni->append(mi);␊ |
641 | m_impl->allMemberNameInfoSDict->append(mni->memberName(),mni);␊ |
642 | }␊ |
643 | }␊ |
644 | }␊ |
645 | ␊ |
646 | void ClassDef::insertMember(MemberDef *md)␊ |
647 | {␊ |
648 | internalInsertMember(md,md->protection(),TRUE);␊ |
649 | }␊ |
650 | ␊ |
651 | // compute the anchors for all members␊ |
652 | void ClassDef::computeAnchors()␊ |
653 | {␊ |
654 | ClassDef *context = Config_getBool("INLINE_INHERITED_MEMB") ? this : 0;␊ |
655 | const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";␊ |
656 | QListIterator<MemberList> mli(m_impl->memberLists);␊ |
657 | MemberList *ml;␊ |
658 | int index = 0;␊ |
659 | for (mli.toFirst();(ml=mli.current());++mli)␊ |
660 | {␊ |
661 | if ((ml->listType()&MemberList::detailedLists)==0)␊ |
662 | {␊ |
663 | setAnchors(context,letters[index++],ml);␊ |
664 | }␊ |
665 | }␊ |
666 | ␊ |
667 | if (m_impl->memberGroupSDict)␊ |
668 | {␊ |
669 | MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);␊ |
670 | MemberGroup *mg;␊ |
671 | for (;(mg=mgli.current());++mgli)␊ |
672 | {␊ |
673 | mg->setAnchors(context);␊ |
674 | }␊ |
675 | }␊ |
676 | }␊ |
677 | ␊ |
678 | void ClassDef::distributeMemberGroupDocumentation()␊ |
679 | {␊ |
680 | if (m_impl->memberGroupSDict)␊ |
681 | {␊ |
682 | MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);␊ |
683 | MemberGroup *mg;␊ |
684 | for (;(mg=mgli.current());++mgli)␊ |
685 | {␊ |
686 | mg->distributeMemberGroupDocumentation();␊ |
687 | }␊ |
688 | }␊ |
689 | }␊ |
690 | ␊ |
691 | void ClassDef::findSectionsInDocumentation()␊ |
692 | {␊ |
693 | docFindSections(documentation(),this,0,docFile());␊ |
694 | if (m_impl->memberGroupSDict)␊ |
695 | {␊ |
696 | MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);␊ |
697 | MemberGroup *mg;␊ |
698 | for (;(mg=mgli.current());++mgli)␊ |
699 | {␊ |
700 | mg->findSectionsInDocumentation();␊ |
701 | }␊ |
702 | }␊ |
703 | QListIterator<MemberList> mli(m_impl->memberLists);␊ |
704 | MemberList *ml;␊ |
705 | for (mli.toFirst();(ml=mli.current());++mli)␊ |
706 | {␊ |
707 | if ((ml->listType()&MemberList::detailedLists)==0)␊ |
708 | {␊ |
709 | ml->findSectionsInDocumentation();␊ |
710 | }␊ |
711 | }␊ |
712 | }␊ |
713 | ␊ |
714 | ␊ |
715 | // add a file name to the used files set␊ |
716 | void ClassDef::insertUsedFile(const char *f)␊ |
717 | {␊ |
718 | if (m_impl->files.find(f)==-1) m_impl->files.append(f);␊ |
719 | if (m_impl->templateInstances)␊ |
720 | {␊ |
721 | QDictIterator<ClassDef> qdi(*m_impl->templateInstances);␊ |
722 | ClassDef *cd;␊ |
723 | for (qdi.toFirst();(cd=qdi.current());++qdi)␊ |
724 | {␊ |
725 | cd->insertUsedFile(f);␊ |
726 | }␊ |
727 | }␊ |
728 | }␊ |
729 | ␊ |
730 | static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd)␊ |
731 | {␊ |
732 | if (bcd->prot!=Public || bcd->virt!=Normal)␊ |
733 | {␊ |
734 | ol.startTypewriter();␊ |
735 | ol.docify(" [");␊ |
736 | QStrList sl;␊ |
737 | if (bcd->prot==Protected) sl.append("protected");␊ |
738 | else if (bcd->prot==Private) sl.append("private");␊ |
739 | if (bcd->virt==Virtual) sl.append("virtual");␊ |
740 | const char *s=sl.first();␊ |
741 | while (s)␊ |
742 | {␊ |
743 | ol.docify(s);␊ |
744 | s=sl.next();␊ |
745 | if (s) ol.docify(", ");␊ |
746 | }␊ |
747 | ol.docify("]");␊ |
748 | ol.endTypewriter();␊ |
749 | }␊ |
750 | }␊ |
751 | ␊ |
752 | void ClassDef::setIncludeFile(FileDef *fd,␊ |
753 | const char *includeName,bool local, bool force)␊ |
754 | {␊ |
755 | //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);␊ |
756 | if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo;␊ |
757 | if ((includeName && m_impl->incInfo->includeName.isEmpty()) ||␊ |
758 | (fd!=0 && m_impl->incInfo->fileDef==0)␊ |
759 | )␊ |
760 | {␊ |
761 | //printf("Setting file info\n");␊ |
762 | m_impl->incInfo->fileDef = fd;␊ |
763 | m_impl->incInfo->includeName = includeName;␊ |
764 | m_impl->incInfo->local = local;␊ |
765 | }␊ |
766 | if (force && includeName) m_impl->incInfo->includeName = includeName;␊ |
767 | }␊ |
768 | ␊ |
769 | // TODO: fix this: a nested template class can have multiple outer templates␊ |
770 | //ArgumentList *ClassDef::outerTemplateArguments() const␊ |
771 | //{␊ |
772 | // int ti;␊ |
773 | // ClassDef *pcd=0;␊ |
774 | // int pi=0;␊ |
775 | // if (m_impl->tempArgs) return m_impl->tempArgs;␊ |
776 | // // find the outer most class scope␊ |
777 | // while ((ti=name().find("::",pi))!=-1 && ␊ |
778 | // (pcd=getClass(name().left(ti)))==0␊ |
779 | // ) pi=ti+2;␊ |
780 | // if (pcd)␊ |
781 | // {␊ |
782 | // return pcd->templateArguments();␊ |
783 | // }␊ |
784 | // return 0;␊ |
785 | //}␊ |
786 | ␊ |
787 | static void searchTemplateSpecs(/*in*/ Definition *d,␊ |
788 | /*out*/ QList<ArgumentList> &result,␊ |
789 | /*out*/ QCString &name)␊ |
790 | {␊ |
791 | if (d->definitionType()==Definition::TypeClass)␊ |
792 | {␊ |
793 | if (d->getOuterScope())␊ |
794 | {␊ |
795 | searchTemplateSpecs(d->getOuterScope(),result,name);␊ |
796 | }␊ |
797 | ClassDef *cd=(ClassDef *)d;␊ |
798 | if (!name.isEmpty()) name+="::";␊ |
799 | QCString clName = d->localName();␊ |
800 | if (clName.right(2)=="-g" || clName.right(2)=="-p")␊ |
801 | {␊ |
802 | clName = clName.left(clName.length()-2);␊ |
803 | }␊ |
804 | name+=clName;␊ |
805 | bool isSpecialization = d->localName().find('<')!=-1;␊ |
806 | if (cd->templateArguments()) ␊ |
807 | {␊ |
808 | result.append(cd->templateArguments());␊ |
809 | if (!isSpecialization)␊ |
810 | {␊ |
811 | name+=tempArgListToString(cd->templateArguments());␊ |
812 | }␊ |
813 | }␊ |
814 | }␊ |
815 | else␊ |
816 | {␊ |
817 | name+=d->qualifiedName();␊ |
818 | }␊ |
819 | }␊ |
820 | ␊ |
821 | static void writeTemplateSpec(OutputList &ol,Definition *d,␊ |
822 | const QCString &type)␊ |
823 | {␊ |
824 | QList<ArgumentList> specs;␊ |
825 | QCString name;␊ |
826 | searchTemplateSpecs(d,specs,name);␊ |
827 | if (specs.count()>0) // class has template scope specifiers␊ |
828 | {␊ |
829 | ol.startSubsubsection(); ␊ |
830 | QListIterator<ArgumentList> spi(specs);␊ |
831 | ArgumentList *al;␊ |
832 | for (spi.toFirst();(al=spi.current());++spi)␊ |
833 | {␊ |
834 | ol.docify("template<");␊ |
835 | Argument *a=al->first();␊ |
836 | while (a)␊ |
837 | {␊ |
838 | ol.docify(a->type);␊ |
839 | if (!a->name.isEmpty())␊ |
840 | {␊ |
841 | ol.docify(" ");␊ |
842 | ol.docify(a->name);␊ |
843 | }␊ |
844 | if (a->defval.length()!=0)␊ |
845 | {␊ |
846 | ol.docify(" = ");␊ |
847 | ol.docify(a->defval);␊ |
848 | } ␊ |
849 | a=al->next();␊ |
850 | if (a) ol.docify(", ");␊ |
851 | }␊ |
852 | ol.docify(">");␊ |
853 | ol.pushGeneratorState();␊ |
854 | ol.disableAllBut(OutputGenerator::Html);␊ |
855 | ol.lineBreak();␊ |
856 | ol.popGeneratorState();␊ |
857 | }␊ |
858 | ol.docify(type.lower()+" "+name);␊ |
859 | ol.endSubsubsection();␊ |
860 | ol.writeString("\n");␊ |
861 | }␊ |
862 | }␊ |
863 | ␊ |
864 | void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag)␊ |
865 | {␊ |
866 | if (!briefDescription().isEmpty())␊ |
867 | {␊ |
868 | ol.startParagraph();␊ |
869 | ol.parseDoc(briefFile(),briefLine(),this,0,␊ |
870 | briefDescription(),TRUE,FALSE,0,TRUE,FALSE);␊ |
871 | ol.pushGeneratorState();␊ |
872 | ol.disable(OutputGenerator::RTF);␊ |
873 | ol.writeString(" \n");␊ |
874 | ol.enable(OutputGenerator::RTF);␊ |
875 | ol.popGeneratorState();␊ |
876 | ␊ |
877 | if (Config_getBool("REPEAT_BRIEF") || ␊ |
878 | !documentation().isEmpty() || ␊ |
879 | exampleFlag␊ |
880 | )␊ |
881 | {␊ |
882 | writeMoreLink(ol,anchor());␊ |
883 | }␊ |
884 | ␊ |
885 | //ol.pushGeneratorState();␊ |
886 | //ol.disable(OutputGenerator::RTF);␊ |
887 | //ol.newParagraph(); // FIXME:PARA␊ |
888 | //ol.popGeneratorState();␊ |
889 | ol.endParagraph();␊ |
890 | }␊ |
891 | ol.writeSynopsis();␊ |
892 | }␊ |
893 | ␊ |
894 | void ClassDef::writeDetailedDocumentationBody(OutputList &ol)␊ |
895 | {␊ |
896 | static bool repeatBrief = Config_getBool("REPEAT_BRIEF");␊ |
897 | ␊ |
898 | ol.startTextBlock();␊ |
899 | ␊ |
900 | writeTemplateSpec(ol,this,compoundTypeString());␊ |
901 | ␊ |
902 | // repeat brief description␊ |
903 | if (!briefDescription().isEmpty() && repeatBrief)␊ |
904 | {␊ |
905 | ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);␊ |
906 | }␊ |
907 | if (!briefDescription().isEmpty() && repeatBrief &&␊ |
908 | !documentation().isEmpty())␊ |
909 | {␊ |
910 | ol.pushGeneratorState();␊ |
911 | ol.disable(OutputGenerator::Html);␊ |
912 | ol.writeString("\n\n");␊ |
913 | ol.popGeneratorState();␊ |
914 | }␊ |
915 | // write documentation␊ |
916 | if (!documentation().isEmpty())␊ |
917 | {␊ |
918 | ol.parseDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);␊ |
919 | }␊ |
920 | // write type constraints␊ |
921 | writeTypeConstraints(ol,this,m_impl->typeConstraints);␊ |
922 | ␊ |
923 | // write examples␊ |
924 | if (hasExamples() && m_impl->exampleSDict)␊ |
925 | {␊ |
926 | ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");␊ |
927 | ol.startDescForItem();␊ |
928 | ol.startParagraph();␊ |
929 | writeExample(ol,m_impl->exampleSDict);␊ |
930 | ol.endParagraph();␊ |
931 | ol.endDescForItem();␊ |
932 | ol.endSimpleSect();␊ |
933 | }␊ |
934 | //ol.newParagraph();␊ |
935 | writeSourceDef(ol,name());␊ |
936 | ol.endTextBlock();␊ |
937 | }␊ |
938 | ␊ |
939 | // write the detailed description for this class␊ |
940 | void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType, bool exampleFlag, ␊ |
941 | const QCString &title,const QCString &anchor)␊ |
942 | {␊ |
943 | if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) || ␊ |
944 | !documentation().isEmpty() || ␊ |
945 | (Config_getBool("SOURCE_BROWSER") && getStartBodyLine()!=-1 && getBodyDef()) ||␊ |
946 | exampleFlag)␊ |
947 | {␊ |
948 | ol.writeRuler();␊ |
949 | ␊ |
950 | ol.pushGeneratorState();␊ |
951 | ol.disableAllBut(OutputGenerator::Html);␊ |
952 | ol.writeAnchor(0,anchor.isEmpty() ? QCString("details") : anchor);␊ |
953 | ol.popGeneratorState();␊ |
954 | ␊ |
955 | if (!anchor.isEmpty())␊ |
956 | {␊ |
957 | ol.pushGeneratorState();␊ |
958 | ol.disable(OutputGenerator::Html);␊ |
959 | ol.disable(OutputGenerator::Man);␊ |
960 | ol.writeAnchor(getOutputFileBase(),anchor);␊ |
961 | ol.popGeneratorState();␊ |
962 | }␊ |
963 | ␊ |
964 | ol.startGroupHeader();␊ |
965 | ol.parseText(title);␊ |
966 | ol.endGroupHeader();␊ |
967 | ␊ |
968 | writeDetailedDocumentationBody(ol);␊ |
969 | ␊ |
970 | }␊ |
971 | else␊ |
972 | {␊ |
973 | writeTemplateSpec(ol,this,pageType);␊ |
974 | }␊ |
975 | }␊ |
976 | ␊ |
977 | void ClassDef::showUsedFiles(OutputList &ol)␊ |
978 | {␊ |
979 | ol.pushGeneratorState();␊ |
980 | ol.disable(OutputGenerator::Man);␊ |
981 | bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");␊ |
982 | ␊ |
983 | ol.writeRuler();␊ |
984 | if (fortranOpt)␊ |
985 | {␊ |
986 | ol.parseText(theTranslator->trGeneratedFromFilesFortran(␊ |
987 | m_impl->lang==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,␊ |
988 | m_impl->files.count()==1));␊ |
989 | }␊ |
990 | else␊ |
991 | {␊ |
992 | ol.parseText(theTranslator->trGeneratedFromFiles(␊ |
993 | m_impl->lang==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,␊ |
994 | m_impl->files.count()==1)); ␊ |
995 | }␊ |
996 | ␊ |
997 | ␊ |
998 | bool first=TRUE;␊ |
999 | const char *file = m_impl->files.first();␊ |
1000 | while (file)␊ |
1001 | {␊ |
1002 | bool ambig;␊ |
1003 | FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig);␊ |
1004 | if (fd)␊ |
1005 | {␊ |
1006 | if (first)␊ |
1007 | {␊ |
1008 | first=FALSE; ␊ |
1009 | ol.startItemList();␊ |
1010 | }␊ |
1011 | ␊ |
1012 | ol.startItemListItem();␊ |
1013 | QCString path=fd->getPath();␊ |
1014 | if (Config_getBool("FULL_PATH_NAMES"))␊ |
1015 | {␊ |
1016 | ol.docify(stripFromPath(path));␊ |
1017 | }␊ |
1018 | ␊ |
1019 | QCString fname = fd->name();␊ |
1020 | if (!fd->getVersion().isEmpty()) // append version if available␊ |
1021 | {␊ |
1022 | fname += " (" + fd->getVersion() + ")";␊ |
1023 | }␊ |
1024 | ␊ |
1025 | // for HTML ␊ |
1026 | ol.pushGeneratorState();␊ |
1027 | ol.disableAllBut(OutputGenerator::Html);␊ |
1028 | if (fd->generateSourceFile())␊ |
1029 | {␊ |
1030 | ol.writeObjectLink(0,fd->getSourceFileBase(),0,fname);␊ |
1031 | }␊ |
1032 | else if (fd->isLinkable())␊ |
1033 | {␊ |
1034 | ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,␊ |
1035 | fname);␊ |
1036 | }␊ |
1037 | else␊ |
1038 | {␊ |
1039 | ol.docify(fname);␊ |
1040 | }␊ |
1041 | ol.popGeneratorState();␊ |
1042 | ␊ |
1043 | // for other output formats␊ |
1044 | ol.pushGeneratorState();␊ |
1045 | ol.disable(OutputGenerator::Html);␊ |
1046 | if (fd->isLinkable())␊ |
1047 | {␊ |
1048 | ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,␊ |
1049 | fname);␊ |
1050 | }␊ |
1051 | else␊ |
1052 | {␊ |
1053 | ol.docify(fname);␊ |
1054 | }␊ |
1055 | ol.popGeneratorState();␊ |
1056 | ␊ |
1057 | ol.endItemListItem();␊ |
1058 | }␊ |
1059 | file=m_impl->files.next();␊ |
1060 | }␊ |
1061 | if (!first) ol.endItemList();␊ |
1062 | ␊ |
1063 | ol.popGeneratorState();␊ |
1064 | }␊ |
1065 | ␊ |
1066 | ␊ |
1067 | void ClassDef::writeInheritanceGraph(OutputList &ol)␊ |
1068 | {␊ |
1069 | // count direct inheritance relations␊ |
1070 | int count=0;␊ |
1071 | BaseClassDef *ibcd;␊ |
1072 | if (m_impl->inheritedBy)␊ |
1073 | {␊ |
1074 | ibcd=m_impl->inheritedBy->first();␊ |
1075 | while (ibcd)␊ |
1076 | {␊ |
1077 | ClassDef *icd=ibcd->classDef;␊ |
1078 | if ( icd->isVisibleInHierarchy()) count++;␊ |
1079 | ibcd=m_impl->inheritedBy->next();␊ |
1080 | }␊ |
1081 | }␊ |
1082 | if (m_impl->inherits)␊ |
1083 | {␊ |
1084 | ibcd=m_impl->inherits->first();␊ |
1085 | while (ibcd)␊ |
1086 | {␊ |
1087 | ClassDef *icd=ibcd->classDef;␊ |
1088 | if ( icd->isVisibleInHierarchy()) count++;␊ |
1089 | ibcd=m_impl->inherits->next();␊ |
1090 | }␊ |
1091 | }␊ |
1092 | ␊ |
1093 | ␊ |
1094 | bool renderDiagram = FALSE;␊ |
1095 | if (Config_getBool("HAVE_DOT") && ␊ |
1096 | (Config_getBool("CLASS_DIAGRAMS") || Config_getBool("CLASS_GRAPH")))␊ |
1097 | // write class diagram using dot␊ |
1098 | {␊ |
1099 | DotClassGraph inheritanceGraph(this,DotNode::Inheritance);␊ |
1100 | if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig())␊ |
1101 | {␊ |
1102 | ol.pushGeneratorState();␊ |
1103 | ol.disable(OutputGenerator::Man);␊ |
1104 | ol.startDotGraph();␊ |
1105 | ol.parseText(theTranslator->trClassDiagram(displayName()));␊ |
1106 | ol.endDotGraph(inheritanceGraph);␊ |
1107 | ol.popGeneratorState();␊ |
1108 | renderDiagram = TRUE;␊ |
1109 | }␊ |
1110 | }␊ |
1111 | else if (Config_getBool("CLASS_DIAGRAMS") && count>0) ␊ |
1112 | // write class diagram using build-in generator␊ |
1113 | {␊ |
1114 | ClassDiagram diagram(this); // create a diagram of this class.␊ |
1115 | ol.startClassDiagram();␊ |
1116 | ol.disable(OutputGenerator::Man);␊ |
1117 | ol.parseText(theTranslator->trClassDiagram(displayName()));␊ |
1118 | ol.enable(OutputGenerator::Man);␊ |
1119 | ol.endClassDiagram(diagram,getOutputFileBase(),displayName());␊ |
1120 | renderDiagram = TRUE;␊ |
1121 | } ␊ |
1122 | ␊ |
1123 | if (renderDiagram) // if we already show the inheritance relations graphically,␊ |
1124 | // then hide the text version␊ |
1125 | {␊ |
1126 | ol.disableAllBut(OutputGenerator::Man);␊ |
1127 | }␊ |
1128 | ␊ |
1129 | if (m_impl->inherits && (count=m_impl->inherits->count())>0)␊ |
1130 | {␊ |
1131 | ol.startParagraph();␊ |
1132 | //parseText(ol,theTranslator->trInherits()+" ");␊ |
1133 | ␊ |
1134 | QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());␊ |
1135 | QRegExp marker("@[0-9]+");␊ |
1136 | int index=0,newIndex,matchLen;␊ |
1137 | // now replace all markers in inheritLine with links to the classes␊ |
1138 | while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)␊ |
1139 | {␊ |
1140 | ol.parseText(inheritLine.mid(index,newIndex-index));␊ |
1141 | bool ok;␊ |
1142 | uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);␊ |
1143 | BaseClassDef *bcd=m_impl->inherits->at(entryIndex);␊ |
1144 | if (ok && bcd)␊ |
1145 | {␊ |
1146 | ClassDef *cd=bcd->classDef;␊ |
1147 | ␊ |
1148 | // use the class name but with the template arguments as given␊ |
1149 | // in the inheritance relation␊ |
1150 | QCString displayName = insertTemplateSpecifierInScope(␊ |
1151 | cd->displayName(),bcd->templSpecifiers);␊ |
1152 | ␊ |
1153 | if (cd->isLinkable())␊ |
1154 | {␊ |
1155 | if (!Config_getString("GENERATE_TAGFILE").isEmpty()) ␊ |
1156 | {␊ |
1157 | Doxygen::tagFile << " <base";␊ |
1158 | if (bcd->prot==Protected)␊ |
1159 | {␊ |
1160 | Doxygen::tagFile << " protection=\"protected\"";␊ |
1161 | }␊ |
1162 | else if (bcd->prot==Private)␊ |
1163 | {␊ |
1164 | Doxygen::tagFile << " protection=\"private\"";␊ |
1165 | }␊ |
1166 | if (bcd->virt==Virtual)␊ |
1167 | {␊ |
1168 | Doxygen::tagFile << " virtualness=\"virtual\"";␊ |
1169 | }␊ |
1170 | Doxygen::tagFile << ">" << convertToXML(cd->name()) ␊ |
1171 | << "</base>" << endl;␊ |
1172 | }␊ |
1173 | ol.writeObjectLink(cd->getReference(),␊ |
1174 | cd->getOutputFileBase(),␊ |
1175 | cd->anchor(),␊ |
1176 | displayName);␊ |
1177 | }␊ |
1178 | else␊ |
1179 | {␊ |
1180 | ol.docify(displayName);␊ |
1181 | }␊ |
1182 | }␊ |
1183 | else␊ |
1184 | {␊ |
1185 | err("error: invalid marker %d in inherits list!\n",entryIndex);␊ |
1186 | }␊ |
1187 | index=newIndex+matchLen;␊ |
1188 | } ␊ |
1189 | ol.parseText(inheritLine.right(inheritLine.length()-index));␊ |
1190 | ol.endParagraph();␊ |
1191 | }␊ |
1192 | ␊ |
1193 | // write subclasses␊ |
1194 | if (m_impl->inheritedBy && (count=m_impl->inheritedBy->count())>0)␊ |
1195 | {␊ |
1196 | ol.startParagraph();␊ |
1197 | QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());␊ |
1198 | QRegExp marker("@[0-9]+");␊ |
1199 | int index=0,newIndex,matchLen;␊ |
1200 | // now replace all markers in inheritLine with links to the classes␊ |
1201 | while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)␊ |
1202 | {␊ |
1203 | ol.parseText(inheritLine.mid(index,newIndex-index));␊ |
1204 | bool ok;␊ |
1205 | uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);␊ |
1206 | BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);␊ |
1207 | if (ok && bcd)␊ |
1208 | {␊ |
1209 | ClassDef *cd=bcd->classDef;␊ |
1210 | if (cd->isLinkable())␊ |
1211 | {␊ |
1212 | ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName());␊ |
1213 | }␊ |
1214 | else␊ |
1215 | {␊ |
1216 | ol.docify(cd->displayName());␊ |
1217 | }␊ |
1218 | writeInheritanceSpecifier(ol,bcd);␊ |
1219 | }␊ |
1220 | index=newIndex+matchLen;␊ |
1221 | } ␊ |
1222 | ol.parseText(inheritLine.right(inheritLine.length()-index));␊ |
1223 | ol.endParagraph();␊ |
1224 | }␊ |
1225 | ␊ |
1226 | if (renderDiagram) ␊ |
1227 | {␊ |
1228 | ol.enableAll();␊ |
1229 | }␊ |
1230 | }␊ |
1231 | ␊ |
1232 | void ClassDef::writeCollaborationGraph(OutputList &ol)␊ |
1233 | {␊ |
1234 | if (Config_getBool("HAVE_DOT") /*&& Config_getBool("COLLABORATION_GRAPH")*/)␊ |
1235 | {␊ |
1236 | DotClassGraph usageImplGraph(this,DotNode::Collaboration);␊ |
1237 | if (!usageImplGraph.isTrivial())␊ |
1238 | {␊ |
1239 | ol.pushGeneratorState();␊ |
1240 | ol.disable(OutputGenerator::Man);␊ |
1241 | ol.startDotGraph();␊ |
1242 | ol.parseText(theTranslator->trCollaborationDiagram(displayName()));␊ |
1243 | ol.endDotGraph(usageImplGraph);␊ |
1244 | ol.popGeneratorState();␊ |
1245 | }␊ |
1246 | }␊ |
1247 | }␊ |
1248 | ␊ |
1249 | void ClassDef::writeIncludeFiles(OutputList &ol)␊ |
1250 | {␊ |
1251 | if (m_impl->incInfo /*&& Config_getBool("SHOW_INCLUDE_FILES")*/)␊ |
1252 | {␊ |
1253 | QCString nm=m_impl->incInfo->includeName.isEmpty() ? ␊ |
1254 | (m_impl->incInfo->fileDef ?␊ |
1255 | m_impl->incInfo->fileDef->docName().data() : "" ␊ |
1256 | ) :␊ |
1257 | m_impl->incInfo->includeName.data();␊ |
1258 | if (!nm.isEmpty())␊ |
1259 | {␊ |
1260 | ol.startParagraph();␊ |
1261 | ol.startTypewriter();␊ |
1262 | SrcLangExt lang = getLanguageFromFileName(nm);␊ |
1263 | bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;␊ |
1264 | if (isIDLorJava)␊ |
1265 | {␊ |
1266 | ol.docify("import ");␊ |
1267 | }␊ |
1268 | else if (isObjectiveC())␊ |
1269 | {␊ |
1270 | ol.docify("#import ");␊ |
1271 | }␊ |
1272 | else␊ |
1273 | {␊ |
1274 | ol.docify("#include ");␊ |
1275 | }␊ |
1276 | if (m_impl->incInfo->local || isIDLorJava)␊ |
1277 | ol.docify("\"");␊ |
1278 | else␊ |
1279 | ol.docify("<");␊ |
1280 | ol.pushGeneratorState();␊ |
1281 | ol.disable(OutputGenerator::Html);␊ |
1282 | ol.docify(nm);␊ |
1283 | ol.disableAllBut(OutputGenerator::Html);␊ |
1284 | ol.enable(OutputGenerator::Html);␊ |
1285 | if (m_impl->incInfo->fileDef)␊ |
1286 | {␊ |
1287 | ol.writeObjectLink(0,m_impl->incInfo->fileDef->includeName(),0,nm);␊ |
1288 | }␊ |
1289 | else␊ |
1290 | {␊ |
1291 | ol.docify(nm);␊ |
1292 | }␊ |
1293 | ol.popGeneratorState();␊ |
1294 | if (m_impl->incInfo->local || isIDLorJava)␊ |
1295 | ol.docify("\"");␊ |
1296 | else␊ |
1297 | ol.docify(">");␊ |
1298 | if (isIDLorJava) ␊ |
1299 | ol.docify(";");␊ |
1300 | ol.endTypewriter();␊ |
1301 | ol.endParagraph();␊ |
1302 | }␊ |
1303 | }␊ |
1304 | }␊ |
1305 | ␊ |
1306 | void ClassDef::writeAllMembersLink(OutputList &ol)␊ |
1307 | {␊ |
1308 | // write link to list of all members (HTML only)␊ |
1309 | if (m_impl->allMemberNameInfoSDict &&␊ |
1310 | !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")␊ |
1311 | )␊ |
1312 | {␊ |
1313 | ol.pushGeneratorState();␊ |
1314 | ol.disableAllBut(OutputGenerator::Html);␊ |
1315 | ol.startParagraph();␊ |
1316 | ol.startTextLink(getMemberListFileName(),0);␊ |
1317 | ol.parseText(theTranslator->trListOfAllMembers());␊ |
1318 | ol.endTextLink();␊ |
1319 | ol.endParagraph();␊ |
1320 | ol.enableAll();␊ |
1321 | ol.popGeneratorState();␊ |
1322 | }␊ |
1323 | }␊ |
1324 | ␊ |
1325 | void ClassDef::writeMemberGroups(OutputList &ol,bool showInline)␊ |
1326 | {␊ |
1327 | // write user defined member groups␊ |
1328 | if (m_impl->memberGroupSDict)␊ |
1329 | {␊ |
1330 | m_impl->memberGroupSDict->sort();␊ |
1331 | MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);␊ |
1332 | MemberGroup *mg;␊ |
1333 | for (;(mg=mgli.current());++mgli)␊ |
1334 | {␊ |
1335 | if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section␊ |
1336 | {␊ |
1337 | mg->writeDeclarations(ol,this,0,0,0,showInline);␊ |
1338 | }␊ |
1339 | else // add this group to the corresponding member section␊ |
1340 | {␊ |
1341 | //printf("addToDeclarationSection(%s)\n",mg->header().data());␊ |
1342 | //mg->addToDeclarationSection();␊ |
1343 | }␊ |
1344 | }␊ |
1345 | }␊ |
1346 | }␊ |
1347 | ␊ |
1348 | void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title)␊ |
1349 | {␊ |
1350 | // nested classes␊ |
1351 | if (m_impl->innerClasses) ␊ |
1352 | {␊ |
1353 | m_impl->innerClasses->writeDeclaration(ol,0,title,TRUE);␊ |
1354 | }␊ |
1355 | }␊ |
1356 | ␊ |
1357 | void ClassDef::startMemberDocumentation(OutputList &ol)␊ |
1358 | {␊ |
1359 | if (Config_getBool("SEPARATE_MEMBER_PAGES"))␊ |
1360 | {␊ |
1361 | ol.disable(OutputGenerator::Html);␊ |
1362 | Doxygen::suppressDocWarnings = TRUE;␊ |
1363 | }␊ |
1364 | }␊ |
1365 | ␊ |
1366 | void ClassDef::endMemberDocumentation(OutputList &ol)␊ |
1367 | {␊ |
1368 | if (Config_getBool("SEPARATE_MEMBER_PAGES"))␊ |
1369 | {␊ |
1370 | ol.enable(OutputGenerator::Html);␊ |
1371 | Doxygen::suppressDocWarnings = FALSE;␊ |
1372 | }␊ |
1373 | }␊ |
1374 | ␊ |
1375 | void ClassDef::startMemberDeclarations(OutputList &ol)␊ |
1376 | {␊ |
1377 | ol.startMemberSections();␊ |
1378 | }␊ |
1379 | ␊ |
1380 | void ClassDef::endMemberDeclarations(OutputList &ol)␊ |
1381 | {␊ |
1382 | ol.endMemberSections();␊ |
1383 | }␊ |
1384 | ␊ |
1385 | void ClassDef::writeAuthorSection(OutputList &ol)␊ |
1386 | {␊ |
1387 | ol.pushGeneratorState();␊ |
1388 | ol.disableAllBut(OutputGenerator::Man);␊ |
1389 | ol.writeString("\n");␊ |
1390 | ol.startGroupHeader();␊ |
1391 | ol.parseText(theTranslator->trAuthor(TRUE,TRUE));␊ |
1392 | ol.endGroupHeader();␊ |
1393 | ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));␊ |
1394 | ol.popGeneratorState();␊ |
1395 | }␊ |
1396 | ␊ |
1397 | ␊ |
1398 | void ClassDef::writeSummaryLinks(OutputList &ol)␊ |
1399 | {␊ |
1400 | static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");␊ |
1401 | ol.pushGeneratorState();␊ |
1402 | ol.disableAllBut(OutputGenerator::Html);␊ |
1403 | QListIterator<LayoutDocEntry> eli(␊ |
1404 | LayoutDocManager::instance().docEntries(LayoutDocManager::Class));␊ |
1405 | LayoutDocEntry *lde;␊ |
1406 | bool first=TRUE;␊ |
1407 | ␊ |
1408 | if (!vhdlOpt)␊ |
1409 | {␊ |
1410 | for (eli.toFirst();(lde=eli.current());++eli)␊ |
1411 | {␊ |
1412 | if (lde->kind()==LayoutDocEntry::ClassNestedClasses && ␊ |
1413 | m_impl->innerClasses &&␊ |
1414 | m_impl->innerClasses->declVisible()␊ |
1415 | )␊ |
1416 | {␊ |
1417 | LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;␊ |
1418 | writeSummaryLink(ol,"nested-classes",ls->title,first);␊ |
1419 | }␊ |
1420 | else if (lde->kind()== LayoutDocEntry::MemberDecl)␊ |
1421 | {␊ |
1422 | LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;␊ |
1423 | MemberList * ml = getMemberList(lmd->type);␊ |
1424 | if (ml && ml->declVisible())␊ |
1425 | {␊ |
1426 | writeSummaryLink(ol,ml->listTypeAsString(),lmd->title,first);␊ |
1427 | }␊ |
1428 | }␊ |
1429 | }␊ |
1430 | }␊ |
1431 | else // VDHL only␊ |
1432 | {␊ |
1433 | SDict<QCString>::Iterator li(m_impl->vhdlSummaryTitles);␊ |
1434 | for (li.toFirst();li.current();++li)␊ |
1435 | {␊ |
1436 | writeSummaryLink(ol,li.current()->data(),li.current()->data(),first);␊ |
1437 | }␊ |
1438 | }␊ |
1439 | if (!first)␊ |
1440 | {␊ |
1441 | ol.writeString(" </div>\n");␊ |
1442 | }␊ |
1443 | ol.popGeneratorState();␊ |
1444 | }␊ |
1445 | ␊ |
1446 | void ClassDef::writeTagFileMarker(OutputList &ol)␊ |
1447 | {␊ |
1448 | // write markers for tag file processing to the output␊ |
1449 | ol.pushGeneratorState();␊ |
1450 | ol.disableAllBut(OutputGenerator::Html);␊ |
1451 | ol.writeString("<!-- doxytag: class=\"");␊ |
1452 | ol.docify(name());␊ |
1453 | ol.writeString("\" -->");␊ |
1454 | if (m_impl->inherits && m_impl->inherits->count()>0)␊ |
1455 | {␊ |
1456 | BaseClassListIterator bli(*m_impl->inherits);␊ |
1457 | ol.writeString("<!-- doxytag: inherits=\"");␊ |
1458 | BaseClassDef *bcd=0;␊ |
1459 | bool first=TRUE;␊ |
1460 | for (bli.toFirst();(bcd=bli.current());++bli)␊ |
1461 | {␊ |
1462 | if (!first) ol.writeString(",");␊ |
1463 | ol.docify(bcd->classDef->name());␊ |
1464 | first=FALSE;␊ |
1465 | }␊ |
1466 | ol.writeString("\" -->");␊ |
1467 | }␊ |
1468 | ol.popGeneratorState();␊ |
1469 | ␊ |
1470 | // write section to the tag file␊ |
1471 | if (!Config_getString("GENERATE_TAGFILE").isEmpty()) ␊ |
1472 | {␊ |
1473 | Doxygen::tagFile << " <compound kind=\"" << compoundTypeString();␊ |
1474 | Doxygen::tagFile << "\"";␊ |
1475 | if (isObjectiveC()) { Doxygen::tagFile << " objc=\"yes\""; }␊ |
1476 | Doxygen::tagFile << ">" << endl;␊ |
1477 | Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;␊ |
1478 | Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;␊ |
1479 | if (!anchor().isEmpty())␊ |
1480 | {␊ |
1481 | Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;␊ |
1482 | }␊ |
1483 | if (m_impl->tempArgs)␊ |
1484 | {␊ |
1485 | ArgumentListIterator ali(*m_impl->tempArgs);␊ |
1486 | Argument *a;␊ |
1487 | for (;(a=ali.current());++ali)␊ |
1488 | {␊ |
1489 | Doxygen::tagFile << " <templarg>" << convertToXML(a->name) << "</templarg>" << endl;␊ |
1490 | }␊ |
1491 | }␊ |
1492 | }␊ |
1493 | }␊ |
1494 | ␊ |
1495 | #if 0␊ |
1496 | void ClassDef::writeInlineDeclaration(OutputList &ol,bool first)␊ |
1497 | {␊ |
1498 | //printf("ClassDef::writeInlineDeclaration for %s\n",name().data());␊ |
1499 | bool exampleFlag=hasExamples();␊ |
1500 | QListIterator<LayoutDocEntry> eli(␊ |
1501 | LayoutDocManager::instance().docEntries(LayoutDocManager::Class));␊ |
1502 | LayoutDocEntry *lde;␊ |
1503 | ol.startMemberHeader(first ? "nested-classes" : 0);␊ |
1504 | //ol.parseText(name()+" "+theTranslator->trClassDocumentation());␊ |
1505 | QCString s = compoundTypeString();␊ |
1506 | if (s.length()>0 && isId(s.at(0))) s[0]=toupper(s[0]);␊ |
1507 | s+=" "+name();␊ |
1508 | ol.parseText(s);␊ |
1509 | ol.endMemberHeader();␊ |
1510 | ol.writeAnchor(getOutputFileBase(),anchor());␊ |
1511 | ol.startInlineDescription();␊ |
1512 | writeBriefDescription(ol,exampleFlag);␊ |
1513 | ol.endInlineDescription();␊ |
1514 | for (eli.toFirst();(lde=eli.current());++eli)␊ |
1515 | {␊ |
1516 | if (lde->kind()==LayoutDocEntry::MemberDecl)␊ |
1517 | {␊ |
1518 | LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;␊ |
1519 | writeMemberDeclarations(ol,lmd->type,lmd->title,lmd->subscript,TRUE);␊ |
1520 | }␊ |
1521 | else if (lde->kind()==LayoutDocEntry::MemberGroups)␊ |
1522 | {␊ |
1523 | writeMemberGroups(ol,TRUE);␊ |
1524 | }␊ |
1525 | }␊ |
1526 | }␊ |
1527 | #endif␊ |
1528 | ␊ |
1529 | /** Write class documentation inside another container (i.e. a group) */␊ |
1530 | void ClassDef::writeInlineDocumentation(OutputList &ol)␊ |
1531 | {␊ |
1532 | ol.addIndexItem(name(),0);␊ |
1533 | //printf("ClassDef::writeInlineDocumentation(%s)\n",name().data());␊ |
1534 | QListIterator<LayoutDocEntry> eli(␊ |
1535 | LayoutDocManager::instance().docEntries(LayoutDocManager::Class));␊ |
1536 | LayoutDocEntry *lde;␊ |
1537 | ␊ |
1538 | // part 1: anchor and title␊ |
1539 | QCString s = compoundTypeString()+" "+name(); ␊ |
1540 | ␊ |
1541 | // part 1a␊ |
1542 | ol.pushGeneratorState();␊ |
1543 | ol.disableAllBut(OutputGenerator::Html);␊ |
1544 | { // only HTML only␊ |
1545 | ol.writeAnchor(0,anchor());␊ |
1546 | ol.startMemberDoc(0,0,0,0,FALSE);␊ |
1547 | ol.startMemberDocName(FALSE);␊ |
1548 | ol.parseText(s);␊ |
1549 | ol.endMemberDocName();␊ |
1550 | ol.endMemberDoc(FALSE);␊ |
1551 | ol.startIndent();␊ |
1552 | }␊ |
1553 | ol.popGeneratorState();␊ |
1554 | ␊ |
1555 | // part 1b␊ |
1556 | ol.pushGeneratorState();␊ |
1557 | ol.disable(OutputGenerator::Html);␊ |
1558 | ol.disable(OutputGenerator::Man);␊ |
1559 | { // for LaTeX/RTF only␊ |
1560 | ol.writeAnchor(getOutputFileBase(),anchor());␊ |
1561 | }␊ |
1562 | ol.popGeneratorState();␊ |
1563 | ␊ |
1564 | // part 1c␊ |
1565 | ol.pushGeneratorState();␊ |
1566 | ol.disable(OutputGenerator::Html);␊ |
1567 | {␊ |
1568 | // for LaTeX/RTF/Man␊ |
1569 | ol.startGroupHeader(1);␊ |
1570 | ol.parseText(s);␊ |
1571 | ol.endGroupHeader(1);␊ |
1572 | }␊ |
1573 | ol.popGeneratorState();␊ |
1574 | ␊ |
1575 | // part 2: the header and detailed description␊ |
1576 | for (eli.toFirst();(lde=eli.current());++eli)␊ |
1577 | {␊ |
1578 | switch (lde->kind())␊ |
1579 | {␊ |
1580 | case LayoutDocEntry::BriefDesc: ␊ |
1581 | {␊ |
1582 | // since we already shown the brief description in the␊ |
1583 | // declaration part of the container, so we use this to␊ |
1584 | // show the details on top.␊ |
1585 | writeDetailedDocumentationBody(ol);␊ |
1586 | }␊ |
1587 | break;␊ |
1588 | case LayoutDocEntry::ClassInheritanceGraph: ␊ |
1589 | writeInheritanceGraph(ol); ␊ |
1590 | break; ␊ |
1591 | case LayoutDocEntry::ClassCollaborationGraph: ␊ |
1592 | writeCollaborationGraph(ol); ␊ |
1593 | break; ␊ |
1594 | case LayoutDocEntry::MemberDeclStart: ␊ |
1595 | startMemberDeclarations(ol);␊ |
1596 | break; ␊ |
1597 | case LayoutDocEntry::MemberDecl:␊ |
1598 | {␊ |
1599 | LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;␊ |
1600 | writeMemberDeclarations(ol,lmd->type,lmd->title,lmd->subscript,TRUE);␊ |
1601 | }␊ |
1602 | break;␊ |
1603 | case LayoutDocEntry::MemberGroups:␊ |
1604 | {␊ |
1605 | writeMemberGroups(ol,TRUE);␊ |
1606 | }␊ |
1607 | break;␊ |
1608 | case LayoutDocEntry::MemberDeclEnd: ␊ |
1609 | endMemberDeclarations(ol);␊ |
1610 | break;␊ |
1611 | case LayoutDocEntry::MemberDefStart: ␊ |
1612 | startMemberDocumentation(ol);␊ |
1613 | break; ␊ |
1614 | case LayoutDocEntry::MemberDef: ␊ |
1615 | {␊ |
1616 | LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;␊ |
1617 | writeMemberDocumentation(ol,lmd->type,lmd->title,TRUE);␊ |
1618 | }␊ |
1619 | break; ␊ |
1620 | case LayoutDocEntry::MemberDefEnd: ␊ |
1621 | endMemberDocumentation(ol);␊ |
1622 | break;␊ |
1623 | default:␊ |
1624 | break;␊ |
1625 | }␊ |
1626 | }␊ |
1627 | ␊ |
1628 | // part 3: close the block␊ |
1629 | ol.pushGeneratorState();␊ |
1630 | ol.disableAllBut(OutputGenerator::Html);␊ |
1631 | { // HTML only␊ |
1632 | ol.endIndent();␊ |
1633 | }␊ |
1634 | ol.popGeneratorState();␊ |
1635 | ␊ |
1636 | // part 4: write tag file information␊ |
1637 | writeTagFileMarker(ol);␊ |
1638 | }␊ |
1639 | ␊ |
1640 | void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor)␊ |
1641 | {␊ |
1642 | // TODO: clean up this mess by moving it to␊ |
1643 | // the output generators...␊ |
1644 | static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");␊ |
1645 | static bool rtfHyperlinks = Config_getBool("RTF_HYPERLINKS");␊ |
1646 | static bool usePDFLatex = Config_getBool("USE_PDFLATEX");␊ |
1647 | ␊ |
1648 | // HTML only␊ |
1649 | ol.pushGeneratorState();␊ |
1650 | ol.disableAllBut(OutputGenerator::Html);␊ |
1651 | ol.docify(" ");␊ |
1652 | ol.startTextLink(getOutputFileBase(),␊ |
1653 | anchor.isEmpty() ? QCString("details") : anchor);␊ |
1654 | ol.parseText(theTranslator->trMore());␊ |
1655 | ol.endTextLink();␊ |
1656 | ol.popGeneratorState();␊ |
1657 | ␊ |
1658 | if (!anchor.isEmpty())␊ |
1659 | {␊ |
1660 | ol.pushGeneratorState();␊ |
1661 | // LaTeX + RTF␊ |
1662 | ol.disable(OutputGenerator::Html);␊ |
1663 | ol.disable(OutputGenerator::Man);␊ |
1664 | if (!(usePDFLatex && pdfHyperlinks))␊ |
1665 | {␊ |
1666 | ol.disable(OutputGenerator::Latex);␊ |
1667 | }␊ |
1668 | if (!rtfHyperlinks)␊ |
1669 | {␊ |
1670 | ol.disable(OutputGenerator::RTF);␊ |
1671 | }␊ |
1672 | ol.docify(" ");␊ |
1673 | ol.startTextLink(getOutputFileBase(), anchor);␊ |
1674 | ol.parseText(theTranslator->trMore());␊ |
1675 | ol.endTextLink();␊ |
1676 | // RTF only␊ |
1677 | ol.disable(OutputGenerator::Latex);␊ |
1678 | ol.writeString("\\par");␊ |
1679 | ol.popGeneratorState();␊ |
1680 | }␊ |
1681 | }␊ |
1682 | ␊ |
1683 | ␊ |
1684 | void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames)␊ |
1685 | {␊ |
1686 | static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");␊ |
1687 | static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");␊ |
1688 | static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");␊ |
1689 | static bool extractLocalClasses = Config_getBool("EXTRACT_LOCAL_CLASSES");␊ |
1690 | bool isLink = isLinkable();␊ |
1691 | if (isLink || ␊ |
1692 | (!hideUndocClasses && ␊ |
1693 | (!isLocal() || extractLocalClasses)␊ |
1694 | )␊ |
1695 | )␊ |
1696 | {␊ |
1697 | if (!found) // first class␊ |
1698 | {␊ |
1699 | ol.startMemberHeader("nested-classes");␊ |
1700 | if (header)␊ |
1701 | {␊ |
1702 | ol.parseText(header);␊ |
1703 | }␊ |
1704 | else if (vhdlOpt)␊ |
1705 | {␊ |
1706 | ol.parseText(VhdlDocGen::trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE));␊ |
1707 | }␊ |
1708 | else␊ |
1709 | {␊ |
1710 | ol.parseText(fortranOpt ? theTranslator->trDataTypes() :␊ |
1711 | theTranslator->trCompounds());␊ |
1712 | }␊ |
1713 | ol.endMemberHeader();␊ |
1714 | ol.startMemberList();␊ |
1715 | found=TRUE;␊ |
1716 | }␊ |
1717 | if (!Config_getString("GENERATE_TAGFILE").isEmpty() &&␊ |
1718 | !isReference()) // skip classes found in tag files␊ |
1719 | {␊ |
1720 | Doxygen::tagFile << " <class kind=\"" << compoundTypeString() ␊ |
1721 | << "\">" << convertToXML(name()) << "</class>" << endl;␊ |
1722 | }␊ |
1723 | ol.startMemberItem(FALSE);␊ |
1724 | QCString ctype = compoundTypeString();␊ |
1725 | QCString cname;␊ |
1726 | if (localNames)␊ |
1727 | {␊ |
1728 | cname = localName();␊ |
1729 | if (cname.right(2)=="-p" || cname.right(2)=="-g")␊ |
1730 | {␊ |
1731 | cname = cname.left(cname.length()-2);␊ |
1732 | }␊ |
1733 | }␊ |
1734 | else␊ |
1735 | {␊ |
1736 | cname = displayName();␊ |
1737 | }␊ |
1738 | ␊ |
1739 | if (!vhdlOpt) // for VHDL we swap the name and the type␊ |
1740 | {␊ |
1741 | ol.writeString(ctype);␊ |
1742 | ol.writeString(" ");␊ |
1743 | ol.insertMemberAlign();␊ |
1744 | }␊ |
1745 | if (isLink) ␊ |
1746 | {␊ |
1747 | ol.writeObjectLink(getReference(),␊ |
1748 | getOutputFileBase(),␊ |
1749 | anchor(),␊ |
1750 | cname␊ |
1751 | );␊ |
1752 | }␊ |
1753 | else ␊ |
1754 | {␊ |
1755 | ol.startBold();␊ |
1756 | ol.docify(cname);␊ |
1757 | ol.endBold();␊ |
1758 | }␊ |
1759 | if (vhdlOpt) // now write the type␊ |
1760 | {␊ |
1761 | ol.writeString(" ");␊ |
1762 | ol.insertMemberAlign();␊ |
1763 | VhdlDocGen::writeClassType(this,ol,cname);␊ |
1764 | }␊ |
1765 | ol.endMemberItem();␊ |
1766 | ␊ |
1767 | // add the brief description if available␊ |
1768 | if (!briefDescription().isEmpty())␊ |
1769 | {␊ |
1770 | ol.startMemberDescription();␊ |
1771 | ol.parseDoc(briefFile(),briefLine(),this,0,␊ |
1772 | briefDescription(),FALSE,FALSE,0,TRUE,FALSE);␊ |
1773 | if (isLinkableInProject())␊ |
1774 | {␊ |
1775 | writeMoreLink(ol,anchor());␊ |
1776 | }␊ |
1777 | ol.endMemberDescription();␊ |
1778 | }␊ |
1779 | }␊ |
1780 | }␊ |
1781 | ␊ |
1782 | void ClassDef::writeDocumentationContents(OutputList &ol,const QCString &pageTitle)␊ |
1783 | {␊ |
1784 | ol.startContents();␊ |
1785 | ␊ |
1786 | QCString pageType = " ";␊ |
1787 | pageType += compoundTypeString();␊ |
1788 | toupper(pageType.at(1));␊ |
1789 | ␊ |
1790 | writeTagFileMarker(ol);␊ |
1791 | ␊ |
1792 | Doxygen::indexList.addIndexItem(this,0);␊ |
1793 | ␊ |
1794 | if (Doxygen::searchIndex)␊ |
1795 | {␊ |
1796 | Doxygen::searchIndex->setCurrentDoc(pageTitle,getOutputFileBase(),anchor());␊ |
1797 | Doxygen::searchIndex->addWord(localName(),TRUE);␊ |
1798 | }␊ |
1799 | bool exampleFlag=hasExamples();␊ |
1800 | ␊ |
1801 | //---------------------------------------- start flexible part -------------------------------␊ |
1802 | ␊ |
1803 | QListIterator<LayoutDocEntry> eli(␊ |
1804 | LayoutDocManager::instance().docEntries(LayoutDocManager::Class));␊ |
1805 | LayoutDocEntry *lde;␊ |
1806 | for (eli.toFirst();(lde=eli.current());++eli)␊ |
1807 | {␊ |
1808 | switch (lde->kind())␊ |
1809 | {␊ |
1810 | case LayoutDocEntry::BriefDesc: ␊ |
1811 | writeBriefDescription(ol,exampleFlag);␊ |
1812 | break; ␊ |
1813 | case LayoutDocEntry::ClassIncludes: ␊ |
1814 | writeIncludeFiles(ol);␊ |
1815 | break;␊ |
1816 | case LayoutDocEntry::ClassInheritanceGraph: ␊ |
1817 | writeInheritanceGraph(ol); ␊ |
1818 | break; ␊ |
1819 | case LayoutDocEntry::ClassCollaborationGraph: ␊ |
1820 | writeCollaborationGraph(ol); ␊ |
1821 | break; ␊ |
1822 | case LayoutDocEntry::ClassAllMembersLink: ␊ |
1823 | writeAllMembersLink(ol);␊ |
1824 | break;␊ |
1825 | case LayoutDocEntry::MemberDeclStart: ␊ |
1826 | startMemberDeclarations(ol);␊ |
1827 | break; ␊ |
1828 | case LayoutDocEntry::MemberGroups: ␊ |
1829 | writeMemberGroups(ol);␊ |
1830 | break;␊ |
1831 | case LayoutDocEntry::MemberDecl: ␊ |
1832 | {␊ |
1833 | LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;␊ |
1834 | writeMemberDeclarations(ol,lmd->type,lmd->title,lmd->subscript);␊ |
1835 | }␊ |
1836 | break; ␊ |
1837 | case LayoutDocEntry::ClassNestedClasses: ␊ |
1838 | {␊ |
1839 | LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;␊ |
1840 | writeNestedClasses(ol,ls->title);␊ |
1841 | }␊ |
1842 | break;␊ |
1843 | case LayoutDocEntry::MemberDeclEnd: ␊ |
1844 | endMemberDeclarations(ol);␊ |
1845 | break;␊ |
1846 | case LayoutDocEntry::DetailedDesc: ␊ |
1847 | {␊ |
1848 | LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;␊ |
1849 | writeDetailedDescription(ol,pageType,exampleFlag,ls->title);␊ |
1850 | }␊ |
1851 | break; ␊ |
1852 | case LayoutDocEntry::MemberDefStart: ␊ |
1853 | startMemberDocumentation(ol);␊ |
1854 | break; ␊ |
1855 | case LayoutDocEntry::MemberDef: ␊ |
1856 | {␊ |
1857 | LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;␊ |
1858 | writeMemberDocumentation(ol,lmd->type,lmd->title);␊ |
1859 | }␊ |
1860 | break; ␊ |
1861 | case LayoutDocEntry::MemberDefEnd: ␊ |
1862 | endMemberDocumentation(ol);␊ |
1863 | break;␊ |
1864 | case LayoutDocEntry::ClassUsedFiles: ␊ |
1865 | showUsedFiles(ol);␊ |
1866 | break;␊ |
1867 | case LayoutDocEntry::AuthorSection: ␊ |
1868 | writeAuthorSection(ol);␊ |
1869 | break;␊ |
1870 | case LayoutDocEntry::NamespaceNestedNamespaces:␊ |
1871 | case LayoutDocEntry::NamespaceClasses:␊ |
1872 | case LayoutDocEntry::FileClasses:␊ |
1873 | case LayoutDocEntry::FileNamespaces:␊ |
1874 | case LayoutDocEntry::FileIncludes:␊ |
1875 | case LayoutDocEntry::FileIncludeGraph:␊ |
1876 | case LayoutDocEntry::FileIncludedByGraph: ␊ |
1877 | case LayoutDocEntry::FileSourceLink:␊ |
1878 | case LayoutDocEntry::GroupClasses: ␊ |
1879 | case LayoutDocEntry::GroupInlineClasses: ␊ |
1880 | case LayoutDocEntry::GroupNamespaces:␊ |
1881 | case LayoutDocEntry::GroupDirs: ␊ |
1882 | case LayoutDocEntry::GroupNestedGroups: ␊ |
1883 | case LayoutDocEntry::GroupFiles:␊ |
1884 | case LayoutDocEntry::GroupGraph: ␊ |
1885 | case LayoutDocEntry::GroupPageDocs:␊ |
1886 | case LayoutDocEntry::DirSubDirs:␊ |
1887 | case LayoutDocEntry::DirFiles:␊ |
1888 | case LayoutDocEntry::DirGraph:␊ |
1889 | err("Internal inconsistency: member %d should not be part of "␊ |
1890 | "LayoutDocManager::Class entry list\n",lde->kind());␊ |
1891 | break;␊ |
1892 | }␊ |
1893 | }␊ |
1894 | ␊ |
1895 | if (!Config_getString("GENERATE_TAGFILE").isEmpty()) ␊ |
1896 | {␊ |
1897 | writeDocAnchorsToTagFile();␊ |
1898 | Doxygen::tagFile << " </compound>" << endl;␊ |
1899 | }␊ |
1900 | ol.endContents();␊ |
1901 | }␊ |
1902 | ␊ |
1903 | // write all documentation for this class␊ |
1904 | void ClassDef::writeDocumentation(OutputList &ol)␊ |
1905 | {␊ |
1906 | static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");␊ |
1907 | static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");␊ |
1908 | static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");␊ |
1909 | QCString pageTitle;␊ |
1910 | ␊ |
1911 | if (fortranOpt)␊ |
1912 | {␊ |
1913 | pageTitle = theTranslator->trCompoundReferenceFortran(displayName(),␊ |
1914 | m_impl->compType,␊ |
1915 | m_impl->tempArgs != 0); ␊ |
1916 | }␊ |
1917 | else if (vhdlOpt)␊ |
1918 | {␊ |
1919 | // TODO: translate␊ |
1920 | pageTitle = VhdlDocGen::getClassTitle(this)+" Reference";␊ |
1921 | }␊ |
1922 | else␊ |
1923 | {␊ |
1924 | pageTitle = theTranslator->trCompoundReference(displayName(),␊ |
1925 | m_impl->compType == Interface && m_impl->lang==SrcLangExt_ObjC ? Class : m_impl->compType,␊ |
1926 | m_impl->tempArgs != 0);␊ |
1927 | }␊ |
1928 | ␊ |
1929 | startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible,!generateTreeView); ␊ |
1930 | if (!generateTreeView)␊ |
1931 | {␊ |
1932 | if (getOuterScope()!=Doxygen::globalScope)␊ |
1933 | {␊ |
1934 | writeNavigationPath(ol);␊ |
1935 | }␊ |
1936 | ol.endQuickIndices();␊ |
1937 | }␊ |
1938 | ␊ |
1939 | startTitle(ol,getOutputFileBase(),this);␊ |
1940 | ol.parseText(pageTitle);␊ |
1941 | addGroupListToTitle(ol,this);␊ |
1942 | endTitle(ol,getOutputFileBase(),name());␊ |
1943 | writeDocumentationContents(ol,pageTitle);␊ |
1944 | ␊ |
1945 | if (generateTreeView)␊ |
1946 | {␊ |
1947 | writeNavigationPath(ol);␊ |
1948 | }␊ |
1949 | ␊ |
1950 | endFile(ol,TRUE);␊ |
1951 | ␊ |
1952 | if (Config_getBool("SEPARATE_MEMBER_PAGES"))␊ |
1953 | {␊ |
1954 | writeMemberPages(ol);␊ |
1955 | }␊ |
1956 | }␊ |
1957 | ␊ |
1958 | void ClassDef::writeMemberPages(OutputList &ol)␊ |
1959 | {␊ |
1960 | ///////////////////////////////////////////////////////////////////////////␊ |
1961 | //// Member definitions on separate pages␊ |
1962 | ///////////////////////////////////////////////////////////////////////////␊ |
1963 | ␊ |
1964 | ol.pushGeneratorState();␊ |
1965 | ol.disableAllBut(OutputGenerator::Html);␊ |
1966 | ␊ |
1967 | QListIterator<MemberList> mli(m_impl->memberLists);␊ |
1968 | MemberList *ml;␊ |
1969 | for (mli.toFirst();(ml=mli.current());++mli)␊ |
1970 | {␊ |
1971 | if (ml->listType()&MemberList::detailedLists)␊ |
1972 | {␊ |
1973 | ml->writeDocumentationPage(ol,name(),this);␊ |
1974 | }␊ |
1975 | }␊ |
1976 | ␊ |
1977 | ol.popGeneratorState();␊ |
1978 | }␊ |
1979 | ␊ |
1980 | void ClassDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const␊ |
1981 | {␊ |
1982 | static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");␊ |
1983 | ␊ |
1984 | ol.writeString(" <div class=\"navtab\">\n");␊ |
1985 | ol.writeString(" <table>\n");␊ |
1986 | ␊ |
1987 | if (m_impl->allMemberNameInfoSDict)␊ |
1988 | {␊ |
1989 | MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);␊ |
1990 | MemberNameInfo *mni;␊ |
1991 | for (;(mni=mnili.current());++mnili)␊ |
1992 | {␊ |
1993 | MemberNameInfoIterator mnii(*mni);␊ |
1994 | MemberInfo *mi;␊ |
1995 | for (mnii.toFirst();(mi=mnii.current());++mnii)␊ |
1996 | {␊ |
1997 | MemberDef *md=mi->memberDef;␊ |
1998 | if (md->getClassDef()==this && md->isLinkable())␊ |
1999 | {␊ |
2000 | ol.writeString(" <tr><td class=\"navtab\">");␊ |
2001 | if (md->isLinkableInProject())␊ |
2002 | {␊ |
2003 | if (md==currentMd) // selected item => highlight␊ |
2004 | {␊ |
2005 | ol.writeString("<a class=\"qindexHL\" ");␊ |
2006 | }␊ |
2007 | else␊ |
2008 | {␊ |
2009 | ol.writeString("<a class=\"qindex\" ");␊ |
2010 | }␊ |
2011 | ol.writeString("href=\"");␊ |
2012 | if (createSubDirs) ol.writeString("../../");␊ |
2013 | ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());␊ |
2014 | ol.writeString("\">");␊ |
2015 | ol.writeString(md->name());␊ |
2016 | ol.writeString("</a>");␊ |
2017 | }␊ |
2018 | ol.writeString("</td></tr>\n");␊ |
2019 | }␊ |
2020 | }␊ |
2021 | }␊ |
2022 | }␊ |
2023 | ␊ |
2024 | ol.writeString(" </table>\n");␊ |
2025 | ol.writeString(" </div>\n");␊ |
2026 | }␊ |
2027 | ␊ |
2028 | ␊ |
2029 | ␊ |
2030 | void ClassDef::writeDocumentationForInnerClasses(OutputList &ol)␊ |
2031 | {␊ |
2032 | // write inner classes after the parent, so the tag files contain␊ |
2033 | // the definition in proper order!␊ |
2034 | if (m_impl->innerClasses)␊ |
2035 | {␊ |
2036 | ClassSDict::Iterator cli(*m_impl->innerClasses);␊ |
2037 | ClassDef *innerCd;␊ |
2038 | for (cli.toFirst();(innerCd=cli.current());++cli)␊ |
2039 | {␊ |
2040 | if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&␊ |
2041 | (innerCd->protection()!=Private || Config_getBool("EXTRACT_PRIVATE"))␊ |
2042 | )␊ |
2043 | {␊ |
2044 | msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name()));␊ |
2045 | innerCd->writeDocumentation(ol);␊ |
2046 | innerCd->writeMemberList(ol);␊ |
2047 | }␊ |
2048 | innerCd->writeDocumentationForInnerClasses(ol);␊ |
2049 | }␊ |
2050 | }␊ |
2051 | }␊ |
2052 | ␊ |
2053 | // write the list of all (inherited) members for this class␊ |
2054 | void ClassDef::writeMemberList(OutputList &ol)␊ |
2055 | {␊ |
2056 | static bool cOpt = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");␊ |
2057 | static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");␊ |
2058 | static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");␊ |
2059 | if (m_impl->allMemberNameInfoSDict==0 || cOpt) return;␊ |
2060 | // only for HTML␊ |
2061 | ol.pushGeneratorState();␊ |
2062 | ol.disableAllBut(OutputGenerator::Html);␊ |
2063 | ␊ |
2064 | QCString memListFile = getMemberListFileName();␊ |
2065 | startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),␊ |
2066 | HLI_ClassVisible,!generateTreeView,getOutputFileBase()); ␊ |
2067 | if (!generateTreeView)␊ |
2068 | {␊ |
2069 | if (getOuterScope()!=Doxygen::globalScope)␊ |
2070 | {␊ |
2071 | writeNavigationPath(ol);␊ |
2072 | }␊ |
2073 | ol.endQuickIndices();␊ |
2074 | }␊ |
2075 | startTitle(ol,0);␊ |
2076 | ol.parseText(displayName()+" "+theTranslator->trMemberList());␊ |
2077 | endTitle(ol,0,0);␊ |
2078 | ol.startContents();␊ |
2079 | ol.parseText(theTranslator->trThisIsTheListOfAllMembers());␊ |
2080 | ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),displayName());␊ |
2081 | ol.parseText(theTranslator->trIncludingInheritedMembers());␊ |
2082 | ␊ |
2083 | //ol.startItemList();␊ |
2084 | ol.writeString("<table>\n");␊ |
2085 | ␊ |
2086 | //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first();␊ |
2087 | MemberNameInfoSDict::Iterator mnii(*m_impl->allMemberNameInfoSDict); ␊ |
2088 | MemberNameInfo *mni;␊ |
2089 | for (mnii.toFirst();(mni=mnii.current());++mnii)␊ |
2090 | {␊ |
2091 | MemberInfo *mi=mni->first();␊ |
2092 | while (mi)␊ |
2093 | {␊ |
2094 | MemberDef *md=mi->memberDef;␊ |
2095 | ClassDef *cd=md->getClassDef();␊ |
2096 | Protection prot = mi->prot;␊ |
2097 | Specifier virt=md->virtualness();␊ |
2098 | ␊ |
2099 | //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",␊ |
2100 | // name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);␊ |
2101 | ␊ |
2102 | ␊ |
2103 | if (cd && !md->name().isEmpty() && md->name()[0]!='@')␊ |
2104 | {␊ |
2105 | bool memberWritten=FALSE;␊ |
2106 | if (cd->isLinkable() && md->isLinkable()) ␊ |
2107 | // create a link to the documentation␊ |
2108 | {␊ |
2109 | QCString name=mi->ambiguityResolutionScope+md->name();␊ |
2110 | //ol.writeListItem();␊ |
2111 | ol.writeString(" <tr class=\"memlist\"><td>");␊ |
2112 | if (cd->isObjectiveC())␊ |
2113 | {␊ |
2114 | if (md->isObjCMethod())␊ |
2115 | {␊ |
2116 | if (md->isStatic())␊ |
2117 | ol.writeString("+ </td><td>");␊ |
2118 | else␊ |
2119 | ol.writeString("- </td><td>");␊ |
2120 | }␊ |
2121 | else␊ |
2122 | ol.writeString("</td><td>");␊ |
2123 | }␊ |
2124 | if (md->isObjCMethod())␊ |
2125 | {␊ |
2126 | ol.writeObjectLink(md->getReference(),␊ |
2127 | md->getOutputFileBase(),␊ |
2128 | md->anchor(),md->name());␊ |
2129 | }␊ |
2130 | else␊ |
2131 | {␊ |
2132 | //Definition *bd = md->getGroupDef();␊ |
2133 | //if (bd==0) bd=cd;␊ |
2134 | ol.writeObjectLink(md->getReference(),␊ |
2135 | md->getOutputFileBase(),␊ |
2136 | md->anchor(),name);␊ |
2137 | ␊ |
2138 | if ( md->isFunction() || md->isSignal() || md->isSlot() ||␊ |
2139 | (md->isFriend() && md->argsString())) ␊ |
2140 | ol.docify(md->argsString());␊ |
2141 | else if (md->isEnumerate())␊ |
2142 | ol.parseText(" "+theTranslator->trEnumName());␊ |
2143 | else if (md->isEnumValue())␊ |
2144 | ol.parseText(" "+theTranslator->trEnumValue());␊ |
2145 | else if (md->isTypedef())␊ |
2146 | ol.docify(" typedef");␊ |
2147 | else if (md->isFriend() && !strcmp(md->typeString(),"friend class"))␊ |
2148 | ol.docify(" class");␊ |
2149 | //ol.writeString("\n");␊ |
2150 | }␊ |
2151 | ol.writeString("</td>");␊ |
2152 | memberWritten=TRUE;␊ |
2153 | }␊ |
2154 | else if (!Config_getBool("HIDE_UNDOC_MEMBERS") && ␊ |
2155 | (md->protection()!=Private || Config_getBool("EXTRACT_PRIVATE") || md->isFriend()) ␊ |
2156 | ) // no documentation, ␊ |
2157 | // generate link to the class instead.␊ |
2158 | {␊ |
2159 | //ol.writeListItem();␊ |
2160 | ol.writeString(" <tr bgcolor=\"#f0f0f0\"><td>");␊ |
2161 | if (cd->isObjectiveC())␊ |
2162 | {␊ |
2163 | if (md->isObjCMethod())␊ |
2164 | {␊ |
2165 | if (md->isStatic())␊ |
2166 | ol.writeString("+ </td><td>");␊ |
2167 | else␊ |
2168 | ol.writeString("- </td><td>");␊ |
2169 | }␊ |
2170 | else␊ |
2171 | ol.writeString("</td><td>");␊ |
2172 | }␊ |
2173 | ol.startBold();␊ |
2174 | ol.docify(md->name());␊ |
2175 | ol.endBold();␊ |
2176 | if (!md->isObjCMethod())␊ |
2177 | {␊ |
2178 | if ( md->isFunction() || md->isSignal() || md->isSlot() ) ␊ |
2179 | ol.docify(md->argsString());␊ |
2180 | else if (md->isEnumerate())␊ |
2181 | ol.parseText(" "+theTranslator->trEnumName());␊ |
2182 | else if (md->isEnumValue())␊ |
2183 | ol.parseText(" "+theTranslator->trEnumValue());␊ |
2184 | else if (md->isTypedef())␊ |
2185 | ol.docify(" typedef");␊ |
2186 | }␊ |
2187 | ol.writeString(" (");␊ |
2188 | ol.parseText(theTranslator->trDefinedIn()+" ");␊ |
2189 | if (cd->isLinkable())␊ |
2190 | {␊ |
2191 | ol.writeObjectLink(␊ |
2192 | cd->getReference(),␊ |
2193 | cd->getOutputFileBase(),␊ |
2194 | cd->anchor(),␊ |
2195 | cd->displayName());␊ |
2196 | }␊ |
2197 | else␊ |
2198 | {␊ |
2199 | ol.startBold();␊ |
2200 | ol.docify(cd->displayName());␊ |
2201 | ol.endBold();␊ |
2202 | }␊ |
2203 | ol.writeString(")");␊ |
2204 | ol.writeString("</td>");␊ |
2205 | memberWritten=TRUE;␊ |
2206 | }␊ |
2207 | if (memberWritten)␊ |
2208 | {␊ |
2209 | ol.writeString("<td>");␊ |
2210 | ol.writeObjectLink(cd->getReference(),␊ |
2211 | cd->getOutputFileBase(),␊ |
2212 | cd->anchor(),␊ |
2213 | md->category() ? ␊ |
2214 | md->category()->displayName() : ␊ |
2215 | cd->displayName());␊ |
2216 | ol.writeString("</td>");␊ |
2217 | ol.writeString("<td>");␊ |
2218 | }␊ |
2219 | if (␊ |
2220 | (prot!=Public || (virt!=Normal && m_impl->lang!=SrcLangExt_ObjC) || ␊ |
2221 | md->isFriend() || md->isRelated() || md->isExplicit() ||␊ |
2222 | md->isMutable() || (md->isInline() && Config_getBool("INLINE_INFO")) ||␊ |
2223 | md->isSignal() || md->isSlot() ||␊ |
2224 | md->isStatic() || vhdlOpt␊ |
2225 | )␊ |
2226 | && memberWritten)␊ |
2227 | {␊ |
2228 | ol.startTypewriter();␊ |
2229 | ol.docify(" [");␊ |
2230 | QStrList sl;␊ |
2231 | if (vhdlOpt) sl.append(VhdlDocGen::trVhdlType(␊ |
2232 | md->getMemberSpecifiers())); //append vhdl type␊ |
2233 | else if (md->isFriend()) sl.append("friend");␊ |
2234 | else if (md->isRelated()) sl.append("related");␊ |
2235 | else␊ |
2236 | {␊ |
2237 | if (Config_getBool("INLINE_INFO") && md->isInline()) ␊ |
2238 | sl.append("inline");␊ |
2239 | if (md->isExplicit()) sl.append("explicit");␊ |
2240 | if (md->isMutable()) sl.append("mutable");␊ |
2241 | if (prot==Protected) sl.append("protected");␊ |
2242 | else if (prot==Private) sl.append("private");␊ |
2243 | else if (prot==Package) sl.append("package");␊ |
2244 | if (virt==Virtual && ␊ |
2245 | m_impl->lang!=SrcLangExt_ObjC) sl.append("virtual");␊ |
2246 | else if (virt==Pure) sl.append("pure virtual");␊ |
2247 | if (md->isStatic()) sl.append("static");␊ |
2248 | if (md->isSignal()) sl.append("signal");␊ |
2249 | if (md->isSlot()) sl.append("slot");␊ |
2250 | }␊ |
2251 | const char *s=sl.first();␊ |
2252 | while (s)␊ |
2253 | {␊ |
2254 | ol.docify(s);␊ |
2255 | s=sl.next();␊ |
2256 | if (s) ol.docify(", ");␊ |
2257 | }␊ |
2258 | ol.docify("]");␊ |
2259 | ol.endTypewriter();␊ |
2260 | }␊ |
2261 | if (memberWritten)␊ |
2262 | {␊ |
2263 | ol.writeString("</td>");␊ |
2264 | ol.writeString("</tr>\n");␊ |
2265 | }␊ |
2266 | }␊ |
2267 | mi=mni->next();␊ |
2268 | }␊ |
2269 | }␊ |
2270 | //ol.endItemList();␊ |
2271 | ␊ |
2272 | ol.writeString("</table>");␊ |
2273 | ␊ |
2274 | endFile(ol);␊ |
2275 | ol.popGeneratorState();␊ |
2276 | }␊ |
2277 | ␊ |
2278 | ␊ |
2279 | // add a reference to an example␊ |
2280 | bool ClassDef::addExample(const char *anchor,const char *nameStr,␊ |
2281 | const char *file)␊ |
2282 | {␊ |
2283 | if (m_impl->exampleSDict==0)␊ |
2284 | {␊ |
2285 | m_impl->exampleSDict = new ExampleSDict;␊ |
2286 | m_impl->exampleSDict->setAutoDelete(TRUE);␊ |
2287 | }␊ |
2288 | if (!m_impl->exampleSDict->find(nameStr))␊ |
2289 | {␊ |
2290 | Example *e=new Example;␊ |
2291 | e->anchor=anchor;␊ |
2292 | e->name=nameStr;␊ |
2293 | e->file=file;␊ |
2294 | m_impl->exampleSDict->inSort(nameStr,e);␊ |
2295 | return TRUE;␊ |
2296 | }␊ |
2297 | return FALSE;␊ |
2298 | }␊ |
2299 | ␊ |
2300 | // returns TRUE if this class is used in an example␊ |
2301 | bool ClassDef::hasExamples()␊ |
2302 | {␊ |
2303 | if (m_impl->exampleSDict==0) ␊ |
2304 | return FALSE;␊ |
2305 | else␊ |
2306 | return m_impl->exampleSDict->count()>0;␊ |
2307 | }␊ |
2308 | ␊ |
2309 | ␊ |
2310 | void ClassDef::setTemplateArguments(ArgumentList *al)␊ |
2311 | {␊ |
2312 | if (al==0) return;␊ |
2313 | if (!m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed␊ |
2314 | m_impl->tempArgs=new ArgumentList; ␊ |
2315 | ArgumentListIterator ali(*al);␊ |
2316 | Argument *a;␊ |
2317 | for (;(a=ali.current());++ali)␊ |
2318 | {␊ |
2319 | m_impl->tempArgs->append(new Argument(*a));␊ |
2320 | }␊ |
2321 | }␊ |
2322 | ␊ |
2323 | void ClassDef::setTypeConstraints(ArgumentList *al)␊ |
2324 | {␊ |
2325 | if (al==0) return;␊ |
2326 | if (!m_impl->typeConstraints) delete m_impl->typeConstraints;␊ |
2327 | m_impl->typeConstraints = new ArgumentList;␊ |
2328 | ArgumentListIterator ali(*al);␊ |
2329 | Argument *a;␊ |
2330 | for (;(a=ali.current());++ali)␊ |
2331 | {␊ |
2332 | m_impl->typeConstraints->append(new Argument(*a));␊ |
2333 | }␊ |
2334 | }␊ |
2335 | ␊ |
2336 | /*! Returns \c TRUE iff this class or a class inheriting from this class␊ |
2337 | * is \e not defined in an external tag file. ␊ |
2338 | */␊ |
2339 | bool ClassDef::hasNonReferenceSuperClass()␊ |
2340 | {␊ |
2341 | bool found=!isReference() && isLinkableInProject() && !isHidden(); ␊ |
2342 | if (found) ␊ |
2343 | {␊ |
2344 | return TRUE; // we're done if this class is not a reference␊ |
2345 | }␊ |
2346 | if (m_impl->inheritedBy)␊ |
2347 | {␊ |
2348 | BaseClassListIterator bcli(*m_impl->inheritedBy);␊ |
2349 | for ( ; bcli.current() && !found ; ++bcli ) // for each super class␊ |
2350 | {␊ |
2351 | ClassDef *bcd=bcli.current()->classDef;␊ |
2352 | // recurse into the super class branch␊ |
2353 | found = found || bcd->hasNonReferenceSuperClass(); ␊ |
2354 | if (!found)␊ |
2355 | {␊ |
2356 | // look for template instances that might have non-reference super classes␊ |
2357 | QDict<ClassDef> *cil = bcd->getTemplateInstances();␊ |
2358 | if (cil)␊ |
2359 | {␊ |
2360 | QDictIterator<ClassDef> tidi(*cil);␊ |
2361 | for ( ; tidi.current() && !found ; ++tidi) // for each template instance␊ |
2362 | {␊ |
2363 | // recurse into the template instance branch␊ |
2364 | found = found || tidi.current()->hasNonReferenceSuperClass();␊ |
2365 | }␊ |
2366 | }␊ |
2367 | }␊ |
2368 | }␊ |
2369 | }␊ |
2370 | return found;␊ |
2371 | }␊ |
2372 | ␊ |
2373 | /*! called from MemberDef::writeDeclaration() to (recusively) write the ␊ |
2374 | * definition of an anonymous struct, union or class.␊ |
2375 | */␊ |
2376 | void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup)␊ |
2377 | {␊ |
2378 | //ol.insertMemberAlign();␊ |
2379 | //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup);␊ |
2380 | ␊ |
2381 | //if (inGroup && md && md->getClassDef()==this) return;␊ |
2382 | ␊ |
2383 | ol.docify(compoundTypeString());␊ |
2384 | int ri=name().findRev("::");␊ |
2385 | if (ri==-1) ri=name().length();␊ |
2386 | QCString cn=name().right(name().length()-ri-2);␊ |
2387 | if (!cn.isEmpty() && cn.at(0)!='@' && md)␊ |
2388 | { ␊ |
2389 | if (cn.right(2)=="-p" || cn.right(2)=="-g")␊ |
2390 | {␊ |
2391 | cn = cn.left(cn.length()-2);␊ |
2392 | }␊ |
2393 | ol.docify(" ");␊ |
2394 | if (isLinkable())␊ |
2395 | {␊ |
2396 | ol.writeObjectLink(0,0,md->anchor(),cn);␊ |
2397 | }␊ |
2398 | else␊ |
2399 | {␊ |
2400 | ol.startBold();␊ |
2401 | ol.docify(cn);␊ |
2402 | ol.endBold();␊ |
2403 | }␊ |
2404 | }␊ |
2405 | ol.docify(" {");␊ |
2406 | ol.endMemberItem(); ␊ |
2407 | ␊ |
2408 | // write user defined member groups␊ |
2409 | if (m_impl->memberGroupSDict)␊ |
2410 | {␊ |
2411 | MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);␊ |
2412 | MemberGroup *mg;␊ |
2413 | for (;(mg=mgli.current());++mgli)␊ |
2414 | {␊ |
2415 | mg->setInGroup(inGroup);␊ |
2416 | mg->writePlainDeclarations(ol,this,0,0,0);␊ |
2417 | }␊ |
2418 | }␊ |
2419 | ␊ |
2420 | writePlainMemberDeclaration(ol,MemberList::pubTypes,inGroup);␊ |
2421 | writePlainMemberDeclaration(ol,MemberList::pubMethods,inGroup);␊ |
2422 | writePlainMemberDeclaration(ol,MemberList::pubAttribs,inGroup);␊ |
2423 | writePlainMemberDeclaration(ol,MemberList::pubSlots,inGroup);␊ |
2424 | writePlainMemberDeclaration(ol,MemberList::signals,inGroup);␊ |
2425 | writePlainMemberDeclaration(ol,MemberList::dcopMethods,inGroup);␊ |
2426 | writePlainMemberDeclaration(ol,MemberList::properties,inGroup);␊ |
2427 | writePlainMemberDeclaration(ol,MemberList::events,inGroup);␊ |
2428 | writePlainMemberDeclaration(ol,MemberList::pubStaticMethods,inGroup);␊ |
2429 | writePlainMemberDeclaration(ol,MemberList::pubStaticAttribs,inGroup);␊ |
2430 | writePlainMemberDeclaration(ol,MemberList::proTypes,inGroup);␊ |
2431 | writePlainMemberDeclaration(ol,MemberList::proMethods,inGroup);␊ |
2432 | writePlainMemberDeclaration(ol,MemberList::proAttribs,inGroup);␊ |
2433 | writePlainMemberDeclaration(ol,MemberList::proSlots,inGroup);␊ |
2434 | writePlainMemberDeclaration(ol,MemberList::proStaticMethods,inGroup);␊ |
2435 | writePlainMemberDeclaration(ol,MemberList::proStaticAttribs,inGroup);␊ |
2436 | writePlainMemberDeclaration(ol,MemberList::pacTypes,inGroup);␊ |
2437 | writePlainMemberDeclaration(ol,MemberList::pacMethods,inGroup);␊ |
2438 | writePlainMemberDeclaration(ol,MemberList::pacAttribs,inGroup);␊ |
2439 | writePlainMemberDeclaration(ol,MemberList::pacStaticMethods,inGroup);␊ |
2440 | writePlainMemberDeclaration(ol,MemberList::pacStaticAttribs,inGroup);␊ |
2441 | if (Config_getBool("EXTRACT_PRIVATE"))␊ |
2442 | {␊ |
2443 | writePlainMemberDeclaration(ol,MemberList::priTypes,inGroup);␊ |
2444 | writePlainMemberDeclaration(ol,MemberList::priMethods,inGroup);␊ |
2445 | writePlainMemberDeclaration(ol,MemberList::priAttribs,inGroup);␊ |
2446 | writePlainMemberDeclaration(ol,MemberList::priSlots,inGroup);␊ |
2447 | writePlainMemberDeclaration(ol,MemberList::priStaticMethods,inGroup);␊ |
2448 | writePlainMemberDeclaration(ol,MemberList::priStaticAttribs,inGroup);␊ |
2449 | }␊ |
2450 | writePlainMemberDeclaration(ol,MemberList::friends,inGroup);␊ |
2451 | writePlainMemberDeclaration(ol,MemberList::related,inGroup);␊ |
2452 | }␊ |
2453 | ␊ |
2454 | /*! a link to this class is possible within this project */␊ |
2455 | bool ClassDef::isLinkableInProject() const␊ |
2456 | { ␊ |
2457 | static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");␊ |
2458 | static bool extractLocal = Config_getBool("EXTRACT_LOCAL_CLASSES");␊ |
2459 | static bool extractStatic = Config_getBool("EXTRACT_STATIC");␊ |
2460 | static bool hideUndoc = Config_getBool("HIDE_UNDOC_CLASSES");␊ |
2461 | if (m_impl->templateMaster)␊ |
2462 | {␊ |
2463 | return m_impl->templateMaster->isLinkableInProject();␊ |
2464 | }␊ |
2465 | else␊ |
2466 | {␊ |
2467 | return !name().isEmpty() && /* has a name */␊ |
2468 | !isArtificial() && !isHidden() && /* not hidden */␊ |
2469 | name().find('@')==-1 && /* not anonymous */␊ |
2470 | (m_impl->prot!=Private || extractPrivate) && /* private */␊ |
2471 | (!m_impl->isLocal || extractLocal) && /* local */␊ |
2472 | (hasDocumentation() || !hideUndoc) && /* documented */ ␊ |
2473 | (!m_impl->isStatic || extractStatic) && /* static */␊ |
2474 | !isReference(); /* not an external reference */␊ |
2475 | }␊ |
2476 | }␊ |
2477 | ␊ |
2478 | bool ClassDef::isLinkable() const␊ |
2479 | {␊ |
2480 | if (m_impl->templateMaster)␊ |
2481 | {␊ |
2482 | return m_impl->templateMaster->isLinkable();␊ |
2483 | }␊ |
2484 | else␊ |
2485 | {␊ |
2486 | return isLinkableInProject() || isReference();␊ |
2487 | }␊ |
2488 | }␊ |
2489 | ␊ |
2490 | ␊ |
2491 | /*! the class is visible in a class diagram, or class hierarchy */␊ |
2492 | bool ClassDef::isVisibleInHierarchy() ␊ |
2493 | { ␊ |
2494 | static bool allExternals = Config_getBool("ALLEXTERNALS");␊ |
2495 | static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");␊ |
2496 | static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");␊ |
2497 | static bool extractStatic = Config_getBool("EXTRACT_STATIC");␊ |
2498 | ␊ |
2499 | return // show all classes or a subclass is visible␊ |
2500 | (allExternals || hasNonReferenceSuperClass()) &&␊ |
2501 | // and not an anonymous compound␊ |
2502 | name().find('@')==-1 &&␊ |
2503 | // not an artificially introduced class␊ |
2504 | !isArtificial() &&␊ |
2505 | // and not privately inherited␊ |
2506 | (m_impl->prot!=Private || extractPrivate) &&␊ |
2507 | // documented or shown anyway or documentation is external ␊ |
2508 | (hasDocumentation() || ␊ |
2509 | !hideUndocClasses || ␊ |
2510 | (m_impl->templateMaster && m_impl->templateMaster->hasDocumentation()) || ␊ |
2511 | isReference()␊ |
2512 | ) &&␊ |
2513 | // is not part of an unnamed namespace or shown anyway␊ |
2514 | (!m_impl->isStatic || extractStatic);␊ |
2515 | }␊ |
2516 | ␊ |
2517 | bool ClassDef::hasDocumentation() const␊ |
2518 | {␊ |
2519 | return Definition::hasDocumentation();␊ |
2520 | }␊ |
2521 | ␊ |
2522 | //----------------------------------------------------------------------␊ |
2523 | // recursive function:␊ |
2524 | // returns TRUE iff class definition `bcd' represents an (in)direct base ␊ |
2525 | // class of class definition `cd'.␊ |
2526 | ␊ |
2527 | bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level)␊ |
2528 | {␊ |
2529 | bool found=FALSE;␊ |
2530 | //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());␊ |
2531 | if (level>256)␊ |
2532 | {␊ |
2533 | err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(name()),qPrint(bcd->name()));␊ |
2534 | abort();␊ |
2535 | return FALSE;␊ |
2536 | }␊ |
2537 | if (baseClasses())␊ |
2538 | {␊ |
2539 | // Beware: trying to optimise the iterator away using ->first() & ->next()␊ |
2540 | // causes bug 625531␊ |
2541 | BaseClassListIterator bcli(*baseClasses());␊ |
2542 | for ( ; bcli.current() && !found ; ++bcli)␊ |
2543 | {␊ |
2544 | ClassDef *ccd=bcli.current()->classDef;␊ |
2545 | if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();␊ |
2546 | //printf("isBaseClass() baseclass %s\n",ccd->name().data());␊ |
2547 | if (ccd==bcd) ␊ |
2548 | found=TRUE;␊ |
2549 | else ␊ |
2550 | found=ccd->isBaseClass(bcd,followInstances,level+1);␊ |
2551 | }␊ |
2552 | }␊ |
2553 | return found;␊ |
2554 | }␊ |
2555 | ␊ |
2556 | //----------------------------------------------------------------------------␊ |
2557 | ␊ |
2558 | static bool isStandardFunc(MemberDef *md)␊ |
2559 | {␊ |
2560 | return md->name()=="operator=" || // assignment operator␊ |
2561 | md->isConstructor() || // constructor␊ |
2562 | md->isDestructor(); // destructor␊ |
2563 | }␊ |
2564 | ␊ |
2565 | /*! ␊ |
2566 | * recusively merges the `all members' lists of a class base ␊ |
2567 | * with that of this class. Must only be called for classes without␊ |
2568 | * subclasses!␊ |
2569 | */␊ |
2570 | void ClassDef::mergeMembers()␊ |
2571 | {␊ |
2572 | if (m_impl->membersMerged) return;␊ |
2573 | ␊ |
2574 | static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");␊ |
2575 | static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");␊ |
2576 | QCString sep="::";␊ |
2577 | if (optimizeOutputForJava || vhdlOpt) sep=".";␊ |
2578 | int sepLen = sep.length();␊ |
2579 | ␊ |
2580 | m_impl->membersMerged=TRUE;␊ |
2581 | //printf(" mergeMembers for %s\n",name().data());␊ |
2582 | bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB" );␊ |
2583 | if (baseClasses())␊ |
2584 | {␊ |
2585 | //printf(" => has base classes!\n");␊ |
2586 | BaseClassListIterator bcli(*baseClasses());␊ |
2587 | BaseClassDef *bcd;␊ |
2588 | for ( ; (bcd=bcli.current()) ; ++bcli )␊ |
2589 | {␊ |
2590 | ClassDef *bClass=bcd->classDef; ␊ |
2591 | ␊ |
2592 | // merge the members in the base class of this inheritance branch first␊ |
2593 | bClass->mergeMembers();␊ |
2594 | ␊ |
2595 | MemberNameInfoSDict *srcMnd = bClass->memberNameInfoSDict();␊ |
2596 | MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;␊ |
2597 | ␊ |
2598 | if (srcMnd)␊ |
2599 | {␊ |
2600 | MemberNameInfoSDict::Iterator srcMnili(*srcMnd);␊ |
2601 | MemberNameInfo *srcMni;␊ |
2602 | for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)␊ |
2603 | {␊ |
2604 | //printf(" Base member name %s\n",srcMni->memberName());␊ |
2605 | MemberNameInfo *dstMni;␊ |
2606 | if (dstMnd!=0 && (dstMni=dstMnd->find(srcMni->memberName())))␊ |
2607 | // a member with that name is already in the class.␊ |
2608 | // the member may hide or reimplement the one in the sub class␊ |
2609 | // or there may be another path to the base class that is already ␊ |
2610 | // visited via another branch in the class hierarchy.␊ |
2611 | {␊ |
2612 | MemberNameInfoIterator srcMnii(*srcMni); ␊ |
2613 | MemberInfo *srcMi;␊ |
2614 | for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )␊ |
2615 | {␊ |
2616 | MemberDef *srcMd = srcMi->memberDef;␊ |
2617 | bool found=FALSE;␊ |
2618 | bool ambigue=FALSE;␊ |
2619 | bool hidden=FALSE;␊ |
2620 | MemberNameInfoIterator dstMnii(*dstMni); ␊ |
2621 | MemberInfo *dstMi;␊ |
2622 | ClassDef *srcCd = srcMd->getClassDef();␊ |
2623 | for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii )␊ |
2624 | {␊ |
2625 | MemberDef *dstMd = dstMi->memberDef;␊ |
2626 | if (srcMd!=dstMd) // different members␊ |
2627 | {␊ |
2628 | ClassDef *dstCd = dstMd->getClassDef();␊ |
2629 | //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());␊ |
2630 | if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE)) ␊ |
2631 | // member is in the same or a base class␊ |
2632 | {␊ |
2633 | LockingPtr<ArgumentList> srcAl = srcMd->argumentList();␊ |
2634 | LockingPtr<ArgumentList> dstAl = dstMd->argumentList();␊ |
2635 | found=matchArguments2(␊ |
2636 | srcMd->getOuterScope(),srcMd->getFileDef(),srcAl.pointer(),␊ |
2637 | dstMd->getOuterScope(),dstMd->getFileDef(),dstAl.pointer(),␊ |
2638 | TRUE␊ |
2639 | );␊ |
2640 | //printf(" Yes, matching (%s<->%s): %d\n",␊ |
2641 | // argListToString(srcMd->argumentList()).data(),␊ |
2642 | // argListToString(dstMd->argumentList()).data(),␊ |
2643 | // found);␊ |
2644 | hidden = hidden || !found;␊ |
2645 | }␊ |
2646 | else // member is in a non base class => multiple inheritance␊ |
2647 | // using the same base class.␊ |
2648 | {␊ |
2649 | //printf("$$ Existing member %s %s add scope %s\n",␊ |
2650 | // dstMi->ambiguityResolutionScope.data(),␊ |
2651 | // dstMd->name().data(),␊ |
2652 | // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());␊ |
2653 | ␊ |
2654 | QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);␊ |
2655 | if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))␊ |
2656 | dstMi->ambiguityResolutionScope.prepend(scope);␊ |
2657 | ambigue=TRUE;␊ |
2658 | }␊ |
2659 | }␊ |
2660 | else // same members␊ |
2661 | {␊ |
2662 | // do not add if base class is virtual or ␊ |
2663 | // if scope paths are equal or␊ |
2664 | // if base class is an interface (and thus implicitly virtual).␊ |
2665 | //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);␊ |
2666 | if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||␊ |
2667 | bClass->name()+sep+srcMi->scopePath == dstMi->scopePath ||␊ |
2668 | dstMd->getClassDef()->compoundType()==Interface␊ |
2669 | ) ␊ |
2670 | {␊ |
2671 | found=TRUE;␊ |
2672 | }␊ |
2673 | else // member can be reached via multiple paths in the ␊ |
2674 | // inheritance tree␊ |
2675 | {␊ |
2676 | //printf("$$ Existing member %s %s add scope %s\n",␊ |
2677 | // dstMi->ambiguityResolutionScope.data(),␊ |
2678 | // dstMd->name().data(),␊ |
2679 | // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());␊ |
2680 | ␊ |
2681 | QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);␊ |
2682 | if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))␊ |
2683 | {␊ |
2684 | dstMi->ambiguityResolutionScope.prepend(scope);␊ |
2685 | }␊ |
2686 | ambigue=TRUE;␊ |
2687 | }␊ |
2688 | }␊ |
2689 | }␊ |
2690 | //printf("member %s::%s hidden %d ambigue %d srcMi->ambigClass=%p\n",␊ |
2691 | // srcCd->name().data(),srcMd->name().data(),hidden,ambigue,srcMi->ambigClass);␊ |
2692 | ␊ |
2693 | // TODO: fix the case where a member is hidden by inheritance␊ |
2694 | // of a member with the same name but with another prototype,␊ |
2695 | // while there is more than one path to the member in the ␊ |
2696 | // base class due to multiple inheritance. In this case␊ |
2697 | // it seems that the member is not reachable by prefixing a ␊ |
2698 | // scope name either (according to my compiler). Currently, ␊ |
2699 | // this case is shown anyway.␊ |
2700 | if (!found && srcMd->protection()!=Private)␊ |
2701 | {␊ |
2702 | Protection prot=srcMd->protection();␊ |
2703 | if (bcd->prot==Protected && prot==Public) prot=bcd->prot;␊ |
2704 | else if (bcd->prot==Private) prot=bcd->prot;␊ |
2705 | ␊ |
2706 | if (inlineInheritedMembers)␊ |
2707 | {␊ |
2708 | if (!isStandardFunc(srcMd))␊ |
2709 | {␊ |
2710 | //printf(" insertMember `%s'\n",srcMd->name().data());␊ |
2711 | internalInsertMember(srcMd,prot,FALSE);␊ |
2712 | }␊ |
2713 | }␊ |
2714 | ␊ |
2715 | Specifier virt=srcMi->virt;␊ |
2716 | if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;␊ |
2717 | ␊ |
2718 | MemberInfo *newMi = new MemberInfo(srcMd,prot,virt,TRUE);␊ |
2719 | newMi->scopePath=bClass->name()+sep+srcMi->scopePath;␊ |
2720 | if (ambigue)␊ |
2721 | {␊ |
2722 | //printf("$$ New member %s %s add scope %s::\n",␊ |
2723 | // srcMi->ambiguityResolutionScope.data(),␊ |
2724 | // srcMd->name().data(),␊ |
2725 | // bClass->name().data());␊ |
2726 | ␊ |
2727 | QCString scope=bClass->name()+sep;␊ |
2728 | if (scope!=srcMi->ambiguityResolutionScope.left(scope.length()))␊ |
2729 | {␊ |
2730 | newMi->ambiguityResolutionScope=␊ |
2731 | scope+srcMi->ambiguityResolutionScope.copy();␊ |
2732 | }␊ |
2733 | }␊ |
2734 | if (hidden)␊ |
2735 | {␊ |
2736 | if (srcMi->ambigClass==0)␊ |
2737 | {␊ |
2738 | newMi->ambigClass=bClass;␊ |
2739 | newMi->ambiguityResolutionScope=bClass->name()+sep;␊ |
2740 | }␊ |
2741 | else␊ |
2742 | {␊ |
2743 | newMi->ambigClass=srcMi->ambigClass;␊ |
2744 | newMi->ambiguityResolutionScope=srcMi->ambigClass->name()+sep;␊ |
2745 | }␊ |
2746 | }␊ |
2747 | dstMni->append(newMi);␊ |
2748 | }␊ |
2749 | }␊ |
2750 | }␊ |
2751 | else // base class has a member that is not in the sub class => copy␊ |
2752 | {␊ |
2753 | // create a deep copy of the list (only the MemberInfo's will be ␊ |
2754 | // copied, not the actual MemberDef's)␊ |
2755 | MemberNameInfo *newMni = 0;␊ |
2756 | newMni = new MemberNameInfo(srcMni->memberName()); ␊ |
2757 | ␊ |
2758 | // copy the member(s) from the base to the sub class␊ |
2759 | MemberNameInfoIterator mnii(*srcMni);␊ |
2760 | MemberInfo *mi;␊ |
2761 | for (;(mi=mnii.current());++mnii)␊ |
2762 | {␊ |
2763 | Protection prot = mi->prot;␊ |
2764 | if (bcd->prot==Protected)␊ |
2765 | {␊ |
2766 | if (prot==Public) prot=Protected;␊ |
2767 | }␊ |
2768 | else if (bcd->prot==Private)␊ |
2769 | {␊ |
2770 | prot=Private;␊ |
2771 | }␊ |
2772 | //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",␊ |
2773 | // name().data(),mi->memberDef->name().data(),mi->prot,␊ |
2774 | // bcd->prot,prot);␊ |
2775 | ␊ |
2776 | if (mi->prot!=Private)␊ |
2777 | {␊ |
2778 | Specifier virt=mi->virt;␊ |
2779 | if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;␊ |
2780 | ␊ |
2781 | if (inlineInheritedMembers)␊ |
2782 | {␊ |
2783 | if (!isStandardFunc(mi->memberDef))␊ |
2784 | {␊ |
2785 | //printf(" insertMember `%s'\n",mi->memberDef->name().data());␊ |
2786 | internalInsertMember(mi->memberDef,prot,FALSE);␊ |
2787 | }␊ |
2788 | }␊ |
2789 | //printf("Adding!\n");␊ |
2790 | MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);␊ |
2791 | newMi->scopePath=bClass->name()+sep+mi->scopePath;␊ |
2792 | newMi->ambigClass=mi->ambigClass;␊ |
2793 | newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope.copy();␊ |
2794 | newMni->append(newMi);␊ |
2795 | }␊ |
2796 | }␊ |
2797 | ␊ |
2798 | if (dstMnd==0)␊ |
2799 | {␊ |
2800 | m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);␊ |
2801 | m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);␊ |
2802 | dstMnd = m_impl->allMemberNameInfoSDict;␊ |
2803 | }␊ |
2804 | // add it to the dictionary␊ |
2805 | dstMnd->append(newMni->memberName(),newMni);␊ |
2806 | }␊ |
2807 | }␊ |
2808 | }␊ |
2809 | }␊ |
2810 | }␊ |
2811 | //printf(" end mergeMembers\n");␊ |
2812 | }␊ |
2813 | ␊ |
2814 | //----------------------------------------------------------------------------␊ |
2815 | ␊ |
2816 | /*! Merges the members of a Objective-C category into this class.␊ |
2817 | */␊ |
2818 | void ClassDef::mergeCategory(ClassDef *category)␊ |
2819 | {␊ |
2820 | category->setCategoryOf(this);␊ |
2821 | category->setArtificial(TRUE);␊ |
2822 | ␊ |
2823 | MemberNameInfoSDict *srcMnd = category->memberNameInfoSDict();␊ |
2824 | MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;␊ |
2825 | ␊ |
2826 | if (srcMnd && dstMnd)␊ |
2827 | {␊ |
2828 | MemberNameInfoSDict::Iterator srcMnili(*srcMnd);␊ |
2829 | MemberNameInfo *srcMni;␊ |
2830 | for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)␊ |
2831 | {␊ |
2832 | MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());␊ |
2833 | if (dstMni) // method is already defined in the class␊ |
2834 | {␊ |
2835 | // TODO: we should remove the other member and insert this one.␊ |
2836 | }␊ |
2837 | else // new method name␊ |
2838 | {␊ |
2839 | // create a deep copy of the list␊ |
2840 | MemberNameInfo *newMni = 0;␊ |
2841 | newMni = new MemberNameInfo(srcMni->memberName()); ␊ |
2842 | ␊ |
2843 | // copy the member(s) from the category to this class␊ |
2844 | MemberNameInfoIterator mnii(*srcMni);␊ |
2845 | MemberInfo *mi;␊ |
2846 | for (;(mi=mnii.current());++mnii)␊ |
2847 | {␊ |
2848 | //printf("Adding '%s'\n",mi->memberDef->name().data());␊ |
2849 | MemberInfo *newMi=new MemberInfo(mi->memberDef,mi->prot,mi->virt,mi->inherited);␊ |
2850 | newMi->scopePath=mi->scopePath;␊ |
2851 | newMi->ambigClass=mi->ambigClass;␊ |
2852 | newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope;␊ |
2853 | newMni->append(newMi);␊ |
2854 | mi->memberDef->moveTo(this);␊ |
2855 | mi->memberDef->setCategory(category);␊ |
2856 | internalInsertMember(mi->memberDef,mi->prot,FALSE);␊ |
2857 | }␊ |
2858 | ␊ |
2859 | // add it to the dictionary␊ |
2860 | dstMnd->append(newMni->memberName(),newMni);␊ |
2861 | }␊ |
2862 | }␊ |
2863 | }␊ |
2864 | }␊ |
2865 | ␊ |
2866 | //----------------------------------------------------------------------------␊ |
2867 | ␊ |
2868 | void ClassDef::addUsedClass(ClassDef *cd,const char *accessName)␊ |
2869 | {␊ |
2870 | //printf("%s::addUsedClass(%s,%s)\n",name().data(),cd->name().data(),accessName);␊ |
2871 | if (m_impl->usesImplClassDict==0) ␊ |
2872 | {␊ |
2873 | m_impl->usesImplClassDict = new UsesClassDict(17); ␊ |
2874 | m_impl->usesImplClassDict->setAutoDelete(TRUE);␊ |
2875 | }␊ |
2876 | UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());␊ |
2877 | if (ucd==0)␊ |
2878 | {␊ |
2879 | ucd = new UsesClassDef(cd);␊ |
2880 | m_impl->usesImplClassDict->insert(cd->name(),ucd);␊ |
2881 | //printf("Adding used class %s to class %s via accessor %s\n",␊ |
2882 | // cd->name().data(),name().data(),accessName);␊ |
2883 | }␊ |
2884 | ucd->addAccessor(accessName);␊ |
2885 | }␊ |
2886 | ␊ |
2887 | void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName)␊ |
2888 | {␊ |
2889 | //printf("%s::addUsedByClass(%s,%s)\n",name().data(),cd->name().data(),accessName);␊ |
2890 | if (m_impl->usedByImplClassDict==0) ␊ |
2891 | {␊ |
2892 | m_impl->usedByImplClassDict = new UsesClassDict(17); ␊ |
2893 | m_impl->usedByImplClassDict->setAutoDelete(TRUE);␊ |
2894 | }␊ |
2895 | UsesClassDef *ucd=m_impl->usedByImplClassDict->find(cd->name());␊ |
2896 | if (ucd==0)␊ |
2897 | {␊ |
2898 | ucd = new UsesClassDef(cd);␊ |
2899 | m_impl->usedByImplClassDict->insert(cd->name(),ucd);␊ |
2900 | //printf("Adding used by class %s to class %s\n",␊ |
2901 | // cd->name().data(),name().data());␊ |
2902 | }␊ |
2903 | ucd->addAccessor(accessName);␊ |
2904 | }␊ |
2905 | ␊ |
2906 | ␊ |
2907 | #if 0␊ |
2908 | /*! Builds up a dictionary of all classes that are used by the state of this ␊ |
2909 | * class (the "implementation"). ␊ |
2910 | * Must be called before mergeMembers() is called!␊ |
2911 | */␊ |
2912 | ␊ |
2913 | void ClassDef::determineImplUsageRelation()␊ |
2914 | {␊ |
2915 | MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);␊ |
2916 | MemberNameInfo *mni;␊ |
2917 | for (;(mni=mnili.current());++mnili)␊ |
2918 | {␊ |
2919 | MemberNameInfoIterator mnii(*mni);␊ |
2920 | MemberInfo *mi;␊ |
2921 | for (mnii.toFirst();(mi=mnii.current());++mnii)␊ |
2922 | {␊ |
2923 | MemberDef *md=mi->memberDef;␊ |
2924 | if (md->isVariable()) // for each member variable in this class␊ |
2925 | {␊ |
2926 | QCString type=removeRedundantWhiteSpace(md->typeString());␊ |
2927 | //printf("in class %s found var type=`%s' name=`%s'\n",␊ |
2928 | // name().data(),type.data(),md->name().data());␊ |
2929 | int pos=0;␊ |
2930 | QCString usedClassName;␊ |
2931 | QCString templSpec;␊ |
2932 | bool found=FALSE;␊ |
2933 | while (extractClassNameFromType(type,pos,usedClassName,templSpec)!=-1 && !found)␊ |
2934 | {␊ |
2935 | //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data());␊ |
2936 | // check if usedClassName is a template argument of its class␊ |
2937 | ClassDef *cd=md->getClassDef();␊ |
2938 | if (cd && cd->templateArguments())␊ |
2939 | {␊ |
2940 | ArgumentListIterator ali(*cd->templateArguments());␊ |
2941 | Argument *arg;␊ |
2942 | int count=0;␊ |
2943 | for (ali.toFirst();(arg=ali.current());++ali,++count)␊ |
2944 | {␊ |
2945 | if (arg->name==usedClassName) // type is a template argument␊ |
2946 | {␊ |
2947 | found=TRUE;␊ |
2948 | if (m_impl->usesImplClassDict==0) m_impl->usesImplClassDict = new UsesClassDict(257); ␊ |
2949 | cd = new ClassDef(cd->getDefFileName(),cd->getDefLine(),␊ |
2950 | usedClassName,ClassDef::Class);␊ |
2951 | cd->setIsTemplateBaseClass(count);␊ |
2952 | UsesClassDef *ucd = new UsesClassDef(cd);␊ |
2953 | m_impl->usesImplClassDict->insert(cd->name(),ucd);␊ |
2954 | ucd->templSpecifiers = templSpec;␊ |
2955 | ucd->addAccessor(md->name());␊ |
2956 | Doxygen::hiddenClasses.append(cd);␊ |
2957 | //printf("Adding used template argument %s to class %s\n",␊ |
2958 | // cd->name().data(),name().data());␊ |
2959 | //printf("Adding accessor %s to class %s\n",␊ |
2960 | // md->name().data(),ucd->classDef->name().data());␊ |
2961 | }␊ |
2962 | }␊ |
2963 | }␊ |
2964 | ␊ |
2965 | if (!found)␊ |
2966 | {␊ |
2967 | cd=0;␊ |
2968 | if (getNamespaceDef()!=0)␊ |
2969 | {␊ |
2970 | cd=getResolvedClass(getNamespaceDef()->name()+"::"+usedClassName,0,&templSpec);␊ |
2971 | }␊ |
2972 | if (cd==0) cd=getResolvedClass(name()+"::"+usedClassName,0,&templSpec);␊ |
2973 | if (cd==0) cd=getResolvedClass(usedClassName,0,&templSpec); // TODO: also try inbetween scopes!␊ |
2974 | //printf("Search for class %s result=%p\n",usedClassName.data(),cd);␊ |
2975 | if (cd) // class exists ␊ |
2976 | {␊ |
2977 | found=TRUE;␊ |
2978 | if (m_impl->usesImplClassDict==0) ␊ |
2979 | {␊ |
2980 | m_impl->usesImplClassDict = new UsesClassDict(257); ␊ |
2981 | m_impl->usesImplClassDict->setAutoDelete(TRUE);␊ |
2982 | }␊ |
2983 | UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());␊ |
2984 | if (ucd==0 || ucd->templSpecifiers!=templSpec)␊ |
2985 | {␊ |
2986 | ucd = new UsesClassDef(cd);␊ |
2987 | m_impl->usesImplClassDict->insert(cd->name(),ucd);␊ |
2988 | ucd->templSpecifiers = templSpec;␊ |
2989 | //printf("Adding used class %s to class %s\n",␊ |
2990 | // cd->name().data(),name().data());␊ |
2991 | }␊ |
2992 | ucd->addAccessor(md->name());␊ |
2993 | //printf("Adding accessor %s to class %s\n",␊ |
2994 | // md->name().data(),ucd->classDef->name().data());␊ |
2995 | }␊ |
2996 | }␊ |
2997 | }␊ |
2998 | }␊ |
2999 | }␊ |
3000 | }␊ |
3001 | #ifdef DUMP␊ |
3002 | if (m_impl->usesClassDict)␊ |
3003 | {␊ |
3004 | msg("Class %s uses the following classes:\n",name().data());␊ |
3005 | UsesClassDictIterator ucdi(*m_impl->usesClassDict);␊ |
3006 | UsesClassDef *ucd;␊ |
3007 | for (;(ucd=ucdi.current());++ucdi)␊ |
3008 | {␊ |
3009 | msg(" %s via ",ucd->classDef->name().data());␊ |
3010 | QDictIterator<void> dvi(*ucd->accessors); ␊ |
3011 | const char *s;␊ |
3012 | for (;(s=dvi.currentKey());++dvi)␊ |
3013 | {␊ |
3014 | msg("%s ",s);␊ |
3015 | }␊ |
3016 | msg("\n");␊ |
3017 | }␊ |
3018 | }␊ |
3019 | #endif␊ |
3020 | }␊ |
3021 | ␊ |
3022 | //----------------------------------------------------------------------------␊ |
3023 | ␊ |
3024 | // I have disabled this code because the graphs it renders quickly become␊ |
3025 | // too large to be of practical use.␊ |
3026 | ␊ |
3027 | void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr)␊ |
3028 | {␊ |
3029 | QCString type = typeStr;␊ |
3030 | static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");␊ |
3031 | int p=0,i,l;␊ |
3032 | while ((i=re.match(type,p,&l))!=-1) // for each class name in the type␊ |
3033 | {␊ |
3034 | ClassDef *cd=getClass(name()+"::"+type.mid(i,l));␊ |
3035 | if (cd==0) cd=getClass(type.mid(i,l)); // TODO: also try inbetween scopes!␊ |
3036 | if (cd && cd!=this && !isBaseClass(cd))␊ |
3037 | {␊ |
3038 | if (m_impl->usesIntfClassDict==0) ␊ |
3039 | {␊ |
3040 | m_impl->usesIntfClassDict = new UsesClassDict(257); ␊ |
3041 | }␊ |
3042 | UsesClassDef *ucd=m_impl->usesIntfClassDict->find(cd->name());␊ |
3043 | if (ucd==0)␊ |
3044 | {␊ |
3045 | ucd = new UsesClassDef(cd);␊ |
3046 | m_impl->usesIntfClassDict->insert(cd->name(),ucd);␊ |
3047 | //printf("in class `%s' adding used intf class `%s'\n",␊ |
3048 | // name().data(),cd->name().data());␊ |
3049 | }␊ |
3050 | ucd->addAccessor(md->name());␊ |
3051 | //printf("in class `%s' adding accessor `%s' to class `%s'\n",␊ |
3052 | // name().data(),md->name().data(),ucd->classDef->name().data());␊ |
3053 | }␊ |
3054 | p=i+l;␊ |
3055 | }␊ |
3056 | }␊ |
3057 | ␊ |
3058 | void ClassDef::determineIntfUsageRelation()␊ |
3059 | {␊ |
3060 | MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoList);␊ |
3061 | MemberNameInfo *mni;␊ |
3062 | for (;(mni=mnili.current());++mnili)␊ |
3063 | {␊ |
3064 | MemberNameInfoIterator mnii(*mni);␊ |
3065 | MemberInfo *mi;␊ |
3066 | for (mnii.toFirst();(mi=mnii.current());++mnii)␊ |
3067 | {␊ |
3068 | MemberDef *md=mi->memberDef;␊ |
3069 | ␊ |
3070 | // compute the protection level for this member␊ |
3071 | Protection protect=md->protection();␊ |
3072 | if (mi->prot==Protected) // inherited protection␊ |
3073 | {␊ |
3074 | if (protect==Public) protect=Protected;␊ |
3075 | else if (protect==Protected) protect=Private;␊ |
3076 | }␊ |
3077 | ␊ |
3078 | if (!md->name().isEmpty() && md->name()[0]!='@' && ␊ |
3079 | (mi->prot!=Private && protect!=Private)␊ |
3080 | )␊ |
3081 | {␊ |
3082 | // add classes found in the return type␊ |
3083 | addUsedInterfaceClasses(md,md->typeString());␊ |
3084 | ArgumentList *al = md->argumentList();␊ |
3085 | if (al) // member has arguments␊ |
3086 | {␊ |
3087 | // add classes found in the types of the argument list␊ |
3088 | ArgumentListIterator ali(*al);␊ |
3089 | Argument *a;␊ |
3090 | for (;(a=ali.current());++ali)␊ |
3091 | {␊ |
3092 | if (!a->type.isEmpty() && a->type.at(0)!='@')␊ |
3093 | {␊ |
3094 | addUsedInterfaceClasses(md,a->type);␊ |
3095 | }␊ |
3096 | }␊ |
3097 | }␊ |
3098 | }␊ |
3099 | }␊ |
3100 | }␊ |
3101 | }␊ |
3102 | #endif␊ |
3103 | ␊ |
3104 | QCString ClassDef::compoundTypeString() const␊ |
3105 | {␊ |
3106 | if (m_impl->compType==Interface && m_impl->lang==SrcLangExt_ObjC) return "class";␊ |
3107 | if (Config_getBool("OPTIMIZE_FOR_FORTRAN"))␊ |
3108 | {␊ |
3109 | switch (m_impl->compType)␊ |
3110 | {␊ |
3111 | case Class: return "module";␊ |
3112 | case Struct: return "type";␊ |
3113 | case Union: return "union";␊ |
3114 | case Interface: return "interface";␊ |
3115 | case Protocol: return "protocol";␊ |
3116 | case Category: return "category";␊ |
3117 | case Exception: return "exception";␊ |
3118 | default: return "unknown";␊ |
3119 | } ␊ |
3120 | }␊ |
3121 | else␊ |
3122 | {␊ |
3123 | switch (m_impl->compType)␊ |
3124 | {␊ |
3125 | case Class: return "class";␊ |
3126 | case Struct: return "struct";␊ |
3127 | case Union: return "union";␊ |
3128 | case Interface: return "interface";␊ |
3129 | case Protocol: return "protocol";␊ |
3130 | case Category: return "category";␊ |
3131 | case Exception: return "exception";␊ |
3132 | default: return "unknown";␊ |
3133 | }␊ |
3134 | }␊ |
3135 | }␊ |
3136 | ␊ |
3137 | QCString ClassDef::getXmlOutputFileBase() const␊ |
3138 | {␊ |
3139 | if (m_impl->templateMaster)␊ |
3140 | {␊ |
3141 | // point to the template of which this class is an instance␊ |
3142 | return m_impl->templateMaster->getOutputFileBase();␊ |
3143 | }␊ |
3144 | else if (isReference())␊ |
3145 | {␊ |
3146 | // point to the external location␊ |
3147 | return m_impl->fileName;␊ |
3148 | }␊ |
3149 | else␊ |
3150 | {␊ |
3151 | // normal locally defined class␊ |
3152 | return convertNameToFile(m_impl->fileName); ␊ |
3153 | }␊ |
3154 | }␊ |
3155 | ␊ |
3156 | QCString ClassDef::getOutputFileBase() const ␊ |
3157 | { ␊ |
3158 | static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");␊ |
3159 | if (inlineGroupedClasses && partOfGroups()!=0)␊ |
3160 | {␊ |
3161 | // point to the group that embeds this class␊ |
3162 | return partOfGroups()->at(0)->getOutputFileBase();␊ |
3163 | }␊ |
3164 | else␊ |
3165 | {␊ |
3166 | return getXmlOutputFileBase();␊ |
3167 | }␊ |
3168 | }␊ |
3169 | ␊ |
3170 | QCString ClassDef::getInstanceOutputFileBase() const ␊ |
3171 | { ␊ |
3172 | if (isReference())␊ |
3173 | {␊ |
3174 | return m_impl->fileName;␊ |
3175 | }␊ |
3176 | else␊ |
3177 | {␊ |
3178 | return convertNameToFile(m_impl->fileName); ␊ |
3179 | }␊ |
3180 | }␊ |
3181 | ␊ |
3182 | QCString ClassDef::getFileBase() const ␊ |
3183 | { ␊ |
3184 | if (m_impl->templateMaster)␊ |
3185 | {␊ |
3186 | return m_impl->templateMaster->getFileBase();␊ |
3187 | }␊ |
3188 | else␊ |
3189 | {␊ |
3190 | return m_impl->fileName; ␊ |
3191 | }␊ |
3192 | }␊ |
3193 | ␊ |
3194 | QCString ClassDef::getSourceFileBase() const ␊ |
3195 | { ␊ |
3196 | if (m_impl->templateMaster)␊ |
3197 | {␊ |
3198 | return m_impl->templateMaster->getSourceFileBase();␊ |
3199 | }␊ |
3200 | else␊ |
3201 | {␊ |
3202 | return convertNameToFile(m_impl->fileName)+"_source"; ␊ |
3203 | }␊ |
3204 | }␊ |
3205 | ␊ |
3206 | void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)␊ |
3207 | {␊ |
3208 | gd->addClass(this);␊ |
3209 | //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data());␊ |
3210 | if (m_impl->allMemberNameInfoSDict==0) return;␊ |
3211 | MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);␊ |
3212 | MemberNameInfo *mni;␊ |
3213 | for (;(mni=mnili.current());++mnili)␊ |
3214 | {␊ |
3215 | MemberNameInfoIterator mnii(*mni);␊ |
3216 | MemberInfo *mi;␊ |
3217 | for (mnii.toFirst();(mi=mnii.current());++mnii)␊ |
3218 | {␊ |
3219 | MemberDef *md=mi->memberDef;␊ |
3220 | md->setGroupDef(gd,pri,fileName,startLine,hasDocs);␊ |
3221 | gd->insertMember(md,TRUE);␊ |
3222 | ClassDef *innerClass = md->getClassDefOfAnonymousType();␊ |
3223 | if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);␊ |
3224 | }␊ |
3225 | }␊ |
3226 | }␊ |
3227 | ␊ |
3228 | void ClassDef::addInnerCompound(Definition *d)␊ |
3229 | {␊ |
3230 | //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data());␊ |
3231 | if (d->definitionType()==Definition::TypeClass) // only classes can be␊ |
3232 | // nested in classes.␊ |
3233 | {␊ |
3234 | if (m_impl->innerClasses==0)␊ |
3235 | {␊ |
3236 | m_impl->innerClasses = new ClassSDict(17);␊ |
3237 | }␊ |
3238 | m_impl->innerClasses->inSort(d->localName(),(ClassDef *)d);␊ |
3239 | }␊ |
3240 | }␊ |
3241 | ␊ |
3242 | Definition *ClassDef::findInnerCompound(const char *name)␊ |
3243 | {␊ |
3244 | Definition *result=0;␊ |
3245 | if (name==0) return 0;␊ |
3246 | if (m_impl->innerClasses)␊ |
3247 | {␊ |
3248 | result = m_impl->innerClasses->find(name);␊ |
3249 | }␊ |
3250 | return result;␊ |
3251 | }␊ |
3252 | ␊ |
3253 | //void ClassDef::initTemplateMapping()␊ |
3254 | //{␊ |
3255 | // m_impl->templateMapping->clear();␊ |
3256 | // ArgumentList *al = templateArguments();␊ |
3257 | // if (al)␊ |
3258 | // {␊ |
3259 | // ArgumentListIterator ali(*al);␊ |
3260 | // Argument *arg;␊ |
3261 | // for (ali.toFirst();(arg=ali.current());++ali)␊ |
3262 | // {␊ |
3263 | // setTemplateArgumentMapping(arg->name,arg->defval);␊ |
3264 | // }␊ |
3265 | // }␊ |
3266 | //}␊ |
3267 | //void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)␊ |
3268 | //{␊ |
3269 | // //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);␊ |
3270 | // if (m_impl->templateMapping && formal)␊ |
3271 | // {␊ |
3272 | // if (m_impl->templateMapping->find(formal))␊ |
3273 | // {␊ |
3274 | // m_impl->templateMapping->remove(formal);␊ |
3275 | // }␊ |
3276 | // m_impl->templateMapping->insert(formal,new QCString(actual));␊ |
3277 | // }␊ |
3278 | //}␊ |
3279 | //␊ |
3280 | //QCString ClassDef::getTemplateArgumentMapping(const char *formal) const␊ |
3281 | //{␊ |
3282 | // if (m_impl->templateMapping && formal)␊ |
3283 | // {␊ |
3284 | // QCString *s = m_impl->templateMapping->find(formal);␊ |
3285 | // if (s)␊ |
3286 | // {␊ |
3287 | // return *s;␊ |
3288 | // }␊ |
3289 | // }␊ |
3290 | // return "";␊ |
3291 | //}␊ |
3292 | ␊ |
3293 | ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,␊ |
3294 | int startLine, const QCString &templSpec,bool &freshInstance)␊ |
3295 | {␊ |
3296 | freshInstance = FALSE;␊ |
3297 | if (m_impl->templateInstances==0) ␊ |
3298 | {␊ |
3299 | m_impl->templateInstances = new QDict<ClassDef>(17);␊ |
3300 | }␊ |
3301 | ClassDef *templateClass=m_impl->templateInstances->find(templSpec);␊ |
3302 | if (templateClass==0)␊ |
3303 | {␊ |
3304 | Debug::print(Debug::Classes,0," New template instance class `%s'`%s'\n",name().data(),templSpec.data());␊ |
3305 | templateClass = new ClassDef(␊ |
3306 | fileName,startLine,localName()+templSpec,ClassDef::Class);␊ |
3307 | templateClass->setTemplateMaster(this);␊ |
3308 | templateClass->setOuterScope(getOuterScope());␊ |
3309 | templateClass->setHidden(isHidden());␊ |
3310 | m_impl->templateInstances->insert(templSpec,templateClass);␊ |
3311 | freshInstance=TRUE;␊ |
3312 | }␊ |
3313 | return templateClass;␊ |
3314 | }␊ |
3315 | ␊ |
3316 | ClassDef *ClassDef::getVariableInstance(const char *templSpec)␊ |
3317 | {␊ |
3318 | if (m_impl->variableInstances==0) ␊ |
3319 | {␊ |
3320 | m_impl->variableInstances = new QDict<ClassDef>(17);␊ |
3321 | m_impl->variableInstances->setAutoDelete(TRUE);␊ |
3322 | }␊ |
3323 | ClassDef *templateClass=m_impl->variableInstances->find(templSpec);␊ |
3324 | if (templateClass==0)␊ |
3325 | {␊ |
3326 | Debug::print(Debug::Classes,0," New template variable instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec));␊ |
3327 | templateClass = new ClassDef("<code>",1,name()+templSpec,␊ |
3328 | ClassDef::Class,0,0,FALSE);␊ |
3329 | templateClass->addMembersToTemplateInstance( this, templSpec );␊ |
3330 | templateClass->setTemplateMaster(this);␊ |
3331 | m_impl->variableInstances->insert(templSpec,templateClass);␊ |
3332 | }␊ |
3333 | return templateClass;␊ |
3334 | }␊ |
3335 | ␊ |
3336 | void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames)␊ |
3337 | {␊ |
3338 | if (templateNames==0) return;␊ |
3339 | if (m_impl->templBaseClassNames==0)␊ |
3340 | {␊ |
3341 | m_impl->templBaseClassNames = new QDict<int>(17);␊ |
3342 | m_impl->templBaseClassNames->setAutoDelete(TRUE);␊ |
3343 | }␊ |
3344 | // make a deep copy of the dictionary.␊ |
3345 | QDictIterator<int> qdi(*templateNames);␊ |
3346 | for (;qdi.current();++qdi)␊ |
3347 | {␊ |
3348 | if (m_impl->templBaseClassNames->find(qdi.currentKey())==0)␊ |
3349 | {␊ |
3350 | m_impl->templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));␊ |
3351 | }␊ |
3352 | }␊ |
3353 | }␊ |
3354 | ␊ |
3355 | QDict<int> *ClassDef::getTemplateBaseClassNames() const␊ |
3356 | {␊ |
3357 | return m_impl->templBaseClassNames;␊ |
3358 | }␊ |
3359 | ␊ |
3360 | void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec)␊ |
3361 | {␊ |
3362 | //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);␊ |
3363 | if (cd->memberNameInfoSDict()==0) return;␊ |
3364 | MemberNameInfoSDict::Iterator mnili(*cd->memberNameInfoSDict());␊ |
3365 | MemberNameInfo *mni;␊ |
3366 | for (;(mni=mnili.current());++mnili)␊ |
3367 | {␊ |
3368 | MemberNameInfoIterator mnii(*mni);␊ |
3369 | MemberInfo *mi;␊ |
3370 | for (mnii.toFirst();(mi=mnii.current());++mnii)␊ |
3371 | {␊ |
3372 | ArgumentList *actualArguments = new ArgumentList;␊ |
3373 | stringToArgumentList(templSpec,actualArguments);␊ |
3374 | MemberDef *md = mi->memberDef;␊ |
3375 | MemberDef *imd = md->createTemplateInstanceMember(␊ |
3376 | cd->templateArguments(),actualArguments);␊ |
3377 | delete actualArguments;␊ |
3378 | //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);␊ |
3379 | imd->setMemberClass(this);␊ |
3380 | imd->setTemplateMaster(md);␊ |
3381 | imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());␊ |
3382 | imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());␊ |
3383 | imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());␊ |
3384 | imd->setMemberSpecifiers(md->getMemberSpecifiers());␊ |
3385 | imd->setMemberGroupId(md->getMemberGroupId());␊ |
3386 | insertMember(imd);␊ |
3387 | //printf("Adding member=%s %s%s to class %s templSpec %s\n",␊ |
3388 | // imd->typeString(),imd->name().data(),imd->argsString(),␊ |
3389 | // imd->getClassDef()->name().data(),templSpec);␊ |
3390 | // insert imd in the list of all members␊ |
3391 | //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());␊ |
3392 | MemberName *mn = Doxygen::memberNameSDict->find(imd->name());␊ |
3393 | if (mn==0)␊ |
3394 | {␊ |
3395 | mn = new MemberName(imd->name());␊ |
3396 | Doxygen::memberNameSDict->append(imd->name(),mn);␊ |
3397 | }␊ |
3398 | mn->append(imd);␊ |
3399 | }␊ |
3400 | }␊ |
3401 | }␊ |
3402 | ␊ |
3403 | QCString ClassDef::getReference() const␊ |
3404 | {␊ |
3405 | if (m_impl->templateMaster)␊ |
3406 | {␊ |
3407 | return m_impl->templateMaster->getReference();␊ |
3408 | }␊ |
3409 | else␊ |
3410 | {␊ |
3411 | return Definition::getReference();␊ |
3412 | }␊ |
3413 | }␊ |
3414 | ␊ |
3415 | bool ClassDef::isReference() const␊ |
3416 | {␊ |
3417 | if (m_impl->templateMaster)␊ |
3418 | {␊ |
3419 | return m_impl->templateMaster->isReference();␊ |
3420 | }␊ |
3421 | else␊ |
3422 | {␊ |
3423 | return Definition::isReference();␊ |
3424 | }␊ |
3425 | }␊ |
3426 | ␊ |
3427 | void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const␊ |
3428 | {␊ |
3429 | Definition *d=getOuterScope();␊ |
3430 | if (d)␊ |
3431 | {␊ |
3432 | if (d->definitionType()==Definition::TypeClass)␊ |
3433 | {␊ |
3434 | ClassDef *cd=(ClassDef *)d;␊ |
3435 | cd->getTemplateParameterLists(lists);␊ |
3436 | }␊ |
3437 | }␊ |
3438 | if (templateArguments())␊ |
3439 | {␊ |
3440 | lists.append(templateArguments());␊ |
3441 | }␊ |
3442 | }␊ |
3443 | ␊ |
3444 | QCString ClassDef::qualifiedNameWithTemplateParameters(␊ |
3445 | QList<ArgumentList> *actualParams) const␊ |
3446 | {␊ |
3447 | static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");␊ |
3448 | static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");␊ |
3449 | //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());␊ |
3450 | QCString scName;␊ |
3451 | Definition *d=getOuterScope();␊ |
3452 | if (d)␊ |
3453 | {␊ |
3454 | if (d->definitionType()==Definition::TypeClass)␊ |
3455 | {␊ |
3456 | ClassDef *cd=(ClassDef *)d;␊ |
3457 | scName = cd->qualifiedNameWithTemplateParameters(actualParams);␊ |
3458 | }␊ |
3459 | else if (!hideScopeNames)␊ |
3460 | {␊ |
3461 | scName = d->qualifiedName();␊ |
3462 | }␊ |
3463 | }␊ |
3464 | ␊ |
3465 | QCString scopeSeparator;␊ |
3466 | if (optimizeOutputJava)␊ |
3467 | scopeSeparator=".";␊ |
3468 | else␊ |
3469 | scopeSeparator="::";␊ |
3470 | ␊ |
3471 | if (!scName.isEmpty()) scName+=scopeSeparator;␊ |
3472 | ␊ |
3473 | bool isSpecialization = localName().find('<')!=-1;␊ |
3474 | bool isGeneric = m_impl->lang==SrcLangExt_CSharp;␊ |
3475 | ␊ |
3476 | QCString clName = className();␊ |
3477 | if (isGeneric && clName.right(2)=="-g") ␊ |
3478 | {␊ |
3479 | clName = clName.left(clName.length()-2);␊ |
3480 | }␊ |
3481 | //printf("m_impl->lang=%d clName=%s\n",m_impl->lang,clName.data());␊ |
3482 | scName+=clName;␊ |
3483 | ArgumentList *al=0;␊ |
3484 | if (templateArguments())␊ |
3485 | {␊ |
3486 | if (actualParams && (al=actualParams->current()))␊ |
3487 | {␊ |
3488 | if (!isSpecialization)␊ |
3489 | {␊ |
3490 | scName+=tempArgListToString(al);␊ |
3491 | }␊ |
3492 | actualParams->next();␊ |
3493 | }␊ |
3494 | else␊ |
3495 | {␊ |
3496 | if (!isSpecialization)␊ |
3497 | {␊ |
3498 | scName+=tempArgListToString(templateArguments());␊ |
3499 | }␊ |
3500 | }␊ |
3501 | }␊ |
3502 | //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());␊ |
3503 | return scName;␊ |
3504 | }␊ |
3505 | ␊ |
3506 | QCString ClassDef::className() const␊ |
3507 | {␊ |
3508 | if (m_impl->className.isEmpty())␊ |
3509 | {␊ |
3510 | return localName();␊ |
3511 | }␊ |
3512 | else␊ |
3513 | {␊ |
3514 | return m_impl->className;␊ |
3515 | }␊ |
3516 | };␊ |
3517 | ␊ |
3518 | void ClassDef::setClassName(const char *name)␊ |
3519 | {␊ |
3520 | m_impl->className = name;␊ |
3521 | }␊ |
3522 | ␊ |
3523 | void ClassDef::addListReferences()␊ |
3524 | {␊ |
3525 | bool fortranOpt=Config_getBool("OPTIMIZE_FOR_FORTRAN");␊ |
3526 | if (!isLinkableInProject()) return;␊ |
3527 | //printf("ClassDef(%s)::addListReferences()\n",name().data());␊ |
3528 | {␊ |
3529 | LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();␊ |
3530 | addRefItem(xrefItems.pointer(),␊ |
3531 | qualifiedName(),␊ |
3532 | fortranOpt?theTranslator->trType(TRUE,TRUE):␊ |
3533 | theTranslator->trClass(TRUE,TRUE),␊ |
3534 | getOutputFileBase(),␊ |
3535 | displayName(),␊ |
3536 | 0␊ |
3537 | );␊ |
3538 | }␊ |
3539 | if (m_impl->memberGroupSDict)␊ |
3540 | {␊ |
3541 | MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);␊ |
3542 | MemberGroup *mg;␊ |
3543 | for (;(mg=mgli.current());++mgli)␊ |
3544 | {␊ |
3545 | mg->addListReferences(this);␊ |
3546 | }␊ |
3547 | }␊ |
3548 | QListIterator<MemberList> mli(m_impl->memberLists);␊ |
3549 | MemberList *ml;␊ |
3550 | for (mli.toFirst();(ml=mli.current());++mli)␊ |
3551 | {␊ |
3552 | if (ml->listType()&MemberList::detailedLists)␊ |
3553 | {␊ |
3554 | ml->addListReferences(this);␊ |
3555 | }␊ |
3556 | }␊ |
3557 | }␊ |
3558 | ␊ |
3559 | MemberDef *ClassDef::getMemberByName(const QCString &name) const␊ |
3560 | {␊ |
3561 | MemberDef *xmd = 0;␊ |
3562 | if (m_impl->allMemberNameInfoSDict)␊ |
3563 | {␊ |
3564 | MemberNameInfo *mni = m_impl->allMemberNameInfoSDict->find(name);␊ |
3565 | if (mni)␊ |
3566 | {␊ |
3567 | const int maxInheritanceDepth = 100000;␊ |
3568 | int mdist=maxInheritanceDepth;␊ |
3569 | MemberNameInfoIterator mnii(*mni);␊ |
3570 | MemberInfo *mi;␊ |
3571 | for (mnii.toFirst();(mi=mnii.current());++mnii)␊ |
3572 | {␊ |
3573 | ClassDef *mcd=mi->memberDef->getClassDef();␊ |
3574 | int m=minClassDistance(this,mcd);␊ |
3575 | //printf("found member in %s linkable=%d m=%d\n",␊ |
3576 | // mcd->name().data(),mcd->isLinkable(),m);␊ |
3577 | if (m<mdist && mcd->isLinkable())␊ |
3578 | {␊ |
3579 | mdist=m;␊ |
3580 | xmd=mi->memberDef;␊ |
3581 | }␊ |
3582 | }␊ |
3583 | }␊ |
3584 | }␊ |
3585 | //printf("getMemberByName(%s)=%p\n",name.data(),xmd);␊ |
3586 | return xmd;␊ |
3587 | }␊ |
3588 | ␊ |
3589 | bool ClassDef::isAccessibleMember(MemberDef *md)␊ |
3590 | {␊ |
3591 | return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);␊ |
3592 | }␊ |
3593 | ␊ |
3594 | MemberList *ClassDef::createMemberList(MemberList::ListType lt)␊ |
3595 | {␊ |
3596 | m_impl->memberLists.setAutoDelete(TRUE);␊ |
3597 | QListIterator<MemberList> mli(m_impl->memberLists);␊ |
3598 | MemberList *ml;␊ |
3599 | for (mli.toFirst();(ml=mli.current());++mli)␊ |
3600 | {␊ |
3601 | if (ml->listType()==lt)␊ |
3602 | {␊ |
3603 | return ml;␊ |
3604 | }␊ |
3605 | }␊ |
3606 | // not found, create a new member list␊ |
3607 | ml = new MemberList(lt);␊ |
3608 | m_impl->memberLists.append(ml);␊ |
3609 | return ml;␊ |
3610 | }␊ |
3611 | ␊ |
3612 | MemberList *ClassDef::getMemberList(MemberList::ListType lt)␊ |
3613 | {␊ |
3614 | MemberList *ml = m_impl->memberLists.first();␊ |
3615 | while (ml)␊ |
3616 | {␊ |
3617 | if (ml->listType()==lt)␊ |
3618 | {␊ |
3619 | return ml;␊ |
3620 | }␊ |
3621 | ml = m_impl->memberLists.next();␊ |
3622 | }␊ |
3623 | return 0;␊ |
3624 | }␊ |
3625 | ␊ |
3626 | void ClassDef::addMemberToList(MemberList::ListType lt,MemberDef *md,bool isBrief)␊ |
3627 | {␊ |
3628 | static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");␊ |
3629 | static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");␊ |
3630 | MemberList *ml = createMemberList(lt);␊ |
3631 | ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));␊ |
3632 | ml->append(md);␊ |
3633 | ␊ |
3634 | // for members in the declaration lists we set the section, needed for member grouping␊ |
3635 | if ((ml->listType()&MemberList::detailedLists)==0) md->setSectionList(this,ml);␊ |
3636 | }␊ |
3637 | ␊ |
3638 | void ClassDef::sortMemberLists()␊ |
3639 | {␊ |
3640 | MemberList *ml = m_impl->memberLists.first();␊ |
3641 | while (ml)␊ |
3642 | {␊ |
3643 | if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }␊ |
3644 | ml = m_impl->memberLists.next();␊ |
3645 | }␊ |
3646 | }␊ |
3647 | ␊ |
3648 | void ClassDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title,␊ |
3649 | const char *subTitle,bool showInline)␊ |
3650 | {␊ |
3651 | static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");␊ |
3652 | MemberList * ml = getMemberList(lt);␊ |
3653 | if (ml) ␊ |
3654 | {␊ |
3655 | if (optimizeVhdl) // use specific declarations function␊ |
3656 | {␊ |
3657 | VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this,0);␊ |
3658 | }␊ |
3659 | else // use generic declaration function␊ |
3660 | {␊ |
3661 | ml->writeDeclarations(ol,this,0,0,0,title,subTitle,FALSE,showInline); ␊ |
3662 | }␊ |
3663 | }␊ |
3664 | }␊ |
3665 | ␊ |
3666 | void ClassDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title,bool showInline)␊ |
3667 | {␊ |
3668 | MemberList * ml = getMemberList(lt);␊ |
3669 | if (ml) ml->writeDocumentation(ol,name(),this,title,FALSE,showInline);␊ |
3670 | }␊ |
3671 | ␊ |
3672 | void ClassDef::writePlainMemberDeclaration(OutputList &ol,MemberList::ListType lt,bool inGroup)␊ |
3673 | {␊ |
3674 | MemberList * ml = getMemberList(lt);␊ |
3675 | if (ml) ␊ |
3676 | {␊ |
3677 | ml->setInGroup(inGroup);␊ |
3678 | ml->writePlainDeclarations(ol,this,0,0,0); ␊ |
3679 | }␊ |
3680 | }␊ |
3681 | ␊ |
3682 | bool ClassDef::isLocal() const ␊ |
3683 | { ␊ |
3684 | return m_impl->isLocal; ␊ |
3685 | }␊ |
3686 | ␊ |
3687 | ClassSDict *ClassDef::getInnerClasses() ␊ |
3688 | { ␊ |
3689 | return m_impl->innerClasses; ␊ |
3690 | }␊ |
3691 | ␊ |
3692 | ClassDef::CompoundType ClassDef::compoundType() const ␊ |
3693 | { ␊ |
3694 | return m_impl->compType; ␊ |
3695 | } ␊ |
3696 | ␊ |
3697 | BaseClassList *ClassDef::baseClasses() const␊ |
3698 | { ␊ |
3699 | return m_impl->inherits; ␊ |
3700 | }␊ |
3701 | ␊ |
3702 | BaseClassList *ClassDef::subClasses() const␊ |
3703 | { ␊ |
3704 | return m_impl->inheritedBy; ␊ |
3705 | }␊ |
3706 | ␊ |
3707 | MemberNameInfoSDict *ClassDef::memberNameInfoSDict() const␊ |
3708 | { ␊ |
3709 | return m_impl->allMemberNameInfoSDict; ␊ |
3710 | }␊ |
3711 | ␊ |
3712 | Protection ClassDef::protection() const ␊ |
3713 | { ␊ |
3714 | return m_impl->prot; ␊ |
3715 | }␊ |
3716 | ␊ |
3717 | ArgumentList *ClassDef::templateArguments() const ␊ |
3718 | { ␊ |
3719 | return m_impl->tempArgs; ␊ |
3720 | }␊ |
3721 | ␊ |
3722 | NamespaceDef *ClassDef::getNamespaceDef() const␊ |
3723 | { ␊ |
3724 | return m_impl->nspace; ␊ |
3725 | }␊ |
3726 | ␊ |
3727 | FileDef *ClassDef::getFileDef() const ␊ |
3728 | { ␊ |
3729 | return m_impl->fileDef; ␊ |
3730 | }␊ |
3731 | ␊ |
3732 | QDict<ClassDef> *ClassDef::getTemplateInstances() const ␊ |
3733 | { ␊ |
3734 | return m_impl->templateInstances; ␊ |
3735 | }␊ |
3736 | ␊ |
3737 | ClassDef *ClassDef::templateMaster() const ␊ |
3738 | { ␊ |
3739 | return m_impl->templateMaster; ␊ |
3740 | } ␊ |
3741 | ␊ |
3742 | bool ClassDef::isTemplate() const ␊ |
3743 | { ␊ |
3744 | return m_impl->tempArgs!=0; ␊ |
3745 | }␊ |
3746 | ␊ |
3747 | IncludeInfo *ClassDef::includeInfo() const ␊ |
3748 | { ␊ |
3749 | return m_impl->incInfo; ␊ |
3750 | }␊ |
3751 | ␊ |
3752 | UsesClassDict *ClassDef::usedImplementationClasses() const ␊ |
3753 | { ␊ |
3754 | return m_impl->usesImplClassDict; ␊ |
3755 | }␊ |
3756 | ␊ |
3757 | UsesClassDict *ClassDef::usedByImplementationClasses() const ␊ |
3758 | { ␊ |
3759 | return m_impl->usedByImplClassDict; ␊ |
3760 | }␊ |
3761 | ␊ |
3762 | UsesClassDict *ClassDef::usedInterfaceClasses() const␊ |
3763 | {␊ |
3764 | return m_impl->usesIntfClassDict;␊ |
3765 | }␊ |
3766 | ␊ |
3767 | bool ClassDef::isTemplateArgument() const␊ |
3768 | {␊ |
3769 | return m_impl->isTemplArg;␊ |
3770 | }␊ |
3771 | ␊ |
3772 | bool ClassDef::isAbstract() const ␊ |
3773 | { ␊ |
3774 | return m_impl->isAbstract; ␊ |
3775 | }␊ |
3776 | ␊ |
3777 | bool ClassDef::isObjectiveC() const ␊ |
3778 | { ␊ |
3779 | return m_impl->lang==SrcLangExt_ObjC; ␊ |
3780 | }␊ |
3781 | ␊ |
3782 | bool ClassDef::isCSharp() const ␊ |
3783 | { ␊ |
3784 | return m_impl->lang==SrcLangExt_CSharp; ␊ |
3785 | }␊ |
3786 | ␊ |
3787 | ClassDef *ClassDef::categoryOf() const ␊ |
3788 | { ␊ |
3789 | return m_impl->categoryOf; ␊ |
3790 | }␊ |
3791 | ␊ |
3792 | const QList<MemberList> &ClassDef::getMemberLists() const ␊ |
3793 | { ␊ |
3794 | return m_impl->memberLists; ␊ |
3795 | }␊ |
3796 | ␊ |
3797 | MemberGroupSDict *ClassDef::getMemberGroupSDict() const ␊ |
3798 | { ␊ |
3799 | return m_impl->memberGroupSDict; ␊ |
3800 | }␊ |
3801 | ␊ |
3802 | void ClassDef::setNamespace(NamespaceDef *nd) ␊ |
3803 | { ␊ |
3804 | m_impl->nspace = nd; ␊ |
3805 | }␊ |
3806 | ␊ |
3807 | void ClassDef::setFileDef(FileDef *fd) ␊ |
3808 | { ␊ |
3809 | m_impl->fileDef=fd; ␊ |
3810 | }␊ |
3811 | ␊ |
3812 | void ClassDef::setSubGrouping(bool enabled) ␊ |
3813 | { ␊ |
3814 | m_impl->subGrouping = enabled; ␊ |
3815 | }␊ |
3816 | ␊ |
3817 | void ClassDef::setProtection(Protection p) ␊ |
3818 | { ␊ |
3819 | m_impl->prot=p; ␊ |
3820 | }␊ |
3821 | ␊ |
3822 | void ClassDef::setIsStatic(bool b) ␊ |
3823 | { ␊ |
3824 | m_impl->isStatic=b; ␊ |
3825 | }␊ |
3826 | ␊ |
3827 | void ClassDef::setLanguage(SrcLangExt lang) ␊ |
3828 | { ␊ |
3829 | m_impl->lang=lang; ␊ |
3830 | }␊ |
3831 | ␊ |
3832 | void ClassDef::setCompoundType(CompoundType t) ␊ |
3833 | { ␊ |
3834 | m_impl->compType = t; ␊ |
3835 | } ␊ |
3836 | ␊ |
3837 | void ClassDef::setTemplateMaster(ClassDef *tm) ␊ |
3838 | { ␊ |
3839 | m_impl->templateMaster=tm; ␊ |
3840 | }␊ |
3841 | ␊ |
3842 | void ClassDef::makeTemplateArgument(bool b) ␊ |
3843 | { ␊ |
3844 | m_impl->isTemplArg = b; ␊ |
3845 | }␊ |
3846 | ␊ |
3847 | void ClassDef::setCategoryOf(ClassDef *cd)␊ |
3848 | {␊ |
3849 | m_impl->categoryOf = cd;␊ |
3850 | }␊ |
3851 | ␊ |
3852 | void ClassDef::setUsedOnly(bool b)␊ |
3853 | {␊ |
3854 | m_impl->usedOnly = b;␊ |
3855 | }␊ |
3856 | ␊ |
3857 | bool ClassDef::isUsedOnly() const␊ |
3858 | {␊ |
3859 | return m_impl->usedOnly;␊ |
3860 | }␊ |
3861 | ␊ |
3862 | void ClassDef::reclassifyMember(MemberDef *md,MemberDef::MemberType t)␊ |
3863 | {␊ |
3864 | md->setMemberType(t);␊ |
3865 | MemberList *ml = m_impl->memberLists.first();␊ |
3866 | while (ml)␊ |
3867 | {␊ |
3868 | ml->remove(md);␊ |
3869 | ml = m_impl->memberLists.next();␊ |
3870 | }␊ |
3871 | insertMember(md);␊ |
3872 | }␊ |
3873 | ␊ |
3874 | QCString ClassDef::anchor() const␊ |
3875 | {␊ |
3876 | QCString anc;␊ |
3877 | if (isEmbeddedInGroupDocs())␊ |
3878 | {␊ |
3879 | if (m_impl->templateMaster)␊ |
3880 | {␊ |
3881 | // point to the template of which this class is an instance␊ |
3882 | anc = m_impl->templateMaster->getOutputFileBase();␊ |
3883 | }␊ |
3884 | else if (isReference())␊ |
3885 | {␊ |
3886 | // point to the external location␊ |
3887 | anc = m_impl->fileName;␊ |
3888 | }␊ |
3889 | else␊ |
3890 | {␊ |
3891 | // normal locally defined class␊ |
3892 | anc = convertNameToFile(m_impl->fileName); ␊ |
3893 | }␊ |
3894 | }␊ |
3895 | return anc;␊ |
3896 | }␊ |
3897 | ␊ |
3898 | bool ClassDef::isEmbeddedInGroupDocs() const␊ |
3899 | {␊ |
3900 | static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");␊ |
3901 | return (inlineGroupedClasses && partOfGroups()!=0);␊ |
3902 | }␊ |
3903 | ␊ |
3904 | ␊ |
3905 |