diff options
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlincubator_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 42 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 1 |
5 files changed, 48 insertions, 14 deletions
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h index aadb147bd5..a674ff274f 100644 --- a/src/qml/qml/qqmlincubator_p.h +++ b/src/qml/qml/qqmlincubator_p.h @@ -61,9 +61,7 @@ QT_BEGIN_NAMESPACE -class QQmlPropertyData; -struct RequiredPropertyInfo; -using RequiredProperties = QHash<QQmlPropertyData*, RequiredPropertyInfo>; +class RequiredProperties; class QQmlIncubator; class Q_QML_PRIVATE_EXPORT QQmlIncubatorPrivate : public QQmlEnginePrivate::Incubator diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index a26cdba53a..6cc2bf49c8 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1505,23 +1505,45 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings) _ddata->deferData(_compiledObjectIndex, compilationUnit, context); + QSet<QString> postHocRequired; + for (auto it = _compiledObject->requiredPropertyExtraDataBegin(); it != _compiledObject->requiredPropertyExtraDataEnd(); ++it) + postHocRequired.insert(stringAt(it->nameIndex)); + bool hadInheritedRequiredProperties = !postHocRequired.empty(); + for (int propertyIndex = 0; propertyIndex != _compiledObject->propertyCount(); ++propertyIndex) { const QV4::CompiledData::Property* property = _compiledObject->propertiesBegin() + propertyIndex; QQmlPropertyData *propertyData = _propertyCache->property(_propertyCache->propertyOffset() + propertyIndex); - if (property->isRequired) { - sharedState->hadRequiredProperties = true; - sharedState->requiredProperties.insert(propertyData, - RequiredPropertyInfo {compilationUnit->stringAt(property->nameIndex), compilationUnit->finalUrl(), property->location, {}}); - } + // only compute stringAt if there's a chance for the lookup to succeed + auto postHocIt = postHocRequired.isEmpty() ? postHocRequired.end() : postHocRequired.find(stringAt(property->nameIndex)); + if (!property->isRequired && postHocRequired.end() == postHocIt) + continue; + if (postHocIt != postHocRequired.end()) + postHocRequired.erase(postHocIt); + sharedState->hadRequiredProperties = true; + sharedState->requiredProperties.insert(propertyData, + RequiredPropertyInfo {compilationUnit->stringAt(property->nameIndex), compilationUnit->finalUrl(), property->location, {}}); + } for (int i = 0; i <= _propertyCache->propertyOffset(); ++i) { - QQmlPropertyData *propertyData = _propertyCache->property(i); - if (propertyData && propertyData->isRequired()) { - sharedState->hadRequiredProperties = true; - sharedState->requiredProperties.insert(propertyData, RequiredPropertyInfo {propertyData->name(_qobject), compilationUnit->finalUrl(), _compiledObject->location, {}}); - } + QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(i); + if (!propertyData) + continue; + if (!propertyData->isRequired() && postHocRequired.isEmpty()) + continue; + QString name = propertyData->name(_qobject); + auto postHocIt = postHocRequired.find(name); + if (!propertyData->isRequired() && postHocRequired.end() == postHocIt ) + continue; + + if (postHocIt != postHocRequired.end()) + postHocRequired.erase(postHocIt); + + sharedState->hadRequiredProperties = true; + sharedState->requiredProperties.insert(propertyData, RequiredPropertyInfo {name, compilationUnit->finalUrl(), _compiledObject->location, {}}); } + if (!postHocRequired.isEmpty() && hadInheritedRequiredProperties) + recordError({}, QLatin1String("Property %1 was marked as required but does not exist").arg(*postHocRequired.begin())); if (_compiledObject->nFunctions > 0) setupFunctions(); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index f8ad90be15..bca450addb 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -86,7 +86,7 @@ struct RequiredPropertyInfo QVector<AliasToRequiredInfo> aliasesToRequired; }; -using RequiredProperties = QHash<QQmlPropertyData*, RequiredPropertyInfo>; +class RequiredProperties : public QHash<QQmlPropertyData*, RequiredPropertyInfo> {}; struct QQmlObjectCreatorSharedState : public QSharedData { diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 8d91fa29e4..540e6afda1 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -400,6 +400,19 @@ const QMetaObject *QQmlPropertyCache::createMetaObject() return _metaObject; } +QQmlPropertyData *QQmlPropertyCache::maybeUnresolvedProperty(int index) const +{ + if (index < 0 || index >= (propertyIndexCacheStart + propertyIndexCache.count())) + return nullptr; + + QQmlPropertyData *rv = nullptr; + if (index < propertyIndexCacheStart) + return _parent->maybeUnresolvedProperty(index); + else + rv = const_cast<QQmlPropertyData *>(&propertyIndexCache.at(index - propertyIndexCacheStart)); + return rv; +} + QQmlPropertyData *QQmlPropertyCache::defaultProperty() const { return property(defaultPropertyName(), nullptr, nullptr); diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 9c576aab39..9e6eaf9778 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -120,6 +120,7 @@ public: } QQmlPropertyData *property(int) const; + QQmlPropertyData *maybeUnresolvedProperty(int) const; QQmlPropertyData *method(int) const; QQmlPropertyData *signal(int index) const; QQmlEnumData *qmlEnum(int) const; |