Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
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
13#include <QtQml/qqmlabstracturlinterceptor.h>
14#include <QtQml/qqmlerror.h>
15#include <QtQml/qqmlfile.h>
16
17#include <private/qfieldlist_p.h>
18#include <private/qqmldirparser_p.h>
19#include <private/qqmltype_p.h>
20#include <private/qstringhash_p.h>
21
22//
23// W A R N I N G
24// -------------
25//
26// This file is not part of the Qt API. It exists purely as an
27// implementation detail. This header file may change from version to
28// version without notice, or even be removed.
29//
30// We mean it.
31//
32
33QT_BEGIN_NAMESPACE
34
35class QQmlTypeNameCache;
36class QDir;
38class QQmlTypeLoader;
40class QTypeRevision;
41class QQmlTypeLoader;
42
44
48
50{
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
72 bool setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir,
73 QQmlImportNamespace *nameSpace, QList<QQmlError> *errors);
74
75 static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts,
76 QTypeRevision version);
77
78 bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
79 QTypeRevision *version_return, QQmlType* type_return,
80 const QString *base = nullptr, bool *typeRecursionDetected = nullptr,
81 QQmlType::RegistrationType = QQmlType::AnyRegistrationType,
83 QList<QQmlError> *errors = nullptr) const;
84};
85
87{
88public:
90 ~QQmlImportNamespace() { qDeleteAll(imports); }
91
93
95 const QString &moduleUri, QTypeRevision version) const;
97 const QString &location, QTypeRevision version) const;
98
99 bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
100 QTypeRevision *version_return, QQmlType* type_return,
101 const QString *base = nullptr, QList<QQmlError> *errors = nullptr,
102 QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
103 bool *typeRecursionDeteced = nullptr);
104
105 // Prefix when used as a qualified import. Otherwise empty.
107
108 // Used by QQmlImports::m_qualifiedSets
109 // set to this in unqualifiedSet to indicate that the lists of imports needs
110 // to be sorted when an inline component import was added
111 // We can't use flag pointer, as that does not work with QFieldList
113 bool needsSorting() const { return nextNamespace == this; }
114 void setNeedsSorting(bool needsSorting)
115 {
116 Q_ASSERT(nextNamespace == this || nextNamespace == nullptr);
117 nextNamespace = needsSorting ? this : nullptr;
118 }
119};
120
121class Q_QML_EXPORT QQmlImports final : public QQmlRefCounted<QQmlImports>
122{
123 Q_DISABLE_COPY_MOVE(QQmlImports)
124 Q_DECLARE_TR_FUNCTIONS(QQmlImports)
125public:
126 enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned };
127
128 enum ImportFlag : quint8 {
129 ImportNoFlag = 0x0,
130 ImportIncomplete = 0x1,
131 };
132 Q_DECLARE_FLAGS(ImportFlags, ImportFlag)
133
134 QQmlImports() = default;
135 ~QQmlImports()
136 {
137 while (QQmlImportNamespace *ns = m_qualifiedSets.takeFirst())
138 delete ns;
139 }
140
141 void setBaseUrl(const QUrl &url, const QString &urlString = QString());
142 QUrl baseUrl() const { return m_baseUrl; }
143
144 bool resolveType(
145 QQmlTypeLoader *typeLoader, const QHashedStringRef &type, QQmlType *type_return,
146 QTypeRevision *version_return, QQmlImportNamespace **ns_return,
147 QList<QQmlError> *errors = nullptr,
148 QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
149 bool *typeRecursionDetected = nullptr) const;
150
151 QTypeRevision addImplicitImport(
152 QQmlTypeLoader *typeLoader, QString *localQmldir, QList<QQmlError> *errors)
153 {
154 Q_ASSERT(errors);
155 qCDebug(lcQmlImport) << "addImplicitImport:" << qPrintable(baseUrl().toString());
156
157 const ImportFlags flags =
158 ImportFlags(!isLocal(baseUrl()) ? ImportIncomplete : ImportNoFlag);
159 return addFileImport(
160 typeLoader, QLatin1String("."), QString(), QTypeRevision(), flags,
161 QQmlImportInstance::Implicit, localQmldir, errors);
162 }
163
164 bool addInlineComponentImport(
165 QQmlImportInstance *const importInstance, const QString &name, const QUrl &importUrl);
166
167 QTypeRevision addFileImport(
168 QQmlTypeLoader *typeLoader, const QString &uri, const QString &prefix,
169 QTypeRevision requestedVersion, ImportFlags flags, quint8 precedence,
170 QString *localQmldir, QList<QQmlError> *errors);
171
172 QTypeRevision addLibraryImport(
173 QQmlTypeLoader *typeLoader, const QString &uri, const QString &prefix,
174 QTypeRevision requestedVersion, const QString &qmldirIdentifier,
175 const QString &qmldirUrl, ImportFlags flags, quint8 precedence,
176 QList<QQmlError> *errors);
177
178 QTypeRevision updateQmldirContent(
179 QQmlTypeLoader *typeLoader, const QString &uri, QTypeRevision version,
180 const QString &prefix, const QString &qmldirIdentifier, const QString &qmldirUrl,
181 QList<QQmlError> *errors);
182
183 void populateCache(QQmlTypeNameCache *cache) const;
184
185 struct ScriptReference
186 {
187 QString nameSpace;
188 QString qualifier;
189 QUrl fileName;
190 QUrl location;
191 };
192
193 QList<ScriptReference> resolvedScripts() const;
194
195 struct CompositeSingletonReference
196 {
197 QString typeName;
198 QString prefix;
199 QTypeRevision version;
200 };
201
202 QList<CompositeSingletonReference> resolvedCompositeSingletons() const;
203
204 static QStringList completeQmldirPaths(
205 const QString &uri, const QStringList &basePaths, QTypeRevision version);
206
207 static QString versionString(QTypeRevision version, ImportVersion importVersion);
208
209 static bool isLocal(const QString &url)
210 {
211 return !QQmlFile::urlToLocalFileOrQrc(url).isEmpty();
212 }
213
214 static bool isLocal(const QUrl &url)
215 {
216 return !QQmlFile::urlToLocalFileOrQrc(url).isEmpty();
217 }
218
219 static QUrl urlFromLocalFileOrQrcOrUrl(const QString &);
220
221 static void setDesignerSupportRequired(bool b);
222
223 static QTypeRevision validVersion(QTypeRevision version = QTypeRevision());
224
225 static QQmlError moduleNotFoundError(const QString &uri, QTypeRevision version);
226
227private:
228 enum class IsLibrary : bool { No = false, Yes = true };
229
230 static void insertImport(QQmlImportNamespace *nameSpace, QQmlImportInstance *import)
231 {
232 for (auto it = nameSpace->imports.cbegin(), end = nameSpace->imports.cend();
233 it != end; ++it) {
234 if ((*it)->precedence < import->precedence)
235 continue;
236
237 nameSpace->imports.insert(it, import);
238 return;
239 }
240 nameSpace->imports.append(import);
241 }
242
243 template<IsLibrary isLibrary>
244 static QQmlImportInstance *addImportToNamespace(
245 QQmlImportNamespace *nameSpace, const QString &uri, const QString &url,
246 QTypeRevision version, quint8 precedence)
247 {
248 Q_ASSERT(nameSpace);
249 Q_ASSERT(url.isEmpty() || url.endsWith(QLatin1Char('/')));
250
251 QQmlImportInstance *import = new QQmlImportInstance;
252 import->uri = uri;
253 import->url = url;
254 import->version = version;
255 import->isLibrary = bool(isLibrary);
256 import->precedence = precedence;
257 import->implicitlyImported = precedence >= QQmlImportInstance::Implicit;
258
259 insertImport(nameSpace, import);
260 return import;
261 }
262
263 QQmlImportNamespace *importNamespace(const QString &prefix);
264
265 bool resolveType(
266 QQmlTypeLoader *typeLoader, const QHashedStringRef &type, QTypeRevision *version_return,
267 QQmlType *type_return, QList<QQmlError> *errors,
268 QQmlType::RegistrationType registrationType,
269 bool *typeRecursionDetected = nullptr) const;
270
271 QQmlImportNamespace *findQualifiedNamespace(const QHashedStringRef &) const;
272
273 QTypeRevision importExtension(
274 QQmlTypeLoader *typeLoader, const QString &uri, QTypeRevision version,
275 const QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors);
276
277 void registerBuiltinModuleTypes(
278 const QQmlTypeLoaderQmldirContent &qmldir, QTypeRevision version);
279
280 QString redirectQmldirContent(
281 QQmlTypeLoader *typeLoader, QQmlTypeLoaderQmldirContent *qmldir);
282
283 bool getQmldirContent(
284 QQmlTypeLoader *typeLoader, const QString &qmldirIdentifier, const QString &uri,
285 QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors);
286
287 QString resolvedUri(const QString &dir_arg, QQmlTypeLoader *typeLoader);
288
289 template<IsLibrary isLibrary, typename Handler>
290 QTypeRevision finalizeImport(
291 QQmlImportNamespace *nameSpace, const QQmlTypeLoaderQmldirContent &qmldir,
292 const QString &importUri, const QString &url, quint8 precedence,
293 QTypeRevision requestedVersion, QTypeRevision importedVersion,
294 QList<QQmlError> *errors, Handler &&handler)
295 {
296 QQmlImportInstance *inserted = addImportToNamespace<isLibrary>(
297 nameSpace, importUri, url, requestedVersion, precedence);
298 Q_ASSERT(inserted);
299
300 registerBuiltinModuleTypes(qmldir, importedVersion);
301
302 if (!inserted->setQmldirContent(url, qmldir, nameSpace, errors))
303 return QTypeRevision();
304
305 return handler(inserted);
306 }
307
308 template<IsLibrary isLibrary>
309 QTypeRevision finalizeImport(
310 QQmlImportNamespace *nameSpace, const QQmlTypeLoaderQmldirContent &qmldir,
311 const QString &importUri, const QString &url, quint8 precedence,
312 QTypeRevision requestedVersion, QTypeRevision importedVersion,
313 QList<QQmlError> *errors)
314 {
315 return finalizeImport<isLibrary>(
316 nameSpace, qmldir, importUri, url, precedence, requestedVersion, importedVersion,
317 errors, [importedVersion](QQmlImportInstance *inserted) {
318 Q_UNUSED(inserted);
319 Q_ASSERT(importedVersion.isValid());
320 return importedVersion;
321 });
322 }
323
324 QUrl m_baseUrl;
325 QString m_base;
326
327 // storage of data related to imports without a namespace
328 // TODO: This needs to be mutable because QQmlImportNamespace likes to sort itself on
329 // resolveType(). Therefore, QQmlImportNamespace::resolveType() is not const.
330 // There should be a better way to do this.
331 mutable QQmlImportNamespace m_unqualifiedset;
332
333 // storage of data related to imports with a namespace
334 QFieldList<QQmlImportNamespace, &QQmlImportNamespace::nextNamespace> m_qualifiedSets;
335};
336
337Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlImports::ImportFlags)
338
339void qmlClearEnginePlugins();// For internal use by qmlClearRegisteredProperties
340
341QT_END_NAMESPACE
342
343#endif // QQMLIMPORT_P_H
QQmlImportInstance * findImportByModuleUri(const QString &moduleUri, QTypeRevision version) const
bool needsSorting() const
QQmlImportNamespace * nextNamespace
QQmlImportInstance * findImportByLocation(const QString &location, QTypeRevision version) 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)
\inmodule QtCore
const QLoggingCategory & category() const
~QmlImportCategoryHolder()=default
static const QLatin1String String_qmldir("qmldir")
#define RESOLVE_TYPE_DEBUG
static const QString dotuidotqml_string(QStringLiteral(".ui.qml"))
static const QLatin1Char Colon(':')
static QTypeRevision qmldirContentError(const QString &uri, QList< QQmlError > *errors)
static const QString dotqml_string(QStringLiteral(".qml"))
static bool designerSupportRequired
void findCompositeSingletons(const QQmlImportNamespace &set, QList< QQmlImports::CompositeSingletonReference > &resultList, const QUrl &baseUrl)
static QTypeRevision matchingModuleVersionForLibraryImport(const QString &uri, QTypeRevision version, QList< QQmlError > *errors)
static QString getVersionInfo(QTypeRevision version)
static const QLatin1Char Dot('.')
static QTypeRevision matchingQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, QTypeRevision version, QList< QQmlError > *errors)
bool excludeBaseUrl(const QString &importUrl, const QString &fileName, const QString &baseUrl)
static const QLatin1Char Slash('/')
static const QLatin1Char Backslash('\\')
static const QLatin1String Slash_qmldir("/qmldir")
static QTypeRevision finalizeLibraryImport(const QString &uri, QTypeRevision version, const QQmlTypeLoaderQmldirContent &qmldir, QQmlImportInstance *inserted, QList< QQmlError > *errors)
const QLoggingCategory & lcQmlImport()
DEFINE_BOOL_CONFIG_OPTION(forceDiskCache, QML_FORCE_DISK_CACHE)
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)