1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
3 | |
4 | #ifndef GENERATOR_H |
5 | #define GENERATOR_H |
6 | |
7 | #include "text.h" |
8 | #include "utilities.h" |
9 | #include "filesystem/fileresolver.h" |
10 | |
11 | #include <QtCore/qlist.h> |
12 | #include <QtCore/qmap.h> |
13 | #include <QtCore/qstring.h> |
14 | #include <QtCore/qstringlist.h> |
15 | #include <QtCore/qtextstream.h> |
16 | #include <optional> |
17 | |
18 | QT_BEGIN_NAMESPACE |
19 | |
20 | typedef QMultiMap<QString, Node *> NodeMultiMap; |
21 | |
22 | class Aggregate; |
23 | class CodeMarker; |
24 | class ExampleNode; |
25 | class FunctionNode; |
26 | class Location; |
27 | class Node; |
28 | class QDocDatabase; |
29 | |
30 | class Generator |
31 | { |
32 | public: |
33 | enum ListType { Generic, Obsolete }; |
34 | |
35 | enum Addendum { |
36 | Invokable, |
37 | PrivateSignal, |
38 | QmlSignalHandler, |
39 | AssociatedProperties, |
40 | BindableProperty |
41 | }; |
42 | |
43 | Generator(FileResolver& file_resolver); |
44 | virtual ~Generator(); |
45 | |
46 | virtual bool canHandleFormat(const QString &format) { return format == this->format(); } |
47 | virtual QString format() = 0; |
48 | virtual void generateDocs(); |
49 | virtual void initializeGenerator(); |
50 | virtual void initializeFormat(); |
51 | virtual void terminateGenerator(); |
52 | virtual QString typeString(const Node *node); |
53 | |
54 | QString fullDocumentLocation(const Node *node, bool useSubdir = false); |
55 | QString linkForExampleFile(const QString &path, const QString &fileExt = QString()); |
56 | static QString exampleFileTitle(const ExampleNode *relative, const QString &fileName); |
57 | static Generator *currentGenerator() { return s_currentGenerator; } |
58 | static Generator *generatorForFormat(const QString &format); |
59 | static void initialize(); |
60 | static const QString &outputDir() { return s_outDir; } |
61 | static const QString &outputSubdir() { return s_outSubdir; } |
62 | static void terminate(); |
63 | static const QStringList &outputFileNames() { return s_outFileNames; } |
64 | static bool noLinkErrors() { return s_noLinkErrors; } |
65 | static bool autolinkErrors() { return s_autolinkErrors; } |
66 | static QString defaultModuleName() { return s_project; } |
67 | static void resetUseOutputSubdirs() { s_useOutputSubdirs = false; } |
68 | static bool useOutputSubdirs() { return s_useOutputSubdirs; } |
69 | static void setQmlTypeContext(QmlTypeNode *t) { s_qmlTypeContext = t; } |
70 | static QmlTypeNode *qmlTypeContext() { return s_qmlTypeContext; } |
71 | static QString cleanRef(const QString &ref, bool xmlCompliant = false); |
72 | static QString plainCode(const QString &markedCode); |
73 | virtual QString fileBase(const Node *node) const; |
74 | |
75 | protected: |
76 | static QFile *openSubPageFile(const Node *node, const QString &fileName); |
77 | void beginSubPage(const Node *node, const QString &fileName); |
78 | void endSubPage(); |
79 | [[nodiscard]] virtual QString fileExtension() const = 0; |
80 | virtual void generateExampleFilePage(const Node *, ResolvedFile, CodeMarker * = nullptr) {} |
81 | virtual void generateAlsoList(const Node *node, CodeMarker *marker); |
82 | virtual void generateAlsoList(const Node *node) { generateAlsoList(node, marker: nullptr); } |
83 | virtual qsizetype generateAtom(const Atom *, const Node *, CodeMarker *) { return 0; } |
84 | virtual qsizetype generateAtom(const Atom *atom, const Node *node) |
85 | { |
86 | return generateAtom(atom, node, nullptr); |
87 | } |
88 | virtual void generateBody(const Node *node, CodeMarker *marker); |
89 | virtual void generateCppReferencePage(Aggregate *, CodeMarker *) {} |
90 | virtual void generateProxyPage(Aggregate *, CodeMarker *) {} |
91 | virtual void generateQmlTypePage(QmlTypeNode *, CodeMarker *) {} |
92 | virtual void generatePageNode(PageNode *, CodeMarker *) {} |
93 | virtual void generateCollectionNode(CollectionNode *, CodeMarker *) {} |
94 | virtual void generateGenericCollectionPage(CollectionNode *, CodeMarker *) {} |
95 | virtual void generateDocumentation(Node *node); |
96 | virtual bool generateText(const Text &text, const Node *relative, CodeMarker *marker); |
97 | virtual bool generateText(const Text &text, const Node *relative) |
98 | { |
99 | return generateText(text, relative, marker: nullptr); |
100 | }; |
101 | virtual int skipAtoms(const Atom *atom, Atom::AtomType type) const; |
102 | |
103 | static bool matchAhead(const Atom *atom, Atom::AtomType expectedAtomType); |
104 | static QString outputPrefix(const Node *node); |
105 | static QString outputSuffix(const Node *node); |
106 | static void supplementAlsoList(const Node *node, QList<Text> &alsoList); |
107 | static QString trimmedTrailing(const QString &string, const QString &prefix, |
108 | const QString &suffix); |
109 | void initializeTextOutput(); |
110 | QString fileName(const Node *node, const QString &extension = QString()) const; |
111 | QMap<QString, QString> &formattingLeftMap(); |
112 | QMap<QString, QString> &formattingRightMap(); |
113 | const Atom *generateAtomList(const Atom *atom, const Node *relative, CodeMarker *marker, |
114 | bool generate, int &numGeneratedAtoms); |
115 | void generateRequiredLinks(const Node *node, CodeMarker *marker); |
116 | void generateLinkToExample(const ExampleNode *en, CodeMarker *marker, |
117 | const QString &exampleUrl); |
118 | virtual void generateFileList(const ExampleNode *en, CodeMarker *marker, bool images); |
119 | static QString formatSince(const Node *node); |
120 | void generateSince(const Node *node, CodeMarker *marker); |
121 | void generateNoexceptNote(const Node *node, CodeMarker *marker); |
122 | void generateStatus(const Node *node, CodeMarker *marker); |
123 | virtual void generateAddendum(const Node *node, Addendum type, CodeMarker *marker, |
124 | bool generateNote); |
125 | virtual void generateAddendum(const Node *node, Addendum type, CodeMarker *marker) |
126 | { |
127 | generateAddendum(node, type, marker, generateNote: true); |
128 | }; |
129 | void generateThreadSafeness(const Node *node, CodeMarker *marker); |
130 | QStringList getMetadataElements(const Aggregate *inner, const QString &t); |
131 | void generateOverloadedSignal(const Node *node, CodeMarker *marker); |
132 | static QString getOverloadedSignalCode(const Node *node); |
133 | QString indent(int level, const QString &markedCode); |
134 | QTextStream &out(); |
135 | QString outFileName(); |
136 | bool parseArg(const QString &src, const QString &tag, int *pos, int n, QStringView *contents, |
137 | QStringView *par1 = nullptr); |
138 | void unknownAtom(const Atom *atom); |
139 | int appendSortedQmlNames(Text &text, const Node *base, const NodeList &subs); |
140 | |
141 | static bool hasExceptions(const Node *node, NodeList &reentrant, NodeList &threadsafe, |
142 | NodeList &nonreentrant); |
143 | |
144 | QString naturalLanguage; |
145 | QString tagFile_; |
146 | QStack<QTextStream *> outStreamStack; |
147 | |
148 | void appendFullName(Text &text, const Node *apparentNode, const Node *relative, |
149 | const Node *actualNode = nullptr); |
150 | void appendFullName(Text &text, const Node *apparentNode, const QString &fullName, |
151 | const Node *actualNode); |
152 | int appendSortedNames(Text &text, const ClassNode *classe, |
153 | const QList<RelatedClass> &classes); |
154 | void appendSignature(Text &text, const Node *node); |
155 | void signatureList(const NodeList &nodes, const Node *relative, CodeMarker *marker); |
156 | |
157 | void addImageToCopy(const ExampleNode *en, const ResolvedFile& resolved_file); |
158 | // TODO: This seems to be used as the predicate in std::sort calls. |
159 | // Remove it as it is unneeded. |
160 | // Indeed, it could be replaced by std::less and, furthermore, |
161 | // std::sort already defaults to operator< when no predicate is |
162 | // provided. |
163 | static bool comparePaths(const QString &a, const QString &b) { return (a < b); } |
164 | |
165 | private: |
166 | static Generator *s_currentGenerator; |
167 | static QMap<QString, QMap<QString, QString>> s_fmtLeftMaps; |
168 | static QMap<QString, QMap<QString, QString>> s_fmtRightMaps; |
169 | static QList<Generator *> s_generators; |
170 | static QString s_project; |
171 | static QString s_outDir; |
172 | static QString s_outSubdir; |
173 | static QStringList s_outFileNames; |
174 | static QSet<QString> s_outputFormats; |
175 | static QHash<QString, QString> s_outputPrefixes; |
176 | static QHash<QString, QString> s_outputSuffixes; |
177 | static bool s_noLinkErrors; |
178 | static bool s_autolinkErrors; |
179 | static bool s_redirectDocumentationToDevNull; |
180 | static bool s_useOutputSubdirs; |
181 | static QmlTypeNode *s_qmlTypeContext; |
182 | |
183 | void generateReimplementsClause(const FunctionNode *fn, CodeMarker *marker); |
184 | static void copyTemplateFiles(const QString &configVar, const QString &subDir); |
185 | |
186 | protected: |
187 | FileResolver& file_resolver; |
188 | |
189 | QDocDatabase *m_qdb { nullptr }; |
190 | bool m_inLink { false }; |
191 | bool m_inContents { false }; |
192 | bool m_inSectionHeading { false }; |
193 | bool { false }; |
194 | bool m_threeColumnEnumValueTable { true }; |
195 | bool m_showInternal { false }; |
196 | bool m_quoting { false }; |
197 | int m_numTableRows { 0 }; |
198 | QString m_link {}; |
199 | QString m_sectionNumber {}; |
200 | }; |
201 | |
202 | std::optional<QString> formatStatus(const Node *node, QDocDatabase *qdb); |
203 | |
204 | QT_END_NAMESPACE |
205 | |
206 | #endif |
207 | |