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>
This commit is contained in:
parent
0d7d53fd46
commit
505a10baf7
@ -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();
|
||||
|
@ -166,7 +166,6 @@ protected:
|
||||
QStringList lastPath_;
|
||||
QRegExp varComment;
|
||||
QRegExp sep;
|
||||
QSet<QString> activeNamespaces_;
|
||||
|
||||
private:
|
||||
QString sequentialIteratorDefinition;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user