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

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