aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-09-05 14:49:25 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-09-06 13:09:37 +0200
commit21e1bfafa1ed86adfa2e9ec4e990a582e4a20266 (patch)
treebf4e020ba25c6752c4e8674657898502cbf06e0c /sources/shiboken6
parent429961686dfce2b2a3a5fba868a2664f281fc824 (diff)
shiboken6: Refactor Handling of CustomConversion
CustomConversion can appear in PrimitiveTypeEntry, ContainerTypeEntry and ValueTypeEntry. Move the field from the base class TypeEntry there. The deprecated QString targetConversionRule() was only implemented for ValueTypeEntry; move it from the base class TypeEntry there. In the original code, CustomConversion was stored as a raw pointer in TypeEntry. This is bad since TypeEntry are cloneable. Use a QSharedPointer to prevent crashes. Change-Id: Ia74219671bbd5792398f9711b4a020f5c9825b1b Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/shiboken6')
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractor.cpp5
-rw-r--r--sources/shiboken6/ApiExtractor/containertypeentry.h4
-rw-r--r--sources/shiboken6/ApiExtractor/customconversion.h7
-rw-r--r--sources/shiboken6/ApiExtractor/messages.cpp8
-rw-r--r--sources/shiboken6/ApiExtractor/messages.h2
-rw-r--r--sources/shiboken6/ApiExtractor/primitivetypeentry.h4
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp5
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp21
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp149
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.h15
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_typedefs.h2
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp67
-rw-r--r--sources/shiboken6/ApiExtractor/valuetypeentry.h14
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp57
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h9
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp18
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h3
17 files changed, 257 insertions, 133 deletions
diff --git a/sources/shiboken6/ApiExtractor/apiextractor.cpp b/sources/shiboken6/ApiExtractor/apiextractor.cpp
index 6958c8c8f..d55a68fad 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractor.cpp
@@ -22,6 +22,7 @@
#include "smartpointertypeentry.h"
#include "typedefentry.h"
#include "typesystemtypeentry.h"
+#include "valuetypeentry.h"
#include "qtcompat.h"
@@ -612,8 +613,8 @@ static void getCode(QStringList &code, const TypeEntry *type)
else if (type->isTypeSystem())
getCode(code, static_cast<const TypeSystemTypeEntry *>(type)->codeSnips());
- CustomConversion *customConversion = type->customConversion();
- if (!customConversion)
+ auto customConversion = CustomConversion::getCustomConversion(type);
+ if (customConversion.isNull())
return;
if (!customConversion->nativeToTargetConversion().isEmpty())
diff --git a/sources/shiboken6/ApiExtractor/containertypeentry.h b/sources/shiboken6/ApiExtractor/containertypeentry.h
index 34ee08808..50c3c91c9 100644
--- a/sources/shiboken6/ApiExtractor/containertypeentry.h
+++ b/sources/shiboken6/ApiExtractor/containertypeentry.h
@@ -36,6 +36,10 @@ public:
bool generateOpaqueContainer(const QString &instantiation) const;
QString opaqueContainerName(const QString &instantiation) const;
+ bool hasCustomConversion() const;
+ void setCustomConversion(const CustomConversionPtr &customConversion);
+ CustomConversionPtr customConversion() const;
+
TypeEntry *clone() const override;
#ifndef QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/ApiExtractor/customconversion.h b/sources/shiboken6/ApiExtractor/customconversion.h
index 172600d48..3a4766fea 100644
--- a/sources/shiboken6/ApiExtractor/customconversion.h
+++ b/sources/shiboken6/ApiExtractor/customconversion.h
@@ -5,6 +5,7 @@
#define CUSTOMCONVERSION_H
#include "typesystem_enums.h"
+#include "typesystem_typedefs.h"
#include <QtCore/QList>
#include <QtCore/QString>
@@ -14,7 +15,7 @@ class TypeEntry;
class CustomConversion
{
public:
- CustomConversion(TypeEntry* ownerType);
+ explicit CustomConversion(const TypeEntry* ownerType);
~CustomConversion();
const TypeEntry* ownerType() const;
@@ -56,6 +57,10 @@ public:
void addTargetToNativeConversion(const QString& sourceTypeName,
const QString& sourceTypeCheck,
const QString& conversion = QString());
+
+ /// Return the custom conversion of a type; helper for type system parser
+ static CustomConversionPtr getCustomConversion(const TypeEntry *type);
+
private:
struct CustomConversionPrivate;
CustomConversionPrivate* m_d;
diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp
index e91aef5cc..29fb23edb 100644
--- a/sources/shiboken6/ApiExtractor/messages.cpp
+++ b/sources/shiboken6/ApiExtractor/messages.cpp
@@ -931,3 +931,11 @@ QString msgArgumentClassNotFound(const AbstractMetaFunctionCPtr &func,
<< "\" for \"" << func->classQualifiedSignature() << "\" not found!";
return result;
}
+
+QString msgMissingCustomConversion(const TypeEntry *t)
+{
+ QString result;
+ QTextStream(&result) << "Entry \"" << t->qualifiedCppName()
+ << "\" is missing a custom conversion.";
+ return result;
+}
diff --git a/sources/shiboken6/ApiExtractor/messages.h b/sources/shiboken6/ApiExtractor/messages.h
index 4a23c6487..4edab4b44 100644
--- a/sources/shiboken6/ApiExtractor/messages.h
+++ b/sources/shiboken6/ApiExtractor/messages.h
@@ -247,4 +247,6 @@ QString msgUnknownCheckFunction(const TypeEntry *t);
QString msgArgumentClassNotFound(const AbstractMetaFunctionCPtr &func,
const TypeEntry *t);
+QString msgMissingCustomConversion(const TypeEntry *t);
+
#endif // MESSAGES_H
diff --git a/sources/shiboken6/ApiExtractor/primitivetypeentry.h b/sources/shiboken6/ApiExtractor/primitivetypeentry.h
index d0b50aa9c..e3e530f38 100644
--- a/sources/shiboken6/ApiExtractor/primitivetypeentry.h
+++ b/sources/shiboken6/ApiExtractor/primitivetypeentry.h
@@ -53,6 +53,10 @@ public:
bool preferredTargetLangType() const;
void setPreferredTargetLangType(bool b);
+ bool hasCustomConversion() const;
+ void setCustomConversion(const CustomConversionPtr &customConversion);
+ CustomConversionPtr customConversion() const;
+
TypeEntry *clone() const override;
#ifndef QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
index d1172ecc0..261ff4a6c 100644
--- a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
@@ -8,6 +8,7 @@
#include <modifications.h>
#include <textstream.h>
#include <complextypeentry.h>
+#include <valuetypeentry.h>
#include <qtcompat.h>
@@ -64,7 +65,9 @@ void TestCodeInjections::testReadFile()
QCOMPARE(classA->typeEntry()->codeSnips().size(), 1);
QString code = classA->typeEntry()->codeSnips().constFirst().code();
QVERIFY(code.indexOf(expected) != -1);
- code = classA->typeEntry()->targetConversionRule();
+ QVERIFY(classA->typeEntry()->isValue());
+ auto *vte = static_cast<const ValueTypeEntry *>(classA->typeEntry());
+ code = vte->targetConversionRule();
QVERIFY(code.indexOf(expected) != -1);
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp b/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
index 5f126c5f5..301dbdb95 100644
--- a/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
@@ -7,6 +7,7 @@
#include <complextypeentry.h>
#include <customconversion.h>
#include <primitivetypeentry.h>
+#include <valuetypeentry.h>
#include <qtcompat.h>
@@ -39,8 +40,10 @@ void TestConversionRuleTag::testConversionRuleTagWithFile()
const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
QVERIFY(classA);
const ComplexTypeEntry* typeEntry = classA->typeEntry();
- QVERIFY(typeEntry->hasTargetConversionRule());
- QCOMPARE(typeEntry->targetConversionRule(), QLatin1String(conversionData));
+ QVERIFY(typeEntry->isValue());
+ auto *vte = static_cast<const ValueTypeEntry *>(typeEntry);
+ QVERIFY(vte->hasTargetConversionRule());
+ QCOMPARE(vte->targetConversionRule(), QLatin1String(conversionData));
}
void TestConversionRuleTag::testConversionRuleTagReplace()
@@ -87,8 +90,8 @@ void TestConversionRuleTag::testConversionRuleTagReplace()
PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType(u"A"_s);
QVERIFY(typeA);
- CustomConversion* conversion = typeA->customConversion();
- QVERIFY(conversion);
+ QVERIFY(typeA->hasCustomConversion());
+ auto conversion = typeA->customConversion();
QCOMPARE(typeA, conversion->ownerType());
QCOMPARE(conversion->nativeToTargetConversion().simplified(),
@@ -153,8 +156,10 @@ if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\n\
auto *classA = AbstractMetaClass::findClass(builder->classes(), u"Date");
QVERIFY(classA);
- CustomConversion* conversion = classA->typeEntry()->customConversion();
- QVERIFY(conversion);
+ QVERIFY(classA->typeEntry()->isValue());
+ auto *vte = static_cast<const ValueTypeEntry *>(classA->typeEntry());
+ QVERIFY(vte->hasCustomConversion());
+ auto conversion = vte->customConversion();
QCOMPARE(conversion->nativeToTargetConversion(), QString());
@@ -216,8 +221,8 @@ void TestConversionRuleTag::testConversionRuleTagWithInsertTemplate()
PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType(u"A"_s);
QVERIFY(typeA);
- CustomConversion* conversion = typeA->customConversion();
- QVERIFY(conversion);
+ QVERIFY(typeA->hasCustomConversion());
+ auto conversion = typeA->customConversion();
QCOMPARE(typeA, conversion->ownerType());
QCOMPARE(conversion->nativeToTargetConversion().trimmed(),
diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp
index 9db414563..50cd01695 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystem.cpp
@@ -53,7 +53,7 @@ class TypeEntryPrivate
public:
explicit TypeEntryPrivate(const QString &entryName, TypeEntry::Type t, const QVersionNumber &vr,
const TypeEntry *parent);
- virtual ~TypeEntryPrivate();
+ virtual ~TypeEntryPrivate() = default;
QString shortName() const;
@@ -66,9 +66,7 @@ public:
mutable QString m_cachedTargetLangEntryName; // "Bar"
IncludeList m_extraIncludes;
Include m_include;
- QString m_targetConversionRule;
QVersionNumber m_version;
- CustomConversion *m_customConversion = nullptr;
SourceLocation m_sourceLocation; // XML file
TypeEntry::CodeGeneration m_codeGeneration = TypeEntry::GenerateCode;
TypeEntry *m_viewOn = nullptr;
@@ -91,11 +89,6 @@ TypeEntryPrivate::TypeEntryPrivate(const QString &entryName, TypeEntry::Type t,
{
}
-TypeEntryPrivate::~TypeEntryPrivate()
-{
- delete m_customConversion;
-}
-
TypeEntry::TypeEntry(const QString &entryName, TypeEntry::Type t, const QVersionNumber &vr,
const TypeEntry *parent) :
TypeEntry(new TypeEntryPrivate(entryName, t, vr, parent))
@@ -143,26 +136,11 @@ void TypeEntry::setInclude(const Include &inc)
}
}
-void TypeEntry::setTargetConversionRule(const QString &conversionRule)
-{
- m_d->m_targetConversionRule = conversionRule;
-}
-
-QString TypeEntry::targetConversionRule() const
-{
- return m_d->m_targetConversionRule;
-}
-
QVersionNumber TypeEntry::version() const
{
return m_d->m_version;
}
-bool TypeEntry::hasTargetConversionRule() const
-{
- return !m_d->m_targetConversionRule.isEmpty();
-}
-
bool TypeEntry::isCppPrimitive() const
{
if (!isPrimitive())
@@ -567,21 +545,6 @@ bool TypeEntry::isComplex() const
return false;
}
-bool TypeEntry::hasCustomConversion() const
-{
- return m_d->m_customConversion != nullptr;
-}
-
-void TypeEntry::setCustomConversion(CustomConversion* customConversion)
-{
- m_d->m_customConversion = customConversion;
-}
-
-CustomConversion* TypeEntry::customConversion() const
-{
- return m_d->m_customConversion;
-}
-
TypeEntry *TypeEntry::viewOn() const
{
return m_d->m_viewOn;
@@ -885,8 +848,9 @@ public:
}
QString m_defaultConstructor;
- uint m_preferredTargetLangType : 1;
+ CustomConversionPtr m_customConversion;
PrimitiveTypeEntry* m_referencedTypeEntry = nullptr;
+ uint m_preferredTargetLangType : 1;
};
PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &entryName, const QVersionNumber &vr,
@@ -961,6 +925,24 @@ void PrimitiveTypeEntry::setPreferredTargetLangType(bool b)
d->m_preferredTargetLangType = b;
}
+bool PrimitiveTypeEntry::hasCustomConversion() const
+{
+ S_D(const PrimitiveTypeEntry);
+ return !d->m_customConversion.isNull();
+}
+
+void PrimitiveTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
+{
+ S_D(PrimitiveTypeEntry);
+ d->m_customConversion = customConversion;
+}
+
+CustomConversionPtr PrimitiveTypeEntry::customConversion() const
+{
+ S_D(const PrimitiveTypeEntry);
+ return d->m_customConversion;
+}
+
TypeEntry *PrimitiveTypeEntry::clone() const
{
S_D(const PrimitiveTypeEntry);
@@ -1805,6 +1787,7 @@ public:
}
OpaqueContainers m_opaqueContainers;
+ CustomConversionPtr m_customConversion;
ContainerTypeEntry::ContainerKind m_containerKind;
};
@@ -1852,6 +1835,24 @@ QString ContainerTypeEntry::opaqueContainerName(const QString &instantiation) co
return it != d->m_opaqueContainers.cend() ? it->name : QString{};
}
+bool ContainerTypeEntry::hasCustomConversion() const
+{
+ S_D(const ContainerTypeEntry);
+ return !d->m_customConversion.isNull();
+}
+
+void ContainerTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
+{
+ S_D(ContainerTypeEntry);
+ d->m_customConversion = customConversion;
+}
+
+CustomConversionPtr ContainerTypeEntry::customConversion() const
+{
+ S_D(const ContainerTypeEntry);
+ return d->m_customConversion;
+}
+
TypeEntry *ContainerTypeEntry::clone() const
{
S_D(const ContainerTypeEntry);
@@ -2126,12 +2127,58 @@ void NamespaceTypeEntry::setGenerateUsing(bool generateUsing)
}
// ----------------- ValueTypeEntry
+
+class ValueTypeEntryPrivate : public ComplexTypeEntryPrivate
+{
+public:
+ using ComplexTypeEntryPrivate::ComplexTypeEntryPrivate;
+
+ QString m_targetConversionRule;
+ CustomConversionPtr m_customConversion;
+};
+
ValueTypeEntry::ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
const TypeEntry *parent) :
- ComplexTypeEntry(entryName, BasicValueType, vr, parent)
+ ComplexTypeEntry(new ValueTypeEntryPrivate(entryName, BasicValueType, vr, parent))
{
}
+bool ValueTypeEntry::hasCustomConversion() const
+{
+ S_D(const ValueTypeEntry);
+ return !d->m_customConversion.isNull();
+}
+
+void ValueTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
+{
+ S_D(ValueTypeEntry);
+ d->m_customConversion = customConversion;
+}
+
+CustomConversionPtr ValueTypeEntry::customConversion() const
+{
+ S_D(const ValueTypeEntry);
+ return d->m_customConversion;
+}
+
+void ValueTypeEntry::setTargetConversionRule(const QString &conversionRule)
+{
+ S_D(ValueTypeEntry);
+ d->m_targetConversionRule = conversionRule;
+}
+
+QString ValueTypeEntry::targetConversionRule() const
+{
+ S_D(const ValueTypeEntry);
+ return d->m_targetConversionRule;
+}
+
+bool ValueTypeEntry::hasTargetConversionRule() const
+{
+ S_D(const ValueTypeEntry);
+ return !d->m_targetConversionRule.isEmpty();
+}
+
bool ValueTypeEntry::isValue() const
{
return true;
@@ -2139,8 +2186,8 @@ bool ValueTypeEntry::isValue() const
TypeEntry *ValueTypeEntry::clone() const
{
- S_D(const ComplexTypeEntry);
- return new ValueTypeEntry(new ComplexTypeEntryPrivate(*d));
+ S_D(const ValueTypeEntry);
+ return new ValueTypeEntry(new ValueTypeEntryPrivate(*d));
}
ValueTypeEntry::ValueTypeEntry(ComplexTypeEntryPrivate *d) :
@@ -2179,11 +2226,9 @@ struct CustomConversion::TargetToNativeConversion::TargetToNativeConversionPriva
QString conversion;
};
-CustomConversion::CustomConversion(TypeEntry* ownerType)
+CustomConversion::CustomConversion(const TypeEntry *ownerType)
+ : m_d(new CustomConversionPrivate(ownerType))
{
- m_d = new CustomConversionPrivate(ownerType);
- if (ownerType)
- ownerType->setCustomConversion(this);
}
CustomConversion::~CustomConversion()
@@ -2302,6 +2347,17 @@ void CustomConversion::TargetToNativeConversion::setConversion(const QString& co
m_d->conversion = conversion;
}
+CustomConversionPtr CustomConversion::getCustomConversion(const TypeEntry *type)
+{
+ if (type->isPrimitive())
+ return static_cast<const PrimitiveTypeEntry *>(type)->customConversion();
+ if (type->isContainer())
+ return static_cast<const ContainerTypeEntry *>(type)->customConversion();
+ if (type->isValue())
+ return static_cast<const ValueTypeEntry *>(type)->customConversion();
+ return {};
+}
+
// ----------------- FunctionTypeEntry
class FunctionTypeEntryPrivate : public TypeEntryPrivate
{
@@ -2426,7 +2482,6 @@ void TypeEntry::formatDebug(QDebug &debug) const
FORMAT_NONEMPTY_STRING("package", m_d->m_targetLangPackage)
FORMAT_BOOL("stream", m_d->m_stream)
FORMAT_BOOL("built-in", m_d->m_builtin)
- FORMAT_NONEMPTY_STRING("targetConversionRule", m_d->m_targetConversionRule)
if (m_d->m_viewOn)
debug << ", views=" << m_d->m_viewOn->name();
if (!m_d->m_version.isNull() && m_d->m_version > QVersionNumber(0, 0))
diff --git a/sources/shiboken6/ApiExtractor/typesystem.h b/sources/shiboken6/ApiExtractor/typesystem.h
index 5e22af5f8..e83f03b67 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.h
+++ b/sources/shiboken6/ApiExtractor/typesystem.h
@@ -12,7 +12,6 @@
#include <QtCore/QScopedPointer>
class AbstractMetaType;
-class CustomConversion;
class CustomTypeEntry;
class PrimitiveTypeEntry;
class SourceLocation;
@@ -160,24 +159,10 @@ public:
Include include() const;
void setInclude(const Include &inc);
- // FIXME PYSIDE7: Remove
- /// Set the target type conversion rule
- void setTargetConversionRule(const QString& conversionRule);
-
- /// Returns the target type conversion rule
- QString targetConversionRule() const;
-
QVersionNumber version() const;
- /// TODO-CONVERTER: mark as deprecated
- bool hasTargetConversionRule() const;
-
bool isCppPrimitive() const;
- bool hasCustomConversion() const;
- void setCustomConversion(CustomConversion* customConversion);
- CustomConversion* customConversion() const;
-
// View on: Type to use for function argument conversion, fex
// std::string_view -> std::string for foo(std::string_view).
// cf AbstractMetaType::viewOn()
diff --git a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
index 3c1ad53f8..89081b9ea 100644
--- a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
@@ -13,6 +13,7 @@ class CodeSnip;
class DocModification;
struct AddedFunction;
+class CustomConversion;
class FieldModification;
class FunctionModification;
class TypeEntry;
@@ -20,6 +21,7 @@ class TypeEntry;
using AddedFunctionPtr = QSharedPointer<AddedFunction>;
using AddedFunctionList = QList<AddedFunctionPtr>;
using CodeSnipList = QList<CodeSnip>;
+using CustomConversionPtr = QSharedPointer<CustomConversion>;
using DocModificationList = QList<DocModification>;
using FieldModificationList = QList<FieldModification>;
using FunctionModificationList = QList<FunctionModification>;
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index 3979d462a..310976550 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -137,7 +137,7 @@ static bool isDocumentation(StackElement el)
return el >= StackElement::FirstDocumentation && el <= StackElement::LastDocumentation;
}
-static QList<CustomConversion *> customConversionsForReview;
+static QList<CustomConversionPtr> customConversionsForReview;
// Set a regular expression for rejection from text. By legacy, those are fixed
// strings, except for '*' meaning 'match all'. Enclosing in "^..$"
@@ -876,7 +876,7 @@ bool TypeSystemParser::endElement(StackElement element)
if (m_generate == TypeEntry::GenerateCode) {
TypeDatabase::instance()->addGlobalUserFunctions(top->addedFunctions);
TypeDatabase::instance()->addGlobalUserFunctionModifications(top->functionMods);
- for (CustomConversion *customConversion : qAsConst(customConversionsForReview)) {
+ for (const auto &customConversion : qAsConst(customConversionsForReview)) {
const CustomConversion::TargetToNativeConversions &toNatives = customConversion->targetToNativeConversions();
for (CustomConversion::TargetToNativeConversion *toNative : toNatives)
toNative->setSourceType(m_context->db->findType(toNative->sourceTypeName()));
@@ -931,22 +931,23 @@ bool TypeSystemParser::endElement(StackElement element)
case StackElement::AddConversion:
switch (parserState()) {
case ParserState::PrimitiveTypeNativeToTargetConversion:
- case ParserState::PrimitiveTypeTargetToNativeConversion:
- if (auto *customConversion = top->entry->customConversion()) {
- QString code = top->conversionCodeSnips.constLast().code();
- if (element == StackElement::AddConversion) {
- if (customConversion->targetToNativeConversions().isEmpty()) {
- m_error = u"CustomConversion's target to native conversions missing."_s;
- return false;
- }
- customConversion->targetToNativeConversions().last()->setConversion(code);
- } else {
- customConversion->setNativeToTargetConversion(code);
+ case ParserState::PrimitiveTypeTargetToNativeConversion: {
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (customConversion.isNull()) {
+ m_error = msgMissingCustomConversion(top->entry);
+ return false;
+ }
+ QString code = top->conversionCodeSnips.constLast().code();
+ if (element == StackElement::AddConversion) {
+ if (customConversion->targetToNativeConversions().isEmpty()) {
+ m_error = u"CustomConversion's target to native conversions missing."_s;
+ return false;
}
+ customConversion->targetToNativeConversions().last()->setConversion(code);
} else {
- m_error = u"CustomConversion object is missing."_s;
- return false;
+ customConversion->setNativeToTargetConversion(code);
}
+ }
break;
case ParserState::ArgumentNativeToTargetConversion: {
@@ -2156,14 +2157,18 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
return true;
}
- if (top->entry->hasTargetConversionRule() || top->entry->hasCustomConversion()) {
- m_error = u"Types can have only one conversion rule"_s;
- return false;
+ ValueTypeEntry *valueTypeEntry = nullptr;
+ if (top->entry->isValue()) {
+ valueTypeEntry = static_cast<ValueTypeEntry *>(top->entry);
+ if (valueTypeEntry->hasTargetConversionRule() || valueTypeEntry->hasCustomConversion()) {
+ m_error = u"Types can have only one conversion rule"_s;
+ return false;
+ }
}
// The old conversion rule tag that uses a file containing the conversion
// will be kept temporarily for compatibility reasons. FIXME PYSIDE7: Remove
- if (!sourceFile.isEmpty()) {
+ if (valueTypeEntry != nullptr && !sourceFile.isEmpty()) {
if (m_generate != TypeEntry::GenerateForSubclass
&& m_generate != TypeEntry::GenerateNothing) {
qWarning(lcShiboken, "Specifying conversion rules by \"file\" is deprecated.");
@@ -2181,12 +2186,18 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
m_error = msgCannotFindSnippet(sourceFile, snippetLabel);
return false;
}
- top->entry->setTargetConversionRule(conversionRuleOptional.value());
+ valueTypeEntry->setTargetConversionRule(conversionRuleOptional.value());
}
return true;
}
- auto *customConversion = new CustomConversion(top->entry);
+ CustomConversionPtr customConversion(new CustomConversion(top->entry));
+ if (top->entry->isPrimitive())
+ static_cast<PrimitiveTypeEntry *>(top->entry)->setCustomConversion(customConversion);
+ else if (top->entry->isContainer())
+ static_cast<ContainerTypeEntry *>(top->entry)->setCustomConversion(customConversion);
+ else if (top->entry->isValue())
+ static_cast<ValueTypeEntry *>(top->entry)->setCustomConversion(customConversion);
customConversionsForReview.append(customConversion);
return true;
}
@@ -2238,7 +2249,12 @@ bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
m_error = u"Target to Native conversions must specify the input type with the 'type' attribute."_s;
return false;
}
- top->entry->customConversion()->addTargetToNativeConversion(sourceTypeName, typeCheck);
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (customConversion.isNull()) {
+ m_error = msgMissingCustomConversion(top->entry);
+ return false;
+ }
+ customConversion->addTargetToNativeConversion(sourceTypeName, typeCheck);
return true;
}
@@ -3331,7 +3347,12 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
const bool replace = replaceIndex == -1
|| convertBoolean(attributes.takeAt(replaceIndex).value(),
replaceAttribute(), true);
- top->entry->customConversion()->setReplaceOriginalTargetToNativeConversions(replace);
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (customConversion.isNull()) {
+ m_error = msgMissingCustomConversion(top->entry);
+ return false;
+ }
+ customConversion->setReplaceOriginalTargetToNativeConversions(replace);
}
}
break;
diff --git a/sources/shiboken6/ApiExtractor/valuetypeentry.h b/sources/shiboken6/ApiExtractor/valuetypeentry.h
index 15cac1a79..af181a24f 100644
--- a/sources/shiboken6/ApiExtractor/valuetypeentry.h
+++ b/sources/shiboken6/ApiExtractor/valuetypeentry.h
@@ -12,6 +12,20 @@ public:
explicit ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
const TypeEntry *parent);
+ bool hasCustomConversion() const;
+ void setCustomConversion(const CustomConversionPtr &customConversion);
+ CustomConversionPtr customConversion() const;
+
+ // FIXME PYSIDE7: Remove
+ /// Set the target type conversion rule
+ void setTargetConversionRule(const QString &conversionRule);
+
+ /// Returns the target type conversion rule
+ QString targetConversionRule() const;
+
+ /// TODO-CONVERTER: mark as deprecated
+ bool hasTargetConversionRule() const;
+
bool isValue() const override;
TypeEntry *clone() const override;
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 7921f6865..6724a4ab5 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -32,6 +32,7 @@
#include <primitivetypeentry.h>
#include <smartpointertypeentry.h>
#include <typesystemtypeentry.h>
+#include <valuetypeentry.h>
#include <parser/enumvalue.h>
#include "qtcompat.h"
@@ -679,9 +680,12 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
}
// python conversion rules
- if (typeEntry->hasTargetConversionRule()) {
- s << "// Python Conversion\n";
- s << typeEntry->targetConversionRule() << '\n';
+ if (typeEntry->isValue()) {
+ auto *vte = static_cast<const ValueTypeEntry *>(typeEntry);
+ if (vte->hasTargetConversionRule()) {
+ s << "// Python Conversion\n";
+ s << vte->targetConversionRule() << '\n';
+ }
}
if (classContext.useWrapper()) {
@@ -1942,13 +1946,16 @@ return result;)";
writePythonToCppConversionFunctions(s, sourceType, targetType, typeCheck, toCppConv, toCppPreConv);
}
- writeCustomConverterFunctions(s, typeEntry->customConversion());
+ if (typeEntry->isValue()) {
+ auto *vte = static_cast<const ValueTypeEntry *>(typeEntry);
+ writeCustomConverterFunctions(s, vte->customConversion());
+ }
}
void CppGenerator::writeCustomConverterFunctions(TextStream &s,
- const CustomConversion *customConversion) const
+ const CustomConversionPtr &customConversion) const
{
- if (!customConversion)
+ if (customConversion.isNull())
return;
const CustomConversion::TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
if (toCppConversions.isEmpty())
@@ -2071,13 +2078,17 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
}
- writeCustomConverterRegister(s, typeEntry->customConversion(), u"converter"_s);
+ if (typeEntry->isValue()) {
+ auto *vte = static_cast<const ValueTypeEntry *>(typeEntry);
+ writeCustomConverterRegister(s, vte->customConversion(), u"converter"_s);
+ }
}
-void CppGenerator::writeCustomConverterRegister(TextStream &s, const CustomConversion *customConversion,
+void CppGenerator::writeCustomConverterRegister(TextStream &s,
+ const CustomConversionPtr &customConversion,
const QString &converterVar)
{
- if (!customConversion)
+ if (customConversion.isNull())
return;
const CustomConversion::TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
if (toCppConversions.isEmpty())
@@ -3417,7 +3428,8 @@ static void replaceCppToPythonVariables(QString &code, const QString &typeName,
code.replace(u"%out"_s, u"pyOut"_s);
}
-void CppGenerator::writeCppToPythonFunction(TextStream &s, const CustomConversion *customConversion) const
+void CppGenerator::writeCppToPythonFunction(TextStream &s,
+ const CustomConversionPtr &customConversion) const
{
QString code = customConversion->nativeToTargetConversion();
auto *ownerType = customConversion->ownerType();
@@ -3427,18 +3439,16 @@ void CppGenerator::writeCppToPythonFunction(TextStream &s, const CustomConversio
}
void CppGenerator::writeCppToPythonFunction(TextStream &s, const AbstractMetaType &containerType) const
{
- const CustomConversion *customConversion = containerType.typeEntry()->customConversion();
- if (!customConversion) {
+ Q_ASSERT(containerType.typeEntry()->isContainer());
+ auto *cte = static_cast<const ContainerTypeEntry *>(containerType.typeEntry());
+ if (!cte->hasCustomConversion()) {
QString m;
QTextStream(&m) << "Can't write the C++ to Python conversion function for container type '"
<< containerType.typeEntry()->qualifiedCppName()
<< "' - no conversion rule was defined for it in the type system.";
throw Exception(m);
}
- if (!containerType.typeEntry()->isContainer()) {
- writeCppToPythonFunction(s, customConversion);
- return;
- }
+ const auto customConversion = cte->customConversion();
QString code = customConversion->nativeToTargetConversion();
for (qsizetype i = 0; i < containerType.instantiations().size(); ++i) {
const AbstractMetaType &type = containerType.instantiations().at(i);
@@ -3565,11 +3575,14 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const AbstractMetaType &containerType) const
{
- const CustomConversion *customConversion = containerType.typeEntry()->customConversion();
- if (!customConversion) {
+ Q_ASSERT(containerType.typeEntry()->isContainer());
+ auto *cte = static_cast<const ContainerTypeEntry *>(containerType.typeEntry());
+ if (!cte->hasCustomConversion()) {
//qFatal
return;
}
+
+ const auto customConversion = cte->customConversion();
const CustomConversion::TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
if (toCppConversions.isEmpty()) {
//qFatal
@@ -4293,7 +4306,7 @@ void CppGenerator::writeSpecialCastFunction(TextStream &s, const AbstractMetaCla
}
void CppGenerator::writePrimitiveConverterInitialization(TextStream &s,
- const CustomConversion *customConversion)
+ const CustomConversionPtr &customConversion)
{
const TypeEntry *type = customConversion->ownerType();
QString converter = converterObject(type);
@@ -6651,10 +6664,10 @@ bool CppGenerator::finishGeneration()
}
}
- const QList<const CustomConversion *> &typeConversions = getPrimitiveCustomConversions();
+ const QList<CustomConversionPtr> &typeConversions = getPrimitiveCustomConversions();
if (!typeConversions.isEmpty()) {
s << "\n// Primitive Type converters.\n\n";
- for (const CustomConversion *conversion : typeConversions) {
+ for (const auto &conversion : typeConversions) {
s << "// C++ to Python conversion for primitive type '" << conversion->ownerType()->qualifiedCppName() << "'.\n";
writeCppToPythonFunction(s, conversion);
writeCustomConverterFunctions(s, conversion);
@@ -6747,7 +6760,7 @@ bool CppGenerator::finishGeneration()
if (!typeConversions.isEmpty()) {
s << '\n';
- for (const CustomConversion *conversion : typeConversions) {
+ for (const auto &conversion : typeConversions) {
writePrimitiveConverterInitialization(s, conversion);
s << '\n';
}
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index 615a0f775..4556849fc 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -96,10 +96,11 @@ private:
void writeConverterFunctions(TextStream &s, const AbstractMetaClass *metaClass,
const GeneratorContext &classContext) const;
void writeCustomConverterFunctions(TextStream &s,
- const CustomConversion *customConversion) const;
+ const CustomConversionPtr &customConversion) const;
void writeConverterRegister(TextStream &s, const AbstractMetaClass *metaClass,
const GeneratorContext &classContext) const;
- static void writeCustomConverterRegister(TextStream &s, const CustomConversion *customConversion,
+ static void writeCustomConverterRegister(TextStream &s,
+ const CustomConversionPtr &customConversion,
const QString &converterVar);
void writeContainerConverterFunctions(TextStream &s,
@@ -295,7 +296,7 @@ private:
/// Writes a C++ to Python conversion function.
void writeCppToPythonFunction(TextStream &s, const QString &code, const QString &sourceTypeName,
QString targetTypeName = QString()) const;
- void writeCppToPythonFunction(TextStream &s, const CustomConversion *customConversion) const;
+ void writeCppToPythonFunction(TextStream &s, const CustomConversionPtr &customConversion) const;
void writeCppToPythonFunction(TextStream &s, const AbstractMetaType &containerType) const;
/// Writes a Python to C++ conversion function.
@@ -451,7 +452,7 @@ private:
static void writeSpecialCastFunction(TextStream &s, const AbstractMetaClass *metaClass);
static void writePrimitiveConverterInitialization(TextStream &s,
- const CustomConversion *customConversion);
+ const CustomConversionPtr &customConversion);
static void writeFlagsConverterInitialization(TextStream &s, const FlagsTypeEntry *enumType);
static void writeEnumConverterInitialization(TextStream &s, const AbstractMetaEnum &metaEnum);
QString writeContainerConverterInitialization(TextStream &s, const AbstractMetaType &type) const;
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 264c8cfea..93c35d2fa 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -29,6 +29,7 @@
#include <namespacetypeentry.h>
#include <primitivetypeentry.h>
#include <pythontypeentry.h>
+#include <valuetypeentry.h>
#include <iostream>
@@ -250,10 +251,11 @@ ShibokenGenerator::FunctionGeneration
AbstractMetaFunctionCList ShibokenGenerator::implicitConversions(const TypeEntry *t) const
{
- if (!generateImplicitConversions())
+ if (!generateImplicitConversions() || !t->isValue())
return {};
- auto *customConversion = t->customConversion();
- if (customConversion && customConversion->replaceOriginalTargetToNativeConversions())
+ auto *vte = static_cast<const ValueTypeEntry *>(t);
+ auto customConversion = vte->customConversion();
+ if (!customConversion.isNull() && customConversion->replaceOriginalTargetToNativeConversions())
return {};
auto result = api().implicitConversions(t);
@@ -1174,15 +1176,13 @@ ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverter
return extConvs;
}
-QList<const CustomConversion *> ShibokenGenerator::getPrimitiveCustomConversions()
+QList<CustomConversionPtr> ShibokenGenerator::getPrimitiveCustomConversions()
{
- QList<const CustomConversion *> conversions;
+ QList<CustomConversionPtr> conversions;
const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
for (const PrimitiveTypeEntry *type : primitiveTypeList) {
- if (!type->shouldGenerate() || !type->isUserPrimitive() || !type->customConversion())
- continue;
-
- conversions << type->customConversion();
+ if (type->shouldGenerate() && type->isUserPrimitive() && type->hasCustomConversion())
+ conversions << type->customConversion();
}
return conversions;
}
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index 767af579d..24c866f33 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -6,6 +6,7 @@
#include <generator.h>
+#include "typesystem_typedefs.h"
#include "customconversion.h"
#include <QtCore/QRegularExpression>
@@ -298,7 +299,7 @@ protected:
ExtendedConverterData getExtendedConverters() const;
/// Returns a list of converters for the non wrapper types of the current module.
- static QList<const CustomConversion *> getPrimitiveCustomConversions() ;
+ static QList<CustomConversionPtr> getPrimitiveCustomConversions();
/// Returns true if the Python wrapper for the received OverloadData must accept a list of arguments.
bool pythonFunctionWrapperUsesListOfArguments(const AbstractMetaFunctionCPtr &func) const;