1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQMLTYPELOADER_P_H
41#define QQMLTYPELOADER_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <private/qqmldatablob_p.h>
55#include <private/qqmlimport_p.h>
56#include <private/qqmlmetatype_p.h>
57
58#include <QtQml/qtqmlglobal.h>
59#include <QtQml/qqmlerror.h>
60
61#include <QtCore/qcache.h>
62#include <QtCore/qmutex.h>
63
64#include <memory>
65
66QT_BEGIN_NAMESPACE
67
68class QQmlScriptBlob;
69class QQmlQmldirData;
70class QQmlTypeData;
71class QQmlEngineExtensionInterface;
72class QQmlExtensionInterface;
73class QQmlProfiler;
74class QQmlTypeLoaderThread;
75class QQmlEngine;
76
77class Q_QML_PRIVATE_EXPORT QQmlTypeLoader
78{
79 Q_DECLARE_TR_FUNCTIONS(QQmlTypeLoader)
80public:
81 enum Mode { PreferSynchronous, Asynchronous, Synchronous };
82
83 class Q_QML_PRIVATE_EXPORT Blob : public QQmlDataBlob
84 {
85 public:
86 Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader);
87 ~Blob() override;
88
89 const QQmlImports &imports() const { return m_importCache; }
90
91 void setCachedUnitStatus(QQmlMetaType::CachedUnitLookupError status) { m_cachedUnitStatus = status; }
92
93 struct PendingImport
94 {
95 QV4::CompiledData::Import::ImportType type = QV4::CompiledData::Import::ImportType::ImportLibrary;
96
97 QString uri;
98 QString qualifier;
99
100 int majorVersion = -1;
101 int minorVersion = -1;
102
103 QV4::CompiledData::Location location;
104
105 int priority = 0;
106
107 PendingImport() = default;
108 PendingImport(Blob *blob, const QV4::CompiledData::Import *import);
109 };
110 using PendingImportPtr = std::shared_ptr<PendingImport>;
111
112 protected:
113 bool addImport(const QV4::CompiledData::Import *import, QList<QQmlError> *errors);
114 bool addImport(PendingImportPtr import, QList<QQmlError> *errors);
115
116 bool fetchQmldir(const QUrl &url, PendingImportPtr import, int priority, QList<QQmlError> *errors);
117 bool updateQmldir(const QQmlRefPointer<QQmlQmldirData> &data, PendingImportPtr import, QList<QQmlError> *errors);
118
119 private:
120 virtual bool qmldirDataAvailable(const QQmlRefPointer<QQmlQmldirData> &, QList<QQmlError> *);
121
122 virtual void scriptImported(const QQmlRefPointer<QQmlScriptBlob> &, const QV4::CompiledData::Location &, const QString &, const QString &) {}
123
124 void dependencyComplete(QQmlDataBlob *) override;
125
126 bool loadImportDependencies(PendingImportPtr currentImport, const QString &qmldirUri, QList<QQmlError> *errors);
127
128 protected:
129 virtual QString stringAt(int) const { return QString(); }
130
131 bool isDebugging() const;
132 bool diskCacheEnabled() const;
133
134 QQmlImports m_importCache;
135 QVector<PendingImportPtr> m_unresolvedImports;
136 QVector<QQmlRefPointer<QQmlQmldirData>> m_qmldirs;
137 QQmlMetaType::CachedUnitLookupError m_cachedUnitStatus = QQmlMetaType::CachedUnitLookupError::NoError;
138 };
139
140 QQmlTypeLoader(QQmlEngine *);
141 ~QQmlTypeLoader();
142
143 QQmlImportDatabase *importDatabase() const;
144
145 static QUrl normalize(const QUrl &unNormalizedUrl);
146
147 QQmlRefPointer<QQmlTypeData> getType(const QUrl &unNormalizedUrl, Mode mode = PreferSynchronous);
148 QQmlRefPointer<QQmlTypeData> getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous);
149
150 QQmlRefPointer<QQmlScriptBlob> getScript(const QUrl &unNormalizedUrl);
151 QQmlRefPointer<QQmlQmldirData> getQmldir(const QUrl &);
152
153 QString absoluteFilePath(const QString &path);
154 bool fileExists(const QString &path, const QString &file);
155 bool directoryExists(const QString &path);
156
157 const QQmlTypeLoaderQmldirContent qmldirContent(const QString &filePath);
158 void setQmldirContent(const QString &filePath, const QString &content);
159
160 void clearCache();
161 void trimCache();
162
163 bool isTypeLoaded(const QUrl &url) const;
164 bool isScriptLoaded(const QUrl &url) const;
165
166 void lock() { m_mutex.lock(); }
167 void unlock() { m_mutex.unlock(); }
168
169 void load(QQmlDataBlob *, Mode = PreferSynchronous);
170 void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous);
171 void loadWithCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit, Mode mode = PreferSynchronous);
172
173 QQmlEngine *engine() const;
174 void initializeEngine(QQmlEngineExtensionInterface *, const char *);
175 void initializeEngine(QQmlExtensionInterface *, const char *);
176 void invalidate();
177
178#if !QT_CONFIG(qml_debug)
179 quintptr profiler() const { return 0; }
180 void setProfiler(quintptr) {}
181#else
182 QQmlProfiler *profiler() const { return m_profiler.data(); }
183 void setProfiler(QQmlProfiler *profiler);
184#endif // QT_CONFIG(qml_debug)
185
186
187private:
188 friend class QQmlDataBlob;
189 friend class QQmlTypeLoaderThread;
190#if QT_CONFIG(qml_network)
191 friend class QQmlTypeLoaderNetworkReplyProxy;
192#endif // qml_network
193
194 void shutdownThread();
195
196 void loadThread(QQmlDataBlob *);
197 void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &);
198 void loadWithCachedUnitThread(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit);
199#if QT_CONFIG(qml_network)
200 void networkReplyFinished(QNetworkReply *);
201 void networkReplyProgress(QNetworkReply *, qint64, qint64);
202
203 typedef QHash<QNetworkReply *, QQmlDataBlob *> NetworkReplies;
204#endif
205
206 void setData(QQmlDataBlob *, const QByteArray &);
207 void setData(QQmlDataBlob *, const QString &fileName);
208 void setData(QQmlDataBlob *, const QQmlDataBlob::SourceCodeData &);
209 void setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit);
210
211 template<typename T>
212 struct TypedCallback
213 {
214 TypedCallback(T *object, void (T::*func)(QQmlTypeData *)) : o(object), mf(func) {}
215
216 static void redirect(void *arg, QQmlTypeData *type)
217 {
218 TypedCallback<T> *self = reinterpret_cast<TypedCallback<T> *>(arg);
219 ((self->o)->*(self->mf))(type);
220 }
221
222 private:
223 T *o;
224 void (T::*mf)(QQmlTypeData *);
225 };
226
227 typedef QHash<QUrl, QQmlTypeData *> TypeCache;
228 typedef QHash<QUrl, QQmlScriptBlob *> ScriptCache;
229 typedef QHash<QUrl, QQmlQmldirData *> QmldirCache;
230 typedef QCache<QString, QCache<QString, bool> > ImportDirCache;
231 typedef QStringHash<QQmlTypeLoaderQmldirContent *> ImportQmlDirCache;
232
233 QQmlEngine *m_engine;
234 QQmlTypeLoaderThread *m_thread;
235 QMutex &m_mutex;
236
237#if QT_CONFIG(qml_debug)
238 QScopedPointer<QQmlProfiler> m_profiler;
239#endif
240
241#if QT_CONFIG(qml_network)
242 NetworkReplies m_networkReplies;
243#endif
244 TypeCache m_typeCache;
245 int m_typeCacheTrimThreshold;
246 ScriptCache m_scriptCache;
247 QmldirCache m_qmldirCache;
248 ImportDirCache m_importDirCache;
249 ImportQmlDirCache m_importQmlDirCache;
250
251 template<typename Loader>
252 void doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode);
253 void updateTypeCacheTrimThreshold();
254
255 friend struct PlainLoader;
256 friend struct CachedLoader;
257 friend struct StaticLoader;
258};
259
260QT_END_NAMESPACE
261
262#endif // QQMLTYPELOADER_P_H
263

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