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 <private/qtqmlcompilerexports_p.h>
18
19#include <private/qqmlirbuilder_p.h>
20#include <private/qqmljsast_p.h>
21#include "qqmljsimporter_p.h"
22#include "qqmljslogger_p.h"
23#include "qqmljsregistercontent_p.h"
24#include "qqmljsscope_p.h"
25#include "qqmljsscopesbyid_p.h"
26
27QT_BEGIN_NAMESPACE
28
29class QQmlJSImportVisitor;
30class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSTypeResolver
31{
32public:
33 enum ParentMode { UseDocumentParent, UseParentProperty };
34 enum CloneMode { CloneTypes, DoNotCloneTypes };
35 enum ListMode { UseListProperty, UseQObjectList };
36
37 QQmlJSTypeResolver(QQmlJSImporter *importer);
38
39 // Note: must be called after the construction to read the QML program
40 void init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *program);
41
42 QQmlJSScope::ConstPtr voidType() const { return m_voidType; }
43 QQmlJSScope::ConstPtr emptyType() const { return m_emptyType; }
44 QQmlJSScope::ConstPtr nullType() const { return m_nullType; }
45 QQmlJSScope::ConstPtr realType() const { return m_realType; }
46 QQmlJSScope::ConstPtr floatType() const { return m_floatType; }
47 QQmlJSScope::ConstPtr int8Type() const { return m_int8Type; }
48 QQmlJSScope::ConstPtr uint8Type() const { return m_uint8Type; }
49 QQmlJSScope::ConstPtr int16Type() const { return m_int16Type; }
50 QQmlJSScope::ConstPtr uint16Type() const { return m_uint16Type; }
51 QQmlJSScope::ConstPtr int32Type() const { return m_int32Type; }
52 QQmlJSScope::ConstPtr uint32Type() const { return m_uint32Type; }
53 QQmlJSScope::ConstPtr int64Type() const { return m_int64Type; }
54 QQmlJSScope::ConstPtr uint64Type() const { return m_uint64Type; }
55 QQmlJSScope::ConstPtr boolType() const { return m_boolType; }
56 QQmlJSScope::ConstPtr stringType() const { return m_stringType; }
57 QQmlJSScope::ConstPtr stringListType() const { return m_stringListType; }
58 QQmlJSScope::ConstPtr byteArrayType() const { return m_byteArrayType; }
59 QQmlJSScope::ConstPtr urlType() const { return m_urlType; }
60 QQmlJSScope::ConstPtr dateTimeType() const { return m_dateTimeType; }
61 QQmlJSScope::ConstPtr dateType() const { return m_dateType; }
62 QQmlJSScope::ConstPtr timeType() const { return m_timeType; }
63 QQmlJSScope::ConstPtr variantListType() const { return m_variantListType; }
64 QQmlJSScope::ConstPtr variantMapType() const { return m_variantMapType; }
65 QQmlJSScope::ConstPtr varType() const { return m_varType; }
66 QQmlJSScope::ConstPtr jsValueType() const { return m_jsValueType; }
67 QQmlJSScope::ConstPtr jsPrimitiveType() const { return m_jsPrimitiveType; }
68 QQmlJSScope::ConstPtr listPropertyType() const { return m_listPropertyType; }
69 QQmlJSScope::ConstPtr metaObjectType() const { return m_metaObjectType; }
70 QQmlJSScope::ConstPtr functionType() const { return m_functionType; }
71 QQmlJSScope::ConstPtr jsGlobalObject() const { return m_jsGlobalObject; }
72 QQmlJSScope::ConstPtr qObjectType() const { return m_qObjectType; }
73 QQmlJSScope::ConstPtr qObjectListType() const { return m_qObjectListType; }
74 QQmlJSScope::ConstPtr arrayType() const { return m_arrayType; }
75
76 QQmlJSScope::ConstPtr scopeForLocation(const QV4::CompiledData::Location &location) const;
77 QQmlJSScope::ConstPtr scopeForId(
78 const QString &id, const QQmlJSScope::ConstPtr &referrer) const;
79 QString idForScope(
80 const QQmlJSScope::ConstPtr &scope, const QQmlJSScope::ConstPtr &referrer) const;
81
82 bool isPrefix(const QString &name) const
83 {
84 return m_imports.hasType(name) && !m_imports.type(name).scope;
85 }
86
87 QQmlJSScope::ConstPtr typeForName(const QString &name) const
88 {
89 return m_imports.type(name).scope;
90 }
91 QQmlJSScope::ConstPtr typeFromAST(QQmlJS::AST::Type *type) const;
92 QQmlJSScope::ConstPtr typeForConst(QV4::ReturnedValue rv) const;
93 QQmlJSRegisterContent typeForBinaryOperation(QSOperator::Op oper,
94 const QQmlJSRegisterContent &left,
95 const QQmlJSRegisterContent &right) const;
96
97 enum class UnaryOperator { Not, Plus, Minus, Increment, Decrement, Complement };
98 QQmlJSRegisterContent typeForArithmeticUnaryOperation(
99 UnaryOperator op, const QQmlJSRegisterContent &operand) const;
100
101 bool isPrimitive(const QQmlJSRegisterContent &type) const;
102 bool isNumeric(const QQmlJSRegisterContent &type) const;
103 bool isIntegral(const QQmlJSRegisterContent &type) const;
104
105 bool canConvertFromTo(const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
106 bool canConvertFromTo(const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const;
107 QQmlJSRegisterContent merge(const QQmlJSRegisterContent &a,
108 const QQmlJSRegisterContent &b) const;
109
110 enum class ComponentIsGeneric { No, Yes };
111 QQmlJSScope::ConstPtr
112 genericType(const QQmlJSScope::ConstPtr &type,
113 ComponentIsGeneric allowComponent = ComponentIsGeneric::No) const;
114
115 QQmlJSRegisterContent builtinType(const QQmlJSScope::ConstPtr &type) const;
116 QQmlJSRegisterContent globalType(const QQmlJSScope::ConstPtr &type) const;
117 QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name) const;
118 QQmlJSRegisterContent memberType(const QQmlJSRegisterContent &type, const QString &name) const;
119 QQmlJSRegisterContent valueType(const QQmlJSRegisterContent &list) const;
120 QQmlJSRegisterContent returnType(
121 const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant,
122 const QQmlJSScope::ConstPtr &scope) const;
123
124 bool registerIsStoredIn(const QQmlJSRegisterContent &reg,
125 const QQmlJSScope::ConstPtr &type) const;
126 bool registerContains(const QQmlJSRegisterContent &reg,
127 const QQmlJSScope::ConstPtr &type) const;
128 QQmlJSScope::ConstPtr containedType(const QQmlJSRegisterContent &container) const;
129 QString containedTypeName(const QQmlJSRegisterContent &container,
130 bool useFancyName = false) const;
131
132 QQmlJSRegisterContent tracked(const QQmlJSRegisterContent &type) const;
133 QQmlJSRegisterContent original(const QQmlJSRegisterContent &type) const;
134
135 QQmlJSScope::ConstPtr trackedContainedType(const QQmlJSRegisterContent &container) const;
136 QQmlJSScope::ConstPtr originalContainedType(const QQmlJSRegisterContent &container) const;
137
138 [[nodiscard]] bool adjustTrackedType(
139 const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const;
140 [[nodiscard]] bool adjustTrackedType(
141 const QQmlJSScope::ConstPtr &tracked,
142 const QList<QQmlJSScope::ConstPtr> &conversions) const;
143 void adjustOriginalType(
144 const QQmlJSScope::ConstPtr &tracked, const QQmlJSScope::ConstPtr &conversion) const;
145 void generalizeType(const QQmlJSScope::ConstPtr &type) const;
146
147 void setParentMode(ParentMode mode) { m_parentMode = mode; }
148 ParentMode parentMode() const { return m_parentMode; }
149
150 void setCloneMode(CloneMode mode) { m_cloneMode = mode; }
151 bool cloneMode() const { return m_cloneMode; }
152
153 QQmlJSScope::ConstPtr storedType(const QQmlJSScope::ConstPtr &type) const;
154 QQmlJSScope::ConstPtr originalType(const QQmlJSScope::ConstPtr &type) const;
155 QQmlJSScope::ConstPtr trackedType(const QQmlJSScope::ConstPtr &type) const;
156 QQmlJSScope::ConstPtr comparableType(const QQmlJSScope::ConstPtr &type) const;
157
158 const QQmlJSScopesById &objectsById() const { return m_objectsById; }
159 bool canCallJSFunctions() const { return m_objectsById.signaturesAreEnforced(); }
160 bool canAddressValueTypes() const { return m_objectsById.valueTypesAreAddressable(); }
161
162 const QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> &signalHandlers() const
163 {
164 return m_signalHandlers;
165 }
166
167 bool equals(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
168
169 QQmlJSRegisterContent convert(
170 const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const;
171
172 QQmlJSScope::ConstPtr merge(const QQmlJSScope::ConstPtr &a,
173 const QQmlJSScope::ConstPtr &b) const;
174
175 bool canHoldUndefined(const QQmlJSRegisterContent &content) const;
176 bool isNumeric(const QQmlJSScope::ConstPtr &type) const;
177 bool isIntegral(const QQmlJSScope::ConstPtr &type) const;
178 bool isSignedInteger(const QQmlJSScope::ConstPtr &type) const;
179 bool isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const;
180
181 bool canHold(const QQmlJSScope::ConstPtr &container,
182 const QQmlJSScope::ConstPtr &contained) const;
183
184 QQmlJSMetaMethod selectConstructor(
185 const QQmlJSScope::ConstPtr &type, const QQmlJSScope::ConstPtr &argument,
186 bool *isExtension) const;
187
188 bool areEquivalentLists(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const;
189
190protected:
191
192 QQmlJSRegisterContent memberType(const QQmlJSScope::ConstPtr &type, const QString &name) const;
193 QQmlJSRegisterContent memberEnumType(const QQmlJSScope::ConstPtr &type,
194 const QString &name) const;
195 bool isPrimitive(const QQmlJSScope::ConstPtr &type) const;
196 bool checkEnums(const QQmlJSScope::ConstPtr &scope, const QString &name,
197 QQmlJSRegisterContent *result, QQmlJSScope::ExtensionKind mode) const;
198 bool canPrimitivelyConvertFromTo(
199 const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const;
200 QQmlJSRegisterContent lengthProperty(bool isWritable, const QQmlJSScope::ConstPtr &scope) const;
201 QQmlJSRegisterContent transformed(
202 const QQmlJSRegisterContent &origin,
203 QQmlJSScope::ConstPtr (QQmlJSTypeResolver::*op)(const QQmlJSScope::ConstPtr &) const) const;
204
205 QQmlJSRegisterContent registerContentForName(
206 const QString &name,
207 const QQmlJSScope::ConstPtr &scopeType = QQmlJSScope::ConstPtr(),
208 bool hasObjectModuelPrefix = false) const;
209
210
211 QQmlJSScope::ConstPtr m_voidType;
212 QQmlJSScope::ConstPtr m_emptyType;
213 QQmlJSScope::ConstPtr m_nullType;
214 QQmlJSScope::ConstPtr m_numberPrototype;
215 QQmlJSScope::ConstPtr m_arrayType;
216 QQmlJSScope::ConstPtr m_realType;
217 QQmlJSScope::ConstPtr m_floatType;
218 QQmlJSScope::ConstPtr m_int8Type;
219 QQmlJSScope::ConstPtr m_uint8Type;
220 QQmlJSScope::ConstPtr m_int16Type;
221 QQmlJSScope::ConstPtr m_uint16Type;
222 QQmlJSScope::ConstPtr m_int32Type;
223 QQmlJSScope::ConstPtr m_uint32Type;
224 QQmlJSScope::ConstPtr m_int64Type;
225 QQmlJSScope::ConstPtr m_uint64Type;
226 QQmlJSScope::ConstPtr m_boolType;
227 QQmlJSScope::ConstPtr m_stringType;
228 QQmlJSScope::ConstPtr m_stringListType;
229 QQmlJSScope::ConstPtr m_byteArrayType;
230 QQmlJSScope::ConstPtr m_urlType;
231 QQmlJSScope::ConstPtr m_dateTimeType;
232 QQmlJSScope::ConstPtr m_dateType;
233 QQmlJSScope::ConstPtr m_timeType;
234 QQmlJSScope::ConstPtr m_variantListType;
235 QQmlJSScope::ConstPtr m_variantMapType;
236 QQmlJSScope::ConstPtr m_varType;
237 QQmlJSScope::ConstPtr m_jsValueType;
238 QQmlJSScope::ConstPtr m_jsPrimitiveType;
239 QQmlJSScope::ConstPtr m_listPropertyType;
240 QQmlJSScope::ConstPtr m_qObjectType;
241 QQmlJSScope::ConstPtr m_qObjectListType;
242 QQmlJSScope::ConstPtr m_metaObjectType;
243 QQmlJSScope::ConstPtr m_functionType;
244 QQmlJSScope::ConstPtr m_jsGlobalObject;
245
246 QQmlJSScopesById m_objectsById;
247 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_objectsByLocation;
248 QQmlJSImporter::ImportedTypes m_imports;
249 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
250
251 ParentMode m_parentMode = UseParentProperty;
252 CloneMode m_cloneMode = CloneTypes;
253 QQmlJSLogger *m_logger = nullptr;
254
255 struct TrackedType
256 {
257 // The type originally found via type analysis.
258 QQmlJSScope::ConstPtr original;
259
260 // Any later replacement used to overwrite the contents of the clone.
261 QQmlJSScope::ConstPtr replacement;
262
263 // A clone of original, used to track the type,
264 // contents possibly overwritten by replacement.
265 QQmlJSScope::Ptr clone;
266 };
267
268 std::unique_ptr<QHash<QQmlJSScope::ConstPtr, TrackedType>> m_trackedTypes;
269};
270
271QT_END_NAMESPACE
272
273#endif // QQMLJSTYPERESOLVER_P_H
274

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