Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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/qqmljscontextualtypes_p.h>
18#include <qtqmlcompilerexports.h>
19
20#include "qqmljsannotation_p.h"
21#include "qqmljsimporter_p.h"
22#include "qqmljslogger_p.h"
23#include "qqmljsscope_p.h"
24#include "qqmljsscopesbyid_p.h"
25
26#include <QtCore/qvariant.h>
27#include <QtCore/qstack.h>
28
29#include <private/qqmljsast_p.h>
30#include <private/qqmljsdiagnosticmessage_p.h>
31#include <private/qv4compileddata_p.h>
32
33#include <functional>
34
36
40
42class Q_QMLCOMPILER_EXPORT QQmlJSImportVisitor : public QQmlJS::AST::Visitor
43{
44public:
47 QQmlJSImporter *importer, QQmlJSLogger *logger,
48 const QString &implicitImportDirectory,
49 const QStringList &qmldirFiles = QStringList());
51
52 using QQmlJS::AST::Visitor::endVisit;
55 using QQmlJS::AST::Visitor::visit;
56
57 QQmlJSScope::Ptr result() const { return m_exportedRootScope; }
58
59 const QQmlJSLogger *logger() const { return m_logger; }
60 QQmlJSLogger *logger() { return m_logger; }
61
62 QQmlJSImporter::ImportedTypes imports() const { return m_rootScopeImports; }
63 QQmlJSScopesById addressableScopes() const { return m_scopesById; }
64 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> signalHandlers() const
65 {
66 return m_signalHandlers;
67 }
68 QSet<QQmlJSScope::ConstPtr> literalScopesToCheck() const { return m_literalScopesToCheck; }
69 QList<QQmlJSScope::ConstPtr> qmlTypes() const { return m_qmlTypes; }
70 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> scopesBylocation() const
71 {
72 return m_scopesByIrLocation;
73 }
74
75 static QString implicitImportDirectory(
76 const QString &localFile, QQmlJSResourceFileMapper *mapper);
77
78 // ### should this be restricted?
79 QQmlJSImporter *importer() { return m_importer; }
80 const QQmlJSImporter *importer() const { return m_importer; }
81
88
89protected:
90 // Linter warnings, we might want to move this at some point
91 bool visit(QQmlJS::AST::StringLiteral *) override;
92
93 bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
94 void endVisit(QQmlJS::AST::ExpressionStatement *ast) override;
95
96 bool visit(QQmlJS::AST::UiProgram *) override;
97 void endVisit(QQmlJS::AST::UiProgram *) override;
98 bool visit(QQmlJS::AST::UiObjectDefinition *) override;
99 void endVisit(QQmlJS::AST::UiObjectDefinition *) override;
100 bool visit(QQmlJS::AST::UiInlineComponent *) override;
101 void endVisit(QQmlJS::AST::UiInlineComponent *) override;
102 bool visit(QQmlJS::AST::UiPublicMember *) override;
103 void endVisit(QQmlJS::AST::UiPublicMember *) override;
104 bool visit(QQmlJS::AST::UiRequired *required) override;
105 bool visit(QQmlJS::AST::UiScriptBinding *) override;
106 void endVisit(QQmlJS::AST::UiScriptBinding *) override;
107 bool visit(QQmlJS::AST::UiArrayBinding *) override;
108 void endVisit(QQmlJS::AST::UiArrayBinding *) override;
109 bool visit(QQmlJS::AST::UiEnumDeclaration *uied) override;
110 bool visit(QQmlJS::AST::FunctionExpression *fexpr) override;
111 void endVisit(QQmlJS::AST::FunctionExpression *) override;
112 bool visit(QQmlJS::AST::UiSourceElement *) override;
113 bool visit(QQmlJS::AST::FunctionDeclaration *fdecl) override;
114 void endVisit(QQmlJS::AST::FunctionDeclaration *) override;
115 bool visit(QQmlJS::AST::ClassExpression *ast) override;
116 void endVisit(QQmlJS::AST::ClassExpression *) override;
117 bool visit(QQmlJS::AST::UiImport *import) override;
118 bool visit(QQmlJS::AST::UiPragma *pragma) override;
119 bool visit(QQmlJS::AST::ClassDeclaration *ast) override;
120 void endVisit(QQmlJS::AST::ClassDeclaration *ast) override;
121 bool visit(QQmlJS::AST::ForStatement *ast) override;
122 void endVisit(QQmlJS::AST::ForStatement *ast) override;
123 bool visit(QQmlJS::AST::ForEachStatement *ast) override;
124 void endVisit(QQmlJS::AST::ForEachStatement *ast) override;
125 bool visit(QQmlJS::AST::Block *ast) override;
126 void endVisit(QQmlJS::AST::Block *ast) override;
127 bool visit(QQmlJS::AST::CaseBlock *ast) override;
128 void endVisit(QQmlJS::AST::CaseBlock *ast) override;
129 bool visit(QQmlJS::AST::Catch *ast) override;
130 void endVisit(QQmlJS::AST::Catch *ast) override;
131 bool visit(QQmlJS::AST::WithStatement *withStatement) override;
132 void endVisit(QQmlJS::AST::WithStatement *ast) override;
133
134 bool visit(QQmlJS::AST::VariableDeclarationList *vdl) override;
135 bool visit(QQmlJS::AST::FormalParameterList *fpl) override;
136
137 bool visit(QQmlJS::AST::UiObjectBinding *uiob) override;
138 void endVisit(QQmlJS::AST::UiObjectBinding *uiob) override;
139
140 bool visit(QQmlJS::AST::ExportDeclaration *exp) override;
141 void endVisit(QQmlJS::AST::ExportDeclaration *exp) override;
142
143 bool visit(QQmlJS::AST::ESModule *module) override;
144 void endVisit(QQmlJS::AST::ESModule *module) override;
145
146 bool visit(QQmlJS::AST::Program *program) override;
147 void endVisit(QQmlJS::AST::Program *program) override;
148
149 void endVisit(QQmlJS::AST::FieldMemberExpression *) override;
150 bool visit(QQmlJS::AST::IdentifierExpression *idexp) override;
151
152 bool visit(QQmlJS::AST::PatternElement *) override;
153
154 void throwRecursionDepthError() override;
155
160 QQmlJSImporter *m_importer = nullptr;
161 QQmlJSLogger *m_logger = nullptr;
162
168 bool m_nextIsInlineComponent = false;
169 bool m_rootIsSingleton = false;
174 QList<QQmlJSScope::ConstPtr> m_qmlTypes;
175
176 // We need to record the locations as IR locations because those contain less data.
177 // This way we can look up objects by IR location later.
178 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_scopesByIrLocation;
179
180 // Maps all qmlNames to the source location of their import
181 QMultiHash<QString, QQmlJS::SourceLocation> m_importTypeLocationMap;
182 // Maps all static modules to the source location of their import
183 QMultiHash<QString, QQmlJS::SourceLocation> m_importStaticModuleLocationMap;
184 // Contains all import source locations (could be extracted from above but that is expensive)
185 QSet<QQmlJS::SourceLocation> m_importLocations;
186 // A set of all types that have been used during type resolution
187 QSet<QString> m_usedTypes;
188
189 QList<UnfinishedBinding> m_bindings;
190
191 // stores JS functions and Script bindings per scope (only the name). mimics
192 // the content of QmlIR::Object::functionsAndExpressions
193 QHash<QQmlJSScope::ConstPtr, QList<QString>> m_functionsAndExpressions;
194
196 {
201 {
202 return x.scope == y.scope && x.name == y.name;
203 }
206 {
207 return !(x == y);
208 }
209 friend size_t qHash(const FunctionOrExpressionIdentifier &x, size_t seed = 0)
210 {
211 return qHashMulti(seed, x.scope, x.name);
212 }
213 };
214
215 // tells whether last-processed UiScriptBinding is truly a script binding
216 bool m_thisScriptBindingIsJavaScript = false;
217 QStack<FunctionOrExpressionIdentifier> m_functionStack;
218 // stores the number of functions inside each function
219 QHash<FunctionOrExpressionIdentifier, int> m_innerFunctions;
221 addFunctionOrExpression(const QQmlJSScope::ConstPtr &scope, const QString &name);
222 void forgetFunctionExpression(const QString &name);
223 int synthesizeCompilationUnitRuntimeFunctionIndices(const QQmlJSScope::Ptr &scope,
224 int count) const;
225 void populateRuntimeFunctionIndicesForDocument() const;
226
227 void enterEnvironment(QQmlJSScope::ScopeType type, const QString &name,
229 // Finds an existing scope before attempting to create a new one. Returns \c
230 // true if the scope already exists and \c false if the new scope is created
231 bool enterEnvironmentNonUnique(QQmlJSScope::ScopeType type, const QString &name,
233 void leaveEnvironment();
234
235 // A set of types that have not been resolved but have been used during the
236 // AST traversal
237 QSet<QQmlJSScope::ConstPtr> m_unresolvedTypes;
238 template<typename ErrorHandler>
240 {
241 if (type->isFullyResolved())
242 return true;
243
244 // Note: ignore duplicates, but only after we are certain that the type
245 // is still unresolved
246 if (m_unresolvedTypes.contains(type))
247 return false;
248
249 m_unresolvedTypes.insert(type);
250
251 handle(type);
252 return false;
253 }
254 bool isTypeResolved(const QQmlJSScope::ConstPtr &type);
255
256 QVector<QQmlJSAnnotation> parseAnnotations(QQmlJS::AST::UiAnnotationList *list);
257 void setAllBindings();
258 void addDefaultProperties();
259 void processDefaultProperties();
260 void processPropertyBindings();
261 void checkRequiredProperties();
262 void processPropertyTypes();
263 void processMethodTypes();
264 void processPropertyBindingObjects();
265 void flushPendingSignalParameters();
266
268
269 void breakInheritanceCycles(const QQmlJSScope::Ptr &scope);
270 void checkDeprecation(const QQmlJSScope::ConstPtr &scope);
271 void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope);
272 bool rootScopeIsValid() const { return m_exportedRootScope->sourceLocation().isValid(); }
273
274 enum class BindingExpressionParseResult { Invalid, Script, Literal, Translation };
275 BindingExpressionParseResult parseBindingExpression(const QString &name,
276 const QQmlJS::AST::Statement *statement);
277 bool isImportPrefix(QString prefix) const;
278
279 // Used to temporarily store annotations for functions and generators wrapped in UiSourceElements
280 QVector<QQmlJSAnnotation> m_pendingMethodAnnotations;
281
288
295
304
311
323 template<typename T>
330
331 QHash<QQmlJSScope::Ptr, QVector<QQmlJSScope::Ptr>> m_pendingDefaultProperties;
332 QVector<PendingPropertyType> m_pendingPropertyTypes;
333 QVector<PendingMethodType> m_pendingMethodTypes;
334 QVector<PendingPropertyObjectBinding> m_pendingPropertyObjectBindings;
335 QVector<RequiredProperty> m_requiredProperties;
336 QVector<QQmlJSScope::Ptr> m_objectBindingScopes;
337 QVector<QQmlJSScope::Ptr> m_objectDefinitionScopes;
338
339 QHash<QQmlJSScope::Ptr, QVector<WithVisibilityScope<QString>>> m_propertyBindings;
340
341 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
342 QSet<QQmlJSScope::ConstPtr> m_literalScopesToCheck;
344
345private:
346 void checkSignal(
347 const QQmlJSScope::ConstPtr &signalScope, const QQmlJS::SourceLocation &location,
348 const QString &handlerName, const QStringList &handlerParameters);
349 void importBaseModules();
350 void resolveAliasesAndIds();
351 void handleIdDeclaration(QQmlJS::AST::UiScriptBinding *scriptBinding);
352
353 void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr);
354 void processImportWarnings(
355 const QString &what,
356 const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation());
357 void addImportWithLocation(const QString &name, const QQmlJS::SourceLocation &loc);
358 void populateCurrentScope(QQmlJSScope::ScopeType type, const QString &name,
360 void enterRootScope(QQmlJSScope::ScopeType type, const QString &name,
362
363 void importFromHost(const QString &path, const QString &prefix,
365 void importFromQrc(const QString &path, const QString &prefix,
367
368public:
370};
371
373
374#endif // QQMLJSIMPORTEDMEMBERSVISITOR_P_H
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
QVector< PendingMethodType > m_pendingMethodTypes
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
bool preVisit(Node *) override
void postVisit(Node *) override
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
Combined button and popup list for selecting options.
QList< QString > QStringList
Constructs a string list that contains the given string, str.
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.