X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fqml%2Fqml%2Fqqmlpropertycache.cpp;h=50674fa1e42442f994b854e3ee11b36c84006b43;hb=7223f1861d3309d336123c90866665cfe2507d7f;hp=6b41c7a3372772085926ee2a22796549cb6abe7f;hpb=ba94fbedd648b04a28d67b920db2883e73459d1f;p=profile%2Fivi%2Fqtdeclarative.git diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 6b41c7a..50674fa 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -41,17 +41,20 @@ #include "qqmlpropertycache_p.h" -#include "qqmlengine_p.h" -#include "qqmlbinding_p.h" +#include +#include +#include #include #include #include #include +#include #include #include // for toupper +#include #ifdef Q_CC_MSVC // nonstandard extension used : zero-sized array in struct/union. @@ -70,6 +73,12 @@ class QQmlPropertyCacheMethodArguments public: QQmlPropertyCacheMethodArguments *next; + //for signal handler rewrites + QString *signalParameterStringForJS; + int signalParameterCountForJS:30; + int parameterError:1; + int argumentsValid:1; + QList *names; int arguments[0]; }; @@ -102,7 +111,7 @@ static QQmlPropertyData::Flags flagsForPropertyType(int propType, QQmlEngine *en 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; @@ -153,7 +162,7 @@ void QQmlPropertyData::lazyLoad(const QMetaProperty &p, QQmlEngine *engine) 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) { @@ -236,7 +245,8 @@ Creates a new empty QQmlPropertyCache. */ 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); } @@ -246,7 +256,8 @@ Creates a new QQmlPropertyCache of \a metaObject. */ 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); @@ -261,6 +272,7 @@ QQmlPropertyCache::~QQmlPropertyCache() 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; @@ -343,16 +355,14 @@ void QQmlPropertyCache::appendProperty(const QString &name, 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, @@ -364,15 +374,14 @@ 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, @@ -392,27 +401,31 @@ void QQmlPropertyCache::appendSignal(const QString &name, quint32 flags, int cor typedef QQmlPropertyCacheMethodArguments A; A *args = static_cast(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(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, @@ -432,26 +445,31 @@ void QQmlPropertyCache::appendSignal(const QHashedCStringRef &name, quint32 flag typedef QQmlPropertyCacheMethodArguments A; A *args = static_cast(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(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, @@ -468,6 +486,10 @@ void QQmlPropertyCache::appendMethod(const QString &name, quint32 flags, int cor 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(names); @@ -477,16 +499,14 @@ void QQmlPropertyCache::appendMethod(const QString &name, quint32 flags, int cor 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, @@ -503,6 +523,10 @@ void QQmlPropertyCache::appendMethod(const QHashedCStringRef &name, quint32 flag 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(names); @@ -512,15 +536,14 @@ void QQmlPropertyCache::appendMethod(const QHashedCStringRef &name, quint32 flag 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. @@ -552,7 +575,7 @@ QString QQmlPropertyCache::defaultPropertyName() const QQmlPropertyData *QQmlPropertyCache::defaultProperty() const { - return property(defaultPropertyName()); + return property(defaultPropertyName(), 0, 0); } QQmlPropertyCache *QQmlPropertyCache::parent() const @@ -706,20 +729,20 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject 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(); @@ -733,7 +756,7 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject str[length + 2] = '\0'; QHashedString on(QString::fromLatin1(str.data())); - stringCache.insert(on, sigdata); + setNamedProperty(on, ii, data, (old != 0)); ++signalHandlerIndex; } } @@ -742,9 +765,8 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject // 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); } } @@ -782,14 +804,14 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject 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); @@ -802,13 +824,19 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject 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()); @@ -859,17 +887,18 @@ void QQmlPropertyCache::update(QQmlEngine *engine, const QMetaObject *metaObject 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(&methodIndexCache.at(index - signalHandlerIndexCacheStart)); if (rv->notFullyResolved()) resolve(rv); Q_ASSERT(rv->isSignal() || rv->coreIndex == -1); + if (c) *c = const_cast(this); return rv; } @@ -894,8 +923,7 @@ QQmlPropertyCache::property(int index) const return _parent->property(index); QQmlPropertyData *rv = const_cast(&propertyIndexCache.at(index - propertyIndexCacheStart)); - if (rv->notFullyResolved()) resolve(rv); - return rv; + return ensureResolved(rv); } QQmlPropertyData * @@ -908,32 +936,60 @@ QQmlPropertyCache::method(int index) const return _parent->method(index); QQmlPropertyData *rv = const_cast(&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(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) { - QQmlPropertyData **rv = stringCache.value(str); - if (rv && (*rv)->notFullyResolved()) resolve(*rv); - return rv?*rv:0; + return (prop->isFunction() ? vmemo->methodCount() + : prop->isSignalHandler() ? vmemo->signalCount() + : vmemo->propertyCount()); +} + +} + +QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *vmemo, QQmlContextData *context) const +{ + 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) @@ -959,6 +1015,14 @@ QString QQmlPropertyData::name(const QMetaObject *metaObject) } } +void QQmlPropertyData::markAsOverrideOf(QQmlPropertyData *predecessor) +{ + overrideIndexIsProperty = !predecessor->isFunction(); + overrideIndex = predecessor->coreIndex; + + predecessor->flags |= QQmlPropertyData::IsOverridden; +} + QStringList QQmlPropertyCache::propertyNames() const { QStringList keys; @@ -1001,16 +1065,63 @@ static int EnumType(const QMetaObject *metaobj, const QByteArray &str, int type) \a index MUST be in the signal index range (see QObjectPrivate::signalIndex()). This is different from QMetaMethod::methodIndex(). */ -QList 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(); + QQmlPropertyCache *c = 0; + QQmlPropertyData *signalData = signal(index, &c); + if (!signalData) + return QString(); + + typedef QQmlPropertyCacheMethodArguments A; + + if (signalData->arguments) { + A *arguments = static_cast(signalData->arguments); + if (arguments->signalParameterStringForJS) { + if (count) + *count = arguments->signalParameterCountForJS; + if (arguments->parameterError) { + if (errorString) + *errorString = *arguments->signalParameterStringForJS; + return QString(); + } + return *arguments->signalParameterStringForJS; + } } - return QMetaObjectPrivate::signal(object->metaObject(), index).parameterNames(); + QList parameterNameList = signalParameterNames(index); + + if (!signalData->arguments) { + int argc = parameterNameList.count(); + A *args = static_cast(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(parameterNameList); + signalData->arguments = args; + args->next = c->argumentsCache; + c->argumentsCache = args; + } + + 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(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 @@ -1034,7 +1145,7 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index, QQmlPropertyData *rv = const_cast(&c->methodIndexCache.at(index - c->methodIndexCacheStart)); - if (rv->arguments) + if (rv->arguments && static_cast(rv->arguments)->argumentsValid) return static_cast(rv->arguments)->arguments; const QMetaObject *metaObject = c->createMetaObject(); @@ -1042,9 +1153,20 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index, QMetaMethod m = metaObject->method(index); int argc = m.parameterCount(); - A *args = static_cast(malloc(sizeof(A) + (argc + 1) * sizeof(int))); - args->arguments[0] = argc; - args->names = 0; + if (!rv->arguments) { + A *args = static_cast(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(rv->arguments); + QList argTypeNames; // Only loaded if needed for (int ii = 0; ii < argc; ++ii) { @@ -1062,15 +1184,11 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index, } 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(rv->arguments)->arguments; } else { @@ -1154,6 +1272,27 @@ int QQmlPropertyCache::methodReturnType(QObject *object, const QQmlPropertyData 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); @@ -1214,7 +1353,8 @@ inline QString qQmlPropertyCacheToString(const QHashedV8String &string) template 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; @@ -1235,7 +1375,7 @@ qQmlPropertyCacheProperty(QQmlEngine *engine, QObject *obj, const T &name, QQmlP 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()) @@ -1246,17 +1386,17 @@ qQmlPropertyCacheProperty(QQmlEngine *engine, QObject *obj, const T &name, QQmlP } 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(engine, obj, name, local); + return qQmlPropertyCacheProperty(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(engine, obj, name, local); + return qQmlPropertyCacheProperty(engine, obj, name, context, local); } static inline const QMetaObjectPrivate *priv(const uint* data) @@ -1319,7 +1459,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) QList > 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()); @@ -1355,7 +1495,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) 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])); @@ -1380,7 +1520,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) } 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()); @@ -1388,6 +1528,23 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) } } +/*! \internal + \a index MUST be in the signal index range (see QObjectPrivate::signalIndex()). + This is different from QMetaMethod::methodIndex(). +*/ +QList 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(); +} + // Returns true if \a from is assignable to a property of type \a to bool QQmlMetaObject::canConvert(const QQmlMetaObject &from, const QQmlMetaObject &to) {