summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Smith <martin.smith@qt.io>2018-07-06 09:54:36 +0200
committerMartin Smith <martin.smith@qt.io>2018-10-23 14:15:23 +0000
commitfcdb57ed07d36b0b72f41da974550f505a162077 (patch)
treea456bc1ca3002fb1e90ab689f81247b65782c790 /src
parent2144c9bb23e672ad76170ba605d8155dda0509cd (diff)
qdoc: Reorganize Qdoc's Node class hierarchy
This is a significant refactoring of QDoc's Node class hierarchy, which is meant to make maintenance of QDoc easier, and which will enable further development of QDoc as a library and plugin. Class DocumentNode is renamed to class PageNode, and it inherits the Node base class instead of inheriting class Aggregate. Class Aggregate inherits class PageNode instead of the Node base class. IOW, class DocumentNode and class Aggregate have swapped places in the class hierarchy, and DocumentNode has changed its name to PageNode. This makes the Node hierarchy more logical because: 1. Every entity that causes a documentation page to be written is a PageNode. 2. Only those PageNodes that can have children are Aggregates. Thus the HeaderFile subtype of the former DocumentNode has been promoted to class HeaderNode, which is a subclass of Aggregate. This makes sense because the old HeaderFile DocumentNode caused a documentation page to be generated, and that documentation page was very much like a class reference page. The \headerfile command is not used a lot in the Qt documentation but there are some useful cases, so it is worth making a subclass of Aggregate to handle them. The HeaderNode is now processed very much like the ClassNode and the NamespaceNode. Developers should be advised that isDocumentNode() is now isPageNode(), but isPageNode() can no longer be used to decide if an Aggregate* is a PageNode* (DocumentNode*), because Aggregate is now a subclass of PageNode. So a new convenience function is added: isTextPageNode(), which returns true if your Node* is a PageNode but not an Aggregate. IOW, isTextPageNode() returns true if the Node* is some kind of text page that doesn't represent a C++ or QML declaration. Class ExampleNode is a subclass of PageNode, not Aggregate. IOW, an ExampleNode no longer has children. Instead, the example files and example images that belong to the example are stored as string lists. It seems to work, but there might be problems in help files I haven't found yet. Class CollectionNode is now a subclass of Node instead of LeafNode. Class LeafNode is removed. All former subclasses of LeafNode are now subclasses of Node. This change also removes a lot of DITA bitrot. Work remaining to be done: 1. Remove the remaining DITA bitrot. 2. Consider letting QmlProperty and JsProperty be instances of Property and use the Genus value to distiguish them. 3. Also consider replacing QmlPropertyGroup and JsPropertyGroup with a single PropertyGroup and use the Genus value to distinguish them. This update also rearranges the parameters passed to the clang parser, and it removes some diff conflict lines that got saved by mistake. Change-Id: I918f83030c48d96db4a5588ab53458f221a5374e Reviewed-by: Martin Smith <martin.smith@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qdoc/atom.cpp4
-rw-r--r--src/qdoc/atom.h2
-rw-r--r--src/qdoc/clangcodeparser.cpp23
-rw-r--r--src/qdoc/codemarker.cpp58
-rw-r--r--src/qdoc/codeparser.cpp14
-rw-r--r--src/qdoc/cppcodemarker.cpp17
-rw-r--r--src/qdoc/cppcodeparser.cpp168
-rw-r--r--src/qdoc/cppcodeparser.h3
-rw-r--r--src/qdoc/doc.cpp18
-rw-r--r--src/qdoc/generator.cpp470
-rw-r--r--src/qdoc/generator.h17
-rw-r--r--src/qdoc/helpprojectwriter.cpp182
-rw-r--r--src/qdoc/helpprojectwriter.h2
-rw-r--r--src/qdoc/htmlgenerator.cpp665
-rw-r--r--src/qdoc/htmlgenerator.h9
-rw-r--r--src/qdoc/node.cpp1124
-rw-r--r--src/qdoc/node.h557
-rw-r--r--src/qdoc/qdocdatabase.cpp101
-rw-r--r--src/qdoc/qdocdatabase.h24
-rw-r--r--src/qdoc/qdocindexfiles.cpp621
-rw-r--r--src/qdoc/qdoctagfiles.cpp8
-rw-r--r--src/qdoc/qmlcodemarker.cpp7
-rw-r--r--src/qdoc/qmlvisitor.cpp71
-rw-r--r--src/qdoc/sections.cpp198
-rw-r--r--src/qdoc/tree.cpp126
-rw-r--r--src/qdoc/tree.h24
-rw-r--r--src/qdoc/webxmlgenerator.cpp46
-rw-r--r--src/qdoc/webxmlgenerator.h2
28 files changed, 2316 insertions, 2245 deletions
diff --git a/src/qdoc/atom.cpp b/src/qdoc/atom.cpp
index c9a76e77d..d2ff7acae 100644
--- a/src/qdoc/atom.cpp
+++ b/src/qdoc/atom.cpp
@@ -78,6 +78,8 @@ QT_BEGIN_NAMESPACE
\value DivLeft
\value DivRight
\value EndQmlText
+ \value ExampleFileLink
+ \value ExampleImageLink
\value FormatElse
\value FormatEndif
\value FormatIf
@@ -162,6 +164,8 @@ static const struct {
{ "DivLeft", Atom::DivLeft },
{ "DivRight", Atom::DivRight },
{ "EndQmlText", Atom::EndQmlText },
+ { "ExampleFileLink", Atom::ExampleFileLink},
+ { "ExampleImageLink", Atom::ExampleImageLink},
{ "FootnoteLeft", Atom::FootnoteLeft },
{ "FootnoteRight", Atom::FootnoteRight },
{ "FormatElse", Atom::FormatElse },
diff --git a/src/qdoc/atom.h b/src/qdoc/atom.h
index 2ad4a1353..12330b9ab 100644
--- a/src/qdoc/atom.h
+++ b/src/qdoc/atom.h
@@ -60,6 +60,8 @@ public:
DivLeft,
DivRight,
EndQmlText,
+ ExampleFileLink,
+ ExampleImageLink,
FootnoteLeft,
FootnoteRight,
FormatElse,
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp
index bc76a2068..19b6ea553 100644
--- a/src/qdoc/clangcodeparser.cpp
+++ b/src/qdoc/clangcodeparser.cpp
@@ -253,7 +253,7 @@ static Node *findNodeForCursor(QDocDatabase* qdb, CXCursor cur) {
bool isVariadic = clang_isFunctionTypeVariadic(funcType);
QVarLengthArray<QString, 20> args;
for (Node *candidate : qAsConst(candidates)) {
- if (!candidate->isFunction())
+ if (!candidate->isFunction(Node::CPP))
continue;
auto fn = static_cast<FunctionNode*>(candidate);
const auto &funcParams = fn->parameters();
@@ -332,7 +332,7 @@ static Node *findFunctionNodeForCursor(QDocDatabase* qdb, CXCursor cur) {
bool isVariadic = clang_isFunctionTypeVariadic(funcType);
QVarLengthArray<QString, 20> args;
for (Node *candidate : qAsConst(candidates)) {
- if (!candidate->isFunction())
+ if (!candidate->isFunction(Node::CPP))
continue;
auto fn = static_cast<FunctionNode*>(candidate);
const auto &funcParams = fn->parameters();
@@ -535,7 +535,7 @@ CXChildVisitResult ClangVisitor::visitFnSignature(CXCursor cursor, CXSourceLocat
ignoreSignature = true;
} else {
*fnNode = findFunctionNodeForCursor(qdb_, cursor);
- if (*fnNode && (*fnNode)->isFunction()) {
+ if (*fnNode && (*fnNode)->isFunction(Node::CPP)) {
FunctionNode* fn = static_cast<FunctionNode*>(*fnNode);
readParameterNamesAndAttributes(fn, cursor);
}
@@ -646,7 +646,7 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
CXType funcType = clang_getCursorType(cursor);
- FunctionNode* fn = new FunctionNode(Node::Function, parent_, name, false);
+ FunctionNode* fn = new FunctionNode(parent_, name);
CXSourceRange range = clang_Cursor_getCommentRange(cursor);
if (!clang_Range_isNull(range)) {
@@ -989,7 +989,7 @@ Node* ClangVisitor::nodeForCommentAtLocation(CXSourceLocation loc, CXSourceLocat
}
auto *node = findNodeForCursor(qdb_, *decl_it);
// borrow the parameter name from the definition
- if (node && node->isFunction())
+ if (node && node->isFunction(Node::CPP))
readParameterNamesAndAttributes(static_cast<FunctionNode*>(node), *decl_it);
return node;
}
@@ -1091,6 +1091,8 @@ static const char *defaultArgs_[] = {
"-std=c++14",
#ifndef Q_OS_WIN
"-fPIC",
+#else
+ "-fms-compatibility-version=19",
#endif
"-fno-exceptions", // Workaround for clang bug http://reviews.llvm.org/D17988
"-DQ_QDOC",
@@ -1100,11 +1102,10 @@ static const char *defaultArgs_[] = {
"-DQT_ANNOTATE_FUNCTION(a)=__attribute__((annotate(#a)))",
"-DQT_ANNOTATE_ACCESS_SPECIFIER(a)=__attribute__((annotate(#a)))",
"-Wno-constant-logical-operand",
-#ifdef Q_OS_WIN
- "-fms-compatibility-version=19",
-#endif
- "-I" CLANG_RESOURCE_DIR
+ "-Wno-macro-redefined",
+ "-Wno-nullability-completeness"
};
+static QByteArray clangResourcePath = "-I";
/*!
Load the default arguments and the defines into \a args.
@@ -1114,6 +1115,8 @@ void ClangCodeParser::getDefaultArgs()
{
args_.clear();
args_.insert(args_.begin(), std::begin(defaultArgs_), std::end(defaultArgs_));
+ clangResourcePath += CLANG_RESOURCE_DIR;
+ args_.push_back(clangResourcePath.data());
// Add the defines from the qdocconf file.
for (const auto &p : qAsConst(defines_))
args_.push_back(p.constData());
@@ -1139,7 +1142,7 @@ static QVector<QByteArray> includePathsFromHeaders(const QHash<QString, QString>
*/
void ClangCodeParser::getMoreArgs()
{
- if (includePaths_.isEmpty() || includePaths_.at(0) != QByteArray("-I")) {
+ if (includePaths_.isEmpty()) {
/*
The include paths provided are inadequate. Make a list
of reasonable places to look for include files and use
diff --git a/src/qdoc/codemarker.cpp b/src/qdoc/codemarker.cpp
index d807a9e37..2b1c1a316 100644
--- a/src/qdoc/codemarker.cpp
+++ b/src/qdoc/codemarker.cpp
@@ -262,7 +262,7 @@ QString CodeMarker::taggedNode(const Node* node)
QString tag;
QString name = node->name();
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Namespace:
tag = QLatin1String("@namespace");
break;
@@ -294,14 +294,9 @@ QString CodeMarker::taggedNode(const Node* node)
name = name.mid(4);
tag = QLatin1String("@property");
break;
- case Node::Document:
+ case Node::Page:
tag = QLatin1String("@property");
break;
- case Node::QmlMethod:
- case Node::QmlSignal:
- case Node::QmlSignalHandler:
- tag = QLatin1String("@function");
- break;
default:
tag = QLatin1String("@unknown");
break;
@@ -313,22 +308,29 @@ QString CodeMarker::taggedNode(const Node* node)
QString CodeMarker::taggedQmlNode(const Node* node)
{
QString tag;
- switch (node->type()) {
- case Node::QmlProperty:
+ if (node->isFunction()) {
+ const FunctionNode* fn = static_cast<const FunctionNode*>(node);
+ switch (fn->metaness()) {
+ case FunctionNode::JsSignal:
+ case FunctionNode::QmlSignal:
+ tag = QLatin1String("@signal");
+ break;
+ case FunctionNode::JsSignalHandler:
+ case FunctionNode::QmlSignalHandler:
+ tag = QLatin1String("@signalhandler");
+ break;
+ case FunctionNode::JsMethod:
+ case FunctionNode::QmlMethod:
+ tag = QLatin1String("@method");
+ break;
+ default:
+ tag = QLatin1String("@unknown");
+ break;
+ }
+ } else if (node->isQmlProperty() || node->isJsProperty()) {
tag = QLatin1String("@property");
- break;
- case Node::QmlSignal:
- tag = QLatin1String("@signal");
- break;
- case Node::QmlSignalHandler:
- tag = QLatin1String("@signalhandler");
- break;
- case Node::QmlMethod:
- tag = QLatin1String("@method");
- break;
- default:
+ } else {
tag = QLatin1String("@unknown");
- break;
}
return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name())
+ QLatin1String("</") + tag + QLatin1Char('>');
@@ -348,7 +350,7 @@ static QString encode(const QString &string)
QStringList CodeMarker::macRefsForNode(Node *node)
{
QString result = QLatin1String("cpp/");
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Class:
{
const ClassNode *classe = static_cast<const ClassNode *>(node);
@@ -361,8 +363,7 @@ QStringList CodeMarker::macRefsForNode(Node *node)
case Node::Enum:
{
QStringList stringList;
- stringList << encode(result + QLatin1String("tag/") +
- macName(node));
+ stringList << encode(result + QLatin1String("tag/") + macName(node));
foreach (const QString &enumName, node->doc().enumItemNames()) {
// ### Write a plainEnumValue() and use it here
stringList << encode(result + QLatin1String("econst/") +
@@ -413,9 +414,6 @@ QStringList CodeMarker::macRefsForNode(Node *node)
}
return stringList;
}
- case Node::Namespace:
- case Node::Document:
- case Node::QmlType:
default:
return QStringList();
}
@@ -431,12 +429,10 @@ QString CodeMarker::macName(const Node *node, const QString &name)
node = node->parent();
}
- if (node->name().isEmpty()) {
+ if (node->name().isEmpty())
return QLatin1Char('/') + protect(myName);
- }
- else {
+ else
return node->plainFullName() + QLatin1Char('/') + protect(myName);
- }
}
QT_END_NAMESPACE
diff --git a/src/qdoc/codeparser.cpp b/src/qdoc/codeparser.cpp
index f1bb52a19..6a60e1e48 100644
--- a/src/qdoc/codeparser.cpp
+++ b/src/qdoc/codeparser.cpp
@@ -259,11 +259,11 @@ void CodeParser::processCommonMetaCommand(const Location& location,
if (!showInternal_) {
node->setAccess(Node::Private);
node->setStatus(Node::Internal);
- if (node->type() == Node::QmlPropertyGroup) {
+ if (node->nodeType() == Node::QmlPropertyGroup) {
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
+ if ((*p)->nodeType() == Node::QmlProperty) {
(*p)->setAccess(Node::Private);
(*p)->setStatus(Node::Internal);
}
@@ -288,15 +288,13 @@ void CodeParser::processCommonMetaCommand(const Location& location,
node->setThreadSafeness(Node::ThreadSafe);
}
else if (command == COMMAND_TITLE) {
- node->setTitle(arg.first);
- if (!node->isDocumentNode() && !node->isCollectionNode())
- location.warning(tr("Ignored '\\%1'").arg(COMMAND_SUBTITLE));
+ if (!node->setTitle(arg.first))
+ location.warning(tr("Ignored '\\%1'").arg(COMMAND_TITLE));
else if (node->isExample())
qdb_->addExampleNode(static_cast<ExampleNode*>(node));
}
else if (command == COMMAND_SUBTITLE) {
- node->setSubTitle(arg.first);
- if (!node->isDocumentNode() && !node->isCollectionNode())
+ if (!node->setSubtitle(arg.first))
location.warning(tr("Ignored '\\%1'").arg(COMMAND_SUBTITLE));
}
else if (command == COMMAND_QTVARIABLE) {
@@ -414,7 +412,7 @@ void CodeParser::checkModuleInclusion(Node* n)
{
if (n->physicalModuleName().isEmpty()) {
n->setPhysicalModuleName(Generator::defaultModuleName());
- switch (n->type()) {
+ switch (n->nodeType()) {
case Node::Class:
if (n->access() != Node::Private && !n->doc().isEmpty()) {
n->doc().location().warning(tr("Class %1 has no \\inmodule command; "
diff --git a/src/qdoc/cppcodemarker.cpp b/src/qdoc/cppcodemarker.cpp
index 8d657e252..38dc3e66c 100644
--- a/src/qdoc/cppcodemarker.cpp
+++ b/src/qdoc/cppcodemarker.cpp
@@ -129,10 +129,10 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
name = "<@name>" + name + "</@name>";
if ((style == Section::Details) && !node->parent()->name().isEmpty() &&
- (node->type() != Node::Property) && !node->isQmlNode() && !node->isJsNode())
+ !node->isProperty() && !node->isQmlNode() && !node->isJsNode())
name.prepend(taggedNode(node->parent()) + "::");
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Namespace:
synopsis = "namespace " + name;
break;
@@ -140,9 +140,6 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
synopsis = "class " + name;
break;
case Node::Function:
- case Node::QmlSignal:
- case Node::QmlSignalHandler:
- case Node::QmlMethod:
func = (const FunctionNode *) node;
if (style != Section::AllMembers && !func->returnType().isEmpty())
@@ -336,10 +333,7 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
if (node->isQmlProperty() || node->isJsProperty()) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
synopsis = name + " : " + typified(pn->dataType());
- }
- else if ((node->type() == Node::QmlMethod) ||
- (node->type() == Node::QmlSignal) ||
- (node->type() == Node::QmlSignalHandler)) {
+ } else if (node->isFunction(Node::QML) || node->isFunction(Node::JS)) {
const FunctionNode* func = static_cast<const FunctionNode*>(node);
if (!func->returnType().isEmpty())
synopsis = typified(func->returnType(), true) + name;
@@ -360,8 +354,7 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
}
}
synopsis += QLatin1Char(')');
- }
- else
+ } else
synopsis = name;
QString extra;
@@ -412,7 +405,7 @@ QString CppCodeMarker::markedUpFullName(const Node *node, const Node *relative)
QString CppCodeMarker::markedUpEnumValue(const QString &enumValue, const Node *relative)
{
- if (relative->type() != Node::Enum)
+ if (relative->nodeType() != Node::Enum)
return enumValue;
const Node *node = relative->parent();
diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp
index b700823e5..5863aa541 100644
--- a/src/qdoc/cppcodeparser.cpp
+++ b/src/qdoc/cppcodeparser.cpp
@@ -68,7 +68,6 @@ CppCodeParser::CppCodeParser()
<< COMMAND_ENUM
<< COMMAND_EXAMPLE
<< COMMAND_EXTERNALPAGE
- << COMMAND_FILE
<< COMMAND_FN
<< COMMAND_GROUP
<< COMMAND_HEADERFILE
@@ -240,9 +239,14 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
*/
Node::NodeType type = nodeTypeMap[command];
QStringList words = arg.first.split(QLatin1Char(' '));
- QStringList path = words[0].split("::");
+ QStringList path;
+ int idx = 0;
Node *node = 0;
+ if (type == Node::Variable && words.size() > 1)
+ idx = words.size() - 1;
+ path = words[idx].split("::");
+
node = qdb_->findNodeInOpenNamespace(path, type);
if (node == 0)
node = qdb_->findNodeByNameAndType(path, type);
@@ -277,33 +281,19 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
if (Config::generateExamples) {
ExampleNode* en = new ExampleNode(qdb_->primaryTreeRoot(), arg.first);
en->setLocation(doc.startLocation());
- createExampleFileNodes(en);
+ setExampleFileLists(en);
return en;
}
}
else if (command == COMMAND_EXTERNALPAGE) {
- DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
- arg.first,
- Node::ExternalPage,
- Node::ArticlePage);
- dn->setLocation(doc.startLocation());
- return dn;
- }
- else if (command == COMMAND_FILE) {
- DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
- arg.first,
- Node::File,
- Node::NoPageType);
- dn->setLocation(doc.startLocation());
- return dn;
+ ExternalPageNode* epn = new ExternalPageNode(qdb_->primaryTreeRoot(), arg.first);
+ epn->setLocation(doc.startLocation());
+ return epn;
}
else if (command == COMMAND_HEADERFILE) {
- DocumentNode* dn = new DocumentNode(qdb_->primaryTreeRoot(),
- arg.first,
- Node::HeaderFile,
- Node::ApiPage);
- dn->setLocation(doc.startLocation());
- return dn;
+ HeaderNode* hn = new HeaderNode(qdb_->primaryTreeRoot(), arg.first);
+ hn->setLocation(doc.startLocation());
+ return hn;
}
else if (command == COMMAND_GROUP) {
CollectionNode* cn = qdb_->addGroup(arg.first);
@@ -350,35 +340,26 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
ptype = Node::TutorialPage;
else if (t == "faq")
ptype = Node::FAQPage;
- else if (t == "ditamap")
- ptype = Node::DitaMapPage;
else if (t == "attribution")
ptype = Node::AttributionPage;
}
- DocumentNode* dn = 0;
- if (ptype == Node::DitaMapPage)
- dn = new DitaMapNode(qdb_->primaryTreeRoot(), args[0]);
- else
- dn = new DocumentNode(qdb_->primaryTreeRoot(), args[0], Node::Page, ptype);
- dn->setLocation(doc.startLocation());
- return dn;
- }
- else if (command == COMMAND_DITAMAP) {
- DocumentNode* dn = new DitaMapNode(qdb_->primaryTreeRoot(), arg.first);
- dn->setLocation(doc.startLocation());
- return dn;
- }
- else if ((command == COMMAND_QMLTYPE) || (command == COMMAND_JSTYPE)) {
+ PageNode* pn = new PageNode(qdb_->primaryTreeRoot(), args[0], ptype);
+ pn->setLocation(doc.startLocation());
+ return pn;
+ } else if (command == COMMAND_QMLTYPE) {
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) || (command == COMMAND_JSBASICTYPE)) {
+ } else if (command == COMMAND_JSTYPE) {
+ QmlTypeNode* qcn = new QmlTypeNode(qdb_->primaryTreeRoot(), arg.first, Node::JsType);
+ qcn->setLocation(doc.startLocation());
+ return qcn;
+ } else if (command == COMMAND_QMLBASICTYPE) {
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_JSBASICTYPE) {
+ QmlBasicTypeNode* n = new QmlBasicTypeNode(qdb_->primaryTreeRoot(), arg.first, Node::JsBasicType);
n->setLocation(doc.startLocation());
return n;
}
@@ -554,8 +535,7 @@ void CppCodeParser::processQmlProperties(const Doc& doc,
arg = topics.at(i).args;
if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY) ||
(topic == COMMAND_JSPROPERTY) || (topic == COMMAND_JSATTACHEDPROPERTY)) {
- bool attached = ((topic == COMMAND_QMLATTACHEDPROPERTY) ||
- (topic == COMMAND_JSATTACHEDPROPERTY));
+ bool attached = topic.contains(QLatin1String("attached"));
if (splitQmlPropertyArg(arg, type, module, qmlTypeName, property, doc.location())) {
Aggregate* aggregate = qdb_->findQmlType(module, qmlTypeName);
if (!aggregate)
@@ -625,7 +605,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
}
else if (command == COMMAND_REIMP) {
if (node != 0 && node->parent() && !node->parent()->isInternal()) {
- if (node->type() == Node::Function) {
+ if (node->nodeType() == Node::Function) {
FunctionNode *func = (FunctionNode *) node;
if (func->reimplementedFrom().isEmpty() && isWorthWarningAbout(doc)) {
doc.location().warning(tr("Cannot find base function for '\\%1' in %2()")
@@ -653,7 +633,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
}
else if (node->parent() != n)
- node->setRelates(static_cast<Aggregate*>(n));
+ node->setRelates(static_cast<PageNode*>(n));
else
doc.location().warning(tr("Invalid use of '\\%1' (already a member of '%2')")
.arg(COMMAND_RELATES, arg));
@@ -693,15 +673,15 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
doc.location().warning(tr("\\instantiates is only allowed in \\qmltype"));
}
else if (command == COMMAND_QMLDEFAULT) {
- if (node->type() == Node::QmlProperty) {
+ if (node->nodeType() == Node::QmlProperty) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setDefault();
}
- else if (node->type() == Node::QmlPropertyGroup) {
+ else if (node->nodeType() == Node::QmlPropertyGroup) {
QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
+ if ((*p)->nodeType() == Node::QmlProperty) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(*p);
qpn->setDefault();
}
@@ -710,15 +690,15 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
}
}
else if (command == COMMAND_QMLREADONLY) {
- if (node->type() == Node::QmlProperty) {
+ if (node->nodeType() == Node::QmlProperty) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setReadOnly(1);
}
- else if (node->type() == Node::QmlPropertyGroup) {
+ else if (node->nodeType() == Node::QmlPropertyGroup) {
QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
+ if ((*p)->nodeType() == Node::QmlProperty) {
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(*p);
qpn->setReadOnly(1);
}
@@ -1185,9 +1165,7 @@ bool CppCodeParser::parseParameters(const QString& parameters,
/*!
Parse QML/JS signal/method topic commands.
*/
-Node* CppCodeParser::parseOtherFuncArg(const QString& topic,
- const Location& location,
- const QString& funcArg)
+Node* CppCodeParser::parseOtherFuncArg(const QString& topic, const Location& location, const QString& funcArg)
{
QString funcName;
QString returnType;
@@ -1220,24 +1198,11 @@ Node* CppCodeParser::parseOtherFuncArg(const QString& topic,
funcName = colonSplit.last();
Aggregate *aggregate = qdb_->findQmlType(moduleName, elementName);
- bool attached = false;
if (!aggregate)
aggregate = qdb_->findQmlBasicType(moduleName, elementName);
if (!aggregate)
return 0;
- Node::NodeType nodeType = Node::QmlMethod;
- if (topic == COMMAND_QMLSIGNAL || topic == COMMAND_JSSIGNAL) {
- nodeType = Node::QmlSignal;
- } else if (topic == COMMAND_QMLATTACHEDSIGNAL || topic == COMMAND_JSATTACHEDSIGNAL) {
- nodeType = Node::QmlSignal;
- attached = true;
- } else if (topic == COMMAND_QMLATTACHEDMETHOD || topic == COMMAND_JSATTACHEDMETHOD) {
- attached = true;
- } else {
- Q_ASSERT(topic == COMMAND_QMLMETHOD || topic == COMMAND_JSMETHOD);
- }
-
QString params;
QStringList leftParenSplit = funcArg.split('(');
if (leftParenSplit.size() > 1) {
@@ -1245,12 +1210,15 @@ Node* CppCodeParser::parseOtherFuncArg(const QString& topic,
if (rightParenSplit.size() > 0)
params = rightParenSplit[0];
}
- FunctionNode *funcNode = static_cast<FunctionNode*>(new FunctionNode(nodeType, aggregate, funcName, attached));
- funcNode->setAccess(Node::Public);
- funcNode->setLocation(location);
- funcNode->setReturnType(returnType);
- funcNode->setParameters(params);
- return funcNode;
+
+ FunctionNode::Metaness metaness = FunctionNode::getMetanessFromTopic(topic);
+ bool attached = topic.contains(QLatin1String("attached"));
+ FunctionNode *fn = new FunctionNode(metaness, aggregate, funcName, attached);
+ fn->setAccess(Node::Public);
+ fn->setLocation(location);
+ fn->setReturnType(returnType);
+ fn->setParameters(params);
+ return fn;
}
/*!
@@ -1287,13 +1255,12 @@ Node* CppCodeParser::parseMacroArg(const Location& location, const QString& macr
returnType += QChar(' ') + macroName.left(i);
macroName = macroName.mid(i);
}
- newMacroNode = static_cast<FunctionNode*>(new FunctionNode(qdb_->primaryTreeRoot(), macroName));
+ FunctionNode::Metaness metaness = FunctionNode::MacroWithParams;
+ if (params.isEmpty())
+ metaness = FunctionNode::MacroWithoutParams;
+ newMacroNode = new FunctionNode(metaness, qdb_->primaryTreeRoot(), macroName);
newMacroNode->setAccess(Node::Public);
newMacroNode->setLocation(location);
- if (params.isEmpty())
- newMacroNode->setMetaness(FunctionNode::MacroWithoutParams);
- else
- newMacroNode->setMetaness(FunctionNode::MacroWithParams);
newMacroNode->setReturnType(returnType);
newMacroNode->setParameters(params);
if (oldMacroNode && newMacroNode->compare(oldMacroNode)) {
@@ -1304,11 +1271,11 @@ Node* CppCodeParser::parseMacroArg(const Location& location, const QString& macr
return newMacroNode;
}
-void CppCodeParser::createExampleFileNodes(DocumentNode *dn)
+void CppCodeParser::setExampleFileLists(PageNode *pn)
{
- QString examplePath = dn->name();
+ QString examplePath = pn->name();
QString proFileName = examplePath + QLatin1Char('/') + examplePath.split(QLatin1Char('/')).last() + ".pro";
- QString fullPath = Config::findFile(dn->doc().location(),
+ QString fullPath = Config::findFile(pn->doc().location(),
exampleFiles,
exampleDirs,
proFileName);
@@ -1316,13 +1283,13 @@ void CppCodeParser::createExampleFileNodes(DocumentNode *dn)
if (fullPath.isEmpty()) {
QString tmp = proFileName;
proFileName = examplePath + QLatin1Char('/') + "qbuild.pro";
- fullPath = Config::findFile(dn->doc().location(),
+ fullPath = Config::findFile(pn->doc().location(),
exampleFiles,
exampleDirs,
proFileName);
if (fullPath.isEmpty()) {
proFileName = examplePath + QLatin1Char('/') + examplePath.split(QLatin1Char('/')).last() + ".qmlproject";
- fullPath = Config::findFile(dn->doc().location(),
+ fullPath = Config::findFile(pn->doc().location(),
exampleFiles,
exampleDirs,
proFileName);
@@ -1330,8 +1297,8 @@ void CppCodeParser::createExampleFileNodes(DocumentNode *dn)
QString details = QLatin1String("Example directories: ") + exampleDirs.join(QLatin1Char(' '));
if (!exampleFiles.isEmpty())
details += QLatin1String(", example files: ") + exampleFiles.join(QLatin1Char(' '));
- dn->location().warning(tr("Cannot find file '%1' or '%2'").arg(tmp).arg(proFileName), details);
- dn->location().warning(tr(" EXAMPLE PATH DOES NOT EXIST: %1").arg(examplePath), details);
+ pn->location().warning(tr("Cannot find file '%1' or '%2'").arg(tmp).arg(proFileName), details);
+ pn->location().warning(tr(" EXAMPLE PATH DOES NOT EXIST: %1").arg(examplePath), details);
return;
}
}
@@ -1369,20 +1336,15 @@ void CppCodeParser::createExampleFileNodes(DocumentNode *dn)
exampleFiles += Config::getFilesHere(fullPath, "*.qrc *.pro *.qmlproject qmldir");
}
- foreach (const QString &exampleFile, exampleFiles) {
- DocumentNode *fileNode = new DocumentNode(dn,
- exampleFile.mid(sizeOfBoringPartOfName),
- Node::File,
- Node::NoPageType);
- if (fileNode->name().endsWith(".qml"))
- fileNode->setGenus(Node::QML);
- }
- foreach (const QString &imageFile, imageFiles) {
- new DocumentNode(dn,
- imageFile.mid(sizeOfBoringPartOfName),
- Node::Image,
- Node::NoPageType);
- }
+ int i = 0;
+ foreach (const QString &exampleFile, exampleFiles)
+ exampleFiles[i++] = exampleFile.mid(sizeOfBoringPartOfName);
+ i = 0;
+ foreach (const QString &imageFile, imageFiles)
+ imageFiles[i++] = imageFile.mid(sizeOfBoringPartOfName);
+ ExampleNode* en = static_cast<ExampleNode*>(pn);
+ en->setFiles(exampleFiles);
+ en->setImages(imageFiles);
}
/*!
diff --git a/src/qdoc/cppcodeparser.h b/src/qdoc/cppcodeparser.h
index 7ecd666cb..6a1b1dd44 100644
--- a/src/qdoc/cppcodeparser.h
+++ b/src/qdoc/cppcodeparser.h
@@ -119,7 +119,7 @@ protected:
bool matchDataType(CodeChunk *type, QString *var = 0, bool qProp = false);
bool matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal);
bool matchUsingDecl(Aggregate* parent);
- void createExampleFileNodes(DocumentNode *dn);
+ void setExampleFileLists(PageNode *pn);
protected:
QMap<QString, Node::NodeType> nodeTypeMap;
@@ -150,7 +150,6 @@ protected:
#define COMMAND_ENUM Doc::alias("enum")
#define COMMAND_EXAMPLE Doc::alias("example")
#define COMMAND_EXTERNALPAGE Doc::alias("externalpage")
-#define COMMAND_FILE Doc::alias("file")
#define COMMAND_FN Doc::alias("fn")
#define COMMAND_GROUP Doc::alias("group")
#define COMMAND_HEADERFILE Doc::alias("headerfile")
diff --git a/src/qdoc/doc.cpp b/src/qdoc/doc.cpp
index 9cbcaab9e..8fe346fbf 100644
--- a/src/qdoc/doc.cpp
+++ b/src/qdoc/doc.cpp
@@ -1435,7 +1435,6 @@ void DocParser::parse(const QString& source,
}
}
if ((numUppercase >= 1 && numLowercase >= 2) || numStrangeSymbols > 0) {
- qDebug() << "APPENDING: " << cmdStr;
appendWord(cmdStr);
} else {
location().warning(tr("Unknown command '\\%1'").arg(cmdStr),
@@ -1900,6 +1899,7 @@ void DocParser::parseAlso()
while (pos < len && input_[pos] != '\n') {
QString target;
QString str;
+ bool skipMe = false;
if (input_[pos] == '{') {
target = getArgument();
@@ -1918,14 +1918,18 @@ void DocParser::parseAlso()
else {
target = getArgument();
str = cleanLink(target);
+ if (target == QLatin1String("and") || target == QLatin1String("."))
+ skipMe = true;
}
- Text also;
- also << Atom(Atom::Link, target)
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << str
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- priv->addAlso(also);
+ if (!skipMe) {
+ Text also;
+ also << Atom(Atom::Link, target)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << str
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ priv->addAlso(also);
+ }
skipSpacesOnLine();
if (pos < len && input_[pos] == ',') {
diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp
index 58d882671..d12ec60dd 100644
--- a/src/qdoc/generator.cpp
+++ b/src/qdoc/generator.cpp
@@ -273,9 +273,12 @@ void Generator::writeOutFileNames()
/*!
Creates the file named \a fileName in the output directory.
Attaches a QTextStream to the created file, which is written
- to all over the place using out().
+ to all over the place using out(). This function does not
+ store the \a fileName in the \a node as the output file name.
+
+ \sa beginSubPage()
*/
-void Generator::beginSubPage(const Node* node, const QString& fileName)
+void Generator::beginFilePage(const Node* node, const QString& fileName)
{
QString path = outputDir() + QLatin1Char('/');
if (Generator::useOutputSubdirs() && !node->outputSubdirectory().isEmpty() &&
@@ -297,6 +300,22 @@ void Generator::beginSubPage(const Node* node, const QString& fileName)
out->setCodec(outputCodec);
#endif
outStreamStack.push(out);
+}
+
+ /*!
+ Creates the file named \a fileName in the output directory.
+ Attaches a QTextStream to the created file, which is written
+ to all over the place using out(). This function calls another
+ function, \c beginFilePage(), which is really just most of what
+ this function used to contain. We needed a different version
+ that doesn't store the \a fileName in the \a node as the output
+ file name.
+
+ \sa beginFilePage()
+ */
+void Generator::beginSubPage(const Node* node, const QString& fileName)
+{
+ beginFilePage(node, fileName);
const_cast<Node*>(node)->setOutputFileName(fileName);
}
@@ -312,26 +331,57 @@ void Generator::endSubPage()
delete outStreamStack.pop();
}
+/*
+ the code below is effectively equivalent to:
+ input.replace(QRegExp("[^A-Za-z0-9]+"), " ");
+ input = input.trimmed();
+ input.replace(QLatin1Char(' '), QLatin1Char('-'));
+ input = input.toLower();
+ as this function accounted for ~8% of total running time
+ we optimize a bit...
+*/
+static void transmogrify(QString &input, QString &output)
+{
+ // +5 prevents realloc in fileName() below
+ output.reserve(input.size() + 5);
+ bool begun = false;
+ for (int i = 0; i != input.size(); ++i) {
+ QChar c = input.at(i);
+ uint u = c.unicode();
+ if (u >= 'A' && u <= 'Z')
+ u += 'a' - 'A';
+ if ((u >= 'a' && u <= 'z') || (u >= '0' && u <= '9')) {
+ output += QLatin1Char(u);
+ begun = true;
+ }
+ else if (begun) {
+ output += QLatin1Char('-');
+ begun = false;
+ }
+ }
+ while (output.endsWith(QLatin1Char('-')))
+ output.chop(1);
+}
+
QString Generator::fileBase(const Node *node) const
{
if (node->relates())
node = node->relates();
- else if (!node->isAggregate() && !node->isCollectionNode())
+ else if (!node->isPageNode() && !node->isCollectionNode())
node = node->parent();
- if (node->type() == Node::QmlPropertyGroup) {
+ if (node->nodeType() == Node::QmlPropertyGroup)
node = node->parent();
- }
if (node->hasFileNameBase())
return node->fileNameBase();
QString base;
- if (node->isDocumentNode()) {
+ if (node->isTextPageNode()) {
base = node->name();
- if (base.endsWith(".html") && !node->isExampleFile())
+ if (base.endsWith(".html"))
base.truncate(base.length() - 5);
- if (node->isExample() || node->isExampleFile()) {
+ if (node->isExample()) {
QString modPrefix(node->physicalModuleName());
if (modPrefix.isEmpty()) {
modPrefix = project_;
@@ -379,7 +429,7 @@ QString Generator::fileBase(const Node *node) const
forever {
const Node *pp = p->parent();
base.prepend(p->name());
- if (!pp || pp->name().isEmpty() || pp->isDocumentNode())
+ if (!pp || pp->name().isEmpty() || pp->isTextPageNode())
break;
base.prepend(QLatin1Char('-'));
p = pp;
@@ -393,40 +443,33 @@ QString Generator::fileBase(const Node *node) const
}
}
- // the code below is effectively equivalent to:
- // base.replace(QRegExp("[^A-Za-z0-9]+"), " ");
- // base = base.trimmed();
- // base.replace(QLatin1Char(' '), QLatin1Char('-'));
- // base = base.toLower();
- // as this function accounted for ~8% of total running time
- // we optimize a bit...
-
QString res;
- // +5 prevents realloc in fileName() below
- res.reserve(base.size() + 5);
- bool begun = false;
- for (int i = 0; i != base.size(); ++i) {
- QChar c = base.at(i);
- uint u = c.unicode();
- if (u >= 'A' && u <= 'Z')
- u += 'a' - 'A';
- if ((u >= 'a' && u <= 'z') || (u >= '0' && u <= '9')) {
- res += QLatin1Char(u);
- begun = true;
- }
- else if (begun) {
- res += QLatin1Char('-');
- begun = false;
- }
- }
- while (res.endsWith(QLatin1Char('-')))
- res.chop(1);
+ transmogrify(base, res);
Node* n = const_cast<Node*>(node);
n->setFileNameBase(res);
return res;
}
/*!
+ Constructs an href link from an example file name, which
+ is a path to the example file.
+ */
+QString Generator::linkForExampleFile(const QString &path, const Node *parent)
+{
+ QString link = path;
+ QString modPrefix(parent->physicalModuleName());
+ if (modPrefix.isEmpty())
+ modPrefix = project_;
+ link.prepend(modPrefix.toLower() + QLatin1Char('-'));
+
+ QString res;
+ transmogrify(link, res);
+ res.append(QLatin1Char('.'));
+ res.append(fileExtension());
+ return res;
+}
+
+/*!
If the \a node has a URL, return the URL as the file name.
Otherwise, construct the file name from the fileBase() and
either the provided \a extension or fileExtension(), and
@@ -529,10 +572,10 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
fdl.append(QLatin1Char('/'));
}
if (node->isNamespace()) {
-
- // The root namespace has no name - check for this before creating
- // an attribute containing the location of any documentation.
-
+ /*
+ The root namespace has no name - check for this before creating
+ an attribute containing the location of any documentation.
+ */
if (!fileBase(node).isEmpty())
parentName = fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
else
@@ -553,7 +596,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
QLatin1Char('.') + currentGenerator()->fileExtension();
}
}
- else if (node->isDocumentNode() || node->isCollectionNode()) {
+ else if (node->isTextPageNode() || node->isCollectionNode()) {
parentName = fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
}
else if (fileBase(node).isEmpty())
@@ -574,7 +617,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
}
}
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Class:
case Node::Namespace:
parentName = fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
@@ -582,18 +625,31 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
case Node::Function:
{
const FunctionNode *fn = static_cast<const FunctionNode *>(node);
-
- if (fn->isDtor())
- anchorRef = "#dtor." + fn->name().mid(1);
-
- else if (fn->hasOneAssociatedProperty() && fn->doc().isEmpty())
- return fullDocumentLocation(fn->firstAssociatedProperty());
-
- else if (fn->overloadNumber() > 0)
- anchorRef = QLatin1Char('#') + cleanRef(fn->name())
+ switch (fn->metaness()) {
+ case FunctionNode::JsSignal:
+ case FunctionNode::QmlSignal:
+ anchorRef = QLatin1Char('#') + node->name() + "-signal";
+ break;
+ case FunctionNode::JsSignalHandler:
+ case FunctionNode::QmlSignalHandler:
+ anchorRef = QLatin1Char('#') + node->name() + "-signal-handler";
+ break;
+ case FunctionNode::JsMethod:
+ case FunctionNode::QmlMethod:
+ anchorRef = QLatin1Char('#') + node->name() + "-method";
+ break;
+ default:
+ if (fn->isDtor())
+ anchorRef = "#dtor." + fn->name().mid(1);
+ else if (fn->hasOneAssociatedProperty() && fn->doc().isEmpty())
+ return fullDocumentLocation(fn->firstAssociatedProperty());
+ else if (fn->overloadNumber() > 0)
+ anchorRef = QLatin1Char('#') + cleanRef(fn->name())
+ QLatin1Char('-') + QString::number(fn->overloadNumber());
- else
- anchorRef = QLatin1Char('#') + cleanRef(fn->name());
+ else
+ anchorRef = QLatin1Char('#') + cleanRef(fn->name());
+ break;
+ }
break;
}
/*
@@ -616,28 +672,22 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
case Node::Property:
anchorRef = QLatin1Char('#') + node->name() + "-prop";
break;
+ case Node::JsProperty:
case Node::QmlProperty:
if (node->isAttached())
anchorRef = QLatin1Char('#') + node->name() + "-attached-prop";
else
anchorRef = QLatin1Char('#') + node->name() + "-prop";
break;
- case Node::QmlSignal:
- anchorRef = QLatin1Char('#') + node->name() + "-signal";
- break;
- case Node::QmlSignalHandler:
- anchorRef = QLatin1Char('#') + node->name() + "-signal-handler";
- break;
- case Node::QmlMethod:
- anchorRef = QLatin1Char('#') + node->name() + "-method";
- break;
case Node::Variable:
anchorRef = QLatin1Char('#') + node->name() + "-var";
break;
+ case Node::JsType:
case Node::QmlType:
- case Node::Document:
+ case Node::Page:
case Node::Group:
case Node::Module:
+ case Node::JsModule:
case Node::QmlModule:
{
parentName = fileBase(node);
@@ -751,20 +801,12 @@ const Atom *Generator::generateAtomList(const Atom *atom,
*/
void Generator::generateBody(const Node *node, CodeMarker *marker)
{
- bool quiet = false;
-
- if (node->type() == Node::Document) {
- const DocumentNode *dn = static_cast<const DocumentNode *>(node);
- if ((dn->docSubtype() == Node::File) || (dn->docSubtype() == Node::Image)) {
- quiet = true;
- }
- }
if (!node->hasDoc() && !node->hasSharedDoc()) {
/*
Test for special function, like a destructor or copy constructor,
that has no documentation.
*/
- if (node->type() == Node::Function) {
+ if (node->nodeType() == Node::Function) {
const FunctionNode* func = static_cast<const FunctionNode*>(node);
if (func->isDtor()) {
Text text;
@@ -812,12 +854,12 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
generateText(text, node, marker);
out() << "</p>";
}
- else if (!node->isWrapper() && !quiet && !node->isReimplemented()) {
+ else if (!node->isWrapper() && !node->isReimplemented()) {
if (!func->isIgnored()) // undocumented functions added by Q_OBJECT
node->location().warning(tr("No documentation for '%1'").arg(node->plainSignature()));
}
}
- else if (!node->isWrapper() && !quiet && !node->isReimplemented()) {
+ else if (!node->isWrapper() && !node->isReimplemented()) {
/*
Don't require documentation of things defined in Q_GADGET
*/
@@ -826,7 +868,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
}
else if (!node->isSharingComment()) {
- if (node->type() == Node::Function) {
+ if (node->nodeType() == Node::Function) {
const FunctionNode *func = static_cast<const FunctionNode *>(node);
if (!func->reimplementedFrom().isEmpty())
generateReimplementedFrom(func, marker);
@@ -837,7 +879,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
return;
}
- if (node->type() == Node::Enum) {
+ if (node->nodeType() == Node::Enum) {
const EnumNode *enume = (const EnumNode *) node;
QSet<QString> definedItems;
@@ -861,8 +903,6 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
node->doc().location().warning(tr("No such enum item '%1' in %2")
.arg(*a).arg(node->plainFullName()), details);
- if (*a == "Void")
- qDebug() << "VOID:" << node->name() << definedItems;
}
else if (!documentedItems.contains(*a)) {
node->doc().location().warning(tr("Undocumented enum item '%1' in %2")
@@ -872,7 +912,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
}
}
- else if (node->type() == Node::Function) {
+ else if (node->nodeType() == Node::Function) {
const FunctionNode *func = static_cast<const FunctionNode *>(node);
QSet<QString> definedParams;
QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
@@ -933,19 +973,11 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
}
- if (node->isDocumentNode()) {
- const DocumentNode *dn = static_cast<const DocumentNode *>(node);
- if (dn->isExample() && !dn->noAutoList()) {
- generateExampleFiles(dn, marker);
- }
- else if (dn->docSubtype() == Node::File) {
- Text text;
- Quoter quoter;
- Doc::quoteFromFile(dn->doc().location(), quoter, dn->name());
- QString code = quoter.quoteTo(dn->location(), QString(), QString());
- CodeMarker *codeMarker = CodeMarker::markerForFileName(dn->name());
- text << Atom(codeMarker->atomType(), code);
- generateText(text, dn, codeMarker);
+ if (node->isExample()) {
+ const ExampleNode* en = static_cast<const ExampleNode*>(node);
+ if (!en->noAutoList()) {
+ generateFileList(en, marker, false);
+ generateFileList(en, marker, true);
}
}
}
@@ -954,22 +986,94 @@ void Generator::generateCppReferencePage(Node* /* node */, CodeMarker* /* marker
{
}
-void Generator::generateExampleFiles(const DocumentNode *dn, CodeMarker *marker)
+void Generator::generatePageNode(PageNode* /* pn */, CodeMarker* /* marker */)
{
- if (dn->childNodes().isEmpty())
- return;
- generateFileList(dn, marker, Node::File);
- generateFileList(dn, marker, Node::Image);
}
-void Generator::generateDocumentNode(DocumentNode* /* dn */, CodeMarker* /* marker */)
+void Generator::generateCollectionNode(CollectionNode* , CodeMarker* )
{
}
-void Generator::generateCollectionNode(CollectionNode* , CodeMarker* )
+/*!
+ This function is called when the documentation for an example is
+ being formatted. It outputs a list of files for the example, which
+ can be the example's source files or the list of images used by the
+ example. The images are copied into a subtree of
+ \c{...doc/html/images/used-in-examples/...}
+*/
+void Generator::generateFileList(const ExampleNode* en, CodeMarker* marker, bool images)
{
+ Text text;
+ OpenedList openedList(OpenedList::Bullet);
+ QString tag;
+ QStringList paths;
+ Atom::AtomType atomType = Atom::ExampleFileLink;
+
+ if (images) {
+ paths = en->images();
+ tag = "Images:";
+ atomType = Atom::ExampleImageLink;
+ } else { //files
+ paths = en->files();
+ tag = "Files:";
+ }
+ std::sort(paths.begin(), paths.end(), Generator::comparePaths);
+
+ text << Atom::ParaLeft << tag << Atom::ParaRight;
+ text << Atom(Atom::ListLeft, openedList.styleString());
+
+ QString path;
+ foreach (QString file, paths) {
+ if (images) {
+ if (!file.isEmpty()) {
+ QDir dirInfo;
+ QString userFriendlyFilePath;
+ const QString prefix("/images/used-in-examples/");
+ QString srcPath = Config::findFile(en->location(),
+ QStringList(),
+ exampleDirs,
+ file,
+ exampleImgExts);
+ outFileNames_ << prefix.mid(1) + userFriendlyFilePath;
+ userFriendlyFilePath.truncate(userFriendlyFilePath.lastIndexOf('/'));
+ QString imgOutDir = outDir_ + prefix + userFriendlyFilePath;
+ if (!dirInfo.mkpath(imgOutDir))
+ en->location().fatal(tr("Cannot create output directory '%1'").arg(imgOutDir));
+ Config::copyFile(en->location(), srcPath, file, imgOutDir);
+ }
+
+ }
+ else {
+ Text text;
+ Quoter quoter;
+ Doc::quoteFromFile(en->doc().location(), quoter, file);
+ QString code = quoter.quoteTo(en->location(), QString(), QString());
+ CodeMarker *codeMarker = CodeMarker::markerForFileName(file);
+ text << Atom(codeMarker->atomType(), code);
+ Atom a(codeMarker->atomType(), code);
+ beginFilePage(en, linkForExampleFile(file, en));
+ generateText(text, en, codeMarker);
+ endFilePage();
+ }
+
+ openedList.next();
+ text << Atom(Atom::ListItemNumber, openedList.numberString())
+ << Atom(Atom::ListItemLeft, openedList.styleString())
+ << Atom::ParaLeft
+ << Atom(atomType, file)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << file
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
+ << Atom::ParaRight
+ << Atom(Atom::ListItemRight, openedList.styleString());
+ path = file;
+ }
+ text << Atom(Atom::ListRight, openedList.styleString());
+ if (!paths.isEmpty())
+ generateText(text, en, marker);
}
+#if 0
/*!
This function is called when the documentation for an
example is being formatted. It outputs the list of source
@@ -977,9 +1081,9 @@ 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 DocumentNode* dn,
+void Generator::generateFileList(const PageNode* pn,
CodeMarker* marker,
- Node::DocSubtype subtype,
+ Node::NodeSubtype subtype,
const QString& regExp)
{
int count = 0;
@@ -987,7 +1091,7 @@ void Generator::generateFileList(const DocumentNode* dn,
OpenedList openedList(OpenedList::Bullet);
QString tag;
- NodeList children(dn->childNodes());
+ NodeList children(pn->childNodes());
std::sort(children.begin(), children.end(), Generator::compareNodes);
if (!regExp.isEmpty()) {
QRegExp re(regExp);
@@ -1013,7 +1117,7 @@ void Generator::generateFileList(const DocumentNode* dn,
text << Atom(Atom::ListLeft, openedList.styleString());
foreach (const Node* child, children) {
- if (child->docSubtype() == subtype) {
+ if (child->nodeSubtype() == subtype) {
++count;
QString file = child->name();
if (subtype == Node::Image) {
@@ -1021,7 +1125,7 @@ void Generator::generateFileList(const DocumentNode* dn,
QDir dirInfo;
QString userFriendlyFilePath;
const QString prefix("/images/used-in-examples/");
- QString srcPath = Config::findFile(dn->location(),
+ QString srcPath = Config::findFile(pn->location(),
QStringList(),
exampleDirs,
file,
@@ -1031,8 +1135,8 @@ void Generator::generateFileList(const DocumentNode* dn,
userFriendlyFilePath.truncate(userFriendlyFilePath.lastIndexOf('/'));
QString imgOutDir = outDir_ + prefix + userFriendlyFilePath;
if (!dirInfo.mkpath(imgOutDir))
- dn->location().fatal(tr("Cannot create output directory '%1'").arg(imgOutDir));
- Config::copyFile(dn->location(), srcPath, file, imgOutDir);
+ pn->location().fatal(tr("Cannot create output directory '%1'").arg(imgOutDir));
+ Config::copyFile(pn->location(), srcPath, file, imgOutDir);
}
}
@@ -1051,9 +1155,9 @@ void Generator::generateFileList(const DocumentNode* dn,
}
text << Atom(Atom::ListRight, openedList.styleString());
if (count > 0)
- generateText(text, dn, marker);
+ generateText(text, pn, marker);
}
-
+#endif
void Generator::generateInheritedBy(const ClassNode *classe, CodeMarker *marker)
{
if (!classe->derivedClasses().isEmpty()) {
@@ -1113,19 +1217,7 @@ void Generator::generateDocumentation(Node* node)
return;
if (node->isInternal() && !showInternal_)
return;
-
- if (node->isDocumentNode()) {
- DocumentNode* docNode = static_cast<DocumentNode*>(node);
- if (docNode->docSubtype() == Node::ExternalPage)
- return;
- if (docNode->docSubtype() == Node::Image)
- return;
- if (docNode->docSubtype() == Node::Page) {
- if (docNode->count() > 0)
- qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
- }
- }
- else if (node->isQmlPropertyGroup() || node->isJsPropertyGroup())
+ if (node->isExternalPage() || node->isQmlPropertyGroup() || node->isJsPropertyGroup())
return;
/*
@@ -1134,27 +1226,59 @@ void Generator::generateDocumentation(Node* node)
CodeMarker *marker = CodeMarker::markerForFileName(node->location().filePath());
if (node->parent() != 0) {
- if (node->isClass() || (node->isNamespace() && node->docMustBeGenerated())) {
- beginSubPage(node, fileName(node));
- generateCppReferencePage(static_cast<Aggregate*>(node), marker);
- endSubPage();
- }
- else if (node->isQmlType() || node->isJsType()) {
- beginSubPage(node, fileName(node));
- QmlTypeNode* qcn = static_cast<QmlTypeNode*>(node);
- generateQmlTypePage(qcn, marker);
- endSubPage();
- }
- else if (node->isDocumentNode()) {
- beginSubPage(node, fileName(node));
- generateDocumentNode(static_cast<DocumentNode*>(node), marker);
- endSubPage();
- }
- else if (node->isQmlBasicType() || node->isJsBasicType()) {
+ if (node->isCollectionNode()) {
+ /*
+ A collection node collects: groups, C++ modules,
+ QML modules or JavaScript modules. Testing for a
+ CollectionNode must be done before testing for a
+ TextPageNode because a CollectionNode is a PageNode
+ at this point.
+
+ Don't output an HTML page for the collection
+ 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 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));
+ generateCollectionNode(cn, marker);
+ endSubPage();
+ }
+ } else if (node->isTextPageNode()) {
beginSubPage(node, fileName(node));
- QmlBasicTypeNode* qbtn = static_cast<QmlBasicTypeNode*>(node);
- generateQmlBasicTypePage(qbtn, marker);
+ generatePageNode(static_cast<PageNode*>(node), marker);
endSubPage();
+ } else if (node->isAggregate()) {
+ if (node->isClass() || node->isHeader() ||
+ (node->isNamespace() && node->docMustBeGenerated())) {
+ beginSubPage(node, fileName(node));
+ generateCppReferencePage(static_cast<Aggregate*>(node), marker);
+ endSubPage();
+ }
+ else if (node->isQmlType() || node->isJsType()) {
+ beginSubPage(node, fileName(node));
+ QmlTypeNode* qcn = static_cast<QmlTypeNode*>(node);
+ generateQmlTypePage(qcn, marker);
+ endSubPage();
+ }
+ else if (node->isQmlBasicType() || node->isJsBasicType()) {
+ beginSubPage(node, fileName(node));
+ QmlBasicTypeNode* qbtn = static_cast<QmlBasicTypeNode*>(node);
+ generateQmlBasicTypePage(qbtn, marker);
+ endSubPage();
+ }
}
}
@@ -1163,37 +1287,8 @@ void Generator::generateDocumentation(Node* node)
int i = 0;
while (i < aggregate->childNodes().count()) {
Node *c = aggregate->childNodes().at(i);
- if (c->isAggregate() && !c->isPrivate()) {
- generateDocumentation((Aggregate*)c);
- }
- else if (c->isCollectionNode()) {
- /*
- 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, \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 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*>(c);
- if (cn->wasSeen()) {
- qdb_->mergeCollections(cn);
- beginSubPage(c, fileName(c));
- generateCollectionNode(cn, marker);
- endSubPage();
- }
- }
+ if (c->isPageNode() && !c->isPrivate())
+ generateDocumentation(c);
++i;
}
}
@@ -1304,7 +1399,7 @@ void Generator::generateSince(const Node *node, CodeMarker *marker)
text << Atom::ParaLeft
<< "This "
<< typeString(node);
- if (node->type() == Node::Enum)
+ if (node->nodeType() == Node::Enum)
text << " was introduced or modified in ";
else
text << " was introduced in ";
@@ -1599,7 +1694,7 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker)
*/
void Generator::generateOverloadedSignal(const Node* node, CodeMarker* marker)
{
- if (node->type() != Node::Function)
+ if (node->nodeType() != Node::Function)
return;
const FunctionNode *func = static_cast<const FunctionNode *>(node);
if (!func->isSignal())
@@ -2225,7 +2320,7 @@ QString Generator::trimmedTrailing(const QString& string, const QString &prefix,
QString Generator::typeString(const Node *node)
{
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Namespace:
return "namespace";
case Node::Class:
@@ -2234,26 +2329,37 @@ QString Generator::typeString(const Node *node)
return "type";
case Node::QmlBasicType:
return "type";
- case Node::Document:
+ case Node::Page:
return "documentation";
case Node::Enum:
return "enum";
case Node::Typedef:
return "typedef";
- case Node::Function:
+ case Node::Function: {
+ const FunctionNode *fn = static_cast<const FunctionNode*>(node);
+ switch (fn->metaness()) {
+ case FunctionNode::JsSignal:
+ case FunctionNode::QmlSignal:
+ return "signal";
+ case FunctionNode::JsSignalHandler:
+ case FunctionNode::QmlSignalHandler:
+ return "signal handler";
+ case FunctionNode::JsMethod:
+ case FunctionNode::QmlMethod:
+ return "method";
+ default:
+ break;
+ }
return "function";
+ }
case Node::Property:
case Node::QmlProperty:
return "property";
+ case Node::JsPropertyGroup:
case Node::QmlPropertyGroup:
return "property group";
- case Node::QmlSignal:
- return "signal";
- case Node::QmlSignalHandler:
- return "signal handler";
- case Node::QmlMethod:
- return "method";
case Node::Module:
+ case Node::JsModule:
case Node::QmlModule:
return "module";
default:
diff --git a/src/qdoc/generator.h b/src/qdoc/generator.h
index 7925838b5..a58d83852 100644
--- a/src/qdoc/generator.h
+++ b/src/qdoc/generator.h
@@ -71,6 +71,7 @@ public:
QString fullDocumentLocation(const Node *node, bool useSubdir = false);
const Config* config() { return config_; }
+ QString linkForExampleFile(const QString &path, const Node *parent);
static Generator *currentGenerator() { return currentGenerator_; }
static Generator *generatorForFormat(const QString& format);
@@ -102,6 +103,8 @@ public:
static QString plainCode(const QString& markedCode);
protected:
+ void beginFilePage(const Node* node, const QString& fileName);
+ void endFilePage() { endSubPage(); } // for symmetry
void beginSubPage(const Node* node, const QString& fileName);
void endSubPage();
virtual QString fileBase(const Node* node) const;
@@ -113,7 +116,7 @@ protected:
virtual void generateCppReferencePage(Node* node, CodeMarker* marker);
virtual void generateQmlTypePage(QmlTypeNode* , CodeMarker* ) { }
virtual void generateQmlBasicTypePage(QmlBasicTypeNode* , CodeMarker* ) { }
- virtual void generateDocumentNode(DocumentNode* dn, CodeMarker* marker);
+ virtual void generatePageNode(PageNode* pn, 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);
@@ -147,11 +150,14 @@ protected:
CodeMarker *marker,
bool generate,
int& numGeneratedAtoms);
- void generateExampleFiles(const DocumentNode *dn, CodeMarker *marker);
- void generateFileList(const DocumentNode* dn,
+ void generateFileList(const ExampleNode* en, CodeMarker* marker, bool images);
+#if 0
+ // Keeping this until usage shows we no longer need it. mws 17/08/2018
+ void generateFileList(const PageNode* pn,
CodeMarker* marker,
- Node::DocSubtype subtype,
- const QString& regExp = QString());
+ Node::NodeSubtype subtype,
+ const QString& regExp);
+#endif
void generateSince(const Node *node, CodeMarker *marker);
void generateStatus(const Node *node, CodeMarker *marker);
void generatePrivateSignalNote(const Node* node, CodeMarker* marker);
@@ -229,6 +235,7 @@ private:
void generateReimplementedFrom(const FunctionNode *func, CodeMarker *marker);
static bool compareNodes(Node *a, Node *b) { return (a->name() < b->name()); }
+ static bool comparePaths(QString a, QString b) { return (a < b); }
static void copyTemplateFiles(const Config &config,
const QString &configVar,
const QString &subDir);
diff --git a/src/qdoc/helpprojectwriter.cpp b/src/qdoc/helpprojectwriter.cpp
index eb2409e05..e1bc95e18 100644
--- a/src/qdoc/helpprojectwriter.cpp
+++ b/src/qdoc/helpprojectwriter.cpp
@@ -121,57 +121,63 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
QHash<QString, Node::NodeType> typeHash;
typeHash["namespace"] = Node::Namespace;
typeHash["class"] = Node::Class;
- typeHash["doc"] = Node::Document;
- typeHash["fake"] = Node::Document; // Legacy alias for 'doc'
+ typeHash["header"] = Node::HeaderFile;
+ typeHash["headerfile"] = Node::HeaderFile;
+ typeHash["doc"] = Node::Page; // to be removed from qdocconf files
+ typeHash["fake"] = Node::Page; // to be removed from qdocconf files
+ typeHash["page"] = Node::Page;
typeHash["enum"] = Node::Enum;
+ typeHash["example"] = Node::Example;
+ typeHash["externalpage"] = Node::ExternalPage;
typeHash["typedef"] = Node::Typedef;
typeHash["function"] = Node::Function;
typeHash["property"] = Node::Property;
typeHash["variable"] = Node::Variable;
typeHash["group"] = Node::Group;
typeHash["module"] = Node::Module;
+ typeHash["jsmodule"] = Node::JsModule;
typeHash["qmlmodule"] = Node::QmlModule;
- typeHash["qmlproperty"] = Node::QmlProperty;
- typeHash["qmlsignal"] = Node::QmlSignal;
- typeHash["qmlsignalhandler"] = Node::QmlSignalHandler;
- typeHash["qmlmethod"] = Node::QmlMethod;
+ typeHash["qmlproperty"] = Node::JsProperty;
+ typeHash["jsproperty"] = Node::QmlProperty;
+ typeHash["jspropertygroup"] = Node::JsPropertyGroup;
typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
typeHash["qmlclass"] = Node::QmlType; // Legacy alias for 'qmltype'
typeHash["qmltype"] = Node::QmlType;
typeHash["qmlbasictype"] = Node::QmlBasicType;
- QHash<QString, Node::DocSubtype> docSubtypeHash;
- docSubtypeHash["example"] = Node::Example;
- docSubtypeHash["headerfile"] = Node::HeaderFile;
- docSubtypeHash["file"] = Node::File;
- docSubtypeHash["page"] = Node::Page;
- docSubtypeHash["externalpage"] = Node::ExternalPage;
+ QHash<QString, Node::NodeType> pageTypeHash;
+ pageTypeHash["example"] = Node::Example;
+ pageTypeHash["headerfile"] = Node::HeaderFile;
+ pageTypeHash["header"] = Node::HeaderFile;
+ pageTypeHash["page"] = Node::Page;
+ pageTypeHash["externalpage"] = Node::ExternalPage;
- QSet<Node::DocSubtype> allSubTypes = QSet<Node::DocSubtype>::fromList(docSubtypeHash.values());
+ QSet<Node::NodeType> fullSubset = QSet<Node::NodeType>::fromList(pageTypeHash.values());
foreach (const QString &selector, selectors) {
QStringList pieces = selector.split(QLatin1Char(':'));
if (pieces.size() == 1) {
QString lower = selector.toLower();
if (typeHash.contains(lower))
- subproject.selectors[typeHash[lower]] = allSubTypes;
+ subproject.selectors[typeHash[lower]] = fullSubset;
} else if (pieces.size() >= 2) {
- QString docType = pieces[0].toLower();
+ QString pageTypeStr = pieces[0].toLower();
pieces = pieces[1].split(QLatin1Char(','));
- if (typeHash.contains(docType)) {
- QSet<Node::DocSubtype> docSubtypes;
+ if (typeHash.contains(pageTypeStr)) {
+ QSet<Node::NodeType> nodeTypeSet;
for (int i = 0; i < pieces.size(); ++i) {
QString piece = pieces[i].toLower();
- if (typeHash[docType] == Node::Group
- || typeHash[docType] == Node::Module
- || typeHash[docType] == Node::QmlModule) {
+ if (typeHash[pageTypeStr] == Node::Group
+ || typeHash[pageTypeStr] == Node::Module
+ || typeHash[pageTypeStr] == Node::QmlModule
+ || typeHash[pageTypeStr] == Node::JsModule) {
subproject.groups << piece;
continue;
}
- if (docSubtypeHash.contains(piece))
- docSubtypes.insert(docSubtypeHash[piece]);
+ if (pageTypeHash.contains(piece))
+ nodeTypeSet.insert(pageTypeHash[piece]);
}
- subproject.selectors[typeHash[docType]] = docSubtypes;
+ subproject.selectors[typeHash[pageTypeStr]] = nodeTypeSet;
}
}
}
@@ -189,20 +195,20 @@ void HelpProjectWriter::addExtraFiles(const QSet<QString> &files)
projects[i].extraFiles.unite(files);
}
-/*
+/*!
Returns a list of strings describing the keyword details for a given node.
The first string is the human-readable name to be shown in Assistant.
The second string is a unique identifier.
The third string is the location of the documentation for the keyword.
-*/
+ */
QStringList HelpProjectWriter::keywordDetails(const Node *node) const
{
QStringList details;
if (node->parent() && !node->parent()->name().isEmpty()) {
// "name"
- if (node->type() == Node::Enum || node->type() == Node::Typedef)
+ if (node->nodeType() == Node::Enum || node->nodeType() == Node::Typedef)
details << node->parent()->name()+"::"+node->name();
else
details << node->name();
@@ -217,8 +223,8 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
details << node->name();
details << "JS." + node->name();
}
- else if (node->isDocumentNode()) {
- const DocumentNode *fake = static_cast<const DocumentNode *>(node);
+ else if (node->isTextPageNode()) {
+ const PageNode *fake = static_cast<const PageNode *>(node);
details << fake->fullTitle();
details << fake->fullTitle();
}
@@ -247,7 +253,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
if (!docPath.isEmpty() && project.excluded.contains(docPath))
return false;
- QString objName = node->isDocumentNode() ? node->fullTitle() : node->fullDocumentName();
+ QString objName = node->isTextPageNode() ? node->fullTitle() : node->fullDocumentName();
// Only add nodes to the set for each subproject if they match a selector.
// Those that match will be listed in the table of contents.
@@ -257,27 +263,26 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
if (subproject.selectors.isEmpty()) {
project.subprojects[i].nodes[objName] = node;
}
- else if (subproject.selectors.contains(node->type())) {
+ else if (subproject.selectors.contains(node->nodeType())) {
// Add all group members for '[group|module|qmlmodule]:name' selector
if (node->isGroup() || node->isModule() || node->isQmlModule()) {
if (project.subprojects[i].groups.contains(node->name().toLower())) {
const CollectionNode* cn = static_cast<const CollectionNode*>(node);
foreach (const Node* m, cn->members()) {
- QString memberName = m->isDocumentNode()
+ QString memberName = m->isTextPageNode()
? m->fullTitle() : m->fullDocumentName();
project.subprojects[i].nodes[memberName] = m;
}
}
}
// Accept only the node types in the selectors hash.
- else if (!node->isDocumentNode())
+ else if (!node->isTextPageNode())
project.subprojects[i].nodes[objName] = node;
else {
// Accept only doc nodes with subtypes contained in the selector's
// mask.
- const DocumentNode *docNode = static_cast<const DocumentNode *>(node);
- if (subproject.selectors[node->type()].contains(docNode->docSubtype()) &&
- !docNode->isExternalPage() && !docNode->fullTitle().isEmpty()) {
+ if (subproject.selectors[node->nodeType()].contains(node->nodeType()) &&
+ !node->isExternalPage() && !node->fullTitle().isEmpty()) {
project.subprojects[i].nodes[objName] = node;
}
@@ -285,13 +290,15 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
}
}
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Class:
project.keywords.append(keywordDetails(node));
break;
case Node::QmlType:
case Node::QmlBasicType:
+ case Node::JsType:
+ case Node::JsBasicType:
if (node->doc().hasKeywords()) {
foreach (const Atom* keyword, node->doc().keywords()) {
if (!keyword->string().isEmpty()) {
@@ -338,6 +345,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
case Node::Group:
case Node::Module:
case Node::QmlModule:
+ case Node::JsModule:
{
const CollectionNode* cn = static_cast<const CollectionNode*>(node);
if (!cn->fullTitle().isEmpty()) {
@@ -363,9 +371,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
case Node::Property:
case Node::QmlProperty:
- case Node::QmlSignal:
- case Node::QmlSignalHandler:
- case Node::QmlMethod:
+ case Node::JsProperty:
project.keywords.append(keywordDetails(node));
break;
@@ -373,6 +379,17 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
{
const FunctionNode *funcNode = static_cast<const FunctionNode *>(node);
+ /*
+ QML and JS methods, signals, and signal handlers used to be node types,
+ but now they are Function nodes with a Metaness value that specifies
+ what kind of function they are, QmlSignal, JsSignal, QmlMethod, etc. It
+ suffices at this point to test whether the node is of the QML or JS Genus,
+ because we already know it is NodeType::Function.
+ */
+ if (funcNode->isQmlNode() || funcNode->isJsNode()) {
+ project.keywords.append(keywordDetails(node));
+ break;
+ }
// Only insert keywords for non-constructors. Constructors are covered
// by the classes themselves.
@@ -412,30 +429,26 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
}
break;
- // Document nodes (such as manual pages) contain subtypes, titles and other
+ // Page nodes (such as manual pages) contain subtypes, titles and other
// attributes.
- case Node::Document: {
- const DocumentNode *docNode = static_cast<const DocumentNode*>(node);
- if (!docNode->isExternalPage() && docNode->docSubtype() != Node::Image &&
- !docNode->fullTitle().isEmpty()) {
-
- if (docNode->docSubtype() != Node::File) {
- if (docNode->doc().hasKeywords()) {
- foreach (const Atom *keyword, docNode->doc().keywords()) {
- if (!keyword->string().isEmpty()) {
- QStringList details;
- details << keyword->string()
- << keyword->string()
- << gen_->fullDocumentLocation(node, false);
- project.keywords.append(details);
- } else
- docNode->doc().location().warning(
- tr("Bad keyword in %1").arg(gen_->fullDocumentLocation(node, false))
- );
+ case Node::Page: {
+ const PageNode *pn = static_cast<const PageNode*>(node);
+ if (!pn->fullTitle().isEmpty()) {
+ if (pn->doc().hasKeywords()) {
+ foreach (const Atom *keyword, pn->doc().keywords()) {
+ if (!keyword->string().isEmpty()) {
+ QStringList details;
+ details << keyword->string()
+ << keyword->string()
+ << gen_->fullDocumentLocation(node, false);
+ project.keywords.append(details);
+ } else {
+ QString loc = gen_->fullDocumentLocation(node, false);
+ pn->doc().location().warning(tr("Bad keyword in %1").arg(loc));
}
}
- project.keywords.append(keywordDetails(node));
}
+ project.keywords.append(keywordDetails(node));
}
break;
}
@@ -462,26 +475,26 @@ void HelpProjectWriter::generateSections(HelpProject &project,
QXmlStreamWriter &writer, const Node *node)
{
/*
- Don't include index nodes in the help file. Or DITA map nodes.
+ Don't include index nodes in the help file.
*/
- if (node->isIndexNode() || node->docSubtype() == Node::DitaMap)
+ if (node->isIndexNode())
return;
if (!generateSection(project, writer, node))
return;
if (node->isAggregate()) {
- const Aggregate *inner = static_cast<const Aggregate *>(node);
+ const Aggregate *aggregate = static_cast<const Aggregate *>(node);
// Ensure that we don't visit nodes more than once.
QSet<const Node*> childSet;
- foreach (const Node *childNode, inner->childNodes()) {
+ foreach (const Node *childNode, aggregate->childNodes()) {
if (childNode->isIndexNode())
continue;
if (childNode->isPrivate())
continue;
- if (childNode->isDocumentNode()) {
+ if (childNode->isTextPageNode()) {
childSet << childNode;
}
else if (childNode->isQmlPropertyGroup() || childNode->isJsPropertyGroup()) {
@@ -494,8 +507,8 @@ void HelpProjectWriter::generateSections(HelpProject &project,
because The Qml/Js Property Group is
an actual documented thing.
*/
- const Aggregate* inner = static_cast<const Aggregate*>(childNode);
- foreach (const Node* n, inner->childNodes()) {
+ const Aggregate* aggregate = static_cast<const Aggregate*>(childNode);
+ foreach (const Node* n, aggregate->childNodes()) {
if (n->isPrivate())
continue;
childSet << n;
@@ -549,9 +562,9 @@ void HelpProjectWriter::writeSection(QXmlStreamWriter &writer, const QString &pa
writer.writeEndElement(); // section
}
-/*
+/*!
Write subsections for all members, compatibility members and obsolete members.
-*/
+ */
void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &writer,
const Node *node)
{
@@ -561,12 +574,12 @@ void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &write
return;
bool derivedClass = false;
- if (node->type() == Node::Class)
+ if (node->nodeType() == Node::Class)
derivedClass = !(static_cast<const ClassNode *>(node)->baseClasses().isEmpty());
// 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() &&
+ if (!node->isNamespace() && !node->isHeader() &&
(derivedClass || node->isQmlType() || node->isJsType() ||
!project.memberStatus[node].isEmpty())) {
QString membersPath = href + QStringLiteral("-members.html");
@@ -584,7 +597,7 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
QString href = gen_->fullDocumentLocation(node, false);
QString objName = node->name();
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Class:
writer.writeStartElement("section");
@@ -602,6 +615,15 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
writeSection(writer, href, objName);
break;
+ case Node::HeaderFile:
+ writer.writeStartElement("section");
+ writer.writeAttribute("ref", href);
+ writer.writeAttribute("title", node->fullTitle());
+ addMembers(project, writer, node);
+ writer.writeEndElement(); // section
+ break;
+
+ case Node::JsType:
case Node::QmlType:
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
@@ -610,23 +632,21 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
writer.writeEndElement(); // section
break;
- case Node::Document: {
- // Document nodes (such as manual pages) contain subtypes, titles and other
+ case Node::Page: {
+ // Page nodes (such as manual pages) contain subtypes, titles and other
// attributes.
- const DocumentNode *docNode = static_cast<const DocumentNode*>(node);
+ const PageNode *pn = static_cast<const PageNode*>(node);
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
- writer.writeAttribute("title", docNode->fullTitle());
-
- if (docNode->docSubtype() == Node::HeaderFile)
- addMembers(project, writer, node);
+ writer.writeAttribute("title", pn->fullTitle());
writer.writeEndElement(); // section
}
break;
case Node::Group:
case Node::Module:
+ case Node::JsModule:
case Node::QmlModule:
{
const CollectionNode* cn = static_cast<const CollectionNode*>(node);
@@ -650,7 +670,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
qdb_->setLocalSearch();
if (!project.indexRoot.isEmpty())
- rootNode = qdb_->findDocumentNodeByTitle(project.indexRoot);
+ rootNode = qdb_->findPageNodeByTitle(project.indexRoot);
else
rootNode = qdb_->primaryTreeRoot();
@@ -701,9 +721,9 @@ void HelpProjectWriter::generateProject(HelpProject &project)
writer.writeStartElement("toc");
writer.writeStartElement("section");
- const Node* node = qdb_->findDocumentNodeByTitle(project.indexTitle);
+ const Node* node = qdb_->findPageNodeByTitle(project.indexTitle);
if (node == 0)
- node = qdb_->findNodeByNameAndType(QStringList("index.html"), Node::Document);
+ node = qdb_->findNodeByNameAndType(QStringList("index.html"), Node::Page);
QString indexPath;
if (node)
indexPath = gen_->fullDocumentLocation(node, false);
diff --git a/src/qdoc/helpprojectwriter.h b/src/qdoc/helpprojectwriter.h
index c84761d58..81e2a65c4 100644
--- a/src/qdoc/helpprojectwriter.h
+++ b/src/qdoc/helpprojectwriter.h
@@ -45,7 +45,7 @@ struct SubProject
{
QString title;
QString indexTitle;
- QHash<Node::NodeType, QSet<DocumentNode::DocSubtype> > selectors;
+ QHash<Node::NodeType, QSet<Node::NodeType> > selectors;
bool sortPages;
QString type;
QHash<QString, const Node *> nodes;
diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp
index 4c46a3d8a..ec92d4316 100644
--- a/src/qdoc/htmlgenerator.cpp
+++ b/src/qdoc/htmlgenerator.cpp
@@ -536,8 +536,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
break;
}
out() << "<p>";
- if (relative->type() == Node::Property ||
- relative->type() == Node::Variable) {
+ if (relative->nodeType() == Node::Property ||
+ relative->nodeType() == Node::Variable) {
atom = atom->next();
if (atom != nullptr && atom->type() == Atom::String) {
QString firstWord = atom->string().toLower().section(' ', 0, 0, QString::SectionSkipEmpty);
@@ -547,7 +547,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
|| firstWord == QLatin1String("whether")
|| firstWord == QLatin1String("which")) {
QString str = "This ";
- if (relative->type() == Node::Property)
+ if (relative->nodeType() == Node::Property)
str += "property holds ";
else
str += "variable holds ";
@@ -666,7 +666,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
break;
case Atom::AnnotatedList:
{
- const CollectionNode* cn = qdb_->getCollectionNode(atom->string(), Node::DOC);
+ const CollectionNode* cn = qdb_->getCollectionNode(atom->string(), Node::Group);
if (cn)
generateList(cn, marker, atom->string());
}
@@ -696,17 +696,17 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
}
else if ((idx = atom->string().indexOf(QStringLiteral("bymodule"))) != -1) {
QString moduleName = atom->string().mid(idx + 8).trimmed();
- Node::Genus genus = Node::CPP;
+ Node::NodeType type = Node::Module;
if (atom->string().startsWith(QLatin1String("qml")))
- genus = Node::QML;
+ type = Node::QmlModule;
else if (atom->string().startsWith(QLatin1String("js")))
- genus = Node::JS;
+ type = Node::JsModule;
else if (atom->string().startsWith(QLatin1String("groups")))
- genus = Node::DOC;
+ type = Node::Group;
QDocDatabase* qdb = QDocDatabase::qdocDB();
- const CollectionNode* cn = qdb->getCollectionNode(moduleName, genus);
+ const CollectionNode* cn = qdb->getCollectionNode(moduleName, type);
if (cn) {
- if (genus == Node::CPP) {
+ if (type == Node::Module) {
NodeMap m;
cn->getMemberClasses(m);
if (!m.isEmpty()) {
@@ -720,12 +720,23 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
else if (atom->string().startsWith("examplefiles") ||
atom->string().startsWith("exampleimages")) {
if (relative->isExample()) {
- Node::DocSubtype subType = (atom->string().mid(7,5) == "image") ? Node::Image : Node::File;
+#if 0
+ /*
+ The removed code will be physically removed if and
+ when this update is determined to be successful.
+ This overload of generateFileList() should no longer
+ be needed, so there is a qDebug() there to tell me
+ if it would have been called. So far, it hasn't
+ happened. mws 18/08/2018
+ */
+ Node::NodeSubtype subType = (atom->string().mid(7,5) == "image") ? Node::Image : Node::File;
QString regExp;
int secondArg = atom->string().indexOf(" ");
if (secondArg != -1)
- regExp = atom->string().mid(++secondArg);
- generateFileList(static_cast<const DocumentNode*>(relative), marker, subType, regExp);
+ regExp = atom->string().mid(++secondArg);
+ generateFileList(static_cast<const PageNode*>(relative), marker, subType, regExp);
+#endif
+ qDebug() << "GENERATE FILE LIST CALLED" << relative->name() << atom->string();
}
else
relative->location().warning(QString("'\\generatelist \1' can only be used with '\\example' topic command").arg(atom->string()));
@@ -956,6 +967,25 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
skipAhead = 1;
}
break;
+ case Atom::ExampleFileLink:
+ {
+ QString link = linkForExampleFile(atom->string(), relative);
+ if (link.isEmpty() && !noLinkErrors())
+ relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
+ beginLink(link);
+ skipAhead = 1;
+ }
+ break;
+ case Atom::ExampleImageLink:
+ {
+ QString link = atom->string();
+ if (link.isEmpty() && !noLinkErrors())
+ relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
+ link = "images/used-in-examples/" + link;
+ beginLink(link);
+ skipAhead = 1;
+ }
+ break;
case Atom::LinkNode:
{
const Node *node = CodeMarker::nodeForString(atom->string());
@@ -986,7 +1016,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
out() << "<th class=\"tblConst\">Constant</th>";
// If not in \enum topic, skip the value column
- if (relative->type() == Node::Enum)
+ if (relative->nodeType() == Node::Enum)
out() << "<th class=\"tblval\">Value</th>";
out() << "<th class=\"tbldscr\">Description</th></tr>\n";
@@ -1048,7 +1078,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
t = protectEnc(plainCode(marker->markedUpEnumValue(t, relative)));
out() << "<tr><td class=\"topAlign\"><code>" << t << "</code>";
- if (relative->type() == Node::Enum) {
+ if (relative->nodeType() == Node::Enum) {
out() << "</td><td class=\"topAlign tblval\">";
const EnumNode *enume = static_cast<const EnumNode *>(relative);
QString itemValue = enume->itemValue(atom->next()->string());
@@ -1300,8 +1330,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
}
/*!
- Generate a reference page for the C++ class or C++ namespace
- documented in \a node using the \a marker.
+ Generate a reference page for the C++ class, namespace, or
+ header file documented in \a node using the code \a marker
+ provided.
*/
void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
{
@@ -1312,16 +1343,31 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
QString rawTitle;
QString fullTitle;
NamespaceNode* ns = nullptr;
+ SectionVector *summarySections = 0;
+ SectionVector *detailsSections = 0;
+
+ Sections sections(aggregate);
if (aggregate->isNamespace()) {
rawTitle = aggregate->plainName();
fullTitle = aggregate->plainFullName();
title = rawTitle + " Namespace";
ns = static_cast<NamespaceNode*>(aggregate);
+ summarySections = &sections.stdSummarySections();
+ detailsSections = &sections.stdDetailsSections();
}
else if (aggregate->isClass()) {
rawTitle = aggregate->plainName();
fullTitle = aggregate->plainFullName();
title = rawTitle + " Class";
+ summarySections = &sections.stdCppClassSummarySections();
+ detailsSections = &sections.stdCppClassDetailsSections();
+ }
+ else if (aggregate->isHeader()) {
+ rawTitle = aggregate->title();
+ fullTitle = aggregate->fullTitle();
+ title = "Header " + rawTitle;
+ summarySections = &sections.stdSummarySections();
+ detailsSections = &sections.stdDetailsSections();
}
Text subtitleText;
@@ -1329,10 +1375,7 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")" << Atom(Atom::LineBreak);
generateHeader(title, aggregate, marker);
-
- Sections sections(aggregate);
- SectionVector *sectionVector = ns ? &sections.stdSummarySections() : &sections.stdCppClassSummarySections();
- generateTableOfContents(aggregate, marker, sectionVector);
+ generateTableOfContents(aggregate, marker, summarySections);
generateKeywordAnchors(aggregate);
generateTitle(title, subtitleText, SmallSubTitle, aggregate, marker);
if (ns && !ns->hasDoc() && ns->docNode()) {
@@ -1353,6 +1396,7 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
generateBrief(aggregate, marker);
generateRequisites(aggregate, marker);
generateStatus(aggregate, marker);
+ generateSince(aggregate, marker);
out() << "<ul>\n";
@@ -1372,8 +1416,8 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
bool needOtherSection = false;
- SectionVector::ConstIterator s = sectionVector->constBegin();
- while (s != sectionVector->constEnd()) {
+ SectionVector::ConstIterator s = summarySections->constBegin();
+ while (s != summarySections->constEnd()) {
if (s->members().isEmpty() && s->reimplementedMembers().isEmpty()) {
if (!s->inheritedMembers().isEmpty())
needOtherSection = true;
@@ -1408,8 +1452,8 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
out() << "<h3>Additional Inherited Members</h3>\n"
"<ul>\n";
- s = sectionVector->constBegin();
- while (s != sectionVector->constEnd()) {
+ s = summarySections->constBegin();
+ while (s != summarySections->constEnd()) {
if (s->members().isEmpty() && !s->inheritedMembers().isEmpty())
generateSectionInheritedList(*s, aggregate);
++s;
@@ -1432,9 +1476,12 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
generateExtractionMark(aggregate, EndMark);
}
- sectionVector = ns ? &sections.stdDetailsSections() : &sections.stdCppClassDetailsSections();
- s = sectionVector->constBegin();
- while (s != sectionVector->constEnd()) {
+ s = detailsSections->constBegin();
+ while (s != detailsSections->constEnd()) {
+ if (s->isEmpty()) {
+ ++s;
+ continue;
+ }
//out() << "<hr />\n";
if (!s->divClass().isEmpty())
out() << "<div class=\"" << s->divClass() << "\">\n"; // QTBUG-9504
@@ -1443,7 +1490,7 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
NodeVector::ConstIterator m = s->members().constBegin();
while (m != s->members().constEnd()) {
if ((*m)->access() != Node::Private) { // ### check necessary?
- if ((*m)->type() != Node::Class)
+ if ((*m)->nodeType() != Node::Class)
generateDetailedMember(*m, aggregate, marker);
else {
out() << "<h3> class ";
@@ -1454,12 +1501,12 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
QStringList names;
names << (*m)->name();
- if ((*m)->type() == Node::Function) {
+ if ((*m)->nodeType() == Node::Function) {
const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m);
if (func->isSomeCtor() || func->isDtor() || func->overloadNumber() != 0)
names.clear();
}
- else if ((*m)->type() == Node::Property) {
+ else if ((*m)->nodeType() == Node::Property) {
const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m);
if (!prop->getters().isEmpty() &&
!names.contains(prop->getters().first()->name()))
@@ -1471,7 +1518,7 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
if (!prop->notifiers().isEmpty())
names << prop->notifiers().first()->name();
}
- else if ((*m)->type() == Node::Enum) {
+ else if ((*m)->nodeType() == Node::Enum) {
const EnumNode *enume = reinterpret_cast<const EnumNode*>(*m);
if (enume->flagsType())
names << enume->flagsType()->name();
@@ -1511,7 +1558,7 @@ void HtmlGenerator::generateQmlTypePage(QmlTypeNode* qcn, CodeMarker* marker)
generateTableOfContents(qcn, marker, &sections.stdQmlTypeSummarySections());
marker = CodeMarker::markerForLanguage(QLatin1String("QML"));
generateKeywordAnchors(qcn);
- generateTitle(htmlTitle, Text() << qcn->subTitle(), subTitleSize, qcn, marker);
+ generateTitle(htmlTitle, Text() << qcn->subtitle(), subTitleSize, qcn, marker);
generateBrief(qcn, marker);
generateQmlRequisites(qcn, marker);
@@ -1591,7 +1638,7 @@ void HtmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker*
generateTableOfContents(qbtn,marker,&sections.stdQmlTypeSummarySections());
generateKeywordAnchors(qbtn);
generateTitle(htmlTitle,
- Text() << qbtn->subTitle(),
+ Text() << qbtn->subtitle(),
subTitleSize,
qbtn,
marker);
@@ -1634,97 +1681,40 @@ 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.
+ to any underlying parsable C++, QML, or Javascript element.
*/
-void HtmlGenerator::generateDocumentNode(DocumentNode* dn, CodeMarker* marker)
+void HtmlGenerator::generatePageNode(PageNode* pn, CodeMarker* marker)
{
- /*
- If the document node is a page node, and if the page type
- is DITA map page, write the node's contents as a dita
- map and return without doing anything else.
- */
- if (dn->docSubtype() == Node::Page && dn->pageType() == Node::DitaMapPage) {
- const DitaMapNode* dmn = static_cast<const DitaMapNode*>(dn);
- writeDitaMap(dmn);
- return;
- }
-
SubTitleSize subTitleSize = LargeSubTitle;
- Sections sections(dn);
- QString fullTitle = dn->fullTitle();
+ QString fullTitle = pn->fullTitle();
- generateHeader(fullTitle, dn, marker);
+ generateHeader(fullTitle, pn, marker);
/*
Generate the TOC for the new doc format.
Don't generate a TOC for the home page.
*/
- if ((dn->name() != QLatin1String("index.html")))
- generateTableOfContents(dn,marker, nullptr);
+ if ((pn->name() != QLatin1String("index.html")))
+ generateTableOfContents(pn,marker,nullptr);
- generateKeywordAnchors(dn);
+ generateKeywordAnchors(pn);
generateTitle(fullTitle,
- Text() << dn->subTitle(),
+ Text() << pn->subtitle(),
subTitleSize,
- dn,
+ pn,
marker);
- if (dn->isExample()) {
- generateBrief(dn, marker, nullptr, false);
- } else if (dn->docSubtype() == Node::HeaderFile) {
- // Generate brief text and status for modules.
- generateBrief(dn, marker);
- generateStatus(dn, marker);
- generateSince(dn, marker);
-
- out() << "<ul>\n";
-
- QString membersLink = generateAllMembersFile(Sections::allMembersSection(), marker);
- if (!membersLink.isEmpty())
- out() << "<li><a href=\"" << membersLink << "\">"
- << "List of all members, including inherited members</a></li>\n";
-
- QString obsoleteLink = generateObsoleteMembersFile(sections, marker);
- if (!obsoleteLink.isEmpty()) {
- out() << "<li><a href=\"" << obsoleteLink << "\">"
- << "Obsolete members</a></li>\n";
- }
-
- out() << "</ul>\n";
+ if (pn->isExample()) {
+ generateBrief(pn, marker, nullptr, false);
}
- SectionVector::const_iterator s = sections.stdSummarySections().constBegin();
- while (s != sections.stdSummarySections().constEnd()) {
- if (!s->isEmpty()) {
- QString ref = registerRef(s->title());
- out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n';
- out() << "<h2 id=\"" << ref << "\">" << protectEnc(s->title()) << "</h2>\n";
- generateSectionList(*s, dn, marker);
- }
- ++s;
- }
-
- generateExtractionMark(dn, DetailedDescriptionMark);
+ generateExtractionMark(pn, DetailedDescriptionMark);
out() << "<div class=\"descr\"> <a name=\"" << registerRef("details") << "\"></a>\n"; // QTBUG-9504
- generateBody(dn, marker);
+ generateBody(pn, marker);
out() << "</div>\n"; // QTBUG-9504
- generateAlsoList(dn, marker);
- generateExtractionMark(dn, EndMark);
-
- s = sections.stdDetailsSections().constBegin();
- while (s != sections.stdDetailsSections().constEnd()) {
- //out() << "<hr />\n";
- if (!s->isEmpty()) {
- out() << "<h2>" << protectEnc(s->title()) << "</h2>\n";
+ generateAlsoList(pn, marker);
+ generateExtractionMark(pn, EndMark);
- NodeVector::ConstIterator m = s->members().constBegin();
- while (m != s->members().constEnd()) {
- generateDetailedMember(*m, dn, marker);
- ++m;
- }
- }
- ++s;
- }
- generateFooter(dn);
+ generateFooter(pn);
}
/*!
@@ -1739,7 +1729,7 @@ void HtmlGenerator::generateCollectionNode(CollectionNode* cn, CodeMarker* marke
generateHeader(fullTitle, cn, marker);
generateTableOfContents(cn,marker, nullptr);
generateKeywordAnchors(cn);
- generateTitle(fullTitle, Text() << cn->subTitle(), subTitleSize, cn, marker);
+ generateTitle(fullTitle, Text() << cn->subtitle(), subTitleSize, cn, marker);
if (cn->isModule()) {
// Generate brief text and status for modules.
@@ -1866,15 +1856,7 @@ void HtmlGenerator::generateNavigationBar(const QString &title,
<< Atom(itemRight);
}
else {
- if (node->isExampleFile()) {
- navigationbar << Atom(itemLeft)
- << Atom(Atom::NavLink, node->parent()->name())
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, node->parent()->title())
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(itemRight);
-
- } else if (node->isAggregate()) {
+ if (node->isAggregate()) {
QStringList groups = static_cast<const Aggregate*>(node)->groupNames();
if (groups.length() == 1) {
const Node *groupNode = qdb_->findNodeByNameAndType(QStringList(groups[0]), Node::Group);
@@ -2062,7 +2044,7 @@ void HtmlGenerator::generateHeader(const QString& title,
}
void HtmlGenerator::generateTitle(const QString& title,
- const Text &subTitle,
+ const Text &subtitle,
SubTitleSize subTitleSize,
const Node *relative,
CodeMarker *marker)
@@ -2070,13 +2052,13 @@ void HtmlGenerator::generateTitle(const QString& title,
out() << QString(prologue).replace("\\" + COMMAND_VERSION, qdb_->version());
if (!title.isEmpty())
out() << "<h1 class=\"title\">" << protectEnc(title) << "</h1>\n";
- if (!subTitle.isEmpty()) {
+ if (!subtitle.isEmpty()) {
out() << "<span";
if (subTitleSize == SmallSubTitle)
out() << " class=\"small-subtitle\">";
else
out() << " class=\"subtitle\">";
- generateText(subTitle, relative, marker);
+ generateText(subtitle, relative, marker);
out() << "</span>\n";
}
}
@@ -2143,10 +2125,10 @@ void HtmlGenerator::generateRequisites(Aggregate *aggregate, CodeMarker *marker)
requisites.insert(sinceText, text);
}
- if (aggregate->type() == Node::Class || aggregate->type() == Node::Namespace) {
+ if (aggregate->nodeType() == Node::Class || aggregate->nodeType() == Node::Namespace) {
//add the QT variable to the map
if (!aggregate->physicalModuleName().isEmpty()) {
- const CollectionNode* cn = qdb_->getCollectionNode(aggregate->physicalModuleName(), Node::CPP);
+ const CollectionNode* cn = qdb_->getCollectionNode(aggregate->physicalModuleName(), Node::Module);
if (cn && !cn->qtVariable().isEmpty()) {
text.clear();
text << "QT += " + cn->qtVariable();
@@ -2155,7 +2137,7 @@ void HtmlGenerator::generateRequisites(Aggregate *aggregate, CodeMarker *marker)
}
}
- if (aggregate->type() == Node::Class) {
+ if (aggregate->nodeType() == Node::Class) {
ClassNode* classe = static_cast<ClassNode*>(aggregate);
if (classe->qmlElement() != nullptr && classe->status() != Node::Internal) {
text.clear();
@@ -2255,7 +2237,7 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker)
//add the module name and version to the map
QString logicalModuleVersion;
- const CollectionNode* collection = qdb_->getCollectionNode(qcn->logicalModuleName(), qcn->genus());
+ const CollectionNode* collection = qdb_->getCollectionNode(qcn->logicalModuleName(), qcn->nodeType());
if (collection)
logicalModuleVersion = collection->logicalModuleVersion();
else
@@ -2372,6 +2354,10 @@ void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
}
}
+/*!
+ This function is not used currently.
+ It should be removed. MWS 27-06-2018
+ */
void HtmlGenerator::generateIncludes(const Aggregate *aggregate, CodeMarker *marker)
{
if (!aggregate->includes().isEmpty()) {
@@ -2700,8 +2686,9 @@ QString HtmlGenerator::generateObsoleteQmlMembersFile(const Sections &sections,
for (int i = 0; i < details_spv.size(); ++i) {
out() << "<h2>" << protectEnc(details_spv.at(i)->title()) << "</h2>\n";
- NodeVector::ConstIterator m = details_spv.at(i)->members().constBegin();
- while (m != details_spv.at(i)->members().constEnd()) {
+ const NodeVector &members = details_spv.at(i)->obsoleteMembers();
+ NodeVector::ConstIterator m = members.constBegin();
+ while (m != members.constEnd()) {
generateDetailedQmlMember(*m, aggregate, marker);
out() << "<br/>\n";
++m;
@@ -2799,7 +2786,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative,
generateFullName(node, relative);
out() << "</p></td>";
- if (!node->isDocumentNode()) {
+ if (!node->isTextPageNode()) {
Text brief = node->doc().trimmedBriefText(node->name());
if (!brief.isEmpty()) {
out() << "<td class=\"tblDescr\"><p>";
@@ -3118,18 +3105,18 @@ void HtmlGenerator::generateQmlItem(const Node *node,
void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const QString& selector)
{
CNMap cnm;
- Node::Genus genus = Node::DontCare;
+ Node::NodeType type = Node::NoType;
if (selector == QLatin1String("overviews"))
- genus = Node::DOC;
+ type = Node::Group;
else if (selector == QLatin1String("cpp-modules"))
- genus = Node::CPP;
+ type = Node::Module;
else if (selector == QLatin1String("qml-modules"))
- genus = Node::QML;
+ type = Node::QmlModule;
else if (selector == QLatin1String("js-modules"))
- genus = Node::JS;
- if (genus != Node::DontCare) {
+ type = Node::JsModule;
+ if (type != Node::NoType) {
NodeList nl;
- qdb_->mergeCollections(genus, cnm, relative);
+ qdb_->mergeCollections(type, cnm, relative);
CollectionList cl = cnm.values();
foreach (CollectionNode* cn, cl)
nl.append(cn);
@@ -3158,7 +3145,7 @@ void HtmlGenerator::generateSection(const NodeVector& nv, const Node *relative,
bool alignNames = true;
if (!nv.isEmpty()) {
bool twoColumn = false;
- if (nv.first()->type() == Node::Property) {
+ if (nv.first()->nodeType() == Node::Property) {
twoColumn = (nv.count() >= 5);
alignNames = false;
}
@@ -3222,7 +3209,7 @@ void HtmlGenerator::generateSectionList(const Section& section,
alignNames = false;
twoColumn = (members.count() >= 16);
}
- else if (members.first()->type() == Node::Property) {
+ else if (members.first()->nodeType() == Node::Property) {
twoColumn = (members.count() >= 5);
alignNames = false;
}
@@ -3623,51 +3610,58 @@ QString HtmlGenerator::fileBase(const Node *node) const
QString HtmlGenerator::fileName(const Node *node)
{
- if (node->type() == Node::Document) {
- if (static_cast<const DocumentNode *>(node)->docSubtype() == Node::ExternalPage)
- return node->name();
- if (static_cast<const DocumentNode *>(node)->docSubtype() == Node::Image)
- return node->name();
- }
+ if (node->isExternalPage())
+ return node->name();
return Generator::fileName(node);
}
QString HtmlGenerator::refForNode(const Node *node)
{
- const FunctionNode *func;
- const TypedefNode *typedeffe;
QString ref;
-
- switch (node->type()) {
- case Node::Namespace:
- case Node::Class:
- default:
- break;
+ switch (node->nodeType()) {
case Node::Enum:
ref = node->name() + "-enum";
break;
case Node::Typedef:
- typedeffe = static_cast<const TypedefNode *>(node);
- if (typedeffe->associatedEnum()) {
- return refForNode(typedeffe->associatedEnum());
- }
- else {
- ref = node->name() + "-typedef";
+ {
+ const TypedefNode* tdn = static_cast<const TypedefNode *>(node);
+ if (tdn->associatedEnum())
+ return refForNode(tdn->associatedEnum());
+ else
+ ref = node->name() + "-typedef";
}
break;
case Node::Function:
- func = static_cast<const FunctionNode *>(node);
- if (func->hasOneAssociatedProperty() && func->doc().isEmpty()) {
- return refForNode(func->firstAssociatedProperty());
- }
- else {
- ref = func->name();
- if (func->overloadNumber() != 0)
- ref += QLatin1Char('-') + QString::number(func->overloadNumber());
+ {
+ const FunctionNode *fn = static_cast<const FunctionNode *>(node);
+ switch (fn->metaness()) {
+ case FunctionNode::JsSignal:
+ case FunctionNode::QmlSignal:
+ ref = fn->name() + "-signal";
+ break;
+ case FunctionNode::JsSignalHandler:
+ case FunctionNode::QmlSignalHandler:
+ ref = fn->name() + "-signal-handler";
+ break;
+ case FunctionNode::JsMethod:
+ case FunctionNode::QmlMethod:
+ ref = fn->name() + "-method";
+ if (fn->overloadNumber() != 0)
+ ref += QLatin1Char('-') + QString::number(fn->overloadNumber());
+ break;
+ default:
+ if (fn->hasOneAssociatedProperty() && fn->doc().isEmpty()) {
+ return refForNode(fn->firstAssociatedProperty());
+ } else {
+ ref = fn->name();
+ if (fn->overloadNumber() != 0)
+ ref += QLatin1Char('-') + QString::number(fn->overloadNumber());
+ }
+ break;
+ }
}
break;
- case Node::Document:
- break;
+ case Node::JsProperty:
case Node::QmlProperty:
if (node->isAttached())
ref = node->name() + "-attached-prop";
@@ -3675,24 +3669,15 @@ QString HtmlGenerator::refForNode(const Node *node)
ref = node->name() + "-prop";
break;
case Node::QmlPropertyGroup:
+ case Node::JsPropertyGroup:
case Node::Property:
ref = node->name() + "-prop";
break;
- case Node::QmlSignal:
- ref = node->name() + "-signal";
- break;
- case Node::QmlSignalHandler:
- ref = node->name() + "-signal-handler";
- break;
- case Node::QmlMethod:
- func = static_cast<const FunctionNode *>(node);
- ref = func->name() + "-method";
- if (func->overloadNumber() != 0)
- ref += QLatin1Char('-') + QString::number(func->overloadNumber());
- break;
case Node::Variable:
ref = node->name() + "-var";
break;
+ default:
+ break;
}
return registerRef(ref);
}
@@ -3749,11 +3734,12 @@ QString HtmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const
}
QString link = (*node)->url();
- if (link.isEmpty()) {
+ if (link.isEmpty())
link = linkForNode(*node, relative);
- if ((*node)->docSubtype() == Node::Image)
+#if 0 // should never happen now; mws 13/07/2018
+ if ((*node)->nodeSubtype() == Node::Image)
link = "images/used-in-examples/" + link;
- }
+#endif
if (!ref.isEmpty()) {
int hashtag = link.lastIndexOf(QChar('#'));
if (hashtag != -1)
@@ -3941,7 +3927,7 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
int HtmlGenerator::hOffset(const Node *node)
{
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Namespace:
case Node::Class:
case Node::Module:
@@ -3949,7 +3935,7 @@ int HtmlGenerator::hOffset(const Node *node)
case Node::QmlModule:
case Node::QmlBasicType:
case Node::QmlType:
- case Node::Document:
+ case Node::Page:
return 1;
case Node::Enum:
case Node::Typedef:
@@ -3976,9 +3962,9 @@ const QPair<QString,QString> HtmlGenerator::anchorForNode(const Node *node)
QPair<QString,QString> anchorPair;
anchorPair.first = Generator::fileName(node);
- if (node->type() == Node::Document) {
- const DocumentNode *docNode = static_cast<const DocumentNode*>(node);
- anchorPair.second = docNode->title();
+ if (node->nodeType() == Node::Page) {
+ const PageNode *pn = static_cast<const PageNode*>(node);
+ anchorPair.second = pn->title();
}
return anchorPair;
@@ -3999,6 +3985,22 @@ void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker)
}
#endif
+/*!
+ This version of the function is called when outputting the link
+ to an example file or example image, where the \a link is known
+ to be correct.
+ */
+void HtmlGenerator::beginLink(const QString &link)
+{
+ link_ = link;
+ if (link_.isEmpty()) {
+ if (showBrokenLinks)
+ out() << "<i>";
+ }
+ out() << "<a href=\"" << link_ << "\">";
+ inLink_ = true;
+}
+
void HtmlGenerator::beginLink(const QString &link, const Node *node, const Node *relative)
{
link_ = link;
@@ -4047,13 +4049,13 @@ void HtmlGenerator::generateQmlSummary(const Section& section,
while (m != section.members().constEnd()) {
out() << "<li class=\"fn\">";
generateQmlItem(*m,relative,marker,true);
- if ((*m)->type() == Node::QmlPropertyGroup) {
+ if ((*m)->nodeType() == Node::QmlPropertyGroup) {
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*m);
if (!qpgn->childNodes().isEmpty()) {
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
out() << "<ul>\n";
while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
+ if ((*p)->nodeType() == Node::QmlProperty) {
out() << "<li class=\"fn\">";
generateQmlItem(*p, relative, marker, true);
out() << "</li>\n";
@@ -4096,7 +4098,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
out() << "<div class=\"qmlitem\">";
QString nodeRef = refForNode(node);
- if (node->type() == Node::QmlPropertyGroup) {
+ if (node->isQmlPropertyGroup() || node->isJsPropertyGroup()) {
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
out() << "<div class=\"qmlproto\">";
@@ -4109,7 +4111,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
out() << "<b>" << heading << "</b>";
out() << "</p></th></tr>";
while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
+ if ((*p)->isQmlProperty() || (*p)->isJsProperty()) {
qpn = static_cast<QmlPropertyNode*>(*p);
nodeRef = refForNode(qpn);
out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">";
@@ -4127,8 +4129,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
}
out() << "</table></div>";
out() << "</div>";
- }
- else if (node->type() == Node::QmlProperty) {
+ } else if (node->isQmlProperty() || node->isJsProperty()) {
qpn = static_cast<QmlPropertyNode*>(node);
out() << qmlItemHeader;
out() << qmlItemStart.arg(nodeRef, "tblQmlPropNode", refForNode(qpn));
@@ -4152,9 +4153,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
out() << "<div class=\"fngroup\">\n";
out() << qmlItemHeader;
for (const auto m : collective) {
- if (m->type() == Node::QmlSignal ||
- m->type() == Node::QmlSignalHandler ||
- m->type() == Node::QmlMethod) {
+ if (m->isFunction(Node::CPP) || m->isFunction(Node::JS)) {
out() << qmlItemStart.arg(nodeRef, "tblQmlFuncNode", refForNode(m));
generateSynopsis(m, relative, marker, Section::Details, false);
out() << qmlItemEnd;
@@ -4274,24 +4273,24 @@ void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType
if (markType != EndMark) {
out() << "<!-- $$$" + node->name();
if (markType == MemberMark) {
- if (node->type() == Node::Function) {
+ if (node->nodeType() == Node::Function) {
const FunctionNode *func = static_cast<const FunctionNode *>(node);
if (!func->hasAssociatedProperties()) {
if (func->overloadNumber() == 0)
out() << "[overload1]";
out() << "$$$" + func->name() + func->rawParameters().remove(' ');
}
- } else if (node->type() == Node::Property) {
+ } else if (node->nodeType() == Node::Property) {
out() << "-prop";
const PropertyNode *prop = static_cast<const PropertyNode *>(node);
const NodeList &list = prop->functions();
foreach (const Node *propFuncNode, list) {
- if (propFuncNode->type() == Node::Function) {
+ if (propFuncNode->nodeType() == Node::Function) {
const FunctionNode *func = static_cast<const FunctionNode *>(propFuncNode);
out() << "$$$" + func->name() + func->rawParameters().remove(' ');
}
}
- } else if (node->type() == Node::Enum) {
+ } else if (node->nodeType() == Node::Enum) {
const EnumNode *enumNode = static_cast<const EnumNode *>(node);
foreach (const EnumItem &item, enumNode->items())
out() << "$$$" + item.name();
@@ -4385,13 +4384,9 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString
QString docUrl = manifestDir + fileBase(en) + ".html";
writer.writeAttribute("docUrl", docUrl);
QStringList proFiles;
- foreach (const Node* child, en->childNodes()) {
- if (child->docSubtype() == Node::File) {
- QString file = child->name();
- if (file.endsWith(".pro") || file.endsWith(".qmlproject")) {
- proFiles << file;
- }
- }
+ foreach (const QString file, en->files()) {
+ if (file.endsWith(".pro") || file.endsWith(".qmlproject"))
+ proFiles << file;
}
if (!proFiles.isEmpty()) {
if (proFiles.size() == 1) {
@@ -4519,40 +4514,38 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString
}
QString ename = en->name().mid(en->name().lastIndexOf('/')+1);
- QMap<int, const Node*> filesToOpen;
- foreach (const Node* child, en->childNodes()) {
- if (child->docSubtype() == Node::File) {
- QFileInfo fileInfo(child->name());
- QString fileName = fileInfo.fileName().toLower();
- // open .qml, .cpp and .h files with a
- // basename matching the example (project) name
- // QMap key indicates the priority -
- // the lowest value will be the top-most file
- if ((fileInfo.baseName().compare(ename, Qt::CaseInsensitive) == 0)) {
- if (fileName.endsWith(".qml"))
- filesToOpen.insert(0, child);
- else if (fileName.endsWith(".cpp"))
- filesToOpen.insert(1, child);
- else if (fileName.endsWith(".h"))
- filesToOpen.insert(2, child);
- }
- // main.qml takes precedence over main.cpp
- else if (fileName.endsWith("main.qml")) {
- filesToOpen.insert(3, child);
- }
- else if (fileName.endsWith("main.cpp")) {
- filesToOpen.insert(4, child);
- }
+ QMap<int, QString> filesToOpen;
+ foreach (QString file, en->files()) {
+ QFileInfo fileInfo(file);
+ QString fileName = fileInfo.fileName().toLower();
+ // open .qml, .cpp and .h files with a
+ // basename matching the example (project) name
+ // QMap key indicates the priority -
+ // the lowest value will be the top-most file
+ if ((fileInfo.baseName().compare(ename, Qt::CaseInsensitive) == 0)) {
+ if (fileName.endsWith(".qml"))
+ filesToOpen.insert(0, file);
+ else if (fileName.endsWith(".cpp"))
+ filesToOpen.insert(1, file);
+ else if (fileName.endsWith(".h"))
+ filesToOpen.insert(2, file);
+ }
+ // main.qml takes precedence over main.cpp
+ else if (fileName.endsWith("main.qml")) {
+ filesToOpen.insert(3, file);
+ }
+ else if (fileName.endsWith("main.cpp")) {
+ filesToOpen.insert(4, file);
}
}
- QMap<int, const Node*>::const_iterator it = filesToOpen.constEnd();
+ QMap<int, QString>::const_iterator it = filesToOpen.constEnd();
while (it != filesToOpen.constBegin()) {
writer.writeStartElement("fileToOpen");
if (--it == filesToOpen.constBegin()) {
writer.writeAttribute(QStringLiteral("mainFile"), QStringLiteral("true"));
}
- writer.writeCharacters(examplesPath + it.value()->name());
+ writer.writeCharacters(examplesPath + it.value());
writer.writeEndElement();
}
@@ -4592,19 +4585,6 @@ void HtmlGenerator::readManifestMetaContent(const Config &config)
Find global entities that have documentation but no
\e{relates} comand. Report these as errors if they
are not also marked \e {internal}.
-
- type: Class
- type: Namespace
-
- subtype: Example
- subtype: External page
- subtype: Group
- subtype: Header file
- subtype: Module
- subtype: Page
- subtype: QML basic type
- subtype: QML class
- subtype: QML module
*/
void HtmlGenerator::reportOrphans(const Aggregate* parent)
{
@@ -4612,93 +4592,57 @@ void HtmlGenerator::reportOrphans(const Aggregate* parent)
if (children.size() == 0)
return;
- bool related;
- QString message;
+ QString message = "has documentation but no \\relates command";
for (int i=0; i<children.size(); ++i) {
Node* child = children[i];
- if (!child || child->isInternal() || child->doc().isEmpty())
+ if (!child || child->isInternal() || child->doc().isEmpty() || child->relates())
continue;
- if (child->relates()) {
- related = true;
- message = child->relates()->name();
- }
- else {
- related = false;
- message = "has documentation but no \\relates command";
- }
- switch (child->type()) {
- case Node::Namespace:
- break;
- case Node::Class:
- break;
- case Node::QmlType:
- break;
- case Node::QmlBasicType:
- break;
- case Node::Group:
- break;
- case Node::Module:
- break;
- case Node::QmlModule:
- break;
- case Node::Document:
- switch (child->docSubtype()) {
- case Node::Example:
- break;
- case Node::HeaderFile:
- break;
- case Node::File:
- break;
- case Node::Image:
- break;
- case Node::Page:
- break;
- case Node::ExternalPage:
- break;
- default:
- break;
- }
- break;
+ switch (child->nodeType()) {
case Node::Enum:
- if (!related)
- child->location().warning(tr("Global enum, %1, %2").arg(child->name()).arg(message));
+ child->location().warning(tr("Global enum, %1, %2").arg(child->name()).arg(message));
break;
case Node::Typedef:
- if (!related)
- child->location().warning(tr("Global typedef, %1, %2").arg(child->name()).arg(message));
+ child->location().warning(tr("Global typedef, %1, %2").arg(child->name()).arg(message));
break;
case Node::Function:
- if (!related) {
+ {
const FunctionNode* fn = static_cast<const FunctionNode*>(child);
- if (fn->isMacro())
- child->location().warning(tr("Global macro, %1, %2").arg(child->name()).arg(message));
- else
- child->location().warning(tr("Global function, %1(), %2").arg(child->name()).arg(message));
+ switch (fn->metaness()) {
+ case FunctionNode::QmlSignal:
+ child->location().warning(tr("Global QML, signal, %1 %2").arg(child->name()).arg(message));
+ break;
+ case FunctionNode::QmlSignalHandler:
+ child->location().warning(tr("Global QML signal handler, %1, %2").arg(child->name()).arg(message));
+ break;
+ case FunctionNode::QmlMethod:
+ child->location().warning(tr("Global QML method, %1, %2").arg(child->name()).arg(message));
+ break;
+ case FunctionNode::JsSignal:
+ child->location().warning(tr("Global JS, signal, %1 %2").arg(child->name()).arg(message));
+ break;
+ case FunctionNode::JsSignalHandler:
+ child->location().warning(tr("Global JS signal handler, %1, %2").arg(child->name()).arg(message));
+ break;
+ case FunctionNode::JsMethod:
+ child->location().warning(tr("Global JS method, %1, %2").arg(child->name()).arg(message));
+ break;
+ default:
+ if (fn->isMacro())
+ child->location().warning(tr("Global macro, %1, %2").arg(child->name()).arg(message));
+ else
+ child->location().warning(tr("Global function, %1(), %2").arg(child->name()).arg(message));
+ break;
+ }
+ break;
}
- break;
- case Node::Property:
- break;
case Node::Variable:
- if (!related)
- child->location().warning(tr("Global variable, %1, %2").arg(child->name()).arg(message));
+ child->location().warning(tr("Global variable, %1, %2").arg(child->name()).arg(message));
break;
- case Node::QmlPropertyGroup:
+ case Node::JsProperty:
+ child->location().warning(tr("Global JS property, %1, %2").arg(child->name()).arg(message));
break;
case Node::QmlProperty:
- if (!related)
- child->location().warning(tr("Global QML property, %1, %2").arg(child->name()).arg(message));
- break;
- case Node::QmlSignal:
- if (!related)
- child->location().warning(tr("Global QML, signal, %1 %2").arg(child->name()).arg(message));
- break;
- case Node::QmlSignalHandler:
- if (!related)
- child->location().warning(tr("Global QML signal handler, %1, %2").arg(child->name()).arg(message));
- break;
- case Node::QmlMethod:
- if (!related)
- child->location().warning(tr("Global QML method, %1, %2").arg(child->name()).arg(message));
+ child->location().warning(tr("Global QML property, %1, %2").arg(child->name()).arg(message));
break;
default:
break;
@@ -4720,91 +4664,6 @@ QXmlStreamWriter& HtmlGenerator::xmlWriter()
}
/*!
- This function is only called for writing ditamaps.
-
- Calls beginSubPage() in the base class to open the file.
- Then creates a new XML stream writer using the IO device
- from opened file and pushes the XML writer onto a stackj.
- Creates the file named \a fileName in the output directory.
- Attaches a QTextStream to the created file, which is written
- to all over the place using out(). Finally, it sets some
- parameters in the XML writer and calls writeStartDocument().
-
- It also ensures that a GUID map is created for the output file.
- */
-void HtmlGenerator::beginDitamapPage(const Aggregate* node, const QString& fileName)
-{
- Generator::beginSubPage(node,fileName);
- QXmlStreamWriter* writer = new QXmlStreamWriter(out().device());
- xmlWriterStack.push(writer);
- writer->setAutoFormatting(true);
- writer->setAutoFormattingIndent(4);
- writer->writeStartDocument();
-}
-
-/*!
- This function is only called for writing ditamaps.
-
- Calls writeEndDocument() and then pops the XML stream writer
- off the stack and deletes it. Then it calls endSubPage() in
- the base class to close the device.
- */
-void HtmlGenerator::endDitamapPage()
-{
- xmlWriter().writeEndDocument();
- delete xmlWriterStack.pop();
- Generator::endSubPage();
-}
-
-/*!
- This function is only called for writing ditamaps.
-
- Creates the DITA map from the topicrefs in \a node,
- which is a DitaMapNode.
- */
-void HtmlGenerator::writeDitaMap(const DitaMapNode* node)
-{
- beginDitamapPage(node,node->name());
-
- QString doctype = "<!DOCTYPE map PUBLIC \"-//OASIS//DTD DITA Map//EN\" \"map.dtd\">";
-
- xmlWriter().writeDTD(doctype);
- xmlWriter().writeStartElement("map");
- xmlWriter().writeStartElement("topicmeta");
- xmlWriter().writeStartElement("shortdesc");
- xmlWriter().writeCharacters(node->title());
- xmlWriter().writeEndElement(); // </shortdesc>
- xmlWriter().writeEndElement(); // </topicmeta>
- DitaRefList map = node->map();
- writeDitaRefs(map);
- endDitamapPage();
-}
-
-/*!
- Write the \a ditarefs to the current output file.
- */
-void HtmlGenerator::writeDitaRefs(const DitaRefList& ditarefs)
-{
- foreach (DitaRef* t, ditarefs) {
- if (t->isMapRef())
- xmlWriter().writeStartElement("mapref");
- else
- xmlWriter().writeStartElement("topicref");
- xmlWriter().writeAttribute("navtitle",t->navtitle());
- if (t->href().isEmpty()) {
- const DocumentNode* dn = qdb_->findDocumentNodeByTitle(t->navtitle());
- if (dn)
- xmlWriter().writeAttribute("href",fileName(dn));
- }
- else
- xmlWriter().writeAttribute("href",t->href());
- if (t->subrefs() && !t->subrefs()->isEmpty())
- writeDitaRefs(*(t->subrefs()));
- xmlWriter().writeEndElement(); // </topicref> or </mapref>
- }
-}
-
-/*!
Generates bold Note lines that explain how function \a fn
is associated with each of its associated properties.
*/
diff --git a/src/qdoc/htmlgenerator.h b/src/qdoc/htmlgenerator.h
index 4ad85653f..8d50d0e22 100644
--- a/src/qdoc/htmlgenerator.h
+++ b/src/qdoc/htmlgenerator.h
@@ -73,7 +73,7 @@ protected:
void generateCppReferencePage(Node* node, CodeMarker* marker) override;
void generateQmlTypePage(QmlTypeNode* qcn, CodeMarker* marker) override;
void generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker) override;
- void generateDocumentNode(DocumentNode* dn, CodeMarker* marker) override;
+ void generatePageNode(PageNode* pn, CodeMarker* marker) override;
void generateCollectionNode(CollectionNode* cn, CodeMarker* marker) override;
QString fileExtension() const override;
virtual QString refForNode(const Node *node);
@@ -192,15 +192,12 @@ private:
#ifdef GENERATE_MAC_REFS
void generateMacRef(const Node *node, CodeMarker *marker);
#endif
+ void beginLink(const QString &link);
void beginLink(const QString &link, const Node *node, const Node *relative);
void endLink();
void generateExtractionMark(const Node *node, ExtractionMarkType markType);
void reportOrphans(const Aggregate* parent);
- void beginDitamapPage(const Aggregate* node, const QString& fileName);
- void endDitamapPage();
- void writeDitaMap(const DitaMapNode* node);
- void writeDitaRefs(const DitaRefList& ditarefs);
QXmlStreamWriter& xmlWriter();
QHash<QString, QString> refMap;
@@ -255,7 +252,7 @@ public:
inline bool HtmlGenerator::hasBrief(const Node *node)
{
return !(node->isQmlType()
- || node->isDocumentNode()
+ || node->isPageNode()
|| node->isCollectionNode()
|| node->isJsType());
}
diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp
index e23b10d57..6e6202f76 100644
--- a/src/qdoc/node.cpp
+++ b/src/qdoc/node.cpp
@@ -54,40 +54,93 @@ QMap<QString,Node::NodeType> Node::goals_;
*/
void Node::initialize()
{
+ goals_.insert("namespace", Node::Namespace);
goals_.insert("class", Node::Class);
- goals_.insert("qmltype", Node::QmlType);
- goals_.insert("page", Node::Document);
+ goals_.insert("header", Node::HeaderFile);
+ goals_.insert("headerfile", Node::HeaderFile);
+ goals_.insert("page", Node::Page);
+ goals_.insert("enum", Node::Enum);
+ goals_.insert("example", Node::Example);
+ goals_.insert("externalpage", Node::ExternalPage);
+ goals_.insert("typedef", Node::Typedef);
+ goals_.insert("typealias", Node::Typedef);
goals_.insert("function", Node::Function);
goals_.insert("property", Node::Property);
goals_.insert("variable", Node::Variable);
goals_.insert("group", Node::Group);
goals_.insert("module", Node::Module);
+ goals_.insert("qmltype", Node::QmlType);
goals_.insert("qmlmodule", Node::QmlModule);
goals_.insert("qmppropertygroup", Node::QmlPropertyGroup);
goals_.insert("qmlproperty", Node::QmlProperty);
- goals_.insert("qmlsignal", Node::QmlSignal);
- goals_.insert("qmlsignalhandler", Node::QmlSignalHandler);
- goals_.insert("qmlmethod", Node::QmlMethod);
+ goals_.insert("qmlsignal", Node::Function);
+ goals_.insert("qmlsignalhandler", Node::Function);
+ goals_.insert("qmlmethod", Node::Function);
goals_.insert("qmlbasictype", Node::QmlBasicType);
- goals_.insert("enum", Node::Enum);
- goals_.insert("typealias", Node::Typedef);
- goals_.insert("typedef", Node::Typedef);
- goals_.insert("namespace", Node::Namespace);
+ goals_.insert("sharedcomment", Node::SharedComment);
+ goals_.insert("collection", Node::Collection);
+}
+
+/*!
+ If this Node's type is \a from, change the type to \a to
+ and return \c true. Otherwise return false. This function
+ is used to change Qml node types to Javascript node types,
+ because these nodes are created as Qml nodes before it is
+ discovered that the entity represented by the node is not
+ Qml but javascript.
+
+ Note that if the function returns true, which means the node
+ type was indeed changed, then the node's Genus is also changed
+ from QML to JS.
+
+ The function also works in the other direction, but there is
+ no use case for that.
+ */
+bool Node::changeType(NodeType from, NodeType to)
+{
+ if (nodeType_ == from) {
+ nodeType_ = to;
+ switch (to) {
+ case QmlType:
+ case QmlModule:
+ case QmlPropertyGroup:
+ case QmlProperty:
+ case QmlBasicType:
+ setGenus(Node::QML);
+ break;
+ case JsType:
+ case JsModule:
+ case JsPropertyGroup:
+ case JsProperty:
+ case JsBasicType:
+ setGenus(Node::JS);
+ break;
+ default:
+ setGenus(Node::CPP);
+ break;
+ }
+ return true;
+ }
+ return false;
}
+/*!
+ Returns \c true if the node \a n1 is less than node \a n2. The
+ comparison is performed by comparing properties of the nodes
+ in order of increasing complexity.
+ */
bool Node::nodeNameLessThan(const Node *n1, const Node *n2)
{
- if (n1->isAggregate() && n2->isAggregate()) {
- const Aggregate* f1 = static_cast<const Aggregate*>(n1);
- const Aggregate* f2 = static_cast<const Aggregate*>(n2);
-
+ if (n1->isPageNode() && n2->isPageNode()) {
+ const PageNode* f1 = static_cast<const PageNode*>(n1);
+ const PageNode* f2 = static_cast<const PageNode*>(n2);
if (f1->fullTitle() < f2->fullTitle())
return true;
else if (f1->fullTitle() > f2->fullTitle())
return false;
}
- if (n1->type() == Node::Function && n2->type() == Node::Function) {
+ if (n1->nodeType() == Node::Function && n2->nodeType() == Node::Function) {
const FunctionNode* f1 = static_cast<const FunctionNode*>(n1);
const FunctionNode* f2 = static_cast<const FunctionNode*>(n2);
@@ -107,9 +160,9 @@ bool Node::nodeNameLessThan(const Node *n1, const Node *n2)
else if (n1->location().filePath() > n2->location().filePath())
return false;
- if (n1->type() < n2->type())
+ if (n1->nodeType() < n2->nodeType())
return true;
- else if (n1->type() > n2->type())
+ else if (n1->nodeType() > n2->nodeType())
return false;
if (n1->name() < n2->name())
@@ -162,13 +215,13 @@ Node::~Node()
Removes this node from the aggregate's list of related
nodes, or if this node has created a dummy "relates"
aggregate, deletes it.
-*/
+ */
void Node::removeRelates()
{
if (!relatesTo_)
return;
- if (relatesTo_->isDocumentNode() && !relatesTo_->parent()) {
+ if (relatesTo_->isDummyNode() && !relatesTo_->parent()) {
delete relatesTo_;
relatesTo_ = 0;
} else {
@@ -240,32 +293,21 @@ QString Node::plainSignature() const
*/
QString Node::fullName(const Node* relative) const
{
- if ((isDocumentNode() || isGroup()) && !title().isEmpty())
+ if ((isTextPageNode() || isGroup()) && !title().isEmpty())
return title();
return plainFullName(relative);
}
/*!
- Try to match this node's type and subtype with one of the
- pairs in \a types. If a match is found, return true. If no
- match is found, return false.
-
- \a types is a list of type/subtype pairs, where the first
- value in the pair is a Node::NodeType, and the second value is
- a Node::DocSubtype. The second value is used in the match if
- this node's type is Node::Document.
+ Try to match this node's type with one of the \a types.
+ If a match is found, return true. If no match is found,
+ return false.
*/
-bool Node::match(const NodeTypeList& types) const
+bool Node::match(const QList<int>& types) const
{
for (int i=0; i<types.size(); ++i) {
- if (type() == types.at(i).first) {
- if (type() == Node::Document) {
- if (docSubtype() == types.at(i).second)
- return true;
- }
- else
- return true;
- }
+ if (nodeType() == types.at(i))
+ return true;
}
return false;
}
@@ -350,6 +392,95 @@ Node::Node(NodeType type, Aggregate *parent, const QString& name)
operators_.insert("new[]","new-array");
operators_.insert("new","new");
}
+ setPageType(getPageType(type));
+ setGenus(getGenus(type));
+}
+
+/*!
+ Determines the appropriate PageType value for the NodeType
+ value \a t and returns that PageType value.
+ */
+Node::PageType Node::getPageType(Node::NodeType t)
+{
+ switch (t) {
+ case Node::Namespace:
+ case Node::Class:
+ case Node::HeaderFile:
+ case Node::Enum:
+ case Node::Function:
+ case Node::Typedef:
+ case Node::Property:
+ case Node::Variable:
+ case Node::QmlType:
+ case Node::QmlPropertyGroup:
+ case Node::QmlProperty:
+ case Node::QmlBasicType:
+ case Node::JsType:
+ case Node::JsPropertyGroup:
+ case Node::JsProperty:
+ case Node::JsBasicType:
+ case Node::SharedComment:
+ return Node::ApiPage;
+ case Node::Example:
+ return Node::ExamplePage;
+ case Node::Page:
+ case Node::ExternalPage:
+ return Node::NoPageType;
+ case Node::Group:
+ case Node::Module:
+ case Node::QmlModule:
+ case Node::JsModule:
+ case Node::Collection:
+ return Node::OverviewPage;
+ default:
+ return Node::NoPageType;
+ }
+}
+
+/*!
+ Determines the appropriate Genus value for the NodeType
+ value \a t and returns that Genus value. Note that this
+ function is called in the Node() constructor. It always
+ returns Node::CPP when \a t is Node::Function, which
+ means the FunctionNode() constructor must determine its
+ own Genus value separately, because class FunctionNode
+ is a subclass of Node.
+ */
+Node::Genus Node::getGenus(Node::NodeType t)
+{
+ switch (t) {
+ case Node::Enum:
+ case Node::Class:
+ case Node::Module:
+ case Node::Typedef:
+ case Node::Property:
+ case Node::Variable:
+ case Node::Function:
+ case Node::Namespace:
+ case Node::HeaderFile:
+ return Node::CPP;
+ case Node::QmlType:
+ case Node::QmlModule:
+ case Node::QmlProperty:
+ case Node::QmlBasicType:
+ case Node::QmlPropertyGroup:
+ return Node::QML;
+ case Node::JsType:
+ case Node::JsModule:
+ case Node::JsProperty:
+ case Node::JsBasicType:
+ case Node::JsPropertyGroup:
+ return Node::JS;
+ case Node::Page:
+ case Node::Group:
+ case Node::Example:
+ case Node::ExternalPage:
+ return Node::DOC;
+ case Node::Collection:
+ case Node::SharedComment:
+ default:
+ return Node::DontCare;
+ }
}
/*! \fn QString Node::url() const
@@ -377,25 +508,23 @@ QString Node::pageTypeString(unsigned char t)
{
switch ((PageType)t) {
case Node::AttributionPage:
- return "attribution";
+ return QLatin1String("attribution");
case Node::ApiPage:
- return "api";
+ return QLatin1String("api");
case Node::ArticlePage:
- return "article";
+ return QLatin1String("article");
case Node::ExamplePage:
- return "example";
+ return QLatin1String("example");
case Node::HowToPage:
- return "howto";
+ return QLatin1String("howto");
case Node::OverviewPage:
- return "overview";
+ return QLatin1String("overview");
case Node::TutorialPage:
- return "tutorial";
+ return QLatin1String("tutorial");
case Node::FAQPage:
- return "faq";
- case Node::DitaMapPage:
- return "ditamap";
+ return QLatin1String("faq");
default:
- return "article";
+ return QLatin1String("article");
}
}
@@ -405,7 +534,11 @@ QString Node::pageTypeString(unsigned char t)
*/
QString Node::nodeTypeString() const
{
- return nodeTypeString(type());
+ if (isFunction()) {
+ const FunctionNode *fn = static_cast<const FunctionNode*>(this);
+ return fn->kindString();
+ }
+ return nodeTypeString(nodeType());
}
/*!
@@ -416,82 +549,58 @@ QString Node::nodeTypeString(unsigned char t)
{
switch ((NodeType)t) {
case Namespace:
- return "namespace";
+ return QLatin1String("namespace");
case Class:
- return "class";
- case Document:
- return "document";
+ return QLatin1String("class");
+ case HeaderFile:
+ return QLatin1String("header");
+ case Page:
+ return QLatin1String("page");
case Enum:
- return "enum";
+ return QLatin1String("enum");
+ case Example:
+ return QLatin1String("example");
+ case ExternalPage:
+ return QLatin1String("external page");
case Typedef:
- return "typedef";
+ return QLatin1String("typedef");
case Function:
- return "function";
+ return QLatin1String("function");
case Property:
- return "property";
+ return QLatin1String("property");
case Variable:
- return "variable";
+ return QLatin1String("variable");
case Group:
- return "group";
+ return QLatin1String("group");
case Module:
- return "module";
+ return QLatin1String("module");
+
case QmlType:
- return "QML type";
+ return QLatin1String("QML type");
case QmlBasicType:
- return "QML basic type";
+ return QLatin1String("QML basic type");
case QmlModule:
- return "QML module";
+ return QLatin1String("QML module");
case QmlProperty:
- return "QML property";
+ return QLatin1String("QML property");
case QmlPropertyGroup:
- return "QML property group";
- case QmlSignal:
- return "QML signal";
- case QmlSignalHandler:
- return "QML signal handler";
- case QmlMethod:
- return "QML method";
- case SharedComment:
- return "shared comment";
- default:
- break;
- }
- return QString();
-}
-
-/*!
- Returns this node's subtype as a string for use as an
- attribute value in XML or HTML. This is only useful
- in the case where the node type is Document.
- */
-QString Node::nodeSubtypeString() const
-{
- return nodeSubtypeString(docSubtype());
-}
+ return QLatin1String("QML property group");
+
+ case JsType:
+ return QLatin1String("JS type");
+ case JsBasicType:
+ return QLatin1String("JS basic type");
+ case JsModule:
+ return QLatin1String("JS module");
+ case JsProperty:
+ return QLatin1String("JS property");
+ case JsPropertyGroup:
+ return QLatin1String("JS property group");
-/*!
- Returns the node subtype \a t as a string for use as an
- attribute value in XML or HTML. This is only useful
- in the case where the node type is Document.
- */
-QString Node::nodeSubtypeString(unsigned char t)
-{
- switch ((DocSubtype)t) {
- case Example:
- return "example";
- case HeaderFile:
- return "header file";
- case File:
- return "file";
- case Image:
- return "image";
- case Page:
- return "page";
- case ExternalPage:
- return "external page";
- case DitaMap:
- return "ditamap";
- case NoSubtype:
+ case SharedComment:
+ return QLatin1String("shared comment");
+ case Collection:
+ return QLatin1String("collection");
default:
break;
}
@@ -517,8 +626,6 @@ void Node::setPageType(const QString& t)
pageType_ = (unsigned char) ArticlePage;
else if (t == "example")
pageType_ = (unsigned char) ExamplePage;
- else if (t == "ditamap")
- pageType_ = (unsigned char) DitaMapPage;
}
/*! Converts the boolean value \a b to an enum representation
@@ -556,7 +663,7 @@ bool Node::fromFlagValue(FlagValue fv, bool defaultValue)
/*!
Sets the pointer to the node that this node relates to.
*/
-void Node::setRelates(Aggregate *pseudoParent)
+void Node::setRelates(PageNode *pseudoParent)
{
if (pseudoParent == parent())
return;
@@ -573,7 +680,7 @@ void Node::setRelates(const QString& name)
{
removeRelates();
// Create a dummy aggregate for writing the name into the index
- relatesTo_ = new DocumentNode(0, name, Node::NoSubtype, Node::NoPageType);
+ relatesTo_ = new DummyNode(0, name);
}
/*!
@@ -593,7 +700,7 @@ void Node::setLink(LinkType linkType, const QString &link, const QString &desc)
Sets the information about the project and version a node was introduced
in. The string is simplified, removing excess whitespace before being
stored.
-*/
+ */
void Node::setSince(const QString &since)
{
since_ = since.simplified();
@@ -606,14 +713,14 @@ QString Node::accessString() const
{
switch ((Access) access_) {
case Protected:
- return "protected";
+ return QLatin1String("protected");
case Private:
- return "private";
+ return QLatin1String("private");
case Public:
default:
break;
}
- return "public";
+ return QLatin1String("public");
}
/*!
@@ -650,14 +757,14 @@ QString RelatedClass::accessString() const
{
switch (access_) {
case Node::Protected:
- return "protected";
+ return QLatin1String("protected");
case Node::Private:
- return "private";
+ return QLatin1String("private");
case Node::Public:
default:
break;
}
- return "public";
+ return QLatin1String("public");
}
/*!
@@ -909,7 +1016,7 @@ Node* Aggregate::findChildNode(const QString& name, NodeType type)
NodeList nodes = childMap_.values(name);
for (int i=0; i<nodes.size(); ++i) {
Node* node = nodes.at(i);
- if (node->type() == type)
+ if (node->nodeType() == type)
return node;
}
}
@@ -967,7 +1074,7 @@ FunctionNode *Aggregate::findFunctionNode(const QString& name, const QString& pa
parameters should have been specified in the \l command.
But if the primary function is marked internal, search
the secondary list to find one that is not marked internal.
- */
+ */
if (!fn) {
if (!testParams.empty())
return 0;
@@ -1067,7 +1174,7 @@ void Aggregate::normalizeOverloads()
Either the primary function is not active or it is private.
It therefore can't be the primary function. Search the list
of overloads to find one that can be the primary function.
- */
+ */
NodeList& overloads = secondaryFunctionMap_[primaryFunc->name()];
NodeList::ConstIterator s = overloads.constBegin();
while (s != overloads.constEnd()) {
@@ -1076,7 +1183,7 @@ void Aggregate::normalizeOverloads()
Any non-obsolete, non-private function (i.e., visible function)
is preferable to the current primary function. Swap the primary
and overload functions.
- */
+ */
if (overloadFunc->status() == Active && overloadFunc->access() != Private) {
primaryFunc->setOverloadNumber(overloadFunc->overloadNumber());
overloads.replace(overloads.indexOf(overloadFunc), primaryFunc);
@@ -1104,7 +1211,7 @@ void Aggregate::normalizeOverloads()
overload in the secondary function map that is not marked
with \overload but that is active and not private. Then
swap it with the primary function.
- */
+ */
NodeList& overloads = secondaryFunctionMap_[primaryFunc->name()];
NodeList::ConstIterator s = overloads.constBegin();
while (s != overloads.constEnd()) {
@@ -1137,17 +1244,6 @@ void Aggregate::normalizeOverloads()
}
/*!
- */
-void Aggregate::removeFromRelated()
-{
- while (!related_.isEmpty()) {
- Node *p = static_cast<Node *>(related_.takeFirst());
-
- if (p != 0 && p->relates() == this) p->clearRelated();
- }
-}
-
-/*!
Deletes all this node's children.
*/
void Aggregate::deleteChildren()
@@ -1208,24 +1304,6 @@ NodeList Aggregate::overloads(const QString &funcName) const
}
/*!
- Construct an inner node (i.e., not a leaf node) of the
- given \a type and having the given \a parent and \a name.
- */
-Aggregate::Aggregate(NodeType type, Aggregate *parent, const QString& name)
- : Node(type, parent, name), noAutoList_(false)
-{
- switch (type) {
- case Class:
- case QmlType:
- case Namespace:
- setPageType(ApiPage);
- break;
- default:
- break;
- }
-}
-
-/*!
Appends an \a include file to the list of include files.
*/
void Aggregate::addInclude(const QString& include)
@@ -1268,7 +1346,7 @@ bool Aggregate::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
/*
### hack for C++ to handle superfluous
"Foo::" prefixes gracefully
- */
+ */
if (t1 != t2 && t1 != (f2->parent()->name() + "::" + t2)) {
// Accept a difference in the template parametters of the type if one
// is omited (eg. "QAtomicInteger" == "QAtomicInteger<T>")
@@ -1295,9 +1373,7 @@ bool Aggregate::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
void Aggregate::addChild(Node *child)
{
children_.append(child);
- if (child->type() == Function
- || child->type() == QmlMethod
- || child->type() == QmlSignal) {
+ if (child->isFunction()) {
FunctionNode *func = static_cast<FunctionNode*>(child);
QString name = func->name();
if (!primaryFunctionMap_.contains(name)) {
@@ -1311,7 +1387,7 @@ void Aggregate::addChild(Node *child)
}
}
else {
- if (child->type() == Enum)
+ if (child->isEnumType())
enumChildren_.append(child);
childMap_.insertMulti(child->name(), child);
}
@@ -1329,7 +1405,7 @@ void Aggregate::addChild(Node *child)
again, because it is presumed to already be there. We just
want to be able to find the child by its \a title.
*/
-void Aggregate::addChild(Node* child, const QString& title)
+void Aggregate::addChildByTitle(Node* child, const QString& title)
{
childMap_.insertMulti(title, child);
}
@@ -1344,9 +1420,7 @@ void Aggregate::removeChild(Node *child)
{
children_.removeAll(child);
enumChildren_.removeAll(child);
- if (child->type() == Function
- || child->type() == QmlMethod
- || child->type() == QmlSignal) {
+ if (child->isFunction()) {
QMap<QString, Node *>::Iterator primary = primaryFunctionMap_.find(child->name());
NodeList& overloads = secondaryFunctionMap_[child->name()];
if (primary != primaryFunctionMap_.end() && *primary == child) {
@@ -1382,7 +1456,7 @@ void Aggregate::removeChild(Node *child)
}
/*!
- Recursively sets the output subdirectory for children
+ Recursively sets the output subdirectory for children
*/
void Aggregate::setOutputSubdirectory(const QString &t)
{
@@ -1400,7 +1474,7 @@ void Aggregate::setOutputSubdirectory(const QString &t)
This function is only really useful if the class's module has not
been defined in the header file with a QT_MODULE macro or with an
\inmodule command in the documentation.
-*/
+ */
QString Node::physicalModuleName() const
{
if (!physicalModuleName_.isEmpty())
@@ -1421,89 +1495,48 @@ QString Node::physicalModuleName() const
QString physicalModuleName = moduleDir.left(finish);
- if (physicalModuleName == "corelib")
- return "QtCore";
- else if (physicalModuleName == "uitools")
- return "QtUiTools";
- else if (physicalModuleName == "gui")
- return "QtGui";
- else if (physicalModuleName == "network")
- return "QtNetwork";
- else if (physicalModuleName == "opengl")
- return "QtOpenGL";
- else if (physicalModuleName == "svg")
- return "QtSvg";
- else if (physicalModuleName == "sql")
- return "QtSql";
- else if (physicalModuleName == "qtestlib")
- return "QtTest";
+ if (physicalModuleName == QLatin1String("corelib"))
+ return QLatin1String("QtCore");
+ else if (physicalModuleName == QLatin1String("uitools"))
+ return QLatin1String("QtUiTools");
+ else if (physicalModuleName == QLatin1String("gui"))
+ return QLatin1String("QtGui");
+ else if (physicalModuleName == QLatin1String("network"))
+ return QLatin1String("QtNetwork");
+ else if (physicalModuleName == QLatin1String("opengl"))
+ return QLatin1String("QtOpenGL");
+ else if (physicalModuleName == QLatin1String("svg"))
+ return QLatin1String("QtSvg");
+ else if (physicalModuleName == QLatin1String("sql"))
+ return QLatin1String("QtSql");
+ else if (physicalModuleName == QLatin1String("qtestlib"))
+ return QLatin1String("QtTest");
else if (moduleDir.contains("webkit"))
- return "QtWebKit";
- else if (physicalModuleName == "xml")
- return "QtXml";
+ return QLatin1String("QtWebKit");
+ else if (physicalModuleName == QLatin1String("xml"))
+ return QLatin1String("QtXml");
else
return QString();
}
/*!
- Removes a node from the list of nodes related to this one.
- If it is a function node, also remove from the primary/
- secondary function maps.
- */
-void Aggregate::removeRelated(Node *pseudoChild)
-{
- related_.removeAll(pseudoChild);
-
- if (pseudoChild->isFunction()) {
- QMap<QString, Node *>::Iterator p = primaryFunctionMap_.find(pseudoChild->name());
- while (p != primaryFunctionMap_.end()) {
- if (p.value() == pseudoChild) {
- primaryFunctionMap_.erase(p);
- break;
- }
- ++p;
- }
- NodeList& overloads = secondaryFunctionMap_[pseudoChild->name()];
- overloads.removeAll(pseudoChild);
- }
-}
-
-/*!
- Adds \a pseudoChild to the list of nodes related to this one. Resolve a correct
- overload number for a related non-member function.
- */
-void Aggregate::addRelated(Node *pseudoChild)
-{
- related_.append(pseudoChild);
-
- if (pseudoChild->isFunction()) {
- FunctionNode* fn = static_cast<FunctionNode*>(pseudoChild);
- if (primaryFunctionMap_.contains(pseudoChild->name())) {
- secondaryFunctionMap_[pseudoChild->name()].append(pseudoChild);
- fn->setOverloadNumber(secondaryFunctionMap_[pseudoChild->name()].size());
- fn->setOverloadFlag(true);
- }
- else {
- primaryFunctionMap_.insert(pseudoChild->name(), pseudoChild);
- fn->setOverloadNumber(0);
- fn->setOverloadFlag(false);
- }
- }
-}
-
-/*!
- If this node has a child that is a QML property named \a n,
- return the pointer to that child.
+ If this node has a child that is a QML property or JS property
+ named \a n, return a pointer to that child. Otherwise return 0.
*/
QmlPropertyNode* Aggregate::hasQmlProperty(const QString& n) const
{
+ NodeType goal1 = Node::QmlProperty;
+ NodeType goal2 = Node::QmlPropertyGroup;
+ if (isJsNode()) {
+ goal1 = Node::JsProperty;
+ goal2 = Node::JsPropertyGroup;
+ }
foreach (Node* child, childNodes()) {
- if (child->type() == Node::QmlProperty) {
+ if (child->nodeType() == goal1) {
if (child->name() == n)
return static_cast<QmlPropertyNode*>(child);
- }
- else if (child->isQmlPropertyGroup()) {
- QmlPropertyNode* t = child->hasQmlProperty(n);
+ } else if (child->nodeType() == goal2) {
+ QmlPropertyNode* t = static_cast<Aggregate*>(child)->hasQmlProperty(n);
if (t)
return t;
}
@@ -1512,19 +1545,24 @@ QmlPropertyNode* Aggregate::hasQmlProperty(const QString& n) const
}
/*!
- If this node has a child that is a QML property named \a n
- whose type (attached or normal property) matches \a attached,
- return the pointer to that child.
+ If this node has a child that is a QML property or JS property
+ named \a n and that also matches \a attached, return a pointer
+ to that child.
*/
QmlPropertyNode* Aggregate::hasQmlProperty(const QString& n, bool attached) const
{
+ NodeType goal1 = Node::QmlProperty;
+ NodeType goal2 = Node::QmlPropertyGroup;
+ if (isJsNode()) {
+ goal1 = Node::JsProperty;
+ goal2 = Node::JsPropertyGroup;
+ }
foreach (Node* child, childNodes()) {
- if (child->type() == Node::QmlProperty) {
+ if (child->nodeType() == goal1) {
if (child->name() == n && child->isAttached() == attached)
return static_cast<QmlPropertyNode*>(child);
- }
- else if (child->isQmlPropertyGroup()) {
- QmlPropertyNode* t = child->hasQmlProperty(n, attached);
+ } else if (child->nodeType() == goal2) {
+ QmlPropertyNode* t = static_cast<Aggregate*>(child)->hasQmlProperty(n, attached);
if (t)
return t;
}
@@ -1533,68 +1571,6 @@ QmlPropertyNode* Aggregate::hasQmlProperty(const QString& n, bool attached) cons
}
/*!
- \class LeafNode
- */
-
-/*! \fn bool LeafNode::isAggregate() const
- Returns \c false because this is a LeafNode.
- */
-
-/*!
- Constructs a leaf node named \a name of the specified
- \a type. The new leaf node becomes a child of \a parent.
- */
-LeafNode::LeafNode(NodeType type, Aggregate *parent, const QString& name)
- : Node(type, parent, name)
-{
- switch (type) {
- case Enum:
- case Function:
- case Typedef:
- case Variable:
- case QmlProperty:
- case QmlSignal:
- case QmlSignalHandler:
- case QmlMethod:
- case QmlBasicType:
- case SharedComment:
- setPageType(ApiPage);
- break;
- default:
- break;
- }
-}
-
-/*!
- This constructor should only be used when this node's parent
- is meant to be \a parent, but this node is not to be listed
- as a child of \a parent. It is currently only used for the
- documentation case where a \e{qmlproperty} command is used
- to override the QML definition of a QML property.
- */
-LeafNode::LeafNode(Aggregate* parent, NodeType type, const QString& name)
- : Node(type, 0, name)
-{
- setParent(parent);
- switch (type) {
- case Enum:
- case Function:
- case Typedef:
- case Variable:
- case QmlProperty:
- case QmlSignal:
- case QmlSignalHandler:
- case QmlMethod:
- case SharedComment:
- setPageType(ApiPage);
- break;
- default:
- break;
- }
-}
-
-
-/*!
\class NamespaceNode
\brief This class represents a C++ namespace.
@@ -1604,17 +1580,6 @@ LeafNode::LeafNode(Aggregate* parent, NodeType type, const QString& name)
*/
/*!
- Constructs a namespace node for a namespace named \a name.
- The namespace node has the specified \a parent.
- */
-NamespaceNode::NamespaceNode(Aggregate *parent, const QString& name)
- : Aggregate(Namespace, parent, name), seen_(false), documented_(false), tree_(0), docNode_(0)
-{
- setGenus(Node::CPP);
- setPageType(ApiPage);
-}
-
-/*!
Returns true if this namespace is to be documented in the
current module. There can be elements declared in this
namespace spread over multiple modules. Those elements are
@@ -1677,19 +1642,6 @@ bool NamespaceNode::docMustBeGenerated() const
*/
/*!
- Constructs a class node. A class node will generate an API page.
- */
-ClassNode::ClassNode(Aggregate *parent, const QString& name)
- : Aggregate(Class, parent, name)
-{
- abstract_ = false;
- wrapper_ = false;
- qmlelement = 0;
- setGenus(Node::CPP);
- setPageType(ApiPage);
-}
-
-/*!
Adds the base class \a node to this class's list of base
classes. The base class has the specified \a access. This
is a resolved base class.
@@ -1897,106 +1849,100 @@ FunctionNode* ClassNode::findOverriddenFunction(const FunctionNode* fn)
}
/*!
- \class DocumentNode
+ \class Headerode
+ \brief This class represents a C++ header file.
*/
/*!
- 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.
+ \class PageNode
+ */
+
+/*! \fn QString PageNode::title() const
+ Returns the node's title, which is used for the page title.
*/
-DocumentNode::DocumentNode(Aggregate* parent, const QString& name, DocSubtype subtype, Node::PageType ptype)
- : Aggregate(Document, parent, name), nodeSubtype_(subtype)
-{
- setGenus(Node::DOC);
- switch (subtype) {
- case Page:
- setPageType(ptype);
- break;
- case DitaMap:
- setPageType(ptype);
- break;
- case Example:
- setPageType(ExamplePage);
- break;
- default:
- break;
- }
-}
-/*! \fn QString DocumentNode::title() const
- Returns the document node's title. This is used for the page title.
-*/
+/*! \fn QString PageNode::subtitle() const
+ Returns the node's subtitle, which may be empty.
+ */
/*!
- Sets the document node's \a title. This is used for the page title.
+ Returns the node's full title, which is usually whatever
+ title() returns, but for some cases the full title migth
+ be different from title(), so this might require changing,
+ because currently it just returns the title().
+
+ mws 13/07/2018. This function used to test the node subtype
+ for File or Image and append text to the title(), but there
+ are no node subtypes now, so it can't do that. There are no
+ node type values for File and Image either. Files and images
+ are used in examples, but the ExampleNode's example files
+ and example images are stored as lists of path strings.
*/
-void DocumentNode::setTitle(const QString &title)
+QString PageNode::fullTitle() const
{
- title_ = title;
- parent()->addChild(this, title);
+ return title();
}
/*!
- Returns the document node's full title, which is usually
- just title(), but for some DocSubtype values is different
- from title()
+ Sets the node's \a title, which is used for the page title.
+ Returns true.
*/
-QString DocumentNode::fullTitle() const
+bool PageNode::setTitle(const QString &title)
{
- if (nodeSubtype_ == File) {
- if (title().isEmpty())
- return name().mid(name().lastIndexOf('/') + 1) + " Example File";
- else
- return title();
- }
- else if (nodeSubtype_ == Image) {
- if (title().isEmpty())
- return name().mid(name().lastIndexOf('/') + 1) + " Image File";
- else
- return title();
- }
- else if (nodeSubtype_ == HeaderFile) {
- if (title().isEmpty())
- return name();
- else
- return name() + " - " + title();
- }
- else {
- return title();
- }
+ title_ = title;
+ parent()->addChildByTitle(this, title);
+ return true;
}
/*!
- Returns the subtitle.
+ \fn bool PageNode::setSubtitle(const QString &subtitle)
+ Sets the node's \a subtitle. Returns true;
*/
-QString DocumentNode::subTitle() const
-{
- if (!subtitle_.isEmpty())
- return subtitle_;
- if ((nodeSubtype_ == File) || (nodeSubtype_ == Image)) {
- if (title().isEmpty() && name().contains(QLatin1Char('/')))
- return name();
+/*!
+ While there are related nodes, remove the first one. If it
+ relates to this node (it should), clear that relationship.
+ */
+void PageNode::removeFromRelated()
+{
+ while (!related_.isEmpty()) {
+ Node *p = static_cast<Node *>(related_.takeFirst());
+ if (p != 0 && p->relates() == this) p->clearRelated();
}
- return QString();
}
/*!
- \class EnumNode
+ Removes \a pseudoChild from the list of nodes related to
+ this node. If \a pseudoChild is a function node, it is
+ also remove from the primary/secondary function maps of
+ this node, if this node is a subclass of PageNode
+ that has function maps.
*/
+void PageNode::removeRelated(Node *pseudoChild)
+{
+ related_.removeAll(pseudoChild);
+ removePseudoChild(pseudoChild);
+}
/*!
- The constructor for the node representing an enum type
- has a \a parent class and an enum type \a name.
+ Adds \a pseudoChild to the list of nodes related to this
+ node. Also adds \a pseudoChild to the primary/secondary
+ function maps, if this PageNode is the base class of
+ a subclass that has function maps. In that case, it also
+ resolves a correct overload number for a related non-member
+ function.
*/
-EnumNode::EnumNode(Aggregate *parent, const QString& name)
- : LeafNode(Enum, parent, name), flagsType_(0)
+void PageNode::addRelated(Node *pseudoChild)
{
- setGenus(Node::CPP);
+ related_.append(pseudoChild);
+ addPseudoChild(pseudoChild);
}
/*!
+ \class EnumNode
+ */
+
+/*!
Add \a item to the enum type's item list.
*/
void EnumNode::addItem(const EnumItem& item)
@@ -2035,14 +1981,6 @@ QString EnumNode::itemValue(const QString &name) const
/*!
*/
-TypedefNode::TypedefNode(Aggregate *parent, const QString& name)
- : LeafNode(Typedef, parent, name), associatedEnum_(0)
-{
- setGenus(Node::CPP);
-}
-
-/*!
- */
void TypedefNode::setAssociatedEnum(const EnumNode *enume)
{
associatedEnum_ = enume;
@@ -2053,16 +1991,6 @@ void TypedefNode::setAssociatedEnum(const EnumNode *enume)
*/
/*!
- Constructs a TypeAliasNode for the \a aliasedType with the
- specified \a name and \a parent.
- */
-TypeAliasNode::TypeAliasNode(Aggregate *parent, const QString& name, const QString& aliasedType)
- : TypedefNode(parent, name), aliasedType_(aliasedType)
-{
- // nothing.
-}
-
-/*!
\class Parameter
\brief The class Parameter contains one parameter.
@@ -2132,7 +2060,7 @@ QString Parameter::reconstruct(bool value) const
is set by addChild() in the Node base class.
*/
FunctionNode::FunctionNode(Aggregate *parent, const QString& name)
- : LeafNode(Function, parent, name),
+ : Node(Function, parent, name),
metaness_(Plain),
virtualness_(NonVirtual),
const_(false),
@@ -2150,20 +2078,21 @@ FunctionNode::FunctionNode(Aggregate *parent, const QString& name)
isRefRef_(false),
isInvokable_(false)
{
- setGenus(Node::CPP);
+ // nothing
}
/*!
Construct a function node for a QML method or signal, specified
- by \a type. It's parent is \a parent, and it's name is \a name.
- If \a attached is true, it is an attached method or signal.
+ by ther Metaness value \a type. It's parent is \a parent, and
+ it's name is \a name. If \a attached is true, it is an attached
+ method or signal.
Do not set overloadNumber_ in the initializer list because it
is set by addChild() in the Node base class.
*/
-FunctionNode::FunctionNode(NodeType type, Aggregate *parent, const QString& name, bool attached)
- : LeafNode(type, parent, name),
- metaness_(Plain),
+FunctionNode::FunctionNode(Metaness kind, Aggregate *parent, const QString& name, bool attached)
+ : Node(Function, parent, name),
+ metaness_(kind),
virtualness_(NonVirtual),
const_(false),
static_(false),
@@ -2180,13 +2109,9 @@ FunctionNode::FunctionNode(NodeType type, Aggregate *parent, const QString& name
isRefRef_(false),
isInvokable_(false)
{
- setGenus(Node::QML);
- if (type == QmlMethod || type == QmlSignal) {
- if (name.startsWith("__"))
- setStatus(Internal);
- }
- else if (type == Function)
- setGenus(Node::CPP);
+ setGenus(getGenus(metaness_));
+ if (!isCppNode() && name.startsWith("__"))
+ setStatus(Internal);
}
/*!
@@ -2197,14 +2122,14 @@ QString FunctionNode::virtualness() const
{
switch (virtualness_) {
case FunctionNode::NormalVirtual:
- return "virtual";
+ return QLatin1String("virtual");
case FunctionNode::PureVirtual:
- return "pure";
+ return QLatin1String("pure");
case FunctionNode::NonVirtual:
default:
break;
}
- return "non";
+ return QLatin1String("non");
}
/*!
@@ -2227,41 +2152,149 @@ void FunctionNode::setVirtualness(const QString& t)
}
}
+static QMap<QString, FunctionNode::Metaness> metanessMap_;
+static void buildMetanessMap()
+{
+ metanessMap_["plain"] = FunctionNode::Plain;
+ metanessMap_["signal"] = FunctionNode::Signal;
+ metanessMap_["slot"] = FunctionNode::Slot;
+ metanessMap_["constructor"] = FunctionNode::Ctor;
+ metanessMap_["copy-constructor"] = FunctionNode::CCtor;
+ metanessMap_["move-constructor"] = FunctionNode::MCtor;
+ metanessMap_["destructor"] = FunctionNode::Dtor;
+ metanessMap_["macro"] = FunctionNode::MacroWithParams;
+ metanessMap_["macrowithparams"] = FunctionNode::MacroWithParams;
+ metanessMap_["macrowithoutparams"] = FunctionNode::MacroWithoutParams;
+ metanessMap_["copy-assign"] = FunctionNode::CAssign;
+ metanessMap_["move-assign"] = FunctionNode::MAssign;
+ metanessMap_["native"] = FunctionNode::Native;
+ metanessMap_["qmlsignal"] = FunctionNode::QmlSignal;
+ metanessMap_["qmlsignalhandler"] = FunctionNode::QmlSignalHandler;
+ metanessMap_["qmlmethod"] = FunctionNode::QmlMethod;
+ metanessMap_["jssignal"] = FunctionNode::JsSignal;
+ metanessMap_["jssignalhandler"] = FunctionNode::JsSignalHandler;
+ metanessMap_["jsmethos"] = FunctionNode::JsMethod;
+}
+
+static QMap<QString, FunctionNode::Metaness> topicMetanessMap_;
+static void buildTopicMetanessMap()
+{
+ topicMetanessMap_["fn"] = FunctionNode::Plain;
+ topicMetanessMap_["qmlsignal"] = FunctionNode::QmlSignal;
+ topicMetanessMap_["qmlattachedsignal"] = FunctionNode::QmlSignal;
+ topicMetanessMap_["qmlmethod"] = FunctionNode::QmlMethod;
+ topicMetanessMap_["qmlattachedmethod"] = FunctionNode::QmlMethod;
+ topicMetanessMap_["jssignal"] = FunctionNode::JsSignal;
+ topicMetanessMap_["jsattachedsignal"] = FunctionNode::JsSignal;
+ topicMetanessMap_["jsmethod"] = FunctionNode::JsMethod;
+ topicMetanessMap_["jsattachedmethod"] = FunctionNode::JsMethod;
+}
+
+/*!
+ Determines the Genus value for this FunctionNode given the
+ Metaness value \a t. Returns the Genus value. \a t must be
+ one of the values of Metaness. If not, Node::DontCare is
+ returned.
+ */
+Node::Genus FunctionNode::getGenus(FunctionNode::Metaness t)
+{
+ switch (t) {
+ case FunctionNode::Plain:
+ case FunctionNode::Signal:
+ case FunctionNode::Slot:
+ case FunctionNode::Ctor:
+ case FunctionNode::Dtor:
+ case FunctionNode::CCtor:
+ case FunctionNode::MCtor:
+ case FunctionNode::MacroWithParams:
+ case FunctionNode::MacroWithoutParams:
+ case FunctionNode::Native:
+ case FunctionNode::CAssign:
+ case FunctionNode::MAssign:
+ return Node::CPP;
+ case FunctionNode::QmlSignal:
+ case FunctionNode::QmlSignalHandler:
+ case FunctionNode::QmlMethod:
+ return Node::QML;
+ case FunctionNode::JsSignal:
+ case FunctionNode::JsSignalHandler:
+ case FunctionNode::JsMethod:
+ return Node::JS;
+ }
+ return Node::DontCare;
+}
+
+/*!
+ This static function converts the string \a t to an enum
+ value for the kind of function named by \a t.
+ */
+FunctionNode::Metaness FunctionNode::getMetaness(const QString& t)
+{
+ if (metanessMap_.isEmpty())
+ buildMetanessMap();
+ return metanessMap_[t];
+}
+
+/*!
+ This static function converts the topic string \a t to an enum
+ value for the kind of function this FunctionNode represents.
+ */
+FunctionNode::Metaness FunctionNode::getMetanessFromTopic(const QString& t)
+{
+ if (topicMetanessMap_.isEmpty())
+ buildTopicMetanessMap();
+ return topicMetanessMap_[t];
+}
+
/*!
Sets the function node's Metaness value based on the value
of string \a t, which is the value of the function's "meta"
- attribute in an index file.
- */
-void FunctionNode::setMetaness(const QString& t)
-{
- if (t == QLatin1String("plain"))
- metaness_ = Plain;
- else if (t == QLatin1String("signal"))
- metaness_ = Signal;
- else if (t == QLatin1String("slot"))
- metaness_ = Slot;
- else if (t == QLatin1String("constructor"))
- metaness_ = Ctor;
- else if (t == QLatin1String("copy-constructor"))
- metaness_ = CCtor;
- else if (t == QLatin1String("move-constructor"))
- metaness_ = MCtor;
- else if (t == QLatin1String("destructor"))
- metaness_ = Dtor;
- else if (t == QLatin1String("macro"))
- metaness_ = MacroWithParams;
- else if (t == QLatin1String("macrowithparams"))
- metaness_ = MacroWithParams;
- else if (t == QLatin1String("macrowithoutparams"))
- metaness_ = MacroWithoutParams;
- else if (t == QLatin1String("copy-assign"))
- metaness_ = CAssign;
- else if (t == QLatin1String("move-assign"))
- metaness_ = MAssign;
- else if (t == QLatin1String("native"))
- metaness_ = Native;
- else
- metaness_ = Plain;
+ attribute in an index file. Returns the Metaness value
+ */
+FunctionNode::Metaness FunctionNode::setMetaness(const QString& t)
+{
+ metaness_ = getMetaness(t);
+ return metaness_;
+}
+
+/*!
+ If this function node's metaness is \a from, change the
+ metaness to \a to and return \c true. Otherwise return
+ false. This function is used to change Qml function node
+ metaness values to Javascript function node metaness,
+ values because these nodes are created as Qml function
+ nodes before it is discovered that what the function node
+ represents is not a Qml function but a javascript function.
+
+ Note that if the function returns true, which means the node
+ type was indeed changed, then the node's Genus is also changed
+ from QML to JS.
+
+ The function also works in the other direction, but there is
+ no use case for that.
+ */
+bool FunctionNode::changeMetaness(Metaness from, Metaness to)
+{
+ if (metaness_ == from) {
+ metaness_ = to;
+ switch (to) {
+ case QmlSignal:
+ case QmlSignalHandler:
+ case QmlMethod:
+ setGenus(Node::QML);
+ break;
+ case JsSignal:
+ case JsSignalHandler:
+ case JsMethod:
+ setGenus(Node::JS);
+ break;
+ default:
+ setGenus(Node::CPP);
+ break;
+ }
+ return true;
+ }
+ return false;
}
/*! \fn void FunctionNode::setOverloadFlag(bool b)
@@ -2287,10 +2320,35 @@ void FunctionNode::setReimplemented(bool b)
}
/*!
+ Returns a string representing the kind of function this
+ Function node represents, which depends on the Metaness
+ value.
+ */
+QString FunctionNode::kindString() const
+{
+ switch (metaness_) {
+ case FunctionNode::QmlSignal:
+ return "QML signal";
+ case FunctionNode::QmlSignalHandler:
+ return "QML signal handler";
+ case FunctionNode::QmlMethod:
+ return "QML method";
+ case FunctionNode::JsSignal:
+ return "JS signal";
+ case FunctionNode::JsSignalHandler:
+ return "JS signal handler";
+ case FunctionNode::JsMethod:
+ return "JS method";
+ default:
+ return "function";
+ }
+}
+
+/*!
Returns a string representing the Metaness enum value for
this function. It is used in index files.
*/
-QString FunctionNode::metaness() const
+QString FunctionNode::metanessString() const
{
switch (metaness_) {
case FunctionNode::Plain:
@@ -2317,6 +2375,18 @@ QString FunctionNode::metaness() const
return "copy-assign";
case FunctionNode::MAssign:
return "move-assign";
+ case FunctionNode::QmlSignal:
+ return "qmlsignal";
+ case FunctionNode::QmlSignalHandler:
+ return "qmlsignalhandler";
+ case FunctionNode::QmlMethod:
+ return "qmlmethod";
+ case FunctionNode::JsSignal:
+ return "jssignal";
+ case FunctionNode::JsSignalHandler:
+ return "jssignalhandler";
+ case FunctionNode::JsMethod:
+ return "jsmethod";
default:
return "plain";
}
@@ -2513,7 +2583,7 @@ bool FunctionNode::compare(const FunctionNode *fn) const
{
if (!fn)
return false;
- if (type() != fn->type())
+ if (metaness() != fn->metaness())
return false;
if (parent() != fn->parent())
return false;
@@ -2559,6 +2629,9 @@ bool FunctionNode::isIgnored() const
name() == QLatin1String("d_func")) {
return true;
}
+ QString s = signature(false, false);
+ if (s.contains(QLatin1String("enum_type")) && s.contains(QLatin1String("operator|")))
+ return true;
}
return false;
}
@@ -2574,7 +2647,7 @@ bool FunctionNode::isIgnored() const
everything else is set to default values.
*/
PropertyNode::PropertyNode(Aggregate *parent, const QString& name)
- : LeafNode(Property, parent, name),
+ : Node(Property, parent, name),
stored_(FlagValueDefault),
designable_(FlagValueDefault),
scriptable_(FlagValueDefault),
@@ -2585,7 +2658,7 @@ PropertyNode::PropertyNode(Aggregate *parent, const QString& name)
revision_(-1),
overrides_(0)
{
- setGenus(Node::CPP);
+ // nothing
}
/*!
@@ -2630,7 +2703,7 @@ QString PropertyNode::qualifiedDataType() const
/*
'int' becomes 'const int' ('int const' is
correct C++, but looks wrong)
- */
+ */
return "const " + type_;
}
}
@@ -2643,11 +2716,13 @@ bool QmlTypeNode::qmlOnly = false;
QMultiMap<const Node*, Node*> QmlTypeNode::inheritedBy;
/*!
- Constructs a Qml class node. The new node has the given
- \a parent and \a name.
+ Constructs a Qml type node or a Js type node depending on
+ the value of \a type, which is Node::QmlType by default,
+ but which can also be Node::JsType. The new node has the
+ given \a parent and \a name.
*/
-QmlTypeNode::QmlTypeNode(Aggregate *parent, const QString& name)
- : Aggregate(QmlType, parent, name),
+QmlTypeNode::QmlTypeNode(Aggregate *parent, const QString& name, NodeType type)
+ : Aggregate(type, parent, name),
abstract_(false),
cnodeRequired_(false),
wrapper_(false),
@@ -2661,8 +2736,6 @@ QmlTypeNode::QmlTypeNode(Aggregate *parent, const QString& name)
i = 4;
}
setTitle(name.mid(i));
- setPageType(Node::ApiPage);
- setGenus(Node::QML);
}
/*!
@@ -2765,26 +2838,26 @@ bool QmlTypeNode::inherits(Aggregate* type)
}
/*!
- Constructs a Qml basic type node. The new node has the given
- \a parent and \a name.
+ Constructs either a Qml basic type node or a Javascript
+ basic type node, depending on the value pf \a type, which
+ must be either Node::QmlBasicType or Node::JsBasicType.
+ The new node has the given \a parent and \a name.
*/
-QmlBasicTypeNode::QmlBasicTypeNode(Aggregate *parent,
- const QString& name)
- : Aggregate(QmlBasicType, parent, name)
+QmlBasicTypeNode::QmlBasicTypeNode(Aggregate *parent, const QString& name, Node::NodeType type)
+ : Aggregate(type, parent, name)
{
setTitle(name);
- setGenus(Node::QML);
}
/*!
- Constructor for the Qml property group node. \a parent is
- always a QmlTypeNode.
+ Constructor for both the Qml property group node and the
+ Javascript property group node. The determination is made
+ by testing whether the \a parent is a QML node or a JS node.
*/
QmlPropertyGroupNode::QmlPropertyGroupNode(QmlTypeNode* parent, const QString& name)
- : Aggregate(QmlPropertyGroup, parent, name)
+ : Aggregate(parent->isJsType() ? JsPropertyGroup : QmlPropertyGroup, parent, name)
{
idNumber_ = -1;
- setGenus(Node::QML);
}
/*!
@@ -2808,7 +2881,7 @@ QmlPropertyNode::QmlPropertyNode(Aggregate* parent,
const QString& name,
const QString& type,
bool attached)
- : LeafNode(QmlProperty, parent, name),
+ : Node(parent->isJsType() ? JsProperty : QmlProperty, parent, name),
type_(type),
stored_(FlagValueDefault),
designable_(FlagValueDefault),
@@ -2817,12 +2890,10 @@ QmlPropertyNode::QmlPropertyNode(Aggregate* parent,
attached_(attached),
readOnly_(FlagValueDefault)
{
- setPageType(ApiPage);
if (type_ == QString("alias"))
isAlias_ = true;
if (name.startsWith("__"))
setStatus(Internal);
- setGenus(Node::QML);
}
/*!
@@ -2891,7 +2962,7 @@ PropertyNode* QmlPropertyNode::findCorrespondingCppProperty()
Now find the C++ property corresponding to
the QML property in the QML property group,
<group>.<property>.
- */
+ */
if (dotSplit.size() > 1) {
QStringList path(extractClassName(pn->qualifiedDataType()));
Node* nn = QDocDatabase::qdocDB()->findClassNode(path);
@@ -2904,7 +2975,7 @@ PropertyNode* QmlPropertyNode::findCorrespondingCppProperty()
Otherwise, return the C++ property
corresponding to the QML property
group.
- */
+ */
return (pn2 ? pn2 : pn);
}
}
@@ -2943,7 +3014,7 @@ QString Node::fullDocumentName() const
break;
}
- if (n->isDocumentNode())
+ if (n->isTextPageNode())
break;
// Examine the parent node if one exists.
@@ -2958,7 +3029,7 @@ QString Node::fullDocumentName() const
if (n->isQmlType() || n->isJsType())
concatenator = QLatin1Char('.');
- if (n->isDocumentNode())
+ if (n->isTextPageNode())
concatenator = QLatin1Char('#');
return pieces.join(concatenator);
@@ -3056,12 +3127,58 @@ void Aggregate::printChildren(const QString& title)
if (children_.size() > 0) {
for (int i=0; i<children_.size(); ++i) {
Node* n = children_.at(i);
- qDebug() << " CHILD:" << n->name() << n->nodeTypeString() << n->nodeSubtypeString();
+ qDebug() << " CHILD:" << n->name() << n->nodeTypeString();
}
}
}
/*!
+ Removes \a pseudoChild from this node's primary/secondary
+ function maps.
+ */
+void Aggregate::removePseudoChild(Node *pseudoChild)
+{
+ if (pseudoChild->isFunction()) {
+ QMap<QString, Node *>::Iterator p = primaryFunctionMap_.find(pseudoChild->name());
+ while (p != primaryFunctionMap_.end()) {
+ if (p.value() == pseudoChild) {
+ primaryFunctionMap_.erase(p);
+ break;
+ }
+ ++p;
+ }
+ NodeList& overloads = secondaryFunctionMap_[pseudoChild->name()];
+ overloads.removeAll(pseudoChild);
+ }
+}
+
+/*!
+ Adds \a pseudoChild to the list of nodes related to this one. Resolve a correct
+ overload number for a related non-member function.
+ */
+void Aggregate::addPseudoChild(Node *pseudoChild)
+{
+ if (pseudoChild->isFunction()) {
+ FunctionNode* fn = static_cast<FunctionNode*>(pseudoChild);
+ if (primaryFunctionMap_.contains(pseudoChild->name())) {
+ secondaryFunctionMap_[pseudoChild->name()].append(pseudoChild);
+ fn->setOverloadNumber(secondaryFunctionMap_[pseudoChild->name()].size());
+ fn->setOverloadFlag(true);
+ }
+ else {
+ primaryFunctionMap_.insert(pseudoChild->name(), pseudoChild);
+ fn->setOverloadNumber(0);
+ fn->setOverloadFlag(false);
+ }
+ }
+}
+
+/*!
+ \class CollectionNode
+ \brief A class for holding the members of a collection of doc pages.
+ */
+
+/*!
Returns \c true if the collection node's member list is
not empty.
*/
@@ -3154,21 +3271,12 @@ void CollectionNode::printMembers(const QString& title)
if (members_.size() > 0) {
for (int i=0; i<members_.size(); ++i) {
Node* n = members_.at(i);
- qDebug() << " MEMBER:" << n->name() << n->nodeTypeString() << n->nodeSubtypeString();
+ qDebug() << " MEMBER:" << n->name() << n->nodeTypeString();
}
}
}
/*!
- Sets the document node's \a title. This is used for the page title.
- */
-void CollectionNode::setTitle(const QString& title)
-{
- title_ = 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
@@ -3222,10 +3330,10 @@ void SharedCommentNode::setOverloadFlag(bool b)
}
/*!
- Sets the pointer to the node that this node relates to
- in each of the nodes in this shared comment node's collective.
+ Sets each node in this node's collective to be related to
+ \a pseudoParent.
*/
-void SharedCommentNode::setRelates(Aggregate *pseudoParent)
+void SharedCommentNode::setRelates(PageNode *pseudoParent)
{
Node::setRelates(pseudoParent);
for (Node *n : collective_)
diff --git a/src/qdoc/node.h b/src/qdoc/node.h
index d7426ba20..073ab4907 100644
--- a/src/qdoc/node.h
+++ b/src/qdoc/node.h
@@ -42,6 +42,7 @@ QT_BEGIN_NAMESPACE
class Node;
class Tree;
class EnumNode;
+class PageNode;
class ClassNode;
class Aggregate;
class ExampleNode;
@@ -59,8 +60,6 @@ typedef QVector<Node*> NodeVector;
typedef QList<PropertyNode*> PropNodeList;
typedef QMap<QString, Node*> NodeMap;
typedef QMultiMap<QString, Node*> NodeMultiMap;
-typedef QPair<int, int> NodeTypePair;
-typedef QList<NodeTypePair> NodeTypeList;
typedef QMap<QString, CollectionNode*> CNMap;
typedef QMultiMap<QString, CollectionNode*> CNMultiMap;
@@ -73,10 +72,13 @@ public:
NoType,
Namespace,
Class,
- Document,
+ HeaderFile,
+ Page,
Enum,
- Typedef,
+ Example,
+ ExternalPage,
Function,
+ Typedef,
Property,
Variable,
Group,
@@ -85,27 +87,17 @@ public:
QmlModule,
QmlPropertyGroup,
QmlProperty,
- QmlSignal,
- QmlSignalHandler,
- QmlMethod,
QmlBasicType,
+ JsType,
+ JsModule,
+ JsPropertyGroup,
+ JsProperty,
+ JsBasicType,
SharedComment,
+ Collection,
LastType
};
- enum DocSubtype {
- NoSubtype,
- Attribution,
- Example,
- HeaderFile,
- File,
- Image,
- Page,
- ExternalPage,
- DitaMap,
- LastSubtype
- };
-
enum Genus { DontCare, CPP, JS, QML, DOC };
enum Access { Public, Protected, Private };
@@ -143,7 +135,6 @@ public:
OverviewPage,
TutorialPage,
FAQPage,
- DitaMapPage,
OnBeyondZebra
};
@@ -155,6 +146,71 @@ public:
virtual ~Node();
+ NodeType nodeType() const { return (NodeType) nodeType_; }
+ QString nodeTypeString() const;
+ bool changeType(NodeType from, NodeType to);
+
+ Genus genus() const { return (Genus) genus_; }
+ void setGenus(Genus t) { genus_ = (unsigned char) t; }
+ static Genus getGenus(NodeType t);
+
+ PageType pageType() const { return (PageType) pageType_; }
+ QString pageTypeString() const;
+ void setPageType(PageType t) { pageType_ = (unsigned char) t; }
+ void setPageType(const QString& t);
+ static PageType getPageType(NodeType t);
+
+ bool isClass() const { return nodeType_ == Class; }
+ bool isCppNode() const { return genus() == CPP; }
+ bool isEnumType() const { return nodeType_ == Enum; }
+ bool isExample() const { return nodeType_ == Example; }
+ bool isExternalPage() const { return nodeType_ == ExternalPage; }
+ bool isFunction(Genus g = DontCare) const {
+ return (nodeType_ != Function ? false : (genus() == g ? true : g == DontCare));
+ }
+ bool isGroup() const { return nodeType_ == Group; }
+ bool isHeader() const { return nodeType_ == HeaderFile; }
+ bool isIndexNode() const { return indexNodeFlag_; }
+ bool isJsBasicType() const { return nodeType_ == JsBasicType; }
+ bool isJsModule() const { return nodeType_ == JsModule; }
+ bool isJsNode() const { return genus() == JS; }
+ bool isJsProperty() const { return nodeType_ == JsProperty; }
+ bool isJsPropertyGroup() const { return nodeType_ == JsPropertyGroup; }
+ bool isJsType() const { return nodeType_ == JsType; }
+ bool isModule() const { return nodeType_ == Module; }
+ bool isNamespace() const { return nodeType_ == Namespace; }
+ bool isObsolete() const { return (status_ == (unsigned char) Obsolete); }
+ bool isPrivate() const { return (Access) access_ == Private; }
+ bool isProperty() const { return nodeType_ == Property; }
+ bool isPublic() const { return (Access) access_ == Public; }
+ bool isQmlBasicType() const { return nodeType_ == QmlBasicType; }
+ bool isQmlModule() const { return nodeType_ == QmlModule; }
+ bool isQmlNode() const { return genus() == QML; }
+ bool isQmlProperty() const { return nodeType_ == QmlProperty; }
+ bool isQmlPropertyGroup() const { return nodeType_ == QmlPropertyGroup; }
+ bool isQmlType() const { return nodeType_ == QmlType; }
+ bool isSharedCommentNode() const { return nodeType_ == SharedComment; }
+ bool isTypeAlias() const { return nodeType_ == Typedef; }
+ bool isTypedef() const { return nodeType_ == Typedef; }
+ bool isVariable() const { return nodeType_ == Variable; }
+
+ virtual bool isAbstract() const { return false; }
+ virtual bool isAggregate() const { return false; } // means "can have children"
+ virtual bool isAlias() const { return false; }
+ virtual bool isAttached() const { return false; }
+ virtual bool isCollectionNode() const { return false; }
+ virtual bool isDefault() const { return false; }
+ virtual bool isImplicit() const { return false; }
+ virtual bool isInternal() const;
+ virtual bool isMacro() const { return false; }
+ virtual bool isPageNode() const { return false; } // means "generates a doc page"
+ virtual bool isQtQuickNode() const { return false; }
+ virtual bool isReadOnly() const { return false; }
+ virtual bool isReimplemented() const { return false; }
+ virtual bool isStatic() const { return false; }
+ virtual bool isTextPageNode() const { return false; } // means PageNode but not Aggregate
+ virtual bool isWrapper() const;
+
QString plainName() const;
QString plainFullName(const Node* relative = 0) const;
QString plainSignature() const;
@@ -164,8 +220,6 @@ public:
const QString& fileNameBase() const { return fileNameBase_; }
bool hasFileNameBase() const { return !fileNameBase_.isEmpty(); }
void setFileNameBase(const QString& t) { fileNameBase_ = t; }
- Node::Genus genus() const { return (Genus) genus_; }
- void setGenus(Genus t) { genus_ = (unsigned char) t; }
void setAccess(Access t) { access_ = (unsigned char) t; }
void setLocation(const Location& t);
@@ -177,68 +231,14 @@ public:
}
void setThreadSafeness(ThreadSafeness t) { safeness_ = (unsigned char) t; }
void setSince(const QString &since);
- virtual void setRelates(Aggregate* pseudoParent);
- virtual void setRelates(const QString &name);
void setPhysicalModuleName(const QString &name) { physicalModuleName_ = name; }
void setUrl(const QString& url) { url_ = url; }
void setTemplateStuff(const QString &t) { templateStuff_ = t; }
void setReconstitutedBrief(const QString &t) { reconstitutedBrief_ = t; }
- void setPageType(PageType t) { pageType_ = (unsigned char) t; }
- void setPageType(const QString& t);
void setParent(Aggregate* n) { parent_ = n; }
void setIndexNodeFlag(bool isIndexNode = true) { indexNodeFlag_ = isIndexNode; }
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 isAggregate() const = 0;
- 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 isEnumType() const { return false; }
- virtual bool isTypedef() const { return false; }
- virtual bool isTypeAlias() const { return false; }
- virtual bool isExample() const { return false; }
- virtual bool isExampleFile() const { return false; }
- virtual bool isHeaderFile() const { return false; }
- virtual bool isLeaf() const { return false; }
- virtual bool isReimplemented() const { return false; }
- virtual bool isFunction() const { return false; }
- virtual bool isNamespace() const { return false; }
- virtual bool isClass() const { return false; }
- virtual bool isQtQuickNode() const { return false; }
- virtual bool isAbstract() const { return false; }
- virtual bool isProperty() const { return false; }
- virtual bool isVariable() 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;
- virtual bool isReadOnly() const { return false; }
- virtual bool isDefault() const { return false; }
- virtual bool isExternalPage() const { return false; }
- virtual bool isImplicit() const { return false; }
- virtual bool isSharedCommentNode() const { return false; }
- virtual bool isMacro() const { return false; }
- virtual bool isStatic() const { return false; }
virtual void addMember(Node* ) { }
virtual bool hasMembers() const { return false; }
@@ -246,19 +246,10 @@ public:
virtual bool hasClasses() const { return false; }
virtual void setAbstract(bool ) { }
virtual void setWrapper() { }
- virtual QString title() const { return name(); }
- virtual QString fullTitle() const { return name(); }
- virtual QString subTitle() const { return QString(); }
- virtual void setTitle(const QString& ) { }
- virtual void setSubTitle(const QString& ) { }
- virtual QmlPropertyNode* hasQmlProperty(const QString& ) const { return 0; }
- virtual QmlPropertyNode* hasQmlProperty(const QString&, bool ) const { return 0; }
virtual void getMemberNamespaces(NodeMap& ) { }
virtual void getMemberClasses(NodeMap& ) const { }
- virtual bool isInternal() const;
virtual void setDataType(const QString& ) { }
virtual void setReadOnly(bool ) { }
- virtual Node* disambiguate(NodeType , DocSubtype ) { return this; }
virtual bool wasSeen() const { return false; }
virtual void appendGroupName(const QString& ) { }
virtual QString element() const { return QString(); }
@@ -266,13 +257,16 @@ public:
virtual void findChildren(const QString& , NodeList& nodes) const { nodes.clear(); }
virtual void setNoAutoList(bool ) { }
virtual bool docMustBeGenerated() const { return false; }
- bool isIndexNode() const { return indexNodeFlag_; }
- NodeType type() const { return (NodeType) nodeType_; }
- virtual DocSubtype docSubtype() const { return NoSubtype; }
- bool match(const NodeTypeList& types) const;
+
+ virtual QString title() const { return name(); }
+ virtual QString subtitle() const { return QString(); }
+ virtual QString fullTitle() const { return name(); }
+ virtual bool setTitle(const QString& ) { return false; }
+ virtual bool setSubtitle(const QString& ) { return false; }
+
+ bool match(const QList<int>& types) const;
Aggregate* parent() const { return parent_; }
const Node* root() const;
- Aggregate* relates() const { return relatesTo_; }
const QString& name() const { return name_; }
QString physicalModuleName() const;
QString url() const { return url_; }
@@ -289,8 +283,6 @@ public:
void setLink(LinkType linkType, const QString &link, const QString &desc);
Access access() const { return (Access) access_; }
- bool isPublic() const { return (Access) access_ == Public; }
- bool isPrivate() const { return (Access) access_ == Private; }
QString accessString() const;
const Location& declLocation() const { return declLocation_; }
const Location& defLocation() const { return defLocation_; }
@@ -299,19 +291,18 @@ public:
bool hasDoc() const { return !doc_.isEmpty(); }
Status status() const { return (Status) status_; }
Status inheritedStatus() const;
- bool isObsolete() const { return (status_ == (unsigned char) Obsolete); }
ThreadSafeness threadSafeness() const;
ThreadSafeness inheritedThreadSafeness() const;
QString since() const { return since_; }
QString templateStuff() const { return templateStuff_; }
const QString& reconstitutedBrief() const { return reconstitutedBrief_; }
- PageType pageType() const { return (PageType) pageType_; }
- QString pageTypeString() const;
- QString nodeTypeString() const;
QString nodeSubtypeString() const;
virtual void addPageKeywords(const QString& ) { }
void clearRelated() { relatesTo_ = 0; }
+ PageNode* relates() const { return relatesTo_; }
+ virtual void setRelates(PageNode* pseudoParent);
+ virtual void setRelates(const QString &name);
bool isSharingComment() const { return (sharedCommentNode_ != 0); }
bool hasSharedDoc() const;
@@ -349,15 +340,8 @@ public:
static void clearPropertyGroupCount();
static void initialize();
static NodeType goal(const QString& t) { return goals_.value(t); }
-
-/*!
- Returns \c true if the node \a n1 is less than node \a n2. The
- comparison is performed by comparing properties of the nodes
- in order of increasing complexity.
-*/
static bool nodeNameLessThan(const Node *first, const Node *second);
-
protected:
Node(NodeType type, Aggregate* parent, const QString& name);
void removeRelates();
@@ -373,7 +357,7 @@ private:
bool indexNodeFlag_;
Aggregate* parent_;
- Aggregate* relatesTo_;
+ PageNode* relatesTo_;
SharedCommentNode *sharedCommentNode_;
QString name_;
Location declLocation_;
@@ -392,9 +376,79 @@ private:
static int propertyGroupCount_;
static QMap<QString,Node::NodeType> goals_;
};
-Q_DECLARE_TYPEINFO(Node::DocSubtype, Q_PRIMITIVE_TYPE);
-class Aggregate : public Node
+class PageNode : public Node
+{
+public:
+ PageNode(Aggregate* parent, const QString& name) : Node(Page, parent, name),
+ noAutoList_(false) { }
+ PageNode(NodeType type, Aggregate* parent, const QString& name) : Node(type, parent, name),
+ noAutoList_(false) { }
+ PageNode(Aggregate* parent, const QString& name, PageType ptype) : Node(Page, parent, name),
+ noAutoList_(false) { setPageType(ptype); }
+ virtual ~PageNode() { }
+
+ bool isPageNode() const override { return true; }
+ bool isTextPageNode() const override { return !isAggregate(); } // PageNode but not Aggregate
+ virtual bool isDummyNode() const { return false; }
+
+ QString title() const override { return title_; }
+ QString subtitle() const override { return subtitle_; }
+ QString fullTitle() const override;
+ bool setTitle(const QString& title) override;
+ bool setSubtitle(const QString &subtitle) override { subtitle_ = subtitle; return true; }
+ QString nameForLists() const override { return title(); }
+
+ virtual QString imageFileName() const { return QString(); }
+ virtual void setImageFileName(const QString& ) { }
+
+ bool noAutoList() const { return noAutoList_; }
+ void setNoAutoList(bool b) override { noAutoList_ = b; }
+ const QStringList& groupNames() const { return groupNames_; }
+ void appendGroupName(const QString& t) override { groupNames_.append(t); }
+
+ const QStringList& pageKeywords() const { return pageKeywds_; }
+ void addPageKeywords(const QString& t) override { pageKeywds_ << t; }
+ void setOutputFileName(const QString& f) override { outputFileName_ = f; }
+ QString outputFileName() const override { return outputFileName_; }
+
+ void removeFromRelated();
+ const NodeList & relatedNodes() const { return related_; }
+
+ protected:
+ friend class Node;
+ void removeRelated(Node* pseudoChild);
+ void addRelated(Node* pseudoChild);
+ virtual void removePseudoChild(Node *) { }
+ virtual void addPseudoChild(Node *) { }
+
+ protected:
+ bool noAutoList_;
+ QString title_;
+ QString subtitle_;
+ QString outputFileName_;
+ QStringList groupNames_;
+ QStringList pageKeywds_;
+ NodeList related_;
+};
+
+class DummyNode : public PageNode
+{
+public:
+ DummyNode(Aggregate* parent, const QString& name) : PageNode(parent, name) { }
+ bool isDummyNode() const override { return true; }
+};
+
+class ExternalPageNode : public PageNode
+{
+public:
+ ExternalPageNode(Aggregate* parent, const QString& name)
+ : PageNode(Node::ExternalPage, parent, name) {
+ setPageType(Node::ArticlePage);
+ }
+};
+
+class Aggregate : public PageNode
{
public:
virtual ~Aggregate();
@@ -404,86 +458,60 @@ public:
void findChildren(const QString& name, NodeList& nodes) const override;
FunctionNode* findFunctionNode(const QString& name, const QString& params) const;
FunctionNode* findFunctionNode(const FunctionNode* clone) const;
- void addInclude(const QString &include);
- void setIncludes(const QStringList &includes);
+
void normalizeOverloads();
void makeUndocumentedChildrenInternal();
void deleteChildren();
- void removeFromRelated();
bool isAggregate() const override { return true; }
- bool isLeaf() const override { return false; }
const EnumNode* findEnumNodeForValue(const QString &enumValue) const;
- const NodeList & childNodes() const { return children_; }
- const NodeList & relatedNodes() const { return related_; }
int count() const { return children_.size(); }
+ const NodeList & childNodes() const { return children_; }
+
NodeList overloads(const QString &funcName) const;
+ void addInclude(const QString &include);
+ void setIncludes(const QStringList &includes);
const QStringList& includes() const { return includes_; }
QStringList primaryKeys();
QStringList secondaryKeys();
- const QStringList& pageKeywords() const { return pageKeywds; }
- void addPageKeywords(const QString& t) override { pageKeywds << t; }
- void setOutputFileName(const QString& f) override { outputFileName_ = f; }
- QString outputFileName() const override { return outputFileName_; }
- QmlPropertyNode* hasQmlProperty(const QString& ) const override;
- QmlPropertyNode* hasQmlProperty(const QString&, bool attached) const override;
+ QmlPropertyNode* hasQmlProperty(const QString& ) const;
+ QmlPropertyNode* hasQmlProperty(const QString&, bool attached) const;
virtual QmlTypeNode* qmlBaseNode() const { return 0; }
- void addChild(Node* child, const QString& title);
- const QStringList& groupNames() const { return groupNames_; }
- void appendGroupName(const QString& t) override { groupNames_.append(t); }
+ void addChildByTitle(Node* child, const QString& title);
void printChildren(const QString& title);
void addChild(Node* child);
void removeChild(Node* child);
void setOutputSubdirectory(const QString& t) override;
const NodeMap& primaryFunctionMap() { return primaryFunctionMap_; }
const QMap<QString, NodeList>& secondaryFunctionMap() { return secondaryFunctionMap_; }
- bool noAutoList() const { return noAutoList_; }
- void setNoAutoList(bool b) override { noAutoList_ = b; }
+
protected:
- Aggregate(NodeType type, Aggregate* parent, const QString& name);
+ Aggregate(NodeType type, Aggregate* parent, const QString& name) : PageNode(type, parent, name) { }
+
+ void removePseudoChild(Node *pseudoChild) override;
+ void addPseudoChild(Node *pseudoChild) override;
private:
friend class Node;
-
static bool isSameSignature(const FunctionNode* f1, const FunctionNode* f2);
- void removeRelated(Node* pseudoChild);
- void addRelated(Node* pseudoChild);
- QString outputFileName_;
- QStringList pageKeywds;
+private:
QStringList includes_;
- QStringList groupNames_;
NodeList children_;
NodeList enumChildren_;
- NodeList related_;
NodeMap childMap_;
NodeMap primaryFunctionMap_;
QMap<QString, NodeList> secondaryFunctionMap_;
- bool noAutoList_;
-};
-
-class LeafNode : public Node
-{
-public:
- LeafNode();
- virtual ~LeafNode() { }
-
- bool isAggregate() const override { return false; }
- bool isLeaf() const override { return true; }
-
-protected:
- LeafNode(NodeType type, Aggregate* parent, const QString& name);
- LeafNode(Aggregate* parent, NodeType type, const QString& name);
};
class NamespaceNode : public Aggregate
{
public:
- NamespaceNode(Aggregate* parent, const QString& name);
+ NamespaceNode(Aggregate* parent, const QString& name) : Aggregate(Namespace, parent, name),
+ seen_(false), documented_(false), tree_(0), docNode_(0) { }
virtual ~NamespaceNode() { }
- bool isNamespace() const override { return true; }
Tree* tree() const override { return (parent() ? parent()->tree() : tree_); }
bool wasSeen() const override { return seen_; }
@@ -503,7 +531,7 @@ public:
void setDocNode(NamespaceNode* ns) { docNode_ = ns; }
NamespaceNode* docNode() const { return docNode_; }
- private:
+private:
bool seen_;
bool documented_;
Tree* tree_;
@@ -545,9 +573,9 @@ struct UsingClause
class ClassNode : public Aggregate
{
public:
- ClassNode(Aggregate* parent, const QString& name);
+ ClassNode(Aggregate* parent, const QString& name) : Aggregate(Class, parent, name),
+ abstract_(false), wrapper_(false), qmlelement(0) { }
virtual ~ClassNode() { }
- bool isClass() const override { return true; }
bool isWrapper() const override { return wrapper_; }
QString obsoleteLink() const override { return obsoleteLink_; }
void setObsoleteLink(const QString& t) override { obsoleteLink_ = t; }
@@ -589,50 +617,42 @@ private:
QmlTypeNode* qmlelement;
};
-class DocumentNode : public Aggregate
+class HeaderNode : public Aggregate
{
public:
-
- DocumentNode(Aggregate* parent,
- const QString& name,
- DocSubtype docSubtype,
- PageType ptype);
- virtual ~DocumentNode() { }
-
- bool isDocumentNode() const override { return true; }
- void setTitle(const QString &title) override;
- void setSubTitle(const QString &subTitle) override { subtitle_ = subTitle; }
-
- DocSubtype docSubtype() const override { return nodeSubtype_; }
- QString title() const override { return title_; }
- QString fullTitle() const override;
- QString subTitle() const override;
- virtual QString imageFileName() const { return QString(); }
+ HeaderNode(Aggregate* parent, const QString& name) : Aggregate(HeaderFile, parent, name) { }
+ virtual ~HeaderNode() { }
+ QString title() const override { return (title_.isEmpty() ? name() : title_); }
+ QString subtitle() const override { return subtitle_; }
+ QString fullTitle() const override { return (title_.isEmpty() ? name() : name() + " - " + title_); }
+ bool setTitle(const QString& title) override { title_ = title; return true; }
+ bool setSubtitle(const QString &subtitle) override { subtitle_ = subtitle; return true; }
QString nameForLists() const override { return title(); }
- virtual void setImageFileName(const QString& ) { }
-
- bool isHeaderFile() const override { return (docSubtype() == Node::HeaderFile); }
- bool isExample() const override { return (docSubtype() == Node::Example); }
- bool isExampleFile() const override { return (parent() && parent()->isExample()); }
- bool isExternalPage() const override { return nodeSubtype_ == ExternalPage; }
-protected:
- DocSubtype nodeSubtype_;
+private:
QString title_;
QString subtitle_;
};
-class ExampleNode : public DocumentNode
+class ExampleNode : public PageNode
{
public:
ExampleNode(Aggregate* parent, const QString& name)
- : DocumentNode(parent, name, Node::Example, Node::ExamplePage) { }
+ : PageNode(Node::Example, parent, name) { }
virtual ~ExampleNode() { }
QString imageFileName() const override { return imageFileName_; }
void setImageFileName(const QString& ifn) override { imageFileName_ = ifn; }
+ const QStringList& files() const { return files_; }
+ const QStringList& images() const { return images_; }
+ void setFiles(const QStringList files) { files_ = files; }
+ void setImages(const QStringList images) { images_ = images; }
+ void appendFile(QString &file) { files_.append(file); }
+ void appendImage(QString &image) { images_.append(image); }
private:
QString imageFileName_;
+ QStringList files_;
+ QStringList images_;
};
struct ImportRec {
@@ -658,10 +678,8 @@ typedef QList<ImportRec> ImportList;
class QmlTypeNode : public Aggregate
{
public:
- QmlTypeNode(Aggregate* parent, const QString& name);
+ QmlTypeNode(Aggregate* parent, const QString& name, NodeType type = QmlType);
virtual ~QmlTypeNode();
- bool isQmlType() const override { return isQmlNode(); }
- bool isJsType() const override { return isJsNode(); }
bool isQtQuickNode() const override {
return (logicalModuleName() == QLatin1String("QtQuick"));
}
@@ -714,11 +732,8 @@ private:
class QmlBasicTypeNode : public Aggregate
{
public:
- QmlBasicTypeNode(Aggregate* parent,
- const QString& name);
+ QmlBasicTypeNode(Aggregate* parent, const QString& name, NodeType type = QmlBasicType);
virtual ~QmlBasicTypeNode() { }
- bool isQmlBasicType() const override { return (genus() == Node::QML); }
- bool isJsBasicType() const override { return (genus() == Node::JS); }
};
class QmlPropertyGroupNode : public Aggregate
@@ -738,15 +753,13 @@ public:
return parent()->logicalModuleIdentifier();
}
QString idNumber() override;
- bool isQmlPropertyGroup() const override { return genus() == Node::QML; }
- bool isJsPropertyGroup() const override { return genus() == Node::JS; }
QString element() const override { return parent()->name(); }
- private:
+private:
int idNumber_;
};
-class QmlPropertyNode : public LeafNode
+class QmlPropertyNode : public Node
{
Q_DECLARE_TR_FUNCTIONS(QDoc::QmlPropertyNode)
@@ -769,8 +782,6 @@ public:
bool isStored() const { return fromFlagValue(stored_,true); }
bool isDesignable() const { return fromFlagValue(designable_,false); }
bool isWritable();
- bool isQmlProperty() const override { return genus() == QML; }
- bool isJsProperty() const override { return genus() == JS; }
bool isDefault() const override { return isdefault_; }
bool isReadOnly() const override { return fromFlagValue(readOnly_,false); }
bool isAlias() const override { return isAlias_; }
@@ -788,7 +799,7 @@ public:
}
QString element() const override;
- private:
+private:
PropertyNode* findCorrespondingCppProperty();
private:
@@ -816,16 +827,15 @@ private:
QString value_;
};
-class EnumNode : public LeafNode
+class EnumNode : public Node
{
public:
- EnumNode(Aggregate* parent, const QString& name);
+ EnumNode(Aggregate *parent, const QString& name) : Node(Enum, parent, name), flagsType_(0) { }
virtual ~EnumNode() { }
void addItem(const EnumItem& item);
void setFlagsType(TypedefNode* typedeff);
bool hasItem(const QString &name) const { return names_.contains(name); }
- bool isEnumType() const override { return true; }
const QList<EnumItem>& items() const { return items_; }
Access itemAccess(const QString& name) const;
@@ -838,13 +848,13 @@ private:
const TypedefNode* flagsType_;
};
-class TypedefNode : public LeafNode
+class TypedefNode : public Node
{
public:
- TypedefNode(Aggregate* parent, const QString& name);
+ TypedefNode(Aggregate *parent, const QString& name) : Node(Typedef, parent, name),
+ associatedEnum_(0) { }
virtual ~TypedefNode() { }
- virtual bool isTypedef() const { return true; }
const EnumNode* associatedEnum() const { return associatedEnum_; }
private:
@@ -857,14 +867,14 @@ private:
class TypeAliasNode : public TypedefNode
{
- public:
- TypeAliasNode(Aggregate* parent, const QString& name, const QString& aliasedType);
+public:
+ TypeAliasNode(Aggregate *parent, const QString& name, const QString& aliasedType)
+ : TypedefNode(parent, name), aliasedType_(aliasedType) { }
virtual ~TypeAliasNode() { }
- virtual bool isTypeAlias() const { return true; }
QString aliasedType() { return aliasedType_; }
- private:
+private:
QString aliasedType_;
};
@@ -895,36 +905,35 @@ public:
QString reconstruct(bool value = false) const;
- public:
+public:
QString dataType_;
QString name_;
QString defaultValue_;
};
-class SharedCommentNode : public LeafNode
+class SharedCommentNode : public Node
{
- public:
+public:
SharedCommentNode(Node *n)
- : LeafNode(Node::SharedComment, n->parent(), QString()) {
+ : Node(Node::SharedComment, n->parent(), QString()) {
collective_.reserve(1); n->setSharedCommentNode(this);
}
virtual ~SharedCommentNode() { collective_.clear(); }
- bool isSharedCommentNode() const override { return true; }
void append(Node* n) { collective_.append(n); }
const QVector<Node*>& collective() const { return collective_; }
void setOverloadFlag(bool b) override;
- void setRelates(Aggregate* pseudoParent) override;
+ void setRelates(PageNode* pseudoParent) override;
void setRelates(const QString &name) override;
- private:
+private:
QVector<Node*> collective_;
};
//friend class QTypeInfo<Parameter>;
//Q_DECLARE_TYPEINFO(Parameter, Q_MOVABLE_TYPE);
-class FunctionNode : public LeafNode
+class FunctionNode : public Node
{
public:
enum Virtualness { NonVirtual, NormalVirtual, PureVirtual };
@@ -941,17 +950,31 @@ public:
MacroWithoutParams,
Native,
CAssign, // copy-assignment operator
- MAssign // move-assignment operator
+ MAssign, // move-assignment operator
+ QmlSignal,
+ QmlSignalHandler,
+ QmlMethod,
+ JsSignal,
+ JsSignalHandler,
+ JsMethod
};
- FunctionNode(Aggregate* parent, const QString &name);
- FunctionNode(NodeType type, Aggregate* parent, const QString &name, bool attached);
+ FunctionNode(Aggregate* parent, const QString &name); // C++ function (Plain)
+ FunctionNode(Metaness type, Aggregate* parent, const QString &name, bool attached = false);
virtual ~FunctionNode() { }
+ Metaness metaness() const { return metaness_; }
+ QString metanessString() const;
+ bool changeMetaness(Metaness from, Metaness to);
+ void setMetaness(Metaness t) { metaness_ = t; }
+ Metaness setMetaness(const QString& t);
+ QString kindString() const;
+ static Metaness getMetaness(const QString& t);
+ static Metaness getMetanessFromTopic(const QString& t);
+ static Genus getGenus(Metaness t);
+
void setReturnType(const QString& t) { returnType_ = t; }
void setParentPath(const QStringList& p) { parentPath_ = p; }
- void setMetaness(Metaness t) { metaness_ = t; }
- void setMetaness(const QString& t);
void setVirtualness(const QString& t);
void setVirtualness(Virtualness v) { virtualness_ = v; }
void setVirtual() { virtualness_ = NormalVirtual; }
@@ -968,19 +991,17 @@ public:
void setReimplementedFrom(const QString &path) { reimplementedFrom_ = path; }
const QString& returnType() const { return returnType_; }
- QString metaness() const;
QString virtualness() const;
bool isConst() const { return const_; }
bool isStatic() const override { return static_; }
bool isOverload() const { return overload_; }
bool isReimplemented() const override { return reimplemented_; }
- bool isFunction() const override { return true; }
bool isSomeCtor() const { return isCtor() || isCCtor() || isMCtor(); }
bool isMacroWithParams() const { return (metaness_ == MacroWithParams); }
bool isMacroWithoutParams() const { return (metaness_ == MacroWithoutParams); }
- bool isMacro() const override {
- return (isMacroWithParams() || isMacroWithoutParams());
- }
+ bool isMacro() const override { return (isMacroWithParams() || isMacroWithoutParams()); }
+
+ bool isCppFunction() const { return metaness_ == Plain; } // Is this correct?
bool isSignal() const { return (metaness_ == Signal); }
bool isSlot() const { return (metaness_ == Slot); }
bool isCtor() const { return (metaness_ == Ctor); }
@@ -989,30 +1010,22 @@ public:
bool isMCtor() const { return (metaness_ == MCtor); }
bool isCAssign() const { return (metaness_ == CAssign); }
bool isMAssign() const { return (metaness_ == MAssign); }
+
+ bool isJsMethod() const { return (metaness_ == JsMethod); }
+ bool isJsSignal() const { return (metaness_ == JsSignal); }
+ bool isJsSignalHandler() const { return (metaness_ == JsSignalHandler); }
+
+ bool isQmlMethod() const { return (metaness_ == QmlMethod); }
+ bool isQmlSignal() const { return (metaness_ == QmlSignal); }
+ bool isQmlSignalHandler() const { return (metaness_ == QmlSignalHandler); }
+
bool isSpecialMemberFunction() const {
return (isDtor() || isCCtor() || isMCtor() || isCAssign() || isMAssign());
}
bool isNonvirtual() const { return (virtualness_ == NonVirtual); }
bool isVirtual() const { return (virtualness_ == NormalVirtual); }
bool isPureVirtual() const { return (virtualness_ == PureVirtual); }
- bool isQmlSignal() const override {
- return (type() == Node::QmlSignal) && (genus() == Node::QML);
- }
- bool isJsSignal() const override {
- return (type() == Node::QmlSignal) && (genus() == Node::JS);
- }
- bool isQmlSignalHandler() const override {
- return (type() == Node::QmlSignalHandler) && (genus() == Node::QML);
- }
- bool isJsSignalHandler() const override {
- return (type() == Node::QmlSignalHandler) && (genus() == Node::JS);
- }
- bool isQmlMethod() const override {
- return (type() == Node::QmlMethod) && (genus() == Node::QML);
- }
- bool isJsMethod() const override {
- return (type() == Node::QmlMethod) && (genus() == Node::JS);
- }
+
QVector<Parameter> &parameters() { return parameters_; }
const QVector<Parameter>& parameters() const { return parameters_; }
void clearParams() { parameters_.clear(); }
@@ -1032,15 +1045,9 @@ public:
bool isAttached() const override { return attached_; }
bool isQtQuickNode() const override { return parent()->isQtQuickNode(); }
QString qmlTypeName() const override { return parent()->qmlTypeName(); }
- QString logicalModuleName() const override {
- return parent()->logicalModuleName();
- }
- QString logicalModuleVersion() const override {
- return parent()->logicalModuleVersion();
- }
- QString logicalModuleIdentifier() const override {
- return parent()->logicalModuleIdentifier();
- }
+ QString logicalModuleName() const override { return parent()->logicalModuleName(); }
+ QString logicalModuleVersion() const override { return parent()->logicalModuleVersion(); }
+ QString logicalModuleIdentifier() const override { return parent()->logicalModuleIdentifier(); }
bool isPrivateSignal() const { return privateSignal_; }
void setPrivateSignal() { privateSignal_ = true; }
@@ -1107,7 +1114,7 @@ private:
QString tag_;
};
-class PropertyNode : public LeafNode
+class PropertyNode : public Node
{
public:
enum FunctionRole { Getter, Setter, Resetter, Notifier };
@@ -1117,7 +1124,6 @@ public:
virtual ~PropertyNode() { }
void setDataType(const QString& dataType) override { type_ = dataType; }
- bool isProperty() const override { return true; }
void addFunction(FunctionNode* function, FunctionRole role);
void addSignal(FunctionNode* function, FunctionRole role);
void setStored(bool stored) { stored_ = toFlagValue(stored); }
@@ -1199,7 +1205,7 @@ inline NodeList PropertyNode::functions() const
return list;
}
-class VariableNode : public LeafNode
+class VariableNode : public Node
{
public:
VariableNode(Aggregate* parent, const QString &name);
@@ -1213,7 +1219,6 @@ public:
const QString &rightType() const { return rightType_; }
QString dataType() const { return leftType_ + rightType_; }
bool isStatic() const override { return static_; }
- virtual bool isVariable() const override { return true; }
private:
QString leftType_;
@@ -1222,40 +1227,19 @@ private:
};
inline VariableNode::VariableNode(Aggregate* parent, const QString &name)
- : LeafNode(Variable, parent, name), static_(false)
+ : Node(Variable, parent, name), static_(false)
{
setGenus(Node::CPP);
}
-class DitaMapNode : public DocumentNode
+class CollectionNode : public PageNode
{
public:
- DitaMapNode(Aggregate* parent, const QString& name)
- : DocumentNode(parent, name, Node::Page, Node::DitaMapPage) { }
- virtual ~DitaMapNode() { }
-
- const DitaRefList& map() const { return doc().ditamap(); }
-};
-
-class CollectionNode : public LeafNode
-{
- public:
- CollectionNode(NodeType type,
- Aggregate* parent,
- const QString& name,
- Genus genus)
- : LeafNode(type, parent, name), seen_(false), noAutoList_(false)
- {
- setPageType(Node::OverviewPage);
- setGenus(genus);
- }
+ CollectionNode(NodeType type, Aggregate* parent, const QString& name)
+ : PageNode(type, parent, name), seen_(false) { }
virtual ~CollectionNode() { }
bool isCollectionNode() const override { return true; }
- bool isGroup() const override { return genus() == Node::DOC; }
- bool isModule() const override { return genus() == Node::CPP; }
- bool isQmlModule() const override { return genus() == Node::QML; }
- bool isJsModule() const override { return genus() == Node::JS; }
QString qtVariable() const override { return qtVariable_; }
void setQtVariable(const QString& v) override { qtVariable_ = v; }
void addMember(Node* node) override;
@@ -1265,13 +1249,8 @@ class CollectionNode : public LeafNode
void getMemberNamespaces(NodeMap& out) override;
void getMemberClasses(NodeMap& out) const override;
bool wasSeen() const override { return seen_; }
- QString title() const override { return title_; }
- QString subTitle() const override { return subtitle_; }
- QString fullTitle() const override { return title_; }
- QString nameForLists() const override { return title_; }
- void setTitle(const QString &title) override;
- void setSubTitle(const QString &subTitle) override { subtitle_ = subTitle; }
+ QString fullTitle() const override { return title(); }
QString logicalModuleName() const override { return logicalModuleName_; }
QString logicalModuleVersion() const override {
return logicalModuleVersionMajor_ + QLatin1Char('.') + logicalModuleVersionMinor_;
@@ -1288,19 +1267,9 @@ class CollectionNode : public LeafNode
void markSeen() { seen_ = true; }
void markNotSeen() { seen_ = false; }
- bool noAutoList() const { return noAutoList_; }
- void setNoAutoList(bool b) override { noAutoList_ = b; }
-
- const QStringList& groupNames() const { return groupNames_; }
- void appendGroupName(const QString& t) override { groupNames_.append(t); }
-
- private:
+private:
bool seen_;
- bool noAutoList_;
- QString title_;
- QString subtitle_;
NodeList members_;
- QStringList groupNames_;
QString logicalModuleName_;
QString logicalModuleVersionMajor_;
QString logicalModuleVersionMinor_;
diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp
index 8766622b8..6a19baf55 100644
--- a/src/qdoc/qdocdatabase.cpp
+++ b/src/qdoc/qdocdatabase.cpp
@@ -1027,11 +1027,10 @@ void QDocDatabase::findAllClasses(Aggregate* node)
while (c != node->childNodes().constEnd()) {
if ((*c)->access() != Node::Private && (!(*c)->isInternal() || showInternal_) &&
(*c)->tree()->camelCaseModuleName() != QString("QDoc")) {
-
- if ((*c)->type() == Node::Class) {
+ if ((*c)->isClass()) {
QString className = (*c)->name();
if ((*c)->parent() &&
- (*c)->parent()->type() == Node::Namespace &&
+ (*c)->parent()->nodeType() == Node::Namespace &&
!(*c)->parent()->name().isEmpty())
className = (*c)->parent()->name()+"::"+className;
@@ -1084,7 +1083,7 @@ void QDocDatabase::findAllFunctions(Aggregate* node)
if ((*c)->isAggregate()) {
findAllFunctions(static_cast<Aggregate*>(*c));
}
- else if ((*c)->type() == Node::Function) {
+ else if ((*c)->nodeType() == Node::Function) {
const FunctionNode* func = static_cast<const FunctionNode*>(*c);
if ((func->status() > Node::Obsolete) && !func->isInternal() &&
!func->isSomeCtor() && !func->isDtor()) {
@@ -1104,12 +1103,10 @@ void QDocDatabase::findAllAttributions(Aggregate* node)
NodeList::ConstIterator c = node->childNodes().constBegin();
while (c != node->childNodes().constEnd()) {
if ((*c)->access() != Node::Private) {
- if ((*c)->docSubtype() == Node::Page
- && (*c)->pageType() == Node::AttributionPage) {
+ if ((*c)->pageType() == Node::AttributionPage)
attributions_.insertMulti((*c)->tree()->indexTitle(), *c);
- } else if ((*c)->isAggregate()) {
+ else if ((*c)->isAggregate())
findAllAttributions(static_cast<Aggregate*>(*c));
- }
}
++c;
}
@@ -1161,13 +1158,13 @@ void QDocDatabase::findAllObsoleteThings(Aggregate* node)
{
NodeList::const_iterator c = node->childNodes().constBegin();
while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
+ if (!(*c)->isPrivate()) {
QString name = (*c)->name();
- if ((*c)->status() == Node::Obsolete) {
- if ((*c)->type() == Node::Class) {
- if ((*c)->parent() && (*c)->parent()->type() == Node::Namespace &&
- !(*c)->parent()->name().isEmpty())
- name = (*c)->parent()->name() + "::" + name;
+ if ((*c)->isObsolete()) {
+ if ((*c)->isClass()) {
+ Node* parent = (*c)->parent();
+ if (parent && parent->isNamespace() && !parent->name().isEmpty())
+ name = parent->name() + "::" + name;
obsoleteClasses_.insert(name, *c);
}
else if ((*c)->isQmlType() || (*c)->isJsType()) {
@@ -1177,26 +1174,25 @@ void QDocDatabase::findAllObsoleteThings(Aggregate* node)
obsoleteQmlTypes_.insert(name,*c);
}
}
- else if ((*c)->type() == Node::Class) {
+ else if ((*c)->isClass()) { //not obsolete
Aggregate* n = static_cast<Aggregate*>(*c);
bool inserted = false;
NodeList::const_iterator p = n->childNodes().constBegin();
while (p != n->childNodes().constEnd()) {
- if ((*p)->access() != Node::Private) {
- switch ((*p)->type()) {
+ if (!(*p)->isPrivate() && (*p)->isObsolete()) {
+ switch ((*p)->nodeType()) {
case Node::Enum:
case Node::Typedef:
case Node::Function:
case Node::Property:
- case Node::Variable:
- if ((*p)->status() == Node::Obsolete) {
- if ((*c)->parent() && (*c)->parent()->type() == Node::Namespace &&
- !(*c)->parent()->name().isEmpty())
- name = (*c)->parent()->name() + "::" + name;
- classesWithObsoleteMembers_.insert(name, *c);
- inserted = true;
- }
+ case Node::Variable: {
+ Node* parent = (*c)->parent();
+ if (parent && parent->isNamespace() && !parent->name().isEmpty())
+ name = (*c)->parent()->name() + "::" + name;
+ classesWithObsoleteMembers_.insert(name, *c);
+ inserted = true;
break;
+ }
default:
break;
}
@@ -1211,19 +1207,16 @@ void QDocDatabase::findAllObsoleteThings(Aggregate* node)
bool inserted = false;
NodeList::const_iterator p = n->childNodes().constBegin();
while (p != n->childNodes().constEnd()) {
- if ((*p)->access() != Node::Private) {
- switch ((*c)->type()) {
+ if (!(*p)->isPrivate() && (*p)->isObsolete()) {
+ switch ((*p)->nodeType()) {
+ case Node::JsProperty:
case Node::QmlProperty:
- case Node::QmlSignal:
- case Node::QmlSignalHandler:
- case Node::QmlMethod:
+ case Node::Function:
if ((*c)->parent()) {
Node* parent = (*c)->parent();
- if ((parent->isQmlPropertyGroup() ||
- parent->isJsPropertyGroup()) && parent->parent())
+ if ((parent->isQmlPropertyGroup() || parent->isJsPropertyGroup()) && parent->parent())
parent = parent->parent();
- if (parent && (parent->isQmlType() || parent->isJsType()) &&
- !parent->name().isEmpty())
+ if (parent && (parent->isQmlType() || parent->isJsType()) && !parent->name().isEmpty())
name = parent->name() + "::" + name;
}
qmlTypesWithObsoleteMembers_.insert(name,*c);
@@ -1273,7 +1266,7 @@ void QDocDatabase::findAllSince(Aggregate* node)
if (nqcmap == newQmlTypeMaps_.end())
nqcmap = newQmlTypeMaps_.insert(sinceString,NodeMap());
- if ((*child)->type() == Node::Function) {
+ if ((*child)->nodeType() == Node::Function) {
// Insert functions into the general since map.
FunctionNode *func = static_cast<FunctionNode *>(*child);
if ((func->status() > Node::Obsolete) && !func->isSomeCtor() && !func->isDtor()) {
@@ -1281,7 +1274,7 @@ void QDocDatabase::findAllSince(Aggregate* node)
}
}
else {
- if ((*child)->type() == Node::Class) {
+ if ((*child)->nodeType() == Node::Class) {
// Insert classes into the since and class maps.
QString className = (*child)->name();
if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) {
@@ -1506,7 +1499,7 @@ const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* r
if (target.isEmpty())
node = relative;
else if (target.endsWith(".html"))
- node = findNodeByNameAndType(QStringList(target), Node::Document);
+ node = findNodeByNameAndType(QStringList(target), Node::Page);
else {
QStringList path = target.split("::");
int flags = SearchBaseClasses | SearchEnumValues;
@@ -1516,7 +1509,7 @@ const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* r
return n;
relative = 0;
}
- node = findDocumentNodeByTitle(target);
+ node = findPageNodeByTitle(target);
}
return node;
}
@@ -1677,16 +1670,16 @@ Node* QDocDatabase::findNodeInOpenNamespace(QStringList& path, Node::NodeType ty
}
/*!
- 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.
+ Finds all the collection nodes of the specified \a type
+ and merges them into the collection node map \a cnm. Nodes
+ that match the \a relative node are not included.
*/
-void QDocDatabase::mergeCollections(Node::Genus genus, CNMap& cnm, const Node* relative)
+void QDocDatabase::mergeCollections(Node::NodeType type, CNMap& cnm, const Node* relative)
{
cnm.clear();
CNMultiMap cnmm;
foreach (Tree* t, searchOrder()) {
- CNMap* m = t->getCollectionMap(genus);
+ CNMap* m = t->getCollectionMap(type);
if (m && !m->isEmpty()) {
CNMap::const_iterator i = m->cbegin();
while (i != m->cend()) {
@@ -1714,8 +1707,8 @@ void QDocDatabase::mergeCollections(Node::Genus genus, CNMap& cnm, const Node* r
foreach (CollectionNode* v, values) {
if (v != n) {
// Allow multiple (major) versions of QML/JS modules
- if (n->type() == Node::QmlModule
- && n->logicalModuleIdentifier() != v->logicalModuleIdentifier()) {
+ if ((n->isQmlModule() || n->isJsModule()) &&
+ n->logicalModuleIdentifier() != v->logicalModuleIdentifier()) {
if (v->wasSeen() && v != relative && !v->members().isEmpty())
cnm.insert(v->fullTitle().toLower(), v);
continue;
@@ -1738,20 +1731,20 @@ void QDocDatabase::mergeCollections(Node::Genus genus, CNMap& cnm, const Node* r
/*!
Finds all the collection nodes with the same name
- and genus as \a c and merges their members into the
+ and type as \a c and merges their members into the
members list of \a c.
- For QML and JS modules, the merge is done only if
- the module identifier matches between the nodes, to avoid
- merging modules with different (major) versions.
+ For QML and JS modules, only nodes with matching
+ module identifiers are merged to avoid merging
+ modules with different (major) versions.
*/
void QDocDatabase::mergeCollections(CollectionNode* c)
{
foreach (Tree* t, searchOrder()) {
- CollectionNode* cn = t->getCollection(c->name(), c->genus());
+ CollectionNode* cn = t->getCollection(c->name(), c->nodeType());
if (cn && cn != c) {
- if (cn->type() == Node::QmlModule
- && cn->logicalModuleIdentifier() != c->logicalModuleIdentifier())
+ if ((cn->isQmlModule() || cn->isJsModule()) &&
+ cn->logicalModuleIdentifier() != c->logicalModuleIdentifier())
continue;
foreach (Node* n, cn->members())
c->addMember(n);
@@ -1792,7 +1785,7 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
node = relative; // search for a target on the current page.
else if (domain) {
if (first.endsWith(".html"))
- node = domain->findNodeByNameAndType(QStringList(first), Node::Document);
+ node = domain->findNodeByNameAndType(QStringList(first), Node::Page);
else if (first.endsWith(QChar(')'))) {
QString function, params;
int length = first.length();
@@ -1815,7 +1808,7 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
}
else {
if (first.endsWith(".html"))
- node = findNodeByNameAndType(QStringList(first), Node::Document);
+ node = findNodeByNameAndType(QStringList(first), Node::Page);
else if (first.endsWith(QChar(')'))) {
node = findFunctionNode(first, relative, genus);
}
diff --git a/src/qdoc/qdocdatabase.h b/src/qdoc/qdocdatabase.h
index b2f4f02bc..9e53dde53 100644
--- a/src/qdoc/qdocdatabase.h
+++ b/src/qdoc/qdocdatabase.h
@@ -125,9 +125,9 @@ class QDocForest
return 0;
}
- Aggregate* findRelatesNode(const QStringList& path) {
+ PageNode* findRelatesNode(const QStringList& path) {
foreach (Tree* t, searchOrder()) {
- Aggregate* n = t->findRelatesNode(path);
+ PageNode* n = t->findRelatesNode(path);
if (n)
return n;
}
@@ -160,20 +160,20 @@ class QDocForest
return 0;
}
- const DocumentNode* findDocumentNodeByTitle(const QString& title)
+ const PageNode* findPageNodeByTitle(const QString& title)
{
foreach (Tree* t, searchOrder()) {
- const DocumentNode* n = t->findDocumentNodeByTitle(title);
+ const PageNode* n = t->findPageNodeByTitle(title);
if (n)
return n;
}
return 0;
}
- const CollectionNode* getCollectionNode(const QString& name, Node::Genus genus)
+ const CollectionNode* getCollectionNode(const QString& name, Node::NodeType type)
{
foreach (Tree* t, searchOrder()) {
- const CollectionNode* cn = t->getCollection(name, genus);
+ const CollectionNode* cn = t->getCollection(name, type);
if (cn)
return cn;
}
@@ -336,7 +336,7 @@ class QDocDatabase
********************************************************************/
ClassNode* findClassNode(const QStringList& path) { return forest_.findClassNode(path); }
Node* findNodeForInclude(const QStringList& path) { return forest_.findNodeForInclude(path); }
- Aggregate* findRelatesNode(const QStringList& path) { return forest_.findRelatesNode(path); }
+ PageNode* findRelatesNode(const QStringList& path) { return forest_.findRelatesNode(path); }
const Node* findFunctionNode(const QString& target, const Node* relative, Node::Genus genus) {
return forest_.findFunctionNode(target, relative, genus);
}
@@ -348,14 +348,14 @@ class QDocDatabase
}
const Node* findTypeNode(const QString& type, const Node* relative, Node::Genus genus);
const Node* findNodeForTarget(const QString& target, const Node* relative);
- const DocumentNode* findDocumentNodeByTitle(const QString& title) {
- return forest_.findDocumentNodeByTitle(title);
+ const PageNode* findPageNodeByTitle(const QString& title) {
+ return forest_.findPageNodeByTitle(title);
}
Node* findNodeByNameAndType(const QStringList& path, Node::NodeType type) {
return forest_.findNodeByNameAndType(path, type);
}
- const CollectionNode* getCollectionNode(const QString& name, Node::Genus genus) {
- return forest_.getCollectionNode(name, genus);
+ const CollectionNode* getCollectionNode(const QString& name, Node::NodeType type) {
+ return forest_.getCollectionNode(name, type);
}
Node *findFunctionNodeForTag(QString tag) { return primaryTree()->findFunctionNodeForTag(tag); }
Node* findMacroNode(const QString &t) { return primaryTree()->findMacroNode(t); }
@@ -403,7 +403,7 @@ 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::Genus genus, CNMap& cnm, const Node* relative);
+ void mergeCollections(Node::NodeType type, CNMap& cnm, const Node* relative);
void mergeCollections(CollectionNode* c);
void clearSearchOrder() { forest_.clearSearchOrder(); }
void incrementLinkCount(const Node* t) { t->tree()->incrementLinkCount(); }
diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp
index b5d10485f..cdba1b548 100644
--- a/src/qdoc/qdocindexfiles.cpp
+++ b/src/qdoc/qdocindexfiles.cpp
@@ -40,7 +40,17 @@
QT_BEGIN_NAMESPACE
-static Node* top = 0;
+enum QDocAttr {
+ QDocAttrNone,
+ QDocAttrAttribution,
+ QDocAttrExample,
+ QDocAttrFile,
+ QDocAttrImage,
+ QDocAttrDocument,
+ QDocAttrExternalPage
+};
+
+static Node* root_ = 0;
/*!
\class QDocIndexFiles
@@ -99,7 +109,6 @@ void QDocIndexFiles::readIndexes(const QStringList& indexFiles)
foreach (const QString& indexFile, indexFiles) {
QString msg = "Loading index file: " + indexFile;
Location::logToStdErr(msg);
- //qDebug() << msg;
readIndexFile(indexFile);
}
}
@@ -217,6 +226,17 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
abstract = true;
node->setAbstract(abstract);
}
+ else if (elementName == QLatin1String("header")) {
+ node = new HeaderNode(parent, name);
+
+ if (attributes.hasAttribute(QLatin1String("location")))
+ name = attributes.value(QLatin1String("location")).toString();
+
+ if (!indexUrl.isEmpty())
+ location = Location(indexUrl + QLatin1Char('/') + name);
+ else if (!indexUrl.isNull())
+ location = Location(name);
+ }
else if (elementName == QLatin1String("qmlclass")) {
QmlTypeNode* qcn = new QmlTypeNode(parent, name);
qcn->setTitle(attributes.value(QLatin1String("title")).toString());
@@ -333,35 +353,10 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
qpn->setReadOnly(readonly);
node = qpn;
}
- else if ((elementName == QLatin1String("qmlmethod")) ||
- (elementName == QLatin1String("qmlsignal")) ||
- (elementName == QLatin1String("qmlsignalhandler"))) {
- Node::NodeType t = Node::QmlMethod;
- if (elementName == QLatin1String("qmlsignal"))
- t = Node::QmlSignal;
- else if (elementName == QLatin1String("qmlsignalhandler"))
- t = Node::QmlSignalHandler;
- bool attached = false;
- FunctionNode* fn = new FunctionNode(t, parent, name, attached);
- node = fn;
- }
- else if ((elementName == QLatin1String("jsmethod")) ||
- (elementName == QLatin1String("jssignal")) ||
- (elementName == QLatin1String("jssignalhandler"))) {
- Node::NodeType t = Node::QmlMethod;
- if (elementName == QLatin1String("jssignal"))
- t = Node::QmlSignal;
- else if (elementName == QLatin1String("jssignalhandler"))
- t = Node::QmlSignalHandler;
- bool attached = false;
- FunctionNode* fn = new FunctionNode(t, parent, name, attached);
- fn->setGenus(Node::JS);
- node = fn;
- }
else if (elementName == QLatin1String("group")) {
CollectionNode* cn = qdb_->addGroup(name);
cn->setTitle(attributes.value(QLatin1String("title")).toString());
- cn->setSubTitle(attributes.value(QLatin1String("subtitle")).toString());
+ cn->setSubtitle(attributes.value(QLatin1String("subtitle")).toString());
if (attributes.value(QLatin1String("seen")) == QLatin1String("true"))
cn->markSeen();
node = cn;
@@ -369,7 +364,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (elementName == QLatin1String("module")) {
CollectionNode* cn = qdb_->addModule(name);
cn->setTitle(attributes.value(QLatin1String("title")).toString());
- cn->setSubTitle(attributes.value(QLatin1String("subtitle")).toString());
+ cn->setSubtitle(attributes.value(QLatin1String("subtitle")).toString());
if (attributes.value(QLatin1String("seen")) == QLatin1String("true"))
cn->markSeen();
node = cn;
@@ -381,7 +376,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
info << t << attributes.value(QLatin1String("qml-module-version")).toString();
cn->setLogicalModuleInfo(info);
cn->setTitle(attributes.value(QLatin1String("title")).toString());
- cn->setSubTitle(attributes.value(QLatin1String("subtitle")).toString());
+ cn->setSubtitle(attributes.value(QLatin1String("subtitle")).toString());
if (attributes.value(QLatin1String("seen")) == QLatin1String("true"))
cn->markSeen();
node = cn;
@@ -393,44 +388,61 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
info << t << attributes.value(QLatin1String("js-module-version")).toString();
cn->setLogicalModuleInfo(info);
cn->setTitle(attributes.value(QLatin1String("title")).toString());
- cn->setSubTitle(attributes.value(QLatin1String("subtitle")).toString());
+ cn->setSubtitle(attributes.value(QLatin1String("subtitle")).toString());
if (attributes.value(QLatin1String("seen")) == QLatin1String("true"))
cn->markSeen();
node = cn;
}
else if (elementName == QLatin1String("page")) {
- Node::DocSubtype subtype;
+ QDocAttr subtype = QDocAttrNone;
Node::PageType ptype = Node::NoPageType;
QString attr = attributes.value(QLatin1String("subtype")).toString();
if (attr == QLatin1String("attribution")) {
- subtype = Node::Page;
+ subtype = QDocAttrDocument;
ptype = Node::AttributionPage;
}
else if (attr == QLatin1String("example")) {
- subtype = Node::Example;
+ subtype = QDocAttrExample;
ptype = Node::ExamplePage;
}
- else if (attr == QLatin1String("header")) {
- subtype = Node::HeaderFile;
- ptype = Node::ApiPage;
- }
else if (attr == QLatin1String("file")) {
- subtype = Node::File;
+ subtype = QDocAttrFile;
+ ptype = Node::NoPageType;
+ }
+ else if (attr == QLatin1String("image")) {
+ subtype = QDocAttrImage;
ptype = Node::NoPageType;
}
else if (attr == QLatin1String("page")) {
- subtype = Node::Page;
+ subtype = QDocAttrDocument;
ptype = Node::ArticlePage;
}
else if (attr == QLatin1String("externalpage")) {
- subtype = Node::ExternalPage;
+ subtype = QDocAttrExternalPage;
ptype = Node::ArticlePage;
}
else
goto done;
- DocumentNode* docNode = new DocumentNode(parent, name, subtype, ptype);
- docNode->setTitle(attributes.value(QLatin1String("title")).toString());
+ if (current && current->isExample()) {
+ ExampleNode* en = static_cast<ExampleNode *>(current);
+ if (subtype == QDocAttrFile) {
+ en->appendFile(name);
+ goto done;
+ }
+ else if (subtype == QDocAttrImage) {
+ en->appendImage(name);
+ goto done;
+ }
+ }
+ PageNode* pn = 0;
+ if (subtype == QDocAttrExample)
+ pn = new ExampleNode(parent, name);
+ else if (subtype == QDocAttrExternalPage)
+ pn = new ExternalPageNode(parent, name);
+ else
+ pn = new PageNode(parent, name, ptype);
+ pn->setTitle(attributes.value(QLatin1String("title")).toString());
if (attributes.hasAttribute(QLatin1String("location")))
name = attributes.value(QLatin1String("location")).toString();
@@ -440,7 +452,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(name);
- node = docNode;
+ node = pn;
}
else if (elementName == QLatin1String("enum")) {
@@ -486,60 +498,65 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(parent->name().toLower() + ".html");
- }
- else if (elementName == QLatin1String("function")) {
- FunctionNode* functionNode = new FunctionNode(parent, name);
- functionNode->setReturnType(attributes.value(QLatin1String("return")).toString());
- functionNode->setVirtualness(attributes.value(QLatin1String("virtual")).toString());
- functionNode->setMetaness(attributes.value(QLatin1String("meta")).toString());
- functionNode->setConst(attributes.value(QLatin1String("const")) == QLatin1String("true"));
- functionNode->setStatic(attributes.value(QLatin1String("static")) == QLatin1String("true"));
- functionNode->setIsDeleted(attributes.value(QLatin1String("delete")) == QLatin1String("true"));
- functionNode->setIsDefaulted(attributes.value(QLatin1String("default")) == QLatin1String("true"));
- functionNode->setFinal(attributes.value(QLatin1String("final")) == QLatin1String("true"));
- functionNode->setOverride(attributes.value(QLatin1String("override")) == QLatin1String("true"));
- int refness = attributes.value(QLatin1String("refness")).toUInt();
- if (refness == 1)
- functionNode->setRef(true);
- else if (refness == 2)
- functionNode->setRefRef(true);
- if (attributes.value(QLatin1String("overload")) == QLatin1String("true")) {
- functionNode->setOverloadFlag(true);
- functionNode->setOverloadNumber(attributes.value(QLatin1String("overload-number")).toUInt());
- }
- else {
- functionNode->setOverloadFlag(false);
- functionNode->setOverloadNumber(0);
- }
- if (attributes.hasAttribute(QLatin1String("relates"))
- && attributes.value(QLatin1String("relates")) != parent->name()) {
- relatedList_.append(
- QPair<FunctionNode*,QString>(functionNode,
- attributes.value(QLatin1String("relates")).toString()));
- }
- /*
- Note: The "signature" attribute was written to the
- index file, but it is not read back in. Is that ok?
- */
-
- while (reader.readNextStartElement()) {
- QXmlStreamAttributes childAttributes = reader.attributes();
- if (reader.name() == QLatin1String("parameter")) {
- // Do not use the default value for the parameter; it is not
- // required, and has been known to cause problems.
- Parameter parameter(childAttributes.value(QLatin1String("type")).toString(),
- childAttributes.value(QLatin1String("name")).toString(),
- QString()); // childAttributes.value(QLatin1String("default"))
- functionNode->addParameter(parameter);
- } else if (reader.name() == QLatin1String("keyword")) {
- insertTarget(TargetRec::Keyword, childAttributes, functionNode);
- } else if (reader.name() == QLatin1String("target")) {
- insertTarget(TargetRec::Target, childAttributes, functionNode);
+ } else if (elementName == QLatin1String("function")) {
+ QString t = attributes.value(QLatin1String("meta")).toString();
+ bool attached = false;
+ FunctionNode::Metaness metaness = FunctionNode::Plain;
+ if (!t.isEmpty())
+ metaness = FunctionNode::getMetaness(t);
+ if (attributes.value(QLatin1String("attached")) == QLatin1String("true"))
+ attached = true;
+ FunctionNode* fn = new FunctionNode(metaness, parent, name, attached);
+ if (fn->isCppNode()) {
+ fn->setReturnType(attributes.value(QLatin1String("return")).toString());
+ fn->setVirtualness(attributes.value(QLatin1String("virtual")).toString());
+ fn->setConst(attributes.value(QLatin1String("const")) == QLatin1String("true"));
+ fn->setStatic(attributes.value(QLatin1String("static")) == QLatin1String("true"));
+ fn->setIsDeleted(attributes.value(QLatin1String("delete")) == QLatin1String("true"));
+ fn->setIsDefaulted(attributes.value(QLatin1String("default")) == QLatin1String("true"));
+ fn->setFinal(attributes.value(QLatin1String("final")) == QLatin1String("true"));
+ fn->setOverride(attributes.value(QLatin1String("override")) == QLatin1String("true"));
+ int refness = attributes.value(QLatin1String("refness")).toUInt();
+ if (refness == 1)
+ fn->setRef(true);
+ else if (refness == 2)
+ fn->setRefRef(true);
+ if (attributes.value(QLatin1String("overload")) == QLatin1String("true")) {
+ fn->setOverloadFlag(true);
+ fn->setOverloadNumber(attributes.value(QLatin1String("overload-number")).toUInt());
+ }
+ else {
+ fn->setOverloadFlag(false);
+ fn->setOverloadNumber(0);
+ }
+ if (attributes.hasAttribute(QLatin1String("relates"))) {
+ QString relatesName = attributes.value(QLatin1String("relates")).toString();
+ if (relatesName != parent->name())
+ relatedList_.append(QPair<FunctionNode*, QString>(fn, relatesName));
+ }
+ /*
+ Note: The "signature" attribute was written to the
+ index file, but it is not read back in. Is that ok?
+ */
+ while (reader.readNextStartElement()) {
+ QXmlStreamAttributes childAttributes = reader.attributes();
+ if (reader.name() == QLatin1String("parameter")) {
+ // Do not use the default value for the parameter; it is not
+ // required, and has been known to cause problems.
+ Parameter parameter(childAttributes.value(QLatin1String("type")).toString(),
+ childAttributes.value(QLatin1String("name")).toString(),
+ QString()); // childAttributes.value(QLatin1String("default"))
+ fn->addParameter(parameter);
+ } else if (reader.name() == QLatin1String("keyword")) {
+ insertTarget(TargetRec::Keyword, childAttributes, fn);
+ } else if (reader.name() == QLatin1String("target")) {
+ insertTarget(TargetRec::Target, childAttributes, fn);
+ }
+ reader.skipCurrentElement();
}
- reader.skipCurrentElement();
}
- node = functionNode;
+ node = fn;
if (!indexUrl.isEmpty())
location = Location(indexUrl + QLatin1Char('/') + parent->name().toLower() + ".html");
else if (!indexUrl.isNull())
@@ -749,7 +766,7 @@ void QDocIndexFiles::resolveRelates()
QStringList path = relatedPair.second.split("::");
Node* n = qdb_->findRelatesNode(path);
if (n)
- relatedPair.first->setRelates(static_cast<Aggregate*>(n));
+ relatedPair.first->setRelates(static_cast<PageNode*>(n));
}
// Restore original search order
qdb_->setSearchOrder(searchOrder);
@@ -758,8 +775,11 @@ void QDocIndexFiles::resolveRelates()
/*!
Generate the index section with the given \a writer for the \a node
- specified, returning true if an element was written; otherwise returns
- false.
+ specified, returning true if an element was written, and returning
+ false if an element is not written.
+
+ \node Currently \a generateInternalNodes is always \c true. If it is
+ passed as \c false, then nodes marked internal or private are skipped.
*/
bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
Node* node,
@@ -770,41 +790,58 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
Q_ASSERT(gen_);
/*
- Don't include index nodes in a new index file. Or DITA map nodes.
+ Don't include index nodes in a new index file.
*/
- if (node->isIndexNode() || node->docSubtype() == Node::DitaMap)
+ if (node->isIndexNode())
+ return false;
+ if (!generateInternalNodes && (node->isInternal() || node->isPrivate()))
return false;
QString nodeName;
QString logicalModuleName;
QString logicalModuleVersion;
QString qmlFullBaseName;
- switch (node->type()) {
+ QString baseNameAttr;
+ QString moduleNameAttr;
+ QString moduleVerAttr;
+
+ switch (node->nodeType()) {
case Node::Namespace:
nodeName = "namespace";
break;
case Node::Class:
nodeName = "class";
break;
+ case Node::HeaderFile:
+ nodeName = "header";
+ break;
case Node::QmlType:
- {
- if (node->isQmlNode())
- nodeName = "qmlclass";
- else
- nodeName = "jstype";
- CollectionNode* cn = node->logicalModule();
- if (cn)
- logicalModuleName = cn->logicalModuleName();
- qmlFullBaseName = node->qmlFullBaseName();
- }
+ nodeName = "qmlclass";
+ if (node->logicalModule() != nullptr)
+ logicalModuleName = node->logicalModule()->logicalModuleName();
+ baseNameAttr = "qml-base-type";
+ moduleNameAttr = "qml-module-name";
+ moduleVerAttr = "qml-module-version";
+ qmlFullBaseName = node->qmlFullBaseName();
+ break;
+ case Node::JsType:
+ nodeName = "jstype";
+ baseNameAttr = "js-base-type";
+ moduleNameAttr = "js-module-name";
+ moduleVerAttr = "js-module-version";
+ if (node->logicalModule() != nullptr)
+ logicalModuleName = node->logicalModule()->logicalModuleName();
+ qmlFullBaseName = node->qmlFullBaseName();
break;
case Node::QmlBasicType:
- if (node->isQmlNode())
- nodeName = "qmlbasictype";
- else
- nodeName = "jsbasictype";
+ nodeName = "qmlbasictype";
break;
- case Node::Document:
+ case Node::JsBasicType:
+ nodeName = "jsbasictype";
+ break;
+ case Node::Page:
+ case Node::Example:
+ case Node::ExternalPage:
nodeName = "page";
break;
case Node::Group:
@@ -814,10 +851,18 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
nodeName = "module";
break;
case Node::QmlModule:
- if (node->isQmlNode())
- nodeName = "qmlmodule";
- else
- nodeName = "jsmodule";
+ nodeName = "qmlmodule";
+ moduleNameAttr = "qml-module-name";
+ moduleVerAttr = "qml-module-version";
+ logicalModuleName = node->logicalModuleName();
+ logicalModuleVersion = node->logicalModuleVersion();
+ break;
+ case Node::JsModule:
+ nodeName = "jsmodule";
+ moduleNameAttr = "js-module-name";
+ moduleVerAttr = "js-module-version";
+ logicalModuleName = node->logicalModuleName();
+ logicalModuleVersion = node->logicalModuleVersion();
break;
case Node::Enum:
nodeName = "enum";
@@ -835,34 +880,16 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
nodeName = "variable";
break;
case Node::QmlProperty:
- if (node->isQmlNode())
- nodeName = "qmlproperty";
- else
- nodeName = "jsProperty";
- break;
- case Node::QmlPropertyGroup:
- if (node->isQmlNode())
- nodeName = "qmlpropertygroup";
- else
- nodeName = "jspropertygroup";
+ nodeName = "qmlproperty";
break;
- case Node::QmlSignal:
- if (node->isQmlNode())
- nodeName = "qmlsignal";
- else
- nodeName = "jssignal";
+ case Node::JsProperty:
+ nodeName = "jsProperty";
break;
- case Node::QmlSignalHandler:
- if (node->isQmlNode())
- nodeName = "qmlsignalhandler";
- else
- nodeName = "jssignalhandler";
+ case Node::QmlPropertyGroup:
+ nodeName = "qmlpropertygroup";
break;
- case Node::QmlMethod:
- if (node->isQmlNode())
- nodeName = "qmlmethod";
- else
- nodeName = "jsmethod";
+ case Node::JsPropertyGroup:
+ nodeName = "jspropertygroup";
break;
default:
return false;
@@ -877,12 +904,13 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
access = "protected";
break;
case Node::Private:
- {
- access = "private";
- bool b = generateInternalNodes;
- if (b)
- b = false;
- }
+ /*
+ Should we test generateInternalNodes here and return
+ false immediately if it is set? As it is now, we are
+ always writing all internal and private nodes to the
+ index file.
+ */
+ access = "private";
break;
default:
return false;
@@ -897,7 +925,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
QXmlStreamAttributes attributes;
- if (!node->isDocumentNode() && !node->isCollectionNode()) {
+ if (!node->isTextPageNode() && !node->isCollectionNode() && !node->isHeader()) {
QString threadSafety;
switch (node->threadSafeness()) {
case Node::NonReentrant:
@@ -920,8 +948,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
QString status;
switch (node->status()) {
case Node::Obsolete:
- status = "obsolete";
- break;
case Node::Deprecated:
status = "obsolete";
break;
@@ -942,41 +968,22 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("name", objName);
// Write module and base type info for QML/JS types
- if (node->type() == Node::QmlType || node->type() == Node::QmlModule) {
- QString baseNameAttr("qml-base-type");
- QString moduleNameAttr("qml-module-name");
- QString moduleVerAttr("qml-module-version");
- if (node->isJsNode()) {
- baseNameAttr = "js-base-type";
- moduleNameAttr = "js-module-name";
- moduleVerAttr = "js-module-version";
- }
- if (node->type() == Node::QmlModule) {
- logicalModuleName = node->logicalModuleName();
- logicalModuleVersion = node->logicalModuleVersion();
- }
+ if (!moduleNameAttr.isEmpty()) {
if (!logicalModuleName.isEmpty())
writer.writeAttribute(moduleNameAttr, logicalModuleName);
else
writer.writeAttribute(moduleNameAttr, node->name());
if (!logicalModuleVersion.isEmpty())
writer.writeAttribute(moduleVerAttr, logicalModuleVersion);
- if (!qmlFullBaseName.isEmpty())
- writer.writeAttribute(baseNameAttr, qmlFullBaseName);
}
+ if (!baseNameAttr.isEmpty() && !qmlFullBaseName.isEmpty())
+ writer.writeAttribute(baseNameAttr, qmlFullBaseName);
QString href;
if (!node->isExternalPage()) {
QString fullName = node->fullDocumentName();
if (fullName != objName)
writer.writeAttribute("fullname", fullName);
-#if 0
- if (Generator::useOutputSubdirs())
- href = node->outputSubdirectory();
- if (!href.isEmpty())
- href.append(QLatin1Char('/'));
- href.append(gen_->fullDocumentLocation(node));
-#endif
href = gen_->fullDocumentLocation(node);
}
else
@@ -994,7 +1001,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("href", href);
writer.writeAttribute("status", status);
- if (!node->isDocumentNode() && !node->isCollectionNode()) {
+ if (!node->isTextPageNode() && !node->isCollectionNode() && !node->isHeader()) {
writer.writeAttribute("access", access);
if (node->isAbstract())
writer.writeAttribute("abstract", "true");
@@ -1012,7 +1019,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
}
QString brief = node->doc().trimmedBriefText(node->name()).toString();
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Class:
{
// Classes contain information about their base classes.
@@ -1040,6 +1047,21 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("brief", brief);
}
break;
+ case Node::HeaderFile:
+ {
+ const HeaderNode* hn = static_cast<const HeaderNode*>(node);
+ writer.writeAttribute("documented", hn->hasDoc() ? "true" : "false");
+ if (!hn->physicalModuleName().isEmpty())
+ writer.writeAttribute("module", hn->physicalModuleName());
+ if (!hn->groupNames().isEmpty())
+ writer.writeAttribute("groups", hn->groupNames().join(QLatin1Char(',')));
+ if (!brief.isEmpty())
+ writer.writeAttribute("brief", brief);
+ writer.writeAttribute("title", hn->title());
+ writer.writeAttribute("fulltitle", hn->fullTitle());
+ writer.writeAttribute("subtitle", hn->subtitle());
+ }
+ break;
case Node::Namespace:
{
const NamespaceNode* ns = static_cast<const NamespaceNode*>(node);
@@ -1052,60 +1074,54 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("brief", brief);
}
break;
+ case Node::JsType:
case Node::QmlType:
{
const QmlTypeNode* qcn = static_cast<const QmlTypeNode*>(node);
writer.writeAttribute("title", qcn->title());
writer.writeAttribute("fulltitle", qcn->fullTitle());
- writer.writeAttribute("subtitle", qcn->subTitle());
+ writer.writeAttribute("subtitle", qcn->subtitle());
if (!qcn->groupNames().isEmpty())
writer.writeAttribute("groups", qcn->groupNames().join(QLatin1Char(',')));
if (!brief.isEmpty())
writer.writeAttribute("brief", brief);
}
break;
- case Node::Document:
+ case Node::Page:
+ case Node::Example:
+ case Node::ExternalPage:
{
/*
- Document nodes (such as manual pages) have a subtype,
- a title, and other attributes.
+ Page nodes (anything that generates a doc page)
+ no longer have a subtype. Some of the subtypes
+ (Example, External, and Header) have been promoted
+ to be node types. They have become subclasses of
+ PageNode or, in the case of Header, a subclass of
+ Aggregate. The processing for other subtypes that
+ have not (yet) been promoted to be node types is
+ determined by the PageType enum.
*/
bool writeModuleName = false;
- const DocumentNode* docNode = static_cast<const DocumentNode*>(node);
- switch (docNode->docSubtype()) {
- case Node::Example:
+ if (node->isExample()) {
writer.writeAttribute("subtype", "example");
writeModuleName = true;
- break;
- case Node::HeaderFile:
- writer.writeAttribute("subtype", "header");
- writeModuleName = true;
- break;
- case Node::File:
- writer.writeAttribute("subtype", "file");
- break;
- case Node::Page:
- if (docNode->pageType() == Node::AttributionPage)
+ } else if (node->isExternalPage()) {
+ writer.writeAttribute("subtype", "externalpage");
+ } else {
+ if (node->pageType() == Node::AttributionPage)
writer.writeAttribute("subtype", "attribution");
else
writer.writeAttribute("subtype", "page");
-
writeModuleName = true;
- break;
- case Node::ExternalPage:
- writer.writeAttribute("subtype", "externalpage");
- break;
- default:
- break;
}
- writer.writeAttribute("title", docNode->title());
- writer.writeAttribute("fulltitle", docNode->fullTitle());
- writer.writeAttribute("subtitle", docNode->subTitle());
- if (!node->physicalModuleName().isEmpty() && writeModuleName) {
+ const PageNode* pn = static_cast<const PageNode*>(node);
+ writer.writeAttribute("title", pn->title());
+ writer.writeAttribute("fulltitle", pn->fullTitle());
+ writer.writeAttribute("subtitle", pn->subtitle());
+ if (!node->physicalModuleName().isEmpty() && writeModuleName)
writer.writeAttribute("module", node->physicalModuleName());
- }
- if (!docNode->groupNames().isEmpty())
- writer.writeAttribute("groups", docNode->groupNames().join(QLatin1Char(',')));
+ if (!pn->groupNames().isEmpty())
+ writer.writeAttribute("groups", pn->groupNames().join(QLatin1Char(',')));
if (!brief.isEmpty())
writer.writeAttribute("brief", brief);
}
@@ -1115,8 +1131,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
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->subtitle().isEmpty())
+ writer.writeAttribute("subtitle", cn->subtitle());
if (!cn->physicalModuleName().isEmpty())
writer.writeAttribute("module", cn->physicalModuleName());
if (!cn->groupNames().isEmpty())
@@ -1140,8 +1156,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
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->subtitle().isEmpty())
+ writer.writeAttribute("subtitle", cn->subtitle());
if (!cn->physicalModuleName().isEmpty())
writer.writeAttribute("module", cn->physicalModuleName());
if (!cn->groupNames().isEmpty())
@@ -1160,13 +1176,14 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("brief", brief);
}
break;
+ case Node::JsModule:
case Node::QmlModule:
{
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->subtitle().isEmpty())
+ writer.writeAttribute("subtitle", cn->subtitle());
if (!cn->physicalModuleName().isEmpty())
writer.writeAttribute("module", cn->physicalModuleName());
if (!cn->groupNames().isEmpty())
@@ -1187,70 +1204,67 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
break;
case Node::Function:
{
- /*
- Function nodes contain information about the type of
- function being described.
- */
- const FunctionNode* functionNode = static_cast<const FunctionNode*>(node);
- writer.writeAttribute("virtual", functionNode->virtualness());
- writer.writeAttribute("meta", functionNode->metaness());
- writer.writeAttribute("const", functionNode->isConst()?"true":"false");
- writer.writeAttribute("static", functionNode->isStatic()?"true":"false");
- writer.writeAttribute("overload", functionNode->isOverload()?"true":"false");
- writer.writeAttribute("delete", functionNode->isDeleted() ? "true" : "false");
- writer.writeAttribute("default", functionNode->isDefaulted() ? "true" : "false");
- writer.writeAttribute("final", functionNode->isFinal() ? "true" : "false");
- writer.writeAttribute("override", functionNode->isOverride() ? "true" : "false");
- if (functionNode->isRef())
- writer.writeAttribute("refness", QString::number(1));
- else if (functionNode->isRefRef())
- writer.writeAttribute("refness", QString::number(2));
- if (functionNode->isOverload())
- writer.writeAttribute("overload-number", QString::number(functionNode->overloadNumber()));
- if (functionNode->relates()) {
- writer.writeAttribute("relates", functionNode->relates()->name());
- }
- if (functionNode->hasAssociatedProperties()) {
- QStringList associatedProperties;
- foreach (PropertyNode* pn, functionNode->associatedProperties()) {
- associatedProperties << pn->name();
+ const FunctionNode* fn = static_cast<const FunctionNode*>(node);
+ writer.writeAttribute("meta", fn->metanessString());
+ if (fn->isCppNode()) {
+ writer.writeAttribute("virtual", fn->virtualness());
+ writer.writeAttribute("const", fn->isConst() ? "true":"false");
+ writer.writeAttribute("static", fn->isStatic() ? "true":"false");
+ writer.writeAttribute("overload", fn->isOverload() ? "true":"false");
+ writer.writeAttribute("delete", fn->isDeleted() ? "true" : "false");
+ writer.writeAttribute("default", fn->isDefaulted() ? "true" : "false");
+ writer.writeAttribute("final", fn->isFinal() ? "true" : "false");
+ writer.writeAttribute("override", fn->isOverride() ? "true" : "false");
+ if (fn->isRef())
+ writer.writeAttribute("refness", QString::number(1));
+ else if (fn->isRefRef())
+ writer.writeAttribute("refness", QString::number(2));
+ if (fn->isOverload())
+ writer.writeAttribute("overload-number", QString::number(fn->overloadNumber()));
+ if (fn->relates())
+ writer.writeAttribute("relates", fn->relates()->name());
+ if (fn->hasAssociatedProperties()) {
+ QStringList associatedProperties;
+ foreach (PropertyNode* pn, fn->associatedProperties()) {
+ associatedProperties << pn->name();
+ }
+ associatedProperties.sort();
+ writer.writeAttribute("associated-property", associatedProperties.join(QLatin1Char(',')));
+ }
+ writer.writeAttribute("type", fn->returnType());
+ if (!brief.isEmpty())
+ writer.writeAttribute("brief", brief);
+ /*
+ Note: The "signature" attribute is written to the
+ index file, but it is not read back in by qdoc. However,
+ we need it for the webxml generator.
+ */
+ QString signature = fn->signature(false);
+ // 'const' is already part of FunctionNode::signature()
+ if (fn->isFinal())
+ signature += " final";
+ if (fn->isOverride())
+ signature += " override";
+ if (fn->isPureVirtual())
+ signature += " = 0";
+ else if (fn->isDeleted())
+ signature += " = delete";
+ else if (fn->isDefaulted())
+ signature += " = default";
+ writer.writeAttribute("signature", signature);
+
+ for (int i = 0; i < fn->parameters().size(); ++i) {
+ Parameter parameter = fn->parameters()[i];
+ writer.writeStartElement("parameter");
+ writer.writeAttribute("type", parameter.dataType());
+ writer.writeAttribute("name", parameter.name());
+ writer.writeAttribute("default", parameter.defaultValue());
+ writer.writeEndElement(); // parameter
}
- associatedProperties.sort();
- writer.writeAttribute("associated-property", associatedProperties.join(QLatin1Char(',')));
- }
- writer.writeAttribute("type", functionNode->returnType());
- if (!brief.isEmpty())
- writer.writeAttribute("brief", brief);
-
- /*
- Note: The "signature" attribute is written to the
- index file, but it is not read back in by qdoc. However,
- we need it for the webxml generator.
- */
- QString signature = functionNode->signature(false);
- // 'const' is already part of FunctionNode::signature()
- if (functionNode->isFinal())
- signature += " final";
- if (functionNode->isOverride())
- signature += " override";
- if (functionNode->isPureVirtual())
- signature += " = 0";
- else if (functionNode->isDeleted())
- signature += " = delete";
- else if (functionNode->isDefaulted())
- signature += " = default";
- writer.writeAttribute("signature", signature);
-
- for (int i = 0; i < functionNode->parameters().size(); ++i) {
- Parameter parameter = functionNode->parameters()[i];
- writer.writeStartElement("parameter");
- writer.writeAttribute("type", parameter.dataType());
- writer.writeAttribute("name", parameter.name());
- writer.writeAttribute("default", parameter.defaultValue());
- writer.writeEndElement(); // parameter
}
}
break;
+ case Node::JsProperty:
case Node::QmlProperty:
{
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
@@ -1261,6 +1275,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("brief", brief);
}
break;
+ case Node::JsPropertyGroup:
case Node::QmlPropertyGroup:
{
if (!brief.isEmpty())
@@ -1319,9 +1334,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
case Node::Enum:
{
const EnumNode* enumNode = static_cast<const EnumNode*>(node);
- if (enumNode->flagsType()) {
+ if (enumNode->flagsType())
writer.writeAttribute("typedef",enumNode->flagsType()->fullDocumentName());
- }
foreach (const EnumItem& item, enumNode->items()) {
writer.writeStartElement("value");
writer.writeAttribute("name", item.name());
@@ -1333,9 +1347,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
case Node::Typedef:
{
const TypedefNode* typedefNode = static_cast<const TypedefNode*>(node);
- if (typedefNode->associatedEnum()) {
+ if (typedefNode->associatedEnum())
writer.writeAttribute("enum",typedefNode->associatedEnum()->fullDocumentName());
- }
}
break;
default:
@@ -1356,11 +1369,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
if (node->doc().hasTargets()) {
bool external = false;
- if (node->type() == Node::Document) {
- const DocumentNode* docNode = static_cast<const DocumentNode*>(node);
- if (docNode->docSubtype() == Node::ExternalPage)
- external = true;
- }
+ if (node->isExternalPage())
+ external = true;
foreach (const Atom* target, node->doc().targets()) {
QString title = target->string();
QString name = Doc::canonicalTitle(title);
@@ -1393,7 +1403,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
element. Elements for all other nodes are closed in the
opening tag.
*/
- if (node->isAggregate() || node->isCollectionNode()) {
+ if (node->isPageNode() || node->isCollectionNode()) {
if (node->doc().hasTableOfContents()) {
for (int i = 0; i < node->doc().tableOfContents().size(); ++i) {
Atom* item = node->doc().tableOfContents()[i];
@@ -1407,6 +1417,33 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
}
}
}
+ if (node->isExample()) {
+ const ExampleNode* en = static_cast<const ExampleNode*>(node);
+ foreach (const QString& file, en->files()) {
+ writer.writeStartElement("page");
+ writer.writeAttribute("name", file);
+ QString href = gen_->linkForExampleFile(file, en);
+ writer.writeAttribute("href", href);
+ writer.writeAttribute("status", "active");
+ writer.writeAttribute("subtype", "file");
+ writer.writeAttribute("title", "");
+ writer.writeAttribute("fulltitle", file.mid(file.lastIndexOf('/') + 1) + " Example File");
+ writer.writeAttribute("subtitle", file);
+ writer.writeEndElement(); // page
+ }
+ foreach (const QString& file, en->images()) {
+ writer.writeStartElement("page");
+ writer.writeAttribute("name", file);
+ QString href = gen_->linkForExampleFile(file, en);
+ writer.writeAttribute("href", href);
+ writer.writeAttribute("status", "active");
+ writer.writeAttribute("subtype", "image");
+ writer.writeAttribute("title", "");
+ writer.writeAttribute("fulltitle", file.mid(file.lastIndexOf('/') + 1) + " Image File");
+ writer.writeAttribute("subtitle", file);
+ writer.writeEndElement(); // page
+ }
+ }
return true;
}
@@ -1429,9 +1466,9 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
if (generateIndexSection(writer, node, generateInternalNodes)) {
if (node->isAggregate()) {
- const Aggregate* inner = static_cast<const Aggregate*>(node);
+ const Aggregate* aggregate = static_cast<const Aggregate*>(node);
- NodeList cnodes = inner->childNodes();
+ NodeList cnodes = aggregate->childNodes();
std::sort(cnodes.begin(), cnodes.end(), Node::nodeNameLessThan);
foreach (Node* child, cnodes) {
@@ -1439,7 +1476,7 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
}
}
- if (node == top) {
+ if (node == root_) {
/*
We wait until the end of the index file to output the group, module,
and QML module elements. By outputting them at the end, when we read
@@ -1521,11 +1558,11 @@ void QDocIndexFiles::generateIndex(const QString& fileName,
writer.writeAttribute("version", qdb_->version());
writer.writeAttribute("project", g->config()->getString(CONFIG_PROJECT));
- top = qdb_->primaryTreeRoot();
- if (!top->tree()->indexTitle().isEmpty())
- writer.writeAttribute("indexTitle", top->tree()->indexTitle());
+ root_ = qdb_->primaryTreeRoot();
+ if (!root_->tree()->indexTitle().isEmpty())
+ writer.writeAttribute("indexTitle", root_->tree()->indexTitle());
- generateIndexSections(writer, top, generateInternalNodes);
+ generateIndexSections(writer, root_, generateInternalNodes);
writer.writeEndElement(); // INDEX
writer.writeEndElement(); // QDOCINDEX
diff --git a/src/qdoc/qdoctagfiles.cpp b/src/qdoc/qdoctagfiles.cpp
index 528d310ca..9f7d1dd2e 100644
--- a/src/qdoc/qdoctagfiles.cpp
+++ b/src/qdoc/qdoctagfiles.cpp
@@ -101,7 +101,7 @@ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter& writer, const Aggr
continue;
QString kind;
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Namespace:
kind = "namespace";
break;
@@ -141,7 +141,7 @@ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter& writer, const Aggr
writer.writeStartElement("compound");
writer.writeAttribute("kind", kind);
- if (node->type() == Node::Class) {
+ if (node->nodeType() == Node::Class) {
writer.writeTextElement("name", node->fullDocumentName());
writer.writeTextElement("filename", gen_->fullDocumentLocation(node, false));
@@ -187,7 +187,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const Aggreg
QString nodeName;
QString kind;
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Enum:
nodeName = "member";
kind = "enum";
@@ -239,7 +239,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const Aggreg
if (!kind.isEmpty())
writer.writeAttribute("kind", kind);
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Class:
writer.writeCharacters(node->fullDocumentName());
writer.writeEndElement();
diff --git a/src/qdoc/qmlcodemarker.cpp b/src/qdoc/qmlcodemarker.cpp
index 1ceba8016..82e0e6555 100644
--- a/src/qdoc/qmlcodemarker.cpp
+++ b/src/qdoc/qmlcodemarker.cpp
@@ -110,10 +110,15 @@ QString QmlCodeMarker::markedUpCode(const QString &code,
return addMarkUp(code, relative, location);
}
+/*!
+ Constructs and returns the marked up name for the \a node.
+ If the node is any kind of QML or JS function (a method,
+ signal, or handler), "()" is appended to the marked up name.
+ */
QString QmlCodeMarker::markedUpName(const Node *node)
{
QString name = linkTag(node, taggedNode(node));
- if (node->type() == Node::QmlMethod)
+ if (node->isFunction())
name += "()";
return name;
}
diff --git a/src/qdoc/qmlvisitor.cpp b/src/qdoc/qmlvisitor.cpp
index d54378331..0bce4c376 100644
--- a/src/qdoc/qmlvisitor.cpp
+++ b/src/qdoc/qmlvisitor.cpp
@@ -204,9 +204,12 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
if (topicsUsed.size() > 0) {
for (int i=0; i<topicsUsed.size(); ++i) {
QString topic = topicsUsed.at(i).topic;
+ if (!topic.startsWith(QLatin1String("qml")) && !topic.startsWith(QLatin1String("js")))
+ continue; // maybe a qdoc warning here? mws 18/07/18
QString args = topicsUsed.at(i).args;
- if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY) ||
- (topic == COMMAND_JSPROPERTY) || (topic == COMMAND_JSATTACHEDPROPERTY)) {
+ if (topic == COMMAND_JSTYPE) {
+ node->changeType(Node::QmlType, Node::JsType);
+ } else if (topic.endsWith(QLatin1String("property"))) {
QmlPropArgs qpa;
if (splitQmlPropertyArg(doc, args, qpa)) {
if (qpa.name_ == nodePassedIn->name()) {
@@ -214,8 +217,7 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
nodePassedIn->setDataType(qpa.type_);
}
else {
- bool isAttached = (topic == COMMAND_QMLATTACHEDPROPERTY) ||
- (topic == COMMAND_JSATTACHEDPROPERTY);
+ bool isAttached = topic.contains(QLatin1String("attached"));
QmlPropertyNode* n = parent->hasQmlProperty(qpa.name_, isAttached);
if (n == 0)
n = new QmlPropertyNode(parent, qpa.name_, qpa.type_, isAttached);
@@ -226,20 +228,19 @@ 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);
+ if ((topic == COMMAND_JSPROPERTY) || (topic == COMMAND_JSATTACHEDPROPERTY))
+ n->changeType(Node::QmlProperty, Node::JsProperty);
nodes.append(n);
}
}
else
qDebug() << " FAILED TO PARSE QML OR JS PROPERTY:" << topic << args;
- }
- else if ((topic == COMMAND_QMLMETHOD) || (topic == COMMAND_QMLATTACHEDMETHOD) ||
- (topic == COMMAND_JSMETHOD) || (topic == COMMAND_JSATTACHEDMETHOD)) {
+ } else if (topic.endsWith(QLatin1String("method"))) {
if (node->isFunction()) {
FunctionNode* fn = static_cast<FunctionNode*>(node);
QmlSignatureParser qsp(fn, args, doc.location());
+ if (topic == COMMAND_JSMETHOD || topic == COMMAND_JSATTACHEDMETHOD)
+ fn->changeMetaness(FunctionNode::QmlMethod, FunctionNode::JsMethod);
}
}
}
@@ -292,7 +293,7 @@ bool QmlSignatureParser::matchDataType(CodeChunk* dataType, QString* var)
/*
This code is really hard to follow... sorry. The loop is there to match
Alpha::Beta::Gamma::...::Omega.
- */
+ */
for (;;) {
bool virgin = true;
@@ -341,7 +342,7 @@ bool QmlSignatureParser::matchDataType(CodeChunk* dataType, QString* var)
/*
The usual case: Look for an optional identifier, then for
some array brackets.
- */
+ */
dataType->appendHotspot();
if ((var != 0) && match(Tok_Ident))
@@ -580,13 +581,18 @@ QString QmlDocVisitor::getFullyQualifiedId(QQmlJS::AST::UiQualifiedId *id)
qdoc database. Increment the object nesting level, which is used
to test whether we are at the public API level. The public level
is level 1.
-*/
+
+ Note that this visit() function creates the qdoc object node as a
+ QmlType. If it is actually a JsType, this fact is discovered when
+ the qdoc comment is applied to the node. The node's typet is then
+ changed to JsType.
+ */
bool QmlDocVisitor::visit(QQmlJS::AST::UiObjectDefinition *definition)
{
QString type = getFullyQualifiedId(definition->qualifiedTypeNameId);
nestingLevel++;
- if (current->type() == Node::Namespace) {
+ if (current->nodeType() == Node::Namespace) {
QmlTypeNode *component = new QmlTypeNode(current, name);
component->setTitle(name);
component->setImportList(importList);
@@ -680,7 +686,7 @@ QString qualifiedIdToString(QQmlJS::AST::UiQualifiedId *node)
Visits the public \a member declaration, which can be a
signal or a property. It is a custom signal or property.
Only visit the \a member if the nestingLevel is 1.
-*/
+ */
bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
{
if (nestingLevel > 1) {
@@ -692,19 +698,19 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
if (current->isQmlType() || current->isJsType()) {
QmlTypeNode *qmlType = static_cast<QmlTypeNode *>(current);
if (qmlType) {
-
+ FunctionNode::Metaness metaness = FunctionNode::QmlSignal;
+ if (qmlType->isJsType())
+ metaness = FunctionNode::JsSignal;
QString name = member->name.toString();
- FunctionNode *qmlSignal = new FunctionNode(Node::QmlSignal, current, name, false);
-
+ FunctionNode *newSignal = new FunctionNode(metaness, current, name);
QVector<Parameter> parameters;
for (QQmlJS::AST::UiParameterList *it = member->parameters; it; it = it->next) {
const QString type = qualifiedIdToString(it->type);
if (!type.isEmpty() && !it->name.isEmpty())
parameters.append(Parameter(type, QString(), it->name.toString()));
}
-
- qmlSignal->setParameters(parameters);
- applyDocumentation(member->firstSourceLocation(), qmlSignal);
+ newSignal->setParameters(parameters);
+ applyDocumentation(member->firstSourceLocation(), newSignal);
}
}
break;
@@ -718,11 +724,8 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
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();
@@ -763,10 +766,11 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd)
if (current->isQmlType() || current->isJsType()) {
QmlTypeNode* qmlType = static_cast<QmlTypeNode*>(current);
if (qmlType) {
+ FunctionNode::Metaness metaness = FunctionNode::QmlMethod;
+ if (qmlType->isJsType())
+ metaness = FunctionNode::JsMethod;
QString name = fd->name.toString();
- FunctionNode* qmlMethod = new FunctionNode(Node::QmlMethod, current, name, false);
- if (current->isJsType())
- qmlMethod->setGenus(Node::JS);
+ FunctionNode* newMethod = new FunctionNode(metaness, current, name);
int overloads = 0;
NodeList::ConstIterator i = current->childNodes().constBegin();
while (i != current->childNodes().constEnd()) {
@@ -775,7 +779,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd)
i++;
}
if (overloads > 1)
- qmlMethod->setOverloadFlag(true);
+ newMethod->setOverloadFlag(true);
QVector<Parameter> parameters;
QQmlJS::AST::FormalParameterList* formals = fd->formals;
if (formals) {
@@ -784,9 +788,9 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd)
parameters.append(Parameter(QString(), QString(), fpl->element->bindingIdentifier.toString()));
fpl = fpl->next;
} while (fpl && fpl != formals);
- qmlMethod->setParameters(parameters);
+ newMethod->setParameters(parameters);
}
- applyDocumentation(fd->firstSourceLocation(), qmlMethod);
+ applyDocumentation(fd->firstSourceLocation(), newMethod);
}
}
return true;
@@ -820,7 +824,10 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiScriptBinding* )
if (handler.length() > 2 && handler.startsWith("on") && handler.at(2).isUpper()) {
QmlTypeNode* qmlType = static_cast<QmlTypeNode*>(current);
if (qmlType) {
- FunctionNode* qmlSH = new FunctionNode(Node::QmlSignalHandler,current,handler,false);
+ FunctionNode::Metaness metaness = FunctionNode::QmSignalHandler;
+ if (qmlType->isJsType())
+ metaness = FunctionNode::JsSignalHandler;
+ FunctionNode* qmlSH = new FunctionNode(metaness, current, handler);
applyDocumentation(sb->firstSourceLocation(), qmlSH);
}
}
diff --git a/src/qdoc/sections.cpp b/src/qdoc/sections.cpp
index d9bfb624a..1fd7633d8 100644
--- a/src/qdoc/sections.cpp
+++ b/src/qdoc/sections.cpp
@@ -134,30 +134,33 @@ QString Section::sortName(const Node *node, const QString* name)
}
if (node->isFunction()) {
- const FunctionNode *func = static_cast<const FunctionNode *>(node);
- QString sortNo;
- if (func->isSomeCtor())
- sortNo = QLatin1String("C");
- else if (func->isDtor())
- sortNo = QLatin1String("D");
- else if (nodeName.startsWith(QLatin1String("operator"))
- && nodeName.length() > 8
- && !nodeName[8].isLetterOrNumber())
- sortNo = QLatin1String("F");
- else
- sortNo = QLatin1String("E");
- return sortNo + nodeName + QLatin1Char(' ') + QString::number(func->overloadNumber(), 36);
- }
+ const FunctionNode *fn = static_cast<const FunctionNode *>(node);
+ if (fn->isCppFunction()) {
+ QString sortNo;
+ if (fn->isSomeCtor())
+ sortNo = QLatin1String("C");
+ else if (fn->isDtor())
+ sortNo = QLatin1String("D");
+ else if (nodeName.startsWith(QLatin1String("operator"))
+ && nodeName.length() > 8
+ && !nodeName[8].isLetterOrNumber())
+ sortNo = QLatin1String("F");
+ else
+ sortNo = QLatin1String("E");
+ return sortNo + nodeName + QLatin1Char(' ') + QString::number(fn->overloadNumber(), 36);
+ }
+ if (fn->isQmlMethod() || fn->isQmlSignal() || fn->isQmlSignalHandler())
+ return QLatin1Char('E') + nodeName;
+ if (fn->isJsMethod() || fn->isJsSignal() || fn->isJsSignalHandler())
+ return QLatin1Char('E') + nodeName;
+ }
if (node->isClass())
return QLatin1Char('A') + nodeName;
if (node->isProperty() || node->isVariable())
return QLatin1Char('E') + nodeName;
- if (node->isQmlMethod() || node->isQmlSignal() || node->isQmlSignalHandler())
- return QLatin1Char('E') + nodeName;
-
return QLatin1Char('B') + nodeName;
}
@@ -318,18 +321,22 @@ Sections::Sections(Aggregate *aggregate) : aggregate_(aggregate)
{
initSections();
initAggregate(allMembers_, aggregate_);
- switch (aggregate_->type()) {
+ switch (aggregate_->nodeType()) {
case Node::Class:
initAggregate(stdCppClassSummarySections_, aggregate_);
initAggregate(stdCppClassDetailsSections_, aggregate_);
buildStdCppClassRefPageSections();
break;
+ case Node::JsType:
+ case Node::JsBasicType:
case Node::QmlType:
case Node::QmlBasicType:
initAggregate(stdQmlTypeSummarySections_, aggregate_);
initAggregate(stdQmlTypeDetailsSections_, aggregate_);
buildStdQmlTypeRefPageSections();
break;
+ case Node::Namespace:
+ case Node::HeaderFile:
default:
initAggregate(stdSummarySections_, aggregate_);
initAggregate(stdDetailsSections_, aggregate_);
@@ -351,7 +358,8 @@ Sections::Sections(const NodeMultiMap& nsmap) : aggregate_(0)
NodeMultiMap::const_iterator n = nsmap.constBegin();
while (n != nsmap.constEnd()) {
Node* node = n.value();
- switch (node->type()) {
+ switch (node->nodeType()) {
+ case Node::JsType:
case Node::QmlType:
sections[SinceQmlTypes].appendMember(node);
break;
@@ -369,24 +377,40 @@ Sections::Sections(const NodeMultiMap& nsmap) : aggregate_(0)
break;
case Node::Function: {
const FunctionNode* fn = static_cast<const FunctionNode*>(node);
- if (fn->isMacro())
- sections[SinceMacros].appendMember(node);
- else {
- Node* p = fn->parent();
- if (p) {
- if (p->type() == Node::Class)
- sections[SinceMemberFunctions].appendMember(node);
- else if (p->type() == Node::Namespace) {
- if (p->name().isEmpty())
- sections[SinceGlobalFunctions].appendMember(node);
+ switch (fn->metaness()) {
+ case FunctionNode::JsSignal:
+ case FunctionNode::QmlSignal:
+ sections[SinceQmlSignals].appendMember(node);
+ break;
+ case FunctionNode::JsSignalHandler:
+ case FunctionNode::QmlSignalHandler:
+ sections[SinceQmlSignalHandlers].appendMember(node);
+ break;
+ case FunctionNode::JsMethod:
+ case FunctionNode::QmlMethod:
+ sections[SinceQmlMethods].appendMember(node);
+ break;
+ default:
+ if (fn->isMacro())
+ sections[SinceMacros].appendMember(node);
+ else {
+ Node* p = fn->parent();
+ if (p) {
+ if (p->isClass())
+ sections[SinceMemberFunctions].appendMember(node);
+ else if (p->isNamespace()) {
+ if (p->name().isEmpty())
+ sections[SinceGlobalFunctions].appendMember(node);
+ else
+ sections[SinceNamespaceFunctions].appendMember(node);
+ }
else
- sections[SinceNamespaceFunctions].appendMember(node);
+ sections[SinceGlobalFunctions].appendMember(node);
}
else
sections[SinceGlobalFunctions].appendMember(node);
}
- else
- sections[SinceGlobalFunctions].appendMember(node);
+ break;
}
break;
}
@@ -396,18 +420,10 @@ Sections::Sections(const NodeMultiMap& nsmap) : aggregate_(0)
case Node::Variable:
sections[SinceVariables].appendMember(node);
break;
+ case Node::JsProperty:
case Node::QmlProperty:
sections[SinceQmlProperties].appendMember(node);
break;
- case Node::QmlSignal:
- sections[SinceQmlSignals].appendMember(node);
- break;
- case Node::QmlSignalHandler:
- sections[SinceQmlSignalHandlers].appendMember(node);
- break;
- case Node::QmlMethod:
- sections[SinceQmlMethods].appendMember(node);
- break;
default:
break;
}
@@ -424,12 +440,14 @@ Sections::Sections(const NodeMultiMap& nsmap) : aggregate_(0)
Sections::~Sections()
{
if (aggregate_) {
- switch (aggregate_->type()) {
+ switch (aggregate_->nodeType()) {
case Node::Class:
clear(stdCppClassSummarySections());
clear(stdCppClassDetailsSections());
allMembersSection().clear();
break;
+ case Node::JsType:
+ case Node::JsBasicType:
case Node::QmlType:
case Node::QmlBasicType:
clear(stdQmlTypeSummarySections());
@@ -592,7 +610,7 @@ void Sections::reduce(QVector<Section> &v)
*/
void Sections::stdRefPageSwitch(SectionVector &v, Node *n)
{
- switch (n->type()) {
+ switch (n->nodeType()) {
case Node::Namespace:
v[StdNamespaces].insert(n);
return;
@@ -795,20 +813,21 @@ void Sections::distributeQmlNodeInDetailsVector(SectionVector &dv, Node *n)
dv[QmlAttachedProperties].insert(pn);
else
dv[QmlProperties].insert(pn);
- } else if (n->isQmlSignal() || n->isJsSignal()) {
+ } else if (n->isFunction()) {
FunctionNode* fn = static_cast<FunctionNode*>(n);
- if (fn->isAttached())
- dv[QmlAttachedSignals].insert(fn);
- else
- dv[QmlSignals].insert(fn);
- } else if (n->isQmlSignalHandler() || n->isJsSignalHandler()) {
- dv[QmlSignalHandlers].insert(n);
- } else if (n->isQmlMethod() || n->isJsMethod()) {
- FunctionNode* fn = static_cast<FunctionNode*>(n);
- if (fn->isAttached())
- dv[QmlAttachedMethods].insert(fn);
- else
- dv[QmlMethods].insert(fn);
+ if (fn->isQmlSignal() || fn->isJsSignal()) {
+ if (fn->isAttached())
+ dv[QmlAttachedSignals].insert(fn);
+ else
+ dv[QmlSignals].insert(fn);
+ } else if (fn->isQmlSignalHandler() || fn->isJsSignalHandler()) {
+ dv[QmlSignalHandlers].insert(fn);
+ } else if (fn->isQmlMethod() || fn->isJsMethod()) {
+ if (fn->isAttached())
+ dv[QmlAttachedMethods].insert(fn);
+ else
+ dv[QmlMethods].insert(fn);
+ }
} else if (n->isSharedCommentNode() && n->hasDoc())
dv[QmlMethods].insert(n);
}
@@ -823,20 +842,21 @@ void Sections::distributeQmlNodeInSummaryVector(SectionVector &sv, Node *n)
sv[QmlAttachedProperties].insert(pn);
else
sv[QmlProperties].insert(pn);
- } else if (n->isQmlSignal() || n->isJsSignal()) {
+ } else if (n->isFunction()) {
FunctionNode* fn = static_cast<FunctionNode*>(n);
- if (fn->isAttached())
- sv[QmlAttachedSignals].insert(fn);
- else
- sv[QmlSignals].insert(fn);
- } else if (n->isQmlSignalHandler() || n->isJsSignalHandler()) {
- sv[QmlSignalHandlers].insert(n);
- } else if (n->isQmlMethod() || n->isJsMethod()) {
- FunctionNode* fn = static_cast<FunctionNode*>(n);
- if (fn->isAttached())
- sv[QmlAttachedMethods].insert(fn);
- else
- sv[QmlMethods].insert(fn);
+ if (fn->isQmlSignal() || fn->isJsSignal()) {
+ if (fn->isAttached())
+ sv[QmlAttachedSignals].insert(fn);
+ else
+ sv[QmlSignals].insert(fn);
+ } else if (fn->isQmlSignalHandler() || fn->isJsSignalHandler()) {
+ sv[QmlSignalHandlers].insert(fn);
+ } else if (fn->isQmlMethod() || fn->isJsMethod()) {
+ if (fn->isAttached())
+ sv[QmlAttachedMethods].insert(fn);
+ else
+ sv[QmlMethods].insert(fn);
+ }
}
}
@@ -931,12 +951,12 @@ void Sections::buildStdQmlTypeRefPageSections()
SectionVector &dv = stdQmlTypeDetailsSections();
Section &allMembers = allMembersSection();
- const Aggregate* qcn = aggregate_;
+ const Aggregate* qtn = aggregate_;
while (true) {
- if (!qcn->isAbstract() || !classMap)
- classMap = allMembers.newClassMap(qcn);
- NodeList::ConstIterator c = qcn->childNodes().constBegin();
- while (c != qcn->childNodes().constEnd()) {
+ if (!qtn->isAbstract() || !classMap)
+ classMap = allMembers.newClassMap(qtn);
+ NodeList::ConstIterator c = qtn->childNodes().constBegin();
+ while (c != qtn->childNodes().constEnd()) {
Node *n = *c;
if (n->isInternal()) {
++c;
@@ -947,25 +967,25 @@ void Sections::buildStdQmlTypeRefPageSections()
distributeQmlNodeInDetailsVector(dv, n);
++c;
}
- if (qcn->qmlBaseNode() == qcn) {
+ if (qtn->qmlBaseNode() == qtn) {
qDebug() << "qdoc internal error: circular type definition."
- << "QML type" << qcn->name()
+ << "QML type" << qtn->name()
<< "can't be its own base type";
- qcn = 0;
+ qtn = 0;
break;
}
- qcn = static_cast<QmlTypeNode*>(qcn->qmlBaseNode());
- if (qcn == 0)
+ qtn = static_cast<QmlTypeNode*>(qtn->qmlBaseNode());
+ if (qtn == 0)
break;
- if (!qcn->isAbstract())
+ if (!qtn->isAbstract())
break;
}
- while (qcn != 0) {
- if (!qcn->isAbstract() || !classMap)
- classMap = allMembers.newClassMap(qcn);
- NodeList::ConstIterator c = qcn->childNodes().constBegin();
- while (c != qcn->childNodes().constEnd()) {
+ while (qtn != 0) {
+ if (!qtn->isAbstract() || !classMap)
+ classMap = allMembers.newClassMap(qtn);
+ NodeList::ConstIterator c = qtn->childNodes().constBegin();
+ while (c != qtn->childNodes().constEnd()) {
Node *n = *c;
if (n->isInternal()) {
++c;
@@ -974,14 +994,14 @@ void Sections::buildStdQmlTypeRefPageSections()
allMembers.add(classMap, n);
++c;
}
- if (qcn->qmlBaseNode() == qcn) {
+ if (qtn->qmlBaseNode() == qtn) {
qDebug() << "qdoc internal error: circular type definition."
- << "QML type" << qcn->name()
+ << "QML type" << qtn->name()
<< "can't be its own base type";
- qcn = 0;
+ qtn = 0;
break;
}
- qcn = static_cast<QmlTypeNode*>(qcn->qmlBaseNode());
+ qtn = static_cast<QmlTypeNode*>(qtn->qmlBaseNode());
}
reduce(sv);
reduce(dv);
diff --git a/src/qdoc/tree.cpp b/src/qdoc/tree.cpp
index b51f3dc50..ea3950a9e 100644
--- a/src/qdoc/tree.cpp
+++ b/src/qdoc/tree.cpp
@@ -293,14 +293,14 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
return 0;
}
-static NodeTypeList t;
-static const NodeTypeList& relatesTypes()
+static QList<int> t;
+static const QList<int>& relatesTypes()
{
if (t.isEmpty()) {
t.reserve(3);
- t.append(NodeTypePair(Node::Class, Node::NoSubtype));
- t.append(NodeTypePair(Node::Namespace, Node::NoSubtype));
- t.append(NodeTypePair(Node::Document, Node::HeaderFile));
+ t.append(Node::Class);
+ t.append(Node::Namespace);
+ t.append(Node::HeaderFile);
}
return t;
}
@@ -317,10 +317,10 @@ static const NodeTypeList& relatesTypes()
If a matching node is found, a pointer to it is returned.
Otherwise 0 is returned.
*/
-Aggregate* Tree::findRelatesNode(const QStringList& path)
+PageNode* Tree::findRelatesNode(const QStringList& path)
{
Node* n = findNodeRecursive(path, 0, root(), relatesTypes());
- return ((n && n->isAggregate()) ? static_cast<Aggregate*>(n) : 0);
+ return ((n && n->isPageNode()) ? static_cast<PageNode*>(n) : 0);
}
/*!
@@ -351,11 +351,11 @@ void Tree::resolveInheritance(Aggregate* n)
for (int pass = 0; pass < 2; pass++) {
NodeList::ConstIterator c = n->childNodes().constBegin();
while (c != n->childNodes().constEnd()) {
- if ((*c)->type() == Node::Class) {
+ if ((*c)->nodeType() == Node::Class) {
resolveInheritanceHelper(pass, (ClassNode*)*c);
resolveInheritance((ClassNode*)*c);
}
- else if ((*c)->type() == Node::Namespace) {
+ else if ((*c)->nodeType() == Node::Namespace) {
NamespaceNode* ns = static_cast<NamespaceNode*>(*c);
resolveInheritance(ns);
}
@@ -416,7 +416,7 @@ void Tree::resolveInheritanceHelper(int pass, ClassNode* cn)
else {
NodeList::ConstIterator c = cn->childNodes().constBegin();
while (c != cn->childNodes().constEnd()) {
- if ((*c)->type() == Node::Property)
+ if ((*c)->nodeType() == Node::Property)
cn->fixPropertyUsingBaseClasses(static_cast<PropertyNode*>(*c));
++c;
}
@@ -440,7 +440,7 @@ void Tree::resolveProperties()
NodeList::ConstIterator c = parent->childNodes().constBegin();
while (c != parent->childNodes().constEnd()) {
- if ((*c)->type() == Node::Function) {
+ if ((*c)->nodeType() == Node::Function) {
FunctionNode* function = static_cast<FunctionNode*>(*c);
if (function->access() == property->access() &&
(function->status() == property->status() ||
@@ -526,9 +526,9 @@ void Tree::fixInheritance(NamespaceNode* rootNode)
NodeList::ConstIterator c = rootNode->childNodes().constBegin();
while (c != rootNode->childNodes().constEnd()) {
- if ((*c)->type() == Node::Class)
+ if ((*c)->nodeType() == Node::Class)
static_cast<ClassNode*>(*c)->fixBaseClasses();
- else if ((*c)->type() == Node::Namespace) {
+ else if ((*c)->nodeType() == Node::Namespace) {
NamespaceNode* ns = static_cast<NamespaceNode*>(*c);
fixInheritance(ns);
}
@@ -555,7 +555,7 @@ NodeList Tree::allBaseClasses(const ClassNode* classNode) const
the specified \a type and \a subtype. Begin the search at
the \a start node. If the \a start node is 0, begin the
search at the tree root. \a subtype is not used unless
- \a type is \c{Document}.
+ \a type is \c{Page}.
*/
Node* Tree::findNodeByNameAndType(const QStringList& path, Node::NodeType type) const
{
@@ -573,7 +573,7 @@ Node* Tree::findNodeByNameAndType(const QStringList& path, Node::NodeType type)
If the end of the path is reached (i.e. if a matching
node is found for each name in the \a path), the \a type
must match the type of the last matching node, and if the
- type is \e{Document}, the \a subtype must match as well.
+ type is \e{Page}, the \a subtype must match as well.
If the algorithm is successful, the pointer to the final
node is returned. Otherwise 0 is returned.
@@ -586,7 +586,7 @@ Node* Tree::findNodeRecursive(const QStringList& path,
if (!start || path.isEmpty())
return 0; // no place to start, or nothing to search for.
Node* node = const_cast<Node*>(start);
- if (start->isLeaf()) {
+ if (!start->isAggregate()) {
if (pathIndex >= path.size())
return node; // found a match.
return 0; // premature leaf
@@ -608,7 +608,7 @@ Node* Tree::findNodeRecursive(const QStringList& path,
}
else if (n->name() == name) {
if (pathIndex+1 >= path.size()) {
- if ((n->type() == type) || (type == Node::NoType))
+ if ((n->nodeType() == type) || (type == Node::NoType))
return n;
continue;
}
@@ -639,11 +639,11 @@ Node* Tree::findNodeRecursive(const QStringList& path,
Node* Tree::findNodeRecursive(const QStringList& path,
int pathIndex,
Node* start,
- const NodeTypeList& types) const
+ const QList<int> &types) const
{
if (!start || path.isEmpty())
return 0;
- if (start->isLeaf())
+ if (!start->isAggregate())
return ((pathIndex >= path.size()) ? start : 0);
if (pathIndex >= path.size())
return 0;
@@ -657,7 +657,7 @@ Node* Tree::findNodeRecursive(const QStringList& path,
if (n->match(types))
return n;
}
- else if (!n->isLeaf()) {
+ else if (n->isAggregate()) {
n = findNodeRecursive(path, pathIndex+1, n, types);
if (n)
return n;
@@ -689,7 +689,7 @@ const Node* Tree::findNodeForTarget(const QStringList& path,
{
const Node* node = 0;
if ((genus == Node::DontCare) || (genus == Node::DOC)) {
- node = findDocumentNodeByTitle(path.at(0));
+ node = findPageNodeByTitle(path.at(0));
if (node) {
if (!target.isEmpty()) {
ref = getRef(target, node);
@@ -745,7 +745,7 @@ const Node* Tree::findNodeForTarget(const QStringList& path,
}
while (current) {
- if (current->isAggregate()) {
+ if (current->isAggregate()) { // Should this be isPageNode() ???
const Node* node = matchPathAndTarget(path, path_idx, target, current, flags, genus, ref);
if (node)
return node;
@@ -961,17 +961,17 @@ void Tree::insertTarget(const QString& name,
void Tree::resolveTargets(Aggregate* root)
{
foreach (Node* child, root->childNodes()) {
- if (child->type() == Node::Document) {
- DocumentNode* node = static_cast<DocumentNode*>(child);
+ if (child->nodeType() == Node::Page) {
+ PageNode* node = static_cast<PageNode*>(child);
QString key = node->title();
if (!key.isEmpty()) {
if (key.contains(QChar(' ')))
key = Doc::canonicalTitle(key);
- QList<DocumentNode*> nodes = docNodesByTitle_.values(key);
+ QList<PageNode*> nodes = pageNodesByTitle_.values(key);
bool alreadyThere = false;
if (!nodes.empty()) {
for (int i=0; i< nodes.size(); ++i) {
- if (nodes[i]->docSubtype() == Node::ExternalPage) {
+ if (nodes[i]->isExternalPage()) {
if (node->name() == nodes[i]->name()) {
alreadyThere = true;
break;
@@ -980,7 +980,7 @@ void Tree::resolveTargets(Aggregate* root)
}
}
if (!alreadyThere)
- docNodesByTitle_.insert(key, node);
+ pageNodesByTitle_.insert(key, node);
}
}
@@ -1097,29 +1097,29 @@ Tree::findUnambiguousTarget(const QString& target, Node::Genus genus, QString& r
/*!
This function searches for a node with the specified \a title.
*/
-const DocumentNode* Tree::findDocumentNodeByTitle(const QString& title) const
+const PageNode* Tree::findPageNodeByTitle(const QString& title) const
{
- DocumentNodeMultiMap::const_iterator i;
+ PageNodeMultiMap::const_iterator i;
if (title.contains(QChar(' ')))
- i = docNodesByTitle_.constFind(Doc::canonicalTitle(title));
+ i = pageNodesByTitle_.constFind(Doc::canonicalTitle(title));
else
- i = docNodesByTitle_.constFind(title);
- if (i != docNodesByTitle_.constEnd()) {
+ i = pageNodesByTitle_.constFind(title);
+ if (i != pageNodesByTitle_.constEnd()) {
/*
Reporting all these duplicate section titles is probably
overkill. We should report the duplicate file and let
that suffice.
*/
- DocumentNodeMultiMap::const_iterator j = i;
+ PageNodeMultiMap::const_iterator j = i;
++j;
- if (j != docNodesByTitle_.constEnd() && j.key() == i.key()) {
- while (j != docNodesByTitle_.constEnd()) {
+ if (j != pageNodesByTitle_.constEnd() && j.key() == i.key()) {
+ while (j != pageNodesByTitle_.constEnd()) {
if (j.key() == i.key() && j.value()->url().isEmpty()) {
break; // Just report one duplicate for now.
}
++j;
}
- if (j != docNodesByTitle_.cend()) {
+ if (j != pageNodesByTitle_.cend()) {
i.value()->location().warning("This page title exists in more than one file: " + title);
j.value()->location().warning("[It also exists here]");
}
@@ -1163,19 +1163,19 @@ QString Tree::refForAtom(const Atom* atom)
*/
/*!
- Returns a pointer to the collection map specified by \a genus.
- Returns null if \a genus is not specified.
+ Returns a pointer to the collection map specified by \a type.
+ Returns null if \a type is not specified.
*/
-CNMap* Tree::getCollectionMap(Node::Genus genus)
+CNMap* Tree::getCollectionMap(Node::NodeType type)
{
- switch (genus) {
- case Node::DOC:
+ switch (type) {
+ case Node::Group:
return &groups_;
- case Node::CPP:
+ case Node::Module:
return &modules_;
- case Node::QML:
+ case Node::QmlModule:
return &qmlModules_;
- case Node::JS:
+ case Node::JsModule:
return &jsModules_;
default:
break;
@@ -1184,13 +1184,14 @@ CNMap* Tree::getCollectionMap(Node::Genus genus)
}
/*!
- 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.
+ Searches this tree for a collection named \a name with the
+ specified \a type. If the collection is found, a pointer
+ to it is returned. If a collection is not found, null is
+ returned.
*/
-CollectionNode* Tree::getCollection(const QString& name, Node::Genus genus)
+CollectionNode* Tree::getCollection(const QString& name, Node::NodeType type)
{
- CNMap* m = getCollectionMap(genus);
+ CNMap* m = getCollectionMap(type);
if (m) {
CNMap::const_iterator i = m->constFind(name);
if (i != m->cend())
@@ -1202,8 +1203,8 @@ CollectionNode* Tree::getCollection(const QString& name, Node::Genus genus)
/*!
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
+ \a type specifies which kind of collection node you want.
+ If a collection node with the specified \a name and \a type
is not found, a new one is created, and the pointer to the
new one is returned.
@@ -1214,32 +1215,15 @@ CollectionNode* Tree::getCollection(const QString& name, Node::Genus genus)
If it is \c{DontCare}, 0 is returned, which is a programming
error.
*/
-CollectionNode* Tree::findCollection(const QString& name, Node::Genus genus)
+CollectionNode* Tree::findCollection(const QString& name, Node::NodeType type)
{
- CNMap* m = getCollectionMap(genus);
+ CNMap* m = getCollectionMap(type);
if (!m) // error
return 0;
CNMap::const_iterator i = m->constFind(name);
if (i != m->cend())
return i.value();
- Node::NodeType 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);
+ CollectionNode* cn = new CollectionNode(type, root(), name);
cn->markNotSeen();
m->insert(name, cn);
return cn;
diff --git a/src/qdoc/tree.h b/src/qdoc/tree.h
index 136928fc1..145f9f8aa 100644
--- a/src/qdoc/tree.h
+++ b/src/qdoc/tree.h
@@ -81,7 +81,7 @@ struct TargetLoc
};
typedef QMultiMap<QString, TargetRec*> TargetMap;
-typedef QMultiMap<QString, DocumentNode*> DocumentNodeMultiMap;
+typedef QMultiMap<QString, PageNode*> PageNodeMultiMap;
typedef QMap<QString, QmlTypeNode*> QmlTypeMap;
typedef QMultiMap<QString, const ExampleNode*> ExampleNodeMap;
typedef QVector<TargetLoc*> TargetList;
@@ -115,7 +115,7 @@ class Tree
Node* findNodeRecursive(const QStringList& path,
int pathIndex,
Node* start,
- const NodeTypeList& types) const;
+ const QList<int> &types) const;
const Node* findNodeForTarget(const QStringList& path,
const QString& target,
@@ -139,7 +139,7 @@ class Tree
QmlTypeNode* findQmlTypeNode(const QStringList& path);
Node* findNodeByNameAndType(const QStringList& path, Node::NodeType type) const;
- Aggregate* findRelatesNode(const QStringList& path);
+ PageNode* findRelatesNode(const QStringList& path);
QString getRef(const QString& target, const Node* node) const;
void insertTarget(const QString& name,
const QString& title,
@@ -148,7 +148,7 @@ class Tree
int priority);
void resolveTargets(Aggregate* root);
const Node* findUnambiguousTarget(const QString& target, Node::Genus genus, QString& ref) const;
- const DocumentNode* findDocumentNodeByTitle(const QString& title) const;
+ const PageNode* findPageNodeByTitle(const QString& title) const;
void addPropertyFunction(PropertyNode *property,
const QString &funcName,
@@ -171,19 +171,19 @@ class Tree
NodeList allBaseClasses(const ClassNode *classe) const;
QString refForAtom(const Atom* atom);
- CNMap* getCollectionMap(Node::Genus genus);
+ CNMap* getCollectionMap(Node::NodeType type);
const CNMap& groups() const { return groups_; }
const CNMap& modules() const { return modules_; }
const CNMap& qmlModules() const { return qmlModules_; }
const CNMap& jsModules() const { return jsModules_; }
- CollectionNode* getCollection(const QString& name, Node::Genus genus);
- CollectionNode* findCollection(const QString& name, Node::Genus genus);
+ CollectionNode* getCollection(const QString& name, Node::NodeType type);
+ CollectionNode* findCollection(const QString& name, Node::NodeType type);
- 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); }
+ CollectionNode* findGroup(const QString& name) { return findCollection(name, Node::Group); }
+ CollectionNode* findModule(const QString& name) { return findCollection(name, Node::Module); }
+ CollectionNode* findQmlModule(const QString& name) { return findCollection(name, Node::QmlModule); }
+ CollectionNode* findJsModule(const QString& name) { return findCollection(name, Node::JsModule); }
CollectionNode* addGroup(const QString& name) { return findGroup(name); }
CollectionNode* addModule(const QString& name) { return findModule(name); }
@@ -238,7 +238,7 @@ private:
QDocDatabase* qdb_;
NamespaceNode root_;
PropertyMap unresolvedPropertyMap;
- DocumentNodeMultiMap docNodesByTitle_;
+ PageNodeMultiMap pageNodesByTitle_;
TargetMap nodesByTargetRef_;
TargetMap nodesByTargetTitle_;
CNMap groups_;
diff --git a/src/qdoc/webxmlgenerator.cpp b/src/qdoc/webxmlgenerator.cpp
index 3b925a5a8..78a7bb773 100644
--- a/src/qdoc/webxmlgenerator.cpp
+++ b/src/qdoc/webxmlgenerator.cpp
@@ -91,9 +91,9 @@ void WebXMLGenerator::generateCppReferencePage(Node *node, CodeMarker *marker)
endSubPage();
}
-void WebXMLGenerator::generateDocumentNode(DocumentNode *dn, CodeMarker *marker)
+void WebXMLGenerator::generatePageNode(PageNode *pn, CodeMarker *marker)
{
- generateCppReferencePage(dn, marker);
+ generateCppReferencePage(pn, marker);
}
void WebXMLGenerator::generateIndexSections(QXmlStreamWriter &writer,
@@ -109,7 +109,7 @@ void WebXMLGenerator::generateIndexSections(QXmlStreamWriter &writer,
writer.writeAttribute("line", QString::number(node->doc().location().lineNo()));
writer.writeAttribute("column", QString::number(node->doc().location().columnNo()));
- if (node->isDocumentNode())
+ if (node->isTextPageNode())
generateRelations(writer, node);
if (node->isModule()) {
@@ -177,27 +177,25 @@ void WebXMLGenerator::generateDocumentation(Node *node)
{
// Don't generate nodes that are already processed, or if they're not supposed to
// generate output, ie. external, index or images nodes.
- if (!node->url().isNull() ||
- node->isExternalPage() ||
- node->isIndexNode() ||
- node->docSubtype() == Node::Image) {
+ if (!node->url().isNull() || node->isExternalPage() || node->isIndexNode())
return;
- }
if (node->isInternal() && !showInternal_)
return;
CodeMarker *marker = CodeMarker::markerForFileName(node->location().filePath());
if (node->parent()) {
- if (node->isNamespace() || node->isClass())
+ if (node->isNamespace() || node->isClass() || node->isHeader())
generateCppReferencePage(static_cast<Aggregate*>(node), marker);
- else if (node->isDocumentNode())
- generateDocumentNode(static_cast<DocumentNode *>(node), marker);
- else if (node->isCollectionNode() && node->wasSeen()) {
- // see remarks in base class impl.
- qdb_->mergeCollections(static_cast<CollectionNode *>(node));
- generateCppReferencePage(node, marker);
+ else if (node->isCollectionNode()) {
+ if (node->wasSeen()) {
+ // see remarks in base class impl.
+ qdb_->mergeCollections(static_cast<CollectionNode *>(node));
+ generateCppReferencePage(node, marker);
+ }
}
+ else if (node->isTextPageNode())
+ generatePageNode(static_cast<PageNode *>(node), marker);
// else if TODO: anything else?
}
@@ -239,7 +237,7 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer,
case Atom::BriefLeft:
writer.writeStartElement("brief");
- switch (relative->type()) {
+ switch (relative->nodeType()) {
case Node::Property:
writer.writeCharacters("This property");
break;
@@ -249,7 +247,7 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer,
default:
break;
}
- if (relative->type() == Node::Property || relative->type() == Node::Variable) {
+ if (relative->nodeType() == Node::Property || relative->nodeType() == Node::Variable) {
QString str;
const Atom *a = atom->next();
while (a != nullptr && a->type() != Atom::BriefRight) {
@@ -275,7 +273,7 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer,
break;
case Atom::BriefRight:
- if (relative->type() == Node::Property || relative->type() == Node::Variable)
+ if (relative->nodeType() == Node::Property || relative->nodeType() == Node::Variable)
writer.writeCharacters(".");
writer.writeEndElement(); // brief
@@ -457,7 +455,7 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer,
else if (atom->string() == ATOM_LIST_TAG)
writer.writeAttribute("type", "definition");
else if (atom->string() == ATOM_LIST_VALUE) {
- if (relative->type() == Node::Enum)
+ if (relative->nodeType() == Node::Enum)
writer.writeAttribute("type", "enum");
else
writer.writeAttribute("type", "definition");
@@ -665,11 +663,11 @@ void WebXMLGenerator::startLink(QXmlStreamWriter &writer, const Atom *atom,
writer.writeAttribute("raw", atom->string());
writer.writeAttribute("href", link);
writer.writeAttribute("type", targetType(node));
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Enum:
writer.writeAttribute("enum", fullName);
break;
- case Node::Document:
+ case Node::Page:
writer.writeAttribute("page", fullName);
break;
case Node::Property:
@@ -687,12 +685,12 @@ void WebXMLGenerator::startLink(QXmlStreamWriter &writer, const Atom *atom,
QString WebXMLGenerator::targetType(const Node *node)
{
- switch (node->type()) {
+ switch (node->nodeType()) {
case Node::Namespace:
return "namespace";
case Node::Class:
return "class";
- case Node::Document:
+ case Node::Page:
return "page";
case Node::Enum:
return "enum";
@@ -798,7 +796,7 @@ const QPair<QString,QString> WebXMLGenerator::anchorForNode(const Node *node)
QPair<QString,QString> anchorPair;
anchorPair.first = fullDocumentLocation(node);
- if (node->isDocumentNode())
+ if (node->isTextPageNode())
anchorPair.second = node->title();
return anchorPair;
diff --git a/src/qdoc/webxmlgenerator.h b/src/qdoc/webxmlgenerator.h
index 84da52323..6e6f8069f 100644
--- a/src/qdoc/webxmlgenerator.h
+++ b/src/qdoc/webxmlgenerator.h
@@ -51,7 +51,7 @@ public:
protected:
int generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker) override;
void generateCppReferencePage(Node *node, CodeMarker *marker) override;
- void generateDocumentNode(DocumentNode *dn, CodeMarker *marker) override;
+ void generatePageNode(PageNode *pn, CodeMarker *marker) override;
void generateDocumentation(Node *node) override;
QString fileExtension() const override;