diff options
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 17 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlcompiler_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 20 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 6 |
5 files changed, 36 insertions, 17 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index b04c65c968..493eb504c3 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -344,7 +344,7 @@ QHash<int, QHash<int, int> > *QQmlTypeCompiler::objectIndexToIdPerComponent() return &compiledData->objectIndexToIdPerComponent; } -QHash<int, QByteArray> *QQmlTypeCompiler::customParserData() +QHash<int, QQmlCompiledData::CustomParserData> *QQmlTypeCompiler::customParserData() { return &compiledData->customParserData; } @@ -1485,6 +1485,8 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD groupProperties.insert(pos, binding); } + QBitArray customParserBindings(obj->nBindings); + PropertyResolver propertyResolver(propertyCache); QString defaultPropertyName; @@ -1500,20 +1502,24 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD binding = obj->bindingTable(); for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) { + QString name = stringAt(binding->propertyNameIndex); if (customParser) { if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { if (customParser->flags() & QQmlCustomParser::AcceptsAttachedProperties) { customBindings << binding; + customParserBindings.setBit(i); continue; } - } else if ((binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) + } else if (QQmlCodeGenerator::isSignalPropertyName(name) && !(customParser->flags() & QQmlCustomParser::AcceptsSignalHandlers)) { customBindings << binding; + customParserBindings.setBit(i); continue; } else if (binding->type == QV4::CompiledData::Binding::Type_Object || binding->type == QV4::CompiledData::Binding::Type_GroupProperty) { customBindings << binding; + customParserBindings.setBit(i); continue; } } @@ -1523,8 +1529,6 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) continue; - QString name = stringAt(binding->propertyNameIndex); - if (name.constData()->isUpper() && !binding->isAttachedProperty()) { QQmlType *type = 0; QQmlImportNamespace *typeNamespace = 0; @@ -1639,6 +1643,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD } else { if (customParser) { customBindings << binding; + customParserBindings.setBit(i); continue; } if (bindingToDefaultProperty) { @@ -1652,7 +1657,9 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD if (customParser && !customBindings.isEmpty()) { customParser->clearErrors(); customParser->compiler = this; - QByteArray data = customParser->compile(qmlUnit, customBindings); + QQmlCompiledData::CustomParserData data; + data.bindings = customParserBindings; + data.compilationArtifact = customParser->compile(qmlUnit, customBindings); customParser->compiler = 0; customParserData->insert(objectIndex, data); const QList<QQmlError> parserErrors = customParser->errors(); diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 6c4532da5e..d574291869 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -92,7 +92,7 @@ public: QVector<QByteArray> *vmeMetaObjects() const; QHash<int, int> *objectIndexToIdForRoot(); QHash<int, QHash<int, int> > *objectIndexToIdPerComponent(); - QHash<int, QByteArray> *customParserData(); + QHash<int, QQmlCompiledData::CustomParserData> *customParserData(); QQmlJS::MemoryPool *memoryPool(); void setCustomParserBindings(const QVector<int> &bindings); @@ -238,7 +238,7 @@ private: const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes; const QVector<QQmlPropertyCache *> &propertyCaches; const QHash<int, QHash<int, int> > objectIndexToIdPerComponent; - QHash<int, QByteArray> *customParserData; + QHash<int, QQmlCompiledData::CustomParserData> *customParserData; QVector<int> customParserBindings; }; diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index 5a96580f78..5a6291afe6 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -160,7 +160,11 @@ public: QHash<int, QHash<int, int> > objectIndexToIdPerComponent; QHash<int, int> objectIndexToIdForRoot; // hash key is object index - QHash<int, QByteArray> customParserData; + struct CustomParserData { + QByteArray compilationArtifact; // produced by custom parser + QBitArray bindings; // bindings covered by the custom parser + }; + QHash<int, CustomParserData> customParserData; QVector<int> customParserBindings; // index is binding identifier, value is compiled function index. int totalBindingsCount; // Number of bindings used in this type int totalParserStatusCount; // Number of instantiated types that are QQmlParserStatus subclasses diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 5f0b5f79be..5d6cbba910 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -561,7 +561,7 @@ static QQmlType *qmlTypeForObject(QObject *object) return type; } -void QQmlObjectCreator::setupBindings() +void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip) { QQmlListProperty<void> savedList; qSwap(_currentList, savedList); @@ -641,6 +641,9 @@ void QQmlObjectCreator::setupBindings() } + if (static_cast<int>(i) < bindingsToSkip.size() && bindingsToSkip.testBit(i)) + continue; + if (!setPropertyBinding(property, binding)) return; } @@ -1031,10 +1034,13 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent) if (idEntry != objectIndexToId.constEnd()) context->setIdProperty(idEntry.value(), instance); + QBitArray bindingsToSkip; if (customParser) { - QHash<int, QByteArray>::ConstIterator entry = compiledData->customParserData.find(index); - if (entry != compiledData->customParserData.constEnd()) - customParser->setCustomData(instance, *entry); + QHash<int, QQmlCompiledData::CustomParserData>::ConstIterator entry = compiledData->customParserData.find(index); + if (entry != compiledData->customParserData.constEnd()) { + customParser->setCustomData(instance, entry->compilationArtifact); + bindingsToSkip = entry->bindings; + } } if (isComponent) @@ -1056,7 +1062,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent) qSwap(_qmlContext, qmlContext); - bool result = populateInstance(index, instance, cache, /*binding target*/instance, /*value type property*/0, installPropertyCache); + bool result = populateInstance(index, instance, cache, /*binding target*/instance, /*value type property*/0, installPropertyCache, bindingsToSkip); qSwap(_qmlContext, qmlContext); qSwap(_scopeObject, scopeObject); @@ -1136,7 +1142,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru return sharedState->rootContext; } -bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, bool installPropertyCache) +bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, bool installPropertyCache, const QBitArray &bindingsToSkip) { const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index); @@ -1177,7 +1183,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPo QVector<QQmlAbstractBinding*> createdBindings(_compiledObject->nBindings, 0); setupFunctions(); - setupBindings(); + setupBindings(bindingsToSkip); qSwap(_vmeMetaObject, vmeMetaObject); qSwap(_bindingTarget, bindingTarget); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 2545e45fb6..d72b9ec065 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -80,9 +80,11 @@ private: QObject *createInstance(int index, QObject *parent = 0); - bool populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, bool installPropertyCache = true); + bool populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, + QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, bool installPropertyCache = true, + const QBitArray &bindingsToSkip = QBitArray()); - void setupBindings(); + void setupBindings(const QBitArray &bindingsToSkip); bool setPropertyBinding(QQmlPropertyData *property, const QV4::CompiledData::Binding *binding); void setPropertyValue(QQmlPropertyData *property, const QV4::CompiledData::Binding *binding); void setupFunctions(); |