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#ifndef QQMLJSAST_P_H
5#define QQMLJSAST_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qqmljsastvisitor_p.h"
19#include "qqmljsglobal_p.h"
20
21#include <private/qqmljsmemorypool_p.h>
22
23#include <QtCore/qtaggedpointer.h>
24#include <QtCore/qversionnumber.h>
25
26#include <type_traits>
27
28QT_BEGIN_NAMESPACE
29
30class QString;
31
32namespace QQmlJS {
33 class Parser;
34}
35
36#define QQMLJS_DECLARE_AST_NODE(name) \
37 enum { K = Kind_##name };
38
39namespace QSOperator // ### rename
40{
41
42enum Op {
43 Add,
44 And,
45 InplaceAnd,
46 Assign,
47 BitAnd,
48 BitOr,
49 BitXor,
50 InplaceSub,
51 Div,
52 InplaceDiv,
53 Equal,
54 Exp,
55 InplaceExp,
56 Ge,
57 Gt,
58 In,
59 InplaceAdd,
60 InstanceOf,
61 Le,
62 LShift,
63 InplaceLeftShift,
64 Lt,
65 Mod,
66 InplaceMod,
67 Mul,
68 InplaceMul,
69 NotEqual,
70 Or,
71 InplaceOr,
72 RShift,
73 InplaceRightShift,
74 StrictEqual,
75 StrictNotEqual,
76 Sub,
77 URShift,
78 InplaceURightShift,
79 InplaceXor,
80 As,
81 Coalesce,
82 Invalid
83};
84
85} // namespace QSOperator
86
87namespace QQmlJS {
88
89namespace AST {
90
91enum class VariableScope {
92 NoScope,
93 Var,
94 Let,
95 Const
96};
97
98template <typename T1, typename T2>
99T1 cast(T2 *ast)
100{
101 if (ast && ast->kind == std::remove_pointer_t<T1>::K)
102 return static_cast<T1>(ast);
103
104 return nullptr;
105}
106
107FunctionExpression *asAnonymousFunctionDefinition(AST::Node *n);
108ClassExpression *asAnonymousClassDefinition(AST::Node *n);
109
110class QML_PARSER_EXPORT Node: public Managed
111{
112public:
113 enum Kind {
114 Kind_Undefined,
115
116 Kind_ArgumentList,
117 Kind_ArrayPattern,
118 Kind_ArrayMemberExpression,
119 Kind_BinaryExpression,
120 Kind_Block,
121 Kind_BreakStatement,
122 Kind_CallExpression,
123 Kind_CaseBlock,
124 Kind_CaseClause,
125 Kind_CaseClauses,
126 Kind_Catch,
127 Kind_ConditionalExpression,
128 Kind_ContinueStatement,
129 Kind_DebuggerStatement,
130 Kind_DefaultClause,
131 Kind_DeleteExpression,
132 Kind_DoWhileStatement,
133 Kind_ElementList,
134 Kind_Elision,
135 Kind_EmptyStatement,
136 Kind_Expression,
137 Kind_ExpressionStatement,
138 Kind_FalseLiteral,
139 Kind_SuperLiteral,
140 Kind_FieldMemberExpression,
141 Kind_Finally,
142 Kind_ForEachStatement,
143 Kind_ForStatement,
144 Kind_FormalParameterList,
145 Kind_FunctionBody,
146 Kind_FunctionDeclaration,
147 Kind_FunctionExpression,
148 Kind_ClassExpression,
149 Kind_ClassDeclaration,
150 Kind_IdentifierExpression,
151 Kind_IdentifierPropertyName,
152 Kind_InitializerExpression,
153 Kind_ComputedPropertyName,
154 Kind_IfStatement,
155 Kind_LabelledStatement,
156 Kind_NameSpaceImport,
157 Kind_ImportSpecifier,
158 Kind_ImportsList,
159 Kind_NamedImports,
160 Kind_ImportClause,
161 Kind_FromClause,
162 Kind_ImportDeclaration,
163 Kind_Module,
164 Kind_ExportSpecifier,
165 Kind_ExportsList,
166 Kind_ExportClause,
167 Kind_ExportDeclaration,
168 Kind_NewExpression,
169 Kind_NewMemberExpression,
170 Kind_NotExpression,
171 Kind_NullExpression,
172 Kind_YieldExpression,
173 Kind_NumericLiteral,
174 Kind_NumericLiteralPropertyName,
175 Kind_ObjectPattern,
176 Kind_PostDecrementExpression,
177 Kind_PostIncrementExpression,
178 Kind_PreDecrementExpression,
179 Kind_PreIncrementExpression,
180 Kind_Program,
181 Kind_PropertyDefinitionList,
182 Kind_PropertyGetterSetter,
183 Kind_PropertyName,
184 Kind_PropertyNameAndValue,
185 Kind_RegExpLiteral,
186 Kind_ReturnStatement,
187 Kind_StatementList,
188 Kind_StringLiteral,
189 Kind_StringLiteralPropertyName,
190 Kind_SwitchStatement,
191 Kind_TemplateLiteral,
192 Kind_TaggedTemplate,
193 Kind_TypeExpression,
194 Kind_ThisExpression,
195 Kind_ThrowStatement,
196 Kind_TildeExpression,
197 Kind_TrueLiteral,
198 Kind_TryStatement,
199 Kind_TypeOfExpression,
200 Kind_UnaryMinusExpression,
201 Kind_UnaryPlusExpression,
202 Kind_VariableDeclaration,
203 Kind_VariableDeclarationList,
204 Kind_VariableStatement,
205 Kind_VoidExpression,
206 Kind_WhileStatement,
207 Kind_WithStatement,
208 Kind_NestedExpression,
209 Kind_ClassElementList,
210 Kind_PatternElement,
211 Kind_PatternElementList,
212 Kind_PatternProperty,
213 Kind_PatternPropertyList,
214 Kind_Type,
215 Kind_TypeArgument,
216 Kind_TypeAnnotation,
217
218 Kind_UiArrayBinding,
219 Kind_UiImport,
220 Kind_UiObjectBinding,
221 Kind_UiObjectDefinition,
222 Kind_UiInlineComponent,
223 Kind_UiObjectInitializer,
224 Kind_UiObjectMemberList,
225 Kind_UiArrayMemberList,
226 Kind_UiPragmaValueList,
227 Kind_UiPragma,
228 Kind_UiProgram,
229 Kind_UiParameterList,
230 Kind_UiPropertyAttributes,
231 Kind_UiPublicMember,
232 Kind_UiQualifiedId,
233 Kind_UiScriptBinding,
234 Kind_UiSourceElement,
235 Kind_UiHeaderItemList,
236 Kind_UiEnumDeclaration,
237 Kind_UiEnumMemberList,
238 Kind_UiVersionSpecifier,
239 Kind_UiRequired,
240 Kind_UiAnnotation,
241 Kind_UiAnnotationList
242 };
243
244 inline Node() {}
245
246 // NOTE: node destructors are never called,
247 // instead we block free the memory
248 // (see the NodePool class)
249 virtual ~Node() {}
250
251 virtual ExpressionNode *expressionCast();
252 virtual BinaryExpression *binaryExpressionCast();
253 virtual Statement *statementCast();
254 virtual UiObjectMember *uiObjectMemberCast();
255 virtual LeftHandSideExpression *leftHandSideExpressionCast();
256 virtual Pattern *patternCast();
257 // implements the IsFunctionDefinition rules in the spec
258 virtual FunctionExpression *asFunctionDefinition();
259 virtual ClassExpression *asClassDefinition();
260
261 bool ignoreRecursionDepth() const;
262
263 inline void accept(BaseVisitor *visitor)
264 {
265 BaseVisitor::RecursionDepthCheck recursionCheck(visitor);
266
267 // Stack overflow is uncommon, ignoreRecursionDepth() only returns true if
268 // QV4_CRASH_ON_STACKOVERFLOW is set, and ignoreRecursionDepth() needs to be out of line.
269 // Therefore, check for ignoreRecursionDepth() _after_ calling the inline recursionCheck().
270 if (recursionCheck() || ignoreRecursionDepth()) {
271 if (visitor->preVisit(this))
272 accept0(visitor);
273 visitor->postVisit(this);
274 } else {
275 visitor->throwRecursionDepthError();
276 }
277 }
278
279 inline static void accept(Node *node, BaseVisitor *visitor)
280 {
281 if (node)
282 node->accept(visitor);
283 }
284
285 virtual void accept0(BaseVisitor *visitor) = 0;
286 virtual SourceLocation firstSourceLocation() const = 0;
287 virtual SourceLocation lastSourceLocation() const = 0;
288
289// attributes
290 int kind = Kind_Undefined;
291};
292
293template<typename T>
294T lastListElement(T head)
295{
296 auto current = head;
297 while (current->next)
298 current = current->next;
299 return current;
300}
301
302class QML_PARSER_EXPORT UiQualifiedId: public Node
303{
304public:
305 QQMLJS_DECLARE_AST_NODE(UiQualifiedId)
306
307 UiQualifiedId(QStringView name)
308 : next(this), name(name)
309 { kind = K; }
310
311 UiQualifiedId(UiQualifiedId *previous, QStringView name)
312 : name(name)
313 {
314 kind = K;
315 next = previous->next;
316 previous->next = this;
317 }
318
319 UiQualifiedId *finish()
320 {
321 UiQualifiedId *head = next;
322 next = nullptr;
323 return head;
324 }
325
326 void accept0(BaseVisitor *visitor) override;
327
328 SourceLocation firstSourceLocation() const override
329 { return identifierToken; }
330
331 SourceLocation lastSourceLocation() const override
332 {
333 return lastListElement(head: this)->lastOwnSourceLocation();
334 }
335
336 SourceLocation lastOwnSourceLocation() const { return identifierToken; }
337
338 QString toString() const
339 {
340 QString result;
341 toString(out: &result);
342 return result;
343 }
344
345 void toString(QString *out) const
346 {
347 for (const UiQualifiedId *it = this; it; it = it->next) {
348 out->append(v: it->name);
349 if (it->next)
350 out->append(c: QLatin1Char('.'));
351 }
352 }
353
354// attributes
355 UiQualifiedId *next;
356 QStringView name;
357 SourceLocation identifierToken;
358 SourceLocation dotToken;
359};
360
361class QML_PARSER_EXPORT Type: public Node
362{
363public:
364 QQMLJS_DECLARE_AST_NODE(Type)
365
366 Type(UiQualifiedId *typeId, Type *typeArgument = nullptr)
367 : typeId(typeId)
368 , typeArgument(typeArgument ? typeArgument->typeId : nullptr)
369 { kind = K; }
370
371 void accept0(BaseVisitor *visitor) override;
372
373 SourceLocation firstSourceLocation() const override
374 { return typeId->firstSourceLocation(); }
375
376 SourceLocation lastSourceLocation() const override
377 { return typeArgument ? typeArgument->lastSourceLocation() : typeId->lastSourceLocation(); }
378
379 QString toString() const;
380 void toString(QString *out) const;
381
382// attributes
383 UiQualifiedId *typeId;
384 UiQualifiedId *typeArgument;
385};
386
387class QML_PARSER_EXPORT TypeAnnotation: public Node
388{
389public:
390 QQMLJS_DECLARE_AST_NODE(TypeAnnotation)
391
392 TypeAnnotation(Type *type)
393 : type(type)
394 { kind = K; }
395
396 void accept0(BaseVisitor *visitor) override;
397
398 SourceLocation firstSourceLocation() const override
399 { return colonToken; }
400
401 SourceLocation lastSourceLocation() const override
402 { return type->lastSourceLocation(); }
403
404// attributes
405 Type *type;
406 SourceLocation colonToken;
407};
408class QML_PARSER_EXPORT ExpressionNode: public Node
409{
410public:
411 ExpressionNode() {}
412
413 ExpressionNode *expressionCast() override;
414 bool containsOptionalChain() const;
415
416 AST::FormalParameterList *reparseAsFormalParameterList(MemoryPool *pool);
417
418};
419
420class QML_PARSER_EXPORT LeftHandSideExpression : public ExpressionNode
421{
422 LeftHandSideExpression *leftHandSideExpressionCast() override;
423};
424
425class QML_PARSER_EXPORT Statement: public Node
426{
427public:
428 Statement() {}
429
430 Statement *statementCast() override;
431};
432
433class QML_PARSER_EXPORT NestedExpression: public LeftHandSideExpression
434{
435public:
436 QQMLJS_DECLARE_AST_NODE(NestedExpression)
437
438 NestedExpression(ExpressionNode *expression)
439 : expression(expression)
440 { kind = K; }
441
442 void accept0(BaseVisitor *visitor) override;
443
444 SourceLocation firstSourceLocation() const override
445 { return lparenToken; }
446
447 SourceLocation lastSourceLocation() const override
448 { return rparenToken; }
449
450 FunctionExpression *asFunctionDefinition() override;
451 ClassExpression *asClassDefinition() override;
452
453
454// attributes
455 ExpressionNode *expression;
456 SourceLocation lparenToken;
457 SourceLocation rparenToken;
458};
459
460
461class QML_PARSER_EXPORT TypeExpression : public ExpressionNode
462{
463public:
464 QQMLJS_DECLARE_AST_NODE(TypeExpression)
465 TypeExpression(Type *t) : m_type(t) { kind = K; }
466
467 void accept0(BaseVisitor *visitor) override;
468
469 SourceLocation firstSourceLocation() const override {
470 return m_type->firstSourceLocation();
471 }
472
473 SourceLocation lastSourceLocation() const override {
474 return m_type->lastSourceLocation();
475 }
476
477 Type *m_type;
478};
479
480class QML_PARSER_EXPORT ThisExpression: public LeftHandSideExpression
481{
482public:
483 QQMLJS_DECLARE_AST_NODE(ThisExpression)
484
485 ThisExpression() { kind = K; }
486
487 void accept0(BaseVisitor *visitor) override;
488
489 SourceLocation firstSourceLocation() const override
490 { return thisToken; }
491
492 SourceLocation lastSourceLocation() const override
493 { return thisToken; }
494
495// attributes
496 SourceLocation thisToken;
497};
498
499class QML_PARSER_EXPORT IdentifierExpression: public LeftHandSideExpression
500{
501public:
502 QQMLJS_DECLARE_AST_NODE(IdentifierExpression)
503
504 IdentifierExpression(QStringView n):
505 name (n) { kind = K; }
506
507 void accept0(BaseVisitor *visitor) override;
508
509 SourceLocation firstSourceLocation() const override
510 { return identifierToken; }
511
512 SourceLocation lastSourceLocation() const override
513 { return identifierToken; }
514
515// attributes
516 QStringView name;
517 SourceLocation identifierToken;
518};
519
520class QML_PARSER_EXPORT NullExpression: public LeftHandSideExpression
521{
522public:
523 QQMLJS_DECLARE_AST_NODE(NullExpression)
524
525 NullExpression() { kind = K; }
526
527 void accept0(BaseVisitor *visitor) override;
528
529 SourceLocation firstSourceLocation() const override
530 { return nullToken; }
531
532 SourceLocation lastSourceLocation() const override
533 { return nullToken; }
534
535// attributes
536 SourceLocation nullToken;
537};
538
539class QML_PARSER_EXPORT TrueLiteral: public LeftHandSideExpression
540{
541public:
542 QQMLJS_DECLARE_AST_NODE(TrueLiteral)
543
544 TrueLiteral() { kind = K; }
545
546 void accept0(BaseVisitor *visitor) override;
547
548 SourceLocation firstSourceLocation() const override
549 { return trueToken; }
550
551 SourceLocation lastSourceLocation() const override
552 { return trueToken; }
553
554// attributes
555 SourceLocation trueToken;
556};
557
558class QML_PARSER_EXPORT FalseLiteral: public LeftHandSideExpression
559{
560public:
561 QQMLJS_DECLARE_AST_NODE(FalseLiteral)
562
563 FalseLiteral() { kind = K; }
564
565 void accept0(BaseVisitor *visitor) override;
566
567 SourceLocation firstSourceLocation() const override
568 { return falseToken; }
569
570 SourceLocation lastSourceLocation() const override
571 { return falseToken; }
572
573// attributes
574 SourceLocation falseToken;
575};
576
577class QML_PARSER_EXPORT SuperLiteral : public LeftHandSideExpression
578{
579public:
580 QQMLJS_DECLARE_AST_NODE(SuperLiteral)
581
582 SuperLiteral() { kind = K; }
583
584 void accept0(BaseVisitor *visitor) override;
585
586 SourceLocation firstSourceLocation() const override
587 { return superToken; }
588
589 SourceLocation lastSourceLocation() const override
590 { return superToken; }
591
592// attributes
593 SourceLocation superToken;
594};
595
596
597class QML_PARSER_EXPORT NumericLiteral: public LeftHandSideExpression
598{
599public:
600 QQMLJS_DECLARE_AST_NODE(NumericLiteral)
601
602 NumericLiteral(double v):
603 value(v) { kind = K; }
604
605 void accept0(BaseVisitor *visitor) override;
606
607 SourceLocation firstSourceLocation() const override
608 { return literalToken; }
609
610 SourceLocation lastSourceLocation() const override
611 { return literalToken; }
612
613// attributes:
614 double value;
615 SourceLocation literalToken;
616};
617
618class QML_PARSER_EXPORT UiVersionSpecifier : public Node
619{
620public:
621 QQMLJS_DECLARE_AST_NODE(UiVersionSpecifier)
622
623 UiVersionSpecifier(int majorum) : version(QTypeRevision::fromMajorVersion(majorVersion: majorum))
624 {
625 kind = K;
626 }
627
628 UiVersionSpecifier(int majorum, int minorum) : version(QTypeRevision::fromVersion(majorVersion: majorum, minorVersion: minorum))
629 {
630 kind = K;
631 }
632
633 void accept0(BaseVisitor *visitor) override;
634
635 SourceLocation firstSourceLocation() const override { return majorToken; }
636
637 SourceLocation lastSourceLocation() const override
638 {
639 return minorToken.isValid() ? minorToken : majorToken;
640 }
641
642 // attributes:
643 QTypeRevision version;
644 SourceLocation majorToken;
645 SourceLocation minorToken;
646};
647
648class QML_PARSER_EXPORT StringLiteral : public LeftHandSideExpression
649{
650public:
651 QQMLJS_DECLARE_AST_NODE(StringLiteral)
652
653 StringLiteral(QStringView v):
654 value (v) { kind = K; }
655
656 void accept0(BaseVisitor *visitor) override;
657
658 SourceLocation firstSourceLocation() const override
659 { return literalToken; }
660
661 SourceLocation lastSourceLocation() const override
662 { return literalToken; }
663
664// attributes:
665 QStringView value;
666 SourceLocation literalToken;
667};
668
669class QML_PARSER_EXPORT TemplateLiteral : public LeftHandSideExpression
670{
671public:
672 QQMLJS_DECLARE_AST_NODE(TemplateLiteral)
673
674 TemplateLiteral(QStringView str, QStringView raw, ExpressionNode *e)
675 : value(str), rawValue(raw), expression(e), next(nullptr)
676 { kind = K; }
677
678 SourceLocation firstSourceLocation() const override
679 { return literalToken; }
680
681 SourceLocation lastSourceLocation() const override
682 {
683 auto last = lastListElement(head: this);
684 return (last->expression ? last->expression->lastSourceLocation() : last->literalToken);
685 }
686
687 void accept0(BaseVisitor *visitor) override;
688
689 bool hasNoSubstitution = false;
690 QStringView value;
691 QStringView rawValue;
692 ExpressionNode *expression;
693 TemplateLiteral *next;
694 SourceLocation literalToken;
695};
696
697class QML_PARSER_EXPORT RegExpLiteral: public LeftHandSideExpression
698{
699public:
700 QQMLJS_DECLARE_AST_NODE(RegExpLiteral)
701
702 RegExpLiteral(QStringView p, int f):
703 pattern (p), flags (f) { kind = K; }
704
705 void accept0(BaseVisitor *visitor) override;
706
707 SourceLocation firstSourceLocation() const override
708 { return literalToken; }
709
710 SourceLocation lastSourceLocation() const override
711 { return literalToken; }
712
713// attributes:
714 QStringView pattern;
715 int flags;
716 SourceLocation literalToken;
717};
718
719class QML_PARSER_EXPORT Pattern : public LeftHandSideExpression
720{
721public:
722 enum ParseMode {
723 Literal,
724 Binding
725 };
726 Pattern *patternCast() override;
727 virtual bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) = 0;
728 ParseMode parseMode = Literal;
729};
730
731class QML_PARSER_EXPORT ArrayPattern : public Pattern
732{
733public:
734 QQMLJS_DECLARE_AST_NODE(ArrayPattern)
735
736 ArrayPattern(PatternElementList *elts)
737 : elements(elts)
738 { kind = K; }
739
740 void accept0(BaseVisitor *visitor) override;
741
742 SourceLocation firstSourceLocation() const override
743 { return lbracketToken; }
744
745 SourceLocation lastSourceLocation() const override
746 { return rbracketToken; }
747
748 bool isValidArrayLiteral(SourceLocation *errorLocation = nullptr) const;
749
750 bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override;
751
752// attributes
753 PatternElementList *elements = nullptr;
754 SourceLocation lbracketToken;
755 SourceLocation commaToken;
756 SourceLocation rbracketToken;
757};
758
759class QML_PARSER_EXPORT ObjectPattern : public Pattern
760{
761public:
762 QQMLJS_DECLARE_AST_NODE(ObjectPattern)
763
764 ObjectPattern()
765 { kind = K; }
766
767 ObjectPattern(PatternPropertyList *plist)
768 : properties(plist)
769 { kind = K; }
770
771 void accept0(BaseVisitor *visitor) override;
772
773 SourceLocation firstSourceLocation() const override
774 { return lbraceToken; }
775
776 SourceLocation lastSourceLocation() const override
777 { return rbraceToken; }
778
779 bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override;
780
781// attributes
782 PatternPropertyList *properties = nullptr;
783 SourceLocation lbraceToken;
784 SourceLocation rbraceToken;
785};
786
787class QML_PARSER_EXPORT Elision: public Node
788{
789public:
790 QQMLJS_DECLARE_AST_NODE(Elision)
791
792 Elision():
793 next (this) { kind = K; }
794
795 Elision(Elision *previous)
796 {
797 kind = K;
798 next = previous->next;
799 previous->next = this;
800 }
801
802 void accept0(BaseVisitor *visitor) override;
803
804 SourceLocation firstSourceLocation() const override
805 { return commaToken; }
806
807 SourceLocation lastSourceLocation() const override
808 { return lastListElement(head: this)->commaToken; }
809
810 inline Elision *finish ()
811 {
812 Elision *front = next;
813 next = nullptr;
814 return front;
815 }
816
817// attributes
818 Elision *next;
819 SourceLocation commaToken;
820};
821
822class QML_PARSER_EXPORT PropertyName: public Node
823{
824public:
825 QQMLJS_DECLARE_AST_NODE(PropertyName)
826
827 PropertyName() { kind = K; }
828
829 SourceLocation firstSourceLocation() const override
830 { return propertyNameToken; }
831
832 SourceLocation lastSourceLocation() const override
833 { return propertyNameToken; }
834
835 virtual QString asString() const = 0;
836
837// attributes
838 SourceLocation propertyNameToken;
839};
840
841struct QML_PARSER_EXPORT BoundName
842{
843 enum Type {
844 Declared,
845 Injected,
846 };
847
848 QString id;
849 QQmlJS::SourceLocation location;
850 QTaggedPointer<TypeAnnotation, Type> typeAnnotation;
851 BoundName(const QString &id, const QQmlJS::SourceLocation &location,
852 TypeAnnotation *typeAnnotation, Type type = Declared)
853 : id(id), location(location), typeAnnotation(typeAnnotation, type)
854 {}
855 BoundName() = default;
856
857 bool isInjected() const { return typeAnnotation.tag() == Injected; }
858};
859
860struct BoundNames : public QVector<BoundName>
861{
862 int indexOf(const QString &name, int from = 0) const
863 {
864 auto found = std::find_if(first: constBegin() + from, last: constEnd(),
865 pred: [name](const BoundName &it) { return it.id == name; });
866 if (found == constEnd())
867 return -1;
868 return found - constBegin();
869 }
870
871 bool contains(const QString &name) const
872 {
873 return indexOf(name) != -1;
874 }
875};
876
877/*!
878\internal
879This class is needed to pass the information about the equalToken in the parser, and is only needed
880during AST construction. It behaves exactly like the expression it contains: that avoids changing
881all the usages in qqmljs.g from ExpressionNode to InitializerExpression for every rule expecting a
882InitializerOpt_In or InitializerOpt.
883*/
884class QML_PARSER_EXPORT InitializerExpression : public ExpressionNode
885{
886public:
887 QQMLJS_DECLARE_AST_NODE(InitializerExpression)
888
889 InitializerExpression(ExpressionNode *e) : expression(e) { kind = K; }
890
891 void accept0(BaseVisitor *visitor) override;
892
893 SourceLocation firstSourceLocation() const override
894 { return equalToken; }
895
896 SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); }
897
898 FunctionExpression *asFunctionDefinition() override
899 {
900 return expression->asFunctionDefinition();
901 }
902
903 ClassExpression *asClassDefinition() override { return expression->asClassDefinition(); }
904
905 // attributes
906 ExpressionNode *expression;
907 SourceLocation equalToken;
908};
909
910class QML_PARSER_EXPORT PatternElement : public Node
911{
912public:
913 QQMLJS_DECLARE_AST_NODE(PatternElement)
914
915 enum Type {
916 // object literal types
917 Literal,
918 Method,
919 Getter,
920 Setter,
921
922 // used by both bindings and literals
923 SpreadElement,
924 RestElement = SpreadElement,
925
926 // binding types
927 Binding,
928 };
929
930private:
931 /*!
932 \internal
933 Hide InitializerExpression from the AST. InitializerExpression is only needed during parsing for
934 the AST construction, and it is not possible for the parser to directly embed the location of
935 equal tokens inside the PatternElement without the InitializerExpression.
936 */
937 void unwrapInitializer()
938 {
939 if (auto unwrapped = AST::cast<InitializerExpression *>(ast: initializer)) {
940 equalToken = unwrapped->equalToken;
941 initializer = unwrapped->expression;
942 }
943 }
944public:
945
946 PatternElement(ExpressionNode *i = nullptr, Type t = Literal)
947 : initializer(i), type(t)
948 {
949 kind = K;
950 unwrapInitializer();
951 }
952
953 PatternElement(QStringView n, TypeAnnotation *typeAnnotation = nullptr, ExpressionNode *i = nullptr, Type t = Binding)
954 : bindingIdentifier(n), initializer(i), type(t)
955 , typeAnnotation(typeAnnotation)
956 {
957 Q_ASSERT(t >= RestElement);
958 kind = K;
959 unwrapInitializer();
960 }
961
962 PatternElement(Pattern *pattern, ExpressionNode *i = nullptr, Type t = Binding)
963 : bindingTarget(pattern), initializer(i), type(t)
964 {
965 Q_ASSERT(t >= RestElement);
966 kind = K;
967 unwrapInitializer();
968 }
969
970 void accept0(BaseVisitor *visitor) override;
971 virtual bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage);
972
973 SourceLocation firstSourceLocation() const override
974 { return identifierToken.isValid() ? identifierToken : (bindingTarget ? bindingTarget->firstSourceLocation() : initializer->firstSourceLocation()); }
975
976 SourceLocation lastSourceLocation() const override
977 { return initializer ? initializer->lastSourceLocation() : (bindingTarget ? bindingTarget->lastSourceLocation() : (typeAnnotation ? typeAnnotation->lastSourceLocation() : identifierToken)); }
978
979 ExpressionNode *destructuringTarget() const { return bindingTarget; }
980 Pattern *destructuringPattern() const { return bindingTarget ? bindingTarget->patternCast() : nullptr; }
981 PatternElementList *elementList() const { ArrayPattern *a = cast<ArrayPattern *>(ast: bindingTarget); return a ? a->elements : nullptr; }
982 PatternPropertyList *propertyList() const { ObjectPattern *o = cast<ObjectPattern *>(ast: bindingTarget); return o ? o->properties : nullptr; }
983
984 bool isVariableDeclaration() const { return scope != VariableScope::NoScope; }
985 bool isLexicallyScoped() const { return scope == VariableScope::Let || scope == VariableScope::Const; }
986
987 virtual void boundNames(BoundNames *names);
988
989// attributes
990 SourceLocation identifierToken;
991 SourceLocation equalToken;
992 QStringView bindingIdentifier;
993 ExpressionNode *bindingTarget = nullptr;
994 ExpressionNode *initializer = nullptr;
995 Type type = Literal;
996 TypeAnnotation *typeAnnotation = nullptr;
997 // when used in a VariableDeclarationList
998 SourceLocation declarationKindToken;
999 VariableScope scope = VariableScope::NoScope;
1000 bool isForDeclaration = false;
1001 bool isInjectedSignalParameter = false;
1002};
1003
1004class QML_PARSER_EXPORT PatternElementList : public Node
1005{
1006public:
1007 QQMLJS_DECLARE_AST_NODE(PatternElementList)
1008
1009 PatternElementList(Elision *elision, PatternElement *element)
1010 : elision(elision), element(element), next(this)
1011 { kind = K; }
1012
1013 PatternElementList *append(PatternElementList *n) {
1014 n->next = next;
1015 next = n;
1016 return n;
1017 }
1018
1019 inline PatternElementList *finish ()
1020 {
1021 PatternElementList *front = next;
1022 next = 0;
1023 return front;
1024 }
1025
1026 void accept0(BaseVisitor *visitor) override;
1027
1028 void boundNames(BoundNames *names);
1029
1030 SourceLocation firstSourceLocation() const override
1031 { return elision ? elision->firstSourceLocation() : element->firstSourceLocation(); }
1032
1033 SourceLocation lastSourceLocation() const override
1034 {
1035 auto last = lastListElement(head: this);
1036 return last->element ? last->element->lastSourceLocation() : last->elision->lastSourceLocation();
1037 }
1038
1039 Elision *elision = nullptr;
1040 PatternElement *element = nullptr;
1041 PatternElementList *next;
1042};
1043
1044class QML_PARSER_EXPORT PatternProperty : public PatternElement
1045{
1046public:
1047 QQMLJS_DECLARE_AST_NODE(PatternProperty)
1048
1049 PatternProperty(PropertyName *name, ExpressionNode *i = nullptr, Type t = Literal)
1050 : PatternElement(i, t), name(name)
1051 { kind = K; }
1052
1053 PatternProperty(PropertyName *name, QStringView n, ExpressionNode *i = nullptr)
1054 : PatternElement(n, /*type annotation*/nullptr, i), name(name)
1055 { kind = K; }
1056
1057 PatternProperty(PropertyName *name, Pattern *pattern, ExpressionNode *i = nullptr)
1058 : PatternElement(pattern, i), name(name)
1059 { kind = K; }
1060
1061 void accept0(BaseVisitor *visitor) override;
1062
1063 SourceLocation firstSourceLocation() const override
1064 { return name->firstSourceLocation(); }
1065 SourceLocation lastSourceLocation() const override
1066 {
1067 SourceLocation loc = PatternElement::lastSourceLocation();
1068 return loc.isValid() ? loc : name->lastSourceLocation();
1069 }
1070
1071 void boundNames(BoundNames *names) override;
1072 bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override;
1073
1074// attributes
1075 PropertyName *name;
1076 SourceLocation colonToken;
1077};
1078
1079
1080class QML_PARSER_EXPORT PatternPropertyList : public Node
1081{
1082public:
1083 QQMLJS_DECLARE_AST_NODE(PatternPropertyList)
1084
1085 PatternPropertyList(PatternProperty *property)
1086 : property(property), next(this)
1087 { kind = K; }
1088
1089 PatternPropertyList(PatternPropertyList *previous, PatternProperty *property)
1090 : property(property), next(this)
1091 {
1092 kind = K;
1093 next = previous->next;
1094 previous->next = this;
1095 }
1096
1097 void accept0(BaseVisitor *visitor) override;
1098
1099 void boundNames(BoundNames *names);
1100
1101 inline PatternPropertyList *finish ()
1102 {
1103 PatternPropertyList *front = next;
1104 next = 0;
1105 return front;
1106 }
1107
1108 SourceLocation firstSourceLocation() const override
1109 { return property->firstSourceLocation(); }
1110
1111 SourceLocation lastSourceLocation() const override
1112 { return lastListElement(head: this)->property->lastSourceLocation(); }
1113
1114 PatternProperty *property;
1115 PatternPropertyList *next;
1116};
1117
1118class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName
1119{
1120public:
1121 QQMLJS_DECLARE_AST_NODE(IdentifierPropertyName)
1122
1123 IdentifierPropertyName(QStringView n):
1124 id (n) { kind = K; }
1125
1126 void accept0(BaseVisitor *visitor) override;
1127
1128 QString asString() const override { return id.toString(); }
1129
1130// attributes
1131 QStringView id;
1132};
1133
1134class QML_PARSER_EXPORT StringLiteralPropertyName: public PropertyName
1135{
1136public:
1137 QQMLJS_DECLARE_AST_NODE(StringLiteralPropertyName)
1138
1139 StringLiteralPropertyName(QStringView n):
1140 id (n) { kind = K; }
1141
1142 void accept0(BaseVisitor *visitor) override;
1143
1144 QString asString() const override { return id.toString(); }
1145
1146// attributes
1147 QStringView id;
1148};
1149
1150class QML_PARSER_EXPORT NumericLiteralPropertyName: public PropertyName
1151{
1152public:
1153 QQMLJS_DECLARE_AST_NODE(NumericLiteralPropertyName)
1154
1155 NumericLiteralPropertyName(double n):
1156 id (n) { kind = K; }
1157
1158 void accept0(BaseVisitor *visitor) override;
1159
1160 QString asString() const override;
1161
1162// attributes
1163 double id;
1164};
1165
1166class QML_PARSER_EXPORT ComputedPropertyName : public PropertyName
1167{
1168public:
1169 QQMLJS_DECLARE_AST_NODE(ComputedPropertyName)
1170
1171 ComputedPropertyName(ExpressionNode *expression)
1172 : expression(expression)
1173 { kind = K; }
1174
1175 void accept0(BaseVisitor *visitor) override;
1176
1177 QString asString() const override { return QString(); }
1178
1179 SourceLocation firstSourceLocation() const override
1180 { return expression->firstSourceLocation(); }
1181
1182 SourceLocation lastSourceLocation() const override
1183 { return expression->lastSourceLocation(); }
1184
1185// attributes
1186 ExpressionNode *expression;
1187};
1188
1189
1190class QML_PARSER_EXPORT ArrayMemberExpression: public LeftHandSideExpression
1191{
1192public:
1193 QQMLJS_DECLARE_AST_NODE(ArrayMemberExpression)
1194
1195 ArrayMemberExpression(ExpressionNode *b, ExpressionNode *e):
1196 base (b), expression (e)
1197 { kind = K; }
1198
1199 void accept0(BaseVisitor *visitor) override;
1200
1201 SourceLocation firstSourceLocation() const override
1202 { return base->firstSourceLocation(); }
1203
1204 SourceLocation lastSourceLocation() const override
1205 { return rbracketToken; }
1206
1207// attributes
1208 ExpressionNode *base;
1209 ExpressionNode *expression;
1210 SourceLocation optionalToken;
1211 SourceLocation lbracketToken;
1212 SourceLocation rbracketToken;
1213 bool isOptional = false;
1214};
1215
1216class QML_PARSER_EXPORT FieldMemberExpression: public LeftHandSideExpression
1217{
1218public:
1219 QQMLJS_DECLARE_AST_NODE(FieldMemberExpression)
1220
1221 FieldMemberExpression(ExpressionNode *b, QStringView n):
1222 base (b), name (n)
1223 { kind = K; }
1224
1225 void accept0(BaseVisitor *visitor) override;
1226
1227 SourceLocation firstSourceLocation() const override
1228 { return base->firstSourceLocation(); }
1229
1230 SourceLocation lastSourceLocation() const override
1231 { return identifierToken; }
1232
1233 // attributes
1234 ExpressionNode *base;
1235 QStringView name;
1236 SourceLocation dotToken;
1237 SourceLocation identifierToken;
1238 bool isOptional = false;
1239};
1240
1241class QML_PARSER_EXPORT TaggedTemplate : public LeftHandSideExpression
1242{
1243public:
1244 QQMLJS_DECLARE_AST_NODE(TaggedTemplate)
1245
1246 TaggedTemplate(ExpressionNode *b, TemplateLiteral *t)
1247 : base (b), templateLiteral(t)
1248 { kind = K; }
1249
1250 void accept0(BaseVisitor *visitor) override;
1251
1252 SourceLocation firstSourceLocation() const override
1253 { return base->firstSourceLocation(); }
1254
1255 SourceLocation lastSourceLocation() const override
1256 { return templateLiteral->lastSourceLocation(); }
1257
1258 // attributes
1259 ExpressionNode *base;
1260 TemplateLiteral *templateLiteral;
1261};
1262
1263class QML_PARSER_EXPORT NewMemberExpression: public LeftHandSideExpression
1264{
1265public:
1266 QQMLJS_DECLARE_AST_NODE(NewMemberExpression)
1267
1268 NewMemberExpression(ExpressionNode *b, ArgumentList *a):
1269 base (b), arguments (a)
1270 { kind = K; }
1271
1272 void accept0(BaseVisitor *visitor) override;
1273
1274 SourceLocation firstSourceLocation() const override
1275 { return newToken; }
1276
1277 SourceLocation lastSourceLocation() const override
1278 { return rparenToken; }
1279
1280 // attributes
1281 ExpressionNode *base;
1282 ArgumentList *arguments;
1283 SourceLocation newToken;
1284 SourceLocation lparenToken;
1285 SourceLocation rparenToken;
1286};
1287
1288class QML_PARSER_EXPORT NewExpression: public LeftHandSideExpression
1289{
1290public:
1291 QQMLJS_DECLARE_AST_NODE(NewExpression)
1292
1293 NewExpression(ExpressionNode *e):
1294 expression (e) { kind = K; }
1295
1296 void accept0(BaseVisitor *visitor) override;
1297
1298 SourceLocation firstSourceLocation() const override
1299 { return newToken; }
1300
1301 SourceLocation lastSourceLocation() const override
1302 { return expression->lastSourceLocation(); }
1303
1304// attributes
1305 ExpressionNode *expression;
1306 SourceLocation newToken;
1307};
1308
1309class QML_PARSER_EXPORT CallExpression: public LeftHandSideExpression
1310{
1311public:
1312 QQMLJS_DECLARE_AST_NODE(CallExpression)
1313
1314 CallExpression(ExpressionNode *b, ArgumentList *a):
1315 base (b), arguments (a)
1316 { kind = K; }
1317
1318 void accept0(BaseVisitor *visitor) override;
1319
1320 SourceLocation firstSourceLocation() const override
1321 { return base->firstSourceLocation(); }
1322
1323 SourceLocation lastSourceLocation() const override
1324 { return rparenToken; }
1325
1326// attributes
1327 ExpressionNode *base;
1328 ArgumentList *arguments;
1329 SourceLocation optionalToken;
1330 SourceLocation lparenToken;
1331 SourceLocation rparenToken;
1332 bool isOptional = false;
1333};
1334
1335class QML_PARSER_EXPORT ArgumentList: public Node
1336{
1337public:
1338 QQMLJS_DECLARE_AST_NODE(ArgumentList)
1339
1340 ArgumentList(ExpressionNode *e):
1341 expression (e), next (this)
1342 { kind = K; }
1343
1344 ArgumentList(ArgumentList *previous, ExpressionNode *e):
1345 expression (e)
1346 {
1347 kind = K;
1348 next = previous->next;
1349 previous->next = this;
1350 }
1351
1352 void accept0(BaseVisitor *visitor) override;
1353
1354 SourceLocation firstSourceLocation() const override
1355 { return expression->firstSourceLocation(); }
1356
1357 SourceLocation lastSourceLocation() const override
1358 {
1359 if (next)
1360 return next->lastSourceLocation();
1361 return expression->lastSourceLocation();
1362 }
1363
1364 inline ArgumentList *finish ()
1365 {
1366 ArgumentList *front = next;
1367 next = nullptr;
1368 return front;
1369 }
1370
1371// attributes
1372 ExpressionNode *expression;
1373 ArgumentList *next;
1374 SourceLocation commaToken;
1375 bool isSpreadElement = false;
1376};
1377
1378class QML_PARSER_EXPORT PostIncrementExpression: public ExpressionNode
1379{
1380public:
1381 QQMLJS_DECLARE_AST_NODE(PostIncrementExpression)
1382
1383 PostIncrementExpression(ExpressionNode *b):
1384 base (b) { kind = K; }
1385
1386 void accept0(BaseVisitor *visitor) override;
1387
1388 SourceLocation firstSourceLocation() const override
1389 { return base->firstSourceLocation(); }
1390
1391 SourceLocation lastSourceLocation() const override
1392 { return incrementToken; }
1393
1394// attributes
1395 ExpressionNode *base;
1396 SourceLocation incrementToken;
1397};
1398
1399class QML_PARSER_EXPORT PostDecrementExpression: public ExpressionNode
1400{
1401public:
1402 QQMLJS_DECLARE_AST_NODE(PostDecrementExpression)
1403
1404 PostDecrementExpression(ExpressionNode *b):
1405 base (b) { kind = K; }
1406
1407 void accept0(BaseVisitor *visitor) override;
1408
1409 SourceLocation firstSourceLocation() const override
1410 { return base->firstSourceLocation(); }
1411
1412 SourceLocation lastSourceLocation() const override
1413 { return decrementToken; }
1414
1415// attributes
1416 ExpressionNode *base;
1417 SourceLocation decrementToken;
1418};
1419
1420class QML_PARSER_EXPORT DeleteExpression: public ExpressionNode
1421{
1422public:
1423 QQMLJS_DECLARE_AST_NODE(DeleteExpression)
1424
1425 DeleteExpression(ExpressionNode *e):
1426 expression (e) { kind = K; }
1427
1428 void accept0(BaseVisitor *visitor) override;
1429
1430 SourceLocation firstSourceLocation() const override
1431 { return deleteToken; }
1432
1433 SourceLocation lastSourceLocation() const override
1434 { return expression->lastSourceLocation(); }
1435
1436// attributes
1437 ExpressionNode *expression;
1438 SourceLocation deleteToken;
1439};
1440
1441class QML_PARSER_EXPORT VoidExpression: public ExpressionNode
1442{
1443public:
1444 QQMLJS_DECLARE_AST_NODE(VoidExpression)
1445
1446 VoidExpression(ExpressionNode *e):
1447 expression (e) { kind = K; }
1448
1449 void accept0(BaseVisitor *visitor) override;
1450
1451 SourceLocation firstSourceLocation() const override
1452 { return voidToken; }
1453
1454 SourceLocation lastSourceLocation() const override
1455 { return expression->lastSourceLocation(); }
1456
1457// attributes
1458 ExpressionNode *expression;
1459 SourceLocation voidToken;
1460};
1461
1462class QML_PARSER_EXPORT TypeOfExpression: public ExpressionNode
1463{
1464public:
1465 QQMLJS_DECLARE_AST_NODE(TypeOfExpression)
1466
1467 TypeOfExpression(ExpressionNode *e):
1468 expression (e) { kind = K; }
1469
1470 void accept0(BaseVisitor *visitor) override;
1471
1472 SourceLocation firstSourceLocation() const override
1473 { return typeofToken; }
1474
1475 SourceLocation lastSourceLocation() const override
1476 { return expression->lastSourceLocation(); }
1477
1478// attributes
1479 ExpressionNode *expression;
1480 SourceLocation typeofToken;
1481};
1482
1483class QML_PARSER_EXPORT PreIncrementExpression: public ExpressionNode
1484{
1485public:
1486 QQMLJS_DECLARE_AST_NODE(PreIncrementExpression)
1487
1488 PreIncrementExpression(ExpressionNode *e):
1489 expression (e) { kind = K; }
1490
1491 void accept0(BaseVisitor *visitor) override;
1492
1493 SourceLocation firstSourceLocation() const override
1494 { return incrementToken; }
1495
1496 SourceLocation lastSourceLocation() const override
1497 { return expression->lastSourceLocation(); }
1498
1499// attributes
1500 ExpressionNode *expression;
1501 SourceLocation incrementToken;
1502};
1503
1504class QML_PARSER_EXPORT PreDecrementExpression: public ExpressionNode
1505{
1506public:
1507 QQMLJS_DECLARE_AST_NODE(PreDecrementExpression)
1508
1509 PreDecrementExpression(ExpressionNode *e):
1510 expression (e) { kind = K; }
1511
1512 void accept0(BaseVisitor *visitor) override;
1513
1514 SourceLocation firstSourceLocation() const override
1515 { return decrementToken; }
1516
1517 SourceLocation lastSourceLocation() const override
1518 { return expression->lastSourceLocation(); }
1519
1520// attributes
1521 ExpressionNode *expression;
1522 SourceLocation decrementToken;
1523};
1524
1525class QML_PARSER_EXPORT UnaryPlusExpression: public ExpressionNode
1526{
1527public:
1528 QQMLJS_DECLARE_AST_NODE(UnaryPlusExpression)
1529
1530 UnaryPlusExpression(ExpressionNode *e):
1531 expression (e) { kind = K; }
1532
1533 void accept0(BaseVisitor *visitor) override;
1534
1535 SourceLocation firstSourceLocation() const override
1536 { return plusToken; }
1537
1538 SourceLocation lastSourceLocation() const override
1539 { return expression->lastSourceLocation(); }
1540
1541// attributes
1542 ExpressionNode *expression;
1543 SourceLocation plusToken;
1544};
1545
1546class QML_PARSER_EXPORT UnaryMinusExpression: public ExpressionNode
1547{
1548public:
1549 QQMLJS_DECLARE_AST_NODE(UnaryMinusExpression)
1550
1551 UnaryMinusExpression(ExpressionNode *e):
1552 expression (e) { kind = K; }
1553
1554 void accept0(BaseVisitor *visitor) override;
1555
1556 SourceLocation firstSourceLocation() const override
1557 { return minusToken; }
1558
1559 SourceLocation lastSourceLocation() const override
1560 { return expression->lastSourceLocation(); }
1561
1562// attributes
1563 ExpressionNode *expression;
1564 SourceLocation minusToken;
1565};
1566
1567class QML_PARSER_EXPORT TildeExpression: public ExpressionNode
1568{
1569public:
1570 QQMLJS_DECLARE_AST_NODE(TildeExpression)
1571
1572 TildeExpression(ExpressionNode *e):
1573 expression (e) { kind = K; }
1574
1575 void accept0(BaseVisitor *visitor) override;
1576
1577 SourceLocation firstSourceLocation() const override
1578 { return tildeToken; }
1579
1580 SourceLocation lastSourceLocation() const override
1581 { return expression->lastSourceLocation(); }
1582
1583// attributes
1584 ExpressionNode *expression;
1585 SourceLocation tildeToken;
1586};
1587
1588class QML_PARSER_EXPORT NotExpression: public ExpressionNode
1589{
1590public:
1591 QQMLJS_DECLARE_AST_NODE(NotExpression)
1592
1593 NotExpression(ExpressionNode *e):
1594 expression (e) { kind = K; }
1595
1596 void accept0(BaseVisitor *visitor) override;
1597
1598 SourceLocation firstSourceLocation() const override
1599 { return notToken; }
1600
1601 SourceLocation lastSourceLocation() const override
1602 { return expression->lastSourceLocation(); }
1603
1604// attributes
1605 ExpressionNode *expression;
1606 SourceLocation notToken;
1607};
1608
1609class QML_PARSER_EXPORT BinaryExpression: public ExpressionNode
1610{
1611public:
1612 QQMLJS_DECLARE_AST_NODE(BinaryExpression)
1613
1614 BinaryExpression(ExpressionNode *l, int o, ExpressionNode *r):
1615 left (l), op (o), right (r)
1616 { kind = K; }
1617
1618 BinaryExpression *binaryExpressionCast() override;
1619
1620 void accept0(BaseVisitor *visitor) override;
1621
1622 SourceLocation firstSourceLocation() const override
1623 { return left->firstSourceLocation(); }
1624
1625 SourceLocation lastSourceLocation() const override
1626 { return right->lastSourceLocation(); }
1627
1628// attributes
1629 ExpressionNode *left;
1630 int op;
1631 ExpressionNode *right;
1632 SourceLocation operatorToken;
1633};
1634
1635class QML_PARSER_EXPORT ConditionalExpression: public ExpressionNode
1636{
1637public:
1638 QQMLJS_DECLARE_AST_NODE(ConditionalExpression)
1639
1640 ConditionalExpression(ExpressionNode *e, ExpressionNode *t, ExpressionNode *f):
1641 expression (e), ok (t), ko (f)
1642 { kind = K; }
1643
1644 void accept0(BaseVisitor *visitor) override;
1645
1646 SourceLocation firstSourceLocation() const override
1647 { return expression->firstSourceLocation(); }
1648
1649 SourceLocation lastSourceLocation() const override
1650 { return ko->lastSourceLocation(); }
1651
1652// attributes
1653 ExpressionNode *expression;
1654 ExpressionNode *ok;
1655 ExpressionNode *ko;
1656 SourceLocation questionToken;
1657 SourceLocation colonToken;
1658};
1659
1660class QML_PARSER_EXPORT Expression: public ExpressionNode // ### rename
1661{
1662public:
1663 QQMLJS_DECLARE_AST_NODE(Expression)
1664
1665 Expression(ExpressionNode *l, ExpressionNode *r):
1666 left (l), right (r) { kind = K; }
1667
1668 void accept0(BaseVisitor *visitor) override;
1669
1670 SourceLocation firstSourceLocation() const override
1671 { return left->firstSourceLocation(); }
1672
1673 SourceLocation lastSourceLocation() const override
1674 { return right->lastSourceLocation(); }
1675
1676// attributes
1677 ExpressionNode *left;
1678 ExpressionNode *right;
1679 SourceLocation commaToken;
1680};
1681
1682class QML_PARSER_EXPORT Block: public Statement
1683{
1684public:
1685 QQMLJS_DECLARE_AST_NODE(Block)
1686
1687 Block(StatementList *slist):
1688 statements (slist) { kind = K; }
1689
1690 void accept0(BaseVisitor *visitor) override;
1691
1692 SourceLocation firstSourceLocation() const override
1693 { return lbraceToken; }
1694
1695 SourceLocation lastSourceLocation() const override
1696 { return rbraceToken; }
1697
1698 // attributes
1699 StatementList *statements;
1700 SourceLocation lbraceToken;
1701 SourceLocation rbraceToken;
1702};
1703
1704class QML_PARSER_EXPORT StatementList: public Node
1705{
1706public:
1707 QQMLJS_DECLARE_AST_NODE(StatementList)
1708
1709 // ### This should be a Statement, but FunctionDeclaration currently doesn't inherit it.
1710 StatementList(Node *stmt)
1711 : statement(stmt), next (this)
1712 { kind = K; }
1713
1714 StatementList *append(StatementList *n) {
1715 n->next = next;
1716 next = n;
1717 return n;
1718 }
1719
1720 void accept0(BaseVisitor *visitor) override;
1721
1722 SourceLocation firstSourceLocation() const override
1723 { return statement->firstSourceLocation(); }
1724
1725 SourceLocation lastSourceLocation() const override
1726 {
1727 return lastListElement(head: this)->statement->lastSourceLocation();
1728 }
1729
1730 inline StatementList *finish ()
1731 {
1732 StatementList *front = next;
1733 next = nullptr;
1734 return front;
1735 }
1736
1737// attributes
1738 Node *statement = nullptr;
1739 StatementList *next;
1740};
1741
1742class QML_PARSER_EXPORT VariableDeclarationList: public Node
1743{
1744public:
1745 QQMLJS_DECLARE_AST_NODE(VariableDeclarationList)
1746
1747 VariableDeclarationList(PatternElement *decl)
1748 : declaration(decl), next(this)
1749 { kind = K; }
1750
1751 VariableDeclarationList(VariableDeclarationList *previous, PatternElement *decl)
1752 : declaration(decl)
1753 {
1754 kind = K;
1755 next = previous->next;
1756 previous->next = this;
1757 }
1758
1759 void accept0(BaseVisitor *visitor) override;
1760
1761 SourceLocation firstSourceLocation() const override
1762 { return declaration->firstSourceLocation(); }
1763
1764 SourceLocation lastSourceLocation() const override
1765 {
1766 if (next)
1767 return next->lastSourceLocation();
1768 return declaration->lastSourceLocation();
1769 }
1770
1771 inline VariableDeclarationList *finish(VariableScope s)
1772 {
1773 VariableDeclarationList *front = next;
1774 next = nullptr;
1775 VariableDeclarationList *vdl;
1776 for (vdl = front; vdl != nullptr; vdl = vdl->next) {
1777 vdl->declaration->scope = s;
1778 }
1779 return front;
1780 }
1781
1782// attributes
1783 PatternElement *declaration;
1784 VariableDeclarationList *next;
1785 SourceLocation commaToken;
1786};
1787
1788class QML_PARSER_EXPORT VariableStatement: public Statement
1789{
1790public:
1791 QQMLJS_DECLARE_AST_NODE(VariableStatement)
1792
1793 VariableStatement(VariableDeclarationList *vlist):
1794 declarations (vlist)
1795 { kind = K; }
1796
1797 void accept0(BaseVisitor *visitor) override;
1798
1799 SourceLocation firstSourceLocation() const override
1800 { return declarationKindToken; }
1801
1802 SourceLocation lastSourceLocation() const override
1803 { return declarations->lastSourceLocation(); }
1804
1805// attributes
1806 VariableDeclarationList *declarations;
1807 SourceLocation declarationKindToken;
1808};
1809
1810class QML_PARSER_EXPORT EmptyStatement: public Statement
1811{
1812public:
1813 QQMLJS_DECLARE_AST_NODE(EmptyStatement)
1814
1815 EmptyStatement() { kind = K; }
1816
1817 void accept0(BaseVisitor *visitor) override;
1818
1819 SourceLocation firstSourceLocation() const override
1820 { return semicolonToken; }
1821
1822 SourceLocation lastSourceLocation() const override
1823 { return semicolonToken; }
1824
1825// attributes
1826 SourceLocation semicolonToken;
1827};
1828
1829class QML_PARSER_EXPORT ExpressionStatement: public Statement
1830{
1831public:
1832 QQMLJS_DECLARE_AST_NODE(ExpressionStatement)
1833
1834 ExpressionStatement(ExpressionNode *e):
1835 expression (e) { kind = K; }
1836
1837 void accept0(BaseVisitor *visitor) override;
1838
1839 SourceLocation firstSourceLocation() const override
1840 { return expression->firstSourceLocation(); }
1841
1842 SourceLocation lastSourceLocation() const override
1843 { return semicolonToken; }
1844
1845// attributes
1846 ExpressionNode *expression;
1847 SourceLocation semicolonToken;
1848};
1849
1850class QML_PARSER_EXPORT IfStatement: public Statement
1851{
1852public:
1853 QQMLJS_DECLARE_AST_NODE(IfStatement)
1854
1855 IfStatement(ExpressionNode *e, Statement *t, Statement *f = nullptr):
1856 expression (e), ok (t), ko (f)
1857 { kind = K; }
1858
1859 void accept0(BaseVisitor *visitor) override;
1860
1861 SourceLocation firstSourceLocation() const override
1862 { return ifToken; }
1863
1864 SourceLocation lastSourceLocation() const override
1865 {
1866 if (ko)
1867 return ko->lastSourceLocation();
1868
1869 return ok->lastSourceLocation();
1870 }
1871
1872// attributes
1873 ExpressionNode *expression;
1874 Statement *ok;
1875 Statement *ko;
1876 SourceLocation ifToken;
1877 SourceLocation lparenToken;
1878 SourceLocation rparenToken;
1879 SourceLocation elseToken;
1880};
1881
1882class QML_PARSER_EXPORT DoWhileStatement: public Statement
1883{
1884public:
1885 QQMLJS_DECLARE_AST_NODE(DoWhileStatement)
1886
1887 DoWhileStatement(Statement *stmt, ExpressionNode *e):
1888 statement (stmt), expression (e)
1889 { kind = K; }
1890
1891 void accept0(BaseVisitor *visitor) override;
1892
1893 SourceLocation firstSourceLocation() const override
1894 { return doToken; }
1895
1896 SourceLocation lastSourceLocation() const override
1897 { return semicolonToken; }
1898
1899// attributes
1900 Statement *statement;
1901 ExpressionNode *expression;
1902 SourceLocation doToken;
1903 SourceLocation whileToken;
1904 SourceLocation lparenToken;
1905 SourceLocation rparenToken;
1906 SourceLocation semicolonToken;
1907};
1908
1909class QML_PARSER_EXPORT WhileStatement: public Statement
1910{
1911public:
1912 QQMLJS_DECLARE_AST_NODE(WhileStatement)
1913
1914 WhileStatement(ExpressionNode *e, Statement *stmt):
1915 expression (e), statement (stmt)
1916 { kind = K; }
1917
1918 void accept0(BaseVisitor *visitor) override;
1919
1920 SourceLocation firstSourceLocation() const override
1921 { return whileToken; }
1922
1923 SourceLocation lastSourceLocation() const override
1924 { return statement->lastSourceLocation(); }
1925
1926// attributes
1927 ExpressionNode *expression;
1928 Statement *statement;
1929 SourceLocation whileToken;
1930 SourceLocation lparenToken;
1931 SourceLocation rparenToken;
1932};
1933
1934class QML_PARSER_EXPORT ForStatement: public Statement
1935{
1936public:
1937 QQMLJS_DECLARE_AST_NODE(ForStatement)
1938
1939 ForStatement(ExpressionNode *i, ExpressionNode *c, ExpressionNode *e, Statement *stmt):
1940 initialiser (i), condition (c), expression (e), statement (stmt)
1941 { kind = K; }
1942
1943 ForStatement(VariableDeclarationList *vlist, ExpressionNode *c, ExpressionNode *e, Statement *stmt):
1944 declarations (vlist), condition (c), expression (e), statement (stmt)
1945 { kind = K; }
1946
1947
1948 void accept0(BaseVisitor *visitor) override;
1949
1950 SourceLocation firstSourceLocation() const override
1951 { return forToken; }
1952
1953 SourceLocation lastSourceLocation() const override
1954 { return statement->lastSourceLocation(); }
1955
1956// attributes
1957 ExpressionNode *initialiser = nullptr;
1958 VariableDeclarationList *declarations = nullptr;
1959 ExpressionNode *condition;
1960 ExpressionNode *expression;
1961 Statement *statement;
1962 SourceLocation forToken;
1963 SourceLocation lparenToken;
1964 SourceLocation firstSemicolonToken;
1965 SourceLocation secondSemicolonToken;
1966 SourceLocation rparenToken;
1967};
1968
1969enum class ForEachType {
1970 In,
1971 Of
1972};
1973
1974class QML_PARSER_EXPORT ForEachStatement: public Statement
1975{
1976public:
1977 QQMLJS_DECLARE_AST_NODE(ForEachStatement)
1978
1979 ForEachStatement(ExpressionNode *i, ExpressionNode *e, Statement *stmt)
1980 : lhs(i), expression(e), statement(stmt)
1981 { kind = K; }
1982 ForEachStatement(PatternElement *v, ExpressionNode *e, Statement *stmt)
1983 : lhs(v), expression(e), statement(stmt)
1984 { kind = K; }
1985
1986 void accept0(BaseVisitor *visitor) override;
1987
1988 SourceLocation firstSourceLocation() const override
1989 { return forToken; }
1990
1991 SourceLocation lastSourceLocation() const override
1992 { return statement->lastSourceLocation(); }
1993
1994 PatternElement *declaration() const {
1995 return AST::cast<PatternElement *>(ast: lhs);
1996 }
1997
1998// attributes
1999 Node *lhs;
2000 ExpressionNode *expression;
2001 Statement *statement;
2002 SourceLocation forToken;
2003 SourceLocation lparenToken;
2004 SourceLocation inOfToken;
2005 SourceLocation rparenToken;
2006 ForEachType type;
2007};
2008
2009class QML_PARSER_EXPORT ContinueStatement: public Statement
2010{
2011public:
2012 QQMLJS_DECLARE_AST_NODE(ContinueStatement)
2013
2014 ContinueStatement(QStringView l = QStringView()):
2015 label (l) { kind = K; }
2016
2017 void accept0(BaseVisitor *visitor) override;
2018
2019 SourceLocation firstSourceLocation() const override
2020 { return continueToken; }
2021
2022 SourceLocation lastSourceLocation() const override
2023 { return semicolonToken; }
2024
2025// attributes
2026 QStringView label;
2027 SourceLocation continueToken;
2028 SourceLocation identifierToken;
2029 SourceLocation semicolonToken;
2030};
2031
2032class QML_PARSER_EXPORT BreakStatement: public Statement
2033{
2034public:
2035 QQMLJS_DECLARE_AST_NODE(BreakStatement)
2036
2037 BreakStatement(QStringView l):
2038 label (l) { kind = K; }
2039
2040 void accept0(BaseVisitor *visitor) override;
2041
2042 SourceLocation firstSourceLocation() const override
2043 { return breakToken; }
2044
2045 SourceLocation lastSourceLocation() const override
2046 { return semicolonToken; }
2047
2048 // attributes
2049 QStringView label;
2050 SourceLocation breakToken;
2051 SourceLocation identifierToken;
2052 SourceLocation semicolonToken;
2053};
2054
2055class QML_PARSER_EXPORT ReturnStatement: public Statement
2056{
2057public:
2058 QQMLJS_DECLARE_AST_NODE(ReturnStatement)
2059
2060 ReturnStatement(ExpressionNode *e):
2061 expression (e) { kind = K; }
2062
2063 void accept0(BaseVisitor *visitor) override;
2064
2065 SourceLocation firstSourceLocation() const override
2066 { return returnToken; }
2067
2068 SourceLocation lastSourceLocation() const override
2069 { return semicolonToken; }
2070
2071// attributes
2072 ExpressionNode *expression;
2073 SourceLocation returnToken;
2074 SourceLocation semicolonToken;
2075};
2076
2077class QML_PARSER_EXPORT YieldExpression: public ExpressionNode
2078{
2079public:
2080 QQMLJS_DECLARE_AST_NODE(YieldExpression)
2081
2082 YieldExpression(ExpressionNode *e = nullptr):
2083 expression (e) { kind = K; }
2084
2085 void accept0(BaseVisitor *visitor) override;
2086
2087 SourceLocation firstSourceLocation() const override
2088 { return yieldToken; }
2089
2090 SourceLocation lastSourceLocation() const override
2091 { return expression ? expression->lastSourceLocation() : yieldToken; }
2092
2093// attributes
2094 ExpressionNode *expression;
2095 bool isYieldStar = false;
2096 SourceLocation yieldToken;
2097};
2098
2099class QML_PARSER_EXPORT WithStatement: public Statement
2100{
2101public:
2102 QQMLJS_DECLARE_AST_NODE(WithStatement)
2103
2104 WithStatement(ExpressionNode *e, Statement *stmt):
2105 expression (e), statement (stmt)
2106 { kind = K; }
2107
2108 void accept0(BaseVisitor *visitor) override;
2109
2110 SourceLocation firstSourceLocation() const override
2111 { return withToken; }
2112
2113 SourceLocation lastSourceLocation() const override
2114 { return statement->lastSourceLocation(); }
2115
2116// attributes
2117 ExpressionNode *expression;
2118 Statement *statement;
2119 SourceLocation withToken;
2120 SourceLocation lparenToken;
2121 SourceLocation rparenToken;
2122};
2123
2124class QML_PARSER_EXPORT CaseBlock: public Node
2125{
2126public:
2127 QQMLJS_DECLARE_AST_NODE(CaseBlock)
2128
2129 CaseBlock(CaseClauses *c, DefaultClause *d = nullptr, CaseClauses *r = nullptr):
2130 clauses (c), defaultClause (d), moreClauses (r)
2131 { kind = K; }
2132
2133 void accept0(BaseVisitor *visitor) override;
2134
2135 SourceLocation firstSourceLocation() const override
2136 { return lbraceToken; }
2137
2138 SourceLocation lastSourceLocation() const override
2139 { return rbraceToken; }
2140
2141// attributes
2142 CaseClauses *clauses;
2143 DefaultClause *defaultClause;
2144 CaseClauses *moreClauses;
2145 SourceLocation lbraceToken;
2146 SourceLocation rbraceToken;
2147};
2148
2149class QML_PARSER_EXPORT SwitchStatement: public Statement
2150{
2151public:
2152 QQMLJS_DECLARE_AST_NODE(SwitchStatement)
2153
2154 SwitchStatement(ExpressionNode *e, CaseBlock *b):
2155 expression (e), block (b)
2156 { kind = K; }
2157
2158 void accept0(BaseVisitor *visitor) override;
2159
2160 SourceLocation firstSourceLocation() const override
2161 { return switchToken; }
2162
2163 SourceLocation lastSourceLocation() const override
2164 { return block->rbraceToken; }
2165
2166// attributes
2167 ExpressionNode *expression;
2168 CaseBlock *block;
2169 SourceLocation switchToken;
2170 SourceLocation lparenToken;
2171 SourceLocation rparenToken;
2172};
2173
2174class QML_PARSER_EXPORT CaseClause: public Node
2175{
2176public:
2177 QQMLJS_DECLARE_AST_NODE(CaseClause)
2178
2179 CaseClause(ExpressionNode *e, StatementList *slist):
2180 expression (e), statements (slist)
2181 { kind = K; }
2182
2183 void accept0(BaseVisitor *visitor) override;
2184
2185 SourceLocation firstSourceLocation() const override
2186 { return caseToken; }
2187
2188 SourceLocation lastSourceLocation() const override
2189 { return statements ? statements->lastSourceLocation() : colonToken; }
2190
2191// attributes
2192 ExpressionNode *expression;
2193 StatementList *statements;
2194 SourceLocation caseToken;
2195 SourceLocation colonToken;
2196};
2197
2198class QML_PARSER_EXPORT CaseClauses: public Node
2199{
2200public:
2201 QQMLJS_DECLARE_AST_NODE(CaseClauses)
2202
2203 CaseClauses(CaseClause *c):
2204 clause (c), next (this)
2205 { kind = K; }
2206
2207 CaseClauses(CaseClauses *previous, CaseClause *c):
2208 clause (c)
2209 {
2210 kind = K;
2211 next = previous->next;
2212 previous->next = this;
2213 }
2214
2215 void accept0(BaseVisitor *visitor) override;
2216
2217 SourceLocation firstSourceLocation() const override
2218 { return clause->firstSourceLocation(); }
2219
2220 SourceLocation lastSourceLocation() const override
2221 {
2222 return lastListElement(head: this)->clause->lastSourceLocation();
2223 }
2224
2225 inline CaseClauses *finish ()
2226 {
2227 CaseClauses *front = next;
2228 next = nullptr;
2229 return front;
2230 }
2231
2232//attributes
2233 CaseClause *clause;
2234 CaseClauses *next;
2235};
2236
2237class QML_PARSER_EXPORT DefaultClause: public Node
2238{
2239public:
2240 QQMLJS_DECLARE_AST_NODE(DefaultClause)
2241
2242 DefaultClause(StatementList *slist):
2243 statements (slist)
2244 { kind = K; }
2245
2246 void accept0(BaseVisitor *visitor) override;
2247
2248 SourceLocation firstSourceLocation() const override
2249 { return defaultToken; }
2250
2251 SourceLocation lastSourceLocation() const override
2252 { return statements ? statements->lastSourceLocation() : colonToken; }
2253
2254// attributes
2255 StatementList *statements;
2256 SourceLocation defaultToken;
2257 SourceLocation colonToken;
2258};
2259
2260class QML_PARSER_EXPORT LabelledStatement: public Statement
2261{
2262public:
2263 QQMLJS_DECLARE_AST_NODE(LabelledStatement)
2264
2265 LabelledStatement(QStringView l, Statement *stmt):
2266 label (l), statement (stmt)
2267 { kind = K; }
2268
2269 void accept0(BaseVisitor *visitor) override;
2270
2271 SourceLocation firstSourceLocation() const override
2272 { return identifierToken; }
2273
2274 SourceLocation lastSourceLocation() const override
2275 { return statement->lastSourceLocation(); }
2276
2277// attributes
2278 QStringView label;
2279 Statement *statement;
2280 SourceLocation identifierToken;
2281 SourceLocation colonToken;
2282};
2283
2284class QML_PARSER_EXPORT ThrowStatement: public Statement
2285{
2286public:
2287 QQMLJS_DECLARE_AST_NODE(ThrowStatement)
2288
2289 ThrowStatement(ExpressionNode *e):
2290 expression (e) { kind = K; }
2291
2292 void accept0(BaseVisitor *visitor) override;
2293
2294 SourceLocation firstSourceLocation() const override
2295 { return throwToken; }
2296
2297 SourceLocation lastSourceLocation() const override
2298 { return semicolonToken; }
2299
2300 // attributes
2301 ExpressionNode *expression;
2302 SourceLocation throwToken;
2303 SourceLocation semicolonToken;
2304};
2305
2306class QML_PARSER_EXPORT Catch: public Node
2307{
2308public:
2309 QQMLJS_DECLARE_AST_NODE(Catch)
2310
2311 Catch(PatternElement *p, Block *stmt)
2312 : patternElement(p), statement(stmt)
2313 { kind = K; }
2314
2315 void accept0(BaseVisitor *visitor) override;
2316
2317 SourceLocation firstSourceLocation() const override
2318 { return catchToken; }
2319
2320 SourceLocation lastSourceLocation() const override
2321 { return statement->lastSourceLocation(); }
2322
2323// attributes
2324 PatternElement *patternElement;
2325 Block *statement;
2326 SourceLocation catchToken;
2327 SourceLocation lparenToken;
2328 SourceLocation identifierToken;
2329 SourceLocation rparenToken;
2330};
2331
2332class QML_PARSER_EXPORT Finally: public Node
2333{
2334public:
2335 QQMLJS_DECLARE_AST_NODE(Finally)
2336
2337 Finally(Block *stmt):
2338 statement (stmt)
2339 { kind = K; }
2340
2341 void accept0(BaseVisitor *visitor) override;
2342
2343 SourceLocation firstSourceLocation() const override
2344 { return finallyToken; }
2345
2346 SourceLocation lastSourceLocation() const override
2347 { return statement ? statement->lastSourceLocation() : finallyToken; }
2348
2349// attributes
2350 Block *statement;
2351 SourceLocation finallyToken;
2352};
2353
2354class QML_PARSER_EXPORT TryStatement: public Statement
2355{
2356public:
2357 QQMLJS_DECLARE_AST_NODE(TryStatement)
2358
2359 TryStatement(Statement *stmt, Catch *c, Finally *f):
2360 statement (stmt), catchExpression (c), finallyExpression (f)
2361 { kind = K; }
2362
2363 TryStatement(Statement *stmt, Finally *f):
2364 statement (stmt), catchExpression (nullptr), finallyExpression (f)
2365 { kind = K; }
2366
2367 TryStatement(Statement *stmt, Catch *c):
2368 statement (stmt), catchExpression (c), finallyExpression (nullptr)
2369 { kind = K; }
2370
2371 void accept0(BaseVisitor *visitor) override;
2372
2373 SourceLocation firstSourceLocation() const override
2374 { return tryToken; }
2375
2376 SourceLocation lastSourceLocation() const override
2377 {
2378 if (finallyExpression)
2379 return finallyExpression->statement->rbraceToken;
2380 else if (catchExpression)
2381 return catchExpression->statement->rbraceToken;
2382
2383 return statement->lastSourceLocation();
2384 }
2385
2386// attributes
2387 Statement *statement;
2388 Catch *catchExpression;
2389 Finally *finallyExpression;
2390 SourceLocation tryToken;
2391};
2392
2393class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode
2394{
2395public:
2396 QQMLJS_DECLARE_AST_NODE(FunctionExpression)
2397
2398 FunctionExpression(QStringView n, FormalParameterList *f, StatementList *b, TypeAnnotation *typeAnnotation = nullptr):
2399 name (n), formals (f), body (b),
2400 typeAnnotation(typeAnnotation)
2401 { kind = K; }
2402
2403 void accept0(BaseVisitor *visitor) override;
2404
2405 SourceLocation firstSourceLocation() const override
2406 { return functionToken; }
2407
2408 SourceLocation lastSourceLocation() const override
2409 { return rbraceToken; }
2410
2411 FunctionExpression *asFunctionDefinition() override;
2412
2413// attributes
2414 QStringView name;
2415 bool isArrowFunction = false;
2416 bool isGenerator = false;
2417 FormalParameterList *formals;
2418 StatementList *body;
2419 TypeAnnotation *typeAnnotation;
2420 SourceLocation functionToken;
2421 // for generators:
2422 SourceLocation starToken;
2423 SourceLocation identifierToken;
2424 SourceLocation lparenToken;
2425 SourceLocation rparenToken;
2426 SourceLocation lbraceToken;
2427 SourceLocation rbraceToken;
2428};
2429
2430class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
2431{
2432public:
2433 QQMLJS_DECLARE_AST_NODE(FunctionDeclaration)
2434
2435 FunctionDeclaration(QStringView n, FormalParameterList *f, StatementList *b, TypeAnnotation *typeAnnotation = nullptr):
2436 FunctionExpression(n, f, b, typeAnnotation)
2437 { kind = K; }
2438
2439 void accept0(BaseVisitor *visitor) override;
2440};
2441
2442class QML_PARSER_EXPORT FormalParameterList: public Node
2443{
2444public:
2445 QQMLJS_DECLARE_AST_NODE(FormalParameterList)
2446
2447 FormalParameterList(FormalParameterList *previous, PatternElement *e)
2448 : element(e)
2449 {
2450 kind = K;
2451 if (previous) {
2452 next = previous->next;
2453 previous->next = this;
2454 } else {
2455 next = this;
2456 }
2457 }
2458
2459 FormalParameterList *append(FormalParameterList *n) {
2460 n->next = next;
2461 next = n;
2462 return n;
2463 }
2464
2465 bool isSimpleParameterList()
2466 {
2467 AST::FormalParameterList *formals = this;
2468 while (formals) {
2469 PatternElement *e = formals->element;
2470 if (e && e->type == PatternElement::RestElement)
2471 return false;
2472 if (e && (e->initializer || e->bindingTarget))
2473 return false;
2474 formals = formals->next;
2475 }
2476 return true;
2477 }
2478
2479 int length()
2480 {
2481 // the length property of Function objects
2482 int l = 0;
2483 AST::FormalParameterList *formals = this;
2484 while (formals) {
2485 PatternElement *e = formals->element;
2486 if (!e || e->initializer)
2487 break;
2488 if (e->type == PatternElement::RestElement)
2489 break;
2490 ++l;
2491 formals = formals->next;
2492 }
2493 return l;
2494 }
2495
2496 bool containsName(const QString &name) const {
2497 for (const FormalParameterList *it = this; it; it = it->next) {
2498 PatternElement *b = it->element;
2499 // ### handle binding patterns
2500 if (b && b->bindingIdentifier == name)
2501 return true;
2502 }
2503 return false;
2504 }
2505
2506 BoundNames formals() const;
2507
2508 BoundNames boundNames() const;
2509
2510 void accept0(BaseVisitor *visitor) override;
2511
2512 SourceLocation firstSourceLocation() const override
2513 { return element->firstSourceLocation(); }
2514
2515 SourceLocation lastSourceLocation() const override
2516 {
2517 return lastListElement(head: this)->element->lastSourceLocation();
2518 }
2519
2520 FormalParameterList *finish(MemoryPool *pool);
2521
2522// attributes
2523 PatternElement *element = nullptr;
2524 FormalParameterList *next;
2525};
2526
2527class QML_PARSER_EXPORT ClassExpression : public ExpressionNode
2528{
2529public:
2530 QQMLJS_DECLARE_AST_NODE(ClassExpression)
2531
2532 ClassExpression(QStringView n, ExpressionNode *heritage, ClassElementList *elements)
2533 : name(n), heritage(heritage), elements(elements)
2534 { kind = K; }
2535
2536 void accept0(BaseVisitor *visitor) override;
2537
2538 SourceLocation firstSourceLocation() const override
2539 { return classToken; }
2540
2541 SourceLocation lastSourceLocation() const override
2542 { return rbraceToken; }
2543
2544 ClassExpression *asClassDefinition() override;
2545
2546// attributes
2547 QStringView name;
2548 ExpressionNode *heritage;
2549 ClassElementList *elements;
2550 SourceLocation classToken;
2551 SourceLocation identifierToken;
2552 SourceLocation lbraceToken;
2553 SourceLocation rbraceToken;
2554};
2555
2556class QML_PARSER_EXPORT ClassDeclaration: public ClassExpression
2557{
2558public:
2559 QQMLJS_DECLARE_AST_NODE(ClassDeclaration)
2560
2561 ClassDeclaration(QStringView n, ExpressionNode *heritage, ClassElementList *elements)
2562 : ClassExpression(n, heritage, elements)
2563 { kind = K; }
2564
2565 void accept0(BaseVisitor *visitor) override;
2566};
2567
2568
2569class QML_PARSER_EXPORT ClassElementList : public Node
2570{
2571public:
2572 QQMLJS_DECLARE_AST_NODE(ClassElementList)
2573
2574 ClassElementList(PatternProperty *property, bool isStatic)
2575 : isStatic(isStatic), property(property)
2576 {
2577 kind = K;
2578 next = this;
2579 }
2580
2581 ClassElementList *append(ClassElementList *n) {
2582 n->next = next;
2583 next = n;
2584 return n;
2585 }
2586
2587 void accept0(BaseVisitor *visitor) override;
2588
2589 SourceLocation firstSourceLocation() const override
2590 { return property->firstSourceLocation(); }
2591
2592 SourceLocation lastSourceLocation() const override
2593 {
2594 if (next)
2595 return next->lastSourceLocation();
2596 return property->lastSourceLocation();
2597 }
2598
2599 ClassElementList *finish();
2600
2601 bool isStatic;
2602 ClassElementList *next;
2603 PatternProperty *property;
2604};
2605
2606class QML_PARSER_EXPORT Program: public Node
2607{
2608public:
2609 QQMLJS_DECLARE_AST_NODE(Program)
2610
2611 Program(StatementList *statements)
2612 : statements(statements)
2613 { kind = K; }
2614
2615 void accept0(BaseVisitor *visitor) override;
2616
2617 SourceLocation firstSourceLocation() const override
2618 { return statements ? statements->firstSourceLocation() : SourceLocation(); }
2619
2620 SourceLocation lastSourceLocation() const override
2621 { return statements ? statements->lastSourceLocation() : SourceLocation(); }
2622
2623// attributes
2624 StatementList *statements;
2625};
2626
2627class QML_PARSER_EXPORT ImportSpecifier: public Node
2628{
2629public:
2630 QQMLJS_DECLARE_AST_NODE(ImportSpecifier)
2631
2632 ImportSpecifier(QStringView importedBinding)
2633 : importedBinding(importedBinding)
2634 {
2635 kind = K;
2636 }
2637
2638 ImportSpecifier(QStringView identifier, QStringView importedBinding)
2639 : identifier(identifier), importedBinding(importedBinding)
2640 {
2641 kind = K;
2642 }
2643
2644 void accept0(BaseVisitor *visitor) override;
2645
2646 SourceLocation firstSourceLocation() const override
2647 { return identifier.isNull() ? importedBindingToken : identifierToken; }
2648 SourceLocation lastSourceLocation() const override
2649 { return importedBindingToken; }
2650
2651// attributes
2652 SourceLocation identifierToken;
2653 SourceLocation importedBindingToken;
2654 QStringView identifier;
2655 QStringView importedBinding;
2656};
2657
2658class QML_PARSER_EXPORT ImportsList: public Node
2659{
2660public:
2661 QQMLJS_DECLARE_AST_NODE(ImportsList)
2662
2663 ImportsList(ImportSpecifier *importSpecifier)
2664 : importSpecifier(importSpecifier)
2665 {
2666 kind = K;
2667 next = this;
2668 }
2669
2670 ImportsList(ImportsList *previous, ImportSpecifier *importSpecifier)
2671 : importSpecifier(importSpecifier)
2672 {
2673 kind = K;
2674 if (previous) {
2675 next = previous->next;
2676 previous->next = this;
2677 } else {
2678 next = this;
2679 }
2680 }
2681
2682 ImportsList *finish()
2683 {
2684 ImportsList *head = next;
2685 next = nullptr;
2686 return head;
2687 }
2688
2689 void accept0(BaseVisitor *visitor) override;
2690
2691 SourceLocation firstSourceLocation() const override
2692 { return importSpecifierToken; }
2693
2694 SourceLocation lastSourceLocation() const override
2695 {
2696 return lastListElement(head: this)->importSpecifierToken;
2697 }
2698
2699// attributes
2700 SourceLocation importSpecifierToken;
2701 ImportSpecifier *importSpecifier;
2702 ImportsList *next = this;
2703};
2704
2705class QML_PARSER_EXPORT NamedImports: public Node
2706{
2707public:
2708 QQMLJS_DECLARE_AST_NODE(NamedImports)
2709
2710 NamedImports()
2711 {
2712 kind = K;
2713 }
2714
2715 NamedImports(ImportsList *importsList)
2716 : importsList(importsList)
2717 {
2718 kind = K;
2719 }
2720
2721 void accept0(BaseVisitor *visitor) override;
2722
2723 SourceLocation firstSourceLocation() const override
2724 { return leftBraceToken; }
2725 SourceLocation lastSourceLocation() const override
2726 { return rightBraceToken; }
2727
2728// attributes
2729 SourceLocation leftBraceToken;
2730 SourceLocation rightBraceToken;
2731 ImportsList *importsList = nullptr;
2732};
2733
2734class QML_PARSER_EXPORT NameSpaceImport: public Node
2735{
2736public:
2737 QQMLJS_DECLARE_AST_NODE(NameSpaceImport)
2738
2739 NameSpaceImport(QStringView importedBinding)
2740 : importedBinding(importedBinding)
2741 {
2742 kind = K;
2743 }
2744
2745 void accept0(BaseVisitor *visitor) override;
2746
2747 virtual SourceLocation firstSourceLocation() const override
2748 { return starToken; }
2749 virtual SourceLocation lastSourceLocation() const override
2750 { return importedBindingToken; }
2751
2752// attributes
2753 SourceLocation starToken;
2754 SourceLocation importedBindingToken;
2755 QStringView importedBinding;
2756};
2757
2758class QML_PARSER_EXPORT ImportClause: public Node
2759{
2760public:
2761 QQMLJS_DECLARE_AST_NODE(ImportClause)
2762
2763 ImportClause(QStringView importedDefaultBinding)
2764 : importedDefaultBinding(importedDefaultBinding)
2765 {
2766 kind = K;
2767 }
2768
2769 ImportClause(NameSpaceImport *nameSpaceImport)
2770 : nameSpaceImport(nameSpaceImport)
2771 {
2772 kind = K;
2773 }
2774
2775 ImportClause(NamedImports *namedImports)
2776 : namedImports(namedImports)
2777 {
2778 kind = K;
2779 }
2780
2781 ImportClause(QStringView importedDefaultBinding, NameSpaceImport *nameSpaceImport)
2782 : importedDefaultBinding(importedDefaultBinding)
2783 , nameSpaceImport(nameSpaceImport)
2784 {
2785 kind = K;
2786 }
2787
2788 ImportClause(QStringView importedDefaultBinding, NamedImports *namedImports)
2789 : importedDefaultBinding(importedDefaultBinding)
2790 , namedImports(namedImports)
2791 {
2792 kind = K;
2793 }
2794
2795 void accept0(BaseVisitor *visitor) override;
2796
2797 virtual SourceLocation firstSourceLocation() const override
2798 { return importedDefaultBinding.isNull() ? (nameSpaceImport ? nameSpaceImport->firstSourceLocation() : namedImports->firstSourceLocation()) : importedDefaultBindingToken; }
2799 virtual SourceLocation lastSourceLocation() const override
2800 { return importedDefaultBinding.isNull() ? (nameSpaceImport ? nameSpaceImport->lastSourceLocation() : namedImports->lastSourceLocation()) : importedDefaultBindingToken; }
2801
2802// attributes
2803 SourceLocation importedDefaultBindingToken;
2804 QStringView importedDefaultBinding;
2805 NameSpaceImport *nameSpaceImport = nullptr;
2806 NamedImports *namedImports = nullptr;
2807};
2808
2809class QML_PARSER_EXPORT FromClause: public Node
2810{
2811public:
2812 QQMLJS_DECLARE_AST_NODE(FromClause)
2813
2814 FromClause(QStringView moduleSpecifier)
2815 : moduleSpecifier(moduleSpecifier)
2816 {
2817 kind = K;
2818 }
2819
2820 void accept0(BaseVisitor *visitor) override;
2821
2822 SourceLocation firstSourceLocation() const override
2823 { return fromToken; }
2824
2825 SourceLocation lastSourceLocation() const override
2826 { return moduleSpecifierToken; }
2827
2828// attributes
2829 SourceLocation fromToken;
2830 SourceLocation moduleSpecifierToken;
2831 QStringView moduleSpecifier;
2832};
2833
2834class QML_PARSER_EXPORT ImportDeclaration: public Statement
2835{
2836public:
2837 QQMLJS_DECLARE_AST_NODE(ImportDeclaration)
2838
2839 ImportDeclaration(ImportClause *importClause, FromClause *fromClause)
2840 : importClause(importClause), fromClause(fromClause)
2841 {
2842 kind = K;
2843 }
2844
2845 ImportDeclaration(QStringView moduleSpecifier)
2846 : moduleSpecifier(moduleSpecifier)
2847 {
2848 kind = K;
2849 }
2850
2851 void accept0(BaseVisitor *visitor) override;
2852
2853 SourceLocation firstSourceLocation() const override
2854 { return importToken; }
2855
2856 SourceLocation lastSourceLocation() const override
2857 { return moduleSpecifier.isNull() ? fromClause->lastSourceLocation() : moduleSpecifierToken; }
2858
2859// attributes
2860 SourceLocation importToken;
2861 SourceLocation moduleSpecifierToken;
2862 QStringView moduleSpecifier;
2863 ImportClause *importClause = nullptr;
2864 FromClause *fromClause = nullptr;
2865};
2866
2867class QML_PARSER_EXPORT ExportSpecifier: public Node
2868{
2869public:
2870 QQMLJS_DECLARE_AST_NODE(ExportSpecifier)
2871
2872 ExportSpecifier(QStringView identifier)
2873 : identifier(identifier), exportedIdentifier(identifier)
2874 {
2875 kind = K;
2876 }
2877
2878 ExportSpecifier(QStringView identifier, QStringView exportedIdentifier)
2879 : identifier(identifier), exportedIdentifier(exportedIdentifier)
2880 {
2881 kind = K;
2882 }
2883
2884 void accept0(BaseVisitor *visitor) override;
2885
2886 SourceLocation firstSourceLocation() const override
2887 { return identifierToken; }
2888 SourceLocation lastSourceLocation() const override
2889 { return exportedIdentifierToken.isValid() ? exportedIdentifierToken : identifierToken; }
2890
2891// attributes
2892 SourceLocation identifierToken;
2893 SourceLocation exportedIdentifierToken;
2894 QStringView identifier;
2895 QStringView exportedIdentifier;
2896};
2897
2898class QML_PARSER_EXPORT ExportsList: public Node
2899{
2900public:
2901 QQMLJS_DECLARE_AST_NODE(ExportsList)
2902
2903 ExportsList(ExportSpecifier *exportSpecifier)
2904 : exportSpecifier(exportSpecifier)
2905 {
2906 kind = K;
2907 next = this;
2908 }
2909
2910 ExportsList(ExportsList *previous, ExportSpecifier *exportSpecifier)
2911 : exportSpecifier(exportSpecifier)
2912 {
2913 kind = K;
2914 if (previous) {
2915 next = previous->next;
2916 previous->next = this;
2917 } else {
2918 next = this;
2919 }
2920 }
2921
2922 ExportsList *finish()
2923 {
2924 ExportsList *head = next;
2925 next = nullptr;
2926 return head;
2927 }
2928
2929 void accept0(BaseVisitor *visitor) override;
2930
2931 SourceLocation firstSourceLocation() const override
2932 { return exportSpecifier->firstSourceLocation(); }
2933 SourceLocation lastSourceLocation() const override
2934 { return lastListElement(head: this)->exportSpecifier->lastSourceLocation(); }
2935
2936// attributes
2937 ExportSpecifier *exportSpecifier;
2938 ExportsList *next;
2939};
2940
2941class QML_PARSER_EXPORT ExportClause: public Node
2942{
2943public:
2944 QQMLJS_DECLARE_AST_NODE(ExportClause)
2945
2946 ExportClause()
2947 {
2948 kind = K;
2949 }
2950
2951 ExportClause(ExportsList *exportsList)
2952 : exportsList(exportsList)
2953 {
2954 kind = K;
2955 }
2956
2957 void accept0(BaseVisitor *visitor) override;
2958
2959 SourceLocation firstSourceLocation() const override
2960 { return leftBraceToken; }
2961 SourceLocation lastSourceLocation() const override
2962 { return rightBraceToken; }
2963
2964// attributes
2965 SourceLocation leftBraceToken;
2966 SourceLocation rightBraceToken;
2967 ExportsList *exportsList = nullptr;
2968};
2969
2970class QML_PARSER_EXPORT ExportDeclaration: public Statement
2971{
2972public:
2973 QQMLJS_DECLARE_AST_NODE(ExportDeclaration)
2974
2975 ExportDeclaration(FromClause *fromClause)
2976 : fromClause(fromClause)
2977 {
2978 kind = K;
2979 }
2980
2981 ExportDeclaration(ExportClause *exportClause, FromClause *fromClause)
2982 : exportClause(exportClause), fromClause(fromClause)
2983 {
2984 kind = K;
2985 }
2986
2987 ExportDeclaration(ExportClause *exportClause)
2988 : exportClause(exportClause)
2989 {
2990 kind = K;
2991 }
2992
2993 ExportDeclaration(bool exportDefault, Node *variableStatementOrDeclaration)
2994 : variableStatementOrDeclaration(variableStatementOrDeclaration)
2995 , exportDefault(exportDefault)
2996 {
2997 kind = K;
2998 }
2999
3000 bool exportsAll() const
3001 {
3002 return fromClause && !exportClause;
3003 }
3004
3005 void accept0(BaseVisitor *visitor) override;
3006
3007 SourceLocation firstSourceLocation() const override
3008 { return exportToken; }
3009 SourceLocation lastSourceLocation() const override
3010 { return fromClause ? fromClause->lastSourceLocation() : (exportClause ? exportClause->lastSourceLocation() : variableStatementOrDeclaration->lastSourceLocation()); }
3011
3012// attributes
3013 SourceLocation exportToken;
3014 ExportClause *exportClause = nullptr;
3015 FromClause *fromClause = nullptr;
3016 Node *variableStatementOrDeclaration = nullptr;
3017 bool exportDefault = false;
3018};
3019
3020class QML_PARSER_EXPORT ESModule: public Node
3021{
3022public:
3023 QQMLJS_DECLARE_AST_NODE(Module)
3024
3025 ESModule(StatementList *body)
3026 : body(body)
3027 {
3028 kind = K;
3029 }
3030
3031 void accept0(BaseVisitor *visitor) override;
3032
3033 SourceLocation firstSourceLocation() const override
3034 { return body ? body->firstSourceLocation() : SourceLocation(); }
3035
3036 SourceLocation lastSourceLocation() const override
3037 { return body ? body->lastSourceLocation() : SourceLocation(); }
3038
3039// attributes
3040 StatementList *body;
3041};
3042
3043class QML_PARSER_EXPORT DebuggerStatement: public Statement
3044{
3045public:
3046 QQMLJS_DECLARE_AST_NODE(DebuggerStatement)
3047
3048 DebuggerStatement()
3049 { kind = K; }
3050
3051 void accept0(BaseVisitor *visitor) override;
3052
3053 SourceLocation firstSourceLocation() const override
3054 { return debuggerToken; }
3055
3056 SourceLocation lastSourceLocation() const override
3057 { return semicolonToken; }
3058
3059// attributes
3060 SourceLocation debuggerToken;
3061 SourceLocation semicolonToken;
3062};
3063
3064class QML_PARSER_EXPORT UiImport: public Node
3065{
3066public:
3067 QQMLJS_DECLARE_AST_NODE(UiImport)
3068
3069 UiImport(QStringView fileName)
3070 : fileName(fileName), importUri(nullptr)
3071 { kind = K; }
3072
3073 UiImport(UiQualifiedId *uri)
3074 : importUri(uri)
3075 { kind = K; }
3076
3077 void accept0(BaseVisitor *visitor) override;
3078
3079 SourceLocation firstSourceLocation() const override
3080 { return importToken; }
3081
3082 SourceLocation lastSourceLocation() const override
3083 { return semicolonToken; }
3084
3085// attributes
3086 QStringView fileName;
3087 UiQualifiedId *importUri;
3088 QStringView importId;
3089 SourceLocation importToken;
3090 SourceLocation fileNameToken;
3091 SourceLocation asToken;
3092 SourceLocation importIdToken;
3093 SourceLocation semicolonToken;
3094 UiVersionSpecifier *version = nullptr;
3095};
3096
3097class QML_PARSER_EXPORT UiObjectMember: public Node
3098{
3099public:
3100 SourceLocation firstSourceLocation() const override = 0;
3101 SourceLocation lastSourceLocation() const override = 0;
3102
3103 UiObjectMember *uiObjectMemberCast() override;
3104
3105// attributes
3106 UiAnnotationList *annotations = nullptr;
3107};
3108
3109class QML_PARSER_EXPORT UiObjectMemberList: public Node
3110{
3111public:
3112 QQMLJS_DECLARE_AST_NODE(UiObjectMemberList)
3113
3114 UiObjectMemberList(UiObjectMember *member)
3115 : next(this), member(member)
3116 { kind = K; }
3117
3118 UiObjectMemberList(UiObjectMemberList *previous, UiObjectMember *member)
3119 : member(member)
3120 {
3121 kind = K;
3122 next = previous->next;
3123 previous->next = this;
3124 }
3125
3126 void accept0(BaseVisitor *visitor) override;
3127
3128 SourceLocation firstSourceLocation() const override
3129 { return member->firstSourceLocation(); }
3130
3131 SourceLocation lastSourceLocation() const override
3132 { return lastListElement(head: this)->member->lastSourceLocation(); }
3133
3134 UiObjectMemberList *finish()
3135 {
3136 UiObjectMemberList *head = next;
3137 next = nullptr;
3138 return head;
3139 }
3140
3141// attributes
3142 UiObjectMemberList *next;
3143 UiObjectMember *member;
3144};
3145
3146class QML_PARSER_EXPORT UiPragmaValueList: public Node
3147{
3148public:
3149 QQMLJS_DECLARE_AST_NODE(UiPragmaValueList)
3150
3151 UiPragmaValueList(QStringView value)
3152 : value(value)
3153 , next(this)
3154 {
3155 kind = K;
3156 }
3157
3158 UiPragmaValueList(UiPragmaValueList *previous, QStringView value)
3159 : value(value)
3160 {
3161 kind = K;
3162 next = previous->next;
3163 previous->next = this;
3164 }
3165
3166 void accept0(BaseVisitor *visitor) override;
3167
3168 SourceLocation firstSourceLocation() const override
3169 { return location; }
3170
3171 SourceLocation lastSourceLocation() const override
3172 { return lastListElement(head: this)->location; }
3173
3174 UiPragmaValueList *finish()
3175 {
3176 UiPragmaValueList *head = next;
3177 next = nullptr;
3178 return head;
3179 }
3180
3181 QStringView value;
3182 UiPragmaValueList *next;
3183 SourceLocation location;
3184};
3185
3186class QML_PARSER_EXPORT UiPragma: public Node
3187{
3188public:
3189 QQMLJS_DECLARE_AST_NODE(UiPragma)
3190
3191 UiPragma(QStringView name, UiPragmaValueList *values = nullptr)
3192 : name(name), values(values)
3193 { kind = K; }
3194
3195 void accept0(BaseVisitor *visitor) override;
3196
3197 SourceLocation firstSourceLocation() const override
3198 { return pragmaToken; }
3199
3200 SourceLocation lastSourceLocation() const override
3201 { return semicolonToken; }
3202
3203// attributes
3204 QStringView name;
3205 UiPragmaValueList *values;
3206 SourceLocation pragmaToken;
3207 SourceLocation pragmaIdToken;
3208 SourceLocation colonToken;
3209 SourceLocation semicolonToken;
3210};
3211
3212class QML_PARSER_EXPORT UiRequired: public Node
3213{
3214public:
3215 QQMLJS_DECLARE_AST_NODE(UiRequired)
3216
3217 UiRequired(QStringView name)
3218 :name(name)
3219 { kind = K; }
3220
3221 void accept0(BaseVisitor *visitor) override;
3222
3223 SourceLocation firstSourceLocation() const override
3224 { return requiredToken; }
3225
3226 SourceLocation lastSourceLocation() const override
3227 { return semicolonToken; }
3228
3229 QStringView name;
3230 SourceLocation requiredToken;
3231 SourceLocation semicolonToken;
3232};
3233
3234class QML_PARSER_EXPORT UiHeaderItemList: public Node
3235{
3236public:
3237 QQMLJS_DECLARE_AST_NODE(UiHeaderItemList)
3238
3239 UiHeaderItemList(UiImport *import)
3240 : headerItem(import), next(this)
3241 { kind = K; }
3242
3243 UiHeaderItemList(UiPragma *pragma)
3244 : headerItem(pragma), next(this)
3245 { kind = K; }
3246
3247 UiHeaderItemList(UiHeaderItemList *previous, UiImport *import)
3248 : headerItem(import)
3249 {
3250 kind = K;
3251 next = previous->next;
3252 previous->next = this;
3253 }
3254
3255 UiHeaderItemList(UiHeaderItemList *previous, UiPragma *pragma)
3256 : headerItem(pragma)
3257 {
3258 kind = K;
3259 next = previous->next;
3260 previous->next = this;
3261 }
3262
3263 UiHeaderItemList *finish()
3264 {
3265 UiHeaderItemList *head = next;
3266 next = nullptr;
3267 return head;
3268 }
3269
3270 void accept0(BaseVisitor *visitor) override;
3271
3272 SourceLocation firstSourceLocation() const override
3273 { return headerItem->firstSourceLocation(); }
3274
3275 SourceLocation lastSourceLocation() const override
3276 { return lastListElement(head: this)->headerItem->lastSourceLocation(); }
3277
3278// attributes
3279 Node *headerItem;
3280 UiHeaderItemList *next;
3281};
3282
3283class QML_PARSER_EXPORT UiProgram: public Node
3284{
3285public:
3286 QQMLJS_DECLARE_AST_NODE(UiProgram)
3287
3288 UiProgram(UiHeaderItemList *headers, UiObjectMemberList *members)
3289 : headers(headers), members(members)
3290 { kind = K; }
3291
3292 void accept0(BaseVisitor *visitor) override;
3293
3294 SourceLocation firstSourceLocation() const override
3295 {
3296 if (headers)
3297 return headers->firstSourceLocation();
3298 else if (members)
3299 return members->firstSourceLocation();
3300 return SourceLocation();
3301 }
3302
3303 SourceLocation lastSourceLocation() const override
3304 {
3305 if (members)
3306 return members->lastSourceLocation();
3307 else if (headers)
3308 return headers->lastSourceLocation();
3309 return SourceLocation();
3310 }
3311
3312// attributes
3313 UiHeaderItemList *headers;
3314 UiObjectMemberList *members;
3315};
3316
3317class QML_PARSER_EXPORT UiArrayMemberList: public Node
3318{
3319public:
3320 QQMLJS_DECLARE_AST_NODE(UiArrayMemberList)
3321
3322 UiArrayMemberList(UiObjectMember *member)
3323 : next(this), member(member)
3324 { kind = K; }
3325
3326 UiArrayMemberList(UiArrayMemberList *previous, UiObjectMember *member)
3327 : member(member)
3328 {
3329 kind = K;
3330 next = previous->next;
3331 previous->next = this;
3332 }
3333
3334 void accept0(BaseVisitor *visitor) override;
3335
3336 SourceLocation firstSourceLocation() const override
3337 { return member->firstSourceLocation(); }
3338
3339 SourceLocation lastSourceLocation() const override
3340 { return lastListElement(head: this)->member->lastSourceLocation(); }
3341
3342 UiArrayMemberList *finish()
3343 {
3344 UiArrayMemberList *head = next;
3345 next = nullptr;
3346 return head;
3347 }
3348
3349// attributes
3350 UiArrayMemberList *next;
3351 UiObjectMember *member;
3352 SourceLocation commaToken;
3353};
3354
3355class QML_PARSER_EXPORT UiObjectInitializer: public Node
3356{
3357public:
3358 QQMLJS_DECLARE_AST_NODE(UiObjectInitializer)
3359
3360 UiObjectInitializer(UiObjectMemberList *members)
3361 : members(members)
3362 { kind = K; }
3363
3364 void accept0(BaseVisitor *visitor) override;
3365
3366 SourceLocation firstSourceLocation() const override
3367 { return lbraceToken; }
3368
3369 SourceLocation lastSourceLocation() const override
3370 { return rbraceToken; }
3371
3372// attributes
3373 SourceLocation lbraceToken;
3374 UiObjectMemberList *members;
3375 SourceLocation rbraceToken;
3376};
3377
3378class QML_PARSER_EXPORT UiParameterList: public Node
3379{
3380public:
3381 QQMLJS_DECLARE_AST_NODE(UiParameterList)
3382
3383 UiParameterList(Type *t, QStringView n):
3384 type (t), name (n), next (this)
3385 { kind = K; }
3386
3387 UiParameterList(UiParameterList *previous, Type *t, QStringView n):
3388 type (t), name (n)
3389 {
3390 kind = K;
3391 next = previous->next;
3392 previous->next = this;
3393 }
3394
3395 void accept0(BaseVisitor *) override;
3396
3397 SourceLocation firstSourceLocation() const override
3398 { return colonToken.isValid() ? identifierToken : propertyTypeToken; }
3399
3400 SourceLocation lastSourceLocation() const override
3401 {
3402 auto last = lastListElement(head: this);
3403 return last->lastOwnSourceLocation();
3404 }
3405
3406 SourceLocation lastOwnSourceLocation() const
3407 {
3408 return (colonToken.isValid() ? propertyTypeToken : identifierToken);
3409 }
3410
3411 inline UiParameterList *finish ()
3412 {
3413 UiParameterList *front = next;
3414 next = nullptr;
3415 return front;
3416 }
3417
3418// attributes
3419 Type *type;
3420 QStringView name;
3421 UiParameterList *next;
3422 SourceLocation commaToken;
3423 SourceLocation propertyTypeToken;
3424 SourceLocation identifierToken;
3425 SourceLocation colonToken;
3426};
3427
3428class QML_PARSER_EXPORT UiPropertyAttributes : public Node
3429{
3430 QQMLJS_DECLARE_AST_NODE(UiPropertyAttributes)
3431public:
3432 UiPropertyAttributes() { kind = K; }
3433
3434 SourceLocation defaultToken() const { return m_defaultToken; }
3435 bool isDefaultMember() const { return defaultToken().isValid(); }
3436 SourceLocation requiredToken() const { return m_requiredToken; }
3437 bool isRequired() const { return requiredToken().isValid(); }
3438 SourceLocation readonlyToken() const { return m_readonlyToken; }
3439 bool isReadonly() const { return readonlyToken().isValid(); }
3440
3441 SourceLocation propertyToken() const { return m_propertyToken; }
3442
3443 template <bool InvalidIsLargest = true>
3444 static bool compareLocationsByBegin(const SourceLocation *& lhs, const SourceLocation *& rhs)
3445 {
3446 if (lhs->isValid() && rhs->isValid())
3447 return lhs->begin() < rhs->begin();
3448 else if (lhs->isValid())
3449 return InvalidIsLargest;
3450 else
3451 return !InvalidIsLargest;
3452 }
3453
3454 void accept0(BaseVisitor *) override {} // intentionally do nothing
3455
3456 SourceLocation firstSourceLocation() const override;
3457
3458 SourceLocation lastSourceLocation() const override;
3459
3460private:
3461 friend class QQmlJS::Parser;
3462 SourceLocation m_defaultToken;
3463 SourceLocation m_readonlyToken;
3464 SourceLocation m_requiredToken;
3465 SourceLocation m_propertyToken;
3466};
3467
3468class QML_PARSER_EXPORT UiPublicMember: public UiObjectMember
3469{
3470public:
3471 QQMLJS_DECLARE_AST_NODE(UiPublicMember)
3472
3473 UiPublicMember(UiQualifiedId *memberType,
3474 QStringView name)
3475 : type(Property), memberType(memberType), name(name), statement(nullptr), binding(nullptr), parameters(nullptr)
3476 { kind = K; }
3477
3478 UiPublicMember(UiQualifiedId *memberType,
3479 QStringView name,
3480 Statement *statement)
3481 : type(Property), memberType(memberType), name(name), statement(statement), binding(nullptr), parameters(nullptr)
3482 { kind = K; }
3483
3484 void accept0(BaseVisitor *visitor) override;
3485
3486 SourceLocation firstSourceLocation() const override
3487 {
3488 if (hasAttributes)
3489 return m_attributes->firstSourceLocation();
3490 else
3491 return m_propertyToken;
3492 }
3493
3494 SourceLocation lastSourceLocation() const override
3495 {
3496 if (binding)
3497 return binding->lastSourceLocation();
3498 if (statement)
3499 return statement->lastSourceLocation();
3500
3501 return semicolonToken;
3502 }
3503
3504 SourceLocation defaultToken() const
3505 {
3506 return hasAttributes ? m_attributes->defaultToken() : SourceLocation {};
3507 }
3508 bool isDefaultMember() const { return defaultToken().isValid(); }
3509
3510 SourceLocation requiredToken() const
3511 {
3512 return hasAttributes ? m_attributes->requiredToken() : SourceLocation {};
3513 }
3514 bool isRequired() const { return requiredToken().isValid(); }
3515
3516 SourceLocation readonlyToken() const
3517 {
3518 return hasAttributes ? m_attributes->readonlyToken() : SourceLocation {};
3519 }
3520 bool isReadonly() const { return readonlyToken().isValid(); }
3521
3522 void setAttributes(UiPropertyAttributes *attributes)
3523 {
3524 m_attributes = attributes;
3525 hasAttributes = true;
3526 }
3527
3528 SourceLocation propertyToken() const
3529 {
3530 return hasAttributes ? m_attributes->propertyToken() : m_propertyToken;
3531 }
3532
3533 void setPropertyToken(SourceLocation token)
3534 {
3535 m_propertyToken = token;
3536 hasAttributes = false;
3537 }
3538
3539// attributes
3540 enum : bool { Signal, Property } type;
3541 bool hasAttributes = false;
3542 QStringView typeModifier;
3543 UiQualifiedId *memberType;
3544 QStringView name;
3545 Statement *statement; // initialized with a JS expression
3546 UiObjectMember *binding; // initialized with a QML object or array.
3547 UiParameterList *parameters;
3548 // TODO: merge source locations
3549 SourceLocation typeModifierToken;
3550 SourceLocation typeToken;
3551 SourceLocation identifierToken;
3552 SourceLocation colonToken;
3553 SourceLocation semicolonToken;
3554private:
3555 union {
3556 SourceLocation m_propertyToken = SourceLocation {};
3557 UiPropertyAttributes *m_attributes;
3558 };
3559};
3560
3561class QML_PARSER_EXPORT UiObjectDefinition: public UiObjectMember
3562{
3563public:
3564 QQMLJS_DECLARE_AST_NODE(UiObjectDefinition)
3565
3566 UiObjectDefinition(UiQualifiedId *qualifiedTypeNameId,
3567 UiObjectInitializer *initializer)
3568 : qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer)
3569 { kind = K; }
3570
3571 void accept0(BaseVisitor *visitor) override;
3572
3573 SourceLocation firstSourceLocation() const override
3574 { return qualifiedTypeNameId->identifierToken; }
3575
3576 SourceLocation lastSourceLocation() const override
3577 { return initializer->rbraceToken; }
3578
3579// attributes
3580 UiQualifiedId *qualifiedTypeNameId;
3581 UiObjectInitializer *initializer;
3582};
3583
3584class QML_PARSER_EXPORT UiInlineComponent: public UiObjectMember
3585{
3586public:
3587 QQMLJS_DECLARE_AST_NODE(UiInlineComponent)
3588
3589 UiInlineComponent(QStringView inlineComponentName, UiObjectDefinition* inlineComponent)
3590 : name(inlineComponentName), component(inlineComponent)
3591 { kind = K; }
3592
3593 SourceLocation lastSourceLocation() const override
3594 {return component->lastSourceLocation();}
3595
3596 SourceLocation firstSourceLocation() const override
3597 {return componentToken;}
3598
3599 void accept0(BaseVisitor *visitor) override;
3600
3601 // attributes
3602 QStringView name;
3603 UiObjectDefinition* component;
3604 SourceLocation componentToken;
3605 SourceLocation identifierToken;
3606};
3607
3608class QML_PARSER_EXPORT UiSourceElement: public UiObjectMember
3609{
3610public:
3611 QQMLJS_DECLARE_AST_NODE(UiSourceElement)
3612
3613 UiSourceElement(Node *sourceElement)
3614 : sourceElement(sourceElement)
3615 { kind = K; }
3616
3617 SourceLocation firstSourceLocation() const override
3618 {
3619 if (FunctionExpression *funDecl = sourceElement->asFunctionDefinition())
3620 return funDecl->firstSourceLocation();
3621 else if (VariableStatement *varStmt = cast<VariableStatement *>(ast: sourceElement))
3622 return varStmt->firstSourceLocation();
3623
3624 return SourceLocation();
3625 }
3626
3627 SourceLocation lastSourceLocation() const override
3628 {
3629 if (FunctionExpression *funDecl = sourceElement->asFunctionDefinition())
3630 return funDecl->lastSourceLocation();
3631 else if (VariableStatement *varStmt = cast<VariableStatement *>(ast: sourceElement))
3632 return varStmt->lastSourceLocation();
3633
3634 return SourceLocation();
3635 }
3636
3637 void accept0(BaseVisitor *visitor) override;
3638
3639
3640// attributes
3641 Node *sourceElement;
3642};
3643
3644class QML_PARSER_EXPORT UiObjectBinding: public UiObjectMember
3645{
3646public:
3647 QQMLJS_DECLARE_AST_NODE(UiObjectBinding)
3648
3649 UiObjectBinding(UiQualifiedId *qualifiedId,
3650 UiQualifiedId *qualifiedTypeNameId,
3651 UiObjectInitializer *initializer)
3652 : qualifiedId(qualifiedId),
3653 qualifiedTypeNameId(qualifiedTypeNameId),
3654 initializer(initializer),
3655 hasOnToken(false)
3656 { kind = K; }
3657
3658 SourceLocation firstSourceLocation() const override
3659 {
3660 if (hasOnToken && qualifiedTypeNameId)
3661 return qualifiedTypeNameId->identifierToken;
3662
3663 return qualifiedId->identifierToken;
3664 }
3665
3666 SourceLocation lastSourceLocation() const override
3667 { return initializer->rbraceToken; }
3668
3669 void accept0(BaseVisitor *visitor) override;
3670
3671
3672// attributes
3673 UiQualifiedId *qualifiedId;
3674 UiQualifiedId *qualifiedTypeNameId;
3675 UiObjectInitializer *initializer;
3676 SourceLocation colonToken;
3677 bool hasOnToken;
3678};
3679
3680class QML_PARSER_EXPORT UiScriptBinding: public UiObjectMember
3681{
3682public:
3683 QQMLJS_DECLARE_AST_NODE(UiScriptBinding)
3684
3685 UiScriptBinding(UiQualifiedId *qualifiedId,
3686 Statement *statement)
3687 : qualifiedId(qualifiedId),
3688 statement(statement)
3689 { kind = K; }
3690
3691 SourceLocation firstSourceLocation() const override
3692 { return qualifiedId->identifierToken; }
3693
3694 SourceLocation lastSourceLocation() const override
3695 { return statement->lastSourceLocation(); }
3696
3697 void accept0(BaseVisitor *visitor) override;
3698
3699// attributes
3700 UiQualifiedId *qualifiedId;
3701 Statement *statement;
3702 SourceLocation colonToken;
3703};
3704
3705class QML_PARSER_EXPORT UiArrayBinding: public UiObjectMember
3706{
3707public:
3708 QQMLJS_DECLARE_AST_NODE(UiArrayBinding)
3709
3710 UiArrayBinding(UiQualifiedId *qualifiedId,
3711 UiArrayMemberList *members)
3712 : qualifiedId(qualifiedId),
3713 members(members)
3714 { kind = K; }
3715
3716 SourceLocation firstSourceLocation() const override
3717 { Q_ASSERT(qualifiedId); return qualifiedId->identifierToken; }
3718
3719 SourceLocation lastSourceLocation() const override
3720 { return rbracketToken; }
3721
3722 void accept0(BaseVisitor *visitor) override;
3723
3724// attributes
3725 UiQualifiedId *qualifiedId;
3726 UiArrayMemberList *members;
3727 SourceLocation colonToken;
3728 SourceLocation lbracketToken;
3729 SourceLocation rbracketToken;
3730};
3731
3732class QML_PARSER_EXPORT UiEnumMemberList: public Node
3733{
3734 QQMLJS_DECLARE_AST_NODE(UiEnumMemberList)
3735public:
3736 UiEnumMemberList(QStringView member, double v = 0.0)
3737 : next(this), member(member), value(v)
3738 { kind = K; }
3739
3740 UiEnumMemberList(UiEnumMemberList *previous, QStringView member)
3741 : member(member)
3742 {
3743 kind = K;
3744 next = previous->next;
3745 previous->next = this;
3746 value = previous->value + 1;
3747 }
3748
3749 UiEnumMemberList(UiEnumMemberList *previous, QStringView member, double v)
3750 : member(member), value(v)
3751 {
3752 kind = K;
3753 next = previous->next;
3754 previous->next = this;
3755 }
3756
3757 SourceLocation firstSourceLocation() const override
3758 { return memberToken; }
3759
3760 SourceLocation lastSourceLocation() const override
3761 {
3762 auto last = lastListElement(head: this);
3763 return last->valueToken.isValid() ? last->valueToken : last->memberToken;
3764 }
3765
3766 void accept0(BaseVisitor *visitor) override;
3767
3768 UiEnumMemberList *finish()
3769 {
3770 UiEnumMemberList *head = next;
3771 next = nullptr;
3772 return head;
3773 }
3774
3775// attributes
3776 UiEnumMemberList *next;
3777 QStringView member;
3778 double value;
3779 SourceLocation memberToken;
3780 SourceLocation valueToken;
3781};
3782
3783class QML_PARSER_EXPORT UiEnumDeclaration: public UiObjectMember
3784{
3785public:
3786 QQMLJS_DECLARE_AST_NODE(UiEnumDeclaration)
3787
3788 UiEnumDeclaration(QStringView name,
3789 UiEnumMemberList *members)
3790 : name(name)
3791 , members(members)
3792 { kind = K; }
3793
3794 SourceLocation firstSourceLocation() const override
3795 { return enumToken; }
3796
3797 SourceLocation lastSourceLocation() const override
3798 { return rbraceToken; }
3799
3800 void accept0(BaseVisitor *visitor) override;
3801
3802// attributes
3803 SourceLocation enumToken;
3804 SourceLocation identifierToken;
3805 SourceLocation lbraceToken;
3806 SourceLocation rbraceToken;
3807 QStringView name;
3808 UiEnumMemberList *members;
3809};
3810
3811class QML_PARSER_EXPORT UiAnnotation: public Node
3812{
3813public:
3814 QQMLJS_DECLARE_AST_NODE(UiAnnotation)
3815
3816 UiAnnotation(UiQualifiedId *qualifiedTypeNameId,
3817 UiObjectInitializer *initializer)
3818 : qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer)
3819 { kind = K; }
3820
3821 void accept0(BaseVisitor *visitor) override;
3822
3823 SourceLocation firstSourceLocation() const override
3824 { return qualifiedTypeNameId->identifierToken; }
3825
3826 SourceLocation lastSourceLocation() const override
3827 { return initializer->rbraceToken; }
3828
3829// attributes
3830 UiQualifiedId *qualifiedTypeNameId;
3831 UiObjectInitializer *initializer;
3832};
3833
3834class QML_PARSER_EXPORT UiAnnotationList: public Node
3835{
3836public:
3837 QQMLJS_DECLARE_AST_NODE(UiAnnotationList)
3838
3839 UiAnnotationList(UiAnnotation *annotation)
3840 : next(this), annotation(annotation)
3841 { kind = K; }
3842
3843 UiAnnotationList(UiAnnotationList *previous, UiAnnotation *annotation)
3844 : annotation(annotation)
3845 {
3846 kind = K;
3847 next = previous->next;
3848 previous->next = this;
3849 }
3850
3851 void accept0(BaseVisitor *visitor) override;
3852
3853 SourceLocation firstSourceLocation() const override
3854 { return annotation->firstSourceLocation(); }
3855
3856 SourceLocation lastSourceLocation() const override
3857 { return lastListElement(head: this)->annotation->lastSourceLocation(); }
3858
3859 UiAnnotationList *finish()
3860 {
3861 UiAnnotationList *head = next;
3862 next = nullptr;
3863 return head;
3864 }
3865
3866// attributes
3867 UiAnnotationList *next;
3868 UiAnnotation *annotation;
3869};
3870
3871} } // namespace AST
3872
3873
3874QT_END_NAMESPACE
3875
3876#endif
3877

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtdeclarative/src/qml/parser/qqmljsast_p.h