diff options
author | Martin Smith <martin.smith@digia.com> | 2013-06-10 13:54:11 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-06-11 14:33:00 +0200 |
commit | 505a10baf76dc9cc10432d62205dc352bd6cefbe (patch) | |
tree | 7bc7f8e7b989e816faab336429d87c9894797e8f | |
parent | 0d7d53fd46e8ab512bed88d0dab114cfada227ce (diff) |
qdoc: qdoc was confused by namespace and module with same name
When qdoc searched for QtConncurrent::blockingFilter(),
it found the module node for QtConcurrent instead of the
namespace. This was because qdoc wasn't given specific
enough instructions on how to perform the search. Now
it searches for the namespace first, then the C++ class,
then the module.
Task-number: QTBUG-31535
Change-Id: I4f8aec503903508789738f2a77c76f47a3e80a93
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
-rw-r--r-- | src/tools/qdoc/cppcodeparser.cpp | 49 | ||||
-rw-r--r-- | src/tools/qdoc/cppcodeparser.h | 1 | ||||
-rw-r--r-- | src/tools/qdoc/puredocparser.cpp | 4 | ||||
-rw-r--r-- | src/tools/qdoc/qdocdatabase.cpp | 52 | ||||
-rw-r--r-- | src/tools/qdoc/qdocdatabase.h | 6 | ||||
-rw-r--r-- | src/tools/qdoc/tree.cpp | 12 | ||||
-rw-r--r-- | src/tools/qdoc/tree.h | 6 |
7 files changed, 86 insertions, 44 deletions
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 41fe2f775c..5c25eeedc4 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -207,10 +207,10 @@ void CppCodeParser::parseSourceFile(const Location& location, const QString& fil readToken(); /* - The set of active namespaces is cleared before parsing + The set of open namespaces is cleared before parsing each source file. The word "source" here means cpp file. */ - activeNamespaces_.clear(); + qdb_->clearOpenNamespaces(); matchDocsAndStuff(); in.close(); @@ -323,21 +323,18 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, doc.startLocation().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_FN)); } else { - if (!activeNamespaces_.isEmpty()) { - foreach (const QString& usedNamespace_, activeNamespaces_) { - QStringList newPath = usedNamespace_.split("::") + parentPath; - func = qdb_->findFunctionNode(newPath, clone); - if (func) - break; - } - } - // Search the root namespace if no match was found. - if (func == 0) + func = qdb_->findNodeInOpenNamespace(parentPath, clone); + /* + Search the root namespace if no match was found. + */ + if (func == 0) { func = qdb_->findFunctionNode(parentPath, clone); + } if (func == 0) { - if (parentPath.isEmpty() && !lastPath_.isEmpty()) + if (parentPath.isEmpty() && !lastPath_.isEmpty()) { func = qdb_->findFunctionNode(lastPath_, clone); + } if (func == 0) { doc.location().warning(tr("Cannot find '%1' in '\\%2' %3") .arg(clone->name() + "(...)") @@ -426,16 +423,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, C++ namespace, search for it first in all the known C++ namespaces. */ - if (!activeNamespaces_.isEmpty()) { - foreach (const QString& usedNamespace_, activeNamespaces_) { - QStringList newPath = usedNamespace_.split("::") + path; - node = qdb_->findNodeByNameAndType(newPath, type, subtype); - if (node) { - path = newPath; - break; - } - } - } + node = qdb_->findNodeInOpenNamespace(path, type, subtype); /* If the node was not found in a C++ namespace, search @@ -458,7 +446,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, if (path.size() > 1) { path.pop_back(); QString ns = path.join("::"); - activeNamespaces_.insert(ns); + qdb_->insertOpenNamespace(ns); } } return node; @@ -1718,7 +1706,7 @@ bool CppCodeParser::matchUsingDecl() /* So far, so good. We have 'using namespace Foo;'. */ - activeNamespaces_.insert(name); + qdb_->insertOpenNamespace(name); return true; } @@ -2125,13 +2113,7 @@ bool CppCodeParser::matchDocsAndStuff() FunctionNode *func = 0; if (matchFunctionDecl(0, &parentPath, &clone, QString(), extra)) { - foreach (const QString& usedNamespace_, activeNamespaces_) { - QStringList newPath = usedNamespace_.split("::") + parentPath; - func = qdb_->findFunctionNode(newPath, clone); - if (func) { - break; - } - } + func = qdb_->findNodeInOpenNamespace(parentPath, clone); if (func == 0) func = qdb_->findFunctionNode(parentPath, clone); @@ -2256,9 +2238,8 @@ bool CppCodeParser::makeFunctionNode(const QString& signature, Tokenizer* outerTokenizer = tokenizer; int outerTok = tok; - Location loc; QByteArray latin1 = signature.toLatin1(); - Tokenizer stringTokenizer(loc, latin1); + Tokenizer stringTokenizer(location(), latin1); stringTokenizer.setParsingFnOrMacro(true); tokenizer = &stringTokenizer; readToken(); diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h index eae5d1e97d..957142712b 100644 --- a/src/tools/qdoc/cppcodeparser.h +++ b/src/tools/qdoc/cppcodeparser.h @@ -166,7 +166,6 @@ protected: QStringList lastPath_; QRegExp varComment; QRegExp sep; - QSet<QString> activeNamespaces_; private: QString sequentialIteratorDefinition; diff --git a/src/tools/qdoc/puredocparser.cpp b/src/tools/qdoc/puredocparser.cpp index aba17d79b1..d11ef3a3c7 100644 --- a/src/tools/qdoc/puredocparser.cpp +++ b/src/tools/qdoc/puredocparser.cpp @@ -101,10 +101,10 @@ void PureDocParser::parseSourceFile(const Location& location, const QString& fil readToken(); /* - The set of active namespaces is cleared before parsing + The set of open namespaces is cleared before parsing each source file. The word "source" here means cpp file. */ - activeNamespaces_.clear(); + qdb_->clearOpenNamespaces(); processQdocComments(); in.close(); diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index 674917f6dc..7a3df4e4f2 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -1126,4 +1126,56 @@ QString QDocDatabase::refForAtom(const Atom* atom) return QString(); } +/*! + 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 and \a subtype that is + reached with the specified \a path. If such a 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. + */ +Node* QDocDatabase::findNodeInOpenNamespace(QStringList& path, + Node::Type type, + Node::SubType subtype) +{ + Node* n = 0; + if (!openNamespaces_.isEmpty()) { + foreach (const QString& t, openNamespaces_) { + QStringList p = t.split("::") + path; + n = findNodeByNameAndType(p, type, subtype); + if (n) { + path = p; + break; + } + } + } + return n; +} + QT_END_NAMESPACE diff --git a/src/tools/qdoc/qdocdatabase.h b/src/tools/qdoc/qdocdatabase.h index d97fb3809a..d88160ee56 100644 --- a/src/tools/qdoc/qdocdatabase.h +++ b/src/tools/qdoc/qdocdatabase.h @@ -196,6 +196,11 @@ class QDocDatabase Generator* g, bool generateInternalNodes = false); + void clearOpenNamespaces() { openNamespaces_.clear(); } + void insertOpenNamespace(const QString& path) { openNamespaces_.insert(path); } + FunctionNode* findNodeInOpenNamespace(const QStringList& parentPath, const FunctionNode* clone); + Node* findNodeInOpenNamespace(QStringList& path, Node::Type type, Node::SubType subtype); + /* debugging functions */ void printModules() const; void printQmlModules() const; @@ -240,6 +245,7 @@ class QDocDatabase TextToNodeMap legaleseTexts_; DocNodeMultiMap docNodesByTitle_; TargetRecMultiMap targetRecMultiMap_; + QSet<QString> openNamespaces_; }; QT_END_NAMESPACE diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index 1efab11a92..553c569ae9 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -367,7 +367,11 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& parentPath, const Node* relative, int findFlags) const { - const Node* parent = findNode(parentPath, relative, findFlags); + const Node* parent = findNamespaceNode(parentPath); + if (parent == 0) + parent = findClassNode(parentPath, 0); + if (parent == 0) + parent = findNode(parentPath, relative, findFlags); if (parent == 0 || !parent->isInnerNode()) return 0; return ((InnerNode*)parent)->findFunctionNode(clone); @@ -658,7 +662,7 @@ Node* Tree::findNodeRecursive(const QStringList& path, Node* start, Node::Type type, Node::SubType subtype, - bool acceptCollision) + bool acceptCollision) const { if (!start || path.isEmpty()) return 0; // no place to start, or nothing to search for. @@ -736,7 +740,7 @@ EnumNode* Tree::findEnumNode(const QStringList& path, Node* start) at the root of the tree. Only a C++ class node named \a path is acceptible. If one is not found, 0 is returned. */ -ClassNode* Tree::findClassNode(const QStringList& path, Node* start) +ClassNode* Tree::findClassNode(const QStringList& path, Node* start) const { if (!start) start = const_cast<NamespaceNode*>(root()); @@ -748,7 +752,7 @@ ClassNode* Tree::findClassNode(const QStringList& path, Node* start) the root of the tree. Only a Namespace node named \a path is acceptible. If one is not found, 0 is returned. */ -NamespaceNode* Tree::findNamespaceNode(const QStringList& path) +NamespaceNode* Tree::findNamespaceNode(const QStringList& path) const { Node* start = const_cast<NamespaceNode*>(root()); return static_cast<NamespaceNode*>(findNodeRecursive(path, 0, start, Node::Namespace, Node::NoSubType)); diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h index 67cd3a9752..e44b8d7d12 100644 --- a/src/tools/qdoc/tree.h +++ b/src/tools/qdoc/tree.h @@ -82,9 +82,9 @@ class Tree ~Tree(); EnumNode* findEnumNode(const QStringList& path, Node* start = 0); - ClassNode* findClassNode(const QStringList& path, Node* start = 0); + ClassNode* findClassNode(const QStringList& path, Node* start = 0) const; QmlClassNode* findQmlTypeNode(const QStringList& path); - NamespaceNode* findNamespaceNode(const QStringList& path); + NamespaceNode* findNamespaceNode(const QStringList& path) const; DocNode* findQmlModuleNode(const QStringList& path, Node* start = 0); Node* findNodeByNameAndType(const QStringList& path, @@ -98,7 +98,7 @@ class Tree Node* start, Node::Type type, Node::SubType subtype, - bool acceptCollision = false); + bool acceptCollision = false) const; const Node* findNode(const QStringList &path, const Node* relative = 0, |