aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator/generator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/generator/generator.cpp')
-rw-r--r--sources/shiboken6/generator/generator.cpp123
1 files changed, 83 insertions, 40 deletions
diff --git a/sources/shiboken6/generator/generator.cpp b/sources/shiboken6/generator/generator.cpp
index ddf38d209..a01326530 100644
--- a/sources/shiboken6/generator/generator.cpp
+++ b/sources/shiboken6/generator/generator.cpp
@@ -10,6 +10,7 @@
#include "abstractmetafunction.h"
#include "abstractmetalang.h"
#include "messages.h"
+#include <optionsparser.h>
#include "reporthandler.h"
#include "fileout.h"
#include "arraytypeentry.h"
@@ -29,8 +30,14 @@
using namespace Qt::StringLiterals;
-static const char ENABLE_PYSIDE_EXTENSIONS[] = "enable-pyside-extensions";
-static const char AVOID_PROTECTED_HACK[] = "avoid-protected-hack";
+static constexpr auto ENABLE_PYSIDE_EXTENSIONS = "enable-pyside-extensions"_L1;
+static constexpr auto AVOID_PROTECTED_HACK = "avoid-protected-hack"_L1;
+
+struct GeneratorOptions
+{
+ bool usePySideExtensions = false;
+ bool avoidProtectedHack = false;
+};
struct Generator::GeneratorPrivate
{
@@ -40,10 +47,14 @@ struct Generator::GeneratorPrivate
QString licenseComment;
AbstractMetaClassCList m_invisibleTopNamespaces;
bool m_hasPrivateClasses = false;
- bool m_usePySideExtensions = false;
- bool m_avoidProtectedHack = false;
+ static GeneratorOptions m_options;
};
+GeneratorOptions Generator::GeneratorPrivate::m_options;
+
+// Kept as a variable for a potential Qt-in-namespace support
+QString Generator::m_gsp = "::"_L1;
+
Generator::Generator() : m_d(new GeneratorPrivate)
{
}
@@ -78,26 +89,44 @@ bool Generator::setup(const ApiExtractorResult &api)
return doSetup();
}
-Generator::OptionDescriptions Generator::options() const
+QList<OptionDescription> Generator::options()
{
return {
- {QLatin1StringView(AVOID_PROTECTED_HACK),
+ {AVOID_PROTECTED_HACK,
u"Avoid the use of the '#define protected public' hack."_s},
- {QLatin1StringView(ENABLE_PYSIDE_EXTENSIONS),
+ {ENABLE_PYSIDE_EXTENSIONS,
u"Enable PySide extensions, such as support for signal/slots,\n"
"use this if you are creating a binding for a Qt-based library."_s}
};
}
-bool Generator::handleOption(const QString & key, const QString & /* value */)
+class GeneratorOptionsParser : public OptionsParser
+{
+public:
+ explicit GeneratorOptionsParser(GeneratorOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+
+private:
+ GeneratorOptions *m_options;
+};
+
+bool GeneratorOptionsParser::handleBoolOption(const QString & key, OptionSource source)
{
- if (key == QLatin1StringView(ENABLE_PYSIDE_EXTENSIONS))
- return ( m_d->m_usePySideExtensions = true);
- if (key == QLatin1StringView(AVOID_PROTECTED_HACK))
- return (m_d->m_avoidProtectedHack = true);
+ if (source == OptionSource::CommandLineSingleDash)
+ return false;
+ if (key == ENABLE_PYSIDE_EXTENSIONS)
+ return ( m_options->usePySideExtensions = true);
+ if (key == AVOID_PROTECTED_HACK)
+ return ( m_options->avoidProtectedHack = true);
return false;
}
+std::shared_ptr<OptionsParser> Generator::createOptionsParser()
+{
+ return std::make_shared<GeneratorOptionsParser>(&GeneratorPrivate::m_options);
+}
+
QString Generator::fileNameForContextHelper(const GeneratorContext &context,
const QString &suffix,
FileNameFlags flags)
@@ -202,10 +231,9 @@ QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType &smartP
const AbstractMetaType innerType = smartPointerType.getSmartPointerInnerType();
smartPointerType.typeEntry()->qualifiedCppName();
QString fileName = smartPointerType.typeEntry()->qualifiedCppName().toLower();
- fileName.replace(u"::"_s, u"_"_s);
- fileName.append(u"_"_s);
+ fileName.append(u'_');
fileName.append(innerType.name().toLower());
-
+ fileName.replace(u"::"_s, u"_"_s); // std::shared_ptr<std::string>
return fileName;
}
@@ -267,14 +295,14 @@ bool Generator::hasPrivateClasses() const
return m_d->m_hasPrivateClasses;
}
-bool Generator::usePySideExtensions() const
+bool Generator::usePySideExtensions()
{
- return m_d->m_usePySideExtensions;
+ return GeneratorPrivate::m_options.usePySideExtensions;
}
-bool Generator::avoidProtectedHack() const
+bool Generator::avoidProtectedHack()
{
- return m_d->m_avoidProtectedHack;
+ return GeneratorPrivate::m_options.avoidProtectedHack;
}
QString Generator::getFullTypeName(TypeEntryCPtr type)
@@ -282,9 +310,7 @@ QString Generator::getFullTypeName(TypeEntryCPtr type)
QString result = type->qualifiedCppName();
if (type->isArray())
type = std::static_pointer_cast<const ArrayTypeEntry>(type)->nestedTypeEntry();
- if (!isCppPrimitive(type))
- result.prepend(u"::"_s);
- return result;
+ return isCppPrimitive(type) ? result : addGlobalScopePrefix(result);
}
QString Generator::getFullTypeName(const AbstractMetaType &type)
@@ -294,7 +320,7 @@ QString Generator::getFullTypeName(const AbstractMetaType &type)
if (type.isVoidPointer())
return u"void*"_s;
if (type.typeEntry()->isContainer())
- return u"::"_s + type.cppSignature();
+ return addGlobalScopePrefix(type.cppSignature());
QString typeName;
if (type.typeEntry()->isComplex() && type.hasInstantiations())
typeName = getFullTypeNameWithoutModifiers(type);
@@ -305,7 +331,9 @@ QString Generator::getFullTypeName(const AbstractMetaType &type)
QString Generator::getFullTypeName(const AbstractMetaClassCPtr &metaClass)
{
- return u"::"_s + metaClass->qualifiedCppName();
+ const QString &qualName = metaClass->qualifiedCppName();
+ // Typedefs are generated into the global namespace
+ return metaClass->isTypeDef() ? qualName : addGlobalScopePrefix(qualName);
}
QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType &type)
@@ -331,7 +359,7 @@ QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType &type)
}
while (typeName.endsWith(u'*') || typeName.endsWith(u' '))
typeName.chop(1);
- return u"::"_s + typeName;
+ return addGlobalScopePrefix(typeName);
}
std::optional<DefaultValue>
@@ -360,7 +388,7 @@ std::optional<DefaultValue>
if (type.isNativePointer())
return DefaultValue(DefaultValue::Pointer, type.typeEntry()->qualifiedCppName());
if (type.isPointer())
- return DefaultValue(DefaultValue::Pointer, u"::"_s + type.typeEntry()->qualifiedCppName());
+ return DefaultValue(DefaultValue::Pointer, getFullTypeName(type.typeEntry()));
if (type.typeEntry()->isSmartPointer())
return minimalConstructor(api, type.typeEntry());
@@ -409,8 +437,7 @@ std::optional<DefaultValue>
if (const auto nullValue = enumEntry->nullValue())
return DefaultValue(DefaultValue::Enum, nullValue->name());
return DefaultValue(DefaultValue::Custom,
- u"static_cast< ::"_s + type->qualifiedCppName()
- + u">(0)"_s);
+ "static_cast< "_L1 + getFullTypeName(type) + ">(0)"_L1);
}
if (type->isFlags()) {
@@ -502,8 +529,7 @@ std::optional<DefaultValue>
for (auto it = candidates.cbegin(), end = candidates.cend(); it != end; ++it) {
const AbstractMetaArgumentList &arguments = it.value()->arguments();
QStringList args;
- for (qsizetype i = 0, size = arguments.size(); i < size; ++i) {
- const AbstractMetaArgument &arg = arguments.at(i);
+ for (const auto &arg : arguments) {
if (arg.hasModifiedDefaultValueExpression()) {
args << arg.defaultValueExpression(); // Spell out modified values
break;
@@ -538,20 +564,20 @@ QString Generator::translateType(AbstractMetaType cType,
} else if (cType.isArray()) {
s = translateType(*cType.arrayElementType(), context, options) + u"[]"_s;
} else {
+ AbstractMetaType copyType = cType;
if (options & Generator::ExcludeConst || options & Generator::ExcludeReference) {
- AbstractMetaType copyType = cType;
-
if (options & Generator::ExcludeConst)
copyType.setConstant(false);
-
if (options & Generator::ExcludeReference)
copyType.setReferenceType(NoReference);
+ }
- s = copyType.cppSignature();
- if (!copyType.typeEntry()->isVoid() && !isCppPrimitive(copyType.typeEntry()))
- s.prepend(u"::"_s);
- } else {
- s = cType.cppSignature();
+ s = copyType.cppSignature();
+ const auto te = copyType.typeEntry();
+ if (!te->isVoid() && !isCppPrimitive(te)) { // Add scope resolution
+ const auto pos = s.indexOf(te->qualifiedCppName()); // Skip const/volatile
+ Q_ASSERT(pos >= 0);
+ s.insert(pos, u"::"_s);
}
}
@@ -575,7 +601,6 @@ static const QHash<QString, QString> &pythonOperators()
{u"operator++"_s, u"__iadd__"_s},
{u"operator--"_s, u"__isub__"_s},
{u"operator*="_s, u"__imul__"_s},
- {u"operator/="_s, u"__idiv__"_s},
{u"operator%="_s, u"__imod__"_s},
// Bitwise operators
{u"operator&"_s, u"__and__"_s},
@@ -596,7 +621,10 @@ static const QHash<QString, QString> &pythonOperators()
{u"operator<"_s, u"__lt__"_s},
{u"operator>"_s, u"__gt__"_s},
{u"operator<="_s, u"__le__"_s},
- {u"operator>="_s, u"__ge__"_s}
+ {u"operator>="_s, u"__ge__"_s},
+ // Conversion (note bool has special handling with heuristics)
+ {u"operator int"_s, u"__int__"_s},
+ {u"operator double"_s, u"__float__"_s}
};
return result;
}
@@ -606,6 +634,11 @@ QString Generator::pythonOperatorFunctionName(const QString &cppOpFuncName)
return pythonOperators().value(cppOpFuncName);
}
+bool Generator::isPythonOperatorFunctionName(const QString &cppOpFuncName)
+{
+ return pythonOperators().contains(cppOpFuncName);
+}
+
QString Generator::subDirectoryForPackage(QString packageNameIn) const
{
if (packageNameIn.isEmpty())
@@ -614,6 +647,16 @@ QString Generator::subDirectoryForPackage(QString packageNameIn) const
return packageNameIn;
}
+QString Generator::addGlobalScopePrefix(const QString &t)
+{
+ return t.startsWith("std::"_L1) ? t : m_gsp + t;
+}
+
+QString Generator::globalScopePrefix(const GeneratorContext &classContext)
+{
+ return classContext.useWrapper() ? QString{} : m_gsp;
+}
+
template<typename T>
static QString getClassTargetFullName_(T t, bool includePackageName)
{