Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmljsast.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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 <QString>
6#include <QLocale>
7#include "common/qqmljssourcelocation_p.h"
8#include "qqmljsast_p.h"
9
11#include <qlocale.h>
12
13#include <algorithm>
14#include <array>
15
16QT_BEGIN_NAMESPACE
17
18namespace QQmlJS { namespace AST {
19
20FunctionExpression *asAnonymousFunctionDefinition(Node *n)
21{
22 if (!n)
23 return nullptr;
24 FunctionExpression *f = n->asFunctionDefinition();
25 if (!f || !f->name.isNull())
26 return nullptr;
27 return f;
28}
29
30ClassExpression *asAnonymousClassDefinition(Node *n)
31{
32 if (!n)
33 return nullptr;
34 ClassExpression *c = n->asClassDefinition();
35 if (!c || !c->name.isNull())
36 return nullptr;
37 return c;
38}
39
41{
42 return nullptr;
43}
44
46{
47 return nullptr;
48}
49
51{
52 return nullptr;
53}
54
56{
57 return nullptr;
58}
59
64
66{
67 return nullptr;
68}
69
71{
72 return nullptr;
73}
74
76{
77 return nullptr;
78}
79
81{
82 static const bool doIgnore = qEnvironmentVariableIsSet("QV4_CRASH_ON_STACKOVERFLOW");
83 return doIgnore;
84}
85
87{
88 return this;
89}
90
92{
93 for (const Node *node = this;;) {
94 switch (node->kind) {
96 const auto *fme = AST::cast<const FieldMemberExpression*>(node);
97 if (fme->isOptional)
98 return true;
99 node = fme->base;
100 break;
101 }
103 const auto *ame = AST::cast<const ArrayMemberExpression*>(node);
104 if (ame->isOptional)
105 return true;
106 node = ame->base;
107 break;
108 }
109 case Kind_CallExpression: {
110 const auto *ce = AST::cast<const CallExpression*>(node);
111 if (ce->isOptional)
112 return true;
113 node = ce->base;
114 break;
115 }
117 const auto *ne = AST::cast<const NestedExpression*>(node);
118 node = ne->expression;
119 break;
120 }
121 default:
122 // These unhandled nodes lead to invalid lvalues anyway, so they do not need to be handled here.
123 return false;
124 }
125 }
126 return false;
127}
128
130{
131 AST::ExpressionNode *expr = this;
132 AST::FormalParameterList *f = nullptr;
135 if (!f)
136 return nullptr;
137
140 }
141
142 AST::ExpressionNode *rhs = nullptr;
144 if (assign->op != QSOperator::Assign)
145 return nullptr;
146 expr = assign->left;
147 rhs = assign->right;
148 }
149 AST::PatternElement *binding = nullptr;
151 binding = new (pool) AST::PatternElement(idExpr->name, /*type annotation*/nullptr, rhs);
153 } else if (AST::Pattern *p = expr->patternCast()) {
155 QString s;
157 return nullptr;
158 binding = new (pool) AST::PatternElement(p, rhs);
160 }
161 if (!binding)
162 return nullptr;
163
164 return new (pool) AST::FormalParameterList(f, binding);
165}
166
171
173{
174 visitor->visit(this);
175 visitor->endVisit(this);
176}
177
179{
180 return this;
181}
182
184{
185 return this;
186}
187
189{
190 if (visitor->visit(this)) {
192 }
193 visitor->endVisit(this);
194}
195
200
205
207{
208 if (visitor->visit(this)) {
209 }
210
211 visitor->endVisit(this);
212}
213
215{
216 if (visitor->visit(this)) {
217 }
218
219 visitor->endVisit(this);
220}
221
223{
224 if (visitor->visit(this)) {
225 }
226
227 visitor->endVisit(this);
228}
229
231{
232 if (visitor->visit(this)) {
233 }
234
235 visitor->endVisit(this);
236}
237
239{
240 if (visitor->visit(this)) {
241 }
242
243 visitor->endVisit(this);
244}
245
247{
248 if (visitor->visit(this)) {
249 }
250
251 visitor->endVisit(this);
252}
253
254
256{
257 if (visitor->visit(this)) {
258 }
259
260 visitor->endVisit(this);
261}
262
264{
265 bool accepted = true;
266 for (TemplateLiteral *it = this; it && accepted; it = it->next) {
269 }
270}
271
273{
274 if (visitor->visit(this)) {
275 }
276
277 visitor->endVisit(this);
278}
279
281{
282 if (visitor->visit(this)) {
283 }
284
285 visitor->endVisit(this);
286}
287
289{
290 if (visitor->visit(this))
292
293 visitor->endVisit(this);
294}
295
297 for (PatternElementList *it = elements; it != nullptr; it = it->next) {
299 if (e && e->bindingTarget != nullptr) {
300 if (errorLocation)
302 return false;
303 }
304 }
305 return true;
306}
307
309{
310 if (visitor->visit(this)) {
312 }
313
314 visitor->endVisit(this);
315}
316
317/*
318 This is the grammar for AssignmentPattern that we need to convert the literal to:
319
320 AssignmentPattern:
321 ObjectAssignmentPattern
322 ArrayAssignmentPattern
323 ArrayAssignmentPattern:
324 [ ElisionOpt AssignmentRestElementOpt ]
325 [ AssignmentElementList ]
326 [ AssignmentElementList , ElisionOpt AssignmentRestElementOpt ]
327 AssignmentElementList:
328 AssignmentElisionElement
329 AssignmentElementList , AssignmentElisionElement
330 AssignmentElisionElement:
331 ElisionOpt AssignmentElement
332 AssignmentRestElement:
333 ... DestructuringAssignmentTarget
334
335 ObjectAssignmentPattern:
336 {}
337 { AssignmentPropertyList }
338 { AssignmentPropertyList, }
339 AssignmentPropertyList:
340 AssignmentProperty
341 AssignmentPropertyList , AssignmentProperty
342 AssignmentProperty:
343 IdentifierReference InitializerOpt_In
344 PropertyName:
345 AssignmentElement
346
347 AssignmentElement:
348 DestructuringAssignmentTarget InitializerOpt_In
349 DestructuringAssignmentTarget:
350 LeftHandSideExpression
351
352 It was originally parsed with the following grammar:
353
354ArrayLiteral:
355 [ ElisionOpt ]
356 [ ElementList ]
357 [ ElementList , ElisionOpt ]
358ElementList:
359 ElisionOpt AssignmentExpression_In
360 ElisionOpt SpreadElement
361 ElementList , ElisionOpt AssignmentExpression_In
362 ElementList , Elisionopt SpreadElement
363SpreadElement:
364 ... AssignmentExpression_In
365ObjectLiteral:
366 {}
367 { PropertyDefinitionList }
368 { PropertyDefinitionList , }
369PropertyDefinitionList:
370 PropertyDefinition
371 PropertyDefinitionList , PropertyDefinition
372PropertyDefinition:
373 IdentifierReference
374 CoverInitializedName
375 PropertyName : AssignmentExpression_In
376 MethodDefinition
377PropertyName:
378 LiteralPropertyName
379 ComputedPropertyName
380
381*/
383{
384 if (parseMode == Binding)
385 return true;
386 for (auto *it = elements; it; it = it->next) {
387 if (!it->element)
388 continue;
391 *errorMessage = QString::fromLatin1("'...' can only appear as last element in a destructuring list.");
392 return false;
393 }
395 return false;
396 }
398 return true;
399}
400
402{
403 if (parseMode == Binding)
404 return true;
405 for (auto *it = properties; it; it = it->next) {
407 return false;
408 }
410 return true;
411}
412
414{
417 Q_ASSERT(bindingTarget == nullptr);
418 Q_ASSERT(bindingTarget == nullptr);
421
422 initializer = nullptr;
424 if (type == SpreadElement) {
425 if (!lhs) {
427 *errorMessage = QString::fromLatin1("Invalid lhs expression after '...' in destructuring expression.");
428 return false;
429 }
430 } else {
432
434 if (b->op != QSOperator::Assign) {
436 *errorMessage = QString::fromLatin1("Invalid assignment operation in destructuring expression");
437 return false;
438 }
441 Q_ASSERT(lhs);
442 } else {
444 }
445 if (!lhs) {
447 *errorMessage = QString::fromLatin1("Destructuring target is not a left hand side expression.");
448 return false;
449 }
450 }
451
452 if (auto *i = cast<IdentifierExpression *>(lhs)) {
455 return true;
456 }
457
459 if (auto *p = lhs->patternCast()) {
461 return false;
462 }
463 return true;
464}
465
467{
469 if (type == Binding)
470 return true;
471 if (type == Getter || type == Setter) {
473 *errorMessage = QString::fromLatin1("Invalid getter/setter in destructuring expression.");
474 return false;
475 }
476 if (type == Method)
477 type = Literal;
480}
481
482
484{
485 if (visitor->visit(this)) {
486 // ###
487 }
488
489 visitor->endVisit(this);
490}
491
493{
494 if (visitor->visit(this)) {
495 }
496
497 visitor->endVisit(this);
498}
499
501{
502 if (visitor->visit(this)) {
503 }
504
505 visitor->endVisit(this);
506}
507
509{
510 if (visitor->visit(this)) {
511 }
512
513 visitor->endVisit(this);
514}
515
516namespace {
517struct LocaleWithoutZeroPadding : public QLocale
518{
519 LocaleWithoutZeroPadding()
520 : QLocale(QLocale::C)
521 {
522 setNumberOptions(QLocale::OmitLeadingZeroInExponent | QLocale::OmitGroupSeparator);
523 }
524};
525}
526
528{
529 // Can't use QString::number here anymore as it does zero padding by default now.
530
531 // In C++11 this initialization is thread-safe (6.7 [stmt.dcl] p4)
533 // Because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 we can't use thread_local
534 // for the locale variable and therefore rely on toString(double) to be thread-safe.
535 return locale.toString(id, 'g', 16);
536}
537
539{
540 if (visitor->visit(this)) {
543 }
544
545 visitor->endVisit(this);
546}
547
549{
550 if (visitor->visit(this)) {
552 }
553
554 visitor->endVisit(this);
555}
556
558{
559 if (visitor->visit(this)) {
562 }
563
564 visitor->endVisit(this);
565}
566
568{
569 if (visitor->visit(this)) {
571 }
572
573 visitor->endVisit(this);
574}
575
577{
578 if (visitor->visit(this)) {
581 }
582
583 visitor->endVisit(this);
584}
585
587{
588 if (visitor->visit(this)) {
589 for (ArgumentList *it = this; it; it = it->next) {
591 }
592 }
593
594 visitor->endVisit(this);
595}
596
598{
599 if (visitor->visit(this)) {
601 }
602
603 visitor->endVisit(this);
604}
605
607{
608 if (visitor->visit(this)) {
610 }
611
612 visitor->endVisit(this);
613}
614
616{
617 if (visitor->visit(this)) {
619 }
620
621 visitor->endVisit(this);
622}
623
625{
626 if (visitor->visit(this)) {
628 }
629
630 visitor->endVisit(this);
631}
632
634{
635 if (visitor->visit(this)) {
637 }
638
639 visitor->endVisit(this);
640}
641
643{
644 if (visitor->visit(this)) {
646 }
647
648 visitor->endVisit(this);
649}
650
652{
653 if (visitor->visit(this)) {
655 }
656
657 visitor->endVisit(this);
658}
659
661{
662 if (visitor->visit(this)) {
664 }
665
666 visitor->endVisit(this);
667}
668
670{
671 if (visitor->visit(this)) {
673 }
674
675 visitor->endVisit(this);
676}
677
679{
680 if (visitor->visit(this)) {
682 }
683
684 visitor->endVisit(this);
685}
686
688{
689 if (visitor->visit(this)) {
691 }
692
693 visitor->endVisit(this);
694}
695
697{
698 if (visitor->visit(this)) {
701 }
702
703 visitor->endVisit(this);
704}
705
707{
708 if (visitor->visit(this)) {
710 accept(ok, visitor);
711 accept(ko, visitor);
712 }
713
714 visitor->endVisit(this);
715}
716
718{
719 if (visitor->visit(this)) {
722 }
723
724 visitor->endVisit(this);
725}
726
728{
729 if (visitor->visit(this)) {
731 }
732
733 visitor->endVisit(this);
734}
735
737{
738 if (visitor->visit(this)) {
739 for (StatementList *it = this; it; it = it->next) {
741 }
742 }
743
744 visitor->endVisit(this);
745}
746
748{
749 if (visitor->visit(this)) {
751 }
752
753 visitor->endVisit(this);
754}
755
757{
758 if (visitor->visit(this)) {
759 for (VariableDeclarationList *it = this; it; it = it->next) {
761 }
762 }
763
764 visitor->endVisit(this);
765}
766
768{
769 if (visitor->visit(this)) {
770 }
771
772 visitor->endVisit(this);
773}
774
776{
777 if (visitor->visit(this)) {
779 }
780
781 visitor->endVisit(this);
782}
783
785{
786 if (visitor->visit(this)) {
788 accept(ok, visitor);
789 accept(ko, visitor);
790 }
791
792 visitor->endVisit(this);
793}
794
796{
797 if (visitor->visit(this)) {
800 }
801
802 visitor->endVisit(this);
803}
804
806{
807 if (visitor->visit(this)) {
810 }
811
812 visitor->endVisit(this);
813}
814
827
829{
830 if (visitor->visit(this)) {
834 }
835
836 visitor->endVisit(this);
837}
838
840{
841 if (visitor->visit(this)) {
842 }
843
844 visitor->endVisit(this);
845}
846
848{
849 if (visitor->visit(this)) {
850 }
851
852 visitor->endVisit(this);
853}
854
856{
857 if (visitor->visit(this)) {
859 }
860
861 visitor->endVisit(this);
862}
863
865{
866 if (visitor->visit(this)) {
868 }
869
870 visitor->endVisit(this);
871}
872
873
875{
876 if (visitor->visit(this)) {
879 }
880
881 visitor->endVisit(this);
882}
883
885{
886 if (visitor->visit(this)) {
889 }
890
891 visitor->endVisit(this);
892}
893
895{
896 if (visitor->visit(this)) {
900 }
901
902 visitor->endVisit(this);
903}
904
906{
907 if (visitor->visit(this)) {
908 for (CaseClauses *it = this; it; it = it->next) {
910 }
911 }
912
913 visitor->endVisit(this);
914}
915
917{
918 if (visitor->visit(this)) {
921 }
922
923 visitor->endVisit(this);
924}
925
927{
928 if (visitor->visit(this)) {
930 }
931
932 visitor->endVisit(this);
933}
934
936{
937 if (visitor->visit(this)) {
939 }
940
941 visitor->endVisit(this);
942}
943
945{
946 if (visitor->visit(this)) {
948 }
949
950 visitor->endVisit(this);
951}
952
963
965{
966 if (visitor->visit(this)) {
969 }
970
971 visitor->endVisit(this);
972}
973
975{
976 if (visitor->visit(this)) {
978 }
979
980 visitor->endVisit(this);
981}
982
984{
985 if (visitor->visit(this)) {
989 }
990
991 visitor->endVisit(this);
992}
993
995{
996 if (visitor->visit(this)) {
1000 }
1001
1002 visitor->endVisit(this);
1003}
1004
1009
1011{
1013 int i = 0;
1014 for (const FormalParameterList *it = this; it; it = it->next) {
1015 if (it->element) {
1018 if (duplicateIndex >= 0) {
1019 // change the name of the earlier argument to enforce the lookup semantics from the spec
1021 }
1024 : BoundName::Declared };
1025 }
1026 ++i;
1027 }
1028 return formals;
1029}
1030
1032{
1034 for (const FormalParameterList *it = this; it; it = it->next) {
1035 if (it->element)
1037 }
1038 return names;
1039}
1040
1042{
1043 bool accepted = true;
1044 for (FormalParameterList *it = this; it && accepted; it = it->next) {
1046 if (accepted)
1049 }
1050}
1051
1058
1060{
1061 if (visitor->visit(this)) {
1063 }
1064
1065 visitor->endVisit(this);
1066}
1067
1069{
1070 if (visitor->visit(this)) {
1071
1072 }
1073 visitor->endVisit(this);
1074}
1075
1077{
1078 if (visitor->visit(this)) {
1079 for (ImportsList *it = this; it; it = it->next) {
1081 }
1082 }
1083
1084 visitor->endVisit(this);
1085}
1086
1088{
1089 if (visitor->visit(this)) {
1091 }
1092
1093 visitor->endVisit(this);
1094}
1095
1097{
1098 if (visitor->visit(this)) {
1099 }
1100
1101 visitor->endVisit(this);
1102}
1103
1105{
1106 if (visitor->visit(this)) {
1107 }
1108
1109 visitor->endVisit(this);
1110}
1111
1113{
1114 if (visitor->visit(this)) {
1117 }
1118
1119 visitor->endVisit(this);
1120}
1121
1123{
1124 if (visitor->visit(this)) {
1127 }
1128
1129 visitor->endVisit(this);
1130}
1131
1133{
1134 if (visitor->visit(this)) {
1135
1136 }
1137
1138 visitor->endVisit(this);
1139}
1140
1142{
1143 if (visitor->visit(this)) {
1144 for (ExportsList *it = this; it; it = it->next) {
1146 }
1147 }
1148
1149 visitor->endVisit(this);
1150}
1151
1153{
1154 if (visitor->visit(this)) {
1156 }
1157
1158 visitor->endVisit(this);
1159}
1160
1171
1173{
1174 if (visitor->visit(this)) {
1176 }
1177
1178 visitor->endVisit(this);
1179}
1180
1182{
1183 if (visitor->visit(this)) {
1184 }
1185
1186 visitor->endVisit(this);
1187}
1188
1190{
1191 if (visitor->visit(this)) {
1194 }
1195
1196 visitor->endVisit(this);
1197}
1198
1200{
1201 if (visitor->visit(this)) {
1202 // accept(annotations, visitor); // accept manually in visit if interested
1203 // accept(memberType, visitor); // accept manually in visit if interested
1206 // accept(parameters, visitor); // accept manually in visit if interested
1207 }
1208
1209 visitor->endVisit(this);
1210}
1211
1213{
1214 if (visitor->visit(this)) {
1215 // accept(annotations, visitor); // accept manually in visit if interested
1218 }
1219
1220 visitor->endVisit(this);
1221}
1222
1224{
1225 if (visitor->visit(this)) {
1227 }
1228
1229 visitor->endVisit(this);
1230}
1231
1233{
1234 if (visitor->visit(this)) {
1235 // accept(type, visitor); // accept manually in visit if interested
1236 }
1237 visitor->endVisit(this);
1238}
1239
1241{
1242 if (visitor->visit(this)) {
1243 // accept(annotations, visitor); // accept manually in visit if interested
1247 }
1248
1249 visitor->endVisit(this);
1250}
1251
1253{
1254 if (visitor->visit(this)) {
1255 // accept(annotations, visitor); // accept manually in visit if interested
1258 }
1259
1260 visitor->endVisit(this);
1261}
1262
1264{
1265 if (visitor->visit(this)) {
1266 // accept(annotations, visitor); // accept manually in visit if interested
1269 }
1270
1271 visitor->endVisit(this);
1272}
1273
1275{
1276 if (visitor->visit(this)) {
1277 for (UiObjectMemberList *it = this; it; it = it->next)
1279 }
1280
1281 visitor->endVisit(this);
1282}
1283
1285{
1286 if (visitor->visit(this)) {
1287 for (UiArrayMemberList *it = this; it; it = it->next)
1289 }
1290
1291 visitor->endVisit(this);
1292}
1293
1295{
1296 if (visitor->visit(this)) {
1297 // accept(next, visitor) // accept manually in visit if interested
1298 }
1299
1300 visitor->endVisit(this);
1301}
1302
1304{
1305 if (visitor->visit(this)) {
1308 }
1309
1310 visitor->endVisit(this);
1311}
1312
1314{
1315 if (visitor->visit(this)) {
1317 }
1318
1319 visitor->endVisit(this);
1320}
1321
1323{
1324 if (visitor->visit(this)) {
1326 // accept(version, visitor); // accept manually in visit if interested
1327 }
1328
1329 visitor->endVisit(this);
1330}
1331
1333{
1334 if (visitor->visit(this)) {
1335 }
1336
1337 visitor->endVisit(this);
1338}
1339
1340
1342{
1343 if (visitor->visit(this)) {
1344 }
1345
1346 visitor->endVisit(this);
1347}
1348
1350{
1351 bool accepted = true;
1352 for (UiHeaderItemList *it = this; it && accepted; it = it->next) {
1354 if (accepted)
1356
1358 }
1359}
1360
1361
1363{
1364 if (visitor->visit(this)) {
1365 // accept(annotations, visitor); // accept manually in visit if interested
1367 }
1368
1369 visitor->endVisit(this);
1370}
1371
1373{
1374 if (visitor->visit(this)) {
1375 // accept(annotations, visitor); // accept manually in visit if interested
1377 }
1378
1379 visitor->endVisit(this);
1380}
1381
1383{
1384 if (visitor->visit(this)) {
1385 }
1386
1387 visitor->endVisit(this);
1388}
1389
1391{
1392 if (visitor->visit(this)) {
1395 }
1396
1397 visitor->endVisit(this);
1398}
1399
1404
1406{
1407 if (visitor->visit(this)) {
1411 }
1412
1413 visitor->endVisit(this);
1414}
1415
1428
1430{
1431 bool accepted = true;
1432 for (PatternElementList *it = this; it && accepted; it = it->next) {
1434 if (accepted) {
1437 }
1439 }
1440}
1441
1443{
1444 for (PatternElementList *it = this; it; it = it->next) {
1445 if (it->element)
1447 }
1448}
1449
1451{
1452 if (visitor->visit(this)) {
1457 }
1458
1459 visitor->endVisit(this);
1460}
1461
1466
1468{
1469 bool accepted = true;
1470 for (PatternPropertyList *it = this; it && accepted; it = it->next) {
1472 if (accepted)
1475 }
1476}
1477
1483
1485{
1486 if (visitor->visit(this)) {
1488 }
1489
1490 visitor->endVisit(this);
1491}
1492
1494{
1495 if (visitor->visit(this)) {
1498 }
1499
1500 visitor->endVisit(this);
1501}
1502
1504{
1505 return this;
1506}
1507
1509{
1510 if (visitor->visit(this)) {
1513 }
1514
1515 visitor->endVisit(this);
1516}
1517
1519{
1520 bool accepted = true;
1521 for (ClassElementList *it = this; it && accepted; it = it->next) {
1523 if (accepted)
1525
1527 }
1528}
1529
1531{
1533 next = nullptr;
1534 return front;
1535}
1536
1538{
1539 return this;
1540}
1541
1546
1548{
1549 if (visitor->visit(this)) {
1550 }
1551 visitor->endVisit(this);
1552}
1553
1555{
1557 toString(&result);
1558 return result;
1559}
1560
1562{
1564
1565 if (typeArgument) {
1566 out->append(QLatin1Char('<'));
1568 out->append(QLatin1Char('>'));
1569 };
1570}
1571
1573{
1574 if (visitor->visit(this)) {
1575 // accept(annotations, visitor); // accept manually in visit if interested
1577 }
1578
1579 visitor->endVisit(this);
1580}
1581
1583{
1584 if (visitor->visit(this)) {
1585 }
1586
1587 visitor->endVisit(this);
1588}
1589
1591{
1592 if (visitor->visit(this)) {
1593 for (UiAnnotationList *it = this; it; it = it->next)
1595 }
1596
1597 visitor->endVisit(this);
1598}
1599
1601{
1602 if (visitor->visit(this)) {
1605 }
1606
1607 visitor->endVisit(this);
1608}
1609
1616
1623
1624} } // namespace QQmlJS::AST
1625
1626QT_END_NAMESPACE
FunctionExpression * asAnonymousFunctionDefinition(Node *n)
Definition qqmljsast.cpp:20
ClassExpression * asAnonymousClassDefinition(Node *n)
Definition qqmljsast.cpp:30