summaryrefslogtreecommitdiffstats
path: root/src/tools/qdoc
diff options
context:
space:
mode:
authorMartin Smith <martin.smith@digia.com>2014-03-19 15:12:07 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-31 21:05:23 +0200
commit2ea15849a09208ac19d189acdc51c313b64a0b3a (patch)
tree630825cea808fcd38e39a257754b8dffd72307a5 /src/tools/qdoc
parent900c150a07f627c20ad68ec59253196d9960b034 (diff)
qdoc: \l{Qt::Window} links to the wrong page
kThis update fixes a bug introduced by the extensive changes for QTBUG-35377. The name Qt represents two namespaces, one in C++ and one in QML. The name "Window" is used in both of them, so the link \l{Qt::Window} would cause a collision in the single tree qdoc. In the multiple tree qdoc, there is no collision, but in this case the link should have gone to the C++ page and it went to the QML page instead. The fix involved correcting the way qdoc searches for link targets. Task-number: QTBUG-37633 Change-Id: Ib9b209eced937a0be0d3299f300ebf22b2776012 Reviewed-by: Martin Smith <martin.smith@digia.com>
Diffstat (limited to 'src/tools/qdoc')
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.cpp125
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp69
-rw-r--r--src/tools/qdoc/qdocdatabase.cpp53
-rw-r--r--src/tools/qdoc/qdocdatabase.h86
-rw-r--r--src/tools/qdoc/tree.cpp105
-rw-r--r--src/tools/qdoc/tree.h11
6 files changed, 220 insertions, 229 deletions
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp
index 8ac1b1ef82..90661d80e0 100644
--- a/src/tools/qdoc/ditaxmlgenerator.cpp
+++ b/src/tools/qdoc/ditaxmlgenerator.cpp
@@ -3389,68 +3389,71 @@ void DitaXmlGenerator::writeText(const QString& markedCode, const Node* relative
for (int k = 0; k != 6; ++k) {
if (parseArg(src, markTags[k], &i, n, &arg, &par1)) {
const Node* n = 0;
- if (k == 0) { // <@link>
- if (!text.isEmpty()) {
- writeCharacters(text);
- text.clear();
- }
- n = CodeMarker::nodeForString(par1.toString());
- QString link = linkForNode(n, relative);
- addLink(link, arg);
- }
- else if (k == 4) { // <@param>
- if (!text.isEmpty()) {
- writeCharacters(text);
- text.clear();
- }
- writeStartTag(DT_i);
- //writeCharacters(" " + arg.toString());
- writeCharacters(arg.toString());
- writeEndTag(); // </i>
- }
- else if (k == 5) { // <@extra>
- if (!text.isEmpty()) {
- writeCharacters(text);
- text.clear();
- }
- writeStartTag(DT_tt);
- writeCharacters(arg.toString());
- writeEndTag(); // </tt>
- }
- else {
- if (!text.isEmpty()) {
- writeCharacters(text);
- text.clear();
- }
- par1 = QStringRef();
- QString link;
- n = qdb_->resolveTarget(arg.toString(), relative);
- if (n && n->subType() == Node::QmlBasicType) {
- if (relative && relative->subType() == Node::QmlClass) {
- link = linkForNode(n,relative);
- addLink(link, arg);
+ switch (k) {
+ case 0: // <@link>
+ if (!text.isEmpty()) {
+ writeCharacters(text);
+ text.clear();
}
- else {
- writeCharacters(arg.toString());
+ n = CodeMarker::nodeForString(par1.toString());
+ addLink(linkForNode(n, relative), arg);
+ break;
+ case 4: // <@param>
+ if (!text.isEmpty()) {
+ writeCharacters(text);
+ text.clear();
}
- }
- else {
- // (zzz) Is this correct for all cases?
- link = linkForNode(n,relative);
- addLink(link, arg);
- }
- }
+ writeStartTag(DT_i);
+ //writeCharacters(" " + arg.toString());
+ writeCharacters(arg.toString());
+ writeEndTag(); // </i>
+ break;
+ case 5: // <@extra>
+ if (!text.isEmpty()) {
+ writeCharacters(text);
+ text.clear();
+ }
+ writeStartTag(DT_tt);
+ writeCharacters(arg.toString());
+ writeEndTag(); // </tt>
+ break;
+ case 3:
+ if (!text.isEmpty()) {
+ writeCharacters(text);
+ text.clear();
+ }
+ par1 = QStringRef();
+ n = qdb_->resolveFunctionTarget(arg.toString(), relative);
+ addLink(linkForNode(n, relative), arg);
+ break;
+ case 1:
+ case 2:
+ default:
+ if (!text.isEmpty()) {
+ writeCharacters(text);
+ text.clear();
+ }
+ par1 = QStringRef();
+ n = qdb_->resolveType(arg.toString(), relative);
+ if (n && n->subType() == Node::QmlBasicType) {
+ if (relative && relative->subType() == Node::QmlClass)
+ addLink(linkForNode(n, relative), arg);
+ else
+ writeCharacters(arg.toString());
+ }
+ else
+ addLink(linkForNode(n, relative), arg); // (zzz) Is this correct for all cases?
+ break;
+ } // switch
break;
}
}
}
- else {
+ else
text += src.at(i++);
- }
}
- if (!text.isEmpty()) {
+ if (!text.isEmpty())
writeCharacters(text);
- }
}
void DitaXmlGenerator::generateLink(const Atom* atom, CodeMarker* marker)
@@ -3830,18 +3833,18 @@ QString DitaXmlGenerator::getLink(const Atom* atom, const Node* relative, const
QString ref;
QString first = path.first().trimmed();
- if (first.isEmpty()) {
+ if (first.isEmpty())
*node = relative;
- }
- else if (first.endsWith(".html")) {
+ else if (first.endsWith(".html"))
*node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document, Node::NoSubType);
- }
+ else if (first.endsWith("()")) // The target is a C++ function or QML method.
+ *node = qdb_->resolveFunctionTarget(first, relative);
else {
*node = qdb_->resolveTarget(first, relative);
+ if (!(*node))
+ *node = qdb_->findDocNodeByTitle(first);
if (!*node)
- *node = qdb_->findDocNodeByTitle(first, relative);
- if (!*node)
- *node = qdb_->findUnambiguousTarget(first, ref, relative);
+ *node = qdb_->findUnambiguousTarget(first, ref);
}
if (*node) {
@@ -4601,7 +4604,7 @@ void DitaXmlGenerator::replaceTypesWithLinks(const Node* n, const InnerNode* par
}
i += 2;
if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) {
- const Node* tn = qdb_->resolveTarget(arg.toString(), parent);
+ const Node* tn = qdb_->resolveType(arg.toString(), parent);
if (tn) {
//Do not generate a link from a C++ function to a QML Basic Type (such as int)
if (n->type() == Node::Function && tn->subType() == Node::QmlBasicType)
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index ec430d0951..ceed09a7cf 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -320,6 +320,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
if (!inLink_ && !inContents_ && !inSectionHeading_) {
const Node *node = 0;
QString link = getLink(atom, relative, &node);
+ QDocDatabase::debug = false;
if (!link.isEmpty()) {
beginLink(link, node, relative);
generateLink(atom, marker);
@@ -3188,7 +3189,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
i += 2;
if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
- const Node* n = qdb_->resolveTarget(par1.toString(), relative);
+ const Node* n = qdb_->resolveFunctionTarget(par1.toString(), relative);
QString link = linkForNode(n, relative);
addLink(link, arg, &html);
par1 = QStringRef();
@@ -3228,20 +3229,18 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
}
else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) {
par1 = QStringRef();
- const Node* n = qdb_->resolveTarget(arg.toString(), relative);
- addLink(linkForNode(n,relative), arg, &html);
- handled = true;
- }
-#if 0
- // Apparently, this clause was never used.
- // <@func> is taken out above.
- else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
- par1 = QStringRef();
- const Node* n = qdb_->resolveTarget(arg.toString(), relative);
- addLink(linkForNode(n,relative), arg, &html);
+ if (arg.at(0) == QChar('&'))
+ html += arg.toString();
+ else {
+ // zzz resolveClassTarget()
+ const Node* n = qdb_->resolveTarget(arg.toString(), relative);
+ if (n)
+ addLink(linkForNode(n,relative), arg, &html);
+ else
+ html += arg.toString();
+ }
handled = true;
}
-#endif
if (!handled) {
html += charLangle;
html += charAt;
@@ -3763,45 +3762,35 @@ QString HtmlGenerator::getLink(const Atom *atom, const Node *relative, const Nod
*node = 0;
inObsoleteLink = false;
- if (atom->string().contains(QLatin1Char(':')) &&
- (atom->string().startsWith("file:")
- || atom->string().startsWith("http:")
- || atom->string().startsWith("https:")
- || atom->string().startsWith("ftp:")
- || atom->string().startsWith("mailto:"))) {
-
- link = atom->string();
+ if (atom->string().contains(QLatin1Char(':')) && (atom->string().startsWith("file:") ||
+ atom->string().startsWith("http:") ||
+ atom->string().startsWith("https:") ||
+ atom->string().startsWith("ftp:") ||
+ atom->string().startsWith("mailto:"))) {
+ link = atom->string(); // It's some kind of protocol.
}
else {
QStringList path;
- if (atom->string().contains('#')) {
- path = atom->string().split('#');
- }
- else {
- path.append(atom->string());
- }
+ if (atom->string().contains('#'))
+ path = atom->string().split('#'); // The target is in the html file.
+ else
+ path.append(atom->string()); // It's a general case target.
QString ref;
QString first = path.first().trimmed();
- if (first.isEmpty()) {
+ if (first.isEmpty())
*node = relative;
- }
- else if (first.endsWith(".html")) {
- /*
- This is not a recursive search. That's ok in
- this case, because we are searching for a page
- node, which must be a direct child of the tree
- root.
- */
+ else if (first.endsWith(".html")) // The target is an html file.
*node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document, Node::NoSubType);
+ else if (first.endsWith("()")) { // The target is a C++ function or QML method.
+ *node = qdb_->resolveFunctionTarget(first, relative);
}
else {
+ *node = qdb_->resolveTarget(first, relative);
if (!(*node))
- *node = qdb_->resolveTarget(first, relative);
- if (!(*node))
- *node = qdb_->findDocNodeByTitle(first, relative);
+ *node = qdb_->findDocNodeByTitle(first);
if (!(*node)) {
- *node = qdb_->findUnambiguousTarget(first, ref, relative);
+ *node = qdb_->findUnambiguousTarget(first, ref);
if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) {
QString final = (*node)->url() + "#" + ref;
return final;
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp
index 289e57d16c..ffd2dd9b3b 100644
--- a/src/tools/qdoc/qdocdatabase.cpp
+++ b/src/tools/qdoc/qdocdatabase.cpp
@@ -51,6 +51,7 @@ 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
@@ -368,38 +369,30 @@ void QDocForest::newPrimaryTree(const QString& module)
}
/*!
- Searches the Tree \a t for a node named \a target and returns
+ Searches the trees for a node named \a target and returns
a pointer to it if found. The \a relative node is the starting
- point, but it only makes sense in the primary tree. Therefore,
- when this function is called with \a t being an index tree,
- \a relative is 0. When relative is 0, the root node of \a t is
- the starting point.
- */
-const Node* QDocForest::resolveTargetHelper(const QString& target,
- const Node* relative,
- Tree* t)
+ point, but it only makes sense in the primary tree, which is
+ searched first. After the primary tree is searched, \a relative
+ is set to 0 for searching the index trees. When relative is 0,
+ the root node of the index tree is the starting point.
+ */
+const Node* QDocForest::resolveTarget(const QString& target, const Node* relative)
{
- const Node* node = 0;
- if (target.endsWith("()")) {
- QString funcName = target;
- funcName.chop(2);
- QStringList path = funcName.split("::");
- const FunctionNode* fn = t->findFunctionNode(path, relative, SearchBaseClasses);
- if (fn && fn->metaness() != FunctionNode::MacroWithoutParams)
- node = fn;
- }
- else {
- QStringList path = target.split("::");
- int flags = SearchBaseClasses | SearchEnumValues | NonFunction;
- node = t->findNode(path, relative, flags);
- if (!node) {
- QStringList path = target.split("::");
- const FunctionNode* fn = t->findFunctionNode(path, relative, SearchBaseClasses);
- if (fn && fn->metaness() != FunctionNode::MacroWithoutParams)
- node = fn;
- }
+ QStringList path = target.split("::");
+ int flags = SearchBaseClasses | SearchEnumValues | NonFunction;
+
+ foreach (Tree* t, searchOrder()) {
+ const Node* n = t->findNode(path, relative, flags);
+ if (n)
+ return n;
+#if 0
+ n = t->findDocNodeByTitle(target);
+ if (n)
+ return n;
+#endif
+ relative = 0;
}
- return node;
+ return 0;
}
/*!
@@ -1356,7 +1349,7 @@ const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* r
else {
node = resolveTarget(target, relative);
if (!node)
- node = findDocNodeByTitle(target, relative);
+ node = findDocNodeByTitle(target);
}
return node;
}
diff --git a/src/tools/qdoc/qdocdatabase.h b/src/tools/qdoc/qdocdatabase.h
index 1fff24cb65..7bbff89fa3 100644
--- a/src/tools/qdoc/qdocdatabase.h
+++ b/src/tools/qdoc/qdocdatabase.h
@@ -89,11 +89,11 @@ class QDocForest
const Node* findNode(const QStringList& path, const Node* relative, int findFlags) {
foreach (Tree* t, searchOrder()) {
const Node* n = t->findNode(path, relative, findFlags);
- if (n) return n;
+ if (n)
+ return n;
relative = 0;
}
- if (Config::debug_)
- qDebug() << "FAILED SEARCH 1" << path;
+ //qDebug() << "FAILED SEARCH 1" << path;
return 0;
}
@@ -103,55 +103,53 @@ class QDocForest
bool acceptCollision = false) {
foreach (Tree* t, searchOrder()) {
Node* n = t->findNodeByNameAndType(path, type, subtype, acceptCollision);
- if (n) return n;
+ if (n)
+ return n;
}
- if (Config::debug_)
- qDebug() << "FAILED SEARCH 2" << path << type << subtype;
+ //qDebug() << "FAILED SEARCH 2" << path << type << subtype;
return 0;
}
ClassNode* findClassNode(const QStringList& path) {
foreach (Tree* t, searchOrder()) {
ClassNode* n = t->findClassNode(path);
- if (n) return n;
+ if (n)
+ return n;
}
- if (Config::debug_)
- qDebug() << "FAILED SEARCH 3" << path;
+ //qDebug() << "FAILED SEARCH 3" << path;
return 0;
}
InnerNode* findRelatesNode(const QStringList& path) {
foreach (Tree* t, searchOrder()) {
InnerNode* n = t->findRelatesNode(path);
- if (n) return n;
+ if (n)
+ return n;
}
- if (Config::debug_)
- qDebug() << "FAILED SEARCH 4" << path;
+ //qDebug() << "FAILED SEARCH 4" << path;
return 0;
}
- const Node* resolveTarget(const QString& target, const Node* relative) {
- const Node* r = relative;
+ const Node* resolveFunctionTarget(const QString& target, const Node* relative) {
foreach (Tree* t, searchOrder()) {
- const Node* n = resolveTargetHelper(target, relative, t);
- if (n) return n;
+ const Node* n = t->resolveFunctionTarget(target, relative);
+ if (n)
+ return n;
relative = 0;
}
- if (Config::debug_) {
- qDebug() << "FAILED SEARCH 6" << target << r;
- }
return 0;
}
+ const Node* resolveTarget(const QString& target, const Node* relative);
const Node* resolveType(const QStringList& path, const Node* relative)
{
foreach (Tree* t, searchOrder()) {
const Node* n = resolveTypeHelper(path, relative, t);
- if (n) return n;
+ if (n)
+ return n;
relative = 0;
}
- if (Config::debug_)
- qDebug() << "FAILED SEARCH 5" << path;
+ //qDebug() << "FAILED SEARCH 5" << path;
return 0;
}
@@ -159,32 +157,32 @@ class QDocForest
{
foreach (Tree* t, searchOrder()) {
QString ref = t->findTarget(target, node);
- if (!ref.isEmpty()) return ref;
+ if (!ref.isEmpty())
+ return ref;
}
- if (Config::debug_)
- qDebug() << "FAILED SEARCH 7" << target;
+ //qDebug() << "FAILED SEARCH 7" << target;
return QString();
}
- const Node* findUnambiguousTarget(const QString& target, QString& ref, const Node* relative)
+ const Node* findUnambiguousTarget(const QString& target, QString& ref)
{
foreach (Tree* t, searchOrder()) {
- const Node* n = t->findUnambiguousTarget(target, ref, relative);
- if (n) return n;
+ const Node* n = t->findUnambiguousTarget(target, ref);
+ if (n)
+ return n;
}
- if (Config::debug_)
- qDebug() << "FAILED SEARCH 8" << target;
+ //qDebug() << "FAILED SEARCH 8" << target;
return 0;
}
- const DocNode* findDocNodeByTitle(const QString& title, const Node* relative)
+ const DocNode* findDocNodeByTitle(const QString& title)
{
foreach (Tree* t, searchOrder()) {
- const DocNode* n = t->findDocNodeByTitle(title, relative);
- if (n) return n;
+ const DocNode* n = t->findDocNodeByTitle(title);
+ if (n)
+ return n;
}
- if (Config::debug_)
- qDebug() << "FAILED SEARCH 9" << title;
+ //qDebug() << "FAILED SEARCH 9" << title;
return 0;
}
@@ -192,7 +190,8 @@ class QDocForest
{
foreach (Tree* t, searchOrder()) {
QmlClassNode* qcn = t->lookupQmlType(name);
- if (qcn) return qcn;
+ if (qcn)
+ return qcn;
}
return 0;
}
@@ -209,7 +208,6 @@ class QDocForest
private:
void newPrimaryTree(const QString& module);
NamespaceNode* newIndexTree(const QString& module);
- const Node* resolveTargetHelper(const QString& target, const Node* relative, Tree* t);
const Node* resolveTypeHelper(const QStringList& path, const Node* relative, Tree* t);
private:
@@ -329,13 +327,16 @@ class QDocDatabase
const Node* resolveTarget(const QString& target, const Node* relative) {
return forest_.resolveTarget(target, relative);
}
+ const Node* resolveFunctionTarget(const QString& target, const Node* relative) {
+ return forest_.resolveFunctionTarget(target, relative);
+ }
const Node* resolveType(const QString& type, const Node* relative);
const Node* findNodeForTarget(const QString& target, const Node* relative);
- const DocNode* findDocNodeByTitle(const QString& title, const Node* relative = 0) {
- return forest_.findDocNodeByTitle(title, relative);
+ const DocNode* findDocNodeByTitle(const QString& title) {
+ return forest_.findDocNodeByTitle(title);
}
- const Node* findUnambiguousTarget(const QString& target, QString& ref, const Node* relative) {
- return forest_.findUnambiguousTarget(target, ref, relative);
+ const Node* findUnambiguousTarget(const QString& target, QString& ref) {
+ return forest_.findUnambiguousTarget(target, ref);
}
Node* findNodeByNameAndType(const QStringList& path, Node::Type type, Node::SubType subtype){
return forest_.findNodeByNameAndType(path, type, subtype, false);
@@ -389,6 +390,9 @@ class QDocDatabase
QDocDatabase& operator=(QDocDatabase const& );
Tree* primaryTree() { return forest_.primaryTree(); }
+ public:
+ static bool debug;
+
private:
static QDocDatabase* qdocDB_;
static NodeMap typeNodeMap_;
diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp
index e3dc4c657a..d17468f3a9 100644
--- a/src/tools/qdoc/tree.cpp
+++ b/src/tools/qdoc/tree.cpp
@@ -220,17 +220,23 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
if (!relative)
relative = root();
- /*
- If the path contains two double colons ("::"), check
- first to see if it is a reference to a QML method. If
- it is a reference to a QML method, first look up the
- QML class node in the QML module map.
- */
if (path.size() == 3 && !path[0].isEmpty()) {
- QmlClassNode* qcn = qdb_->findQmlType(path[0], path[1]);
- if (qcn) {
- return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2]));
+ QmlClassNode* qcn = lookupQmlType(QString(path[0] + "::" + path[1]));
+ if (!qcn) {
+ QStringList p(path[1]);
+ Node* n = findNodeByNameAndType(p, Node::Document, Node::QmlClass, true);
+ if (n) {
+ if (n->subType() == Node::QmlClass)
+ qcn = static_cast<QmlClassNode*>(n);
+ else if (n->subType() == Node::Collision) {
+ NameCollisionNode* ncn;
+ ncn = static_cast<NameCollisionNode*>(n);
+ qcn = static_cast<QmlClassNode*>(ncn->findAny(Node::Document, Node::QmlClass));
+ }
+ }
}
+ if (qcn)
+ return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2]));
}
do {
@@ -555,7 +561,7 @@ NodeList Tree::allBaseClasses(const ClassNode* classNode) const
Node* Tree::findNodeByNameAndType(const QStringList& path,
Node::Type type,
Node::SubType subtype,
- bool acceptCollision)
+ bool acceptCollision) const
{
Node* result = findNodeRecursive(path, 0, root(), type, subtype, acceptCollision);
return result;
@@ -581,22 +587,23 @@ Node* Tree::findNodeByNameAndType(const QStringList& path,
*/
Node* Tree::findNodeRecursive(const QStringList& path,
int pathIndex,
- Node* start,
+ const Node* start,
Node::Type type,
Node::SubType subtype,
bool acceptCollision) const
{
if (!start || path.isEmpty())
return 0; // no place to start, or nothing to search for.
+ Node* node = const_cast<Node*>(start);
if (start->isLeaf()) {
if (pathIndex >= path.size())
- return start; // found a match.
+ return node; // found a match.
return 0; // premature leaf
}
if (pathIndex >= path.size())
return 0; // end of search path.
- InnerNode* current = static_cast<InnerNode*>(start);
+ InnerNode* current = static_cast<InnerNode*>(node);
const NodeList& children = current->childNodes();
const QString& name = path.at(pathIndex);
for (int i=0; i<children.size(); ++i) {
@@ -714,7 +721,9 @@ const Node* Tree::findNode(const QStringList& path, const Node* start, int findF
QML node.
*/
const Node* n = findNode(path, current, findFlags, false);
- return (n ? n : findNode(path, current, findFlags, true));
+ if (n)
+ return n;
+ return findNode(path, current, findFlags, true);
}
/*!
@@ -745,7 +754,7 @@ const Node* Tree::findNode(const QStringList& path, const Node* start, int findF
class node.
*/
if (qml && path.size() >= 2 && !path[0].isEmpty()) {
- QmlClassNode* qcn = qdb_->findQmlType(path[0], path[1]);
+ QmlClassNode* qcn = lookupQmlType(QString(path[0] + "::" + path[1]));
if (qcn) {
node = qcn;
if (path.size() == 2)
@@ -759,17 +768,18 @@ const Node* Tree::findNode(const QStringList& path, const Node* start, int findF
break;
const Node* next = static_cast<const InnerNode*>(node)->findChildNode(path.at(i), qml);
- if (!next && (findFlags & SearchEnumValues) && i == path.size()-1)
+ if (!next && (findFlags & SearchEnumValues) && i == path.size()-1) {
next = static_cast<const InnerNode*>(node)->findEnumNodeForValue(path.at(i));
-
+ }
if (!next && !qml && node->type() == Node::Class && (findFlags & SearchBaseClasses)) {
NodeList baseClasses = allBaseClasses(static_cast<const ClassNode*>(node));
foreach (const Node* baseClass, baseClasses) {
next = static_cast<const InnerNode*>(baseClass)->findChildNode(path.at(i));
if (!next && (findFlags & SearchEnumValues) && i == path.size() - 1)
next = static_cast<const InnerNode*>(baseClass)->findEnumNodeForValue(path.at(i));
- if (next)
+ if (next) {
break;
+ }
}
}
node = next;
@@ -903,7 +913,7 @@ void Tree::resolveTargets(InnerNode* root)
finds one, it sets \a ref and returns the found node.
*/
const Node*
-Tree::findUnambiguousTarget(const QString& target, QString& ref, const Node* relative)
+Tree::findUnambiguousTarget(const QString& target, QString& ref)
{
TargetRec bestTarget;
int numBestTargets = 0;
@@ -932,15 +942,15 @@ Tree::findUnambiguousTarget(const QString& target, QString& ref, const Node* rel
return bestTarget.node_;
}
else if (bestTargetList.size() > 1) {
- if (relative && !relative->qmlModuleName().isEmpty()) {
- for (int i=0; i<bestTargetList.size(); ++i) {
- const Node* n = bestTargetList.at(i).node_;
- if (n && relative->qmlModuleName() == n->qmlModuleName()) {
- ref = bestTargetList.at(i).ref_;
- return n;
- }
- }
+#if 0
+ qDebug() << "TARGET:" << target << numBestTargets;
+ for (int i=0; i<bestTargetList.size(); ++i) {
+ const Node* n = bestTargetList.at(i).node_;
+ qDebug() << " " << n->name() << n->title();
}
+#endif
+ ref = bestTargetList.at(0).ref_;
+ return bestTargetList.at(0).node_;
}
}
ref.clear();
@@ -949,36 +959,12 @@ Tree::findUnambiguousTarget(const QString& target, QString& ref, const Node* rel
/*!
This function searches for a node with the specified \a title.
- If \a relative node is provided, it is used to disambiguate if
- it has a QML module identifier.
*/
-const DocNode* Tree::findDocNodeByTitle(const QString& title, const Node* relative) const
+const DocNode* Tree::findDocNodeByTitle(const QString& title) const
{
QString key = Doc::canonicalTitle(title);
DocNodeMultiMap::const_iterator i = docNodesByTitle_.constFind(key);
if (i != docNodesByTitle_.constEnd()) {
- if (relative && !relative->qmlModuleName().isEmpty()) {
- const DocNode* dn = i.value();
- InnerNode* parent = dn->parent();
- if (parent && parent->type() == Node::Document && parent->subType() == Node::Collision) {
- const NodeList& nl = parent->childNodes();
- NodeList::ConstIterator it = nl.constBegin();
- while (it != nl.constEnd()) {
- if ((*it)->qmlModuleName() == relative->qmlModuleName()) {
- /*
- By returning here, we avoid printing
- all the duplicate header warnings,
- which are not really duplicates now,
- because of the QML module name being
- used as a namespace qualifier.
- */
- dn = static_cast<const DocNode*>(*it);
- return dn;
- }
- ++it;
- }
- }
- }
/*
Reporting all these duplicate section titles is probably
overkill. We should report the duplicate file and let
@@ -1269,4 +1255,19 @@ void Tree::insertQmlType(const QString& key, QmlClassNode* n)
qmlTypeMap_.insert(key,n);
}
+/*!
+ Split \a target on "::" and find the function node with that
+ path.
+ */
+const Node* Tree::resolveFunctionTarget(const QString& target, const Node* relative)
+{
+ QString t = target;
+ t.chop(2);
+ QStringList path = t.split("::");
+ const FunctionNode* fn = findFunctionNode(path, relative, SearchBaseClasses);
+ if (fn && fn->metaness() != FunctionNode::MacroWithoutParams)
+ return fn;
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h
index 565cb9c471..916682daad 100644
--- a/src/tools/qdoc/tree.h
+++ b/src/tools/qdoc/tree.h
@@ -86,10 +86,11 @@ class Tree
ClassNode* findClassNode(const QStringList& path, Node* start = 0) const;
NamespaceNode* findNamespaceNode(const QStringList& path) const;
FunctionNode* findFunctionNode(const QStringList& parentPath, const FunctionNode* clone);
+ const Node* resolveFunctionTarget(const QString& target, const Node* relative);
Node* findNodeRecursive(const QStringList& path,
int pathIndex,
- Node* start,
+ const Node* start,
Node::Type type,
Node::SubType subtype,
bool acceptCollision = false) const;
@@ -112,7 +113,7 @@ class Tree
Node* findNodeByNameAndType(const QStringList& path,
Node::Type type,
Node::SubType subtype,
- bool acceptCollision = false);
+ bool acceptCollision = false) const;
InnerNode* findRelatesNode(const QStringList& path);
@@ -121,8 +122,8 @@ class Tree
QString findTarget(const QString& target, const Node* node) const;
void insertTarget(const QString& name, TargetRec::Type type, Node* node, int priority);
void resolveTargets(InnerNode* root);
- const Node* findUnambiguousTarget(const QString& target, QString& ref, const Node* relative);
- const DocNode* findDocNodeByTitle(const QString& title, const Node* relative = 0) const;
+ const Node* findUnambiguousTarget(const QString& target, QString& ref);
+ const DocNode* findDocNodeByTitle(const QString& title) const;
void addPropertyFunction(PropertyNode *property,
const QString &funcName,
@@ -173,7 +174,7 @@ class Tree
ModuleNode* addToModule(const QString& name, Node* node);
QmlModuleNode* addToQmlModule(const QString& name, Node* node);
- QmlClassNode* lookupQmlType(const QString& name) { return qmlTypeMap_.value(name); }
+ QmlClassNode* lookupQmlType(const QString& name) const { return qmlTypeMap_.value(name); }
void insertQmlType(const QString& key, QmlClassNode* n);
void addExampleNode(ExampleNode* n) { exampleNodeMap_.insert(n->title(), n); }
ExampleNodeMap& exampleNodeMap() { return exampleNodeMap_; }