qdoc: Improve searching of collection nodes

QDocDatabase provided a way to search for a collection node in
the primary tree only. This was insufficient for use cases where
we want to list groups, C++ classes or QML types in other modules
using the \generatelist or \annotatedlist commands.

This commit does the following changes:
    - Add a function to find a collection node across all
      trees, use it for generating output for the list commands
      and generating C++ class/QML/JS type requisite tables.
    - Modify the code for \generatelist command to accept
      'qmltypesbymodule' and 'jstypesbymodule' as parameters.
    - Modify constness of some functions to enable above
      changes.

Change-Id: I3dbdadfd224754db4bdc1602a5ffab9d46c51f00
Reviewed-by: Martin Smith <martin.smith@digia.com>
This commit is contained in:
Topi Reinio 2015-06-09 10:59:10 +02:00 committed by Topi Reiniö
parent 80dbdf0de3
commit 7a85be3371
5 changed files with 50 additions and 26 deletions

View File

@ -3452,6 +3452,20 @@
with the \l {inmodule-command} {\\inmodule} command in its \\class
comment.
\section2 \c qmltypesbymodule
Similar to \c classesbymodule argument, but used for listing the
QML types from the QML module specified with the second argument.
\note Support for this argument was introduced in QDoc 5.6.
\section2 \c jstypesbymodule
Similar to \c classesbymodule argument, but used for listing the
JavaScript types from the module specified with the second argument.
\note Support for this argument was introduced in QDoc 5.6.
\section2 \c compatclasses
The \c compatclasses argument generates a list in alphabetical

View File

