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#ifndef QV4COMPILERSCANFUNCTIONS_P_H
4#define QV4COMPILERSCANFUNCTIONS_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <private/qtqmlcompilerglobal_p.h>
18#include <private/qqmljsastvisitor_p.h>
19#include <private/qqmljsast_p.h>
20#include <private/qqmljsengine_p.h>
21#include <private/qv4compilercontext_p.h>
22#include <private/qv4util_p.h>
23#include <QtCore/QStringList>
24#include <QStack>
25#include <QScopedValueRollback>
26
27QT_BEGIN_NAMESPACE
28
29namespace QV4 {
30
31namespace Moth {
32struct Instruction;
33}
34
35namespace CompiledData {
36struct CompilationUnit;
37}
38
39namespace Compiler {
40
41class Codegen;
42
43class ScanFunctions: protected QQmlJS::AST::Visitor
44{
45 typedef QScopedValueRollback<bool> TemporaryBoolAssignment;
46public:
47 ScanFunctions(Codegen *cg, const QString &sourceCode, ContextType defaultProgramType);
48 void operator()(QQmlJS::AST::Node *node);
49
50 // see comment at its call site in generateJSCodeForFunctionsAndBindings
51 // for why this function is necessary
52 void handleTopLevelFunctionFormals(QQmlJS::AST::FunctionExpression *node) {
53 if (node && node->formals)
54 node->formals->accept(visitor: this);
55 }
56
57 void enterGlobalEnvironment(ContextType compilationMode);
58 void enterEnvironment(QQmlJS::AST::Node *node, ContextType compilationMode,
59 const QString &name);
60 void leaveEnvironment();
61
62 void enterQmlFunction(QQmlJS::AST::FunctionExpression *ast)
63 { enterFunction(ast, nameContext: FunctionNameContext::None); }
64
65protected:
66 // Function declarations add their name to the outer scope, but not the
67 // inner scope. Function expressions add their name to the inner scope,
68 // unless the name is actually picked from the outer scope rather than
69 // given after the function token. QML functions don't add their name
70 // anywhere because the name is already recorded in the QML element.
71 // This enum is used to control the behavior of enterFunction().
72 enum class FunctionNameContext {
73 None, Inner, Outer
74 };
75
76 using Visitor::visit;
77 using Visitor::endVisit;
78
79 void checkDirectivePrologue(QQmlJS::AST::StatementList *ast);
80
81 void checkName(QStringView name, const QQmlJS::SourceLocation &loc);
82
83 bool visit(QQmlJS::AST::Program *ast) override;
84 void endVisit(QQmlJS::AST::Program *) override;
85
86 bool visit(QQmlJS::AST::ESModule *ast) override;
87 void endVisit(QQmlJS::AST::ESModule *) override;
88
89 bool visit(QQmlJS::AST::ExportDeclaration *declaration) override;
90 bool visit(QQmlJS::AST::ImportDeclaration *declaration) override;
91
92 bool visit(QQmlJS::AST::CallExpression *ast) override;
93 bool visit(QQmlJS::AST::PatternElement *ast) override;
94 bool visit(QQmlJS::AST::IdentifierExpression *ast) override;
95 bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
96 bool visit(QQmlJS::AST::FunctionExpression *ast) override;
97 bool visit(QQmlJS::AST::TemplateLiteral *ast) override;
98 bool visit(QQmlJS::AST::SuperLiteral *) override;
99 bool visit(QQmlJS::AST::FieldMemberExpression *) override;
100 bool visit(QQmlJS::AST::ArrayPattern *) override;
101
102 bool enterFunction(QQmlJS::AST::FunctionExpression *ast,
103 FunctionNameContext nameContext);
104
105 void endVisit(QQmlJS::AST::FunctionExpression *) override;
106
107 bool visit(QQmlJS::AST::ObjectPattern *ast) override;
108
109 bool visit(QQmlJS::AST::PatternProperty *ast) override;
110 void endVisit(QQmlJS::AST::PatternProperty *) override;
111
112 bool visit(QQmlJS::AST::FunctionDeclaration *ast) override;
113 void endVisit(QQmlJS::AST::FunctionDeclaration *) override;
114
115 bool visit(QQmlJS::AST::ClassExpression *ast) override;
116 void endVisit(QQmlJS::AST::ClassExpression *) override;
117
118 bool visit(QQmlJS::AST::ClassDeclaration *ast) override;
119 void endVisit(QQmlJS::AST::ClassDeclaration *) override;
120
121 bool visit(QQmlJS::AST::DoWhileStatement *ast) override;
122 bool visit(QQmlJS::AST::ForStatement *ast) override;
123 void endVisit(QQmlJS::AST::ForStatement *) override;
124 bool visit(QQmlJS::AST::ForEachStatement *ast) override;
125 void endVisit(QQmlJS::AST::ForEachStatement *) override;
126
127 bool visit(QQmlJS::AST::ThisExpression *ast) override;
128
129 bool visit(QQmlJS::AST::Block *ast) override;
130 void endVisit(QQmlJS::AST::Block *ast) override;
131
132 bool visit(QQmlJS::AST::CaseBlock *ast) override;
133 void endVisit(QQmlJS::AST::CaseBlock *ast) override;
134
135 bool visit(QQmlJS::AST::Catch *ast) override;
136 void endVisit(QQmlJS::AST::Catch *ast) override;
137
138 bool visit(QQmlJS::AST::WithStatement *ast) override;
139 void endVisit(QQmlJS::AST::WithStatement *ast) override;
140
141 void throwRecursionDepthError() override;
142
143protected:
144 bool enterFunction(QQmlJS::AST::Node *ast, const QString &name,
145 QQmlJS::AST::FormalParameterList *formals,
146 QQmlJS::AST::StatementList *body, FunctionNameContext nameContext);
147
148 void calcEscapingVariables();
149// fields:
150 Codegen *_cg;
151 const QString _sourceCode;
152 Context *_context;
153 QStack<Context *> _contextStack;
154
155 bool _allowFuncDecls;
156 ContextType defaultProgramType;
157
158private:
159 static constexpr QQmlJS::AST::Node *astNodeForGlobalEnvironment = nullptr;
160};
161
162}
163
164}
165
166QT_END_NAMESPACE
167
168#endif // QV4CODEGEN_P_H
169

source code of qtdeclarative/src/qml/compiler/qv4compilerscanfunctions_p.h