diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-07-13 14:11:00 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-07-14 07:53:59 +0200 |
commit | 805cc07cb18c972eceaea7dc3d48f840f4795243 (patch) | |
tree | ed810baed0c82cb08a0ee2605bcfbcff9096e833 /sources/shiboken2/generator | |
parent | 8b9ab12aa6b4f3c5e1e02529895770d63ae10b1b (diff) |
shiboken2: Refactor generating return values of virtual functions
Split out a function returning the return statement as a string.
Change-Id: I9c893a8e0068d7d5d6eff4c7ae44c5f754211bdd
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/shiboken2/generator')
-rw-r--r-- | sources/shiboken2/generator/shiboken2/cppgenerator.cpp | 119 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/cppgenerator.h | 5 |
2 files changed, 66 insertions, 58 deletions
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 001c6d902..b071ae181 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -793,7 +793,7 @@ void CppGenerator::writeVirtualMethodCppCall(QTextStream &s, const CodeSnipList &snips, const AbstractMetaArgument *lastArg, const TypeEntry *retType, - const DefaultValue &defaultReturnExpr) + const QString &returnStatement) { if (!snips.isEmpty()) { writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, @@ -803,11 +803,8 @@ void CppGenerator::writeVirtualMethodCppCall(QTextStream &s, if (func->isAbstract()) { s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '" << func->ownerClass()->name() << '.' << funcName - << "()' not implemented.\");\n"; - s << INDENT << "return"; - if (retType) - s << ' ' << defaultReturnExpr.returnValue(); - s << ";\n"; + << "()' not implemented.\");\n" + << INDENT << returnStatement << '\n'; return; } @@ -826,6 +823,56 @@ void CppGenerator::writeVirtualMethodCppCall(QTextStream &s, s << INDENT << "return;\n"; } +// Determine the return statement (void or a result value). +QString CppGenerator::virtualMethodReturn(QTextStream &s, + const AbstractMetaFunction *func, + const FunctionModificationList &functionModifications) +{ + const AbstractMetaType *returnType = func->type(); + if (!returnType) + return QLatin1String("return;"); + for (const FunctionModification &mod : functionModifications) { + for (const ArgumentModification &argMod : mod.argument_mods) { + if (argMod.index == 0 && !argMod.replacedDefaultExpression.isEmpty()) { + static const QRegularExpression regex(QStringLiteral("%(\\d+)")); + Q_ASSERT(regex.isValid()); + QString expr = argMod.replacedDefaultExpression; + for (int offset = 0; ; ) { + const QRegularExpressionMatch match = regex.match(expr, offset); + if (!match.hasMatch()) + break; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const int argId = match.capturedView(1).toInt() - 1; +#else + const int argId = match.capturedRef(1).toInt() - 1; +#endif + if (argId < 0 || argId > func->arguments().count()) { + qCWarning(lcShiboken, "The expression used in return value contains an invalid index."); + break; + } + expr.replace(match.captured(0), func->arguments().at(argId)->name()); + offset = match.capturedStart(1); + } + DefaultValue defaultReturnExpr(DefaultValue::Custom, expr); + return QLatin1String("return ") + defaultReturnExpr.returnValue() + + QLatin1Char(';'); + } + } + } + const DefaultValue defaultReturnExpr = minimalConstructor(returnType); + if (!defaultReturnExpr.isValid()) { + QString errorMsg = QLatin1String(__FUNCTION__) + QLatin1String(": "); + if (const AbstractMetaClass *c = func->implementingClass()) + errorMsg += c->qualifiedCppName() + QLatin1String("::"); + errorMsg += func->signature(); + errorMsg = msgCouldNotFindMinimalConstructor(errorMsg, func->type()->cppSignature()); + qCWarning(lcShiboken).noquote().nospace() << errorMsg; + s << Qt::endl << INDENT << "#error " << errorMsg << Qt::endl; + } + return QLatin1String("return ") + defaultReturnExpr.returnValue() + + QLatin1Char(';'); +} + void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFunction *func, int cacheIndex) @@ -845,57 +892,15 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, Indentation indentation(INDENT); const FunctionModificationList &functionModifications = func->modifications(); - DefaultValue defaultReturnExpr; - if (retType) { - for (const FunctionModification &mod : functionModifications) { - for (const ArgumentModification &argMod : mod.argument_mods) { - if (argMod.index == 0 && !argMod.replacedDefaultExpression.isEmpty()) { - static const QRegularExpression regex(QStringLiteral("%(\\d+)")); - Q_ASSERT(regex.isValid()); - QString expr = argMod.replacedDefaultExpression; - for (int offset = 0; ; ) { - const QRegularExpressionMatch match = regex.match(expr, offset); - if (!match.hasMatch()) - break; -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - const int argId = match.capturedView(1).toInt() - 1; -#else - const int argId = match.capturedRef(1).toInt() - 1; -#endif - if (argId < 0 || argId > func->arguments().count()) { - qCWarning(lcShiboken) << "The expression used in return value contains an invalid index."; - break; - } - expr.replace(match.captured(0), func->arguments().at(argId)->name()); - offset = match.capturedStart(1); - } - defaultReturnExpr.setType(DefaultValue::Custom); - defaultReturnExpr.setValue(expr); - } - } - } - if (!defaultReturnExpr.isValid()) - defaultReturnExpr = minimalConstructor(func->type()); - if (!defaultReturnExpr.isValid()) { - QString errorMsg = QLatin1String(__FUNCTION__) + QLatin1String(": "); - if (const AbstractMetaClass *c = func->implementingClass()) - errorMsg += c->qualifiedCppName() + QLatin1String("::"); - errorMsg += func->signature(); - errorMsg = msgCouldNotFindMinimalConstructor(errorMsg, func->type()->cppSignature()); - qCWarning(lcShiboken).noquote().nospace() << errorMsg; - s << Qt::endl << INDENT << "#error " << errorMsg << Qt::endl; - } - } else { - defaultReturnExpr.setType(DefaultValue::Void); - } + + const QString returnStatement = virtualMethodReturn(s, func, functionModifications); if (func->isAbstract() && func->isModifiedRemoved()) { qCWarning(lcShiboken).noquote().nospace() << QString::fromLatin1("Pure virtual method '%1::%2' must be implement but was "\ "completely removed on type system.") .arg(func->ownerClass()->name(), func->minimalSignature()); - s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl; - s << "}\n\n"; + s << INDENT << returnStatement << "\n}\n\n"; return; } @@ -925,7 +930,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, { Indentation indentation(INDENT); writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType, - defaultReturnExpr); + returnStatement); } if (multi_line) s << INDENT << "}\n"; @@ -936,7 +941,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, s << INDENT << "if (PyErr_Occurred())\n"; { Indentation indentation(INDENT); - s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl; + s << INDENT << returnStatement << '\n'; } s << INDENT << "static PyObject *pyFuncName = Shiboken::String::createStaticString(\"" @@ -950,7 +955,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, if (useOverrideCaching(func->ownerClass())) s << INDENT << "m_PyMethodCache[" << cacheIndex << "] = true;\n"; writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType, - defaultReturnExpr); + returnStatement); } s << INDENT << "}\n\n"; //WS @@ -1040,7 +1045,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, { Indentation indent(INDENT); s << INDENT << "PyErr_Print();\n"; - s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl; + s << INDENT << returnStatement << '\n'; } s << INDENT << "}\n"; @@ -1062,7 +1067,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, "\"Invalid return value in function %s, expected %s, got %s.\", \""; s << func->ownerClass()->name() << '.' << funcName << "\", " << getVirtualFunctionReturnTypeName(func); s << ", Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n"; - s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl; + s << INDENT << returnStatement << '\n'; } s << INDENT << "}\n"; @@ -1083,7 +1088,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, "\"Invalid return value in function %s, expected %s, got %s.\", \""; s << func->ownerClass()->name() << '.' << funcName << "\", " << getVirtualFunctionReturnTypeName(func); s << ", Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n"; - s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl; + s << INDENT << returnStatement << '\n'; } s << INDENT << "}\n"; diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h index 16ee412c9..1cc6c1ca0 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.h +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h @@ -63,7 +63,10 @@ private: void writeVirtualMethodCppCall(QTextStream &s, const AbstractMetaFunction *func, const QString &funcName, const CodeSnipList &snips, const AbstractMetaArgument *lastArg, const TypeEntry *retType, - const DefaultValue &defaultReturnExpr); + const QString &returnStatement); + QString virtualMethodReturn(QTextStream &s, + const AbstractMetaFunction *func, + const FunctionModificationList &functionModifications); void writeMetaObjectMethod(QTextStream &s, const GeneratorContext &classContext); void writeMetaCast(QTextStream &s, const GeneratorContext &classContext); |