From cd84491aad703f7b983a3d61277a27998e53396a Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 12 Feb 2013 09:40:02 +0100 Subject: qdoc: inherited members do not show up for QML components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was a regression bug owing to a big qdoc cleanup for Qt5. But the way QML inheritance had been handled was not a good design, so it has been changed here. When a .qml file is parsed by qdoc, the base type of the QML component is detected, and its name is stored in qdoc's tree node for the component. After qdoc has parsed all the QML files, it traverses the tree, and for each QML component that has a base type name but no base type node pointer yet, it searches the tree for the base type node and stores the pointer to the node in the node for the components. Then when the output generator generates the doc page for the component, it has access to all the inherited members in the base type. Task-number: QTBUG-29569 Change-Id: Ib4958d05f55fa48a572f8ca51ffd57712f29bbc7 Reviewed-by: J-P Nurmi Reviewed-by: Topi Reiniƶ Reviewed-by: Martin Smith --- src/tools/qdoc/cppcodemarker.cpp | 10 +++++----- src/tools/qdoc/cppcodeparser.cpp | 9 ++++----- src/tools/qdoc/ditaxmlgenerator.cpp | 2 +- src/tools/qdoc/htmlgenerator.cpp | 2 +- src/tools/qdoc/node.cpp | 2 +- src/tools/qdoc/node.h | 12 +++++++----- src/tools/qdoc/qdocdatabase.cpp | 30 ++++++++++++++++++++++++++++++ src/tools/qdoc/qdocdatabase.h | 1 + src/tools/qdoc/qmlvisitor.cpp | 15 ++++++--------- src/tools/qdoc/tree.cpp | 4 +++- 10 files changed, 59 insertions(+), 28 deletions(-) (limited to 'src/tools') diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp index 0bebe0d670..c85c5c64ef 100644 --- a/src/tools/qdoc/cppcodemarker.cpp +++ b/src/tools/qdoc/cppcodemarker.cpp @@ -1165,8 +1165,8 @@ QList
CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno } ++c; } - if (qcn->qmlBase() != 0) { - qcn = static_cast(qcn->qmlBase()); + if (qcn->qmlBaseNode() != 0) { + qcn = static_cast(qcn->qmlBaseNode()); if (!qcn->isAbstract()) qcn = 0; } @@ -1241,8 +1241,8 @@ QList
CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno } ++c; } - if (qcn->qmlBase() != 0) { - qcn = static_cast(qcn->qmlBase()); + if (qcn->qmlBaseNode() != 0) { + qcn = static_cast(qcn->qmlBaseNode()); if (!qcn->isAbstract()) qcn = 0; } @@ -1287,7 +1287,7 @@ QList
CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno } ++c; } - const DocNode* dn = current->qmlBase(); + const DocNode* dn = current->qmlBaseNode(); if (dn) { if (dn->subType() == Node::QmlClass) current = static_cast(dn); diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 0af5a841eb..68edb1336a 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -951,11 +951,10 @@ 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 { - setLink(node, Node::InheritsLink, arg); - if (node->subType() == Node::QmlClass) { - QmlClassNode::addInheritedBy(arg,node); - } + else if (node->subType() == Node::QmlClass) { + QmlClassNode *qmlClass = static_cast(node); + qmlClass->setQmlBaseName(arg); + QmlClassNode::addInheritedBy(arg,node); } } else if (command == COMMAND_QMLINSTANTIATES) { diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp index 43d3a8071d..22694dd0d3 100644 --- a/src/tools/qdoc/ditaxmlgenerator.cpp +++ b/src/tools/qdoc/ditaxmlgenerator.cpp @@ -4198,7 +4198,7 @@ void DitaXmlGenerator::generateQmlInherits(const QmlClassNode* qcn, CodeMarker* { if (!qcn) return; - const DocNode* base = qcn->qmlBase(); + const DocNode* base = qcn->qmlBaseNode(); if (base) { writeStartTag(DT_qmlInherits); //writeStartTag(DT_qmlTypeDef); diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 8052558dc6..8718161703 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -3869,7 +3869,7 @@ void HtmlGenerator::generateQmlInherits(const QmlClassNode* qcn, CodeMarker* mar { if (!qcn) return; - const DocNode* base = qcn->qmlBase(); + const DocNode* base = qcn->qmlBaseNode(); if (base) { Text text; text << Atom::ParaLeft << "Inherits "; diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index 0fb9ccc97f..5fbdb487db 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -2097,7 +2097,7 @@ QmlClassNode::QmlClassNode(InnerNode *parent, const QString& name) abstract_(false), cnodeRequired_(false), cnode_(0), - base_(0) + baseNode_(0) { int i = 0; if (name.startsWith("QML:")) { diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index 11c08fb659..ecb3c5771e 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -131,8 +131,7 @@ public: NextLink, PreviousLink, ContentsLink, - IndexLink, - InheritsLink /*, + IndexLink /*, GlossaryLink, CopyrightLink, ChapterLink, @@ -546,8 +545,10 @@ public: virtual void setAbstract(bool b) { abstract_ = b; } const ImportList& importList() const { return importList_; } void setImportList(const ImportList& il) { importList_ = il; } - const DocNode* qmlBase() const { return base_; } - void setQmlBase(DocNode* b) { base_ = b; } + const QString& qmlBaseName() const { return baseName_; } + void setQmlBaseName(const QString& name) { baseName_ = name; } + const DocNode* qmlBaseNode() const { return baseNode_; } + void setQmlBaseNode(DocNode* b) { baseNode_ = b; } void requireCppClass() { cnodeRequired_ = true; } bool cppClassRequired() const { return cnodeRequired_; } static void addInheritedBy(const QString& base, Node* sub); @@ -562,7 +563,8 @@ private: bool abstract_; bool cnodeRequired_; ClassNode* cnode_; - DocNode* base_; + QString baseName_; + DocNode* baseNode_; ImportList importList_; }; diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index 982df5bbc3..4208d529c8 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -623,6 +623,7 @@ const NodeMultiMap& QDocDatabase::getSinceMap(const QString& key) const to generating documentation. */ void QDocDatabase::resolveIssues() { + resolveQmlInheritance(treeRoot()); resolveTargets(treeRoot()); tree_->resolveCppToQmlLinks(); } @@ -821,6 +822,35 @@ QString QDocDatabase::findTarget(const QString& target, const Node* node) const return QString(); } +/*! + For each QML Type node in the tree beginning at \a root, + if it has a QML base type name but its QML base type node + pointer is 0, use the QML base type name to look up the + base type node. If the node is found in the tree, set the + node's QML base type node pointer. + */ +void QDocDatabase::resolveQmlInheritance(InnerNode* root) +{ + // Dop we need recursion? + foreach (Node* child, root->childNodes()) { + if (child->type() == Node::Document && child->subType() == Node::QmlClass) { + QmlClassNode* qcn = static_cast(child); + if ((qcn->qmlBaseNode() == 0) && !qcn->qmlBaseName().isEmpty()) { + QmlClassNode* bqcn = findQmlType(QString(), qcn->qmlBaseName()); + if (bqcn) { + qcn->setQmlBaseNode(bqcn); + } +#if 0 + else { + qDebug() << "Unable to resolve QML base type:" << qcn->qmlBaseName() + << "for QML type:" << qcn->name(); + } +#endif + } + } + } +} + /*! */ void QDocDatabase::resolveTargets(InnerNode* root) diff --git a/src/tools/qdoc/qdocdatabase.h b/src/tools/qdoc/qdocdatabase.h index 857fd301bb..9c6810941d 100644 --- a/src/tools/qdoc/qdocdatabase.h +++ b/src/tools/qdoc/qdocdatabase.h @@ -140,6 +140,7 @@ class QDocDatabase Tree* tree() { return tree_; } NamespaceNode* treeRoot() { return tree_->root(); } void resolveInheritance() { tree_->resolveInheritance(); } + void resolveQmlInheritance(InnerNode* root); void resolveIssues(); void fixInheritance() { tree_->fixInheritance(); } void resolveProperties() { tree_->resolveProperties(); } diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp index 9dc15d56f1..15af03d9ba 100644 --- a/src/tools/qdoc/qmlvisitor.cpp +++ b/src/tools/qdoc/qmlvisitor.cpp @@ -106,7 +106,7 @@ QmlDocVisitor::~QmlDocVisitor() } /*! - Returns the location of thre nearest comment above the \a offset. + Returns the location of the nearest comment above the \a offset. */ QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) const { @@ -322,11 +322,10 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation, else if (command == COMMAND_QMLINHERITS) { if (node->name() == args[0].first) doc.location().warning(tr("%1 tries to inherit itself").arg(args[0].first)); - else { - CodeParser::setLink(node, Node::InheritsLink, args[0].first); - if (node->subType() == Node::QmlClass) { - QmlClassNode::addInheritedBy(args[0].first,node); - } + else if (node->subType() == Node::QmlClass) { + QmlClassNode *qmlClass = static_cast(node); + qmlClass->setQmlBaseName(args[0].first); + QmlClassNode::addInheritedBy(args[0].first,node); } } else if (command == COMMAND_QMLDEFAULT) { @@ -389,11 +388,9 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiObjectDefinition *definition) QmlClassNode *component = new QmlClassNode(current, name); component->setTitle(name); component->setImportList(importList); - if (applyDocumentation(definition->firstSourceLocation(), component)) { QmlClassNode::addInheritedBy(type, component); - if (!component->links().contains(Node::InheritsLink)) - component->setLink(Node::InheritsLink, type, type); + component->setQmlBaseName(type); } current = component; } diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index ea1d2a92e2..1efab11a92 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -399,10 +399,12 @@ void Tree::addPropertyFunction(PropertyNode* property, /*! This function resolves inheritance and reimplementation settings - for each class node found in the namspace beginning ar \a rootNode. + for each C++ class node found in the namspace beginning at \a rootNode. If it finds another namespace node in the child list of \a rootNode, it calls itself recursively. For each child of \a rootNode that is a class node, it calls the other resolveInheritance() function. + + This function does not resolve QML inheritance. */ void Tree::resolveInheritance(NamespaceNode* rootNode) { -- cgit v1.2.3