Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qqmldomscriptelements.cpp
Go to the documentation of this file.
1
// Copyright (C) 2023 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant
4
5
#
include
"qqmldom_utils_p.h"
6
#
include
"qqmldomitem_p.h"
7
#
include
"qqmldompath_p.h"
8
#
include
"qqmldomscriptelements_p.h"
9
#
include
<
memory
>
10
#
include
<
utility
>
11
#
include
<
variant
>
12
13
using
namespace
QQmlJS::Dom::ScriptElements;
14
using
QQmlJS
::
Dom
::DomType;
15
using
QQmlJS
::
Dom
::ScriptElement;
16
using
QQmlJS
::
Dom
::ScriptElementVariant;
17
18
/*!
19
\internal
20
\class ScriptElementBase
21
22
The base class for all script elements.
23
24
Derived classes should implement createFileLocations, DomElement::updatePathFromOwner and
25
DomBase::iterateDirectSubpaths. Furthermore, they need their own DomType enum.
26
27
updatePathFromOwner and createFileLocations should be called on the script element root node
28
after it was constructed for the DomItem-wrapping to work correctly. Without it, methods like
29
iterateDirectSubpaths and all the stuff in DomItem will not work.
30
31
createFileLocations does not work without having the pathFromOwner set
32
first via updatePathFromOwner.
33
34
In derived classes, the updatePathFromOwner-implementation should call the base implementation
35
and also call recursively updatePathFromOwner on the derived class's children.
36
37
See \l ScriptElementBase::createFileLocations for the createFileLocations implementation in
38
derived classes.
39
40
Derived classes need to implement iterateDirectSubpaths to comply with the DomItem interface.
41
*/
42
43
/*!
44
\internal
45
\fn ScriptElementBase::createFileLocations
46
47
Usually, all the visits/recursive calls to DOM elements can be done using the DomItem interface,
48
once all the DOM has been constructed.
49
50
During construction, createFileLocations can be used to annotate the DOM representation with the
51
corresponding source locations, which are needed, e.g., to find the corresponding DOM element
52
from a certain text position. When called, createFileLocations sets an entry for itself in the
53
FileLocationsTree.
54
55
Derived classes should call the base implemenatation and recursively call createFileLocations on
56
all their children.
57
58
Usually, only the root of the script DOM element requires one createFileLocations call after
59
construction \b{and} after a pathFromOwner was set using updatePathFromOwner.
60
61
*/
62
63
/*!
64
\internal
65
\class ScriptList
66
67
A Helper class for writing script elements that contain lists, helps for implementing the
68
recursive calls of iterateDirectSubpaths, updatePathFromOwner and createFileLocations.
69
*/
70
71
/*!
72
\internal
73
Helper for fields with elements in iterateDirectSubpaths.
74
*/
75
static
bool
wrap
(
const
QQmlJS
::
Dom
::
DomItem
&self, QQmlJS::Dom::DirectVisitor visitor, QStringView field,
76
const
ScriptElementVariant
&value)
77
{
78
if
(!value)
79
return
true
;
80
81
const
bool
b = visitor(
82
QQmlJS
::
Dom
::
PathEls
::Field(field), [&self, field, &value]() ->
QQmlJS
::
Dom
::
DomItem
{
83
const
QQmlJS
::
Dom
::
Path
pathFromOwner{ self
.
pathFromOwner
(
)
.withField(field) };
84
return
self
.
subScriptElementWrapperItem
(
value
)
;
85
});
86
return
b;
87
}
88
89
/*!
90
\internal
91
Helper for fields with lists in iterateDirectSubpaths.
92
*/
93
static
bool
wrap
(
const
QQmlJS
::
Dom
::
DomItem
&self, QQmlJS::Dom::DirectVisitor visitor, QStringView field,
94
const
ScriptList &value)
95
{
96
const
bool
b = visitor(
97
QQmlJS
::
Dom
::
PathEls
::Field(field), [&self, field, &value]() ->
QQmlJS
::
Dom
::
DomItem
{
98
const
QQmlJS
::
Dom
::
Path
pathFromOwner{ self
.
pathFromOwner
(
)
.withField(field) };
99
return
self
.
subListItem
(
value.asList(pathFromOwner)
)
;
100
});
101
return
b;
102
}
103
104
bool
GenericScriptElement::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
105
{
106
bool
cont =
true
;
107
for
(
auto
it = m_children.begin(); it != m_children.end(); ++it) {
108
cont &= std::visit(
109
[&self, &visitor, &it](
auto
&&e) {
return
wrap(self, visitor, it->first, e); },
110
it->second);
111
}
112
for
(
auto
it = m_values.begin(); it != m_values.end(); ++it) {
113
cont &= self.invokeVisitorOnValue(visitor, PathEls::Field(it->first), it->second);
114
}
115
return
cont;
116
}
117
118
void
GenericScriptElement::updatePathFromOwner(
const
Path &p)
119
{
120
BaseT::updatePathFromOwner(p);
121
for
(
auto
it = m_children.begin(); it != m_children.end(); ++it) {
122
std::visit(qOverloadedVisitor{ [&p, &it](ScriptElementVariant &e) {
123
e.base()->updatePathFromOwner(p.withField(it->first));
124
},
125
[&p, &it](ScriptList &list) {
126
list.updatePathFromOwner(p.withField(it->first));
127
} },
128
it->second);
129
}
130
}
131
132
void
GenericScriptElement::createFileLocations(
const
FileLocations::Tree &base)
133
{
134
BaseT::createFileLocations(base);
135
for
(
auto
it = m_children.begin(); it != m_children.end(); ++it) {
136
std::visit(
137
qOverloadedVisitor{
138
[&base](ScriptElementVariant &e) { e.base()->createFileLocations(base); },
139
[&base](ScriptList &list) { list.createFileLocations(base); } },
140
it->second);
141
}
142
}
143
144
bool
BlockStatement::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
145
{
146
// TODO: test me
147
bool
cont =
true
;
148
cont &= wrap(self, visitor, Fields::statements, m_statements);
149
return
cont;
150
}
151
152
void
BlockStatement::updatePathFromOwner(
const
Path &p)
153
{
154
BaseT::updatePathFromOwner(p);
155
m_statements.updatePathFromOwner(p.withField(Fields::statements));
156
}
157
158
void
BlockStatement::createFileLocations(
const
FileLocations::Tree &base)
159
{
160
BaseT::createFileLocations(base);
161
m_statements.createFileLocations(base);
162
}
163
164
bool
IdentifierExpression::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
165
{
166
bool
cont =
true
;
167
cont &= self.invokeVisitorOnValue(visitor, PathEls::Field(Fields::identifier), m_name);
168
return
cont;
169
}
170
171
bool
Literal::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
172
{
173
bool
cont =
true
;
174
std::visit(
175
[&cont, &visitor, &self](
auto
&&e) {
176
cont &= self.invokeVisitorOnValue(visitor, PathEls::Field(Fields::value), e);
177
},
178
m_value);
179
return
cont;
180
}
181
182
bool
IfStatement::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
183
{
184
// TODO: test me
185
bool
cont =
true
;
186
cont &= wrap(self, visitor, Fields::condition, m_condition);
187
cont &= wrap(self, visitor, Fields::consequence, m_consequence);
188
cont &= wrap(self, visitor, Fields::alternative, m_alternative);
189
return
cont;
190
}
191
192
void
IfStatement::updatePathFromOwner(
const
Path &p)
193
{
194
BaseT::updatePathFromOwner(p);
195
if
(
auto
ptr = m_condition.base())
196
ptr->updatePathFromOwner(p.withField(Fields::condition));
197
if
(
auto
ptr = m_consequence.base())
198
ptr->updatePathFromOwner(p.withField(Fields::consequence));
199
if
(
auto
ptr = m_alternative.base())
200
ptr->updatePathFromOwner(p.withField(Fields::alternative));
201
}
202
203
void
IfStatement::createFileLocations(
const
FileLocations::Tree &base)
204
{
205
BaseT::createFileLocations(base);
206
if
(
auto
ptr = m_condition.base())
207
ptr->createFileLocations(base);
208
if
(
auto
ptr = m_consequence.base())
209
ptr->createFileLocations(base);
210
if
(
auto
ptr = m_alternative.base())
211
ptr->createFileLocations(base);
212
}
213
214
bool
ForStatement::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
215
{
216
bool
cont =
true
;
217
cont &= wrap(self, visitor, Fields::initializer, m_initializer);
218
cont &= wrap(self, visitor, Fields::declarations, m_declarations);
219
cont &= wrap(self, visitor, Fields::condition, m_condition);
220
cont &= wrap(self, visitor, Fields::expression, m_expression);
221
cont &= wrap(self, visitor, Fields::body, m_body);
222
return
cont;
223
}
224
225
void
ForStatement::updatePathFromOwner(
const
Path &p)
226
{
227
BaseT::updatePathFromOwner(p);
228
if
(
auto
ptr = m_initializer.base())
229
ptr->updatePathFromOwner(p.withField(Fields::initializer));
230
if
(
auto
ptr = m_declarations.base())
231
ptr->updatePathFromOwner(p.withField(Fields::declarations));
232
if
(
auto
ptr = m_condition.base())
233
ptr->updatePathFromOwner(p.withField(Fields::condition));
234
if
(
auto
ptr = m_expression.base())
235
ptr->updatePathFromOwner(p.withField(Fields::expression));
236
if
(
auto
ptr = m_body.base())
237
ptr->updatePathFromOwner(p.withField(Fields::body));
238
}
239
240
void
ForStatement::createFileLocations(
const
FileLocations::Tree &base)
241
{
242
BaseT::createFileLocations(base);
243
if
(
auto
ptr = m_initializer.base())
244
ptr->createFileLocations(base);
245
if
(
auto
ptr = m_declarations.base())
246
ptr->createFileLocations(base);
247
if
(
auto
ptr = m_condition.base())
248
ptr->createFileLocations(base);
249
if
(
auto
ptr = m_expression.base())
250
ptr->createFileLocations(base);
251
if
(
auto
ptr = m_body.base())
252
ptr->createFileLocations(base);
253
}
254
255
bool
BinaryExpression::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
256
{
257
bool
cont =
true
;
258
cont &= wrap(self, visitor, Fields::left, m_left);
259
cont &= self.invokeVisitorOnValue(visitor, PathEls::Field(Fields::operation), m_operator);
260
cont &= wrap(self, visitor, Fields::right, m_right);
261
return
cont;
262
}
263
264
void
BinaryExpression::updatePathFromOwner(
const
Path &p)
265
{
266
BaseT::updatePathFromOwner(p);
267
if
(
auto
ptr = m_left.base())
268
ptr->updatePathFromOwner(p.withField(Fields::left));
269
if
(
auto
ptr = m_right.base())
270
ptr->updatePathFromOwner(p.withField(Fields::right));
271
}
272
273
void
BinaryExpression::createFileLocations(
const
FileLocations::Tree &base)
274
{
275
BaseT::createFileLocations(base);
276
if
(
auto
ptr = m_left.base())
277
ptr->createFileLocations(base);
278
if
(
auto
ptr = m_right.base())
279
ptr->createFileLocations(base);
280
}
281
282
bool
VariableDeclarationEntry::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
283
{
284
bool
cont =
true
;
285
cont &= self.invokeVisitorOnValue(visitor, PathEls::Field(Fields::scopeType), m_scopeType);
286
cont &= wrap(self, visitor, Fields::identifier, m_identifier);
287
cont &= wrap(self, visitor, Fields::initializer, m_initializer);
288
return
cont;
289
}
290
291
void
VariableDeclarationEntry::updatePathFromOwner(
const
Path &p)
292
{
293
BaseT::updatePathFromOwner(p);
294
if
(
auto
ptr = m_identifier.base())
295
ptr->updatePathFromOwner(p.withField(Fields::identifier));
296
if
(
auto
ptr = m_initializer.base())
297
ptr->updatePathFromOwner(p.withField(Fields::initializer));
298
}
299
300
void
VariableDeclarationEntry::createFileLocations(
const
FileLocations::Tree &base)
301
{
302
BaseT::createFileLocations(base);
303
if
(
auto
ptr = m_identifier.base())
304
ptr->createFileLocations(base);
305
if
(
auto
ptr = m_initializer.base())
306
ptr->createFileLocations(base);
307
}
308
309
bool
VariableDeclaration::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
310
{
311
bool
cont =
true
;
312
cont &= wrap(self, visitor, Fields::declarations, m_declarations);
313
return
cont;
314
}
315
316
void
VariableDeclaration::updatePathFromOwner(
const
Path &p)
317
{
318
BaseT::updatePathFromOwner(p);
319
m_declarations.updatePathFromOwner(p.withField(Fields::declarations));
320
}
321
322
void
VariableDeclaration::createFileLocations(
const
FileLocations::Tree &base)
323
{
324
BaseT::createFileLocations(base);
325
m_declarations.createFileLocations(base);
326
}
327
328
bool
ReturnStatement::iterateDirectSubpaths(
const
DomItem &self, DirectVisitor visitor)
const
329
{
330
bool
cont =
true
;
331
cont &= wrap(self, visitor, Fields::expression, m_expression);
332
return
cont;
333
}
334
335
void
ReturnStatement::updatePathFromOwner(
const
Path &p)
336
{
337
BaseT::updatePathFromOwner(p);
338
if
(
auto
ptr = m_expression.base())
339
ptr->updatePathFromOwner(p.withField(Fields::expression));
340
}
341
342
void
ReturnStatement::createFileLocations(
const
FileLocations::Tree &base)
343
{
344
BaseT::createFileLocations(base);
345
if
(
auto
ptr = m_expression.base())
346
ptr->createFileLocations(base);
347
}
348
349
void
ScriptList::replaceKindForGenericChildren(DomType oldType, DomType newType)
350
{
351
for
(
auto
&it : m_list) {
352
if
(
auto
current = it.data()) {
353
if
(
auto
genericElement =
354
std::get_if<std::shared_ptr<ScriptElements::GenericScriptElement>>(
355
&*current)) {
356
if
((*genericElement)->kind() == oldType)
357
(*genericElement)->setKind(newType);
358
}
359
}
360
}
361
}
QQmlJS::Dom::DomItem
A value type that references any element of the Dom.
Definition
qqmldomitem_p.h:851
QQmlJS::Dom::DomItem::subListItem
DomItem subListItem(const List &list) const
Definition
qqmldomitem_p.h:2167
QQmlJS::Dom::DomItem::pathFromOwner
Path pathFromOwner() const
Definition
qqmldomitem.cpp:1949
QQmlJS::Dom::DomItem::subScriptElementWrapperItem
DomItem subScriptElementWrapperItem(const ScriptElementVariant &obj) const
Definition
qqmldomitem_p.h:1104
QQmlJS::Dom::Path
Definition
qqmldompath_p.h:582
QQmlJS::Dom::ScriptElementVariant
Use this to contain any script element.
Definition
qqmldomitem_p.h:708
QQmlJS::Dom::PathEls
Definition
qqmldompath_p.h:47
QQmlJS::Dom
Definition
qqmljsimportvisitor_p.h:38
QQmlJS
Definition
qv4bytecodegenerator_p.h:27
wrap
static bool wrap(const QQmlJS::Dom::DomItem &self, QQmlJS::Dom::DirectVisitor visitor, QStringView field, const ScriptList &value)
Definition
qqmldomscriptelements.cpp:93
wrap
static bool wrap(const QQmlJS::Dom::DomItem &self, QQmlJS::Dom::DirectVisitor visitor, QStringView field, const ScriptElementVariant &value)
Definition
qqmldomscriptelements.cpp:75
qtdeclarative
src
qmldom
qqmldomscriptelements.cpp
Generated on
for Qt by
1.18.0