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 QQMLDOMCOMMENTS_P_H |
5 | #define |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include "qqmldom_fwd_p.h" |
19 | #include "qqmldomconstants_p.h" |
20 | #include "qqmldomfunctionref_p.h" |
21 | #include "qqmldomitem_p.h" |
22 | #include "qqmldomattachedinfo_p.h" |
23 | |
24 | #include <QtQml/private/qqmljsast_p.h> |
25 | #include <QtQml/private/qqmljsengine_p.h> |
26 | |
27 | #include <QtCore/QMultiMap> |
28 | #include <QtCore/QHash> |
29 | #include <QtCore/QStack> |
30 | #include <QtCore/QCoreApplication> |
31 | |
32 | #include <memory> |
33 | |
34 | QT_BEGIN_NAMESPACE |
35 | namespace QQmlJS { |
36 | namespace Dom { |
37 | |
38 | class QMLDOM_EXPORT |
39 | { |
40 | Q_DECLARE_TR_FUNCTIONS(CommentInfo) |
41 | public: |
42 | (QStringView); |
43 | |
44 | QStringView () const { return rawComment.mid(pos: 0, n: commentBegin); } |
45 | |
46 | QStringView () const { return rawComment.mid(pos: commentBegin, n: commentEnd - commentBegin); } |
47 | |
48 | QStringView () const |
49 | { |
50 | return rawComment.mid(pos: commentContentBegin, n: commentContentEnd - commentContentEnd); |
51 | } |
52 | |
53 | QStringView () const |
54 | { |
55 | return rawComment.mid(pos: commentEnd, n: rawComment.size() - commentEnd); |
56 | } |
57 | |
58 | quint32 ; |
59 | quint32 ; |
60 | quint32 ; |
61 | quint32 ; |
62 | QStringView ; |
63 | QStringView ; |
64 | bool = false; |
65 | bool = false; |
66 | int ; |
67 | QStringView ; |
68 | QStringList ; |
69 | }; |
70 | |
71 | class QMLDOM_EXPORT |
72 | { |
73 | public: |
74 | constexpr static DomType = DomType::Comment; |
75 | DomType () const { return kindValue; } |
76 | |
77 | (QString c, int newlinesBefore = 1) |
78 | : m_commentStr(c), m_comment(m_commentStr), m_newlinesBefore(newlinesBefore) |
79 | { |
80 | } |
81 | (QStringView c, int newlinesBefore = 1) : m_comment(c), m_newlinesBefore(newlinesBefore) |
82 | { |
83 | } |
84 | |
85 | bool (DomItem &self, DirectVisitor visitor); |
86 | int () const { return m_newlinesBefore; } |
87 | void (int n) { m_newlinesBefore = n; } |
88 | QStringView () const { return m_comment; } |
89 | CommentInfo () const { return CommentInfo(m_comment); } |
90 | void (OutWriter &lw, SourceLocation * = nullptr) const; |
91 | |
92 | friend bool (const Comment &c1, const Comment &c2) |
93 | { |
94 | return c1.m_newlinesBefore == c2.m_newlinesBefore && c1.m_comment == c2.m_comment; |
95 | } |
96 | friend bool (const Comment &c1, const Comment &c2) { return !(c1 == c2); } |
97 | |
98 | private: |
99 | QString ; |
100 | QStringView ; |
101 | int ; |
102 | }; |
103 | |
104 | class QMLDOM_EXPORT |
105 | { |
106 | public: |
107 | constexpr static DomType = DomType::CommentedElement; |
108 | DomType () const { return kindValue; } |
109 | |
110 | bool (DomItem &self, DirectVisitor visitor); |
111 | void (OutWriter &lw, QList<SourceLocation> *locations = nullptr) const; |
112 | void (OutWriter &lw, QList<SourceLocation> *locations = nullptr) const; |
113 | QMultiMap<quint32, const QList<Comment> *> (SourceLocation elLocation) const; |
114 | |
115 | friend bool (const CommentedElement &c1, const CommentedElement &c2) |
116 | { |
117 | return c1.preComments == c2.preComments && c1.postComments == c2.postComments; |
118 | } |
119 | friend bool (const CommentedElement &c1, const CommentedElement &c2) |
120 | { |
121 | return !(c1 == c2); |
122 | } |
123 | |
124 | QList<Comment> ; |
125 | QList<Comment> ; |
126 | }; |
127 | |
128 | class QMLDOM_EXPORT |
129 | { |
130 | public: |
131 | constexpr static DomType = DomType::RegionComments; |
132 | DomType () const { return kindValue; } |
133 | |
134 | bool (DomItem &self, DirectVisitor visitor); |
135 | |
136 | friend bool (const RegionComments &c1, const RegionComments &c2) |
137 | { |
138 | return c1.regionComments == c2.regionComments; |
139 | } |
140 | friend bool (const RegionComments &c1, const RegionComments &c2) |
141 | { |
142 | return !(c1 == c2); |
143 | } |
144 | |
145 | Path (const Comment &, QString regionName) |
146 | { |
147 | auto &preList = regionComments[regionName].preComments; |
148 | index_type idx = preList.size(); |
149 | preList.append(t: comment); |
150 | return Path::Field(s: Fields::regionComments) |
151 | .key(name: regionName) |
152 | .field(name: Fields::preComments) |
153 | .index(i: idx); |
154 | } |
155 | |
156 | Path (const Comment &, QString regionName) |
157 | { |
158 | auto &postList = regionComments[regionName].postComments; |
159 | index_type idx = postList.size(); |
160 | postList.append(t: comment); |
161 | return Path::Field(s: Fields::regionComments) |
162 | .key(name: regionName) |
163 | .field(name: Fields::postComments) |
164 | .index(i: idx); |
165 | } |
166 | |
167 | QMap<QString, CommentedElement> ; |
168 | }; |
169 | |
170 | class QMLDOM_EXPORT final : public OwningItem |
171 | { |
172 | protected: |
173 | std::shared_ptr<OwningItem> (DomItem &) const override |
174 | { |
175 | return std::make_shared<AstComments>(args: *this); |
176 | } |
177 | |
178 | public: |
179 | constexpr static DomType = DomType::AstComments; |
180 | DomType () const override { return kindValue; } |
181 | bool (DomItem &self, DirectVisitor) override; |
182 | std::shared_ptr<AstComments> (DomItem &self) const |
183 | { |
184 | return std::static_pointer_cast<AstComments>(r: doCopy(self)); |
185 | } |
186 | |
187 | Path (DomItem &self) const override { return self.m_ownerPath; } |
188 | static void (MutableDomItem &item); |
189 | static void (std::shared_ptr<Engine> engine, AST::Node *n, |
190 | std::shared_ptr<AstComments> , |
191 | MutableDomItem rootItem, FileLocations::Tree rootItemLocations); |
192 | (std::shared_ptr<Engine> e) : m_engine(e) { } |
193 | (const AstComments &o) |
194 | : OwningItem(o), m_engine(o.m_engine), m_commentedElements(o.m_commentedElements) |
195 | { |
196 | } |
197 | |
198 | const QHash<AST::Node *, CommentedElement> &() const |
199 | { |
200 | return m_commentedElements; |
201 | } |
202 | CommentedElement *(AST::Node *n) |
203 | { |
204 | if (m_commentedElements.contains(key: n)) |
205 | return &(m_commentedElements[n]); |
206 | return nullptr; |
207 | } |
208 | QMultiMap<quint32, const QList<Comment> *> (AST::Node *n); |
209 | |
210 | private: |
211 | std::shared_ptr<Engine> ; |
212 | QHash<AST::Node *, CommentedElement> ; |
213 | }; |
214 | |
215 | class VisitAll : public AST::Visitor |
216 | { |
217 | public: |
218 | VisitAll() = default; |
219 | |
220 | static QSet<int> uiKinds(); |
221 | |
222 | void throwRecursionDepthError() override { } |
223 | |
224 | bool visit(AST::UiPublicMember *el) override |
225 | { |
226 | AST::Node::accept(node: el->annotations, visitor: this); |
227 | AST::Node::accept(node: el->memberType, visitor: this); |
228 | return true; |
229 | } |
230 | |
231 | bool visit(AST::UiSourceElement *el) override |
232 | { |
233 | AST::Node::accept(node: el->annotations, visitor: this); |
234 | return true; |
235 | } |
236 | |
237 | bool visit(AST::UiObjectDefinition *el) override |
238 | { |
239 | AST::Node::accept(node: el->annotations, visitor: this); |
240 | return true; |
241 | } |
242 | |
243 | bool visit(AST::UiObjectBinding *el) override |
244 | { |
245 | AST::Node::accept(node: el->annotations, visitor: this); |
246 | return true; |
247 | } |
248 | |
249 | bool visit(AST::UiScriptBinding *el) override |
250 | { |
251 | AST::Node::accept(node: el->annotations, visitor: this); |
252 | return true; |
253 | } |
254 | |
255 | bool visit(AST::UiArrayBinding *el) override |
256 | { |
257 | AST::Node::accept(node: el->annotations, visitor: this); |
258 | return true; |
259 | } |
260 | |
261 | bool visit(AST::UiParameterList *el) override |
262 | { |
263 | AST::Node::accept(node: el->type, visitor: this); |
264 | return true; |
265 | } |
266 | |
267 | bool visit(AST::UiQualifiedId *el) override |
268 | { |
269 | AST::Node::accept(node: el->next, visitor: this); |
270 | return true; |
271 | } |
272 | |
273 | bool visit(AST::UiEnumDeclaration *el) override |
274 | { |
275 | AST::Node::accept(node: el->annotations, visitor: this); |
276 | return true; |
277 | } |
278 | |
279 | bool visit(AST::UiInlineComponent *el) override |
280 | { |
281 | AST::Node::accept(node: el->annotations, visitor: this); |
282 | return true; |
283 | } |
284 | |
285 | void endVisit(AST::UiImport *el) override { AST::Node::accept(node: el->version, visitor: this); } |
286 | void endVisit(AST::UiPublicMember *el) override { AST::Node::accept(node: el->parameters, visitor: this); } |
287 | |
288 | void endVisit(AST::UiParameterList *el) override |
289 | { |
290 | AST::Node::accept(node: el->next, visitor: this); // put other args at the same level as this one... |
291 | } |
292 | |
293 | void endVisit(AST::UiEnumMemberList *el) override |
294 | { |
295 | AST::Node::accept(node: el->next, |
296 | visitor: this); // put other enum members at the same level as this one... |
297 | } |
298 | |
299 | bool visit(AST::TemplateLiteral *el) override |
300 | { |
301 | AST::Node::accept(node: el->expression, visitor: this); |
302 | return true; |
303 | } |
304 | |
305 | void endVisit(AST::Elision *el) override |
306 | { |
307 | AST::Node::accept(node: el->next, visitor: this); // emit other elisions at the same level |
308 | } |
309 | }; |
310 | } // namespace Dom |
311 | } // namespace QQmlJS |
312 | QT_END_NAMESPACE |
313 | |
314 | #endif // QQMLDOMCOMMENTS_P_H |
315 | |