From ba96602c73e28e91fa25282d5ea9c65ce8a0269e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 5 Jul 2018 14:16:40 +0200 Subject: shiboken: Add support for const Foo* fields Task-number: PYSIDE-304 Task-number: PYSIDE-672 Change-Id: Ic0e8e9ada594f27a8224adfb43847b3b8149c33d Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Christian Tismer --- .../tests/QtWidgets/python_properties_test.py | 2 ++ .../shiboken2/generator/shiboken2/cppgenerator.cpp | 27 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'sources') diff --git a/sources/pyside2/tests/QtWidgets/python_properties_test.py b/sources/pyside2/tests/QtWidgets/python_properties_test.py index f5bcf5eb8..f4e46f2bd 100644 --- a/sources/pyside2/tests/QtWidgets/python_properties_test.py +++ b/sources/pyside2/tests/QtWidgets/python_properties_test.py @@ -39,6 +39,8 @@ class Properties(unittest.TestCase): p = QtWidgets.QStyleOptionViewItem() self.assertTrue(isinstance(p.locale, QtCore.QLocale)) + # PSYIDE-304, can assign to a "const QWidget *" field + p.widget = None if __name__ == '__main__': unittest.main() diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index f868c281d..380820f24 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -220,6 +220,21 @@ static QString chopType(QString s) return s; } +// Helper for field setters: Check for "const QWidget *" (settable field), +// but not "int *const" (read-only field). +static bool isPointerToConst(const AbstractMetaType *t) +{ + const AbstractMetaType::Indirections &indirections = t->indirectionsV(); + return t->isConstant() && !indirections.isEmpty() + && indirections.constLast() != Indirection::ConstPointer; +} + +static inline bool canGenerateFieldSetter(const AbstractMetaField *field) +{ + const AbstractMetaType *type = field->type(); + return !type->isConstant() || isPointerToConst(type); +} + /*! Function used to write the class generated binding code on the buffer \param s the output buffer @@ -551,7 +566,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) if (metaField->isStatic()) continue; writeGetterFunction(s, metaField, classContext); - if (!metaField->type()->isConstant()) + if (canGenerateFieldSetter(metaField)) writeSetterFunction(s, metaField, classContext); s << endl; } @@ -562,10 +577,12 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) if (metaField->isStatic()) continue; - bool hasSetter = !metaField->type()->isConstant(); s << INDENT << "{const_cast(\"" << metaField->name() << "\"), "; - s << cpythonGetterFunctionName(metaField); - s << ", " << (hasSetter ? cpythonSetterFunctionName(metaField) : QLatin1String("0")); + s << cpythonGetterFunctionName(metaField) << ", "; + if (canGenerateFieldSetter(metaField)) + s << cpythonSetterFunctionName(metaField); + else + s << '0'; s << "}," << endl; } s << INDENT << "{0} // Sentinel" << endl; @@ -4224,6 +4241,8 @@ void CppGenerator::writeSetterFunction(QTextStream &s, s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_local);" << endl; s << INDENT << cppField << " = cppOut_local"; } else { + if (isPointerToConst(fieldType)) + s << "const "; s << getFullTypeNameWithoutModifiers(fieldType); s << QString::fromLatin1("*").repeated(fieldType->indirections()) << "& cppOut_ptr = "; s << cppField << ';' << endl; -- cgit v1.2.3