@ -471,7 +471,7 @@ QString HtmlGenerator::generateLinksToBrokenLinksPage(CodeMarker* marker, int& c
*/
int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker)
{
int skipAhead = 0;
int idx, skipAhead = 0;
static bool in_para = false;
switch (atom->type()) {
@ -661,7 +661,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
break;
case Atom::AnnotatedList:
{
CollectionNode* cn = qdb_->getCollection(atom->string(), Node::DOC);
const CollectionNode* cn = qdb_->getCollectionNode(atom->string(), Node::DOC);
if (cn)
generateList(cn, marker, atom->string());
}
@ -683,16 +683,25 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
else if (atom->string() == QLatin1String("qmltypes")) {
generateCompactList(Generic, relative, qdb_->getQmlTypes(), true, QStringLiteral(""));
}
else if (atom->string().contains("classesbymodule")) {
QString physicalModuleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed();
else if ((idx = atom->string().indexOf(QStringLiteral("bymodule"))) != -1) {
QString moduleName = atom->string().mid(idx + 8).trimmed();
Node::Genus genus = Node::CPP;
if (atom->string().startsWith(QStringLiteral("qml")))
genus = Node::QML;
else if (atom->string().startsWith(QStringLiteral("js")))
genus = Node::JS;
QDocDatabase* qdb = QDocDatabase::qdocDB();
CollectionNode* cn = qdb->findModule(physicalModuleName);
const CollectionNode* cn = qdb->getCollectionNode(moduleName, genus);
if (cn) {
NodeMap m;
cn->getMemberClasses(m);
if (!m.isEmpty()) {
generateAnnotatedList(relative, marker, m);
if (genus == Node::CPP) {
NodeMap m;
cn->getMemberClasses(m);
if (!m.isEmpty()) {
generateAnnotatedList(relative, marker, m);
}
}
else
generateAnnotatedList(relative, marker, cn->members());
}
}
else if (atom->string() == QLatin1String("classhierarchy")) {
@ -2131,7 +2140,7 @@ void HtmlGenerator::generateRequisites(Aggregate *inner, CodeMarker *marker)
if (inner->type() == Node::Class || inner->type() == Node::Namespace) {
//add the QT variable to the map
if (!inner->physicalModuleName().isEmpty()) {
CollectionNode* cn = qdb_->findModule(inner->physicalModuleName());
const CollectionNode* cn = qdb_->getCollectionNode(inner->physicalModuleName(), Node::CPP);
if (cn && !cn->qtVariable().isEmpty()) {
text.clear();
text << "QT += " + cn->qtVariable();
@ -2241,11 +2250,7 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker)
//add the module name and version to the map
QString logicalModuleVersion;
CollectionNode* collection = 0;
if (qcn->isJsNode())
collection = qdb_->findJsModule(qcn->logicalModuleName());
else
collection = qdb_->findQmlModule(qcn->logicalModuleName());
const CollectionNode* collection = qdb_->getCollectionNode(qcn->logicalModuleName(), qcn->genus());
if (collection)
logicalModuleVersion = collection->logicalModuleVersion();
else

View File

@ -2838,7 +2838,7 @@ void CollectionNode::getMemberNamespaces(NodeMap& out)
Loads \a out with all this collection node's members that
are class nodes.
*/
void CollectionNode::getMemberClasses(NodeMap& out)
void CollectionNode::getMemberClasses(NodeMap& out) const
{
out.clear();
NodeList::const_iterator i = members_.cbegin();

View File

@ -245,7 +245,7 @@ public:
virtual QmlPropertyNode* hasQmlProperty(const QString& ) const { return 0; }
virtual QmlPropertyNode* hasQmlProperty(const QString&, bool ) const { return 0; }
virtual void getMemberNamespaces(NodeMap& ) { }
virtual void getMemberClasses(NodeMap& ) { }
virtual void getMemberClasses(NodeMap& ) const { }
virtual bool isInternal() const;
virtual void setDataType(const QString& ) { }
virtual void setReadOnly(bool ) { }
@ -1118,7 +1118,7 @@ class CollectionNode : public Aggregate
virtual bool hasNamespaces() const Q_DECL_OVERRIDE;
virtual bool hasClasses() const Q_DECL_OVERRIDE;
virtual void getMemberNamespaces(NodeMap& out) Q_DECL_OVERRIDE;
virtual void getMemberClasses(NodeMap& out) Q_DECL_OVERRIDE;
virtual void getMemberClasses(NodeMap& out) const Q_DECL_OVERRIDE;
virtual bool wasSeen() const Q_DECL_OVERRIDE { return seen_; }
virtual QString title() const Q_DECL_OVERRIDE { return title_; }
virtual QString subTitle() const Q_DECL_OVERRIDE { return subtitle_; }

View File

@ -177,6 +177,16 @@ class QDocForest
return 0;
}
const CollectionNode* getCollectionNode(const QString& name, Node::Genus genus)
{
foreach (Tree* t, searchOrder()) {
const CollectionNode* cn = t->getCollection(name, genus);
if (cn)
return cn;
}
return 0;
}
QmlTypeNode* lookupQmlType(const QString& name)
{
foreach (Tree* t, searchOrder()) {
@ -221,19 +231,11 @@ class QDocDatabase
Tree* findTree(const QString& t) { return forest_.findTree(t); }
CollectionNode* getCollection(const QString& name, Node::Genus genus) {
return primaryTree()->getCollection(name, genus);
}
const CNMap& groups() { return primaryTree()->groups(); }
const CNMap& modules() { return primaryTree()->modules(); }
const CNMap& qmlModules() { return primaryTree()->qmlModules(); }
const CNMap& jsModules() { return primaryTree()->jsModules(); }
CollectionNode* findGroup(const QString& name) { return primaryTree()->findGroup(name); }
CollectionNode* findModule(const QString& name) { return primaryTree()->findModule(name); }
CollectionNode* findQmlModule(const QString& name) { return primaryTree()->findQmlModule(name); }
CollectionNode* findJsModule(const QString& name) { return primaryTree()->findJsModule(name); }
CollectionNode* addGroup(const QString& name) { return primaryTree()->addGroup(name); }
CollectionNode* addModule(const QString& name) { return primaryTree()->addModule(name); }
CollectionNode* addQmlModule(const QString& name) { return primaryTree()->addQmlModule(name); }
@ -339,6 +341,9 @@ class QDocDatabase
Node* findNodeByNameAndType(const QStringList& path, Node::NodeType type) {
return forest_.findNodeByNameAndType(path, type);
}
const CollectionNode* getCollectionNode(const QString& name, Node::Genus genus) {
return forest_.getCollectionNode(name, genus);
}
private:
const Node* findNodeForTarget(QStringList& targetPath,