48 Q_DECLARE_TR_FUNCTIONS(QQmlTypeLoader)
50 using ChecksumCache = QQmlTypeLoaderThreadData::ChecksumCache;
53 class Q_QML_EXPORT
Blob :
public QQmlDataBlob
56 Blob(
const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader);
59 const QQmlImports *imports()
const {
return m_importCache.data(); }
61 void setCachedUnitStatus(QQmlMetaType::CachedUnitLookupError status) { m_cachedUnitStatus = status; }
68 QV4::CompiledData::Import::ImportType type
69 = QV4::CompiledData::Import::ImportType::ImportLibrary;
70 QV4::CompiledData::Location location;
72 QQmlImports::ImportFlags flags;
73 quint8 precedence = 0;
76 QTypeRevision version;
78 PendingImport() =
default;
79 PendingImport(
const QQmlRefPointer<Blob> &blob,
const QV4::CompiledData::Import *import,
80 QQmlImports::ImportFlags flags);
82 using PendingImportPtr = std::shared_ptr<PendingImport>;
84 void importQmldirScripts(
const PendingImportPtr &import,
const QQmlTypeLoaderQmldirContent &qmldir,
const QUrl &qmldirUrl);
85 bool handleLocalQmldirForImport(
86 const PendingImportPtr &import,
const QString &qmldirFilePath,
87 const QString &qmldirUrl, QList<QQmlError> *errors);
90 bool addImport(
const QV4::CompiledData::Import *import, QQmlImports::ImportFlags,
91 QList<QQmlError> *errors);
92 bool addImport(
const PendingImportPtr &import, QList<QQmlError> *errors);
95 const QUrl &url,
const PendingImportPtr &import,
int priority,
96 QList<QQmlError> *errors);
97 bool updateQmldir(
const QQmlRefPointer<QQmlQmldirData> &data,
const PendingImportPtr &import, QList<QQmlError> *errors);
100 bool addScriptImport(
const PendingImportPtr &import);
101 bool addFileImport(
const PendingImportPtr &import, QList<QQmlError> *errors);
102 bool addLibraryImport(
const PendingImportPtr &import, QList<QQmlError> *errors);
104 virtual bool qmldirDataAvailable(
const QQmlRefPointer<QQmlQmldirData> &, QList<QQmlError> *);
106 virtual void scriptImported(
107 const QQmlRefPointer<QQmlScriptBlob> &,
const QV4::CompiledData::Location &,
108 const QString &,
const QString &)
110 assertTypeLoaderThread();
113 void dependencyComplete(
const QQmlDataBlob::Ptr &) override;
115 bool loadImportDependencies(
116 const PendingImportPtr ¤tImport,
const QString &qmldirUri,
117 QQmlImports::ImportFlags flags, QList<QQmlError> *errors);
121 bool registerPendingTypes(
const PendingImportPtr &import);
123 bool loadDependentImports(
124 const QList<QQmlDirParser::Import> &imports,
const QString &qualifier,
125 QTypeRevision version, quint8 precedence, QQmlImports::ImportFlags flags,
126 QList<QQmlError> *errors);
127 virtual QString stringAt(
int)
const {
return QString(); }
129 QQmlRefPointer<QQmlImports> m_importCache;
130 QList<PendingImportPtr> m_unresolvedImports;
131 QList<QQmlRefPointer<QQmlQmldirData>> m_qmldirs;
132 QQmlMetaType::CachedUnitLookupError m_cachedUnitStatus = QQmlMetaType::CachedUnitLookupError::NoError;
135 QQmlTypeLoader(QV4::ExecutionEngine *engine);
144 return engine->handle()->typeLoader();
152 return Engine::get(engine)->handle()->typeLoader();
160 if (path->startsWith(QStringLiteral(
"//"))) {
163 *path = QUrl::fromLocalFile(*path).toLocalFile();
169 template<
typename TypeReference>
171 QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache,
172 const QList<TypeReference> &compositeSingletons)
174 QQmlTypeLoaderThreadDataPtr data(&m_data);
176 QCryptographicHash hash(QCryptographicHash::Md5);
177 return (resolvedTypeCache->addToHash(&hash, &data->checksumCache)
178 && addTypeReferenceChecksumsToHash(
179 compositeSingletons, &data->checksumCache, &hash))
193 const QUrl &relativeUrl,
const QV4::CompiledData::Unit *unit);
202 Q_ASSERT(!filePath.endsWith(QLatin1Char(
'/')));
203 const qsizetype pastLastSlash = filePath.lastIndexOf(QLatin1Char(
'/')) + 1;
205 filePath.left(pastLastSlash - 1),
206 filePath.mid(pastLastSlash, filePath.size() - pastLastSlash));
209 bool fileExists(
const QString &dirPath,
const QString &file)
const;
219 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit);
227 void drop(
const QQmlDataBlob::Ptr &blob);
236 QUrl interceptUrl(
const QUrl &url, QQmlAbstractUrlInterceptor::DataType type)
const;
239#if !QT_CONFIG(qml_debug)
240 quintptr profiler()
const {
return 0; }
241 void setProfiler(quintptr) {}
243 QQmlProfiler *profiler()
const
245 QQmlTypeLoaderConfiguredDataConstPtr data(&m_data);
246 return data->profiler.data();
248 void setProfiler(QQmlProfiler *profiler);
253 QQmlTypeLoaderConfiguredDataConstPtr data(&m_data);
254 return data->importPaths;
261 QQmlTypeLoaderConfiguredDataConstPtr data(&m_data);
262 return data->pluginPaths;
269 QQmlTypeLoaderThreadDataPtr data(&m_data);
270 data->initializedPlugins.insert(plugin);
274 QQmlTypeLoaderThreadDataConstPtr data(&m_data);
275 return data->initializedPlugins.contains(plugin);
280 QQmlTypeLoaderThreadDataPtr data(&m_data);
281 data->modulesForWhichPluginsHaveBeenProcessed.insert(module);
285 QQmlTypeLoaderThreadDataConstPtr data(&m_data);
286 return data->modulesForWhichPluginsHaveBeenProcessed.contains(module);
289#if QT_CONFIG(qml_network)
290 QQmlNetworkAccessManagerFactoryPtrConst networkAccessManagerFactory()
const;
291 void setNetworkAccessManagerFactory(QQmlNetworkAccessManagerFactory *factory);
292 QNetworkAccessManager *createNetworkAccessManager(QObject *parent)
const;
300 friend struct PlainLoader;
306#if QT_CONFIG(qml_network)
307 friend class QQmlTypeLoaderNetworkReplyProxy;
310 enum PathType { Local, Remote, LocalOrRemote };
312 enum LocalQmldirResult {
315 QmldirInterceptedToRemote,
323 void shutdownThread();
331 void trimCache(
const QQmlTypeLoaderSharedDataPtr &data);
333 void loadThread(
const QQmlDataBlob::Ptr &);
334 void loadWithStaticDataThread(
const QQmlDataBlob::Ptr &,
const QByteArray &);
335 void loadWithCachedUnitThread(
const QQmlDataBlob::Ptr &blob,
const QQmlPrivate::CachedQmlUnit *unit);
336#if QT_CONFIG(qml_network)
337 void networkReplyFinished(QNetworkReply *);
338 void networkReplyProgress(QNetworkReply *, qint64, qint64);
341 enum class DataOrigin { Device, Static };
342 void setData(
const QQmlDataBlob::Ptr &,
const QByteArray &, DataOrigin);
343 void setData(
const QQmlDataBlob::Ptr &,
const QString &fileName);
344 void setData(
const QQmlDataBlob::Ptr &,
const QQmlDataBlob::SourceCodeData &);
345 void setCachedUnit(
const QQmlDataBlob::Ptr &blob,
const QQmlPrivate::CachedQmlUnit *unit);
347 QStringList importPathList(PathType type)
const;
348 void clearQmldirInfo();
350 LocalQmldirResult locateLocalQmldir(
351 QQmlTypeLoader::Blob *blob,
const QQmlTypeLoader::Blob::PendingImportPtr &import,
352 QList<QQmlError> *errors);
355 void loadWithCachedUnit(
356 const QQmlDataBlob::Ptr &blob,
const QQmlPrivate::CachedQmlUnit *unit,
359 template<
typename Loader>
360 void doLoad(
const Loader &loader,
const QQmlDataBlob::Ptr &blob,
Mode mode);
361 void updateTypeCacheTrimThreshold(
const QQmlTypeLoaderSharedDataPtr &data);
363 template<
typename TypeReference>
364 static bool addTypeReferenceChecksumsToHash(
365 const QList<TypeReference> &typeRefs,
366 QHash<quintptr, QByteArray> *checksums, QCryptographicHash *hash)
368 for (
const auto &typeRef: typeRefs) {
369 if (typeRef.typeData) {
370 const auto unit = typeRef.typeData->compilationUnit()->unitData();
371 hash->addData({unit->md5Checksum,
sizeof(unit->md5Checksum)});
372 }
else if (
const QMetaObject *mo = typeRef.type.metaObject()) {
373 const auto propertyCache = QQmlMetaType::propertyCache(mo);
375 hash->addData(propertyCache->checksum(checksums, &ok));
383 template<
typename Blob>
384 QQmlRefPointer<Blob> finalizeBlob(QQmlRefPointer<Blob> &&blob, QQmlTypeLoader::Mode mode)
386 QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError;
387 const QQmlMetaType::CacheMode cacheMode = aotCacheMode();
388 if (
const QQmlPrivate::CachedQmlUnit *cachedUnit = (cacheMode != QQmlMetaType::RejectAll)
389 ? QQmlMetaType::findCachedCompilationUnit(blob->url(), cacheMode, &error)
391 loadWithCachedUnit(QQmlDataBlob::Ptr(blob.data()), cachedUnit, mode);
393 blob->setCachedUnitStatus(error);
394 load(QQmlDataBlob::Ptr(blob.data()), mode);
400 QQmlMetaType::CacheMode aotCacheMode();
402 QQmlTypeLoaderLockedData m_data;