aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-09-23 07:37:12 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-09-23 14:06:46 +0200
commita8b52c80ac54602001b3988ea5f37805c6fe4eb2 (patch)
treee60fb37afd0c6dfb0c184a9d9ab81132ce7ca69d /sources/shiboken2
parent8526bf4f922df87a0c51d9447bf498a3290dfdbf (diff)
shiboken2: Add a way of specifying properties in typesystem XML
Add a list of TypeSystemProperty to ComplexTypeEntry, parse it from XML and add those properties in AbstractMetaBuilderPrivate::parseQ_Properties(). Task-number: PYSIDE-1019 Change-Id: Idf6ecde7c9de6bf1e56be423921672152e97de70 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp23
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp9
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h1
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp9
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h1
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h4
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.cpp35
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.h3
-rw-r--r--sources/shiboken2/doc/typesystem_manipulating_objects.rst32
9 files changed, 115 insertions, 2 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index d9cf69e05..4197c4cfa 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -2790,7 +2790,8 @@ void AbstractMetaBuilderPrivate::parseQ_Properties(AbstractMetaClass *metaClass,
{
const QStringList scopes = currentScope()->qualifiedName();
QString errorMessage;
- for (int i = 0; i < declarations.size(); ++i) {
+ int i = 0;
+ for (; i < declarations.size(); ++i) {
if (auto spec = QPropertySpec::parseQ_Property(this, metaClass, declarations.at(i), scopes, &errorMessage)) {
spec->setIndex(i);
metaClass->addPropertySpec(spec);
@@ -2801,6 +2802,26 @@ void AbstractMetaBuilderPrivate::parseQ_Properties(AbstractMetaClass *metaClass,
qCWarning(lcShiboken, "%s", qPrintable(message));
}
}
+
+ // User-added properties
+ auto typeEntry = metaClass->typeEntry();
+ for (const TypeSystemProperty &tp : typeEntry->properties()) {
+ QPropertySpec *spec = nullptr;
+ if (metaClass->propertySpecByName(tp.name))
+ errorMessage = msgPropertyExists(metaClass->name(), tp.name);
+ else
+ spec = QPropertySpec::fromTypeSystemProperty(this, metaClass, tp, scopes, &errorMessage);
+
+ if (spec) {
+ spec->setIndex(i++);
+ metaClass->addPropertySpec(spec);
+ } else {
+ QString message;
+ QTextStream str(&message);
+ str << typeEntry->sourceLocation() << errorMessage;
+ qCWarning(lcShiboken, "%s", qPrintable(message));
+ }
+ }
}
static AbstractMetaFunction* findCopyCtor(AbstractMetaClass* cls)
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 9a512cd44..0caaaf40c 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -1695,6 +1695,15 @@ bool AbstractMetaClass::hasProtectedMembers() const
return hasProtectedFields() || hasProtectedFunctions();
}
+QPropertySpec *AbstractMetaClass::propertySpecByName(const QString &name) const
+{
+ for (auto propertySpec : m_propertySpecs) {
+ if (name == propertySpec->name())
+ return propertySpec;
+ }
+ return nullptr;
+}
+
QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const
{
for (const auto &propertySpec : m_propertySpecs) {
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 38ba316b7..c17051f45 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -1607,6 +1607,7 @@ public:
return m_propertySpecs;
}
+ QPropertySpec *propertySpecByName(const QString &name) const;
QPropertySpec *propertySpecForRead(const QString &name) const;
QPropertySpec *propertySpecForWrite(const QString &name) const;
QPropertySpec *propertySpecForReset(const QString &name) const;
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index 031c74324..95dcda558 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -378,6 +378,13 @@ QString msgPropertyTypeParsingFailed(const QString &name, const QString &typeNam
return result;
}
+QString msgPropertyExists(const QString &className, const QString &name)
+{
+ return QLatin1String("class ") + className
+ + QLatin1String(" already has a property \"") + name
+ + QLatin1String("\" (defined by Q_PROPERTY).");
+}
+
// docparser.cpp
QString msgCannotFindDocumentation(const QString &fileName,
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
index 191985d3e..3f1a8650b 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -129,6 +129,7 @@ QString msgNamespaceToBeExtendedNotFound(const QString &namespaceName, const QSt
QString msgPropertyTypeParsingFailed(const QString &name, const QString &typeName,
const QString &why);
+QString msgPropertyExists(const QString &className, const QString &name);
QString msgCannotFindDocumentation(const QString &fileName,
const char *what, const QString &name,
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 08d4cf311..0c8f85738 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -1268,6 +1268,9 @@ public:
return m_fieldMods;
}
+ const QList<TypeSystemProperty> &properties() const { return m_properties; }
+ void addProperty(const TypeSystemProperty &p) { m_properties.append(p); }
+
QString defaultSuperclass() const
{
return m_defaultSuperclass;
@@ -1374,6 +1377,7 @@ private:
AddedFunctionList m_addedFunctions;
FunctionModificationList m_functionMods;
FieldModificationList m_fieldMods;
+ QList<TypeSystemProperty> m_properties;
QString m_defaultConstructor;
QString m_defaultSuperclass;
QString m_qualifiedCppName;
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
index 44616da0a..04aadbb63 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
@@ -366,6 +366,7 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
{u"object-type", StackElement::ObjectTypeEntry},
{u"parent", StackElement::ParentOwner},
{u"primitive-type", StackElement::PrimitiveTypeEntry},
+ {u"property", StackElement::Property},
{u"reference-count", StackElement::ReferenceCount},
{u"reject-enum-value", StackElement::RejectEnumValue},
{u"rejection", StackElement::Rejection},
@@ -2235,6 +2236,36 @@ bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &,
return true;
}
+bool TypeSystemParser::parseProperty(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if ((topElement.type & StackElement::ComplexTypeEntryMask) == 0) {
+ m_error = QString::fromLatin1("Add property requires a complex type as parent"
+ ", was=%1").arg(topElement.type, 0, 16);
+ return false;
+ }
+
+ TypeSystemProperty property;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == nameAttribute()) {
+ property.name = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("get")) {
+ property.read = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("type")) {
+ property.type = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("set")) {
+ property.write = attributes->takeAt(i).value().toString();
+ }
+ }
+ if (!property.isValid()) {
+ m_error = QLatin1String("<property> element is missing required attibutes (name/type/get).");
+ return false;
+ }
+ static_cast<ComplexTypeEntry *>(topElement.entry)->addProperty(property);
+ return true;
+}
+
bool TypeSystemParser::parseModifyFunction(const QXmlStreamReader &reader,
const StackElement &topElement,
QXmlStreamAttributes *attributes)
@@ -3000,6 +3031,10 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
if (!parseAddFunction(reader, topElement, &attributes))
return false;
break;
+ case StackElement::Property:
+ if (!parseProperty(reader, topElement, &attributes))
+ return false;
+ break;
case StackElement::ModifyFunction:
if (!parseModifyFunction(reader, topElement, &attributes))
return false;
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.h b/sources/shiboken2/ApiExtractor/typesystemparser.h
index 66d61f4a1..a36063f54 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.h
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.h
@@ -88,6 +88,7 @@ class StackElement
TargetToNative = 0x1200,
AddConversion = 0x1300,
SystemInclude = 0x1400,
+ Property = 0x1500,
SimpleMask = 0x3f00,
// Code snip tags (0x1000, 0x2000, ... , 0xf000)
@@ -232,6 +233,8 @@ private:
bool parseModifyField(const QXmlStreamReader &, QXmlStreamAttributes *);
bool parseAddFunction(const QXmlStreamReader &, const StackElement &topElement,
QXmlStreamAttributes *);
+ bool parseProperty(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
bool parseModifyFunction(const QXmlStreamReader &, const StackElement &topElement,
QXmlStreamAttributes *);
bool parseReplaceDefaultExpression(const QXmlStreamReader &,
diff --git a/sources/shiboken2/doc/typesystem_manipulating_objects.rst b/sources/shiboken2/doc/typesystem_manipulating_objects.rst
index c14c4e941..98f503074 100644
--- a/sources/shiboken2/doc/typesystem_manipulating_objects.rst
+++ b/sources/shiboken2/doc/typesystem_manipulating_objects.rst
@@ -233,3 +233,35 @@ conversion-rule
.. note:: You can also use the conversion-rule node to specify :ref:`how the conversion of a single function argument should be done in a function <conversion-rule>`.
The ``file`` and ``snippet`` attributes are also supported (see :ref:`inject-code` nodes).
+
+
+property
+^^^^^^^^
+
+ The ``property`` element allows you to add properties complementing the
+ properties obtained from the ``Q_PROPERTY`` macro in Qt-based code when using
+ the PySide2 extension. It may appear as a child of a complex type such as
+ ``object-type`` or ``value-type``.
+
+ .. code-block:: xml
+
+ <property name="..." type="..." get="..." set="..." since="..."/>
+
+ The ``name`` attribute specifies the name of the property, the ``type``
+ attribute specifies the C++ type and the ``get`` attribute specifies the
+ name of the accessor function.
+
+ The optional ``set`` attribute specifies name of the setter function.
+
+ The optional ``since`` attribute specifies the API version when this
+ property appears.
+
+ For example:
+
+ .. code-block:: xml
+
+ <object-type name="QMainWindow">
+ <property name="centralWidget" type="QWidget *" get="centralWidget" set="setCentralWidget"/>
+
+ specifies ``centralWidget`` to be a Python property in addition to the normal properties
+ of ``QMainWindow`` defined for Qt Designer usage.