diff options
Diffstat (limited to 'src/tools/qdoc/qdocdatabase.cpp')
-rw-r--r-- | src/tools/qdoc/qdocdatabase.cpp | 1688 |
1 files changed, 0 insertions, 1688 deletions
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp deleted file mode 100644 index bf84fa8335..0000000000 --- a/src/tools/qdoc/qdocdatabase.cpp +++ /dev/null @@ -1,1688 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "generator.h" -#include "atom.h" -#include "tree.h" -#include "qdocdatabase.h" -#include "qdoctagfiles.h" -#include "qdocindexfiles.h" -#include <qdebug.h> - -QT_BEGIN_NAMESPACE - -static NodeMap emptyNodeMap_; -static NodeMultiMap emptyNodeMultiMap_; -bool QDocDatabase::debug = false; - -/*! \class QDocForest - This class manages a collection of trees. Each tree is an - instance of class Tree, which is a private class. - - The forest is populated as each index file is loaded. - Each index file adds a tree to the forest. Each tree - is named with the name of the module it represents. - - The search order is created by searchOrder(), if it has - not already been created. The search order and module - names arrays have parallel structure, i.e. modulNames_[i] - is the module name of the Tree at searchOrder_[i]. - */ - -/*! - Destroys the qdoc forest. This requires deleting - each Tree in the forest. Note that the forest has - been transferred into the search order array, so - what is really being used to destroy the forest - is the search order array. - */ -QDocForest::~QDocForest() -{ - for (int i=0; i<searchOrder_.size(); ++i) - delete searchOrder_.at(i); - forest_.clear(); - searchOrder_.clear(); - indexSearchOrder_.clear(); - moduleNames_.clear(); - primaryTree_ = 0; -} - -/*! - Initializes the forest prior to a traversal and - returns a pointer to the root node of the primary - tree. If the forest is empty, it return 0 - */ -NamespaceNode* QDocForest::firstRoot() -{ - currentIndex_ = 0; - return (!searchOrder().isEmpty() ? searchOrder()[0]->root() : 0); -} - -/*! - Increments the forest's current tree index. If the current - tree index is still within the forest, the function returns - the root node of the current tree. Otherwise it returns 0. - */ -NamespaceNode* QDocForest::nextRoot() -{ - ++currentIndex_; - return (currentIndex_ < searchOrder().size() ? searchOrder()[currentIndex_]->root() : 0); -} - -/*! - Initializes the forest prior to a traversal and - returns a pointer to the primary tree. If the - forest is empty, it returns 0. - */ -Tree* QDocForest::firstTree() -{ - currentIndex_ = 0; - return (!searchOrder().isEmpty() ? searchOrder()[0] : 0); -} - -/*! - Increments the forest's current tree index. If the current - tree index is still within the forest, the function returns - the pointer to the current tree. Otherwise it returns 0. - */ -Tree* QDocForest::nextTree() -{ - ++currentIndex_; - return (currentIndex_ < searchOrder().size() ? searchOrder()[currentIndex_] : 0); -} - -/*! - \fn Tree* QDocForest::primaryTree() - - Returns the pointer to the primary tree. - */ - -/*! - Finds the tree for module \a t in the forest and - sets the primary tree to be that tree. After the - primary tree is set, that tree is removed from the - forest. - - \node It gets re-inserted into the forest after the - search order is built. - */ -void QDocForest::setPrimaryTree(const QString& t) -{ - QString T = t.toLower(); - primaryTree_ = findTree(T); - forest_.remove(T); - if (!primaryTree_) - qDebug() << "ERROR: Could not set primary tree to:" << t; -} - -/*! - If the search order array is empty, create the search order. - If the search order array is not empty, do nothing. - */ -void QDocForest::setSearchOrder(QStringList& t) -{ - if (!searchOrder_.isEmpty()) - return; - - /* Allocate space for the search order. */ - searchOrder_.reserve(forest_.size()+1); - searchOrder_.clear(); - moduleNames_.reserve(forest_.size()+1); - moduleNames_.clear(); - - /* The primary tree is always first in the search order. */ - QString primaryName = primaryTree()->physicalModuleName(); - searchOrder_.append(primaryTree_); - moduleNames_.append(primaryName); - forest_.remove(primaryName); - - QMap<QString, Tree*>::iterator i; - foreach (QString m, t) { - if (primaryName != m) { - i = forest_.find(m); - if (i != forest_.end()) { - searchOrder_.append(i.value()); - moduleNames_.append(m); - forest_.remove(m); - } - } - } - /* - If any trees remain in the forest, just add them - to the search order sequentially, because we don't - know any better at this point. - */ - if (!forest_.isEmpty()) { - i = forest_.begin(); - while (i != forest_.end()) { - searchOrder_.append(i.value()); - moduleNames_.append(i.key()); - ++i; - } - forest_.clear(); - } - - /* - Rebuild the forest after constructing the search order. - It was destroyed during construction of the search order, - but it is needed for module-specific searches. - - Note that this loop also inserts the primary tree into the - forrest. That is a requirement. - */ - for (int i=0; i<searchOrder_.size(); ++i) { - if (!forest_.contains(moduleNames_.at(i))) { - forest_.insert(moduleNames_.at(i), searchOrder_.at(i)); - } - } -#if 0 - qDebug() << " SEARCH ORDER:"; - for (int i=0; i<moduleNames_.size(); ++i) - qDebug() << " " << i+1 << "." << moduleNames_.at(i); - qDebug() << " FOREST:" << forest_.keys(); - qDebug() << "SEARCH ORDER:" << moduleNames_; -#endif -} - -/*! - Returns an ordered array of Tree pointers that represents - the order in which the trees should be searched. The first - Tree in the array is the tree for the current module, i.e. - the module for which qdoc is generating documentation. - - The other Tree pointers in the array represent the index - files that were loaded in preparation for generating this - module's documentation. Each Tree pointer represents one - index file. The index file Tree points have been ordered - heuristically to, hopefully, minimize searching. Thr order - will probably be changed. - - If the search order array is empty, this function calls - indexSearchOrder(). The search order array is empty while - the index files are being loaded, but some searches must - be performed during this time, notably searches for base - class nodes. These searches require a temporary search - order. The temporary order changes throughout the loading - of the index files, but it is always the tree for the - current index file first, followed by the trees for the - index files that have already been loaded. The only - ordering required in this temporary search order is that - the current tree must be searched first. - */ -const QVector<Tree*>& QDocForest::searchOrder() -{ - if (searchOrder_.isEmpty()) - return indexSearchOrder(); - return searchOrder_; -} - -/*! - There are two search orders used by qdoc when searching for - things. The normal search order is returned by searchOrder(), - but this normal search order is not known until all the index - files have been read. At that point, setSearchOrder() is - called. - - During the reading of the index files, the vector holding - the normal search order remains empty. Whenever the search - order is requested, if that vector is empty, this function - is called to return a temporary search order, which includes - all the index files that have been read so far, plus the - one being read now. That one is prepended to the front of - the vector. - */ -const QVector<Tree*>& QDocForest::indexSearchOrder() -{ - if (forest_.size() > indexSearchOrder_.size()) - indexSearchOrder_.prepend(primaryTree_); - return indexSearchOrder_; -} - -/*! - Create a new Tree for the index file for the specified - \a module and add it to the forest. Return the pointer - to its root. - */ -NamespaceNode* QDocForest::newIndexTree(const QString& module) -{ - primaryTree_ = new Tree(module, qdb_); - forest_.insert(module, primaryTree_); - return primaryTree_->root(); -} - -/*! - Create a new Tree for use as the primary tree. This tree - will represent the primary module. \a module is camel case. - */ -void QDocForest::newPrimaryTree(const QString& module) -{ - primaryTree_ = new Tree(module, qdb_); -} - -/*! - Searches through the forest for a node named \a targetPath - and returns a pointer to it if found. The \a relative node - is the starting point. It only makes sense for the primary - tree, which is searched first. After the primary tree has - been searched, \a relative is set to 0 for searching the - other trees, which are all index trees. With relative set - to 0, the starting point for each index tree is the root - of the index tree. - */ -const Node* QDocForest::findNodeForTarget(QStringList& targetPath, - const Node* relative, - Node::Genus genus, - QString& ref) -{ - int flags = SearchBaseClasses | SearchEnumValues; - - QString entity = targetPath.at(0); - targetPath.removeFirst(); - QStringList entityPath = entity.split("::"); - - QString target; - if (!targetPath.isEmpty()) { - target = targetPath.at(0); - targetPath.removeFirst(); - } - - foreach (Tree* t, searchOrder()) { - const Node* n = t->findNodeForTarget(entityPath, target, relative, flags, genus, ref); - if (n) - return n; - relative = 0; - } - return 0; -} - -/*! - Print the list of module names ordered according - to how many successful searches each tree had. - */ -void QDocForest::printLinkCounts(const QString& project) -{ - Location::null.report(QString("%1: Link Counts").arg(project)); - QMultiMap<int, QString> m; - foreach (Tree* t, searchOrder()) { - if (t->linkCount() < 0) - m.insert(t->linkCount(), t->physicalModuleName()); - } - QString depends = "depends +="; - QString module = project.toLower(); - QMultiMap<int, QString>::iterator i = m.begin(); - while (i != m.end()) { - QString line = " " + i.value(); - if (i.value() != module) - depends += " " + i.value(); - int pad = 30 - line.length(); - for (int k=0; k<pad; ++k) - line += " "; - line += "%1"; - Location::null.report(line.arg(-(i.key()))); - ++i; - } - Location::null.report("Optimal depends variable:"); - Location::null.report(depends); -} - -/*! - Print the list of module names ordered according - to how many successful searches each tree had. - */ -QString QDocForest::getLinkCounts(QStringList& strings, QVector<int>& counts) -{ - QMultiMap<int, QString> m; - foreach (Tree* t, searchOrder()) { - if (t->linkCount() < 0) - m.insert(t->linkCount(), t->physicalModuleName()); - } - QString depends = "depends +="; - QString module = Generator::defaultModuleName().toLower(); - QMultiMap<int, QString>::iterator i = m.begin(); - while (i != m.end()) { - if (i.value() != module) { - counts.append(-(i.key())); - strings.append(i.value()); - depends += " " + i.value(); - } - ++i; - } - return depends; -} - -/*! \class QDocDatabase - This class provides exclusive access to the qdoc database, - which consists of a forrest of trees and a lot of maps and - other useful data structures. - */ - -QDocDatabase* QDocDatabase::qdocDB_ = NULL; -NodeMap QDocDatabase::typeNodeMap_; - -/*! - Constructs the singleton qdoc database object. The singleton - constructs the \a forest_ object, which is also a singleton. - \a showInternal_ is normally false. If it is true, qdoc will - write documentation for nodes marked \c internal. - - \a singleExec_ is false when qdoc is being used in the standard - way of running qdoc twices for each module, first with -prepare - and then with -generate. First the -prepare phase is run for - each module, then the -generate phase is run for each module. - - When \a singleExec_ is true, qdoc is run only once. During the - single execution, qdoc processes the qdocconf files for all the - modules sequentially in a loop. Each source file for each module - is read exactly once. - */ -QDocDatabase::QDocDatabase() - : showInternal_(false), singleExec_(false), forest_(this) -{ - // nothing -} - -/*! - Destroys the qdoc database object. This requires destroying - the forest object, which contains an array of tree pointers. - Each tree is deleted. - */ -QDocDatabase::~QDocDatabase() -{ - // nothing. -} - -/*! - Creates the singleton. Allows only one instance of the class - to be created. Returns a pointer to the singleton. -*/ -QDocDatabase* QDocDatabase::qdocDB() -{ - if (!qdocDB_) { - qdocDB_ = new QDocDatabase; - initializeDB(); - } - return qdocDB_; -} - -/*! - Destroys the singleton. - */ -void QDocDatabase::destroyQdocDB() -{ - if (qdocDB_) { - delete qdocDB_; - qdocDB_ = 0; - } -} - -/*! - Initialize data structures in the singleton qdoc database. - - In particular, the type node map is initialized with a lot - type names that don't refer to documented types. For example, - the C++ standard types are included. These might be documented - here at some point, but for now they are not. Other examples - include \c array and \c data, which are just generic names - used as place holders in function signatures that appear in - the documentation. - - Also calls Node::initialize() to initialize the search goal map. - */ -void QDocDatabase::initializeDB() -{ - Node::initialize(); - typeNodeMap_.insert( "accepted", 0); - typeNodeMap_.insert( "actionPerformed", 0); - typeNodeMap_.insert( "activated", 0); - typeNodeMap_.insert( "alias", 0); - typeNodeMap_.insert( "anchors", 0); - typeNodeMap_.insert( "any", 0); - typeNodeMap_.insert( "array", 0); - typeNodeMap_.insert( "autoSearch", 0); - typeNodeMap_.insert( "axis", 0); - typeNodeMap_.insert( "backClicked", 0); - typeNodeMap_.insert( "bool", 0); - typeNodeMap_.insert( "boomTime", 0); - typeNodeMap_.insert( "border", 0); - typeNodeMap_.insert( "buttonClicked", 0); - typeNodeMap_.insert( "callback", 0); - typeNodeMap_.insert( "char", 0); - typeNodeMap_.insert( "clicked", 0); - typeNodeMap_.insert( "close", 0); - typeNodeMap_.insert( "closed", 0); - typeNodeMap_.insert( "color", 0); - typeNodeMap_.insert( "cond", 0); - typeNodeMap_.insert( "data", 0); - typeNodeMap_.insert( "dataReady", 0); - typeNodeMap_.insert( "dateString", 0); - typeNodeMap_.insert( "dateTimeString", 0); - typeNodeMap_.insert( "datetime", 0); - typeNodeMap_.insert( "day", 0); - typeNodeMap_.insert( "deactivated", 0); - typeNodeMap_.insert( "double", 0); - typeNodeMap_.insert( "drag", 0); - typeNodeMap_.insert( "easing", 0); - typeNodeMap_.insert( "enumeration", 0); - typeNodeMap_.insert( "error", 0); - typeNodeMap_.insert( "exposure", 0); - typeNodeMap_.insert( "fatalError", 0); - typeNodeMap_.insert( "fileSelected", 0); - typeNodeMap_.insert( "flags", 0); - typeNodeMap_.insert( "float", 0); - typeNodeMap_.insert( "focus", 0); - typeNodeMap_.insert( "focusZone", 0); - typeNodeMap_.insert( "format", 0); - typeNodeMap_.insert( "framePainted", 0); - typeNodeMap_.insert( "from", 0); - typeNodeMap_.insert( "frontClicked", 0); - typeNodeMap_.insert( "function", 0); - typeNodeMap_.insert( "hasOpened", 0); - typeNodeMap_.insert( "hovered", 0); - typeNodeMap_.insert( "hoveredTitle", 0); - typeNodeMap_.insert( "hoveredUrl", 0); - typeNodeMap_.insert( "imageCapture", 0); - typeNodeMap_.insert( "imageProcessing", 0); - typeNodeMap_.insert( "index", 0); - typeNodeMap_.insert( "initialized", 0); - typeNodeMap_.insert( "int", 0); - typeNodeMap_.insert( "isLoaded", 0); - typeNodeMap_.insert( "item", 0); - typeNodeMap_.insert( "jsdict", 0); - typeNodeMap_.insert( "jsobject", 0); - typeNodeMap_.insert( "key", 0); - typeNodeMap_.insert( "keysequence", 0); - typeNodeMap_.insert( "list", 0); - typeNodeMap_.insert( "listViewClicked", 0); - typeNodeMap_.insert( "loadRequest", 0); - typeNodeMap_.insert( "locale", 0); - typeNodeMap_.insert( "location", 0); - typeNodeMap_.insert( "long", 0); - typeNodeMap_.insert( "message", 0); - typeNodeMap_.insert( "messageReceived", 0); - typeNodeMap_.insert( "mode", 0); - typeNodeMap_.insert( "month", 0); - typeNodeMap_.insert( "name", 0); - typeNodeMap_.insert( "number", 0); - typeNodeMap_.insert( "object", 0); - typeNodeMap_.insert( "offset", 0); - typeNodeMap_.insert( "ok", 0); - typeNodeMap_.insert( "openCamera", 0); - typeNodeMap_.insert( "openImage", 0); - typeNodeMap_.insert( "openVideo", 0); - typeNodeMap_.insert( "padding", 0); - typeNodeMap_.insert( "parent", 0); - typeNodeMap_.insert( "path", 0); - typeNodeMap_.insert( "photoModeSelected", 0); - typeNodeMap_.insert( "position", 0); - typeNodeMap_.insert( "precision", 0); - typeNodeMap_.insert( "presetClicked", 0); - typeNodeMap_.insert( "preview", 0); - typeNodeMap_.insert( "previewSelected", 0); - typeNodeMap_.insert( "progress", 0); - typeNodeMap_.insert( "puzzleLost", 0); - typeNodeMap_.insert( "qmlSignal", 0); - typeNodeMap_.insert( "real", 0); - typeNodeMap_.insert( "rectangle", 0); - typeNodeMap_.insert( "request", 0); - typeNodeMap_.insert( "requestId", 0); - typeNodeMap_.insert( "section", 0); - typeNodeMap_.insert( "selected", 0); - typeNodeMap_.insert( "send", 0); - typeNodeMap_.insert( "settingsClicked", 0); - typeNodeMap_.insert( "shoe", 0); - typeNodeMap_.insert( "short", 0); - typeNodeMap_.insert( "signed", 0); - typeNodeMap_.insert( "sizeChanged", 0); - typeNodeMap_.insert( "size_t", 0); - typeNodeMap_.insert( "sockaddr", 0); - typeNodeMap_.insert( "someOtherSignal", 0); - typeNodeMap_.insert( "sourceSize", 0); - typeNodeMap_.insert( "startButtonClicked", 0); - typeNodeMap_.insert( "state", 0); - typeNodeMap_.insert( "std::initializer_list", 0); - typeNodeMap_.insert( "std::list", 0); - typeNodeMap_.insert( "std::map", 0); - typeNodeMap_.insert( "std::pair", 0); - typeNodeMap_.insert( "std::string", 0); - typeNodeMap_.insert( "std::vector", 0); - typeNodeMap_.insert( "string", 0); - typeNodeMap_.insert( "stringlist", 0); - typeNodeMap_.insert( "swapPlayers", 0); - typeNodeMap_.insert( "symbol", 0); - typeNodeMap_.insert( "t", 0); - typeNodeMap_.insert( "T", 0); - typeNodeMap_.insert( "tagChanged", 0); - typeNodeMap_.insert( "timeString", 0); - typeNodeMap_.insert( "timeout", 0); - typeNodeMap_.insert( "to", 0); - typeNodeMap_.insert( "toggled", 0); - typeNodeMap_.insert( "type", 0); - typeNodeMap_.insert( "unsigned", 0); - typeNodeMap_.insert( "urllist", 0); - typeNodeMap_.insert( "va_list", 0); - typeNodeMap_.insert( "value", 0); - typeNodeMap_.insert( "valueEmitted", 0); - typeNodeMap_.insert( "videoFramePainted", 0); - typeNodeMap_.insert( "videoModeSelected", 0); - typeNodeMap_.insert( "videoRecorder", 0); - typeNodeMap_.insert( "void", 0); - typeNodeMap_.insert( "volatile", 0); - typeNodeMap_.insert( "wchar_t", 0); - typeNodeMap_.insert( "x", 0); - typeNodeMap_.insert( "y", 0); - typeNodeMap_.insert( "zoom", 0); - typeNodeMap_.insert( "zoomTo", 0); -} - -/*! \fn NamespaceNode* QDocDatabase::primaryTreeRoot() - Returns a pointer to the root node of the primary tree. - */ - -/*! - \fn const CNMap& QDocDatabase::groups() - Returns a const reference to the collection of all - group nodes in the primary tree. -*/ - -/*! - \fn const CNMap& QDocDatabase::modules() - Returns a const reference to the collection of all - module nodes in the primary tree. -*/ - -/*! - \fn const CNMap& QDocDatabase::qmlModules() - Returns a const reference to the collection of all - QML module nodes in the primary tree. -*/ - -/*! - \fn const CNMap& QDocDatabase::jsModules() - Returns a const reference to the collection of all - JovaScript module nodes in the primary tree. -*/ - -/*! \fn CollectionNode* QDocDatabase::findGroup(const QString& name) - Find the group node named \a name and return a pointer - to it. If a matching node is not found, add a new group - node named \a name and return a pointer to that one. - - If a new group node is added, its parent is the tree root, - and the new group node is marked \e{not seen}. - */ - -/*! \fn CollectionNode* QDocDatabase::findModule(const QString& name) - Find the module node named \a name and return a pointer - to it. If a matching node is not found, add a new module - node named \a name and return a pointer to that one. - - If a new module node is added, its parent is the tree root, - and the new module node is marked \e{not seen}. - */ - -/*! \fn CollectionNode* QDocDatabase::findQmlModule(const QString& name, bool javaScript) - Find the QML module node named \a name and return a pointer - to it. If a matching node is not found, add a new QML module - node named \a name and return a pointer to that one. - - If \a javaScript is set, the return collection must be a - JavaScript module. - - If a new QML or JavaScript module node is added, its parent - is the tree root, and the new node is marked \e{not seen}. - */ - -/*! \fn CollectionNode* QDocDatabase::addGroup(const QString& name) - Looks up the group named \a name in the primary tree. If - a match is found, a pointer to the node is returned. - Otherwise, a new group node named \a name is created and - inserted into the collection, and the pointer to that node - is returned. - */ - -/*! \fn CollectionNode* QDocDatabase::addModule(const QString& name) - Looks up the module named \a name in the primary tree. If - a match is found, a pointer to the node is returned. - Otherwise, a new module node named \a name is created and - inserted into the collection, and the pointer to that node - is returned. - */ - -/*! \fn CollectionNode* QDocDatabase::addQmlModule(const QString& name) - Looks up the QML module named \a name in the primary tree. - If a match is found, a pointer to the node is returned. - Otherwise, a new QML module node named \a name is created - and inserted into the collection, and the pointer to that - node is returned. - */ - -/*! \fn CollectionNode* QDocDatabase::addJsModule(const QString& name) - Looks up the JavaScript module named \a name in the primary - tree. If a match is found, a pointer to the node is returned. - Otherwise, a new JavaScript module node named \a name is - created and inserted into the collection, and the pointer to - that node is returned. - */ - -/*! \fn CollectionNode* QDocDatabase::addToGroup(const QString& name, Node* node) - Looks up the group node named \a name in the collection - of all group nodes. If a match is not found, a new group - node named \a name is created and inserted into the collection. - Then append \a node to the group's members list, and append the - group node to the member list of the \a node. The parent of the - \a node is not changed by this function. Returns a pointer to - the group node. - */ - -/*! \fn CollectionNode* QDocDatabase::addToModule(const QString& name, Node* node) - Looks up the module node named \a name in the collection - of all module nodes. If a match is not found, a new module - node named \a name is created and inserted into the collection. - Then append \a node to the module's members list. The parent of - \a node is not changed by this function. Returns the module node. - */ - -/*! \fn Collection* QDocDatabase::addToQmlModule(const QString& name, Node* node) - Looks up the QML module named \a name. If it isn't there, - create it. Then append \a node to the QML module's member - list. The parent of \a node is not changed by this function. - */ - -/*! \fn Collection* QDocDatabase::addToJsModule(const QString& name, Node* node) - Looks up the JavaScript module named \a name. If it isn't there, - create it. Then append \a node to the JavaScript module's member - list. The parent of \a node is not changed by this function. - */ - -/*! - Looks up the QML type node identified by the qualified Qml - type \a name and returns a pointer to the QML type node. - */ -QmlTypeNode* QDocDatabase::findQmlType(const QString& name) -{ - QmlTypeNode* qcn = forest_.lookupQmlType(name); - if (qcn) - return qcn; - return 0; -} - -/*! - Looks up the QML type node identified by the Qml module id - \a qmid and QML type \a name and returns a pointer to the - QML type node. The key is \a qmid + "::" + \a name. - - If the QML module id is empty, it looks up the QML type by - \a name only. - */ -QmlTypeNode* QDocDatabase::findQmlType(const QString& qmid, const QString& name) -{ - if (!qmid.isEmpty()) { - QString t = qmid + "::" + name; - QmlTypeNode* qcn = forest_.lookupQmlType(t); - if (qcn) - return qcn; - } - - QStringList path(name); - Node* n = forest_.findNodeByNameAndType(path, Node::QmlType); - if (n && (n->isQmlType() || n->isJsType())) - return static_cast<QmlTypeNode*>(n); - return 0; -} - -/*! - Looks up the QML type node identified by the Qml module id - constructed from the strings in the \a import record and the - QML type \a name and returns a pointer to the QML type node. - If a QML type node is not found, 0 is returned. - */ -QmlTypeNode* QDocDatabase::findQmlType(const ImportRec& import, const QString& name) -{ - if (!import.isEmpty()) { - QStringList dotSplit; - dotSplit = name.split(QLatin1Char('.')); - QString qmName; - if (import.importUri_.isEmpty()) - qmName = import.name_; - else - qmName = import.importUri_; - for (int i=0; i<dotSplit.size(); ++i) { - QString qualifiedName = qmName + "::" + dotSplit[i]; - QmlTypeNode* qcn = forest_.lookupQmlType(qualifiedName); - if (qcn) - return qcn; - } - } - return 0; -} - -/*! - This function calls a set of functions for each tree in the - forest that has not already been analyzed. In this way, when - running qdoc in \e singleExec mode, each tree is analyzed in - turn, and its classes and types are added to the appropriate - node maps. - */ -void QDocDatabase::processForest() -{ - Tree* t = forest_.firstTree(); - while (t) { - findAllClasses(t->root()); - findAllFunctions(t->root()); - findAllObsoleteThings(t->root()); - findAllLegaleseTexts(t->root()); - findAllSince(t->root()); - t->setTreeHasBeenAnalyzed(); - t = forest_.nextTree(); - } - resolveNamespaces(); -} - -/*! - This function calls \a func for each tree in the forest, - but only if Tree::treeHasBeenAnalyzed() returns false for - the tree. In this way, when running qdoc in \e singleExec - mode, each tree is analyzed in turn, and its classes and - types are added to the appropriate node maps. - */ -void QDocDatabase::processForest(void (QDocDatabase::*func) (InnerNode*)) -{ - Tree* t = forest_.firstTree(); - while (t) { - if (!t->treeHasBeenAnalyzed()) { - (this->*(func))(t->root()); - } - t = forest_.nextTree(); - } -} - -/*! - Constructs the collection of legalese texts, if it has not - already been constructed and returns a reference to it. - */ -TextToNodeMap& QDocDatabase::getLegaleseTexts() -{ - if (legaleseTexts_.isEmpty()) - processForest(&QDocDatabase::findAllLegaleseTexts); - return legaleseTexts_; -} - -/*! - Construct the data structures for obsolete things, if they - have not already been constructed. Returns a reference to - the map of C++ classes with obsolete members. - */ -NodeMultiMap& QDocDatabase::getClassesWithObsoleteMembers() -{ - if (obsoleteClasses_.isEmpty() && obsoleteQmlTypes_.isEmpty()) - processForest(&QDocDatabase::findAllObsoleteThings); - return classesWithObsoleteMembers_; -} - -/*! - Construct the data structures for obsolete things, if they - have not already been constructed. Returns a reference to - the map of obsolete QML types. - */ -NodeMultiMap& QDocDatabase::getObsoleteQmlTypes() -{ - if (obsoleteClasses_.isEmpty() && obsoleteQmlTypes_.isEmpty()) - processForest(&QDocDatabase::findAllObsoleteThings); - return obsoleteQmlTypes_; -} - -/*! - Construct the data structures for obsolete things, if they - have not already been constructed. Returns a reference to - the map of QML types with obsolete members. - */ -NodeMultiMap& QDocDatabase::getQmlTypesWithObsoleteMembers() -{ - if (obsoleteClasses_.isEmpty() && obsoleteQmlTypes_.isEmpty()) - processForest(&QDocDatabase::findAllObsoleteThings); - return qmlTypesWithObsoleteMembers_; -} - -/*! \fn NodeMultiMap& QDocDatabase::getNamespaces() - Returns a reference to the map of all namespace nodes. - This function must not be called in the -prepare phase. - */ - -/*! - Construct the data structures for QML basic types, if they - have not already been constructed. Returns a reference to - the map of QML basic types. - */ -NodeMultiMap& QDocDatabase::getQmlBasicTypes() -{ - if (cppClasses_.isEmpty() && qmlBasicTypes_.isEmpty()) - processForest(&QDocDatabase::findAllClasses); - return qmlBasicTypes_; -} - -/*! - Construct the data structures for obsolete things, if they - have not already been constructed. Returns a reference to - the multimap of QML types. - */ -NodeMultiMap& QDocDatabase::getQmlTypes() -{ - if (cppClasses_.isEmpty() && qmlTypes_.isEmpty()) - processForest(&QDocDatabase::findAllClasses); - return qmlTypes_; -} - -/*! - Construct the data structures for obsolete things, if they - have not already been constructed. Returns a reference to - the map of obsolete C++ clases. - */ -NodeMultiMap& QDocDatabase::getObsoleteClasses() -{ - if (obsoleteClasses_.isEmpty() && obsoleteQmlTypes_.isEmpty()) - processForest(&QDocDatabase::findAllObsoleteThings); - return obsoleteClasses_; -} - -/*! - Construct the C++ class data structures, if they have not - already been constructed. Returns a reference to the map - of all C++ classes. - */ -NodeMultiMap& QDocDatabase::getCppClasses() -{ - if (cppClasses_.isEmpty() && qmlTypes_.isEmpty()) - processForest(&QDocDatabase::findAllClasses); - return cppClasses_; -} - -/*! - Finds all the C++ class nodes and QML type nodes and - sorts them into maps. - */ -void QDocDatabase::findAllClasses(InnerNode* node) -{ - NodeList::const_iterator c = node->childNodes().constBegin(); - while (c != node->childNodes().constEnd()) { - if ((*c)->access() != Node::Private && (!(*c)->isInternal() || showInternal_) && - (*c)->tree()->camelCaseModuleName() != QString("QDoc")) { - if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) { - QString className = (*c)->name(); - if ((*c)->parent() && - (*c)->parent()->type() == Node::Namespace && - !(*c)->parent()->name().isEmpty()) - className = (*c)->parent()->name()+"::"+className; - - cppClasses_.insert(className, *c); - } - else if (((*c)->isQmlType() || (*c)->isQmlBasicType() || - (*c)->isJsType() || (*c)->isJsBasicType()) && !(*c)->doc().isEmpty()) { - QString qmlTypeName = (*c)->name(); - if (qmlTypeName.startsWith(QLatin1String("QML:"))) - qmlTypes_.insert(qmlTypeName.mid(4),*c); - else - qmlTypes_.insert(qmlTypeName,*c); - - //also add to the QML basic type map - if ((*c)->isQmlBasicType() || (*c)->isJsType()) - qmlBasicTypes_.insert(qmlTypeName,*c); - } - else if ((*c)->isInnerNode()) { - findAllClasses(static_cast<InnerNode*>(*c)); - } - } - ++c; - } -} - -/*! - Construct the function index data structure and return it. - This data structure is used to output the function index page. - */ -NodeMapMap& QDocDatabase::getFunctionIndex() -{ - processForest(&QDocDatabase::findAllFunctions); - return funcIndex_; -} - -/*! - Finds all the function nodes - */ -void QDocDatabase::findAllFunctions(InnerNode* node) -{ - NodeList::ConstIterator c = node->childNodes().constBegin(); - while (c != node->childNodes().constEnd()) { - if ((*c)->access() != Node::Private) { - if ((*c)->isInnerNode()) { - findAllFunctions(static_cast<InnerNode*>(*c)); - } - else if ((*c)->type() == Node::Function) { - const FunctionNode* func = static_cast<const FunctionNode*>(*c); - if ((func->status() > Node::Obsolete) && - !func->isInternal() && - (func->metaness() != FunctionNode::Ctor) && - (func->metaness() != FunctionNode::Dtor)) { - funcIndex_[(*c)->name()].insert((*c)->parent()->fullDocumentName(), *c); - } - } - } - ++c; - } -} - -/*! - Finds all the nodes containing legalese text and puts them - in a map. - */ -void QDocDatabase::findAllLegaleseTexts(InnerNode* node) -{ - NodeList::ConstIterator c = node->childNodes().constBegin(); - while (c != node->childNodes().constEnd()) { - if ((*c)->access() != Node::Private) { - if (!(*c)->doc().legaleseText().isEmpty()) - legaleseTexts_.insertMulti((*c)->doc().legaleseText(), *c); - if ((*c)->isInnerNode()) - findAllLegaleseTexts(static_cast<InnerNode *>(*c)); - } - ++c; - } -} - -/*! - Finds all the namespace nodes and puts them in an index. - */ -void QDocDatabase::findAllNamespaces(InnerNode* node) -{ - NodeList::ConstIterator c = node->childNodes().constBegin(); - while (c != node->childNodes().constEnd()) { - if ((*c)->access() != Node::Private || (*c)->isNamespace()) { - if ((*c)->isInnerNode()) { - findAllNamespaces(static_cast<InnerNode *>(*c)); - if ((*c)->isNamespace()) { - // Ensure that the namespace's name is not empty (the root - // namespace has no name). - if (!(*c)->name().isEmpty()) { - nmm_.insert((*c)->name(), *c); - } - } - } - } - ++c; - } -} - -/*! - Finds all nodes with status = Obsolete and sorts them into - maps. They can be C++ classes, QML types, or they can be - functions, enum types, typedefs, methods, etc. - */ -void QDocDatabase::findAllObsoleteThings(InnerNode* node) -{ - NodeList::const_iterator c = node->childNodes().constBegin(); - while (c != node->childNodes().constEnd()) { - if ((*c)->access() != Node::Private) { - QString name = (*c)->name(); - if ((*c)->status() == Node::Obsolete) { - if ((*c)->type() == Node::Class) { - if ((*c)->parent() && (*c)->parent()->type() == Node::Namespace && - !(*c)->parent()->name().isEmpty()) - name = (*c)->parent()->name() + "::" + name; - obsoleteClasses_.insert(name, *c); - } - else if ((*c)->isQmlType() || (*c)->isJsType()) { - if (name.startsWith(QLatin1String("QML:"))) - name = name.mid(4); - name = (*c)->logicalModuleName() + "::" + name; - obsoleteQmlTypes_.insert(name,*c); - } - } - else if ((*c)->type() == Node::Class) { - InnerNode* n = static_cast<InnerNode*>(*c); - bool inserted = false; - NodeList::const_iterator p = n->childNodes().constBegin(); - while (p != n->childNodes().constEnd()) { - if ((*p)->access() != Node::Private) { - switch ((*p)->type()) { - case Node::Enum: - case Node::Typedef: - case Node::Function: - case Node::Property: - case Node::Variable: - if ((*p)->status() == Node::Obsolete) { - if ((*c)->parent() && (*c)->parent()->type() == Node::Namespace && - !(*c)->parent()->name().isEmpty()) - name = (*c)->parent()->name() + "::" + name; - classesWithObsoleteMembers_.insert(name, *c); - inserted = true; - } - break; - default: - break; - } - } - if (inserted) - break; - ++p; - } - } - else if ((*c)->isQmlType() || (*c)->isJsType()) { - InnerNode* n = static_cast<InnerNode*>(*c); - bool inserted = false; - NodeList::const_iterator p = n->childNodes().constBegin(); - while (p != n->childNodes().constEnd()) { - if ((*p)->access() != Node::Private) { - switch ((*c)->type()) { - case Node::QmlProperty: - case Node::QmlSignal: - case Node::QmlSignalHandler: - case Node::QmlMethod: - if ((*c)->parent()) { - Node* parent = (*c)->parent(); - if ((parent->isQmlPropertyGroup() || - parent->isJsPropertyGroup()) && parent->parent()) - parent = parent->parent(); - if (parent && (parent->isQmlType() || parent->isJsType()) && - !parent->name().isEmpty()) - name = parent->name() + "::" + name; - } - qmlTypesWithObsoleteMembers_.insert(name,*c); - inserted = true; - break; - default: - break; - } - } - if (inserted) - break; - ++p; - } - } - else if ((*c)->isInnerNode()) { - findAllObsoleteThings(static_cast<InnerNode*>(*c)); - } - } - ++c; - } -} - -/*! - Finds all the nodes where a \e{since} command appeared in the - qdoc comment and sorts them into maps according to the kind of - node. - - This function is used for generating the "New Classes... in x.y" - section on the \e{What's New in Qt x.y} page. - */ -void QDocDatabase::findAllSince(InnerNode* node) -{ - NodeList::const_iterator child = node->childNodes().constBegin(); - while (child != node->childNodes().constEnd()) { - QString sinceString = (*child)->since(); - // Insert a new entry into each map for each new since string found. - if (((*child)->access() != Node::Private) && !sinceString.isEmpty()) { - NodeMultiMapMap::iterator nsmap = newSinceMaps_.find(sinceString); - if (nsmap == newSinceMaps_.end()) - nsmap = newSinceMaps_.insert(sinceString,NodeMultiMap()); - - NodeMapMap::iterator ncmap = newClassMaps_.find(sinceString); - if (ncmap == newClassMaps_.end()) - ncmap = newClassMaps_.insert(sinceString,NodeMap()); - - NodeMapMap::iterator nqcmap = newQmlTypeMaps_.find(sinceString); - if (nqcmap == newQmlTypeMaps_.end()) - nqcmap = newQmlTypeMaps_.insert(sinceString,NodeMap()); - - if ((*child)->type() == Node::Function) { - // Insert functions into the general since map. - FunctionNode *func = static_cast<FunctionNode *>(*child); - if ((func->status() > Node::Obsolete) && - (func->metaness() != FunctionNode::Ctor) && - (func->metaness() != FunctionNode::Dtor)) { - nsmap.value().insert(func->name(),(*child)); - } - } - else { - if ((*child)->type() == Node::Class) { - // Insert classes into the since and class maps. - QString className = (*child)->name(); - if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) { - className = (*child)->parent()->name()+"::"+className; - } - nsmap.value().insert(className,(*child)); - ncmap.value().insert(className,(*child)); - } - else if ((*child)->isQmlType() || (*child)->isJsType()) { - // Insert QML elements into the since and element maps. - QString className = (*child)->name(); - if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) { - className = (*child)->parent()->name()+"::"+className; - } - nsmap.value().insert(className,(*child)); - nqcmap.value().insert(className,(*child)); - } - else if ((*child)->isQmlProperty() || (*child)->isJsProperty()) { - // Insert QML properties into the since map. - QString propertyName = (*child)->name(); - nsmap.value().insert(propertyName,(*child)); - } - else { - // Insert external documents into the general since map. - QString name = (*child)->name(); - if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) { - name = (*child)->parent()->name()+"::"+name; - } - nsmap.value().insert(name,(*child)); - } - } - } - // Recursively find child nodes with since commands. - if ((*child)->isInnerNode()) - findAllSince(static_cast<InnerNode *>(*child)); - - ++child; - } -} - -/*! - Find the \a key in the map of new class maps, and return a - reference to the value, which is a NodeMap. If \a key is not - found, return a reference to an empty NodeMap. - */ -const NodeMap& QDocDatabase::getClassMap(const QString& key) -{ - if (newSinceMaps_.isEmpty() && newClassMaps_.isEmpty() && newQmlTypeMaps_.isEmpty()) - processForest(&QDocDatabase::findAllSince); - NodeMapMap::const_iterator i = newClassMaps_.constFind(key); - if (i != newClassMaps_.constEnd()) - return i.value(); - return emptyNodeMap_; -} - -/*! - Find the \a key in the map of new QML type maps, and return a - reference to the value, which is a NodeMap. If the \a key is not - found, return a reference to an empty NodeMap. - */ -const NodeMap& QDocDatabase::getQmlTypeMap(const QString& key) -{ - if (newSinceMaps_.isEmpty() && newClassMaps_.isEmpty() && newQmlTypeMaps_.isEmpty()) - processForest(&QDocDatabase::findAllSince); - NodeMapMap::const_iterator i = newQmlTypeMaps_.constFind(key); - if (i != newQmlTypeMaps_.constEnd()) - return i.value(); - return emptyNodeMap_; -} - -/*! - Find the \a key in the map of new \e {since} maps, and return - a reference to the value, which is a NodeMultiMap. If \a key - is not found, return a reference to an empty NodeMultiMap. - */ -const NodeMap& QDocDatabase::getSinceMap(const QString& key) -{ - if (newSinceMaps_.isEmpty() && newClassMaps_.isEmpty() && newQmlTypeMaps_.isEmpty()) - processForest(&QDocDatabase::findAllSince); - NodeMultiMapMap::const_iterator i = newSinceMaps_.constFind(key); - if (i != newSinceMaps_.constEnd()) - return i.value(); - return emptyNodeMultiMap_; -} - -/*! - Performs several housekeeping algorithms that create - certain data structures and resolve lots of links, prior - to generating documentation. - */ -void QDocDatabase::resolveIssues() { - resolveQmlInheritance(primaryTreeRoot()); - primaryTree()->resolveTargets(primaryTreeRoot()); - primaryTree()->resolveCppToQmlLinks(); -} - -void QDocDatabase::resolveStuff() -{ - primaryTree()->resolveInheritance(); - resolveQmlInheritance(primaryTreeRoot()); - //primaryTree()->resolveTargets(primaryTreeRoot()); - primaryTree()->resolveCppToQmlLinks(); - primaryTree()->resolveUsingClauses(); - resolveNamespaces(); -} - -/*! - */ -void QDocDatabase::resolveNamespaces() -{ - if (!namespaceIndex_.isEmpty()) - return; - Tree* t = forest_.firstTree(); - while (t) { - findAllNamespaces(t->root()); - t = forest_.nextTree(); - } - QList<QString> keys = nmm_.uniqueKeys(); - foreach (QString s, keys) { - NamespaceNode* ns = 0; - QList<Node*> nodes = nmm_.values(s); - int count = nmm_.remove(s); - if (count > 1) { - foreach (Node* n, nodes) { - if (n->isNamespace() && n->wasSeen()) { - ns = static_cast<NamespaceNode*>(n); - break; - } - } - } - else if (count == 1) - ns = static_cast<NamespaceNode*>(nodes.at(0)); - if (ns && ns->wasSeen()) { - if (count >1) { - foreach (Node* n, nodes) { - if (n->isNamespace()) { - NamespaceNode* NS = static_cast<NamespaceNode*>(n); - if ((NS != ns) && !NS->childNodes().isEmpty()) { - const NodeList& children = NS->childNodes(); - int i = children.size() - 1; - while (i >= 0) { - Node* child = children.at(i--); - if (!child) - continue; - if (!child->isClass() - && !child->isQmlType() - && !child->isNamespace()) { - NS->removeChild(child); - ns->addChild(child); - } - else { - NS->setStatus(Node::Intermediate); - NS->setAccess(Node::Public); - ns->addOrphan(child); - } - } - } - } - } - } - namespaceIndex_.insert(ns->name(), ns); - } - } -} - - -/*! - This function is called for autolinking to a \a type, - which could be a function return type or a parameter - type. The tree node that represents the \a type is - returned. All the trees are searched until a match is - found. When searching the primary tree, the search - begins at \a relative and proceeds up the parent chain. - When searching the index trees, the search begins at the - root. - */ -const Node* QDocDatabase::findTypeNode(const QString& type, const Node* relative) -{ - QStringList path = type.split("::"); - if ((path.size() == 1) && (path.at(0)[0].isLower() || path.at(0) == QString("T"))) { - NodeMap::iterator i = typeNodeMap_.find(path.at(0)); - if (i != typeNodeMap_.end()) - return i.value(); - } - return forest_.findTypeNode(path, relative); -} - -/*! - Finds the node that will generate the documentation that - contains the \a target and returns a pointer to it. - - Can this be improved by using the target map in Tree? - */ -const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* relative) -{ - const Node* node = 0; - if (target.isEmpty()) - node = relative; - else if (target.endsWith(".html")) - node = findNodeByNameAndType(QStringList(target), Node::Document); - else { - QStringList path = target.split("::"); - int flags = SearchBaseClasses | SearchEnumValues; // | NonFunction; - foreach (Tree* t, searchOrder()) { - const Node* n = t->findNode(path, relative, flags, Node::DontCare); - if (n) - return n; - relative = 0; - } - node = findDocumentNodeByTitle(target); - } - return node; -} - -/*! - For each QML Type node in the tree beginning at \a root, - if it has a QML base type name but its QML base type node - pointer is 0, use the QML base type name to look up the - base type node. If the node is found in the tree, set the - node's QML base type node pointer. - */ -void QDocDatabase::resolveQmlInheritance(InnerNode* root) -{ - NodeMap previousSearches; - // Do we need recursion? - foreach (Node* child, root->childNodes()) { - if (child->isQmlType() || child->isJsType()) { - QmlTypeNode* qcn = static_cast<QmlTypeNode*>(child); - if (qcn->qmlBaseNodeNotSet() && !qcn->qmlBaseName().isEmpty()) { - QmlTypeNode* bqcn = static_cast<QmlTypeNode*>(previousSearches.value(qcn->qmlBaseName())); - if (bqcn) - qcn->setQmlBaseNode(bqcn); - else { - if (!qcn->importList().isEmpty()) { - const ImportList& imports = qcn->importList(); - for (int i=0; i<imports.size(); ++i) { - bqcn = findQmlType(imports[i], qcn->qmlBaseName()); - if (bqcn) - break; - } - } - if (bqcn == 0) { - bqcn = findQmlType(QString(), qcn->qmlBaseName()); - } - if (bqcn) { - qcn->setQmlBaseNode(bqcn); - previousSearches.insert(qcn->qmlBaseName(), bqcn); - } -#if 0 - else { - qDebug() << "Temporary error message (ignore): UNABLE to resolve QML base type:" - << qcn->qmlBaseName() << "for QML type:" << qcn->name(); - } -#endif - } - } - } - } -} - -/*! - Generates a tag file and writes it to \a name. - */ -void QDocDatabase::generateTagFile(const QString& name, Generator* g) -{ - if (!name.isEmpty()) { - QDocTagFiles::qdocTagFiles()->generateTagFile(name, g); - QDocTagFiles::destroyQDocTagFiles(); - } -} - -/*! - Reads and parses the qdoc index files listed in \a t. - */ -void QDocDatabase::readIndexes(const QStringList& t) -{ - QStringList indexFiles; - foreach (const QString& f, t) { - QString fn = f.mid(f.lastIndexOf(QChar('/'))+1); - if (!isLoaded(fn)) - indexFiles << f; - else - qDebug() << "This index file is already in memory:" << f; - } - QDocIndexFiles::qdocIndexFiles()->readIndexes(indexFiles); - QDocIndexFiles::destroyQDocIndexFiles(); -} - -/*! - Generates a qdoc index file and write it to \a fileName. The - index file is generated with the parameters \a url, \a title, - \a g, and \a generateInternalNodes. - */ -void QDocDatabase::generateIndex(const QString& fileName, - const QString& url, - const QString& title, - Generator* g, - bool generateInternalNodes) -{ - QString t = fileName.mid(fileName.lastIndexOf(QChar('/'))+1); - primaryTree()->setIndexFileName(t); - QDocIndexFiles::qdocIndexFiles()->generateIndex(fileName, url, title, g, generateInternalNodes); - QDocIndexFiles::destroyQDocIndexFiles(); -} - -/*! - If there are open namespaces, search for the function node - having the same function name as the \a clone node in each - open namespace. The \a parentPath is a portion of the path - name provided with the function name at the point of - reference. \a parentPath is usually a class name. Return - the pointer to the function node if one is found in an - open namespace. Otherwise return 0. - - This open namespace concept is of dubious value and might - be removed. - */ -FunctionNode* QDocDatabase::findNodeInOpenNamespace(const QStringList& parentPath, - const FunctionNode* clone) -{ - FunctionNode* fn = 0; - if (!openNamespaces_.isEmpty()) { - foreach (const QString& t, openNamespaces_) { - QStringList path = t.split("::") + parentPath; - fn = findFunctionNode(path, clone); - if (fn) - break; - } - } - return fn; -} - -/*! - Find a node of the specified \a type that is reached with - the specified \a path qualified with the name of one of the - open namespaces (might not be any open ones). If the node - is found in an open namespace, prefix \a path with the name - of the open namespace and "::" and return a pointer to the - node. Othewrwise return 0. - - This function only searches in the current primary tree. - */ -Node* QDocDatabase::findNodeInOpenNamespace(QStringList& path, Node::Type type) -{ - if (path.isEmpty()) - return 0; - Node* n = 0; - if (!openNamespaces_.isEmpty()) { - foreach (const QString& t, openNamespaces_) { - QStringList p; - if (t != path[0]) - p = t.split("::") + path; - else - p = path; - n = primaryTree()->findNodeByNameAndType(p, type); - if (n) { - path = p; - break; - } - } - } - return n; -} - -/*! - Finds all the collection nodes of the specified \a genus - into the collection node map \a cnm. Nodes that match the - \a relative node are not included. - */ -void QDocDatabase::mergeCollections(Node::Genus genus, CNMap& cnm, const Node* relative) -{ - cnm.clear(); - CNMultiMap cnmm; - foreach (Tree* t, searchOrder()) { - CNMap* m = t->getCollectionMap(genus); - if (m && !m->isEmpty()) { - CNMap::const_iterator i = m->cbegin(); - while (i != m->cend()) { - if (!i.value()->isInternal()) - cnmm.insert(i.key(), i.value()); - ++i; - } - } - } - if (cnmm.isEmpty()) - return; - QRegExp singleDigit("\\b([0-9])\\b"); - QStringList keys = cnmm.uniqueKeys(); - foreach (const QString &key, keys) { - QList<CollectionNode*> values = cnmm.values(key); - CollectionNode* n = 0; - foreach (CollectionNode* v, values) { - if (v && v->wasSeen() && (v != relative)) { - n = v; - break; - } - } - if (n) { - if (values.size() > 1) { - foreach (CollectionNode* v, values) { - if (v != n) { - foreach (Node* t, v->members()) - n->addMember(t); - } - } - } - if (!n->members().isEmpty()) { - QString sortKey = n->fullTitle().toLower(); - if (sortKey.startsWith("the ")) - sortKey.remove(0, 4); - sortKey.replace(singleDigit, "0\\1"); - cnm.insert(sortKey, n); - } - } - } -} - -/*! - Finds all the collection nodes with the same name - and genus as \a c and merges their members into the - members list of \a c. - */ -void QDocDatabase::mergeCollections(CollectionNode* c) -{ - foreach (Tree* t, searchOrder()) { - CollectionNode* cn = t->getCollection(c->name(), c->genus()); - if (cn && cn != c) { - foreach (Node* n, cn->members()) - c->addMember(n); - } - } -} - -/*! - Searches for the node that matches the path in \a atom. The - \a relative node is used if the first leg of the path is - empty, i.e. if the path begins with a hashtag. The function - also sets \a ref if there remains an unused leg in the path - after the node is found. The node is returned as well as the - \a ref. If the returned node pointer is null, \a ref is not - valid. - */ -const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, QString& ref) -{ - const Node* node = 0; - - Atom* atom = const_cast<Atom*>(a); - QStringList targetPath = atom->string().split("#"); - QString first = targetPath.first().trimmed(); - - Tree* domain = 0; - Node::Genus genus = Node::DontCare; - // Reserved for future use - //Node::Type goal = Node::NoType; - - if (atom->isLinkAtom()) { - domain = atom->domain(); - genus = atom->genus(); - // Reserved for future use - //goal = atom->goal(); - } - - if (first.isEmpty()) - node = relative; // search for a target on the current page. - else if (domain) { - if (first.endsWith(".html")) - node = domain->findNodeByNameAndType(QStringList(first), Node::Document); - else if (first.endsWith("()")) - node = domain->findFunctionNode(first, 0, genus); - else { - int flags = SearchBaseClasses | SearchEnumValues; - QStringList nodePath = first.split("::"); - QString target; - targetPath.removeFirst(); - if (!targetPath.isEmpty()) { - target = targetPath.at(0); - targetPath.removeFirst(); - } - if (relative && relative->tree()->physicalModuleName() != domain->physicalModuleName()) - relative = 0; - node = domain->findNodeForTarget(nodePath, target, relative, flags, genus, ref); - return node; - } - } - else { - if (first.endsWith(".html")) { - node = findNodeByNameAndType(QStringList(first), Node::Document); - // the path may also refer to an example file with .html extension - if (!node && first.contains("/")) - return findNodeForTarget(targetPath, relative, genus, ref); - } - else if (first.endsWith("()")) - node = findFunctionNode(first, relative, genus); - else { - node = findNodeForTarget(targetPath, relative, genus, ref); - return node; - } - } - - if (node && ref.isEmpty()) { - if (!node->url().isEmpty()) - return node; - targetPath.removeFirst(); - if (!targetPath.isEmpty()) { - ref = node->root()->tree()->getRef(targetPath.first(), node); - if (ref.isEmpty()) - node = 0; - } - } - return node; -} - -QT_END_NAMESPACE |