diff options
author | Marco Benelli <marco.benelli@qt.io> | 2017-07-14 11:19:54 +0200 |
---|---|---|
committer | Topi Reinio <topi.reinio@qt.io> | 2020-09-26 17:33:46 +0200 |
commit | 8b962f66637b9a9474c40f2889c50cdc505e59d4 (patch) | |
tree | cdfa167f9f674de3c10a53f1b14e40f4c9601134 /src | |
parent | f4aab8114032984a2456262f75152361e932951c (diff) | |
download | qttools-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.cpp | 111 | ||||
-rw-r--r-- | src/qdoc/helpprojectwriter.h | 23 |
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); |