qdoc: Fixed minor version number in DITA XML
authorMartin Smith <martin.smith@nokia.com>
Fri, 4 May 2012 13:51:20 +0000 (15:51 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 4 May 2012 15:57:46 +0000 (17:57 +0200)
The DITA XML didn't contain the correct
QML Module version mumber in the imports
statement.

Change-Id: I22b75facc1396c5adea88be49c86fff11f19f27b
Reviewed-by: Casper van Donderen <casper.vandonderen@nokia.com>
src/tools/qdoc/codeparser.cpp
src/tools/qdoc/cppcodeparser.cpp
src/tools/qdoc/main.cpp
src/tools/qdoc/node.cpp
src/tools/qdoc/node.h
src/tools/qdoc/qmlvisitor.cpp
src/tools/qdoc/tree.cpp
src/tools/qdoc/tree.h

index 5173a40..f06cc1f 100644 (file)
@@ -250,11 +250,12 @@ void CodeParser::processCommonMetaCommand(const Location& location,
         node->setModuleName(arg);
     }
     else if (command == COMMAND_INQMLMODULE) {
-        node->setQmlModuleName(arg);
-        tree->addToQmlModule(node,arg);
+        node->setQmlModule(arg);
+        FakeNode* fn = FakeNode::lookupQmlModuleNode(tree, arg);
+        fn->addQmlModuleMember(node);
         QString qmid = node->qmlModuleIdentifier();
         QmlClassNode* qcn = static_cast<QmlClassNode*>(node);
-        QmlClassNode::moduleMap.insert(qmid + QLatin1String("::") + node->name(), qcn);
+        QmlClassNode::insertQmlModuleMember(qmid, qcn);
     }
     else if (command == COMMAND_MAINCLASS) {
         node->setStatus(Node::Main);
index d8367b3..4e010fc 100644 (file)
@@ -711,7 +711,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
         return new FakeNode(tree_->root(), arg, Node::Module, Node::OverviewPage);
     }
     else if (command == COMMAND_QMLMODULE) {
-        return new FakeNode(tree_->root(), arg, Node::QmlModule, Node::OverviewPage);
+        return FakeNode::lookupQmlModuleNode(tree_, arg);
     }
     else if (command == COMMAND_PAGE) {
         Node::PageType ptype = Node::ArticlePage;
index f230f92..742075c 100644 (file)
@@ -365,7 +365,6 @@ static void processQdocconfFile(const QString &fileName)
       targets, URLs, links, and other stuff that needs resolving.
      */
     tree->resolveGroups();
-    tree->resolveQmlModules();
     tree->resolveTargets(tree->root());
     tree->resolveCppToQmlLinks();
     tree->resolveQmlInheritance();
index c648c72..30fa76a 100644 (file)
@@ -1452,6 +1452,8 @@ QmlClassNode* ClassNode::findQmlBaseNode()
     return result;
 }
 
+QMap<QString, FakeNode*> FakeNode::qmlModuleMap_;
+
 /*!
   \class FakeNode
  */
@@ -1472,10 +1474,13 @@ FakeNode::FakeNode(InnerNode* parent, const QString& name, SubType subtype, Node
         setPageType(ptype);
         break;
     case Module:
-    case QmlModule:
     case Group:
         setPageType(OverviewPage);
         break;
+    case QmlModule:
+        setQmlModule(name);
+        setPageType(OverviewPage);
+        break;
     case QmlClass:
     case QmlBasicType:
         setPageType(ApiPage);
@@ -1548,6 +1553,47 @@ QString FakeNode::subTitle() const
 }
 
 /*!
+  The QML module map contains an entry for each QML module
+  identifier. A QML module identifier is constucted from the
+  QML module name and the module's major version number, like
+  this: \e {<module-name><major-version>}
+
+  If the QML module map does not contain the module identifier
+  \a qmid, insert the QML module node \a fn mapped to \a qmid.
+ */
+void FakeNode::insertQmlModuleNode(const QString& qmid, FakeNode* fn)
+{
+    if (!qmlModuleMap_.contains(qmid))
+        qmlModuleMap_.insert(qmid,fn);
+}
+
+/*!
+  Returns a pointer to the QML module node (FakeNode) that is
+  mapped to the QML module identifier constructed from \a arg.
+  If that QML module node does not yet exist, it is constructed
+  and inserted into the QML module map mapped to the QML module
+  identifier constructed from \a arg.
+ */
+FakeNode* FakeNode::lookupQmlModuleNode(Tree* tree, const QString& arg)
+{
+    QStringList dotSplit;
+    QStringList blankSplit = arg.split(QLatin1Char(' '));
+    QString qmid = blankSplit[0];
+    if (blankSplit.size() > 1) {
+        dotSplit = blankSplit[1].split(QLatin1Char('.'));
+        qmid += dotSplit[0];
+    }
+    FakeNode* fn = 0;
+    if (qmlModuleMap_.contains(qmid))
+        fn = qmlModuleMap_.value(qmid);
+    if (!fn) {
+        fn = new FakeNode(tree->root(), arg, Node::QmlModule, Node::OverviewPage);
+        insertQmlModuleNode(qmid,fn);
+    }
+    return fn;
+}
+
+/*!
   The constructor calls the FakeNode constructor with
   \a parent, \a name, and Node::Example.
  */
@@ -1964,7 +2010,7 @@ QString PropertyNode::qualifiedDataType() const
 
 bool QmlClassNode::qmlOnly = false;
 QMultiMap<QString,Node*> QmlClassNode::inheritedBy;
-QMap<QString, QmlClassNode*> QmlClassNode::moduleMap;
+QMap<QString, QmlClassNode*> QmlClassNode::qmlModuleMemberMap_;
 
 /*!
   Constructs a Qml class node (i.e. a Fake node with the
@@ -1990,7 +2036,7 @@ QmlClassNode::QmlClassNode(InnerNode *parent,
 }
 
 /*!
-  I made this so I could print a debug message here.
+  Needed for printing a debug messages.
  */
 QmlClassNode::~QmlClassNode()
 {
@@ -2006,7 +2052,26 @@ QmlClassNode::~QmlClassNode()
 void QmlClassNode::terminate()
 {
     inheritedBy.clear();
-    moduleMap.clear();
+    qmlModuleMemberMap_.clear();
+}
+
+/*!
+  Insert the QML type node \a qcn into the static QML module
+  member map. The key is \a qmid + "::" + qcn->name().
+ */
+void QmlClassNode::insertQmlModuleMember(const QString& qmid, QmlClassNode* qcn)
+{
+    qmlModuleMemberMap_.insert(qmid + "::" + qcn->name(), qcn);
+}
+
+/*!
+  Lookup the QML type node identified by the Qml module id
+  \a qmid and QML type \a name, and return a pointer to the
+  node. The key is \a qmid + "::" + qcn->name().
+ */
+QmlClassNode* QmlClassNode::lookupQmlTypeNode(const QString& qmid, const QString& name)
+{
+    return qmlModuleMemberMap_.value(qmid + "::" + name);
 }
 
 /*!
@@ -2057,20 +2122,38 @@ void QmlClassNode::subclasses(const QString& base, NodeList& subs)
   is returned is the concatenation of the QML module name
   and its version number. e.g., if an element or component
   is defined to be in the QML module QtQuick 1, its module
-  identifier is "QtQuick1". See setQmlModuleName().
+  identifier is "QtQuick1". See setQmlModule().
  */
 
 /*!
   This function splits \a arg on the blank character to get a
-  QML module name and version number. It stores these separately.
-  The version number is not required.
+  QML module name and version number. It then spilts the version
+  number on the '.' character to get a major version number and
+  a minor vrsion number. Both version numbers must be present.
+  It stores these components separately. If all three are found,
+  true is returned. If any of the three is not found or is not
+  correct, false is returned.
  */
-void Node::setQmlModuleName(const QString& arg)
+bool Node::setQmlModule(const QString& arg)
 {
+    QStringList dotSplit;
     QStringList blankSplit = arg.split(QLatin1Char(' '));
     qmlModuleName_ = blankSplit[0];
-    if (blankSplit.size() > 1)
-        qmlModuleVersion_ = blankSplit[1];
+    qmlModuleVersionMajor_ = "1";
+    qmlModuleVersionMinor_ = "0";
+    if (blankSplit.size() > 1) {
+        dotSplit = blankSplit[1].split(QLatin1Char('.'));
+        qmlModuleVersionMajor_ = dotSplit[0];
+        if (dotSplit.size() > 1) {
+            qmlModuleVersionMinor_ = dotSplit[1];
+            return true;
+        }
+        else
+            doc().location().warning(tr("Minor version number missing for '\\qmlmodule' or '\\inqmlmodule'; 0 assumed."));
+    }
+    else
+        doc().location().warning(tr("Module version number missing for '\\qmlmodule' or '\\inqmlmodule'; 1.0 assumed."));
+    return false;
 }
 
 /*!
index 2cb93a8..8083f2c 100644 (file)
@@ -231,9 +231,9 @@ public:
     QString ditaXmlHref();
     QString extractClassName(const QString &string) const;
     virtual QString qmlModuleName() const { return qmlModuleName_; }
-    virtual QString qmlModuleVersion() const { return qmlModuleVersion_; }
-    virtual QString qmlModuleIdentifier() const { return qmlModuleName_ + qmlModuleVersion_; }
-    virtual void setQmlModuleName(const QString& );
+    virtual QString qmlModuleVersion() const { return qmlModuleVersionMajor_ + "." + qmlModuleVersionMinor_; }
+    virtual QString qmlModuleIdentifier() const { return qmlModuleName_ + qmlModuleVersionMajor_; }
+    virtual bool setQmlModule(const QString& );
     virtual ClassNode* classNode() { return 0; }
     virtual void clearCurrentChild() { }
     virtual const ImportList* importList() const { return 0; }
@@ -290,7 +290,8 @@ private:
     mutable QString uuid;
     QString outSubDir_;
     QString qmlModuleName_;
-    QString qmlModuleVersion_;
+    QString qmlModuleVersionMajor_;
+    QString qmlModuleVersionMinor_;
     static QStringMap operators_;
     static int propertyGroupCount_;
 };
@@ -474,11 +475,16 @@ public:
     virtual void setImageFileName(const QString& ) { }
     virtual bool isQmlPropertyGroup() const { return (nodeSubtype_ == QmlPropertyGroup); }
 
+    static void insertQmlModuleNode(const QString& qmid, FakeNode* fn);
+    static FakeNode* lookupQmlModuleNode(Tree* tree, const QString& arg);
+
 protected:
     SubType nodeSubtype_;
     QString title_;
     QString subtitle_;
     NodeList nodeList; // used for groups and QML modules.
+
+    static QMap<QString, FakeNode*> qmlModuleMap_;
 };
 
 class NameCollisionNode : public FakeNode
@@ -542,10 +548,13 @@ public:
     static void subclasses(const QString& base, NodeList& subs);
     static void terminate();
 
+    static void insertQmlModuleMember(const QString& qmid, QmlClassNode* qcn);
+    static QmlClassNode* lookupQmlTypeNode(const QString& qmid, const QString& name);
+
 public:
     static bool qmlOnly;
     static QMultiMap<QString,Node*> inheritedBy;
-    static QMap<QString, QmlClassNode*> moduleMap;
+    static QMap<QString, QmlClassNode*> qmlModuleMemberMap_;
 
 private:
     bool abstract;
index 36dc5cc..1544227 100644 (file)
@@ -311,11 +311,12 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation,
                 node->setStatus(Node::Deprecated);
             }
             else if (command == COMMAND_INQMLMODULE) {
-                node->setQmlModuleName(args[0]);
-                tree->addToQmlModule(node,args[0]);
+                node->setQmlModule(args[0]);
+                FakeNode* fn = FakeNode::lookupQmlModuleNode(tree, args[0]);
+                fn->addQmlModuleMember(node);
                 QString qmid = node->qmlModuleIdentifier();
                 QmlClassNode* qcn = static_cast<QmlClassNode*>(node);
-                QmlClassNode::moduleMap.insert(qmid + "::" + node->name(), qcn);
+                QmlClassNode::insertQmlModuleMember(qmid, qcn);
             }
             else if (command == COMMAND_QMLINHERITS) {
                 if (node->name() == args[0])
index ac55cb7..c4cc78a 100644 (file)
@@ -92,7 +92,6 @@ public:
     QMap<ClassNode* , QList<InheritanceBound> > unresolvedInheritanceMap;
     PropertyMap unresolvedPropertyMap;
     NodeMultiMap groupMap;
-    NodeMultiMap qmlModuleMap;
     QMultiMap<QString, QString> publicGroupMap;
     FakeNodeHash fakeNodesByTitle;
     TargetHash targetHash;
@@ -176,11 +175,13 @@ const Node* Tree::findNode(const QStringList& path,
         /*
           If the path contains one or two double colons ("::"),
           check first to see if the first two path strings refer
-          to a QML element. If yes, that reference identifies a
-          QML class node.
+          to a QML element. If they do, path[0] will be the QML
+          module identifier, and path[1] will be the QML type.
+          If the anser is yes, the reference identifies a QML
+          class node.
         */
         if (qml && path.size() >= 2) {
-            QmlClassNode* qcn = QmlClassNode::moduleMap.value(path[0]+ "::" +path[1]);
+            QmlClassNode* qcn = QmlClassNode::lookupQmlTypeNode(path[0], path[1]);
             if (qcn) {
                 node = qcn;
                 if (path.size() == 2)
@@ -250,7 +251,7 @@ QmlClassNode* Tree::findQmlClassNode(const QString& module, const QString& name)
         }
         return 0;
     }
-    return QmlClassNode::moduleMap.value(module + "::" + name);
+    return QmlClassNode::lookupQmlTypeNode(module, name);
 }
 
 /*!
@@ -328,7 +329,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
       QML class node in the QML module map.
      */
     if (path.size() == 3) {
-        QmlClassNode* qcn = QmlClassNode::moduleMap.value(path[0]+ "::" +path[1]);
+        QmlClassNode* qcn = QmlClassNode::lookupQmlTypeNode(path[0], path[1]);
         if (qcn) {
             return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2]));
         }
