[new compiler] Fix timing of property assignment error handling
[qt:qtdeclarative.git] / src / qml / compiler / qqmltypecompiler_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #ifndef QQMLTYPECOMPILER_P_H
42 #define QQMLTYPECOMPILER_P_H
43
44 #include <qglobal.h>
45 #include <qqmlerror.h>
46 #include <qhash.h>
47 #include <private/qqmlcompiler_p.h>
48
49 QT_BEGIN_NAMESPACE
50
51 class QQmlEnginePrivate;
52 class QQmlCompiledData;
53 class QQmlError;
54 class QQmlTypeData;
55 class QQmlImports;
56
57 namespace QtQml {
58 struct ParsedQML;
59 }
60
61 namespace QV4 {
62 namespace CompiledData {
63 struct QmlUnit;
64 struct Location;
65 }
66 }
67
68 struct QQmlTypeCompiler
69 {
70     Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
71 public:
72     QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlCompiledData *compiledData, QQmlTypeData *typeData, QtQml::ParsedQML *parsedQML);
73
74     bool compile();
75
76     QList<QQmlError> compilationErrors() const { return errors; }
77     void recordError(const QQmlError &error);
78
79     QString stringAt(int idx) const;
80     int registerString(const QString &str);
81
82     const QV4::CompiledData::QmlUnit *qmlUnit() const;
83
84     QQmlEnginePrivate *enginePrivate() const { return engine; }
85     const QQmlImports *imports() const;
86     QHash<int, QQmlCompiledData::TypeReference *> *resolvedTypes();
87     QList<QtQml::QmlObject*> *qmlObjects();
88     int rootObjectIndex() const;
89     void setPropertyCaches(const QVector<QQmlPropertyCache *> &caches);
90     const QVector<QQmlPropertyCache *> &propertyCaches() const;
91     void setVMEMetaObjects(const QVector<QByteArray> &metaObjects);
92     QVector<QByteArray> *vmeMetaObjects() const;
93     QHash<int, int> *objectIndexToIdForRoot();
94     QHash<int, QHash<int, int> > *objectIndexToIdPerComponent();
95     QHash<int, QByteArray> *customParserData();
96     QQmlJS::MemoryPool *memoryPool();
97     const QList<CompiledFunctionOrExpression> &functions() const;
98     void setCustomParserBindings(const QVector<int> &bindings);
99
100 private:
101     QList<QQmlError> errors;
102     QQmlEnginePrivate *engine;
103     QQmlCompiledData *compiledData;
104     QQmlTypeData *typeData;
105     QtQml::ParsedQML *parsedQML;
106 };
107
108 struct QQmlCompilePass
109 {
110     virtual ~QQmlCompilePass() {}
111
112     QQmlCompilePass(QQmlTypeCompiler *typeCompiler);
113
114     QString stringAt(int idx) const { return compiler->stringAt(idx); }
115 protected:
116     void recordError(const QV4::CompiledData::Location &location, const QString &description);
117
118     QQmlTypeCompiler *compiler;
119 };
120
121 class QQmlPropertyCacheCreator : public QQmlCompilePass
122 {
123     Q_DECLARE_TR_FUNCTIONS(QQmlPropertyCacheCreator)
124 public:
125     QQmlPropertyCacheCreator(QQmlTypeCompiler *typeCompiler);
126     ~QQmlPropertyCacheCreator();
127
128     bool buildMetaObjects();
129 protected:
130     bool buildMetaObjectRecursively(int objectIndex, int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding);
131     bool ensureMetaObject(int objectIndex);
132     bool createMetaObject(int objectIndex, const QtQml::QmlObject *obj, QQmlPropertyCache *baseTypeCache);
133
134     QQmlEnginePrivate *enginePrivate;
135     const QList<QtQml::QmlObject*> &qmlObjects;
136     const QQmlImports *imports;
137     QHash<int, QQmlCompiledData::TypeReference*> *resolvedTypes;
138     QVector<QByteArray> vmeMetaObjects;
139     QVector<QQmlPropertyCache*> propertyCaches;
140 };
141
142 class QQmlComponentAndAliasResolver : public QQmlCompilePass
143 {
144     Q_DECLARE_TR_FUNCTIONS(QQmlAnonymousComponentResolver)
145 public:
146     QQmlComponentAndAliasResolver(QQmlTypeCompiler *typeCompiler);
147
148     bool resolve();
149
150 protected:
151     void findAndRegisterImplicitComponents(const QtQml::QmlObject *obj, int objectIndex);
152     bool collectIdsAndAliases(int objectIndex);
153     bool resolveAliases();
154
155     QQmlEnginePrivate *enginePrivate;
156     QQmlJS::MemoryPool *pool;
157
158     QList<QtQml::QmlObject*> *qmlObjects;
159     const int indexOfRootObject;
160
161     // indices of the objects that are actually Component {}
162     QVector<int> componentRoots;
163     // indices of objects that are the beginning of a new component
164     // scope. This is sorted and used for binary search.
165     QVector<int> componentBoundaries;
166
167     int _componentIndex;
168     QHash<int, int> _idToObjectIndex;
169     QHash<int, int> *_objectIndexToIdInScope;
170     QList<int> _objectsWithAliases;
171
172     QHash<int, QQmlCompiledData::TypeReference*> *resolvedTypes;
173     const QVector<QQmlPropertyCache *> propertyCaches;
174     QVector<QByteArray> *vmeMetaObjectData;
175     QHash<int, int> *objectIndexToIdForRoot;
176     QHash<int, QHash<int, int> > *objectIndexToIdPerComponent;
177 };
178
179 class QQmlPropertyValidator : public QQmlCompilePass, public QQmlCustomParserCompilerBackend
180 {
181     Q_DECLARE_TR_FUNCTIONS(QQmlPropertyValidator)
182 public:
183     QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler, const QVector<int> &runtimeFunctionIndices);
184
185     bool validate();
186
187     // Re-implemented for QQmlCustomParser
188     virtual const QQmlImports &imports() const;
189     virtual QQmlJS::AST::Node *astForBinding(int scriptIndex) const;
190     virtual QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *binding, QQmlCustomParser *parser);
191
192 private:
193     bool validateObject(int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding);
194     bool validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
195     bool validateObjectBinding(QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
196
197     bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); }
198
199     QQmlEnginePrivate *enginePrivate;
200     const QV4::CompiledData::QmlUnit *qmlUnit;
201     const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes;
202     const QVector<QQmlPropertyCache *> &propertyCaches;
203     const QHash<int, QHash<int, int> > objectIndexToIdPerComponent;
204     QHash<int, QByteArray> *customParserData;
205     QVector<int> customParserBindings;
206     const QVector<int> &runtimeFunctionIndices;
207 };
208
209 QT_END_NAMESPACE
210
211 #endif // QQMLTYPECOMPILER_P_H