1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39#ifndef QQMLTYPECOMPILER_P_H
40#define QQMLTYPECOMPILER_P_H
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists purely as an
47// implementation detail. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51//
52
53#include <qglobal.h>
54#include <qqmlerror.h>
55#include <qhash.h>
56#include <private/qqmltypeloader_p.h>
57#include <private/qqmlirbuilder_p.h>
58#include <private/qqmlpropertycachecreator_p.h>
59
60QT_BEGIN_NAMESPACE
61
62class QQmlEnginePrivate;
63class QQmlError;
64class QQmlTypeData;
65class QQmlImports;
66
67namespace QmlIR {
68struct Document;
69}
70
71namespace QV4 {
72namespace CompiledData {
73struct QmlUnit;
74struct Location;
75}
76}
77
78struct QQmlTypeCompiler
79{
80 Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
81public:
82 QQmlTypeCompiler(QQmlEnginePrivate *engine,
83 QQmlTypeData *typeData,
84 QmlIR::Document *document,
85 const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
86 QV4::ResolvedTypeReferenceMap *resolvedTypeCache,
87 const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
88
89 // --- interface used by QQmlPropertyCacheCreator
90 typedef QmlIR::Object CompiledObject;
91 const QmlIR::Object *objectAt(int index) const { return document->objects.at(i: index); }
92 int objectCount() const { return document->objects.count(); }
93 QString stringAt(int idx) const;
94 QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); }
95 QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); }
96 QV4::ResolvedTypeReferenceMap *resolvedTypes = nullptr;
97 // ---
98
99 QQmlRefPointer<QV4::ExecutableCompilationUnit> compile();
100
101 QList<QQmlError> compilationErrors() const { return errors; }
102 void recordError(const QV4::CompiledData::Location &location, const QString &description);
103 void recordError(const QQmlJS::DiagnosticMessage &message);
104 void recordError(const QQmlError &e);
105
106 int registerString(const QString &str);
107 int registerConstant(QV4::ReturnedValue v);
108
109 const QV4::CompiledData::Unit *qmlUnit() const;
110
111 QUrl url() const { return typeData->finalUrl(); }
112 QQmlEnginePrivate *enginePrivate() const { return engine; }
113 const QQmlImports *imports() const;
114 QVector<QmlIR::Object *> *qmlObjects() const;
115 void setPropertyCaches(QQmlPropertyCacheVector &&caches);
116 const QQmlPropertyCacheVector *propertyCaches() const;
117 QQmlPropertyCacheVector &&takePropertyCaches();
118 void setComponentRoots(const QVector<quint32> &roots) { m_componentRoots = roots; }
119 const QVector<quint32> &componentRoots() const { return m_componentRoots; }
120 QQmlJS::MemoryPool *memoryPool();
121 QStringRef newStringRef(const QString &string);
122 const QV4::Compiler::StringTableGenerator *stringPool() const;
123
124 const QHash<int, QQmlCustomParser*> &customParserCache() const { return customParsers; }
125
126 QString bindingAsString(const QmlIR::Object *object, int scriptIndex) const;
127
128 void addImport(const QString &module, const QString &qualifier, int majorVersion, int minorVersion);
129
130 QV4::ResolvedTypeReference *resolvedType(int id) const
131 {
132 return resolvedTypes->value(akey: id);
133 }
134
135 CompositeMetaTypeIds typeIdsForComponent(int objectId = 0) const;
136
137private:
138 QList<QQmlError> errors;
139 QQmlEnginePrivate *engine;
140 const QV4::CompiledData::DependentTypesHasher &dependencyHasher;
141 QmlIR::Document *document;
142 // index is string index of type name (use obj->inheritedTypeNameIndex)
143 QHash<int, QQmlCustomParser*> customParsers;
144
145 // index in first hash is component index, vector inside contains object indices of objects with id property
146 QVector<quint32> m_componentRoots;
147 QQmlPropertyCacheVector m_propertyCaches;
148
149 QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
150 QQmlTypeData *typeData;
151};
152
153struct QQmlCompilePass
154{
155 QQmlCompilePass(QQmlTypeCompiler *typeCompiler);
156
157 QString stringAt(int idx) const { return compiler->stringAt(idx); }
158protected:
159 void recordError(const QV4::CompiledData::Location &location, const QString &description) const
160 { compiler->recordError(location, description); }
161 void recordError(const QQmlError &error)
162 { compiler->recordError(e: error); }
163
164 QV4::ResolvedTypeReference *resolvedType(int id) const
165 { return compiler->resolvedType(id); }
166 bool containsResolvedType(int id) const
167 { return compiler->resolvedTypes->contains(akey: id); }
168 QV4::ResolvedTypeReferenceMap::iterator insertResolvedType(
169 int id, QV4::ResolvedTypeReference *value)
170 { return compiler->resolvedTypes->insert(akey: id, avalue: value); }
171
172 QQmlTypeCompiler *compiler;
173};
174
175// "Converts" signal expressions to full-fleged function declarations with
176// parameters taken from the signal declarations
177// It also updates the QV4::CompiledData::Binding objects to set the property name
178// to the final signal name (onTextChanged -> textChanged) and sets the IsSignalExpression flag.
179struct SignalHandlerConverter : public QQmlCompilePass
180{
181 Q_DECLARE_TR_FUNCTIONS(SignalHandlerConverter)
182public:
183 SignalHandlerConverter(QQmlTypeCompiler *typeCompiler);
184
185 bool convertSignalHandlerExpressionsToFunctionDeclarations();
186
187private:
188 bool convertSignalHandlerExpressionsToFunctionDeclarations(const QmlIR::Object *obj, const QString &typeName, QQmlPropertyCache *propertyCache);
189
190 QQmlEnginePrivate *enginePrivate;
191 const QVector<QmlIR::Object*> &qmlObjects;
192 const QQmlImports *imports;
193 const QHash<int, QQmlCustomParser*> &customParsers;
194 const QSet<QString> &illegalNames;
195 const QQmlPropertyCacheVector * const propertyCaches;
196};
197
198// ### This will go away when the codegen resolves all enums to constant expressions
199// and we replace the constant expression with a literal binding instead of using
200// a script.
201class QQmlEnumTypeResolver : public QQmlCompilePass
202{
203 Q_DECLARE_TR_FUNCTIONS(QQmlEnumTypeResolver)
204public:
205 QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler);
206
207 bool resolveEnumBindings();
208
209private:
210 bool assignEnumToBinding(QmlIR::Binding *binding, const QStringRef &enumName, int enumValue, bool isQtObject);
211 bool assignEnumToBinding(QmlIR::Binding *binding, const QString &enumName, int enumValue, bool isQtObject)
212 {
213 return assignEnumToBinding(binding, enumName: QStringRef(&enumName), enumValue, isQtObject);
214 }
215 bool tryQualifiedEnumAssignment(const QmlIR::Object *obj, const QQmlPropertyCache *propertyCache,
216 const QQmlPropertyData *prop,
217 QmlIR::Binding *binding);
218 int evaluateEnum(const QString &scope, const QStringRef &enumName, const QStringRef &enumValue, bool *ok) const;
219
220
221 const QVector<QmlIR::Object*> &qmlObjects;
222 const QQmlPropertyCacheVector * const propertyCaches;
223 const QQmlImports *imports;
224};
225
226class QQmlCustomParserScriptIndexer: public QQmlCompilePass
227{
228public:
229 QQmlCustomParserScriptIndexer(QQmlTypeCompiler *typeCompiler);
230
231 void annotateBindingsWithScriptStrings();
232
233private:
234 void scanObjectRecursively(int objectIndex, bool annotateScriptBindings = false);
235
236 const QVector<QmlIR::Object*> &qmlObjects;
237 const QHash<int, QQmlCustomParser*> &customParsers;
238};
239
240// Annotate properties bound to aliases with a flag
241class QQmlAliasAnnotator : public QQmlCompilePass
242{
243public:
244 QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler);
245
246 void annotateBindingsToAliases();
247private:
248 const QVector<QmlIR::Object*> &qmlObjects;
249 const QQmlPropertyCacheVector * const propertyCaches;
250};
251
252class QQmlScriptStringScanner : public QQmlCompilePass
253{
254public:
255 QQmlScriptStringScanner(QQmlTypeCompiler *typeCompiler);
256
257 void scan();
258
259private:
260 const QVector<QmlIR::Object*> &qmlObjects;
261 const QQmlPropertyCacheVector * const propertyCaches;
262};
263
264class QQmlComponentAndAliasResolver : public QQmlCompilePass
265{
266 Q_DECLARE_TR_FUNCTIONS(QQmlAnonymousComponentResolver)
267public:
268 QQmlComponentAndAliasResolver(QQmlTypeCompiler *typeCompiler);
269
270 bool resolve();
271
272protected:
273 void findAndRegisterImplicitComponents(const QmlIR::Object *obj, QQmlPropertyCache *propertyCache);
274 bool collectIdsAndAliases(int objectIndex);
275 bool resolveAliases(int componentIndex);
276 void propertyDataForAlias(QmlIR::Alias *alias, int *type, quint32 *propertyFlags);
277
278 enum AliasResolutionResult {
279 NoAliasResolved,
280 SomeAliasesResolved,
281 AllAliasesResolved
282 };
283
284 AliasResolutionResult resolveAliasesInObject(int objectIndex, QQmlError *error);
285
286 QQmlEnginePrivate *enginePrivate;
287 QQmlJS::MemoryPool *pool;
288
289 QVector<QmlIR::Object*> *qmlObjects;
290
291 // indices of the objects that are actually Component {}
292 QVector<quint32> componentRoots;
293
294 // Deliberate choice of map over hash here to ensure stable generated output.
295 QMap<int, int> _idToObjectIndex;
296 QVector<int> _objectsWithAliases;
297
298 QQmlPropertyCacheVector propertyCaches;
299};
300
301class QQmlDeferredAndCustomParserBindingScanner : public QQmlCompilePass
302{
303public:
304 QQmlDeferredAndCustomParserBindingScanner(QQmlTypeCompiler *typeCompiler);
305
306 bool scanObject();
307
308private:
309 bool scanObject(int objectIndex);
310
311 QVector<QmlIR::Object*> *qmlObjects;
312 const QQmlPropertyCacheVector * const propertyCaches;
313 const QHash<int, QQmlCustomParser*> &customParsers;
314
315 bool _seenObjectWithId;
316};
317
318class QQmlDefaultPropertyMerger : public QQmlCompilePass
319{
320public:
321 QQmlDefaultPropertyMerger(QQmlTypeCompiler *typeCompiler);
322
323 void mergeDefaultProperties();
324
325private:
326 void mergeDefaultProperties(int objectIndex);
327
328 const QVector<QmlIR::Object*> &qmlObjects;
329 const QQmlPropertyCacheVector * const propertyCaches;
330};
331
332QT_END_NAMESPACE
333
334#endif // QQMLTYPECOMPILER_P_H
335

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