summaryrefslogtreecommitdiffstats
path: root/src/qdoc/tree.h
diff options
context:
space:
mode:
authorMartin Smith <martin.smith@qt.io>2019-01-22 12:11:13 +0100
committerPaul Wicking <paul.wicking@qt.io>2019-02-06 13:19:48 +0000
commitbf8ee4c99d56c2bf770343b7db07f68a2c6a7617 (patch)
tree73095c02dbfbce7d0830f890aabaa58d2c0e9224 /src/qdoc/tree.h
parentb3c9f6cb9eb104bf4fe86b377aee7875473f97b4 (diff)
qdoc: Major clean-up of FunctionNode and parameter processingv5.13.0-alpha1
This update was motivated by the need to correct two known issues in qdoc. First, linking to overloaded functions failed in some cases because the overloads were not numbered consistently, causing links to go to the wrong overload or to nowhere at all. Second, the mechanism for handling the \relates command didn't support using it to relate a function to more than one class. For example, there are many global qHash() functions spread around QtBase. Each is meant to compute a hash index for an object of some class type, so the object can be inserted into a QHash map for that class type. It is then desired to relate qHash(type Xxx, int seed) to both QHash<type> and class Xxx, so that the documentation for that qHash() function appears as a related non-member function of both QHash<type> and class Xxx. The example above also illustrates the overload numbering problem, because all these qHash() functions are overloads of the name qHash. To make matters worse, they are not all in the same module. Most of them are in QtCore, but a few are in QtNetwork, and this distribution problem will become worse over time as more qHash() functions are added. Prior to this update, qdoc was unable to relate a function to something in a different module, or it didn't always work. While designing a fix for these issues, it became clear that the processing of the FunctionNode and the function parameters would have to be rewritten. That's what this update does. These are the main points: 1. A new subclass of Node is added to act as a proxy for a class in another module. This ProxyNode acts as a place holder for the functions (and possibly other elements) that are related to a class in another module. This is used for the qHash() functions in QtNetwork that are related to QHash in QtCore. qdoc generates an html file named qtnetwork/qhash-proxy.html that contains the documentation for these functions. But these functions are listed as related non-members on the QHash class reference page in the qtcore output directory. They are listed there in the summary, but they link to the qhash-proxy.html page in qtnetwork. 2. A new, Parameters class is added to qdoc (parameters.h and parameters.cpp), and the class Parameter is moved there from node.h. class Parameters replaces the old QVector<Parameter> wherever it was used. This encapsulates all the parameter processing and matching in the Parameters class and simplifies the code at all the places where QVector<Parameter> had been used. 3. The assignment of overload numbers is now done in the normalizeOverloads() function, which is called after all the headers and sources have been processed but before the generate phase begins. This assignment is a simple renumbering now because all the overloads of a function are linked to each other via a nextOverload_ link in the FunctionNode. The first function named qHash() is inserted into the Aggregate node's function map, but subsequent qHash() FunctionNodes are not entered into the function map but are linked to the first qHash() via its nextOverload_ link. 4. The \relates command can now be used multiple times in a single qdoc comment. There remains some work to be done here because this currently only works for global entities, but there are several cases where \relates has been used in the qdoc comment of a member of a class. This will be fixed soon, I believe. When qdoc sees the first \relates Xxx command, for example for qHash(Yyy, seed), that qHash() is a child of the global namespace. qdoc allows it to remain as a child of the global namespace but it tells class Xxx to "adopt" that child (see Node::adoptChild()). This function makes this instance of qHash() be a child of class Xxx (in this case QHash<type>), so that the parent of this qHash() becomes Xxx. After this "adoption," qHash() is a child of both the global namespace and class Xxx, but qHash() only knows it is a child of Xxx, i.e. its parent pointer is Xxx. If this is the first qHash() to become a child of Xxx, it is inserted into the function map of Xxx, but its nextOverload_ link is not changed. This is because all the global qHash() functions have already been linked into the nextOverload_ linked list, and this list must not be changed. Hence, when qdoc searches for qHash(something) to make a link to it, it will find it as a child of the global namespace, but it will correctly link to it using its actual parent pointer. When qdoc sees the second \relates Yyy for this qHash() function, qdoc sees that this FunctionNode has already been made a related non-member of Xxx, so it can't let Yyy "adopt" it. Instead, it tells Yyy to clone this qHash(), which creates a shallow copy of it but resets its nextOverload_ pointer to nullptr. I believe this clone of qHash() won't be found in a search for a function named qHash(), because the global one (the adopted one) will be found first. Or, if it is found, a link to the clone will be generated, but that's ok because the documentation is identical. Note that the existence of qHash in two child lists is taken into account at destruction time. The only place where a Node is destroyed is in the destructor of Tree, which destroys the Node tree from the root down to the leaves. Each aggregate node is responsible for deleting each of its child nodes, but it only deletes a child node if it is the parent of that child node. All of the above revealed that some of the findFunctionNode() functions were either no longer needed or weren't being called in the first place, so they were deleted. This change is now ready for testing. Change-Id: I6da3e2e9e71d39a29d90e073ed614309a49e3d4c Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Diffstat (limited to 'src/qdoc/tree.h')
-rw-r--r--src/qdoc/tree.h62
1 files changed, 29 insertions, 33 deletions
diff --git a/src/qdoc/tree.h b/src/qdoc/tree.h
index 145f9f8aa..86637bf3e 100644
--- a/src/qdoc/tree.h
+++ b/src/qdoc/tree.h
@@ -89,25 +89,37 @@ typedef QMap<QString, TargetList*> TargetListMap;
class Tree
{
- private:
friend class QDocForest;
friend class QDocDatabase;
+ private: // Note the constructor and destructor are private.
typedef QMap<PropertyNode::FunctionRole, QString> RoleMap;
typedef QMap<PropertyNode*, RoleMap> PropertyMap;
Tree(const QString& camelCaseModuleName, QDocDatabase* qdb);
~Tree();
+ public: // Of necessity, a few public functions remain.
+ const QString &camelCaseModuleName() const { return camelCaseModuleName_; }
+ const QString &physicalModuleName() const { return physicalModuleName_; }
+ const QString &indexFileName() const { return indexFileName_; }
+ long incrementLinkCount() { return --linkCount_; }
+ void clearLinkCount() { linkCount_ = 0; }
+ long linkCount() const { return linkCount_; }
+ const QString &indexTitle() const { return indexTitle_; }
+ void setIndexTitle(const QString &t) { indexTitle_ = t; }
+ NodeList &proxies() { return proxies_; }
+ void appendProxy(ProxyNode *t) { proxies_.append(t); }
+
+ private: // The rest of the class is private.
+ Aggregate *findAggregate(const QString &name);
Node* findNodeForInclude(const QStringList& path) const;
ClassNode* findClassNode(const QStringList& path, const Node* start = 0) const;
NamespaceNode* findNamespaceNode(const QStringList& path) const;
- FunctionNode* findFunctionNode(const QStringList& parentPath, const FunctionNode* clone);
- const Node* findFunctionNode(const QString& target,
- const QString& params,
- const Node* relative,
- Node::Genus genus) const;
-
+ const FunctionNode *findFunctionNode(const QStringList &path,
+ const Parameters &parameters,
+ const Node *relative,
+ Node::Genus genus) const;
Node* findNodeRecursive(const QStringList& path,
int pathIndex,
const Node* start,
@@ -132,14 +144,14 @@ class Tree
QString& ref) const;
const Node* findNode(const QStringList &path,
- const Node* relative, // = 0,
- int findFlags, // = 0,
- Node::Genus genus) const; // = Node::DontCare) const;
+ const Node *relative,
+ int flags,
+ Node::Genus genus) const;
QmlTypeNode* findQmlTypeNode(const QStringList& path);
Node* findNodeByNameAndType(const QStringList& path, Node::NodeType type) const;
- PageNode* findRelatesNode(const QStringList& path);
+ Aggregate *findRelatesNode(const QStringList &path);
QString getRef(const QString& target, const Node* node) const;
void insertTarget(const QString& name,
const QString& title,
@@ -153,22 +165,16 @@ class Tree
void addPropertyFunction(PropertyNode *property,
const QString &funcName,
PropertyNode::FunctionRole funcRole);
- void resolveInheritance(Aggregate* n = 0);
+ void resolveInheritance(Aggregate *n);
void resolveInheritanceHelper(int pass, ClassNode* cn);
void resolveProperties();
void resolveCppToQmlLinks();
void resolveUsingClauses();
- void fixInheritance(NamespaceNode *rootNode = 0);
+ void fixInheritance(NamespaceNode *rootNode);
NamespaceNode *root() { return &root_; }
-
- const FunctionNode *findFunctionNode(const QStringList &path,
- const QString& params,
- const Node *relative = 0,
- int findFlags = 0,
- Node::Genus genus = Node::DontCare) const;
const NamespaceNode *root() const { return &root_; }
- NodeList allBaseClasses(const ClassNode *classe) const;
+ ClassList allBaseClasses(const ClassNode *classe) const;
QString refForAtom(const Atom* atom);
CNMap* getCollectionMap(Node::NodeType type);
@@ -200,7 +206,6 @@ class Tree
void insertQmlType(const QString& key, QmlTypeNode* n);
void addExampleNode(ExampleNode* n) { exampleNodeMap_.insert(n->title(), n); }
ExampleNodeMap& exampleNodeMap() { return exampleNodeMap_; }
- const Node* checkForCollision(const QString& name);
void setIndexFileName(const QString& t) { indexFileName_ = t; }
bool treeHasBeenAnalyzed() const { return treeHasBeenAnalyzed_; }
@@ -214,18 +219,8 @@ class Tree
bool broken);
TargetList* getTargetList(const QString& module);
QStringList getTargetListKeys() { return targetListMap_->keys(); }
- Node* findFunctionNodeForTag(const QString &tag, Aggregate* parent = 0);
- Node *findMacroNode(const QString &t, const Aggregate *parent = 0);
-
- public:
- const QString& camelCaseModuleName() const { return camelCaseModuleName_; }
- const QString& physicalModuleName() const { return physicalModuleName_; }
- const QString& indexFileName() const { return indexFileName_; }
- long incrementLinkCount() { return --linkCount_; }
- void clearLinkCount() { linkCount_ = 0; }
- long linkCount() const { return linkCount_; }
- const QString& indexTitle() const { return indexTitle_; }
- void setIndexTitle(const QString &t) { indexTitle_ = t; }
+ FunctionNode *findFunctionNodeForTag(const QString &tag, Aggregate *parent = 0);
+ FunctionNode *findMacroNode(const QString &t, const Aggregate *parent = 0);
private:
bool treeHasBeenAnalyzed_;
@@ -248,6 +243,7 @@ private:
QmlTypeMap qmlTypeMap_;
ExampleNodeMap exampleNodeMap_;
TargetListMap* targetListMap_;
+ NodeList proxies_;
};
QT_END_NAMESPACE