aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp9
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h1
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h89
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h9
4 files changed, 74 insertions, 34 deletions
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index e71568b2d8..c0c5f341e5 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -501,6 +501,15 @@ int ExecutableCompilationUnit::totalObjectCount() const {
return inlineComponentData[*icRootName].totalObjectCount;
}
+ResolvedTypeReference *ExecutableCompilationUnit::resolvedType(QMetaType type) const
+{
+ for (ResolvedTypeReference *ref : std::as_const(resolvedTypes)) {
+ if (ref->type().typeId() == type)
+ return ref;
+ }
+ return nullptr;
+}
+
int ExecutableCompilationUnit::totalParserStatusCount() const {
if (!icRootName)
return m_totalParserStatusCount;
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h
index f7a491c740..5ad3838658 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit_p.h
+++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h
@@ -144,6 +144,7 @@ public:
QVector<QQmlRefPointer<QQmlScriptData>> dependentScripts;
ResolvedTypeReferenceMap resolvedTypes;
ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); }
+ ResolvedTypeReference *resolvedType(QMetaType type) const;
bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const;
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 05e669a856..efd897ad4e 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -887,53 +887,74 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
const QQmlPropertyData *targetProperty = targetCache->property(coreIndex);
Q_ASSERT(targetProperty);
+ const QMetaType targetPropType = targetProperty->propType();
+
+ const auto resolveType = [](QMetaType targetPropType) {
+ if (targetPropType.flags() & QMetaType::IsEnumeration)
+ return targetPropType.underlyingType();
+ else
+ return targetPropType;
+ };
+
+ const auto populateWithPropertyData = [&](const QQmlPropertyData *property) {
+ *type = resolveType(property->propType());
+ writable = property->isWritable();
+ resettable = property->isResettable();
+ bindable = property->isBindable();
+
+ // Copy type flags
+ propertyFlags->copyPropertyTypeFlags(property->flags());
+ if (property->isVarProperty())
+ propertyFlags->setType(QQmlPropertyData::Flags::QVariantType);
+ };
+
// for deep aliases, valueTypeIndex is always set
- if (!QQmlMetaType::isValueType(targetProperty->propType()) && valueTypeIndex != -1) {
+ if (!QQmlMetaType::isValueType(targetPropType) && valueTypeIndex != -1) {
// deep alias property
- *type = targetProperty->propType();
- QQmlPropertyCache::ConstPtr typeCache = QQmlMetaType::propertyCacheForType(*type);
- Q_ASSERT(typeCache);
- const QQmlPropertyData *typeProperty = typeCache->property(valueTypeIndex);
- if (typeProperty == nullptr) {
- return qQmlCompileError(alias.referenceLocation,
- QQmlPropertyCacheCreatorBase::tr("Invalid alias target"));
+ QQmlPropertyCache::ConstPtr typeCache
+ = QQmlMetaType::propertyCacheForType(targetPropType);
+
+ if (!typeCache) {
+ // See if it's a half-resolved composite type
+ if (const QV4::ResolvedTypeReference *typeRef
+ = objectContainer->resolvedType(targetPropType)) {
+ typeCache = typeRef->typePropertyCache();
+ }
}
- *type = typeProperty->propType();
- writable = typeProperty->isWritable();
- resettable = typeProperty->isResettable();
- bindable = typeProperty->isBindable();
+ const QQmlPropertyData *typeProperty = typeCache
+ ? typeCache->property(valueTypeIndex)
+ : nullptr;
+ if (typeProperty == nullptr) {
+ return qQmlCompileError(
+ alias.referenceLocation,
+ QQmlPropertyCacheCreatorBase::tr("Invalid alias target"));
+ }
+ populateWithPropertyData(typeProperty);
} else {
// value type or primitive type or enum
- *type = targetProperty->propType();
-
- writable = targetProperty->isWritable();
- resettable = targetProperty->isResettable();
- bindable = targetProperty->isBindable();
+ populateWithPropertyData(targetProperty);
if (valueTypeIndex != -1) {
- const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(*type);
- if (valueTypeMetaObject->property(valueTypeIndex).isEnumType())
- *type = QMetaType::fromType<int>();
- else
- *type = valueTypeMetaObject->property(valueTypeIndex).metaType();
- } else {
- if (targetProperty->isEnum()) {
- *type = QMetaType::fromType<int>();
- } else {
- // Copy type flags
- propertyFlags->copyPropertyTypeFlags(targetProperty->flags());
-
- if (targetProperty->isVarProperty())
- propertyFlags->setType(QQmlPropertyData::Flags::QVariantType);
- }
+ const QMetaObject *valueTypeMetaObject
+ = QQmlMetaType::metaObjectForValueType(*type);
+ const QMetaProperty valueTypeMetaProperty
+ = valueTypeMetaObject->property(valueTypeIndex);
+ *type = resolveType(valueTypeMetaProperty.metaType());
+
+ // We can only write or reset the value type property if we can write
+ // the value type itself.
+ resettable = writable && valueTypeMetaProperty.isResettable();
+ writable = writable && valueTypeMetaProperty.isWritable();
+
+ bindable = valueTypeMetaProperty.isBindable();
}
}
}
- propertyFlags->setIsWritable(!(alias.hasFlag(QV4::CompiledData::Alias::IsReadOnly))
- && writable);
+ propertyFlags->setIsWritable(
+ writable && !alias.hasFlag(QV4::CompiledData::Alias::IsReadOnly));
propertyFlags->setIsResettable(resettable);
propertyFlags->setIsBindable(bindable);
return QQmlError();
diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h
index a379946664..2e183ed837 100644
--- a/src/qml/qml/qqmltypecompiler_p.h
+++ b/src/qml/qml/qqmltypecompiler_p.h
@@ -108,6 +108,15 @@ public:
return resolvedTypes->value(id);
}
+ QV4::ResolvedTypeReference *resolvedType(QMetaType type) const
+ {
+ for (QV4::ResolvedTypeReference *ref : std::as_const(*resolvedTypes)) {
+ if (ref->type().typeId() == type)
+ return ref;
+ }
+ return nullptr;
+ }
+
QQmlType qmlTypeForComponent(const QString &inlineComponentName = QString()) const;
private: