#include "qqmlpropertycache_p.h"
-#include "qqmlengine_p.h"
-#include "qqmlbinding_p.h"
+#include <private/qqmlengine_p.h>
+#include <private/qqmlbinding_p.h>
+#include <private/qqmlvmemetaobject_p.h>
#include <private/qv8engine_p.h>
#include <private/qmetaobject_p.h>
#include <private/qqmlaccessors_p.h>
#include <private/qmetaobjectbuilder_p.h>
+#include <private/qqmlrewrite_p.h>
#include <QtCore/qdebug.h>
#include <ctype.h> // for toupper
+#include <limits.h>
#ifdef Q_CC_MSVC
// nonstandard extension used : zero-sized array in struct/union.
#define Q_INT16_MAX 32767
-class QQmlPropertyCacheMethodArguments
+class QQmlPropertyCacheMethodArguments
{
public:
QQmlPropertyCacheMethodArguments *next;
+ //for signal handler rewrites
+ QString *signalParameterStringForJS;
+ int signalParameterCountForJS:30;
+ int parameterError:1;
+ int argumentsValid:1;
+
QList<QByteArray> *names;
int arguments[0];
};
return flags;
}
-// Flags that do depend on the property's QMetaProperty::userType() and thus are slow to
+// Flags that do depend on the property's QMetaProperty::userType() and thus are slow to
// load
static QQmlPropertyData::Flags flagsForPropertyType(int propType, QQmlEngine *engine)
{
QQmlPropertyData::Flags flags;
- if (propType == QMetaType::QObjectStar || propType == QMetaType::QWidgetStar) {
+ if (propType == QMetaType::QObjectStar) {
flags |= QQmlPropertyData::IsQObjectDerived;
} else if (propType == QMetaType::QVariant) {
flags |= QQmlPropertyData::IsQVariant;
} else if (propType == qMetaTypeId<QQmlV8Handle>()) {
flags |= QQmlPropertyData::IsV8Handle;
} else {
- QQmlMetaType::TypeCategory cat =
+ QQmlMetaType::TypeCategory cat =
engine ? QQmlEnginePrivate::get(engine)->typeCategory(propType)
: QQmlMetaType::typeCategory(propType);
flags = fastFlagsForProperty(p);
int type = p.type();
- if (type == QMetaType::QObjectStar || type == QMetaType::QWidgetStar) {
+ if (type == QMetaType::QObjectStar) {
propType = type;
flags |= QQmlPropertyData::IsQObjectDerived;
} else if (type == QMetaType::QVariant) {
*/
QQmlPropertyCache::QQmlPropertyCache(QQmlEngine *e)
: engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
- signalHandlerIndexCacheStart(0), _ownMetaObject(false), _metaObject(0), argumentsCache(0)
+ signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false),
+ _metaObject(0), argumentsCache(0)
{
Q_ASSERT(engine);
}
*/
QQmlPropertyCache::QQmlPropertyCache(QQmlEngine *e, const QMetaObject *metaObject)
: engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
- signalHandlerIndexCacheStart(0), _ownMetaObject(false), _metaObject(0), argumentsCache(0)
+ signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false),
+ _metaObject(0), argumentsCache(0)
{
Q_ASSERT(engine);
Q_ASSERT(metaObject);
QQmlPropertyCacheMethodArguments *args = argumentsCache;
while (args) {
QQmlPropertyCacheMethodArguments *next = args->next;
+ if (args->signalParameterStringForJS) delete args->signalParameterStringForJS;
if (args->names) delete args->names;
free(args);
args = next;
data.notifyIndex = notifyIndex;
data.flags = flags;
- QHashedString string(name);
- if (QQmlPropertyData **old = stringCache.value(string)) {
- data.overrideIndexIsProperty = !(*old)->isFunction();
- data.overrideIndex = (*old)->coreIndex;
- (*old)->flags |= QQmlPropertyData::IsOverridden;
- }
+ QQmlPropertyData *old = findNamedProperty(name);
+ if (old)
+ data.markAsOverrideOf(old);
+ int index = propertyIndexCache.count();
propertyIndexCache.append(data);
- stringCache.insert(string, propertyIndexCache.data() + propertyIndexCache.count() - 1);
+ setNamedProperty(name, index + propertyOffset(), propertyIndexCache.data() + index, (old != 0));
}
void QQmlPropertyCache::appendProperty(const QHashedCStringRef &name,
data.notifyIndex = notifyIndex;
data.flags = flags;
- if (QQmlPropertyData **old = stringCache.value(name)) {
- data.overrideIndexIsProperty = !(*old)->isFunction();
- data.overrideIndex = (*old)->coreIndex;
- (*old)->flags |= QQmlPropertyData::IsOverridden;
- }
+ QQmlPropertyData *old = findNamedProperty(name);
+ if (old)
+ data.markAsOverrideOf(old);
+ int index = propertyIndexCache.count();
propertyIndexCache.append(data);
- stringCache.insert(name, propertyIndexCache.data() + propertyIndexCache.count() - 1);
+ setNamedProperty(name, index + propertyOffset(), propertyIndexCache.data() + index, (old != 0));
}
void QQmlPropertyCache::appendSignal(const QString &name, quint32 flags, int coreIndex,
typedef QQmlPropertyCacheMethodArguments A;
A *args = static_cast<A *>(malloc(sizeof(A) + (argumentCount + 1) * sizeof(int)));
::memcpy(args->arguments, types, (argumentCount + 1) * sizeof(int));
+ args->argumentsValid = true;
+ args->signalParameterStringForJS = 0;
+ args->signalParameterCountForJS = 0;
+ args->parameterError = false;
args->names = new QList<QByteArray>(names);
args->next = argumentsCache;
argumentsCache = args;
data.arguments = args;
}
- QString handlerName = QLatin1String("on") + name;
- handlerName[2] = handlerName[2].toUpper();
-
- QHashedString string(name);
- if (QQmlPropertyData **old = stringCache.value(string)) {
- data.overrideIndexIsProperty = !(*old)->isFunction();
- data.overrideIndex = (*old)->coreIndex;
- (*old)->flags |= QQmlPropertyData::IsOverridden;
- }
+ QQmlPropertyData *old = findNamedProperty(name);
+ if (old)
+ data.markAsOverrideOf(old);
+ int methodIndex = methodIndexCache.count();
methodIndexCache.append(data);
+
+ int signalHandlerIndex = signalHandlerIndexCache.count();
signalHandlerIndexCache.append(handler);
- stringCache.insert(string, methodIndexCache.data() + methodIndexCache.count() - 1);
- stringCache.insert(handlerName, signalHandlerIndexCache.data() + signalHandlerIndexCache.count() - 1);
+ QString handlerName = QLatin1String("on") + name;
+ handlerName[2] = handlerName[2].toUpper();
+
+ setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != 0));
+ setNamedProperty(handlerName, signalHandlerIndex + signalOffset(), signalHandlerIndexCache.data() + signalHandlerIndex, (old != 0));
}
void QQmlPropertyCache::appendSignal(const QHashedCStringRef &name, quint32 flags, int coreIndex,
typedef QQmlPropertyCacheMethodArguments A;
A *args = static_cast<A *>(malloc(sizeof(A) + (argumentCount + 1) * sizeof(int)));
::memcpy(args->arguments, types, (argumentCount + 1) * sizeof(int));
+ args->argumentsValid = true;
+ args->signalParameterStringForJS = 0;
+ args->signalParameterCountForJS = 0;
+ args->parameterError = false;
args->names = new QList<QByteArray>(names);
args->next = argumentsCache;
argumentsCache = args;
data.arguments = args;
}
- QString handlerName = QLatin1String("on") + name.toUtf16();
- handlerName[2] = handlerName[2].toUpper();
-
- if (QQmlPropertyData **old = stringCache.value(name)) {
- data.overrideIndexIsProperty = !(*old)->isFunction();
- data.overrideIndex = (*old)->coreIndex;
- (*old)->flags |= QQmlPropertyData::IsOverridden;
- }
+ QQmlPropertyData *old = findNamedProperty(name);
+ if (old)
+ data.markAsOverrideOf(old);
+ int methodIndex = methodIndexCache.count();
methodIndexCache.append(data);
+
+ int signalHandlerIndex = signalHandlerIndexCache.count();
signalHandlerIndexCache.append(handler);
- stringCache.insert(name, methodIndexCache.data() + methodIndexCache.count() - 1);
- stringCache.insert(handlerName, signalHandlerIndexCache.data() + signalHandlerIndexCache.count() - 1);
+ QString handlerName = QLatin1String("on") + name.toUtf16();
+ handlerName[2] = handlerName[2].toUpper();
+
+ setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != 0));
+ setNamedProperty(handlerName, signalHandlerIndex + signalOffset(), signalHandlerIndexCache.data() + signalHandlerIndex, (old != 0));
}
void QQmlPropertyCache::appendMethod(const QString &name, quint32 flags, int coreIndex,
args->arguments[0] = argumentCount;
for (int ii = 0; ii < argumentCount; ++ii)
args->arguments[ii + 1] = QMetaType::QVariant;
+ args->argumentsValid = true;
+ args->signalParameterStringForJS = 0;
+ args->signalParameterCountForJS = 0;
+ args->parameterError = false;
args->names = 0;
if (argumentCount)
args->names = new QList<QByteArray>(names);
data.flags = flags;
- QHashedString string(name);
- if (QQmlPropertyData **old = stringCache.value(string)) {
- data.overrideIndexIsProperty = !(*old)->isFunction();
- data.overrideIndex = (*old)->coreIndex;
- (*old)->flags |= QQmlPropertyData::IsOverridden;
- }
+ QQmlPropertyData *old = findNamedProperty(name);
+ if (old)
+ data.markAsOverrideOf(old);
+ int methodIndex = methodIndexCache.count();
methodIndexCache.append(data);
- stringCache.insert(string, methodIndexCache.data() + methodIndexCache.count() - 1);
+ setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != 0));
}
void QQmlPropertyCache::appendMethod(const QHashedCStringRef &name, quint32 flags, int coreIndex,
args->arguments[0] = argumentCount;
for (int ii = 0; ii < argumentCount; ++ii)
args->arguments[ii + 1] = QMetaType::QVariant;
+ args->argumentsValid = true;
+ args->signalParameterStringForJS = 0;
+ args->signalParameterCountForJS = 0;
+ args->parameterError = false;
args->names = 0;
if (argumentCount)
args->names = new QList<QByteArray>(names);
data.flags = flags;
- if (QQmlPropertyData **old = stringCache.value(name)) {
- data.overrideIndexIsProperty = !(*old)->isFunction();
- data.overrideIndex = (*old)->coreIndex;
- (*old)->flags |= QQmlPropertyData::IsOverridden;
- }
+ QQmlPropertyData *old = findNamedProperty(name);
+ if (old)
+ data.markAsOverrideOf(old);
+ int methodIndex = methodIndexCache.count();
methodIndexCache.append(data);
- stringCache.insert(name, methodIndexCache.data() + methodIndexCache.count() - 1);
+ setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != 0));
}
// Returns this property cache's metaObject. May be null if it hasn't been created yet.
QQmlPropertyData *QQmlPropertyCache::defaultProperty() const
{
- return property(defaultPropertyName());
+ return property(defaultPropertyName(), 0, 0);
}
QQmlPropertyCache *QQmlPropertyCache::parent() const
return rv;
}
-void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject,
- int revision,
+void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject,
+ int revision,
QQmlPropertyData::Flag propertyFlags,
QQmlPropertyData::Flag methodFlags,
QQmlPropertyData::Flag signalFlags)
if (ii == destroyedIdx1 || ii == destroyedIdx2 || ii == deleteLaterIdx)
continue;
QMetaMethod m = metaObject->method(ii);
- if (m.access() == QMetaMethod::Private)
+ if (m.access() == QMetaMethod::Private)
continue;
// Extract method name
if (utf8) {
QHashedString methodName(QString::fromUtf8(rawName, cptr - rawName));
- if (QQmlPropertyData **it = stringCache.value(methodName))
- old = *it;
- stringCache.insert(methodName, data);
+ if (StringCache::mapped_type *it = stringCache.value(methodName))
+ old = it->second;
+ setNamedProperty(methodName, ii, data, (old != 0));
if (data->isSignal()) {
QHashedString on(QStringLiteral("on") % methodName.at(0).toUpper() % methodName.midRef(1));
- stringCache.insert(on, sigdata);
+ setNamedProperty(on, ii, sigdata, (old != 0));
++signalHandlerIndex;
}
} else {
QHashedCStringRef methodName(rawName, cptr - rawName);
- if (QQmlPropertyData **it = stringCache.value(methodName))
- old = *it;
- stringCache.insert(methodName, data);
+ if (StringCache::mapped_type *it = stringCache.value(methodName))
+ old = it->second;
+ setNamedProperty(methodName, ii, data, (old != 0));
if (data->isSignal()) {
int length = methodName.length();
str[length + 2] = '\0';
QHashedString on(QString::fromLatin1(str.data()));
- stringCache.insert(on, sigdata);
+ setNamedProperty(on, ii, data, (old != 0));
++signalHandlerIndex;
}
}
// We only overload methods in the same class, exactly like C++
if (old->isFunction() && old->coreIndex >= methodOffset)
data->flags |= QQmlPropertyData::IsOverload;
- data->overrideIndexIsProperty = !old->isFunction();
- data->overrideIndex = old->coreIndex;
- old->flags |= QQmlPropertyData::IsOverridden;
+
+ data->markAsOverrideOf(old);
}
}
data->lazyLoad(p, engine);
data->flags |= propertyFlags;
- if (!dynamicMetaObject)
+ if (!dynamicMetaObject)
data->flags |= QQmlPropertyData::IsDirect;
Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
if (utf8) {
QHashedString propName(QString::fromUtf8(str, cptr - str));
- if (QQmlPropertyData **it = stringCache.value(propName))
- old = *it;
- stringCache.insert(propName, data);
+ if (StringCache::mapped_type *it = stringCache.value(propName))
+ old = it->second;
+ setNamedProperty(propName, ii, data, (old != 0));
} else {
QHashedCStringRef propName(str, cptr - str);
- if (QQmlPropertyData **it = stringCache.value(propName))
- old = *it;
- stringCache.insert(propName, data);
+ if (StringCache::mapped_type *it = stringCache.value(propName))
+ old = it->second;
+ setNamedProperty(propName, ii, data, (old != 0));
}
QQmlAccessorProperties::Property *accessorProperty = accessorProperties.property(str);
data->accessors = accessorProperty->accessors;
data->accessorData = accessorProperty->data;
} else if (old) {
- data->overrideIndexIsProperty = !old->isFunction();
- data->overrideIndex = old->coreIndex;
- old->flags |= QQmlPropertyData::IsOverridden;
+ data->markAsOverrideOf(old);
}
}
}
+QQmlPropertyData *QQmlPropertyCache::ensureResolved(QQmlPropertyData *p) const
+{
+ if (p && p->notFullyResolved())
+ resolve(p);
+
+ return p;
+}
+
void QQmlPropertyCache::resolve(QQmlPropertyData *data) const
{
Q_ASSERT(data->notFullyResolved());
This is different from QMetaMethod::methodIndex().
*/
QQmlPropertyData *
-QQmlPropertyCache::signal(int index) const
+QQmlPropertyCache::signal(int index, QQmlPropertyCache **c) const
{
if (index < 0 || index >= (signalHandlerIndexCacheStart + signalHandlerIndexCache.count()))
return 0;
if (index < signalHandlerIndexCacheStart)
- return _parent->signal(index);
+ return _parent->signal(index, c);
QQmlPropertyData *rv = const_cast<QQmlPropertyData *>(&methodIndexCache.at(index - signalHandlerIndexCacheStart));
if (rv->notFullyResolved()) resolve(rv);
Q_ASSERT(rv->isSignal() || rv->coreIndex == -1);
+ if (c) *c = const_cast<QQmlPropertyCache *>(this);
return rv;
}
{
if (index < 0 || index >= (propertyIndexCacheStart + propertyIndexCache.count()))
return 0;
-
+
if (index < propertyIndexCacheStart)
return _parent->property(index);
QQmlPropertyData *rv = const_cast<QQmlPropertyData *>(&propertyIndexCache.at(index - propertyIndexCacheStart));
- if (rv->notFullyResolved()) resolve(rv);
- return rv;
+ return ensureResolved(rv);
}
QQmlPropertyData *
return _parent->method(index);
QQmlPropertyData *rv = const_cast<QQmlPropertyData *>(&methodIndexCache.at(index - methodIndexCacheStart));
- if (rv->notFullyResolved()) resolve(rv);
- return rv;
+ return ensureResolved(rv);
}
-QQmlPropertyData *
-QQmlPropertyCache::property(const QHashedStringRef &str) const
+QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it, QObject *object, QQmlContextData *context) const
{
- QQmlPropertyData **rv = stringCache.value(str);
- if (rv && (*rv)->notFullyResolved()) resolve(*rv);
- return rv?*rv:0;
+ QQmlData *data = (object ? QQmlData::get(object) : 0);
+ const QQmlVMEMetaObject *vmemo = (data && data->hasVMEMetaObject ? static_cast<const QQmlVMEMetaObject *>(object->metaObject()) : 0);
+ return findProperty(it, vmemo, context);
}
-QQmlPropertyData *
-QQmlPropertyCache::property(const QHashedCStringRef &str) const
+namespace {
+
+inline bool contextHasNoExtensions(QQmlContextData *context)
{
- QQmlPropertyData **rv = stringCache.value(str);
- if (rv && (*rv)->notFullyResolved()) resolve(*rv);
- return rv?*rv:0;
+ // This context has no extension if its parent is the engine's rootContext,
+ // which has children but no imports
+ return (!context->parent || !context->parent->imports);
}
-QQmlPropertyData *
-QQmlPropertyCache::property(const QString &str) const
+inline int maximumIndexForProperty(QQmlPropertyData *prop, const QQmlVMEMetaObject *vmemo)
+{
+ return (prop->isFunction() ? vmemo->methodCount()
+ : prop->isSignalHandler() ? vmemo->signalCount()
+ : vmemo->propertyCount());
+}
+
+}
+
+QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *vmemo, QQmlContextData *context) const
{
- QQmlPropertyData **rv = stringCache.value(str);
- if (rv && (*rv)->notFullyResolved()) resolve(*rv);
- return rv?*rv:0;
+ StringCache::ConstIterator end = stringCache.end();
+
+ if (it != end) {
+ if (vmemo && context && !contextHasNoExtensions(context)) {
+ // Find the highest property offset known to the supplied context
+ do {
+ if (vmemo->ctxt == context)
+ break;
+
+ vmemo = vmemo->parentVMEMetaObject();
+ } while (vmemo);
+ }
+
+ do {
+ // Is this property available to this context?
+ const StringCache::mapped_type &property(it.value());
+ if (!vmemo || (property.first < maximumIndexForProperty(property.second, vmemo)))
+ return ensureResolved(property.second);
+
+ it = stringCache.findNext(it);
+ } while (it != end);
+ }
+
+ return 0;
}
QString QQmlPropertyData::name(QObject *object)
}
}
+void QQmlPropertyData::markAsOverrideOf(QQmlPropertyData *predecessor)
+{
+ overrideIndexIsProperty = !predecessor->isFunction();
+ overrideIndex = predecessor->coreIndex;
+
+ predecessor->flags |= QQmlPropertyData::IsOverridden;
+}
+
QStringList QQmlPropertyCache::propertyNames() const
{
QStringList keys;
- for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter)
+ for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter)
keys.append(iter.key());
return keys;
}
if (scopeIdx != -1) {
scope = str.left(scopeIdx);
name = str.mid(scopeIdx + 2);
- } else {
+ } else {
name = str;
}
const QMetaObject *meta;
\a index MUST be in the signal index range (see QObjectPrivate::signalIndex()).
This is different from QMetaMethod::methodIndex().
*/
-QList<QByteArray> QQmlPropertyCache::signalParameterNames(QObject *object, int index)
+QString QQmlPropertyCache::signalParameterStringForJS(int index, int *count, QString *errorString)
{
- QQmlData *data = QQmlData::get(object, false);
- if (data->propertyCache) {
- QQmlPropertyData *p = data->propertyCache->signal(index);
- if (!p->hasArguments())
- return QList<QByteArray>();
+ QQmlPropertyCache *c = 0;
+ QQmlPropertyData *signalData = signal(index, &c);
+ if (!signalData)
+ return QString();
+
+ typedef QQmlPropertyCacheMethodArguments A;
+
+ if (signalData->arguments) {
+ A *arguments = static_cast<A *>(signalData->arguments);
+ if (arguments->signalParameterStringForJS) {
+ if (count)
+ *count = arguments->signalParameterCountForJS;
+ if (arguments->parameterError) {
+ if (errorString)
+ *errorString = *arguments->signalParameterStringForJS;
+ return QString();
+ }
+ return *arguments->signalParameterStringForJS;
+ }
+ }
+
+ QList<QByteArray> parameterNameList = signalParameterNames(index);
+
+ if (!signalData->arguments) {
+ int argc = parameterNameList.count();
+ A *args = static_cast<A *>(malloc(sizeof(A) + (argc + 1) * sizeof(int)));
+ args->arguments[0] = argc;
+ args->argumentsValid = false;
+ args->signalParameterStringForJS = 0;
+ args->signalParameterCountForJS = 0;
+ args->parameterError = false;
+ args->names = new QList<QByteArray>(parameterNameList);
+ signalData->arguments = args;
+ args->next = c->argumentsCache;
+ c->argumentsCache = args;
}
- return QMetaObjectPrivate::signal(object->metaObject(), index).parameterNames();
+ QQmlRewrite::RewriteSignalHandler rewriter;
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
+ const QString ¶meters = rewriter.createParameterString(parameterNameList,
+ ep->v8engine()->illegalNames());
+
+ bool error = rewriter.hasParameterError();
+ A *arguments = static_cast<A *>(signalData->arguments);
+ arguments->signalParameterStringForJS = new QString(error ? rewriter.parameterError() : parameters);
+ arguments->signalParameterCountForJS = rewriter.parameterCountForJS();
+ if (count)
+ *count = arguments->signalParameterCountForJS;
+ if (error) {
+ arguments->parameterError = true;
+ if (errorString)
+ *errorString = *arguments->signalParameterStringForJS;
+ return QString();
+ }
+ return *arguments->signalParameterStringForJS;
}
// Returns an array of the arguments for method \a index. The first entry in the array
// is the number of arguments.
-int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index,
+int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index,
QVarLengthArray<int, 9> &dummy,
QByteArray *unknownTypeError)
{
QQmlPropertyData *rv = const_cast<QQmlPropertyData *>(&c->methodIndexCache.at(index - c->methodIndexCacheStart));
- if (rv->arguments)
+ if (rv->arguments && static_cast<A *>(rv->arguments)->argumentsValid)
return static_cast<A *>(rv->arguments)->arguments;
const QMetaObject *metaObject = c->createMetaObject();
QMetaMethod m = metaObject->method(index);
int argc = m.parameterCount();
- A *args = static_cast<A *>(malloc(sizeof(A) + (argc + 1) * sizeof(int)));
- args->arguments[0] = argc;
- args->names = 0;
+ if (!rv->arguments) {
+ A *args = static_cast<A *>(malloc(sizeof(A) + (argc + 1) * sizeof(int)));
+ args->arguments[0] = argc;
+ args->argumentsValid = false;
+ args->signalParameterStringForJS = 0;
+ args->signalParameterCountForJS = 0;
+ args->parameterError = false;
+ args->names = 0;
+ rv->arguments = args;
+ args->next = c->argumentsCache;
+ c->argumentsCache = args;
+ }
+ A *args = static_cast<A *>(rv->arguments);
+
QList<QByteArray> argTypeNames; // Only loaded if needed
for (int ii = 0; ii < argc; ++ii) {
}
if (type == QMetaType::UnknownType) {
if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
- free(args);
return 0;
}
args->arguments[ii + 1] = type;
}
-
- rv->arguments = args;
- args->next = c->argumentsCache;
- c->argumentsCache = args;
+ args->argumentsValid = true;
return static_cast<A *>(rv->arguments)->arguments;
} else {
return type;
}
+int QQmlPropertyCache::originalClone(int index)
+{
+ while (signal(index)->isCloned())
+ --index;
+ return index;
+}
+
+int QQmlPropertyCache::originalClone(QObject *object, int index)
+{
+ QQmlData *data = QQmlData::get(object, false);
+ if (data && data->propertyCache) {
+ QQmlPropertyCache *cache = data->propertyCache;
+ while (cache->signal(index)->isCloned())
+ --index;
+ } else {
+ while (QMetaObjectPrivate::signal(object->metaObject(), index).attributes() & QMetaMethod::Cloned)
+ --index;
+ }
+ return index;
+}
+
QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, const QString &property)
{
Q_ASSERT(metaObject);
template<typename T>
QQmlPropertyData *
-qQmlPropertyCacheProperty(QQmlEngine *engine, QObject *obj, const T &name, QQmlPropertyData &local)
+qQmlPropertyCacheProperty(QQmlEngine *engine, QObject *obj, const T &name,
+ QQmlContextData *context, QQmlPropertyData &local)
{
QQmlPropertyCache *cache = 0;
QQmlPropertyData *rv = 0;
if (cache) {
- rv = cache->property(name);
+ rv = cache->property(name, obj, context);
} else {
local = qQmlPropertyCacheCreate(obj->metaObject(), qQmlPropertyCacheToString(name));
if (local.isValid())
}
QQmlPropertyData *
-QQmlPropertyCache::property(QQmlEngine *engine, QObject *obj,
- const QHashedV8String &name, QQmlPropertyData &local)
+QQmlPropertyCache::property(QQmlEngine *engine, QObject *obj, const QHashedV8String &name,
+ QQmlContextData *context, QQmlPropertyData &local)
{
- return qQmlPropertyCacheProperty<QHashedV8String>(engine, obj, name, local);
+ return qQmlPropertyCacheProperty<QHashedV8String>(engine, obj, name, context, local);
}
QQmlPropertyData *
QQmlPropertyCache::property(QQmlEngine *engine, QObject *obj,
- const QString &name, QQmlPropertyData &local)
+ const QString &name, QQmlContextData *context, QQmlPropertyData &local)
{
- return qQmlPropertyCacheProperty<QString>(engine, obj, name, local);
+ return qQmlPropertyCacheProperty<QString>(engine, obj, name, context, local);
}
static inline const QMetaObjectPrivate *priv(const uint* data)
QList<QPair<QString, QQmlPropertyData *> > methods;
for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter)
- Insert::in(this, properties, methods, iter, iter.value());
+ Insert::in(this, properties, methods, iter, iter.value().second);
Q_ASSERT(properties.count() == propertyIndexCache.count());
Q_ASSERT(methods.count() == methodIndexCache.count());
QQmlPropertyCacheMethodArguments *arguments = 0;
if (data->hasArguments()) {
arguments = (QQmlPropertyCacheMethodArguments *)data->arguments;
-
+ Q_ASSERT(arguments->argumentsValid);
for (int ii = 0; ii < arguments->arguments[0]; ++ii) {
if (ii != 0) signature.append(",");
signature.append(QMetaType::typeName(arguments->arguments[1 + ii]));
}
if (!_defaultPropertyName.isEmpty()) {
- QQmlPropertyData *dp = property(_defaultPropertyName);
+ QQmlPropertyData *dp = property(_defaultPropertyName, 0, 0);
if (dp && dp->coreIndex >= propertyIndexCacheStart) {
Q_ASSERT(!dp->isFunction());
builder.addClassInfo("DefaultProperty", _defaultPropertyName.toUtf8());
}
}
+/*! \internal
+ \a index MUST be in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
+QList<QByteArray> QQmlPropertyCache::signalParameterNames(int index) const
+{
+ QQmlPropertyData *signalData = signal(index);
+ if (signalData && signalData->hasArguments()) {
+ QQmlPropertyCacheMethodArguments *args = (QQmlPropertyCacheMethodArguments *)signalData->arguments;
+ if (args && args->names)
+ return *args->names;
+ const QMetaMethod &method = QMetaObjectPrivate::signal(firstCppMetaObject(), index);
+ return method.parameterNames();
+ }
+ return QList<QByteArray>();
+}
+
// Returns true if \a from is assignable to a property of type \a to
bool QQmlMetaObject::canConvert(const QQmlMetaObject &from, const QQmlMetaObject &to)
{