qdoc: Fixed handling of QML references

Updated qdoc to handle QML references without using the
QML module version.

Task-number: QTBUG-32173
Change-Id: Ibfba9bc92458ae04017706e904625e7d32fc0be4
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
This commit is contained in:
Martin Smith 2013-10-01 14:35:37 +02:00 committed by The Qt Project
parent 2c925906f5
commit b906f3919b
8 changed files with 133 additions and 99 deletions

View File

@ -2122,6 +2122,7 @@ QmlClassNode::QmlClassNode(InnerNode *parent, const QString& name)
cnodeRequired_(false),
wrapper_(false),
cnode_(0),
qmlModule_(0),
baseNode_(0)
{
int i = 0;
@ -2171,45 +2172,27 @@ void QmlClassNode::subclasses(const QString& base, NodeList& subs)
}
}
/*! \fn QString QmlClassNode::qmlModuleIdentifier() const
This function is called to get a string that is used either
as a prefix for the file name to use for QML element or
component reference page, or as a qualifier to prefix a
reference to a QML element or comnponent. The string that
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 setQmlModuleInfo().
*/
/*!
This function splits \a arg on the blank character to get a
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 major the major and minor version
numbers should be present, but the minor version number is not
QML module name and version number. If the version number is
present, it spilts the version number on the '.' character to
get a major version number and a minor vrsion number. If the
version number is present, both the major and minor version
numbers should be there, but the minor version number is not
absolutely necessary.
It stores the three components separately in this node. If all
three are found, true is returned. If any of the three is not
found or is not in the correct format, false is returned.
*/
bool Node::setQmlModuleInfo(const QString& arg)
void QmlModuleNode::setQmlModuleInfo(const QString& arg)
{
QStringList dotSplit;
QStringList blankSplit = arg.split(QLatin1Char(' '));
qmlModuleName_ = blankSplit[0];
qmlModuleVersionMajor_ = "1";
qmlModuleVersionMinor_ = "0";
if (blankSplit.size() > 1) {
dotSplit = blankSplit[1].split(QLatin1Char('.'));
QStringList dotSplit = blankSplit[1].split(QLatin1Char('.'));
qmlModuleVersionMajor_ = dotSplit[0];
if (dotSplit.size() > 1) {
if (dotSplit.size() > 1)
qmlModuleVersionMinor_ = dotSplit[1];
return true;
}
else
qmlModuleVersionMinor_ = "0";
}
return false;
}
/*!
@ -2258,6 +2241,36 @@ void QmlClassNode::clearCurrentChild()
}
}
/*!
If the QML type's QML module pointer is set, return the QML
module name from the QML module node. Otherwise, return the
empty string.
*/
QString QmlClassNode::qmlModuleName() const
{
return (qmlModule_ ? qmlModule_->qmlModuleName() : QString());
}
/*!
If the QML type's QML module pointer is set, return the QML
module version from the QML module node. Otherwise, return
the empty string.
*/
QString QmlClassNode::qmlModuleVersion() const
{
return (qmlModule_ ? qmlModule_->qmlModuleVersion() : QString());
}
/*!
If the QML type's QML module pointer is set, return the QML
module identifier from the QML module node. Otherwise, return
the empty string.
*/
QString QmlClassNode::qmlModuleIdentifier() const
{
return (qmlModule_ ? qmlModule_->qmlModuleIdentifier() : QString());
}
/*!
Constructs a Qml basic type node (i.e. a Document node with
the subtype QmlBasicType. The new node has the given
@ -2526,7 +2539,7 @@ QString Node::fullDocumentName() const
if (n->type() == Node::Document) {
if ((n->subType() == Node::QmlClass) && !n->qmlModuleName().isEmpty())
pieces.insert(0, n->qmlModuleIdentifier());
pieces.insert(0, n->qmlModuleName());
break;
}

View File

@ -60,6 +60,7 @@ class InnerNode;
class ExampleNode;
class QmlClassNode;
class QDocDatabase;
class QmlModuleNode;
class QmlPropertyNode;
typedef QList<Node*> NodeList;
@ -193,6 +194,7 @@ public:
void markNotSeen() { seen_ = false; }
virtual bool isInnerNode() const = 0;
virtual bool isQmlModule() const { return false; }
virtual bool isExample() const { return false; }
virtual bool isExampleFile() const { return false; }
virtual bool isLeaf() const { return false; }
@ -263,10 +265,12 @@ public:
QString extractClassName(const QString &string) const;
virtual QString qmlTypeName() const { return name_; }
virtual QString qmlFullBaseName() const { return QString(); }
virtual QString qmlModuleName() const { return qmlModuleName_; }
virtual QString qmlModuleVersion() const { return qmlModuleVersionMajor_ + "." + qmlModuleVersionMinor_; }
virtual QString qmlModuleIdentifier() const { return qmlModuleName_ + qmlModuleVersionMajor_; }
virtual bool setQmlModuleInfo(const QString& );
virtual QString qmlModuleName() const { return QString(); }
virtual QString qmlModuleVersion() const { return QString(); }
virtual QString qmlModuleIdentifier() const { return QString(); }
virtual void setQmlModuleInfo(const QString& ) { }
virtual QmlModuleNode* qmlModule() const { return 0; }
virtual void setQmlModule(QmlModuleNode* ) { }
virtual ClassNode* classNode() { return 0; }
virtual void setClassNode(ClassNode* ) { }
virtual void clearCurrentChild() { }
@ -316,9 +320,6 @@ private:
QString reconstitutedBrief_;
mutable QString uuid_;
QString outSubDir_;
QString qmlModuleName_;
QString qmlModuleVersionMajor_;
QString qmlModuleVersionMinor_;
static QStringMap operators_;
static int propertyGroupCount_;
};
@ -526,6 +527,25 @@ private:
QString qtVariable_;
};
class QmlModuleNode : public DocNode
{
public:
QmlModuleNode(InnerNode* parent, const QString& name)
: DocNode(parent, name, Node::QmlModule, Node::OverviewPage) { }
virtual ~QmlModuleNode() { }
virtual bool isQmlModule() const { return true; }
virtual QString qmlModuleName() const { return qmlModuleName_; }
virtual QString qmlModuleVersion() const { return qmlModuleVersionMajor_ + "." + qmlModuleVersionMinor_; }
virtual QString qmlModuleIdentifier() const { return qmlModuleName_ + qmlModuleVersionMajor_; }
virtual void setQmlModuleInfo(const QString& );
private:
QString qmlModuleName_;
QString qmlModuleVersionMajor_;
QString qmlModuleVersionMinor_;
};
class NameCollisionNode : public DocNode
{
public:
@ -603,6 +623,11 @@ public:
virtual QString qmlFullBaseName() const;
virtual QString obsoleteLink() const { return obsoleteLink_; }
virtual void setObsoleteLink(const QString& t) { obsoleteLink_ = t; };
virtual QString qmlModuleName() const;
virtual QString qmlModuleVersion() const;
virtual QString qmlModuleIdentifier() const;
virtual QmlModuleNode* qmlModule() const { return qmlModule_; }
virtual void setQmlModule(QmlModuleNode* t) { qmlModule_ = t; }
const ImportList& importList() const { return importList_; }
void setImportList(const ImportList& il) { importList_ = il; }
const QString& qmlBaseName() const { return baseName_; }
@ -626,6 +651,7 @@ private:
ClassNode* cnode_;
QString baseName_;
QString obsoleteLink_;
QmlModuleNode* qmlModule_;
QmlClassNode* baseNode_;
ImportList importList_;
};

View File

@ -185,27 +185,17 @@ DocNode* QDocDatabase::findModule(const QString& name)
If a new QML module node is added, its parent is the tree root,
and the new QML module node is marked \e{not seen}.
*/
DocNode* QDocDatabase::findQmlModule(const QString& name)
QmlModuleNode* QDocDatabase::findQmlModule(const QString& name)
{
QStringList dotSplit;
QStringList blankSplit = name.split(QLatin1Char(' '));
QString qmid = blankSplit[0];
QString qmlModuleName = qmid;
if (blankSplit.size() > 1) {
dotSplit = blankSplit[1].split(QLatin1Char('.'));
qmid += dotSplit[0];
}
DocNode* dn = 0;
if (qmlModules_.contains(qmlModuleName))
return qmlModules_.value(qmlModuleName);
dn = new DocNode(tree_->root(), qmlModuleName, Node::QmlModule, Node::OverviewPage);
dn->markNotSeen();
dn->setQmlModuleInfo(name);
qmlModules_.insert(qmlModuleName,dn);
masterMap_.insert(qmlModuleName,dn);
masterMap_.insert(qmid,dn);
masterMap_.insert(dn->name(),dn);
return dn;
if (qmlModules_.contains(name))
return static_cast<QmlModuleNode*>(qmlModules_.value(name));
QmlModuleNode* qmn = new QmlModuleNode(tree_->root(), name);
qmn->markNotSeen();
qmn->setQmlModuleInfo(name);
qmlModules_.insert(name, qmn);
masterMap_.insert(name, qmn);
return qmn;
}
/*!
@ -246,11 +236,14 @@ DocNode* QDocDatabase::addModule(const QString& name)
to that node is returned. The QML module node is marked \e{seen}
in either case.
*/
DocNode* QDocDatabase::addQmlModule(const QString& name)
QmlModuleNode* QDocDatabase::addQmlModule(const QString& name)
{
DocNode* qmlModule = findQmlModule(name);
qmlModule->markSeen();
return qmlModule;
QStringList blankSplit = name.split(QLatin1Char(' '));
QmlModuleNode* qmn = findQmlModule(blankSplit[0]);
qmn->setQmlModuleInfo(name);
qmn->markSeen();
masterMap_.insert(qmn->qmlModuleIdentifier(),qmn);
return qmn;
}
/*!
@ -289,9 +282,8 @@ DocNode* QDocDatabase::addToModule(const QString& name, Node* node)
Looks up the QML module named \a name. If it isn't there,
create it. Then append \a node to the QML module's member
list. The parent of \a node is not changed by this function.
Returns a pointer to the QML module node.
*/
DocNode* QDocDatabase::addToQmlModule(const QString& name, Node* node)
void QDocDatabase::addToQmlModule(const QString& name, Node* node)
{
QStringList qmid;
QStringList dotSplit;
@ -302,9 +294,11 @@ DocNode* QDocDatabase::addToQmlModule(const QString& name, Node* node)
dotSplit = blankSplit[1].split(QLatin1Char('.'));
qmid.append(blankSplit[0] + dotSplit[0]);
}
DocNode* dn = findQmlModule(name);
dn->addMember(node);
node->setQmlModuleInfo(name);
QmlModuleNode* qmn = findQmlModule(blankSplit[0]);
qmn->addMember(node);
node->setQmlModule(qmn);
if (node->subType() == Node::QmlClass) {
QmlClassNode* n = static_cast<QmlClassNode*>(node);
for (int i=0; i<qmid.size(); ++i) {
@ -317,7 +311,6 @@ DocNode* QDocDatabase::addToQmlModule(const QString& name, Node* node)
if (!masterMap_.contains(node->name(),node))
masterMap_.insert(node->name(),node);
}
return dn;
}
/*!

View File

@ -96,15 +96,15 @@ class QDocDatabase
DocNode* getGroup(const QString& name);
DocNode* findGroup(const QString& name);
DocNode* findModule(const QString& name);
DocNode* findQmlModule(const QString& name);
QmlModuleNode* findQmlModule(const QString& name);
DocNode* addGroup(const QString& name);
DocNode* addModule(const QString& name);
DocNode* addQmlModule(const QString& name);
QmlModuleNode* addQmlModule(const QString& name);
DocNode* addToGroup(const QString& name, Node* node);
DocNode* addToModule(const QString& name, Node* node);
DocNode* addToQmlModule(const QString& name, Node* node);
void addToQmlModule(const QString& name, Node* node);
QmlClassNode* findQmlType(const QString& qmid, const QString& name) const;
QmlClassNode* findQmlType(const ImportRec& import, const QString& name) const;

View File

@ -202,9 +202,8 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
QmlClassNode* qcn = new QmlClassNode(parent, name);
qcn->setTitle(element.attribute("title"));
QString qmlModuleName = element.attribute("qml-module-name");
QString qmlModuleVersion = element.attribute("qml-module-version");
if (!qmlModuleName.isEmpty())
qdb_->addToQmlModule(qmlModuleName + " " + qmlModuleVersion, qcn);
qdb_->addToQmlModule(qmlModuleName, qcn);
QString qmlFullBaseName = element.attribute("qml-base-type");
if (!qmlFullBaseName.isEmpty())
qcn->setQmlBaseName(qmlFullBaseName);
@ -273,50 +272,58 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
else if (element.nodeName() == "page") {
Node::SubType subtype;
Node::PageType ptype = Node::NoPageType;
if (element.attribute("subtype") == "example") {
QString attr = element.attribute("subtype");
if (attr == "example") {
subtype = Node::Example;
ptype = Node::ExamplePage;
}
else if (element.attribute("subtype") == "header") {
else if (attr == "header") {
subtype = Node::HeaderFile;
ptype = Node::ApiPage;
}
else if (element.attribute("subtype") == "file") {
else if (attr == "file") {
subtype = Node::File;
ptype = Node::NoPageType;
}
else if (element.attribute("subtype") == "group") {
else if (attr == "group") {
subtype = Node::Group;
ptype = Node::OverviewPage;
}
else if (element.attribute("subtype") == "module") {
else if (attr == "module") {
subtype = Node::Module;
ptype = Node::OverviewPage;
}
else if (element.attribute("subtype") == "qmlmodule") {
else if (attr == "qmlmodule") {
subtype = Node::QmlModule;
ptype = Node::OverviewPage;
}
else if (element.attribute("subtype") == "page") {
else if (attr == "page") {
subtype = Node::Page;
ptype = Node::ArticlePage;
}
else if (element.attribute("subtype") == "externalpage") {
else if (attr == "externalpage") {
subtype = Node::ExternalPage;
ptype = Node::ArticlePage;
}
else if (element.attribute("subtype") == "qmlclass") {
else if (attr == "qmlclass") {
subtype = Node::QmlClass;
ptype = Node::ApiPage;
}
else if (element.attribute("subtype") == "qmlbasictype") {
else if (attr == "qmlbasictype") {
subtype = Node::QmlBasicType;
ptype = Node::ApiPage;
}
else
return;
DocNode* docNode = new DocNode(parent, name, subtype, ptype);
DocNode* docNode = 0;
if (subtype == Node::QmlModule) {
QString t = element.attribute("qml-module-name") + " " +
element.attribute("qml-module-version");
docNode = qdb_->addQmlModule(t);
}
else
docNode = new DocNode(parent, name, subtype, ptype);
docNode->setTitle(element.attribute("title"));
if (element.hasAttribute("location"))
@ -650,8 +657,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
nodeName = "page";
if (node->subType() == Node::QmlClass) {
nodeName = "qmlclass";
qmlModuleName = node->qmlModuleName();
qmlModuleVersion = node->qmlModuleVersion();
QmlModuleNode* qmn = node->qmlModule();
if (qmn)
qmlModuleName = qmn->qmlModuleName();
qmlFullBaseName = node->qmlFullBaseName();
}
else if (node->subType() == Node::QmlBasicType)
@ -771,9 +779,14 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("status", status);
writer.writeAttribute("name", objName);
if (node->isQmlModule()) {
qmlModuleName = node->qmlModuleName();
qmlModuleVersion = node->qmlModuleVersion();
}
if (!qmlModuleName.isEmpty()) {
writer.writeAttribute("qml-module-name", qmlModuleName);
writer.writeAttribute("qml-module-version", qmlModuleVersion);
if (node->isQmlModule())
writer.writeAttribute("qml-module-version", qmlModuleVersion);
if (!qmlFullBaseName.isEmpty())
writer.writeAttribute("qml-base-type", qmlFullBaseName);
}

View File

@ -374,6 +374,9 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation,
}
else if (command == COMMAND_INQMLMODULE) {
qdb->addToQmlModule(args[0].first,node);
if (node->name() == QString("workerscript"))
qDebug() << "INQMLMODULE workerscript:" << node << node->qmlModule()
<< node->qmlModule()->isIndexNode() << node->name() << args[0].first;
}
else if (command == COMMAND_QMLINHERITS) {
if (node->name() == args[0].first)

View File

@ -758,17 +758,4 @@ NamespaceNode* Tree::findNamespaceNode(const QStringList& path) const
return static_cast<NamespaceNode*>(findNodeRecursive(path, 0, start, Node::Namespace, Node::NoSubType));
}
/*!
Find the Qml module node named \a path. Begin the search at the
\a start node. If the \a start node is 0, begin the search
at the root of the tree. Only a Qml module node named \a path is
acceptible. If one is not found, 0 is returned.
*/
DocNode* Tree::findQmlModuleNode(const QStringList& path, Node* start)
{
if (!start)
start = const_cast<NamespaceNode*>(root());
return static_cast<DocNode*>(findNodeRecursive(path, 0, start, Node::Document, Node::QmlModule));
}
QT_END_NAMESPACE

View File

@ -85,7 +85,6 @@ class Tree
ClassNode* findClassNode(const QStringList& path, Node* start = 0) const;
QmlClassNode* findQmlTypeNode(const QStringList& path);
NamespaceNode* findNamespaceNode(const QStringList& path) const;
DocNode* findQmlModuleNode(const QStringList& path, Node* start = 0);
Node* findNodeByNameAndType(const QStringList& path,
Node::Type type,