Don't check for revisions when assigning to grouped properties
This leads to wrong behavior in some cases, where we reject valid revisions, and there is probably no case, where this could lead to a conflict for the user of the API. Change-Id: I1614332cf4c07c6a227551612331dd69b2ae71f3 Task-number: QTBUG-40043 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This commit is contained in:
parent
b13412f4db
commit
e9a6c1d4e3
|
@ -1875,17 +1875,17 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
|
|||
|
||||
#ifndef V4_BOOTSTRAP
|
||||
|
||||
QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision, QObject *object, QQmlContextData *context)
|
||||
QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision, RevisionCheck check)
|
||||
{
|
||||
if (notInRevision) *notInRevision = false;
|
||||
|
||||
QQmlPropertyData *d = cache->property(name, object, context);
|
||||
QQmlPropertyData *d = cache->property(name, 0, 0);
|
||||
|
||||
// Find the first property
|
||||
while (d && d->isFunction())
|
||||
d = cache->overrideData(d);
|
||||
|
||||
if (d && !cache->isAllowedInRevision(d)) {
|
||||
if (check != IgnoreRevision && d && !cache->isAllowedInRevision(d)) {
|
||||
if (notInRevision) *notInRevision = true;
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -1894,11 +1894,11 @@ QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRev
|
|||
}
|
||||
|
||||
|
||||
QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevision, QObject *object, QQmlContextData *context)
|
||||
QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevision)
|
||||
{
|
||||
if (notInRevision) *notInRevision = false;
|
||||
|
||||
QQmlPropertyData *d = cache->property(name, object, context);
|
||||
QQmlPropertyData *d = cache->property(name, 0, 0);
|
||||
if (notInRevision) *notInRevision = false;
|
||||
|
||||
while (d && !(d->isFunction()))
|
||||
|
@ -1914,7 +1914,7 @@ QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevis
|
|||
if (name.endsWith(QStringLiteral("Changed"))) {
|
||||
QString propName = name.mid(0, name.length() - static_cast<int>(strlen("Changed")));
|
||||
|
||||
d = property(propName, notInRevision, object, context);
|
||||
d = property(propName, notInRevision);
|
||||
if (d)
|
||||
return cache->signal(d->notifyIndex);
|
||||
}
|
||||
|
|
|
@ -460,10 +460,15 @@ struct Q_QML_EXPORT PropertyResolver
|
|||
return cache->property(index);
|
||||
}
|
||||
|
||||
QQmlPropertyData *property(const QString &name, bool *notInRevision = 0, QObject *object = 0, QQmlContextData *context = 0);
|
||||
enum RevisionCheck {
|
||||
CheckRevision,
|
||||
IgnoreRevision
|
||||
};
|
||||
|
||||
QQmlPropertyData *property(const QString &name, bool *notInRevision = 0, RevisionCheck check = CheckRevision);
|
||||
|
||||
// This code must match the semantics of QQmlPropertyPrivate::findSignalByName
|
||||
QQmlPropertyData *signal(const QString &name, bool *notInRevision, QObject *object = 0, QQmlContextData *context = 0);
|
||||
QQmlPropertyData *signal(const QString &name, bool *notInRevision);
|
||||
|
||||
QQmlPropertyCache *cache;
|
||||
};
|
||||
|
|
|
@ -1859,6 +1859,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
|
|||
}
|
||||
|
||||
bool bindingToDefaultProperty = false;
|
||||
bool isGroupProperty = instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty;
|
||||
|
||||
bool notInRevision = false;
|
||||
QQmlPropertyData *pd = 0;
|
||||
|
@ -1867,7 +1868,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
|
|||
|| binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
|
||||
pd = propertyResolver.signal(name, ¬InRevision);
|
||||
else
|
||||
pd = propertyResolver.property(name, ¬InRevision);
|
||||
pd = propertyResolver.property(name, ¬InRevision, isGroupProperty ? QmlIR::PropertyResolver::IgnoreRevision : QmlIR::PropertyResolver::CheckRevision);
|
||||
|
||||
if (notInRevision) {
|
||||
QString typeName = stringAt(obj->inheritedTypeNameIndex);
|
||||
|
@ -1879,7 +1880,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty)
|
||||
if (isGroupProperty)
|
||||
COMPILE_EXCEPTION(binding, tr("Cannot assign a value directly to a grouped property"));
|
||||
|
||||
pd = defaultProperty;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import Qt.test 1.1
|
||||
import QtQuick 2.0
|
||||
|
||||
MyItemUsingRevisionedObject {
|
||||
property real test
|
||||
|
||||
revisioned.prop1: 10
|
||||
revisioned.prop2: 1
|
||||
|
||||
Component.onCompleted: test = revisioned.prop1 + revisioned.prop2
|
||||
}
|
||||
|
|
@ -452,6 +452,7 @@ void registerTypes()
|
|||
qmlRegisterType<MyRevisionedSubclass>("Qt.test",1,0,"MyRevisionedSubclass");
|
||||
// MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1
|
||||
qmlRegisterType<MyRevisionedSubclass,1>("Qt.test",1,1,"MyRevisionedSubclass");
|
||||
qmlRegisterType<MyItemUsingRevisionedObject>("Qt.test", 1, 0, "MyItemUsingRevisionedObject");
|
||||
|
||||
#ifndef QT_NO_WIDGETS
|
||||
qmlRegisterExtendedType<QWidget,QWidgetDeclarativeUI>("Qt.test",1,0,"QWidget");
|
||||
|
|
|
@ -1084,10 +1084,27 @@ protected:
|
|||
qreal m_p4;
|
||||
};
|
||||
|
||||
|
||||
class MyItemUsingRevisionedObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(MyRevisionedClass *revisioned READ revisioned)
|
||||
|
||||
public:
|
||||
MyItemUsingRevisionedObject() {
|
||||
m_revisioned = new MyRevisionedClass;
|
||||
}
|
||||
|
||||
MyRevisionedClass *revisioned() const { return m_revisioned; }
|
||||
private:
|
||||
MyRevisionedClass *m_revisioned;
|
||||
};
|
||||
|
||||
QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered)
|
||||
QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered)
|
||||
QML_DECLARE_TYPE(MyRevisionedClass)
|
||||
QML_DECLARE_TYPE(MyRevisionedSubclass)
|
||||
QML_DECLARE_TYPE(MyItemUsingRevisionedObject)
|
||||
Q_DECLARE_METATYPE(MyQmlObject::MyType)
|
||||
|
||||
|
||||
|
|
|
@ -6578,6 +6578,15 @@ void tst_qqmlecmascript::revision()
|
|||
QCOMPARE(object->property("test").toReal(), 11.);
|
||||
delete object;
|
||||
}
|
||||
|
||||
{
|
||||
QQmlComponent component(&engine, testFileUrl("metaobjectRevision5.qml"));
|
||||
|
||||
QObject *object = component.create();
|
||||
QVERIFY(object != 0);
|
||||
QCOMPARE(object->property("test").toReal(), 11.);
|
||||
delete object;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::realToInt()
|
||||
|
|
Loading…
Reference in New Issue