diff options
author | Topi Reinio <topi.reinio@qt.io> | 2021-03-11 13:32:13 +0100 |
---|---|---|
committer | Topi Reinio <topi.reinio@qt.io> | 2021-03-22 10:18:32 +0100 |
commit | 10268e3e9c5f47db8231f2ac907a46cf9283d365 (patch) | |
tree | ccfa72e90a0bf30dbfcfa1f0ba835afad49be4dc /src | |
parent | ccd9f4eb9b8200fa26f32ffacae6ae93619ca867 (diff) | |
download | qttools-10268e3e9c5f47db8231f2ac907a46cf9283d365.tar.gz |
qdoc: Stop auto-linking to section titles
The purpose of the auto-linking feature is to link strings in the
text that resemble class or function names to API reference. However,
QDoc did not discriminate between the types of the resolved link
targets. Therefore, writing
\section1 QString
on a random \page would potentially redirect all autolinks to QString
to that section.
To fix, turn Node::Genus into attributes so we can do bitwise operations
on the genus, and introduce Node::API that includes all API reference
node genera.
Node::API is not assigned to nodes directly, but is used in searches
to match against any API reference nodes.
Pick-to: 6.0 6.1
Task-number: QTBUG-91141
Change-Id: Ic0a22b7105e1278662f5ae7d4132980200638225
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qdoc/aggregate.cpp | 4 | ||||
-rw-r--r-- | src/qdoc/atom.cpp | 4 | ||||
-rw-r--r-- | src/qdoc/docbookgenerator.cpp | 6 | ||||
-rw-r--r-- | src/qdoc/htmlgenerator.cpp | 5 | ||||
-rw-r--r-- | src/qdoc/node.h | 9 | ||||
-rw-r--r-- | src/qdoc/qdocdatabase.cpp | 20 | ||||
-rw-r--r-- | src/qdoc/qdocdatabase.h | 5 | ||||
-rw-r--r-- | src/qdoc/tree.cpp | 8 | ||||
-rw-r--r-- | src/qdoc/webxmlgenerator.cpp | 2 | ||||
-rw-r--r-- | src/qdoc/xmlgenerator.cpp | 5 | ||||
-rw-r--r-- | src/qdoc/xmlgenerator.h | 3 |
11 files changed, 46 insertions, 25 deletions
diff --git a/src/qdoc/aggregate.cpp b/src/qdoc/aggregate.cpp index f2d8bec7a..c824dc793 100644 --- a/src/qdoc/aggregate.cpp +++ b/src/qdoc/aggregate.cpp @@ -104,7 +104,7 @@ Node *Aggregate::findChildNode(const QString &name, Node::Genus genus, int findF } else { const NodeList &nodes = m_nonfunctionMap.values(name); for (auto *node : nodes) { - if (genus == node->genus()) { + if (genus & node->genus()) { if (findFlags & TypesOnly) { if (!node->isTypedef() && !node->isClassNode() && !node->isQmlType() && !node->isQmlBasicType() && !node->isJsType() @@ -116,7 +116,7 @@ Node *Aggregate::findChildNode(const QString &name, Node::Genus genus, int findF } } } - if (genus != Node::DontCare && this->genus() != genus) + if (genus != Node::DontCare && !(genus & this->genus())) return nullptr; return m_functionMap.value(name); } diff --git a/src/qdoc/atom.cpp b/src/qdoc/atom.cpp index f0a7c63f2..ee788ec2d 100644 --- a/src/qdoc/atom.cpp +++ b/src/qdoc/atom.cpp @@ -442,6 +442,10 @@ void LinkAtom::resolveSquareBracketParams() genus_ = Node::DOC; continue; } + if (param == "api") { + genus_ = Node::API; + continue; + } error_ = squareBracketParams_; break; } diff --git a/src/qdoc/docbookgenerator.cpp b/src/qdoc/docbookgenerator.cpp index 2e1a5ca29..6919de47f 100644 --- a/src/qdoc/docbookgenerator.cpp +++ b/src/qdoc/docbookgenerator.cpp @@ -227,13 +227,17 @@ int DocBookGenerator::generateAtom(const Atom *atom, const Node *relative, CodeM int idx = 0; int skipAhead = 0; static bool inPara = false; + Node::Genus genus = Node::DontCare; switch (atom->type()) { case Atom::AutoLink: + // Allow auto-linking to nodes in API reference + genus = Node::API; + Q_FALLTHROUGH(); case Atom::NavAutoLink: if (!inLink && !m_inContents && !m_inSectionHeading) { const Node *node = nullptr; - QString link = getAutoLink(atom, relative, &node); + QString link = getAutoLink(atom, relative, &node, genus); if (!link.isEmpty() && node && node->status() == Node::Obsolete && relative->parent() != node && !relative->isObsolete()) { link.clear(); diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp index 8d58a9616..994e2af47 100644 --- a/src/qdoc/htmlgenerator.cpp +++ b/src/qdoc/htmlgenerator.cpp @@ -299,6 +299,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark { int idx, skipAhead = 0; static bool in_para = false; + Node::Genus genus = Node::DontCare; switch (atom->type()) { case Atom::AutoLink: { @@ -307,12 +308,14 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark out() << protectEnc(atom->string()); break; } + // Allow auto-linking to nodes in API reference + genus = Node::API; } Q_FALLTHROUGH(); case Atom::NavAutoLink: if (!m_inLink && !m_inContents && !m_inSectionHeading) { const Node *node = nullptr; - QString link = getAutoLink(atom, relative, &node); + QString link = getAutoLink(atom, relative, &node, genus); if (link.isEmpty()) { if (autolinkErrors()) relative->doc().location().warning( diff --git a/src/qdoc/node.h b/src/qdoc/node.h index c69b69255..acf7c27af 100644 --- a/src/qdoc/node.h +++ b/src/qdoc/node.h @@ -107,7 +107,14 @@ public: LastType }; - enum Genus : unsigned char { DontCare, CPP, JS, QML, DOC }; + enum Genus : unsigned char { + DontCare = 0x0, + CPP = 0x1, + JS = 0x2, + QML = 0x4, + DOC = 0x8, + API = CPP | JS | QML + }; enum Status : unsigned char { Obsolete, diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp index 9df6532d7..3b189fad5 100644 --- a/src/qdoc/qdocdatabase.cpp +++ b/src/qdoc/qdocdatabase.cpp @@ -1508,15 +1508,16 @@ void QDocDatabase::mergeCollections(CollectionNode *c) } /*! - 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) + Searches for the node that matches the path in \a atom and the + specified \a genus. The \a relative node is used if the first + leg of the path is empty, i.e. if the path begins with '#'. + 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 also not valid. + */ +const Node *QDocDatabase::findNodeForAtom(const Atom *a, const Node *relative, QString &ref, + Node::Genus genus) { const Node *node = nullptr; @@ -1525,7 +1526,6 @@ const Node *QDocDatabase::findNodeForAtom(const Atom *a, const Node *relative, Q QString first = targetPath.first().trimmed(); Tree *domain = nullptr; - Node::Genus genus = Node::DontCare; if (atom->isLinkAtom()) { domain = atom->domain(); diff --git a/src/qdoc/qdocdatabase.h b/src/qdoc/qdocdatabase.h index 5d85b9d68..6d11242fc 100644 --- a/src/qdoc/qdocdatabase.h +++ b/src/qdoc/qdocdatabase.h @@ -308,9 +308,10 @@ public: /*******************************************************************/ /***************************************************************************** - This function can handle parameters enclosed in '[' ']' (domanin and genus). + This function can handle parameters enclosed in '[' ']' (domain and genus). ******************************************************************************/ - const Node *findNodeForAtom(const Atom *atom, const Node *relative, QString &ref); + const Node *findNodeForAtom(const Atom *atom, const Node *relative, QString &ref, + Node::Genus genus = Node::DontCare); /*******************************************************************/ /******************************************************************* diff --git a/src/qdoc/tree.cpp b/src/qdoc/tree.cpp index 138798d20..9d220d9d7 100644 --- a/src/qdoc/tree.cpp +++ b/src/qdoc/tree.cpp @@ -595,7 +595,7 @@ const Node *Tree::matchPathAndTarget(const QStringList &path, int idx, const QSt NodeVector nodes; static_cast<const Aggregate *>(node)->findChildren(name, nodes); for (const auto *node : qAsConst(nodes)) { - if (genus != Node::DontCare && node->genus() != genus) + if (genus != Node::DontCare && !(genus & node->genus())) continue; const Node *t = matchPathAndTarget(path, idx + 1, target, node, flags, genus, ref); if (t && !t->isPrivate()) @@ -830,7 +830,7 @@ const Node *Tree::findUnambiguousTarget(const QString &target, Node::Genus genus if (it.key() != key) break; TargetRec *candidate = it.value(); - if ((genus == Node::DontCare) || (genus == candidate->genus())) { + if ((genus == Node::DontCare) || (genus & candidate->genus())) { if (!bestTarget || (candidate->priority_ < bestTarget->priority_)) { bestTarget = candidate; bestTargetList.clear(); @@ -854,7 +854,7 @@ const Node *Tree::findUnambiguousTarget(const QString &target, Node::Genus genus if (it.key() != key) break; TargetRec *candidate = it.value(); - if ((genus == Node::DontCare) || (genus == candidate->genus())) { + if ((genus == Node::DontCare) || (genus & candidate->genus())) { if (!bestTarget || (candidate->priority_ < bestTarget->priority_)) { bestTarget = candidate; bestTargetList.clear(); @@ -1216,7 +1216,7 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, const Parame if (relative == nullptr) relative = root(); else if (genus != Node::DontCare) { - if (genus != relative->genus()) + if (!(genus & relative->genus())) relative = root(); } diff --git a/src/qdoc/webxmlgenerator.cpp b/src/qdoc/webxmlgenerator.cpp index 8befa6642..08e5d06d0 100644 --- a/src/qdoc/webxmlgenerator.cpp +++ b/src/qdoc/webxmlgenerator.cpp @@ -301,7 +301,7 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer, const Ato case Atom::AutoLink: if (!m_inLink && !m_inSectionHeading) { const Node *node = nullptr; - QString link = getLink(atom, relative, &node); + QString link = getAutoLink(atom, relative, &node, Node::API); if (node) { startLink(writer, atom, node, link); if (m_inLink) { diff --git a/src/qdoc/xmlgenerator.cpp b/src/qdoc/xmlgenerator.cpp index d161e5693..e5d879e5e 100644 --- a/src/qdoc/xmlgenerator.cpp +++ b/src/qdoc/xmlgenerator.cpp @@ -405,11 +405,12 @@ QString XmlGenerator::getLink(const Atom *atom, const Node *relative, const Node to the node holding the qdoc comment where the link command was found. */ -QString XmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const Node **node) +QString XmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const Node **node, + Node::Genus genus) { QString ref; - *node = m_qdb->findNodeForAtom(atom, relative, ref); + *node = m_qdb->findNodeForAtom(atom, relative, ref, genus); if (!(*node)) return QString(); diff --git a/src/qdoc/xmlgenerator.h b/src/qdoc/xmlgenerator.h index 0397096c5..a57648412 100644 --- a/src/qdoc/xmlgenerator.h +++ b/src/qdoc/xmlgenerator.h @@ -59,7 +59,8 @@ protected: QString refForNode(const Node *node); QString linkForNode(const Node *node, const Node *relative); QString getLink(const Atom *atom, const Node *relative, const Node **node); - QString getAutoLink(const Atom *atom, const Node *relative, const Node **node); + QString getAutoLink(const Atom *atom, const Node *relative, const Node **node, + Node::Genus = Node::DontCare); QPair<QString, QString> anchorForNode(const Node *node); |