qdoc: Update for classes in namespaces

The resolving of namespaces across module boundaries
was moving all the nodes for elements contained in the
namespace into the namespace node for the \namespace
command for that namespace. But moving class and
namespace nodes is wrong because they are actually in
different modules where they should also be output.
This update to the fix for the original bug leaves
the class and nested namespace nodes where they are
but adds them as special "orphan" nodes to the
namespace node that has the \namespace command.

These orphan nodes are then included in the namespace
content list when it is written out.

Change-Id: I0eee368ed39f28129b5b43bb4a16963961f53db3
Task-number: QTBUG-44688
Reviewed-by: Martin Smith <martin.smith@digia.com>
Martin Smith 2015-03-17 13:50:06 +01:00
parent 58da6f96a8
commit 6a5e2f69a8
5 changed files with 44 additions and 9 deletions

View File

@ -807,6 +807,21 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
}
++n;
}
if (inner->isNamespace()) {
const NamespaceNode* ns = static_cast<const NamespaceNode*>(inner);
if (!ns->orphans().isEmpty()) {
foreach (Node* n, ns->orphans()) {
// Use inner as a temporary parent when inserting orphans
InnerNode* p = n->parent();
n->setParent(const_cast<InnerNode*>(inner));
if (n->isClass())
insert(classes, n, style, status);
else if (n->isNamespace())
insert(namespaces, n, style, status);
n->setParent(p);
}
}
}
append(sections, namespaces);
append(sections, classes);
append(sections, types);

View File

@ -1006,7 +1006,8 @@ void Generator::generateInnerNode(InnerNode* node)
CodeMarker *marker = CodeMarker::markerForFileName(node->location().filePath());
if (node->parent() != 0) {
if (node->isNamespace() || node->isClass()) {
if ((node->isNamespace() && node->status() != Node::Intermediate)
|| node->isClass()) {
beginSubPage(node, fileName(node));
generateClassLikeNode(node, marker);
endSubPage();

View File

@ -883,12 +883,14 @@ void InnerNode::setOverload(FunctionNode *func, bool overlode)
/*!
Mark all child nodes that have no documentation as having
private access and internal status. qdoc will then ignore
them for documentation purposes.
them for documentation purposes. Some nodes have an
Intermediate status, meaning that they should be ignored,
but not their children.
*/
void InnerNode::makeUndocumentedChildrenInternal()
{
foreach (Node *child, childNodes()) {
if (child->doc().isEmpty()) {
if (child->doc().isEmpty() && child->status() != Node::Intermediate) {
child->setAccess(Node::Private);
child->setStatus(Node::Internal);
}

View File

@ -116,7 +116,8 @@ public:
Deprecated,
Preliminary,
Commendable,
Internal
Internal,
Intermediate
}; // don't reorder this enum
enum ThreadSafeness {
@ -458,10 +459,13 @@ public:
void markSeen() { seen_ = true; }
void markNotSeen() { seen_ = false; }
void setTree(Tree* t) { tree_ = t; }
const NodeList& orphans() const { return orphans_; }
void addOrphan(Node* child) { orphans_.append(child); }
private:
bool seen_;
Tree* tree_;
NodeList orphans_;
};
struct RelatedClass

View File

@ -1310,11 +1310,24 @@ void QDocDatabase::resolveNamespaces()
foreach (Node* n, nodes) {
if (n->isNamespace()) {
NamespaceNode* NS = static_cast<NamespaceNode*>(n);
if (NS != ns) {
while (!NS->childNodes().isEmpty()) {
Node* child = NS->childNodes().first();
NS->removeChild(child);
ns->addChild(child);
if ((NS != ns) && !NS->childNodes().isEmpty()) {
const NodeList& children = NS->childNodes();
int i = children.size() - 1;
while (i >= 0) {
Node* child = children.at(i--);
if (!child)
continue;
if (!child->isClass()
&& !child->isQmlType()
&& !child->isNamespace()) {
NS->removeChild(child);
ns->addChild(child);
}
else {
NS->setStatus(Node::Intermediate);
NS->setAccess(Node::Public);
ns->addOrphan(child);
}
}
}
}