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::ImportedScope<QQmlJSScope::ConstPtr>> &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 = 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 = 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 QQmlJSScope::ConstPtr merge(
207 const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
208
209 QQmlJSRegisterContent extractNonVoidFromOptionalType(
210 QQmlJSRegisterContent content) const;
211
212 QQmlJSMetaMethod selectConstructor(
213 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument,
214 bool *isExtension) const;
215
216
217 // Creation of "tracked" QQmlJSRegisterContents
218
219 QQmlJSRegisterContent typeForBinaryOperation(
220 QSOperator::Op oper, QQmlJSRegisterContent left,
221 QQmlJSRegisterContent right) const;
222
223 enum class UnaryOperator { Not, Plus, Minus, Increment, Decrement, Complement };
224 QQmlJSRegisterContent typeForArithmeticUnaryOperation(
225 UnaryOperator op, QQmlJSRegisterContent operand) const;
226
227 QQmlJSRegisterContent merge(
228 QQmlJSRegisterContent a, QQmlJSRegisterContent b) const;
229
230 QQmlJSRegisterContent literalType(const QQmlJSScope::ConstPtr &type) const;
231 QQmlJSRegisterContent operationType(const QQmlJSScope::ConstPtr &type) const;
232 QQmlJSRegisterContent namedType(const QQmlJSScope::ConstPtr &type) const;
233 QQmlJSRegisterContent syntheticType(const QQmlJSScope::ConstPtr &type) const;
234
235 QQmlJSRegisterContent scopedType(
236 QQmlJSRegisterContent scope, const QString &name,
237 int lookupIndex = QQmlJSRegisterContent::InvalidLookupIndex,
238 QQmlJSScopesByIdOptions options = Default) const;
239
240 QQmlJSRegisterContent memberType(
241 QQmlJSRegisterContent type, const QString &name,
242 int lookupIndex = QQmlJSRegisterContent::InvalidLookupIndex) const;
243
244 QQmlJSRegisterContent elementType(QQmlJSRegisterContent list) const;
245
246 QQmlJSRegisterContent returnType(
247 const QQmlJSMetaMethod &method, const QQmlJSScope::ConstPtr &returnType,
248 QQmlJSRegisterContent scope) const;
249
250 QQmlJSRegisterContent extensionType(
251 const QQmlJSScope::ConstPtr &extension, QQmlJSRegisterContent base) const;
252
253 QQmlJSRegisterContent baseType(
254 const QQmlJSScope::ConstPtr &base, QQmlJSRegisterContent derived) const;
255
256 QQmlJSRegisterContent parentScope(
257 const QQmlJSScope::ConstPtr &parent, QQmlJSRegisterContent child) const;
258
259 QQmlJSRegisterContent iteratorPointer(
260 QQmlJSRegisterContent listType, QQmlJS::AST::ForEachType type,
261 int lookupIndex) const;
262
263 QQmlJSRegisterContent convert(
264 QQmlJSRegisterContent from, QQmlJSRegisterContent to) const;
265 QQmlJSRegisterContent convert(
266 QQmlJSRegisterContent from, const QQmlJSScope::ConstPtr &to) const;
267
268
269 // Type adjustment
270
271 [[nodiscard]] bool adjustTrackedType(
272 QQmlJSRegisterContent tracked, const QQmlJSScope::ConstPtr &conversion) const;
273 [[nodiscard]] bool adjustTrackedType(
274 QQmlJSRegisterContent tracked, QQmlJSRegisterContent conversion) const;
275 [[nodiscard]] bool adjustTrackedType(
276 QQmlJSRegisterContent tracked,
277 const QList<QQmlJSRegisterContent> &conversions) const;
278 void adjustOriginalType(
279 QQmlJSRegisterContent tracked, const QQmlJSScope::ConstPtr &conversion) const;
280 void generalizeType(QQmlJSRegisterContent type) const;
281
282
283protected:
284
285 QQmlJSRegisterContent memberType(QQmlJSRegisterContent type, const QString &name,
286 int baseLookupIndex, int resultLookupIndex) const;
287 QQmlJSRegisterContent memberEnumType(QQmlJSRegisterContent type,
288 const QString &name) const;
289 bool checkEnums(QQmlJSRegisterContent scope, const QString &name,
290 QQmlJSRegisterContent *result) const;
291 bool canPrimitivelyConvertFromTo(
292 const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
293 QQmlJSRegisterContent lengthProperty(bool isWritable, QQmlJSRegisterContent scope) const;
294
295 QQmlJSScope::ConstPtr containedTypeForName(const QString &name) const;
296 QQmlJSRegisterContent registerContentForName(
297 const QString &name, QQmlJSRegisterContent scopeType = {}) const;
298
299 QQmlJSScope::ConstPtr resolveParentProperty(
300 const QString &name, const QQmlJSScope::ConstPtr &base,
301 const QQmlJSScope::ConstPtr &propType) const;
302
303 std::unique_ptr<QQmlJSRegisterContentPool> m_pool;
304
305 QQmlJSScope::ConstPtr m_voidType;
306 QQmlJSScope::ConstPtr m_emptyType;
307 QQmlJSScope::ConstPtr m_nullType;
308 QQmlJSScope::ConstPtr m_numberPrototype;
309 QQmlJSScope::ConstPtr m_arrayPrototype;
310 QQmlJSScope::ConstPtr m_realType;
311 QQmlJSScope::ConstPtr m_floatType;
312 QQmlJSScope::ConstPtr m_int8Type;
313 QQmlJSScope::ConstPtr m_uint8Type;
314 QQmlJSScope::ConstPtr m_int16Type;
315 QQmlJSScope::ConstPtr m_uint16Type;
316 QQmlJSScope::ConstPtr m_int32Type;
317 QQmlJSScope::ConstPtr m_uint32Type;
318 QQmlJSScope::ConstPtr m_int64Type;
319 QQmlJSScope::ConstPtr m_uint64Type;
320 QQmlJSScope::ConstPtr m_sizeType;
321 QQmlJSScope::ConstPtr m_boolType;
322 QQmlJSScope::ConstPtr m_stringType;
323 QQmlJSScope::ConstPtr m_stringListType;
324 QQmlJSScope::ConstPtr m_byteArrayType;
325 QQmlJSScope::ConstPtr m_urlType;
326 QQmlJSScope::ConstPtr m_dateTimeType;
327 QQmlJSScope::ConstPtr m_dateType;
328 QQmlJSScope::ConstPtr m_timeType;
329 QQmlJSScope::ConstPtr m_regexpType;
330 QQmlJSScope::ConstPtr m_variantListType;
331 QQmlJSScope::ConstPtr m_variantMapType;
332 QQmlJSScope::ConstPtr m_varType;
333 QQmlJSScope::ConstPtr m_qmlPropertyMapType;
334 QQmlJSScope::ConstPtr m_jsValueType;
335 QQmlJSScope::ConstPtr m_jsPrimitiveType;
336 QQmlJSScope::ConstPtr m_listPropertyType;
337 QQmlJSScope::ConstPtr m_qObjectType;
338 QQmlJSScope::ConstPtr m_qObjectListType;
339 QQmlJSScope::ConstPtr m_qQmlScriptStringType;
340 QQmlJSScope::ConstPtr m_metaObjectType;
341 QQmlJSScope::ConstPtr m_functionType;
342 QQmlJSScope::ConstPtr m_jsGlobalObject;
343 QQmlJSScope::ConstPtr m_forInIteratorPtr;
344 QQmlJSScope::ConstPtr m_forOfIteratorPtr;
345
346 QQmlJSRegisterContent m_jsGlobalObjectContent;
347
348 QQmlJSScopesById m_objectsById;
349 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_objectsByLocation;
350 QQmlJSImporter::ImportedTypes m_imports;
351 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
352 QStringList m_seenModuleQualifiers;
353
354 ParentMode m_parentMode = UseParentProperty;
355 CloneMode m_cloneMode = CloneTypes;
356 QQmlJSLogger *m_logger = nullptr;
357};
358
359/*!
360\internal
361
362QQmlJSTypeResolver expects to be outlived by its importer and mapper. It crashes when its importer
363or mapper gets destructed. Therefore, you can use this struct to extend the lifetime of its
364dependencies in case you need to store the resolver as a class member.
365QQmlJSTypeResolver also expects to be outlived by the logger used by the importvisitor, while the
366importvisitor actually does not and will not outlive the QQmlJSTypeResolver.
367*/
369{
370 std::shared_ptr<QQmlJSImporter> importer;
372 std::shared_ptr<QQmlJSLogger> logger;
373};
374
375QT_END_NAMESPACE
376
377#endif // QQMLJSTYPERESOLVER_P_H
std::shared_ptr< QQmlJSResourceFileMapper > mapper
std::shared_ptr< QQmlJSLogger > logger
std::shared_ptr< QQmlJSImporter > importer