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 QQMLTYPELOADER_P_H
5#define QQMLTYPELOADER_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
18#include <private/qqmldatablob_p.h>
19#include <private/qqmlimport_p.h>
20#include <private/qqmlmetatype_p.h>
21
22#include <QtQml/qtqmlglobal.h>
23#include <QtQml/qqmlerror.h>
24
25#include <QtCore/qcache.h>
26#include <QtCore/qmutex.h>
27
28#include <memory>
29
30QT_BEGIN_NAMESPACE
31
32class QQmlScriptBlob;
33class QQmlQmldirData;
34class QQmlTypeData;
35class QQmlEngineExtensionInterface;
36class QQmlExtensionInterface;
37class QQmlProfiler;
38class QQmlTypeLoaderThread;
39class QQmlEngine;
40
41class Q_QML_PRIVATE_EXPORT QQmlTypeLoader
42{
43 Q_DECLARE_TR_FUNCTIONS(QQmlTypeLoader)
44public:
45 using ChecksumCache = QHash<quintptr, QByteArray>;
46 enum Mode { PreferSynchronous, Asynchronous, Synchronous };
47
48 class Q_QML_PRIVATE_EXPORT Blob : public QQmlDataBlob
49 {
50 public:
51 Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader);
52 ~Blob() override;
53
54 const QQmlImports *imports() const { return m_importCache.data(); }
55
56 void setCachedUnitStatus(QQmlMetaType::CachedUnitLookupError status) { m_cachedUnitStatus = status; }
57
58 struct PendingImport
59 {
60 QString uri;
61 QString qualifier;
62
63 QV4::CompiledData::Import::ImportType type
64 = QV4::CompiledData::Import::ImportType::ImportLibrary;
65 QV4::CompiledData::Location location;
66
67 QQmlImports::ImportFlags flags;
68 quint8 precedence = 0;
69 int priority = 0;
70
71 QTypeRevision version;
72
73 PendingImport() = default;
74 PendingImport(Blob *blob, const QV4::CompiledData::Import *import,
75 QQmlImports::ImportFlags flags);
76 };
77 using PendingImportPtr = std::shared_ptr<PendingImport>;
78
79 void importQmldirScripts(const PendingImportPtr &import, const QQmlTypeLoaderQmldirContent &qmldir, const QUrl &qmldirUrl);
80
81 protected:
82 bool addImport(const QV4::CompiledData::Import *import, QQmlImports::ImportFlags,
83 QList<QQmlError> *errors);
84 bool addImport(PendingImportPtr import, QList<QQmlError> *errors);
85
86 bool fetchQmldir(const QUrl &url, PendingImportPtr import, int priority, QList<QQmlError> *errors);
87 bool updateQmldir(const QQmlRefPointer<QQmlQmldirData> &data, const PendingImportPtr &import, QList<QQmlError> *errors);
88
89 private:
90 bool addScriptImport(const PendingImportPtr &import);
91 bool addFileImport(const PendingImportPtr &import, QList<QQmlError> *errors);
92 bool addLibraryImport(const PendingImportPtr &import, QList<QQmlError> *errors);
93
94 virtual bool qmldirDataAvailable(const QQmlRefPointer<QQmlQmldirData> &, QList<QQmlError> *);
95
96 virtual void scriptImported(const QQmlRefPointer<QQmlScriptBlob> &, const QV4::CompiledData::Location &, const QString &, const QString &) {}
97
98 void dependencyComplete(QQmlDataBlob *) override;
99
100 bool loadImportDependencies(
101 const PendingImportPtr &currentImport, const QString &qmldirUri,
102 QQmlImports::ImportFlags flags, QList<QQmlError> *errors);
103
104 protected:
105 bool loadDependentImports(
106 const QList<QQmlDirParser::Import> &imports, const QString &qualifier,
107 QTypeRevision version, quint16 precedence, QQmlImports::ImportFlags flags,
108 QList<QQmlError> *errors);
109 virtual QString stringAt(int) const { return QString(); }
110
111 bool isDebugging() const;
112 bool readCacheFile() const;
113 bool writeCacheFile() const;
114 QQmlMetaType::CacheMode aotCacheMode() const;
115
116 QQmlRefPointer<QQmlImports> m_importCache;
117 QVector<PendingImportPtr> m_unresolvedImports;
118 QVector<QQmlRefPointer<QQmlQmldirData>> m_qmldirs;
119 QQmlMetaType::CachedUnitLookupError m_cachedUnitStatus = QQmlMetaType::CachedUnitLookupError::NoError;
120 };
121
122 QQmlTypeLoader(QQmlEngine *);
123 ~QQmlTypeLoader();
124
125 QQmlImportDatabase *importDatabase() const;
126 ChecksumCache *checksumCache() { return &m_checksumCache; }
127 const ChecksumCache *checksumCache() const { return &m_checksumCache; }
128
129 static QUrl normalize(const QUrl &unNormalizedUrl);
130
131 QQmlRefPointer<QQmlTypeData> getType(const QUrl &unNormalizedUrl, Mode mode = PreferSynchronous);
132 QQmlRefPointer<QQmlTypeData> getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous);
133
134 QQmlRefPointer<QQmlScriptBlob> getScript(const QUrl &unNormalizedUrl);
135 QQmlRefPointer<QQmlQmldirData> getQmldir(const QUrl &);
136
137 QString absoluteFilePath(const QString &path);
138 bool fileExists(const QString &path, const QString &file);
139 bool directoryExists(const QString &path);
140
141 const QQmlTypeLoaderQmldirContent qmldirContent(const QString &filePath);
142 void setQmldirContent(const QString &filePath, const QString &content);
143
144 void clearCache();
145 void trimCache();
146
147 bool isTypeLoaded(const QUrl &url) const;
148 bool isScriptLoaded(const QUrl &url) const;
149
150 void lock() { m_mutex.lock(); }
151 void unlock() { m_mutex.unlock(); }
152
153 void load(QQmlDataBlob *, Mode = PreferSynchronous);
154 void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous);
155 void loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode = PreferSynchronous);
156
157 QQmlEngine *engine() const;
158 void initializeEngine(QQmlEngineExtensionInterface *, const char *);
159 void initializeEngine(QQmlExtensionInterface *, const char *);
160 void invalidate();
161
162#if !QT_CONFIG(qml_debug)
163 quintptr profiler() const { return 0; }
164 void setProfiler(quintptr) {}
165#else
166 QQmlProfiler *profiler() const { return m_profiler.data(); }
167 void setProfiler(QQmlProfiler *profiler);
168#endif // QT_CONFIG(qml_debug)
169
170
171private:
172 friend class QQmlDataBlob;
173 friend class QQmlTypeLoaderThread;
174#if QT_CONFIG(qml_network)
175 friend class QQmlTypeLoaderNetworkReplyProxy;
176#endif // qml_network
177
178 void shutdownThread();
179
180 void loadThread(const QQmlDataBlob::Ptr &);
181 void loadWithStaticDataThread(const QQmlDataBlob::Ptr &, const QByteArray &);
182 void loadWithCachedUnitThread(const QQmlDataBlob::Ptr &blob, const QQmlPrivate::CachedQmlUnit *unit);
183#if QT_CONFIG(qml_network)
184 void networkReplyFinished(QNetworkReply *);
185 void networkReplyProgress(QNetworkReply *, qint64, qint64);
186
187 typedef QHash<QNetworkReply *, QQmlDataBlob::Ptr> NetworkReplies;
188#endif
189
190 void setData(const QQmlDataBlob::Ptr &, const QByteArray &);
191 void setData(const QQmlDataBlob::Ptr &, const QString &fileName);
192 void setData(const QQmlDataBlob::Ptr &, const QQmlDataBlob::SourceCodeData &);
193 void setCachedUnit(const QQmlDataBlob::Ptr &blob, const QQmlPrivate::CachedQmlUnit *unit);
194
195 typedef QHash<QUrl, QQmlTypeData *> TypeCache;
196 typedef QHash<QUrl, QQmlScriptBlob *> ScriptCache;
197 typedef QHash<QUrl, QQmlQmldirData *> QmldirCache;
198 typedef QCache<QString, QCache<QString, bool> > ImportDirCache;
199 typedef QStringHash<QQmlTypeLoaderQmldirContent *> ImportQmlDirCache;
200
201 QQmlEngine *m_engine;
202 QQmlTypeLoaderThread *m_thread;
203 QMutex &m_mutex;
204
205#if QT_CONFIG(qml_debug)
206 QScopedPointer<QQmlProfiler> m_profiler;
207#endif
208
209#if QT_CONFIG(qml_network)
210 NetworkReplies m_networkReplies;
211#endif
212 TypeCache m_typeCache;
213 int m_typeCacheTrimThreshold;
214 ScriptCache m_scriptCache;
215 QmldirCache m_qmldirCache;
216 ImportDirCache m_importDirCache;
217 ImportQmlDirCache m_importQmlDirCache;
218 ChecksumCache m_checksumCache;
219
220 template<typename Loader>
221 void doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode);
222 void updateTypeCacheTrimThreshold();
223
224 friend struct PlainLoader;
225 friend struct CachedLoader;
226 friend struct StaticLoader;
227};
228
229QT_END_NAMESPACE
230
231#endif // QQMLTYPELOADER_P_H
232

source code of qtdeclarative/src/qml/qml/qqmltypeloader_p.h