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
4#ifndef QQMLJSTYPERESOLVER_P_H
5#define QQMLJSTYPERESOLVER_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#include <memory>
18#include <qtqmlcompilerexports.h>
19
20#include <private/qqmlirbuilder_p.h>
21#include <private/qqmljsast_p.h>
22#include "qqmljsimporter_p.h"
23#include "qqmljslogger_p.h"
24#include "qqmljsregistercontent_p.h"
25#include "qqmljsresourcefilemapper_p.h"
26#include "qqmljsscope_p.h"
27#include "qqmljsscopesbyid_p.h"
28
29QT_BEGIN_NAMESPACE
30
31class QQmlJSImportVisitor;
32class Q_QMLCOMPILER_EXPORT QQmlJSTypeResolver
33{
34public:
35 enum ParentMode { UseDocumentParent, UseParentProperty };
36 enum CloneMode { CloneTypes, DoNotCloneTypes };
37 enum ListMode { UseListProperty, UseQObjectList };
38
39 QQmlJSTypeResolver(QQmlJSImporter *importer);
40
41 // Note: must be called after the construction to read the QML program
42 void init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *program);
43
44 QQmlJSScope::ConstPtr voidType() const { return m_voidType; }
45 QQmlJSScope::ConstPtr emptyType() const { return m_emptyType; }
46 QQmlJSScope::ConstPtr nullType() const { return m_nullType; }
47 QQmlJSScope::ConstPtr realType() const { return m_realType; }
48 QQmlJSScope::ConstPtr floatType() const { return m_floatType; }
49 QQmlJSScope::ConstPtr int8Type() const { return m_int8Type; }
50 QQmlJSScope::ConstPtr uint8Type() const { return m_uint8Type; }
51 QQmlJSScope::ConstPtr int16Type() const { return m_int16Type; }
52 QQmlJSScope::ConstPtr uint16Type() const { return m_uint16Type; }
53 QQmlJSScope::ConstPtr int32Type() const { return m_int32Type; }
54 QQmlJSScope::ConstPtr uint32Type() const { return m_uint32Type; }
55 QQmlJSScope::ConstPtr int64Type() const { return m_int64Type; }
56 QQmlJSScope::ConstPtr uint64Type() const { return m_uint64Type; }
57 QQmlJSScope::ConstPtr sizeType() const { return m_sizeType; }
58 QQmlJSScope::ConstPtr boolType() const { return m_boolType; }
59 QQmlJSScope::ConstPtr stringType() const { return m_stringType; }
60 QQmlJSScope::ConstPtr stringListType() const { return m_stringListType; }
61 QQmlJSScope::ConstPtr byteArrayType() const { return m_byteArrayType; }
62 QQmlJSScope::ConstPtr urlType() const { return m_urlType; }
63 QQmlJSScope::ConstPtr dateTimeType() const { return m_dateTimeType; }
64 QQmlJSScope::ConstPtr dateType() const { return m_dateType; }
65 QQmlJSScope::ConstPtr timeType() const { return m_timeType; }
66 QQmlJSScope::ConstPtr variantListType() const { return m_variantListType; }
67 QQmlJSScope::ConstPtr variantMapType() const { return m_variantMapType; }
68 QQmlJSScope::ConstPtr varType() const { return m_varType; }
69 QQmlJSScope::ConstPtr jsValueType() const { return m_jsValueType; }
70 QQmlJSScope::ConstPtr jsPrimitiveType() const { return m_jsPrimitiveType; }
71 QQmlJSScope::ConstPtr listPropertyType() const { return m_listPropertyType; }
72 QQmlJSScope::ConstPtr metaObjectType() const { return m_metaObjectType; }
73 QQmlJSScope::ConstPtr functionType() const { return m_functionType; }
74 QQmlJSScope::ConstPtr jsGlobalObject() const { return m_jsGlobalObject; }
75 QQmlJSScope::ConstPtr qObjectType() const { return m_qObjectType; }
76 QQmlJSScope::ConstPtr qObjectListType() const { return m_qObjectListType; }
77 QQmlJSScope::ConstPtr arrayPrototype() const { return m_arrayPrototype; }
78 QQmlJSScope::ConstPtr forInIteratorPtr() const { return m_forInIteratorPtr; }
79 QQmlJSScope::ConstPtr forOfIteratorPtr() const { return m_forOfIteratorPtr; }
80
81 QQmlJSScope::ConstPtr mathObject() const;
82 QQmlJSScope::ConstPtr consoleObject() const;
83
84 QQmlJSScope::ConstPtr scopeForLocation(const QV4::CompiledData::Location &location) const;
85
86 bool isPrefix(const QString &name) const
87 {
88 return m_imports.hasType(name) && !m_imports.type(name).scope;
89 }
90
91 const QHash<QString, QQmlJS::ImportedScope<QQmlJSScope::ConstPtr>> &importedTypes() const
92 {
93 return m_imports.types();
94 }
95
96 const auto &importedNames() const
97 {
98 return m_imports.contextualTypes().names();
99 }
100
101 QQmlJSScope::ConstPtr typeForName(const QString &name) const
102 {
103 return m_imports.type(name).scope;
104 }
105 QString nameForType(const QQmlJSScope::ConstPtr &type) const
106 {
107 // We want here not the name of the original type. That one may not exist.
108 // We want the name of the type we've used as replacement since that is
109 // whatever we do with the type expects.
110 return m_imports.name(type: comparableType(type));
111 }
112
113 QQmlJSScope::ConstPtr typeFromAST(QQmlJS::AST::Type *type) const;
114 QQmlJSScope::ConstPtr typeForConst(QV4::ReturnedValue rv) const;
115 QQmlJSRegisterContent typeForBinaryOperation(QSOperator::Op oper,
116 const QQmlJSRegisterContent &left,
117 const QQmlJSRegisterContent &right) const;
118
119 enum class UnaryOperator { Not, Plus, Minus, Increment, Decrement, Complement };
120 QQmlJSRegisterContent typeForArithmeticUnaryOperation(
121 UnaryOperator op, const QQmlJSRegisterContent &operand) const;
122
123 bool isPrimitive(const QQmlJSRegisterContent &type) const;
124 bool isPrimitive(const QQmlJSScope::ConstPtr &type) const;
125
126 bool isNumeric(const QQmlJSRegisterContent &type) const;
127 bool isIntegral(const QQmlJSRegisterContent &type) const;
128
129 bool canConvertFromTo(const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
130 bool canConvertFromTo(const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const;
131 QQmlJSRegisterContent merge(const QQmlJSRegisterContent &a,
132 const QQmlJSRegisterContent &b) const;
133
134 enum class ComponentIsGeneric { No, Yes };
135 QQmlJSScope::ConstPtr
136 genericType(const QQmlJSScope::ConstPtr &type,
137 ComponentIsGeneric allowComponent = ComponentIsGeneric::No) const;
138
139 QQmlJSRegisterContent builtinType(const QQmlJSScope::ConstPtr &type) const;
140 QQmlJSRegisterContent globalType(const QQmlJSScope::ConstPtr &type) const;
141 QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name,
142 int lookupIndex = QQmlJSRegisterContent::InvalidLookupIndex,
143 QQmlJSScopesByIdOptions options = Default) const;
144 QQmlJSRegisterContent memberType(
145 const QQmlJSRegisterContent &type, const QString &name,
146 int lookupIndex = QQmlJSRegisterContent::InvalidLookupIndex) const;
147 QQmlJSRegisterContent valueType(const QQmlJSRegisterContent &list) const;
148 QQmlJSRegisterContent returnType(
149 const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant,
150 const QQmlJSScope::ConstPtr &scope) const;
151
152 QQmlJSRegisterContent iteratorPointer(
153 const QQmlJSRegisterContent &listType, QQmlJS::AST::ForEachType type,
154 int lookupIndex) const;
155
156 bool registerIsStoredIn(const QQmlJSRegisterContent &reg,
157 const QQmlJSScope::ConstPtr &type) const;
158 bool registerContains(const QQmlJSRegisterContent &reg,
159 const QQmlJSScope::ConstPtr &type) const;
160 QQmlJSScope::ConstPtr containedType(const QQmlJSRegisterContent &container) const;
161 QString containedTypeName(const QQmlJSRegisterContent &container,
162 bool useFancyName = false) const;
163
164 QQmlJSRegisterContent tracked(const QQmlJSRegisterContent &type) const;
165 QQmlJSRegisterContent original(const QQmlJSRegisterContent &type) const;
166
167 QQmlJSScope::ConstPtr trackedContainedType(const QQmlJSRegisterContent &container) const;
168 QQmlJSScope::ConstPtr originalContainedType(const QQmlJSRegisterContent &container) const;
169
170 [[nodiscard]] bool adjustTrackedType(
171 const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const;
172 [[nodiscard]] bool adjustTrackedType(
173 const QQmlJSScope::ConstPtr &tracked,
174 const QList<QQmlJSScope::ConstPtr> &conversions) const;
175 void adjustOriginalType(
176 const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const;
177 void generalizeType(const QQmlJSScope::ConstPtr &type) const;
178
179 void setParentMode(ParentMode mode) { m_parentMode = mode; }
180 ParentMode parentMode() const { return m_parentMode; }
181
182 void setCloneMode(CloneMode mode) { m_cloneMode = mode; }
183 bool cloneMode() const { return m_cloneMode; }
184
185 QQmlJSScope::ConstPtr storedType(const QQmlJSScope::ConstPtr &type) const;
186 QQmlJSScope::ConstPtr originalType(const QQmlJSScope::ConstPtr &type) const;
187 QQmlJSScope::ConstPtr trackedType(const QQmlJSScope::ConstPtr &type) const;
188 QQmlJSScope::ConstPtr comparableType(const QQmlJSScope::ConstPtr &type) const;
189
190 const QQmlJSScopesById &objectsById() const { return m_objectsById; }
191 bool canCallJSFunctions() const { return m_objectsById.signaturesAreEnforced(); }
192 bool canAddressValueTypes() const { return m_objectsById.valueTypesAreAddressable(); }
193
194 const QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> &signalHandlers() const
195 {
196 return m_signalHandlers;
197 }
198
199 bool equals(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
200
201 QQmlJSRegisterContent convert(
202 const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const;
203 QQmlJSRegisterContent cast(
204 const QQmlJSRegisterContent &from, const QQmlJSScope::ConstPtr &to) const;
205
206 QQmlJSScope::ConstPtr merge(const QQmlJSScope::ConstPtr &a,
207 const QQmlJSScope::ConstPtr &b) const;
208
209 bool canHoldUndefined(const QQmlJSRegisterContent &content) const;
210 bool isOptionalType(const QQmlJSRegisterContent &content) const;
211 QQmlJSScope::ConstPtr extractNonVoidFromOptionalType(
212 const QQmlJSRegisterContent &content) const;
213
214 bool isNumeric(const QQmlJSScope::ConstPtr &type) const;
215 bool isIntegral(const QQmlJSScope::ConstPtr &type) const;
216 bool isSignedInteger(const QQmlJSScope::ConstPtr &type) const;
217 bool isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const;
218 bool isNativeArrayIndex(const QQmlJSScope::ConstPtr &type) const;
219
220 bool canHold(const QQmlJSScope::ConstPtr &container,
221 const QQmlJSScope::ConstPtr &contained) const;
222
223 bool canPopulate(
224 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument,
225 bool *isExtension) const;
226
227 QQmlJSMetaMethod selectConstructor(
228 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument,
229 bool *isExtension) const;
230
231 bool areEquivalentLists(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
232
233 bool isTriviallyCopyable(const QQmlJSScope::ConstPtr &type) const;
234
235 bool inherits(const QQmlJSScope::ConstPtr &derived, const QQmlJSScope::ConstPtr &base) const;
236 QQmlJSLogger *logger() const { return m_logger; }
237 QStringList seenModuleQualifiers() const { return m_seenModuleQualifiers; }
238
239protected:
240
241 QQmlJSRegisterContent memberType(
242 const QQmlJSScope::ConstPtr &type, const QString &name,
243 int baseLookupIndex, int resultLookupIndex) const;
244 QQmlJSRegisterContent memberEnumType(const QQmlJSScope::ConstPtr &type,
245 const QString &name) const;
246 bool checkEnums(const QQmlJSScope::ConstPtr &scope, const QString &name,
247 QQmlJSRegisterContent *result, QQmlJSScope::ExtensionKind mode) const;
248 bool canPrimitivelyConvertFromTo(
249 const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
250 QQmlJSRegisterContent lengthProperty(bool isWritable, const QQmlJSScope::ConstPtr &scope) const;
251 QQmlJSRegisterContent transformed(
252 const QQmlJSRegisterContent &origin,
253 QQmlJSScope::ConstPtr (QQmlJSTypeResolver::*op)(const QQmlJSScope::ConstPtr &) const) const;
254
255 QQmlJSRegisterContent registerContentForName(
256 const QString &name,
257 const QQmlJSScope::ConstPtr &scopeType = QQmlJSScope::ConstPtr(),
258 bool hasObjectModuelPrefix = false) const;
259
260
261 QQmlJSScope::ConstPtr m_voidType;
262 QQmlJSScope::ConstPtr m_emptyType;
263 QQmlJSScope::ConstPtr m_nullType;
264 QQmlJSScope::ConstPtr m_numberPrototype;
265 QQmlJSScope::ConstPtr m_arrayPrototype;
266 QQmlJSScope::ConstPtr m_realType;
267 QQmlJSScope::ConstPtr m_floatType;
268 QQmlJSScope::ConstPtr m_int8Type;
269 QQmlJSScope::ConstPtr m_uint8Type;
270 QQmlJSScope::ConstPtr m_int16Type;
271 QQmlJSScope::ConstPtr m_uint16Type;
272 QQmlJSScope::ConstPtr m_int32Type;
273 QQmlJSScope::ConstPtr m_uint32Type;
274 QQmlJSScope::ConstPtr m_int64Type;
275 QQmlJSScope::ConstPtr m_uint64Type;
276 QQmlJSScope::ConstPtr m_sizeType;
277 QQmlJSScope::ConstPtr m_boolType;
278 QQmlJSScope::ConstPtr m_stringType;
279 QQmlJSScope::ConstPtr m_stringListType;
280 QQmlJSScope::ConstPtr m_byteArrayType;
281 QQmlJSScope::ConstPtr m_urlType;
282 QQmlJSScope::ConstPtr m_dateTimeType;
283 QQmlJSScope::ConstPtr m_dateType;
284 QQmlJSScope::ConstPtr m_timeType;
285 QQmlJSScope::ConstPtr m_variantListType;
286 QQmlJSScope::ConstPtr m_variantMapType;
287 QQmlJSScope::ConstPtr m_varType;
288 QQmlJSScope::ConstPtr m_jsValueType;
289 QQmlJSScope::ConstPtr m_jsPrimitiveType;
290 QQmlJSScope::ConstPtr m_listPropertyType;
291 QQmlJSScope::ConstPtr m_qObjectType;
292 QQmlJSScope::ConstPtr m_qObjectListType;
293 QQmlJSScope::ConstPtr m_qQmlScriptStringType;
294 QQmlJSScope::ConstPtr m_metaObjectType;
295 QQmlJSScope::ConstPtr m_functionType;
296 QQmlJSScope::ConstPtr m_jsGlobalObject;
297 QQmlJSScope::ConstPtr m_forInIteratorPtr;
298 QQmlJSScope::ConstPtr m_forOfIteratorPtr;
299
300 QQmlJSScopesById m_objectsById;
301 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_objectsByLocation;
302 QQmlJSImporter::ImportedTypes m_imports;
303 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
304 QStringList m_seenModuleQualifiers;
305
306 ParentMode m_parentMode = UseParentProperty;
307 CloneMode m_cloneMode = CloneTypes;
308 QQmlJSLogger *m_logger = nullptr;
309
310 struct TrackedType
311 {
312 // The type originally found via type analysis.
313 QQmlJSScope::ConstPtr original;
314
315 // Any later replacement used to overwrite the contents of the clone.
316 QQmlJSScope::ConstPtr replacement;
317
318 // A clone of original, used to track the type,
319 // contents possibly overwritten by replacement.
320 QQmlJSScope::Ptr clone;
321 };
322
323 std::unique_ptr<QHash<QQmlJSScope::ConstPtr, TrackedType>> m_trackedTypes;
324};
325
326/*!
327\internal
328
329QQmlJSTypeResolver expects to be outlived by its importer and mapper. It crashes when its importer
330or mapper gets destructed. Therefore, you can use this struct to extend the lifetime of its
331dependencies in case you need to store the resolver as a class member.
332QQmlJSTypeResolver also expects to be outlived by the logger used by the importvisitor, while the
333importvisitor actually does not and will not outlive the QQmlJSTypeResolver.
334*/
335struct QQmlJSTypeResolverDependencies
336{
337 std::shared_ptr<QQmlJSImporter> importer;
338 std::shared_ptr<QQmlJSResourceFileMapper> mapper;
339 std::shared_ptr<QQmlJSLogger> logger;
340};
341
342QT_END_NAMESPACE
343
344#endif // QQMLJSTYPERESOLVER_P_H
345

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtdeclarative/src/qmlcompiler/qqmljstyperesolver_p.h