summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarco Benelli <marco.benelli@qt.io>2017-07-14 11:19:54 +0200
committerTopi Reinio <topi.reinio@qt.io>2020-09-26 17:33:46 +0200
commit8b962f66637b9a9474c40f2889c50cdc505e59d4 (patch)
treecdfa167f9f674de3c10a53f1b14e40f4c9601134 /src
parentf4aab8114032984a2456262f75152361e932951c (diff)
downloadqttools-8b962f66637b9a9474c40f2889c50cdc505e59d4.tar.gz
qdoc: include QML import + major version number in keyword
The QML import and major version number is needed to disambiguate components with the same name that belongs to distincts modules. The unqualified keyword is kept for retro-compatibility. Task-number: QTBUG-61876 Change-Id: Id886f8fb6ecbad7a9cccd05025709ba6eab13093 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qdoc/helpprojectwriter.cpp111
-rw-r--r--src/qdoc/helpprojectwriter.h23
2 files changed, 73 insertions, 61 deletions
diff --git a/src/qdoc/helpprojectwriter.cpp b/src/qdoc/helpprojectwriter.cpp
index 95b87d76f..ce20095d7 100644
--- a/src/qdoc/helpprojectwriter.cpp
+++ b/src/qdoc/helpprojectwriter.cpp
@@ -195,44 +195,37 @@ void HelpProjectWriter::addExtraFiles(const QSet<QString> &files)
projects[i].extraFiles.unite(files);
}
-/*!
- Returns a list of strings describing the keyword details for a given node.
-
- The first string is the human-readable name to be shown in Assistant.
- The second string is a unique identifier.
- The third string is the location of the documentation for the keyword.
- */
-QStringList HelpProjectWriter::keywordDetails(const Node *node) const
+Keyword HelpProjectWriter::keywordDetails(const Node *node) const
{
- QStringList details;
+ QString ref = gen_->fullDocumentLocation(node, false);
if (node->parent() && !node->parent()->name().isEmpty()) {
- // "name"
- if (node->isEnumType() || node->isTypedef())
- details << node->parent()->name() + "::" + node->name();
- else
- details << node->name();
- // "id"
- if (!node->isRelatedNonmember())
- details << node->parent()->name() + "::" + node->name();
- else
- details << node->name();
+ QString name = (node->isEnumType() || node->isTypedef())
+ ? node->parent()->name()+"::"+node->name()
+ : node->name();
+ QString id = (!node->isRelatedNonmember())
+ ? node->parent()->name()+"::"+node->name()
+ : node->name();
+ return Keyword(name, id, ref);
} else if (node->isQmlType() || node->isQmlBasicType()) {
- details << node->name();
- details << "QML." + node->name();
+ QString name = node->name();
+ QString moduleName = node->logicalModuleName();
+ QStringList ids("QML." + name);
+ if (!moduleName.isEmpty()) {
+ QString majorVersion = node->logicalModule()
+ ? node->logicalModule()->logicalModuleVersion().split('.')[0]
+ : QString();
+ ids << "QML." + moduleName + majorVersion + "." + name;
+ }
+ return Keyword(name, ids, ref);
} else if (node->isJsType() || node->isJsBasicType()) {
- details << node->name();
- details << "JS." + node->name();
+ return Keyword(node->name(), "JS." + node->name(), ref);
} else if (node->isTextPageNode()) {
- const PageNode *fake = static_cast<const PageNode *>(node);
- details << fake->fullTitle();
- details << fake->fullTitle();
+ const auto *pageNode = static_cast<const PageNode *>(node);
+ return Keyword(pageNode->fullTitle(), pageNode->fullTitle(), ref);
} else {
- details << node->name();
- details << node->name();
+ return Keyword(node->name(), node->name(), ref);
}
- details << gen_->fullDocumentLocation(node, false);
- return details;
}
bool HelpProjectWriter::generateSection(HelpProject &project, QXmlStreamWriter & /* writer */,
@@ -300,11 +293,11 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QXmlStreamWriter &
const auto keywords = node->doc().keywords();
for (const Atom *keyword : keywords) {
if (!keyword->string().isEmpty()) {
- QStringList details;
- details << keyword->string() << keyword->string()
- << gen_->fullDocumentLocation(node, false);
- project.keywords.append(details);
- } else
+ project.keywords.append(Keyword(keyword->string(),
+ keyword->string(),
+ gen_->fullDocumentLocation(node, false)));
+ }
+ else
node->doc().location().warning(
QStringLiteral("Bad keyword in %1")
.arg(gen_->fullDocumentLocation(node, false)));
@@ -328,15 +321,15 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QXmlStreamWriter &
if (enumNode->itemAccess(item.name()) == Access::Private)
continue;
+ QString name;
+ QString id;
if (!node->parent()->name().isEmpty()) {
- details << node->parent()->name() + "::" + item.name(); // "name"
- details << node->parent()->name() + "::" + item.name(); // "id"
+ name = id = node->parent()->name() + "::" + item.name();
} else {
- details << item.name(); // "name"
- details << item.name(); // "id"
+ name = id = item.name();
}
- details << gen_->fullDocumentLocation(node, false);
- project.keywords.append(details);
+ QString ref = gen_->fullDocumentLocation(node, false);
+ project.keywords.append(Keyword(name, id, ref));
}
}
break;
@@ -345,16 +338,15 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QXmlStreamWriter &
case Node::Module:
case Node::QmlModule:
case Node::JsModule: {
- const CollectionNode *cn = static_cast<const CollectionNode *>(node);
+ const auto *cn = static_cast<const CollectionNode *>(node);
if (!cn->fullTitle().isEmpty()) {
if (cn->doc().hasKeywords()) {
const auto keywords = cn->doc().keywords();
for (const Atom *keyword : keywords) {
if (!keyword->string().isEmpty()) {
- QStringList details;
- details << keyword->string() << keyword->string()
- << gen_->fullDocumentLocation(node, false);
- project.keywords.append(details);
+ project.keywords.append(Keyword(keyword->string(),
+ keyword->string(),
+ gen_->fullDocumentLocation(node, false)));
} else
cn->doc().location().warning(
QStringLiteral("Bad keyword in %1")
@@ -403,12 +395,12 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QXmlStreamWriter &
case Node::TypeAlias:
case Node::Typedef: {
const TypedefNode *typedefNode = static_cast<const TypedefNode *>(node);
- QStringList typedefDetails = keywordDetails(node);
+ Keyword typedefDetails = keywordDetails(node);
const EnumNode *enumNode = typedefNode->associatedEnum();
// Use the location of any associated enum node in preference
// to that of the typedef.
if (enumNode)
- typedefDetails[2] = gen_->fullDocumentLocation(enumNode, false);
+ typedefDetails.ref = gen_->fullDocumentLocation(enumNode, false);
project.keywords.append(typedefDetails);
} break;
@@ -420,16 +412,15 @@ bool HelpProjectWriter::generateSection(HelpProject &project, QXmlStreamWriter &
// Page nodes (such as manual pages) contain subtypes, titles and other
// attributes.
case Node::Page: {
- const PageNode *pn = static_cast<const PageNode *>(node);
+ const auto *pn = static_cast<const PageNode *>(node);
if (!pn->fullTitle().isEmpty()) {
if (pn->doc().hasKeywords()) {
const auto keywords = pn->doc().keywords();
for (const Atom *keyword : keywords) {
if (!keyword->string().isEmpty()) {
- QStringList details;
- details << keyword->string() << keyword->string()
- << gen_->fullDocumentLocation(node, false);
- project.keywords.append(details);
+ project.keywords.append(Keyword(keyword->string(),
+ keyword->string(),
+ gen_->fullDocumentLocation(node, false)));
} else {
QString loc = gen_->fullDocumentLocation(node, false);
pn->doc().location().warning(QStringLiteral("Bad keyword in %1").arg(loc));
@@ -798,12 +789,14 @@ void HelpProjectWriter::generateProject(HelpProject &project)
writer.writeStartElement("keywords");
std::sort(project.keywords.begin(), project.keywords.end());
- for (const QStringList &details : qAsConst(project.keywords)) {
- writer.writeStartElement("keyword");
- writer.writeAttribute("name", details[0]);
- writer.writeAttribute("id", details[1]);
- writer.writeAttribute("ref", details[2]);
- writer.writeEndElement(); // keyword
+ for (const auto &k : qAsConst(project.keywords)) {
+ for (const auto &id : qAsConst(k.ids)) {
+ writer.writeStartElement("keyword");
+ writer.writeAttribute("name", k.name);
+ writer.writeAttribute("id", id);
+ writer.writeAttribute("ref", k.ref);
+ writer.writeEndElement(); //keyword
+ }
}
writer.writeEndElement(); // keywords
diff --git a/src/qdoc/helpprojectwriter.h b/src/qdoc/helpprojectwriter.h
index b9f310fd9..332140124 100644
--- a/src/qdoc/helpprojectwriter.h
+++ b/src/qdoc/helpprojectwriter.h
@@ -53,6 +53,24 @@ struct SubProject
QStringList groups;
};
+/*
+ * Name is the human-readable name to be shown in Assistant.
+ * Ids is a list of unique identifiers.
+ * Ref is the location of the documentation for the keyword.
+ */
+struct Keyword {
+ QString name;
+ QStringList ids;
+ QString ref;
+ Keyword(QString name, QString id, QString ref) : name(name), ids(QStringList(id)), ref(ref) {}
+ Keyword(QString name, QStringList ids, QString ref) : name(name), ids(ids), ref(ref) {}
+ bool operator<(const Keyword &o) const
+ {
+ // Order by name; use id as a secondary sort key
+ return (name == o.name) ? ids.last() < o.ids.last() : name < o.name;
+ }
+};
+
struct HelpProject
{
using NodeStatusSet = QSet<unsigned char>;
@@ -64,7 +82,7 @@ struct HelpProject
QString fileName;
QString indexRoot;
QString indexTitle;
- QList<QStringList> keywords;
+ QList<Keyword> keywords;
QSet<QString> files;
QSet<QString> extraFiles;
QSet<QString> filterAttributes;
@@ -75,6 +93,7 @@ struct HelpProject
bool includeIndexNodes;
};
+
class HelpProjectWriter
{
public:
@@ -88,7 +107,7 @@ private:
void generateProject(HelpProject &project);
void generateSections(HelpProject &project, QXmlStreamWriter &writer, const Node *node);
bool generateSection(HelpProject &project, QXmlStreamWriter &writer, const Node *node);
- QStringList keywordDetails(const Node *node) const;
+ Keyword keywordDetails(const Node *node) const;
void writeHashFile(QFile &file);
void writeNode(HelpProject &project, QXmlStreamWriter &writer, const Node *node);
void readSelectors(SubProject &subproject, const QStringList &selectors);