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 lbracketToken;
1211 SourceLocation rbracketToken;
1212 bool isOptional = false;
1213};
1214
1215class QML_PARSER_EXPORT FieldMemberExpression: public LeftHandSideExpression
1216{
1217public:
1218 QQMLJS_DECLARE_AST_NODE(FieldMemberExpression)
1219
1220 FieldMemberExpression(ExpressionNode *b, QStringView n):
1221 base (b), name (n)
1222 { kind = K; }
1223
1224 void accept0(BaseVisitor *visitor) override;
1225
1226 SourceLocation firstSourceLocation() const override
1227 { return base->firstSourceLocation(); }
1228
1229 SourceLocation lastSourceLocation() const override
1230 { return identifierToken; }
1231
1232 // attributes
1233 ExpressionNode *base;
1234 QStringView name;
1235 SourceLocation dotToken;
1236 SourceLocation identifierToken;
1237 bool isOptional = false;
1238};
1239
1240class QML_PARSER_EXPORT TaggedTemplate : public LeftHandSideExpression
1241{
1242public:
1243 QQMLJS_DECLARE_AST_NODE(TaggedTemplate)
1244
1245 TaggedTemplate(ExpressionNode *b, TemplateLiteral *t)
1246 : base (b), templateLiteral(t)
1247 { kind = K; }
1248
1249 void accept0(BaseVisitor *visitor) override;
1250
1251 SourceLocation firstSourceLocation() const override
1252 { return base->firstSourceLocation(); }
1253
1254 SourceLocation lastSourceLocation() const override
1255 { return templateLiteral->lastSourceLocation(); }
1256
1257 // attributes
1258 ExpressionNode *base;
1259 TemplateLiteral *templateLiteral;
1260};
1261
1262class QML_PARSER_EXPORT NewMemberExpression: public LeftHandSideExpression
1263{
1264public:
1265 QQMLJS_DECLARE_AST_NODE(NewMemberExpression)
1266
1267 NewMemberExpression(ExpressionNode *b, ArgumentList *a):
1268 base (b), arguments (a)
1269 { kind = K; }
1270
1271 void accept0(BaseVisitor *visitor) override;
1272
1273 SourceLocation firstSourceLocation() const override
1274 { return newToken; }
1275
1276 SourceLocation lastSourceLocation() const override
1277 { return rparenToken; }
1278
1279 // attributes
1280 ExpressionNode *base;
1281 ArgumentList *arguments;
1282 SourceLocation newToken;
1283 SourceLocation lparenToken;
1284 SourceLocation rparenToken;
1285};
1286
1287class QML_PARSER_EXPORT NewExpression: public LeftHandSideExpression
1288{
1289public:
1290 QQMLJS_DECLARE_AST_NODE(NewExpression)
1291
1292 NewExpression(ExpressionNode *e):
1293 expression (e) { kind = K; }
1294
1295 void accept0(BaseVisitor *visitor) override;
1296
1297 SourceLocation firstSourceLocation() const override
1298 { return newToken; }
1299
1300 SourceLocation lastSourceLocation() const override
1301 { return expression->lastSourceLocation(); }
1302
1303// attributes
1304 ExpressionNode *expression;
1305 SourceLocation newToken;
1306};
1307
1308class QML_PARSER_EXPORT CallExpression: public LeftHandSideExpression
1309{
1310public:
1311 QQMLJS_DECLARE_AST_NODE(CallExpression)
1312
1313 CallExpression(ExpressionNode *b, ArgumentList *a):
1314 base (b), arguments (a)
1315 { kind = K; }
1316
1317 void accept0(BaseVisitor *visitor) override;
1318
1319 SourceLocation firstSourceLocation() const override
1320 { return base->firstSourceLocation(); }
1321
1322 SourceLocation lastSourceLocation() const override
1323 { return rparenToken; }
1324
1325// attributes
1326 ExpressionNode *base;
1327 ArgumentList *arguments;
1328 SourceLocation lparenToken;
1329 SourceLocation rparenToken;
1330 bool isOptional = false;
1331};
1332
1333class QML_PARSER_EXPORT ArgumentList: public Node
1334{
1335public:
1336 QQMLJS_DECLARE_AST_NODE(ArgumentList)
1337
1338 ArgumentList(ExpressionNode *e):
1339 expression (e), next (this)
1340 { kind = K; }
1341
1342 ArgumentList(ArgumentList *previous, ExpressionNode *e):
1343 expression (e)
1344 {
1345 kind = K;
1346 next = previous->next;
1347 previous->next = this;
1348 }
1349
1350 void accept0(BaseVisitor *visitor) override;
1351
1352 SourceLocation firstSourceLocation() const override
1353 { return expression->firstSourceLocation(); }
1354
1355 SourceLocation lastSourceLocation() const override
1356 {
1357 if (next)
1358 return next->lastSourceLocation();
1359 return expression->lastSourceLocation();
1360 }
1361
1362 inline ArgumentList *finish ()
1363 {
1364 ArgumentList *front = next;
1365 next = nullptr;
1366 return front;
1367 }
1368
1369// attributes
1370 ExpressionNode *expression;
1371 ArgumentList *next;
1372 SourceLocation commaToken;
1373 bool isSpreadElement = false;
1374};
1375
1376class QML_PARSER_EXPORT PostIncrementExpression: public ExpressionNode
1377{
1378public:
1379 QQMLJS_DECLARE_AST_NODE(PostIncrementExpression)
1380
1381 PostIncrementExpression(ExpressionNode *b):
1382 base (b) { kind = K; }
1383
1384 void accept0(BaseVisitor *visitor) override;
1385
1386 SourceLocation firstSourceLocation() const override
1387 { return base->firstSourceLocation(); }
1388
1389 SourceLocation lastSourceLocation() const override
1390 { return incrementToken; }
1391
1392// attributes
1393 ExpressionNode *base;
1394 SourceLocation incrementToken;
1395};
1396
1397class QML_PARSER_EXPORT PostDecrementExpression: public ExpressionNode
1398{
1399public:
1400 QQMLJS_DECLARE_AST_NODE(PostDecrementExpression)
1401
1402 PostDecrementExpression(ExpressionNode *b):
1403 base (b) { kind = K; }
1404
1405 void accept0(BaseVisitor *visitor) override;
1406
1407 SourceLocation firstSourceLocation() const override
1408 { return base->firstSourceLocation(); }
1409
1410 SourceLocation lastSourceLocation() const override
1411 { return decrementToken; }
1412
1413// attributes
1414 ExpressionNode *base;
1415 SourceLocation decrementToken;
1416};
1417
1418class QML_PARSER_EXPORT DeleteExpression: public ExpressionNode
1419{
1420public:
1421 QQMLJS_DECLARE_AST_NODE(DeleteExpression)
1422
1423 DeleteExpression(ExpressionNode *e):
1424 expression (e) { kind = K; }
1425
1426 void accept0(BaseVisitor *visitor) override;
1427
1428 SourceLocation firstSourceLocation() const override
1429 { return deleteToken; }
1430
1431 SourceLocation lastSourceLocation() const override
1432 { return expression->lastSourceLocation(); }
1433
1434// attributes
1435 ExpressionNode *expression;
1436 SourceLocation deleteToken;
1437};
1438
1439class QML_PARSER_EXPORT VoidExpression: public ExpressionNode
1440{
1441public:
1442 QQMLJS_DECLARE_AST_NODE(VoidExpression)
1443
1444 VoidExpression(ExpressionNode *e):
1445 expression (e) { kind = K; }
1446
1447 void accept0(BaseVisitor *visitor) override;
1448
1449 SourceLocation firstSourceLocation() const override
1450 { return voidToken; }
1451
1452 SourceLocation lastSourceLocation() const override
1453 { return expression->lastSourceLocation(); }
1454
1455// attributes
1456 ExpressionNode *expression;
1457 SourceLocation voidToken;
1458};
1459
1460class QML_PARSER_EXPORT TypeOfExpression: public ExpressionNode
1461{
1462public:
1463 QQMLJS_DECLARE_AST_NODE(TypeOfExpression)
1464
1465 TypeOfExpression(ExpressionNode *e):
1466 expression (e) { kind = K; }
1467
1468 void accept0(BaseVisitor *visitor) override;
1469
1470 SourceLocation firstSourceLocation() const override
1471 { return typeofToken; }
1472
1473 SourceLocation lastSourceLocation() const override
1474 { return expression->lastSourceLocation(); }
1475
1476// attributes
1477 ExpressionNode *expression;
1478 SourceLocation typeofToken;
1479};
1480
1481class QML_PARSER_EXPORT PreIncrementExpression: public ExpressionNode
1482{
1483public:
1484 QQMLJS_DECLARE_AST_NODE(PreIncrementExpression)
1485
1486 PreIncrementExpression(ExpressionNode *e):
1487 expression (e) { kind = K; }
1488
1489 void accept0(BaseVisitor *visitor) override;
1490
1491 SourceLocation firstSourceLocation() const override
1492 { return incrementToken; }
1493
1494 SourceLocation lastSourceLocation() const override
1495 { return expression->lastSourceLocation(); }
1496
1497// attributes
1498 ExpressionNode *expression;
1499 SourceLocation incrementToken;
1500};
1501
1502class QML_PARSER_EXPORT PreDecrementExpression: public ExpressionNode
1503{
1504public:
1505 QQMLJS_DECLARE_AST_NODE(PreDecrementExpression)
1506
1507 PreDecrementExpression(ExpressionNode *e):
1508 expression (e) { kind = K; }
1509
1510 void accept0(BaseVisitor *visitor) override;
1511
1512 SourceLocation firstSourceLocation() const override
1513 { return decrementToken; }
1514
1515 SourceLocation lastSourceLocation() const override
1516 { return expression->lastSourceLocation(); }
1517
1518// attributes
1519 ExpressionNode *expression;
1520 SourceLocation decrementToken;
1521};
1522
1523class QML_PARSER_EXPORT UnaryPlusExpression: public ExpressionNode
1524{
1525public:
1526 QQMLJS_DECLARE_AST_NODE(UnaryPlusExpression)
1527
1528 UnaryPlusExpression(ExpressionNode *e):
1529 expression (e) { kind = K; }
1530
1531 void accept0(BaseVisitor *visitor) override;
1532
1533 SourceLocation firstSourceLocation() const override
1534 { return plusToken; }
1535
1536 SourceLocation lastSourceLocation() const override
1537 { return expression->lastSourceLocation(); }
1538
1539// attributes
1540 ExpressionNode *expression;
1541 SourceLocation plusToken;
1542};
1543
1544class QML_PARSER_EXPORT UnaryMinusExpression: public ExpressionNode
1545{
1546public:
1547 QQMLJS_DECLARE_AST_NODE(UnaryMinusExpression)
1548
1549 UnaryMinusExpression(ExpressionNode *e):
1550 expression (e) { kind = K; }
1551
1552 void accept0(BaseVisitor *visitor) override;
1553
1554 SourceLocation firstSourceLocation() const override
1555 { return minusToken; }
1556
1557 SourceLocation lastSourceLocation() const override
1558 { return expression->lastSourceLocation(); }
1559
1560// attributes
1561 ExpressionNode *expression;
1562 SourceLocation minusToken;
1563};
1564
1565class QML_PARSER_EXPORT TildeExpression: public ExpressionNode
1566{
1567public:
1568 QQMLJS_DECLARE_AST_NODE(TildeExpression)
1569
1570 TildeExpression(ExpressionNode *e):
1571 expression (e) { kind = K; }
1572
1573 void accept0(BaseVisitor *visitor) override;
1574
1575 SourceLocation firstSourceLocation() const override
1576 { return tildeToken; }
1577
1578 SourceLocation lastSourceLocation() const override
1579 { return expression->lastSourceLocation(); }
1580
1581// attributes
1582 ExpressionNode *expression;
1583 SourceLocation tildeToken;
1584};
1585
1586class QML_PARSER_EXPORT NotExpression: public ExpressionNode
1587{
1588public:
1589 QQMLJS_DECLARE_AST_NODE(NotExpression)
1590
1591 NotExpression(ExpressionNode *e):
1592 expression (e) { kind = K; }
1593
1594 void accept0(BaseVisitor *visitor) override;
1595
1596 SourceLocation firstSourceLocation() const override
1597 { return notToken; }
1598
1599 SourceLocation lastSourceLocation() const override
1600 { return expression->lastSourceLocation(); }
1601
1602// attributes
1603 ExpressionNode *expression;
1604 SourceLocation notToken;
1605};
1606
1607class QML_PARSER_EXPORT BinaryExpression: public ExpressionNode
1608{
1609public:
1610 QQMLJS_DECLARE_AST_NODE(BinaryExpression)
1611
1612 BinaryExpression(ExpressionNode *l, int o, ExpressionNode *r):
1613 left (l), op (o), right (r)
1614 { kind = K; }
1615
1616 BinaryExpression *binaryExpressionCast() override;
1617
1618 void accept0(BaseVisitor *visitor) override;
1619
1620 SourceLocation firstSourceLocation() const override
1621 { return left->firstSourceLocation(); }
1622
1623 SourceLocation lastSourceLocation() const override
1624 { return right->lastSourceLocation(); }
1625
1626// attributes
1627 ExpressionNode *left;
1628 int op;
1629 ExpressionNode *right;
1630 SourceLocation operatorToken;
1631};
1632
1633class QML_PARSER_EXPORT ConditionalExpression: public ExpressionNode
1634{
1635public:
1636 QQMLJS_DECLARE_AST_NODE(ConditionalExpression)
1637
1638 ConditionalExpression(ExpressionNode *e, ExpressionNode *t, ExpressionNode *f):
1639 expression (e), ok (t), ko (f)
1640 { kind = K; }
1641
1642 void accept0(BaseVisitor *visitor) override;
1643
1644 SourceLocation firstSourceLocation() const override
1645 { return expression->firstSourceLocation(); }
1646
1647 SourceLocation lastSourceLocation() const override
1648 { return ko->lastSourceLocation(); }
1649
1650// attributes
1651 ExpressionNode *expression;
1652 ExpressionNode *ok;
1653 ExpressionNode *ko;
1654 SourceLocation questionToken;
1655 SourceLocation colonToken;
1656};
1657
1658class QML_PARSER_EXPORT Expression: public ExpressionNode // ### rename
1659{
1660public:
1661 QQMLJS_DECLARE_AST_NODE(Expression)
1662
1663 Expression(ExpressionNode *l, ExpressionNode *r):
1664 left (l), right (r) { kind = K; }
1665
1666 void accept0(BaseVisitor *visitor) override;
1667
1668 SourceLocation firstSourceLocation() const override
1669 { return left->firstSourceLocation(); }
1670
1671 SourceLocation lastSourceLocation() const override
1672 { return right->lastSourceLocation(); }
1673
1674// attributes
1675 ExpressionNode *left;
1676 ExpressionNode *right;
1677 SourceLocation commaToken;
1678};
1679
1680class QML_PARSER_EXPORT Block: public Statement
1681{
1682public:
1683 QQMLJS_DECLARE_AST_NODE(Block)
1684
1685 Block(StatementList *slist):
1686 statements (slist) { kind = K; }
1687
1688 void accept0(BaseVisitor *visitor) override;
1689
1690 SourceLocation firstSourceLocation() const override
1691 { return lbraceToken; }
1692
1693 SourceLocation lastSourceLocation() const override
1694 { return rbraceToken; }
1695
1696 // attributes
1697 StatementList *statements;
1698 SourceLocation lbraceToken;
1699 SourceLocation rbraceToken;
1700};
1701
1702class QML_PARSER_EXPORT StatementList: public Node
1703{
1704public:
1705 QQMLJS_DECLARE_AST_NODE(StatementList)
1706
1707 // ### This should be a Statement, but FunctionDeclaration currently doesn't inherit it.
1708 StatementList(Node *stmt)
1709 : statement(stmt), next (this)
1710 { kind = K; }
1711
1712 StatementList *append(StatementList *n) {
1713 n->next = next;
1714 next = n;
1715 return n;
1716 }
1717
1718 void accept0(BaseVisitor *visitor) override;
1719
1720 SourceLocation firstSourceLocation() const override
1721 { return statement->firstSourceLocation(); }
1722
1723 SourceLocation lastSourceLocation() const override
1724 {
1725 return lastListElement(head: this)->statement->lastSourceLocation();
1726 }
1727
1728 inline StatementList *finish ()
1729 {
1730 StatementList *front = next;
1731 next = nullptr;
1732 return front;
1733 }
1734
1735// attributes
1736 Node *statement = nullptr;
1737 StatementList *next;
1738};
1739
1740class QML_PARSER_EXPORT VariableDeclarationList: public Node
1741{
1742public:
1743 QQMLJS_DECLARE_AST_NODE(VariableDeclarationList)
1744
1745 VariableDeclarationList(PatternElement *decl)
1746 : declaration(decl), next(this)
1747 { kind = K; }
1748
1749 VariableDeclarationList(VariableDeclarationList *previous, PatternElement *decl)
1750 : declaration(decl)
1751 {
1752 kind = K;
1753 next = previous->next;
1754 previous->next = this;
1755 }
1756
1757 void accept0(BaseVisitor *visitor) override;
1758
1759 SourceLocation firstSourceLocation() const override
1760 { return declaration->firstSourceLocation(); }
1761
1762 SourceLocation lastSourceLocation() const override
1763 {
1764 if (next)
1765 return next->lastSourceLocation();
1766 return declaration->lastSourceLocation();
1767 }
1768
1769 inline VariableDeclarationList *finish(VariableScope s)
1770 {
1771 VariableDeclarationList *front = next;
1772 next = nullptr;
1773 VariableDeclarationList *vdl;
1774 for (vdl = front; vdl != nullptr; vdl = vdl->next) {
1775 vdl->declaration->scope = s;
1776 }
1777 return front;
1778 }
1779
1780// attributes
1781 PatternElement *declaration;
1782 VariableDeclarationList *next;
1783 SourceLocation commaToken;
1784};
1785
1786class QML_PARSER_EXPORT VariableStatement: public Statement
1787{
1788public:
1789 QQMLJS_DECLARE_AST_NODE(VariableStatement)
1790
1791 VariableStatement(VariableDeclarationList *vlist):
1792 declarations (vlist)
1793 { kind = K; }
1794
1795 void accept0(BaseVisitor *visitor) override;
1796
1797 SourceLocation firstSourceLocation() const override
1798 { return declarationKindToken; }
1799
1800 SourceLocation lastSourceLocation() const override
1801 { return declarations->lastSourceLocation(); }
1802
1803// attributes
1804 VariableDeclarationList *declarations;
1805 SourceLocation declarationKindToken;
1806};
1807
1808class QML_PARSER_EXPORT EmptyStatement: public Statement
1809{
1810public:
1811 QQMLJS_DECLARE_AST_NODE(EmptyStatement)
1812
1813 EmptyStatement() { kind = K; }
1814
1815 void accept0(BaseVisitor *visitor) override;
1816
1817 SourceLocation firstSourceLocation() const override
1818 { return semicolonToken; }
1819
1820 SourceLocation lastSourceLocation() const override
1821 { return semicolonToken; }
1822
1823// attributes
1824 SourceLocation semicolonToken;
1825};
1826
1827class QML_PARSER_EXPORT ExpressionStatement: public Statement
1828{
1829public:
1830 QQMLJS_DECLARE_AST_NODE(ExpressionStatement)
1831
1832 ExpressionStatement(ExpressionNode *e):
1833 expression (e) { kind = K; }
1834
1835 void accept0(BaseVisitor *visitor) override;
1836
1837 SourceLocation firstSourceLocation() const override
1838 { return expression->firstSourceLocation(); }
1839
1840 SourceLocation lastSourceLocation() const override
1841 { return semicolonToken; }
1842
1843// attributes
1844 ExpressionNode *expression;
1845 SourceLocation semicolonToken;
1846};
1847
1848class QML_PARSER_EXPORT IfStatement: public Statement
1849{
1850public:
1851 QQMLJS_DECLARE_AST_NODE(IfStatement)
1852
1853 IfStatement(ExpressionNode *e, Statement *t, Statement *f = nullptr):
1854 expression (e), ok (t), ko (f)
1855 { kind = K; }
1856
1857 void accept0(BaseVisitor *visitor) override;
1858
1859 SourceLocation firstSourceLocation() const override
1860 { return ifToken; }
1861
1862 SourceLocation lastSourceLocation() const override
1863 {
1864 if (ko)
1865 return ko->lastSourceLocation();
1866
1867 return ok->lastSourceLocation();
1868 }
1869
1870// attributes
1871 ExpressionNode *expression;
1872 Statement *ok;
1873 Statement *ko;
1874 SourceLocation ifToken;
1875 SourceLocation lparenToken;
1876 SourceLocation rparenToken;
1877 SourceLocation elseToken;
1878};
1879
1880class QML_PARSER_EXPORT DoWhileStatement: public Statement
1881{
1882public:
1883 QQMLJS_DECLARE_AST_NODE(DoWhileStatement)
1884
1885 DoWhileStatement(Statement *stmt, ExpressionNode *e):
1886 statement (stmt), expression (e)
1887 { kind = K; }
1888
1889 void accept0(BaseVisitor *visitor) override;
1890
1891 SourceLocation firstSourceLocation() const override
1892 { return doToken; }
1893
1894 SourceLocation lastSourceLocation() const override
1895 { return semicolonToken; }
1896
1897// attributes
1898 Statement *statement;
1899 ExpressionNode *expression;
1900 SourceLocation doToken;
1901 SourceLocation whileToken;
1902 SourceLocation lparenToken;
1903 SourceLocation rparenToken;
1904 SourceLocation semicolonToken;
1905};
1906
1907class QML_PARSER_EXPORT WhileStatement: public Statement
1908{
1909public:
1910 QQMLJS_DECLARE_AST_NODE(WhileStatement)
1911
1912 WhileStatement(ExpressionNode *e, Statement *stmt):
1913 expression (e), statement (stmt)
1914 { kind = K; }
1915
1916 void accept0(BaseVisitor *visitor) override;
1917
1918 SourceLocation firstSourceLocation() const override
1919 { return whileToken; }
1920
1921 SourceLocation lastSourceLocation() const override
1922 { return statement->lastSourceLocation(); }
1923
1924// attributes
1925 ExpressionNode *expression;
1926 Statement *statement;
1927 SourceLocation whileToken;
1928 SourceLocation lparenToken;
1929 SourceLocation rparenToken;
1930};
1931
1932class QML_PARSER_EXPORT ForStatement: public Statement
1933{
1934public:
1935 QQMLJS_DECLARE_AST_NODE(ForStatement)
1936
1937 ForStatement(ExpressionNode *i, ExpressionNode *c, ExpressionNode *e, Statement *stmt):
1938 initialiser (i), condition (c), expression (e), statement (stmt)
1939 { kind = K; }
1940
1941 ForStatement(VariableDeclarationList *vlist, ExpressionNode *c, ExpressionNode *e, Statement *stmt):
1942 declarations (vlist), condition (c), expression (e), statement (stmt)
1943 { kind = K; }
1944
1945
1946 void accept0(BaseVisitor *visitor) override;
1947
1948 SourceLocation firstSourceLocation() const override
1949 { return forToken; }
1950
1951 SourceLocation lastSourceLocation() const override
1952 { return statement->lastSourceLocation(); }
1953
1954// attributes
1955 ExpressionNode *initialiser = nullptr;
1956 VariableDeclarationList *declarations = nullptr;
1957 ExpressionNode *condition;
1958 ExpressionNode *expression;
1959 Statement *statement;
1960 SourceLocation forToken;
1961 SourceLocation lparenToken;
1962 SourceLocation firstSemicolonToken;
1963 SourceLocation secondSemicolonToken;
1964 SourceLocation rparenToken;
1965};
1966
1967enum class ForEachType {
1968 In,
1969 Of
1970};
1971
1972class QML_PARSER_EXPORT ForEachStatement: public Statement
1973{
1974public:
1975 QQMLJS_DECLARE_AST_NODE(ForEachStatement)
1976
1977 ForEachStatement(ExpressionNode *i, ExpressionNode *e, Statement *stmt)
1978 : lhs(i), expression(e), statement(stmt)
1979 { kind = K; }
1980 ForEachStatement(PatternElement *v, ExpressionNode *e, Statement *stmt)
1981 : lhs(v), expression(e), statement(stmt)
1982 { kind = K; }
1983
1984 void accept0(BaseVisitor *visitor) override;
1985
1986 SourceLocation firstSourceLocation() const override
1987 { return forToken; }
1988
1989 SourceLocation lastSourceLocation() const override
1990 { return statement->lastSourceLocation(); }
1991
1992 PatternElement *declaration() const {
1993 return AST::cast<PatternElement *>(ast: lhs);
1994 }
1995
1996// attributes
1997 Node *lhs;
1998 ExpressionNode *expression;
1999 Statement *statement;
2000 SourceLocation forToken;
2001 SourceLocation lparenToken;
2002 SourceLocation inOfToken;
2003 SourceLocation rparenToken;
2004 ForEachType type;
2005};
2006
2007class QML_PARSER_EXPORT ContinueStatement: public Statement
2008{
2009public:
2010 QQMLJS_DECLARE_AST_NODE(ContinueStatement)
2011
2012 ContinueStatement(QStringView l = QStringView()):
2013 label (l) { kind = K; }
2014
2015 void accept0(BaseVisitor *visitor) override;
2016
2017 SourceLocation firstSourceLocation() const override
2018 { return continueToken; }
2019
2020 SourceLocation lastSourceLocation() const override
2021 { return semicolonToken; }
2022
2023// attributes
2024 QStringView label;
2025 SourceLocation continueToken;
2026 SourceLocation identifierToken;
2027 SourceLocation semicolonToken;
2028};
2029
2030class QML_PARSER_EXPORT BreakStatement: public Statement
2031{
2032public:
2033 QQMLJS_DECLARE_AST_NODE(BreakStatement)
2034
2035 BreakStatement(QStringView l):
2036 label (l) { kind = K; }
2037
2038 void accept0(BaseVisitor *visitor) override;
2039
2040 SourceLocation firstSourceLocation() const override
2041 { return breakToken; }
2042
2043 SourceLocation lastSourceLocation() const override
2044 { return semicolonToken; }
2045
2046 // attributes
2047 QStringView label;
2048 SourceLocation breakToken;
2049 SourceLocation identifierToken;
2050 SourceLocation semicolonToken;
2051};
2052
2053class QML_PARSER_EXPORT ReturnStatement: public Statement
2054{
2055public:
2056 QQMLJS_DECLARE_AST_NODE(ReturnStatement)
2057
2058 ReturnStatement(ExpressionNode *e):
2059 expression (e) { kind = K; }
2060
2061 void accept0(BaseVisitor *visitor) override;
2062
2063 SourceLocation firstSourceLocation() const override
2064 { return returnToken; }
2065
2066 SourceLocation lastSourceLocation() const override
2067 { return semicolonToken; }
2068
2069// attributes
2070 ExpressionNode *expression;
2071 SourceLocation returnToken;
2072 SourceLocation semicolonToken;
2073};
2074
2075class QML_PARSER_EXPORT YieldExpression: public ExpressionNode
2076{
2077public:
2078 QQMLJS_DECLARE_AST_NODE(YieldExpression)
2079
2080 YieldExpression(ExpressionNode *e = nullptr):
2081 expression (e) { kind = K; }
2082
2083 void accept0(BaseVisitor *visitor) override;
2084
2085 SourceLocation firstSourceLocation() const override
2086 { return yieldToken; }
2087
2088 SourceLocation lastSourceLocation() const override
2089 { return expression ? expression->lastSourceLocation() : yieldToken; }
2090
2091// attributes
2092 ExpressionNode *expression;
2093 bool isYieldStar = false;
2094 SourceLocation yieldToken;
2095};
2096
2097class QML_PARSER_EXPORT WithStatement: public Statement
2098{
2099public:
2100 QQMLJS_DECLARE_AST_NODE(WithStatement)
2101
2102 WithStatement(ExpressionNode *e, Statement *stmt):
2103 expression (e), statement (stmt)
2104 { kind = K; }
2105
2106 void accept0(BaseVisitor *visitor) override;
2107
2108 SourceLocation firstSourceLocation() const override
2109 { return withToken; }
2110
2111 SourceLocation lastSourceLocation() const override
2112 { return statement->lastSourceLocation(); }
2113
2114// attributes
2115 ExpressionNode *expression;
2116 Statement *statement;
2117 SourceLocation withToken;
2118 SourceLocation lparenToken;
2119 SourceLocation rparenToken;
2120};
2121
2122class QML_PARSER_EXPORT CaseBlock: public Node
2123{
2124public:
2125 QQMLJS_DECLARE_AST_NODE(CaseBlock)
2126
2127 CaseBlock(CaseClauses *c, DefaultClause *d = nullptr, CaseClauses *r = nullptr):
2128 clauses (c), defaultClause (d), moreClauses (r)
2129 { kind = K; }
2130
2131 void accept0(BaseVisitor *visitor) override;
2132
2133 SourceLocation firstSourceLocation() const override
2134 { return lbraceToken; }
2135
2136 SourceLocation lastSourceLocation() const override
2137 { return rbraceToken; }
2138
2139// attributes
2140 CaseClauses *clauses;
2141 DefaultClause *defaultClause;
2142 CaseClauses *moreClauses;
2143 SourceLocation lbraceToken;
2144 SourceLocation rbraceToken;
2145};
2146
2147class QML_PARSER_EXPORT SwitchStatement: public Statement
2148{
2149public:
2150 QQMLJS_DECLARE_AST_NODE(SwitchStatement)
2151
2152 SwitchStatement(ExpressionNode *e, CaseBlock *b):
2153 expression (e), block (b)
2154 { kind = K; }
2155
2156 void accept0(BaseVisitor *visitor) override;
2157
2158 SourceLocation firstSourceLocation() const override
2159 { return switchToken; }
2160
2161 SourceLocation lastSourceLocation() const override
2162 { return block->rbraceToken; }
2163
2164// attributes
2165 ExpressionNode *expression;
2166 CaseBlock *block;
2167 SourceLocation switchToken;
2168 SourceLocation lparenToken;
2169 SourceLocation rparenToken;
2170};
2171
2172class QML_PARSER_EXPORT CaseClause: public Node
2173{
2174public:
2175 QQMLJS_DECLARE_AST_NODE(CaseClause)
2176
2177 CaseClause(ExpressionNode *e, StatementList *slist):
2178 expression (e), statements (slist)
2179 { kind = K; }
2180
2181 void accept0(BaseVisitor *visitor) override;
2182
2183 SourceLocation firstSourceLocation() const override
2184 { return caseToken; }
2185
2186 SourceLocation lastSourceLocation() const override
2187 { return statements ? statements->lastSourceLocation() : colonToken; }
2188
2189// attributes
2190 ExpressionNode *expression;
2191 StatementList *statements;
2192 SourceLocation caseToken;
2193 SourceLocation colonToken;
2194};
2195
2196class QML_PARSER_EXPORT CaseClauses: public Node
2197{
2198public:
2199 QQMLJS_DECLARE_AST_NODE(CaseClauses)
2200
2201 CaseClauses(CaseClause *c):
2202 clause (c), next (this)
2203 { kind = K; }
2204
2205 CaseClauses(CaseClauses *previous, CaseClause *c):
2206 clause (c)
2207 {
2208 kind = K;
2209 next = previous->next;
2210 previous->next = this;
2211 }
2212
2213 void accept0(BaseVisitor *visitor) override;
2214
2215 SourceLocation firstSourceLocation() const override
2216 { return clause->firstSourceLocation(); }
2217
2218 SourceLocation lastSourceLocation() const override
2219 {
2220 return lastListElement(head: this)->clause->lastSourceLocation();
2221 }
2222
2223 inline CaseClauses *finish ()
2224 {
2225 CaseClauses *front = next;
2226 next = nullptr;
2227 return front;
2228 }
2229
2230//attributes
2231 CaseClause *clause;
2232 CaseClauses *next;
2233};
2234
2235class QML_PARSER_EXPORT DefaultClause: public Node
2236{
2237public:
2238 QQMLJS_DECLARE_AST_NODE(DefaultClause)
2239
2240 DefaultClause(StatementList *slist):
2241 statements (slist)
2242 { kind = K; }
2243
2244 void accept0(BaseVisitor *visitor) override;
2245
2246 SourceLocation firstSourceLocation() const override
2247 { return defaultToken; }
2248
2249 SourceLocation lastSourceLocation() const override
2250 { return statements ? statements->lastSourceLocation() : colonToken; }
2251
2252// attributes
2253 StatementList *statements;
2254 SourceLocation defaultToken;
2255 SourceLocation colonToken;
2256};
2257
2258class QML_PARSER_EXPORT LabelledStatement: public Statement
2259{
2260public:
2261 QQMLJS_DECLARE_AST_NODE(LabelledStatement)
2262
2263 LabelledStatement(QStringView l, Statement *stmt):
2264 label (l), statement (stmt)
2265 { kind = K; }
2266
2267 void accept0(BaseVisitor *visitor) override;
2268
2269 SourceLocation firstSourceLocation() const override
2270 { return identifierToken; }
2271
2272 SourceLocation lastSourceLocation() const override
2273 { return statement->lastSourceLocation(); }
2274
2275// attributes
2276 QStringView label;
2277 Statement *statement;
2278 SourceLocation identifierToken;
2279 SourceLocation colonToken;
2280};
2281
2282class QML_PARSER_EXPORT ThrowStatement: public Statement
2283{
2284public:
2285 QQMLJS_DECLARE_AST_NODE(ThrowStatement)
2286
2287 ThrowStatement(ExpressionNode *e):
2288 expression (e) { kind = K; }
2289
2290 void accept0(BaseVisitor *visitor) override;
2291
2292 SourceLocation firstSourceLocation() const override
2293 { return throwToken; }
2294
2295 SourceLocation lastSourceLocation() const override
2296 { return semicolonToken; }
2297
2298 // attributes
2299 ExpressionNode *expression;
2300 SourceLocation throwToken;
2301 SourceLocation semicolonToken;
2302};
2303
2304class QML_PARSER_EXPORT Catch: public Node
2305{
2306public:
2307 QQMLJS_DECLARE_AST_NODE(Catch)
2308
2309 Catch(PatternElement *p, Block *stmt)
2310 : patternElement(p), statement(stmt)
2311 { kind = K; }
2312
2313 void accept0(BaseVisitor *visitor) override;
2314
2315 SourceLocation firstSourceLocation() const override
2316 { return catchToken; }
2317
2318 SourceLocation lastSourceLocation() const override
2319 { return statement->lastSourceLocation(); }
2320
2321// attributes
2322 PatternElement *patternElement;
2323 Block *statement;
2324 SourceLocation catchToken;
2325 SourceLocation lparenToken;
2326 SourceLocation identifierToken;
2327 SourceLocation rparenToken;
2328};
2329
2330class QML_PARSER_EXPORT Finally: public Node
2331{
2332public:
2333 QQMLJS_DECLARE_AST_NODE(Finally)
2334
2335 Finally(Block *stmt):
2336 statement (stmt)
2337 { kind = K; }
2338
2339 void accept0(BaseVisitor *visitor) override;
2340
2341 SourceLocation firstSourceLocation() const override
2342 { return finallyToken; }
2343
2344 SourceLocation lastSourceLocation() const override
2345 { return statement ? statement->lastSourceLocation() : finallyToken; }
2346
2347// attributes
2348 Block *statement;
2349 SourceLocation finallyToken;
2350};
2351
2352class QML_PARSER_EXPORT TryStatement: public Statement
2353{
2354public:
2355 QQMLJS_DECLARE_AST_NODE(TryStatement)
2356
2357 TryStatement(Statement *stmt, Catch *c, Finally *f):
2358 statement (stmt), catchExpression (c), finallyExpression (f)
2359 { kind = K; }
2360
2361 TryStatement(Statement *stmt, Finally *f):
2362 statement (stmt), catchExpression (nullptr), finallyExpression (f)
2363 { kind = K; }
2364
2365 TryStatement(Statement *stmt, Catch *c):
2366 statement (stmt), catchExpression (c), finallyExpression (nullptr)
2367 { kind = K; }
2368
2369 void accept0(BaseVisitor *visitor) override;
2370
2371 SourceLocation firstSourceLocation() const override
2372 { return tryToken; }
2373
2374 SourceLocation lastSourceLocation() const override
2375 {
2376 if (finallyExpression)
2377 return finallyExpression->statement->rbraceToken;
2378 else if (catchExpression)
2379 return catchExpression->statement->rbraceToken;
2380
2381 return statement->lastSourceLocation();
2382 }
2383
2384// attributes
2385 Statement *statement;
2386 Catch *catchExpression;
2387 Finally *finallyExpression;
2388 SourceLocation tryToken;
2389};
2390
2391class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode
2392{
2393public:
2394 QQMLJS_DECLARE_AST_NODE(FunctionExpression)
2395
2396 FunctionExpression(QStringView n, FormalParameterList *f, StatementList *b, TypeAnnotation *typeAnnotation = nullptr):
2397 name (n), formals (f), body (b),
2398 typeAnnotation(typeAnnotation)
2399 { kind = K; }
2400
2401 void accept0(BaseVisitor *visitor) override;
2402
2403 SourceLocation firstSourceLocation() const override
2404 { return functionToken; }
2405
2406 SourceLocation lastSourceLocation() const override
2407 { return rbraceToken; }
2408
2409 FunctionExpression *asFunctionDefinition() override;
2410
2411// attributes
2412 QStringView name;
2413 bool isArrowFunction = false;
2414 bool isGenerator = false;
2415 FormalParameterList *formals;
2416 StatementList *body;
2417 TypeAnnotation *typeAnnotation;
2418 SourceLocation functionToken;
2419 // for generators:
2420 SourceLocation starToken;
2421 SourceLocation identifierToken;
2422 SourceLocation lparenToken;
2423 SourceLocation rparenToken;
2424 SourceLocation lbraceToken;
2425 SourceLocation rbraceToken;
2426};
2427
2428class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
2429{
2430public:
2431 QQMLJS_DECLARE_AST_NODE(FunctionDeclaration)
2432
2433 FunctionDeclaration(QStringView n, FormalParameterList *f, StatementList *b, TypeAnnotation *typeAnnotation = nullptr):
2434 FunctionExpression(n, f, b, typeAnnotation)
2435 { kind = K; }
2436
2437 void accept0(BaseVisitor *visitor) override;
2438};
2439
2440class QML_PARSER_EXPORT FormalParameterList: public Node
2441{
2442public:
2443 QQMLJS_DECLARE_AST_NODE(FormalParameterList)
2444
2445 FormalParameterList(FormalParameterList *previous, PatternElement *e)
2446 : element(e)
2447 {
2448 kind = K;
2449 if (previous) {
2450 next = previous->next;
2451 previous->next = this;
2452 } else {
2453 next = this;
2454 }
2455 }
2456
2457 FormalParameterList *append(FormalParameterList *n) {
2458 n->next = next;
2459 next = n;
2460 return n;
2461 }
2462
2463 bool isSimpleParameterList()
2464 {
2465 AST::FormalParameterList *formals = this;
2466 while (formals) {
2467 PatternElement *e = formals->element;
2468 if (e && e->type == PatternElement::RestElement)
2469 return false;
2470 if (e && (e->initializer || e->bindingTarget))
2471 return false;
2472 formals = formals->next;
2473 }
2474 return true;
2475 }
2476
2477 int length()
2478 {
2479 // the length property of Function objects
2480 int l = 0;
2481 AST::FormalParameterList *formals = this;
2482 while (formals) {
2483 PatternElement *e = formals->element;
2484 if (!e || e->initializer)
2485 break;
2486 if (e->type == PatternElement::RestElement)
2487 break;
2488 ++l;
2489 formals = formals->next;
2490 }
2491 return l;
2492 }
2493
2494 bool containsName(const QString &name) const {
2495 for (const FormalParameterList *it = this; it; it = it->next) {
2496 PatternElement *b = it->element;
2497 // ### handle binding patterns
2498 if (b && b->bindingIdentifier == name)
2499 return true;
2500 }
2501 return false;
2502 }
2503
2504 BoundNames formals() const;
2505
2506 BoundNames boundNames() const;
2507
2508 void accept0(BaseVisitor *visitor) override;
2509
2510 SourceLocation firstSourceLocation() const override
2511 { return element->firstSourceLocation(); }
2512
2513 SourceLocation lastSourceLocation() const override
2514 {
2515 return lastListElement(head: this)->element->lastSourceLocation();
2516 }
2517
2518 FormalParameterList *finish(MemoryPool *pool);
2519
2520// attributes
2521 PatternElement *element = nullptr;
2522 FormalParameterList *next;
2523};
2524
2525class QML_PARSER_EXPORT ClassExpression : public ExpressionNode
2526{
2527public:
2528 QQMLJS_DECLARE_AST_NODE(ClassExpression)
2529
2530 ClassExpression(QStringView n, ExpressionNode *heritage, ClassElementList *elements)
2531 : name(n), heritage(heritage), elements(elements)
2532 { kind = K; }
2533
2534 void accept0(BaseVisitor *visitor) override;
2535
2536 SourceLocation firstSourceLocation() const override
2537 { return classToken; }
2538
2539 SourceLocation lastSourceLocation() const override
2540 { return rbraceToken; }
2541
2542 ClassExpression *asClassDefinition() override;
2543
2544// attributes
2545 QStringView name;
2546 ExpressionNode *heritage;
2547 ClassElementList *elements;
2548 SourceLocation classToken;
2549 SourceLocation identifierToken;
2550 SourceLocation lbraceToken;
2551 SourceLocation rbraceToken;
2552};
2553
2554class QML_PARSER_EXPORT ClassDeclaration: public ClassExpression
2555{
2556public:
2557 QQMLJS_DECLARE_AST_NODE(ClassDeclaration)
2558
2559 ClassDeclaration(QStringView n, ExpressionNode *heritage, ClassElementList *elements)
2560 : ClassExpression(n, heritage, elements)
2561 { kind = K; }
2562
2563 void accept0(BaseVisitor *visitor) override;
2564};
2565
2566
2567class QML_PARSER_EXPORT ClassElementList : public Node
2568{
2569public:
2570 QQMLJS_DECLARE_AST_NODE(ClassElementList)
2571
2572 ClassElementList(PatternProperty *property, bool isStatic)
2573 : isStatic(isStatic), property(property)
2574 {
2575 kind = K;
2576 next = this;
2577 }
2578
2579 ClassElementList *append(ClassElementList *n) {
2580 n->next = next;
2581 next = n;
2582 return n;
2583 }
2584
2585 void accept0(BaseVisitor *visitor) override;
2586
2587 SourceLocation firstSourceLocation() const override
2588 { return property->firstSourceLocation(); }
2589
2590 SourceLocation lastSourceLocation() const override
2591 {
2592 if (next)
2593 return next->lastSourceLocation();
2594 return property->lastSourceLocation();
2595 }
2596
2597 ClassElementList *finish();
2598
2599 bool isStatic;
2600 ClassElementList *next;
2601 PatternProperty *property;
2602};
2603
2604class QML_PARSER_EXPORT Program: public Node
2605{
2606public:
2607 QQMLJS_DECLARE_AST_NODE(Program)
2608
2609 Program(StatementList *statements)
2610 : statements(statements)
2611 { kind = K; }
2612
2613 void accept0(BaseVisitor *visitor) override;
2614
2615 SourceLocation firstSourceLocation() const override
2616 { return statements ? statements->firstSourceLocation() : SourceLocation(); }
2617
2618 SourceLocation lastSourceLocation() const override
2619 { return statements ? statements->lastSourceLocation() : SourceLocation(); }
2620
2621// attributes
2622 StatementList *statements;
2623};
2624
2625class QML_PARSER_EXPORT ImportSpecifier: public Node
2626{
2627public:
2628 QQMLJS_DECLARE_AST_NODE(ImportSpecifier)
2629
2630 ImportSpecifier(QStringView importedBinding)
2631 : importedBinding(importedBinding)
2632 {
2633 kind = K;
2634 }
2635
2636 ImportSpecifier(QStringView identifier, QStringView importedBinding)
2637 : identifier(identifier), importedBinding(importedBinding)
2638 {
2639 kind = K;
2640 }
2641
2642 void accept0(BaseVisitor *visitor) override;
2643
2644 SourceLocation firstSourceLocation() const override
2645 { return identifier.isNull() ? importedBindingToken : identifierToken; }
2646 SourceLocation lastSourceLocation() const override
2647 { return importedBindingToken; }
2648
2649// attributes
2650 SourceLocation identifierToken;
2651 SourceLocation importedBindingToken;
2652 QStringView identifier;
2653 QStringView importedBinding;
2654};
2655
2656class QML_PARSER_EXPORT ImportsList: public Node
2657{
2658public:
2659 QQMLJS_DECLARE_AST_NODE(ImportsList)
2660
2661 ImportsList(ImportSpecifier *importSpecifier)
2662 : importSpecifier(importSpecifier)
2663 {
2664 kind = K;
2665 next = this;
2666 }
2667
2668 ImportsList(ImportsList *previous, ImportSpecifier *importSpecifier)
2669 : importSpecifier(importSpecifier)
2670 {
2671 kind = K;
2672 if (previous) {
2673 next = previous->next;
2674 previous->next = this;
2675 } else {
2676 next = this;
2677 }
2678 }
2679
2680 ImportsList *finish()
2681 {
2682 ImportsList *head = next;
2683 next = nullptr;
2684 return head;
2685 }
2686
2687 void accept0(BaseVisitor *visitor) override;
2688
2689 SourceLocation firstSourceLocation() const override
2690 { return importSpecifierToken; }
2691
2692 SourceLocation lastSourceLocation() const override
2693 {
2694 return lastListElement(head: this)->importSpecifierToken;
2695 }
2696
2697// attributes
2698 SourceLocation importSpecifierToken;
2699 ImportSpecifier *importSpecifier;
2700 ImportsList *next = this;
2701};
2702
2703class QML_PARSER_EXPORT NamedImports: public Node
2704{
2705public:
2706 QQMLJS_DECLARE_AST_NODE(NamedImports)
2707
2708 NamedImports()
2709 {
2710 kind = K;
2711 }
2712
2713 NamedImports(ImportsList *importsList)
2714 : importsList(importsList)
2715 {
2716 kind = K;
2717 }
2718
2719 void accept0(BaseVisitor *visitor) override;
2720
2721 SourceLocation firstSourceLocation() const override
2722 { return leftBraceToken; }
2723 SourceLocation lastSourceLocation() const override
2724 { return rightBraceToken; }
2725
2726// attributes
2727 SourceLocation leftBraceToken;
2728 SourceLocation rightBraceToken;
2729 ImportsList *importsList = nullptr;
2730};
2731
2732class QML_PARSER_EXPORT NameSpaceImport: public Node
2733{
2734public:
2735 QQMLJS_DECLARE_AST_NODE(NameSpaceImport)
2736
2737 NameSpaceImport(QStringView importedBinding)
2738 : importedBinding(importedBinding)
2739 {
2740 kind = K;
2741 }
2742
2743 void accept0(BaseVisitor *visitor) override;
2744
2745 virtual SourceLocation firstSourceLocation() const override
2746 { return starToken; }
2747 virtual SourceLocation lastSourceLocation() const override
2748 { return importedBindingToken; }
2749
2750// attributes
2751 SourceLocation starToken;
2752 SourceLocation importedBindingToken;
2753 QStringView importedBinding;
2754};
2755
2756class QML_PARSER_EXPORT ImportClause: public Node
2757{
2758public:
2759 QQMLJS_DECLARE_AST_NODE(ImportClause)
2760
2761 ImportClause(QStringView importedDefaultBinding)
2762 : importedDefaultBinding(importedDefaultBinding)
2763 {
2764 kind = K;
2765 }
2766
2767 ImportClause(NameSpaceImport *nameSpaceImport)
2768 : nameSpaceImport(nameSpaceImport)
2769 {
2770 kind = K;
2771 }
2772
2773 ImportClause(NamedImports *namedImports)
2774 : namedImports(namedImports)
2775 {
2776 kind = K;
2777 }
2778
2779 ImportClause(QStringView importedDefaultBinding, NameSpaceImport *nameSpaceImport)
2780 : importedDefaultBinding(importedDefaultBinding)
2781 , nameSpaceImport(nameSpaceImport)
2782 {
2783 kind = K;
2784 }
2785
2786 ImportClause(QStringView importedDefaultBinding, NamedImports *namedImports)
2787 : importedDefaultBinding(importedDefaultBinding)
2788 , namedImports(namedImports)
2789 {
2790 kind = K;
2791 }
2792
2793 void accept0(BaseVisitor *visitor) override;
2794
2795 virtual SourceLocation firstSourceLocation() const override
2796 { return importedDefaultBinding.isNull() ? (nameSpaceImport ? nameSpaceImport->firstSourceLocation() : namedImports->firstSourceLocation()) : importedDefaultBindingToken; }
2797 virtual SourceLocation lastSourceLocation() const override
2798 { return importedDefaultBinding.isNull() ? (nameSpaceImport ? nameSpaceImport->lastSourceLocation() : namedImports->lastSourceLocation()) : importedDefaultBindingToken; }
2799
2800// attributes
2801 SourceLocation importedDefaultBindingToken;
2802 QStringView importedDefaultBinding;
2803 NameSpaceImport *nameSpaceImport = nullptr;
2804 NamedImports *namedImports = nullptr;
2805};
2806
2807class QML_PARSER_EXPORT FromClause: public Node
2808{
2809public:
2810 QQMLJS_DECLARE_AST_NODE(FromClause)
2811
2812 FromClause(QStringView moduleSpecifier)
2813 : moduleSpecifier(moduleSpecifier)
2814 {
2815 kind = K;
2816 }
2817
2818 void accept0(BaseVisitor *visitor) override;
2819
2820 SourceLocation firstSourceLocation() const override
2821 { return fromToken; }
2822
2823 SourceLocation lastSourceLocation() const override
2824 { return moduleSpecifierToken; }
2825
2826// attributes
2827 SourceLocation fromToken;
2828 SourceLocation moduleSpecifierToken;
2829 QStringView moduleSpecifier;
2830};
2831
2832class QML_PARSER_EXPORT ImportDeclaration: public Statement
2833{
2834public:
2835 QQMLJS_DECLARE_AST_NODE(ImportDeclaration)
2836
2837 ImportDeclaration(ImportClause *importClause, FromClause *fromClause)
2838 : importClause(importClause), fromClause(fromClause)
2839 {
2840 kind = K;
2841 }
2842
2843 ImportDeclaration(QStringView moduleSpecifier)
2844 : moduleSpecifier(moduleSpecifier)
2845 {
2846 kind = K;
2847 }
2848
2849 void accept0(BaseVisitor *visitor) override;
2850
2851 SourceLocation firstSourceLocation() const override
2852 { return importToken; }
2853
2854 SourceLocation lastSourceLocation() const override
2855 { return moduleSpecifier.isNull() ? fromClause->lastSourceLocation() : moduleSpecifierToken; }
2856
2857// attributes
2858 SourceLocation importToken;
2859 SourceLocation moduleSpecifierToken;
2860 QStringView moduleSpecifier;
2861 ImportClause *importClause = nullptr;
2862 FromClause *fromClause = nullptr;
2863};
2864
2865class QML_PARSER_EXPORT ExportSpecifier: public Node
2866{
2867public:
2868 QQMLJS_DECLARE_AST_NODE(ExportSpecifier)
2869
2870 ExportSpecifier(QStringView identifier)
2871 : identifier(identifier), exportedIdentifier(identifier)
2872 {
2873 kind = K;
2874 }
2875
2876 ExportSpecifier(QStringView identifier, QStringView exportedIdentifier)
2877 : identifier(identifier), exportedIdentifier(exportedIdentifier)
2878 {
2879 kind = K;
2880 }
2881
2882 void accept0(BaseVisitor *visitor) override;
2883
2884 SourceLocation firstSourceLocation() const override
2885 { return identifierToken; }
2886 SourceLocation lastSourceLocation() const override
2887 { return exportedIdentifierToken.isValid() ? exportedIdentifierToken : identifierToken; }
2888
2889// attributes
2890 SourceLocation identifierToken;
2891 SourceLocation exportedIdentifierToken;
2892 QStringView identifier;
2893 QStringView exportedIdentifier;
2894};
2895
2896class QML_PARSER_EXPORT ExportsList: public Node
2897{
2898public:
2899 QQMLJS_DECLARE_AST_NODE(ExportsList)
2900
2901 ExportsList(ExportSpecifier *exportSpecifier)
2902 : exportSpecifier(exportSpecifier)
2903 {
2904 kind = K;
2905 next = this;
2906 }
2907
2908 ExportsList(ExportsList *previous, ExportSpecifier *exportSpecifier)
2909 : exportSpecifier(exportSpecifier)
2910 {
2911 kind = K;
2912 if (previous) {
2913 next = previous->next;
2914 previous->next = this;
2915 } else {
2916 next = this;
2917 }
2918 }
2919
2920 ExportsList *finish()
2921 {
2922 ExportsList *head = next;
2923 next = nullptr;
2924 return head;
2925 }
2926
2927 void accept0(BaseVisitor *visitor) override;
2928
2929 SourceLocation firstSourceLocation() const override
2930 { return exportSpecifier->firstSourceLocation(); }
2931 SourceLocation lastSourceLocation() const override
2932 { return lastListElement(head: this)->exportSpecifier->lastSourceLocation(); }
2933
2934// attributes
2935 ExportSpecifier *exportSpecifier;
2936 ExportsList *next;
2937};
2938
2939class QML_PARSER_EXPORT ExportClause: public Node
2940{
2941public:
2942 QQMLJS_DECLARE_AST_NODE(ExportClause)
2943
2944 ExportClause()
2945 {
2946 kind = K;
2947 }
2948
2949 ExportClause(ExportsList *exportsList)
2950 : exportsList(exportsList)
2951 {
2952 kind = K;
2953 }
2954
2955 void accept0(BaseVisitor *visitor) override;
2956
2957 SourceLocation firstSourceLocation() const override
2958 { return leftBraceToken; }
2959 SourceLocation lastSourceLocation() const override
2960 { return rightBraceToken; }
2961
2962// attributes
2963 SourceLocation leftBraceToken;
2964 SourceLocation rightBraceToken;
2965 ExportsList *exportsList = nullptr;
2966};
2967
2968class QML_PARSER_EXPORT ExportDeclaration: public Statement
2969{
2970public:
2971 QQMLJS_DECLARE_AST_NODE(ExportDeclaration)
2972
2973 ExportDeclaration(FromClause *fromClause)
2974 : fromClause(fromClause)
2975 {
2976 kind = K;
2977 }
2978
2979 ExportDeclaration(ExportClause *exportClause, FromClause *fromClause)
2980 : exportClause(exportClause), fromClause(fromClause)
2981 {
2982 kind = K;
2983 }
2984
2985 ExportDeclaration(ExportClause *exportClause)
2986 : exportClause(exportClause)
2987 {
2988 kind = K;
2989 }
2990
2991 ExportDeclaration(bool exportDefault, Node *variableStatementOrDeclaration)
2992 : variableStatementOrDeclaration(variableStatementOrDeclaration)
2993 , exportDefault(exportDefault)
2994 {
2995 kind = K;
2996 }
2997
2998 bool exportsAll() const
2999 {
3000 return fromClause && !exportClause;
3001 }
3002
3003 void accept0(BaseVisitor *visitor) override;
3004
3005 SourceLocation firstSourceLocation() const override
3006 { return exportToken; }
3007 SourceLocation lastSourceLocation() const override
3008 { return fromClause ? fromClause->lastSourceLocation() : (exportClause ? exportClause->lastSourceLocation() : variableStatementOrDeclaration->lastSourceLocation()); }
3009
3010// attributes
3011 SourceLocation exportToken;
3012 ExportClause *exportClause = nullptr;
3013 FromClause *fromClause = nullptr;
3014 Node *variableStatementOrDeclaration = nullptr;
3015 bool exportDefault = false;
3016};
3017
3018class QML_PARSER_EXPORT ESModule: public Node
3019{
3020public:
3021 QQMLJS_DECLARE_AST_NODE(Module)
3022
3023 ESModule(StatementList *body)
3024 : body(body)
3025 {
3026 kind = K;
3027 }
3028
3029 void accept0(BaseVisitor *visitor) override;
3030
3031 SourceLocation firstSourceLocation() const override
3032 { return body ? body->firstSourceLocation() : SourceLocation(); }
3033
3034 SourceLocation lastSourceLocation() const override
3035 { return body ? body->lastSourceLocation() : SourceLocation(); }
3036
3037// attributes
3038 StatementList *body;
3039};
3040
3041class QML_PARSER_EXPORT DebuggerStatement: public Statement
3042{
3043public:
3044 QQMLJS_DECLARE_AST_NODE(DebuggerStatement)
3045
3046 DebuggerStatement()
3047 { kind = K; }
3048
3049 void accept0(BaseVisitor *visitor) override;
3050
3051 SourceLocation firstSourceLocation() const override
3052 { return debuggerToken; }
3053
3054 SourceLocation lastSourceLocation() const override
3055 { return semicolonToken; }
3056
3057// attributes
3058 SourceLocation debuggerToken;
3059 SourceLocation semicolonToken;
3060};
3061
3062class QML_PARSER_EXPORT UiImport: public Node
3063{
3064public:
3065 QQMLJS_DECLARE_AST_NODE(UiImport)
3066
3067 UiImport(QStringView fileName)
3068 : fileName(fileName), importUri(nullptr)
3069 { kind = K; }
3070
3071 UiImport(UiQualifiedId *uri)
3072 : importUri(uri)
3073 { kind = K; }
3074
3075 void accept0(BaseVisitor *visitor) override;
3076
3077 SourceLocation firstSourceLocation() const override
3078 { return importToken; }
3079
3080 SourceLocation lastSourceLocation() const override
3081 { return semicolonToken; }
3082
3083// attributes
3084 QStringView fileName;
3085 UiQualifiedId *importUri;
3086 QStringView importId;
3087 SourceLocation importToken;
3088 SourceLocation fileNameToken;
3089 SourceLocation asToken;
3090 SourceLocation importIdToken;
3091 SourceLocation semicolonToken;
3092 UiVersionSpecifier *version = nullptr;
3093};
3094
3095class QML_PARSER_EXPORT UiObjectMember: public Node
3096{
3097public:
3098 SourceLocation firstSourceLocation() const override = 0;
3099 SourceLocation lastSourceLocation() const override = 0;
3100
3101 UiObjectMember *uiObjectMemberCast() override;
3102
3103// attributes
3104 UiAnnotationList *annotations = nullptr;
3105};
3106
3107class QML_PARSER_EXPORT UiObjectMemberList: public Node
3108{
3109public:
3110 QQMLJS_DECLARE_AST_NODE(UiObjectMemberList)
3111
3112 UiObjectMemberList(UiObjectMember *member)
3113 : next(this), member(member)
3114 { kind = K; }
3115
3116 UiObjectMemberList(UiObjectMemberList *previous, UiObjectMember *member)
3117 : member(member)
3118 {
3119 kind = K;
3120 next = previous->next;
3121 previous->next = this;
3122 }
3123
3124 void accept0(BaseVisitor *visitor) override;
3125
3126 SourceLocation firstSourceLocation() const override
3127 { return member->firstSourceLocation(); }
3128
3129 SourceLocation lastSourceLocation() const override
3130 { return lastListElement(head: this)->member->lastSourceLocation(); }
3131
3132 UiObjectMemberList *finish()
3133 {
3134 UiObjectMemberList *head = next;
3135 next = nullptr;
3136 return head;
3137 }
3138
3139// attributes
3140 UiObjectMemberList *next;
3141 UiObjectMember *member;
3142};
3143
3144class QML_PARSER_EXPORT UiPragmaValueList: public Node
3145{
3146public:
3147 QQMLJS_DECLARE_AST_NODE(UiPragmaValueList)
3148
3149 UiPragmaValueList(QStringView value)
3150 : value(value)
3151 , next(this)
3152 {
3153 kind = K;
3154 }
3155
3156 UiPragmaValueList(UiPragmaValueList *previous, QStringView value)
3157 : value(value)
3158 {
3159 kind = K;
3160 next = previous->next;
3161 previous->next = this;
3162 }
3163
3164 void accept0(BaseVisitor *visitor) override;
3165
3166 SourceLocation firstSourceLocation() const override
3167 { return location; }
3168
3169 SourceLocation lastSourceLocation() const override
3170 { return lastListElement(head: this)->location; }
3171
3172 UiPragmaValueList *finish()
3173 {
3174 UiPragmaValueList *head = next;
3175 next = nullptr;
3176 return head;
3177 }
3178
3179 QStringView value;
3180 UiPragmaValueList *next;
3181 SourceLocation location;
3182};
3183
3184class QML_PARSER_EXPORT UiPragma: public Node
3185{
3186public:
3187 QQMLJS_DECLARE_AST_NODE(UiPragma)
3188
3189 UiPragma(QStringView name, UiPragmaValueList *values = nullptr)
3190 : name(name), values(values)
3191 { kind = K; }
3192
3193 void accept0(BaseVisitor *visitor) override;
3194
3195 SourceLocation firstSourceLocation() const override
3196 { return pragmaToken; }
3197
3198 SourceLocation lastSourceLocation() const override
3199 { return semicolonToken; }
3200
3201// attributes
3202 QStringView name;
3203 UiPragmaValueList *values;
3204 SourceLocation pragmaToken;
3205 SourceLocation pragmaIdToken;
3206 SourceLocation colonToken;
3207 SourceLocation semicolonToken;
3208};
3209
3210class QML_PARSER_EXPORT UiRequired: public Node
3211{
3212public:
3213 QQMLJS_DECLARE_AST_NODE(UiRequired)
3214
3215 UiRequired(QStringView name)
3216 :name(name)
3217 { kind = K; }
3218
3219 void accept0(BaseVisitor *visitor) override;
3220
3221 SourceLocation firstSourceLocation() const override
3222 { return requiredToken; }
3223
3224 SourceLocation lastSourceLocation() const override
3225 { return semicolonToken; }
3226
3227 QStringView name;
3228 SourceLocation requiredToken;
3229 SourceLocation semicolonToken;
3230};
3231
3232class QML_PARSER_EXPORT UiHeaderItemList: public Node
3233{
3234public:
3235 QQMLJS_DECLARE_AST_NODE(UiHeaderItemList)
3236
3237 UiHeaderItemList(UiImport *import)
3238 : headerItem(import), next(this)
3239 { kind = K; }
3240
3241 UiHeaderItemList(UiPragma *pragma)
3242 : headerItem(pragma), next(this)
3243 { kind = K; }
3244
3245 UiHeaderItemList(UiHeaderItemList *previous, UiImport *import)
3246 : headerItem(import)
3247 {
3248 kind = K;
3249 next = previous->next;
3250 previous->next = this;
3251 }
3252
3253 UiHeaderItemList(UiHeaderItemList *previous, UiPragma *pragma)
3254 : headerItem(pragma)
3255 {
3256 kind = K;
3257 next = previous->next;
3258 previous->next = this;
3259 }
3260
3261 UiHeaderItemList *finish()
3262 {
3263 UiHeaderItemList *head = next;
3264 next = nullptr;
3265 return head;
3266 }
3267
3268 void accept0(BaseVisitor *visitor) override;
3269
3270 SourceLocation firstSourceLocation() const override
3271 { return headerItem->firstSourceLocation(); }
3272
3273 SourceLocation lastSourceLocation() const override
3274 { return lastListElement(head: this)->headerItem->lastSourceLocation(); }
3275
3276// attributes
3277 Node *headerItem;
3278 UiHeaderItemList *next;
3279};
3280
3281class QML_PARSER_EXPORT UiProgram: public Node
3282{
3283public:
3284 QQMLJS_DECLARE_AST_NODE(UiProgram)
3285
3286 UiProgram(UiHeaderItemList *headers, UiObjectMemberList *members)
3287 : headers(headers), members(members)
3288 { kind = K; }
3289
3290 void accept0(BaseVisitor *visitor) override;
3291
3292 SourceLocation firstSourceLocation() const override
3293 {
3294 if (headers)
3295 return headers->firstSourceLocation();
3296 else if (members)
3297 return members->firstSourceLocation();
3298 return SourceLocation();
3299 }
3300
3301 SourceLocation lastSourceLocation() const override
3302 {
3303 if (members)
3304 return members->lastSourceLocation();
3305 else if (headers)
3306 return headers->lastSourceLocation();
3307 return SourceLocation();
3308 }
3309
3310// attributes
3311 UiHeaderItemList *headers;
3312 UiObjectMemberList *members;
3313};
3314
3315class QML_PARSER_EXPORT UiArrayMemberList: public Node
3316{
3317public:
3318 QQMLJS_DECLARE_AST_NODE(UiArrayMemberList)
3319
3320 UiArrayMemberList(UiObjectMember *member)
3321 : next(this), member(member)
3322 { kind = K; }
3323
3324 UiArrayMemberList(UiArrayMemberList *previous, UiObjectMember *member)
3325 : member(member)
3326 {
3327 kind = K;
3328 next = previous->next;
3329 previous->next = this;
3330 }
3331
3332 void accept0(BaseVisitor *visitor) override;
3333
3334 SourceLocation firstSourceLocation() const override
3335 { return member->firstSourceLocation(); }
3336
3337 SourceLocation lastSourceLocation() const override
3338 { return lastListElement(head: this)->member->lastSourceLocation(); }
3339
3340 UiArrayMemberList *finish()
3341 {
3342 UiArrayMemberList *head = next;
3343 next = nullptr;
3344 return head;
3345 }
3346
3347// attributes
3348 UiArrayMemberList *next;
3349 UiObjectMember *member;
3350 SourceLocation commaToken;
3351};
3352
3353class QML_PARSER_EXPORT UiObjectInitializer: public Node
3354{
3355public:
3356 QQMLJS_DECLARE_AST_NODE(UiObjectInitializer)
3357
3358 UiObjectInitializer(UiObjectMemberList *members)
3359 : members(members)
3360 { kind = K; }
3361
3362 void accept0(BaseVisitor *visitor) override;
3363
3364 SourceLocation firstSourceLocation() const override
3365 { return lbraceToken; }
3366
3367 SourceLocation lastSourceLocation() const override
3368 { return rbraceToken; }
3369
3370// attributes
3371 SourceLocation lbraceToken;
3372 UiObjectMemberList *members;
3373 SourceLocation rbraceToken;
3374};
3375
3376class QML_PARSER_EXPORT UiParameterList: public Node
3377{
3378public:
3379 QQMLJS_DECLARE_AST_NODE(UiParameterList)
3380
3381 UiParameterList(Type *t, QStringView n):
3382 type (t), name (n), next (this)
3383 { kind = K; }
3384
3385 UiParameterList(UiParameterList *previous, Type *t, QStringView n):
3386 type (t), name (n)
3387 {
3388 kind = K;
3389 next = previous->next;
3390 previous->next = this;
3391 }
3392
3393 void accept0(BaseVisitor *) override;
3394
3395 SourceLocation firstSourceLocation() const override
3396 { return colonToken.isValid() ? identifierToken : propertyTypeToken; }
3397
3398 SourceLocation lastSourceLocation() const override
3399 {
3400 auto last = lastListElement(head: this);
3401 return last->lastOwnSourceLocation();
3402 }
3403
3404 SourceLocation lastOwnSourceLocation() const
3405 {
3406 return (colonToken.isValid() ? propertyTypeToken : identifierToken);
3407 }
3408
3409 inline UiParameterList *finish ()
3410 {
3411 UiParameterList *front = next;
3412 next = nullptr;
3413 return front;
3414 }
3415
3416// attributes
3417 Type *type;
3418 QStringView name;
3419 UiParameterList *next;
3420 SourceLocation commaToken;
3421 SourceLocation propertyTypeToken;
3422 SourceLocation identifierToken;
3423 SourceLocation colonToken;
3424};
3425
3426class QML_PARSER_EXPORT UiPropertyAttributes : public Node
3427{
3428 QQMLJS_DECLARE_AST_NODE(UiPropertyAttributes)
3429public:
3430 UiPropertyAttributes() { kind = K; }
3431
3432 SourceLocation defaultToken() const { return m_defaultToken; }
3433 bool isDefaultMember() const { return defaultToken().isValid(); }
3434 SourceLocation requiredToken() const { return m_requiredToken; }
3435 bool isRequired() const { return requiredToken().isValid(); }
3436 SourceLocation readonlyToken() const { return m_readonlyToken; }
3437 bool isReadonly() const { return readonlyToken().isValid(); }
3438
3439 SourceLocation propertyToken() const { return m_propertyToken; }
3440
3441 template <bool InvalidIsLargest = true>
3442 static bool compareLocationsByBegin(const SourceLocation *& lhs, const SourceLocation *& rhs)
3443 {
3444 if (lhs->isValid() && rhs->isValid())
3445 return lhs->begin() < rhs->begin();
3446 else if (lhs->isValid())
3447 return InvalidIsLargest;
3448 else
3449 return !InvalidIsLargest;
3450 }
3451
3452 void accept0(BaseVisitor *) override {} // intentionally do nothing
3453
3454 SourceLocation firstSourceLocation() const override;
3455
3456 SourceLocation lastSourceLocation() const override;
3457
3458private:
3459 friend class QQmlJS::Parser;
3460 SourceLocation m_defaultToken;
3461 SourceLocation m_readonlyToken;
3462 SourceLocation m_requiredToken;
3463 SourceLocation m_propertyToken;
3464};
3465
3466class QML_PARSER_EXPORT UiPublicMember: public UiObjectMember
3467{
3468public:
3469 QQMLJS_DECLARE_AST_NODE(UiPublicMember)
3470
3471 UiPublicMember(UiQualifiedId *memberType,
3472 QStringView name)
3473 : type(Property), memberType(memberType), name(name), statement(nullptr), binding(nullptr), parameters(nullptr)
3474 { kind = K; }
3475
3476 UiPublicMember(UiQualifiedId *memberType,
3477 QStringView name,
3478 Statement *statement)
3479 : type(Property), memberType(memberType), name(name), statement(statement), binding(nullptr), parameters(nullptr)
3480 { kind = K; }
3481
3482 void accept0(BaseVisitor *visitor) override;
3483
3484 SourceLocation firstSourceLocation() const override
3485 {
3486 if (hasAttributes)
3487 return m_attributes->firstSourceLocation();
3488 else
3489 return m_propertyToken;
3490 }
3491
3492 SourceLocation lastSourceLocation() const override
3493 {
3494 if (binding)
3495 return binding->lastSourceLocation();
3496 if (statement)
3497 return statement->lastSourceLocation();
3498
3499 return semicolonToken;
3500 }
3501
3502 SourceLocation defaultToken() const
3503 {
3504 return hasAttributes ? m_attributes->defaultToken() : SourceLocation {};
3505 }
3506 bool isDefaultMember() const { return defaultToken().isValid(); }
3507
3508 SourceLocation requiredToken() const
3509 {
3510 return hasAttributes ? m_attributes->requiredToken() : SourceLocation {};
3511 }
3512 bool isRequired() const { return requiredToken().isValid(); }
3513
3514 SourceLocation readonlyToken() const
3515 {
3516 return hasAttributes ? m_attributes->readonlyToken() : SourceLocation {};
3517 }
3518 bool isReadonly() const { return readonlyToken().isValid(); }
3519
3520 void setAttributes(UiPropertyAttributes *attributes)
3521 {
3522 m_attributes = attributes;
3523 hasAttributes = true;
3524 }
3525
3526 SourceLocation propertyToken() const
3527 {
3528 return hasAttributes ? m_attributes->propertyToken() : m_propertyToken;
3529 }
3530
3531 void setPropertyToken(SourceLocation token)
3532 {
3533 m_propertyToken = token;
3534 hasAttributes = false;
3535 }
3536
3537// attributes
3538 enum : bool { Signal, Property } type;
3539 bool hasAttributes = false;
3540 QStringView typeModifier;
3541 UiQualifiedId *memberType;
3542 QStringView name;
3543 Statement *statement; // initialized with a JS expression
3544 UiObjectMember *binding; // initialized with a QML object or array.
3545 UiParameterList *parameters;
3546 // TODO: merge source locations
3547 SourceLocation typeModifierToken;
3548 SourceLocation typeToken;
3549 SourceLocation identifierToken;
3550 SourceLocation colonToken;
3551 SourceLocation semicolonToken;
3552private:
3553 union {
3554 SourceLocation m_propertyToken = SourceLocation {};
3555 UiPropertyAttributes *m_attributes;
3556 };
3557};
3558
3559class QML_PARSER_EXPORT UiObjectDefinition: public UiObjectMember
3560{
3561public:
3562 QQMLJS_DECLARE_AST_NODE(UiObjectDefinition)
3563
3564 UiObjectDefinition(UiQualifiedId *qualifiedTypeNameId,
3565 UiObjectInitializer *initializer)
3566 : qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer)
3567 { kind = K; }
3568
3569 void accept0(BaseVisitor *visitor) override;
3570
3571 SourceLocation firstSourceLocation() const override
3572 { return qualifiedTypeNameId->identifierToken; }
3573
3574 SourceLocation lastSourceLocation() const override
3575 { return initializer->rbraceToken; }
3576
3577// attributes
3578 UiQualifiedId *qualifiedTypeNameId;
3579 UiObjectInitializer *initializer;
3580};
3581
3582class QML_PARSER_EXPORT UiInlineComponent: public UiObjectMember
3583{
3584public:
3585 QQMLJS_DECLARE_AST_NODE(UiInlineComponent)
3586
3587 UiInlineComponent(QStringView inlineComponentName, UiObjectDefinition* inlineComponent)
3588 : name(inlineComponentName), component(inlineComponent)
3589 { kind = K; }
3590
3591 SourceLocation lastSourceLocation() const override
3592 {return component->lastSourceLocation();}
3593
3594 SourceLocation firstSourceLocation() const override
3595 {return componentToken;}
3596
3597 void accept0(BaseVisitor *visitor) override;
3598
3599 // attributes
3600 QStringView name;
3601 UiObjectDefinition* component;
3602 SourceLocation componentToken;
3603 SourceLocation identifierToken;
3604};
3605
3606class QML_PARSER_EXPORT UiSourceElement: public UiObjectMember
3607{
3608public:
3609 QQMLJS_DECLARE_AST_NODE(UiSourceElement)
3610
3611 UiSourceElement(Node *sourceElement)
3612 : sourceElement(sourceElement)
3613 { kind = K; }
3614
3615 SourceLocation firstSourceLocation() const override
3616 {
3617 if (FunctionExpression *funDecl = sourceElement->asFunctionDefinition())
3618 return funDecl->firstSourceLocation();
3619 else if (VariableStatement *varStmt = cast<VariableStatement *>(ast: sourceElement))
3620 return varStmt->firstSourceLocation();
3621
3622 return SourceLocation();
3623 }
3624
3625 SourceLocation lastSourceLocation() const override
3626 {
3627 if (FunctionExpression *funDecl = sourceElement->asFunctionDefinition())
3628 return funDecl->lastSourceLocation();
3629 else if (VariableStatement *varStmt = cast<VariableStatement *>(ast: sourceElement))
3630 return varStmt->lastSourceLocation();
3631
3632 return SourceLocation();
3633 }
3634
3635 void accept0(BaseVisitor *visitor) override;
3636
3637
3638// attributes
3639 Node *sourceElement;
3640};
3641
3642class QML_PARSER_EXPORT UiObjectBinding: public UiObjectMember
3643{
3644public:
3645 QQMLJS_DECLARE_AST_NODE(UiObjectBinding)
3646
3647 UiObjectBinding(UiQualifiedId *qualifiedId,
3648 UiQualifiedId *qualifiedTypeNameId,
3649 UiObjectInitializer *initializer)
3650 : qualifiedId(qualifiedId),
3651 qualifiedTypeNameId(qualifiedTypeNameId),
3652 initializer(initializer),
3653 hasOnToken(false)
3654 { kind = K; }
3655
3656 SourceLocation firstSourceLocation() const override
3657 {
3658 if (hasOnToken && qualifiedTypeNameId)
3659 return qualifiedTypeNameId->identifierToken;
3660
3661 return qualifiedId->identifierToken;
3662 }
3663
3664 SourceLocation lastSourceLocation() const override
3665 { return initializer->rbraceToken; }
3666
3667 void accept0(BaseVisitor *visitor) override;
3668
3669
3670// attributes
3671 UiQualifiedId *qualifiedId;
3672 UiQualifiedId *qualifiedTypeNameId;
3673 UiObjectInitializer *initializer;
3674 SourceLocation colonToken;
3675 bool hasOnToken;
3676};
3677
3678class QML_PARSER_EXPORT UiScriptBinding: public UiObjectMember
3679{
3680public:
3681 QQMLJS_DECLARE_AST_NODE(UiScriptBinding)
3682
3683 UiScriptBinding(UiQualifiedId *qualifiedId,
3684 Statement *statement)
3685 : qualifiedId(qualifiedId),
3686 statement(statement)
3687 { kind = K; }
3688
3689 SourceLocation firstSourceLocation() const override
3690 { return qualifiedId->identifierToken; }
3691
3692 SourceLocation lastSourceLocation() const override
3693 { return statement->lastSourceLocation(); }
3694
3695 void accept0(BaseVisitor *visitor) override;
3696
3697// attributes
3698 UiQualifiedId *qualifiedId;
3699 Statement *statement;
3700 SourceLocation colonToken;
3701};
3702
3703class QML_PARSER_EXPORT UiArrayBinding: public UiObjectMember
3704{
3705public:
3706 QQMLJS_DECLARE_AST_NODE(UiArrayBinding)
3707
3708 UiArrayBinding(UiQualifiedId *qualifiedId,
3709 UiArrayMemberList *members)
3710 : qualifiedId(qualifiedId),
3711 members(members)
3712 { kind = K; }
3713
3714 SourceLocation firstSourceLocation() const override
3715 { Q_ASSERT(qualifiedId); return qualifiedId->identifierToken; }
3716
3717 SourceLocation lastSourceLocation() const override
3718 { return rbracketToken; }
3719
3720 void accept0(BaseVisitor *visitor) override;
3721
3722// attributes
3723 UiQualifiedId *qualifiedId;
3724 UiArrayMemberList *members;
3725 SourceLocation colonToken;
3726 SourceLocation lbracketToken;
3727 SourceLocation rbracketToken;
3728};
3729
3730class QML_PARSER_EXPORT UiEnumMemberList: public Node
3731{
3732 QQMLJS_DECLARE_AST_NODE(UiEnumMemberList)
3733public:
3734 UiEnumMemberList(QStringView member, double v = 0.0)
3735 : next(this), member(member), value(v)
3736 { kind = K; }
3737
3738 UiEnumMemberList(UiEnumMemberList *previous, QStringView member)
3739 : member(member)
3740 {
3741 kind = K;
3742 next = previous->next;
3743 previous->next = this;
3744 value = previous->value + 1;
3745 }
3746
3747 UiEnumMemberList(UiEnumMemberList *previous, QStringView member, double v)
3748 : member(member), value(v)
3749 {
3750 kind = K;
3751 next = previous->next;
3752 previous->next = this;
3753 }
3754
3755 SourceLocation firstSourceLocation() const override
3756 { return memberToken; }
3757
3758 SourceLocation lastSourceLocation() const override
3759 {
3760 auto last = lastListElement(head: this);
3761 return last->valueToken.isValid() ? last->valueToken : last->memberToken;
3762 }
3763
3764 void accept0(BaseVisitor *visitor) override;
3765
3766 UiEnumMemberList *finish()
3767 {
3768 UiEnumMemberList *head = next;
3769 next = nullptr;
3770 return head;
3771 }
3772
3773// attributes
3774 UiEnumMemberList *next;
3775 QStringView member;
3776 double value;
3777 SourceLocation memberToken;
3778 SourceLocation valueToken;
3779};
3780
3781class QML_PARSER_EXPORT UiEnumDeclaration: public UiObjectMember
3782{
3783public:
3784 QQMLJS_DECLARE_AST_NODE(UiEnumDeclaration)
3785
3786 UiEnumDeclaration(QStringView name,
3787 UiEnumMemberList *members)
3788 : name(name)
3789 , members(members)
3790 { kind = K; }
3791
3792 SourceLocation firstSourceLocation() const override
3793 { return enumToken; }
3794
3795 SourceLocation lastSourceLocation() const override
3796 { return rbraceToken; }
3797
3798 void accept0(BaseVisitor *visitor) override;
3799
3800// attributes
3801 SourceLocation enumToken;
3802 SourceLocation identifierToken;
3803 SourceLocation lbraceToken;
3804 SourceLocation rbraceToken;
3805 QStringView name;
3806 UiEnumMemberList *members;
3807};
3808
3809class QML_PARSER_EXPORT UiAnnotation: public Node
3810{
3811public:
3812 QQMLJS_DECLARE_AST_NODE(UiAnnotation)
3813
3814 UiAnnotation(UiQualifiedId *qualifiedTypeNameId,
3815 UiObjectInitializer *initializer)
3816 : qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer)
3817 { kind = K; }
3818
3819 void accept0(BaseVisitor *visitor) override;
3820
3821 SourceLocation firstSourceLocation() const override
3822 { return qualifiedTypeNameId->identifierToken; }
3823
3824 SourceLocation lastSourceLocation() const override
3825 { return initializer->rbraceToken; }
3826
3827// attributes
3828 UiQualifiedId *qualifiedTypeNameId;
3829 UiObjectInitializer *initializer;
3830};
3831
3832class QML_PARSER_EXPORT UiAnnotationList: public Node
3833{
3834public:
3835 QQMLJS_DECLARE_AST_NODE(UiAnnotationList)
3836
3837 UiAnnotationList(UiAnnotation *annotation)
3838 : next(this), annotation(annotation)
3839 { kind = K; }
3840
3841 UiAnnotationList(UiAnnotationList *previous, UiAnnotation *annotation)
3842 : annotation(annotation)
3843 {
3844 kind = K;
3845 next = previous->next;
3846 previous->next = this;
3847 }
3848
3849 void accept0(BaseVisitor *visitor) override;
3850
3851 SourceLocation firstSourceLocation() const override
3852 { return annotation->firstSourceLocation(); }
3853
3854 SourceLocation lastSourceLocation() const override
3855 { return lastListElement(head: this)->annotation->lastSourceLocation(); }
3856
3857 UiAnnotationList *finish()
3858 {
3859 UiAnnotationList *head = next;
3860 next = nullptr;
3861 return head;
3862 }
3863
3864// attributes
3865 UiAnnotationList *next;
3866 UiAnnotation *annotation;
3867};
3868
3869} } // namespace AST
3870
3871
3872QT_END_NAMESPACE
3873
3874#endif
3875

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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