Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmljsimportvisitor_p.h
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef QQMLJSIMPORTEDMEMBERSVISITOR_P_H
5#define QQMLJSIMPORTEDMEMBERSVISITOR_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#include <private/qtqmlcompilerexports_p.h>
18
19#include "qqmljsannotation_p.h"
20#include "qqmljsimporter_p.h"
21#include "qqmljslogger_p.h"
22#include "qqmljsscope_p.h"
23#include "qqmljsscopesbyid_p.h"
24
25#include <QtCore/qvariant.h>
26#include <QtCore/qstack.h>
27
28#include <private/qqmljsast_p.h>
29#include <private/qqmljsdiagnosticmessage_p.h>
30#include <private/qv4compileddata_p.h>
31
32#include <functional>
33
35
36namespace QQmlJS::Dom {
38}
39
41class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSImportVisitor : public QQmlJS::AST::Visitor
42{
43public:
46 QQmlJSImporter *importer, QQmlJSLogger *logger,
47 const QString &implicitImportDirectory,
48 const QStringList &qmldirFiles = QStringList());
50
51 using QQmlJS::AST::Visitor::endVisit;
54 using QQmlJS::AST::Visitor::visit;
55
56 QQmlJSScope::Ptr result() const { return m_exportedRootScope; }
57
58 const QQmlJSLogger *logger() const { return m_logger; }
59 QQmlJSLogger *logger() { return m_logger; }
60
61 QQmlJSImporter::ImportedTypes imports() const { return m_rootScopeImports; }
62 QQmlJSScopesById addressableScopes() const { return m_scopesById; }
64 {
65 return m_signalHandlers;
66 }
67 QSet<QQmlJSScope::ConstPtr> literalScopesToCheck() const { return m_literalScopesToCheck; }
68 QList<QQmlJSScope::ConstPtr> qmlTypes() const { return m_qmlTypes; }
70 {
71 return m_scopesByIrLocation;
72 }
73
74 static QString implicitImportDirectory(
75 const QString &localFile, QQmlJSResourceFileMapper *mapper);
76
77 // ### should this be restricted?
78 QQmlJSImporter *importer() { return m_importer; }
79 const QQmlJSImporter *importer() const { return m_importer; }
80
82 {
86 };
87
88protected:
89 // Linter warnings, we might want to move this at some point
90 bool visit(QQmlJS::AST::StringLiteral *) override;
91
92 bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
93 void endVisit(QQmlJS::AST::ExpressionStatement *ast) override;
94
95 bool visit(QQmlJS::AST::UiProgram *) override;
96 void endVisit(QQmlJS::AST::UiProgram *) override;
97 bool visit(QQmlJS::AST::UiObjectDefinition *) override;
98 void endVisit(QQmlJS::AST::UiObjectDefinition *) override;
99 bool visit(QQmlJS::AST::UiInlineComponent *) override;
100 void endVisit(QQmlJS::AST::UiInlineComponent *) override;
101 bool visit(QQmlJS::AST::UiPublicMember *) override;
102 void endVisit(QQmlJS::AST::UiPublicMember *) override;
103 bool visit(QQmlJS::AST::UiRequired *required) override;
104 bool visit(QQmlJS::AST::UiScriptBinding *) override;
105 void endVisit(QQmlJS::AST::UiScriptBinding *) override;
106 bool visit(QQmlJS::AST::UiArrayBinding *) override;
107 void endVisit(QQmlJS::AST::UiArrayBinding *) override;
108 bool visit(QQmlJS::AST::UiEnumDeclaration *uied) override;
109 bool visit(QQmlJS::AST::FunctionExpression *fexpr) override;
110 void endVisit(QQmlJS::AST::FunctionExpression *) override;
111 bool visit(QQmlJS::AST::UiSourceElement *) override;
112 bool visit(QQmlJS::AST::FunctionDeclaration *fdecl) override;
113 void endVisit(QQmlJS::AST::FunctionDeclaration *) override;
114 bool visit(QQmlJS::AST::ClassExpression *ast) override;
115 void endVisit(QQmlJS::AST::ClassExpression *) override;
116 bool visit(QQmlJS::AST::UiImport *import) override;
117 bool visit(QQmlJS::AST::UiPragma *pragma) override;
118 bool visit(QQmlJS::AST::ClassDeclaration *ast) override;
119 void endVisit(QQmlJS::AST::ClassDeclaration *ast) override;
120 bool visit(QQmlJS::AST::ForStatement *ast) override;
121 void endVisit(QQmlJS::AST::ForStatement *ast) override;
122 bool visit(QQmlJS::AST::ForEachStatement *ast) override;
123 void endVisit(QQmlJS::AST::ForEachStatement *ast) override;
124 bool visit(QQmlJS::AST::Block *ast) override;
125 void endVisit(QQmlJS::AST::Block *ast) override;
126 bool visit(QQmlJS::AST::CaseBlock *ast) override;
127 void endVisit(QQmlJS::AST::CaseBlock *ast) override;
128 bool visit(QQmlJS::AST::Catch *ast) override;
129 void endVisit(QQmlJS::AST::Catch *ast) override;
130 bool visit(QQmlJS::AST::WithStatement *withStatement) override;
131 void endVisit(QQmlJS::AST::WithStatement *ast) override;
132
133 bool visit(QQmlJS::AST::VariableDeclarationList *vdl) override;
134 bool visit(QQmlJS::AST::FormalParameterList *fpl) override;
135
136 bool visit(QQmlJS::AST::UiObjectBinding *uiob) override;
137 void endVisit(QQmlJS::AST::UiObjectBinding *uiob) override;
138
139 bool visit(QQmlJS::AST::ExportDeclaration *exp) override;
140 void endVisit(QQmlJS::AST::ExportDeclaration *exp) override;
141
142 bool visit(QQmlJS::AST::ESModule *module) override;
143 void endVisit(QQmlJS::AST::ESModule *module) override;
144
145 bool visit(QQmlJS::AST::Program *program) override;
146 void endVisit(QQmlJS::AST::Program *program) override;
147
148 void endVisit(QQmlJS::AST::FieldMemberExpression *) override;
149 bool visit(QQmlJS::AST::IdentifierExpression *idexp) override;
150
151 bool visit(QQmlJS::AST::PatternElement *) override;
152
153 void throwRecursionDepthError() override;
154
159 QQmlJSImporter *m_importer = nullptr;
160 QQmlJSLogger *m_logger = nullptr;
161
167 bool m_nextIsInlineComponent = false;
168 bool m_rootIsSingleton = false;
174
175 // We need to record the locations as IR locations because those contain less data.
176 // This way we can look up objects by IR location later.
178
179 // Maps all qmlNames to the source location of their import
181 // Maps all static modules to the source location of their import
183 // Contains all import source locations (could be extracted from above but that is expensive)
185 // A set of all types that have been used during type resolution
187
189
190 // stores JS functions and Script bindings per scope (only the name). mimics
191 // the content of QmlIR::Object::functionsAndExpressions
193
195 {
200 {
201 return x.scope == y.scope && x.name == y.name;
202 }
205 {
206 return !(x == y);
207 }
208 friend size_t qHash(const FunctionOrExpressionIdentifier &x, size_t seed = 0)
209 {
210 return qHashMulti(seed, x.scope, x.name);
211 }
212 };
213
214 // tells whether last-processed UiScriptBinding is truly a script binding
215 bool m_thisScriptBindingIsJavaScript = false;
217 // stores the number of functions inside each function
220 addFunctionOrExpression(const QQmlJSScope::ConstPtr &scope, const QString &name);
221 void forgetFunctionExpression(const QString &name);
222 int synthesizeCompilationUnitRuntimeFunctionIndices(const QQmlJSScope::Ptr &scope,
223 int count) const;
224 void populateRuntimeFunctionIndicesForDocument() const;
225
226 void enterEnvironment(QQmlJSScope::ScopeType type, const QString &name,
228 // Finds an existing scope before attempting to create a new one. Returns \c
229 // true if the scope already exists and \c false if the new scope is created
230 bool enterEnvironmentNonUnique(QQmlJSScope::ScopeType type, const QString &name,
232 void leaveEnvironment();
233
234 // A set of types that have not been resolved but have been used during the
235 // AST traversal
237 template<typename ErrorHandler>
239 {
240 if (type->isFullyResolved())
241 return true;
242
243 // Note: ignore duplicates, but only after we are certain that the type
244 // is still unresolved
245 if (m_unresolvedTypes.contains(type))
246 return false;
247
248 m_unresolvedTypes.insert(type);
249
250 handle(type);
251 return false;
252 }
253 bool isTypeResolved(const QQmlJSScope::ConstPtr &type);
254
256 void setAllBindings();
257 void addDefaultProperties();
258 void processDefaultProperties();
259 void processPropertyBindings();
260 void checkRequiredProperties();
261 void processPropertyTypes();
262 void processPropertyBindingObjects();
263 void flushPendingSignalParameters();
264
266
267 void breakInheritanceCycles(const QQmlJSScope::Ptr &scope);
268 void checkDeprecation(const QQmlJSScope::ConstPtr &scope);
269 void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope);
270 bool rootScopeIsValid() const { return m_exportedRootScope->sourceLocation().isValid(); }
271
272 enum class BindingExpressionParseResult { Invalid, Script, Literal, Translation };
273 BindingExpressionParseResult parseBindingExpression(const QString &name,
274 const QQmlJS::AST::Statement *statement);
275 bool isImportPrefix(QString prefix) const;
276
277 // Used to temporarily store annotations for functions and generators wrapped in UiSourceElements
279
281 {
285 };
286
288 {
294 };
295
297 {
301 };
302
314 template<typename T>
316 {
320 };
321
328
330
334
335private:
336 void checkSignal(
337 const QQmlJSScope::ConstPtr &signalScope, const QQmlJS::SourceLocation &location,
338 const QString &handlerName, const QStringList &handlerParameters);
339 void importBaseModules();
340 void resolveAliasesAndIds();
341 void handleIdDeclaration(QQmlJS::AST::UiScriptBinding *scriptBinding);
342
343 void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr);
344 void processImportWarnings(
345 const QString &what,
346 const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation());
347 void addImportWithLocation(const QString &name, const QQmlJS::SourceLocation &loc);
348 void populateCurrentScope(QQmlJSScope::ScopeType type, const QString &name,
350 void enterRootScope(QQmlJSScope::ScopeType type, const QString &name,
352
353 void importFromHost(const QString &path, const QString &prefix,
355 void importFromQrc(const QString &path, const QString &prefix,
357
358public:
360};
361
363
364#endif // QQMLJSIMPORTEDMEMBERSVISITOR_P_H
\inmodule QtCore
Definition qhash.h:818
Definition qlist.h:74
\inmodule QtCore
Definition qhash.h:1348
QQmlJSImporter::ImportedTypes imports() const
QStack< FunctionOrExpressionIdentifier > m_functionStack
QHash< QQmlJSScope::ConstPtr, QList< QString > > m_functionsAndExpressions
QMultiHash< QString, QQmlJS::SourceLocation > m_importTypeLocationMap
QQmlJSScope::Ptr m_currentScope
QMultiHash< QString, QQmlJS::SourceLocation > m_importStaticModuleLocationMap
QQmlJSImporter * importer()
QQmlJS::SourceLocation m_pendingSignalHandler
QQmlJSScope::ConstPtr m_globalScope
QList< QQmlJSScope::ConstPtr > m_qmlTypes
const QQmlJSLogger * logger() const
QQmlJSScope::Ptr m_savedBindingOuterScope
QHash< QQmlJS::SourceLocation, QQmlJSMetaSignalHandler > m_signalHandlers
const QQmlJSImporter * importer() const
QHash< QV4::CompiledData::Location, QQmlJSScope::ConstPtr > m_scopesByIrLocation
QList< UnfinishedBinding > m_bindings
QHash< QQmlJSScope::Ptr, QVector< QQmlJSScope::Ptr > > m_pendingDefaultProperties
QQmlJSScope::Ptr result() const
QQmlJSScope::RootDocumentNameType InlineComponentOrDocumentRootName
QList< QQmlJSScope::ConstPtr > qmlTypes() const
QVector< QQmlJSScope::Ptr > m_objectDefinitionScopes
QVector< QQmlJSAnnotation > m_pendingMethodAnnotations
QQmlJSScopesById addressableScopes() const
QQmlJSScope::RootDocumentNameType RootDocumentNameType
QHash< QQmlJS::SourceLocation, QQmlJSMetaSignalHandler > signalHandlers() const
QHash< FunctionOrExpressionIdentifier, int > m_innerFunctions
QSet< QQmlJSScope::ConstPtr > literalScopesToCheck() const
QVector< PendingPropertyObjectBinding > m_pendingPropertyObjectBindings
QSet< QQmlJS::SourceLocation > m_importLocations
QVector< RequiredProperty > m_requiredProperties
QVector< PendingPropertyType > m_pendingPropertyTypes
QVector< QQmlJSScope::Ptr > m_objectBindingScopes
QSet< QQmlJSScope::ConstPtr > m_literalScopesToCheck
bool isTypeResolved(const QQmlJSScope::ConstPtr &type, ErrorHandler handle)
QSet< QQmlJSScope::ConstPtr > m_unresolvedTypes
const QQmlJSScope::Ptr m_exportedRootScope
QQmlJSImporter::ImportedTypes m_rootScopeImports
QHash< QQmlJSScope::Ptr, QVector< WithVisibilityScope< QString > > > m_propertyBindings
QQmlJSScope::ConstPtr scopeById(const QString &id, const QQmlJSScope::ConstPtr &current)
QHash< QV4::CompiledData::Location, QQmlJSScope::ConstPtr > scopesBylocation() const
QQmlJSScopesById m_scopesById
QString InlineComponentNameType
std::monostate RootDocumentNameType
std::variant< InlineComponentNameType, RootDocumentNameType > InlineComponentOrDocumentRootName
A Hashable type to differentiate document roots from different inline components.
QQmlJS::SourceLocation sourceLocation() const
virtual QQmlJSASTClassListToVisit void throwRecursionDepthError()=0
bool preVisit(Node *) override
void postVisit(Node *) override
Definition qset.h:18
bool contains(const T &value) const
Definition qset.h:71
iterator insert(const T &value)
Definition qset.h:155
\inmodule QtCore
Definition qstack.h:13
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
Combined button and popup list for selecting options.
constexpr QtPrivate::QHashMultiReturnType< T... > qHashMulti(size_t seed, const T &... args) noexcept(std::conjunction_v< QtPrivate::QNothrowHashable< T >... >)
@ Invalid
GLint location
GLuint64 GLenum void * handle
GLint GLint GLint GLint GLint x
[0]
GLenum GLenum GLsizei count
GLenum type
GLenum target
GLuint program
GLuint name
GLint y
GLsizei const GLchar *const * path
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
QList< int > list
[14]
QDataWidgetMapper * mapper
[0]
friend bool operator==(const FunctionOrExpressionIdentifier &x, const FunctionOrExpressionIdentifier &y)
friend bool operator!=(const FunctionOrExpressionIdentifier &x, const FunctionOrExpressionIdentifier &y)
friend size_t qHash(const FunctionOrExpressionIdentifier &x, size_t seed=0)
std::function< QQmlJSMetaPropertyBinding()> create
Utility wrapper that adds visibility scope to the data.