diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-09-23 07:37:12 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-09-23 14:06:46 +0200 |
commit | a8b52c80ac54602001b3988ea5f37805c6fe4eb2 (patch) | |
tree | e60fb37afd0c6dfb0c184a9d9ab81132ce7ca69d /sources/shiboken2 | |
parent | 8526bf4f922df87a0c51d9447bf498a3290dfdbf (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.cpp | 23 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetalang.cpp | 9 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetalang.h | 1 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/messages.cpp | 9 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/messages.h | 1 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.h | 4 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystemparser.cpp | 35 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystemparser.h | 3 | ||||
-rw-r--r-- | sources/shiboken2/doc/typesystem_manipulating_objects.rst | 32 |
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. |