diff options
Diffstat (limited to 'sources/shiboken6/generator/generator.cpp')
-rw-r--r-- | sources/shiboken6/generator/generator.cpp | 123 |
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) { |