summaryrefslogtreecommitdiffstats
path: root/src/qdoc/qdocdatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qdoc/qdocdatabase.cpp')
-rw-r--r--src/qdoc/qdocdatabase.cpp674
1 files changed, 217 insertions, 457 deletions
diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp
index 6a19baf55..bed2f0be1 100644
--- a/src/qdoc/qdocdatabase.cpp
+++ b/src/qdoc/qdocdatabase.cpp
@@ -40,18 +40,41 @@ 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.
+/*!
+ \class QDocForest
+
+ A class representing a forest of Tree objects.
+
+ This private class manages a collection of Tree objects (a
+ forest) for the singleton QDocDatabase object. It is only
+ accessed by that singleton QDocDatabase object, which is a
+ friend. Each tree in the forest is an instance of class
+ Tree, which is a mostly private class. Both QDocForest and
+ QDocDatabase are friends of Tree and have full access.
- 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.
+ There are two kinds of trees in the forest, differing not
+ in structure but in use. One Tree is the primary tree. It
+ is the tree representing the module being documented. All
+ the other trees in the forest are called index trees. Each
+ one represents the contents of the index file for one of
+ the modules the current module must be able to link to.
+
+ The instances of subclasses of Node in the primary tree
+ will contain documentation in an instance of Doc. The
+ index trees contain no documentation, and each Node in
+ an index tree is marked as an index node.
+
+ Each tree is named with the name of its module.
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].
+
+ The primary tree is always the first tree in the search
+ order. i.e., when the database is searched, the primary
+ tree is always searched first, unless a specific tree is
+ being searched.
*/
/*!
@@ -312,9 +335,9 @@ const Node* QDocForest::findNodeForTarget(QStringList& targetPath,
const Node* n = t->findNodeForTarget(entityPath, target, relative, flags, genus, ref);
if (n)
return n;
- relative = 0;
+ relative = nullptr;
}
- return 0;
+ return nullptr;
}
/*!
@@ -373,58 +396,27 @@ QString QDocForest::getLinkCounts(QStringList& strings, QVector<int>& counts)
}
/*!
- Finds the node for the qualified function path in \a target
- that also has the parameters in \a params and returns it.
- \a target is the path name to the function, without a return
- type and withpout the parameters.
+ Finds the FunctionNode for the qualified function name
+ in \a path, that also has the specified \a parameters.
+ Returns a pointer to the first matching function.
- \a relative is the node in the primary tree where the search
- begins. It is not used in the other trees, if the node is not
- found in the primary tree. \a genus can be used to force the
- search to find a C++ function or a QML function.
-
- The entire forest is searched, but the first match is accepted.
+ \a relative is a node in the primary tree where the search
+ should begin. It is only used when searching the primary
+ tree. \a genus can be used to force the search to find a
+ C++ function or a QML function.
*/
-const FunctionNode* QDocForest::findFunctionNode(const QString& target,
- const QString& params,
+const FunctionNode *QDocForest::findFunctionNode(const QStringList &path,
+ const Parameters &parameters,
const Node* relative,
Node::Genus genus)
{
foreach (Tree* t, searchOrder()) {
- const Node* n = t->findFunctionNode(target, params, relative, genus);
- if (n)
- return static_cast<const FunctionNode *>(n);
- relative = 0;
+ const FunctionNode *fn = t->findFunctionNode(path, parameters, relative, genus);
+ if (fn)
+ return fn;
+ relative = nullptr;
}
- return 0;
-}
-
-/*!
- Finds the node for the qualified function path in \a target
- and returns it. \a target is a complete function signature
- without the return type.
-
- \a relative is the node in the primary tree where the search
- begins. It is not used in the other trees, if the node is not
- found in the primary tree. \a genus can be used to force the
- search to find a C++ function or a QML function.
-
- The entire forest is searched, but the first match is accepted.
- */
-const Node* QDocForest::findFunctionNode(const QString& target,
- const Node* relative,
- Node::Genus genus)
-{
- QString function, params;
- int length = target.length();
- if (target.endsWith(QChar(')'))) {
- int position = target.lastIndexOf(QChar('('));
- params = target.mid(position+1, length-position-2);
- function = target.left(position);
- }
- else
- function = target;
- return findFunctionNode(function, params, relative, genus);
+ return nullptr;
}
/*! \class QDocDatabase
@@ -435,6 +427,17 @@ const Node* QDocForest::findFunctionNode(const QString& target,
QDocDatabase* QDocDatabase::qdocDB_ = NULL;
NodeMap QDocDatabase::typeNodeMap_;
+NodeMultiMap QDocDatabase::obsoleteClasses_;
+NodeMultiMap QDocDatabase::classesWithObsoleteMembers_;
+NodeMultiMap QDocDatabase::obsoleteQmlTypes_;
+NodeMultiMap QDocDatabase::qmlTypesWithObsoleteMembers_;
+NodeMultiMap QDocDatabase::cppClasses_;
+NodeMultiMap QDocDatabase::qmlBasicTypes_;
+NodeMultiMap QDocDatabase::qmlTypes_;
+NodeMultiMap QDocDatabase::examples_;
+NodeMapMap QDocDatabase::newClassMaps_;
+NodeMapMap QDocDatabase::newQmlTypeMaps_;
+NodeMultiMapMap QDocDatabase::newSinceMaps_;
/*!
Constructs the singleton qdoc database object. The singleton
@@ -895,7 +898,7 @@ void QDocDatabase::processForest(void (QDocDatabase::*func) (Aggregate*))
/*!
Constructs the collection of legalese texts, if it has not
- already been constructed and returns a reference to it.
+ already been constructed, and returns a reference to it.
*/
TextToNodeMap& QDocDatabase::getLegaleseTexts()
{
@@ -1018,98 +1021,14 @@ NodeMultiMap& QDocDatabase::getCppClasses()
}
/*!
- Finds all the C++ class nodes and QML type nodes and
- sorts them into maps.
- */
-void QDocDatabase::findAllClasses(Aggregate* 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)->isClass()) {
- QString className = (*c)->name();
- if ((*c)->parent() &&
- (*c)->parent()->nodeType() == Node::Namespace &&
- !(*c)->parent()->name().isEmpty())
- className = (*c)->parent()->name()+"::"+className;
-
- cppClasses_.insert(className.toLower(), *c);
- }
- else if ((*c)->isQmlType() || (*c)->isQmlBasicType() ||
- (*c)->isJsType() || (*c)->isJsBasicType()) {
- QString qmlTypeName = (*c)->name().toLower();
- if (qmlTypeName.startsWith(QLatin1String("QML:"), Qt::CaseInsensitive))
- qmlTypes_.insert(qmlTypeName.mid(4),*c);
- else
- qmlTypes_.insert(qmlTypeName,*c);
-
- //also add to the QML basic type map
- if ((*c)->isQmlBasicType() || (*c)->isJsBasicType())
- qmlBasicTypes_.insert(qmlTypeName,*c);
- }
- else if ((*c)->isExample()) {
- // use the module index title as key for the example map
- QString title = (*c)->tree()->indexTitle();
- if (!examples_.contains(title, *c))
- examples_.insert(title, *c);
- }
- else if ((*c)->isAggregate()) {
- findAllClasses(static_cast<Aggregate*>(*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(Aggregate* node)
-{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
- if ((*c)->isAggregate()) {
- findAllFunctions(static_cast<Aggregate*>(*c));
- }
- else if ((*c)->nodeType() == Node::Function) {
- const FunctionNode* func = static_cast<const FunctionNode*>(*c);
- if ((func->status() > Node::Obsolete) && !func->isInternal() &&
- !func->isSomeCtor() && !func->isDtor()) {
- funcIndex_[(*c)->name()].insert((*c)->parent()->fullDocumentName(), *c);
- }
- }
- }
- ++c;
- }
-}
-
-/*!
- Finds all the attribution pages and collects them per module
- */
-void QDocDatabase::findAllAttributions(Aggregate* node)
-{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
- if ((*c)->pageType() == Node::AttributionPage)
- attributions_.insertMulti((*c)->tree()->indexTitle(), *c);
- else if ((*c)->isAggregate())
- findAllAttributions(static_cast<Aggregate*>(*c));
- }
- ++c;
- }
+ if (functionIndex_.isEmpty())
+ processForest(&QDocDatabase::findAllFunctions);
+ return functionIndex_;
}
/*!
@@ -1118,9 +1037,9 @@ void QDocDatabase::findAllAttributions(Aggregate* node)
*/
void QDocDatabase::findAllLegaleseTexts(Aggregate* node)
{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
+ NodeList::ConstIterator c = node->constBegin();
+ while (c != node->constEnd()) {
+ if (!(*c)->isPrivate()) {
if (!(*c)->doc().legaleseText().isEmpty())
legaleseTexts_.insertMulti((*c)->doc().legaleseText(), *c);
if ((*c)->isAggregate())
@@ -1131,189 +1050,23 @@ void QDocDatabase::findAllLegaleseTexts(Aggregate* node)
}
/*!
- Finds all the namespace nodes in the tree beginning at
- \a node and puts them in a map to be used later as an
- index.
+ \fn void QDocDatabase::findAllObsoleteThings(Aggregate *node)
- Ensure each namespace node has a name before inserting
- it into the map, because the root namespace node has no
- name, and we are not interested in it.
- */
-void QDocDatabase::findAllNamespaces(Aggregate* node)
-{
- foreach (Node* n, node->childNodes()) {
- if (n->isNamespace() && !n->name().isEmpty())
- nmm_.insert(n->name(), n);
- if (n->isNamespace() || (n->isAggregate() && n->access() != Node::Private))
- findAllNamespaces(static_cast<Aggregate *>(n));
- }
-}
-
-/*!
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(Aggregate* node)
-{
- NodeList::const_iterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if (!(*c)->isPrivate()) {
- QString name = (*c)->name();
- if ((*c)->isObsolete()) {
- if ((*c)->isClass()) {
- Node* parent = (*c)->parent();
- if (parent && parent->isNamespace() && !parent->name().isEmpty())
- name = 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)->isClass()) { //not obsolete
- Aggregate* n = static_cast<Aggregate*>(*c);
- bool inserted = false;
- NodeList::const_iterator p = n->childNodes().constBegin();
- while (p != n->childNodes().constEnd()) {
- if (!(*p)->isPrivate() && (*p)->isObsolete()) {
- switch ((*p)->nodeType()) {
- case Node::Enum:
- case Node::Typedef:
- case Node::Function:
- case Node::Property:
- case Node::Variable: {
- Node* parent = (*c)->parent();
- if (parent && parent->isNamespace() && !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()) {
- Aggregate* n = static_cast<Aggregate*>(*c);
- bool inserted = false;
- NodeList::const_iterator p = n->childNodes().constBegin();
- while (p != n->childNodes().constEnd()) {
- if (!(*p)->isPrivate() && (*p)->isObsolete()) {
- switch ((*p)->nodeType()) {
- case Node::JsProperty:
- case Node::QmlProperty:
- case Node::Function:
- 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)->isAggregate()) {
- findAllObsoleteThings(static_cast<Aggregate*>(*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.
+ \fn void QDocDatabase::findAllSince(Aggregate *node)
+
+ Finds all the nodes in \a node 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(Aggregate* 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)->nodeType() == Node::Function) {
- // Insert functions into the general since map.
- FunctionNode *func = static_cast<FunctionNode *>(*child);
- if ((func->status() > Node::Obsolete) && !func->isSomeCtor() && !func->isDtor()) {
- nsmap.value().insert(func->name(),(*child));
- }
- }
- else {
- if ((*child)->nodeType() == 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)->isAggregate())
- findAllSince(static_cast<Aggregate *>(*child));
-
- ++child;
- }
-}
/*!
Find the \a key in the map of new class maps, and return a
@@ -1361,61 +1114,73 @@ const NodeMap& QDocDatabase::getSinceMap(const QString& key)
}
/*!
- Performs several housekeeping algorithms that create
- certain data structures and resolve lots of links, prior
- to generating documentation.
- */
-void QDocDatabase::resolveIssues() {
- primaryTreeRoot()->normalizeOverloads();
- fixInheritance();
- resolveProperties();
- primaryTreeRoot()->makeUndocumentedChildrenInternal();
- resolveQmlInheritance(primaryTreeRoot());
- primaryTree()->resolveTargets(primaryTreeRoot());
- primaryTree()->resolveCppToQmlLinks();
- if (!Generator::singleExec()) {
- QDocIndexFiles::qdocIndexFiles()->resolveRelates();
- QDocIndexFiles::destroyQDocIndexFiles();
+ Performs several housekeeping tasks prior to generating the
+ documentation. These tasks create required data structures
+ and resolve links.
+ */
+void QDocDatabase::resolveStuff() {
+ if (Generator::dualExec() || Generator::preparing()) {
+ primaryTree()->resolveInheritance(primaryTreeRoot());
+ primaryTreeRoot()->normalizeOverloads();
+ primaryTree()->fixInheritance(primaryTreeRoot());
+ primaryTree()->resolveProperties();
+ primaryTreeRoot()->markUndocumentedChildrenInternal();
+ primaryTreeRoot()->resolveQmlInheritance();
+ primaryTree()->resolveTargets(primaryTreeRoot());
+ primaryTree()->resolveCppToQmlLinks();
+ primaryTree()->resolveUsingClauses();
}
- if (Generator::generating())
+ if (Generator::singleExec() && Generator::generating()) {
+ primaryTree()->resolveInheritance(primaryTreeRoot());
+ primaryTreeRoot()->resolveQmlInheritance();
+ //primaryTree()->resolveTargets(primaryTreeRoot());
+ primaryTree()->resolveCppToQmlLinks();
+ primaryTree()->resolveUsingClauses();
+ }
+ if (Generator::generating()) {
resolveNamespaces();
+ resolveProxies();
+ }
+ if (Generator::dualExec())
+ QDocIndexFiles::destroyQDocIndexFiles();
}
-void QDocDatabase::resolveStuff()
+/*!
+ Returns a reference to the namespace map. Constructs the
+ namespace map if it hasn't been constructed yet.
+ */
+NodeMultiMap &QDocDatabase::getNamespaces()
{
- primaryTree()->resolveInheritance();
- resolveQmlInheritance(primaryTreeRoot());
- //primaryTree()->resolveTargets(primaryTreeRoot());
- primaryTree()->resolveCppToQmlLinks();
- primaryTree()->resolveUsingClauses();
resolveNamespaces();
+ return namespaceIndex_;
}
/*!
- Multiple namespace nodes for a particular namespace can be
- created in multiple places. This function first finds all
- namespace nodes and inserts them into a multimap. Then it
- combines all the namespace nodes with the same name into a
- single node and inserts that combined namespace node into
- a namespace index.
+ Multiple namespace nodes for namespace X can exist in the
+ qdoc database in different trees. This function first finds
+ all namespace nodes in all the trees and inserts them into
+ a multimap. Then it combines all the namespace nodes that
+ have the same name into a single namespace node of that
+ name and inserts that combined namespace node into an index.
*/
void QDocDatabase::resolveNamespaces()
{
if (!namespaceIndex_.isEmpty())
return;
+ NodeMultiMap namespaceMultimap;
Tree* t = forest_.firstTree();
while (t) {
- findAllNamespaces(t->root());
+ t->root()->findAllNamespaces(namespaceMultimap);
t = forest_.nextTree();
}
- QList<QString> keys = nmm_.uniqueKeys();
+ QList<QString> keys = namespaceMultimap.uniqueKeys();
foreach (const QString &s, keys) {
NamespaceNode* ns = 0;
NamespaceNode* somewhere = 0;
- QList<Node*> nodes = nmm_.values(s);
- int count = nmm_.remove(s);
+ NodeList namespaces = namespaceMultimap.values(s);
+ int count = namespaceMultimap.remove(s);
if (count > 0) {
- foreach (Node* n, nodes) {
+ foreach (Node *n, namespaces) {
ns = static_cast<NamespaceNode*>(n);
if (ns->isDocumentedHere())
break;
@@ -1424,49 +1189,122 @@ void QDocDatabase::resolveNamespaces()
ns = 0;
}
if (ns) {
- foreach (Node* n, nodes) {
+ foreach (Node *n, namespaces) {
NamespaceNode* NS = static_cast<NamespaceNode*>(n);
if (NS->wasDocumented() && NS != ns) {
- ns->doc().location().warning(tr("Namespace %1 documented more than once").arg(NS->name()));
+ ns->doc().location().warning(tr("Namespace %1 documented more than once")
+ .arg(NS->name()));
NS->doc().location().warning(tr("...also seen here"));
}
}
} else if (somewhere == 0) {
- foreach (Node* n, nodes) {
+ foreach (Node *n, namespaces) {
NamespaceNode* NS = static_cast<NamespaceNode*>(n);
NS->reportDocumentedChildrenInUndocumentedNamespace();
}
}
if (somewhere) {
- foreach (Node* n, nodes) {
+ foreach (Node *n, namespaces) {
NamespaceNode* NS = static_cast<NamespaceNode*>(n);
if (NS != somewhere)
NS->setDocNode(somewhere);
}
}
}
+ /*
+ If there are multiple namespace nodes with the same
+ name and one of them will be the reference page for
+ the namespace, include all the nodes in the public
+ API of the namespace in the single namespace node
+ that will generate the namespace reference page for
+ the namespace.
+ */
if (ns && count > 1) {
- foreach (Node* n, nodes) {
+ foreach (Node *n, namespaces) {
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 && child->isPublic() && !child->isInternal())
- ns->addOrphan(child);
+ if (NS != ns) {
+ NodeList::ConstIterator c = NS->constBegin();
+ while (c != NS->constEnd()) {
+ Node *N = *c;
+ if (N && N->isPublic() && !N->isInternal())
+ ns->includeChild(N);
+ ++c;
}
}
}
}
if (ns == 0)
- ns = static_cast<NamespaceNode*>(nodes.at(0));
+ ns = static_cast<NamespaceNode*>(namespaces.at(0));
namespaceIndex_.insert(ns->name(), ns);
}
}
/*!
+ Each instance of class Tree that represents an index file
+ must be traversed to find all instances of class ProxyNode.
+ For each ProxyNode found, look up the ProxyNode's name in
+ the primary Tree. If it is found, it means that the proxy
+ node contains elements (normally just functions) that are
+ documented in the module represented by the Tree containing
+ the proxy node but that are related to the node we found in
+ the primary tree.
+ */
+void QDocDatabase::resolveProxies()
+{
+ // The first tree is the primary tree.
+ // Skip the primary tree.
+ Tree *t = forest_.firstTree();
+ t = forest_.nextTree();
+ while (t) {
+ NodeList &proxies = t->proxies();
+ if (!proxies.isEmpty()) {
+ foreach (Node *n, proxies) {
+ ProxyNode *pn = static_cast<ProxyNode*>(n);
+ if (pn->count() > 0) {
+ Aggregate *aggregate = primaryTree()->findAggregate(pn->name());
+ if (aggregate != nullptr)
+ aggregate->appendToRelatedByProxy(pn->childNodes());
+ }
+ }
+ }
+ t = forest_.nextTree();
+ }
+}
+
+
+/*!
+ Finds the function node for the qualified function path in
+ \a target and returns a pointer to it. The \a target is a
+ function signature with or without parameters but without
+ the return type.
+
+ \a relative is the node in the primary tree where the search
+ begins. It is not used in the other trees, if the node is not
+ found in the primary tree. \a genus can be used to force the
+ search to find a C++ function or a QML function.
+
+ The entire forest is searched, but the first match is accepted.
+ */
+const FunctionNode *QDocDatabase::findFunctionNode(const QString &target,
+ const Node *relative,
+ Node::Genus genus)
+{
+ QString signature;
+ QString function = target;
+ int length = target.length();
+ if (function.endsWith("()"))
+ function.chop(2);
+ if (function.endsWith(QChar(')'))) {
+ int position = function.lastIndexOf(QChar('('));
+ signature = function.mid(position + 1, length - position - 2);
+ function = function.left(position);
+ }
+ QStringList path = function.split("::");
+ return forest_.findFunctionNode(path, Parameters(signature), relative, genus);
+}
+
+/*!
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
@@ -1515,58 +1353,6 @@ const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* r
}
/*!
- 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(Aggregate* 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 && (bqcn != qcn)) {
- qcn->setQmlBaseNode(bqcn);
- QmlTypeNode::addInheritedBy(bqcn, qcn);
- }
- 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 && (bqcn != qcn)) {
- if (bqcn->logicalModuleVersion()[0] != imports[i].version_[0])
- bqcn = 0; // Safeguard for QTBUG-53529
- break;
- }
- }
- }
- if (bqcn == 0) {
- bqcn = findQmlType(QString(), qcn->qmlBaseName());
- }
- if (bqcn && (bqcn != qcn)) {
- qcn->setQmlBaseNode(bqcn);
- QmlTypeNode::addInheritedBy(bqcn, qcn);
- 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)
@@ -1595,49 +1381,18 @@ void QDocDatabase::readIndexes(const QStringList& t)
/*!
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)
+ index file is generated with the parameters \a url and \a title,
+ using the generator \a g.
+ */
+void QDocDatabase::generateIndex(const QString &fileName, const QString &url, const QString &title, Generator *g)
{
QString t = fileName.mid(fileName.lastIndexOf(QChar('/'))+1);
primaryTree()->setIndexFileName(t);
- QDocIndexFiles::qdocIndexFiles()->generateIndex(fileName, url, title, g, generateInternalNodes);
+ QDocIndexFiles::qdocIndexFiles()->generateIndex(fileName, url, title, g);
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
@@ -1787,12 +1542,18 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
if (first.endsWith(".html"))
node = domain->findNodeByNameAndType(QStringList(first), Node::Page);
else if (first.endsWith(QChar(')'))) {
- QString function, params;
+ QString signature;
+ QString function = first;
int length = first.length();
- int position = first.lastIndexOf(QChar('('));
- params = first.mid(position+1, length-position-2);
- function = first.left(position);
- node = domain->findFunctionNode(function, params, 0, genus);
+ if (function.endsWith("()"))
+ function.chop(2);
+ if (function.endsWith(QChar(')'))) {
+ int position = function.lastIndexOf(QChar('('));
+ signature = function.mid(position + 1, length - position - 2);
+ function = function.left(position);
+ }
+ QStringList path = function.split("::");
+ node = domain->findFunctionNode(path, Parameters(signature), nullptr, genus);
}
if (!node) {
int flags = SearchBaseClasses | SearchEnumValues;
@@ -1809,9 +1570,8 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
else {
if (first.endsWith(".html"))
node = findNodeByNameAndType(QStringList(first), Node::Page);
- else if (first.endsWith(QChar(')'))) {
+ else if (first.endsWith(QChar(')')))
node = findFunctionNode(first, relative, genus);
- }
if (!node)
return findNodeForTarget(targetPath, relative, genus, ref);
}