aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/generator/shiboken/shibokengenerator.cpp')
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp680
1 files changed, 483 insertions, 197 deletions
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 55851e650..67fd9c994 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "shibokengenerator.h"
+#include "generatorstrings.h"
#include "generatorargument.h"
#include "defaultvalue.h"
#include "generatorcontext.h"
@@ -20,12 +21,12 @@
#include <messages.h>
#include <modifications.h>
#include "overloaddata.h"
+#include <optionsparser.h>
#include "propertyspec.h"
#include "pytypenames.h"
#include <reporthandler.h>
#include <textstream.h>
#include <typedatabase.h>
-#include <abstractmetabuilder.h>
#include <containertypeentry.h>
#include <customtypenentry.h>
#include <enumtypeentry.h>
@@ -33,6 +34,7 @@
#include <namespacetypeentry.h>
#include <primitivetypeentry.h>
#include <pythontypeentry.h>
+#include <smartpointertypeentry.h>
#include <valuetypeentry.h>
#include <iostream>
@@ -42,39 +44,69 @@
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QRegularExpression>
+
+#include <algorithm>
#include <limits>
#include <memory>
+#include <utility>
using namespace Qt::StringLiterals;
-static const char PARENT_CTOR_HEURISTIC[] = "enable-parent-ctor-heuristic";
-static const char RETURN_VALUE_HEURISTIC[] = "enable-return-value-heuristic";
-static const char DISABLE_VERBOSE_ERROR_MESSAGES[] = "disable-verbose-error-messages";
-static const char USE_ISNULL_AS_NB_NONZERO[] = "use-isnull-as-nb_nonzero";
-static const char USE_OPERATOR_BOOL_AS_NB_NONZERO[] = "use-operator-bool-as-nb_nonzero";
-static const char WRAPPER_DIAGNOSTICS[] = "wrapper-diagnostics";
-static const char NO_IMPLICIT_CONVERSIONS[] = "no-implicit-conversions";
-static const char LEAN_HEADERS[] = "lean-headers";
-
-const QString CPP_ARG = u"cppArg"_s;
-const QString CPP_ARG_REMOVED = u"removed_cppArg"_s;
-const QString CPP_RETURN_VAR = u"cppResult"_s;
-const QString CPP_SELF_VAR = u"cppSelf"_s;
-const QString NULL_PTR = u"nullptr"_s;
-const QString PYTHON_ARG = u"pyArg"_s;
-const QString PYTHON_ARGS = u"pyArgs"_s;
-const QString PYTHON_OVERRIDE_VAR = u"pyOverride"_s;
-const QString PYTHON_RETURN_VAR = u"pyResult"_s;
-const QString PYTHON_TO_CPP_VAR = u"pythonToCpp"_s;
-
-const QString CONV_RULE_OUT_VAR_SUFFIX = u"_out"_s;
-const QString BEGIN_ALLOW_THREADS =
- u"PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS"_s;
-const QString END_ALLOW_THREADS = u"PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS"_s;
+static constexpr auto PARENT_CTOR_HEURISTIC = "enable-parent-ctor-heuristic"_L1;
+static constexpr auto RETURN_VALUE_HEURISTIC = "enable-return-value-heuristic"_L1;
+static constexpr auto DISABLE_VERBOSE_ERROR_MESSAGES = "disable-verbose-error-messages"_L1;
+static constexpr auto USE_ISNULL_AS_NB_BOOL = "use-isnull-as-nb-bool"_L1;
+// FIXME PYSIDE 7: Remove USE_ISNULL_AS_NB_NONZERO/USE_OPERATOR_BOOL_AS_NB_NONZERO
+static constexpr auto USE_ISNULL_AS_NB_NONZERO = "use-isnull-as-nb_nonzero"_L1;
+static constexpr auto USE_OPERATOR_BOOL_AS_NB_BOOL = "use-operator-bool-as-nb-bool"_L1;
+static constexpr auto USE_OPERATOR_BOOL_AS_NB_NONZERO = "use-operator-bool-as-nb-nonzero"_L1;
+static constexpr auto WRAPPER_DIAGNOSTICS = "wrapper-diagnostics"_L1;
+static constexpr auto NO_IMPLICIT_CONVERSIONS = "no-implicit-conversions"_L1;
+static constexpr auto LEAN_HEADERS = "lean-headers"_L1;
+
+QString CPP_ARG_N(int i)
+{
+ return CPP_ARG + QString::number(i);
+}
+
+constexpr auto CPP_ARG_REMOVED_PREFIX = "removed_cppArg"_L1;
+
+QString CPP_ARG_REMOVED(int i)
+{
+ return CPP_ARG_REMOVED_PREFIX + QString::number(i);
+}
+
+const char *const METHOD_DEF_SENTINEL = "{nullptr, nullptr, 0, nullptr} // Sentinel\n";
+const char *const PYTHON_TO_CPPCONVERSION_STRUCT = "Shiboken::Conversions::PythonToCppConversion";
+
+const char *const openTargetExternC = R"(
+// Target ---------------------------------------------------------
+
+extern "C" {
+)";
+const char *const closeExternC = "} // extern \"C\"\n\n";
+const char *const richCompareComment =
+ "// PYSIDE-74: By default, we redirect to object's tp_richcompare (which is `==`, `!=`).\n";
+
+struct ShibokenGeneratorOptions
+{
+ bool useCtorHeuristic = false;
+ bool userReturnValueHeuristic = false;
+ bool verboseErrorMessagesDisabled = false;
+ bool useIsNullAsNbBool = false;
+ // FIXME PYSIDE 7 Flip m_leanHeaders default or remove?
+ bool leanHeaders = false;
+ bool useOperatorBoolAsNbBool = false;
+ // FIXME PYSIDE 7 Flip generateImplicitConversions default or remove?
+ bool generateImplicitConversions = true;
+ bool wrapperDiagnostics = false;
+};
struct GeneratorClassInfoCacheEntry
{
ShibokenGenerator::FunctionGroups functionGroups;
+ QList<AbstractMetaFunctionCList> numberProtocolOperators;
+ BoolCastFunctionOptional boolCastFunctionO;
bool needsGetattroFunction = false;
};
@@ -102,6 +134,10 @@ const ShibokenGenerator::TypeSystemConverterRegExps &
return result;
}
+// Options are static to avoid duplicated handling since ShibokenGenerator
+// is instantiated for HeaderGenerator and CppGenerator.
+ShibokenGeneratorOptions ShibokenGenerator::m_options;
+
ShibokenGenerator::ShibokenGenerator() = default;
ShibokenGenerator::~ShibokenGenerator() = default;
@@ -110,32 +146,32 @@ ShibokenGenerator::~ShibokenGenerator() = default;
static const QHash<QString, QString> &primitiveTypesCorrespondences()
{
static const QHash<QString, QString> result = {
- {u"bool"_s, pyBoolT()},
- {u"char"_s, sbkCharT()},
- {u"signed char"_s, sbkCharT()},
- {u"unsigned char"_s, sbkCharT()},
- {intT(), pyLongT()},
- {u"signed int"_s, pyLongT()},
- {u"uint"_s, pyLongT()},
- {u"unsigned int"_s, pyLongT()},
- {shortT(), pyLongT()},
- {u"ushort"_s, pyLongT()},
- {u"signed short"_s, pyLongT()},
- {u"signed short int"_s, pyLongT()},
- {unsignedShortT(), pyLongT()},
- {u"unsigned short int"_s, pyLongT()},
- {longT(), pyLongT()},
- {doubleT(), pyFloatT()},
- {floatT(), pyFloatT()},
- {u"unsigned long"_s, pyLongT()},
- {u"signed long"_s, pyLongT()},
- {u"ulong"_s, pyLongT()},
- {u"unsigned long int"_s, pyLongT()},
- {u"long long"_s, pyLongT()},
- {u"__int64"_s, pyLongT()},
- {u"unsigned long long"_s, pyLongT()},
- {u"unsigned __int64"_s, pyLongT()},
- {u"size_t"_s, pyLongT()}
+ {u"bool"_s, pyBoolT},
+ {u"char"_s, sbkCharT},
+ {u"signed char"_s, sbkCharT},
+ {u"unsigned char"_s, sbkCharT},
+ {intT, pyLongT},
+ {u"signed int"_s, pyLongT},
+ {u"uint"_s, pyLongT},
+ {u"unsigned int"_s, pyLongT},
+ {shortT, pyLongT},
+ {u"ushort"_s, pyLongT},
+ {u"signed short"_s, pyLongT},
+ {u"signed short int"_s, pyLongT},
+ {unsignedShortT, pyLongT},
+ {u"unsigned short int"_s, pyLongT},
+ {longT, pyLongT},
+ {doubleT, pyFloatT},
+ {floatT, pyFloatT},
+ {u"unsigned long"_s, pyLongT},
+ {u"signed long"_s, pyLongT},
+ {u"ulong"_s, pyLongT},
+ {u"unsigned long int"_s, pyLongT},
+ {u"long long"_s, pyLongT},
+ {u"__int64"_s, pyLongT},
+ {u"unsigned long long"_s, pyLongT},
+ {u"unsigned __int64"_s, pyLongT},
+ {u"size_t"_s, pyLongT}
};
return result;
}
@@ -145,18 +181,18 @@ const QHash<QString, QChar> &ShibokenGenerator::formatUnits()
static const QHash<QString, QChar> result = {
{u"char"_s, u'b'},
{u"unsigned char"_s, u'B'},
- {intT(), u'i'},
+ {intT, u'i'},
{u"unsigned int"_s, u'I'},
- {shortT(), u'h'},
- {unsignedShortT(), u'H'},
- {longT(), u'l'},
- {unsignedLongLongT(), u'k'},
- {longLongT(), u'L'},
+ {shortT, u'h'},
+ {unsignedShortT, u'H'},
+ {longT, u'l'},
+ {unsignedLongLongT, u'k'},
+ {longLongT, u'L'},
{u"__int64"_s, u'L'},
- {unsignedLongLongT(), u'K'},
+ {unsignedLongLongT, u'K'},
{u"unsigned __int64"_s, u'K'},
- {doubleT(), u'd'},
- {floatT(), u'f'},
+ {doubleT, u'd'},
+ {floatT, u'f'},
};
return result;
}
@@ -179,7 +215,7 @@ QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType
return translateType(cType, context, options);
}
-bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClassCPtr &metaClass) const
+bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClassCPtr &metaClass)
{
const auto wrapper = metaClass->cppWrapper();
return wrapper.testFlag(AbstractMetaClass::CppVirtualMethodWrapper)
@@ -187,8 +223,17 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClassCPtr &me
&& wrapper.testFlag(AbstractMetaClass::CppProtectedHackWrapper));
}
-ShibokenGenerator::FunctionGeneration
- ShibokenGenerator::functionGeneration(const AbstractMetaFunctionCPtr &func) const
+bool ShibokenGenerator::shouldGenerateMetaObjectFunctions(const AbstractMetaClassCPtr &metaClass)
+{
+ return usePySideExtensions()
+ && (!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
+ && !metaClass->typeEntry()->typeFlags()
+ .testFlag(ComplexTypeEntry::DisableQtMetaObjectFunctions)
+ && isQObject(metaClass);
+}
+
+ShibokenGenerator::FunctionGeneration ShibokenGenerator::functionGeneration(
+ const AbstractMetaFunctionCPtr &func)
{
FunctionGeneration result;
@@ -231,7 +276,7 @@ ShibokenGenerator::FunctionGeneration
// Check on virtuals (including operators).
const bool isAbstract = func->isAbstract();
if (!(isAbstract || func->isVirtual())
- || func->attributes().testFlag(AbstractMetaFunction::FinalCppMethod)
+ || func->cppAttributes().testFlag(FunctionAttribute::Final)
|| func->isModifiedFinal()) {
return result;
}
@@ -272,7 +317,7 @@ AbstractMetaFunctionCList ShibokenGenerator::implicitConversions(const TypeEntry
return result;
}
-QString ShibokenGenerator::wrapperName(const AbstractMetaClassCPtr &metaClass) const
+QString ShibokenGenerator::wrapperName(const AbstractMetaClassCPtr &metaClass)
{
Q_ASSERT(shouldGenerateCppWrapper(metaClass));
QString result = metaClass->name();
@@ -290,7 +335,7 @@ QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClassCPtr &meta
fullClassName.prepend(enclosing->name() + u'.');
enclosing = enclosing->enclosingClass();
}
- fullClassName.prepend(packageName() + u'.');
+ fullClassName.prepend(metaClass->typeEntry()->targetLangPackage() + u'.');
return fullClassName;
}
@@ -354,6 +399,11 @@ QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunctionCPtr
return funcName;
}
+bool ShibokenGenerator::wrapperDiagnostics()
+{
+ return m_options.wrapperDiagnostics;
+}
+
QString ShibokenGenerator::protectedEnumSurrogateName(const AbstractMetaEnum &metaEnum)
{
QString result = metaEnum.fullName();
@@ -389,7 +439,7 @@ QString ShibokenGenerator::cpythonFunctionName(const AbstractMetaFunctionCPtr &f
QString ShibokenGenerator::cpythonMethodDefinitionName(const AbstractMetaFunctionCPtr &func)
{
if (!func->ownerClass())
- return QString();
+ return {};
return cpythonBaseName(func->ownerClass()->typeEntry()) + u"Method_"_s
+ func->name();
}
@@ -413,13 +463,13 @@ QString ShibokenGenerator::cpythonGetattroFunctionName(const AbstractMetaClassCP
QString ShibokenGenerator::cpythonGetterFunctionName(const QString &name,
const AbstractMetaClassCPtr &enclosingClass)
{
- return cpythonBaseName(enclosingClass) + QStringLiteral("_get_") + name;
+ return cpythonBaseName(enclosingClass) + "_get_"_L1 + name;
}
QString ShibokenGenerator::cpythonSetterFunctionName(const QString &name,
const AbstractMetaClassCPtr &enclosingClass)
{
- return cpythonBaseName(enclosingClass) + QStringLiteral("_set_") + name;
+ return cpythonBaseName(enclosingClass) + "_set_"_L1 + name;
}
QString ShibokenGenerator::cpythonGetterFunctionName(const AbstractMetaField &metaField)
@@ -492,7 +542,7 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType &metaType,
const QString &argName)
{
if (!metaType.isWrapperType())
- return QString();
+ return {};
return u"reinterpret_cast< ::"_s + metaType.cppSignature()
+ u" *>(Shiboken::Conversions::cppPointer("_s + cpythonTypeNameExt(metaType)
+ u", reinterpret_cast<SbkObject *>("_s + argName + u")))"_s;
@@ -503,7 +553,7 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const TypeEntryCPtr &type,
{
if (!type->isWrapperType())
return QString();
- return u"reinterpret_cast< ::"_s + type->qualifiedCppName()
+ return u"reinterpret_cast< "_s + getFullTypeName(type)
+ u" *>(Shiboken::Conversions::cppPointer("_s + cpythonTypeNameExt(type)
+ u", reinterpret_cast<SbkObject *>("_s + argName + u")))"_s;
}
@@ -523,10 +573,10 @@ void ShibokenGenerator::writeToCppConversion(TextStream &s,
}
void ShibokenGenerator::writeToCppConversion(TextStream &s, const AbstractMetaType &type,
- const AbstractMetaClassCPtr &context, const QString &inArgName,
+ const QString &inArgName,
const QString &outArgName)
{
- s << cpythonToCppConversionFunction(type, context) << inArgName << ", &" << outArgName << ')';
+ s << cpythonToCppConversionFunction(type) << inArgName << ", &" << outArgName << ')';
}
bool ShibokenGenerator::shouldRejectNullPointerArgument(const AbstractMetaFunctionCPtr &func,
@@ -576,11 +626,12 @@ QString ShibokenGenerator::containerCpythonBaseName(const ContainerTypeEntryCPtr
return u"PyDict"_s;
case ContainerTypeEntry::ListContainer:
case ContainerTypeEntry::PairContainer:
+ case ContainerTypeEntry::SpanContainer:
break;
default:
Q_ASSERT(false);
}
- return cPySequenceT();
+ return cPySequenceT;
}
QString ShibokenGenerator::cpythonBaseName(const TypeEntryCPtr &type)
@@ -600,7 +651,7 @@ QString ShibokenGenerator::cpythonBaseName(const TypeEntryCPtr &type)
const auto ctype = std::static_pointer_cast<const ContainerTypeEntry>(type);
baseName = containerCpythonBaseName(ctype);
} else {
- baseName = cPyObjectT();
+ baseName = cPyObjectT;
}
return baseName.replace(u"::"_s, u"_"_s);
}
@@ -615,12 +666,6 @@ QString ShibokenGenerator::cpythonTypeName(const TypeEntryCPtr &type)
return cpythonBaseName(type) + u"_TypeF()"_s;
}
-QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntryCPtr &type)
-{
- return cppApiVariableName(type->targetLangPackage()) + u'['
- + getTypeIndexVariableName(type) + u']';
-}
-
QString ShibokenGenerator::converterObject(const AbstractMetaType &type)
{
if (type.isCString())
@@ -629,7 +674,7 @@ QString ShibokenGenerator::converterObject(const AbstractMetaType &type)
return u"Shiboken::Conversions::PrimitiveTypeConverter<void *>()"_s;
const AbstractMetaTypeList nestedArrayTypes = type.nestedArrayTypes();
if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast().isCppPrimitive()) {
- return QStringLiteral("Shiboken::Conversions::ArrayTypeConverter<")
+ return "Shiboken::Conversions::ArrayTypeConverter<"_L1
+ nestedArrayTypes.constLast().minimalSignature()
+ u">("_s + QString::number(nestedArrayTypes.size())
+ u')';
@@ -651,23 +696,20 @@ QString ShibokenGenerator::converterObject(const TypeEntryCPtr &type)
if (type->isWrapperType())
return QString::fromLatin1("PepType_SOTP(reinterpret_cast<PyTypeObject *>(%1))->converter")
.arg(cpythonTypeNameExt(type));
- if (type->isEnum())
+ if (type->isEnum() || type->isFlags())
return QString::fromLatin1("PepType_SETP(reinterpret_cast<SbkEnumType *>(%1))->converter")
.arg(cpythonTypeNameExt(type));
- if (type->isFlags())
- return QString::fromLatin1("PepType_PFTP(reinterpret_cast<PySideQFlagsType *>(%1))->converter")
- .arg(cpythonTypeNameExt(type));
if (type->isArray()) {
qDebug() << "Warning: no idea how to handle the Qt5 type " << type->qualifiedCppName();
- return QString();
+ return {};
}
/* the typedef'd primitive types case */
auto pte = std::dynamic_pointer_cast<const PrimitiveTypeEntry>(type);
if (!pte) {
qDebug() << "Warning: the Qt5 primitive type is unknown" << type->qualifiedCppName();
- return QString();
+ return {};
}
pte = basicReferencedTypeEntry(pte);
if (pte->isPrimitive() && !isCppPrimitive(pte) && !pte->customConversion()) {
@@ -679,13 +721,29 @@ QString ShibokenGenerator::converterObject(const TypeEntryCPtr &type)
+ u'[' + getTypeIndexVariableName(type) + u']';
}
-QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType &type)
+QString ShibokenGenerator::cpythonTypeNameExtSet(const TypeEntryCPtr &type)
+{
+ return cppApiVariableName(type->targetLangPackage()) + u'['
+ + getTypeIndexVariableName(type) + "].type"_L1;
+}
+
+QString ShibokenGenerator::cpythonTypeNameExtSet(const AbstractMetaType &type)
{
return cppApiVariableName(type.typeEntry()->targetLangPackage()) + u'['
- + getTypeIndexVariableName(type) + u']';
+ + getTypeIndexVariableName(type) + "].type"_L1;
+}
+
+QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntryCPtr &type)
+{
+ return "Shiboken::Module::get("_L1 + cppApiVariableName(type->targetLangPackage())
+ + u'[' + getTypeIndexVariableName(type) + "])"_L1;
}
-static inline QString unknownOperator() { return QStringLiteral("__UNKNOWN_OPERATOR__"); }
+QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType &type)
+{
+ return u"Shiboken::Module::get("_s + cppApiVariableName(type.typeEntry()->targetLangPackage())
+ + u'[' + getTypeIndexVariableName(type) + "])"_L1;
+}
QString ShibokenGenerator::fixedCppTypeName(const TargetToNativeConversion &toNative)
{
@@ -735,7 +793,7 @@ QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunction
QString op = Generator::pythonOperatorFunctionName(func->originalName());
if (op.isEmpty()) {
qCWarning(lcShiboken).noquote().nospace() << msgUnknownOperator(func.get());
- return unknownOperator();
+ return "__UNKNOWN_OPERATOR__"_L1;
}
if (func->arguments().isEmpty()) {
if (op == u"__sub__")
@@ -752,8 +810,8 @@ QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunction
bool ShibokenGenerator::isNumber(const QString &cpythonApiName)
{
- return cpythonApiName == pyFloatT() || cpythonApiName == pyLongT()
- || cpythonApiName == pyBoolT();
+ return cpythonApiName == pyFloatT || cpythonApiName == pyLongT
+ || cpythonApiName == pyBoolT;
}
static std::optional<TypeSystem::CPythonType>
@@ -800,7 +858,7 @@ bool ShibokenGenerator::isPyInt(const TypeEntryCPtr &type)
if (!cPythonTypeOpt.has_value()) {
const auto &mapping = primitiveTypesCorrespondences();
const auto it = mapping.constFind(pte->name());
- return it != mapping.cend() && it.value() == pyLongT();
+ return it != mapping.cend() && it.value() == pyLongT;
}
return cPythonTypeOpt.value() == TypeSystem::CPythonType::Integer;
}
@@ -929,7 +987,7 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntryCPtr &typ
.arg(converterObject(type));
}
-QString ShibokenGenerator::cpythonIsConvertibleFunction(AbstractMetaType metaType)
+QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType &metaType)
{
const auto typeEntry = metaType.typeEntry();
if (typeEntry->isCustom()) {
@@ -946,12 +1004,14 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(AbstractMetaType metaTyp
return result;
}
if (metaType.isWrapperType()) {
- if (metaType.isPointer() || metaType.isValueTypeWithCopyConstructorOnly())
+ if (metaType.isPointer() || metaType.isValueTypeWithCopyConstructorOnly()) {
result += u"pythonToCppPointerConversion"_s;
- else if (metaType.referenceType() == LValueReference)
+ } else if (metaType.referenceType() == LValueReference
+ || (metaType.referenceType() == RValueReference && typeEntry->isObject())) {
result += u"pythonToCppReferenceConversion"_s;
- else
+ } else {
result += u"pythonToCppValueConversion"_s;
+ }
result += u'(' + cpythonTypeNameExt(metaType) + u", "_s;
return result;
}
@@ -980,20 +1040,18 @@ QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaClas
+ cpythonTypeNameExt(metaClass->typeEntry()) + u", "_s;
}
-QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaType &type,
- AbstractMetaClassCPtr /* context */)
+QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaType &type)
{
if (type.isWrapperType()) {
return u"Shiboken::Conversions::pythonToCpp"_s
+ (type.isPointer() ? u"Pointer"_s : u"Copy"_s)
+ u'(' + cpythonTypeNameExt(type) + u", "_s;
}
- return QStringLiteral("Shiboken::Conversions::pythonToCppCopy(%1, ")
- .arg(converterObject(type));
+ return "Shiboken::Conversions::pythonToCppCopy("_L1
+ + converterObject(type) + ", "_L1;
}
-QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaType &type,
- AbstractMetaClassCPtr /* context */)
+QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaType &type)
{
if (type.isWrapperType()) {
QString conversion;
@@ -1012,9 +1070,10 @@ QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaT
result += u'&';
return result;
}
- return QStringLiteral("Shiboken::Conversions::copyToPython(%1, %2")
- .arg(converterObject(type),
- (type.isCString() || type.isVoidPointer()) ? QString() : u"&"_s);
+
+ const auto indirections = type.indirections() - 1;
+ return u"Shiboken::Conversions::copyToPython("_s + converterObject(type)
+ + u", "_s + AbstractMetaType::dereferencePrefix(indirections);
}
QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaClassCPtr &metaClass)
@@ -1045,13 +1104,14 @@ QString ShibokenGenerator::argumentString(const AbstractMetaFunctionCPtr &func,
auto type = options.testFlag(OriginalTypeDescription)
? argument.type() : argument.modifiedType();
+
QString arg = translateType(type, func->implementingClass(), options);
if (argument.isTypeModified())
arg.replace(u'$', u'.'); // Haehh?
// "int a", "int a[]"
- const int arrayPos = arg.indexOf(u'[');
+ const auto arrayPos = arg.indexOf(u'[');
if (arrayPos != -1)
arg.insert(arrayPos, u' ' + argument.name());
else
@@ -1087,6 +1147,10 @@ void ShibokenGenerator::writeFunctionArguments(TextStream &s,
Options options) const
{
int argUsed = 0;
+ if (func->isUserAddedPythonOverride()) {
+ s << "Shiboken::GilState &gil, PyObject *" << PYTHON_OVERRIDE_VAR;
+ argUsed += 2;
+ }
for (const auto &arg : func->arguments()) {
if (options.testFlag(Generator::SkipRemovedArguments) && arg.isModifiedRemoved())
continue;
@@ -1123,6 +1187,8 @@ QString ShibokenGenerator::functionSignature(const AbstractMetaFunctionCPtr &fun
{
StringStream s(TextStream::Language::Cpp);
// The actual function
+ if (!options.testFlag(Option::SkipDefaultValues) && func->isStatic()) // Declaration
+ s << "static ";
if (func->isEmptyFunction() || func->needsReturnType())
s << functionReturnType(func, options) << ' ';
else
@@ -1224,7 +1290,7 @@ static QString getArgumentsFromMethodCall(const QString &str)
// For more information check this:
// http://perl.plover.com/yak/regex/samples/slide083.html
static QLatin1String funcCall("%CPPSELF.%FUNCTION_NAME");
- int pos = str.indexOf(funcCall);
+ auto pos = str.indexOf(funcCall);
if (pos == -1)
return QString();
pos = pos + funcCall.size();
@@ -1268,7 +1334,7 @@ void ShibokenGenerator::processClassCodeSnip(QString &code, const GeneratorConte
code.replace(u"%TYPE"_s, className);
code.replace(u"%CPPTYPE"_s, metaClass->name());
- processCodeSnip(code);
+ processCodeSnip(code, context.effectiveClassName());
}
void ShibokenGenerator::processCodeSnip(QString &code) const
@@ -1286,6 +1352,15 @@ void ShibokenGenerator::processCodeSnip(QString &code) const
replaceTypeCheckTypeSystemVariable(code);
}
+void ShibokenGenerator::processCodeSnip(QString &code, const QString &context) const
+{
+ try {
+ processCodeSnip(code);
+ } catch (const std::exception &e) {
+ throw Exception(msgSnippetError(context, e.what()));
+ }
+}
+
ShibokenGenerator::ArgumentVarReplacementList
ShibokenGenerator::getArgumentReplacement(const AbstractMetaFunctionCPtr &func,
bool usePyArgs, TypeSystem::Language language,
@@ -1306,7 +1381,7 @@ ShibokenGenerator::ArgumentVarReplacementList
if (argRemoved && hasConversionRule)
argValue = arg.name() + CONV_RULE_OUT_VAR_SUFFIX;
else if (argRemoved || (lastArg && arg.argumentIndex() > lastArg->argumentIndex()))
- argValue = CPP_ARG_REMOVED + QString::number(i);
+ argValue = CPP_ARG_REMOVED(i);
if (!argRemoved && argValue.isEmpty()) {
int argPos = i - removed;
AbstractMetaType type = arg.modifiedType();
@@ -1316,7 +1391,7 @@ ShibokenGenerator::ArgumentVarReplacementList
} else {
argValue = hasConversionRule
? arg.name() + CONV_RULE_OUT_VAR_SUFFIX
- : CPP_ARG + QString::number(argPos);
+ : CPP_ARG_N(argPos);
const auto generatorArg = GeneratorArgument::fromMetaType(type);
AbstractMetaType::applyDereference(&argValue, generatorArg.indirections);
}
@@ -1358,7 +1433,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
static void replacePyArg0(TypeSystem::Language language, QString *code)
{
- static const QString pyArg0 = u"%PYARG_0"_s;
+ static constexpr auto pyArg0 = "%PYARG_0"_L1;
if (!code->contains(pyArg0))
return;
@@ -1397,13 +1472,13 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
// Replace %PYARG_# variables.
replacePyArg0(language, &code);
- static const QRegularExpression pyArgsRegex(QStringLiteral("%PYARG_(\\d+)"));
+ static const QRegularExpression pyArgsRegex("%PYARG_(\\d+)"_L1);
Q_ASSERT(pyArgsRegex.isValid());
if (language == TypeSystem::TargetLangCode) {
if (usePyArgs) {
code.replace(pyArgsRegex, PYTHON_ARGS + u"[\\1-1]"_s);
} else {
- static const QRegularExpression pyArgsRegexCheck(QStringLiteral("%PYARG_([2-9]+)"));
+ static const QRegularExpression pyArgsRegexCheck("%PYARG_([2-9]+)"_L1);
Q_ASSERT(pyArgsRegexCheck.isValid());
const QRegularExpressionMatch match = pyArgsRegexCheck.match(code);
if (match.hasMatch()) {
@@ -1416,12 +1491,12 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
} else {
// Replaces the simplest case of attribution to a
// Python argument on the binding virtual method.
- static const QRegularExpression pyArgsAttributionRegex(QStringLiteral("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)"));
+ static const QRegularExpression pyArgsAttributionRegex("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)"_L1);
Q_ASSERT(pyArgsAttributionRegex.isValid());
code.replace(pyArgsAttributionRegex, u"PyTuple_SET_ITEM("_s
- + PYTHON_ARGS + u", \\1-1, \\2)"_s);
+ + PYTHON_ARGS + u".object(), \\1-1, \\2)"_s);
code.replace(pyArgsRegex, u"PyTuple_GET_ITEM("_s
- + PYTHON_ARGS + u", \\1-1)"_s);
+ + PYTHON_ARGS + u".object(), \\1-1)"_s);
}
// Replace %ARG#_TYPE variables.
@@ -1433,7 +1508,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
code.replace(argTypeVar, argTypeVal);
}
- static const QRegularExpression cppArgTypeRegexCheck(QStringLiteral("%ARG(\\d+)_TYPE"));
+ static const QRegularExpression cppArgTypeRegexCheck("%ARG(\\d+)_TYPE"_L1);
Q_ASSERT(cppArgTypeRegexCheck.isValid());
QRegularExpressionMatchIterator rit = cppArgTypeRegexCheck.globalMatch(code);
while (rit.hasNext()) {
@@ -1525,7 +1600,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
QStringList args;
for (const ArgumentVarReplacementPair &pair : argReplacements) {
- if (pair.second.startsWith(CPP_ARG_REMOVED))
+ if (pair.second.startsWith(CPP_ARG_REMOVED_PREFIX))
continue;
args << pair.second;
}
@@ -1575,8 +1650,8 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
if (isProtected) {
code.replace(u"%TYPE::%FUNCTION_NAME"_s,
- QStringLiteral("%1::%2_protected")
- .arg(wrapperName(func->ownerClass()), func->originalName()));
+ wrapperName(func->ownerClass()) + "::"_L1
+ + func->originalName() + "_protected"_L1);
code.replace(u"%FUNCTION_NAME"_s,
func->originalName() + u"_protected"_s);
}
@@ -1590,7 +1665,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
replaceTemplateVariables(code, func);
- processCodeSnip(code);
+ processCodeSnip(code, func->classQualifiedSignature());
s << "// Begin code injection\n" << code << "// End of code injection\n\n";
}
@@ -1598,7 +1673,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
// and false if it is a variable.
static bool isVariable(const QString &code)
{
- static const QRegularExpression expr(QStringLiteral("^\\s*\\*?\\s*[A-Za-z_][A-Za-z_0-9.]*\\s*(?:\\[[^\\[]+\\])*$"));
+ static const QRegularExpression expr("^\\s*\\*?\\s*[A-Za-z_][A-Za-z_0-9.]*\\s*(?:\\[[^\\[]+\\])*$"_L1);
Q_ASSERT(expr.isValid());
return expr.match(code.trimmed()).hasMatch();
}
@@ -1659,7 +1734,7 @@ const QHash<int, QString> &ShibokenGenerator::typeSystemConvName()
return result;
}
-using StringPair = QPair<QString, QString>;
+using StringPair = std::pair<QString, QString>;
void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable,
QString &code) const
@@ -1694,9 +1769,6 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
varType = miniNormalizer(varType);
QString varName = list.at(1).trimmed();
if (!varType.isEmpty()) {
- const QString conversionSignature = conversionType.cppSignature();
- if (varType != u"auto" && varType != conversionSignature)
- throw Exception(msgConversionTypesDiffer(varType, conversionSignature));
c << getFullTypeName(conversionType) << ' ' << varName
<< minimalConstructorExpression(api(), conversionType) << ";\n";
}
@@ -1713,7 +1785,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
case TypeSystemCheckFunction:
conversion = cpythonCheckFunction(conversionType);
if (conversionType.typeEntry()->isPrimitive()
- && (conversionType.typeEntry()->name() == cPyObjectT()
+ && (conversionType.typeEntry()->name() == cPyObjectT
|| !conversion.endsWith(u' '))) {
conversion += u'(';
break;
@@ -1744,7 +1816,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
}
}
}
- replacements.append(qMakePair(conversionString, conversion));
+ replacements.append(std::make_pair(conversionString, conversion));
}
for (const StringPair &rep : std::as_const(replacements))
code.replace(rep.first, rep.second);
@@ -1776,8 +1848,8 @@ bool ShibokenGenerator::useOverrideCaching(const AbstractMetaClassCPtr &metaClas
return metaClass->isPolymorphic();
}
-ShibokenGenerator::AttroCheck
- ShibokenGenerator::checkAttroFunctionNeeds(const AbstractMetaClassCPtr &metaClass) const
+ShibokenGenerator::AttroCheck ShibokenGenerator::checkAttroFunctionNeeds(
+ const AbstractMetaClassCPtr &metaClass)
{
AttroCheck result;
if (metaClass->typeEntry()->isSmartPointer()) {
@@ -1789,7 +1861,7 @@ ShibokenGenerator::AttroCheck
FunctionQueryOption::GetAttroFunction)) {
result |= AttroCheckFlag::GetattroUser;
}
- if (usePySideExtensions() && metaClass->qualifiedCppName() == qObjectT())
+ if (usePySideExtensions() && metaClass->qualifiedCppName() == qObjectT)
result |= AttroCheckFlag::SetattroQObject;
if (useOverrideCaching(metaClass))
result |= AttroCheckFlag::SetattroMethodOverride;
@@ -1870,17 +1942,17 @@ AbstractMetaClassCPtr
QString ShibokenGenerator::getModuleHeaderFileBaseName(const QString &moduleName)
{
- return moduleCppPrefix(moduleName).toLower() + QStringLiteral("_python");
+ return moduleCppPrefix(moduleName).toLower() + "_python"_L1;
}
QString ShibokenGenerator::getModuleHeaderFileName(const QString &moduleName)
{
- return getModuleHeaderFileBaseName(moduleName) + QStringLiteral(".h");
+ return getModuleHeaderFileBaseName(moduleName) + ".h"_L1;
}
QString ShibokenGenerator::getPrivateModuleHeaderFileName(const QString &moduleName)
{
- return getModuleHeaderFileBaseName(moduleName) + QStringLiteral("_p.h");
+ return getModuleHeaderFileBaseName(moduleName) + "_p.h"_L1;
}
IncludeGroupList ShibokenGenerator::classIncludes(const AbstractMetaClassCPtr &metaClass) const
@@ -1897,7 +1969,7 @@ IncludeGroupList ShibokenGenerator::classIncludes(const AbstractMetaClassCPtr &m
result.append({u"Argument includes"_s, typeEntry->argumentIncludes()});
const auto implicitConvs = implicitConversions(typeEntry);
- for (auto &f : implicitConvs) {
+ for (const auto &f : implicitConvs) {
if (f->isConversionOperator()) {
const auto source = f->ownerClass();
Q_ASSERT(source);
@@ -1967,8 +2039,11 @@ const GeneratorClassInfoCacheEntry &
auto it = cache->find(scope);
if (it == cache->end()) {
it = cache->insert(scope, {});
- it.value().functionGroups = getFunctionGroupsImpl(scope);
- it.value().needsGetattroFunction = classNeedsGetattroFunctionImpl(scope);
+ auto &entry = it.value();
+ entry.functionGroups = getFunctionGroupsImpl(scope);
+ entry.needsGetattroFunction = classNeedsGetattroFunctionImpl(scope);
+ entry.numberProtocolOperators = getNumberProtocolOperators(scope);
+ entry.boolCastFunctionO = getBoolCast(scope);
}
return it.value();
}
@@ -1980,6 +2055,19 @@ ShibokenGenerator::FunctionGroups
return getGeneratorClassInfo(scope).functionGroups;
}
+QList<AbstractMetaFunctionCList>
+ ShibokenGenerator::numberProtocolOperators(const AbstractMetaClassCPtr &scope)
+{
+ Q_ASSERT(scope);
+ return getGeneratorClassInfo(scope).numberProtocolOperators;
+}
+
+BoolCastFunctionOptional ShibokenGenerator::boolCast(const AbstractMetaClassCPtr &scope)
+{
+ Q_ASSERT(scope);
+ return getGeneratorClassInfo(scope).boolCastFunctionO;
+}
+
// Use non-const overloads only, for example, "foo()" and "foo()const"
// the second is removed.
static void removeConstOverloads(AbstractMetaFunctionCList *overloads)
@@ -2029,10 +2117,153 @@ ShibokenGenerator::FunctionGroups
return results;
}
+static bool removeNumberProtocolOperator(const AbstractMetaFunctionCPtr &f)
+{
+ return !f->generateBinding()
+ || (f->ownerClass() != f->implementingClass() && !f->isAbstract());
+}
+
+QList<AbstractMetaFunctionCList>
+ ShibokenGenerator::getNumberProtocolOperators(const AbstractMetaClassCPtr &metaClass)
+{
+ QList<AbstractMetaFunctionCList> result;
+ if (metaClass->isNamespace())
+ return result;
+ result = filterGroupedOperatorFunctions(
+ metaClass,
+ OperatorQueryOption::ArithmeticOp
+ | OperatorQueryOption::IncDecrementOp
+ | OperatorQueryOption::LogicalOp
+ | OperatorQueryOption::BitwiseOp
+ | OperatorQueryOption::ConversionOp);
+
+ for (auto i = result.size() - 1; i >= 0; --i) {
+ AbstractMetaFunctionCList &l = result[i];
+ auto rend = std::remove_if(l.begin(), l.end(), removeNumberProtocolOperator);
+ l.erase(rend, l.end());
+ if (l.isEmpty())
+ result.removeAt(i);
+ }
+
+ return result;
+}
+
+BoolCastFunctionOptional
+ShibokenGenerator::getBoolCast(const AbstractMetaClassCPtr &metaClass)
+{
+ if (metaClass->isNamespace())
+ return std::nullopt;
+
+ const auto te = metaClass->typeEntry();
+ if (te->isSmartPointer()) {
+ auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(te);
+
+ auto valueCheckMethod = ste->valueCheckMethod();
+ if (!valueCheckMethod.isEmpty()) {
+ const auto func = metaClass->findFunction(valueCheckMethod);
+ if (!func)
+ throw Exception(msgMethodNotFound(metaClass, valueCheckMethod));
+ return BoolCastFunction{func, false};
+ }
+
+ auto nullCheckMethod = ste->nullCheckMethod();
+ if (!nullCheckMethod.isEmpty()) {
+ const auto func = metaClass->findFunction(nullCheckMethod);
+ if (!func)
+ throw Exception(msgMethodNotFound(metaClass, nullCheckMethod));
+ return BoolCastFunction{func, true};
+ }
+ }
+
+ auto mode = te->operatorBoolMode();
+ if (useOperatorBoolAsNbBool()
+ ? mode != TypeSystem::BoolCast::Disabled : mode == TypeSystem::BoolCast::Enabled) {
+ const auto func = metaClass->findOperatorBool();
+ if (func)
+ return BoolCastFunction{func, false};
+ }
+
+ mode = te->isNullMode();
+ if (useIsNullAsNbBool()
+ ? mode != TypeSystem::BoolCast::Disabled : mode == TypeSystem::BoolCast::Enabled) {
+ const auto func = metaClass->findQtIsNullMethod();
+ if (func)
+ return BoolCastFunction{func, true};
+ }
+ return std::nullopt;
+}
+
+static bool isInplaceAdd(const AbstractMetaFunctionCPtr &func)
+{
+ return func->name() == u"operator+=";
+}
+
+static bool isIncrementOperator(const AbstractMetaFunctionCPtr &func)
+{
+ return func->functionType() == AbstractMetaFunction::IncrementOperator;
+}
+
+static bool isDecrementOperator(const AbstractMetaFunctionCPtr &func)
+{
+ return func->functionType() == AbstractMetaFunction::DecrementOperator;
+}
+
+// Filter predicate for operator functions
+static bool skipOperatorFunc(const AbstractMetaFunctionCPtr &func)
+{
+ if (func->isModifiedRemoved() || func->usesRValueReferences())
+ return true;
+ const auto &name = func->name();
+ return name == u"operator[]" || name == u"operator->" || name == u"operator!"
+ || name == u"operator/="; // __idiv__ is not needed in Python3
+}
+
+QList<AbstractMetaFunctionCList>
+ShibokenGenerator::filterGroupedOperatorFunctions(const AbstractMetaClassCPtr &metaClass,
+ OperatorQueryOptions query)
+{
+ // ( func_name, num_args ) => func_list
+ QMap<std::pair<QString, int>, AbstractMetaFunctionCList> results;
+ auto funcs = metaClass->operatorOverloads(query);
+ auto end = std::remove_if(funcs.begin(), funcs.end(), skipOperatorFunc);
+ funcs.erase(end, funcs.end());
+ // If we have operator+=, we remove the operator++/-- which would
+ // otherwise be used for emulating __iadd__, __isub__.
+ if (std::any_of(funcs.cbegin(), funcs.cend(), isInplaceAdd)) {
+ end = std::remove_if(funcs.begin(), funcs.end(),
+ [] (const AbstractMetaFunctionCPtr &func) {
+ return func->isIncDecrementOperator();
+ });
+ funcs.erase(end, funcs.end());
+ } else {
+ // If both prefix/postfix ++/-- are present, remove one
+ if (std::count_if(funcs.begin(), funcs.end(), isIncrementOperator) > 1)
+ funcs.erase(std::find_if(funcs.begin(), funcs.end(), isIncrementOperator));
+ if (std::count_if(funcs.begin(), funcs.end(), isDecrementOperator) > 1)
+ funcs.erase(std::find_if(funcs.begin(), funcs.end(), isDecrementOperator));
+ }
+ for (const auto &func : funcs) {
+ int args;
+ if (func->isComparisonOperator()) {
+ args = -1;
+ } else {
+ args = func->arguments().size();
+ }
+ auto op = std::make_pair(func->name(), args);
+ results[op].append(func);
+ }
+ QList<AbstractMetaFunctionCList> result;
+ result.reserve(results.size());
+ for (auto it = results.cbegin(), end = results.cend(); it != end; ++it)
+ result.append(it.value());
+ return result;
+}
+
static bool hidesBaseClassFunctions(const AbstractMetaFunctionCPtr &f)
{
- return 0 == (f->attributes()
- & (AbstractMetaFunction::OverriddenCppMethod | AbstractMetaFunction::FinalCppMethod));
+ auto attributes = f->cppAttributes();
+ return !attributes.testFlag(FunctionAttribute::Override)
+ && !attributes.testFlag(FunctionAttribute::Final);
}
void ShibokenGenerator::getInheritedOverloads(const AbstractMetaClassCPtr &scope,
@@ -2105,92 +2336,108 @@ void ShibokenGenerator::getInheritedOverloads(const AbstractMetaClassCPtr &scope
}
}
-Generator::OptionDescriptions ShibokenGenerator::options() const
+QList<OptionDescription> ShibokenGenerator::options()
{
- auto result = Generator::options();
- result.append({
- {QLatin1StringView(DISABLE_VERBOSE_ERROR_MESSAGES),
+ return {
+ {DISABLE_VERBOSE_ERROR_MESSAGES,
u"Disable verbose error messages. Turn the python code hard to debug\n"
"but safe few kB on the generated bindings."_s},
- {QLatin1StringView(PARENT_CTOR_HEURISTIC),
+ {PARENT_CTOR_HEURISTIC,
u"Enable heuristics to detect parent relationship on constructors."_s},
- {QLatin1StringView(RETURN_VALUE_HEURISTIC),
+ {RETURN_VALUE_HEURISTIC,
u"Enable heuristics to detect parent relationship on return values\n"
"(USE WITH CAUTION!)"_s},
- {QLatin1StringView(USE_ISNULL_AS_NB_NONZERO),
+ {USE_ISNULL_AS_NB_BOOL,
u"If a class have an isNull() const method, it will be used to compute\n"
"the value of boolean casts"_s},
- {QLatin1StringView(LEAN_HEADERS),
+ {LEAN_HEADERS,
u"Forward declare classes in module headers"_s},
- {QLatin1StringView(USE_OPERATOR_BOOL_AS_NB_NONZERO),
+ {USE_OPERATOR_BOOL_AS_NB_BOOL,
u"If a class has an operator bool, it will be used to compute\n"
"the value of boolean casts"_s},
- {QLatin1StringView(NO_IMPLICIT_CONVERSIONS),
+ {NO_IMPLICIT_CONVERSIONS,
u"Do not generate implicit_conversions for function arguments."_s},
- {QLatin1StringView(WRAPPER_DIAGNOSTICS),
+ {WRAPPER_DIAGNOSTICS,
u"Generate diagnostic code around wrappers"_s}
- });
- return result;
+ };
}
-bool ShibokenGenerator::handleOption(const QString &key, const QString &value)
+class ShibokenGeneratorOptionsParser : public OptionsParser
{
- if (Generator::handleOption(key, value))
- return true;
- if (key == QLatin1StringView(PARENT_CTOR_HEURISTIC))
- return (m_useCtorHeuristic = true);
- if (key == QLatin1StringView(RETURN_VALUE_HEURISTIC))
- return (m_userReturnValueHeuristic = true);
- if (key == QLatin1StringView(DISABLE_VERBOSE_ERROR_MESSAGES))
- return (m_verboseErrorMessagesDisabled = true);
- if (key == QLatin1StringView(USE_ISNULL_AS_NB_NONZERO))
- return (m_useIsNullAsNbNonZero = true);
- if (key == QLatin1StringView(LEAN_HEADERS))
- return (m_leanHeaders= true);
- if (key == QLatin1StringView(USE_OPERATOR_BOOL_AS_NB_NONZERO))
- return (m_useOperatorBoolAsNbNonZero = true);
- if (key == QLatin1StringView(NO_IMPLICIT_CONVERSIONS)) {
- return m_generateImplicitConversions = false;
+public:
+ explicit ShibokenGeneratorOptionsParser(ShibokenGeneratorOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString & key, OptionSource source) override;
+
+private:
+ ShibokenGeneratorOptions *m_options;
+};
+
+bool ShibokenGeneratorOptionsParser::handleBoolOption(const QString &key, OptionSource source)
+{
+ if (source == OptionSource::CommandLineSingleDash)
+ return false;
+ if (key == PARENT_CTOR_HEURISTIC)
+ return (m_options->useCtorHeuristic = true);
+ if (key == RETURN_VALUE_HEURISTIC)
+ return (m_options->userReturnValueHeuristic = true);
+ if (key == DISABLE_VERBOSE_ERROR_MESSAGES)
+ return (m_options->verboseErrorMessagesDisabled = true);
+ if (key == USE_ISNULL_AS_NB_BOOL || key == USE_ISNULL_AS_NB_NONZERO) {
+ return (m_options->useIsNullAsNbBool = true);
+ }
+ if (key == LEAN_HEADERS)
+ return (m_options->leanHeaders= true);
+ if (key == USE_OPERATOR_BOOL_AS_NB_BOOL || key == USE_OPERATOR_BOOL_AS_NB_NONZERO) {
+ return (m_options->useOperatorBoolAsNbBool = true);
+ }
+ if (key == NO_IMPLICIT_CONVERSIONS) {
+ m_options->generateImplicitConversions = false;
return true;
}
- if (key == QLatin1StringView(WRAPPER_DIAGNOSTICS))
- return (m_wrapperDiagnostics = true);
+ if (key == WRAPPER_DIAGNOSTICS)
+ return (m_options->wrapperDiagnostics = true);
return false;
}
+std::shared_ptr<OptionsParser> ShibokenGenerator::createOptionsParser()
+{
+ return std::make_shared<ShibokenGeneratorOptionsParser>(&m_options);
+}
+
bool ShibokenGenerator::doSetup()
{
return true;
}
-bool ShibokenGenerator::useCtorHeuristic() const
+bool ShibokenGenerator::useCtorHeuristic()
{
- return m_useCtorHeuristic;
+ return m_options.useCtorHeuristic;
}
-bool ShibokenGenerator::useReturnValueHeuristic() const
+bool ShibokenGenerator::useReturnValueHeuristic()
{
- return m_userReturnValueHeuristic;
+ return m_options.userReturnValueHeuristic;
}
-bool ShibokenGenerator::useIsNullAsNbNonZero() const
+bool ShibokenGenerator::useIsNullAsNbBool()
{
- return m_useIsNullAsNbNonZero;
+ return m_options.useIsNullAsNbBool;
}
-bool ShibokenGenerator::leanHeaders() const
+bool ShibokenGenerator::leanHeaders()
{
- return m_leanHeaders;
+ return m_options.leanHeaders;
}
-bool ShibokenGenerator::useOperatorBoolAsNbNonZero() const
+bool ShibokenGenerator::useOperatorBoolAsNbBool()
{
- return m_useOperatorBoolAsNbNonZero;
+ return m_options.useOperatorBoolAsNbBool;
}
-bool ShibokenGenerator::generateImplicitConversions() const
+bool ShibokenGenerator::generateImplicitConversions()
{
- return m_generateImplicitConversions;
+ return m_options.generateImplicitConversions;
}
QString ShibokenGenerator::moduleCppPrefix(const QString &moduleName)
@@ -2200,19 +2447,24 @@ QString ShibokenGenerator::moduleCppPrefix(const QString &moduleName)
return result;
}
+QString ShibokenGenerator::cppApiVariableNameOld(const QString &moduleName)
+{
+ return "Sbk"_L1 + moduleCppPrefix(moduleName) + "Types"_L1;
+}
+
QString ShibokenGenerator::cppApiVariableName(const QString &moduleName)
{
- return u"Sbk"_s + moduleCppPrefix(moduleName) + u"Types"_s;
+ return "Sbk"_L1 + moduleCppPrefix(moduleName) + "TypeStructs"_L1;
}
QString ShibokenGenerator::pythonModuleObjectName(const QString &moduleName)
{
- return u"Sbk"_s + moduleCppPrefix(moduleName) + u"ModuleObject"_s;
+ return "Sbk"_L1 + moduleCppPrefix(moduleName) + "ModuleObject"_L1;
}
QString ShibokenGenerator::convertersVariableName(const QString &moduleName)
{
- QString result = cppApiVariableName(moduleName);
+ QString result = cppApiVariableNameOld(moduleName);
result.chop(1);
result.append(u"Converters"_s);
return result;
@@ -2220,11 +2472,11 @@ QString ShibokenGenerator::convertersVariableName(const QString &moduleName)
static QString processInstantiationsVariableName(const AbstractMetaType &type)
{
- QString res = u'_' + _fixedCppTypeName(type.typeEntry()->qualifiedCppName()).toUpper();
+ QString res = u'_' + _fixedCppTypeName(type.typeEntry()->qualifiedCppName());
for (const auto &instantiation : type.instantiations()) {
res += instantiation.isContainer()
? processInstantiationsVariableName(instantiation)
- : u'_' + _fixedCppTypeName(instantiation.cppSignature()).toUpper();
+ : u'_' + _fixedCppTypeName(instantiation.cppSignature());
}
return res;
}
@@ -2233,7 +2485,7 @@ static void appendIndexSuffix(QString *s)
{
if (!s->endsWith(u'_'))
s->append(u'_');
- s->append(QStringLiteral("IDX"));
+ s->append("IDX"_L1);
}
QString
@@ -2242,7 +2494,7 @@ QString
const auto templateBaseClass = metaClass->templateBaseClass();
Q_ASSERT(templateBaseClass);
QString result = u"SBK_"_s
- + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper();
+ + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName());
for (const auto &instantiation : metaClass->templateBaseClassInstantiations())
result += processInstantiationsVariableName(instantiation);
appendIndexSuffix(&result);
@@ -2264,7 +2516,7 @@ QString ShibokenGenerator::getTypeIndexVariableName(TypeEntryCPtr type)
const int dot = package.lastIndexOf(u'.');
result += QStringView{package}.right(package.size() - (dot + 1));
}
- result += _fixedCppTypeName(type->qualifiedCppName()).toUpper();
+ result += _fixedCppTypeName(type->qualifiedCppName());
appendIndexSuffix(&result);
return result;
}
@@ -2272,15 +2524,49 @@ QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaType &type
{
QString result = u"SBK"_s;
if (type.typeEntry()->isContainer())
- result += u'_' + moduleName().toUpper();
+ result += u'_' + moduleName();
result += processInstantiationsVariableName(type);
appendIndexSuffix(&result);
return result;
}
-bool ShibokenGenerator::verboseErrorMessagesDisabled() const
+void collectfromTypeEntry(TypeEntryCPtr entry, QStringList &typeNames)
+{
+ if (entry->shouldGenerate()) {
+ typeNames[entry->sbkIndex()] = entry->qualifiedTargetLangName();
+ if (entry->isEnum()) {
+ auto ete = std::static_pointer_cast<const EnumTypeEntry>(entry);
+ if (ete->flags()) {
+ auto entry = ete->flags();
+ typeNames[entry->sbkIndex()] = entry->qualifiedTargetLangName();
+ }
+ }
+ }
+}
+
+void ShibokenGenerator::collectFullTypeNamesArray(QStringList &typeNames)
+{
+ for (const auto &metaClass : api().classes()) {
+ collectfromTypeEntry(metaClass->typeEntry(), typeNames);
+
+ for (const AbstractMetaEnum &metaEnum : metaClass->enums())
+ collectfromTypeEntry(metaEnum.typeEntry(), typeNames);
+
+ int smartPointerCountIndex = getMaxTypeIndex();
+ for (const auto &smp : api().instantiatedSmartPointers()) {
+ auto entry = smp.type.typeEntry();
+ typeNames[smartPointerCountIndex] =
+ smp.specialized->typeEntry()->qualifiedTargetLangName();
+ ++smartPointerCountIndex;
+ }
+ }
+ for (const AbstractMetaEnum &metaEnum : api().globalEnums())
+ collectfromTypeEntry(metaEnum.typeEntry(), typeNames);
+}
+
+bool ShibokenGenerator::verboseErrorMessagesDisabled()
{
- return m_verboseErrorMessagesDisabled;
+ return m_options.verboseErrorMessagesDisabled;
}
bool ShibokenGenerator::pythonFunctionWrapperUsesListOfArguments(const AbstractMetaFunctionCPtr &func) const