util/tools/qdoc3/node.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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   Find the function node in this node for the function named \a name.
       
   222  */
       
   223 FunctionNode *InnerNode::findFunctionNode(const QString& name)
       
   224 {
       
   225     return static_cast<FunctionNode *>(primaryFunctionMap.value(name));
       
   226 }
       
   227 
       
   228 /*!
       
   229   Find the function node in this node that has the same name as \a clone.
       
   230  */
       
   231 FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone)
       
   232 {
       
   233     QMap<QString, Node *>::ConstIterator c =
       
   234 	    primaryFunctionMap.find(clone->name());
       
   235     if (c != primaryFunctionMap.end()) {
       
   236 	if (isSameSignature(clone, (FunctionNode *) *c)) {
       
   237 	    return (FunctionNode *) *c;
       
   238 	}
       
   239         else if (secondaryFunctionMap.contains(clone->name())) {
       
   240 	    const NodeList& secs = secondaryFunctionMap[clone->name()];
       
   241 	    NodeList::ConstIterator s = secs.begin();
       
   242 	    while (s != secs.end()) {
       
   243 		if (isSameSignature(clone, (FunctionNode *) *s))
       
   244 		    return (FunctionNode *) *s;
       
   245 		++s;
       
   246 	    }
       
   247 	}
       
   248     }
       
   249     return 0;
       
   250 }
       
   251 
       
   252 /*!
       
   253   Returns the list of keys from the primary function map.
       
   254  */
       
   255 QStringList InnerNode::primaryKeys()
       
   256 {
       
   257     QStringList t;
       
   258     QMap<QString, Node*>::iterator i = primaryFunctionMap.begin();
       
   259     while (i != primaryFunctionMap.end()) {
       
   260         t.append(i.key());
       
   261         ++i;
       
   262     }
       
   263     return t;
       
   264 }
       
   265 
       
   266 /*!
       
   267   Returns the list of keys from the secondary function map.
       
   268  */
       
   269 QStringList InnerNode::secondaryKeys()
       
   270 {
       
   271     QStringList t;
       
   272     QMap<QString, NodeList>::iterator i = secondaryFunctionMap.begin();
       
   273     while (i != secondaryFunctionMap.end()) {
       
   274         t.append(i.key());
       
   275         ++i;
       
   276     }
       
   277     return t;
       
   278 }
       
   279 
       
   280 /*!
       
   281  */
       
   282 void InnerNode::setOverload(const FunctionNode *func, bool overlode)
       
   283 {
       
   284     Node *node = (Node *) func;
       
   285     Node *&primary = primaryFunctionMap[func->name()];
       
   286 
       
   287     if (secondaryFunctionMap.contains(func->name())) {
       
   288 	NodeList& secs = secondaryFunctionMap[func->name()];
       
   289 	if (overlode) {
       
   290 	    if (primary == node) {
       
   291 		primary = secs.first();
       
   292 		secs.erase(secs.begin());
       
   293 		secs.append(node);
       
   294 	    }
       
   295             else {
       
   296 		secs.removeAll(node);
       
   297                 secs.append(node);
       
   298             }
       
   299 	}
       
   300         else {
       
   301 	    if (primary != node) {
       
   302 		secs.removeAll(node);
       
   303 		secs.prepend(primary);
       
   304 		primary = node;
       
   305 	    }
       
   306 	}
       
   307     }
       
   308 }
       
   309 
       
   310 /*!
       
   311  */
       
   312 void InnerNode::makeUndocumentedChildrenInternal()
       
   313 {
       
   314     foreach (Node *child, childNodes()) {
       
   315         if (child->doc().isEmpty()) {
       
   316             child->setAccess(Node::Private);
       
   317             child->setStatus(Node::Internal);
       
   318         }
       
   319     }
       
   320 }
       
   321 
       
   322 /*!
       
   323  */
       
   324 void InnerNode::normalizeOverloads()
       
   325 {
       
   326     QMap<QString, Node *>::Iterator p1 = primaryFunctionMap.begin();
       
   327     while (p1 != primaryFunctionMap.end()) {
       
   328         FunctionNode *primaryFunc = (FunctionNode *) *p1;
       
   329         if (secondaryFunctionMap.contains(primaryFunc->name()) &&
       
   330             (primaryFunc->status() != Commendable ||
       
   331              primaryFunc->access() == Private)) {
       
   332 
       
   333 	    NodeList& secs = secondaryFunctionMap[primaryFunc->name()];
       
   334 	    NodeList::ConstIterator s = secs.begin();
       
   335 	    while (s != secs.end()) {
       
   336 		FunctionNode *secondaryFunc = (FunctionNode *) *s;
       
   337 
       
   338                 // Any non-obsolete, non-compatibility, non-private functions
       
   339                 // (i.e, visible functions) are preferable to the primary
       
   340                 // function.
       
   341 
       
   342                 if (secondaryFunc->status() == Commendable &&
       
   343                     secondaryFunc->access() != Private) {
       
   344 
       
   345                     *p1 = secondaryFunc;
       
   346                     int index = secondaryFunctionMap[primaryFunc->name()].indexOf(secondaryFunc);
       
   347                     secondaryFunctionMap[primaryFunc->name()].replace(index, primaryFunc);
       
   348                     break;
       
   349                 }
       
   350                 ++s;
       
   351             }
       
   352         }
       
   353         ++p1;
       
   354     }
       
   355 
       
   356     QMap<QString, Node *>::ConstIterator p = primaryFunctionMap.begin();
       
   357     while (p != primaryFunctionMap.end()) {
       
   358 	FunctionNode *primaryFunc = (FunctionNode *) *p;
       
   359 	if (primaryFunc->isOverload())
       
   360 	    primaryFunc->ove = false;
       
   361 	if (secondaryFunctionMap.contains(primaryFunc->name())) {
       
   362 	    NodeList& secs = secondaryFunctionMap[primaryFunc->name()];
       
   363 	    NodeList::ConstIterator s = secs.begin();
       
   364 	    while (s != secs.end()) {
       
   365 		FunctionNode *secondaryFunc = (FunctionNode *) *s;
       
   366 		if (!secondaryFunc->isOverload())
       
   367 		    secondaryFunc->ove = true;
       
   368 		++s;
       
   369 	    }
       
   370 	}
       
   371 	++p;
       
   372     }
       
   373 
       
   374     NodeList::ConstIterator c = childNodes().begin();
       
   375     while (c != childNodes().end()) {
       
   376 	if ((*c)->isInnerNode())
       
   377 	    ((InnerNode *) *c)->normalizeOverloads();
       
   378 	++c;
       
   379     }
       
   380 }
       
   381 
       
   382 /*!
       
   383  */
       
   384 void InnerNode::removeFromRelated() 
       
   385 {
       
   386     while (!related.isEmpty()) {
       
   387         Node *p = static_cast<Node *>(related.takeFirst());
       
   388 
       
   389         if (p != 0 && p->relates() == this) p->clearRelated();
       
   390     }
       
   391 }
       
   392 
       
   393 /*!
       
   394  */
       
   395 void InnerNode::deleteChildren()
       
   396 {
       
   397     qDeleteAll(children);
       
   398 }
       
   399 
       
   400 /*!
       
   401   Returns true.
       
   402  */
       
   403 bool InnerNode::isInnerNode() const
       
   404 {
       
   405     return true;
       
   406 }
       
   407 
       
   408 /*!
       
   409  */
       
   410 const Node *InnerNode::findNode(const QString& name) const
       
   411 {
       
   412     InnerNode *that = (InnerNode *) this;
       
   413     return that->findNode(name);
       
   414 }
       
   415 
       
   416 /*!
       
   417  */
       
   418 const Node *InnerNode::findNode(const QString& name, Type type) const
       
   419 {
       
   420     InnerNode *that = (InnerNode *) this;
       
   421     return that->findNode(name, type);
       
   422 }
       
   423 
       
   424 /*!
       
   425   Find the function node in this node that has the given \a name. 
       
   426  */
       
   427 const FunctionNode *InnerNode::findFunctionNode(const QString& name) const
       
   428 {
       
   429     InnerNode *that = (InnerNode *) this;
       
   430     return that->findFunctionNode(name);
       
   431 }
       
   432 
       
   433 /*!
       
   434   Find the function node in this node that has the same name as \a clone.
       
   435  */
       
   436 const FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) const
       
   437 {
       
   438     InnerNode *that = (InnerNode *) this;
       
   439     return that->findFunctionNode(clone);
       
   440 }
       
   441 
       
   442 /*!
       
   443  */
       
   444 const EnumNode *InnerNode::findEnumNodeForValue(const QString &enumValue) const
       
   445 {
       
   446     foreach (const Node *node, enumChildren) {
       
   447         const EnumNode *enume = static_cast<const EnumNode *>(node);
       
   448         if (enume->hasItem(enumValue))
       
   449             return enume;
       
   450     }
       
   451     return 0;
       
   452 }
       
   453 
       
   454 /*!
       
   455  */
       
   456 int InnerNode::overloadNumber(const FunctionNode *func) const
       
   457 {
       
   458     Node *node = (Node *) func;
       
   459     if (primaryFunctionMap[func->name()] == node) {
       
   460         return 1;
       
   461     }
       
   462     else {
       
   463         return secondaryFunctionMap[func->name()].indexOf(node) + 2;
       
   464     }
       
   465 }
       
   466 
       
   467 /*!
       
   468  */
       
   469 int InnerNode::numOverloads(const QString& funcName) const
       
   470 {
       
   471     if (primaryFunctionMap.contains(funcName)) {
       
   472         return secondaryFunctionMap[funcName].count() + 1;
       
   473     }
       
   474     else {
       
   475         return 0;
       
   476     }
       
   477 }
       
   478 
       
   479 /*!
       
   480  */
       
   481 NodeList InnerNode::overloads(const QString &funcName) const
       
   482 {
       
   483     NodeList result;
       
   484     Node *primary = primaryFunctionMap.value(funcName);
       
   485     if (primary) {
       
   486         result << primary;
       
   487         result += secondaryFunctionMap[funcName];
       
   488     }
       
   489     return result;
       
   490 }
       
   491 
       
   492 /*!
       
   493  */
       
   494 InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name)
       
   495     : Node(type, parent, name)
       
   496 {
       
   497 }
       
   498 
       
   499 /*!
       
   500  */
       
   501 void InnerNode::addInclude(const QString& include)
       
   502 {
       
   503     inc.append(include);
       
   504 }
       
   505 
       
   506 /*!
       
   507  */
       
   508 void InnerNode::setIncludes(const QStringList& includes)
       
   509 {
       
   510     inc = includes;
       
   511 }
       
   512 
       
   513 /*!
       
   514   f1 is always the clone
       
   515  */
       
   516 bool InnerNode::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
       
   517 {
       
   518     if (f1->parameters().count() != f2->parameters().count())
       
   519         return false;
       
   520     if (f1->isConst() != f2->isConst())
       
   521         return false;
       
   522 
       
   523     QList<Parameter>::ConstIterator p1 = f1->parameters().begin();
       
   524     QList<Parameter>::ConstIterator p2 = f2->parameters().begin();
       
   525     while (p2 != f2->parameters().end()) {
       
   526 	if ((*p1).hasType() && (*p2).hasType()) {
       
   527             if ((*p1).rightType() != (*p2).rightType())
       
   528                 return false;
       
   529 
       
   530             QString t1 = p1->leftType();
       
   531             QString t2 = p2->leftType();
       
   532 
       
   533             if (t1.length() < t2.length())
       
   534                 qSwap(t1, t2);
       
   535 
       
   536             /*
       
   537               ### hack for C++ to handle superfluous
       
   538               "Foo::" prefixes gracefully
       
   539             */
       
   540             if (t1 != t2 && t1 != (f2->parent()->name() + "::" + t2))
       
   541                 return false;
       
   542         }
       
   543         ++p1;
       
   544         ++p2;
       
   545     }
       
   546     return true;
       
   547 }
       
   548 
       
   549 /*!
       
   550  */
       
   551 void InnerNode::addChild(Node *child)
       
   552 {
       
   553     children.append(child);
       
   554     if ((child->type() == Function) || (child->type() == QmlMethod)) {
       
   555         FunctionNode *func = (FunctionNode *) child;
       
   556         if (!primaryFunctionMap.contains(func->name())) {
       
   557             primaryFunctionMap.insert(func->name(), func);
       
   558 	}
       
   559         else {
       
   560 	    NodeList &secs = secondaryFunctionMap[func->name()];
       
   561 	    secs.append(func);
       
   562 	}
       
   563     }
       
   564     else {
       
   565         if (child->type() == Enum)
       
   566             enumChildren.append(child);
       
   567 	childMap.insert(child->name(), child);
       
   568     }
       
   569 }
       
   570 
       
   571 /*!
       
   572  */
       
   573 void InnerNode::removeChild(Node *child)
       
   574 {
       
   575     children.removeAll(child);
       
   576     enumChildren.removeAll(child);
       
   577     if (child->type() == Function) {
       
   578 	QMap<QString, Node *>::Iterator prim =
       
   579 		primaryFunctionMap.find(child->name());
       
   580 	NodeList& secs = secondaryFunctionMap[child->name()];
       
   581 	if (*prim == child) {
       
   582 	    if (secs.isEmpty()) {
       
   583 		primaryFunctionMap.remove(child->name());
       
   584 	    }
       
   585             else {
       
   586 		primaryFunctionMap.insert(child->name(), secs.takeFirst());
       
   587 	    }
       
   588 	}
       
   589         else {
       
   590 	    secs.removeAll(child);
       
   591 	}
       
   592         QMap<QString, Node *>::Iterator ent = childMap.find( child->name() );
       
   593         if ( *ent == child )
       
   594             childMap.erase( ent );
       
   595     }
       
   596     else {
       
   597 	QMap<QString, Node *>::Iterator ent = childMap.find(child->name());
       
   598 	if (*ent == child)
       
   599 	    childMap.erase(ent);
       
   600     }
       
   601 }
       
   602 
       
   603 /*!
       
   604   Find the module (QtCore, QtGui, etc.) to which the class belongs.
       
   605   We do this by obtaining the full path to the header file's location
       
   606   and examine everything between "src/" and the filename.  This is
       
   607   semi-dirty because we are assuming a particular directory structure.
       
   608 
       
   609   This function is only really useful if the class's module has not
       
   610   been defined in the header file with a QT_MODULE macro or with an
       
   611   \inmodule command in the documentation.
       
   612 */
       
   613 QString Node::moduleName() const
       
   614 {
       
   615     if (!mod.isEmpty())
       
   616         return mod;
       
   617 
       
   618     QString path = location().filePath();
       
   619     QString pattern = QString("src") + QDir::separator();
       
   620     int start = path.lastIndexOf(pattern);
       
   621 
       
   622     if (start == -1)
       
   623         return "";
       
   624 
       
   625     QString moduleDir = path.mid(start + pattern.size());
       
   626     int finish = moduleDir.indexOf(QDir::separator());
       
   627 
       
   628     if (finish == -1)
       
   629         return "";
       
   630 
       
   631     QString moduleName = moduleDir.left(finish);
       
   632 
       
   633     if (moduleName == "corelib")
       
   634         return "QtCore";
       
   635     else if (moduleName == "uitools")
       
   636         return "QtUiTools";
       
   637     else if (moduleName == "gui")
       
   638         return "QtGui";
       
   639     else if (moduleName == "network")
       
   640         return "QtNetwork";
       
   641     else if (moduleName == "opengl")
       
   642         return "QtOpenGL";
       
   643     else if (moduleName == "qt3support")
       
   644         return "Qt3Support";
       
   645     else if (moduleName == "svg")
       
   646         return "QtSvg";
       
   647     else if (moduleName == "sql")
       
   648         return "QtSql";
       
   649     else if (moduleName == "qtestlib")
       
   650         return "QtTest";
       
   651     else if (moduleDir.contains("webkit"))
       
   652         return "QtWebKit";
       
   653     else if (moduleName == "xml")
       
   654         return "QtXml";
       
   655     else
       
   656         return "";
       
   657 }
       
   658 
       
   659 /*!
       
   660  */
       
   661 void InnerNode::removeRelated(Node *pseudoChild)
       
   662 {
       
   663     related.removeAll(pseudoChild);
       
   664 }
       
   665 
       
   666 /*!
       
   667   \class LeafNode
       
   668  */
       
   669 
       
   670 /*!
       
   671   Returns false because this is a LeafNode.
       
   672  */
       
   673 bool LeafNode::isInnerNode() const
       
   674 {
       
   675     return false;
       
   676 }
       
   677 
       
   678 /*!
       
   679  */
       
   680 LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name)
       
   681     : Node(type, parent, name)
       
   682 {
       
   683 }
       
   684 
       
   685 /*!
       
   686   \class NamespaceNode
       
   687  */
       
   688 
       
   689 /*!
       
   690  */
       
   691 NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
       
   692     : InnerNode(Namespace, parent, name)
       
   693 {
       
   694 }
       
   695 
       
   696 /*!
       
   697   \class ClassNode
       
   698  */
       
   699 
       
   700 /*!
       
   701  */
       
   702 ClassNode::ClassNode(InnerNode *parent, const QString& name)
       
   703     : InnerNode(Class, parent, name)
       
   704 {
       
   705     hidden = false;
       
   706 }
       
   707 
       
   708 /*!
       
   709  */
       
   710 void ClassNode::addBaseClass(Access access,
       
   711                              ClassNode *node,
       
   712                              const QString &dataTypeWithTemplateArgs)
       
   713 {
       
   714     bas.append(RelatedClass(access, node, dataTypeWithTemplateArgs));
       
   715     node->der.append(RelatedClass(access, this));
       
   716 }
       
   717 
       
   718 /*!
       
   719  */
       
   720 void ClassNode::fixBaseClasses()
       
   721 {
       
   722     int i;
       
   723 
       
   724     i = 0;
       
   725     while (i < bas.size()) {
       
   726         ClassNode *baseClass = bas.at(i).node;
       
   727         if (baseClass->access() == Node::Private) {
       
   728             bas.removeAt(i);
       
   729 
       
   730             const QList<RelatedClass> &basesBases = baseClass->baseClasses();
       
   731             for (int j = basesBases.size() - 1; j >= 0; --j)
       
   732                 bas.insert(i, basesBases.at(j));
       
   733         }
       
   734         else {
       
   735             ++i;
       
   736         }
       
   737     }
       
   738 
       
   739     i = 0;
       
   740     while (i < der.size()) {
       
   741         ClassNode *derivedClass = der.at(i).node;
       
   742         if (derivedClass->access() == Node::Private) {
       
   743             der.removeAt(i);
       
   744 
       
   745             const QList<RelatedClass> &dersDers =
       
   746                 derivedClass->derivedClasses();
       
   747             for (int j = dersDers.size() - 1; j >= 0; --j)
       
   748                 der.insert(i, dersDers.at(j));
       
   749         }
       
   750         else {
       
   751             ++i;
       
   752         }
       
   753     }
       
   754 }
       
   755 
       
   756 /*!
       
   757   \class FakeNode
       
   758  */
       
   759 
       
   760 /*!
       
   761   The type of a FakeNode is Fake, and it has a \a subtype,
       
   762   which specifies the type of FakeNode.
       
   763  */
       
   764 FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype)
       
   765     : InnerNode(Fake, parent, name), sub(subtype)
       
   766 {
       
   767 }
       
   768 
       
   769 /*!
       
   770   Returns the fake node's full title, which is usually
       
   771   just title(), but for some SubType values is different
       
   772   from title()
       
   773  */
       
   774 QString FakeNode::fullTitle() const
       
   775 {
       
   776     if (sub == File) {
       
   777         if (title().isEmpty())
       
   778             return name().mid(name().lastIndexOf('/') + 1) + " Example File";
       
   779         else
       
   780             return title();
       
   781     }
       
   782     else if (sub == Image) {
       
   783         if (title().isEmpty())
       
   784             return name().mid(name().lastIndexOf('/') + 1) + " Image File";
       
   785         else
       
   786             return title();
       
   787     }
       
   788     else if (sub == HeaderFile) {
       
   789         if (title().isEmpty())
       
   790             return name();
       
   791         else
       
   792             return name() + " - " + title();
       
   793     }
       
   794     else {
       
   795         return title();
       
   796     }
       
   797 }
       
   798 
       
   799 /*!
       
   800   Returns the subtitle.
       
   801  */
       
   802 QString FakeNode::subTitle() const
       
   803 {
       
   804     if (!stle.isEmpty())
       
   805         return stle;
       
   806 
       
   807     if ((sub == File) || (sub == Image)) {
       
   808         if (title().isEmpty() && name().contains("/"))
       
   809             return name();
       
   810     }
       
   811     return QString();
       
   812 }
       
   813 
       
   814 /*!
       
   815   \class EnumNode
       
   816  */
       
   817 
       
   818 /*!
       
   819  */
       
   820 EnumNode::EnumNode(InnerNode *parent, const QString& name)
       
   821     : LeafNode(Enum, parent, name), ft(0)
       
   822 {
       
   823 }
       
   824 
       
   825 /*!
       
   826  */
       
   827 void EnumNode::addItem(const EnumItem& item)
       
   828 {
       
   829     itms.append(item);
       
   830     names.insert(item.name());
       
   831 }
       
   832 
       
   833 /*!
       
   834  */
       
   835 Node::Access EnumNode::itemAccess(const QString &name) const
       
   836 {
       
   837     if (doc().omitEnumItemNames().contains(name)) {
       
   838         return Private;
       
   839     }
       
   840     else {
       
   841         return Public;
       
   842     }
       
   843 }
       
   844 
       
   845 /*!
       
   846   Returns the enum value associated with the enum \a name.
       
   847  */
       
   848 QString EnumNode::itemValue(const QString &name) const
       
   849 {
       
   850     foreach (const EnumItem &item, itms) {
       
   851         if (item.name() == name)
       
   852             return item.value();
       
   853     }
       
   854     return QString();
       
   855 }
       
   856 
       
   857 /*!
       
   858   \class TypedefNode
       
   859  */
       
   860 
       
   861 /*!
       
   862  */
       
   863 TypedefNode::TypedefNode(InnerNode *parent, const QString& name)
       
   864     : LeafNode(Typedef, parent, name), ae(0)
       
   865 {
       
   866 }
       
   867 
       
   868 /*!
       
   869  */
       
   870 void TypedefNode::setAssociatedEnum(const EnumNode *enume)
       
   871 {
       
   872     ae = enume;
       
   873 }
       
   874 
       
   875 /*!
       
   876   \class Parameter
       
   877   \brief The class Parameter contains one parameter.
       
   878 
       
   879   A parameter can be a function parameter or a macro
       
   880   parameter.
       
   881  */
       
   882 
       
   883 /*!
       
   884   Constructs this parameter from the left and right types
       
   885   \a leftType and rightType, the parameter \a name, and the
       
   886   \a defaultValue. In practice, \a rightType is not used,
       
   887   and I don't know what is was meant for.
       
   888  */
       
   889 Parameter::Parameter(const QString& leftType,
       
   890                      const QString& rightType,
       
   891 		     const QString& name,
       
   892                      const QString& defaultValue)
       
   893     : lef(leftType), rig(rightType), nam(name), def(defaultValue)
       
   894 {
       
   895 }
       
   896 
       
   897 /*!
       
   898   The standard copy constructor copies the strings from \a p.
       
   899  */
       
   900 Parameter::Parameter(const Parameter& p)
       
   901     : lef(p.lef), rig(p.rig), nam(p.nam), def(p.def)
       
   902 {
       
   903 }
       
   904 
       
   905 /*!
       
   906   Assigning Parameter \a p to this Parameter copies the
       
   907   strings across. 
       
   908  */
       
   909 Parameter& Parameter::operator=(const Parameter& p)
       
   910 {
       
   911     lef = p.lef;
       
   912     rig = p.rig;
       
   913     nam = p.nam;
       
   914     def = p.def;
       
   915     return *this;
       
   916 }
       
   917 
       
   918 /*!
       
   919   Reconstructs the text describing the parameter and
       
   920   returns it. If \a value is true, the default value
       
   921   will be included, if there is one.
       
   922  */
       
   923 QString Parameter::reconstruct(bool value) const
       
   924 {
       
   925     QString p = lef + rig;
       
   926     if (!p.endsWith(QChar('*')) && !p.endsWith(QChar('&')) && !p.endsWith(QChar(' ')))
       
   927         p += " ";
       
   928     p += nam;
       
   929     if (value)
       
   930         p += def;
       
   931     return p;
       
   932 }
       
   933 
       
   934 
       
   935 /*!
       
   936   \class FunctionNode
       
   937  */
       
   938 
       
   939 /*!
       
   940   Construct a function node for a C++ function. It's parent
       
   941   is \a parent, and it's name is \a name.
       
   942  */
       
   943 FunctionNode::FunctionNode(InnerNode *parent, const QString& name)
       
   944     : LeafNode(Function, parent, name),
       
   945       met(Plain),
       
   946       vir(NonVirtual),
       
   947       con(false),
       
   948       sta(false),
       
   949       ove(false),
       
   950       att(false),
       
   951       rf(0),
       
   952       ap(0)
       
   953 {
       
   954     // nothing.
       
   955 }
       
   956 
       
   957 /*!
       
   958   Construct a function node for a QML method or signal, specified
       
   959   by \a type. It's parent is \a parent, and it's name is \a name.
       
   960   If \a attached is true, it is an attached method or signal.
       
   961  */
       
   962 FunctionNode::FunctionNode(Type type, InnerNode *parent, const QString& name, bool attached)
       
   963     : LeafNode(type, parent, name),
       
   964       met(Plain),
       
   965       vir(NonVirtual),
       
   966       con(false),
       
   967       sta(false),
       
   968       ove(false),
       
   969       att(attached),
       
   970       rf(0),
       
   971       ap(0)
       
   972 {
       
   973     // nothing.
       
   974 }
       
   975 
       
   976 /*!
       
   977  */
       
   978 void FunctionNode::setOverload(bool overlode)
       
   979 {
       
   980     parent()->setOverload(this, overlode);
       
   981     ove = overlode;
       
   982 }
       
   983 
       
   984 /*!
       
   985   Sets the function node's reimplementation flag to \a r.
       
   986   When \a r is true, it is supposed to mean that this function
       
   987   is a reimplementation of a virtual function in a base class,
       
   988   but it really just means the \e reimp command was seen in the
       
   989   qdoc comment.
       
   990  */
       
   991 void FunctionNode::setReimp(bool r)
       
   992 {
       
   993     reimp = r;
       
   994 }
       
   995 
       
   996 /*!
       
   997  */
       
   998 void FunctionNode::addParameter(const Parameter& parameter)
       
   999 {
       
  1000     params.append(parameter);
       
  1001 }
       
  1002 
       
  1003 /*!
       
  1004  */
       
  1005 void FunctionNode::borrowParameterNames(const FunctionNode *source)
       
  1006 {
       
  1007     QList<Parameter>::Iterator t = params.begin();
       
  1008     QList<Parameter>::ConstIterator s = source->params.begin();
       
  1009     while (s != source->params.end() && t != params.end()) {
       
  1010 	if (!(*s).name().isEmpty())
       
  1011 	    (*t).setName((*s).name());
       
  1012 	++s;
       
  1013 	++t;
       
  1014     }
       
  1015 }
       
  1016 
       
  1017 /*!
       
  1018   If this function is a reimplementation, \a from points
       
  1019   to the FunctionNode of the function being reimplemented.
       
  1020  */
       
  1021 void FunctionNode::setReimplementedFrom(FunctionNode *from)
       
  1022 {
       
  1023     rf = from;
       
  1024     from->rb.append(this);
       
  1025 }
       
  1026 
       
  1027 /*!
       
  1028   Sets the "associated" property to \a property. The function
       
  1029   might be the setter or getter for a property, for example.
       
  1030  */
       
  1031 void FunctionNode::setAssociatedProperty(PropertyNode *property)
       
  1032 {
       
  1033     ap = property;
       
  1034 }
       
  1035 
       
  1036 /*!
       
  1037   Returns the overload number for this function obtained
       
  1038   from the parent.
       
  1039  */
       
  1040 int FunctionNode::overloadNumber() const
       
  1041 {
       
  1042     return parent()->overloadNumber(this);
       
  1043 }
       
  1044 
       
  1045 /*!
       
  1046   Returns the number of times this function name has been
       
  1047   overloaded, obtained from the parent.
       
  1048  */
       
  1049 int FunctionNode::numOverloads() const
       
  1050 {
       
  1051     return parent()->numOverloads(name());
       
  1052 }
       
  1053 
       
  1054 /*!
       
  1055   Returns the list of parameter names.
       
  1056  */
       
  1057 QStringList FunctionNode::parameterNames() const
       
  1058 {
       
  1059     QStringList names;
       
  1060     QList<Parameter>::ConstIterator p = parameters().begin();
       
  1061     while (p != parameters().end()) {
       
  1062         names << (*p).name();
       
  1063         ++p;
       
  1064     }
       
  1065     return names;
       
  1066 }
       
  1067 
       
  1068 /*!
       
  1069   Returns the list of reconstructed parameters. If \a values
       
  1070   is true, the default values are included, if any are present.
       
  1071  */
       
  1072 QStringList FunctionNode::reconstructParams(bool values) const
       
  1073 {
       
  1074     QStringList params;
       
  1075     QList<Parameter>::ConstIterator p = parameters().begin();
       
  1076     while (p != parameters().end()) {
       
  1077         params << (*p).reconstruct(values);
       
  1078         ++p;
       
  1079     }
       
  1080     return params;
       
  1081 }
       
  1082 
       
  1083 /*!
       
  1084   Reconstructs and returns the function's signature. If \a values
       
  1085   is true, the default values of the parameters are included, if
       
  1086   present.
       
  1087  */
       
  1088 QString FunctionNode::signature(bool values) const
       
  1089 {
       
  1090     QString s;
       
  1091     if (!returnType().isEmpty())
       
  1092         s = returnType() + " ";
       
  1093     s += name() + "(";
       
  1094     QStringList params = reconstructParams(values);
       
  1095     int p = params.size();
       
  1096     if (p > 0) {
       
  1097         for (int i=0; i<p; i++) {
       
  1098             s += params[i];
       
  1099             if (i < (p-1))
       
  1100                 s += ", ";
       
  1101         }
       
  1102     }
       
  1103     s += ")";
       
  1104     return s;
       
  1105 }
       
  1106 
       
  1107 /*!
       
  1108   Print some debugging stuff.
       
  1109  */
       
  1110 void FunctionNode::debug() const
       
  1111 {
       
  1112     qDebug() << "QML METHOD" << name() << "rt" << rt << "pp" << pp;
       
  1113 }
       
  1114 
       
  1115 /*!
       
  1116   \class PropertyNode
       
  1117  */
       
  1118 
       
  1119 /*!
       
  1120  */
       
  1121 PropertyNode::PropertyNode(InnerNode *parent, const QString& name)
       
  1122     : LeafNode(Property, parent, name),
       
  1123       sto(Trool_Default),
       
  1124       des(Trool_Default),
       
  1125       overrides(0)
       
  1126 {
       
  1127 }
       
  1128 
       
  1129 /*!
       
  1130  */
       
  1131 void PropertyNode::setOverriddenFrom(const PropertyNode *baseProperty)
       
  1132 {
       
  1133     for (int i = 0; i < NumFunctionRoles; ++i) {
       
  1134         if (funcs[i].isEmpty())
       
  1135             funcs[i] = baseProperty->funcs[i];
       
  1136     }
       
  1137     if (sto == Trool_Default)
       
  1138         sto = baseProperty->sto;
       
  1139     if (des == Trool_Default)
       
  1140         des = baseProperty->des;
       
  1141     overrides = baseProperty;
       
  1142 }
       
  1143 
       
  1144 /*!
       
  1145  */
       
  1146 QString PropertyNode::qualifiedDataType() const
       
  1147 {
       
  1148     if (setters().isEmpty() && resetters().isEmpty()) {
       
  1149         if (dt.contains("*") || dt.contains("&")) {
       
  1150             // 'QWidget *' becomes 'QWidget *' const
       
  1151             return dt + " const";
       
  1152         }
       
  1153         else {
       
  1154             /*
       
  1155               'int' becomes 'const int' ('int const' is
       
  1156               correct C++, but looks wrong)
       
  1157             */
       
  1158             return "const " + dt;
       
  1159         }
       
  1160     }
       
  1161     else {
       
  1162         return dt;
       
  1163     }
       
  1164 }
       
  1165 
       
  1166 /*!
       
  1167  */
       
  1168 PropertyNode::Trool PropertyNode::toTrool(bool boolean)
       
  1169 {
       
  1170     return boolean ? Trool_True : Trool_False;
       
  1171 }
       
  1172 
       
  1173 /*!
       
  1174  */
       
  1175 bool PropertyNode::fromTrool(Trool troolean, bool defaultValue)
       
  1176 {
       
  1177     switch (troolean) {
       
  1178     case Trool_True:
       
  1179         return true;
       
  1180     case Trool_False:
       
  1181         return false;
       
  1182     default:
       
  1183         return defaultValue;
       
  1184     }
       
  1185 }
       
  1186 
       
  1187 /*!
       
  1188   \class TargetNode
       
  1189  */
       
  1190 
       
  1191 /*!
       
  1192  */
       
  1193 TargetNode::TargetNode(InnerNode *parent, const QString& name)
       
  1194     : LeafNode(Target, parent, name)
       
  1195 {
       
  1196 }
       
  1197 
       
  1198 /*!
       
  1199   Returns false because this is a TargetNode.
       
  1200  */
       
  1201 bool TargetNode::isInnerNode() const
       
  1202 {
       
  1203     return false;
       
  1204 }
       
  1205 
       
  1206 #ifdef QDOC_QML
       
  1207 bool QmlClassNode::qmlOnly = false;
       
  1208 
       
  1209 /*!
       
  1210   Constructor for the Qml class node.
       
  1211  */
       
  1212 QmlClassNode::QmlClassNode(InnerNode *parent,
       
  1213                            const QString& name,
       
  1214                            const ClassNode* cn)
       
  1215     : FakeNode(parent, name, QmlClass), cnode(cn)
       
  1216 {
       
  1217     setTitle((qmlOnly ? "" : "QML ") + name + " Element Reference");
       
  1218 }
       
  1219 
       
  1220 /*!
       
  1221   The base file name for this kind of node has "qml_"
       
  1222   prepended to it.
       
  1223 
       
  1224   But not yet. Still testing.
       
  1225  */
       
  1226 QString QmlClassNode::fileBase() const
       
  1227 {
       
  1228 #if 0    
       
  1229     if (Node::fileBase() == "item")
       
  1230         qDebug() << "FILEBASE: qmlitem" << name();
       
  1231     return "qml_" + Node::fileBase();
       
  1232 #endif
       
  1233     return Node::fileBase();
       
  1234 }
       
  1235 
       
  1236 /*!
       
  1237   Constructor for the Qml property group node. \a parent is
       
  1238   always a QmlClassNode. 
       
  1239  */
       
  1240 QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent,
       
  1241                                    const QString& name,
       
  1242                                    bool attached)
       
  1243     : FakeNode(parent, name, QmlPropertyGroup),
       
  1244       isdefault(false),
       
  1245       att(attached)
       
  1246 {
       
  1247     // nothing.
       
  1248 }
       
  1249 
       
  1250 /*!
       
  1251   Constructor for the QML property node.
       
  1252  */
       
  1253 QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
       
  1254                                  const QString& name,
       
  1255                                  const QString& type,
       
  1256                                  bool attached)
       
  1257     : LeafNode(QmlProperty, parent, name),
       
  1258       dt(type),
       
  1259       sto(Trool_Default),
       
  1260       des(Trool_Default),
       
  1261       att(attached)
       
  1262 {
       
  1263     // nothing.
       
  1264 }
       
  1265 
       
  1266 /*!
       
  1267   I don't know what this is.
       
  1268  */
       
  1269 QmlPropertyNode::Trool QmlPropertyNode::toTrool(bool boolean)
       
  1270 {
       
  1271     return boolean ? Trool_True : Trool_False;
       
  1272 }
       
  1273 
       
  1274 /*!
       
  1275   I don't know what this is either.
       
  1276  */
       
  1277 bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue)
       
  1278 {
       
  1279     switch (troolean) {
       
  1280     case Trool_True:
       
  1281         return true;
       
  1282     case Trool_False:
       
  1283         return false;
       
  1284     default:
       
  1285         return defaultValue;
       
  1286     }
       
  1287 }
       
  1288 #endif
       
  1289 
       
  1290 QT_END_NAMESPACE