Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmljstyperesolver_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:significant
4
5#ifndef QQMLJSTYPERESOLVER_P_H
6#define QQMLJSTYPERESOLVER_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17
18#include <memory>
19#include <qtqmlcompilerexports.h>
20
21#include <private/qqmlirbuilder_p.h>
22#include <private/qqmljsast_p.h>
24#include "qqmljslogger_p.h"
27#include "qqmljsscope_p.h"
29
31
32class QQmlJSImportVisitor;
33class Q_QMLCOMPILER_EXPORT QQmlJSTypeResolver
34{
35public:
36 QQmlJSTypeResolver(QQmlJSImporter *importer);
37
38 // Note: must be called after the construction to read the QML program
39 void init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *program);
40
41 QQmlJSRegisterContentPool *registerContentPool() const { return m_pool.get(); }
42 QQmlJSLogger *logger() const { return m_logger; }
43
44
45 // Configuration options
46
47 enum ParentMode { UseDocumentParent, UseParentProperty };
48 void setParentMode(ParentMode mode) { m_parentMode = mode; }
49 ParentMode parentMode() const { return m_parentMode; }
50
51 enum CloneMode { CloneTypes, DoNotCloneTypes };
52 void setCloneMode(CloneMode mode) { m_cloneMode = mode; }
53 CloneMode cloneMode() const { return m_cloneMode; }
54
55
56 // Builtin types
57
58 QQmlJSScope::ConstPtr voidType() const { return m_voidType; }
59 QQmlJSScope::ConstPtr emptyType() const { return m_emptyType; }
60 QQmlJSScope::ConstPtr nullType() const { return m_nullType; }
61 QQmlJSScope::ConstPtr realType() const { return m_realType; }
62 QQmlJSScope::ConstPtr floatType() const { return m_floatType; }
63 QQmlJSScope::ConstPtr int8Type() const { return m_int8Type; }
64 QQmlJSScope::ConstPtr uint8Type() const { return m_uint8Type; }
65 QQmlJSScope::ConstPtr int16Type() const { return m_int16Type; }
66 QQmlJSScope::ConstPtr uint16Type() const { return m_uint16Type; }
67 QQmlJSScope::ConstPtr int32Type() const { return m_int32Type; }
68 QQmlJSScope::ConstPtr uint32Type() const { return m_uint32Type; }
69 QQmlJSScope::ConstPtr int64Type() const { return m_int64Type; }
70 QQmlJSScope::ConstPtr uint64Type() const { return m_uint64Type; }
71 QQmlJSScope::ConstPtr sizeType() const { return m_sizeType; }
72 QQmlJSScope::ConstPtr boolType() const { return m_boolType; }
73 QQmlJSScope::ConstPtr stringType() const { return m_stringType; }
74 QQmlJSScope::ConstPtr stringListType() const { return m_stringListType; }
75 QQmlJSScope::ConstPtr byteArrayType() const { return m_byteArrayType; }
76 QQmlJSScope::ConstPtr urlType() const { return m_urlType; }
77 QQmlJSScope::ConstPtr dateTimeType() const { return m_dateTimeType; }
78 QQmlJSScope::ConstPtr dateType() const { return m_dateType; }
79 QQmlJSScope::ConstPtr timeType() const { return m_timeType; }
80 QQmlJSScope::ConstPtr regexpType() const { return m_regexpType; }
81 QQmlJSScope::ConstPtr variantListType() const { return m_variantListType; }
82 QQmlJSScope::ConstPtr variantMapType() const { return m_variantMapType; }
83 QQmlJSScope::ConstPtr varType() const { return m_varType; }
84 QQmlJSScope::ConstPtr qmlPropertyMapType() const { return m_qmlPropertyMapType; }
85 QQmlJSScope::ConstPtr jsValueType() const { return m_jsValueType; }
86 QQmlJSScope::ConstPtr jsPrimitiveType() const { return m_jsPrimitiveType; }
87 QQmlJSScope::ConstPtr listPropertyType() const { return m_listPropertyType; }
88 QQmlJSScope::ConstPtr metaObjectType() const { return m_metaObjectType; }
89 QQmlJSScope::ConstPtr functionType() const { return m_functionType; }
90 QQmlJSScope::ConstPtr jsGlobalObject() const { return m_jsGlobalObject; }
91 QQmlJSScope::ConstPtr qObjectType() const { return m_qObjectType; }
92 QQmlJSScope::ConstPtr qObjectListType() const { return m_qObjectListType; }
93 QQmlJSScope::ConstPtr arrayPrototype() const { return m_arrayPrototype; }
94 QQmlJSScope::ConstPtr forInIteratorPtr() const { return m_forInIteratorPtr; }
95 QQmlJSScope::ConstPtr forOfIteratorPtr() const { return m_forOfIteratorPtr; }
96 QQmlJSScope::ConstPtr qQmlScriptStringType() const { return m_qQmlScriptStringType; }
97
98 QQmlJSRegisterContent jsGlobalObjectContent() const { return m_jsGlobalObjectContent; }
99 QQmlJSScope::ConstPtr mathObject() const;
100 QQmlJSScope::ConstPtr consoleObject() const;
101
102 QQmlJSScope::ConstPtr typeForConst(QV4::ReturnedValue rv) const;
103
104
105 // Querying imports and imported types
106
107 bool isPrefix(const QString &name) const
108 {
109 return m_imports.hasType(name) && !m_imports.type(name).scope;
110 }
111
112 const QHash<QString, QQmlJS::ContextualType> &importedTypes() const
113 {
114 return m_imports.types();
115 }
116
117 const auto &importedNames() const
118 {
119 return m_imports.contextualTypes().names();
120 }
121
122 QQmlJSScope::ConstPtr typeForName(const QString &name) const
123 {
124 return m_imports.type(name).scope;
125 }
126
127 QString nameForType(const QQmlJSScope::ConstPtr &type) const
128 {
129 return m_imports.name(type);
130 }
131
132 QStringList seenModuleQualifiers() const { return m_seenModuleQualifiers; }
133
134
135 // Querying types from current document
136
137 QQmlJSScope::ConstPtr scopeForLocation(const QV4::CompiledData::Location &location) const;
138 QQmlJSScope::ConstPtr typeFromAST(QQmlJS::AST::Type *type) const;
139 QQmlJSScope::ConstPtr typeForId(
140 const QQmlJSScope::ConstPtr &scope, const QString &name,
141 QQmlJSScopesByIdOptions options = QQmlJSScopesByIdOption::Default) const
142 {
143 return m_objectsById.scope(name, scope, options);
144 }
145
146 const QQmlJSScopesById &objectsById() const { return m_objectsById; }
147 bool canCallJSFunctions() const { return m_objectsById.signaturesAreEnforced(); }
148 bool canAddressValueTypes() const { return m_objectsById.valueTypesAreAddressable(); }
149
150 QQmlJSScope::ConstPtr scopedType(
151 const QQmlJSScope::ConstPtr &scope, const QString &name,
152 QQmlJSScopesByIdOptions options = QQmlJSScopesByIdOption::Default) const;
153
154 const QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> &signalHandlers() const
155 {
156 return m_signalHandlers;
157 }
158
159
160 // Classification of types
161
162 bool isPrimitive(QQmlJSRegisterContent type) const;
163 bool isPrimitive(const QQmlJSScope::ConstPtr &type) const;
164
165 bool isNumeric(QQmlJSRegisterContent type) const;
166 bool isNumeric(const QQmlJSScope::ConstPtr &type) const;
167
168 bool isIntegral(QQmlJSRegisterContent type) const;
169 bool isIntegral(const QQmlJSScope::ConstPtr &type) const;
170
171 bool isSignedInteger(const QQmlJSScope::ConstPtr &type) const;
172 bool isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const;
173 bool isNativeArrayIndex(const QQmlJSScope::ConstPtr &type) const;
174
175 bool canHold(const QQmlJSScope::ConstPtr &container,
176 const QQmlJSScope::ConstPtr &contained) const;
177 bool canHoldUndefined(QQmlJSRegisterContent content) const;
178 bool isOptionalType(QQmlJSRegisterContent content) const;
179
180 bool canPopulate(
181 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument,
182 bool *isExtension) const;
183
184 bool canConvertFromTo(const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
185 bool canConvertFromTo(QQmlJSRegisterContent from, QQmlJSRegisterContent to) const;
186
187 bool areEquivalentLists(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
188
189 bool isTriviallyCopyable(const QQmlJSScope::ConstPtr &type) const;
190
191 bool inherits(const QQmlJSScope::ConstPtr &derived, const QQmlJSScope::ConstPtr &base) const;
192
193
194 // Querying of types given other types
195
196 enum class ComponentIsGeneric { No, Yes };
197 QQmlJSScope::ConstPtr genericType(
198 const QQmlJSScope::ConstPtr &type,
199 ComponentIsGeneric allowComponent = ComponentIsGeneric::No) const;
200
201 QQmlJSScope::ConstPtr storedType(const QQmlJSScope::ConstPtr &type) const;
202
203 QQmlJSRegisterContent original(QQmlJSRegisterContent type) const;
204 QQmlJSScope::ConstPtr originalContainedType(QQmlJSRegisterContent container) const;
205
206 QQmlJSRegisterContent shadowed(QQmlJSRegisterContent type) const;
207
208 QQmlJSScope::ConstPtr merge(
209 const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
210
211 QQmlJSRegisterContent extractNonVoidFromOptionalType(
212 QQmlJSRegisterContent content) const;
213
214 QQmlJSMetaMethod selectConstructor(
215 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument,
216 bool *isExtension) const;
217
218
219 // Creation of "tracked" QQmlJSRegisterContents
220
221 QQmlJSRegisterContent typeForBinaryOperation(
222 QSOperator::Op oper, QQmlJSRegisterContent left,
223 QQmlJSRegisterContent right) const;
224
225 enum class UnaryOperator { Not, Plus, Minus, Increment, Decrement, Complement };
226 QQmlJSRegisterContent typeForArithmeticUnaryOperation(
227 UnaryOperator op, QQmlJSRegisterContent operand) const;
228
229 QQmlJSRegisterContent merge(
230 QQmlJSRegisterContent a, QQmlJSRegisterContent b) const;
231
232 QQmlJSRegisterContent literalType(const QQmlJSScope::ConstPtr &type) const;
233 QQmlJSRegisterContent operationType(const QQmlJSScope::ConstPtr &type) const;
234 QQmlJSRegisterContent namedType(const QQmlJSScope::ConstPtr &type) const;
235 QQmlJSRegisterContent syntheticType(const QQmlJSScope::ConstPtr &type) const;
236
237 QQmlJSRegisterContent scopedType(
238 QQmlJSRegisterContent scope, const QString &name,
239 int lookupIndex = QQmlJSRegisterContent::InvalidLookupIndex,
240 QQmlJSScopesByIdOptions options = QQmlJSScopesByIdOption::Default) const;
241
242 QQmlJSRegisterContent memberType(
243 QQmlJSRegisterContent type, const QString &name,
244 int lookupIndex = QQmlJSRegisterContent::InvalidLookupIndex) const;
245
246 QQmlJSRegisterContent elementType(QQmlJSRegisterContent list) const;
247
248 QQmlJSRegisterContent returnType(
249 const QQmlJSMetaMethod &method, const QQmlJSScope::ConstPtr &returnType,
250 QQmlJSRegisterContent scope) const;
251
252 QQmlJSRegisterContent extensionType(
253 const QQmlJSScope::ConstPtr &extension, QQmlJSRegisterContent base) const;
254
255 QQmlJSRegisterContent baseType(
256 const QQmlJSScope::ConstPtr &base, QQmlJSRegisterContent derived) const;
257
258 QQmlJSRegisterContent parentScope(
259 const QQmlJSScope::ConstPtr &parent, QQmlJSRegisterContent child) const;
260
261 QQmlJSRegisterContent iteratorPointer(
262 QQmlJSRegisterContent listType, QQmlJS::AST::ForEachType type,
263 int lookupIndex) const;
264
265 QQmlJSRegisterContent convert(
266 QQmlJSRegisterContent from, QQmlJSRegisterContent to) const;
267 QQmlJSRegisterContent convert(
268 QQmlJSRegisterContent from, const QQmlJSScope::ConstPtr &to) const;
269
270
271 // Type adjustment
272
273 [[nodiscard]] bool adjustTrackedType(
274 QQmlJSRegisterContent tracked, const QQmlJSScope::ConstPtr &conversion) const;
275 [[nodiscard]] bool adjustTrackedType(
276 QQmlJSRegisterContent tracked, QQmlJSRegisterContent conversion) const;
277 [[nodiscard]] bool adjustTrackedType(
278 QQmlJSRegisterContent tracked,
279 const QList<QQmlJSRegisterContent> &conversions) const;
280 void adjustOriginalType(
281 QQmlJSRegisterContent tracked, const QQmlJSScope::ConstPtr &conversion) const;
282 void generalizeType(QQmlJSRegisterContent type) const;
283
284
285protected:
286
287 QQmlJSRegisterContent memberType(QQmlJSRegisterContent type, const QString &name,
288 int baseLookupIndex, int resultLookupIndex) const;
289 QQmlJSRegisterContent memberEnumType(QQmlJSRegisterContent type,
290 const QString &name) const;
291 bool checkEnums(QQmlJSRegisterContent scope, const QString &name,
292 QQmlJSRegisterContent *result) const;
293 bool canPrimitivelyConvertFromTo(
294 const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
295 QQmlJSRegisterContent lengthProperty(bool isWritable, QQmlJSRegisterContent scope) const;
296
297 QQmlJSScope::ConstPtr containedTypeForName(const QString &name) const;
298 QQmlJSRegisterContent registerContentForName(
299 const QString &name, QQmlJSRegisterContent scopeType = {}) const;
300
301 QQmlJSScope::ConstPtr resolveParentProperty(
302 const QString &name, const QQmlJSScope::ConstPtr &base,
303 const QQmlJSScope::ConstPtr &propType) const;
304
305 std::unique_ptr<QQmlJSRegisterContentPool> m_pool;
306
307 QQmlJSScope::ConstPtr m_voidType;
308 QQmlJSScope::ConstPtr m_emptyType;
309 QQmlJSScope::ConstPtr m_nullType;
310 QQmlJSScope::ConstPtr m_numberPrototype;
311 QQmlJSScope::ConstPtr m_arrayPrototype;
312 QQmlJSScope::ConstPtr m_realType;
313 QQmlJSScope::ConstPtr m_floatType;
314 QQmlJSScope::ConstPtr m_int8Type;
315 QQmlJSScope::ConstPtr m_uint8Type;
316 QQmlJSScope::ConstPtr m_int16Type;
317 QQmlJSScope::ConstPtr m_uint16Type;
318 QQmlJSScope::ConstPtr m_int32Type;
319 QQmlJSScope::ConstPtr m_uint32Type;
320 QQmlJSScope::ConstPtr m_int64Type;
321 QQmlJSScope::ConstPtr m_uint64Type;
322 QQmlJSScope::ConstPtr m_sizeType;
323 QQmlJSScope::ConstPtr m_boolType;
324 QQmlJSScope::ConstPtr m_stringType;
325 QQmlJSScope::ConstPtr m_stringListType;
326 QQmlJSScope::ConstPtr m_byteArrayType;
327 QQmlJSScope::ConstPtr m_urlType;
328 QQmlJSScope::ConstPtr m_dateTimeType;
329 QQmlJSScope::ConstPtr m_dateType;
330 QQmlJSScope::ConstPtr m_timeType;
331 QQmlJSScope::ConstPtr m_regexpType;
332 QQmlJSScope::ConstPtr m_variantListType;
333 QQmlJSScope::ConstPtr m_variantMapType;
334 QQmlJSScope::ConstPtr m_varType;
335 QQmlJSScope::ConstPtr m_qmlPropertyMapType;
336 QQmlJSScope::ConstPtr m_jsValueType;
337 QQmlJSScope::ConstPtr m_jsPrimitiveType;
338 QQmlJSScope::ConstPtr m_listPropertyType;
339 QQmlJSScope::ConstPtr m_qObjectType;
340 QQmlJSScope::ConstPtr m_qObjectListType;
341 QQmlJSScope::ConstPtr m_qQmlScriptStringType;
342 QQmlJSScope::ConstPtr m_metaObjectType;
343 QQmlJSScope::ConstPtr m_functionType;
344 QQmlJSScope::ConstPtr m_jsGlobalObject;
345 QQmlJSScope::ConstPtr m_forInIteratorPtr;
346 QQmlJSScope::ConstPtr m_forOfIteratorPtr;
347
348 QQmlJSRegisterContent m_jsGlobalObjectContent;
349
350 QQmlJSScopesById m_objectsById;
351 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_objectsByLocation;
352 QQmlJSImporter::ImportedTypes m_imports;
353 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
354 QStringList m_seenModuleQualifiers;
355
356 ParentMode m_parentMode = UseParentProperty;
357 CloneMode m_cloneMode = CloneTypes;
358 QQmlJSLogger *m_logger = nullptr;
359};
360
361/*!
362\internal
363
364QQmlJSTypeResolver expects to be outlived by its importer and mapper. It crashes when its importer
365or mapper gets destructed. Therefore, you can use this struct to extend the lifetime of its
366dependencies in case you need to store the resolver as a class member.
367QQmlJSTypeResolver also expects to be outlived by the logger used by the importvisitor, while the
368importvisitor actually does not and will not outlive the QQmlJSTypeResolver.
369*/
371{
372 std::shared_ptr<QQmlJSImporter> importer;
374 std::shared_ptr<QQmlJSLogger> logger;
375};
376
377QT_END_NAMESPACE
378
379#endif // QQMLJSTYPERESOLVER_P_H
Combined button and popup list for selecting options.
std::shared_ptr< QQmlJSResourceFileMapper > mapper
std::shared_ptr< QQmlJSLogger > logger
std::shared_ptr< QQmlJSImporter > importer