diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-07-27 22:09:25 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-07-28 14:59:40 +0200 |
commit | f0ebbfa8b128be39fe618188cad3320987c89051 (patch) | |
tree | c88d45ed7b94aa0e0ecad017f257a88df74f8238 | |
parent | ecc588bfbc15c1c344093601374e16c4e64dc075 (diff) |
shiboken6: Introduce a new normalization function for added functions
QMetaObject::normalizedSignature() was used for normalizing
added function signatures as well as matching modify-function
signatures. The function replaces const-ref by value which
is convenient for matching existing functions, but very problematic
for adding functions. It also does not work for added functions
with parameter names ("const QVariant &@name@" will be left unchanged).
Introduce a new function that only normalizes white space for
the add function cases.
[ChangeLog][shiboken] A new, simpler normalization function has
been introduced for signatures of added functions (which means
for example that const-ref is preserved).
Change-Id: I642aa484095523e3dabb263fadedb20e3c0d3f15
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Tismer <tismer@stackless.com>
4 files changed, 59 insertions, 2 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp index cac311626..0437664a0 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp @@ -1567,7 +1567,11 @@ AbstractMetaFunction * const auto &args = addedFunc->arguments(); - for (int i = 0; i < args.count(); ++i) { + qsizetype argCount = args.count(); + // Check "foo(void)" + if (argCount == 1 && args.constFirst().typeInfo.isVoid()) + argCount = 0; + for (qsizetype i = 0; i < argCount; ++i) { const AddedFunction::Argument &arg = args.at(i); auto type = translateType(arg.typeInfo, metaClass, {}, errorMessage); if (Q_UNLIKELY(!type.has_value())) { diff --git a/sources/shiboken6/ApiExtractor/typedatabase.cpp b/sources/shiboken6/ApiExtractor/typedatabase.cpp index 8a4e6d2f1..596af53ca 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp @@ -105,8 +105,60 @@ static const IntTypeNormalizationEntries &intTypeNormalizationEntries() return result; } +// Normalization helpers +enum CharCategory { Space, Identifier, Other }; + +static CharCategory charCategory(QChar c) +{ + if (c.isSpace()) + return Space; + if (c.isLetterOrNumber() || c == u'_') + return Identifier; + return Other; +} + +// Normalize a C++ function signature: +// Drop space except between identifiers ("unsigned int", "const int") +static QString normalizeCppFunctionSignature(const QString &signatureIn) +{ + const QString signature = signatureIn.simplified(); + QString result; + result.reserve(signature.size()); + + CharCategory lastNonSpaceCategory = Other; + bool pendingSpace = false; + for (QChar c : signature) { + if (c.isSpace()) { + pendingSpace = true; + } else { + const auto category = charCategory(c); + if (pendingSpace) { + if (lastNonSpaceCategory == Identifier && category == Identifier) + result.append(u' '); + pendingSpace = false; + } + lastNonSpaceCategory = category; + result.append(c); + } + } + return result; +} + +// Normalize a signature for <add-function> by removing spaces +QString TypeDatabase::normalizedAddedFunctionSignature(const QString &signature) +{ + return normalizeCppFunctionSignature(signature); +} + +// Normalize a signature for matching by <modify-function>/<function> +// by removing spaces and changing const-ref to value. +// FIXME: PYSIDE7: Check whether the above simple normalization can be used +// here as well. Note though that const-ref would then have to be spelled out +// in typeystem XML. QString TypeDatabase::normalizedSignature(const QString &signature) { + // QMetaObject::normalizedSignature() changes const-ref to value and + // changes "unsigned int" to "uint" which is undone by the below code QString normalized = QLatin1String(QMetaObject::normalizedSignature(signature.toUtf8().constData())); if (instance() && signature.contains(QLatin1String("unsigned"))) { diff --git a/sources/shiboken6/ApiExtractor/typedatabase.h b/sources/shiboken6/ApiExtractor/typedatabase.h index 082d833b5..f8878f896 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.h +++ b/sources/shiboken6/ApiExtractor/typedatabase.h @@ -107,6 +107,7 @@ public: static TypeDatabase *instance(bool newInstance = false); static QString normalizedSignature(const QString &signature); + static QString normalizedAddedFunctionSignature(const QString &signature); QStringList requiredTargetImports() const; diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp index ea07b752e..19943a5a9 100644 --- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp @@ -2284,7 +2284,7 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &, } } - QString signature = TypeDatabase::normalizedSignature(originalSignature); + QString signature = TypeDatabase::normalizedAddedFunctionSignature(originalSignature); if (signature.isEmpty()) { m_error = QLatin1String("No signature for the added function"); return false; |