From e0205cc7ebc4383f84b2fc05cabe9e6bf5f737e3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 14 May 2018 12:19:34 +0200 Subject: Improve error handling when writing type conversion functions Add an errorMessage parameter to ShibokenGenerator::buildAbstractMetaTypeFromString() and output the message in ShibokenGenerator::replaceConverterTypeSystemVariable(). Change-Id: I249778b3efe89c265590a7d4977cf2a4e76063f9 Reviewed-by: Alexandru Croitor --- .../generator/shiboken2/shibokengenerator.cpp | 67 +++++++++++++++------- .../generator/shiboken2/shibokengenerator.h | 3 +- 2 files changed, 48 insertions(+), 22 deletions(-) (limited to 'sources/shiboken2/generator') diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index b2734418c..69d7d5a53 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -1996,6 +1996,17 @@ static QString getConverterTypeSystemVariableArgument(const QString& code, int p return arg; } typedef QPair StringPair; + +static QString msgCannotFindType(const QString &type, const QString &variable, + const QString &why) +{ + QString result; + QTextStream(&result) << "Could not find type '" + << type << "' for use in '" << variable << "' conversion: " << why + << "\nMake sure to use the full C++ name, e.g. 'Namespace::Class'."; + return result; +} + void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable, QString& code) { QVector replacements; @@ -2005,12 +2016,12 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa const QStringList list = match.capturedTexts(); QString conversionString = list.constFirst(); QString conversionTypeName = list.constLast(); - const AbstractMetaType* conversionType = buildAbstractMetaTypeFromString(conversionTypeName); + QString message; + const AbstractMetaType *conversionType = buildAbstractMetaTypeFromString(conversionTypeName, &message); if (!conversionType) { - qFatal(qPrintable(QString::fromLatin1("Could not find type '%1' for use in '%2' conversion. " - "Make sure to use the full C++ name, e.g. 'Namespace::Class'.") - .arg(conversionTypeName).arg(m_typeSystemConvName[converterVariable])), NULL); - + qFatal("%s", qPrintable(msgCannotFindType(conversionTypeName, + m_typeSystemConvName[converterVariable], + message))); } QString conversion; QTextStream c(&conversion); @@ -2312,7 +2323,8 @@ bool ShibokenGenerator::isCopyable(const AbstractMetaClass *metaClass) return false; } -AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature) +AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature, + QString *errorMessage) { typeSignature = typeSignature.trimmed(); if (typeSignature.startsWith(QLatin1String("::"))) @@ -2348,9 +2360,10 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ typeString.remove(0, 2); QString adjustedTypeName = typeString; - QStringList instantiatedTypes; + AbstractMetaTypeList instantiations; int lpos = typeString.indexOf(QLatin1Char('<')); if (lpos > -1) { + QStringList instantiatedTypes; int rpos = typeString.lastIndexOf(QLatin1Char('>')); if ((lpos != -1) && (rpos != -1)) { QString type = typeString.mid(lpos + 1, rpos - lpos - 1); @@ -2369,25 +2382,37 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ instantiatedTypes << type.mid(start).trimmed(); adjustedTypeName.truncate(lpos); } + for (const QString &instantiatedType : qAsConst(instantiatedTypes)) { + AbstractMetaType *tmplArgType = buildAbstractMetaTypeFromString(instantiatedType); + if (!tmplArgType) { + if (errorMessage) { + QTextStream(errorMessage) << "Cannot find template type \"" + << instantiatedType << "\" for \"" << typeSignature << "\"."; + } + return nullptr; + } + instantiations.append(tmplArgType); + } } TypeEntry* typeEntry = TypeDatabase::instance()->findType(adjustedTypeName); - - AbstractMetaType* metaType = 0; - if (typeEntry) { - metaType = new AbstractMetaType(); - metaType->setTypeEntry(typeEntry); - metaType->setIndirections(indirections); - metaType->setReferenceType(refType); - metaType->setConstant(isConst); - metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); - for (const QString &instantiation : qAsConst(instantiatedTypes)) { - AbstractMetaType* tmplArgType = buildAbstractMetaTypeFromString(instantiation); - metaType->addInstantiation(tmplArgType); + if (!typeEntry) { + if (errorMessage) { + QTextStream(errorMessage) << "Cannot find type \"" << adjustedTypeName + << "\" for \"" << typeSignature << "\"."; } - metaType->decideUsagePattern(); - m_metaTypeFromStringCache.insert(typeSignature, metaType); + return nullptr; } + + AbstractMetaType *metaType = new AbstractMetaType(); + metaType->setTypeEntry(typeEntry); + metaType->setIndirections(indirections); + metaType->setReferenceType(refType); + metaType->setConstant(isConst); + metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); + metaType->setInstantiations(instantiations); + metaType->decideUsagePattern(); + m_metaTypeFromStringCache.insert(typeSignature, metaType); return metaType; } diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h index d44f4aa66..3271d741d 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h @@ -467,7 +467,8 @@ public: * \param typeSignature The string describing the type to be built. * \return A new AbstractMetaType object that must be deleted by the caller, or a NULL pointer in case of failure. */ - AbstractMetaType* buildAbstractMetaTypeFromString(QString typeSignature); + AbstractMetaType *buildAbstractMetaTypeFromString(QString typeSignature, + QString *errorMessage = nullptr); /// Creates an AbstractMetaType object from a TypeEntry. AbstractMetaType* buildAbstractMetaTypeFromTypeEntry(const TypeEntry* typeEntry); -- cgit v1.2.3