aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2020-08-01 14:29:45 +0200
committerChristian Tismer <tismer@stackless.com>2020-09-16 14:56:30 +0200
commitdedbc42b569d0dc25de10712168b99d0844c8e50 (patch)
tree1709327427dfa644d754d85b6a25ba110e1ac378 /sources/shiboken2/generator/shiboken2/cppgenerator.cpp
parent850b6faeaa580176863b3933e13c08b467720937 (diff)
feature_select: Implement True Properties
This feature is now almost fully implemented. TODO: Static properties like `QtWidgets.QApplication.platformName` are skipped for now. They need support by the meta class. Maybe this is a reason to use QtCore.Property instead of vanilla Python property and improve it. With the new infrastructure, we can also consider to add properties which have no equivalent in the Qt implementation. A prominent example is "central_widget". Change-Id: Ia0e32e41de8ab72e3bba74878e61bcbac6da50ea Task-number: PYSIDE-1019 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/shiboken2/generator/shiboken2/cppgenerator.cpp')
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp66
1 files changed, 65 insertions, 1 deletions
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 8dba64818..d38463e2c 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -288,6 +288,34 @@ static inline bool canGenerateFieldSetter(const AbstractMetaField *field)
return !type->isConstant() || isPointerToConst(type);
}
+static bool isStdSetterName(QString setterName, QString propertyName)
+{
+ return setterName.size() == propertyName.size() + 3
+ && setterName.startsWith(QLatin1String("set"))
+ && setterName.endsWith(propertyName.rightRef(propertyName.size() - 1))
+ && setterName.at(3) == propertyName.at(0).toUpper();
+}
+
+static QString buildPropertyString(QPropertySpec *spec)
+{
+ QString text;
+ text += QLatin1Char('"');
+ text += spec->name();
+ text += QLatin1Char(':');
+
+ if (spec->read() != spec->name())
+ text += spec->read();
+
+ if (!spec->write().isEmpty()) {
+ text += QLatin1Char(':');
+ if (!isStdSetterName(spec->write(), spec->name()))
+ text += spec->write();
+ }
+
+ text += QLatin1Char('"');
+ return text;
+}
+
/*!
Function used to write the class generated binding code on the buffer
\param s the output buffer
@@ -556,6 +584,22 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo
// Write single method definitions
s << singleMethodDefinitions;
+ if (usePySideExtensions()) {
+ // PYSIDE-1019: Write a compressed list of all properties `name:getter[:setter]`.
+ // Default values are suppressed.
+ QStringList sorter;
+ for (const auto spec : metaClass->propertySpecs())
+ sorter.append(buildPropertyString(spec));
+ sorter.sort();
+
+ s << '\n';
+ s << "static const char *" << className << "_properties[] = {\n";
+ for (const auto &entry : qAsConst(sorter))
+ s << INDENT << entry << ",\n";
+ s << INDENT << NULL_PTR << " // Sentinel\n";
+ s << "};\n\n";
+ }
+
// Write methods definition
s << "static PyMethodDef " << className << "_methods[] = {\n";
s << methodsDefinitions << Qt::endl;
@@ -951,8 +995,22 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
s << INDENT << returnStatement << '\n';
}
+ //PYSIDE-1019: Add info about properties.
+ int propFlag = 0;
+ if (func->isPropertyReader())
+ propFlag |= 1;
+ if (func->isPropertyWriter())
+ propFlag |= 2;
+ if (propFlag && func->isStatic())
+ propFlag |= 4;
+ QString propStr;
+ if (propFlag)
+ propStr = QString::number(propFlag) + QLatin1Char(':');
+
s << INDENT << "static PyObject *nameCache[2] = {};\n";
- s << INDENT << "static const char *funcName = \"" << funcName << "\";\n";
+ if (propFlag)
+ s << INDENT << "// This method belongs to a property.\n";
+ s << INDENT << "static const char *funcName = \"" << propStr << funcName << "\";\n";
s << INDENT << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR
<< "(Shiboken::BindingManager::instance().getOverride(this, nameCache, funcName));\n";
s << INDENT << "if (" << PYTHON_OVERRIDE_VAR << ".isNull()) {\n";
@@ -5159,6 +5217,12 @@ void CppGenerator::writeClassRegister(QTextStream &s,
s << INDENT << ");\n";
s << INDENT << Qt::endl;
+ if (usePySideExtensions()) {
+ QString className = metaClass->qualifiedCppName();
+ s << INDENT << "SbkObjectType_SetPropertyStrings(reinterpret_cast<PyTypeObject *>(" << typePtr << "), "
+ << chopType(pyTypeName) << "_properties);\n";
+ }
+
if (!classContext.forSmartPointer())
s << INDENT << cpythonTypeNameExt(classTypeEntry) << Qt::endl;
else