tools/qdoc3/node.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    41 
    41 
    42 /*
    42 /*
    43   node.cpp
    43   node.cpp
    44 */
    44 */
    45 
    45 
    46 #include <QtCore>
       
    47 #include "node.h"
    46 #include "node.h"
       
    47 #include <qdebug.h>
    48 
    48 
    49 QT_BEGIN_NAMESPACE
    49 QT_BEGIN_NAMESPACE
    50 
    50 
    51 /*!
    51 /*!
    52   \class Node
    52   \class Node
    83     }
    83     }
    84     d = doc;
    84     d = doc;
    85 }
    85 }
    86 
    86 
    87 /*!
    87 /*!
       
    88   Construct a node with the given \a type and having the
       
    89   given \a parent and \a name. The new node is added to the
       
    90   parent's child list.
    88  */
    91  */
    89 Node::Node(Type type, InnerNode *parent, const QString& name)
    92 Node::Node(Type type, InnerNode *parent, const QString& name)
    90     : typ(type),
    93     : typ(type),
    91       acc(Public),
    94       acc(Public),
       
    95       saf(UnspecifiedSafeness),
       
    96       pageTyp(NoPageType),
    92       sta(Commendable),
    97       sta(Commendable),
    93       saf(UnspecifiedSafeness),
       
    94       par(parent),
    98       par(parent),
    95       rel(0),
    99       rel(0),
    96       nam(name)
   100       nam(name)
    97 {
   101 {
    98     if (par)
   102     if (par)
    99         par->addChild(this);
   103         par->addChild(this);
   100 }
   104 }
   101 
   105 
   102 /*!
   106 /*!
       
   107   Returns the node's URL.
   103  */
   108  */
   104 QString Node::url() const
   109 QString Node::url() const
   105 {
   110 {
   106     return u;
   111     return u;
   107 }
   112 }
   108 
   113 
   109 /*!
   114 /*!
       
   115   Sets the node's URL to \a url
   110  */
   116  */
   111 void Node::setUrl(const QString &url)
   117 void Node::setUrl(const QString &url)
   112 {
   118 {
   113     u = url;
   119     u = url;
   114 }
   120 }
   115 
   121 
   116 /*!
   122 void Node::setPageType(const QString& t)
       
   123 {
       
   124     if ((t == "API") || (t == "api"))
       
   125         pageTyp = ApiPage;
       
   126     else if (t == "article")
       
   127         pageTyp = ArticlePage;
       
   128     else if (t == "example")
       
   129         pageTyp = ExamplePage;
       
   130 }
       
   131 
       
   132 /*!
       
   133   Sets the pointer to the node that this node relates to.
   117  */
   134  */
   118 void Node::setRelates(InnerNode *pseudoParent)
   135 void Node::setRelates(InnerNode *pseudoParent)
   119 {
   136 {
   120     if (rel)
   137     if (rel)
   121             rel->removeRelated(this);
   138             rel->removeRelated(this);
   188     deleteChildren();
   205     deleteChildren();
   189     removeFromRelated();
   206     removeFromRelated();
   190 }
   207 }
   191 
   208 
   192 /*!
   209 /*!
       
   210   Find the node in this node's children that has the
       
   211   given \a name. If this node is a QML class node, be
       
   212   sure to also look in the children of its property
       
   213   group nodes. Return the matching node or 0.
   193  */
   214  */
   194 Node *InnerNode::findNode(const QString& name)
   215 Node *InnerNode::findNode(const QString& name)
   195 {
   216 {
   196     Node *node = childMap.value(name);
   217     Node *node = childMap.value(name);
   197     if (node)
   218     if (node)
   198         return node;
   219         return node;
       
   220     if ((type() == Fake) && (subType() == QmlClass)) {
       
   221         for (int i=0; i<children.size(); ++i) {
       
   222             Node* n = children.at(i);
       
   223             if (n->subType() == QmlPropertyGroup) {
       
   224                 node = static_cast<InnerNode*>(n)->findNode(name);
       
   225                 if (node)
       
   226                     return node;
       
   227             }
       
   228         }
       
   229     }
   199     return primaryFunctionMap.value(name);
   230     return primaryFunctionMap.value(name);
   200 }
   231 }
   201 
   232 
   202 /*!
   233 /*!
       
   234   Same as the other findNode(), but if the node with the
       
   235   specified \a name is not of the specified \a type, return
       
   236   0.
   203  */
   237  */
   204 Node *InnerNode::findNode(const QString& name, Type type)
   238 Node *InnerNode::findNode(const QString& name, Type type)
   205 {
   239 {
   206     if (type == Function) {
   240     if (type == Function) {
   207         return primaryFunctionMap.value(name);
   241         return primaryFunctionMap.value(name);
   379     }
   413     }
   380 }
   414 }
   381 
   415 
   382 /*!
   416 /*!
   383  */
   417  */
   384 void InnerNode::removeFromRelated() 
   418 void InnerNode::removeFromRelated()
   385 {
   419 {
   386     while (!related.isEmpty()) {
   420     while (!related.isEmpty()) {
   387         Node *p = static_cast<Node *>(related.takeFirst());
   421         Node *p = static_cast<Node *>(related.takeFirst());
   388 
   422 
   389         if (p != 0 && p->relates() == this) p->clearRelated();
   423         if (p != 0 && p->relates() == this) p->clearRelated();
   396 {
   430 {
   397     qDeleteAll(children);
   431     qDeleteAll(children);
   398 }
   432 }
   399 
   433 
   400 /*!
   434 /*!
   401   Returns true.
   435   Returns true because this is an inner node.
   402  */
   436  */
   403 bool InnerNode::isInnerNode() const
   437 bool InnerNode::isInnerNode() const
   404 {
   438 {
   405     return true;
   439     return true;
   406 }
   440 }
   420     InnerNode *that = (InnerNode *) this;
   454     InnerNode *that = (InnerNode *) this;
   421     return that->findNode(name, type);
   455     return that->findNode(name, type);
   422 }
   456 }
   423 
   457 
   424 /*!
   458 /*!
   425   Find the function node in this node that has the given \a name. 
   459   Find the function node in this node that has the given \a name.
   426  */
   460  */
   427 const FunctionNode *InnerNode::findFunctionNode(const QString& name) const
   461 const FunctionNode *InnerNode::findFunctionNode(const QString& name) const
   428 {
   462 {
   429     InnerNode *that = (InnerNode *) this;
   463     InnerNode *that = (InnerNode *) this;
   430     return that->findFunctionNode(name);
   464     return that->findFunctionNode(name);
   450     }
   484     }
   451     return 0;
   485     return 0;
   452 }
   486 }
   453 
   487 
   454 /*!
   488 /*!
       
   489   Returnds the sequence number of the function node \a func
       
   490   in the list of overloaded functions for a class, such that
       
   491   all the functions have the same name as the \a func.
   455  */
   492  */
   456 int InnerNode::overloadNumber(const FunctionNode *func) const
   493 int InnerNode::overloadNumber(const FunctionNode *func) const
   457 {
   494 {
   458     Node *node = (Node *) func;
   495     Node *node = (Node *) func;
   459     if (primaryFunctionMap[func->name()] == node) {
   496     if (primaryFunctionMap[func->name()] == node) {
   463         return secondaryFunctionMap[func->name()].indexOf(node) + 2;
   500         return secondaryFunctionMap[func->name()].indexOf(node) + 2;
   464     }
   501     }
   465 }
   502 }
   466 
   503 
   467 /*!
   504 /*!
       
   505   Returns the number of member functions of a class such that
       
   506   the functions are all named \a funcName.
   468  */
   507  */
   469 int InnerNode::numOverloads(const QString& funcName) const
   508 int InnerNode::numOverloads(const QString& funcName) const
   470 {
   509 {
   471     if (primaryFunctionMap.contains(funcName)) {
   510     if (primaryFunctionMap.contains(funcName)) {
   472         return secondaryFunctionMap[funcName].count() + 1;
   511         return secondaryFunctionMap[funcName].count() + 1;
   475         return 0;
   514         return 0;
   476     }
   515     }
   477 }
   516 }
   478 
   517 
   479 /*!
   518 /*!
       
   519   Returns a node list containing all the member functions of
       
   520   some class such that the functions overload the name \a funcName.
   480  */
   521  */
   481 NodeList InnerNode::overloads(const QString &funcName) const
   522 NodeList InnerNode::overloads(const QString &funcName) const
   482 {
   523 {
   483     NodeList result;
   524     NodeList result;
   484     Node *primary = primaryFunctionMap.value(funcName);
   525     Node *primary = primaryFunctionMap.value(funcName);
   488     }
   529     }
   489     return result;
   530     return result;
   490 }
   531 }
   491 
   532 
   492 /*!
   533 /*!
       
   534   Construct an inner node (i.e., not a leaf node) of the
       
   535   given \a type and having the given \a parent and \a name.
   493  */
   536  */
   494 InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name)
   537 InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name)
   495     : Node(type, parent, name)
   538     : Node(type, parent, name)
   496 {
   539 {
       
   540     if (type == Class)
       
   541         setPageType(ApiPage);
   497 }
   542 }
   498 
   543 
   499 /*!
   544 /*!
   500  */
   545  */
   501 void InnerNode::addInclude(const QString& include)
   546 void InnerNode::addInclude(const QString& include)
   545     }
   590     }
   546     return true;
   591     return true;
   547 }
   592 }
   548 
   593 
   549 /*!
   594 /*!
       
   595   Adds the \a child to this node's child list.
   550  */
   596  */
   551 void InnerNode::addChild(Node *child)
   597 void InnerNode::addChild(Node *child)
   552 {
   598 {
   553     children.append(child);
   599     children.append(child);
   554     if ((child->type() == Function) || (child->type() == QmlMethod)) {
   600     if ((child->type() == Function) || (child->type() == QmlMethod)) {
   562 	}
   608 	}
   563     }
   609     }
   564     else {
   610     else {
   565         if (child->type() == Enum)
   611         if (child->type() == Enum)
   566             enumChildren.append(child);
   612             enumChildren.append(child);
   567 	childMap.insert(child->name(), child);
   613         childMap.insert(child->name(), child);
   568     }
   614     }
   569 }
   615 }
   570 
   616 
   571 /*!
   617 /*!
   572  */
   618  */
   674 {
   720 {
   675     return false;
   721     return false;
   676 }
   722 }
   677 
   723 
   678 /*!
   724 /*!
       
   725   Constructs a leaf node named \a name of the specified
       
   726   \a type. The new leaf node becomes a child of \a parent.
   679  */
   727  */
   680 LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name)
   728 LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name)
   681     : Node(type, parent, name)
   729     : Node(type, parent, name)
   682 {
   730 {
   683 }
   731 }
   685 /*!
   733 /*!
   686   \class NamespaceNode
   734   \class NamespaceNode
   687  */
   735  */
   688 
   736 
   689 /*!
   737 /*!
       
   738   Constructs a namespace node.
   690  */
   739  */
   691 NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
   740 NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
   692     : InnerNode(Namespace, parent, name)
   741     : InnerNode(Namespace, parent, name)
   693 {
   742 {
       
   743     setPageType(ApiPage);
   694 }
   744 }
   695 
   745 
   696 /*!
   746 /*!
   697   \class ClassNode
   747   \class ClassNode
   698  */
   748  */
   699 
   749 
   700 /*!
   750 /*!
       
   751   Constructs a class node. A class node will generate an API page.
   701  */
   752  */
   702 ClassNode::ClassNode(InnerNode *parent, const QString& name)
   753 ClassNode::ClassNode(InnerNode *parent, const QString& name)
   703     : InnerNode(Class, parent, name)
   754     : InnerNode(Class, parent, name)
   704 {
   755 {
   705     hidden = false;
   756     hidden = false;
       
   757     setPageType(ApiPage);
   706 }
   758 }
   707 
   759 
   708 /*!
   760 /*!
   709  */
   761  */
   710 void ClassNode::addBaseClass(Access access,
   762 void ClassNode::addBaseClass(Access access,
   757   \class FakeNode
   809   \class FakeNode
   758  */
   810  */
   759 
   811 
   760 /*!
   812 /*!
   761   The type of a FakeNode is Fake, and it has a \a subtype,
   813   The type of a FakeNode is Fake, and it has a \a subtype,
   762   which specifies the type of FakeNode.
   814   which specifies the type of FakeNode. The page type for
       
   815   the page index is set here.
   763  */
   816  */
   764 FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype)
   817 FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype)
   765     : InnerNode(Fake, parent, name), sub(subtype)
   818     : InnerNode(Fake, parent, name), sub(subtype)
   766 {
   819 {
       
   820     switch (subtype) {
       
   821     case Module:
       
   822     case Page:
       
   823     case Group:
       
   824         setPageType(ArticlePage);
       
   825         break;
       
   826     case QmlClass:
       
   827     case QmlBasicType:
       
   828         setPageType(ApiPage);
       
   829         break;
       
   830     case Example:
       
   831         setPageType(ExamplePage);
       
   832         break;
       
   833     default:
       
   834         break;
       
   835     }
   767 }
   836 }
   768 
   837 
   769 /*!
   838 /*!
   770   Returns the fake node's full title, which is usually
   839   Returns the fake node's full title, which is usually
   771   just title(), but for some SubType values is different
   840   just title(), but for some SubType values is different
   902 {
   971 {
   903 }
   972 }
   904 
   973 
   905 /*!
   974 /*!
   906   Assigning Parameter \a p to this Parameter copies the
   975   Assigning Parameter \a p to this Parameter copies the
   907   strings across. 
   976   strings across.
   908  */
   977  */
   909 Parameter& Parameter::operator=(const Parameter& p)
   978 Parameter& Parameter::operator=(const Parameter& p)
   910 {
   979 {
   911     lef = p.lef;
   980     lef = p.lef;
   912     rig = p.rig;
   981     rig = p.rig;
  1107 /*!
  1176 /*!
  1108   Print some debugging stuff.
  1177   Print some debugging stuff.
  1109  */
  1178  */
  1110 void FunctionNode::debug() const
  1179 void FunctionNode::debug() const
  1111 {
  1180 {
  1112     qDebug() << "QML METHOD" << name() << "rt" << rt << "pp" << pp;
  1181     qDebug("QML METHOD %s rt %s pp %s",
       
  1182             qPrintable(name()), qPrintable(rt), qPrintable(pp.join(" ")));
  1113 }
  1183 }
  1114 
  1184 
  1115 /*!
  1185 /*!
  1116   \class PropertyNode
  1186   \class PropertyNode
  1117  */
  1187  */
  1203     return false;
  1273     return false;
  1204 }
  1274 }
  1205 
  1275 
  1206 #ifdef QDOC_QML
  1276 #ifdef QDOC_QML
  1207 bool QmlClassNode::qmlOnly = false;
  1277 bool QmlClassNode::qmlOnly = false;
  1208 
  1278 QMultiMap<QString,Node*> QmlClassNode::inheritedBy;
  1209 /*!
  1279 
  1210   Constructor for the Qml class node.
  1280 /*!
       
  1281   Constructs a Qml class node (i.e. a Fake node with the
       
  1282   subtype QmlClass. The new node has the given \a parent
       
  1283   and \a name and is associated with the C++ class node
       
  1284   specified by \a cn which may be null if the the Qml
       
  1285   class node is not associated with a C++ class node.
  1211  */
  1286  */
  1212 QmlClassNode::QmlClassNode(InnerNode *parent,
  1287 QmlClassNode::QmlClassNode(InnerNode *parent,
  1213                            const QString& name,
  1288                            const QString& name,
  1214                            const ClassNode* cn)
  1289                            const ClassNode* cn)
  1215     : FakeNode(parent, name, QmlClass), cnode(cn)
  1290     : FakeNode(parent, name, QmlClass), cnode(cn)
  1216 {
  1291 {
  1217     setTitle((qmlOnly ? "" : "QML ") + name + " Element Reference");
  1292     setTitle((qmlOnly ? "" : "QML ") + name + " Element");
       
  1293 }
       
  1294 
       
  1295 /*!
       
  1296   I made this so I could print a debug message here.
       
  1297  */
       
  1298 QmlClassNode::~QmlClassNode()
       
  1299 {
       
  1300 #ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
       
  1301     qDebug() << "Deleting QmlClassNode:" << name();
       
  1302 #endif
       
  1303 }
       
  1304 
       
  1305 /*!
       
  1306   Clear the multimap so that subsequent runs don't try to use
       
  1307   nodes from a previous run.
       
  1308  */
       
  1309 void QmlClassNode::clear()
       
  1310 {
       
  1311     inheritedBy.clear();
  1218 }
  1312 }
  1219 
  1313 
  1220 /*!
  1314 /*!
  1221   The base file name for this kind of node has "qml_"
  1315   The base file name for this kind of node has "qml_"
  1222   prepended to it.
  1316   prepended to it.
  1223 
  1317 
  1224   But not yet. Still testing.
  1318   But not yet. Still testing.
  1225  */
  1319  */
  1226 QString QmlClassNode::fileBase() const
  1320 QString QmlClassNode::fileBase() const
  1227 {
  1321 {
  1228 #if 0    
  1322 #if 0
  1229     if (Node::fileBase() == "item")
  1323     if (Node::fileBase() == "item")
  1230         qDebug() << "FILEBASE: qmlitem" << name();
  1324         qDebug() << "FILEBASE: qmlitem" << name();
  1231     return "qml_" + Node::fileBase();
  1325     return "qml_" + Node::fileBase();
  1232 #endif
  1326 #endif
  1233     return Node::fileBase();
  1327     return Node::fileBase();
  1234 }
  1328 }
  1235 
  1329 
  1236 /*!
  1330 /*!
       
  1331   Record the fact that QML class \a base is inherited by
       
  1332   QML class \a sub.
       
  1333  */
       
  1334 void QmlClassNode::addInheritedBy(const QString& base, Node* sub)
       
  1335 {
       
  1336     inheritedBy.insert(base,sub);
       
  1337 #ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
       
  1338     qDebug() << "QmlClassNode::addInheritedBy(): insert" << base << sub->name() << inheritedBy.size();
       
  1339 #endif
       
  1340 }
       
  1341 
       
  1342 /*!
       
  1343   Loads the list \a subs with the nodes of all the subclasses of \a base.
       
  1344  */
       
  1345 void QmlClassNode::subclasses(const QString& base, NodeList& subs)
       
  1346 {
       
  1347     subs.clear();
       
  1348     if (inheritedBy.count(base) > 0) {
       
  1349         subs = inheritedBy.values(base);
       
  1350 #ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
       
  1351         qDebug() << "QmlClassNode::subclasses():" <<  inheritedBy.count(base) << base
       
  1352                  << "subs:" << subs.size() << "total size:" << inheritedBy.size();
       
  1353 #endif
       
  1354     }
       
  1355 }
       
  1356 
       
  1357 /*!
       
  1358   Constructs a Qml basic type node (i.e. a Fake node with
       
  1359   the subtype QmlBasicType. The new node has the given
       
  1360   \a parent and \a name.
       
  1361  */
       
  1362 QmlBasicTypeNode::QmlBasicTypeNode(InnerNode *parent,
       
  1363                                    const QString& name)
       
  1364     : FakeNode(parent, name, QmlBasicType)
       
  1365 {
       
  1366     setTitle(name);
       
  1367 }
       
  1368 
       
  1369 /*!
  1237   Constructor for the Qml property group node. \a parent is
  1370   Constructor for the Qml property group node. \a parent is
  1238   always a QmlClassNode. 
  1371   always a QmlClassNode.
  1239  */
  1372  */
  1240 QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent,
  1373 QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent,
  1241                                    const QString& name,
  1374                                    const QString& name,
  1242                                    bool attached)
  1375                                    bool attached)
  1243     : FakeNode(parent, name, QmlPropertyGroup),
  1376     : FakeNode(parent, name, QmlPropertyGroup),