From 46959875cf7ddeb9bbcee883e4bfaef63992b870 Mon Sep 17 00:00:00 2001
From: Martin Smith
Date: Fri, 23 May 2014 13:26:36 +0200
Subject: qdoc: Give documenter more control of linking
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This update is preparation for implementing the actual task
described in the bug. To implement it required converting
the QML type node and the QML basic type node to be first
order tree nodes instead of subtypes of the documentation
node. This cleans up a lot of messy logic in some places.
It was also necessary to split the getLink() function in the
html output generator into two functions, one still called
getLink(), which handles the \l command, and one called
qetAutoLink() which is called for generating auto links.
This should make qdoc run faster.
The basic infrastructure was also added for parsing the
string in the square brackets for the \l command.
There will be a further update to complete this task.
Note that some autolinks might not be generated due to
this change. I haven't seen any yet, but I believe there
will be some. This can be fixed later, if it is a problem.
Task-number: QTBUG-39221
Change-Id: I8135229984398408205ba901b9ef95ceac74683c
Reviewed-by: Topi Reiniƶ
---
src/tools/qdoc/atom.cpp | 47 ++--
src/tools/qdoc/atom.h | 54 ++--
src/tools/qdoc/codemarker.cpp | 17 +-
src/tools/qdoc/cppcodeparser.cpp | 15 +-
src/tools/qdoc/ditaxmlgenerator.cpp | 153 +++++++-----
src/tools/qdoc/ditaxmlgenerator.h | 1 +
src/tools/qdoc/doc.cpp | 81 +++++-
src/tools/qdoc/generator.cpp | 117 +++++----
src/tools/qdoc/generator.h | 4 +-
src/tools/qdoc/helpprojectwriter.cpp | 65 +++--
src/tools/qdoc/htmlgenerator.cpp | 470 ++++++++++++++++++++---------------
src/tools/qdoc/htmlgenerator.h | 3 +
src/tools/qdoc/main.cpp | 8 +-
src/tools/qdoc/node.cpp | 110 +++++---
src/tools/qdoc/node.h | 26 +-
src/tools/qdoc/qdocdatabase.cpp | 55 ++--
src/tools/qdoc/qdocdatabase.h | 40 +--
src/tools/qdoc/qdocindexfiles.cpp | 60 ++---
src/tools/qdoc/qmlvisitor.cpp | 12 +-
src/tools/qdoc/tree.cpp | 76 +++---
src/tools/qdoc/tree.h | 11 +-
21 files changed, 816 insertions(+), 609 deletions(-)
(limited to 'src/tools')
diff --git a/src/tools/qdoc/atom.cpp b/src/tools/qdoc/atom.cpp
index 6f9da3790d..8816ea5d6f 100644
--- a/src/tools/qdoc/atom.cpp
+++ b/src/tools/qdoc/atom.cpp
@@ -42,31 +42,12 @@
#include
#include "atom.h"
#include "location.h"
+#include "qdocdatabase.h"
#include
+#include
QT_BEGIN_NAMESPACE
-QLatin1String Atom::BOLD_ ("bold");
-QLatin1String Atom::INDEX_ ("index");
-QLatin1String Atom::ITALIC_ ("italic");
-QLatin1String Atom::LINK_ ("link");
-QLatin1String Atom::PARAMETER_ ("parameter");
-QLatin1String Atom::SPAN_ ("span");
-QLatin1String Atom::SUBSCRIPT_ ("subscript");
-QLatin1String Atom::SUPERSCRIPT_ ("superscript");
-QLatin1String Atom::TELETYPE_ ("teletype");
-QLatin1String Atom::UICONTROL_ ("uicontrol");
-QLatin1String Atom::UNDERLINE_ ("underline");
-
-QLatin1String Atom::BULLET_ ("bullet");
-QLatin1String Atom::TAG_ ("tag");
-QLatin1String Atom::VALUE_ ("value");
-QLatin1String Atom::LOWERALPHA_ ("loweralpha");
-QLatin1String Atom::LOWERROMAN_ ("lowerroman");
-QLatin1String Atom::NUMERIC_ ("numeric");
-QLatin1String Atom::UPPERALPHA_ ("upperalpha");
-QLatin1String Atom::UPPERROMAN_ ("upperroman");
-
/*! \class Atom
\brief The Atom class is the fundamental unit for representing
documents internally.
@@ -387,4 +368,28 @@ void Atom::dump() const
str.toLatin1().data());
}
+/*!
+ The only constructor for LinkAtom. It only create an Atom
+ of type Atom::Link with \a p1 being the link text. \a p2
+ contains some search parameters.
+ */
+LinkAtom::LinkAtom(const QString& p1, const QString& p2)
+ : Atom(Link, p1), qml_(false), goal_(Node::NoType), domain_(0)
+{
+ QStringList params = p2.toLower().split(QLatin1Char(' '));
+ foreach (const QString& p, params) {
+ if (p == "qml")
+ qml_ = true;
+ else {
+ if (!domain_) {
+ domain_ = QDocDatabase::qdocDB()->findTree(p);
+ if (domain_)
+ continue;
+ }
+ if (goal_ == Node::NoType)
+ goal_ = Node::goal(p);
+ }
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/atom.h b/src/tools/qdoc/atom.h
index 84a52c9257..999919482b 100644
--- a/src/tools/qdoc/atom.h
+++ b/src/tools/qdoc/atom.h
@@ -39,17 +39,16 @@
**
****************************************************************************/
-/*
- atom.h
-*/
-
#ifndef ATOM_H
#define ATOM_H
#include
+#include "node.h"
QT_BEGIN_NAMESPACE
+class Tree;
+
class Atom
{
public:
@@ -169,6 +168,8 @@ public:
previous->next_ = this;
}
+ virtual ~Atom() { }
+
void appendChar(QChar ch) { strs[0] += ch; }
void appendString(const QString& string) { strs[0] += string; }
void chopString() { strs[0].chop(1); }
@@ -186,33 +187,34 @@ public:
int count() const { return strs.size(); }
void dump() const;
- static QLatin1String BOLD_;
- static QLatin1String INDEX_;
- static QLatin1String ITALIC_;
- static QLatin1String LINK_;
- static QLatin1String PARAMETER_;
- static QLatin1String SPAN_;
- static QLatin1String SUBSCRIPT_;
- static QLatin1String SUPERSCRIPT_;
- static QLatin1String TELETYPE_;
- static QLatin1String UICONTROL_;
- static QLatin1String UNDERLINE_;
-
- static QLatin1String BULLET_;
- static QLatin1String TAG_;
- static QLatin1String VALUE_;
- static QLatin1String LOWERALPHA_;
- static QLatin1String LOWERROMAN_;
- static QLatin1String NUMERIC_;
- static QLatin1String UPPERALPHA_;
- static QLatin1String UPPERROMAN_;
-
-private:
+ virtual bool qml() const { return false; }
+ virtual bool specifiesDomain() const { return false; }
+ virtual Tree* domain() const { return 0; }
+ virtual Node::Type goal() const { return Node::NoType; }
+
+ protected:
Atom* next_;
Type type_;
QStringList strs;
};
+class LinkAtom : public Atom
+{
+ public:
+ LinkAtom(const QString& p1, const QString& p2);
+ virtual ~LinkAtom() { }
+
+ virtual bool qml() const { return qml_; }
+ virtual bool specifiesDomain() const { return (domain_ != 0); }
+ virtual Tree* domain() const { return domain_; }
+ virtual Node::Type goal() const { return goal_; }
+
+ protected:
+ bool qml_;
+ Node::Type goal_;
+ Tree* domain_;
+};
+
#define ATOM_FORMATTING_BOLD "bold"
#define ATOM_FORMATTING_INDEX "index"
#define ATOM_FORMATTING_ITALIC "italic"
diff --git a/src/tools/qdoc/codemarker.cpp b/src/tools/qdoc/codemarker.cpp
index ec342c6df0..235b3c3f04 100644
--- a/src/tools/qdoc/codemarker.cpp
+++ b/src/tools/qdoc/codemarker.cpp
@@ -273,7 +273,7 @@ QString CodeMarker::taggedNode(const Node* node)
case Node::Property:
tag = QLatin1String("@property");
break;
- case Node::Document:
+ case Node::QmlType:
/*
Remove the "QML:" prefix, if present.
There shouldn't be any of these "QML:"
@@ -282,10 +282,11 @@ QString CodeMarker::taggedNode(const Node* node)
qualifiers, but this code is kept to
be backward compatible.
*/
- if (node->subType() == Node::QmlClass) {
- if (node->name().startsWith(QLatin1String("QML:")))
- name = name.mid(4);
- }
+ if (node->name().startsWith(QLatin1String("QML:")))
+ name = name.mid(4);
+ tag = QLatin1String("@property");
+ break;
+ case Node::Document:
tag = QLatin1String("@property");
break;
case Node::QmlMethod:
@@ -400,9 +401,8 @@ void CodeMarker::insert(FastSection &fastSection,
InnerNode* p = node->parent();
if (p->type() == Node::QmlPropertyGroup)
p = p->parent();
- if (p != fastSection.parent_) { // && !node->parent()->isAbstract()) {
- if (p->subType() != Node::QmlClass || !p->isAbstract()) {
- //if (node->type() != Node::QmlProperty) {
+ if (p != fastSection.parent_) {
+ if (!p->isQmlType() || !p->isAbstract()) {
inheritedMember = true;
}
}
@@ -622,6 +622,7 @@ QStringList CodeMarker::macRefsForNode(Node *node)
}
case Node::Namespace:
case Node::Document:
+ case Node::QmlType:
default:
return QStringList();
}
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp
index cda541c928..2755bf7254 100644
--- a/src/tools/qdoc/cppcodeparser.cpp
+++ b/src/tools/qdoc/cppcodeparser.cpp
@@ -408,17 +408,13 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
without including the namespace qualifier.
*/
Node::Type type = nodeTypeMap[command];
- Node::SubType subtype = Node::NoSubType;
- if (type == Node::Document)
- subtype = Node::QmlClass;
-
QStringList paths = arg.first.split(QLatin1Char(' '));
QStringList path = paths[0].split("::");
Node *node = 0;
- node = qdb_->findNodeInOpenNamespace(path, type, subtype);
+ node = qdb_->findNodeInOpenNamespace(path, type);
if (node == 0)
- node = qdb_->findNodeByNameAndType(path, type, subtype);
+ node = qdb_->findNodeByNameAndType(path, type);
if (node == 0) {
doc.location().warning(tr("Cannot find '%1' specified with '\\%2' in any header file")
.arg(arg.first).arg(command));
@@ -971,14 +967,14 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
else if (command == COMMAND_QMLINHERITS) {
if (node->name() == arg)
doc.location().warning(tr("%1 tries to inherit itself").arg(arg));
- else if (node->subType() == Node::QmlClass) {
+ else if (node->isQmlType()) {
QmlClassNode *qmlClass = static_cast(node);
qmlClass->setQmlBaseName(arg);
QmlClassNode::addInheritedBy(arg,node);
}
}
else if (command == COMMAND_QMLINSTANTIATES) {
- if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
+ if (node->isQmlType()) {
ClassNode* classNode = qdb_->findClassNode(arg.split("::"));
if (classNode)
node->setClassNode(classNode);
@@ -1023,9 +1019,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
}
}
else if (command == COMMAND_QMLABSTRACT) {
- if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
+ if (node->isQmlType())
node->setAbstract(true);
- }
}
else {
processCommonMetaCommand(doc.location(),command,argLocPair,node);
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp
index 90661d80e0..bbd32204ce 100644
--- a/src/tools/qdoc/ditaxmlgenerator.cpp
+++ b/src/tools/qdoc/ditaxmlgenerator.cpp
@@ -819,7 +819,6 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
}
break;
case Atom::BriefRight:
- // if (relative->type() != Node::Document)
writeEndTag(); // or
if (in_para)
in_para = false;
@@ -1106,10 +1105,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
while (n != nsmap.constEnd()) {
const Node* node = n.value();
switch (node->type()) {
- case Node::Document:
- if (node->subType() == Node::QmlClass) {
- sections[QmlClass].appendMember((Node*)node);
- }
+ case Node::QmlType:
+ sections[QmlClass].appendMember((Node*)node);
break;
case Node::Namespace:
sections[Namespace].appendMember((Node*)node);
@@ -1256,8 +1253,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
images.append(QLatin1Char('/'));
fileName = images + atom->string();
}
- if (relative && (relative->type() == Node::Document) &&
- (relative->subType() == Node::Example)) {
+ if (relative && relative->isExample()) {
const ExampleNode* cen = static_cast(relative);
if (cen->imageFileName().isEmpty()) {
ExampleNode* en = const_cast(cen);
@@ -1313,8 +1309,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
{
const Node *node = 0;
QString myLink = getLink(atom, relative, &node);
- if (myLink.isEmpty())
- myLink = getCollisionLink(atom);
+ //if (myLink.isEmpty())
+ //myLink = getCollisionLink(atom);
if (myLink.isEmpty() && !noLinkErrors())
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
else if (!inSectionHeading_)
@@ -2052,7 +2048,7 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
generateLowStatusMembers(inner,marker,CodeMarker::Compat);
writeEndTag(); //
}
- else if ((inner->type() == Node::Document) && (inner->subType() == Node::HeaderFile)) {
+ else if (inner->isHeaderFile()) {
const DocNode* dn = const_cast(static_cast(inner));
rawTitle = inner->plainName();
fullTitle = inner->plainFullName();
@@ -2168,7 +2164,7 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
generateLowStatusMembers(inner,marker,CodeMarker::Compat);
writeEndTag(); //
}
- else if ((inner->type() == Node::Document) && (inner->subType() == Node::QmlClass)) {
+ else if (inner->isQmlType()) {
QmlClassNode* qcn = const_cast(static_cast(inner));
ClassNode* cn = qcn->classNode();
rawTitle = inner->plainName();
@@ -2216,6 +2212,36 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
}
}
+/*!
+ Generate the DITA page for a qdoc file that doesn't map
+ to an underlying c++ file.
+ */
+void DitaXmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker)
+{
+ QList sections;
+ QList::const_iterator s;
+ QString fullTitle = "QML Basic Type: " + qbtn->fullTitle();
+
+ generateHeader(qbtn, fullTitle);
+ generateBrief(qbtn, marker); //
+ writeProlog(qbtn);
+
+ writeStartTag(DT_body);
+ enterSection(QString(), QString());
+
+ if (!qbtn->doc().isEmpty()) {
+ generateBody(qbtn, marker);
+ generateAlsoList(qbtn, marker);
+ }
+ leaveSection(); //
+ if (!writeEndTag()) { //