diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-07-13 15:20:46 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-07-14 17:06:46 +0200 |
commit | 8cdaeb26552313e7b9d67fa062a3d9ff597c2e06 (patch) | |
tree | 7ba18ecdb22417bb38c756f5379c6dd991b5000a | |
parent | bb6a73260ec8272647265f42180963604ad0f755 (diff) |
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>
-rw-r--r-- | src/tools/moc/generator.cpp | 51 | ||||
-rw-r--r-- | src/tools/moc/moc.cpp | 17 | ||||
-rw-r--r-- | src/tools/moc/moc.h | 1 | ||||
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 7 |
4 files changed, 63 insertions, 13 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index dda022050c..1853d9df52 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -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"); } diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 6acabbf2ce..ad9c684541 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -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()) diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index b4bb105601..487e04e081 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -156,6 +156,7 @@ struct PrivateQPropertyDef QByteArray setter; QByteArray accessor; QByteArray storage; + bool isNotifiedProperty; }; Q_DECLARE_TYPEINFO(PrivateQPropertyDef, Q_MOVABLE_TYPE); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 4ea376df68..1432018647 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -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) |