@@ -592,16 +593,6 @@ void Tree::addToGroup(Node* node, const QString& group)
 }
 
 /*!
-  This function adds the \a node to the QML \a module. The QML
-  module can be listed anywhere using the \e{annotated list}
-  command.
- */
-void Tree::addToQmlModule(Node* node, const QString& module)
-{
-    priv->qmlModuleMap.insert(module, node);
-}
-
-/*!
   Returns the group map.
  */
 NodeMultiMap Tree::groups() const
@@ -610,14 +601,6 @@ NodeMultiMap Tree::groups() const
 }
 
 /*!
-  Returns the QML module map.
- */
-NodeMultiMap Tree::qmlModules() const
-{
-    return priv->qmlModuleMap;
-}
-
-/*!
  */
 void Tree::addToPublicGroup(Node* node, const QString& group)
 {
@@ -765,20 +748,6 @@ void Tree::resolveGroups()
 }
 
 /*!
-  For each node in the QML module map, add the node to the
-  appropriate QML module node.
- */
-void Tree::resolveQmlModules()
-{
-    NodeMultiMap::const_iterator i;
-    for (i = priv->qmlModuleMap.constBegin(); i != priv->qmlModuleMap.constEnd(); ++i) {
-        Node* n = findQmlModuleNode(QStringList(i.key()));
-        if (n)
-            n->addQmlModuleMember(i.value());
-    }
-}
-
-/*!
  */
 void Tree::resolveTargets(InnerNode* root)
 {
@@ -2319,15 +2288,6 @@ Node* Tree::findNodeByNameAndType(const QStringList& path,
     return result;
 }
 
-#if 0
-    if (result)
-        qDebug() << "FOUND:" << path << Node::nodeTypeString(type)
-                 << Node::nodeSubtypeString(subtype);
-    else
-        qDebug() << "NOT FOUND:" << path << Node::nodeTypeString(type)
-                 << Node::nodeSubtypeString(subtype);
-#endif
-
 /*!
   Recursive search for a node identified by \a path. Each
   path element is a name. \a pathIndex specifies the index
@@ -2445,11 +2405,13 @@ QmlClassNode* Tree::findQmlClassNode(const QStringList& path, Node* start)
     /*
       If the path contains one or two double colons ("::"),
       check first to see if the first two path strings refer
-      to a QML element. If yes, that reference identifies a
-      QML class node.
+      to a QML element. If they do, path[0] will be the QML
+      module identifier, and path[1] will be the QML type.
+      If the anser is yes, the reference identifies a QML
+      class node.
     */
     if (path.size() >= 2) {
-        QmlClassNode* qcn = QmlClassNode::moduleMap.value(path[0]+ "::" +path[1]);
+        QmlClassNode* qcn = QmlClassNode::lookupQmlTypeNode(path[0], path[1]);
         if (qcn)
             return qcn;
     }
@@ -2499,50 +2461,3 @@ FakeNode* Tree::findQmlModuleNode(const QStringList& path, Node* start)
 }
 
 QT_END_NAMESPACE
