aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-11-16 11:20:25 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-11-16 19:03:28 +0100
commit3ac9ba58e6ac969b420be17d5de465dbb2ce21c3 (patch)
treebf51182ead18c14dfceb23951a210382e6675dba
parent15763626e56fb7d495f56e77e4c8f730f560e2f5 (diff)
shiboken6: Refactor Python operator handling
The mapping of the function name to the Python operators was duplicated in ShibokenGenerator and QtDocGenerator. Move it to the Generator base class and use it in the QtDocGenerator as well. Add the underscores. Remove the functions retrieving the Python rich comparison operator code from ShibokenGenerator and add a comparison operator type enum to AbstractMetaFunction instead. Use that to retrieve the Python rich comparison operator code. Task-number: PYSIDE-1711 Change-Id: Ib73412b819c60c3af22bc72c6bd1cfaa7f25904a Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.cpp48
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.h13
-rw-r--r--sources/shiboken6/generator/generator.cpp47
-rw-r--r--sources/shiboken6/generator/generator.h2
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp53
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.h1
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp14
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp69
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h3
9 files changed, 133 insertions, 117 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
index eb255523a..f80a3f59a 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
@@ -711,6 +711,23 @@ void AbstractMetaFunction::setFunctionType(AbstractMetaFunction::FunctionType ty
d->m_functionType = type;
}
+std::optional<AbstractMetaFunction::ComparisonOperatorType> AbstractMetaFunction::comparisonOperatorType() const
+{
+ if (d->m_functionType != ComparisonOperator)
+ return {};
+ static const QHash<QString, ComparisonOperatorType> mapping = {
+ {u"operator=="_qs, OperatorEqual},
+ {u"operator!="_qs, OperatorNotEqual},
+ {u"operator<"_qs, OperatorLess},
+ {u"operator<="_qs, OperatorLessEqual},
+ {u"operator>"_qs, OperatorGreater},
+ {u"operator>="_qs, OperatorGreaterEqual}
+ };
+ const auto it = mapping.constFind(originalName());
+ Q_ASSERT(it != mapping.constEnd());
+ return it.value();
+}
+
// Auto-detect whether a function should be wrapped into
// Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS, that is, temporarily release
// the GIL (global interpreter lock). Doing so is required for any thread-wait
@@ -1443,6 +1460,37 @@ bool AbstractMetaFunction::isVisibilityModifiedToPrivate() const
return false;
}
+struct ComparisonOperator
+{
+ const char *cppOperator;
+ const char *pythonOpCode;
+};
+
+using ComparisonOperatorMapping = QHash<AbstractMetaFunction::ComparisonOperatorType, ComparisonOperator>;
+
+static const ComparisonOperatorMapping &comparisonOperatorMapping()
+{
+ static const ComparisonOperatorMapping result = {
+ {AbstractMetaFunction::OperatorEqual, {"==", "Py_EQ"}},
+ {AbstractMetaFunction::OperatorNotEqual, {"!=", "Py_NE"}},
+ {AbstractMetaFunction::OperatorLess, {"<", "Py_LT"}},
+ {AbstractMetaFunction::OperatorLessEqual, {"<=", "Py_LE"}},
+ {AbstractMetaFunction::OperatorGreater, {">", "Py_GT"}},
+ {AbstractMetaFunction::OperatorGreaterEqual, {">=", "Py_GE"}}
+ };
+ return result;
+}
+
+const char * AbstractMetaFunction::pythonRichCompareOpCode(ComparisonOperatorType ct)
+{
+ return comparisonOperatorMapping().value(ct).pythonOpCode;
+}
+
+const char * AbstractMetaFunction::cppComparisonOperator(ComparisonOperatorType ct)
+{
+ return comparisonOperatorMapping().value(ct).cppOperator;
+}
+
#ifndef QT_NO_DEBUG_STREAM
void AbstractMetaFunction::formatDebugBrief(QDebug &debug) const
{
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.h b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
index 307f3aa33..a7074de3c 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
@@ -37,6 +37,8 @@
#include <QtCore/QScopedPointer>
+#include <optional>
+
QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QRegularExpression)
@@ -84,6 +86,12 @@ public:
};
Q_ENUM(FunctionType)
+ enum ComparisonOperatorType {
+ OperatorEqual, OperatorNotEqual, OperatorLess, OperatorLessEqual,
+ OperatorGreater, OperatorGreaterEqual
+ };
+ Q_ENUM(ComparisonOperatorType)
+
enum CompareResultFlag {
EqualName = 0x00000001,
EqualArguments = 0x00000002,
@@ -279,6 +287,8 @@ public:
FunctionType functionType() const;
void setFunctionType(FunctionType type);
+ std::optional<ComparisonOperatorType> comparisonOperatorType() const;
+
bool usesRValueReferences() const;
bool generateBinding() const;
@@ -416,6 +426,9 @@ public:
SourceLocation sourceLocation() const;
void setSourceLocation(const SourceLocation &sourceLocation);
+ static const char *pythonRichCompareOpCode(ComparisonOperatorType ct);
+ static const char *cppComparisonOperator(ComparisonOperatorType ct);
+
private:
template <class Predicate>
bool traverseCodeSnips(Predicate predicate,
diff --git a/sources/shiboken6/generator/generator.cpp b/sources/shiboken6/generator/generator.cpp
index dd7e00e35..ef9cf3d47 100644
--- a/sources/shiboken6/generator/generator.cpp
+++ b/sources/shiboken6/generator/generator.cpp
@@ -805,6 +805,53 @@ QString Generator::translateType(AbstractMetaType cType,
return s;
}
+static const QHash<QString, QString> &pythonOperators()
+{
+ static const QHash<QString, QString> result = {
+ // call operator
+ {u"operator()"_qs, u"__call__"_qs},
+ // Arithmetic operators
+ {u"operator+"_qs, u"__add__"_qs},
+ {u"operator-"_qs, u"__sub__"_qs},
+ {u"operator*"_qs, u"__mul__"_qs},
+ {u"operator/"_qs, u"__div__"_qs},
+ {u"operator%"_qs, u"__mod__"_qs},
+ // Inplace arithmetic operators
+ {u"operator+="_qs, u"__iadd__"_qs},
+ {u"operator-="_qs, u"__isub__"_qs},
+ {u"operator++"_qs, u"__iadd__"_qs},
+ {u"operator--"_qs, u"__isub__"_qs},
+ {u"operator*="_qs, u"__imul__"_qs},
+ {u"operator/="_qs, u"__idiv__"_qs},
+ {u"operator%="_qs, u"__imod__"_qs},
+ // Bitwise operators
+ {u"operator&"_qs, u"__and__"_qs},
+ {u"operator^"_qs, u"__xor__"_qs},
+ {u"operator|"_qs, u"__or__"_qs},
+ {u"operator<<"_qs, u"__lshift__"_qs},
+ {u"operator>>"_qs, u"__rshift__"_qs},
+ {u"operator~"_qs, u"__invert__"_qs},
+ // Inplace bitwise operators
+ {u"operator&="_qs, u"__iand__"_qs},
+ {u"operator^="_qs, u"__ixor__"_qs},
+ {u"operator|="_qs, u"__ior__"_qs},
+ {u"operator<<="_qs, u"__ilshift__"_qs},
+ {u"operator>>="_qs, u"__irshift__"_qs},
+ // Comparison operators
+ {u"operator=="_qs, u"__eq__"_qs},
+ {u"operator!="_qs, u"__ne__"_qs},
+ {u"operator<"_qs, u"__lt__"_qs},
+ {u"operator>"_qs, u"__gt__"_qs},
+ {u"operator<="_qs, u"__le__"_qs},
+ {u"operator>="_qs, u"__ge__"_qs}
+ };
+ return result;
+}
+
+QString Generator::pythonOperatorFunctionName(const QString &cppOpFuncName)
+{
+ return pythonOperators().value(cppOpFuncName);
+}
QString Generator::subDirectoryForClass(const AbstractMetaClass *clazz) const
{
diff --git a/sources/shiboken6/generator/generator.h b/sources/shiboken6/generator/generator.h
index 59d1b9822..82f231b93 100644
--- a/sources/shiboken6/generator/generator.h
+++ b/sources/shiboken6/generator/generator.h
@@ -288,6 +288,8 @@ protected:
const AbstractMetaClass *context,
Options options = NoOption) const;
+ static QString pythonOperatorFunctionName(const QString &cppOpFuncName);
+
/**
* Returns the package name.
*/
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
index 713706bf3..5302a84ad 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
@@ -108,47 +108,6 @@ static inline QVersionNumber versionOf(const TypeEntry *te)
return QVersionNumber();
}
-static const QHash<QString, QString> &operatorMapping()
-{
- static const QHash<QString, QString> result = {
- {QLatin1String("operator+"), QLatin1String("__add__")},
- {QLatin1String("operator+="), QLatin1String("__iadd__")},
- {QLatin1String("operator-"), QLatin1String("__sub__")},
- {QLatin1String("operator-="), QLatin1String("__isub__")},
- {QLatin1String("operator*"), QLatin1String("__mul__")},
- {QLatin1String("operator*="), QLatin1String("__imul__")},
- {QLatin1String("operator/"), QLatin1String("__div__")},
- {QLatin1String("operator/="), QLatin1String("__idiv__")},
- {QLatin1String("operator%"), QLatin1String("__mod__")},
- {QLatin1String("operator%="), QLatin1String("__imod__")},
- {QLatin1String("operator<<"), QLatin1String("__lshift__")},
- {QLatin1String("operator<<="), QLatin1String("__ilshift__")},
- {QLatin1String("operator>>"), QLatin1String("__rshift__")},
- {QLatin1String("operator>>="), QLatin1String("__irshift__")},
- {QLatin1String("operator&"), QLatin1String("__and__")},
- {QLatin1String("operator&="), QLatin1String("__iand__")},
- {QLatin1String("operator|"), QLatin1String("__or__")},
- {QLatin1String("operator|="), QLatin1String("__ior__")},
- {QLatin1String("operator^"), QLatin1String("__xor__")},
- {QLatin1String("operator^="), QLatin1String("__ixor__")},
- {QLatin1String("operator=="), QLatin1String("__eq__")},
- {QLatin1String("operator!="), QLatin1String("__ne__")},
- {QLatin1String("operator<"), QLatin1String("__lt__")},
- {QLatin1String("operator<="), QLatin1String("__le__")},
- {QLatin1String("operator>"), QLatin1String("__gt__")},
- {QLatin1String("operator>="), QLatin1String("__ge__")},
- };
- return result;
-}
-
-static QString getFuncName(const AbstractMetaFunctionCPtr& cppFunc)
-{
- const auto it = operatorMapping().constFind(cppFunc->name());
- QString result = it != operatorMapping().cend() ? it.value() : cppFunc->name();
- result.replace(QLatin1String("::"), QLatin1String("."));
- return result;
-}
-
QtDocGenerator::QtDocGenerator()
{
m_parameters.snippetComparison =
@@ -689,6 +648,18 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type,
return strType;
}
+QString QtDocGenerator::getFuncName(const AbstractMetaFunctionCPtr& cppFunc)
+{
+ QString result = cppFunc->name();
+ if (cppFunc->isOperatorOverload()) {
+ const QString pythonOperator = Generator::pythonOperatorFunctionName(result);
+ if (!pythonOperator.isEmpty())
+ return pythonOperator;
+ }
+ result.replace(u"::"_qs, u"."_qs);
+ return result;
+}
+
void QtDocGenerator::writeParameterType(TextStream& s, const AbstractMetaClass* cppClass,
const AbstractMetaArgument &arg) const
{
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
index ab2f2fd45..54f716e4c 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
@@ -113,6 +113,7 @@ private:
static QString parseArgDocStyle(const AbstractMetaClass *cppClass,
const AbstractMetaFunctionCPtr &func);
QString translateToPythonType(const AbstractMetaType &type, const AbstractMetaClass *cppClass) const;
+ static QString getFuncName(const AbstractMetaFunctionCPtr& cppFunc);
bool convertToRst(const QString &sourceFileName,
const QString &targetFileName,
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 6b26ea043..a9d41f1f0 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -4927,14 +4927,11 @@ void CppGenerator::writeRichCompareFunction(TextStream &s,
for (const AbstractMetaFunctionCList &overloads : groupedFuncs) {
const auto rfunc = overloads[0];
- QString operatorId = ShibokenGenerator::pythonRichCompareOperatorId(rfunc);
- s << "case " << operatorId << ':' << '\n';
+ const auto op = rfunc->comparisonOperatorType().value();
+ s << "case " << AbstractMetaFunction::pythonRichCompareOpCode(op) << ':' << '\n';
Indentation indent(s);
- QString op = rfunc->originalName();
- op = op.right(op.size() - QLatin1String("operator").size());
-
int alternativeNumericTypes = 0;
for (const auto &func : overloads) {
if (!func->isStatic() &&
@@ -4982,7 +4979,8 @@ void CppGenerator::writeRichCompareFunction(TextStream &s,
// expression
if (func->isPointerOperator())
s << '&';
- s << CPP_SELF_VAR << ' ' << op << '(';
+ s << CPP_SELF_VAR << ' '
+ << AbstractMetaFunction::cppComparisonOperator(op) << " (";
if (argType.shouldDereferenceArgument())
s << '*';
s << CPP_ARG0 << ");\n"
@@ -4998,10 +4996,10 @@ void CppGenerator::writeRichCompareFunction(TextStream &s,
}
s << " else {\n";
- if (operatorId == QLatin1String("Py_EQ") || operatorId == QLatin1String("Py_NE")) {
+ if (op == AbstractMetaFunction::OperatorEqual || op == AbstractMetaFunction::OperatorNotEqual) {
Indentation indent(s);
s << PYTHON_RETURN_VAR << " = "
- << (operatorId == QLatin1String("Py_EQ") ? "Py_False" : "Py_True") << ";\n"
+ << (op == AbstractMetaFunction::OperatorEqual ? "Py_False" : "Py_True") << ";\n"
<< "Py_INCREF(" << PYTHON_RETURN_VAR << ");\n";
} else {
Indentation indent(s);
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 70d7f7236..32a9f1f29 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -686,64 +686,13 @@ QString ShibokenGenerator::pythonPrimitiveTypeName(const QString &cppTypeName)
return it.value();
}
-static const QHash<QString, QString> &pythonOperators()
-{
- static const QHash<QString, QString> result = {
- // call operator
- {QLatin1String("operator()"), QLatin1String("call")},
- // Arithmetic operators
- {QLatin1String("operator+"), QLatin1String("add")},
- {QLatin1String("operator-"), QLatin1String("sub")},
- {QLatin1String("operator*"), QLatin1String("mul")},
- {QLatin1String("operator/"), QLatin1String("div")},
- {QLatin1String("operator%"), QLatin1String("mod")},
- // Inplace arithmetic operators
- {QLatin1String("operator+="), QLatin1String("iadd")},
- {QLatin1String("operator-="), QLatin1String("isub")},
- {QLatin1String("operator++"), QLatin1String("iadd")},
- {QLatin1String("operator--"), QLatin1String("isub")},
- {QLatin1String("operator*="), QLatin1String("imul")},
- {QLatin1String("operator/="), QLatin1String("idiv")},
- {QLatin1String("operator%="), QLatin1String("imod")},
- // Bitwise operators
- {QLatin1String("operator&"), QLatin1String("and")},
- {QLatin1String("operator^"), QLatin1String("xor")},
- {QLatin1String("operator|"), QLatin1String("or")},
- {QLatin1String("operator<<"), QLatin1String("lshift")},
- {QLatin1String("operator>>"), QLatin1String("rshift")},
- {QLatin1String("operator~"), QLatin1String("invert")},
- // Inplace bitwise operators
- {QLatin1String("operator&="), QLatin1String("iand")},
- {QLatin1String("operator^="), QLatin1String("ixor")},
- {QLatin1String("operator|="), QLatin1String("ior")},
- {QLatin1String("operator<<="), QLatin1String("ilshift")},
- {QLatin1String("operator>>="), QLatin1String("irshift")},
- // Comparison operators
- {QLatin1String("operator=="), QLatin1String("eq")},
- {QLatin1String("operator!="), QLatin1String("ne")},
- {QLatin1String("operator<"), QLatin1String("lt")},
- {QLatin1String("operator>"), QLatin1String("gt")},
- {QLatin1String("operator<="), QLatin1String("le")},
- {QLatin1String("operator>="), QLatin1String("ge")},
- };
- return result;
-}
-
-QString ShibokenGenerator::pythonOperatorFunctionName(const QString &cppOpFuncName)
-{
- QString value = pythonOperators().value(cppOpFuncName);
- if (value.isEmpty())
- return unknownOperator();
- value.prepend(QLatin1String("__"));
- value.append(QLatin1String("__"));
- return value;
-}
-
QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunctionCPtr &func)
{
- QString op = pythonOperatorFunctionName(func->originalName());
- if (op == unknownOperator())
+ QString op = Generator::pythonOperatorFunctionName(func->originalName());
+ if (op.isEmpty()) {
qCWarning(lcShiboken).noquote().nospace() << msgUnknownOperator(func.data());
+ return unknownOperator();
+ }
if (func->arguments().isEmpty()) {
if (op == QLatin1String("__sub__"))
op = QLatin1String("__neg__");
@@ -757,16 +706,6 @@ QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunction
return op;
}
-QString ShibokenGenerator::pythonRichCompareOperatorId(const QString &cppOpFuncName)
-{
- return QLatin1String("Py_") + pythonOperators().value(cppOpFuncName).toUpper();
-}
-
-QString ShibokenGenerator::pythonRichCompareOperatorId(const AbstractMetaFunctionCPtr &func)
-{
- return pythonRichCompareOperatorId(func->originalName());
-}
-
bool ShibokenGenerator::isNumber(const QString &cpythonApiName)
{
return cpythonApiName == pyIntT()
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index ff3feea94..36548e538 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -209,10 +209,7 @@ protected:
static QString pythonPrimitiveTypeName(const QString &cppTypeName);
- static QString pythonOperatorFunctionName(const QString &cppOpFuncName);
static QString pythonOperatorFunctionName(const AbstractMetaFunctionCPtr &func);
- static QString pythonRichCompareOperatorId(const QString &cppOpFuncName);
- static QString pythonRichCompareOperatorId(const AbstractMetaFunctionCPtr &func);
static QString fixedCppTypeName(const CustomConversion::TargetToNativeConversion *toNative);
static QString fixedCppTypeName(const AbstractMetaType &type);