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#ifndef QQMLTYPECOMPILER_P_H
4#define QQMLTYPECOMPILER_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <qglobal.h>
18#include <qqmlerror.h>
19#include <qhash.h>
20#include <private/qqmltypeloader_p.h>
21#include <private/qqmlirbuilder_p.h>
22#include <private/qqmlpropertycachecreator_p.h>
23
24QT_BEGIN_NAMESPACE
25
26class QQmlEnginePrivate;
27class QQmlError;
28class QQmlTypeData;
29class QQmlImports;
30
31namespace QmlIR {
32struct Document;
33}
34
35namespace QV4 {
36namespace CompiledData {
37struct QmlUnit;
38struct Location;
39}
40}
41
42struct QQmlTypeCompiler
43{
44 Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
45public:
46 QQmlTypeCompiler(QQmlEnginePrivate *engine,
47 QQmlTypeData *typeData,
48 QmlIR::Document *document,
49 const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
50 QV4::ResolvedTypeReferenceMap *resolvedTypeCache,
51 const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
52
53 // --- interface used by QQmlPropertyCacheCreator
54 typedef QmlIR::Object CompiledObject;
55 typedef QmlIR::Binding CompiledBinding;
56 using ListPropertyAssignBehavior = QmlIR::Pragma::ListPropertyAssignBehaviorValue;
57
58 // Deliberate choice of map over hash here to ensure stable generated output.
59 using IdToObjectMap = QMap<int, int>;
60
61 const QmlIR::Object *objectAt(int index) const { return document->objects.at(i: index); }
62 QmlIR::Object *objectAt(int index) { return document->objects.at(i: index); }
63 int objectCount() const { return document->objects.size(); }
64 QString stringAt(int idx) const;
65 QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); }
66 QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); }
67 QV4::ResolvedTypeReferenceMap *resolvedTypes = nullptr;
68 ListPropertyAssignBehavior listPropertyAssignBehavior() const
69 {
70 for (const QmlIR::Pragma *pragma: document->pragmas) {
71 if (pragma->type == QmlIR::Pragma::ListPropertyAssignBehavior)
72 return pragma->listPropertyAssignBehavior;
73 }
74 return ListPropertyAssignBehavior::Append;
75 }
76 // ---
77
78 QQmlRefPointer<QV4::ExecutableCompilationUnit> compile();
79
80 QList<QQmlError> compilationErrors() const { return errors; }
81 void recordError(const QV4::CompiledData::Location &location, const QString &description);
82 void recordError(const QQmlJS::DiagnosticMessage &message);
83 void recordError(const QQmlError &e);
84
85 int registerString(const QString &str);
86 int registerConstant(QV4::ReturnedValue v);
87
88 const QV4::CompiledData::Unit *qmlUnit() const;
89
90 QUrl url() const { return typeData->finalUrl(); }
91 QQmlEnginePrivate *enginePrivate() const { return engine; }
92 const QQmlImports *imports() const;
93 QVector<QmlIR::Object *> *qmlObjects() const;
94 QQmlPropertyCacheVector *propertyCaches();
95 const QQmlPropertyCacheVector *propertyCaches() const;
96 QQmlJS::MemoryPool *memoryPool();
97 QStringView newStringRef(const QString &string);
98 const QV4::Compiler::StringTableGenerator *stringPool() const;
99
100 const QHash<int, QQmlCustomParser*> &customParserCache() const { return customParsers; }
101
102 QString bindingAsString(const QmlIR::Object *object, int scriptIndex) const;
103
104 void addImport(const QString &module, const QString &qualifier, QTypeRevision version);
105
106 QV4::ResolvedTypeReference *resolvedType(int id) const
107 {
108 return resolvedTypes->value(key: id);
109 }
110
111 CompositeMetaTypeIds typeIdsForComponent(const QString &inlineComponentName = QString()) const;
112
113private:
114 QList<QQmlError> errors;
115 QQmlEnginePrivate *engine;
116 const QV4::CompiledData::DependentTypesHasher &dependencyHasher;
117 QmlIR::Document *document;
118 // index is string index of type name (use obj->inheritedTypeNameIndex)
119 QHash<int, QQmlCustomParser*> customParsers;
120
121 // index in first hash is component index, vector inside contains object indices of objects with id property
122 QQmlPropertyCacheVector m_propertyCaches;
123
124 QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
125 QQmlTypeData *typeData;
126};
127
128struct QQmlCompilePass
129{
130 QQmlCompilePass(QQmlTypeCompiler *typeCompiler);
131
132 QString stringAt(int idx) const { return compiler->stringAt(idx); }
133protected:
134 void recordError(const QV4::CompiledData::Location &location, const QString &description) const
135 { compiler->recordError(location, description); }
136
137 QV4::ResolvedTypeReference *resolvedType(int id) const
138 { return compiler->resolvedType(id); }
139
140 QQmlTypeCompiler *compiler;
141};
142
143// Resolves signal handlers. Updates the QV4::CompiledData::Binding objects to
144// set the property name to the final signal name (onTextChanged -> textChanged)
145// and sets the IsSignalExpression flag.
146struct SignalHandlerResolver : public QQmlCompilePass
147{
148 Q_DECLARE_TR_FUNCTIONS(SignalHandlerResolver)
149public:
150 SignalHandlerResolver(QQmlTypeCompiler *typeCompiler);
151
152 bool resolveSignalHandlerExpressions();
153
154private:
155 bool resolveSignalHandlerExpressions(const QmlIR::Object *obj, const QString &typeName,
156 const QQmlPropertyCache::ConstPtr &propertyCache);
157
158 QQmlEnginePrivate *enginePrivate;
159 const QVector<QmlIR::Object*> &qmlObjects;
160 const QQmlImports *imports;
161 const QHash<int, QQmlCustomParser*> &customParsers;
162 const QSet<QString> &illegalNames;
163 const QQmlPropertyCacheVector * const propertyCaches;
164};
165
166// ### This will go away when the codegen resolves all enums to constant expressions
167// and we replace the constant expression with a literal binding instead of using
168// a script.
169class QQmlEnumTypeResolver : public QQmlCompilePass
170{
171 Q_DECLARE_TR_FUNCTIONS(QQmlEnumTypeResolver)
172public:
173 QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler);
174
175 bool resolveEnumBindings();
176
177private:
178 bool assignEnumToBinding(QmlIR::Binding *binding, QStringView enumName, int enumValue, bool isQtObject);
179 bool assignEnumToBinding(QmlIR::Binding *binding, const QString &enumName, int enumValue, bool isQtObject)
180 {
181 return assignEnumToBinding(binding, enumName: QStringView(enumName), enumValue, isQtObject);
182 }
183 bool tryQualifiedEnumAssignment(
184 const QmlIR::Object *obj, const QQmlPropertyCache::ConstPtr &propertyCache,
185 const QQmlPropertyData *prop, QmlIR::Binding *binding);
186 int evaluateEnum(const QString &scope, QStringView enumName, QStringView enumValue, bool *ok) const;
187
188
189 const QVector<QmlIR::Object*> &qmlObjects;
190 const QQmlPropertyCacheVector * const propertyCaches;
191 const QQmlImports *imports;
192};
193
194class QQmlCustomParserScriptIndexer: public QQmlCompilePass
195{
196public:
197 QQmlCustomParserScriptIndexer(QQmlTypeCompiler *typeCompiler);
198
199 void annotateBindingsWithScriptStrings();
200
201private:
202 void scanObjectRecursively(int objectIndex, bool annotateScriptBindings = false);
203
204 const QVector<QmlIR::Object*> &qmlObjects;
205 const QHash<int, QQmlCustomParser*> &customParsers;
206};
207
208// Annotate properties bound to aliases with a flag
209class QQmlAliasAnnotator : public QQmlCompilePass
210{
211public:
212 QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler);
213
214 void annotateBindingsToAliases();
215private:
216 const QVector<QmlIR::Object*> &qmlObjects;
217 const QQmlPropertyCacheVector * const propertyCaches;
218};
219
220class QQmlScriptStringScanner : public QQmlCompilePass
221{
222public:
223 QQmlScriptStringScanner(QQmlTypeCompiler *typeCompiler);
224
225 void scan();
226
227private:
228 const QVector<QmlIR::Object*> &qmlObjects;
229 const QQmlPropertyCacheVector * const propertyCaches;
230};
231
232class QQmlDeferredAndCustomParserBindingScanner : public QQmlCompilePass
233{
234 Q_DECLARE_TR_FUNCTIONS(QQmlDeferredAndCustomParserBindingScanner)
235public:
236 QQmlDeferredAndCustomParserBindingScanner(QQmlTypeCompiler *typeCompiler);
237
238 bool scanObject();
239
240private:
241 enum class ScopeDeferred { False, True };
242 bool scanObject(int objectIndex, ScopeDeferred scopeDeferred);
243
244 QVector<QmlIR::Object*> *qmlObjects;
245 const QQmlPropertyCacheVector * const propertyCaches;
246 const QHash<int, QQmlCustomParser*> &customParsers;
247
248 bool _seenObjectWithId;
249};
250
251class QQmlDefaultPropertyMerger : public QQmlCompilePass
252{
253public:
254 QQmlDefaultPropertyMerger(QQmlTypeCompiler *typeCompiler);
255
256 void mergeDefaultProperties();
257
258private:
259 void mergeDefaultProperties(int objectIndex);
260
261 const QVector<QmlIR::Object*> &qmlObjects;
262 const QQmlPropertyCacheVector * const propertyCaches;
263};
264
265QT_END_NAMESPACE
266
267#endif // QQMLTYPECOMPILER_P_H
268

source code of qtdeclarative/src/qml/qml/qqmltypecompiler_p.h