aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator.cpp2
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator_p.h19
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator.cpp5
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp2
-rw-r--r--src/qml/qml/qqmlengine.cpp8
-rw-r--r--src/qml/qml/qqmlengine_p.h2
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp3
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h41
-rw-r--r--tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml10
-rw-r--r--tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml10
-rw-r--r--tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml7
-rw-r--r--tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml7
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp12
13 files changed, 106 insertions, 22 deletions
diff --git a/src/qml/compiler/qqmlpropertycachecreator.cpp b/src/qml/compiler/qqmlpropertycachecreator.cpp
index f8d63ec634..4f8b48f52e 100644
--- a/src/qml/compiler/qqmlpropertycachecreator.cpp
+++ b/src/qml/compiler/qqmlpropertycachecreator.cpp
@@ -64,7 +64,7 @@ QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencing
Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
bool notInRevision = false;
- instantiatingProperty = QmlIR::PropertyResolver(referencingObjectPropertyCache).property(instantiatingPropertyName, &notInRevision);
+ instantiatingProperty = QmlIR::PropertyResolver(referencingObjectPropertyCache).property(instantiatingPropertyName, &notInRevision, QmlIR::PropertyResolver::IgnoreRevision);
}
}
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h
index 5d6a5c177a..0a525e418c 100644
--- a/src/qml/compiler/qqmlpropertycachecreator_p.h
+++ b/src/qml/compiler/qqmlpropertycachecreator_p.h
@@ -184,7 +184,7 @@ inline QQmlPropertyCache *QQmlPropertyCacheCreator<ObjectContainer>::propertyCac
{
if (context.instantiatingProperty) {
if (context.instantiatingProperty->isQObject()) {
- return enginePrivate->rawPropertyCacheForType(context.instantiatingProperty->propType());
+ return enginePrivate->rawPropertyCacheForType(context.instantiatingProperty->propType(), context.instantiatingProperty->typeMinorVersion());
} else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(context.instantiatingProperty->propType())) {
return enginePrivate->cache(vtmo);
}
@@ -476,6 +476,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
pend = obj->propertiesEnd();
for ( ; p != pend; ++p, ++propertyIdx) {
int propertyType = 0;
+ int propertTypeMinorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
if (p->type == QV4::CompiledData::Property::Var) {
@@ -513,6 +514,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
} else {
if (p->type == QV4::CompiledData::Property::Custom) {
propertyType = qmltype.typeId();
+ propertTypeMinorVersion = qmltype.minorVersion();
} else {
propertyType = qmltype.qListTypeId();
}
@@ -532,7 +534,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
if (!obj->defaultPropertyIsAlias && propertyIdx == obj->indexOfDefaultPropertyOrAlias)
cache->_defaultPropertyName = propertyName;
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- propertyType, effectiveSignalIndex);
+ propertyType, propertTypeMinorVersion, effectiveSignalIndex);
effectiveSignalIndex++;
}
@@ -555,7 +557,7 @@ public:
private:
void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex);
- void propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QQmlPropertyRawData::Flags *propertyFlags);
+ void propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyRawData::Flags *propertyFlags);
void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const;
@@ -667,7 +669,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl
template <typename ObjectContainer>
inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(
- const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type,
+ const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion,
QQmlPropertyData::Flags *propertyFlags)
{
const int targetObjectIndex = objectForId(component, alias.targetObjectId);
@@ -685,7 +687,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias
auto targetAlias = targetObject.aliasesBegin();
for (uint i = 0; i < alias.localAliasIndex; ++i)
++targetAlias;
- propertyDataForAlias(component, *targetAlias, type, propertyFlags);
+ propertyDataForAlias(component, *targetAlias, type, minorVersion, propertyFlags);
return;
} else if (alias.encodedMetaPropertyIndex == -1) {
Q_ASSERT(alias.flags & QV4::CompiledData::Alias::AliasPointsToPointerObject);
@@ -697,6 +699,8 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias
else
*type = typeRef->compilationUnit->metaTypeId;
+ *minorVersion = typeRef->minorVersion;
+
propertyFlags->type = QQmlPropertyData::Flags::QObjectDerivedType;
} else {
int coreIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).coreIndex();
@@ -756,8 +760,9 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPrope
Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved);
int type = 0;
+ int minorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
- propertyDataForAlias(component, *alias, &type, &propertyFlags);
+ propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags);
const QString propertyName = objectContainer->stringAt(alias->nameIndex);
@@ -765,7 +770,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPrope
propertyCache->_defaultPropertyName = propertyName;
propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- type, effectiveSignalIndex++);
+ type, minorVersion, effectiveSignalIndex++);
}
}
diff --git a/src/qml/compiler/qqmlpropertyvalidator.cpp b/src/qml/compiler/qqmlpropertyvalidator.cpp
index 7ea89b378d..9fde6848bb 100644
--- a/src/qml/compiler/qqmlpropertyvalidator.cpp
+++ b/src/qml/compiler/qqmlpropertyvalidator.cpp
@@ -665,10 +665,11 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
} else if (property->propType() == qMetaTypeId<QQmlScriptString>()) {
return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected"));
} else {
- // We want to raw metaObject here as the raw metaobject is the
+ // We want to use the raw metaObject here as the raw metaobject is the
// actual property type before we applied any extensions that might
// effect the properties on the type, but don't effect assignability
- QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(property->propType());
+ // Using -1 for the minor version ensures that we get the raw metaObject.
+ QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(property->propType(), -1);
// Will be true if the assgned type inherits propertyMetaObject
bool isAssignable = false;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 97ca597953..836aa8c416 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -823,7 +823,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
if (!pd || !pd->isQObject())
continue;
- QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType());
+ QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeMinorVersion());
const QMetaObject *mo = pc ? pc->firstCppMetaObject() : 0;
while (mo) {
if (mo == &QQmlComponent::staticMetaObject)
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index c47d8a0a81..a66bcaa9bd 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -2342,7 +2342,7 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
}
}
-QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
+QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVersion)
{
Locker locker(this);
auto iter = m_compositeTypes.constFind(t);
@@ -2351,7 +2351,11 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
} else {
QQmlType type = QQmlMetaType::qmlType(t);
locker.unlock();
- return type.isValid() ? cache(type.baseMetaObject()) : 0;
+
+ if (minorVersion >= 0)
+ return type.isValid() ? cache(type, minorVersion) : 0;
+ else
+ return type.isValid() ? cache(type.baseMetaObject()) : 0;
}
}
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 791660cac7..74e232fd84 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -220,7 +220,7 @@ public:
QQmlMetaObject rawMetaObjectForType(int) const;
QQmlMetaObject metaObjectForType(int) const;
QQmlPropertyCache *propertyCacheForType(int);
- QQmlPropertyCache *rawPropertyCacheForType(int);
+ QQmlPropertyCache *rawPropertyCacheForType(int, int minorVersion = -1);
void registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit);
void unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit);
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 7178dffa8b..bce81c1504 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -321,13 +321,14 @@ QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int meth
This is different from QMetaMethod::methodIndex().
*/
void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Flags flags,
- int coreIndex, int propType, int notifyIndex)
+ int coreIndex, int propType, int minorVersion, int notifyIndex)
{
QQmlPropertyData data;
data.setPropType(propType);
data.setCoreIndex(coreIndex);
data.setNotifyIndex(notifyIndex);
data.setFlags(flags);
+ data.setTypeMinorVersion(minorVersion);
QQmlPropertyData *old = findNamedProperty(name);
if (old)
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 6cdb82bd46..e032d4f4c7 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -218,12 +218,38 @@ public:
_coreIndex = qint16(idx);
}
- int revision() const { return _revision; }
- void setRevision(int rev)
+ quint8 revision() const { return _revision; }
+ void setRevision(quint8 rev)
{
- Q_ASSERT(rev >= std::numeric_limits<qint16>::min());
- Q_ASSERT(rev <= std::numeric_limits<qint16>::max());
- _revision = qint16(rev);
+ Q_ASSERT(rev >= std::numeric_limits<quint8>::min());
+ Q_ASSERT(rev <= std::numeric_limits<quint8>::max());
+ _revision = quint8(rev);
+ }
+
+ /* If a property is a C++ type, then we store the minor
+ * version of this type.
+ * This is required to resolve property or signal revisions
+ * if this property is used as a grouped property.
+ *
+ * Test.qml
+ * property TextEdit someTextEdit: TextEdit {}
+ *
+ * Test {
+ * someTextEdit.preeditText: "test" //revision 7
+ * someTextEdit.onEditingFinished: console.log("test") //revision 6
+ * }
+ *
+ * To determine if these properties with revisions are available we need
+ * the minor version of TextEdit as imported in Test.qml.
+ *
+ */
+
+ quint8 typeMinorVersion() const { return _typeMinorVersion; }
+ void setTypeMinorVersion(quint8 rev)
+ {
+ Q_ASSERT(rev >= std::numeric_limits<quint8>::min());
+ Q_ASSERT(rev <= std::numeric_limits<quint8>::max());
+ _typeMinorVersion = quint8(rev);
}
QQmlPropertyCacheMethodArguments *arguments() const { return _arguments; }
@@ -257,7 +283,8 @@ private:
qint16 _notifyIndex;
qint16 _overrideIndex;
- qint16 _revision;
+ quint8 _revision;
+ quint8 _typeMinorVersion;
qint16 _metaObjectOffset;
QQmlPropertyCacheMethodArguments *_arguments;
@@ -390,7 +417,7 @@ public:
QQmlPropertyCache *copyAndReserve(int propertyCount,
int methodCount, int signalCount, int enumCount);
void appendProperty(const QString &, QQmlPropertyRawData::Flags flags, int coreIndex,
- int propType, int notifyIndex);
+ int propType, int revision, int notifyIndex);
void appendSignal(const QString &, QQmlPropertyRawData::Flags, int coreIndex,
const int *types = 0, const QList<QByteArray> &names = QList<QByteArray>());
void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex,
diff --git a/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml
new file mode 100644
index 0000000000..1047926750
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.8
+
+Item {
+ property alias textEdit: textEdit
+
+ TextEdit {
+ id: textEdit
+
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml
new file mode 100644
index 0000000000..552c6c3791
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+
+Item {
+ property alias textEdit: textEdit
+
+ TextEdit {
+ id: textEdit
+
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml
new file mode 100644
index 0000000000..39bd01fe40
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.8
+
+Item {
+ GroupedPropertiesRevisionComponent1 {
+ textEdit.onEditingFinished: console.log("test")
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml
new file mode 100644
index 0000000000..bb9ba79b01
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.8
+
+Item {
+ GroupedPropertiesRevisionComponent2 {
+ textEdit.onEditingFinished: console.log("test")
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index b332ab2194..d6d7506c48 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -75,6 +75,7 @@ private slots:
void urlInterceptor();
void qmlContextProperties();
void testGCCorruption();
+ void testGroupedPropertyRevisions();
public slots:
QObject *createAQObjectForOwnershipTest ()
@@ -873,6 +874,17 @@ void tst_qqmlengine::testGCCorruption()
QVERIFY2(o, qPrintable(c.errorString()));
}
+void tst_qqmlengine::testGroupedPropertyRevisions()
+{
+ QQmlEngine e;
+
+ QQmlComponent c(&e, testFileUrl("testGroupedPropertiesRevision.1.qml"));
+ QScopedPointer<QObject> object(c.create());
+ QVERIFY2(object.data(), qPrintable(c.errorString()));
+ QQmlComponent c2(&e, testFileUrl("testGroupedPropertiesRevision.2.qml"));
+ QVERIFY(!c2.errorString().isEmpty());
+}
+
QTEST_MAIN(tst_qqmlengine)
#include "tst_qqmlengine.moc"