From 2eae75d55a693d04f8a6d2cd09394f7bb9dcb400 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 14 Sep 2021 11:14:05 +0200 Subject: shiboken6: Move AbstractMetaType factory functions into AbstractMetaType They do not really belong to the generator. Task-number: PYSIDE-1660 Change-Id: I550643bb00cbb1af937f45de5a4820c883259802 Reviewed-by: Christian Tismer --- .../shiboken6/ApiExtractor/abstractmetatype.cpp | 53 ++++++++++++++++++ sources/shiboken6/ApiExtractor/abstractmetatype.h | 13 +++++ .../shiboken6/generator/shiboken/cppgenerator.cpp | 24 ++++----- .../generator/shiboken/shibokengenerator.cpp | 62 ++-------------------- .../generator/shiboken/shibokengenerator.h | 18 ------- 5 files changed, 83 insertions(+), 87 deletions(-) diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp index 3401a61c9..f099bba08 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp @@ -27,6 +27,9 @@ ****************************************************************************/ #include "abstractmetatype.h" +#include "abstractmetabuilder.h" +#include "abstractmetalang.h" +#include "messages.h" #include "typedatabase.h" #include "typesystem.h" #include "parser/codemodel.h" @@ -35,6 +38,7 @@ # include #endif +#include #include #include #include @@ -797,6 +801,55 @@ bool AbstractMetaType::valueTypeWithCopyConstructorOnlyPassed() const && isValueTypeWithCopyConstructorOnly(); } +using AbstractMetaTypeCache = QHash; + +Q_GLOBAL_STATIC(AbstractMetaTypeCache, metaTypeFromStringCache) + +std::optional +AbstractMetaType::fromString(QString typeSignature, QString *errorMessage) +{ + typeSignature = typeSignature.trimmed(); + if (typeSignature.startsWith(QLatin1String("::"))) + typeSignature.remove(0, 2); + + auto &cache = *metaTypeFromStringCache(); + auto it = cache.find(typeSignature); + if (it == cache.end()) { + auto metaType = + AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage); + if (Q_UNLIKELY(!metaType.has_value())) { + if (errorMessage) + errorMessage->prepend(msgCannotBuildMetaType(typeSignature)); + return {}; + } + it = cache.insert(typeSignature, metaType.value()); + } + return it.value(); +} + +AbstractMetaType AbstractMetaType::fromTypeEntry(const TypeEntry *typeEntry) +{ + QString typeName = typeEntry->qualifiedCppName(); + if (typeName.startsWith(QLatin1String("::"))) + typeName.remove(0, 2); + auto &cache = *metaTypeFromStringCache(); + auto it = cache.find(typeName); + if (it != cache.end()) + return it.value(); + AbstractMetaType metaType(typeEntry); + metaType.clearIndirections(); + metaType.setReferenceType(NoReference); + metaType.setConstant(false); + metaType.decideUsagePattern(); + cache.insert(typeName, metaType); + return metaType; +} + +AbstractMetaType AbstractMetaType::fromAbstractMetaClass(const AbstractMetaClass *metaClass) +{ + return fromTypeEntry(metaClass->typeEntry()); +} + #ifndef QT_NO_DEBUG_STREAM void AbstractMetaType::formatDebug(QDebug &debug) const { diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.h b/sources/shiboken6/ApiExtractor/abstractmetatype.h index 6aa682e04..79523efef 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetatype.h +++ b/sources/shiboken6/ApiExtractor/abstractmetatype.h @@ -36,6 +36,8 @@ #include #include +#include + QT_FORWARD_DECLARE_CLASS(QDebug) class AbstractMetaTypeData; @@ -194,6 +196,17 @@ public: static AbstractMetaType createVoid(); + /// Builds an AbstractMetaType object from a QString. + /// Returns nullopt if no type could be built from the string. + /// \param typeSignature The string describing the type to be built. + /// \return A new AbstractMetaType object or nullopt in case of failure. + static std::optional + fromString(QString typeSignature, QString *errorMessage = nullptr); + /// Creates an AbstractMetaType object from a TypeEntry. + static AbstractMetaType fromTypeEntry(const TypeEntry *typeEntry); + /// Creates an AbstractMetaType object from an AbstractMetaClass. + static AbstractMetaType fromAbstractMetaClass(const AbstractMetaClass *metaClass); + static void dereference(QString *type); // "foo" -> "(*foo)" static bool stripDereference(QString *type); // "(*foo)" -> "foo" diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 4ad9c35b7..09128279a 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -576,7 +576,7 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon // is done, so this will be fixed in bulk with all the other cases, because the // ownership of the pointers is not clear at the moment. auto pointerToInnerType = - buildAbstractMetaTypeFromString(pointerToInnerTypeName); + AbstractMetaType::fromString(pointerToInnerTypeName); Q_ASSERT(pointerToInnerType.has_value()); auto mutableRfunc = overloads.constFirst(); qSharedPointerConstCast(mutableRfunc)->setType(pointerToInnerType.value()); @@ -1555,7 +1555,7 @@ return result;)"; if (!implicitConvs.isEmpty()) s << "// Implicit conversions.\n"; - AbstractMetaType targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); + AbstractMetaType targetType = AbstractMetaType::fromAbstractMetaClass(metaClass); for (const auto &conv : qAsConst(implicitConvs)) { if (conv->isModifiedRemoved()) continue; @@ -1615,7 +1615,7 @@ return result;)"; } } const AbstractMetaType sourceType = conv->isConversionOperator() - ? buildAbstractMetaTypeFromAbstractMetaClass(conv->ownerClass()) + ? AbstractMetaType::fromAbstractMetaClass(conv->ownerClass()) : conv->arguments().constFirst().type(); writePythonToCppConversionFunctions(s, sourceType, targetType, typeCheck, toCppConv, toCppPreConv); } @@ -1742,13 +1742,13 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass if (!implicitConvs.isEmpty()) s << "// Add implicit conversions to type converter.\n"; - AbstractMetaType targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); + AbstractMetaType targetType = AbstractMetaType::fromAbstractMetaClass(metaClass); for (const auto &conv : qAsConst(implicitConvs)) { if (conv->isModifiedRemoved()) continue; AbstractMetaType sourceType; if (conv->isConversionOperator()) { - sourceType = buildAbstractMetaTypeFromAbstractMetaClass(conv->ownerClass()); + sourceType = AbstractMetaType::fromAbstractMetaClass(conv->ownerClass()); } else { // Constructor that does implicit conversion. if (!conv->typeReplaced(1).isEmpty() || conv->isModifiedToArray(1)) @@ -2541,7 +2541,7 @@ std::optional return argType.viewOn() ? *argType.viewOn() : argType; } - auto argType = buildAbstractMetaTypeFromString(typeReplaced); + auto argType = AbstractMetaType::fromString(typeReplaced); if (!argType.has_value() && !knownPythonTypes().contains(typeReplaced)) { qCWarning(lcShiboken, "%s", qPrintable(msgUnknownTypeInArgumentTypeReplacement(typeReplaced, func.data()))); @@ -5359,7 +5359,7 @@ void CppGenerator::writeFlagsToLong(TextStream &s, const AbstractMetaEnum &cppEn s << "static PyObject *" << cpythonEnumName(cppEnum) << "_long(PyObject *self)\n" << "{\n" << indent << "int val;\n"; - AbstractMetaType flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); + AbstractMetaType flagsType = AbstractMetaType::fromTypeEntry(flagsEntry); s << cpythonToCppConversionFunction(flagsType) << "self, &val);\n" << "return Shiboken::Conversions::copyToPython(Shiboken::Conversions::PrimitiveTypeConverter(), &val);\n" << outdent << "}\n"; @@ -5372,7 +5372,7 @@ void CppGenerator::writeFlagsNonZero(TextStream &s, const AbstractMetaEnum &cppE return; s << "static int " << cpythonEnumName(cppEnum) << "__nonzero(PyObject *self)\n"; s << "{\n" << indent << "int val;\n"; - AbstractMetaType flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); + AbstractMetaType flagsType = AbstractMetaType::fromTypeEntry(flagsEntry); s << cpythonToCppConversionFunction(flagsType) << "self, &val);\n" << "return val != 0;\n" << outdent << "}\n"; @@ -5428,7 +5428,7 @@ void CppGenerator::writeFlagsBinaryOperator(TextStream &s, const AbstractMetaEnu s << "PyObject *" << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject *self, PyObject *" << PYTHON_ARG << ")\n{\n" << indent; - AbstractMetaType flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); + AbstractMetaType flagsType = AbstractMetaType::fromTypeEntry(flagsEntry); s << "::" << flagsEntry->originalName() << " cppResult, " << CPP_SELF_VAR << ", cppArg;\n" << CPP_SELF_VAR << " = static_cast<::" << flagsEntry->originalName() @@ -5457,7 +5457,7 @@ void CppGenerator::writeFlagsUnaryOperator(TextStream &s, const AbstractMetaEnum s << "PyObject *" << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject *self, PyObject *" << PYTHON_ARG << ")\n{\n" << indent; - AbstractMetaType flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); + AbstractMetaType flagsType = AbstractMetaType::fromTypeEntry(flagsEntry); s << "::" << flagsEntry->originalName() << " " << CPP_SELF_VAR << ";\n" << cpythonToCppConversionFunction(flagsType) << "self, &" << CPP_SELF_VAR << ");\n"; @@ -6276,8 +6276,8 @@ bool CppGenerator::finishGeneration() s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << '\n'; for (const AbstractMetaClass *sourceClass : it.value()) { - AbstractMetaType sourceType = buildAbstractMetaTypeFromAbstractMetaClass(sourceClass); - AbstractMetaType targetType = buildAbstractMetaTypeFromTypeEntry(externalType); + AbstractMetaType sourceType = AbstractMetaType::fromAbstractMetaClass(sourceClass); + AbstractMetaType targetType = AbstractMetaType::fromTypeEntry(externalType); writePythonToCppConversionFunctions(s, sourceType, targetType); } } diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index 60d7a5a2c..822c4d2fb 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -129,10 +129,6 @@ using GeneratorClassInfoCache = QHash; - -Q_GLOBAL_STATIC(AbstractMetaTypeCache, metaTypeFromStringCache) - static const char CHECKTYPE_REGEX[] = R"(%CHECKTYPE\[([^\[]*)\]\()"; static const char ISCONVERTIBLE_REGEX[] = R"(%ISCONVERTIBLE\[([^\[]*)\]\()"; static const char CONVERTTOPYTHON_REGEX[] = R"(%CONVERTTOPYTHON\[([^\[]*)\]\()"; @@ -1114,7 +1110,7 @@ ShibokenGenerator::CPythonCheckFunctionResult return {QLatin1String("Shiboken::String::checkPath"), {}}; CPythonCheckFunctionResult result; - result.type = buildAbstractMetaTypeFromString(type); + result.type = AbstractMetaType::fromString(type); if (!result.type.has_value()) { result.checkFunction = type + QLatin1String("_Check"); @@ -1565,7 +1561,7 @@ ShibokenGenerator::ArgumentVarReplacementList AbstractMetaType type = arg.type(); QString typeReplaced = func->typeReplaced(arg.argumentIndex() + 1); if (!typeReplaced.isEmpty()) { - auto builtType = buildAbstractMetaTypeFromString(typeReplaced); + auto builtType = AbstractMetaType::fromString(typeReplaced); if (builtType.has_value()) type = builtType.value(); } @@ -1804,7 +1800,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s, AbstractMetaType type = arg.type(); QString typeReplaced = func->typeReplaced(arg.argumentIndex() + 1); if (!typeReplaced.isEmpty()) { - auto builtType = buildAbstractMetaTypeFromString(typeReplaced); + auto builtType = AbstractMetaType::fromString(typeReplaced); if (builtType.has_value()) type = builtType.value(); } @@ -1944,7 +1940,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa QString conversionString = list.constFirst(); const QString &conversionTypeName = list.constLast(); QString message; - const auto conversionTypeO = buildAbstractMetaTypeFromString(conversionTypeName, &message); + const auto conversionTypeO = AbstractMetaType::fromString(conversionTypeName, &message); if (!conversionTypeO.has_value()) { throw Exception(msgCannotFindType(conversionTypeName, typeSystemConvName().value(converterVariable), @@ -2155,54 +2151,6 @@ QString ShibokenGenerator::getPrivateModuleHeaderFileName(const QString &moduleN return getModuleHeaderFileBaseName(moduleName) + QStringLiteral("_p.h"); } -std::optional - ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature, - QString *errorMessage) -{ - typeSignature = typeSignature.trimmed(); - if (typeSignature.startsWith(QLatin1String("::"))) - typeSignature.remove(0, 2); - - auto &cache = *metaTypeFromStringCache(); - auto it = cache.find(typeSignature); - if (it == cache.end()) { - auto metaType = - AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage); - if (Q_UNLIKELY(!metaType.has_value())) { - if (errorMessage) - errorMessage->prepend(msgCannotBuildMetaType(typeSignature)); - return {}; - } - it = cache.insert(typeSignature, metaType.value()); - } - return it.value(); -} - -AbstractMetaType - ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(const TypeEntry *typeEntry) -{ - QString typeName = typeEntry->qualifiedCppName(); - if (typeName.startsWith(QLatin1String("::"))) - typeName.remove(0, 2); - auto &cache = *metaTypeFromStringCache(); - auto it = cache.find(typeName); - if (it != cache.end()) - return it.value(); - AbstractMetaType metaType(typeEntry); - metaType.clearIndirections(); - metaType.setReferenceType(NoReference); - metaType.setConstant(false); - metaType.decideUsagePattern(); - cache.insert(typeName, metaType); - return metaType; -} - -AbstractMetaType - ShibokenGenerator::buildAbstractMetaTypeFromAbstractMetaClass(const AbstractMetaClass *metaClass) -{ - return ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(metaClass->typeEntry()); -} - /* static void dumpFunction(AbstractMetaFunctionList lst) { @@ -2511,7 +2459,7 @@ void ShibokenGenerator::collectContainerTypesFromConverterMacros(const QString & start += offset; if (code.at(start) != QLatin1Char('%')) { QString typeString = code.mid(start, end - start); - auto type = buildAbstractMetaTypeFromString(typeString, &errorMessage); + auto type = AbstractMetaType::fromString(typeString, &errorMessage); if (type.has_value()) { addInstantiatedContainersAndSmartPointers(type.value(), type->originalTypeDescription()); } else { diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h index 414410141..0ad4a5f79 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.h +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h @@ -332,24 +332,6 @@ protected: /// Returns true if the user don't want verbose error messages on the generated bindings. bool verboseErrorMessagesDisabled() const; - /** - * Builds an AbstractMetaType object from a QString. - * Returns nullptr if no type could be built from the string. - * \param typeSignature The string describing the type to be built. - * \return A new AbstractMetaType object that must be deleted by the caller, - * or a nullptr pointer in case of failure. - */ - static std::optional - buildAbstractMetaTypeFromString(QString typeSignature, - QString *errorMessage = nullptr); - - /// Creates an AbstractMetaType object from a TypeEntry. - static AbstractMetaType - buildAbstractMetaTypeFromTypeEntry(const TypeEntry *typeEntry); - /// Creates an AbstractMetaType object from an AbstractMetaClass. - static AbstractMetaType - buildAbstractMetaTypeFromAbstractMetaClass(const AbstractMetaClass *metaClass); - void collectContainerTypesFromConverterMacros(const QString &code, bool toPythonMacro); static void writeFunctionCall(TextStream &s, -- cgit v1.2.3