tools/qdoc3/node.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the tools applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*
       
    43   node.cpp
       
    44 */
       
    45 
       
    46 #include <QtCore>
       
    47 #include "node.h"
       
    48 
       
    49 QT_BEGIN_NAMESPACE
       
    50 
       
    51 /*!
       
    52   \class Node
       
    53   \brief The Node class is a node in the Tree.
       
    54 
       
    55   A Node represents a class or function or something else
       
    56   from the source code..
       
    57  */
       
    58 
       
    59 /*!
       
    60   When this Node is destroyed, if it has a parent Node, it
       
    61   removes itself from the parent node's child list.
       
    62  */
       
    63 Node::~Node()
       
    64 {
       
    65     if (par)
       
    66         par->removeChild(this);
       
    67     if (rel)
       
    68         rel->removeRelated(this);
       
    69 }
       
    70 
       
    71 /*!
       
    72   Sets this Node's Doc to \a doc. If \a replace is false and
       
    73   this Node already has a Doc, a warning is reported that the
       
    74   Doc is being overridden, and it reports where the previous
       
    75   Doc was found. If \a replace is true, the Doc is replaced
       
    76   silently.
       
    77  */
       
    78 void Node::setDoc(const Doc& doc, bool replace)
       
    79 {
       
    80     if (!d.isEmpty() && !replace) {
       
    81         doc.location().warning(tr("Overrides a previous doc"));
       
    82         d.location().warning(tr("(The previous doc is here)"));
       
    83     }
       
    84     d = doc;
       
    85 }
       
    86 
       
    87 /*!
       
    88  */
       
    89 Node::Node(Type type, InnerNode *parent, const QString& name)
       
    90     : typ(type),
       
    91       acc(Public),
       
    92       sta(Commendable),
       
    93       saf(UnspecifiedSafeness),
       
    94       par(parent),
       
    95       rel(0),
       
    96       nam(name)
       
    97 {
       
    98     if (par)
       
    99         par->addChild(this);
       
   100 }
       
   101 
       
   102 /*!
       
   103  */
       
   104 QString Node::url() const
       
   105 {
       
   106     return u;
       
   107 }
       
   108 
       
   109 /*!
       
   110  */
       
   111 void Node::setUrl(const QString &url)
       
   112 {
       
   113     u = url;
       
   114 }
       
   115 
       
   116 /*!
       
   117  */
       
   118 void Node::setRelates(InnerNode *pseudoParent)
       
   119 {
       
   120     if (rel)
       
   121             rel->removeRelated(this);
       
   122     rel = pseudoParent;
       
   123     pseudoParent->related.append(this);
       
   124 }
       
   125 
       
   126 /*!
       
   127   This function creates a pair that describes a link.
       
   128   The pair is composed from \a link and \a desc. The
       
   129   \a linkType is the map index the pair is filed under.
       
   130  */
       
   131 void Node::setLink(LinkType linkType, const QString &link, const QString &desc)
       
   132 {
       
   133     QPair<QString,QString> linkPair;
       
   134     linkPair.first = link;
       
   135     linkPair.second = desc;
       
   136     linkMap[linkType] = linkPair;
       
   137 }
       
   138 
       
   139 /*!
       
   140  */
       
   141 Node::Status Node::inheritedStatus() const
       
   142 {
       
   143     Status parentStatus = Commendable;
       
   144     if (par)
       
   145         parentStatus = par->inheritedStatus();
       
   146     return (Status)qMin((int)sta, (int)parentStatus);
       
   147 }
       
   148 
       
   149 /*!
       
   150  */
       
   151 Node::ThreadSafeness Node::threadSafeness() const
       
   152 {
       
   153     if (par && saf == par->inheritedThreadSafeness())
       
   154         return UnspecifiedSafeness;
       
   155     return saf;
       
   156 }
       
   157 
       
   158 /*!
       
   159  */
       
   160 Node::ThreadSafeness Node::inheritedThreadSafeness() const
       
   161 {
       
   162     if (par && saf == UnspecifiedSafeness)
       
   163         return par->inheritedThreadSafeness();
       
   164     return saf;
       
   165 }
       
   166 
       
   167 /*!
       
   168  */
       
   169 QString Node::fileBase() const
       
   170 {
       
   171     QString base = name();
       
   172     if (base.endsWith(".html"))
       
   173         base.chop(5);
       
   174     base.replace(QRegExp("[^A-Za-z0-9]+"), " ");
       
   175     base = base.trimmed();
       
   176     base.replace(" ", "-");
       
   177     return base.toLower();
       
   178 }
       
   179 
       
   180 /*!
       
   181   \class InnerNode
       
   182  */
       
   183 
       
   184 /*!
       
   185  */
       
   186 InnerNode::~InnerNode()
       
   187 {
       
   188     deleteChildren();
       
   189     removeFromRelated();
       
   190 }
       
   191 
       
   192 /*!
       
   193  */
       
   194 Node *InnerNode::findNode(const QString& name)
       
   195 {
       
   196     Node *node = childMap.value(name);
       
   197     if (node)
       
   198         return node;
       
   199     return primaryFunctionMap.value(name);
       
   200 }
       
   201 
       
   202 /*!
       
   203  */
       
   204 Node *InnerNode::findNode(const QString& name, Type type)
       
   205 {
       
   206     if (type == Function) {
       
   207         return primaryFunctionMap.value(name);
       
   208     }
       
   209     else {
       
   210         Node *node = childMap.value(name);
       
   211         if (node && node->type() == type) {
       
   212             return node;
       
   213         }
       
   214         else {
       
   215             return 0;
       
   216         }
       
   217     }
       
   218 }
       
   219 
       
   220 /*!
       
   221  */
       
   222 FunctionNode *InnerNode::findFunctionNode(const QString& name)
       
   223 {
       
   224     return static_cast<FunctionNode *>(primaryFunctionMap.value(name));
       
   225 }
       
   226 
       
   227 /*!
       
   228  */
       
   229 FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone)
       
   230 {
       
   231     QMap<QString, Node *>::ConstIterator c =
       
   232 	    primaryFunctionMap.find(clone->name());
       
   233     if (c != primaryFunctionMap.end()) {
       
   234 	if (isSameSignature(clone, (FunctionNode *) *c)) {
       
   235 	    return (FunctionNode *) *c;
       
   236 	}
       
   237         else if (secondaryFunctionMap.contains(clone->name())) {
       
   238 	    const NodeList& secs = secondaryFunctionMap[clone->name()];
       
   239 	    NodeList::ConstIterator s = secs.begin();
       
   240 	    while (s != secs.end()) {
       
   241 		if (isSameSignature(clone, (FunctionNode *) *s))
       
   242 		    return (FunctionNode *) *s;
       
   243 		++s;
       
   244 	    }
       
   245 	}
       
   246     }
       
   247     return 0;
       
   248 }
       
   249 
       
   250 /*!
       
   251  */
       
   252 void InnerNode::setOverload(const FunctionNode *func, bool overlode)
       
   253 {
       
   254     Node *node = (Node *) func;
       
   255     Node *&primary = primaryFunctionMap[func->name()];
       
   256 
       
   257     if (secondaryFunctionMap.contains(func->name())) {
       
   258 	NodeList& secs = secondaryFunctionMap[func->name()];
       
   259 	if (overlode) {
       
   260 	    if (primary == node) {
       
   261 		primary = secs.first();
       
   262 		secs.erase(secs.begin());
       
   263 		secs.append(node);
       
   264 	    }
       
   265             else {
       
   266 		secs.removeAll(node);
       
   267                 secs.append(node);
       
   268             }
       
   269 	}
       
   270         else {
       
   271 	    if (primary != node) {
       
   272 		secs.removeAll(node);
       
   273 		secs.prepend(primary);
       
   274 		primary = node;
       
   275 	    }
       
   276 	}
       
   277     }
       
   278 }
       
   279 
       
   280 /*!
       
   281  */
       
   282 void InnerNode::makeUndocumentedChildrenInternal()
       
   283 {
       
   284     foreach (Node *child, childNodes()) {
       
   285         if (child->doc().isEmpty()) {
       
   286             child->setAccess(Node::Private);
       
   287             child->setStatus(Node::Internal);
       
   288         }
       
   289     }
       
   290 }
       
   291 
       
   292 /*!
       
   293  */
       
   294 void InnerNode::normalizeOverloads()
       
   295 {
       
   296     QMap<QString, Node *>::Iterator p1 = primaryFunctionMap.begin();
       
   297     while (p1 != primaryFunctionMap.end()) {
       
   298         FunctionNode *primaryFunc = (FunctionNode *) *p1;
       
   299         if (secondaryFunctionMap.contains(primaryFunc->name()) &&
       
   300             (primaryFunc->status() != Commendable ||
       
   301              primaryFunc->access() == Private)) {
       
   302 
       
   303 	    NodeList& secs = secondaryFunctionMap[primaryFunc->name()];
       
   304 	    NodeList::ConstIterator s = secs.begin();
       
   305 	    while (s != secs.end()) {
       
   306 		FunctionNode *secondaryFunc = (FunctionNode *) *s;
       
   307 
       
   308                 // Any non-obsolete, non-compatibility, non-private functions
       
   309                 // (i.e, visible functions) are preferable to the primary
       
   310                 // function.
       
   311 
       
   312                 if (secondaryFunc->status() == Commendable &&
       
   313                     secondaryFunc->access() != Private) {
       
   314 
       
   315                     *p1 = secondaryFunc;
       
   316                     int index = secondaryFunctionMap[primaryFunc->name()].indexOf(secondaryFunc);
       
   317                     secondaryFunctionMap[primaryFunc->name()].replace(index, primaryFunc);
       
   318                     break;
       
   319                 }
       
   320                 ++s;
       
   321             }
       
   322         }
       
   323         ++p1;
       
   324     }
       
   325 
       
   326     QMap<QString, Node *>::ConstIterator p = primaryFunctionMap.begin();
       
   327     while (p != primaryFunctionMap.end()) {
       
   328 	FunctionNode *primaryFunc = (FunctionNode *) *p;
       
   329 	if (primaryFunc->isOverload())
       
   330 	    primaryFunc->ove = false;
       
   331 	if (secondaryFunctionMap.contains(primaryFunc->name())) {
       
   332 	    NodeList& secs = secondaryFunctionMap[primaryFunc->name()];
       
   333 	    NodeList::ConstIterator s = secs.begin();
       
   334 	    while (s != secs.end()) {
       
   335 		FunctionNode *secondaryFunc = (FunctionNode *) *s;
       
   336 		if (!secondaryFunc->isOverload())
       
   337 		    secondaryFunc->ove = true;
       
   338 		++s;
       
   339 	    }
       
   340 	}
       
   341 	++p;
       
   342     }
       
   343 
       
   344     NodeList::ConstIterator c = childNodes().begin();
       
   345     while (c != childNodes().end()) {
       
   346 	if ((*c)->isInnerNode())
       
   347 	    ((InnerNode *) *c)->normalizeOverloads();
       
   348 	++c;
       
   349     }
       
   350 }
       
   351 
       
   352 /*!
       
   353  */
       
   354 void InnerNode::removeFromRelated() 
       
   355 {
       
   356     while (!related.isEmpty()) {
       
   357         Node *p = static_cast<Node *>(related.takeFirst());
       
   358 
       
   359         if (p != 0 && p->relates() == this) p->clearRelated();
       
   360     }
       
   361 }
       
   362 
       
   363 /*!
       
   364  */
       
   365 void InnerNode::deleteChildren()
       
   366 {
       
   367     qDeleteAll(children);
       
   368 }
       
   369 
       
   370 /*!
       
   371   Returns true.
       
   372  */
       
   373 bool InnerNode::isInnerNode() const
       
   374 {
       
   375     return true;
       
   376 }
       
   377 
       
   378 /*!
       
   379  */
       
   380 const Node *InnerNode::findNode(const QString& name) const
       
   381 {
       
   382     InnerNode *that = (InnerNode *) this;
       
   383     return that->findNode(name);
       
   384 }
       
   385 
       
   386 /*!
       
   387  */
       
   388 const Node *InnerNode::findNode(const QString& name, Type type) const
       
   389 {
       
   390     InnerNode *that = (InnerNode *) this;
       
   391     return that->findNode(name, type);
       
   392 }
       
   393 
       
   394 /*!
       
   395  */
       
   396 const FunctionNode *InnerNode::findFunctionNode(const QString& name) const
       
   397 {
       
   398     InnerNode *that = (InnerNode *) this;
       
   399     return that->findFunctionNode(name);
       
   400 }
       
   401 
       
   402 /*!
       
   403  */
       
   404 const FunctionNode *InnerNode::findFunctionNode(
       
   405 	const FunctionNode *clone) const
       
   406 {
       
   407     InnerNode *that = (InnerNode *) this;
       
   408     return that->findFunctionNode(clone);
       
   409 }
       
   410 
       
   411 /*!
       
   412  */
       
   413 const EnumNode *InnerNode::findEnumNodeForValue(const QString &enumValue) const
       
   414 {
       
   415     foreach (const Node *node, enumChildren) {
       
   416         const EnumNode *enume = static_cast<const EnumNode *>(node);
       
   417         if (enume->hasItem(enumValue))
       
   418             return enume;
       
   419     }
       
   420     return 0;
       
   421 }
       
   422 
       
   423 /*!
       
   424  */
       
   425 int InnerNode::overloadNumber(const FunctionNode *func) const
       
   426 {
       
   427     Node *node = (Node *) func;
       
   428     if (primaryFunctionMap[func->name()] == node) {
       
   429         return 1;
       
   430     }
       
   431     else {
       
   432         return secondaryFunctionMap[func->name()].indexOf(node) + 2;
       
   433     }
       
   434 }
       
   435 
       
   436 /*!
       
   437  */
       
   438 int InnerNode::numOverloads(const QString& funcName) const
       
   439 {
       
   440     if (primaryFunctionMap.contains(funcName)) {
       
   441         return secondaryFunctionMap[funcName].count() + 1;
       
   442     }
       
   443     else {
       
   444         return 0;
       
   445     }
       
   446 }
       
   447 
       
   448 /*!
       
   449  */
       
   450 NodeList InnerNode::overloads(const QString &funcName) const
       
   451 {
       
   452     NodeList result;
       
   453     Node *primary = primaryFunctionMap.value(funcName);
       
   454     if (primary) {
       
   455         result << primary;
       
   456         result += secondaryFunctionMap[funcName];
       
   457     }
       
   458     return result;
       
   459 }
       
   460 
       
   461 /*!
       
   462  */
       
   463 InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name)
       
   464     : Node(type, parent, name)
       
   465 {
       
   466 }
       
   467 
       
   468 /*!
       
   469  */
       
   470 void InnerNode::addInclude(const QString& include)
       
   471 {
       
   472     inc.append(include);
       
   473 }
       
   474 
       
   475 /*!
       
   476  */
       
   477 void InnerNode::setIncludes(const QStringList& includes)
       
   478 {
       
   479     inc = includes;
       
   480 }
       
   481 
       
   482 /*!
       
   483   f1 is always the clone
       
   484  */
       
   485 bool InnerNode::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
       
   486 {
       
   487     if (f1->parameters().count() != f2->parameters().count())
       
   488         return false;
       
   489     if (f1->isConst() != f2->isConst())
       
   490         return false;
       
   491 
       
   492     QList<Parameter>::ConstIterator p1 = f1->parameters().begin();
       
   493     QList<Parameter>::ConstIterator p2 = f2->parameters().begin();
       
   494     while (p2 != f2->parameters().end()) {
       
   495 	if ((*p1).hasType() && (*p2).hasType()) {
       
   496             if ((*p1).rightType() != (*p2).rightType())
       
   497                 return false;
       
   498 
       
   499             QString t1 = p1->leftType();
       
   500             QString t2 = p2->leftType();
       
   501 
       
   502             if (t1.length() < t2.length())
       
   503                 qSwap(t1, t2);
       
   504 
       
   505             /*
       
   506               ### hack for C++ to handle superfluous
       
   507               "Foo::" prefixes gracefully
       
   508             */
       
   509             if (t1 != t2 && t1 != (f2->parent()->name() + "::" + t2))
       
   510                 return false;
       
   511         }
       
   512         ++p1;
       
   513         ++p2;
       
   514     }
       
   515     return true;
       
   516 }
       
   517 
       
   518 /*!
       
   519  */
       
   520 void InnerNode::addChild(Node *child)
       
   521 {
       
   522     children.append(child);
       
   523     if (child->type() == Function) {
       
   524         FunctionNode *func = (FunctionNode *) child;
       
   525         if (!primaryFunctionMap.contains(func->name())) {
       
   526             primaryFunctionMap.insert(func->name(), func);
       
   527 	}
       
   528         else {
       
   529 	    NodeList &secs = secondaryFunctionMap[func->name()];
       
   530 	    secs.append(func);
       
   531 	}
       
   532     }
       
   533     else {
       
   534         if (child->type() == Enum)
       
   535             enumChildren.append(child);
       
   536 	childMap.insert(child->name(), child);
       
   537     }
       
   538 }
       
   539 
       
   540 /*!
       
   541  */
       
   542 void InnerNode::removeChild(Node *child)
       
   543 {
       
   544     children.removeAll(child);
       
   545     enumChildren.removeAll(child);
       
   546     if (child->type() == Function) {
       
   547 	QMap<QString, Node *>::Iterator prim =
       
   548 		primaryFunctionMap.find(child->name());
       
   549 	NodeList& secs = secondaryFunctionMap[child->name()];
       
   550 	if (*prim == child) {
       
   551 	    if (secs.isEmpty()) {
       
   552 		primaryFunctionMap.remove(child->name());
       
   553 	    }
       
   554             else {
       
   555 		primaryFunctionMap.insert(child->name(), secs.takeFirst());
       
   556 	    }
       
   557 	}
       
   558         else {
       
   559 	    secs.removeAll(child);
       
   560 	}
       
   561         QMap<QString, Node *>::Iterator ent = childMap.find( child->name() );
       
   562         if ( *ent == child )
       
   563             childMap.erase( ent );
       
   564     }
       
   565     else {
       
   566 	QMap<QString, Node *>::Iterator ent = childMap.find(child->name());
       
   567 	if (*ent == child)
       
   568 	    childMap.erase(ent);
       
   569     }
       
   570 }
       
   571 
       
   572 /*!
       
   573   Find the module (QtCore, QtGui, etc.) to which the class belongs.
       
   574   We do this by obtaining the full path to the header file's location
       
   575   and examine everything between "src/" and the filename.  This is
       
   576   semi-dirty because we are assuming a particular directory structure.
       
   577 
       
   578   This function is only really useful if the class's module has not
       
   579   been defined in the header file with a QT_MODULE macro or with an
       
   580   \inmodule command in the documentation.
       
   581 */
       
   582 QString Node::moduleName() const
       
   583 {
       
   584     if (!mod.isEmpty())
       
   585         return mod;
       
   586 
       
   587     QString path = location().filePath();
       
   588     QString pattern = QString("src") + QDir::separator();
       
   589     int start = path.lastIndexOf(pattern);
       
   590 
       
   591     if (start == -1)
       
   592         return "";
       
   593 
       
   594     QString moduleDir = path.mid(start + pattern.size());
       
   595     int finish = moduleDir.indexOf(QDir::separator());
       
   596 
       
   597     if (finish == -1)
       
   598         return "";
       
   599 
       
   600     QString moduleName = moduleDir.left(finish);
       
   601 
       
   602     if (moduleName == "corelib")
       
   603         return "QtCore";
       
   604     else if (moduleName == "uitools")
       
   605         return "QtUiTools";
       
   606     else if (moduleName == "gui")
       
   607         return "QtGui";
       
   608     else if (moduleName == "network")
       
   609         return "QtNetwork";
       
   610     else if (moduleName == "opengl")
       
   611         return "QtOpenGL";
       
   612     else if (moduleName == "qt3support")
       
   613         return "Qt3Support";
       
   614     else if (moduleName == "svg")
       
   615         return "QtSvg";
       
   616     else if (moduleName == "sql")
       
   617         return "QtSql";
       
   618     else if (moduleName == "qtestlib")
       
   619         return "QtTest";
       
   620     else if (moduleDir.contains("webkit"))
       
   621         return "QtWebKit";
       
   622     else if (moduleName == "xml")
       
   623         return "QtXml";
       
   624     else
       
   625         return "";
       
   626 }
       
   627 
       
   628 /*!
       
   629  */
       
   630 void InnerNode::removeRelated(Node *pseudoChild)
       
   631 {
       
   632     related.removeAll(pseudoChild);
       
   633 }
       
   634 
       
   635 /*!
       
   636   \class LeafNode
       
   637  */
       
   638 
       
   639 /*!
       
   640   Returns false because this is a LeafNode.
       
   641  */
       
   642 bool LeafNode::isInnerNode() const
       
   643 {
       
   644     return false;
       
   645 }
       
   646 
       
   647 /*!
       
   648  */
       
   649 LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name)
       
   650     : Node(type, parent, name)
       
   651 {
       
   652 }
       
   653 
       
   654 /*!
       
   655   \class NamespaceNode
       
   656  */
       
   657 
       
   658 /*!
       
   659  */
       
   660 NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
       
   661     : InnerNode(Namespace, parent, name)
       
   662 {
       
   663 }
       
   664 
       
   665 /*!
       
   666   \class ClassNode
       
   667  */
       
   668 
       
   669 /*!
       
   670  */
       
   671 ClassNode::ClassNode(InnerNode *parent, const QString& name)
       
   672     : InnerNode(Class, parent, name)
       
   673 {
       
   674     hidden = false;
       
   675 }
       
   676 
       
   677 /*!
       
   678  */
       
   679 void ClassNode::addBaseClass(Access access,
       
   680                              ClassNode *node,
       
   681                              const QString &dataTypeWithTemplateArgs)
       
   682 {
       
   683     bas.append(RelatedClass(access, node, dataTypeWithTemplateArgs));
       
   684     node->der.append(RelatedClass(access, this));
       
   685 }
       
   686 
       
   687 /*!
       
   688  */
       
   689 void ClassNode::fixBaseClasses()
       
   690 {
       
   691     int i;
       
   692 
       
   693     i = 0;
       
   694     while (i < bas.size()) {
       
   695         ClassNode *baseClass = bas.at(i).node;
       
   696         if (baseClass->access() == Node::Private) {
       
   697             bas.removeAt(i);
       
   698 
       
   699             const QList<RelatedClass> &basesBases = baseClass->baseClasses();
       
   700             for (int j = basesBases.size() - 1; j >= 0; --j)
       
   701                 bas.insert(i, basesBases.at(j));
       
   702         }
       
   703         else {
       
   704             ++i;
       
   705         }
       
   706     }
       
   707 
       
   708     i = 0;
       
   709     while (i < der.size()) {
       
   710         ClassNode *derivedClass = der.at(i).node;
       
   711         if (derivedClass->access() == Node::Private) {
       
   712             der.removeAt(i);
       
   713 
       
   714             const QList<RelatedClass> &dersDers =
       
   715                 derivedClass->derivedClasses();
       
   716             for (int j = dersDers.size() - 1; j >= 0; --j)
       
   717                 der.insert(i, dersDers.at(j));
       
   718         }
       
   719         else {
       
   720             ++i;
       
   721         }
       
   722     }
       
   723 }
       
   724 
       
   725 /*!
       
   726   \class FakeNode
       
   727  */
       
   728 
       
   729 /*!
       
   730   The type of a FakeNode is Fake, and it has a \a subtype,
       
   731   which specifies the type of FakeNode.
       
   732  */
       
   733 FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype)
       
   734     : InnerNode(Fake, parent, name), sub(subtype)
       
   735 {
       
   736 }
       
   737 
       
   738 /*!
       
   739  */
       
   740 QString FakeNode::fullTitle() const
       
   741 {
       
   742     if (sub == File) {
       
   743         if (title().isEmpty())
       
   744             return name().mid(name().lastIndexOf('/') + 1) + " Example File";
       
   745         else
       
   746             return title();
       
   747     }
       
   748     else if (sub == HeaderFile) {
       
   749         if (title().isEmpty())
       
   750             return name();
       
   751         else
       
   752             return name() + " - " + title();
       
   753     }
       
   754     else {
       
   755         return title();
       
   756     }
       
   757 }
       
   758 
       
   759 /*!
       
   760  */
       
   761 QString FakeNode::subTitle() const
       
   762 {
       
   763     if (!stle.isEmpty())
       
   764         return stle;
       
   765 
       
   766     if (sub == File) {
       
   767         if (title().isEmpty() && name().contains("/"))
       
   768             return name();
       
   769     }
       
   770     return QString();
       
   771 }
       
   772 
       
   773 /*!
       
   774   \class EnumNode
       
   775  */
       
   776 
       
   777 /*!
       
   778  */
       
   779 EnumNode::EnumNode(InnerNode *parent, const QString& name)
       
   780     : LeafNode(Enum, parent, name), ft(0)
       
   781 {
       
   782 }
       
   783 
       
   784 /*!
       
   785  */
       
   786 void EnumNode::addItem(const EnumItem& item)
       
   787 {
       
   788     itms.append(item);
       
   789     names.insert(item.name());
       
   790 }
       
   791 
       
   792 /*!
       
   793  */
       
   794 Node::Access EnumNode::itemAccess(const QString &name) const
       
   795 {
       
   796     if (doc().omitEnumItemNames().contains(name)) {
       
   797         return Private;
       
   798     }
       
   799     else {
       
   800         return Public;
       
   801     }
       
   802 }
       
   803 
       
   804 /*!
       
   805   Returns the enum value associated with the enum \a name.
       
   806  */
       
   807 QString EnumNode::itemValue(const QString &name) const
       
   808 {
       
   809     foreach (const EnumItem &item, itms) {
       
   810         if (item.name() == name)
       
   811             return item.value();
       
   812     }
       
   813     return QString();
       
   814 }
       
   815 
       
   816 /*!
       
   817   \class TypedefNode
       
   818  */
       
   819 
       
   820 /*!
       
   821  */
       
   822 TypedefNode::TypedefNode(InnerNode *parent, const QString& name)
       
   823     : LeafNode(Typedef, parent, name), ae(0)
       
   824 {
       
   825 }
       
   826 
       
   827 /*!
       
   828  */
       
   829 void TypedefNode::setAssociatedEnum(const EnumNode *enume)
       
   830 {
       
   831     ae = enume;
       
   832 }
       
   833 
       
   834 /*!
       
   835   \class Parameter
       
   836   \brief The class Parameter contains one parameter.
       
   837 
       
   838   A parameter can be a function parameter or a macro
       
   839   parameter.
       
   840  */
       
   841 
       
   842 /*!
       
   843   Constructs this parameter from the left and right types
       
   844   \a leftType and rightType, the parameter \a name, and the
       
   845   \a defaultValue. In practice, \a rightType is not used,
       
   846   and I don't know what is was meant for.
       
   847  */
       
   848 Parameter::Parameter(const QString& leftType,
       
   849                      const QString& rightType,
       
   850 		     const QString& name,
       
   851                      const QString& defaultValue)
       
   852     : lef(leftType), rig(rightType), nam(name), def(defaultValue)
       
   853 {
       
   854 }
       
   855 
       
   856 /*!
       
   857   The standard copy constructor copies the strings from \a p.
       
   858  */
       
   859 Parameter::Parameter(const Parameter& p)
       
   860     : lef(p.lef), rig(p.rig), nam(p.nam), def(p.def)
       
   861 {
       
   862 }
       
   863 
       
   864 /*!
       
   865   Assigning Parameter \a p to this Parameter copies the
       
   866   strings across. 
       
   867  */
       
   868 Parameter& Parameter::operator=(const Parameter& p)
       
   869 {
       
   870     lef = p.lef;
       
   871     rig = p.rig;
       
   872     nam = p.nam;
       
   873     def = p.def;
       
   874     return *this;
       
   875 }
       
   876 
       
   877 /*!
       
   878   Reconstructs the text describing the parameter and
       
   879   returns it. If \a value is true, the default value
       
   880   will be included, if there is one.
       
   881  */
       
   882 QString Parameter::reconstruct(bool value) const
       
   883 {
       
   884     QString p = lef + rig;
       
   885     if (!p.endsWith(QChar('*')) && !p.endsWith(QChar('&')) && !p.endsWith(QChar(' ')))
       
   886         p += " ";
       
   887     p += nam;
       
   888     if (value)
       
   889         p += def;
       
   890     return p;
       
   891 }
       
   892 
       
   893 
       
   894 /*!
       
   895   \class FunctionNode
       
   896  */
       
   897 
       
   898 /*!
       
   899  */
       
   900 FunctionNode::FunctionNode(InnerNode *parent, const QString& name)
       
   901     : LeafNode(Function, parent, name), met(Plain), vir(NonVirtual),
       
   902       con(false), sta(false), ove(false), rf(0), ap(0)
       
   903 {
       
   904 }
       
   905 
       
   906 /*!
       
   907  */
       
   908 void FunctionNode::setOverload(bool overlode)
       
   909 {
       
   910     parent()->setOverload(this, overlode);
       
   911     ove = overlode;
       
   912 }
       
   913 
       
   914 /*!
       
   915   Sets the function node's reimplementation flag to \a r.
       
   916   When \a r is true, it is supposed to mean that this function
       
   917   is a reimplementation of a virtual function in a base class,
       
   918   but it really just means the \e reimp command was seen in the
       
   919   qdoc comment.
       
   920  */
       
   921 void FunctionNode::setReimp(bool r)
       
   922 {
       
   923     reimp = r;
       
   924 }
       
   925 
       
   926 /*!
       
   927  */
       
   928 void FunctionNode::addParameter(const Parameter& parameter)
       
   929 {
       
   930     params.append(parameter);
       
   931 }
       
   932 
       
   933 /*!
       
   934  */
       
   935 void FunctionNode::borrowParameterNames(const FunctionNode *source)
       
   936 {
       
   937     QList<Parameter>::Iterator t = params.begin();
       
   938     QList<Parameter>::ConstIterator s = source->params.begin();
       
   939     while (s != source->params.end() && t != params.end()) {
       
   940 	if (!(*s).name().isEmpty())
       
   941 	    (*t).setName((*s).name());
       
   942 	++s;
       
   943 	++t;
       
   944     }
       
   945 }
       
   946 
       
   947 /*!
       
   948   If this function is a reimplementation, \a from points
       
   949   to the FunctionNode of the function being reimplemented.
       
   950  */
       
   951 void FunctionNode::setReimplementedFrom(FunctionNode *from)
       
   952 {
       
   953     rf = from;
       
   954     from->rb.append(this);
       
   955 }
       
   956 
       
   957 /*!
       
   958   Sets the "associated" property to \a property. The function
       
   959   might be the setter or getter for a property, for example.
       
   960  */
       
   961 void FunctionNode::setAssociatedProperty(PropertyNode *property)
       
   962 {
       
   963     ap = property;
       
   964 }
       
   965 
       
   966 /*!
       
   967   Returns the overload number for this function obtained
       
   968   from the parent.
       
   969  */
       
   970 int FunctionNode::overloadNumber() const
       
   971 {
       
   972     return parent()->overloadNumber(this);
       
   973 }
       
   974 
       
   975 /*!
       
   976   Returns the number of times this function name has been
       
   977   overloaded, obtained from the parent.
       
   978  */
       
   979 int FunctionNode::numOverloads() const
       
   980 {
       
   981     return parent()->numOverloads(name());
       
   982 }
       
   983 
       
   984 /*!
       
   985   Returns the list of parameter names.
       
   986  */
       
   987 QStringList FunctionNode::parameterNames() const
       
   988 {
       
   989     QStringList names;
       
   990     QList<Parameter>::ConstIterator p = parameters().begin();
       
   991     while (p != parameters().end()) {
       
   992         names << (*p).name();
       
   993         ++p;
       
   994     }
       
   995     return names;
       
   996 }
       
   997 
       
   998 /*!
       
   999   Returns the list of reconstructed parameters. If \a values
       
  1000   is true, the default values are included, if any are present.
       
  1001  */
       
  1002 QStringList FunctionNode::reconstructParams(bool values) const
       
  1003 {
       
  1004     QStringList params;
       
  1005     QList<Parameter>::ConstIterator p = parameters().begin();
       
  1006     while (p != parameters().end()) {
       
  1007         params << (*p).reconstruct(values);
       
  1008         ++p;
       
  1009     }
       
  1010     return params;
       
  1011 }
       
  1012 
       
  1013 /*!
       
  1014   Reconstructs and returns the function's signature. If \a values
       
  1015   is true, the default values of the parameters are included, if
       
  1016   present.
       
  1017  */
       
  1018 QString FunctionNode::signature(bool values) const
       
  1019 {
       
  1020     QString s;
       
  1021     if (!returnType().isEmpty())
       
  1022         s = returnType() + " ";
       
  1023     s += name() + "(";
       
  1024     QStringList params = reconstructParams(values);
       
  1025     int p = params.size();
       
  1026     if (p > 0) {
       
  1027         for (int i=0; i<p; i++) {
       
  1028             s += params[i];
       
  1029             if (i < (p-1))
       
  1030                 s += ", ";
       
  1031         }
       
  1032     }
       
  1033     s += ")";
       
  1034     return s;
       
  1035 }
       
  1036 
       
  1037 
       
  1038 /*!
       
  1039   \class PropertyNode
       
  1040  */
       
  1041 
       
  1042 /*!
       
  1043  */
       
  1044 PropertyNode::PropertyNode(InnerNode *parent, const QString& name)
       
  1045     : LeafNode(Property, parent, name),
       
  1046       sto(Trool_Default),
       
  1047       des(Trool_Default),
       
  1048       overrides(0)
       
  1049 {
       
  1050 }
       
  1051 
       
  1052 /*!
       
  1053  */
       
  1054 void PropertyNode::setOverriddenFrom(const PropertyNode *baseProperty)
       
  1055 {
       
  1056     for (int i = 0; i < NumFunctionRoles; ++i) {
       
  1057         if (funcs[i].isEmpty())
       
  1058             funcs[i] = baseProperty->funcs[i];
       
  1059     }
       
  1060     if (sto == Trool_Default)
       
  1061         sto = baseProperty->sto;
       
  1062     if (des == Trool_Default)
       
  1063         des = baseProperty->des;
       
  1064     overrides = baseProperty;
       
  1065 }
       
  1066 
       
  1067 /*!
       
  1068  */
       
  1069 QString PropertyNode::qualifiedDataType() const
       
  1070 {
       
  1071     if (setters().isEmpty() && resetters().isEmpty()) {
       
  1072         if (dt.contains("*") || dt.contains("&")) {
       
  1073             // 'QWidget *' becomes 'QWidget *' const
       
  1074             return dt + " const";
       
  1075         }
       
  1076         else {
       
  1077             /*
       
  1078               'int' becomes 'const int' ('int const' is
       
  1079               correct C++, but looks wrong)
       
  1080             */
       
  1081             return "const " + dt;
       
  1082         }
       
  1083     }
       
  1084     else {
       
  1085         return dt;
       
  1086     }
       
  1087 }
       
  1088 
       
  1089 /*!
       
  1090  */
       
  1091 PropertyNode::Trool PropertyNode::toTrool(bool boolean)
       
  1092 {
       
  1093     return boolean ? Trool_True : Trool_False;
       
  1094 }
       
  1095 
       
  1096 /*!
       
  1097  */
       
  1098 bool PropertyNode::fromTrool(Trool troolean, bool defaultValue)
       
  1099 {
       
  1100     switch (troolean) {
       
  1101     case Trool_True:
       
  1102         return true;
       
  1103     case Trool_False:
       
  1104         return false;
       
  1105     default:
       
  1106         return defaultValue;
       
  1107     }
       
  1108 }
       
  1109 
       
  1110 /*!
       
  1111   \class TargetNode
       
  1112  */
       
  1113 
       
  1114 /*!
       
  1115  */
       
  1116 TargetNode::TargetNode(InnerNode *parent, const QString& name)
       
  1117     : LeafNode(Target, parent, name)
       
  1118 {
       
  1119 }
       
  1120 
       
  1121 /*!
       
  1122   Returns false because this is a TargetNode.
       
  1123  */
       
  1124 bool TargetNode::isInnerNode() const
       
  1125 {
       
  1126     return false;
       
  1127 }
       
  1128 
       
  1129 #ifdef QDOC_QML
       
  1130 /*!
       
  1131   Constructor for the Qml class node.
       
  1132  */
       
  1133 QmlClassNode::QmlClassNode(InnerNode *parent,
       
  1134                            const QString& name,
       
  1135                            const ClassNode* cn)
       
  1136     : FakeNode(parent, name, QmlClass), cnode(cn)
       
  1137 {
       
  1138     setTitle("QML " + name + " Element Reference");
       
  1139 }
       
  1140 
       
  1141 /*!
       
  1142   The base file name for this kind of node has "qml_"
       
  1143   prepended to it.
       
  1144 
       
  1145   But not yet. Still testing.
       
  1146  */
       
  1147 QString QmlClassNode::fileBase() const
       
  1148 {
       
  1149 #if 0    
       
  1150     if (Node::fileBase() == "item")
       
  1151         qDebug() << "FILEBASE: qmlitem" << name();
       
  1152     return "qml_" + Node::fileBase();
       
  1153 #endif
       
  1154     return Node::fileBase();
       
  1155 }
       
  1156 
       
  1157 /*!
       
  1158   Constructor for the Qml property group node. \a parent is
       
  1159   always a QmlClassNode. 
       
  1160  */
       
  1161 QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent,
       
  1162                                    const QString& name,
       
  1163                                    bool attached)
       
  1164     : FakeNode(parent, name, QmlPropertyGroup),
       
  1165       isdefault(false),
       
  1166       att(attached)
       
  1167 {
       
  1168     // nothing.
       
  1169 }
       
  1170 
       
  1171 /*!
       
  1172   Constructor for the QML property node.
       
  1173  */
       
  1174 QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
       
  1175                                  const QString& name,
       
  1176                                  const QString& type,
       
  1177                                  bool attached)
       
  1178     : LeafNode(QmlProperty, parent, name),
       
  1179       dt(type),
       
  1180       sto(Trool_Default),
       
  1181       des(Trool_Default),
       
  1182       att(attached)
       
  1183 {
       
  1184     // nothing.
       
  1185 }
       
  1186 
       
  1187 /*!
       
  1188   I don't know what this is.
       
  1189  */
       
  1190 QmlPropertyNode::Trool QmlPropertyNode::toTrool(bool boolean)
       
  1191 {
       
  1192     return boolean ? Trool_True : Trool_False;
       
  1193 }
       
  1194 
       
  1195 /*!
       
  1196   I don't know what this is either.
       
  1197  */
       
  1198 bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue)
       
  1199 {
       
  1200     switch (troolean) {
       
  1201     case Trool_True:
       
  1202         return true;
       
  1203     case Trool_False:
       
  1204         return false;
       
  1205     default:
       
  1206         return defaultValue;
       
  1207     }
       
  1208 }
       
  1209 
       
  1210 /*!
       
  1211   Constructor for the QML signal node.
       
  1212  */
       
  1213 QmlSignalNode::QmlSignalNode(QmlClassNode *parent, const QString& name)
       
  1214     : LeafNode(QmlSignal, parent, name)
       
  1215 {
       
  1216     // nothing.
       
  1217 }
       
  1218 
       
  1219 /*!
       
  1220   Constructor for the QML method node.
       
  1221  */
       
  1222 QmlMethodNode::QmlMethodNode(QmlClassNode *parent, const QString& name)
       
  1223     : LeafNode(QmlMethod, parent, name)
       
  1224 {
       
  1225     // nothing.
       
  1226 }
       
  1227 #endif
       
  1228 
       
  1229 QT_END_NAMESPACE