Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmltypenamecache_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 QQMLTYPENAMECACHE_P_H
5#define QQMLTYPENAMECACHE_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/qqmlrefcount_p.h>
19#include "qqmlmetatype_p.h"
20
21#include <private/qstringhash_p.h>
22#include <private/qqmlimport_p.h>
23#include <private/qqmltypemoduleversion_p.h>
24
25#include <QtCore/qvector.h>
26
28
31 : scriptIndex(-1)
32 {}
33 // Imported module
34 QVector<QQmlTypeModuleVersion> modules;
35
36 // Or, imported script
38
39 // Or, imported compositeSingletons
40 QStringHash<QUrl> compositeSingletons;
41
42 // The qualifier of this import
44};
45
46class QQmlType;
47class QQmlEngine;
48class Q_QML_EXPORT QQmlTypeNameCache final : public QQmlRefCounted<QQmlTypeNameCache>
49{
50public:
51 QQmlTypeNameCache(const QQmlRefPointer<QQmlImports> &imports) : m_imports(imports) {}
53
54 inline bool isEmpty() const;
55
56 void add(const QHashedString &name, int sciptIndex = -1, const QHashedString &nameSpace = QHashedString());
57 void add(const QHashedString &name, const QUrl &url, const QHashedString &nameSpace = QHashedString());
58
59 struct Result {
60 inline Result();
61 inline Result(const QQmlImportRef *importNamespace);
62 inline Result(const QQmlType &type);
63 inline Result(int scriptIndex);
64
65 inline bool isValid() const;
66
70 };
71
72 enum class QueryNamespaced { No, Yes };
73
74 // Restrict the types allowed for key. We don't want QV4::ScopedString, for example.
75
76 template<QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion>
77 Result query(const QHashedStringRef &key, QQmlTypeLoader *typeLoader) const
78 {
79 return doQuery<const QHashedStringRef &, recursionRestriction>(key, typeLoader);
80 }
81
82 template<QueryNamespaced queryNamespaced = QueryNamespaced::Yes>
83 Result query(const QHashedStringRef &key, const QQmlImportRef *importNamespace,
84 QQmlTypeLoader *typeLoader) const
85 {
86 return doQuery<const QHashedStringRef &, queryNamespaced>(key, importNamespace, typeLoader);
87 }
88
89 template<QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion>
90 Result query(const QV4::String *key, QQmlTypeLoader *typeLoader) const
91 {
92 return doQuery<const QV4::String *, recursionRestriction>(key, typeLoader);
93 }
94
95 template<QueryNamespaced queryNamespaced = QueryNamespaced::Yes>
96 Result query(const QV4::String *key, const QQmlImportRef *importNamespace,
97 QQmlTypeLoader *typeLoader) const
98 {
99 return doQuery<const QV4::String *, queryNamespaced>(key, importNamespace, typeLoader);
100 }
101
102private:
103 friend class QQmlImports;
104
105 static QHashedStringRef toHashedStringRef(const QHashedStringRef &key) { return key; }
106 static QHashedStringRef toHashedStringRef(const QV4::String *key)
107 {
108 const QV4::Heap::String *heapString = key->d();
109
110 // toQString() would also do simplifyString(). Therefore, we can be sure that this
111 // is safe. Any other operation on the string data cannot keep references on the
112 // non-simplified pieces.
113 if (heapString->subtype >= QV4::Heap::String::StringType_Complex)
114 heapString->simplifyString();
115
116 // This is safe because the string data is backed by the QV4::String we got as
117 // parameter. The contract about passing V4 values as parameters is that you have to
118 // scope them first, so that they don't get gc'd while the callee is working on them.
119 const QStringPrivate &text = heapString->text();
121 }
122
123 static QString toQString(const QHashedStringRef &key) { return key.toString(); }
124 static QString toQString(const QV4::String *key) { return key->toQStringNoThrow(); }
125
126 template<typename Key, QQmlImport::RecursionRestriction recursionRestriction>
127 Result doQuery(Key name, QQmlTypeLoader *typeLoader) const
128 {
129 Result result = doQuery(m_namedImports, name);
130
131 if (!result.isValid())
132 result = typeSearch(m_anonymousImports, name);
133
134 if (!result.isValid())
135 result = doQuery(m_anonymousCompositeSingletons, name);
136
137 if (!result.isValid()) {
138 // Look up anonymous types from the imports of this document
139 // ### it would be nice if QQmlImports allowed us to resolve a namespace
140 // first, and then types on it.
141 QQmlImportNamespace *typeNamespace = nullptr;
142 QList<QQmlError> errors;
143 QQmlType t;
144 bool typeRecursionDetected = false;
145 const bool typeFound = m_imports->resolveType(
146 typeLoader, toHashedStringRef(name), &t, nullptr, &typeNamespace, &errors,
148 recursionRestriction == QQmlImport::AllowRecursion
149 ? &typeRecursionDetected
150 : nullptr);
151 if (typeFound)
152 return Result(t);
153
154 }
155
156 return result;
157 }
158
159 template<typename Key, QueryNamespaced queryNamespaced>
160 Result doQuery(Key name, const QQmlImportRef *importNamespace, QQmlTypeLoader *typeLoader) const
161 {
162 Q_ASSERT(importNamespace && importNamespace->scriptIndex == -1);
163
164 if constexpr (queryNamespaced == QueryNamespaced::Yes) {
165 QMap<const QQmlImportRef *, QStringHash<QQmlImportRef> >::const_iterator it
166 = m_namespacedImports.constFind(importNamespace);
167 if (it != m_namespacedImports.constEnd()) {
168 Result r = doQuery(*it, name);
169 if (r.isValid())
170 return r;
171 }
172 }
173
174 Result result = typeSearch(importNamespace->modules, name);
175
176 if (!result.isValid())
177 result = doQuery(importNamespace->compositeSingletons, name);
178
179 if (!result.isValid()) {
180 // Look up types from the imports of this document
181 // ### it would be nice if QQmlImports allowed us to resolve a namespace
182 // first, and then types on it.
183 const QString qualifiedTypeName = importNamespace->m_qualifier + u'.' + toQString(name);
184 QQmlImportNamespace *typeNamespace = nullptr;
185 QList<QQmlError> errors;
186 QQmlType t;
187 bool typeFound = m_imports->resolveType(
188 typeLoader, qualifiedTypeName, &t, nullptr, &typeNamespace, &errors);
189 if (typeFound)
190 return Result(t);
191 }
192
193 return result;
194 }
195
196 template<typename Key>
197 Result doQuery(const QStringHash<QQmlImportRef> &imports, Key key) const
198 {
199 QQmlImportRef *i = imports.value(key);
200 if (i) {
201 Q_ASSERT(!i->m_qualifier.isEmpty());
202 if (i->scriptIndex != -1) {
203 return Result(i->scriptIndex);
204 } else {
205 return Result(i);
206 }
207 }
208
209 return Result();
210 }
211
212 template<typename Key>
213 Result doQuery(const QStringHash<QUrl> &urls, Key key) const
214 {
215 QUrl *url = urls.value(key);
216 if (url) {
218 return Result(type);
219 }
220
221 return Result();
222 }
223
224 template<typename Key>
225 Result typeSearch(const QVector<QQmlTypeModuleVersion> &modules, Key key) const
226 {
228 for (QVector<QQmlTypeModuleVersion>::const_iterator it = modules.constBegin(); it != end; ++it) {
229 QQmlType type = it->type(key);
230 if (type.isValid())
231 return Result(type);
232 }
233
234 return Result();
235 }
236
237 QStringHash<QQmlImportRef> m_namedImports;
238 QMap<const QQmlImportRef *, QStringHash<QQmlImportRef> > m_namespacedImports;
239 QVector<QQmlTypeModuleVersion> m_anonymousImports;
240 QStringHash<QUrl> m_anonymousCompositeSingletons;
241 QQmlRefPointer<QQmlImports> m_imports;
242};
243
245: importNamespace(nullptr), scriptIndex(-1)
246{
247}
248
250: importNamespace(importNamespace), scriptIndex(-1)
251{
252}
253
255: type(type), importNamespace(nullptr), scriptIndex(-1)
256{
257}
258
260: importNamespace(nullptr), scriptIndex(scriptIndex)
261{
262}
263
265{
266 return type.isValid() || importNamespace || scriptIndex != -1;
267}
268
270{
271 return m_namedImports.isEmpty() && m_anonymousImports.isEmpty()
272 && m_anonymousCompositeSingletons.isEmpty();
273}
274
276
277#endif // QQMLTYPENAMECACHE_P_H
278
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
The QQmlImports class encapsulates one QML document's import statements.
static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version)
Returns the type (if any) of URI-qualified named qualifiedName and version specified by version_major...
The QQmlTypeLoader class abstracts loading files and their dependencies over the network.
Result query(const QV4::String *key, const QQmlImportRef *importNamespace, QQmlTypeLoader *typeLoader) const
QQmlTypeNameCache(const QQmlRefPointer< QQmlImports > &imports)
Result query(const QHashedStringRef &key, const QQmlImportRef *importNamespace, QQmlTypeLoader *typeLoader) const
Result query(const QHashedStringRef &key, QQmlTypeLoader *typeLoader) const
Result query(const QV4::String *key, QQmlTypeLoader *typeLoader) const
@ AnyRegistrationType
Definition qqmltype_p.h:167
const_iterator constEnd() const noexcept
Definition qset.h:143
const_iterator constFind(const T &value) const
Definition qset.h:161
bool isEmpty() const
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
\inmodule QtCore
Definition qurl.h:94
QString text
QSet< QString >::iterator it
Combined button and popup list for selecting options.
GLuint64 key
GLboolean r
[2]
GLuint GLuint end
GLenum type
GLuint name
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QUrl url("example.com")
[constructor-url-reference]
QObject::connect nullptr
QVector< QQmlTypeModuleVersion > modules
QStringHash< QUrl > compositeSingletons
const QQmlImportRef * importNamespace
void simplifyString() const