-
-#if 0
-const Node* Tree::findNodeXXX(const QStringList& path, bool qml) const
-{
-    const Node* current = root();
-    do {
-        const Node* node = current;
-        int i;
-        int start_idx = 0;
-
-        /*
-          If the path contains one or two double colons ("::"),
-          check first to see if the first two path strings refer
-          to a QML element. If yes, that reference identifies a
-          QML class node.
-        */
-        if (qml && path.size() >= 2) {
-            QmlClassNode* qcn = QmlClassNode::moduleMap.value(path[0]+ "::" +path[1]);
-            if (qcn) {
-                node = qcn;
-                if (path.size() == 2)
-                    return node;
-                start_idx = 2;
-            }
-        }
-
-        for (i = start_idx; i < path.size(); ++i) {
-            if (node == 0 || !node->isInnerNode())
-                break;
-
-            const Node* next = static_cast<const InnerNode*>(node)->findChildNodeByName(path.at(i), qml);
-            node = next;
-        }
-        if (node && i == path.size()) {
-            if (node->subType() != Node::QmlPropertyGroup) {
-                if (node->subType() == Node::Collision) {
-                    node = node->applyModuleIdentifier(start);
-                }
-                return node;
-            }
-        }
-        current = current->parent();
-    } while (current);
-
-    return 0;
-}
-#endif
index 62f5995..8aab57f 100644 (file)
@@ -118,14 +118,12 @@ public:
                              PropertyNode::FunctionRole funcRole);
     void addToGroup(Node *node, const QString &group);
     void addToPublicGroup(Node *node, const QString &group);
-    void addToQmlModule(Node* node, const QString& module);
+    void addToQmlModule(Node* node);
     NodeMultiMap groups() const;
-    NodeMultiMap qmlModules() const;
     QMultiMap<QString,QString> publicGroups() const;
     void resolveInheritance(NamespaceNode *rootNode = 0);
     void resolveProperties();
     void resolveGroups();
-    void resolveQmlModules();
     void resolveTargets(InnerNode* root);
     void resolveCppToQmlLinks();
     void fixInheritance(NamespaceNode *rootNode = 0);