aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-01-31 13:53:24 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-01-31 16:37:49 +0000
commita988c31b4824e423a7d05fd0580c7427797ac402 (patch)
treec7995512f9d311cb5ffe08b6a7037c3e6c5dd131
parentc070e503b2db246b014cdb54a8761e2cccea958e (diff)
shiboken6: Improve code snippet error handling
Type conversion errors in code snippets can be hard to diagnose, particularly when they occur in an invalid context due to misspelt snippet markers. Add some functions wrapping the in try/catch, adding some context information to the error messages. Change-Id: I7e35f298497b7fd0b582f43d6941a683e18377b3 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> (cherry picked from commit 866f6620aaa852c6fafb4b96625017ad44ce0dcb) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--sources/shiboken6/ApiExtractor/messages.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/messages.h1
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp40
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h4
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.cpp21
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.h4
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp13
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h1
8 files changed, 70 insertions, 20 deletions
diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp
index 860ecf57f..766b05beb 100644
--- a/sources/shiboken6/ApiExtractor/messages.cpp
+++ b/sources/shiboken6/ApiExtractor/messages.cpp
@@ -862,6 +862,12 @@ QString msgCannotFindSnippet(const QString &file, const QString &snippetLabel)
return result;
}
+QString msgSnippetError(const QString &context, const char *what)
+{
+ return "Error processing code snippet of "_L1 + context
+ + ": "_L1 + QString::fromUtf8(what);
+}
+
QString msgUnableToResolveTypedef(const QString &sourceType, const QString &sourceName)
{
QString result;
diff --git a/sources/shiboken6/ApiExtractor/messages.h b/sources/shiboken6/ApiExtractor/messages.h
index 1d28f384c..2899cbdfa 100644
--- a/sources/shiboken6/ApiExtractor/messages.h
+++ b/sources/shiboken6/ApiExtractor/messages.h
@@ -209,6 +209,7 @@ QString msgIncorrectlyNestedName(const QString &name);
QString msgCannotFindView(const QString &viewedName, const QString &name);
QString msgCannotFindSnippet(const QString &file, const QString &snippetLabel);
+QString msgSnippetError(const QString &context, const char *what);
QString msgUnableToResolveTypedef(const QString &sourceType, const QString &sourceName);
QString msgCyclicDependency(const QString &funcName, const QString &graphName,
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 6fc21e140..1f3c68ddd 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -455,6 +455,19 @@ void CppGenerator::writePyMethodDefs(TextStream &s, const QString &className,
<< methodsDefinitions << METHOD_DEF_SENTINEL << outdent << "};\n\n";
}
+void CppGenerator::writeModuleCodeSnips(TextStream &s, const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language) const
+{
+ if (!codeSnips.isEmpty()) {
+ try {
+ writeCodeSnips(s, codeSnips, position, language);
+ } catch (const std::exception &e) {
+ throw Exception(msgSnippetError("module source of "_L1 + moduleName(), e.what()));
+ }
+ }
+}
+
bool CppGenerator::hasHashFunction(const AbstractMetaClassCPtr &c)
{
return !c->typeEntry()->hashFunction().isEmpty()
@@ -3097,9 +3110,10 @@ void CppGenerator::writeCppToPythonFunction(TextStream &s, const QString &code,
{
QString prettyCode = code;
- processCodeSnip(prettyCode);
+ const QString funcName = cppToPythonFunctionName(sourceTypeName, targetTypeName);
+ processCodeSnip(prettyCode, funcName);
- s << "static PyObject *" << cppToPythonFunctionName(sourceTypeName, targetTypeName)
+ s << "static PyObject *" << funcName
<< "(const void *cppIn)\n{\n" << indent << prettyCode
<< ensureEndl << outdent << "}\n";
}
@@ -3170,7 +3184,7 @@ void CppGenerator::writeCppToPythonFunction(TextStream &s, const AbstractMetaTyp
code.replace(u"%INTYPE_"_s + QString::number(i), typeName);
}
replaceCppToPythonVariables(code, getFullTypeNameWithoutModifiers(containerType), true);
- processCodeSnip(code);
+ processCodeSnip(code, containerType.typeEntry()->qualifiedCppName());
writeCppToPythonFunction(s, code, fixedCppTypeName(containerType),
containerNativeToTargetTypeName(cte));
}
@@ -3179,8 +3193,9 @@ void CppGenerator::writePythonToCppFunction(TextStream &s, const QString &code,
const QString &targetTypeName) const
{
QString prettyCode = code;
- processCodeSnip(prettyCode);
- s << "static void " << pythonToCppFunctionName(sourceTypeName, targetTypeName)
+ const QString funcName = pythonToCppFunctionName(sourceTypeName, targetTypeName);
+ processCodeSnip(prettyCode, funcName);
+ s << "static void " << funcName
<< "(PyObject *pyIn, void *cppOut)\n{\n" << indent << prettyCode
<< ensureEndl << outdent << "}\n";
}
@@ -3283,7 +3298,7 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
+ cpythonTypeNameExt(toNative.sourceType()) + u')';
}
typeCheck.replace(u"%in"_s, u"pyIn"_s);
- processCodeSnip(typeCheck);
+ processCodeSnip(typeCheck, targetType->qualifiedCppName());
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, typeCheck);
}
@@ -6005,8 +6020,7 @@ bool CppGenerator::finishGeneration()
const CodeSnipList snips = moduleEntry->codeSnips();
// module inject-code native/beginning
- if (!snips.isEmpty())
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode);
+ writeModuleCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode);
// cleanup staticMetaObject attribute
if (usePySideExtensions()) {
@@ -6136,8 +6150,8 @@ bool CppGenerator::finishGeneration()
<< indent << "return " << globalModuleVar << ";\n" << outdent;
// module inject-code target/beginning
- if (!snips.isEmpty())
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode);
+ writeModuleCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning,
+ TypeSystem::TargetLangCode);
for (const QString &requiredModule : requiredModules) {
s << "{\n" << indent
@@ -6256,12 +6270,10 @@ bool CppGenerator::finishGeneration()
<< outdent << "}\n";
// module inject-code target/end
- if (!snips.isEmpty())
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode);
+ writeModuleCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode);
// module inject-code native/end
- if (!snips.isEmpty())
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode);
+ writeModuleCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode);
if (usePySideExtensions()) {
for (const AbstractMetaEnum &metaEnum : std::as_const(globalEnums))
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index 54b37fadb..95ed0bf7d 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -521,6 +521,10 @@ private:
static void writePyMethodDefs(TextStream &s, const QString &className,
const QString &methodsDefinitions);
+ void writeModuleCodeSnips(TextStream &s, const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language) const;
+
static bool hasBoolCast(const AbstractMetaClassCPtr &metaClass)
{ return boolCast(metaClass).has_value(); }
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.cpp b/sources/shiboken6/generator/shiboken/headergenerator.cpp
index 6b9ec5b46..9f6de3560 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp
@@ -13,6 +13,7 @@
#include <abstractmetalang_helpers.h>
#include <codesnip.h>
#include <clangparser/compilersupport.h>
+#include <exception.h>
#include <typedatabase.h>
#include <reporthandler.h>
#include <textstream.h>
@@ -20,6 +21,7 @@
#include "containertypeentry.h"
#include "enumtypeentry.h"
#include "flagstypeentry.h"
+#include <messages.h>
#include "namespacetypeentry.h"
#include "primitivetypeentry.h"
#include "typedefentry.h"
@@ -593,10 +595,8 @@ bool HeaderGenerator::finishGeneration()
StringStream macrosStream(TextStream::Language::Cpp);
const auto snips = TypeDatabase::instance()->defaultTypeSystemType()->codeSnips();
- if (!snips.isEmpty()) {
- writeCodeSnips(macrosStream, snips, TypeSystem::CodeSnipPositionDeclaration,
- TypeSystem::TargetLangCode);
- }
+ writeModuleCodeSnips(macrosStream, snips, TypeSystem::CodeSnipPositionDeclaration,
+ TypeSystem::TargetLangCode);
macrosStream << "// Type indices\nenum : int {\n";
auto classList = api().classes();
@@ -891,3 +891,16 @@ void HeaderGenerator::writeSbkTypeFunction(TextStream &s, const AbstractMetaType
s << "template<> inline PyTypeObject *SbkType< ::" << metaType.cppSignature() << " >() "
<< "{ return " << cpythonTypeNameExt(metaType) << "; }\n";
}
+
+void HeaderGenerator::writeModuleCodeSnips(TextStream &s, const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language) const
+{
+ if (!codeSnips.isEmpty()) {
+ try {
+ writeCodeSnips(s, codeSnips, position, language);
+ } catch (const std::exception &e) {
+ throw Exception(msgSnippetError("module header of "_L1 + moduleName(), e.what()));
+ }
+ }
+}
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.h b/sources/shiboken6/generator/shiboken/headergenerator.h
index 5b5f5a4a1..e986ff405 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.h
+++ b/sources/shiboken6/generator/shiboken/headergenerator.h
@@ -6,6 +6,7 @@
#include "shibokengenerator.h"
#include "include.h"
+#include "modifications_typedefs.h"
#include <QtCore/QSet>
@@ -56,6 +57,9 @@ private:
void writeWrapperClass(TextStream &s, const QString &wrapperName, const GeneratorContext &classContext) const;
void writeInheritedWrapperClassDeclaration(TextStream &s,
const GeneratorContext &classContext) const;
+ void writeModuleCodeSnips(TextStream &s, const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language) const;
AbstractMetaClassCList m_alternateTemplateIndexes;
};
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index a26a9ee34..3830540cf 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -1326,7 +1326,7 @@ void ShibokenGenerator::processClassCodeSnip(QString &code, const GeneratorConte
code.replace(u"%TYPE"_s, className);
code.replace(u"%CPPTYPE"_s, metaClass->name());
- processCodeSnip(code);
+ processCodeSnip(code, context.effectiveClassName());
}
void ShibokenGenerator::processCodeSnip(QString &code) const
@@ -1344,6 +1344,15 @@ void ShibokenGenerator::processCodeSnip(QString &code) const
replaceTypeCheckTypeSystemVariable(code);
}
+void ShibokenGenerator::processCodeSnip(QString &code, const QString &context) const
+{
+ try {
+ processCodeSnip(code);
+ } catch (const std::exception &e) {
+ throw Exception(msgSnippetError(context, e.what()));
+ }
+}
+
ShibokenGenerator::ArgumentVarReplacementList
ShibokenGenerator::getArgumentReplacement(const AbstractMetaFunctionCPtr &func,
bool usePyArgs, TypeSystem::Language language,
@@ -1648,7 +1657,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
replaceTemplateVariables(code, func);
- processCodeSnip(code);
+ processCodeSnip(code, func->classQualifiedSignature());
s << "// Begin code injection\n" << code << "// End of code injection\n\n";
}
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index 457e13d83..25eb78541 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -145,6 +145,7 @@ protected:
/// Replaces variables for the user's custom code at global or class level.
void processCodeSnip(QString &code) const;
+ void processCodeSnip(QString &code, const QString &context) const;
void processClassCodeSnip(QString &code, const GeneratorContext &context) const;
/**