1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QDECLARATIVEPROPERTYCACHE_P_H
43 #define QDECLARATIVEPROPERTYCACHE_P_H
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.
56 #include <private/qdeclarativerefcount_p.h>
57 #include "qdeclarativecleanup_p.h"
58 #include "qdeclarativenotifier_p.h"
60 #include <private/qhashedstring_p.h>
61 #include <QtCore/qvarlengtharray.h>
62 #include <QtCore/qvector.h>
68 class QV8QObjectWrapper;
69 class QDeclarativeEngine;
70 class QDeclarativePropertyData;
71 class QDeclarativeAccessors;
72 class QDeclarativePropertyCacheMethodArguments;
74 // We have this somewhat awful split between RawData and Data so that RawData can be
75 // used in unions. In normal code, you should always use Data which initializes RawData
76 // to an invalid state on construction.
77 class QDeclarativePropertyRawData
82 ValueTypeFlagMask = 0x0000FFFF, // Flags in valueTypeFlags must fit in this mask
84 // Can apply to all properties, except IsFunction
85 IsConstant = 0x00000001, // Has CONST flag
86 IsWritable = 0x00000002, // Has WRITE function
87 IsResettable = 0x00000004, // Has RESET function
88 IsAlias = 0x00000008, // Is a QML alias to another property
89 IsFinal = 0x00000010, // Has FINAL flag
90 IsDirect = 0x00000020, // Exists on a C++ QMetaObject
91 HasAccessors = 0x00000040, // Has property accessors
93 // These are mutualy exclusive
94 IsFunction = 0x00000080, // Is an invokable
95 IsQObjectDerived = 0x00000100, // Property type is a QObject* derived type
96 IsEnumType = 0x00000200, // Property type is an enum
97 IsQList = 0x00000400, // Property type is a QML list
98 IsQmlBinding = 0x00000800, // Property type is a QDeclarativeBinding*
99 IsQJSValue = 0x00001000, // Property type is a QScriptValue
100 IsV8Handle = 0x00002000, // Property type is a QDeclarativeV8Handle
101 IsVMEProperty = 0x00004000, // Property type is a "var" property of VMEMO
102 IsValueTypeVirtual = 0x00008000, // Property is a value type "virtual" property
103 IsQVariant = 0x00010000, // Property is a QVariant
105 // Apply only to IsFunctions
106 IsVMEFunction = 0x00020000, // Function was added by QML
107 HasArguments = 0x00040000, // Function takes arguments
108 IsSignal = 0x00080000, // Function is a signal
109 IsVMESignal = 0x00100000, // Signal was added by QML
110 IsV8Function = 0x00200000, // Function takes QDeclarativeV8Function* args
111 IsSignalHandler = 0x00400000, // Function is a signal handler
112 IsOverload = 0x00800000, // Function is an overload of another function
114 // Internal QDeclarativePropertyCache flags
115 NotFullyResolved = 0x01000000 // True if the type data is to be lazily resolved
117 Q_DECLARE_FLAGS(Flags, Flag)
119 Flags getFlags() const { return Flag(flags); }
120 void setFlags(Flags f) { flags = f; }
122 bool isValid() const { return coreIndex != -1; }
124 bool isConstant() const { return flags & IsConstant; }
125 bool isWritable() const { return flags & IsWritable; }
126 bool isResettable() const { return flags & IsResettable; }
127 bool isAlias() const { return flags & IsAlias; }
128 bool isFinal() const { return flags & IsFinal; }
129 bool isDirect() const { return flags & IsDirect; }
130 bool hasAccessors() const { return flags & HasAccessors; }
131 bool isFunction() const { return flags & IsFunction; }
132 bool isQObject() const { return flags & IsQObjectDerived; }
133 bool isEnum() const { return flags & IsEnumType; }
134 bool isQList() const { return flags & IsQList; }
135 bool isQmlBinding() const { return flags & IsQmlBinding; }
136 bool isQJSValue() const { return flags & IsQJSValue; }
137 bool isV8Handle() const { return flags & IsV8Handle; }
138 bool isVMEProperty() const { return flags & IsVMEProperty; }
139 bool isValueTypeVirtual() const { return flags & IsValueTypeVirtual; }
140 bool isQVariant() const { return flags & IsQVariant; }
141 bool isVMEFunction() const { return flags & IsVMEFunction; }
142 bool hasArguments() const { return flags & HasArguments; }
143 bool isSignal() const { return flags & IsSignal; }
144 bool isVMESignal() const { return flags & IsVMESignal; }
145 bool isV8Function() const { return flags & IsV8Function; }
146 bool isSignalHandler() const { return flags & IsSignalHandler; }
147 bool isOverload() const { return flags & IsOverload; }
149 bool hasOverride() const { return !(flags & IsValueTypeVirtual) &&
150 !(flags & HasAccessors) &&
151 overrideIndex >= 0; }
153 // Returns -1 if not a value type virtual property
154 inline int getValueTypeCoreIndex() const;
156 // Returns the "encoded" index for use with bindings. Encoding is:
157 // coreIndex | (valueTypeCoreIndex << 24)
158 inline int encodedIndex() const;
161 int propType; // When !NotFullyResolved
162 const char *propTypeName; // When NotFullyResolved
166 int notifyIndex; // When !IsFunction
167 void *arguments; // When IsFunction && HasArguments
171 struct { // When !HasAccessors
173 qint16 metaObjectOffset;
176 struct { // When IsValueTypeVirtual
177 quint16 valueTypeFlags; // flags of the access property on the value type proxy
179 quint8 valueTypePropType; // The QVariant::Type of access property on the value
181 quint8 valueTypeCoreIndex; // The prop index of the access property on the value
185 struct { // When !IsValueTypeVirtual
186 uint overrideIndexIsProperty : 1;
187 signed int overrideIndex : 31;
191 struct { // When HasAccessors
192 QDeclarativeAccessors *accessors;
193 intptr_t accessorData;
198 friend class QDeclarativePropertyData;
199 friend class QDeclarativePropertyCache;
202 Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyRawData::Flags);
204 class QDeclarativePropertyData : public QDeclarativePropertyRawData
207 inline QDeclarativePropertyData();
208 inline QDeclarativePropertyData(const QDeclarativePropertyRawData &);
210 inline bool operator==(const QDeclarativePropertyRawData &);
212 static Flags flagsForProperty(const QMetaProperty &, QDeclarativeEngine *engine = 0);
213 void load(const QMetaProperty &, QDeclarativeEngine *engine = 0);
214 void load(const QMetaMethod &);
215 QString name(QObject *);
216 QString name(const QMetaObject *);
219 friend class QDeclarativePropertyCache;
220 void lazyLoad(const QMetaProperty &, QDeclarativeEngine *engine = 0);
221 void lazyLoad(const QMetaMethod &);
222 bool notFullyResolved() const { return flags & NotFullyResolved; }
225 class Q_DECLARATIVE_EXPORT QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarativeCleanup
228 QDeclarativePropertyCache(QDeclarativeEngine *);
229 QDeclarativePropertyCache(QDeclarativeEngine *, const QMetaObject *);
230 virtual ~QDeclarativePropertyCache();
232 void update(QDeclarativeEngine *, const QMetaObject *);
234 QDeclarativePropertyCache *copy();
236 QDeclarativePropertyCache *copyAndAppend(QDeclarativeEngine *, const QMetaObject *,
237 QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags,
238 QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags,
239 QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags);
240 QDeclarativePropertyCache *copyAndAppend(QDeclarativeEngine *, const QMetaObject *, int revision,
241 QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags,
242 QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags,
243 QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags);
245 void append(QDeclarativeEngine *, const QMetaObject *,
246 QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags,
247 QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags,
248 QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags);
249 void append(QDeclarativeEngine *, const QMetaObject *, int revision,
250 QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags,
251 QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags,
252 QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags);
254 inline QDeclarativePropertyData *property(const QHashedV8String &) const;
255 QDeclarativePropertyData *property(const QHashedStringRef &) const;
256 QDeclarativePropertyData *property(const QHashedCStringRef &) const;
257 QDeclarativePropertyData *property(const QString &) const;
258 QDeclarativePropertyData *property(int) const;
259 QDeclarativePropertyData *method(int) const;
260 QStringList propertyNames() const;
262 inline QDeclarativePropertyData *overrideData(QDeclarativePropertyData *) const;
263 inline bool isAllowedInRevision(QDeclarativePropertyData *) const;
265 inline QDeclarativeEngine *qmlEngine() const;
266 static QDeclarativePropertyData *property(QDeclarativeEngine *, QObject *, const QString &,
267 QDeclarativePropertyData &);
268 static QDeclarativePropertyData *property(QDeclarativeEngine *, QObject *, const QHashedV8String &,
269 QDeclarativePropertyData &);
270 static int *methodParameterTypes(QObject *, int index, QVarLengthArray<int, 9> &dummy,
271 QByteArray *unknownTypeError);
273 static bool isDynamicMetaObject(const QMetaObject *);
275 virtual void destroy();
276 virtual void clear();
279 friend class QDeclarativeEnginePrivate;
280 friend class QV8QObjectWrapper;
282 inline QDeclarativePropertyCache *copy(int reserve);
284 // Implemented in v8/qv8qobjectwrapper.cpp
285 v8::Local<v8::Object> newQObject(QObject *, QV8Engine *);
287 typedef QVector<QDeclarativePropertyData> IndexCache;
288 typedef QStringHash<QDeclarativePropertyData *> StringCache;
289 typedef QVector<int> AllowedRevisionCache;
291 void resolve(QDeclarativePropertyData *) const;
292 void updateRecur(QDeclarativeEngine *, const QMetaObject *);
294 QDeclarativeEngine *engine;
296 QDeclarativePropertyCache *parent;
297 int propertyIndexCacheStart;
298 int methodIndexCacheStart;
299 int signalHanderIndexCacheStart;
301 IndexCache propertyIndexCache;
302 IndexCache methodIndexCache;
303 IndexCache signalHandlerIndexCache;
304 StringCache stringCache;
305 AllowedRevisionCache allowedRevisionCache;
306 v8::Persistent<v8::Function> constructor;
308 const QMetaObject *metaObject;
309 QDeclarativePropertyCacheMethodArguments *argumentsCache;
312 QDeclarativePropertyData::QDeclarativePropertyData()
317 overrideIndexIsProperty = false;
320 metaObjectOffset = -1;
324 QDeclarativePropertyData::QDeclarativePropertyData(const QDeclarativePropertyRawData &d)
326 *(static_cast<QDeclarativePropertyRawData *>(this)) = d;
329 bool QDeclarativePropertyData::operator==(const QDeclarativePropertyRawData &other)
331 return flags == other.flags &&
332 propType == other.propType &&
333 coreIndex == other.coreIndex &&
334 notifyIndex == other.notifyIndex &&
335 revision == other.revision &&
336 (!isValueTypeVirtual() ||
337 (valueTypeCoreIndex == other.valueTypeCoreIndex &&
338 valueTypePropType == other.valueTypePropType));
341 int QDeclarativePropertyRawData::getValueTypeCoreIndex() const
343 return isValueTypeVirtual()?valueTypeCoreIndex:-1;
346 int QDeclarativePropertyRawData::encodedIndex() const
348 return isValueTypeVirtual()?(coreIndex | (valueTypeCoreIndex << 24)):coreIndex;
351 QDeclarativePropertyData *
352 QDeclarativePropertyCache::overrideData(QDeclarativePropertyData *data) const
354 if (!data->hasOverride())
357 if (data->overrideIndexIsProperty)
358 return property(data->overrideIndex);
360 return method(data->overrideIndex);
363 bool QDeclarativePropertyCache::isAllowedInRevision(QDeclarativePropertyData *data) const
365 return (data->hasAccessors() || (data->metaObjectOffset == -1 && data->revision == 0)) ||
366 (allowedRevisionCache[data->metaObjectOffset] >= data->revision);
369 QDeclarativeEngine *QDeclarativePropertyCache::qmlEngine() const
374 QDeclarativePropertyData *QDeclarativePropertyCache::property(const QHashedV8String &str) const
376 QDeclarativePropertyData **rv = stringCache.value(str);
377 if (rv && (*rv)->notFullyResolved()) resolve(*rv);
383 #endif // QDECLARATIVEPROPERTYCACHE_P_H