From 338f9c4f7c42d2a7bcd2c5b37137b3cc7cd9775d Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Mon, 11 Aug 2014 11:58:44 +0200 Subject: [PATCH] qdoc: Distinguish between QML property and attached property A recent change in qtdeclarative (60ed6a43) added an attached property 'Window' to Item type, with property names identical to the ones already available in Window. This caused QDoc to report warnings for duplicate documentation for QML properties, because there was no distiction between a QML property and an attached property. This change fixes the issue by: - Allowing identical names for \qmlproperty and \qmlattachedproperty - Using distinct URLs/UUIDs/anchor references for them - Marking attached properties with '[attached]' qualifier in 'All Members' page. This doesn't solve the issue of disambiguating between a similarly named QML property and attached property when linking from an external location. However, these can be solved with the help of the \target command. Task-number: QTBUG-40674 Change-Id: Icc74de237366e9897334689fe354ab83e4af0356 Reviewed-by: Martin Smith Reviewed-by: Jerome Pasion Reviewed-by: Shawn Rutledge --- src/tools/qdoc/cppcodeparser.cpp | 2 +- src/tools/qdoc/generator.cpp | 5 ++++- src/tools/qdoc/htmlgenerator.cpp | 9 ++++++++- src/tools/qdoc/node.cpp | 26 +++++++++++++++++++++++++- src/tools/qdoc/node.h | 2 ++ src/tools/qdoc/qmlvisitor.cpp | 2 +- 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 2755bf72541..df11ee5b24f 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -832,7 +832,7 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis if (splitQmlPropertyArg(arg, type, module, qmlType, property)) { qmlClass = qdb_->findQmlType(module, qmlType); if (qmlClass) { - if (qmlClass->hasQmlProperty(property) != 0) { + if (qmlClass->hasQmlProperty(property, attached) != 0) { QString msg = tr("QML property documented multiple times: '%1'").arg(arg); doc.startLocation().warning(msg); } diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp index 6bba83efdb3..6fdc2a916c4 100644 --- a/src/tools/qdoc/generator.cpp +++ b/src/tools/qdoc/generator.cpp @@ -545,7 +545,10 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir) anchorRef = QLatin1Char('#') + node->name() + "-prop"; break; case Node::QmlProperty: - anchorRef = QLatin1Char('#') + node->name() + "-prop"; + if (node->isAttached()) + anchorRef = QLatin1Char('#') + node->name() + "-attached-prop"; + else + anchorRef = QLatin1Char('#') + node->name() + "-prop"; break; case Node::QmlSignal: anchorRef = QLatin1Char('#') + node->name() + "-signal"; diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index ffaa014d60c..51e61117c4b 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -2477,6 +2477,8 @@ QString HtmlGenerator::generateAllQmlMembersFile(QmlClassNode* qml_cn, CodeMarke prefix = prefix.left(keys.at(j).indexOf("::")+1); } generateQmlItem(nodes[j], qcn, marker, true); + if (nodes[j]->isAttached()) + out() << " [attached]"; //generateSynopsis(nodes[j], qcn, marker, CodeMarker::Subpage, false, &prefix); out() << "\n"; } @@ -3627,8 +3629,13 @@ QString HtmlGenerator::refForNode(const Node *node) break; case Node::Document: break; - case Node::QmlPropertyGroup: case Node::QmlProperty: + if (node->isAttached()) + ref = node->name() + "-attached-prop"; + else + ref = node->name() + "-prop"; + break; + case Node::QmlPropertyGroup: case Node::Property: ref = node->name() + "-prop"; break; diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index 03b798cbb3f..f16c35c3a95 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -1338,6 +1338,27 @@ QmlPropertyNode* InnerNode::hasQmlProperty(const QString& n) const return 0; } +/*! + If this node has a child that is a QML property named \a n + whose type (attached or normal property) matches \a attached, + return the pointer to that child. + */ +QmlPropertyNode* InnerNode::hasQmlProperty(const QString& n, bool attached) const +{ + foreach (Node* child, childNodes()) { + if (child->type() == Node::QmlProperty) { + if (child->name() == n && child->isAttached() == attached) + return static_cast(child); + } + else if (child->isQmlPropertyGroup()) { + QmlPropertyNode* t = child->hasQmlProperty(n, attached); + if (t) + return t; + } + } + return 0; +} + /*! \class LeafNode */ @@ -2797,7 +2818,10 @@ QString Node::idForNode() const str = "qml-module-" + name(); break; case Node::QmlProperty: - str = "qml-property-" + name(); + if (isAttached()) + str = "qml-attached-property-" + name(); + else + str = "qml-property-" + name(); break; case Node::QmlPropertyGroup: { diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index 4f9097d7748..37fbe482b03 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -239,6 +239,7 @@ public: virtual void setTitle(const QString& ) { } virtual void setSubTitle(const QString& ) { } 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 bool isInternal() const; @@ -391,6 +392,7 @@ public: virtual void setOutputFileName(const QString& f) { outputFileName_ = f; } virtual QString outputFileName() const { return outputFileName_; } virtual QmlPropertyNode* hasQmlProperty(const QString& ) const; + virtual QmlPropertyNode* hasQmlProperty(const QString&, bool attached) const; void addChild(Node* child, const QString& title); const QStringList& groupNames() const { return groupNames_; } virtual void appendGroupName(const QString& t) { groupNames_.append(t); } diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp index 2ef751e9bc7..fbe4940c19f 100644 --- a/src/tools/qdoc/qmlvisitor.cpp +++ b/src/tools/qdoc/qmlvisitor.cpp @@ -266,7 +266,7 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod } else { bool isAttached = (topic == COMMAND_QMLATTACHEDPROPERTY); - QmlPropertyNode* n = parent->hasQmlProperty(qpa.name_); + QmlPropertyNode* n = parent->hasQmlProperty(qpa.name_, isAttached); if (n == 0) n = new QmlPropertyNode(parent, qpa.name_, qpa.type_, isAttached); n->setLocation(doc.location());