Optimize default property resolution in compiler
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativeparser_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVEPARSER_P_H
43 #define QDECLARATIVEPARSER_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qdeclarative.h"
57
58 #include <QtCore/qbytearray.h>
59 #include <QtCore/qlist.h>
60 #include <QtCore/qurl.h>
61 #include <QtCore/qstring.h>
62 #include <QtCore/qstringlist.h>
63
64 #include <private/qobject_p.h>
65 #include <private/qdeclarativerefcount_p.h>
66 #include <private/qdeclarativeglobal_p.h>
67 #include <private/qdeclarativepool_p.h>
68 #include <private/qfieldlist_p.h>
69 #include <private/qdeclarativepropertycache_p.h>
70 #include <private/qfastmetabuilder_p.h>
71 #include <private/qhashedstring_p.h>
72 #include <private/qhashfield_p.h>
73
74 QT_BEGIN_HEADER
75
76 QT_BEGIN_NAMESPACE
77
78 QT_MODULE(Declarative)
79
80 class QDeclarativePropertyCache;
81 namespace QDeclarativeJS { namespace AST { class Node; class StringLiteral; } }
82 namespace QDeclarativeCompilerTypes { class BindingReference; class ComponentCompileState; }
83
84 /*
85     XXX
86
87     These types are created (and owned) by the QDeclarativeScriptParser and consumed by the 
88     QDeclarativeCompiler.  During the compilation phase the compiler will update some of
89     the fields for its own use.
90
91     The types are part of the generic sounding "QDeclarativeParser" namespace for legacy 
92     reasons (there used to be more in this namespace) and will be cleaned up and
93     migrated into a more appropriate location eventually.
94 */
95 namespace QDeclarativeParser
96 {
97     struct Location 
98     {
99         Location() : line(-1), column(-1) {}
100         int line;
101         int column;
102
103         inline bool operator<(const Location &other) {
104             return line < other.line || 
105                    (line == other.line && column < other.column);
106         }
107     };
108
109     struct LocationRange
110     {
111         LocationRange() : offset(0), length(0) {}
112         quint32 offset;
113         quint32 length;
114     };
115
116     struct LocationSpan
117     {
118         Location start;
119         Location end;
120         LocationRange range;
121
122         bool operator<(LocationSpan &o) const {
123             return (start.line < o.start.line) ||
124                    (start.line == o.start.line && start.column < o.start.column);
125         }
126     };
127
128     class Object;
129     class Property;
130     class Q_DECLARATIVE_EXPORT Variant 
131     {
132     public:
133         enum Type {
134             Invalid,
135             Boolean,
136             Number,
137             String,
138             Script
139         };
140
141         Variant();
142         Variant(const Variant &);
143         explicit Variant(bool);
144         explicit Variant(double, const QStringRef &asWritten = QStringRef());
145         explicit Variant(QDeclarativeJS::AST::StringLiteral *);
146         explicit Variant(const QStringRef &asWritten, QDeclarativeJS::AST::Node *);
147         Variant &operator=(const Variant &);
148
149         Type type() const;
150
151         bool isBoolean() const { return type() == Boolean; }
152         bool isNumber() const { return type() == Number; }
153         bool isString() const { return type() == String; }
154         bool isScript() const { return type() == Script; }
155         bool isStringList() const;
156
157         bool asBoolean() const;
158         QString asString() const;
159         double asNumber() const;
160         QString asScript() const;
161         QDeclarativeJS::AST::Node *asAST() const;
162         QStringList asStringList() const;
163
164     private:
165         Type t;
166         union {
167             bool b;
168             double d;
169             QDeclarativeJS::AST::StringLiteral *l;
170             QDeclarativeJS::AST::Node *n;
171         };
172         QStringRef asWritten;
173     };
174
175     class Value : public QDeclarativePool::POD
176     {
177     public:
178         Value();
179
180         enum Type {
181             // The type of this value assignment is not yet known
182             Unknown,
183             // This is used as a literal property assignment
184             Literal,
185             // This is used as a property binding assignment
186             PropertyBinding,
187             // This is used as a QDeclarativePropertyValueSource assignment
188             ValueSource,
189             // This is used as a QDeclarativePropertyValueInterceptor assignment
190             ValueInterceptor,
191             // This is used as a property QObject assignment
192             CreatedObject,
193             // This is used as a signal object assignment
194             SignalObject,
195             // This is used as a signal expression assignment
196             SignalExpression,
197             // This is used as an id assignment only
198             Id
199         };
200         Type type;
201
202         // ### Temporary (for id only)
203         QString primitive() const { return value.isString() ? value.asString() : value.asScript(); }
204
205         // Primitive value
206         Variant value;
207         // Object value
208         Object *object;
209
210         LocationSpan location;
211
212         // Used by compiler
213         QDeclarativeCompilerTypes::BindingReference *bindingReference;
214         int signalExpressionContextStack;
215
216         // Used in Property::ValueList lists
217         Value *nextValue;
218     };
219
220     class Property : public QDeclarativePool::POD
221     {
222     public:
223         Property();
224
225         // The Object to which this property is attached
226         Object *parent;
227
228         Object *getValue(const LocationSpan &);
229         void addValue(Value *v);
230         void addOnValue(Value *v);
231
232         // The QVariant::Type of the property, or 0 (QVariant::Invalid) if 
233         // unknown.
234         int type;
235         // The metaobject index of this property, or -1 if unknown.
236         int index;
237         // The core data in the case of a regular property.  
238         // XXX This has to be a value now as the synthCache may change during
239         // compilation which invalidates pointers.  We should fix this.
240         QDeclarativePropertyCache::Data core;
241
242         // Returns true if this is an empty property - both value and values
243         // are unset.
244         bool isEmpty() const;
245
246         typedef QFieldList<Value, &Value::nextValue> ValueList;
247         // The list of values assigned to this property.  Content in values
248         // and value are mutually exclusive
249         ValueList values;
250         // The list of values assigned to this property using the "on" syntax
251         ValueList onValues;
252         // The accessed property.  This is used to represent dot properties.
253         // Content in value and values are mutually exclusive.
254         Object *value;
255         // The property name
256         const QHashedStringRef &name() const { return _name; }
257         void setName(const QString &n) { _name = QHashedStringRef(pool()->NewString(n)); }
258         void setName(const QHashedStringRef &n) { _name = n; }
259         // True if this property was accessed as the default property.  
260         bool isDefault;
261         // True if the setting of this property will be deferred.  Set by the
262         // QDeclarativeCompiler
263         bool isDeferred;
264         // True if this property is a value-type pseudo-property
265         bool isValueTypeSubProperty;
266         // True if this property is a property alias.  Set by the 
267         // QDeclarativeCompiler
268         bool isAlias;
269
270         // Used for scriptStringProperties
271         int scriptStringScope;
272
273         LocationSpan location;
274         LocationRange listValueRange;
275
276         // Used in Object::MainPropertyList
277         Property *nextMainProperty;
278
279         // Used in Object::PropertyList lists
280         Property *nextProperty;
281
282     private:
283         friend class Object;
284         QHashedStringRef _name;
285     };
286
287     class Object : public QDeclarativePool::Class
288     {
289     public:
290         Object();
291         virtual ~Object(); 
292
293         // Type of the object.  The integer is an index into the 
294         // QDeclarativeCompiledData::types array, or -1 if the object is a property
295         // group.
296         int type;
297
298         // The fully-qualified name of this type
299         QByteArray typeName;
300         // The id assigned to the object (if any).  Set by the QDeclarativeCompiler
301         QString id;
302         // The id index assigned to the object (if any).  Set by the QDeclarativeCompiler
303         int idIndex;
304         // Custom parsed data
305         QByteArray custom;
306         // Bit mask of the properties assigned bindings
307         QByteArray bindingBitmask; 
308         void setBindingBit(int);
309         // Returns the metaobject for this type, or 0 if not available.  
310         // Internally selectd between the metatype and extObject variables
311         const QMetaObject *metaObject() const;
312
313         // The compile time metaobject for this type
314         const QMetaObject *metatype;
315         // The synthesized metaobject, if QML added signals or properties to
316         // this type.  Otherwise null
317         QAbstractDynamicMetaObject extObject;
318         QByteArray metadata; // Generated by compiler
319         QByteArray synthdata; // Generated by compiler
320         QDeclarativePropertyCache *synthCache; // Generated by compiler
321
322         Property *getDefaultProperty();
323         // name ptr must be guarenteed to remain valid
324         Property *getProperty(const QHashedStringRef &name, bool create=true);
325         Property *getProperty(const QStringRef &name, bool create=true);
326         Property *getProperty(const QString &name, bool create=true);
327
328         Property *defaultProperty;
329
330         typedef QFieldList<Property, &Property::nextMainProperty> MainPropertyList;
331         MainPropertyList properties;
332         QHashField propertiesHashField;
333
334         // Output of the compilation phase (these properties continue to exist
335         // in either the defaultProperty or properties members too)
336         void addValueProperty(Property *);
337         void addSignalProperty(Property *);
338         void addAttachedProperty(Property *);
339         void addGroupedProperty(Property *);
340         void addValueTypeProperty(Property *);
341         void addScriptStringProperty(Property *);
342
343         typedef QFieldList<Property, &Property::nextProperty> PropertyList;
344         PropertyList valueProperties;
345         PropertyList signalProperties;
346         PropertyList attachedProperties;
347         PropertyList groupedProperties;
348         PropertyList valueTypeProperties;
349         PropertyList scriptStringProperties;
350
351         // Script blocks that were nested under this object
352         struct ScriptBlock {
353             enum Pragma { 
354                 None   = 0x00000000,
355                 Shared = 0x00000001
356             };
357             Q_DECLARE_FLAGS(Pragmas, Pragma)
358
359             QString code;
360             QString file;
361             Pragmas pragmas;
362         };
363
364         // The bytes to cast instances by to get to the QDeclarativeParserStatus 
365         // interface.  -1 indicates the type doesn't support this interface.
366         // Set by the QDeclarativeCompiler.
367         int parserStatusCast;
368
369         LocationSpan location;
370
371         struct DynamicProperty : public QDeclarativePool::POD 
372         {
373             DynamicProperty();
374
375             enum Type { Variant, Int, Bool, Real, String, Url, Color, Time, 
376                         Date, DateTime, Alias, Custom, CustomList };
377
378             bool isDefaultProperty;
379             Type type;
380
381             QHashedStringRef customType;
382             QHashedStringRef name;
383             QDeclarativeParser::Property *defaultValue;
384             LocationSpan location;
385
386             // Used by Object::DynamicPropertyList
387             DynamicProperty *nextProperty;
388
389             // Used by the compiler
390             QByteArray *resolvedCustomTypeName;
391             QFastMetaBuilder::StringRef typeRef;
392             QFastMetaBuilder::StringRef nameRef;
393             QFastMetaBuilder::StringRef changedSignatureRef;
394         };
395
396         struct DynamicSignal : public QDeclarativePool::Class
397         {
398             DynamicSignal();
399
400             QHashedStringRef name;
401             QList<QHashedCStringRef> parameterTypes;
402             QList<QByteArray> parameterNames;
403
404             int parameterTypesLength() const;
405             int parameterNamesLength() const;
406
407             // Used by Object::DynamicSignalList
408             DynamicSignal *nextSignal;
409
410             // Used by the compiler
411             QFastMetaBuilder::StringRef signatureRef;
412             QFastMetaBuilder::StringRef parameterNamesRef;
413         };
414
415         struct DynamicSlot : public QDeclarativePool::Class
416         {
417             DynamicSlot();
418
419             QHashedStringRef name;
420             QString body;
421             QList<QByteArray> parameterNames;
422             LocationSpan location;
423
424             int parameterNamesLength() const;
425
426             // Used by Object::DynamicSlotList
427             DynamicSlot *nextSlot;
428
429             // Used by the compiler
430             QFastMetaBuilder::StringRef signatureRef;
431             QFastMetaBuilder::StringRef parameterNamesRef;
432         };
433
434         // The list of dynamic properties
435         typedef QFieldList<DynamicProperty, &DynamicProperty::nextProperty> DynamicPropertyList;
436         DynamicPropertyList dynamicProperties;
437         // The list of dynamic signals
438         typedef QFieldList<DynamicSignal, &DynamicSignal::nextSignal> DynamicSignalList;
439         DynamicSignalList dynamicSignals;
440         // The list of dynamic slots
441         typedef QFieldList<DynamicSlot, &DynamicSlot::nextSlot> DynamicSlotList;
442         DynamicSlotList dynamicSlots;
443
444         // Used by compiler
445         QDeclarativeCompilerTypes::ComponentCompileState *componentCompileState;
446
447         // Used by ComponentCompileState::AliasingObjectsList
448         Object *nextAliasingObject;
449         // Used by ComponentComppileState::IdList
450         Object *nextIdObject;
451     };
452
453 }
454
455 Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeParser::Object::ScriptBlock::Pragmas);
456
457 QT_END_NAMESPACE
458
459 Q_DECLARE_METATYPE(QDeclarativeParser::Variant)
460
461 QT_END_HEADER
462
463 #endif // QDECLARATIVEPARSER_P_H