// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QQMLJSASTVISITOR_P_H #define QQMLJSASTVISITOR_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "qqmljsastfwd_p.h" #include "qqmljsglobal_p.h" QT_BEGIN_NAMESPACE // as done in https://en.wikipedia.org/wiki/X_Macro #define QQmlJSASTUiClassListToVisit \ X(UiProgram) \ X(UiHeaderItemList) \ X(UiPragmaValueList) \ X(UiPragma) \ X(UiImport) \ X(UiPublicMember) \ X(UiSourceElement) \ X(UiObjectDefinition) \ X(UiObjectInitializer) \ X(UiObjectBinding) \ X(UiScriptBinding) \ X(UiArrayBinding) \ X(UiParameterList) \ X(UiObjectMemberList) \ X(UiArrayMemberList) \ X(UiQualifiedId) \ X(UiEnumDeclaration) \ X(UiEnumMemberList) \ X(UiVersionSpecifier) \ X(UiInlineComponent) \ X(UiAnnotation) \ X(UiAnnotationList) \ X(UiRequired) #define QQmlJSASTQQmlJSClassListToVisit \ X(TypeExpression) \ X(ThisExpression) \ X(IdentifierExpression) \ X(NullExpression) \ X(TrueLiteral) \ X(FalseLiteral) \ X(SuperLiteral) \ X(StringLiteral) \ X(TemplateLiteral) \ X(NumericLiteral) \ X(RegExpLiteral) \ X(ArrayPattern) \ X(ObjectPattern) \ X(PatternElementList) \ X(PatternPropertyList) \ X(PatternElement) \ X(PatternProperty) \ X(Elision) \ X(NestedExpression) \ X(IdentifierPropertyName) \ X(StringLiteralPropertyName) \ X(NumericLiteralPropertyName) \ X(ComputedPropertyName) \ X(ArrayMemberExpression) \ X(FieldMemberExpression) \ X(TaggedTemplate) \ X(NewMemberExpression) \ X(NewExpression) \ X(CallExpression) \ X(ArgumentList) \ X(PostIncrementExpression) \ X(PostDecrementExpression) \ X(DeleteExpression) \ X(VoidExpression) \ X(TypeOfExpression) \ X(PreIncrementExpression) \ X(PreDecrementExpression) \ X(UnaryPlusExpression) \ X(UnaryMinusExpression) \ X(TildeExpression) \ X(NotExpression) \ X(BinaryExpression) \ X(ConditionalExpression) \ X(Expression) \ X(Block) \ X(StatementList) \ X(VariableStatement) \ X(VariableDeclarationList) \ X(EmptyStatement) \ X(ExpressionStatement) \ X(IfStatement) \ X(DoWhileStatement) \ X(WhileStatement) \ X(ForStatement) \ X(ForEachStatement) \ X(ContinueStatement) \ X(BreakStatement) \ X(ReturnStatement) \ X(YieldExpression) \ X(WithStatement) \ X(SwitchStatement) \ X(CaseBlock) \ X(CaseClauses) \ X(CaseClause) \ X(DefaultClause) \ X(LabelledStatement) \ X(ThrowStatement) \ X(TryStatement) \ X(Catch) \ X(Finally) \ X(FunctionDeclaration) \ X(FunctionExpression) \ X(FormalParameterList) \ X(ClassExpression) \ X(ClassDeclaration) \ X(ClassElementList) \ X(Program) \ X(NameSpaceImport) \ X(ImportSpecifier) \ X(ImportsList) \ X(NamedImports) \ X(FromClause) \ X(ImportClause) \ X(ImportDeclaration) \ X(ExportSpecifier) \ X(ExportsList) \ X(ExportClause) \ X(ExportDeclaration) \ X(ESModule) \ X(DebuggerStatement) \ X(Type) \ X(TypeAnnotation) #define QQmlJSASTClassListToVisit QQmlJSASTUiClassListToVisit QQmlJSASTQQmlJSClassListToVisit namespace QQmlJS { namespace AST { class QML_PARSER_EXPORT BaseVisitor { public: class RecursionDepthCheck { Q_DISABLE_COPY(RecursionDepthCheck) public: RecursionDepthCheck(RecursionDepthCheck &&) = delete; RecursionDepthCheck &operator=(RecursionDepthCheck &&) = delete; RecursionDepthCheck(BaseVisitor *visitor) : m_visitor(visitor) { ++(m_visitor->m_recursionDepth); } ~RecursionDepthCheck() { --(m_visitor->m_recursionDepth); } bool operator()() const { return m_visitor->m_recursionDepth < s_recursionLimit; } private: static const quint16 s_recursionLimit = 4096; BaseVisitor *m_visitor; }; BaseVisitor(quint16 parentRecursionDepth = 0); virtual ~BaseVisitor(); virtual bool preVisit(Node *) = 0; virtual void postVisit(Node *) = 0; #define X(name) \ virtual bool visit(name *) = 0; \ virtual void endVisit(name *) = 0; QQmlJSASTClassListToVisit #undef X virtual void throwRecursionDepthError() = 0; quint16 recursionDepth() const { return m_recursionDepth; } protected: quint16 m_recursionDepth = 0; friend class RecursionDepthCheck; }; class QML_PARSER_EXPORT Visitor: public BaseVisitor { public: Visitor(quint16 parentRecursionDepth = 0); bool preVisit(Node *) override { return true; } void postVisit(Node *) override {} #define X(name) \ bool visit(name *) override { return true; } \ void endVisit(name *) override { } QQmlJSASTClassListToVisit #undef X }; class QML_PARSER_EXPORT JSVisitor : public BaseVisitor { public: JSVisitor() = default; bool preVisit(Node *) override { return true; } void postVisit(Node *) override { } #define X(name) \ bool visit(name *) override { return true; } \ void endVisit(name *) override { } QQmlJSASTQQmlJSClassListToVisit #undef X #define X(name) \ bool visit(name *) override \ { \ Q_ASSERT(false); \ return false; \ } \ void endVisit(name *) override { } QQmlJSASTUiClassListToVisit #undef X }; // namespace AST } } // namespace AST QT_END_NAMESPACE #endif // QQMLJSASTVISITOR_P_H