moc: allow wrapper generation for QProperty in pimpl class
Previously, only QNotifiedProperty was supported. As moc cannot determine by itself whether the backing property is a QProperty or a QNotifiedProperty, allow NOTIFY false to indicate that it is a plain QProperty. For symmetry, NOTIFY true is also allowed and means that the backing property is a QNotifiedProperty. Change-Id: I66f3105c976ef084198ce8658bc07499a3cb1cd8 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>bb10
parent
bb6a73260e
commit
8cdaeb2655
|
|
@ -1606,6 +1606,7 @@ void Generator::generateQPropertyApi()
|
|||
};
|
||||
|
||||
const bool stored = (property.name == property.storage);
|
||||
const bool isNotifiedProperty = property.isNotifiedProperty;
|
||||
|
||||
// property accessor
|
||||
fprintf(out, "\n%s %s::_qt_property_api_%s::value() const\n{\n",
|
||||
|
|
@ -1630,10 +1631,16 @@ void Generator::generateQPropertyApi()
|
|||
property.type.name.constData());
|
||||
printAccessor();
|
||||
if (stored) {
|
||||
fprintf(out, " thisPtr->%s->%s.setValue(thisPtr->%s, value);\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " thisPtr->%s->%s.setValue(thisPtr->%s, value);\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " thisPtr->%s->%s.setValue(value);\n", property.accessor.constData(), property.storage.constData());
|
||||
} else {
|
||||
fprintf(out, " if (auto *target = thisPtr->%s->%s)\n", property.accessor.constData(), property.storage.constData());
|
||||
fprintf(out, " target->setValue(thisPtr->%s, value);\n", property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " target->setValue(thisPtr->%s, value);\n", property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " target->setValue(value);\n");
|
||||
}
|
||||
fprintf(out, "}\n");
|
||||
|
||||
|
|
@ -1644,10 +1651,16 @@ void Generator::generateQPropertyApi()
|
|||
property.type.name.constData());
|
||||
printAccessor();
|
||||
if (stored) {
|
||||
fprintf(out, " thisPtr->%s->%s.setValue(thisPtr->%s, std::move(value));\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " thisPtr->%s->%s.setValue(thisPtr->%s, std::move(value));\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " thisPtr->%s->%s.setValue(std::move(value));\n", property.accessor.constData(), property.storage.constData());
|
||||
} else {
|
||||
fprintf(out, " if (auto *target = thisPtr->%s->%s)\n", property.accessor.constData(), property.storage.constData());
|
||||
fprintf(out, " target->setValue(thisPtr->%s, std::move(value));\n", property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " target->setValue(thisPtr->%s, std::move(value));\n", property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " target->setValue(std::move(value));\n");
|
||||
}
|
||||
fprintf(out, "}\n");
|
||||
|
||||
|
|
@ -1659,10 +1672,16 @@ void Generator::generateQPropertyApi()
|
|||
property.type.name.constData());
|
||||
printAccessor();
|
||||
if (stored) {
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(thisPtr->%s, binding);\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(thisPtr->%s, binding);\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(binding);\n", property.accessor.constData(), property.storage.constData());
|
||||
} else {
|
||||
fprintf(out, " if (auto *target = thisPtr->%s->%s)\n", property.accessor.constData(), property.storage.constData());
|
||||
fprintf(out, " return target->setBinding(thisPtr->%s, binding);\n", property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " return target->setBinding(thisPtr->%s, binding);\n", property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " return target->setBinding(binding);\n");
|
||||
fprintf(out, " else\n");
|
||||
fprintf(out, " return QPropertyBinding<%s>();\n", property.type.name.constData());
|
||||
}
|
||||
|
|
@ -1676,10 +1695,16 @@ void Generator::generateQPropertyApi()
|
|||
property.type.name.constData());
|
||||
printAccessor();
|
||||
if (stored) {
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(thisPtr->%s, std::move(binding));\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(thisPtr->%s, std::move(binding));\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(std::move(binding));\n", property.accessor.constData(), property.storage.constData());
|
||||
} else {
|
||||
fprintf(out, " if (auto *target = thisPtr->%s->%s)\n", property.accessor.constData(), property.storage.constData());
|
||||
fprintf(out, " return target->setBinding(thisPtr->%s, std::move(binding));\n", property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " return target->setBinding(thisPtr->%s, std::move(binding));\n", property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " return target->setBinding(std::move(binding));\n");
|
||||
fprintf(out, " else\n");
|
||||
fprintf(out, " return QPropertyBinding<%s>();\n", property.type.name.constData());
|
||||
}
|
||||
|
|
@ -1691,10 +1716,16 @@ void Generator::generateQPropertyApi()
|
|||
property.name.constData());
|
||||
printAccessor();
|
||||
if (stored) {
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(thisPtr->%s, binding);\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(thisPtr->%s, binding);\n", property.accessor.constData(), property.storage.constData(), property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " return thisPtr->%s->%s.setBinding(binding);\n", property.accessor.constData(), property.storage.constData());
|
||||
} else {
|
||||
fprintf(out, " if (auto *target = thisPtr->%s->%s)\n", property.accessor.constData(), property.storage.constData());
|
||||
fprintf(out, " return target->setBinding(thisPtr->%s, binding);\n", property.accessor.constData());
|
||||
if (isNotifiedProperty)
|
||||
fprintf(out, " return target->setBinding(thisPtr->%s, binding);\n", property.accessor.constData());
|
||||
else
|
||||
fprintf(out, " return target->setBinding(binding);\n");
|
||||
fprintf(out, " else\n");
|
||||
fprintf(out, " return false;\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1387,8 +1387,19 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
|
|||
checkIsFunction(propDef.designable, "DESIGNABLE");
|
||||
break;
|
||||
case 'N': if (l != "NOTIFY") error(2);
|
||||
propDef.notify = v;
|
||||
break;
|
||||
if (v == "false") {
|
||||
if (!propDef.isQProperty)
|
||||
error(1);
|
||||
propDef.isQPropertyWithNotifier = false;
|
||||
break;
|
||||
} else if (v == "true") {
|
||||
if (!propDef.isQProperty)
|
||||
error(1);
|
||||
break;
|
||||
} else {
|
||||
propDef.notify = v;
|
||||
break;
|
||||
}
|
||||
case 'U': if (l != "USER") error(2);
|
||||
propDef.user = v + v2;
|
||||
checkIsFunction(propDef.user, "USER");
|
||||
|
|
@ -1543,7 +1554,7 @@ void Moc::parsePrivateQProperty(ClassDef *def)
|
|||
propDef.qpropertyname = stored ? name : (name + "()");
|
||||
|
||||
def->privateQProperties += PrivateQPropertyDef {
|
||||
type, name, setter, accessor, propDef.qpropertyname
|
||||
type, name, setter, accessor, propDef.qpropertyname, propDef.isQPropertyWithNotifier
|
||||
};
|
||||
|
||||
if (propDef.read.isEmpty())
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ struct PrivateQPropertyDef
|
|||
QByteArray setter;
|
||||
QByteArray accessor;
|
||||
QByteArray storage;
|
||||
bool isNotifiedProperty;
|
||||
};
|
||||
Q_DECLARE_TYPEINFO(PrivateQPropertyDef, Q_MOVABLE_TYPE);
|
||||
|
||||
|
|
|
|||
|
|
@ -4170,11 +4170,13 @@ class ClassWithPrivateQPropertyShim :public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
Q_PRIVATE_QPROPERTY(d_func(), int, testProperty, setTestProperty, NOTIFY testPropertyChanged)
|
||||
Q_PRIVATE_QPROPERTY(d_func(), int, testProperty2, setTestProperty2, NOTIFY false)
|
||||
Q_PRIVATE_QPROPERTY(d_func(), int, lazyTestProperty, setLazyTestProperty,
|
||||
NOTIFY lazyTestPropertyChanged STORED false)
|
||||
|
||||
Q_PRIVATE_QPROPERTIES_BEGIN
|
||||
Q_PRIVATE_QPROPERTY_IMPL(testProperty)
|
||||
Q_PRIVATE_QPROPERTY_IMPL(testProperty2)
|
||||
Q_PRIVATE_QPROPERTY_IMPL(lazyTestProperty)
|
||||
Q_PRIVATE_QPROPERTIES_END
|
||||
|
||||
|
|
@ -4192,6 +4194,7 @@ public:
|
|||
|
||||
void onTestPropertyChanged() { q->testPropertyChanged(); }
|
||||
QNotifiedProperty<int, &Private::onTestPropertyChanged> testProperty;
|
||||
QProperty<int> testProperty2;
|
||||
|
||||
void onLazyTestPropertyChanged() { q->lazyTestPropertyChanged(); }
|
||||
|
||||
|
|
@ -4258,6 +4261,10 @@ void tst_Moc::privateQPropertyShim()
|
|||
testObject.setLazyTestProperty(400);
|
||||
QVERIFY(!testObject.lazyTestProperty.hasBinding());
|
||||
QCOMPARE(testObject.lazyTestProperty(), 400);
|
||||
|
||||
// mo generates correct code for plain QProperty in PIMPL
|
||||
testObject.testProperty2.setValue(42);
|
||||
QCOMPARE(testObject.testProperty2.value(), 42);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Moc)
|
||||
|
|
|
|||
Loading…
Reference in New Issue