diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-05-12 11:15:30 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-05-15 12:49:18 +0200 |
commit | 8c733ba3d56b8934e6c7c46a293b93f387e334ca (patch) | |
tree | bb1cfe632a09030b2ee9def46b47a8c8f3281bbc | |
parent | d2c1f891cce0b7339ac86009e1fbb042d40dda0f (diff) |
shiboken: Move wrapperName and type into GeneratorContext
Introduce a Type enumeration to GeneratorContext and add
the wrapper name as a string. Overwrite creation function
in ShibokenGenerator to add this.
Remove unused wrapperName overloads.
Use the wrapper name and type from the GeneratorContext where
applicable instead of repeatedly running the check in
shouldGenerateCppWrapper().
Change-Id: I52cace3ad165c2cd6c6ce718cec822abfb8ad8ce
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
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); |