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 QQMLIMPORT_P_H
41 #define QQMLIMPORT_P_H
42 
43 #include <QtCore/qurl.h>
44 #include <QtCore/qcoreapplication.h>
45 #include <QtCore/qset.h>
46 #include <QtCore/qstringlist.h>
47 #include <QtQml/qqmlerror.h>
48 #include <private/qqmldirparser_p.h>
49 #include <private/qqmltype_p.h>
50 #include <private/qstringhash_p.h>
51 
52 //
53 //  W A R N I N G
54 //  -------------
55 //
56 // This file is not part of the Qt API.  It exists purely as an
57 // implementation detail.  This header file may change from version to
58 // version without notice, or even be removed.
59 //
60 // We mean it.
61 //
62 
63 QT_BEGIN_NAMESPACE
64 
65 class QQmlTypeNameCache;
66 class QQmlEngine;
67 class QDir;
68 class QQmlImportNamespace;
69 class QQmlImportsPrivate;
70 class QQmlImportDatabase;
71 class QQmlTypeLoader;
72 class QQmlTypeLoaderQmldirContent;
73 
74 namespace QQmlImport {
75     enum RecursionRestriction { PreventRecursion, AllowRecursion };
76 }
77 
78 struct QQmlImportInstance
79 {
80     QString uri; // e.g. QtQuick
81     QString url; // the base path of the import
82     QString localDirectoryPath; // the base path of the import if it's a local file
83     QQmlType containingType; // points to the containing type for inline components
84     int majversion; // the major version imported
85     int minversion; // the minor version imported
86     bool isLibrary; // true means that this is not a file import
87     bool implicitlyImported = false;
88     bool isInlineComponent = false;
89     QQmlDirComponents qmlDirComponents; // a copy of the components listed in the qmldir
90     QQmlDirScripts qmlDirScripts; // a copy of the scripts in the qmldir
91 
92     bool setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir,
93                           QQmlImportNamespace *nameSpace, QList<QQmlError> *errors);
94 
95     static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin);
96 
97     bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
98                      int *vmajor, int *vminor, QQmlType* type_return,
99                      QString *base = nullptr, bool *typeRecursionDetected = nullptr,
100                      QQmlType::RegistrationType = QQmlType::AnyRegistrationType,
101                      QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion,
102                      QList<QQmlError> *errors = nullptr) const;
103 };
104 
105 class QQmlImportNamespace
106 {
107 public:
QQmlImportNamespace()108     QQmlImportNamespace() : nextNamespace(nullptr) {}
~QQmlImportNamespace()109     ~QQmlImportNamespace() { qDeleteAll(imports); }
110 
111     QList<QQmlImportInstance *> imports;
112 
113     QQmlImportInstance *findImport(const QString &uri) const;
114 
115     bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
116                      int *vmajor, int *vminor, QQmlType* type_return,
117                      QString *base = nullptr, QList<QQmlError> *errors = nullptr,
118                      QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
119                      bool *typeRecursionDeteced = nullptr);
120 
121     // Prefix when used as a qualified import.  Otherwise empty.
122     QHashedString prefix;
123 
124     // Used by QQmlImportsPrivate::qualifiedSets
125     // set to this in unqualifiedSet to indicate that the lists of imports needs
126     // to be sorted when an inline component import was added
127     // We can't use flag pointer, as that does not work with QFieldList
128     QQmlImportNamespace *nextNamespace;
129     bool needsSorting() const;
130     void setNeedsSorting(bool needsSorting);
131 };
132 
133 class Q_QML_PRIVATE_EXPORT QQmlImports
134 {
135 public:
136     enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned };
137 
138     QQmlImports(QQmlTypeLoader *);
139     QQmlImports(const QQmlImports &);
140     ~QQmlImports();
141     QQmlImports &operator=(const QQmlImports &);
142 
143     void setBaseUrl(const QUrl &url, const QString &urlString = QString());
144     QUrl baseUrl() const;
145 
146     bool resolveType(const QHashedStringRef &type,
147                      QQmlType *type_return,
148                      int *version_major, int *version_minor,
149                      QQmlImportNamespace **ns_return,
150                      QList<QQmlError> *errors = nullptr,
151                      QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
152                      bool *typeRecursionDetected = nullptr) const;
153     bool resolveType(QQmlImportNamespace *,
154                      const QHashedStringRef& type,
155                      QQmlType *type_return, int *version_major, int *version_minor,
156                      QQmlType::RegistrationType registrationType
157                      = QQmlType::AnyRegistrationType) const;
158 
159     bool addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlError> *errors);
160 
161     bool addInlineComponentImport(QQmlImportInstance  *const importInstance, const QString &name, const QUrl importUrl, QQmlType containingType);
162 
163     bool addFileImport(QQmlImportDatabase *,
164                        const QString& uri, const QString& prefix, int vmaj, int vmin, bool incomplete,
165                        QList<QQmlError> *errors);
166 
167     bool addLibraryImport(QQmlImportDatabase *importDb,
168                           const QString &uri, const QString &prefix, int vmaj, int vmin,
169                           const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, QList<QQmlError> *errors);
170 
171     bool updateQmldirContent(QQmlImportDatabase *importDb,
172                              const QString &uri, const QString &prefix,
173                              const QString &qmldirIdentifier, const QString &qmldirUrl, QList<QQmlError> *errors);
174 
175     enum LocalQmldirResult {
176         QmldirFound,
177         QmldirNotFound,
178         QmldirInterceptedToRemote
179     };
180 
181     LocalQmldirResult locateLocalQmldir(
182             QQmlImportDatabase *, const QString &uri, int vmaj, int vmin,
183             QString *qmldirFilePath, QString *url);
184 
185     void populateCache(QQmlTypeNameCache *cache) const;
186 
187     struct ScriptReference
188     {
189         QString nameSpace;
190         QString qualifier;
191         QUrl location;
192     };
193 
194     QList<ScriptReference> resolvedScripts() const;
195 
196     struct CompositeSingletonReference
197     {
198         QString typeName;
199         QString prefix;
200         int majorVersion;
201         int minorVersion;
202     };
203 
204     QList<CompositeSingletonReference> resolvedCompositeSingletons() const;
205 
206     static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin);
207     static QString versionString(int vmaj, int vmin, ImportVersion version);
208 
209     static bool isLocal(const QString &url);
210     static bool isLocal(const QUrl &url);
211     static QUrl urlFromLocalFileOrQrcOrUrl(const QString &);
212 
213     static void setDesignerSupportRequired(bool b);
214 
215 private:
216     friend class QQmlImportDatabase;
217     QQmlImportsPrivate *d;
218 };
219 
220 class Q_QML_PRIVATE_EXPORT QQmlImportDatabase
221 {
222     Q_DECLARE_TR_FUNCTIONS(QQmlImportDatabase)
223 public:
224     enum PathType { Local, Remote, LocalOrRemote };
225 
226     QQmlImportDatabase(QQmlEngine *);
227     ~QQmlImportDatabase();
228 
229 #if QT_CONFIG(library)
230     bool importDynamicPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, int vmaj, QList<QQmlError> *errors);
231     bool removeDynamicPlugin(const QString &filePath);
232     QStringList dynamicPlugins() const;
233 #endif
234 
235     QStringList importPathList(PathType type = LocalOrRemote) const;
236     void setImportPathList(const QStringList &paths);
237     void addImportPath(const QString& dir);
238 
239     QStringList pluginPathList() const;
240     void setPluginPathList(const QStringList &paths);
241     void addPluginPath(const QString& path);
242 
243 private:
244     friend class QQmlImportsPrivate;
245     QString resolvePlugin(QQmlTypeLoader *typeLoader,
246                           const QString &qmldirPath, const QString &qmldirPluginPath,
247                           const QString &baseName, const QStringList &suffixes,
248                           const QString &prefix = QString());
249     QString resolvePlugin(QQmlTypeLoader *typeLoader,
250                           const QString &qmldirPath, const QString &qmldirPluginPath,
251                           const QString &baseName);
252     bool importStaticPlugin(QObject *instance, const QString &basePath, const QString &uri,
253                           const QString &typeNamespace, int vmaj, QList<QQmlError> *errors);
254     void clearDirCache();
255     void finalizePlugin(QObject *instance, const QString &path, const QString &uri);
256 
257     struct QmldirCache {
258         int versionMajor;
259         int versionMinor;
260         QString qmldirFilePath;
261         QString qmldirPathUrl;
262         QmldirCache *next;
263     };
264     // Maps from an import to a linked list of qmldir info.
265     // Used in QQmlImportsPrivate::locateQmldir()
266     QStringHash<QmldirCache *> qmldirCache;
267 
268     // XXX thread
269     QStringList filePluginPath;
270     QStringList fileImportPath;
271 
272     QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
273     QSet<QString> initializedPlugins;
274     QQmlEngine *engine;
275 };
276 
277 void qmlClearEnginePlugins();// For internal use by qmlClearRegisteredProperties
278 
279 QT_END_NAMESPACE
280 
281 #endif // QQMLIMPORT_P_H
282 
283