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
4#include <QString>
5#include <QLocale>
6#include "qqmljsast_p.h"
7
8#include "qqmljsastvisitor_p.h"
9#include <qlocale.h>
10
11#include <algorithm>
12#include <array>
13
14QT_BEGIN_NAMESPACE
15
16namespace QQmlJS { namespace AST {
17
18FunctionExpression *asAnonymousFunctionDefinition(Node *n)
19{
20 if (!n)
21 return nullptr;
22 FunctionExpression *f = n->asFunctionDefinition();
23 if (!f || !f->name.isNull())
24 return nullptr;
25 return f;
26}
27
28ClassExpression *asAnonymousClassDefinition(Node *n)
29{
30 if (!n)
31 return nullptr;
32 ClassExpression *c = n->asClassDefinition();
33 if (!c || !c->name.isNull())
34 return nullptr;
35 return c;
36}
37
38ExpressionNode *Node::expressionCast()
39{
40 return nullptr;
41}
42
43BinaryExpression *Node::binaryExpressionCast()
44{
45 return nullptr;
46}
47
48Statement *Node::statementCast()
49{
50 return nullptr;
51}
52
53UiObjectMember *Node::uiObjectMemberCast()
54{
55 return nullptr;
56}
57
58LeftHandSideExpression *Node::leftHandSideExpressionCast()
59{
60 return nullptr;
61}
62
63Pattern *Node::patternCast()
64{
65 return nullptr;
66}
67
68FunctionExpression *Node::asFunctionDefinition()
69{
70 return nullptr;
71}
72
73ClassExpression *Node::asClassDefinition()
74{
75 return nullptr;
76}
77
78bool Node::ignoreRecursionDepth() const
79{
80 static const bool doIgnore = qEnvironmentVariableIsSet(varName: "QV4_CRASH_ON_STACKOVERFLOW");
81 return doIgnore;
82}
83
84ExpressionNode *ExpressionNode::expressionCast()
85{
86 return this;
87}
88
89bool ExpressionNode::containsOptionalChain() const
90{
91 for (const Node *node = this;;) {
92 switch (node->kind) {
93 case Kind_FieldMemberExpression: {
94 const auto *fme = AST::cast<const FieldMemberExpression*>(ast: node);
95 if (fme->isOptional)
96 return true;
97 node = fme->base;
98 break;
99 }
100 case Kind_ArrayMemberExpression: {
101 const auto *ame = AST::cast<const ArrayMemberExpression*>(ast: node);
102 if (ame->isOptional)
103 return true;
104 node = ame->base;
105 break;
106 }
107 case Kind_CallExpression: {
108 const auto *ce = AST::cast<const CallExpression*>(ast: node);
109 if (ce->isOptional)
110 return true;
111 node = ce->base;
112 break;
113 }
114 case Kind_NestedExpression: {
115 const auto *ne = AST::cast<const NestedExpression*>(ast: node);
116 node = ne->expression;
117 break;
118 }
119 default:
120 // These unhandled nodes lead to invalid lvalues anyway, so they do not need to be handled here.
121 return false;
122 }
123 }
124 return false;
125}
126
127FormalParameterList *ExpressionNode::reparseAsFormalParameterList(MemoryPool *pool)
128{
129 AST::ExpressionNode *expr = this;
130 AST::FormalParameterList *f = nullptr;
131 if (AST::Expression *commaExpr = AST::cast<AST::Expression *>(ast: expr)) {
132 f = commaExpr->left->reparseAsFormalParameterList(pool);
133 if (!f)
134 return nullptr;
135
136 expr = commaExpr->right;
137 }
138
139 AST::ExpressionNode *rhs = nullptr;
140 if (AST::BinaryExpression *assign = AST::cast<AST::BinaryExpression *>(ast: expr)) {
141 if (assign->op != QSOperator::Assign)
142 return nullptr;
143 expr = assign->left;
144 rhs = assign->right;
145 }
146 AST::PatternElement *binding = nullptr;
147 if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(ast: expr)) {
148 binding = new (pool) AST::PatternElement(idExpr->name, /*type annotation*/nullptr, rhs);
149 binding->identifierToken = idExpr->identifierToken;
150 } else if (AST::Pattern *p = expr->patternCast()) {
151 SourceLocation loc;
152 QString s;
153 if (!p->convertLiteralToAssignmentPattern(pool, errorLocation: &loc, errorMessage: &s))
154 return nullptr;
155 binding = new (pool) AST::PatternElement(p, rhs);
156 binding->identifierToken = p->firstSourceLocation();
157 }
158 if (!binding)
159 return nullptr;
160 return new (pool) AST::FormalParameterList(f, binding);
161}
162
163BinaryExpression *BinaryExpression::binaryExpressionCast()
164{
165 return this;
166}
167
168void TypeExpression::accept0(BaseVisitor *visitor)
169{
170 visitor->visit(this);
171 visitor->endVisit(this);
172}
173
174Statement *Statement::statementCast()
175{
176 return this;
177}
178
179UiObjectMember *UiObjectMember::uiObjectMemberCast()
180{
181 return this;
182}
183
184void NestedExpression::accept0(BaseVisitor *visitor)
185{
186 if (visitor->visit(this)) {
187 accept(node: expression, visitor);
188 }
189 visitor->endVisit(this);
190}
191
192FunctionExpression *NestedExpression::asFunctionDefinition()
193{
194 return expression->asFunctionDefinition();
195}
196
197ClassExpression *NestedExpression::asClassDefinition()
198{
199 return expression->asClassDefinition();
200}
201
202void ThisExpression::accept0(BaseVisitor *visitor)
203{
204 if (visitor->visit(this)) {
205 }
206
207 visitor->endVisit(this);
208}
209
210void IdentifierExpression::accept0(BaseVisitor *visitor)
211{
212 if (visitor->visit(this)) {
213 }
214
215 visitor->endVisit(this);
216}
217
218void NullExpression::accept0(BaseVisitor *visitor)
219{
220 if (visitor->visit(this)) {
221 }
222
223 visitor->endVisit(this);
224}
225
226void TrueLiteral::accept0(BaseVisitor *visitor)
227{
228 if (visitor->visit(this)) {
229 }
230
231 visitor->endVisit(this);
232}
233
234void FalseLiteral::accept0(BaseVisitor *visitor)
235{
236 if (visitor->visit(this)) {
237 }
238
239 visitor->endVisit(this);
240}
241
242void SuperLiteral::accept0(BaseVisitor *visitor)
243{
244 if (visitor->visit(this)) {
245 }
246
247 visitor->endVisit(this);
248}
249
250
251void StringLiteral::accept0(BaseVisitor *visitor)
252{
253 if (visitor->visit(this)) {
254 }
255
256 visitor->endVisit(this);
257}
258
259void TemplateLiteral::accept0(BaseVisitor *visitor)
260{
261 bool accepted = true;
262 for (TemplateLiteral *it = this; it && accepted; it = it->next) {
263 accepted = visitor->visit(it);
264 visitor->endVisit(it);
265 }
266}
267
268void NumericLiteral::accept0(BaseVisitor *visitor)
269{
270 if (visitor->visit(this)) {
271 }
272
273 visitor->endVisit(this);
274}
275
276void RegExpLiteral::accept0(BaseVisitor *visitor)
277{
278 if (visitor->visit(this)) {
279 }
280
281 visitor->endVisit(this);
282}
283
284void ArrayPattern::accept0(BaseVisitor *visitor)
285{
286 if (visitor->visit(this))
287 accept(node: elements, visitor);
288
289 visitor->endVisit(this);
290}
291
292bool ArrayPattern::isValidArrayLiteral(SourceLocation *errorLocation) const {
293 for (PatternElementList *it = elements; it != nullptr; it = it->next) {
294 PatternElement *e = it->element;
295 if (e && e->bindingTarget != nullptr) {
296 if (errorLocation)
297 *errorLocation = e->firstSourceLocation();
298 return false;
299 }
300 }
301 return true;
302}
303
304void ObjectPattern::accept0(BaseVisitor *visitor)
305{
306 if (visitor->visit(this)) {
307 accept(node: properties, visitor);
308 }
309
310 visitor->endVisit(this);
311}
312
313/*
314 This is the grammar for AssignmentPattern that we need to convert the literal to:
315
316 AssignmentPattern:
317 ObjectAssignmentPattern
318 ArrayAssignmentPattern
319 ArrayAssignmentPattern:
320 [ ElisionOpt AssignmentRestElementOpt ]
321 [ AssignmentElementList ]
322 [ AssignmentElementList , ElisionOpt AssignmentRestElementOpt ]
323 AssignmentElementList:
324 AssignmentElisionElement
325 AssignmentElementList , AssignmentElisionElement
326 AssignmentElisionElement:
327 ElisionOpt AssignmentElement
328 AssignmentRestElement:
329 ... DestructuringAssignmentTarget
330
331 ObjectAssignmentPattern:
332 {}
333 { AssignmentPropertyList }
334 { AssignmentPropertyList, }
335 AssignmentPropertyList:
336 AssignmentProperty
337 AssignmentPropertyList , AssignmentProperty
338 AssignmentProperty:
339 IdentifierReference InitializerOpt_In
340 PropertyName:
341 AssignmentElement
342
343 AssignmentElement:
344 DestructuringAssignmentTarget InitializerOpt_In
345 DestructuringAssignmentTarget:
346 LeftHandSideExpression
347
348 It was originally parsed with the following grammar:
349
350ArrayLiteral:
351 [ ElisionOpt ]
352 [ ElementList ]
353 [ ElementList , ElisionOpt ]
354ElementList:
355 ElisionOpt AssignmentExpression_In
356 ElisionOpt SpreadElement
357 ElementList , ElisionOpt AssignmentExpression_In
358 ElementList , Elisionopt SpreadElement
359SpreadElement:
360 ... AssignmentExpression_In
361ObjectLiteral:
362 {}
363 { PropertyDefinitionList }
364 { PropertyDefinitionList , }
365PropertyDefinitionList:
366 PropertyDefinition
367 PropertyDefinitionList , PropertyDefinition
368PropertyDefinition:
369 IdentifierReference
370 CoverInitializedName
371 PropertyName : AssignmentExpression_In
372 MethodDefinition
373PropertyName:
374 LiteralPropertyName
375 ComputedPropertyName
376
377*/
378bool ArrayPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage)
379{
380 if (parseMode == Binding)
381 return true;
382 for (auto *it = elements; it; it = it->next) {
383 if (!it->element)
384 continue;
385 if (it->element->type == PatternElement::SpreadElement && it->next) {
386 *errorLocation = it->element->firstSourceLocation();
387 *errorMessage = QString::fromLatin1(ba: "'...' can only appear as last element in a destructuring list.");
388 return false;
389 }
390 if (!it->element->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage))
391 return false;
392 }
393 parseMode = Binding;
394 return true;
395}
396
397bool ObjectPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage)
398{
399 if (parseMode == Binding)
400 return true;
401 for (auto *it = properties; it; it = it->next) {
402 if (!it->property->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage))
403 return false;
404 }
405 parseMode = Binding;
406 return true;
407}
408
409bool PatternElement::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage)
410{
411 Q_ASSERT(type == Literal || type == SpreadElement);
412 Q_ASSERT(bindingIdentifier.isNull());
413 Q_ASSERT(bindingTarget == nullptr);
414 Q_ASSERT(bindingTarget == nullptr);
415 Q_ASSERT(initializer);
416 ExpressionNode *init = initializer;
417
418 initializer = nullptr;
419 LeftHandSideExpression *lhs = init->leftHandSideExpressionCast();
420 if (type == SpreadElement) {
421 if (!lhs) {
422 *errorLocation = init->firstSourceLocation();
423 *errorMessage = QString::fromLatin1(ba: "Invalid lhs expression after '...' in destructuring expression.");
424 return false;
425 }
426 } else {
427 type = PatternElement::Binding;
428
429 if (BinaryExpression *b = init->binaryExpressionCast()) {
430 if (b->op != QSOperator::Assign) {
431 *errorLocation = b->operatorToken;
432 *errorMessage = QString::fromLatin1(ba: "Invalid assignment operation in destructuring expression");
433 return false;
434 }
435 lhs = b->left->leftHandSideExpressionCast();
436 initializer = b->right;
437 Q_ASSERT(lhs);
438 } else {
439 lhs = init->leftHandSideExpressionCast();
440 }
441 if (!lhs) {
442 *errorLocation = init->firstSourceLocation();
443 *errorMessage = QString::fromLatin1(ba: "Destructuring target is not a left hand side expression.");
444 return false;
445 }
446 }
447
448 if (auto *i = cast<IdentifierExpression *>(ast: lhs)) {
449 bindingIdentifier = i->name;
450 identifierToken = i->identifierToken;
451 return true;
452 }
453
454 bindingTarget = lhs;
455 if (auto *p = lhs->patternCast()) {
456 if (!p->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage))
457 return false;
458 }
459 return true;
460}
461
462bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage)
463{
464 Q_ASSERT(type != SpreadElement);
465 if (type == Binding)
466 return true;
467 if (type == Getter || type == Setter) {
468 *errorLocation = firstSourceLocation();
469 *errorMessage = QString::fromLatin1(ba: "Invalid getter/setter in destructuring expression.");
470 return false;
471 }
472 if (type == Method)
473 type = Literal;
474 Q_ASSERT(type == Literal);
475 return PatternElement::convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage);
476}
477
478
479void Elision::accept0(BaseVisitor *visitor)
480{
481 if (visitor->visit(this)) {
482 // ###
483 }
484
485 visitor->endVisit(this);
486}
487
488void IdentifierPropertyName::accept0(BaseVisitor *visitor)
489{
490 if (visitor->visit(this)) {
491 }
492
493 visitor->endVisit(this);
494}
495
496void StringLiteralPropertyName::accept0(BaseVisitor *visitor)
497{
498 if (visitor->visit(this)) {
499 }
500
501 visitor->endVisit(this);
502}
503
504void NumericLiteralPropertyName::accept0(BaseVisitor *visitor)
505{
506 if (visitor->visit(this)) {
507 }
508
509 visitor->endVisit(this);
510}
511
512namespace {
513struct LocaleWithoutZeroPadding : public QLocale
514{
515 LocaleWithoutZeroPadding()
516 : QLocale(QLocale::C)
517 {
518 setNumberOptions(QLocale::OmitLeadingZeroInExponent | QLocale::OmitGroupSeparator);
519 }
520};
521}
522
523QString NumericLiteralPropertyName::asString()const
524{
525 // Can't use QString::number here anymore as it does zero padding by default now.
526
527 // In C++11 this initialization is thread-safe (6.7 [stmt.dcl] p4)
528 static LocaleWithoutZeroPadding locale;
529 // Because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 we can't use thread_local
530 // for the locale variable and therefore rely on toString(double) to be thread-safe.
531 return locale.toString(f: id, format: 'g', precision: 16);
532}
533
534void ArrayMemberExpression::accept0(BaseVisitor *visitor)
535{
536 if (visitor->visit(this)) {
537 accept(node: base, visitor);
538 accept(node: expression, visitor);
539 }
540
541 visitor->endVisit(this);
542}
543
544void FieldMemberExpression::accept0(BaseVisitor *visitor)
545{
546 if (visitor->visit(this)) {
547 accept(node: base, visitor);
548 }
549
550 visitor->endVisit(this);
551}
552
553void NewMemberExpression::accept0(BaseVisitor *visitor)
554{
555 if (visitor->visit(this)) {
556 accept(node: base, visitor);
557 accept(node: arguments, visitor);
558 }
559
560 visitor->endVisit(this);
561}
562
563void NewExpression::accept0(BaseVisitor *visitor)
564{
565 if (visitor->visit(this)) {
566 accept(node: expression, visitor);
567 }
568
569 visitor->endVisit(this);
570}
571
572void CallExpression::accept0(BaseVisitor *visitor)
573{
574 if (visitor->visit(this)) {
575 accept(node: base, visitor);
576 accept(node: arguments, visitor);
577 }
578
579 visitor->endVisit(this);
580}
581
582void ArgumentList::accept0(BaseVisitor *visitor)
583{
584 if (visitor->visit(this)) {
585 for (ArgumentList *it = this; it; it = it->next) {
586 accept(node: it->expression, visitor);
587 }
588 }
589
590 visitor->endVisit(this);
591}
592
593void PostIncrementExpression::accept0(BaseVisitor *visitor)
594{
595 if (visitor->visit(this)) {
596 accept(node: base, visitor);
597 }
598
599 visitor->endVisit(this);
600}
601
602void PostDecrementExpression::accept0(BaseVisitor *visitor)
603{
604 if (visitor->visit(this)) {
605 accept(node: base, visitor);
606 }
607
608 visitor->endVisit(this);
609}
610
611void DeleteExpression::accept0(BaseVisitor *visitor)
612{
613 if (visitor->visit(this)) {
614 accept(node: expression, visitor);
615 }
616
617 visitor->endVisit(this);
618}
619
620void VoidExpression::accept0(BaseVisitor *visitor)
621{
622 if (visitor->visit(this)) {
623 accept(node: expression, visitor);
624 }
625
626 visitor->endVisit(this);
627}
628
629void TypeOfExpression::accept0(BaseVisitor *visitor)
630{
631 if (visitor->visit(this)) {
632 accept(node: expression, visitor);
633 }
634
635 visitor->endVisit(this);
636}
637
638void PreIncrementExpression::accept0(BaseVisitor *visitor)
639{
640 if (visitor->visit(this)) {
641 accept(node: expression, visitor);
642 }
643
644 visitor->endVisit(this);
645}
646
647void PreDecrementExpression::accept0(BaseVisitor *visitor)
648{
649 if (visitor->visit(this)) {
650 accept(node: expression, visitor);
651 }
652
653 visitor->endVisit(this);
654}
655
656void UnaryPlusExpression::accept0(BaseVisitor *visitor)
657{
658 if (visitor->visit(this)) {
659 accept(node: expression, visitor);
660 }
661
662 visitor->endVisit(this);
663}
664
665void UnaryMinusExpression::accept0(BaseVisitor *visitor)
666{
667 if (visitor->visit(this)) {
668 accept(node: expression, visitor);
669 }
670
671 visitor->endVisit(this);
672}
673
674void TildeExpression::accept0(BaseVisitor *visitor)
675{
676 if (visitor->visit(this)) {
677 accept(node: expression, visitor);
678 }
679
680 visitor->endVisit(this);
681}
682
683void NotExpression::accept0(BaseVisitor *visitor)
684{
685 if (visitor->visit(this)) {
686 accept(node: expression, visitor);
687 }
688
689 visitor->endVisit(this);
690}
691
692void BinaryExpression::accept0(BaseVisitor *visitor)
693{
694 if (visitor->visit(this)) {
695 accept(node: left, visitor);
696 accept(node: right, visitor);
697 }
698
699 visitor->endVisit(this);
700}
701
702void ConditionalExpression::accept0(BaseVisitor *visitor)
703{
704 if (visitor->visit(this)) {
705 accept(node: expression, visitor);
706 accept(node: ok, visitor);
707 accept(node: ko, visitor);
708 }
709
710 visitor->endVisit(this);
711}
712
713void Expression::accept0(BaseVisitor *visitor)
714{
715 if (visitor->visit(this)) {
716 accept(node: left, visitor);
717 accept(node: right, visitor);
718 }
719
720 visitor->endVisit(this);
721}
722
723void Block::accept0(BaseVisitor *visitor)
724{
725 if (visitor->visit(this)) {
726 accept(node: statements, visitor);
727 }
728
729 visitor->endVisit(this);
730}
731
732void StatementList::accept0(BaseVisitor *visitor)
733{
734 if (visitor->visit(this)) {
735 for (StatementList *it = this; it; it = it->next) {
736 accept(node: it->statement, visitor);
737 }
738 }
739
740 visitor->endVisit(this);
741}
742
743void VariableStatement::accept0(BaseVisitor *visitor)
744{
745 if (visitor->visit(this)) {
746 accept(node: declarations, visitor);
747 }
748
749 visitor->endVisit(this);
750}
751
752void VariableDeclarationList::accept0(BaseVisitor *visitor)
753{
754 if (visitor->visit(this)) {
755 for (VariableDeclarationList *it = this; it; it = it->next) {
756 accept(node: it->declaration, visitor);
757 }
758 }
759
760 visitor->endVisit(this);
761}
762
763void EmptyStatement::accept0(BaseVisitor *visitor)
764{
765 if (visitor->visit(this)) {
766 }
767
768 visitor->endVisit(this);
769}
770
771void ExpressionStatement::accept0(BaseVisitor *visitor)
772{
773 if (visitor->visit(this)) {
774 accept(node: expression, visitor);
775 }
776
777 visitor->endVisit(this);
778}
779
780void IfStatement::accept0(BaseVisitor *visitor)
781{
782 if (visitor->visit(this)) {
783 accept(node: expression, visitor);
784 accept(node: ok, visitor);
785 accept(node: ko, visitor);
786 }
787
788 visitor->endVisit(this);
789}
790
791void DoWhileStatement::accept0(BaseVisitor *visitor)
792{
793 if (visitor->visit(this)) {
794 accept(node: statement, visitor);
795 accept(node: expression, visitor);
796 }
797
798 visitor->endVisit(this);
799}
800
801void WhileStatement::accept0(BaseVisitor *visitor)
802{
803 if (visitor->visit(this)) {
804 accept(node: expression, visitor);
805 accept(node: statement, visitor);
806 }
807
808 visitor->endVisit(this);
809}
810
811void ForStatement::accept0(BaseVisitor *visitor)
812{
813 if (visitor->visit(this)) {
814 accept(node: initialiser, visitor);
815 accept(node: declarations, visitor);
816 accept(node: condition, visitor);
817 accept(node: expression, visitor);
818 accept(node: statement, visitor);
819 }
820
821 visitor->endVisit(this);
822}
823
824void ForEachStatement::accept0(BaseVisitor *visitor)
825{
826 if (visitor->visit(this)) {
827 accept(node: lhs, visitor);
828 accept(node: expression, visitor);
829 accept(node: statement, visitor);
830 }
831
832 visitor->endVisit(this);
833}
834
835void ContinueStatement::accept0(BaseVisitor *visitor)
836{
837 if (visitor->visit(this)) {
838 }
839
840 visitor->endVisit(this);
841}
842
843void BreakStatement::accept0(BaseVisitor *visitor)
844{
845 if (visitor->visit(this)) {
846 }
847
848 visitor->endVisit(this);
849}
850
851void ReturnStatement::accept0(BaseVisitor *visitor)
852{
853 if (visitor->visit(this)) {
854 accept(node: expression, visitor);
855 }
856
857 visitor->endVisit(this);
858}
859
860void YieldExpression::accept0(BaseVisitor *visitor)
861{
862 if (visitor->visit(this)) {
863 accept(node: expression, visitor);
864 }
865
866 visitor->endVisit(this);
867}
868
869
870void WithStatement::accept0(BaseVisitor *visitor)
871{
872 if (visitor->visit(this)) {
873 accept(node: expression, visitor);
874 accept(node: statement, visitor);
875 }
876
877 visitor->endVisit(this);
878}
879
880void SwitchStatement::accept0(BaseVisitor *visitor)
881{
882 if (visitor->visit(this)) {
883 accept(node: expression, visitor);
884 accept(node: block, visitor);
885 }
886
887 visitor->endVisit(this);
888}
889
890void CaseBlock::accept0(BaseVisitor *visitor)
891{
892 if (visitor->visit(this)) {
893 accept(node: clauses, visitor);
894 accept(node: defaultClause, visitor);
895 accept(node: moreClauses, visitor);
896 }
897
898 visitor->endVisit(this);
899}
900
901void CaseClauses::accept0(BaseVisitor *visitor)
902{
903 if (visitor->visit(this)) {
904 for (CaseClauses *it = this; it; it = it->next) {
905 accept(node: it->clause, visitor);
906 }
907 }
908
909 visitor->endVisit(this);
910}
911
912void CaseClause::accept0(BaseVisitor *visitor)
913{
914 if (visitor->visit(this)) {
915 accept(node: expression, visitor);
916 accept(node: statements, visitor);
917 }
918
919 visitor->endVisit(this);
920}
921
922void DefaultClause::accept0(BaseVisitor *visitor)
923{
924 if (visitor->visit(this)) {
925 accept(node: statements, visitor);
926 }
927
928 visitor->endVisit(this);
929}
930
931void LabelledStatement::accept0(BaseVisitor *visitor)
932{
933 if (visitor->visit(this)) {
934 accept(node: statement, visitor);
935 }
936
937 visitor->endVisit(this);
938}
939
940void ThrowStatement::accept0(BaseVisitor *visitor)
941{
942 if (visitor->visit(this)) {
943 accept(node: expression, visitor);
944 }
945
946 visitor->endVisit(this);
947}
948
949void TryStatement::accept0(BaseVisitor *visitor)
950{
951 if (visitor->visit(this)) {
952 accept(node: statement, visitor);
953 accept(node: catchExpression, visitor);
954 accept(node: finallyExpression, visitor);
955 }
956
957 visitor->endVisit(this);
958}
959
960void Catch::accept0(BaseVisitor *visitor)
961{
962 if (visitor->visit(this)) {
963 accept(node: patternElement, visitor);
964 accept(node: statement, visitor);
965 }
966
967 visitor->endVisit(this);
968}
969
970void Finally::accept0(BaseVisitor *visitor)
971{
972 if (visitor->visit(this)) {
973 accept(node: statement, visitor);
974 }
975
976 visitor->endVisit(this);
977}
978
979void FunctionDeclaration::accept0(BaseVisitor *visitor)
980{
981 if (visitor->visit(this)) {
982 accept(node: formals, visitor);
983 accept(node: typeAnnotation, visitor);
984 accept(node: body, visitor);
985 }
986
987 visitor->endVisit(this);
988}
989
990void FunctionExpression::accept0(BaseVisitor *visitor)
991{
992 if (visitor->visit(this)) {
993 accept(node: formals, visitor);
994 accept(node: typeAnnotation, visitor);
995 accept(node: body, visitor);
996 }
997
998 visitor->endVisit(this);
999}
1000
1001FunctionExpression *FunctionExpression::asFunctionDefinition()
1002{
1003 return this;
1004}
1005
1006BoundNames FormalParameterList::formals() const
1007{
1008 BoundNames formals;
1009 int i = 0;
1010 for (const FormalParameterList *it = this; it; it = it->next) {
1011 if (it->element) {
1012 QString name = it->element->bindingIdentifier.toString();
1013 int duplicateIndex = formals.indexOf(name);
1014 if (duplicateIndex >= 0) {
1015 // change the name of the earlier argument to enforce the lookup semantics from the spec
1016 formals[duplicateIndex].id += QLatin1String("#") + QString::number(i);
1017 }
1018 formals += {
1019 name,
1020 it->element->typeAnnotation,
1021 it->element->isInjectedSignalParameter
1022 ? BoundName::Injected
1023 : BoundName::Declared
1024 };
1025 }
1026 ++i;
1027 }
1028 return formals;
1029}
1030
1031BoundNames FormalParameterList::boundNames() const
1032{
1033 BoundNames names;
1034 for (const FormalParameterList *it = this; it; it = it->next) {
1035 if (it->element)
1036 it->element->boundNames(names: &names);
1037 }
1038 return names;
1039}
1040
1041void FormalParameterList::accept0(BaseVisitor *visitor)
1042{
1043 bool accepted = true;
1044 for (FormalParameterList *it = this; it && accepted; it = it->next) {
1045 accepted = visitor->visit(it);
1046 if (accepted)
1047 accept(node: it->element, visitor);
1048 visitor->endVisit(it);
1049 }
1050}
1051
1052FormalParameterList *FormalParameterList::finish(QQmlJS::MemoryPool *)
1053{
1054 FormalParameterList *front = next;
1055 next = nullptr;
1056 return front;
1057}
1058
1059void Program::accept0(BaseVisitor *visitor)
1060{
1061 if (visitor->visit(this)) {
1062 accept(node: statements, visitor);
1063 }
1064
1065 visitor->endVisit(this);
1066}
1067
1068void ImportSpecifier::accept0(BaseVisitor *visitor)
1069{
1070 if (visitor->visit(this)) {
1071
1072 }
1073 visitor->endVisit(this);
1074}
1075
1076void ImportsList::accept0(BaseVisitor *visitor)
1077{
1078 if (visitor->visit(this)) {
1079 for (ImportsList *it = this; it; it = it->next) {
1080 accept(node: it->importSpecifier, visitor);
1081 }
1082 }
1083
1084 visitor->endVisit(this);
1085}
1086
1087void NamedImports::accept0(BaseVisitor *visitor)
1088{
1089 if (visitor->visit(this)) {
1090 accept(node: importsList, visitor);
1091 }
1092
1093 visitor->endVisit(this);
1094}
1095
1096void FromClause::accept0(BaseVisitor *visitor)
1097{
1098 if (visitor->visit(this)) {
1099 }
1100
1101 visitor->endVisit(this);
1102}
1103
1104void NameSpaceImport::accept0(BaseVisitor *visitor)
1105{
1106 if (visitor->visit(this)) {
1107 }
1108
1109 visitor->endVisit(this);
1110}
1111
1112void ImportClause::accept0(BaseVisitor *visitor)
1113{
1114 if (visitor->visit(this)) {
1115 accept(node: nameSpaceImport, visitor);
1116 accept(node: namedImports, visitor);
1117 }
1118
1119 visitor->endVisit(this);
1120}
1121
1122void ImportDeclaration::accept0(BaseVisitor *visitor)
1123{
1124 if (visitor->visit(this)) {
1125 accept(node: importClause, visitor);
1126 accept(node: fromClause, visitor);
1127 }
1128
1129 visitor->endVisit(this);
1130}
1131
1132void ExportSpecifier::accept0(BaseVisitor *visitor)
1133{
1134 if (visitor->visit(this)) {
1135
1136 }
1137
1138 visitor->endVisit(this);
1139}
1140
1141void ExportsList::accept0(BaseVisitor *visitor)
1142{
1143 if (visitor->visit(this)) {
1144 for (ExportsList *it = this; it; it = it->next) {
1145 accept(node: it->exportSpecifier, visitor);
1146 }
1147 }
1148
1149 visitor->endVisit(this);
1150}
1151
1152void ExportClause::accept0(BaseVisitor *visitor)
1153{
1154 if (visitor->visit(this)) {
1155 accept(node: exportsList, visitor);
1156 }
1157
1158 visitor->endVisit(this);
1159}
1160
1161void ExportDeclaration::accept0(BaseVisitor *visitor)
1162{
1163 if (visitor->visit(this)) {
1164 accept(node: fromClause, visitor);
1165 accept(node: exportClause, visitor);
1166 accept(node: variableStatementOrDeclaration, visitor);
1167 }
1168
1169 visitor->endVisit(this);
1170}
1171
1172void ESModule::accept0(BaseVisitor *visitor)
1173{
1174 if (visitor->visit(this)) {
1175 accept(node: body, visitor);
1176 }
1177
1178 visitor->endVisit(this);
1179}
1180
1181void DebuggerStatement::accept0(BaseVisitor *visitor)
1182{
1183 if (visitor->visit(this)) {
1184 }
1185
1186 visitor->endVisit(this);
1187}
1188
1189void UiProgram::accept0(BaseVisitor *visitor)
1190{
1191 if (visitor->visit(this)) {
1192 accept(node: headers, visitor);
1193 accept(node: members, visitor);
1194 }
1195
1196 visitor->endVisit(this);
1197}
1198
1199void UiPublicMember::accept0(BaseVisitor *visitor)
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
1204 accept(node: statement, visitor);
1205 accept(node: binding, visitor);
1206 // accept(parameters, visitor); // accept manually in visit if interested
1207 }
1208
1209 visitor->endVisit(this);
1210}
1211
1212void UiObjectDefinition::accept0(BaseVisitor *visitor)
1213{
1214 if (visitor->visit(this)) {
1215 // accept(annotations, visitor); // accept manually in visit if interested
1216 accept(node: qualifiedTypeNameId, visitor);
1217 accept(node: initializer, visitor);
1218 }
1219
1220 visitor->endVisit(this);
1221}
1222
1223void UiObjectInitializer::accept0(BaseVisitor *visitor)
1224{
1225 if (visitor->visit(this)) {
1226 accept(node: members, visitor);
1227 }
1228
1229 visitor->endVisit(this);
1230}
1231
1232void UiParameterList::accept0(BaseVisitor *visitor)
1233{
1234 if (visitor->visit(this)) {
1235 // accept(type, visitor); // accept manually in visit if interested
1236 }
1237 visitor->endVisit(this);
1238}
1239
1240void UiObjectBinding::accept0(BaseVisitor *visitor)
1241{
1242 if (visitor->visit(this)) {
1243 // accept(annotations, visitor); // accept manually in visit if interested
1244 accept(node: qualifiedId, visitor);
1245 accept(node: qualifiedTypeNameId, visitor);
1246 accept(node: initializer, visitor);
1247 }
1248
1249 visitor->endVisit(this);
1250}
1251
1252void UiScriptBinding::accept0(BaseVisitor *visitor)
1253{
1254 if (visitor->visit(this)) {
1255 // accept(annotations, visitor); // accept manually in visit if interested
1256 accept(node: qualifiedId, visitor);
1257 accept(node: statement, visitor);
1258 }
1259
1260 visitor->endVisit(this);
1261}
1262
1263void UiArrayBinding::accept0(BaseVisitor *visitor)
1264{
1265 if (visitor->visit(this)) {
1266 // accept(annotations, visitor); // accept manually in visit if interested
1267 accept(node: qualifiedId, visitor);
1268 accept(node: members, visitor);
1269 }
1270
1271 visitor->endVisit(this);
1272}
1273
1274void UiObjectMemberList::accept0(BaseVisitor *visitor)
1275{
1276 if (visitor->visit(this)) {
1277 for (UiObjectMemberList *it = this; it; it = it->next)
1278 accept(node: it->member, visitor);
1279 }
1280
1281 visitor->endVisit(this);
1282}
1283
1284void UiArrayMemberList::accept0(BaseVisitor *visitor)
1285{
1286 if (visitor->visit(this)) {
1287 for (UiArrayMemberList *it = this; it; it = it->next)
1288 accept(node: it->member, visitor);
1289 }
1290
1291 visitor->endVisit(this);
1292}
1293
1294void UiQualifiedId::accept0(BaseVisitor *visitor)
1295{
1296 if (visitor->visit(this)) {
1297 // accept(next, visitor) // accept manually in visit if interested
1298 }
1299
1300 visitor->endVisit(this);
1301}
1302
1303void Type::accept0(BaseVisitor *visitor)
1304{
1305 if (visitor->visit(this)) {
1306 accept(node: typeId, visitor);
1307 accept(node: typeArgument, visitor);
1308 }
1309
1310 visitor->endVisit(this);
1311}
1312
1313void TypeAnnotation::accept0(BaseVisitor *visitor)
1314{
1315 if (visitor->visit(this)) {
1316 accept(node: type, visitor);
1317 }
1318
1319 visitor->endVisit(this);
1320}
1321
1322void UiImport::accept0(BaseVisitor *visitor)
1323{
1324 if (visitor->visit(this)) {
1325 accept(node: importUri, visitor);
1326 // accept(version, visitor); // accept manually in visit if interested
1327 }
1328
1329 visitor->endVisit(this);
1330}
1331
1332void UiPragmaValueList::accept0(BaseVisitor *visitor)
1333{
1334 if (visitor->visit(this)) {
1335 }
1336
1337 visitor->endVisit(this);
1338}
1339
1340
1341void UiPragma::accept0(BaseVisitor *visitor)
1342{
1343 if (visitor->visit(this)) {
1344 }
1345
1346 visitor->endVisit(this);
1347}
1348
1349void UiHeaderItemList::accept0(BaseVisitor *visitor)
1350{
1351 bool accepted = true;
1352 for (UiHeaderItemList *it = this; it && accepted; it = it->next) {
1353 accepted = visitor->visit(it);
1354 if (accepted)
1355 accept(node: it->headerItem, visitor);
1356
1357 visitor->endVisit(it);
1358 }
1359}
1360
1361
1362void UiSourceElement::accept0(BaseVisitor *visitor)
1363{
1364 if (visitor->visit(this)) {
1365 // accept(annotations, visitor); // accept manually in visit if interested
1366 accept(node: sourceElement, visitor);
1367 }
1368
1369 visitor->endVisit(this);
1370}
1371
1372void UiEnumDeclaration::accept0(BaseVisitor *visitor)
1373{
1374 if (visitor->visit(this)) {
1375 // accept(annotations, visitor); // accept manually in visit if interested
1376 accept(node: members, visitor);
1377 }
1378
1379 visitor->endVisit(this);
1380}
1381
1382void UiEnumMemberList::accept0(BaseVisitor *visitor)
1383{
1384 if (visitor->visit(this)) {
1385 }
1386
1387 visitor->endVisit(this);
1388}
1389
1390void TaggedTemplate::accept0(BaseVisitor *visitor)
1391{
1392 if (visitor->visit(this)) {
1393 accept(node: base, visitor);
1394 accept(node: templateLiteral, visitor);
1395 }
1396
1397 visitor->endVisit(this);
1398}
1399
1400void PatternElement::accept0(BaseVisitor *visitor)
1401{
1402 if (visitor->visit(this)) {
1403 accept(node: bindingTarget, visitor);
1404 accept(node: typeAnnotation, visitor);
1405 accept(node: initializer, visitor);
1406 }
1407
1408 visitor->endVisit(this);
1409}
1410
1411void PatternElement::boundNames(BoundNames *names)
1412{
1413 if (bindingTarget) {
1414 if (PatternElementList *e = elementList())
1415 e->boundNames(names);
1416 else if (PatternPropertyList *p = propertyList())
1417 p->boundNames(names);
1418 } else {
1419 names->append(t: {bindingIdentifier.toString(), typeAnnotation,
1420 isInjectedSignalParameter ? BoundName::Injected : BoundName::Declared});
1421 }
1422}
1423
1424void PatternElementList::accept0(BaseVisitor *visitor)
1425{
1426 bool accepted = true;
1427 for (PatternElementList *it = this; it && accepted; it = it->next) {
1428 accepted = visitor->visit(it);
1429 if (accepted) {
1430 accept(node: it->elision, visitor);
1431 accept(node: it->element, visitor);
1432 }
1433 visitor->endVisit(it);
1434 }
1435}
1436
1437void PatternElementList::boundNames(BoundNames *names)
1438{
1439 for (PatternElementList *it = this; it; it = it->next) {
1440 if (it->element)
1441 it->element->boundNames(names);
1442 }
1443}
1444
1445void PatternProperty::accept0(BaseVisitor *visitor)
1446{
1447 if (visitor->visit(this)) {
1448 accept(node: name, visitor);
1449 accept(node: bindingTarget, visitor);
1450 accept(node: typeAnnotation, visitor);
1451 accept(node: initializer, visitor);
1452 }
1453
1454 visitor->endVisit(this);
1455}
1456
1457void PatternProperty::boundNames(BoundNames *names)
1458{
1459 PatternElement::boundNames(names);
1460}
1461
1462void PatternPropertyList::accept0(BaseVisitor *visitor)
1463{
1464 bool accepted = true;
1465 for (PatternPropertyList *it = this; it && accepted; it = it->next) {
1466 accepted = visitor->visit(it);
1467 if (accepted)
1468 accept(node: it->property, visitor);
1469 visitor->endVisit(it);
1470 }
1471}
1472
1473void PatternPropertyList::boundNames(BoundNames *names)
1474{
1475 for (PatternPropertyList *it = this; it; it = it->next)
1476 it->property->boundNames(names);
1477}
1478
1479void ComputedPropertyName::accept0(BaseVisitor *visitor)
1480{
1481 if (visitor->visit(this)) {
1482 accept(node: expression, visitor);
1483 }
1484
1485 visitor->endVisit(this);
1486}
1487
1488void ClassExpression::accept0(BaseVisitor *visitor)
1489{
1490 if (visitor->visit(this)) {
1491 accept(node: heritage, visitor);
1492 accept(node: elements, visitor);
1493 }
1494
1495 visitor->endVisit(this);
1496}
1497
1498ClassExpression *ClassExpression::asClassDefinition()
1499{
1500 return this;
1501}
1502
1503void ClassDeclaration::accept0(BaseVisitor *visitor)
1504{
1505 if (visitor->visit(this)) {
1506 accept(node: heritage, visitor);
1507 accept(node: elements, visitor);
1508 }
1509
1510 visitor->endVisit(this);
1511}
1512
1513void ClassElementList::accept0(BaseVisitor *visitor)
1514{
1515 bool accepted = true;
1516 for (ClassElementList *it = this; it && accepted; it = it->next) {
1517 accepted = visitor->visit(it);
1518 if (accepted)
1519 accept(node: it->property, visitor);
1520
1521 visitor->endVisit(it);
1522 }
1523}
1524
1525ClassElementList *ClassElementList::finish()
1526{
1527 ClassElementList *front = next;
1528 next = nullptr;
1529 return front;
1530}
1531
1532Pattern *Pattern::patternCast()
1533{
1534 return this;
1535}
1536
1537LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast()
1538{
1539 return this;
1540}
1541
1542void UiVersionSpecifier::accept0(BaseVisitor *visitor)
1543{
1544 if (visitor->visit(this)) {
1545 }
1546 visitor->endVisit(this);
1547}
1548
1549QString Type::toString() const
1550{
1551 QString result;
1552 toString(out: &result);
1553 return result;
1554}
1555
1556void Type::toString(QString *out) const
1557{
1558 typeId->toString(out);
1559
1560 if (typeArgument) {
1561 out->append(c: QLatin1Char('<'));
1562 typeArgument->toString(out);
1563 out->append(c: QLatin1Char('>'));
1564 };
1565}
1566
1567void UiInlineComponent::accept0(BaseVisitor *visitor)
1568{
1569 if (visitor->visit(this)) {
1570 // accept(annotations, visitor); // accept manually in visit if interested
1571 accept(node: component, visitor);
1572 }
1573
1574 visitor->endVisit(this);
1575}
1576
1577void UiRequired::accept0(BaseVisitor *visitor)
1578{
1579 if (visitor->visit(this)) {
1580 }
1581
1582 visitor->endVisit(this);
1583}
1584
1585void UiAnnotationList::accept0(BaseVisitor *visitor)
1586{
1587 if (visitor->visit(this)) {
1588 for (UiAnnotationList *it = this; it; it = it->next)
1589 accept(node: it->annotation, visitor);
1590 }
1591
1592 visitor->endVisit(this);
1593}
1594
1595void UiAnnotation::accept0(BaseVisitor *visitor)
1596{
1597 if (visitor->visit(this)) {
1598 accept(node: qualifiedTypeNameId, visitor);
1599 accept(node: initializer, visitor);
1600 }
1601
1602 visitor->endVisit(this);
1603}
1604
1605SourceLocation UiPropertyAttributes::firstSourceLocation() const
1606{
1607 std::array<const SourceLocation *, 4> tokens {&m_propertyToken, &m_defaultToken, &m_readonlyToken, &m_requiredToken};
1608 const auto it = std::min_element(first: tokens.begin(), last: tokens.end(), comp: compareLocationsByBegin<true>);
1609 return **it;
1610}
1611
1612SourceLocation UiPropertyAttributes::lastSourceLocation() const
1613{
1614 std::array<const SourceLocation *, 4> tokens {&m_propertyToken, &m_defaultToken, &m_readonlyToken, &m_requiredToken};
1615 const auto it = std::max_element(first: tokens.begin(), last: tokens.end(), comp: compareLocationsByBegin<false>);
1616 return **it;
1617}
1618
1619} } // namespace QQmlJS::AST
1620
1621QT_END_NAMESPACE
1622
1623
1624

source code of qtdeclarative/src/qml/parser/qqmljsast.cpp