1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 /*
30   tree.h
31 */
32 
33 #ifndef TREE_H
34 #define TREE_H
35 
36 #include "node.h"
37 
38 #include <QtCore/qstack.h>
39 
40 QT_BEGIN_NAMESPACE
41 
42 class QStringList;
43 class QDocDatabase;
44 
45 struct TargetRec
46 {
47 public:
48     enum TargetType { Unknown, Target, Keyword, Contents, Class, Function, Page, Subtitle };
49 
TargetRecTargetRec50     TargetRec(const QString &name, const QString &title, TargetRec::TargetType type, Node *node,
51               int priority)
52         : node_(node), ref_(name), title_(title), priority_(priority), type_(type)
53     {
54         // Discard the dedicated ref for keywords - they always
55         // link to the top of the QDoc comment they appear in
56         if (type == Keyword)
57             ref_.clear();
58     }
59 
isEmptyTargetRec60     bool isEmpty() const { return ref_.isEmpty(); }
genusTargetRec61     Node::Genus genus() { return (node_ ? node_->genus() : Node::DontCare); }
62 
63     Node *node_;
64     QString ref_;
65     QString title_;
66     int priority_;
67     TargetType type_;
68 };
69 
70 struct TargetLoc
71 {
72 public:
TargetLocTargetLoc73     TargetLoc(const Node *loc, const QString &t, const QString &fileName, const QString &text,
74               bool broken)
75         : loc_(loc), target_(t), fileName_(fileName), text_(text), broken_(broken)
76     {
77     }
78     const Node *loc_;
79     QString target_;
80     QString fileName_;
81     QString text_;
82     bool broken_;
83 };
84 
85 typedef QMultiMap<QString, TargetRec *> TargetMap;
86 typedef QMultiMap<QString, PageNode *> PageNodeMultiMap;
87 typedef QMap<QString, QmlTypeNode *> QmlTypeMap;
88 typedef QMultiMap<QString, const ExampleNode *> ExampleNodeMap;
89 typedef QVector<TargetLoc *> TargetList;
90 typedef QMap<QString, TargetList *> TargetListMap;
91 
92 class Tree
93 {
94     friend class QDocForest;
95     friend class QDocDatabase;
96 
97 private: // Note the constructor and destructor are private.
98     typedef QMap<PropertyNode::FunctionRole, QString> RoleMap;
99     typedef QMap<PropertyNode *, RoleMap> PropertyMap;
100 
101     Tree(const QString &camelCaseModuleName, QDocDatabase *qdb);
102     ~Tree();
103 
104 public: // Of necessity, a few public functions remain.
camelCaseModuleName()105     const QString &camelCaseModuleName() const { return camelCaseModuleName_; }
physicalModuleName()106     const QString &physicalModuleName() const { return physicalModuleName_; }
indexFileName()107     const QString &indexFileName() const { return indexFileName_; }
incrementLinkCount()108     long incrementLinkCount() { return --linkCount_; }
clearLinkCount()109     void clearLinkCount() { linkCount_ = 0; }
linkCount()110     long linkCount() const { return linkCount_; }
indexTitle()111     const QString &indexTitle() const { return indexTitle_; }
setIndexTitle(const QString & t)112     void setIndexTitle(const QString &t) { indexTitle_ = t; }
proxies()113     NodeList &proxies() { return proxies_; }
appendProxy(ProxyNode * t)114     void appendProxy(ProxyNode *t) { proxies_.append(t); }
115     void addToDontDocumentMap(QString &arg);
116     void markDontDocumentNodes();
117 
118 private: // The rest of the class is private.
119     Aggregate *findAggregate(const QString &name);
120     Node *findNodeForInclude(const QStringList &path) const;
121     ClassNode *findClassNode(const QStringList &path, const Node *start = nullptr) const;
122     NamespaceNode *findNamespaceNode(const QStringList &path) const;
123     const FunctionNode *findFunctionNode(const QStringList &path, const Parameters &parameters,
124                                          const Node *relative, Node::Genus genus) const;
125     Node *findNodeRecursive(const QStringList &path, int pathIndex, const Node *start,
126                             bool (Node::*)() const) const;
127     const Node *findNodeForTarget(const QStringList &path, const QString &target, const Node *node,
128                                   int flags, Node::Genus genus, QString &ref) const;
129     const Node *matchPathAndTarget(const QStringList &path, int idx, const QString &target,
130                                    const Node *node, int flags, Node::Genus genus,
131                                    QString &ref) const;
132 
133     const Node *findNode(const QStringList &path, const Node *relative, int flags,
134                          Node::Genus genus) const;
135 
136     QmlTypeNode *findQmlTypeNode(const QStringList &path);
137 
138     Node *findNodeByNameAndType(const QStringList &path, bool (Node::*isMatch)() const) const;
139     Aggregate *findRelatesNode(const QStringList &path);
140     QString getRef(const QString &target, const Node *node) const;
141     void insertTarget(const QString &name, const QString &title, TargetRec::TargetType type,
142                       Node *node, int priority);
143     void resolveTargets(Aggregate *root);
144     const Node *findUnambiguousTarget(const QString &target, Node::Genus genus, QString &ref) const;
145     const PageNode *findPageNodeByTitle(const QString &title) const;
146 
147     void addPropertyFunction(PropertyNode *property, const QString &funcName,
148                              PropertyNode::FunctionRole funcRole);
149     void resolveBaseClasses(Aggregate *n);
150     void resolveBaseClassesHelper(int pass, ClassNode *cn);
151     void resolvePropertyOverriddenFromPtrs(Aggregate *n);
152     void resolveProperties();
153     void resolveCppToQmlLinks();
154     void resolveUsingClauses(Aggregate *parent = nullptr);
155     void removePrivateAndInternalBases(NamespaceNode *rootNode);
root()156     NamespaceNode *root() { return &root_; }
root()157     const NamespaceNode *root() const { return &root_; }
158 
159     ClassList allBaseClasses(const ClassNode *classe) const;
160     QString refForAtom(const Atom *atom);
161 
162     CNMap *getCollectionMap(Node::NodeType type);
groups()163     const CNMap &groups() const { return groups_; }
modules()164     const CNMap &modules() const { return modules_; }
qmlModules()165     const CNMap &qmlModules() const { return qmlModules_; }
jsModules()166     const CNMap &jsModules() const { return jsModules_; }
167 
168     CollectionNode *getCollection(const QString &name, Node::NodeType type);
169     CollectionNode *findCollection(const QString &name, Node::NodeType type);
170 
findGroup(const QString & name)171     CollectionNode *findGroup(const QString &name) { return findCollection(name, Node::Group); }
findModule(const QString & name)172     CollectionNode *findModule(const QString &name) { return findCollection(name, Node::Module); }
findQmlModule(const QString & name)173     CollectionNode *findQmlModule(const QString &name)
174     {
175         return findCollection(name, Node::QmlModule);
176     }
findJsModule(const QString & name)177     CollectionNode *findJsModule(const QString &name)
178     {
179         return findCollection(name, Node::JsModule);
180     }
181 
addGroup(const QString & name)182     CollectionNode *addGroup(const QString &name) { return findGroup(name); }
addModule(const QString & name)183     CollectionNode *addModule(const QString &name) { return findModule(name); }
addQmlModule(const QString & name)184     CollectionNode *addQmlModule(const QString &name) { return findQmlModule(name); }
addJsModule(const QString & name)185     CollectionNode *addJsModule(const QString &name) { return findJsModule(name); }
186 
187     CollectionNode *addToGroup(const QString &name, Node *node);
188     CollectionNode *addToModule(const QString &name, Node *node);
189     CollectionNode *addToQmlModule(const QString &name, Node *node);
190     CollectionNode *addToJsModule(const QString &name, Node *node);
191 
lookupQmlType(const QString & name)192     QmlTypeNode *lookupQmlType(const QString &name) const { return qmlTypeMap_.value(name); }
lookupQmlBasicType(const QString & name)193     Aggregate *lookupQmlBasicType(const QString &name) const { return qmlTypeMap_.value(name); }
194     void insertQmlType(const QString &key, QmlTypeNode *n);
addExampleNode(ExampleNode * n)195     void addExampleNode(ExampleNode *n) { exampleNodeMap_.insert(n->title(), n); }
exampleNodeMap()196     ExampleNodeMap &exampleNodeMap() { return exampleNodeMap_; }
setIndexFileName(const QString & t)197     void setIndexFileName(const QString &t) { indexFileName_ = t; }
198 
treeHasBeenAnalyzed()199     bool treeHasBeenAnalyzed() const { return treeHasBeenAnalyzed_; }
docsHaveBeenGenerated()200     bool docsHaveBeenGenerated() const { return docsHaveBeenGenerated_; }
setTreeHasBeenAnalyzed()201     void setTreeHasBeenAnalyzed() { treeHasBeenAnalyzed_ = true; }
setdocsHaveBeenGenerated()202     void setdocsHaveBeenGenerated() { docsHaveBeenGenerated_ = true; }
203     QString getNewLinkTarget(const Node *locNode, const Node *t, const QString &fileName,
204                              QString &text, bool broken);
205     TargetList *getTargetList(const QString &module);
getTargetListKeys()206     QStringList getTargetListKeys() { return targetListMap_->keys(); }
207     FunctionNode *findFunctionNodeForTag(const QString &tag, Aggregate *parent = nullptr);
208     FunctionNode *findMacroNode(const QString &t, const Aggregate *parent = nullptr);
209 
210 private:
211     bool treeHasBeenAnalyzed_;
212     bool docsHaveBeenGenerated_;
213     long linkCount_;
214     QString camelCaseModuleName_;
215     QString physicalModuleName_;
216     QString indexFileName_;
217     QString indexTitle_;
218     QDocDatabase *qdb_;
219     NamespaceNode root_;
220     PropertyMap unresolvedPropertyMap;
221     PageNodeMultiMap pageNodesByTitle_;
222     TargetMap nodesByTargetRef_;
223     TargetMap nodesByTargetTitle_;
224     CNMap groups_;
225     CNMap modules_;
226     CNMap qmlModules_;
227     CNMap jsModules_;
228     QmlTypeMap qmlTypeMap_;
229     ExampleNodeMap exampleNodeMap_;
230     TargetListMap *targetListMap_;
231     NodeList proxies_;
232     NodeMap dontDocumentMap_;
233 };
234 
235 QT_END_NAMESPACE
236 
237 #endif
238