From 84f5d3fca336730508eeb0144d4ee42feff34f0c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Sat, 21 Mar 2020 21:17:57 +0100 Subject: shiboken: Improve error messages about invalid types of added functions Change translateType() to pass up the error instead of aborting so that the error is printed in traverseFunction() along with the name. The abort in case of failure will then occur in fillAddedFunctions(). Task-number: PYSIDE-946 Task-number: PYSIDE-1241 Change-Id: Iee9ca478b28c8f82d9c4b6c5165f3028bf1e0d08 Reviewed-by: Christian Tismer --- .../shiboken2/ApiExtractor/abstractmetabuilder.cpp | 65 ++++++++++++++-------- .../shiboken2/ApiExtractor/abstractmetabuilder_p.h | 3 +- sources/shiboken2/ApiExtractor/messages.cpp | 22 ++++++++ sources/shiboken2/ApiExtractor/messages.h | 7 +++ 4 files changed, 72 insertions(+), 25 deletions(-) diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 4566ed3bc..4b62ac4a5 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1613,9 +1613,22 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc, AbstractMetaClass *metaClass) { - auto *metaFunction = new AbstractMetaFunction(addedFunc); - metaFunction->setType(translateType(addedFunc->returnType())); + QString errorMessage; + AbstractMetaType *returnType = nullptr; + if (addedFunc->returnType().name != QLatin1String("void")) { + returnType = translateType(addedFunc->returnType(), &errorMessage); + if (!returnType) { + qCWarning(lcShiboken, "%s", + qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(), + addedFunc->returnType().name, + errorMessage))); + return nullptr; + } + } + + auto metaFunction = new AbstractMetaFunction(addedFunc); + metaFunction->setType(returnType); const auto &args = addedFunc->arguments(); AbstractMetaArgumentList metaArguments; @@ -1623,11 +1636,12 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu for (int i = 0; i < args.count(); ++i) { const AddedFunction::TypeInfo& typeInfo = args.at(i).typeInfo; auto *metaArg = new AbstractMetaArgument; - AbstractMetaType *type = translateType(typeInfo); + AbstractMetaType *type = translateType(typeInfo, &errorMessage); if (Q_UNLIKELY(!type)) { - qCWarning(lcShiboken, - "Unable to translate type \"%s\" of argument %d of added function \"%s\".", - qPrintable(typeInfo.name), i + 1, qPrintable(addedFunc->name())); + qCWarning(lcShiboken, "%s", + qPrintable(msgAddedFunctionInvalidArgType(addedFunc->name(), + typeInfo.name, i + 1, + errorMessage))); delete metaFunction; return nullptr; } @@ -2041,7 +2055,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return metaFunction; } -AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo) +AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo, + QString *errorMessage) { Q_ASSERT(!typeInfo.name.isEmpty()); TypeDatabase* typeDb = TypeDatabase::instance(); @@ -2060,12 +2075,11 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: if (!type && typeInfo.name.contains(QLatin1Char('<'))) { const QStringList& parsedType = parseTemplateType(typeInfo.name); if (parsedType.isEmpty()) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name); - } else { - templateArgs = parsedType.mid(1); - isTemplate = (type = typeDb->findContainerType(parsedType[0])); + *errorMessage = QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name); + return nullptr; } + templateArgs = parsedType.mid(1); + isTemplate = (type = typeDb->findContainerType(parsedType[0])); } if (!type) { @@ -2076,20 +2090,18 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: if (it.key().endsWith(colonColon() + typeName)) candidates.append(it.key()); } - - QString msg = QStringLiteral("Type '%1' wasn't found in the type database.\n").arg(typeName); + QTextStream str(errorMessage); + str << "Type '" << typeName << "' wasn't found in the type database.\n"; if (candidates.isEmpty()) { - qFatal("%sDeclare it in the type system using the proper <*-type> tag.", - qPrintable(msg)); - } - - msg += QLatin1String("Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n"); - candidates.sort(); - for (const QString& candidate : qAsConst(candidates)) { - msg += QLatin1String(" ") + candidate + QLatin1Char('\n'); + str << "Declare it in the type system using the proper <*-type> tag."; + } else { + str << "Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n"; + candidates.sort(); + for (const QString& candidate : qAsConst(candidates)) + str << " " << candidate << '\n'; } - qFatal("%s", qPrintable(msg)); + return nullptr; } auto *metaType = new AbstractMetaType; @@ -2100,7 +2112,12 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: metaType->setConstant(typeInfo.isConstant); if (isTemplate) { for (const QString& templateArg : qAsConst(templateArgs)) { - AbstractMetaType *metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg)); + AbstractMetaType *metaArgType = nullptr; + if (templateArg != QLatin1String("void")) { + metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); + if (!metaArgType) + return nullptr; + } metaType->addInstantiation(metaArgType); } metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index b381a62cd..be73697f0 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -136,7 +136,8 @@ public: QString fixDefaultValue(const ArgumentModelItem &item, AbstractMetaType *type, AbstractMetaFunction *fnc, AbstractMetaClass *, int argumentIndex); - AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo); + AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo, + QString *errorMessage); AbstractMetaType *translateType(const TypeInfo &type, AbstractMetaClass *currentClass, TranslateTypeFlags flags = {}, diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp index 546e9c4ed..0eb3c607f 100644 --- a/sources/shiboken2/ApiExtractor/messages.cpp +++ b/sources/shiboken2/ApiExtractor/messages.cpp @@ -107,6 +107,28 @@ static void msgFormatEnumType(Stream &str, str << " (class: " << className << ')'; } +QString msgAddedFunctionInvalidArgType(const QString &addedFuncName, + const QString &typeName, + int pos, const QString &why) +{ + QString result; + QTextStream str(&result); + str << "Unable to translate type \"" << typeName << "\" of argument " + << pos << " of added function \"" << addedFuncName << "\": " << why; + return result; +} + +QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName, + const QString &typeName, const QString &why) +{ + QString result; + QTextStream str(&result); + str << "Unable to translate return type \"" << typeName + << "\" of added function \"" << addedFuncName << "\": " + << why; + return result; +} + QString msgNoEnumTypeEntry(const EnumModelItem &enumItem, const QString &className) { diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h index 2b7b75ba0..ad0553fbc 100644 --- a/sources/shiboken2/ApiExtractor/messages.h +++ b/sources/shiboken2/ApiExtractor/messages.h @@ -45,6 +45,13 @@ QT_FORWARD_DECLARE_CLASS(QDir) QT_FORWARD_DECLARE_CLASS(QFile) QT_FORWARD_DECLARE_CLASS(QXmlStreamReader) +QString msgAddedFunctionInvalidArgType(const QString &addedFuncName, + const QString &typeName, + int pos, const QString &why); + +QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName, + const QString &typeName, const QString &why); + QString msgNoFunctionForModification(const QString &signature, const QString &originalSignature, const QString &className, -- cgit v1.2.3