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

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