QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObject *metaObject, 
                                                                  const QString &property)
{
    Q_ASSERT(metaObject);

    QDeclarativePropertyCache::Data rv;
    {
        const QMetaObject *cmo = metaObject;
        while (cmo) {
            int idx = metaObject->indexOfProperty(property.toUtf8());
            if (idx != -1) {
                QMetaProperty p = metaObject->property(idx);
                if (p.isScriptable()) {
                    rv.load(metaObject->property(idx));
                    if (!isDynamicMetaObject(cmo))
                        rv.flags |= Data::IsDirect;
                    return rv;
                } else {
                    while (cmo && cmo->propertyOffset() >= idx)
                        cmo = cmo->superClass();
                }
            } else {
                cmo = 0;
            }
        }
    }

    int methodCount = metaObject->methodCount();
    for (int ii = methodCount - 1; ii >= 3; --ii) { // >=3 to block the destroyed signal and deleteLater() slot
        QMetaMethod m = metaObject->method(ii);
        if (m.access() == QMetaMethod::Private)
            continue;
        QString methodName = QString::fromUtf8(m.signature());

        int parenIdx = methodName.indexOf(QLatin1Char('('));
        Q_ASSERT(parenIdx != -1);
        QStringRef methodNameRef = methodName.leftRef(parenIdx);

        if (methodNameRef == property) {
            rv.load(m);
            if (!isDynamicMetaObject(m.enclosingMetaObject()))
                rv.flags |= Data::IsDirect;
            return rv;
        }
    }

    return rv;
}
Example #2
0
File: qnode.cpp Project: RSATom/Qt
/*!
 * \internal
 *
 * Find the most derived metaobject that doesn't have a dynamic
 * metaobject farther up the chain.
 * TODO: Add support to QMetaObject to explicitly say if it's a dynamic
 * or static metaobject so we don't need this logic
 */
const QMetaObject *QNodePrivate::findStaticMetaObject(const QMetaObject *metaObject)
{
    const QMetaObject *lastStaticMetaobject = nullptr;
    auto mo = metaObject;
    while (mo) {
        const bool dynamicMetaObject = isDynamicMetaObject(mo);
        if (dynamicMetaObject)
            lastStaticMetaobject = nullptr;

        if (!dynamicMetaObject && !lastStaticMetaobject)
            lastStaticMetaobject = mo;

        mo = mo->superClass();
    }
    Q_ASSERT(lastStaticMetaobject);
    return lastStaticMetaobject;
}
void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaObject *metaObject, 
                                       int revision, 
                                       Data::Flag propertyFlags, Data::Flag methodFlags, Data::Flag signalFlags)
{
    Q_UNUSED(revision);

    qPersistentDispose(constructor); // Now invalid

    bool dynamicMetaObject = isDynamicMetaObject(metaObject);

    allowedRevisionCache.append(0);

    int methodCount = metaObject->methodCount();
    // 3 to block the destroyed signal and the deleteLater() slot
    int methodOffset = qMax(3, metaObject->methodOffset()); 

    methodIndexCache.resize(methodCount - methodIndexCacheStart);
    for (int ii = methodOffset; ii < methodCount; ++ii) {
        QMetaMethod m = metaObject->method(ii);
        if (m.access() == QMetaMethod::Private) 
            continue;

        // Extract method name
        const char *signature = m.signature();
        const char *cptr = signature;
        while (*cptr != '(') { Q_ASSERT(*cptr != 0); ++cptr; }
        QString str = dynamicMetaObject?QString::fromUtf8(signature, cptr - signature):
                                        QString::fromLatin1(signature, cptr - signature);
        QHashedString methodName(str);

        Data *data = &methodIndexCache[ii - methodIndexCacheStart];

        data->lazyLoad(m);
        if (data->isSignal())
            data->flags |= signalFlags;
        else
            data->flags |= methodFlags;

        if (!dynamicMetaObject)
            data->flags |= Data::IsDirect;

        data->metaObjectOffset = allowedRevisionCache.count() - 1;

        if (Data **old = stringCache.value(methodName)) {
            // We only overload methods in the same class, exactly like C++
            if ((*old)->flags & Data::IsFunction && (*old)->coreIndex >= methodOffset)
                data->relatedIndex = (*old)->coreIndex;
            data->overrideIndexIsProperty = !bool((*old)->flags & Data::IsFunction);
            data->overrideIndex = (*old)->coreIndex;
        }

        stringCache.insert(methodName, data);
    }

    int propCount = metaObject->propertyCount();
    int propOffset = metaObject->propertyOffset();

    propertyIndexCache.resize(propCount - propertyIndexCacheStart);
    for (int ii = propOffset; ii < propCount; ++ii) {
        QMetaProperty p = metaObject->property(ii);
        if (!p.isScriptable())
            continue;

        QString str = dynamicMetaObject?QString::fromUtf8(p.name()):
                                        QString::fromLatin1(p.name());
        QHashedString propName(str);

        Data *data = &propertyIndexCache[ii - propertyIndexCacheStart];

        data->lazyLoad(p, engine);
        data->flags |= propertyFlags;

        if (!dynamicMetaObject) 
            data->flags |= Data::IsDirect;

        data->metaObjectOffset = allowedRevisionCache.count() - 1;

        if (Data **old = stringCache.value(propName)) {
            data->overrideIndexIsProperty = !bool((*old)->flags & Data::IsFunction);
            data->overrideIndex = (*old)->coreIndex;
        }

        stringCache.insert(propName, data);
    }
}