Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmlimport_p.h
Go to the documentation of this file.
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 QQMLIMPORT_P_H
5#define QQMLIMPORT_P_H
6
7#include <QtCore/qurl.h>
8#include <QtCore/qcoreapplication.h>
9#include <QtCore/qloggingcategory.h>
10#include <QtCore/qset.h>
11#include <QtCore/qstringlist.h>
12#include <QtQml/qqmlengine.h>
13#include <QtQml/qqmlerror.h>
14#include <QtQml/qqmlfile.h>
15#include <private/qqmldirparser_p.h>
16#include <private/qqmltype_p.h>
17#include <private/qstringhash_p.h>
18#include <private/qv4compileddata_p.h>
19#include <private/qfieldlist_p.h>
20
21//
22// W A R N I N G
23// -------------
24//
25// This file is not part of the Qt API. It exists purely as an
26// implementation detail. This header file may change from version to
27// version without notice, or even be removed.
28//
29// We mean it.
30//
31
33
35class QQmlEngine;
36class QDir;
39class QQmlTypeLoader;
41class QTypeRevision;
42
44
45namespace QQmlImport {
47}
48
50{
52 Lowest = std::numeric_limits<quint8>::max(),
55 };
56
57 QString uri; // e.g. QtQuick
58 QString url; // the base path of the import
59 QTypeRevision version; // the version imported
60
61 bool isLibrary; // true means that this is not a file import
62
63 // not covered by precedence. You can set a component as implicitly imported after the fact.
64 bool implicitlyImported = false;
65 bool isInlineComponent = false;
66
68
69 QQmlDirComponents qmlDirComponents; // a copy of the components listed in the qmldir
70 QQmlDirScripts qmlDirScripts; // a copy of the scripts in the qmldir
71
73 QQmlImportNamespace *nameSpace, QList<QQmlError> *errors);
74
75 static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts,
77
78 bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
79 QTypeRevision *version_return, QQmlType* type_return,
80 const QString *base = nullptr, bool *typeRecursionDetected = nullptr,
83 QList<QQmlError> *errors = nullptr) const;
84};
85
87{
88public:
91
93
94 QQmlImportInstance *findImport(const QString &uri) const;
95
96 bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
97 QTypeRevision *version_return, QQmlType* type_return,
98 const QString *base = nullptr, QList<QQmlError> *errors = nullptr,
100 bool *typeRecursionDeteced = nullptr);
101
102 // Prefix when used as a qualified import. Otherwise empty.
104
105 // Used by QQmlImports::m_qualifiedSets
106 // set to this in unqualifiedSet to indicate that the lists of imports needs
107 // to be sorted when an inline component import was added
108 // We can't use flag pointer, as that does not work with QFieldList
110 bool needsSorting() const { return nextNamespace == this; }
112 {
113 Q_ASSERT(nextNamespace == this || nextNamespace == nullptr);
114 nextNamespace = needsSorting ? this : nullptr;
115 }
116};
117
118class Q_QML_PRIVATE_EXPORT QQmlImports final : public QQmlRefCounted<QQmlImports>
119{
120 Q_DISABLE_COPY_MOVE(QQmlImports)
121public:
123
125 ImportNoFlag = 0x0,
126 ImportIncomplete = 0x1,
127 };
128 Q_DECLARE_FLAGS(ImportFlags, ImportFlag)
129
132 {
133 while (QQmlImportNamespace *ns = m_qualifiedSets.takeFirst())
134 delete ns;
135 }
136
137 void setBaseUrl(const QUrl &url, const QString &urlString = QString());
138 QUrl baseUrl() const { return m_baseUrl; }
139
140 bool resolveType(
141 const QHashedStringRef &type, QQmlType *type_return, QTypeRevision *version_return,
142 QQmlImportNamespace **ns_return, QList<QQmlError> *errors = nullptr,
144 bool *typeRecursionDetected = nullptr) const;
145
147 QQmlImportDatabase *importDb, QString *localQmldir, QList<QQmlError> *errors)
148 {
149 Q_ASSERT(errors);
150 qCDebug(lcQmlImport) << "addImplicitImport:" << qPrintable(baseUrl().toString());
151
152 const ImportFlags flags =
153 ImportFlags(!isLocal(baseUrl()) ? ImportIncomplete : ImportNoFlag);
154 return addFileImport(
155 importDb, QLatin1String("."), QString(), QTypeRevision(),
156 flags, QQmlImportInstance::Implicit, localQmldir, errors);
157 }
158
159 bool addInlineComponentImport(
160 QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl);
161
162 QTypeRevision addFileImport(
163 QQmlImportDatabase *importDb, const QString &uri, const QString &prefix,
164 QTypeRevision version, ImportFlags flags, quint16 precedence, QString *localQmldir,
165 QList<QQmlError> *errors);
166
167 QTypeRevision addLibraryImport(
168 QQmlImportDatabase *importDb, const QString &uri, const QString &prefix,
169 QTypeRevision version, const QString &qmldirIdentifier, const QString &qmldirUrl,
170 ImportFlags flags, quint16 precedence, QList<QQmlError> *errors);
171
172 QTypeRevision updateQmldirContent(
173 QQmlImportDatabase *importDb, const QString &uri, const QString &prefix,
174 const QString &qmldirIdentifier, const QString &qmldirUrl, QList<QQmlError> *errors);
175
176 void populateCache(QQmlTypeNameCache *cache) const;
177
179 {
183 };
184
185 QList<ScriptReference> resolvedScripts() const;
186
188 {
192 };
193
194 QList<CompositeSingletonReference> resolvedCompositeSingletons() const;
195
196 static QStringList completeQmldirPaths(
197 const QString &uri, const QStringList &basePaths, QTypeRevision version);
198
199 static QString versionString(QTypeRevision version, ImportVersion importVersion);
200
201 static bool isLocal(const QString &url)
202 {
204 }
205
206 static bool isLocal(const QUrl &url)
207 {
209 }
210
211 static QUrl urlFromLocalFileOrQrcOrUrl(const QString &);
212
213 static void setDesignerSupportRequired(bool b);
214
215 static QTypeRevision validVersion(QTypeRevision version = QTypeRevision());
216
217private:
218 friend class QQmlImportDatabase;
219
220 QQmlImportNamespace *importNamespace(const QString &prefix);
221
222 bool resolveType(
223 const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return,
224 QList<QQmlError> *errors, QQmlType::RegistrationType registrationType,
225 bool *typeRecursionDetected = nullptr) const;
226
227 QQmlImportNamespace *findQualifiedNamespace(const QHashedStringRef &) const;
228
229 static QTypeRevision matchingQmldirVersion(
230 const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri,
231 QTypeRevision version, QList<QQmlError> *errors);
232
233 QTypeRevision importExtension(
234 const QString &uri, QTypeRevision version, QQmlImportDatabase *database,
235 const QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors);
236
237 bool getQmldirContent(
238 const QString &qmldirIdentifier, const QString &uri, QQmlTypeLoaderQmldirContent *qmldir,
239 QList<QQmlError> *errors);
240
241 QString resolvedUri(const QString &dir_arg, QQmlImportDatabase *database);
242
243 QQmlImportInstance *addImportToNamespace(
244 QQmlImportNamespace *nameSpace, const QString &uri, const QString &url,
246 QList<QQmlError> *errors, quint16 precedence);
247
248 QUrl m_baseUrl;
249 QString m_base;
250
251 // storage of data related to imports without a namespace
252 // TODO: This needs to be mutable because QQmlImportNamespace likes to sort itself on
253 // resolveType(). Therefore, QQmlImportNamespace::resolveType() is not const.
254 // There should be a better way to do this.
255 mutable QQmlImportNamespace m_unqualifiedset;
256
257 // storage of data related to imports with a namespace
259
260 QQmlTypeLoader *m_typeLoader = nullptr;
261};
262
263Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlImports::ImportFlags)
264
265class Q_QML_PRIVATE_EXPORT QQmlImportDatabase
266{
268public:
270
274 };
275
281 };
282
284 ~QQmlImportDatabase() { clearDirCache(); }
285
286 bool removeDynamicPlugin(const QString &pluginId);
288
291 void addImportPath(const QString& dir);
292
293 QStringList pluginPathList() const { return filePluginPath; }
295
296 void addPluginPath(const QString& path);
297
298 template<typename Callback>
301 const Callback &callback);
302
303 static QTypeRevision lockModule(const QString &uri, const QString &typeNamespace,
304 QTypeRevision version, QList<QQmlError> *errors);
305
306private:
307 friend class QQmlImports;
308 friend class QQmlPluginImporter;
309
310 QString absoluteFilePath(const QString &path) const;
311 void clearDirCache();
312
313 struct QmldirCache {
314 QTypeRevision version;
315 QString qmldirFilePath;
316 QString qmldirPathUrl;
317 QmldirCache *next;
318 };
319 // Maps from an import to a linked list of qmldir info.
320 // Used in QQmlImports::locateQmldir()
321 QStringHash<QmldirCache *> qmldirCache;
322
323 // XXX thread
324 QStringList filePluginPath;
325 QStringList fileImportPath;
326
327 QSet<QString> modulesForWhichPluginsHaveBeenLoaded;
328 QSet<QString> initializedPlugins;
330};
331
332template<typename Callback>
334 const QString &uri, QTypeRevision version,
336{
337 // Check cache first
338
340 QmldirCache *cacheTail = nullptr;
341
342 QmldirCache **cachePtr = qmldirCache.value(uri);
343 QmldirCache *cacheHead = cachePtr ? *cachePtr : nullptr;
344 if (cacheHead) {
345 cacheTail = cacheHead;
346 do {
347 if (cacheTail->version == version) {
348 if (cacheTail->qmldirFilePath.isEmpty()) {
349 return cacheTail->qmldirPathUrl.isEmpty()
352 }
353 if (callback(cacheTail->qmldirFilePath, cacheTail->qmldirPathUrl))
354 return QmldirFound;
356 }
357 } while (cacheTail->next && (cacheTail = cacheTail->next));
358 }
359
360
361 // Do not try to construct the cache if it already had any entries for the URI.
362 // Otherwise we might duplicate cache entries.
364 return result;
365
366 const bool hasInterceptors = !engine->urlInterceptors().isEmpty();
367
368 // Interceptor might redirect remote files to local ones.
369 QStringList localImportPaths = importPathList(hasInterceptors ? LocalOrRemote : Local);
370
371 // Search local import paths for a matching version
373 uri, localImportPaths, version);
374
375 QString qmldirAbsoluteFilePath;
376 for (QString qmldirPath : qmlDirPaths) {
377 if (hasInterceptors) {
378 const QUrl intercepted = engine->interceptUrl(
381 qmldirPath = QQmlFile::urlToLocalFileOrQrc(intercepted);
383 && qmldirPath.isEmpty()
384 && !QQmlFile::isLocalFile(intercepted)) {
386 }
387 }
388
389 qmldirAbsoluteFilePath = absoluteFilePath(qmldirPath);
390 if (!qmldirAbsoluteFilePath.isEmpty()) {
391 QString url;
392 const QString absolutePath = qmldirAbsoluteFilePath.left(
393 qmldirAbsoluteFilePath.lastIndexOf(u'/') + 1);
394 if (absolutePath.at(0) == u':') {
396 } else {
398 // This handles the UNC path case as when the path is retrieved from the QUrl it
399 // will convert the host name from upper case to lower case. So the absoluteFilePath
400 // is changed at this point to make sure it will match later on in that case.
401 if (qmldirAbsoluteFilePath.startsWith(QStringLiteral("//"))) {
402 qmldirAbsoluteFilePath = QUrl::fromLocalFile(qmldirAbsoluteFilePath)
404 }
405 }
406
407 QmldirCache *cache = new QmldirCache;
408 cache->version = version;
409 cache->qmldirFilePath = qmldirAbsoluteFilePath;
410 cache->qmldirPathUrl = url;
411 cache->next = nullptr;
412 if (cacheTail)
413 cacheTail->next = cache;
414 else
415 qmldirCache.insert(uri, cache);
416 cacheTail = cache;
417
418 if (result != QmldirFound)
419 result = callback(qmldirAbsoluteFilePath, url) ? QmldirFound : QmldirRejected;
420
421 // Do not return here. Rather, construct the complete cache for this URI.
422 }
423 }
424
425 // Nothing found? Add an empty cache entry to signal that for further requests.
427 QmldirCache *cache = new QmldirCache;
428 cache->version = version;
429 cache->next = cacheHead;
431 // The actual value doesn't matter as long as it's not empty.
432 // We only use it to discern QmldirInterceptedToRemote from QmldirNotFound above.
433 cache->qmldirPathUrl = QStringLiteral("intercepted");
434 }
435 qmldirCache.insert(uri, cache);
436
437 if (result == QmldirNotFound) {
439 << "locateLocalQmldir:" << qPrintable(uri) << "module's qmldir file not found";
440 }
441 } else {
443 << "locateLocalQmldir:" << qPrintable(uri) << "module's qmldir found at"
444 << qmldirAbsoluteFilePath;
445 }
446
447 return result;
448}
449
450void qmlClearEnginePlugins();// For internal use by qmlClearRegisteredProperties
451
453
454#endif // QQMLIMPORT_P_H
455
\inmodule QtCore
Definition qdir.h:19
bool isEmpty() const noexcept
Definition qlist.h:390
\inmodule QtCore
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
QList< QQmlAbstractUrlInterceptor * > urlInterceptors() const
Returns the list of currently active URL interceptors.
QUrl interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataType type) const
Run the current URL interceptors on the given url of the given type and return the result.
static bool isLocalFile(const QString &url)
Returns true if url is a local file that can be opened with QFile.
Definition qqmlfile.cpp:549
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to QFile.
Definition qqmlfile.cpp:643
The QQmlImportDatabase class manages the QML imports for a QQmlEngine.
void addPluginPath(const QString &path)
QStringList dynamicPlugins() const
QStringList importPathList(PathType type=LocalOrRemote) const
bool removeDynamicPlugin(const QString &pluginId)
void setPluginPathList(const QStringList &paths)
void addImportPath(const QString &dir)
QStringList pluginPathList() const
static QTypeRevision lockModule(const QString &uri, const QString &typeNamespace, QTypeRevision version, QList< QQmlError > *errors)
LocalQmldirResult locateLocalQmldir(const QString &uri, QTypeRevision version, LocalQmldirSearchLocation location, const Callback &callback)
void setImportPathList(const QStringList &paths)
bool needsSorting() const
QQmlImportNamespace * nextNamespace
QQmlImportInstance * findImport(const QString &uri) const
QHashedString prefix
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return, const QString *base=nullptr, QList< QQmlError > *errors=nullptr, QQmlType::RegistrationType registrationType=QQmlType::AnyRegistrationType, bool *typeRecursionDeteced=nullptr)
QList< QQmlImportInstance * > imports
void setNeedsSorting(bool needsSorting)
The QQmlImports class encapsulates one QML document's import statements.
QTypeRevision addImplicitImport(QQmlImportDatabase *importDb, QString *localQmldir, QList< QQmlError > *errors)
QUrl baseUrl() const
static QUrl urlFromLocalFileOrQrcOrUrl(const QString &)
static bool isLocal(const QString &url)
static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths, QTypeRevision version)
Forms complete paths to a qmldir file, from a base URL, a module URI and version specification.
static bool isLocal(const QUrl &url)
The QQmlTypeLoader class abstracts loading files and their dependencies over the network.
@ AnyRegistrationType
Definition qqmltype_p.h:158
Definition qset.h:18
void insert(const K &, const T &)
T * value(const K &) const
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.h:279
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5299
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
Definition qstring.cpp:5161
\inmodule QtCore
\inmodule QtCore
Definition qurl.h:94
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition qurl.cpp:3354
@ RemoveScheme
Definition qurl.h:105
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2828
#define this
Definition dialogs.cpp:9
qDeleteAll(list.begin(), list.end())
QCache< int, Employee > cache
[0]
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
#define Q_DECLARE_TR_FUNCTIONS(context)
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition qflags.h:194
#define qCDebug(category,...)
GLint location
GLboolean GLboolean GLboolean b
GLenum type
GLsizei const GLuint * paths
GLbitfield flags
GLuint name
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
const QLoggingCategory & lcQmlImport()
void qmlClearEnginePlugins()
const QLoggingCategory & lcQmlImport()
@ Unversioned
@ PartiallyVersioned
QT_BEGIN_NAMESPACE typedef void(* Callback)(QQmlNotifierEndpoint *, void **)
static QString absolutePath(const QString &path)
static QUrl resolvedUrl(const QUrl &url, const QQmlRefPointer< QQmlContextData > &context)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define qPrintable(string)
Definition qstring.h:1391
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
static QString absoluteFilePath(const Options *options, const QString &relativeFileName)
Definition main.cpp:1791
unsigned short quint16
Definition qtypes.h:43
unsigned char quint8
Definition qtypes.h:41
QUrl url("example.com")
[constructor-url-reference]
QUrl baseUrl
QObject::connect nullptr
QString dir
[11]
char * toString(const MyType &t)
[31]
QJSEngine engine
[0]
QQmlDirComponents qmlDirComponents
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return, const QString *base=nullptr, bool *typeRecursionDetected=nullptr, QQmlType::RegistrationType=QQmlType::AnyRegistrationType, QQmlImport::RecursionRestriction recursionRestriction=QQmlImport::PreventRecursion, QList< QQmlError > *errors=nullptr) const
bool setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir, QQmlImportNamespace *nameSpace, QList< QQmlError > *errors)
QQmlDirScripts qmlDirScripts
QTypeRevision version
static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, QTypeRevision version)