diff options
6 files changed, 79 insertions, 65 deletions
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp index c04661ab6..88ba1f04f 100644 --- a/sources/shiboken2/generator/generator.cpp +++ b/sources/shiboken2/generator/generator.cpp @@ -151,6 +151,12 @@ QString DefaultValue::constructorParameter() const return m_value + QLatin1String("()"); } +QString GeneratorContext::smartPointerWrapperName() const +{ + Q_ASSERT(m_type == SmartPointer); + return m_preciseClassType->cppSignature(); +} + struct Generator::GeneratorPrivate { const ApiExtractor *apiextractor = nullptr; @@ -453,7 +459,7 @@ GeneratorContext Generator::contextForSmartPointer(const AbstractMetaClass *c, GeneratorContext result; result.m_metaClass = c; result.m_preciseClassType = t; - result.m_forSmartPointer = true; + result.m_type = GeneratorContext::SmartPointer; return result; } diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h index 48412e7ea..5a55422a1 100644 --- a/sources/shiboken2/generator/generator.h +++ b/sources/shiboken2/generator/generator.h @@ -149,16 +149,29 @@ class GeneratorContext { friend class ShibokenGenerator; friend class Generator; public: + enum Type { Class, WrappedClass, SmartPointer }; + GeneratorContext() = default; const AbstractMetaClass *metaClass() const { return m_metaClass; } - bool forSmartPointer() const { return m_forSmartPointer; } const AbstractMetaType *preciseType() const { return m_preciseClassType; } + bool forSmartPointer() const { return m_type == SmartPointer; } + bool useWrapper() const { return m_type == WrappedClass; } + + QString wrapperName() const + { + Q_ASSERT(m_type == WrappedClass); + return m_wrappername; + } + + QString smartPointerWrapperName() const; + private: const AbstractMetaClass *m_metaClass = nullptr; const AbstractMetaType *m_preciseClassType = nullptr; - bool m_forSmartPointer = false; + QString m_wrappername; + Type m_type = Class; }; /** diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 1ef901ade..2d3182874 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -405,11 +405,11 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo s << metaClass->typeEntry()->conversionRule() << Qt::endl; } - if (shouldGenerateCppWrapper(metaClass)) { + if (classContext.useWrapper()) { s << "// Native ---------------------------------------------------------\n\n"; if (avoidProtectedHack() && usePySideExtensions()) { - s << "void " << wrapperName(metaClass) << "::pysideInitQtMetaTypes()\n{\n"; + s << "void " << classContext.wrapperName() << "::pysideInitQtMetaTypes()\n{\n"; Indentation indent(INDENT); writeInitQtMetaTypeFunctionBody(s, classContext); s << "}\n\n"; @@ -701,7 +701,7 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo void CppGenerator::writeCacheResetNative(QTextStream &s, const GeneratorContext &classContext) { Indentation indentation(INDENT); - s << "void " << wrapperName(classContext.metaClass()) + s << "void " << classContext.wrapperName() << "::resetPyMethodCache()\n{\n"; s << INDENT << "std::fill_n(m_PyMethodCache, sizeof(m_PyMethodCache) / sizeof(m_PyMethodCache[0]), false);\n"; s << "}\n\n"; @@ -711,7 +711,7 @@ void CppGenerator::writeConstructorNative(QTextStream &s, const GeneratorContext const AbstractMetaFunction *func) { Indentation indentation(INDENT); - const QString qualifiedName = wrapperName(classContext.metaClass()) + QLatin1String("::"); + const QString qualifiedName = classContext.wrapperName() + QLatin1String("::"); s << functionSignature(func, qualifiedName, QString(), OriginalTypeDescription | SkipDefaultValues); s << " : "; @@ -730,8 +730,8 @@ void CppGenerator::writeConstructorNative(QTextStream &s, const GeneratorContext void CppGenerator::writeDestructorNative(QTextStream &s, const GeneratorContext &classContext) { Indentation indentation(INDENT); - s << wrapperName(classContext.metaClass()) << "::~" - << wrapperName(classContext.metaClass()) << "()\n{\n"; + s << classContext.wrapperName() << "::~" + << classContext.wrapperName() << "()\n{\n"; if (wrapperDiagnostics()) s << INDENT << R"(std::cerr << __FUNCTION__ << ' ' << this << '\n';)" << '\n'; // kill pyobject @@ -1143,7 +1143,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, void CppGenerator::writeMetaObjectMethod(QTextStream &s, const GeneratorContext &classContext) { Indentation indentation(INDENT); - QString wrapperClassName = wrapperName(classContext.metaClass()); + const QString wrapperClassName = classContext.wrapperName(); const QString qualifiedCppName = classContext.metaClass()->qualifiedCppName(); s << "const QMetaObject *" << wrapperClassName << "::metaObject() const\n{\n"; s << INDENT << "if (QObject::d_ptr->metaObject)\n" @@ -1184,7 +1184,7 @@ void CppGenerator::writeMetaObjectMethod(QTextStream &s, const GeneratorContext void CppGenerator::writeMetaCast(QTextStream &s, const GeneratorContext &classContext) { Indentation indentation(INDENT); - QString wrapperClassName = wrapperName(classContext.metaClass()); + const QString wrapperClassName = classContext.wrapperName(); const QString qualifiedCppName = classContext.metaClass()->qualifiedCppName(); s << "void *" << wrapperClassName << "::qt_metacast(const char *_clname)\n{\n"; s << INDENT << "if (!_clname) return {};\n"; @@ -1376,10 +1376,10 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla QString computedWrapperName; if (!classContext.forSmartPointer()) { - computedWrapperName = shouldGenerateCppWrapper(metaClass) - ? wrapperName(metaClass) : metaClass->qualifiedCppName(); + computedWrapperName = classContext.useWrapper() + ? classContext.wrapperName() : metaClass->qualifiedCppName(); } else { - computedWrapperName = wrapperName(classContext.preciseType()); + computedWrapperName = classContext.smartPointerWrapperName(); } c << INDENT << "return Shiboken::Object::newObject(" << cpythonType @@ -1560,9 +1560,9 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas s << qualifiedCppNameInvocation << ").name());\n"; - if (shouldGenerateCppWrapper(metaClass)) { + if (classContext.useWrapper()) { s << INDENT << "Shiboken::Conversions::registerConverterName(converter, typeid(::"; - s << wrapperName(metaClass) << ").name());\n"; + s << classContext.wrapperName() << ").name());\n"; } s << Qt::endl; @@ -1641,6 +1641,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over { const AbstractMetaFunction *rfunc = overloadData.referenceFunction(); const AbstractMetaClass *ownerClass = rfunc->ownerClass(); + Q_ASSERT(ownerClass == context.metaClass()); int minArgs = overloadData.minArgs(); int maxArgs = overloadData.maxArgs(); bool initPythonArguments; @@ -1665,10 +1666,9 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over // Declare pointer for the underlying C++ object. s << INDENT << "::"; if (!context.forSmartPointer()) { - s << (shouldGenerateCppWrapper(ownerClass) ? wrapperName(ownerClass) - : ownerClass->qualifiedCppName()); + s << (context.useWrapper() ? context.wrapperName() : ownerClass->qualifiedCppName()); } else { - s << context.preciseType()->cppSignature(); + s << context.smartPointerWrapperName(); } s << " *cptr{};\n"; @@ -2093,13 +2093,14 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s, const AbstractMetaClass *metaClass = context.metaClass(); bool useWrapperClass = avoidProtectedHack() && metaClass->hasProtectedMembers(); + Q_ASSERT(!useWrapperClass || context.useWrapper()); QString className; if (!context.forSmartPointer()) { className = useWrapperClass - ? wrapperName(metaClass) + ? context.wrapperName() : (QLatin1String("::") + metaClass->qualifiedCppName()); } else { - className = context.preciseType()->cppSignature(); + className = context.smartPointerWrapperName(); } writeInvalidPyObjectCheck(s, QLatin1String("self")); @@ -3334,8 +3335,9 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f if (func->isConstructor()) { isCtor = true; const auto owner = func->ownerClass(); - QString className = shouldGenerateCppWrapper(owner) - ? wrapperName(owner) : owner->qualifiedCppName(); + Q_ASSERT(owner == context.metaClass()); + QString className = context.useWrapper() + ? context.wrapperName() : owner->qualifiedCppName(); if (func->functionType() == AbstractMetaFunction::CopyConstructorFunction && maxArgs == 1) { mc << "new ::" << className << "(*" << CPP_ARG0 << ')'; @@ -3935,11 +3937,8 @@ void CppGenerator::writeClassDefinition(QTextStream &s, QLatin1String("Sbk_object_dealloc /* PYSIDE-832: Prevent replacement of \"0\" with subtype_dealloc. */"); tp_init.clear(); } else { - QString deallocClassName; - if (shouldGenerateCppWrapper(metaClass)) - deallocClassName = wrapperName(metaClass); - else - deallocClassName = cppClassName; + QString deallocClassName = classContext.useWrapper() + ? classContext.wrapperName() : cppClassName; if (isQApp) tp_dealloc = QLatin1String("&SbkDeallocQAppWrapper"); else @@ -4334,7 +4333,7 @@ void CppGenerator::writeGetterFunction(QTextStream &s, QString cppField; if (avoidProtectedHack() && metaField->isProtected()) { QTextStream(&cppField) << "static_cast<" - << wrapperName(metaField->enclosingClass()) << " *>(" + << context.wrapperName() << " *>(" << CPP_SELF_VAR << ")->" << protectedFieldGetterName(metaField) << "()"; } else { cppField = QLatin1String(CPP_SELF_VAR) + QLatin1String("->") + metaField->name(); @@ -4438,7 +4437,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s, s << getFullTypeNameWithoutModifiers(fieldType); s << (fieldType->indirections() == 1 ? " *" : "") << " cppOut;\n"; s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut);\n"; - s << INDENT << "static_cast<" << wrapperName(metaField->enclosingClass()) + s << INDENT << "static_cast<" << context.wrapperName() << " *>(" << CPP_SELF_VAR << ")->" << protectedFieldSetterName(metaField) << "(cppOut)"; } else if (isCppIntegralPrimitive(fieldType) || fieldType->typeEntry()->isEnum() || fieldType->typeEntry()->isFlags()) { @@ -5056,11 +5055,11 @@ void CppGenerator::writeClassRegister(QTextStream &s, if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) { QString dtorClassName = metaClass->qualifiedCppName(); if (((avoidProtectedHack() && metaClass->hasProtectedDestructor()) || classTypeEntry->isValue()) - && shouldGenerateCppWrapper(metaClass)) { - dtorClassName = wrapperName(metaClass); + && classContext.useWrapper()) { + dtorClassName = classContext.wrapperName(); } if (classContext.forSmartPointer()) - dtorClassName = wrapperName(classContext.preciseType()); + dtorClassName = classContext.smartPointerWrapperName(); s << "&Shiboken::callCppDestructor< ::" << dtorClassName << " >,\n"; } else { @@ -5170,8 +5169,8 @@ void CppGenerator::writeClassRegister(QTextStream &s, } if (usePySideExtensions()) { - if (avoidProtectedHack() && shouldGenerateCppWrapper(metaClass)) - s << INDENT << wrapperName(metaClass) << "::pysideInitQtMetaTypes();\n"; + if (avoidProtectedHack() && classContext.useWrapper()) + s << INDENT << classContext.wrapperName() << "::pysideInitQtMetaTypes();\n"; else writeInitQtMetaTypeFunctionBody(s, classContext); } @@ -5325,10 +5324,10 @@ void CppGenerator::writeSetattroFunction(QTextStream &s, AttroCheck attroCheck, writeSetattroDefinition(s, metaClass); // PYSIDE-803: Detect duck-punching; clear cache if a method is set. if (attroCheck.testFlag(AttroCheckFlag::SetattroMethodOverride) - && ShibokenGenerator::shouldGenerateCppWrapper(metaClass)) { + && context.useWrapper()) { s << INDENT << "if (value && PyCallable_Check(value)) {\n"; s << INDENT << " auto plain_inst = " << cpythonWrapperCPtr(metaClass, QLatin1String("self")) << ";\n"; - s << INDENT << " auto inst = dynamic_cast<" << wrapperName(metaClass) << " *>(plain_inst);\n"; + s << INDENT << " auto inst = dynamic_cast<" << context.wrapperName() << " *>(plain_inst);\n"; s << INDENT << " if (inst)\n"; s << INDENT << " inst->resetPyMethodCache();\n"; s << INDENT << "}\n"; diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp index 65bc8909e..8b3fe1653 100644 --- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp @@ -103,10 +103,10 @@ void HeaderGenerator::generateClass(QTextStream &s, const GeneratorContext &clas QString wrapperName; if (!classContext.forSmartPointer()) { - wrapperName = shouldGenerateCppWrapper(metaClass) - ? HeaderGenerator::wrapperName(metaClass) : metaClass->qualifiedCppName(); + wrapperName = classContext.useWrapper() + ? classContext.wrapperName() : metaClass->qualifiedCppName(); } else { - wrapperName = HeaderGenerator::wrapperName(classContext.preciseType()); + wrapperName = classContext.smartPointerWrapperName(); } QString outerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper(); QString innerHeaderGuard; @@ -121,11 +121,10 @@ void HeaderGenerator::generateClass(QTextStream &s, const GeneratorContext &clas //Includes s << metaClass->typeEntry()->include() << Qt::endl; - if (shouldGenerateCppWrapper(metaClass) && - usePySideExtensions() && metaClass->isQObject()) + if (classContext.useWrapper() && usePySideExtensions() && metaClass->isQObject()) s << "namespace PySide { class DynamicQMetaObject; }\n\n"; - while (shouldGenerateCppWrapper(metaClass)) { + while (classContext.useWrapper()) { if (!innerHeaderGuard.isEmpty()) { s << "# ifndef SBK_" << innerHeaderGuard << "_H\n"; s << "# define SBK_" << innerHeaderGuard << "_H\n\n"; @@ -208,9 +207,10 @@ void HeaderGenerator::generateClass(QTextStream &s, const GeneratorContext &clas break; classContext = contextForClass(metaClass); if (!classContext.forSmartPointer()) { - wrapperName = HeaderGenerator::wrapperName(metaClass); + wrapperName = classContext.useWrapper() + ? classContext.wrapperName() : metaClass->qualifiedCppName(); } else { - wrapperName = HeaderGenerator::wrapperName(classContext.preciseType()); + wrapperName = classContext.smartPointerWrapperName(); } innerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper(); } diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index d08ebcf14..5478acb2a 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -356,20 +356,6 @@ QString ShibokenGenerator::wrapperName(const AbstractMetaClass *metaClass) const return result + QLatin1String("Wrapper"); } -QString ShibokenGenerator::wrapperName(const AbstractMetaType *metaType) const -{ - return metaType->cppSignature(); -} - -QString ShibokenGenerator::wrapperName(const TypeEntry *type) const -{ - QString name = type->name(); - int pos = name.lastIndexOf(QLatin1String("::")); - if (pos >= 0) - name = name.remove(0, pos + 2); - return name + QLatin1String("Wrapper"); -} - QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClass) { QString fullClassName = metaClass->name(); @@ -1468,6 +1454,16 @@ void ShibokenGenerator::writeFunctionArguments(QTextStream &s, } } +GeneratorContext ShibokenGenerator::contextForClass(const AbstractMetaClass *c) const +{ + GeneratorContext result = Generator::contextForClass(c); + if (shouldGenerateCppWrapper(c)) { + result.m_type = GeneratorContext::WrappedClass; + result.m_wrappername = wrapperName(c); + } + return result; +} + QString ShibokenGenerator::functionReturnType(const AbstractMetaFunction *func, Options options) const { QString modifiedReturnType = QString(func->typeReplaced(0)); @@ -1671,8 +1667,8 @@ void ShibokenGenerator::processClassCodeSnip(QString &code, const GeneratorConte // for the class context in which the variable is used. code.replace(QLatin1String("%PYTHONTYPEOBJECT"), cpythonTypeName(metaClass) + QLatin1String("->type")); - const QString className = shouldGenerateCppWrapper(metaClass) - ? wrapperName(metaClass) : metaClass->qualifiedCppName(); + const QString className = context.useWrapper() + ? context.wrapperName() : metaClass->qualifiedCppName(); code.replace(QLatin1String("%TYPE"), className); code.replace(QLatin1String("%CPPTYPE"), metaClass->name()); @@ -2166,8 +2162,8 @@ bool ShibokenGenerator::injectedCodeCallsCppFunction(const GeneratorContext &con if (func->isConstructor()) { funcCall.prepend(QLatin1String("new ")); const auto owner = func->ownerClass(); - const QString className = shouldGenerateCppWrapper(owner) - ? wrapperName(owner) : owner->qualifiedCppName(); + const QString className = context.useWrapper() + ? context.wrapperName() : owner->qualifiedCppName(); wrappedCtorCall = QLatin1String("new ") + className + QLatin1Char('('); } CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode); diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h index 0a502cac3..d8259d245 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h @@ -107,6 +107,8 @@ protected: const AbstractMetaFunction *func, Options options = NoOption) const override; + GeneratorContext contextForClass(const AbstractMetaClass *c) const override; + /** * Returns a map with all functions grouped, the function name is used as key. * Example of return value: { "foo" -> ["foo(int)", "foo(int, long)], "bar" -> "bar(double)"} @@ -229,8 +231,6 @@ protected: static void lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList &enumList, const AbstractMetaClass *metaClass); QString wrapperName(const AbstractMetaClass *metaClass) const; - QString wrapperName(const AbstractMetaType *metaType) const; - QString wrapperName(const TypeEntry *type) const; QString fullPythonClassName(const AbstractMetaClass *metaClass); QString fullPythonFunctionName(const AbstractMetaFunction *func); |