qdoc: Support documentation of JavaScript

This update provides the actual support for documenting
JavaScript. It has been tested with JavaScript commands
in qdoc comments in .qdoc files but not in .js files.
Currently, we have the use case of needing to document
JavaScript using qdoc comments in .qdoc files.

For each qdoc command for QML, i.e. \qmltype, \qmlproperty,
etc, there is now a corresponding JavaScript command, i.e.
\jstype, \jsproperty, etc. Some of these might not be needed,
but they are all provided.

Briefly, document JavaScript in a .qdoc file the same way you
would document QML in a .qdoc file, but instead of using the
\qmlxxx commands, use \jsxxx commands.

Change-Id: Ib68a5f66c16472af87d9f776db162332ca13fbb7
Task-number: QTBUG-43715
Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
This commit is contained in:
Martin Smith 2015-02-13 13:00:22 +01:00
parent fe7c2662b5
commit 62a2f46d29
22 changed files with 1023 additions and 942 deletions

View File

@ -394,7 +394,7 @@ void CodeMarker::insert(FastSection &fastSection,
if (p->type() == Node::QmlPropertyGroup)
p = p->parent();
if (p != fastSection.parent_) {
if (!p->isQmlType() || !p->isAbstract()) {
if ((!p->isQmlType() && !p->isJsType()) || !p->isAbstract()) {
inheritedMember = true;
}
}

View File

@ -218,7 +218,8 @@ const QSet<QString>& CodeParser::commonMetaCommands()
<< COMMAND_SUBTITLE
<< COMMAND_THREADSAFE
<< COMMAND_TITLE
<< COMMAND_WRAPPER;
<< COMMAND_WRAPPER
<< COMMAND_INJSMODULE;
}
return commonMetaCommands_;
}
@ -251,6 +252,9 @@ void CodeParser::processCommonMetaCommand(const Location& location,
else if (command == COMMAND_INQMLMODULE) {
qdb_->addToQmlModule(arg.first,node);
}
else if (command == COMMAND_INJSMODULE) {
qdb_->addToJsModule(arg.first, node);
}
else if (command == COMMAND_MAINCLASS) {
node->setStatus(Node::Main);
}
@ -297,14 +301,14 @@ void CodeParser::processCommonMetaCommand(const Location& location,
}
else if (command == COMMAND_TITLE) {
node->setTitle(arg.first);
if (!node->isDocNode() && !node->isCollectionNode())
if (!node->isDocumentNode() && !node->isCollectionNode())
location.warning(tr("Ignored '\\%1'").arg(COMMAND_SUBTITLE));
else if (node->isExample())
qdb_->addExampleNode(static_cast<ExampleNode*>(node));
}
else if (command == COMMAND_SUBTITLE) {
node->setSubTitle(arg.first);
if (!node->isDocNode() && !node->isCollectionNode())
if (!node->isDocumentNode() && !node->isCollectionNode())
location.warning(tr("Ignored '\\%1'").arg(COMMAND_SUBTITLE));
}
else if (command == COMMAND_QTVARIABLE) {

View File

@ -135,7 +135,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
name = "<@name>" + name + "</@name>";
if ((style == Detailed) && !node->parent()->name().isEmpty() &&
(node->type() != Node::Property) && !node->isQmlNode())
(node->type() != Node::Property) && !node->isQmlNode() && !node->isJsNode())
name.prepend(taggedNode(node->parent()) + "::");
switch (node->type()) {
@ -307,14 +307,14 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
QString name = taggedQmlNode(node);
if (summary)
name = linkTag(node,name);
else if (node->type() == Node::QmlProperty) {
else if (node->isQmlProperty() || node->isJsProperty()) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
if (pn->isAttached())
name.prepend(pn->element() + QLatin1Char('.'));
}
name = "<@name>" + name + "</@name>";
QString synopsis;
if (node->type() == Node::QmlProperty) {
if (node->isQmlProperty() || node->isJsProperty()) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
synopsis = name + " : " + typified(pn->dataType());
}
@ -1134,10 +1134,10 @@ QList<Section> CppCodeMarker::qmlSections(QmlTypeNode* qmlTypeNode, SynopsisStyl
++c;
continue;
}
if ((*c)->type() == Node::QmlPropertyGroup) {
if ((*c)->isQmlPropertyGroup() || (*c)->isJsPropertyGroup()) {
insert(qmlproperties, *c, style, status);
}
else if ((*c)->type() == Node::QmlProperty) {
else if ((*c)->isQmlProperty() || (*c)->isJsProperty()) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
if (pn->isAttached())
insert(qmlattachedproperties,*c,style, status);
@ -1145,17 +1145,17 @@ QList<Section> CppCodeMarker::qmlSections(QmlTypeNode* qmlTypeNode, SynopsisStyl
insert(qmlproperties,*c,style, status);
}
}
else if ((*c)->type() == Node::QmlSignal) {
else if ((*c)->isQmlSignal() || (*c)->isJsSignal()) {
const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
if (sn->isAttached())
insert(qmlattachedsignals,*c,style, status);
else
insert(qmlsignals,*c,style, status);
}
else if ((*c)->type() == Node::QmlSignalHandler) {
else if ((*c)->isQmlSignalHandler() || (*c)->isJsSignalHandler()) {
insert(qmlsignalhandlers,*c,style, status);
}
else if ((*c)->type() == Node::QmlMethod) {
else if ((*c)->isQmlMethod() || (*c)->isJsMethod()) {
const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
if (mn->isAttached())
insert(qmlattachedmethods,*c,style, status);
@ -1199,27 +1199,27 @@ QList<Section> CppCodeMarker::qmlSections(QmlTypeNode* qmlTypeNode, SynopsisStyl
++c;
continue;
}
if ((*c)->type() == Node::QmlPropertyGroup) {
if ((*c)->isQmlPropertyGroup() || (*c)->isJsPropertyGroup()) {
insert(qmlproperties,*c,style, status);
}
else if ((*c)->type() == Node::QmlProperty) {
else if ((*c)->isQmlProperty() || (*c)->isJsProperty()) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
if (pn->isAttached())
insert(qmlattachedproperties,*c,style, status);
else
insert(qmlproperties,*c,style, status);
}
else if ((*c)->type() == Node::QmlSignal) {
else if ((*c)->isQmlSignal() || (*c)->isJsSignal()) {
const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
if (sn->isAttached())
insert(qmlattachedsignals,*c,style, status);
else
insert(qmlsignals,*c,style, status);
}
else if ((*c)->type() == Node::QmlSignalHandler) {
else if ((*c)->isQmlSignalHandler() || (*c)->isJsSignalHandler()) {
insert(qmlsignalhandlers,*c,style, status);
}
else if ((*c)->type() == Node::QmlMethod) {
else if ((*c)->isQmlMethod() || (*c)->isJsMethod()) {
const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
if (mn->isAttached())
insert(qmlattachedmethods,*c,style, status);
@ -1271,11 +1271,11 @@ QList<Section> CppCodeMarker::qmlSections(QmlTypeNode* qmlTypeNode, SynopsisStyl
}
NodeList::ConstIterator c = current->childNodes().constBegin();
while (c != current->childNodes().constEnd()) {
if ((*c)->type() == Node::QmlPropertyGroup) {
if ((*c)->isQmlPropertyGroup() || (*c)->isJsPropertyGroup()) {
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*c);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
if ((*p)->isQmlProperty() || (*c)->isJsProperty()) {
QString key = (*p)->name();
key = sortName(*p, &key);
all.memberMap.insert(key,*p);

View File

@ -285,7 +285,6 @@ const QSet<QString>& CppCodeParser::topicCommands()
<< COMMAND_PROPERTY
<< COMMAND_TYPEDEF
<< COMMAND_VARIABLE
<< COMMAND_QMLCLASS
<< COMMAND_QMLTYPE
<< COMMAND_QMLPROPERTY
<< COMMAND_QMLPROPERTYGROUP
@ -446,37 +445,56 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
}
}
else if (command == COMMAND_EXTERNALPAGE) {
DocNode* dn = new DocNode(qdb_->primaryTreeRoot(), arg.first, Node::ExternalPage, Node::ArticlePage);
DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
arg.first,
Node::ExternalPage,
Node::ArticlePage);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_FILE) {
DocNode* dn = new DocNode(qdb_->primaryTreeRoot(), arg.first, Node::File, Node::NoPageType);
DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
arg.first,
Node::File,
Node::NoPageType);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_HEADERFILE) {
DocNode* dn = new DocNode(qdb_->primaryTreeRoot(), arg.first, Node::HeaderFile, Node::ApiPage);
DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
arg.first,
Node::HeaderFile,
Node::ApiPage);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_GROUP) {
GroupNode* gn = qdb_->addGroup(arg.first);
gn->setLocation(doc.startLocation());
gn->markSeen();
return gn;
CollectionNode* cn = qdb_->addGroup(arg.first);
cn->setLocation(doc.startLocation());
cn->markSeen();
return cn;
}
else if (command == COMMAND_MODULE) {
ModuleNode* mn = qdb_->addModule(arg.first);
mn->setLocation(doc.startLocation());
mn->markSeen();
return mn;
CollectionNode* cn = qdb_->addModule(arg.first);
cn->setLocation(doc.startLocation());
cn->markSeen();
return cn;
}
else if (command == COMMAND_QMLMODULE) {
QmlModuleNode* qmn = qdb_->addQmlModule(arg.first);
qmn->setLocation(doc.startLocation());
qmn->markSeen();
return qmn;
QStringList blankSplit = arg.first.split(QLatin1Char(' '));
CollectionNode* cn = qdb_->addQmlModule(blankSplit[0]);
cn->setLogicalModuleInfo(blankSplit);
cn->setLocation(doc.startLocation());
cn->markSeen();
return cn;
}
else if (command == COMMAND_JSMODULE) {
QStringList blankSplit = arg.first.split(QLatin1Char(' '));
CollectionNode* cn = qdb_->addJsModule(blankSplit[0]);
cn->setLogicalModuleInfo(blankSplit);
cn->setLocation(doc.startLocation());
cn->markSeen();
return cn;
}
else if (command == COMMAND_PAGE) {
Node::PageType ptype = Node::ArticlePage;
@ -508,66 +526,41 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
tr("Also used here: %1").arg(other));
}
#endif
DocNode* dn = 0;
DocumentNode* dn = 0;
if (ptype == Node::DitaMapPage)
dn = new DitaMapNode(qdb_->primaryTreeRoot(), args[0]);
else
dn = new DocNode(qdb_->primaryTreeRoot(), args[0], Node::Page, ptype);
dn = new DocumentNode(qdb_->primaryTreeRoot(), args[0], Node::Page, ptype);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_DITAMAP) {
DocNode* dn = new DitaMapNode(qdb_->primaryTreeRoot(), arg.first);
DocumentNode* dn = new DitaMapNode(qdb_->primaryTreeRoot(), arg.first);
dn->setLocation(doc.startLocation());
return dn;
}
else if ((command == COMMAND_QMLCLASS) || (command == COMMAND_QMLTYPE)) {
if (command == COMMAND_QMLCLASS)
doc.startLocation().warning(tr("\\qmlclass is deprecated; use \\qmltype instead"));
ClassNode* classNode = 0;
QStringList names = arg.first.split(QLatin1Char(' '));
if (names.size() > 1) {
if (names[1] != "0")
doc.startLocation().warning(tr("\\qmltype no longer has a 2nd argument; "
"use '\\instantiates <class>' in \\qmltype "
"comments instead"));
else
doc.startLocation().warning(tr("The 0 arg is no longer used for indicating "
"that the QML type does not instantiate a "
"C++ class"));
/*
If the second argument of the \\qmlclass command
is 0 we should ignore the C++ class. The second
argument should only be 0 when you are documenting
QML in a .qdoc file.
*/
if (names[1] != "0")
classNode = qdb_->findClassNode(names[1].split("::"));
}
#if 0
const Node* n = qdb_->checkForCollision(names[0]);
if (n) {
QString other = n->doc().location().fileName();
doc.location().warning(tr("Name/title collision detected: '%1' in '\\%2'")
.arg(names[0]).arg(command),
tr("Also used here: %1").arg(other));
}
#endif
QmlTypeNode* qcn = new QmlTypeNode(qdb_->primaryTreeRoot(), names[0]);
qcn->setClassNode(classNode);
else if ((command == COMMAND_QMLTYPE) || (command == COMMAND_JSTYPE)) {
QmlTypeNode* qcn = new QmlTypeNode(qdb_->primaryTreeRoot(), arg.first);
if (command == COMMAND_JSTYPE)
qcn->setGenus(Node::JS);
qcn->setLocation(doc.startLocation());
return qcn;
}
else if (command == COMMAND_QMLBASICTYPE) {
else if ((command == COMMAND_QMLBASICTYPE) || (command == COMMAND_JSBASICTYPE)) {
QmlBasicTypeNode* n = new QmlBasicTypeNode(qdb_->primaryTreeRoot(), arg.first);
if (command == COMMAND_JSBASICTYPE)
n->setGenus(Node::JS);
n->setLocation(doc.startLocation());
return n;
}
else if ((command == COMMAND_QMLSIGNAL) ||
(command == COMMAND_QMLMETHOD) ||
(command == COMMAND_QMLATTACHEDSIGNAL) ||
(command == COMMAND_QMLATTACHEDMETHOD)) {
(command == COMMAND_QMLATTACHEDMETHOD) ||
(command == COMMAND_JSSIGNAL) ||
(command == COMMAND_JSMETHOD) ||
(command == COMMAND_JSATTACHEDSIGNAL) ||
(command == COMMAND_JSATTACHEDMETHOD)) {
QString module;
QString qmlTypeName;
QString type;
@ -576,16 +569,20 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
if (qmlType) {
bool attached = false;
Node::Type nodeType = Node::QmlMethod;
if (command == COMMAND_QMLSIGNAL)
if ((command == COMMAND_QMLSIGNAL) ||
(command == COMMAND_JSSIGNAL))
nodeType = Node::QmlSignal;
else if (command == COMMAND_QMLATTACHEDSIGNAL) {
else if ((command == COMMAND_QMLATTACHEDSIGNAL) ||
(command == COMMAND_JSATTACHEDSIGNAL)) {
nodeType = Node::QmlSignal;
attached = true;
}
else if (command == COMMAND_QMLMETHOD) {
else if ((command == COMMAND_QMLMETHOD) ||
(command == COMMAND_JSMETHOD)) {
// do nothing
}
else if (command == COMMAND_QMLATTACHEDMETHOD)
else if ((command == COMMAND_QMLATTACHEDMETHOD) ||
(command == COMMAND_JSATTACHEDMETHOD))
attached = true;
else
return 0; // never get here.
@ -595,8 +592,14 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
nodeType,
attached,
command);
if (fn)
if (fn) {
fn->setLocation(doc.startLocation());
if ((command == COMMAND_JSSIGNAL) ||
(command == COMMAND_JSMETHOD) ||
(command == COMMAND_JSATTACHEDSIGNAL) ||
(command == COMMAND_JSATTACHEDMETHOD))
fn->setGenus(Node::JS);
}
return fn;
}
}
@ -741,7 +744,10 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
Currently, this function is called only for \e{qmlproperty}
and \e{qmlattachedproperty}.
*/
void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs)
void CppCodeParser::processQmlProperties(const Doc& doc,
NodeList& nodes,
DocList& docs,
bool jsProps)
{
QString arg;
QString type;
@ -756,14 +762,18 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis
Topic qmlPropertyGroupTopic;
const TopicList& topics = doc.topicsUsed();
for (int i=0; i<topics.size(); ++i) {
if (topics.at(i).topic == COMMAND_QMLPROPERTYGROUP) {
if ((topics.at(i).topic == COMMAND_QMLPROPERTYGROUP) ||
(topics.at(i).topic == COMMAND_JSPROPERTYGROUP)) {
qmlPropertyGroupTopic = topics.at(i);
break;
}
}
if (qmlPropertyGroupTopic.isEmpty() && topics.size() > 1) {
qmlPropertyGroupTopic = topics.at(0);
qmlPropertyGroupTopic.topic = COMMAND_QMLPROPERTYGROUP;
if (jsProps)
qmlPropertyGroupTopic.topic = COMMAND_JSPROPERTYGROUP;
else
qmlPropertyGroupTopic.topic = COMMAND_QMLPROPERTYGROUP;
arg = qmlPropertyGroupTopic.args;
if (splitQmlPropertyArg(arg, type, module, qmlTypeName, property)) {
int i = property.indexOf('.');
@ -790,6 +800,8 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis
if (qmlType) {
qpgn = new QmlPropertyGroupNode(qmlType, property);
qpgn->setLocation(doc.startLocation());
if (jsProps)
qpgn->setGenus(Node::JS);
nodes.append(qpgn);
docs.append(doc);
}
@ -801,8 +813,10 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis
}
topic = topics.at(i).topic;
arg = topics.at(i).args;
if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) {
bool attached = (topic == COMMAND_QMLATTACHEDPROPERTY);
if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY) ||
(topic == COMMAND_JSPROPERTY) || (topic == COMMAND_JSATTACHEDPROPERTY)) {
bool attached = ((topic == COMMAND_QMLATTACHEDPROPERTY) ||
(topic == COMMAND_JSATTACHEDPROPERTY));
if (splitQmlPropertyArg(arg, type, module, qmlTypeName, property)) {
qmlType = qdb_->findQmlType(module, qmlTypeName);
if (qmlType) {
@ -813,10 +827,14 @@ void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocLis
else if (qpgn) {
qpn = new QmlPropertyNode(qpgn, property, type, attached);
qpn->setLocation(doc.startLocation());
if (jsProps)
qpn->setGenus(Node::JS);
}
else {
qpn = new QmlPropertyNode(qmlType, property, type, attached);
qpn->setLocation(doc.startLocation());
if (jsProps)
qpn->setGenus(Node::JS);
nodes.append(qpn);
docs.append(doc);
}
@ -941,14 +959,14 @@ 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 if (node->isQmlType()) {
else if (node->isQmlType() || node->isJsType()) {
QmlTypeNode* qmlType = static_cast<QmlTypeNode*>(node);
qmlType->setQmlBaseName(arg);
QmlTypeNode::addInheritedBy(arg,node);
}
}
else if (command == COMMAND_QMLINSTANTIATES) {
if (node->isQmlType()) {
if (node->isQmlType() || node->isJsType()) {
ClassNode* classNode = qdb_->findClassNode(arg.split("::"));
if (classNode)
node->setClassNode(classNode);
@ -993,7 +1011,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
}
}
else if (command == COMMAND_QMLABSTRACT) {
if (node->isQmlType())
if (node->isQmlType() || node->isJsType())
node->setAbstract(true);
}
else {
@ -2095,6 +2113,7 @@ bool CppCodeParser::matchDocsAndStuff()
Doc doc(start_loc,end_loc,comment,metacommandsAllowed, topicCommandsAllowed);
QString topic;
bool isQmlPropertyTopic = false;
bool isJsPropertyTopic = false;
const TopicList& topics = doc.topicsUsed();
if (!topics.isEmpty()) {
@ -2104,6 +2123,11 @@ bool CppCodeParser::matchDocsAndStuff()
(topic == COMMAND_QMLATTACHEDPROPERTY)) {
isQmlPropertyTopic = true;
}
else if ((topic == COMMAND_JSPROPERTY) ||
(topic == COMMAND_JSPROPERTYGROUP) ||
(topic == COMMAND_JSATTACHEDPROPERTY)) {
isJsPropertyTopic = true;
}
}
NodeList nodes;
DocList docs;
@ -2140,9 +2164,9 @@ bool CppCodeParser::matchDocsAndStuff()
.arg(COMMAND_FN).arg(COMMAND_PAGE));
}
}
else if (isQmlPropertyTopic) {
else if (isQmlPropertyTopic || isJsPropertyTopic) {
Doc nodeDoc = doc;
processQmlProperties(nodeDoc, nodes, docs);
processQmlProperties(nodeDoc, nodes, docs, isJsPropertyTopic);
}
else {
ArgList args;
@ -2326,7 +2350,7 @@ void CppCodeParser::instantiateIteratorMacro(const QString &container,
matchDeclList(QDocDatabase::qdocDB()->primaryTreeRoot());
}
void CppCodeParser::createExampleFileNodes(DocNode *dn)
void CppCodeParser::createExampleFileNodes(DocumentNode *dn)
{
QString examplePath = dn->name();
QString proFileName = examplePath + QLatin1Char('/') + examplePath.split(QLatin1Char('/')).last() + ".pro";
@ -2394,13 +2418,13 @@ void CppCodeParser::createExampleFileNodes(DocNode *dn)
}
foreach (const QString &exampleFile, exampleFiles) {
new DocNode(dn,
new DocumentNode(dn,
exampleFile.mid(sizeOfBoringPartOfName),
Node::File,
Node::NoPageType);
}
foreach (const QString &imageFile, imageFiles) {
new DocNode(dn,
new DocumentNode(dn,
imageFile.mid(sizeOfBoringPartOfName),
Node::Image,
Node::NoPageType);

View File

@ -81,7 +81,7 @@ protected:
virtual Node* processTopicCommand(const Doc& doc,
const QString& command,
const ArgLocPair& arg);
void processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs);
void processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs, bool jsProps);
bool splitQmlPropertyGroupArg(const QString& arg,
QString& module,
QString& element,
@ -148,7 +148,7 @@ protected:
void instantiateIteratorMacro(const QString &container,
const QString &includeFile,
const QString &macroDef);
void createExampleFileNodes(DocNode *dn);
void createExampleFileNodes(DocumentNode *dn);
protected:
QMap<QString, Node::Type> nodeTypeMap;
@ -203,7 +203,6 @@ protected:
#define COMMAND_TYPEDEF Doc::alias("typedef")
#define COMMAND_VARIABLE Doc::alias("variable")
#define COMMAND_QMLABSTRACT Doc::alias("qmlabstract")
#define COMMAND_QMLCLASS Doc::alias("qmlclass")
#define COMMAND_QMLTYPE Doc::alias("qmltype")
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
#define COMMAND_QMLPROPERTYGROUP Doc::alias("qmlpropertygroup")

View File

@ -2821,9 +2821,6 @@ QString DocParser::slashed(const QString& str)
return QLatin1Char('/') + result + QLatin1Char('/');
}
#define COMMAND_BRIEF Doc::alias("brief")
#define COMMAND_QMLBRIEF Doc::alias("qmlbrief")
/*!
Parse the qdoc comment \a source. Build up a list of all the topic
commands found including their arguments. This constructor is used

View File

@ -310,7 +310,7 @@ QString Generator::fileBase(const Node *node) const
return node->fileNameBase();
QString base;
if (node->isDocNode()) {
if (node->isDocumentNode()) {
base = node->name();
if (base.endsWith(".html") && !node->isExampleFile())
base.truncate(base.length() - 5);
@ -326,7 +326,8 @@ QString Generator::fileBase(const Node *node) const
base.append(QLatin1String("-example"));
}
}
else if (node->isQmlType() || node->isQmlBasicType()) {
else if (node->isQmlType() || node->isQmlBasicType() ||
node->isJsType() || node->isJsBasicType()) {
base = node->name();
if (!node->logicalModuleName().isEmpty()) {
base.prepend(node->logicalModuleName() + QLatin1Char('-'));
@ -336,7 +337,10 @@ QString Generator::fileBase(const Node *node) const
we prepend a prefix (by default, "qml-") to the file name of QML
element doc files.
*/
base.prepend(outputPrefix(QLatin1String("QML")));
if (node->isQmlType() || node->isQmlBasicType())
base.prepend(outputPrefix(QLatin1String("QML")));
else
base.prepend(outputPrefix(QLatin1String("JS")));
}
else if (node->isCollectionNode()) {
base = node->name();
@ -346,6 +350,9 @@ QString Generator::fileBase(const Node *node) const
if (node->isQmlModule()) {
base.append("-qmlmodule");
}
else if (node->isJsModule()) {
base.append("-jsmodule");
}
else if (node->isModule()) {
base.append("-module");
}
@ -356,7 +363,7 @@ QString Generator::fileBase(const Node *node) const
forever {
const Node *pp = p->parent();
base.prepend(p->name());
if (!pp || pp->name().isEmpty() || pp->isDocNode())
if (!pp || pp->name().isEmpty() || pp->isDocumentNode())
break;
base.prepend(QLatin1Char('-'));
p = pp;
@ -456,21 +463,27 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
else
return QString();
}
else if (node->isQmlType() || node->isQmlBasicType()) {
else if (node->isQmlType() || node->isQmlBasicType() ||
node->isJsType() || node->isJsBasicType()) {
QString fb = fileBase(node);
if (fb.startsWith(Generator::outputPrefix(QLatin1String("QML"))))
return fb + QLatin1Char('.') + currentGenerator()->fileExtension();
else if (fb.startsWith(Generator::outputPrefix(QLatin1String("JS"))))
return fb + QLatin1Char('.') + currentGenerator()->fileExtension();
else {
QString mq;
if (!node->logicalModuleName().isEmpty()) {
mq = node->logicalModuleName().replace(QChar('.'),QChar('-'));
mq = mq.toLower() + QLatin1Char('-');
}
return fdl+ Generator::outputPrefix(QLatin1String("QML")) + mq +
fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
QLatin1String prefix = QLatin1String("QML");
if (node->isJsType() || node->isJsBasicType())
prefix = QLatin1String("JS");
return fdl+ Generator::outputPrefix(prefix) + mq + fileBase(node) +
QLatin1Char('.') + currentGenerator()->fileExtension();
}
}
else if (node->isDocNode() || node->isCollectionNode()) {
else if (node->isDocumentNode() || node->isCollectionNode()) {
parentName = fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
}
else if (fileBase(node).isEmpty())
@ -482,7 +495,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
parentName = fullDocumentLocation(node->relates());
}
else if ((parentNode = node->parent())) {
if (parentNode->type() == Node::QmlPropertyGroup) {
if (parentNode->isQmlPropertyGroup() || parentNode->isJsPropertyGroup()) {
parentNode = parentNode->parent();
parentName = fullDocumentLocation(parentNode);
}
@ -683,7 +696,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
bool quiet = false;
if (node->type() == Node::Document) {
const DocNode *dn = static_cast<const DocNode *>(node);
const DocumentNode *dn = static_cast<const DocumentNode *>(node);
if ((dn->subType() == Node::File) || (dn->subType() == Node::Image)) {
quiet = true;
}
@ -808,8 +821,8 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
}
if (node->isDocNode()) {
const DocNode *dn = static_cast<const DocNode *>(node);
if (node->isDocumentNode()) {
const DocumentNode *dn = static_cast<const DocumentNode *>(node);
if (dn->isExample()) {
generateExampleFiles(dn, marker);
}
@ -829,7 +842,7 @@ void Generator::generateClassLikeNode(InnerNode* /* classe */, CodeMarker* /* ma
{
}
void Generator::generateExampleFiles(const DocNode *dn, CodeMarker *marker)
void Generator::generateExampleFiles(const DocumentNode *dn, CodeMarker *marker)
{
if (dn->childNodes().isEmpty())
return;
@ -837,7 +850,7 @@ void Generator::generateExampleFiles(const DocNode *dn, CodeMarker *marker)
generateFileList(dn, marker, Node::Image, QString("Images:"));
}
void Generator::generateDocNode(DocNode* /* dn */, CodeMarker* /* marker */)
void Generator::generateDocumentNode(DocumentNode* /* dn */, CodeMarker* /* marker */)
{
}
@ -852,7 +865,7 @@ void Generator::generateCollectionNode(CollectionNode* , CodeMarker* )
by the example. The images are copied into a subtree of
\c{...doc/html/images/used-in-examples/...}
*/
void Generator::generateFileList(const DocNode* dn,
void Generator::generateFileList(const DocumentNode* dn,
CodeMarker* marker,
Node::SubType subtype,
const QString& tag)
@ -973,8 +986,8 @@ void Generator::generateInnerNode(InnerNode* node)
if (node->isInternal() && !showInternal_)
return;
if (node->isDocNode()) {
DocNode* docNode = static_cast<DocNode*>(node);
if (node->isDocumentNode()) {
DocumentNode* docNode = static_cast<DocumentNode*>(node);
if (docNode->subType() == Node::ExternalPage)
return;
if (docNode->subType() == Node::Image)
@ -984,7 +997,7 @@ void Generator::generateInnerNode(InnerNode* node)
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
}
}
else if (node->isQmlPropertyGroup())
else if (node->isQmlPropertyGroup() || node->isJsPropertyGroup())
return;
/*
@ -998,44 +1011,44 @@ void Generator::generateInnerNode(InnerNode* node)
generateClassLikeNode(node, marker);
endSubPage();
}
if (node->isQmlType()) {
if (node->isQmlType() || node->isJsType()) {
beginSubPage(node, fileName(node));
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(node);
generateQmlTypePage(qcn, marker);
endSubPage();
}
else if (node->isDocNode()) {
else if (node->isDocumentNode()) {
beginSubPage(node, fileName(node));
generateDocNode(static_cast<DocNode*>(node), marker);
generateDocumentNode(static_cast<DocumentNode*>(node), marker);
endSubPage();
}
else if (node->isQmlBasicType()) {
else if (node->isQmlBasicType() || node->isJsBasicType()) {
beginSubPage(node, fileName(node));
QmlBasicTypeNode* qbtn = static_cast<QmlBasicTypeNode*>(node);
generateQmlBasicTypePage(qbtn, marker);
endSubPage();
}
else if (node->isCollectionNode()) {
CollectionNode* cn = static_cast<CollectionNode*>(node);
/*
A collection node is one of: group, module,
or QML module.
A collection node collects: groups, C++ modules,
QML modules or JavaScript modules.
Don't output an HTML page for the collection
node unless the \group, \module, or \qmlmodule
command was actually seen by qdoc in the qdoc
comment for the node.
node unless the \group, \module, \qmlmodule or
\jsmodule command was actually seen by qdoc in
the qdoc comment for the node.
A key prerequisite in this case is the call to
mergeCollections(cn). We don't know if this
collection (group, module, or QML module) has
members in other modules. We know at this point
that cn's members list contains only members in
the current module. Therefore, before outputting
the page for cn, we must search for members of
cn in the other modules and add them to the
members list.
mergeCollections(cn). We must determine whether
this group, module, QML module, or JavaScript
module has members in other modules. We know at
this point that cn's members list contains only
members in the current module. Therefore, before
outputting the page for cn, we must search for
members of cn in the other modules and add them
to the members list.
*/
CollectionNode* cn = static_cast<CollectionNode*>(node);
if (cn->wasSeen()) {
qdb_->mergeCollections(cn);
beginSubPage(node, fileName(node));
@ -1652,8 +1665,10 @@ void Generator::initialize(const Config &config)
foreach (const QString &prefix, prefixes)
outputPrefixes[prefix] = config.getString(CONFIG_OUTPUTPREFIXES + Config::dot + prefix);
}
else
else {
outputPrefixes[QLatin1String("QML")] = QLatin1String("qml-");
outputPrefixes[QLatin1String("JS")] = QLatin1String("js-");
}
noLinkErrors_ = config.getBool(CONFIG_NOLINKERRORS);
autolinkErrors_ = config.getBool(CONFIG_AUTOLINKERRORS);
}

View File

@ -116,7 +116,7 @@ protected:
virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker);
virtual void generateQmlTypePage(QmlTypeNode* , CodeMarker* ) { }
virtual void generateQmlBasicTypePage(QmlBasicTypeNode* , CodeMarker* ) { }
virtual void generateDocNode(DocNode* dn, CodeMarker* marker);
virtual void generateDocumentNode(DocumentNode* dn, CodeMarker* marker);
virtual void generateCollectionNode(CollectionNode* cn, CodeMarker* marker);
virtual void generateInheritedBy(const ClassNode *classe, CodeMarker *marker);
virtual void generateInherits(const ClassNode *classe, CodeMarker *marker);
@ -149,8 +149,8 @@ protected:
CodeMarker *marker,
bool generate,
int& numGeneratedAtoms);
void generateExampleFiles(const DocNode *dn, CodeMarker *marker);
void generateFileList(const DocNode* dn,
void generateExampleFiles(const DocumentNode *dn, CodeMarker *marker);
void generateFileList(const DocumentNode* dn,
CodeMarker* marker,
Node::SubType subtype,
const QString& tag);

View File

@ -196,7 +196,7 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
{
QStringList details;
if (node->type() == Node::QmlProperty) {
if (node->isQmlProperty() || node->isJsProperty()) {
// "name"
details << node->name();
// "id"
@ -215,8 +215,12 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
details << node->name();
details << "QML." + node->name();
}
else if (node->isDocNode()) {
const DocNode *fake = static_cast<const DocNode *>(node);
else if (node->isJsType() || node->isJsBasicType()) {
details << node->name();
details << "JS." + node->name();
}
else if (node->isDocumentNode()) {
const DocumentNode *fake = static_cast<const DocumentNode *>(node);
details << fake->fullTitle();
details << fake->fullTitle();
}
@ -246,8 +250,8 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
return false;
QString objName;
if (node->isDocNode()) {
const DocNode *fake = static_cast<const DocNode *>(node);
if (node->isDocumentNode()) {
const DocumentNode *fake = static_cast<const DocumentNode *>(node);
objName = fake->fullTitle();
}
else
@ -269,7 +273,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
else {
// Accept only fake nodes with subtypes contained in the selector's
// mask.
const DocNode *docNode = static_cast<const DocNode *>(node);
const DocumentNode *docNode = static_cast<const DocumentNode *>(node);
if (subproject.selectors[node->type()].contains(docNode->subType()) &&
docNode->subType() != Node::ExternalPage &&
!docNode->fullTitle().isEmpty()) {
@ -412,7 +416,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
// Document nodes (such as manual pages) contain subtypes, titles and other
// attributes.
case Node::Document: {
const DocNode *docNode = static_cast<const DocNode*>(node);
const DocumentNode *docNode = static_cast<const DocumentNode*>(node);
if (docNode->subType() != Node::ExternalPage &&
docNode->subType() != Node::Image &&
!docNode->fullTitle().isEmpty()) {
@ -481,17 +485,17 @@ void HelpProjectWriter::generateSections(HelpProject &project,
continue;
if (childNode->type() == Node::Document) {
childMap[static_cast<const DocNode *>(childNode)->fullTitle()] = childNode;
childMap[static_cast<const DocumentNode *>(childNode)->fullTitle()] = childNode;
}
else if (childNode->type() == Node::QmlPropertyGroup) {
else if (childNode->isQmlPropertyGroup() || childNode->isJsPropertyGroup()) {
/*
Don't visit QML property group nodes,
Don't visit QML/JS property group nodes,
but visit their children, which are all
QML property nodes.
QML/JS property nodes.
This is probably not correct anymore,
because The Qml Property Group is an
actual documented thing.
because The Qml/Js Property Group is
an actual documented thing.
*/
const InnerNode* inner = static_cast<const InnerNode*>(childNode);
foreach (const Node* n, inner->childNodes()) {
@ -566,7 +570,8 @@ void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &write
// Do not generate a 'List of all members' for namespaces or header files,
// but always generate it for derived classes and QML classes
if (!node->isNamespace() && !node->isHeaderFile() &&
(derivedClass || node->isQmlType() || !project.memberStatus[node].isEmpty())) {
(derivedClass || node->isQmlType() || node->isJsType() ||
!project.memberStatus[node].isEmpty())) {
QString membersPath = href + QStringLiteral("-members.html");
writeSection(writer, membersPath, tr("List of all members"));
}
@ -615,7 +620,7 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
case Node::Document: {
// Document nodes (such as manual pages) contain subtypes, titles and other
// attributes.
const DocNode *docNode = static_cast<const DocNode*>(node);
const DocumentNode *docNode = static_cast<const DocumentNode*>(node);
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
@ -652,7 +657,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
qdb_->setLocalSearch();
if (!project.indexRoot.isEmpty())
rootNode = qdb_->findDocNodeByTitle(project.indexRoot);
rootNode = qdb_->findDocumentNodeByTitle(project.indexRoot);
else
rootNode = qdb_->primaryTreeRoot();
@ -695,7 +700,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
writer.writeStartElement("toc");
writer.writeStartElement("section");
const Node* node = qdb_->findDocNodeByTitle(project.indexTitle);
const Node* node = qdb_->findDocumentNodeByTitle(project.indexTitle);
if (node == 0)
node = qdb_->findNodeByNameAndType(QStringList("index.html"), Node::Document);
QString indexPath;

View File

@ -50,7 +50,7 @@ struct SubProject
{
QString title;
QString indexTitle;
QHash<Node::Type, QSet<DocNode::SubType> > selectors;
QHash<Node::Type, QSet<DocumentNode::SubType> > selectors;
bool sortPages;
QString type;
QHash<QString, const Node *> nodes;

View File

@ -513,7 +513,10 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
case Atom::BriefLeft:
// Do not output the brief for QML nodes, doc nodes or collections
// (groups, modules, qml module nodes)
if (relative->isQmlType() || relative->isDocNode() || relative->isCollectionNode()) {
if (relative->isQmlType() ||
relative->isDocumentNode() ||
relative->isCollectionNode() ||
relative->isJsType()) {
skipAhead = skipAtoms(atom, Atom::BriefRight);
break;
}
@ -549,7 +552,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
}
break;
case Atom::BriefRight:
if (!relative->isDocNode())
if (!relative->isDocumentNode())
out() << "</p>\n";
break;
case Atom::C:
@ -660,9 +663,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
break;
case Atom::AnnotatedList:
{
GroupNode* gn = qdb_->getGroup(atom->string());
if (gn)
generateList(gn, marker, atom->string());
CollectionNode* cn = qdb_->getCollection(atom->string(), Node::DOC);
if (cn)
generateList(cn, marker, atom->string());
}
break;
case Atom::GeneratedList:
@ -685,10 +688,10 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
else if (atom->string().contains("classesbymodule")) {
QString physicalModuleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed();
QDocDatabase* qdb = QDocDatabase::qdocDB();
ModuleNode* mn = qdb->findModule(physicalModuleName);
if (mn) {
CollectionNode* cn = qdb->findModule(physicalModuleName);
if (cn) {
NodeMap m;
mn->getMemberClasses(m);
cn->getMemberClasses(m);
if (!m.isEmpty()) {
generateAnnotatedList(relative, marker, m);
}
@ -751,7 +754,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
Remove permanently if it is not missed.
*/
else if (atom->string() == "relatedinline") {
const DocNode *dn = static_cast<const DocNode *>(relative);
const DocumentNode *dn = static_cast<const DocumentNode *>(relative);
if (dn && !dn->members().isEmpty()) {
// Reverse the list into the original scan order.
// Should be sorted. But on what? It may not be a
@ -1537,7 +1540,11 @@ void HtmlGenerator::generateQmlTypePage(QmlTypeNode* qcn, CodeMarker* marker)
Generator::setQmlTypeContext(qcn);
SubTitleSize subTitleSize = LargeSubTitle;
QList<Section>::const_iterator s;
QString htmlTitle = qcn->fullTitle() + " QML Type";
QString htmlTitle = qcn->fullTitle();
if (qcn->isJsType())
htmlTitle += " JavaScript Type";
else
htmlTitle += " QML Type";
generateHeader(htmlTitle, qcn, marker);
QList<Section> sections = marker->qmlSections(qcn, CodeMarker::Summary);
@ -1609,7 +1616,11 @@ void HtmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker*
{
SubTitleSize subTitleSize = LargeSubTitle;
QList<Section>::const_iterator s;
QString htmlTitle = qbtn->fullTitle() + " QML Basic Type";
QString htmlTitle = qbtn->fullTitle();
if (qbtn->isJsType())
htmlTitle += " JavaScript Basic Type";
else
htmlTitle += " QML Basic Type";
marker = CodeMarker::markerForLanguage(QLatin1String("QML"));
@ -1636,7 +1647,7 @@ void HtmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker*
Generate the HTML page for an entity that doesn't map
to any underlying parsable C++ class or QML component.
*/
void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker)
void HtmlGenerator::generateDocumentNode(DocumentNode* dn, CodeMarker* marker)
{
/*
If the document node is a page node, and if the page type
@ -1805,7 +1816,7 @@ void HtmlGenerator::generateCollectionNode(CollectionNode* cn, CodeMarker* marke
if (cn->isGroup())
generateAnnotatedList(cn, marker, cn->members());
else if (cn->isQmlModule())
else if (cn->isQmlModule() || cn->isJsModule())
generateAnnotatedList(cn, marker, cn->members());
sections = marker->sections(cn, CodeMarker::Detailed, CodeMarker::Okay);
@ -1872,7 +1883,8 @@ void HtmlGenerator::generateNavigationBar(const QString &title,
<< Atom(Atom::String, cn->name())
<< Atom(Atom::ListItemRight);
}
else if (node->isQmlType() || node->isQmlBasicType()) {
else if (node->isQmlType() || node->isQmlBasicType() ||
node->isJsType() || node->isJsBasicType()) {
if (!qmltypespage.isEmpty())
navigationbar << Atom(Atom::ListItemLeft)
<< Atom(Atom::NavLink, qmltypespage)
@ -2133,10 +2145,10 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker)
if (inner->type() == Node::Class || inner->type() == Node::Namespace) {
//add the QT variable to the map
if (!inner->physicalModuleName().isEmpty()) {
ModuleNode* moduleNode = qdb_->findModule(inner->physicalModuleName());
if (moduleNode && !moduleNode->qtVariable().isEmpty()) {
CollectionNode* cn = qdb_->findModule(inner->physicalModuleName());
if (cn && !cn->qtVariable().isEmpty()) {
text.clear();
text << "QT += " + moduleNode->qtVariable();
text << "QT += " + cn->qtVariable();
requisites.insert(qtVariableText, text);
}
}
@ -2243,9 +2255,13 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker)
//add the module name and version to the map
QString logicalModuleVersion;
QmlModuleNode* qmn = qdb_->findQmlModule(qcn->logicalModuleName());
if (qmn)
logicalModuleVersion = qmn->logicalModuleVersion();
CollectionNode* collection = 0;
if (qcn->isJsNode())
qdb_->findJsModule(qcn->logicalModuleName());
else
qdb_->findQmlModule(qcn->logicalModuleName());
if (collection)
logicalModuleVersion = collection->logicalModuleVersion();
else
logicalModuleVersion = qcn->logicalModuleVersion();
text.clear();
@ -2419,7 +2435,10 @@ void HtmlGenerator::generateTableOfContents(const Node *node,
}
}
}
else if (sections && (node->isClass() || node->isNamespace() || node->isQmlType())) {
else if (sections && (node->isClass() ||
node->isNamespace() ||
node->isQmlType() ||
node->isJsType())) {
QList<Section>::ConstIterator s = sections->constBegin();
while (s != sections->constEnd()) {
if (!s->members.isEmpty()) {
@ -2848,7 +2867,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative,
generateFullName(node, relative);
out() << "</p></td>";
if (!node->isDocNode()) {
if (!node->isDocumentNode()) {
Text brief = node->doc().trimmedBriefText(node->name());
if (!brief.isEmpty()) {
out() << "<td class=\"tblDescr\"><p>";
@ -3025,7 +3044,7 @@ void HtmlGenerator::generateCompactList(ListType listType,
}
QStringList pieces;
if (it.value()->isQmlType())
if (it.value()->isQmlType() || it.value()->isJsType())
pieces << it.value()->name();
else
pieces = it.value()->fullName(relative).split("::");
@ -3136,30 +3155,20 @@ void HtmlGenerator::generateQmlItem(const Node *node,
void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const QString& selector)
{
NodeList nl;
CollectionList cl;
QRegExp singleDigit("\\b([0-9])\\b");
if (selector == "overviews") {
CNMap groups;
qdb_->mergeCollections(Node::Group, groups, relative);
cl = groups.values();
foreach (CollectionNode* cn, cl)
nl.append(cn);
generateAnnotatedList(relative, marker, nl);
}
else if (selector == "cpp-modules") {
CNMap modules;
qdb_->mergeCollections(Node::Module, modules, relative);
cl = modules.values();
foreach (CollectionNode* cn, cl)
nl.append(cn);
generateAnnotatedList(relative, marker, nl);
}
else if (selector == "qml-modules") {
CNMap qmlModules;
qdb_->mergeCollections(Node::QmlModule, qmlModules, relative);
cl = qmlModules.values();
CNMap cnm;
Node::Genus genus = Node::DontCare;
if (selector == "overviews")
genus = Node::DOC;
else if (selector == "cpp-modules")
genus = Node::CPP;
else if (selector == "qml-modules")
genus = Node::QML;
else if (selector == "js-modules")
genus = Node::JS;
if (genus != Node::DontCare) {
NodeList nl;
qdb_->mergeCollections(genus, cnm, relative);
CollectionList cl = cnm.values();
foreach (CollectionNode* cn, cl)
nl.append(cn);
generateAnnotatedList(relative, marker, nl);
@ -3167,69 +3176,19 @@ void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const
else {
/*
\generatelist {selector} is only allowed in a
comment where the topic is \group, \module, or
\qmlmodule.
comment where the topic is \group, \module,
\qmlmodule, or \jsmodule
*/
if (!relative || !relative->isCollectionNode()) {
relative->doc().location().warning(tr("\\generatelist {%1} is only allowed in \\group, \\module, and \\qmlmodule comments.").arg(selector));
relative->doc().location().warning(tr("\\generatelist {%1} is only allowed in \\group, "
"\\module, \\qmlmodule, and \\jsmodule comments.").arg(selector));
return;
}
if (selector == "related") {
Node* n = const_cast<Node*>(relative);
CollectionNode* cn = static_cast<CollectionNode*>(n);
qdb_->mergeCollections(cn);
generateAnnotatedList(cn, marker, cn->members());
}
else {
Node* n = const_cast<Node*>(relative);
CollectionNode* cn = static_cast<CollectionNode*>(n);
qdb_->mergeCollections(cn);
generateAnnotatedList(cn, marker, cn->members());
}
Node* n = const_cast<Node*>(relative);
CollectionNode* cn = static_cast<CollectionNode*>(n);
qdb_->mergeCollections(cn);
generateAnnotatedList(cn, marker, cn->members());
}
#if 0
QStringList keys = groups.uniqueKeys();
foreach (const QString &key, keys) {
GroupNode* gn = static_cast<GroupNode*>(groups.value(key));
if (gn) {
out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg(
linkForNode(gn, relative)).arg(
protectEnc(gn->fullTitle()));
#if 0
if (gn->members().isEmpty())
continue;
NodeMap nm;
foreach (Node* member, gn->members()) {
if (member->isInternal() || member->isExample() || member->isExternalPage() ||
member->isObsolete())
continue;
// not interested either in individual (Qt Designer etc.) manual chapters
if (member->links().contains(Node::ContentsLink))
continue;
QString sortKey = member->fullTitle().toLower();
if (sortKey.startsWith("the "))
sortKey.remove(0, 4);
sortKey.replace(singleDigit, "0\\1");
nm.insert(sortKey, member);
}
out() << "<ul>\n";
QStringList titles = nm.keys();
foreach (const QString &t, titles) {
Node* member = nm.value(t);
QString title = member->fullTitle();
if (title.startsWith("The "))
title.remove(0, 4);
out() << "<li><a href=\"" << linkForNode(member, relative) << "\">"
<< protectEnc(title) << "</a></li>\n";
}
out() << "</ul>\n";
#endif
}
}
#endif
}
void HtmlGenerator::generateSection(const NodeList& nl,
@ -3507,8 +3466,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
par1 = QStringRef();
const Node* n = qdb_->findTypeNode(arg.toString(), relative);
html += QLatin1String("<span class=\"type\">");
if (n && n->isQmlBasicType()) {
if (relative && relative->isQmlType())
if (n && (n->isQmlBasicType() || n->isJsBasicType())) {
if (relative && (relative->isQmlType() || relative->isJsType()))
addLink(linkForNode(n,relative), arg, &html);
else
html += arg;
@ -3778,9 +3737,9 @@ QString HtmlGenerator::fileBase(const Node *node) const
QString HtmlGenerator::fileName(const Node *node)
{
if (node->type() == Node::Document) {
if (static_cast<const DocNode *>(node)->subType() == Node::ExternalPage)
if (static_cast<const DocumentNode *>(node)->subType() == Node::ExternalPage)
return node->name();
if (static_cast<const DocNode *>(node)->subType() == Node::Image)
if (static_cast<const DocumentNode *>(node)->subType() == Node::Image)
return node->name();
}
return Generator::fileName(node);
@ -3938,13 +3897,15 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
return QString();
QString fn = fileName(node);
if (node && node->parent() && node->parent()->isQmlType() && node->parent()->isAbstract()) {
if (node && node->parent() &&
(node->parent()->isQmlType() || node->parent()->isJsType())
&& node->parent()->isAbstract()) {
if (Generator::qmlTypeContext())
fn = fileName(Generator::qmlTypeContext());
}
QString link = fn;
if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) {
if (!node->isInnerNode() || node->isQmlPropertyGroup() || node->isJsPropertyGroup()) {
QString ref = refForNode(node);
if (relative && fn == fileName(relative) && ref == refForNode(relative))
return QString();
@ -4107,7 +4068,7 @@ const QPair<QString,QString> HtmlGenerator::anchorForNode(const Node *node)
anchorPair.first = Generator::fileName(node);
if (node->type() == Node::Document) {
const DocNode *docNode = static_cast<const DocNode*>(node);
const DocumentNode *docNode = static_cast<const DocumentNode*>(node);
anchorPair.second = docNode->title();
}
@ -4418,7 +4379,10 @@ void HtmlGenerator::generateInstantiatedBy(ClassNode* cn, CodeMarker* marker)
text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
text << Atom(Atom::String, cn->name());
text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
text << " is instantiated by QML Type ";
if (qcn->isQmlType())
text << " is instantiated by QML Type ";
else
text << " is instantiated by Javascript Type ";
text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
text << Atom(Atom::String, qcn->name());
@ -4917,9 +4881,9 @@ void HtmlGenerator::writeDitaRefs(const DitaRefList& ditarefs)
xmlWriter().writeStartElement("topicref");
xmlWriter().writeAttribute("navtitle",t->navtitle());
if (t->href().isEmpty()) {
const DocNode* fn = qdb_->findDocNodeByTitle(t->navtitle());
if (fn)
xmlWriter().writeAttribute("href",fileName(fn));
const DocumentNode* dn = qdb_->findDocumentNodeByTitle(t->navtitle());
if (dn)
xmlWriter().writeAttribute("href",fileName(dn));
}
else
xmlWriter().writeAttribute("href",t->href());

View File

@ -98,7 +98,7 @@ protected:
virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker) Q_DECL_OVERRIDE;
virtual void generateQmlTypePage(QmlTypeNode* qcn, CodeMarker* marker) Q_DECL_OVERRIDE;
virtual void generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker) Q_DECL_OVERRIDE;
virtual void generateDocNode(DocNode* dn, CodeMarker* marker) Q_DECL_OVERRIDE;
virtual void generateDocumentNode(DocumentNode* dn, CodeMarker* marker) Q_DECL_OVERRIDE;
virtual void generateCollectionNode(CollectionNode* cn, CodeMarker* marker) Q_DECL_OVERRIDE;
virtual QString fileExtension() const Q_DECL_OVERRIDE;
virtual QString refForNode(const Node *node);

View File

@ -149,7 +149,7 @@ QString Node::plainFullName(const Node* relative) const
*/
QString Node::fullName(const Node* relative) const
{
if (isDocNode())
if (isDocumentNode())
return title();
else if (isClass()) {
const ClassNode* cn = static_cast<const ClassNode*>(this);
@ -624,17 +624,18 @@ QString Node::guid() const
}
/*!
If this node is a QML class node, return a pointer to it.
If it is a child of a QML class node, return a pointer to
the QML class node. Otherwise, return 0;
If this node is a QML or JS type node, return a pointer to
it. If it is a child of a QML or JS type node, return the
pointer to its parent QMLor JS type node. Otherwise return
0;
*/
QmlTypeNode* Node::qmlTypeNode()
{
if (isQmlNode()) {
if (isQmlNode() || isJsNode()) {
Node* n = this;
while (n && !n->isQmlType())
while (n && !(n->isQmlType() || n->isJsType()))
n = n->parent();
if (n && n->isQmlType())
if (n && (n->isQmlType() || n->isJsType()))
return static_cast<QmlTypeNode*>(n);
}
return 0;
@ -716,10 +717,10 @@ Node *InnerNode::findChildNode(const QString& name, Node::Genus genus) const
Node *node = childMap.value(name);
if (node && !node->isQmlPropertyGroup()) // mws asks: Why not property group?
return node;
if (isQmlType()) {
if (isQmlType() || isJsType()) {
for (int i=0; i<children_.size(); ++i) {
Node* n = children_.at(i);
if (n->isQmlPropertyGroup()) {
if (n->isQmlPropertyGroup() || isJsPropertyGroup()) {
node = static_cast<InnerNode*>(n)->findChildNode(name, genus);
if (node)
return node;
@ -754,7 +755,7 @@ void InnerNode::findChildren(const QString& name, NodeList& nodes) const
if (!t.isEmpty())
nodes.append(t);
}
if (!nodes.isEmpty() || !isQmlNode())
if (!nodes.isEmpty() || !(isQmlNode() || isJsNode()))
return;
int i = name.indexOf(QChar('.'));
if (i < 0)
@ -764,7 +765,7 @@ void InnerNode::findChildren(const QString& name, NodeList& nodes) const
if (t.isEmpty())
return;
foreach (Node* n, t) {
if (n->isQmlPropertyGroup()) {
if (n->isQmlPropertyGroup() || n->isJsPropertyGroup()) {
n->findChildren(name, nodes);
if (!nodes.isEmpty())
break;
@ -772,45 +773,6 @@ void InnerNode::findChildren(const QString& name, NodeList& nodes) const
}
}
#if 0
/*!
Find the node in this node's children that has the given \a name. If
this node is a QML class node, be sure to also look in the children
of its property group nodes. Return the matching node or 0. This is
not a recearsive search.
If \a qml is true, only match a node for which node->isQmlNode()
returns \c true. If \a qml is false, only match a node for which
node->isQmlNode() returns \c false.
*/
Node* InnerNode::findChildNode(const QString& name, bool qml) const
{
NodeList nodes = childMap.values(name);
if (!nodes.isEmpty()) {
for (int i=0; i<nodes.size(); ++i) {
Node* node = nodes.at(i);
if (!qml) {
if (!node->isQmlNode())
return node;
}
else if (node->isQmlNode())
return node;
}
}
if (qml && isQmlType()) {
for (int i=0; i<children_.size(); ++i) {
Node* node = children_.at(i);
if (node->isQmlPropertyGroup()) {
node = static_cast<InnerNode*>(node)->findChildNode(name);
if (node)
return node;
}
}
}
return primaryFunctionMap.value(name);
}
#endif
/*!
This function is like findChildNode(), but if a node
with the specified \a name is found but it is not of the
@ -831,63 +793,6 @@ Node* InnerNode::findChildNode(const QString& name, Type type)
return 0;
}
#if 0
/*!
*/
void InnerNode::findNodes(const QString& name, NodeList& n)
{
n.clear();
Node* node = 0;
NodeList nodes = childMap.values(name);
/*
<sigh> If this node's child map contains no nodes named
name, then if this node is a QML class, search each of its
property group nodes for a node named name. If a match is
found, append it to the output list and return immediately.
*/
if (nodes.isEmpty()) {
if (isQmlType()) {
for (int i=0; i<children_.size(); ++i) {
node = children_.at(i);
if (node->isQmlPropertyGroup()) {
node = static_cast<InnerNode*>(node)->findChildNode(name);
if (node) {
n.append(node);
return;
}
}
}
}
}
else {
/*
If the childMap does contain one or more nodes named
name, traverse the list of matching nodes. Append each
matching node that is not a property group node to the
output list. Search each property group node for a node
named name and append that node to the output list.
This is overkill, I think, but should produce a useful
list.
*/
for (int i=0; i<nodes.size(); ++i) {
node = nodes.at(i);
if (!node->isQmlPropertyGroup())
n.append(node);
else {
node = static_cast<InnerNode*>(node)->findChildNode(name);
if (node)
n.append(node);
}
}
}
if (!n.isEmpty())
return;
node = primaryFunctionMap.value(name);
if (node)
n.append(node);
}
#endif
/*!
Find a function node that is a child of this nose, such
that the function node has the specified \a name.
@ -1642,15 +1547,15 @@ QmlTypeNode* ClassNode::findQmlBaseNode()
}
/*!
\class DocNode
\class DocumentNode
*/
/*!
The type of a DocNode is Document, and it has a \a subtype,
which specifies the type of DocNode. The page type for
The type of a DocumentNode is Document, and it has a \a subtype,
which specifies the type of DocumentNode. The page type for
the page index is set here.
*/
DocNode::DocNode(InnerNode* parent, const QString& name, SubType subtype, Node::PageType ptype)
DocumentNode::DocumentNode(InnerNode* parent, const QString& name, SubType subtype, Node::PageType ptype)
: InnerNode(Document, parent, name), nodeSubtype_(subtype)
{
setGenus(Node::DOC);
@ -1669,14 +1574,14 @@ DocNode::DocNode(InnerNode* parent, const QString& name, SubType subtype, Node::
}
}
/*! \fn QString DocNode::title() const
/*! \fn QString DocumentNode::title() const
Returns the document node's title. This is used for the page title.
*/
/*!
Sets the document node's \a title. This is used for the page title.
*/
void DocNode::setTitle(const QString &title)
void DocumentNode::setTitle(const QString &title)
{
title_ = title;
parent()->addChild(this, title);
@ -1687,7 +1592,7 @@ void DocNode::setTitle(const QString &title)
just title(), but for some SubType values is different
from title()
*/
QString DocNode::fullTitle() const
QString DocumentNode::fullTitle() const
{
if (nodeSubtype_ == File) {
if (title().isEmpty())
@ -1715,7 +1620,7 @@ QString DocNode::fullTitle() const
/*!
Returns the subtitle.
*/
QString DocNode::subTitle() const
QString DocumentNode::subTitle() const
{
if (!subtitle_.isEmpty())
return subtitle_;
@ -2205,29 +2110,6 @@ void QmlTypeNode::subclasses(const QString& base, NodeList& subs)
}
}
/*!
This function splits \a arg on the blank character to get a
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.
*/
void QmlModuleNode::setQmlModuleInfo(const QString& arg)
{
QStringList blankSplit = arg.split(QLatin1Char(' '));
logicalModuleName_ = blankSplit[0];
if (blankSplit.size() > 1) {
QStringList dotSplit = blankSplit[1].split(QLatin1Char('.'));
logicalModuleVersionMajor_ = dotSplit[0];
if (dotSplit.size() > 1)
logicalModuleVersionMinor_ = dotSplit[1];
else
logicalModuleVersionMinor_ = "0";
}
}
QmlTypeNode* QmlTypeNode::qmlBaseNode()
{
if (!qmlBaseNode_ && !qmlBaseName_.isEmpty()) {
@ -2389,7 +2271,7 @@ PropertyNode* QmlPropertyNode::findCorrespondingCppProperty()
{
PropertyNode* pn;
Node* n = parent();
while (n && !n->isQmlType())
while (n && !(n->isQmlType() || n->isJsType()))
n = n->parent();
if (n) {
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(n);
@ -2454,12 +2336,12 @@ QString Node::fullDocumentName() const
if (!n->name().isEmpty() && !n->isQmlPropertyGroup())
pieces.insert(0, n->name());
if (n->isQmlType() && !n->logicalModuleName().isEmpty()) {
if ((n->isQmlType() || n->isJsType()) && !n->logicalModuleName().isEmpty()) {
pieces.insert(0, n->logicalModuleName());
break;
}
if (n->isDocNode())
if (n->isDocumentNode())
break;
// Examine the parent node if one exists.
@ -2471,10 +2353,10 @@ QString Node::fullDocumentName() const
// Create a name based on the type of the ancestor node.
QString concatenator = "::";
if (n->isQmlType())
if (n->isQmlType() || n->isJsType())
concatenator = QLatin1Char('.');
if (n->isDocNode())
if (n->isDocumentNode())
concatenator = QLatin1Char('#');
return pieces.join(concatenator);
@ -2655,6 +2537,8 @@ QString Node::idForNode() const
str = "namespace-member-" + func->name();
else if (parent_->isQmlType())
str = "qml-method-" + parent_->name().toLower() + "-" + func->name();
else if (parent_->isJsType())
str = "js-method-" + parent_->name().toLower() + "-" + func->name();
else if (parent_->type() == Document) {
qDebug() << "qdoc internal error: Node subtype not handled:"
<< parent_->subType() << func->name();
@ -2669,10 +2553,16 @@ QString Node::idForNode() const
}
break;
case Node::QmlType:
str = "qml-class-" + name();
if (genus() == QML)
str = "qml-class-" + name();
else
str = "js-type-" + name();
break;
case Node::QmlBasicType:
str = "qml-basic-type-" + name();
if (genus() == QML)
str = "qml-basic-type-" + name();
else
str = "js-basic-type-" + name();
break;
case Node::Document:
{
@ -2713,32 +2603,52 @@ QString Node::idForNode() const
str.replace(QLatin1Char('/'), QLatin1Char('-'));
break;
case Node::QmlModule:
str = "qml-module-" + name();
if (genus() == QML)
str = "qml-module-" + name();
else
str = "js-module-" + name();
break;
case Node::QmlProperty:
if (isAttached())
str = "qml-attached-property-" + name();
if (genus() == QML)
str = "qml-";
else
str = "qml-property-" + name();
str = "js-";
if (isAttached())
str += "attached-property-" + name();
else
str += "property-" + name();
break;
case Node::QmlPropertyGroup:
{
Node* n = const_cast<Node*>(this);
str = "qml-propertygroup-" + n->name();
if (genus() == QML)
str = "qml-propertygroup-" + n->name();
else
str = "js-propertygroup-" + n->name();
}
break;
case Node::Property:
str = "property-" + name();
break;
case Node::QmlSignal:
str = "qml-signal-" + name();
if (genus() == QML)
str = "qml-signal-" + name();
else
str = "js-signal-" + name();
break;
case Node::QmlSignalHandler:
str = "qml-signal-handler-" + name();
if (genus() == QML)
str = "qml-signal-handler-" + name();
else
str = "js-signal-handler-" + name();
break;
case Node::QmlMethod:
func = static_cast<const FunctionNode*>(this);
str = "qml-method-" + parent_->name().toLower() + "-" + func->name();
if (genus() == QML)
str = "qml-method-";
else
str = "js-method-";
str += parent_->name().toLower() + "-" + func->name();
if (func->overloadNumber() != 1)
str += QLatin1Char('-') + QString::number(func->overloadNumber());
break;
@ -2884,4 +2794,48 @@ void CollectionNode::setTitle(const QString& title)
parent()->addChild(this, title);
}
/*!
This function splits \a arg on the blank character to get a
logical 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.
*/
void CollectionNode::setLogicalModuleInfo(const QString& arg)
{
QStringList blankSplit = arg.split(QLatin1Char(' '));
logicalModuleName_ = blankSplit[0];
if (blankSplit.size() > 1) {
QStringList dotSplit = blankSplit[1].split(QLatin1Char('.'));
logicalModuleVersionMajor_ = dotSplit[0];
if (dotSplit.size() > 1)
logicalModuleVersionMinor_ = dotSplit[1];
else
logicalModuleVersionMinor_ = "0";
}
}
/*!
This function accepts the logical module \a info as a string
list. If the logical module info contains the version number,
it spilts the version number on the '.' character to get the
major and minor vrsion numbers. Both major and minor version
numbers should be provided, but the minor version number is
not strictly necessary.
*/
void CollectionNode::setLogicalModuleInfo(const QStringList& info)
{
logicalModuleName_ = info[0];
if (info.size() > 1) {
QStringList dotSplit = info[1].split(QLatin1Char('.'));
logicalModuleVersionMajor_ = dotSplit[0];
if (dotSplit.size() > 1)
logicalModuleVersionMinor_ = dotSplit[1];
else
logicalModuleVersionMinor_ = "0";
}
}
QT_END_NAMESPACE

View File

@ -55,7 +55,6 @@ class QmlTypeNode;
class QDocDatabase;
class FunctionNode;
class PropertyNode;
class QmlModuleNode;
class CollectionNode;
class QmlPropertyNode;
@ -194,14 +193,21 @@ public:
void setIndexNodeFlag() { indexNodeFlag_ = true; }
virtual void setOutputFileName(const QString& ) { }
bool isQmlNode() const { return genus() == QML; }
bool isJsNode() const { return genus() == JS; }
bool isCppNode() const { return genus() == CPP; }
virtual bool isInnerNode() const = 0;
virtual bool isDocNode() const { return false; }
virtual bool isCollectionNode() const { return false; }
virtual bool isDocumentNode() const { return false; }
virtual bool isGroup() const { return false; }
virtual bool isModule() const { return false; }
virtual bool isQmlModule() const { return false; }
virtual bool isJsModule() const { return false; }
virtual bool isQmlType() const { return false; }
virtual bool isJsType() const { return false; }
virtual bool isQmlBasicType() const { return false; }
virtual bool isJsBasicType() const { return false; }
virtual bool isExample() const { return false; }
virtual bool isExampleFile() const { return false; }
virtual bool isHeaderFile() const { return false; }
@ -210,11 +216,19 @@ public:
virtual bool isFunction() const { return false; }
virtual bool isNamespace() const { return false; }
virtual bool isClass() const { return false; }
virtual bool isQmlNode() const { return false; }
virtual bool isCppNode() const { return false; }
virtual bool isQtQuickNode() const { return false; }
virtual bool isAbstract() const { return false; }
virtual bool isProperty() const { return false; }
virtual bool isQmlProperty() const { return false; }
virtual bool isJsProperty() const { return false; }
virtual bool isQmlPropertyGroup() const { return false; }
virtual bool isJsPropertyGroup() const { return false; }
virtual bool isQmlSignal() const { return false; }
virtual bool isJsSignal() const { return false; }
virtual bool isQmlSignalHandler() const { return false; }
virtual bool isJsSignalHandler() const { return false; }
virtual bool isQmlMethod() const { return false; }
virtual bool isJsMethod() const { return false; }
virtual bool isAttached() const { return false; }
virtual bool isAlias() const { return false; }
virtual bool isWrapper() const;
@ -294,9 +308,10 @@ public:
virtual QString logicalModuleName() const { return QString(); }
virtual QString logicalModuleVersion() const { return QString(); }
virtual QString logicalModuleIdentifier() const { return QString(); }
virtual void setQmlModuleInfo(const QString& ) { }
virtual QmlModuleNode* logicalModule() const { return 0; }
virtual void setQmlModule(QmlModuleNode* ) { }
virtual void setLogicalModuleInfo(const QString& ) { }
virtual void setLogicalModuleInfo(const QStringList& ) { }
virtual CollectionNode* logicalModule() const { return 0; }
virtual void setQmlModule(CollectionNode* ) { }
virtual ClassNode* classNode() { return 0; }
virtual void setClassNode(ClassNode* ) { }
virtual const Node* applyModuleName(const Node* ) const { return 0; }
@ -440,7 +455,6 @@ public:
virtual ~NamespaceNode() { }
virtual bool isNamespace() const Q_DECL_OVERRIDE { return true; }
virtual Tree* tree() const Q_DECL_OVERRIDE { return (parent() ? parent()->tree() : tree_); }
virtual bool isCppNode() const Q_DECL_OVERRIDE { return true; }
void setTree(Tree* t) { tree_ = t; }
private:
@ -471,7 +485,6 @@ public:
ClassNode(InnerNode* parent, const QString& name);
virtual ~ClassNode() { }
virtual bool isClass() const Q_DECL_OVERRIDE { return true; }
virtual bool isCppNode() const Q_DECL_OVERRIDE { return true; }
virtual bool isWrapper() const Q_DECL_OVERRIDE { return wrapper_; }
virtual QString obsoleteLink() const Q_DECL_OVERRIDE { return obsoleteLink_; }
virtual void setObsoleteLink(const QString& t) Q_DECL_OVERRIDE { obsoleteLink_ = t; }
@ -511,16 +524,17 @@ private:
QmlTypeNode* qmlelement;
};
class DocNode : public InnerNode
class DocumentNode : public InnerNode
{
public:
DocNode(InnerNode* parent,
DocumentNode(InnerNode* parent,
const QString& name,
SubType subType,
PageType ptype);
virtual ~DocNode() { }
virtual ~DocumentNode() { }
virtual bool isDocumentNode() const Q_DECL_OVERRIDE { return true; }
virtual void setTitle(const QString &title) Q_DECL_OVERRIDE;
virtual void setSubTitle(const QString &subTitle) Q_DECL_OVERRIDE { subtitle_ = subTitle; }
@ -536,7 +550,6 @@ public:
virtual bool isExample() const Q_DECL_OVERRIDE { return (subType() == Node::Example); }
virtual bool isExampleFile() const Q_DECL_OVERRIDE { return (parent() && parent()->isExample()); }
virtual bool isExternalPage() const Q_DECL_OVERRIDE { return nodeSubtype_ == ExternalPage; }
virtual bool isDocNode() const Q_DECL_OVERRIDE { return true; }
protected:
SubType nodeSubtype_;
@ -544,11 +557,11 @@ protected:
QString subtitle_;
};
class ExampleNode : public DocNode
class ExampleNode : public DocumentNode
{
public:
ExampleNode(InnerNode* parent, const QString& name)
: DocNode(parent, name, Node::Example, Node::ExamplePage) { }
: DocumentNode(parent, name, Node::Example, Node::ExamplePage) { }
virtual ~ExampleNode() { }
virtual QString imageFileName() const Q_DECL_OVERRIDE { return imageFileName_; }
virtual void setImageFileName(const QString& ifn) Q_DECL_OVERRIDE { imageFileName_ = ifn; }
@ -582,8 +595,8 @@ class QmlTypeNode : public InnerNode
public:
QmlTypeNode(InnerNode* parent, const QString& name);
virtual ~QmlTypeNode();
virtual bool isQmlNode() const Q_DECL_OVERRIDE { return true; }
virtual bool isQmlType() const Q_DECL_OVERRIDE { return true; }
virtual bool isQmlType() const Q_DECL_OVERRIDE { return genus() == Node::QML; }
virtual bool isJsType() const Q_DECL_OVERRIDE { return genus() == Node::JS; }
virtual bool isQtQuickNode() const Q_DECL_OVERRIDE {
return (logicalModuleName() == QLatin1String("QtQuick"));
}
@ -600,8 +613,8 @@ public:
virtual QString logicalModuleName() const Q_DECL_OVERRIDE;
virtual QString logicalModuleVersion() const Q_DECL_OVERRIDE;
virtual QString logicalModuleIdentifier() const Q_DECL_OVERRIDE;
virtual QmlModuleNode* logicalModule() const Q_DECL_OVERRIDE { return logicalModule_; }
virtual void setQmlModule(QmlModuleNode* t) Q_DECL_OVERRIDE { logicalModule_ = t; }
virtual CollectionNode* logicalModule() const Q_DECL_OVERRIDE { return logicalModule_; }
virtual void setQmlModule(CollectionNode* t) Q_DECL_OVERRIDE { logicalModule_ = t; }
const ImportList& importList() const { return importList_; }
void setImportList(const ImportList& il) { importList_ = il; }
@ -627,7 +640,7 @@ private:
ClassNode* cnode_;
QString qmlBaseName_;
QString obsoleteLink_;
QmlModuleNode* logicalModule_;
CollectionNode* logicalModule_;
QmlTypeNode* qmlBaseNode_;
ImportList importList_;
};
@ -638,8 +651,8 @@ public:
QmlBasicTypeNode(InnerNode* parent,
const QString& name);
virtual ~QmlBasicTypeNode() { }
virtual bool isQmlNode() const Q_DECL_OVERRIDE { return true; }
virtual bool isQmlBasicType() const Q_DECL_OVERRIDE { return true; }
virtual bool isQmlBasicType() const Q_DECL_OVERRIDE { return (genus() == Node::QML); }
virtual bool isJsBasicType() const Q_DECL_OVERRIDE { return (genus() == Node::JS); }
};
class QmlPropertyGroupNode : public InnerNode
@ -647,7 +660,6 @@ class QmlPropertyGroupNode : public InnerNode
public:
QmlPropertyGroupNode(QmlTypeNode* parent, const QString& name);
virtual ~QmlPropertyGroupNode() { }
virtual bool isQmlNode() const Q_DECL_OVERRIDE { return true; }
virtual bool isQtQuickNode() const Q_DECL_OVERRIDE { return parent()->isQtQuickNode(); }
virtual QString qmlTypeName() const Q_DECL_OVERRIDE { return parent()->qmlTypeName(); }
virtual QString logicalModuleName() const Q_DECL_OVERRIDE {
@ -660,7 +672,8 @@ public:
return parent()->logicalModuleIdentifier();
}
virtual QString idNumber() Q_DECL_OVERRIDE;
virtual bool isQmlPropertyGroup() const Q_DECL_OVERRIDE { return true; }
virtual bool isQmlPropertyGroup() const Q_DECL_OVERRIDE { return genus() == Node::QML; }
virtual bool isJsPropertyGroup() const Q_DECL_OVERRIDE { return genus() == Node::JS; }
virtual QString element() const Q_DECL_OVERRIDE { return parent()->name(); }
private:
@ -690,11 +703,12 @@ public:
bool isStored() const { return fromFlagValue(stored_,true); }
bool isDesignable() const { return fromFlagValue(designable_,false); }
bool isWritable();
virtual bool isQmlProperty() const Q_DECL_OVERRIDE { return genus() == QML; }
virtual bool isJsProperty() const Q_DECL_OVERRIDE { return genus() == JS; }
virtual bool isDefault() const Q_DECL_OVERRIDE { return isdefault_; }
virtual bool isReadOnly() const Q_DECL_OVERRIDE { return fromFlagValue(readOnly_,false); }
virtual bool isAlias() const Q_DECL_OVERRIDE { return isAlias_; }
virtual bool isAttached() const Q_DECL_OVERRIDE { return attached_; }
virtual bool isQmlNode() const Q_DECL_OVERRIDE { return true; }
virtual bool isQtQuickNode() const Q_DECL_OVERRIDE { return parent()->isQtQuickNode(); }
virtual QString qmlTypeName() const Q_DECL_OVERRIDE { return parent()->qmlTypeName(); }
virtual QString logicalModuleName() const Q_DECL_OVERRIDE {
@ -742,7 +756,6 @@ public:
EnumNode(InnerNode* parent, const QString& name);
virtual ~EnumNode() { }
virtual bool isCppNode() const Q_DECL_OVERRIDE { return true; }
void addItem(const EnumItem& item);
void setFlagsType(TypedefNode* typedeff);
bool hasItem(const QString &name) const { return names.contains(name); }
@ -764,7 +777,6 @@ public:
TypedefNode(InnerNode* parent, const QString& name);
virtual ~TypedefNode() { }
virtual bool isCppNode() const Q_DECL_OVERRIDE { return true; }
const EnumNode* associatedEnum() const { return ae; }
private:
@ -853,6 +865,12 @@ public:
bool isOverload() const { return ove; }
bool isReimp() const Q_DECL_OVERRIDE { return reimp; }
bool isFunction() const Q_DECL_OVERRIDE { return true; }
virtual bool isQmlSignal() const Q_DECL_OVERRIDE { return genus() == Node::QML; }
virtual bool isJsSignal() const Q_DECL_OVERRIDE { return genus() == Node::JS; }
virtual bool isQmlSignalHandler() const Q_DECL_OVERRIDE { return genus() == Node::QML; }
virtual bool isJsSignalHandler() const Q_DECL_OVERRIDE { return genus() == Node::JS; }
virtual bool isQmlMethod() const Q_DECL_OVERRIDE { return genus() == Node::QML; }
virtual bool isJsMethod() const Q_DECL_OVERRIDE { return genus() == Node::JS; }
int overloadNumber() const;
const QList<Parameter>& parameters() const { return params; }
QStringList parameterNames() const;
@ -866,12 +884,6 @@ public:
QString signature(bool values = false) const;
virtual QString element() const Q_DECL_OVERRIDE { return parent()->name(); }
virtual bool isAttached() const Q_DECL_OVERRIDE { return attached_; }
virtual bool isQmlNode() const Q_DECL_OVERRIDE {
return ((type() == QmlSignal) ||
(type() == QmlMethod) ||
(type() == QmlSignalHandler));
}
virtual bool isCppNode() const Q_DECL_OVERRIDE { return !isQmlNode(); }
virtual bool isQtQuickNode() const Q_DECL_OVERRIDE { return parent()->isQtQuickNode(); }
virtual QString qmlTypeName() const Q_DECL_OVERRIDE { return parent()->qmlTypeName(); }
virtual QString logicalModuleName() const Q_DECL_OVERRIDE {
@ -916,8 +928,8 @@ public:
PropertyNode(InnerNode* parent, const QString& name);
virtual ~PropertyNode() { }
virtual bool isCppNode() const Q_DECL_OVERRIDE { return true; }
virtual void setDataType(const QString& dataType) Q_DECL_OVERRIDE { type_ = dataType; }
virtual bool isProperty() const Q_DECL_OVERRIDE { return true; }
void addFunction(FunctionNode* function, FunctionRole role);
void addSignal(FunctionNode* function, FunctionRole role);
void setStored(bool stored) { stored_ = toFlagValue(stored); }
@ -1004,7 +1016,6 @@ public:
VariableNode(InnerNode* parent, const QString &name);
virtual ~VariableNode() { }
virtual bool isCppNode() const Q_DECL_OVERRIDE { return true; }
void setLeftType(const QString &leftType) { lt = leftType; }
void setRightType(const QString &rightType) { rt = rightType; }
void setStatic(bool statique) { sta = statique; }
@ -1026,11 +1037,11 @@ inline VariableNode::VariableNode(InnerNode* parent, const QString &name)
setGenus(Node::CPP);
}
class DitaMapNode : public DocNode
class DitaMapNode : public DocumentNode
{
public:
DitaMapNode(InnerNode* parent, const QString& name)
: DocNode(parent, name, Node::Page, Node::DitaMapPage) { }
: DocumentNode(parent, name, Node::Page, Node::DitaMapPage) { }
virtual ~DitaMapNode() { }
const DitaRefList& map() const { return doc().ditamap(); }
@ -1039,13 +1050,23 @@ public:
class CollectionNode : public InnerNode
{
public:
CollectionNode(Type type, InnerNode* parent, const QString& name)
: InnerNode(type, parent, name), seen_(false) {
CollectionNode(Type type,
InnerNode* parent,
const QString& name,
Genus genus) : InnerNode(type, parent, name), seen_(false)
{
setPageType(Node::OverviewPage);
setGenus(genus);
}
virtual ~CollectionNode() { }
virtual bool isCollectionNode() const Q_DECL_OVERRIDE { return true; }
virtual bool isGroup() const Q_DECL_OVERRIDE { return genus() == Node::DOC; }
virtual bool isModule() const Q_DECL_OVERRIDE { return genus() == Node::CPP; }
virtual bool isQmlModule() const Q_DECL_OVERRIDE { return genus() == Node::QML; }
virtual bool isJsModule() const Q_DECL_OVERRIDE { return genus() == Node::JS; }
virtual QString qtVariable() const Q_DECL_OVERRIDE { return qtVariable_; }
virtual void setQtVariable(const QString& v) Q_DECL_OVERRIDE { qtVariable_ = v; }
virtual void addMember(Node* node) Q_DECL_OVERRIDE;
virtual bool hasMembers() const Q_DECL_OVERRIDE;
virtual bool hasNamespaces() const Q_DECL_OVERRIDE;
@ -1060,6 +1081,16 @@ class CollectionNode : public InnerNode
virtual void setTitle(const QString &title) Q_DECL_OVERRIDE;
virtual void setSubTitle(const QString &subTitle) Q_DECL_OVERRIDE { subtitle_ = subTitle; }
virtual QString logicalModuleName() const Q_DECL_OVERRIDE { return logicalModuleName_; }
virtual QString logicalModuleVersion() const Q_DECL_OVERRIDE {
return logicalModuleVersionMajor_ + "." + logicalModuleVersionMinor_;
}
virtual QString logicalModuleIdentifier() const Q_DECL_OVERRIDE {
return logicalModuleName_ + logicalModuleVersionMajor_;
}
virtual void setLogicalModuleInfo(const QString& arg) Q_DECL_OVERRIDE;
virtual void setLogicalModuleInfo(const QStringList& info) Q_DECL_OVERRIDE;
const NodeList& members() const { return members_; }
void printMembers(const QString& title);
@ -1071,61 +1102,6 @@ class CollectionNode : public InnerNode
QString title_;
QString subtitle_;
NodeList members_;
};
class GroupNode : public CollectionNode
{
public:
GroupNode(InnerNode* parent, const QString& name)
: CollectionNode(Node::Group, parent, name) {
setGenus(Node::DOC);
}
virtual ~GroupNode() { }
virtual bool isGroup() const Q_DECL_OVERRIDE { return true; }
};
class ModuleNode : public CollectionNode
{
public:
ModuleNode(InnerNode* parent, const QString& name)
: CollectionNode(Node::Module, parent, name) {
setGenus(Node::CPP);
}
virtual ~ModuleNode() { }
virtual bool isModule() const Q_DECL_OVERRIDE { return true; }
virtual bool isCppNode() const Q_DECL_OVERRIDE { return true; }
virtual void setQtVariable(const QString& v) Q_DECL_OVERRIDE { qtVariable_ = v; }
virtual QString qtVariable() const Q_DECL_OVERRIDE { return qtVariable_; }
private:
QString qtVariable_;
};
class QmlModuleNode : public CollectionNode
{
public:
QmlModuleNode(InnerNode* parent, const QString& name)
: CollectionNode(Node::QmlModule, parent, name) {
setGenus(Node::QML);
}
virtual ~QmlModuleNode() { }
virtual bool isQmlNode() const Q_DECL_OVERRIDE { return true; }
virtual bool isQmlModule() const Q_DECL_OVERRIDE { return true; }
virtual QString logicalModuleName() const Q_DECL_OVERRIDE { return logicalModuleName_; }
virtual QString logicalModuleVersion() const Q_DECL_OVERRIDE {
return logicalModuleVersionMajor_ + "." + logicalModuleVersionMinor_;
}
virtual QString logicalModuleIdentifier() const Q_DECL_OVERRIDE {
return logicalModuleName_ + logicalModuleVersionMajor_;
}
virtual void setQmlModuleInfo(const QString& ) Q_DECL_OVERRIDE;
virtual void setQtVariable(const QString& v) Q_DECL_OVERRIDE { qtVariable_ = v; }
virtual QString qtVariable() const Q_DECL_OVERRIDE { return qtVariable_; }
private:
QString logicalModuleName_;
QString logicalModuleVersionMajor_;
QString logicalModuleVersionMinor_;

View File

@ -133,6 +133,7 @@ bool PureDocParser::processQdocComments()
QString topic;
bool isQmlPropertyTopic = false;
bool isJsPropertyTopic = false;
const TopicList& topics = doc.topicsUsed();
if (!topics.isEmpty()) {
@ -142,8 +143,13 @@ bool PureDocParser::processQdocComments()
(topic == COMMAND_QMLATTACHEDPROPERTY)) {
isQmlPropertyTopic = true;
}
else if ((topic == COMMAND_JSPROPERTY) ||
(topic == COMMAND_JSPROPERTYGROUP) ||
(topic == COMMAND_JSATTACHEDPROPERTY)) {
isJsPropertyTopic = true;
}
}
if (isQmlPropertyTopic && topics.size() > 1) {
if ((isQmlPropertyTopic || isJsPropertyTopic) && topics.size() > 1) {
qDebug() << "MULTIPLE TOPICS:" << doc.location().fileName() << doc.location().lineNo();
for (int i=0; i<topics.size(); ++i) {
qDebug() << " " << topics[i].topic << topics[i].args;
@ -158,9 +164,9 @@ bool PureDocParser::processQdocComments()
"(e.g., '\\%1', '\\%2').")
.arg(COMMAND_MODULE).arg(COMMAND_PAGE));
}
else if (isQmlPropertyTopic) {
else if (isQmlPropertyTopic || isJsPropertyTopic) {
Doc nodeDoc = doc;
processQmlProperties(nodeDoc, nodes, docs);
processQmlProperties(nodeDoc, nodes, docs, isJsPropertyTopic);
}
else {
ArgList args;

View File

@ -324,31 +324,6 @@ const Node* QDocForest::findNodeForTarget(QStringList& targetPath,
return 0;
}
/*!
This function merges all the collection maps for collection
nodes of node type \a t into the collection multimap \a cnmm,
which is cleared before starting.
This is mainly useful for groups, which often cross module
boundaries. It might be true that neither modules nor QML
modules cross module boundaries, but this function works for
those cases as well.
*/
void QDocForest::mergeCollectionMaps(Node::Type nt, CNMultiMap& cnmm)
{
foreach (Tree* t, searchOrder()) {
const CNMap& cnm = t->getCollections(nt);
if (!cnm.isEmpty()) {
CNMap::const_iterator i = cnm.begin();
while (i != cnm.end()) {
if (!i.value()->isInternal())
cnmm.insert(i.key(), i.value());
++i;
}
}
}
}
/*!
Print the list of module names ordered according
to how many successful searches each tree had.
@ -633,29 +608,30 @@ void QDocDatabase::initializeDB()
*/
/*!
\fn const GroupMap& QDocDatabase::groups()
\fn const CNMap& QDocDatabase::groups()
Returns a const reference to the collection of all
group nodes in the primary tree.
*/
/*!
\fn const ModuleMap& QDocDatabase::modules()
\fn const CNMap& QDocDatabase::modules()
Returns a const reference to the collection of all
module nodes in the primary tree.
*/
/*!
\fn const QmlModuleMap& QDocDatabase::qmlModules()
\fn const CNMap& QDocDatabase::qmlModules()
Returns a const reference to the collection of all
QML module nodes in the primary tree.
*/
/*! \fn GroupNode* QDocDatabase::getGroup(const QString& name)
Find the group node named \a name and return a pointer
to it. If a matching node is not found, return 0.
*/
/*!
\fn const CNMap& QDocDatabase::jsModules()
Returns a const reference to the collection of all
JovaScript module nodes in the primary tree.
*/
/*! \fn GroupNode* QDocDatabase::findGroup(const QString& name)
/*! \fn CollectionNode* QDocDatabase::findGroup(const QString& name)
Find the group node named \a name and return a pointer
to it. If a matching node is not found, add a new group
node named \a name and return a pointer to that one.
@ -664,7 +640,7 @@ void QDocDatabase::initializeDB()
and the new group node is marked \e{not seen}.
*/
/*! \fn ModuleNode* QDocDatabase::findModule(const QString& name)
/*! \fn CollectionNode* QDocDatabase::findModule(const QString& name)
Find the module node named \a name and return a pointer
to it. If a matching node is not found, add a new module
node named \a name and return a pointer to that one.
@ -673,16 +649,19 @@ void QDocDatabase::initializeDB()
and the new module node is marked \e{not seen}.
*/
/*! \fn QmlModuleNode* QDocDatabase::findQmlModule(const QString& name)
/*! \fn CollectionNode* QDocDatabase::findQmlModule(const QString& name, bool javaScript)
Find the QML module node named \a name and return a pointer
to it. If a matching node is not found, add a new QML module
node named \a name and return a pointer to that one.
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}.
If \a javaScript is set, the return collection must be a
JavaScript module.
If a new QML or JavaScript module node is added, its parent
is the tree root, and the new node is marked \e{not seen}.
*/
/*! \fn GroupNode* QDocDatabase::addGroup(const QString& name)
/*! \fn CollectionNode* QDocDatabase::addGroup(const QString& name)
Looks up the group named \a name in the primary tree. If
a match is found, a pointer to the node is returned.
Otherwise, a new group node named \a name is created and
@ -690,7 +669,7 @@ void QDocDatabase::initializeDB()
is returned.
*/
/*! \fn ModuleNode* QDocDatabase::addModule(const QString& name)
/*! \fn CollectionNode* QDocDatabase::addModule(const QString& name)
Looks up the module named \a name in the primary tree. If
a match is found, a pointer to the node is returned.
Otherwise, a new module node named \a name is created and
@ -698,7 +677,7 @@ void QDocDatabase::initializeDB()
is returned.
*/
/*! \fn QmlModuleNode* QDocDatabase::addQmlModule(const QString& name)
/*! \fn CollectionNode* QDocDatabase::addQmlModule(const QString& name)
Looks up the QML module named \a name in the primary tree.
If a match is found, a pointer to the node is returned.
Otherwise, a new QML module node named \a name is created
@ -706,7 +685,15 @@ void QDocDatabase::initializeDB()
node is returned.
*/
/*! \fn GroupNode* QDocDatabase::addToGroup(const QString& name, Node* node)
/*! \fn CollectionNode* QDocDatabase::addJsModule(const QString& name)
Looks up the JavaScript module named \a name in the primary
tree. If a match is found, a pointer to the node is returned.
Otherwise, a new JavaScript module node named \a name is
created and inserted into the collection, and the pointer to
that node is returned.
*/
/*! \fn CollectionNode* QDocDatabase::addToGroup(const QString& name, Node* node)
Looks up the group node named \a name in the collection
of all group nodes. If a match is not found, a new group
node named \a name is created and inserted into the collection.
@ -716,7 +703,7 @@ void QDocDatabase::initializeDB()
the group node.
*/
/*! \fn ModuleNode* QDocDatabase::addToModule(const QString& name, Node* node)
/*! \fn CollectionNode* QDocDatabase::addToModule(const QString& name, Node* node)
Looks up the module node named \a name in the collection
of all module nodes. If a match is not found, a new module
node named \a name is created and inserted into the collection.
@ -724,12 +711,18 @@ void QDocDatabase::initializeDB()
\a node is not changed by this function. Returns the module node.
*/
/*! \fn QmlModuleNode* QDocDatabase::addToQmlModule(const QString& name, Node* node)
/*! \fn Collection* QDocDatabase::addToQmlModule(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.
*/
/*! \fn Collection* QDocDatabase::addToJsModule(const QString& name, Node* node)
Looks up the JavaScript module named \a name. If it isn't there,
create it. Then append \a node to the JavaScript module's member
list. The parent of \a node is not changed by this function.
*/
/*!
Looks up the QML type node identified by the qualified Qml
type \a name and returns a pointer to the QML type node.
@ -761,7 +754,7 @@ QmlTypeNode* QDocDatabase::findQmlType(const QString& qmid, const QString& name)
QStringList path(name);
Node* n = forest_.findNodeByNameAndType(path, Node::QmlType);
if (n && n->isQmlType())
if (n && (n->isQmlType() || n->isJsType()))
return static_cast<QmlTypeNode*>(n);
return 0;
}
@ -1009,7 +1002,8 @@ void QDocDatabase::findAllClasses(InnerNode* node)
serviceClasses_.insert(serviceName, *c);
}
}
else if (((*c)->isQmlType() || (*c)->isQmlBasicType())&& !(*c)->doc().isEmpty()) {
else if (((*c)->isQmlType() || (*c)->isQmlBasicType() ||
(*c)->isJsType() || (*c)->isJsBasicType()) && !(*c)->doc().isEmpty()) {
QString qmlTypeName = (*c)->name();
if (qmlTypeName.startsWith(QLatin1String("QML:")))
qmlTypes_.insert(qmlTypeName.mid(4),*c);
@ -1017,7 +1011,7 @@ void QDocDatabase::findAllClasses(InnerNode* node)
qmlTypes_.insert(qmlTypeName,*c);
//also add to the QML basic type map
if ((*c)->isQmlBasicType())
if ((*c)->isQmlBasicType() || (*c)->isJsType())
qmlBasicTypes_.insert(qmlTypeName,*c);
}
else if ((*c)->isInnerNode()) {
@ -1121,7 +1115,7 @@ void QDocDatabase::findAllObsoleteThings(InnerNode* node)
name = (*c)->parent()->name() + "::" + name;
obsoleteClasses_.insert(name, *c);
}
else if ((*c)->isQmlType()) {
else if ((*c)->isQmlType() || (*c)->isJsType()) {
if (name.startsWith(QLatin1String("QML:")))
name = name.mid(4);
name = (*c)->logicalModuleName() + "::" + name;
@ -1157,7 +1151,7 @@ void QDocDatabase::findAllObsoleteThings(InnerNode* node)
++p;
}
}
else if ((*c)->isQmlType()) {
else if ((*c)->isQmlType() || (*c)->isJsType()) {
InnerNode* n = static_cast<InnerNode*>(*c);
bool inserted = false;
NodeList::const_iterator p = n->childNodes().constBegin();
@ -1170,9 +1164,11 @@ void QDocDatabase::findAllObsoleteThings(InnerNode* node)
case Node::QmlMethod:
if ((*c)->parent()) {
Node* parent = (*c)->parent();
if (parent->type() == Node::QmlPropertyGroup && parent->parent())
if ((parent->isQmlPropertyGroup() ||
parent->isJsPropertyGroup()) && parent->parent())
parent = parent->parent();
if (parent && parent->isQmlType() && !parent->name().isEmpty())
if (parent && (parent->isQmlType() || parent->isJsType()) &&
!parent->name().isEmpty())
name = parent->name() + "::" + name;
}
qmlTypesWithObsoleteMembers_.insert(name,*c);
@ -1241,7 +1237,7 @@ void QDocDatabase::findAllSince(InnerNode* node)
nsmap.value().insert(className,(*child));
ncmap.value().insert(className,(*child));
}
else if ((*child)->isQmlType()) {
else if ((*child)->isQmlType() || (*child)->isJsType()) {
// Insert QML elements into the since and element maps.
QString className = (*child)->name();
if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) {
@ -1250,7 +1246,7 @@ void QDocDatabase::findAllSince(InnerNode* node)
nsmap.value().insert(className,(*child));
nqcmap.value().insert(className,(*child));
}
else if ((*child)->type() == Node::QmlProperty) {
else if ((*child)->isQmlProperty() || (*child)->isJsProperty()) {
// Insert QML properties into the since map.
QString propertyName = (*child)->name();
nsmap.value().insert(propertyName,(*child));
@ -1380,7 +1376,7 @@ const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* r
return n;
relative = 0;
}
node = findDocNodeByTitle(target);
node = findDocumentNodeByTitle(target);
}
return node;
}
@ -1397,7 +1393,7 @@ void QDocDatabase::resolveQmlInheritance(InnerNode* root)
NodeMap previousSearches;
// Do we need recursion?
foreach (Node* child, root->childNodes()) {
if (child->isQmlType()) {
if (child->isQmlType() || child->isJsType()) {
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(child);
if (qcn->qmlBaseNodeNotSet() && !qcn->qmlBaseName().isEmpty()) {
QmlTypeNode* bqcn = static_cast<QmlTypeNode*>(previousSearches.value(qcn->qmlBaseName()));
@ -1536,18 +1532,28 @@ Node* QDocDatabase::findNodeInOpenNamespace(QStringList& path, Node::Type type)
}
/*!
Finds all the collection nodes of type \a nt into the
collection node map \a cnn. Nodes that match \a relative
are not included.
Finds all the collection nodes of the specified \a genus
into the collection node map \a cnm. Nodes that match the
\a relative node are not included.
*/
void QDocDatabase::mergeCollections(Node::Type nt, CNMap& cnm, const Node* relative)
void QDocDatabase::mergeCollections(Node::Genus genus, CNMap& cnm, const Node* relative)
{
QRegExp singleDigit("\\b([0-9])\\b");
CNMultiMap cnmm;
forest_.mergeCollectionMaps(nt, cnmm);
cnm.clear();
CNMultiMap cnmm;
foreach (Tree* t, searchOrder()) {
CNMap* m = t->getCollectionMap(genus);
if (m && !m->isEmpty()) {
CNMap::const_iterator i = m->begin();
while (i != m->end()) {
if (!i.value()->isInternal())
cnmm.insert(i.key(), i.value());
++i;
}
}
}
if (cnmm.isEmpty())
return;
QRegExp singleDigit("\\b([0-9])\\b");
QStringList keys = cnmm.uniqueKeys();
foreach (const QString &key, keys) {
QList<CollectionNode*> values = cnmm.values(key);
@ -1580,19 +1586,16 @@ void QDocDatabase::mergeCollections(Node::Type nt, CNMap& cnm, const Node* relat
/*!
Finds all the collection nodes with the same name
and type as \a cn and merges their members into the
members list of \a cn.
and genus as \a c and merges their members into the
members list of \a c.
*/
void QDocDatabase::mergeCollections(CollectionNode* cn)
void QDocDatabase::mergeCollections(CollectionNode* c)
{
CollectionList cl;
forest_.getCorrespondingCollections(cn, cl);
if (!cl.empty()) {
foreach (CollectionNode* v, cl) {
if (v != cn) {
foreach (Node* t, v->members())
cn->addMember(t);
}
foreach (Tree* t, searchOrder()) {
CollectionNode* cn = t->getCollection(c->name(), c->genus());
if (cn && cn != c) {
foreach (Node* n, cn->members())
c->addMember(n);
}
}
}

View File

@ -167,10 +167,10 @@ class QDocForest
return 0;
}
const DocNode* findDocNodeByTitle(const QString& title)
const DocumentNode* findDocumentNodeByTitle(const QString& title)
{
foreach (Tree* t, searchOrder()) {
const DocNode* n = t->findDocNodeByTitle(title);
const DocumentNode* n = t->findDocumentNodeByTitle(title);
if (n)
return n;
}
@ -186,16 +186,6 @@ class QDocForest
}
return 0;
}
void mergeCollectionMaps(Node::Type nt, CNMultiMap& cnmm);
void getCorrespondingCollections(CollectionNode* cn, CollectionList& cl)
{
foreach (Tree* t, searchOrder()) {
CollectionNode* ccn = t->getCorrespondingCollection(cn);
if (ccn)
cl.append(ccn);
}
}
void clearSearchOrder() { searchOrder_.clear(); }
void clearLinkCounts()
{
@ -230,28 +220,38 @@ class QDocDatabase
~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(); }
GroupNode* getGroup(const QString& name) { return primaryTree()->getGroup(name); }
GroupNode* findGroup(const QString& name) { return primaryTree()->findGroup(name); }
ModuleNode* findModule(const QString& name) { return primaryTree()->findModule(name); }
QmlModuleNode* findQmlModule(const QString& name) { return primaryTree()->findQmlModule(name); }
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); }
GroupNode* addGroup(const QString& name) { return primaryTree()->addGroup(name); }
ModuleNode* addModule(const QString& name) { return primaryTree()->addModule(name); }
QmlModuleNode* addQmlModule(const QString& name) { return primaryTree()->addQmlModule(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); }
CollectionNode* addJsModule(const QString& name) { return primaryTree()->addJsModule(name); }
GroupNode* addToGroup(const QString& name, Node* node) {
CollectionNode* addToGroup(const QString& name, Node* node) {
return primaryTree()->addToGroup(name, node);
}
ModuleNode* addToModule(const QString& name, Node* node) {
CollectionNode* addToModule(const QString& name, Node* node) {
return primaryTree()->addToModule(name, node);
}
QmlModuleNode* addToQmlModule(const QString& name, Node* node) {
CollectionNode* addToQmlModule(const QString& name, Node* node) {
return primaryTree()->addToQmlModule(name, node);
}
CollectionNode* addToJsModule(const QString& name, Node* node) {
return primaryTree()->addToJsModule(name, node);
}
void addExampleNode(ExampleNode* n) { primaryTree()->addExampleNode(n); }
ExampleNodeMap& exampleNodeMap() { return primaryTree()->exampleNodeMap(); }
@ -336,8 +336,8 @@ class QDocDatabase
}
const Node* findTypeNode(const QString& type, const Node* relative);
const Node* findNodeForTarget(const QString& target, const Node* relative);
const DocNode* findDocNodeByTitle(const QString& title) {
return forest_.findDocNodeByTitle(title);
const DocumentNode* findDocumentNodeByTitle(const QString& title) {
return forest_.findDocumentNodeByTitle(title);
}
Node* findNodeByNameAndType(const QStringList& path, Node::Type type) {
return forest_.findNodeByNameAndType(path, type);
@ -386,8 +386,8 @@ class QDocDatabase
void setLocalSearch() { forest_.searchOrder_ = QVector<Tree*>(1, primaryTree()); }
void setSearchOrder(const QVector<Tree*>& searchOrder) { forest_.searchOrder_ = searchOrder; }
void setSearchOrder(QStringList& t) { forest_.setSearchOrder(t); }
void mergeCollections(Node::Type nt, CNMap& cnm, const Node* relative);
void mergeCollections(CollectionNode* cn);
void mergeCollections(Node::Genus genus, CNMap& cnm, const Node* relative);
void mergeCollections(CollectionNode* c);
void clearSearchOrder() { forest_.clearSearchOrder(); }
void incrementLinkCount(const Node* t) { t->tree()->incrementLinkCount(); }
void clearLinkCounts() { forest_.clearLinkCounts(); }

View File

@ -229,6 +229,29 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
location = Location(name);
node = qcn;
}
else if (element.nodeName() == "jstype") {
QmlTypeNode* qcn = new QmlTypeNode(parent, name);
qcn->setGenus(Node::JS);
qcn->setTitle(element.attribute("title"));
QString logicalModuleName = element.attribute("js-module-name");
if (!logicalModuleName.isEmpty())
qdb_->addToQmlModule(logicalModuleName, qcn);
bool abstract = false;
if (element.attribute("abstract") == "true")
abstract = true;
qcn->setAbstract(abstract);
QString qmlFullBaseName = element.attribute("js-base-type");
if (!qmlFullBaseName.isEmpty()) {
qcn->setQmlBaseName(qmlFullBaseName);
}
if (element.hasAttribute("location"))
name = element.attribute("location", QString());
if (!indexUrl.isEmpty())
location = Location(indexUrl + QLatin1Char('/') + name);
else if (!indexUrl.isNull())
location = Location(name);
node = qcn;
}
else if (element.nodeName() == "qmlbasictype") {
QmlBasicTypeNode* qbtn = new QmlBasicTypeNode(parent, name);
qbtn->setTitle(element.attribute("title"));
@ -240,6 +263,18 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
location = Location(name);
node = qbtn;
}
else if (element.nodeName() == "jsbasictype") {
QmlBasicTypeNode* qbtn = new QmlBasicTypeNode(parent, name);
qbtn->setGenus(Node::JS);
qbtn->setTitle(element.attribute("title"));
if (element.hasAttribute("location"))
name = element.attribute("location", QString());
if (!indexUrl.isEmpty())
location = Location(indexUrl + QLatin1Char('/') + name);
else if (!indexUrl.isNull())
location = Location(name);
node = qbtn;
}
else if (element.nodeName() == "qmlpropertygroup") {
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(parent);
QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name);
@ -251,6 +286,18 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
location = Location(name);
node = qpgn;
}
else if (element.nodeName() == "jspropertygroup") {
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(parent);
QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name);
qpgn->setGenus(Node::JS);
if (element.hasAttribute("location"))
name = element.attribute("location", QString());
if (!indexUrl.isEmpty())
location = Location(indexUrl + QLatin1Char('/') + name);
else if (!indexUrl.isNull())
location = Location(name);
node = qpgn;
}
else if (element.nodeName() == "qmlproperty") {
QString type = element.attribute("type");
bool attached = false;
@ -271,6 +318,27 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
qpn->setReadOnly(readonly);
node = qpn;
}
else if (element.nodeName() == "jsproperty") {
QString type = element.attribute("type");
bool attached = false;
if (element.attribute("attached") == "true")
attached = true;
bool readonly = false;
if (element.attribute("writable") == "false")
readonly = true;
QmlPropertyNode* qpn = 0;
if (parent->isJsType()) {
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(parent);
qpn = new QmlPropertyNode(qcn, name, type, attached);
}
else if (parent->isJsPropertyGroup()) {
QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(parent);
qpn = new QmlPropertyNode(qpgn, name, type, attached);
}
qpn->setGenus(Node::JS);
qpn->setReadOnly(readonly);
node = qpn;
}
else if ((element.nodeName() == "qmlmethod") ||
(element.nodeName() == "qmlsignal") ||
(element.nodeName() == "qmlsignalhandler")) {
@ -283,30 +351,58 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
FunctionNode* fn = new FunctionNode(t, parent, name, attached);
node = fn;
}
else if ((element.nodeName() == "jsmethod") ||
(element.nodeName() == "jssignal") ||
(element.nodeName() == "jssignalhandler")) {
Node::Type t = Node::QmlMethod;
if (element.nodeName() == "jssignal")
t = Node::QmlSignal;
else if (element.nodeName() == "jssignalhandler")
t = Node::QmlSignalHandler;
bool attached = false;
FunctionNode* fn = new FunctionNode(t, parent, name, attached);
fn->setGenus(Node::JS);
node = fn;
}
else if (element.nodeName() == "group") {
GroupNode* gn = qdb_->addGroup(name);
gn->setTitle(element.attribute("title"));
gn->setSubTitle(element.attribute("subtitle"));
CollectionNode* cn = qdb_->addGroup(name);
cn->setTitle(element.attribute("title"));
cn->setSubTitle(element.attribute("subtitle"));
if (element.attribute("seen") == "true")
gn->markSeen();
node = gn;
cn->markSeen();
node = cn;
}
else if (element.nodeName() == "module") {
ModuleNode* mn = qdb_->addModule(name);
mn->setTitle(element.attribute("title"));
mn->setSubTitle(element.attribute("subtitle"));
CollectionNode* cn = qdb_->addModule(name);
cn->setTitle(element.attribute("title"));
cn->setSubTitle(element.attribute("subtitle"));
if (element.attribute("seen") == "true")
mn->markSeen();
node = mn;
cn->markSeen();
node = cn;
}
else if (element.nodeName() == "qmlmodule") {
QString t = element.attribute("qml-module-name") + " " + element.attribute("qml-module-version");
QmlModuleNode* qmn = qdb_->addQmlModule(t);
qmn->setTitle(element.attribute("title"));
qmn->setSubTitle(element.attribute("subtitle"));
QString t = element.attribute("qml-module-name");
CollectionNode* cn = qdb_->addQmlModule(t);
QStringList info;
info << t << element.attribute("qml-module-version");
cn->setLogicalModuleInfo(info);
cn->setTitle(element.attribute("title"));
cn->setSubTitle(element.attribute("subtitle"));
if (element.attribute("seen") == "true")
qmn->markSeen();
node = qmn;
cn->markSeen();
node = cn;
}
else if (element.nodeName() == "jsmodule") {
QString t = element.attribute("js-module-name");
CollectionNode* cn = qdb_->addJsModule(t);
QStringList info;
info << t << element.attribute("js-module-version");
cn->setLogicalModuleInfo(info);
cn->setTitle(element.attribute("title"));
cn->setSubTitle(element.attribute("subtitle"));
if (element.attribute("seen") == "true")
cn->markSeen();
node = cn;
}
else if (element.nodeName() == "page") {
Node::SubType subtype;
@ -335,7 +431,7 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
else
return;
DocNode* docNode = new DocNode(parent, name, subtype, ptype);
DocumentNode* docNode = new DocumentNode(parent, name, subtype, ptype);
docNode->setTitle(element.attribute("title"));
if (element.hasAttribute("location"))
@ -492,7 +588,9 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
if ((element.nodeName() != "page") &&
(element.nodeName() != "qmlclass") &&
(element.nodeName() != "qmlbasictype")) {
(element.nodeName() != "qmlbasictype") &&
(element.nodeName() != "jstype") &&
(element.nodeName() != "jsbasictype")) {
QString threadSafety = element.attribute("threadsafety");
if (threadSafety == "non-reentrant")
node->setThreadSafeness(Node::NonReentrant);
@ -646,15 +744,21 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
break;
case Node::QmlType:
{
nodeName = "qmlclass";
QmlModuleNode* qmn = node->logicalModule();
if (qmn)
logicalModuleName = qmn->logicalModuleName();
if (node->isQmlNode())
nodeName = "qmlclass";
else
nodeName = "jstype";
CollectionNode* cn = node->logicalModule();
if (cn)
logicalModuleName = cn->logicalModuleName();
qmlFullBaseName = node->qmlFullBaseName();
}
break;
case Node::QmlBasicType:
nodeName = "qmlbasictype";
if (node->isQmlNode())
nodeName = "qmlbasictype";
else
nodeName = "jsbasictype";
break;
case Node::Document:
nodeName = "page";
@ -666,7 +770,10 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
nodeName = "module";
break;
case Node::QmlModule:
nodeName = "qmlmodule";
if (node->isQmlNode())
nodeName = "qmlmodule";
else
nodeName = "jsmodule";
break;
case Node::Enum:
nodeName = "enum";
@ -684,19 +791,34 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
nodeName = "variable";
break;
case Node::QmlProperty:
nodeName = "qmlproperty";
if (node->isQmlNode())
nodeName = "qmlproperty";
else
nodeName = "jsProperty";
break;
case Node::QmlPropertyGroup:
nodeName = "qmlpropertygroup";
if (node->isQmlNode())
nodeName = "qmlpropertygroup";
else
nodeName = "jspropertygroup";
break;
case Node::QmlSignal:
nodeName = "qmlsignal";
if (node->isQmlNode())
nodeName = "qmlsignal";
else
nodeName = "jssignal";
break;
case Node::QmlSignalHandler:
nodeName = "qmlsignalhandler";
if (node->isQmlNode())
nodeName = "qmlsignalhandler";
else
nodeName = "jssignalhandler";
break;
case Node::QmlMethod:
nodeName = "qmlmethod";
if (node->isQmlNode())
nodeName = "qmlmethod";
else
nodeName = "jsmethod";
break;
default:
return false;
@ -711,16 +833,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
access = "protected";
break;
case Node::Private:
#if 0
// Do not include private non-internal nodes in the index.
// (Internal public and protected nodes are marked as private
// by qdoc. We can check their internal status to determine
// whether they were really private to begin with.)
if (node->status() == Node::Internal && generateInternalNodes)
access = "internal";
else
return false;
#endif
{
access = "private";
bool b = generateInternalNodes;
@ -741,7 +853,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
QXmlStreamAttributes attributes;
if (!node->isDocNode() && !node->isGroup() && !node->isModule() && !node->isQmlModule()) {
if (!node->isDocumentNode() && !node->isCollectionNode()) {
QString threadSafety;
switch (node->threadSafeness()) {
case Node::NonReentrant:
@ -791,13 +903,24 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
if (node->isQmlModule()) {
logicalModuleName = node->logicalModuleName();
logicalModuleVersion = node->logicalModuleVersion();
if (!logicalModuleName.isEmpty()) {
writer.writeAttribute("qml-module-name", logicalModuleName);
if (node->isQmlModule())
writer.writeAttribute("qml-module-version", logicalModuleVersion);
if (!qmlFullBaseName.isEmpty())
writer.writeAttribute("qml-base-type", qmlFullBaseName);
}
}
if (!logicalModuleName.isEmpty()) {
writer.writeAttribute("qml-module-name", logicalModuleName);
if (node->isQmlModule())
writer.writeAttribute("qml-module-version", logicalModuleVersion);
if (!qmlFullBaseName.isEmpty())
writer.writeAttribute("qml-base-type", qmlFullBaseName);
else if (node->isJsModule()) {
logicalModuleName = node->logicalModuleName();
logicalModuleVersion = node->logicalModuleVersion();
if (!logicalModuleName.isEmpty()) {
writer.writeAttribute("js-module-name", logicalModuleName);
if (node->isQmlModule())
writer.writeAttribute("js-module-version", logicalModuleVersion);
if (!qmlFullBaseName.isEmpty())
writer.writeAttribute("js-base-type", qmlFullBaseName);
}
}
QString href;
@ -816,12 +939,12 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
}
else
href = node->name();
if (node->isQmlNode()) {
if (node->isQmlNode() || node->isJsNode()) {
InnerNode* p = node->parent();
if (p) {
if (p->isQmlPropertyGroup())
if (p->isQmlPropertyGroup() || p->isJsPropertyGroup())
p = p->parent();
if (p && p->isQmlType() && p->isAbstract())
if (p && (p->isQmlType() || p->isJsType()) && p->isAbstract())
href.clear();
}
}
@ -829,7 +952,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("href", href);
writer.writeAttribute("status", status);
if (!node->isDocNode() && !node->isGroup() && !node->isModule() && !node->isQmlModule()) {
if (!node->isDocumentNode() && !node->isCollectionNode()) {
writer.writeAttribute("access", access);
if (node->isAbstract())
writer.writeAttribute("abstract", "true");
@ -898,7 +1021,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
a title, and other attributes.
*/
bool writeModuleName = false;
const DocNode* docNode = static_cast<const DocNode*>(node);
const DocumentNode* docNode = static_cast<const DocumentNode*>(node);
switch (docNode->subType()) {
case Node::Example:
writer.writeAttribute("subtype", "example");
@ -935,22 +1058,22 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
break;
case Node::Group:
{
const GroupNode* gn = static_cast<const GroupNode*>(node);
writer.writeAttribute("seen", gn->wasSeen() ? "true" : "false");
writer.writeAttribute("title", gn->title());
if (!gn->subTitle().isEmpty())
writer.writeAttribute("subtitle", gn->subTitle());
if (!gn->physicalModuleName().isEmpty())
writer.writeAttribute("module", gn->physicalModuleName());
if (!gn->groupNames().isEmpty())
writer.writeAttribute("groups", gn->groupNames().join(","));
const CollectionNode* cn = static_cast<const CollectionNode*>(node);
writer.writeAttribute("seen", cn->wasSeen() ? "true" : "false");
writer.writeAttribute("title", cn->title());
if (!cn->subTitle().isEmpty())
writer.writeAttribute("subtitle", cn->subTitle());
if (!cn->physicalModuleName().isEmpty())
writer.writeAttribute("module", cn->physicalModuleName());
if (!cn->groupNames().isEmpty())
writer.writeAttribute("groups", cn->groupNames().join(","));
/*
This is not read back in, so it probably
shouldn't be written out in the first place.
*/
if (!gn->members().isEmpty()) {
if (!cn->members().isEmpty()) {
QStringList names;
foreach (const Node* member, gn->members())
foreach (const Node* member, cn->members())
names.append(member->name());
writer.writeAttribute("members", names.join(","));
}
@ -960,22 +1083,22 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
break;
case Node::Module:
{
const ModuleNode* mn = static_cast<const ModuleNode*>(node);
writer.writeAttribute("seen", mn->wasSeen() ? "true" : "false");
writer.writeAttribute("title", mn->title());
if (!mn->subTitle().isEmpty())
writer.writeAttribute("subtitle", mn->subTitle());
if (!mn->physicalModuleName().isEmpty())
writer.writeAttribute("module", mn->physicalModuleName());
if (!mn->groupNames().isEmpty())
writer.writeAttribute("groups", mn->groupNames().join(","));
const CollectionNode* cn = static_cast<const CollectionNode*>(node);
writer.writeAttribute("seen", cn->wasSeen() ? "true" : "false");
writer.writeAttribute("title", cn->title());
if (!cn->subTitle().isEmpty())
writer.writeAttribute("subtitle", cn->subTitle());
if (!cn->physicalModuleName().isEmpty())
writer.writeAttribute("module", cn->physicalModuleName());
if (!cn->groupNames().isEmpty())
writer.writeAttribute("groups", cn->groupNames().join(","));
/*
This is not read back in, so it probably
shouldn't be written out in the first place.
*/
if (!mn->members().isEmpty()) {
if (!cn->members().isEmpty()) {
QStringList names;
foreach (const Node* member, mn->members())
foreach (const Node* member, cn->members())
names.append(member->name());
writer.writeAttribute("members", names.join(","));
}
@ -985,22 +1108,22 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
break;
case Node::QmlModule:
{
const QmlModuleNode* qmn = static_cast<const QmlModuleNode*>(node);
writer.writeAttribute("seen", qmn->wasSeen() ? "true" : "false");
writer.writeAttribute("title", qmn->title());
if (!qmn->subTitle().isEmpty())
writer.writeAttribute("subtitle", qmn->subTitle());
if (!qmn->physicalModuleName().isEmpty())
writer.writeAttribute("module", qmn->physicalModuleName());
if (!qmn->groupNames().isEmpty())
writer.writeAttribute("groups", qmn->groupNames().join(","));
const CollectionNode* cn = static_cast<const CollectionNode*>(node);
writer.writeAttribute("seen", cn->wasSeen() ? "true" : "false");
writer.writeAttribute("title", cn->title());
if (!cn->subTitle().isEmpty())
writer.writeAttribute("subtitle", cn->subTitle());
if (!cn->physicalModuleName().isEmpty())
writer.writeAttribute("module", cn->physicalModuleName());
if (!cn->groupNames().isEmpty())
writer.writeAttribute("groups", cn->groupNames().join(","));
/*
This is not read back in, so it probably
shouldn't be written out in the first place.
*/
if (!qmn->members().isEmpty()) {
if (!cn->members().isEmpty()) {
QStringList names;
foreach (const Node* member, qmn->members())
foreach (const Node* member, cn->members())
names.append(member->name());
writer.writeAttribute("members", names.join(","));
}
@ -1195,7 +1318,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
if (node->doc().hasTargets()) {
bool external = false;
if (node->type() == Node::Document) {
const DocNode* docNode = static_cast<const DocNode*>(node);
const DocumentNode* docNode = static_cast<const DocumentNode*>(node);
if (docNode->subType() == Node::ExternalPage)
external = true;
}
@ -1295,9 +1418,17 @@ bool compareNodes(const Node* n1, const Node* n2)
return false;
}
if (n1->isDocNode() && n2->isDocNode()) {
const DocNode* f1 = static_cast<const DocNode*>(n1);
const DocNode* f2 = static_cast<const DocNode*>(n2);
if (n1->isDocumentNode() && n2->isDocumentNode()) {
const DocumentNode* f1 = static_cast<const DocumentNode*>(n1);
const DocumentNode* f2 = static_cast<const DocumentNode*>(n2);
if (f1->fullTitle() < f2->fullTitle())
return true;
else if (f1->fullTitle() > f2->fullTitle())
return false;
}
else if (n1->isCollectionNode() && n2->isCollectionNode()) {
const CollectionNode* f1 = static_cast<const CollectionNode*>(n1);
const CollectionNode* f2 = static_cast<const CollectionNode*>(n2);
if (f1->fullTitle() < f2->fullTitle())
return true;
else if (f1->fullTitle() > f2->fullTitle())
@ -1321,7 +1452,7 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
Note that groups, modules, and QML modules are written
after all the other nodes.
*/
if (node->isGroup() || node->isModule() || node->isQmlModule())
if (node->isGroup() || node->isModule() || node->isQmlModule() || node->isJsModule())
return;
if (generateIndexSection(writer, node, generateInternalNodes)) {
@ -1374,6 +1505,16 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
++g;
}
}
const CNMap& jsModules = qdb_->jsModules();
if (!jsModules.isEmpty()) {
CNMap::ConstIterator g = jsModules.constBegin();
while (g != jsModules.constEnd()) {
if (generateIndexSection(writer, g.value(), generateInternalNodes))
writer.writeEndElement();
++g;
}
}
}
writer.writeEndElement();

View File

@ -76,6 +76,19 @@ QT_BEGIN_NAMESPACE
#define COMMAND_QMLBASICTYPE Doc::alias("qmlbasictype")
#define COMMAND_QMLMODULE Doc::alias("qmlmodule")
#define COMMAND_JSTYPE Doc::alias("jstype")
#define COMMAND_JSMODULE Doc::alias("jsmodule")
#define COMMAND_JSPROPERTY Doc::alias("jsproperty")
#define COMMAND_JSPROPERTYGROUP Doc::alias("jspropertygroup")
#define COMMAND_JSATTACHEDPROPERTY Doc::alias("jsattachedproperty")
#define COMMAND_INJSMODULE Doc::alias("injsmodule")
#define COMMAND_JSSIGNAL Doc::alias("jssignal")
#define COMMAND_JSATTACHEDSIGNAL Doc::alias("jsattachedsignal")
#define COMMAND_JSMETHOD Doc::alias("jsmethod")
#define COMMAND_JSATTACHEDMETHOD Doc::alias("jsattachedmethod")
#define COMMAND_JSBASICTYPE Doc::alias("jsbasictype")
#define COMMAND_JSMODULE Doc::alias("jsmodule")
/*!
Constructs the QML code parser.
*/
@ -205,7 +218,16 @@ const QSet<QString>& QmlCodeParser::topicCommands()
<< COMMAND_QMLATTACHEDSIGNAL
<< COMMAND_QMLMETHOD
<< COMMAND_QMLATTACHEDMETHOD
<< COMMAND_QMLBASICTYPE;
<< COMMAND_QMLBASICTYPE
<< COMMAND_JSTYPE
<< COMMAND_JSPROPERTY
<< COMMAND_JSPROPERTYGROUP
<< COMMAND_JSATTACHEDPROPERTY
<< COMMAND_JSSIGNAL
<< COMMAND_JSATTACHEDSIGNAL
<< COMMAND_JSMETHOD
<< COMMAND_JSATTACHEDMETHOD
<< COMMAND_JSBASICTYPE;
}
return topicCommands_;
}
@ -231,6 +253,7 @@ const QSet<QString>& QmlCodeParser::otherMetaCommands()
<< COMMAND_SINCE
<< COMMAND_QMLABSTRACT
<< COMMAND_INQMLMODULE
<< COMMAND_INJSMODULE
<< COMMAND_WRAPPER;
}
return otherMetaCommands_;

View File

@ -72,6 +72,18 @@ QT_BEGIN_NAMESPACE
#define COMMAND_QMLREADONLY Doc::alias(QLatin1String("readonly"))
#define COMMAND_QMLBASICTYPE Doc::alias(QLatin1String("qmlbasictype"))
#define COMMAND_JSTYPE Doc::alias(QLatin1String("jstype"))
#define COMMAND_JSMODULE Doc::alias(QLatin1String("jsmodule"))
#define COMMAND_JSPROPERTY Doc::alias(QLatin1String("jsproperty"))
#define COMMAND_JSPROPERTYGROUP Doc::alias(QLatin1String("jspropertygroup"))
#define COMMAND_JSATTACHEDPROPERTY Doc::alias(QLatin1String("jsattachedproperty"))
#define COMMAND_INJSMODULE Doc::alias(QLatin1String("injsmodule"))
#define COMMAND_JSSIGNAL Doc::alias(QLatin1String("jssignal"))
#define COMMAND_JSATTACHEDSIGNAL Doc::alias(QLatin1String("jsattachedsignal"))
#define COMMAND_JSMETHOD Doc::alias(QLatin1String("jsmethod"))
#define COMMAND_JSATTACHEDMETHOD Doc::alias(QLatin1String("jsattachedmethod"))
#define COMMAND_JSBASICTYPE Doc::alias(QLatin1String("jsbasictype"))
/*!
The constructor stores all the parameters in local data members.
*/
@ -134,82 +146,6 @@ QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) cons
return QQmlJS::AST::SourceLocation();
}
#if 0
ArgList args;
QSet<QString>::iterator i = metacommands.begin();
while (i != metacommands.end()) {
if (topics_.contains(*i)) {
topic = *i;
break;
}
++i;
}
if (!topic.isEmpty()) {
args = doc.metaCommandArgs(topic);
if ((topic == COMMAND_QMLCLASS) || (topic == COMMAND_QMLTYPE)) {
// do nothing.
}
else if (topic == COMMAND_QMLPROPERTY) {
if (node->type() == Node::QmlProperty) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setReadOnly(0);
if (qpn->dataType() == "alias") {
QStringList part = args[0].first.split(QLatin1Char(' '));
qpn->setDataType(part[0]);
}
}
}
else if (topic == COMMAND_QMLPROPERTYGROUP) {
// zzz ?
}
else if (topic == COMMAND_QMLMODULE) {
}
else if (topic == COMMAND_QMLATTACHEDPROPERTY) {
if (node->type() == Node::QmlProperty) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setReadOnly(0);
}
}
else if (topic == COMMAND_QMLSIGNAL) {
}
else if (topic == COMMAND_QMLATTACHEDSIGNAL) {
}
else if (topic == COMMAND_QMLMETHOD) {
}
else if (topic == COMMAND_QMLATTACHEDMETHOD) {
}
else if (topic == COMMAND_QMLBASICTYPE) {
}
}
if (node->type() == Node::QmlProperty) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
for (int i=0; i<topicsUsed.size(); ++i) {
if (topicsUsed.at(i).topic == "qmlproperty") {
/*
A \qmlproperty command would be used in a QML file
to document the underlying property for a property
alias.
*/
QmlPropArgs qpa;
if (splitQmlPropertyArg(doc, topicsUsed.at(i).args, qpa)) {
QmlPropertyNode* n = parent->hasQmlPropertyNode(qpa.name_);
if (n == 0)
n = new QmlPropertyNode(qpn, qpa.name_, qpa.type_, false);
n->setLocation(doc.location());
n->setReadOnly(qpn->isReadOnly());
if (qpn->isDefault())
n->setDefault();
}
else
qDebug() << " FAILED TO PARSE QML PROPERTY:"
<< topicsUsed.at(i).topic << topicsUsed.at(i).args;
}
}
}
#endif
/*!
Finds the nearest unused qdoc comment above the QML entity
represented by the \a node and processes the qdoc commands
@ -241,7 +177,8 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
nodes.append(node);
if (topicsUsed.size() > 0) {
for (int i=0; i<topicsUsed.size(); ++i) {
if (topicsUsed.at(i).topic == COMMAND_QMLPROPERTYGROUP) {
if ((topicsUsed.at(i).topic == COMMAND_QMLPROPERTYGROUP) ||
(topicsUsed.at(i).topic == COMMAND_JSPROPERTYGROUP)) {
qDebug() << "PROPERTY GROUP COMMAND SEEN:" << topicsUsed.at(i).args << filePath_;
break;
}
@ -249,7 +186,8 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
for (int i=0; i<topicsUsed.size(); ++i) {
QString topic = topicsUsed.at(i).topic;
QString args = topicsUsed.at(i).args;
if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) {
if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY) ||
(topic == COMMAND_JSPROPERTY) || (topic == COMMAND_JSATTACHEDPROPERTY)) {
QmlPropArgs qpa;
if (splitQmlPropertyArg(doc, args, qpa)) {
if (qpa.name_ == nodePassedIn->name()) {
@ -257,7 +195,8 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
nodePassedIn->setDataType(qpa.type_);
}
else {
bool isAttached = (topic == COMMAND_QMLATTACHEDPROPERTY);
bool isAttached = (topic == COMMAND_QMLATTACHEDPROPERTY) ||
(topic == COMMAND_JSATTACHEDPROPERTY);
QmlPropertyNode* n = parent->hasQmlProperty(qpa.name_, isAttached);
if (n == 0)
n = new QmlPropertyNode(parent, qpa.name_, qpa.type_, isAttached);
@ -268,11 +207,14 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
n->setDefault();
if (isAttached)
n->setReadOnly(0);
if ((topic == COMMAND_JSPROPERTY) ||
(topic == COMMAND_JSATTACHEDPROPERTY))
n->setGenus(Node::JS);
nodes.append(n);
}
}
else
qDebug() << " FAILED TO PARSE QML PROPERTY:" << topic << args;
qDebug() << " FAILED TO PARSE QML OR JS PROPERTY:" << topic << args;
}
}
}
@ -357,33 +299,33 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation,
QString command = *i;
ArgList args = doc.metaCommandArgs(command);
if (command == COMMAND_QMLABSTRACT) {
if (node->isQmlType()) {
if (node->isQmlType() || node->isJsType()) {
node->setAbstract(true);
}
}
else if (command == COMMAND_DEPRECATED) {
node->setStatus(Node::Obsolete);
}
else if (command == COMMAND_INQMLMODULE) {
else if ((command == COMMAND_INQMLMODULE) || (command == COMMAND_INJSMODULE)) {
qdb->addToQmlModule(args[0].first,node);
}
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 if (node->isQmlType()) {
else if (node->isQmlType() || node->isJsType()) {
QmlTypeNode *qmlType = static_cast<QmlTypeNode*>(node);
qmlType->setQmlBaseName(args[0].first);
QmlTypeNode::addInheritedBy(args[0].first,node);
}
}
else if (command == COMMAND_QMLDEFAULT) {
if (node->type() == Node::QmlProperty) {
if (node->isQmlProperty() || node->isJsProperty()) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setDefault();
}
}
else if (command == COMMAND_QMLREADONLY) {
if (node->type() == Node::QmlProperty) {
if (node->isQmlProperty() || node->isJsProperty()) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setReadOnly(1);
}
@ -532,7 +474,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
switch (member->type) {
case QQmlJS::AST::UiPublicMember::Signal:
{
if (current->isQmlType()) {
if (current->isQmlType() || current->isJsType()) {
QmlTypeNode *qmlType = static_cast<QmlTypeNode *>(current);
if (qmlType) {
@ -555,13 +497,16 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
{
QString type = member->memberType.toString();
QString name = member->name.toString();
if (current->isQmlType()) {
if (current->isQmlType() || current->isJsType()) {
QmlTypeNode *qmlType = static_cast<QmlTypeNode *>(current);
if (qmlType) {
QString name = member->name.toString();
QmlPropertyNode* qmlPropNode = qmlType->hasQmlProperty(name);
if (qmlPropNode == 0)
if (qmlPropNode == 0) {
qmlPropNode = new QmlPropertyNode(qmlType, name, type, false);
if (current->isJsType())
qmlPropNode->setGenus(Node::JS);
}
qmlPropNode->setReadOnly(member->isReadonlyMember);
if (member->isDefaultMember)
qmlPropNode->setDefault();
@ -599,11 +544,13 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd)
if (nestingLevel > 1) {
return true;
}
if (current->isQmlType()) {
if (current->isQmlType() || current->isJsType()) {
QmlTypeNode* qmlType = static_cast<QmlTypeNode*>(current);
if (qmlType) {
QString name = fd->name.toString();
FunctionNode* qmlMethod = new FunctionNode(Node::QmlMethod, current, name, false);
if (current->isJsType())
qmlMethod->setGenus(Node::JS);
int overloads = 0;
NodeList::ConstIterator overloadIterator = current->childNodes().constBegin();
while (overloadIterator != current->childNodes().constEnd()) {
@ -652,7 +599,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiScriptBinding* )
if (nestingLevel > 1) {
return true;
}
if (current->isQmlType()) {
if (current->isQmlType() || current->isJsType()) {
QString handler = sb->qualifiedId->name.toString();
if (handler.length() > 2 && handler.startsWith("on") && handler.at(2).isUpper()) {
QmlTypeNode* qmlType = static_cast<QmlTypeNode*>(current);

View File

@ -225,7 +225,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
if (!qcn) {
QStringList p(path[1]);
Node* n = findNodeByNameAndType(p, Node::QmlType);
if (n && n->isQmlType())
if (n && (n->isQmlType() || n->isJsType()))
qcn = static_cast<QmlTypeNode*>(n);
}
if (qcn)
@ -253,7 +253,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
else
next = ((InnerNode*) node)->findChildNode(path.at(i), genus);
if (!next && node->type() == Node::Class && (findFlags & SearchBaseClasses)) {
if (!next && node->isClass() && (findFlags & SearchBaseClasses)) {
NodeList baseClasses = allBaseClasses(static_cast<const ClassNode*>(node));
foreach (const Node* baseClass, baseClasses) {
if (i == path.size() - 1)
@ -489,7 +489,7 @@ void Tree::resolveCppToQmlLinks()
{
foreach (Node* child, root_.childNodes()) {
if (child->isQmlType()) {
if (child->isQmlType() || child->isJsType()) {
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(child);
ClassNode* cn = const_cast<ClassNode*>(qcn->classNode());
if (cn)
@ -694,7 +694,7 @@ const Node* Tree::findNodeForTarget(const QStringList& path,
p = path.join(QString("::"));
else if ((genus == Node::DontCare) || (genus == Node::DOC)) {
p = path.at(0);
node = findDocNodeByTitle(p);
node = findDocumentNodeByTitle(p);
if (node) {
if (!target.isEmpty()) {
ref = getRef(target, node);
@ -967,12 +967,12 @@ void Tree::resolveTargets(InnerNode* root)
// need recursion
foreach (Node* child, root->childNodes()) {
if (child->type() == Node::Document) {
DocNode* node = static_cast<DocNode*>(child);
DocumentNode* node = static_cast<DocumentNode*>(child);
QString key = node->title();
if (!key.isEmpty()) {
if (key.contains(QChar(' ')))
key = Doc::canonicalTitle(key);
QList<DocNode*> nodes = docNodesByTitle_.values(key);
QList<DocumentNode*> nodes = docNodesByTitle_.values(key);
bool alreadyThere = false;
if (!nodes.empty()) {
for (int i=0; i< nodes.size(); ++i) {
@ -1095,9 +1095,9 @@ Tree::findUnambiguousTarget(const QString& target, QString& ref) const
/*!
This function searches for a node with the specified \a title.
*/
const DocNode* Tree::findDocNodeByTitle(const QString& title) const
const DocumentNode* Tree::findDocumentNodeByTitle(const QString& title) const
{
DocNodeMultiMap::const_iterator i;
DocumentNodeMultiMap::const_iterator i;
if (title.contains(QChar(' ')))
i = docNodesByTitle_.constFind(Doc::canonicalTitle(title));
else
@ -1108,7 +1108,7 @@ const DocNode* Tree::findDocNodeByTitle(const QString& title) const
overkill. We should report the duplicate file and let
that suffice.
*/
DocNodeMultiMap::const_iterator j = i;
DocumentNodeMultiMap::const_iterator j = i;
++j;
if (j != docNodesByTitle_.constEnd() && j.key() == i.key()) {
QList<Location> internalLocations;
@ -1164,62 +1164,89 @@ QString Tree::refForAtom(const Atom* atom)
*/
/*!
Returns the collection node in this tree that has the same
name and type as \a cn. Returns 0 if no match is found.
If the matching node is \a cn, return 0.
Returns a pointer to the collection map specified by \a genus.
Returns null if \a genus is not specified.
*/
CollectionNode* Tree::getCorrespondingCollection(CollectionNode* cn)
CNMap* Tree::getCollectionMap(Node::Genus genus)
{
CollectionNode* ccn = 0;
if (cn->isGroup())
ccn = getGroup(cn->name());
else if (cn->isModule())
ccn = getModule(cn->name());
else if (cn->isQmlModule())
ccn = getQmlModule(cn->name());
if (ccn == cn)
ccn = 0;
return ccn;
}
/*!
Find the group node named \a name and return a pointer
to it. If a matching node is not found, return 0.
*/
GroupNode* Tree::getGroup(const QString& name)
{
CNMap::const_iterator i = groups_.find(name);
if (i != groups_.end())
return static_cast<GroupNode*>(i.value());
switch (genus) {
case Node::DOC:
return &groups_;
case Node::CPP:
return &modules_;
case Node::QML:
return &qmlModules_;
case Node::JS:
return &jsModules_;
default:
break;
}
return 0;
}
/*!
Find the module node named \a name and return a pointer
to it. If a matching node is not found, return 0.
Returns a pointer to the collection named \a name of the
specified \a genus in this tree. If there is no matching
collection in this tree, 0 is returned.
*/
ModuleNode* Tree::getModule(const QString& name)
CollectionNode* Tree::getCollection(const QString& name, Node::Genus genus)
{
CNMap::const_iterator i = modules_.find(name);
if (i != modules_.end())
return static_cast<ModuleNode*>(i.value());
CNMap* m = getCollectionMap(genus);
if (m) {
CNMap::const_iterator i = m->find(name);
if (i != m->end())
return i.value();
}
return 0;
}
/*!
Find the QML module node named \a name and return a pointer
to it. If a matching node is not found, return 0.
Find the group, module, QML module, or JavaScript module
named \a name and return a pointer to that collection node.
\a genus specifies which kind of collection node you want.
If a collection node with the specified \a name and \a genus
is not found, a new one is created, and the pointer to the
new one is returned.
If a new collection node is created, its parent is the tree
root, and the new collection node is marked \e{not seen}.
\a genus must be specified, i.e. it must not be \c{DontCare}.
If it is \c{DontCare}, 0 is returned, which is a programming
error.
*/
QmlModuleNode* Tree::getQmlModule(const QString& name)
CollectionNode* Tree::findCollection(const QString& name, Node::Genus genus)
{
CNMap::const_iterator i = qmlModules_.find(name);
if (i != qmlModules_.end())
return static_cast<QmlModuleNode*>(i.value());
return 0;
CNMap* m = getCollectionMap(genus);
if (!m) // error
return 0;
CNMap::const_iterator i = m->find(name);
if (i != m->end())
return i.value();
Node::Type t = Node::NoType;
switch (genus) {
case Node::DOC:
t = Node::Group;
break;
case Node::CPP:
t = Node::Module;
break;
case Node::QML:
t = Node::QmlModule;
break;
case Node::JS:
t = Node::QmlModule;
break;
default:
break;
}
CollectionNode* cn = new CollectionNode(t, root(), name, genus);
cn->markNotSeen();
m->insert(name, cn);
return cn;
}
/*!
/*! \fn CollectionNode* Tree::findGroup(const QString& name)
Find the group node named \a name and return a pointer
to it. If the group node is not found, add a new group
node named \a name and return a pointer to the new one.
@ -1227,18 +1254,8 @@ QmlModuleNode* Tree::getQmlModule(const QString& name)
If a new group node is added, its parent is the tree root,
and the new group node is marked \e{not seen}.
*/
GroupNode* Tree::findGroup(const QString& name)
{
CNMap::const_iterator i = groups_.find(name);
if (i != groups_.end())
return static_cast<GroupNode*>(i.value());;
GroupNode* gn = new GroupNode(root(), name);
gn->markNotSeen();
groups_.insert(name, gn);
return gn;
}
/*!
/*! \fn CollectionNode* Tree::findModule(const QString& name)
Find the module node named \a name and return a pointer
to it. If a matching node is not found, add a new module
node named \a name and return a pointer to that one.
@ -1246,77 +1263,56 @@ GroupNode* Tree::findGroup(const QString& name)
If a new module node is added, its parent is the tree root,
and the new module node is marked \e{not seen}.
*/
ModuleNode* Tree::findModule(const QString& name)
{
CNMap::const_iterator i = modules_.find(name);
if (i != modules_.end())
return static_cast<ModuleNode*>(i.value());
ModuleNode* mn = new ModuleNode(root(), name);
mn->markNotSeen();
modules_.insert(name, mn);
return mn;
}
/*!
/*! \fn CollectionNode* Tree::findQmlModule(const QString& name)
Find the QML module node named \a name and return a pointer
to it. If a matching node is not found, add a new QML module
node named \a name and return a pointer to that one.
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}.
and the new node is marked \e{not seen}.
*/
QmlModuleNode* Tree::findQmlModule(const QString& name)
{
CNMap::const_iterator i = qmlModules_.find(name);
if (i != qmlModules_.end())
return static_cast<QmlModuleNode*>(i.value());
QmlModuleNode* qmn = new QmlModuleNode(root(), name);
qmn->markNotSeen();
qmn->setQmlModuleInfo(name);
qmlModules_.insert(name, qmn);
return qmn;
}
/*!
/*! \fn CollectionNode* Tree::findJsModule(const QString& name)
Find the JavaScript module named \a name and return a pointer
to it. If a matching node is not found, add a new JavaScript
module node named \a name and return a pointer to that one.
If a new JavaScript module node is added, its parent is the
tree root, and the new node is marked \e{not seen}.
*/
/*! \fn CollectionNode* Tree::addGroup(const QString& name)
Looks up the group node named \a name in the collection
of all group nodes. If a match is found, a pointer to the
node is returned. Otherwise, a new group node named \a name
is created and inserted into the collection, and the pointer
to that node is returned.
*/
GroupNode* Tree::addGroup(const QString& name)
{
GroupNode* group = findGroup(name);
return group;
}
/*!
/*! \fn CollectionNode* Tree::addModule(const QString& name)
Looks up the module node named \a name in the collection
of all module nodes. If a match is found, a pointer to the
node is returned. Otherwise, a new module node named \a name
is created and inserted into the collection, and the pointer
to that node is returned.
*/
ModuleNode* Tree::addModule(const QString& name)
{
ModuleNode* module = findModule(name);
return module;
}
/*!
/*! \fn CollectionNode* Tree::addQmlModule(const QString& name)
Looks up the QML module node named \a name in the collection
of all QML module nodes. If a match is found, a pointer to the
node is returned. Otherwise, a new QML module node named \a name
is created and inserted into the collection, and the pointer
to that node is returned.
*/
QmlModuleNode* Tree::addQmlModule(const QString& name)
{
QStringList blankSplit = name.split(QLatin1Char(' '));
QmlModuleNode* qmn = findQmlModule(blankSplit[0]);
qmn->setQmlModuleInfo(name);
return qmn;
}
/*! \fn CollectionNode* Tree::addJsModule(const QString& name)
Looks up the JavaScript module node named \a name in the collection
of all JavaScript module nodes. If a match is found, a pointer to the
node is returned. Otherwise, a new JavaScrpt module node named \a name
is created and inserted into the collection, and the pointer
to that node is returned.
*/
/*!
Looks up the group node named \a name in the collection
@ -1327,14 +1323,14 @@ QmlModuleNode* Tree::addQmlModule(const QString& name)
\a node is not changed by this function. Returns a pointer to
the group node.
*/
GroupNode* Tree::addToGroup(const QString& name, Node* node)
CollectionNode* Tree::addToGroup(const QString& name, Node* node)
{
GroupNode* gn = findGroup(name);
CollectionNode* cn = findGroup(name);
if (!node->isInternal()) {
gn->addMember(node);
cn->addMember(node);
node->appendGroupName(name);
}
return gn;
return cn;
}
/*!
@ -1344,12 +1340,12 @@ GroupNode* Tree::addToGroup(const QString& name, Node* node)
Then append \a node to the module's members list. The parent of
\a node is not changed by this function. Returns the module node.
*/
ModuleNode* Tree::addToModule(const QString& name, Node* node)
CollectionNode* Tree::addToModule(const QString& name, Node* node)
{
ModuleNode* mn = findModule(name);
mn->addMember(node);
CollectionNode* cn = findModule(name);
cn->addMember(node);
node->setPhysicalModuleName(name);
return mn;
return cn;
}
/*!
@ -1358,7 +1354,7 @@ ModuleNode* Tree::addToModule(const QString& name, Node* node)
list. The parent of \a node is not changed by this function.
Returns the pointer to the QML module node.
*/
QmlModuleNode* Tree::addToQmlModule(const QString& name, Node* node)
CollectionNode* Tree::addToQmlModule(const QString& name, Node* node)
{
QStringList qmid;
QStringList dotSplit;
@ -1370,9 +1366,9 @@ QmlModuleNode* Tree::addToQmlModule(const QString& name, Node* node)
qmid.append(blankSplit[0] + dotSplit[0]);
}
QmlModuleNode* qmn = findQmlModule(blankSplit[0]);
qmn->addMember(node);
node->setQmlModule(qmn);
CollectionNode* cn = findQmlModule(blankSplit[0]);
cn->addMember(node);
node->setQmlModule(cn);
if (node->isQmlType()) {
QmlTypeNode* n = static_cast<QmlTypeNode*>(node);
for (int i=0; i<qmid.size(); ++i) {
@ -1380,7 +1376,38 @@ QmlModuleNode* Tree::addToQmlModule(const QString& name, Node* node)
insertQmlType(key, n);
}
}
return qmn;
return cn;
}
/*!
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 the pointer to the QML module node.
*/
CollectionNode* Tree::addToJsModule(const QString& name, Node* node)
{
QStringList qmid;
QStringList dotSplit;
QStringList blankSplit = name.split(QLatin1Char(' '));
qmid.append(blankSplit[0]);
if (blankSplit.size() > 1) {
qmid.append(blankSplit[0] + blankSplit[1]);
dotSplit = blankSplit[1].split(QLatin1Char('.'));
qmid.append(blankSplit[0] + dotSplit[0]);
}
CollectionNode* cn = findJsModule(blankSplit[0]);
cn->addMember(node);
node->setQmlModule(cn);
if (node->isJsType()) {
QmlTypeNode* n = static_cast<QmlTypeNode*>(node);
for (int i=0; i<qmid.size(); ++i) {
QString key = qmid[i] + "::" + node->name();
insertQmlType(key, n);
}
}
return cn;
}
/*!

View File

@ -80,7 +80,7 @@ struct TargetLoc
};
typedef QMultiMap<QString, TargetRec*> TargetMap;
typedef QMultiMap<QString, DocNode*> DocNodeMultiMap;
typedef QMultiMap<QString, DocumentNode*> DocumentNodeMultiMap;
typedef QMap<QString, QmlTypeNode*> QmlTypeMap;
typedef QMultiMap<QString, const ExampleNode*> ExampleNodeMap;
typedef QVector<TargetLoc*> TargetList;
@ -144,7 +144,7 @@ class Tree
int priority);
void resolveTargets(InnerNode* root);
const Node* findUnambiguousTarget(const QString& target, QString& ref) const;
const DocNode* findDocNodeByTitle(const QString& title) const;
const DocumentNode* findDocumentNodeByTitle(const QString& title) const;
void addPropertyFunction(PropertyNode *property,
const QString &funcName,
@ -167,34 +167,29 @@ class Tree
NodeList allBaseClasses(const ClassNode *classe) const;
QString refForAtom(const Atom* atom);
CNMap* getCollectionMap(Node::Genus genus);
const CNMap& groups() const { return groups_; }
const CNMap& modules() const { return modules_; }
const CNMap& qmlModules() const { return qmlModules_; }
const CNMap& getCollections(Node::Type t) const {
if (t == Node::Group)
return groups_;
if (t == Node::Module)
return modules_;
return qmlModules_;
}
const CNMap& jsModules() const { return jsModules_; }
CollectionNode* getCorrespondingCollection(CollectionNode* cn);
CollectionNode* getCollection(const QString& name, Node::Genus genus);
CollectionNode* findCollection(const QString& name, Node::Genus genus);
GroupNode* getGroup(const QString& name);
ModuleNode* getModule(const QString& name);
QmlModuleNode* getQmlModule(const QString& name);
CollectionNode* findGroup(const QString& name) { return findCollection(name, Node::DOC); }
CollectionNode* findModule(const QString& name) { return findCollection(name, Node::CPP); }
CollectionNode* findQmlModule(const QString& name) { return findCollection(name, Node::QML); }
CollectionNode* findJsModule(const QString& name) { return findCollection(name, Node::JS); }
GroupNode* findGroup(const QString& name);
ModuleNode* findModule(const QString& name);
QmlModuleNode* findQmlModule(const QString& name);
CollectionNode* addGroup(const QString& name) { return findGroup(name); }
CollectionNode* addModule(const QString& name) { return findModule(name); }
CollectionNode* addQmlModule(const QString& name) { return findQmlModule(name); }
CollectionNode* addJsModule(const QString& name) { return findJsModule(name); }
GroupNode* addGroup(const QString& name);
ModuleNode* addModule(const QString& name);
QmlModuleNode* addQmlModule(const QString& name);
GroupNode* addToGroup(const QString& name, Node* node);
ModuleNode* addToModule(const QString& name, Node* node);
QmlModuleNode* addToQmlModule(const QString& name, Node* node);
CollectionNode* addToGroup(const QString& name, Node* node);
CollectionNode* addToModule(const QString& name, Node* node);
CollectionNode* addToQmlModule(const QString& name, Node* node);
CollectionNode* addToJsModule(const QString& name, Node* node);
QmlTypeNode* lookupQmlType(const QString& name) const { return qmlTypeMap_.value(name); }
void insertQmlType(const QString& key, QmlTypeNode* n);
@ -231,12 +226,13 @@ private:
QDocDatabase* qdb_;
NamespaceNode root_;
PropertyMap unresolvedPropertyMap;
DocNodeMultiMap docNodesByTitle_;
DocumentNodeMultiMap docNodesByTitle_;
TargetMap nodesByTargetRef_;
TargetMap nodesByTargetTitle_;
CNMap groups_;
CNMap modules_;
CNMap qmlModules_;
CNMap jsModules_;
QmlTypeMap qmlTypeMap_;
ExampleNodeMap exampleNodeMap_;
TargetListMap* targetListMap_;