From 1a3afc7549238463a35d374eaed96410cf76bfb8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 2 Aug 2017 15:17:01 +0200 Subject: FunctionModification: Make it possible to specify a regular expression It should make it easier to specify the modifications for GL functions. Task-number: PYSIDE-516 Change-Id: Ieb2e540f61785d13ee46a196a18d03b311d308e1 Reviewed-by: Alexandru Croitor --- .../shiboken2/ApiExtractor/abstractmetabuilder.cpp | 7 ++-- .../ApiExtractor/tests/testmodifyfunction.cpp | 18 ++++++++-- .../ApiExtractor/tests/testmodifyfunction.h | 1 + sources/shiboken2/ApiExtractor/typedatabase.cpp | 2 +- sources/shiboken2/ApiExtractor/typesystem.cpp | 39 ++++++++++++++++++---- sources/shiboken2/ApiExtractor/typesystem.h | 12 ++++++- 6 files changed, 65 insertions(+), 14 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 5b606e063..64c482c54 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -179,7 +179,7 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications() FunctionModificationList modifications = centry->functionModifications(); for (const FunctionModification &modification : qAsConst(modifications)) { - QString signature = modification.signature; + QString signature = modification.signature(); QString name = signature.trimmed(); name.truncate(name.indexOf(QLatin1Char('('))); @@ -192,7 +192,8 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications() bool found = false; QStringList possibleSignatures; for (AbstractMetaFunction *function : functions) { - if (function->minimalSignature() == signature && function->implementingClass() == clazz) { + if (function->implementingClass() == clazz + && modification.matches(function->minimalSignature())) { found = true; break; } @@ -3122,7 +3123,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, FunctionModificationList mods = function->modifications(templateClass); for (int i = 0; i < mods.size(); ++i) { FunctionModification mod = mods.at(i); - mod.signature = f->minimalSignature(); + mod.setSignature(f->minimalSignature()); // If we ever need it... Below is the code to do // substitution of the template instantation type inside diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp index 3d4ef9c89..dd82a0f14 100644 --- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp @@ -32,24 +32,36 @@ #include #include +void TestModifyFunction::testRenameArgument_data() +{ + QTest::addColumn("pattern"); + QTest::newRow("fixed_string") << QByteArrayLiteral("method(int)"); + QTest::newRow("regular_expression") << QByteArrayLiteral("^method.*"); +} + void TestModifyFunction::testRenameArgument() { + QFETCH(QByteArray, pattern); + const char* cppCode ="\ struct A {\n\ void method(int=0);\n\ };\n"; - const char* xmlCode = "\ + const char xmlCode1[] = "\ \n\ \n\ \n\ - \n\ + \n\ \n\ \n\ \n\ \n\ \n\ \n"; - QScopedPointer builder(TestUtil::parse(cppCode, xmlCode, false)); + + const QByteArray xmlCode = QByteArray(xmlCode1) + pattern + QByteArray(xmlCode2); + QScopedPointer builder(TestUtil::parse(cppCode, xmlCode.constData(), false)); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h index fcaa0f9db..6bb62daf4 100644 --- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h +++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h @@ -37,6 +37,7 @@ class TestModifyFunction : public QObject private slots: void testOwnershipTransfer(); void testWithApiVersion(); + void testRenameArgument_data(); void testRenameArgument(); void invalidateAfterUse(); void testGlobalFunctionModification(); diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index 8cd9eeb89..be0d987a4 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -390,7 +390,7 @@ FunctionModificationList TypeDatabase::functionModifications(const QString& sign FunctionModificationList lst; for (int i = 0; i < m_functionMods.count(); ++i) { const FunctionModification& mod = m_functionMods.at(i); - if (mod.signature == signature) + if (mod.matches(signature)) lst << mod; } diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index 13664c336..0f35e2dd6 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -811,7 +811,8 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts return false; } FunctionModification mod(since); - mod.signature = signature; + if (!mod.setSignature(signature, &m_error)) + return false; mod.renamedToName = attributes[QLatin1String("rename")]; mod.modifiers |= Modification::Rename; m_contextStack.top()->functionMods << mod; @@ -1722,7 +1723,8 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts m_contextStack.top()->addedFunctions << func; FunctionModification mod(since); - mod.signature = m_currentSignature; + if (!mod.setSignature(m_currentSignature, &m_error)) + return false; m_contextStack.top()->functionMods << mod; } break; @@ -1747,7 +1749,9 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts } FunctionModification mod(since); - m_currentSignature = mod.signature = signature; + if (!mod.setSignature(signature, &m_error)) + return false; + m_currentSignature = signature; QString access = attributes[QLatin1String("access")].toLower(); if (!access.isEmpty()) { @@ -2106,7 +2110,7 @@ FunctionModificationList ComplexTypeEntry::functionModifications(const QString & FunctionModificationList lst; for (int i = 0; i < m_functionMods.count(); ++i) { const FunctionModification &mod = m_functionMods.at(i); - if (mod.signature == signature) + if (mod.matches(signature)) lst << mod; } return lst; @@ -2271,9 +2275,26 @@ QString CodeSnipFragment::code() const return m_code; } +bool FunctionModification::setSignature(const QString &s, QString *errorMessage) +{ + if (s.startsWith(QLatin1Char('^'))) { + m_signaturePattern.setPattern(s); + if (!m_signaturePattern.isValid()) { + if (errorMessage) { + *errorMessage = QLatin1String("Invalid signature pattern: \"") + + s + QLatin1String("\": ") + m_signaturePattern.errorString(); + } + return false; + } + } else { + m_signature = s; + } + return true; +} + QString FunctionModification::toString() const { - QString str = signature + QLatin1String("->"); + QString str = signature() + QLatin1String("->"); if (modifiers & AccessModifierMask) { switch (modifiers & AccessModifierMask) { case Private: str += QLatin1String("private"); break; @@ -2312,8 +2333,14 @@ bool FunctionModification::operator!=(const FunctionModification& other) const bool FunctionModification::operator==(const FunctionModification& other) const { - if (signature != other.signature) + if (m_signature.isEmpty() != other.m_signature.isEmpty()) + return false; + + if (m_signature.isEmpty() + ? m_signaturePattern != other.m_signaturePattern + : m_signature != other.m_signature) { return false; + } if (association != other.association) return false; diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index 6c65adbe1..f825379e7 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -383,16 +383,26 @@ struct FunctionModification: public Modification bool operator!=(const FunctionModification& other) const; bool operator==(const FunctionModification& other) const; + bool matches(const QString &functionSignature) const + { + return m_signature.isEmpty() + ? m_signaturePattern.match(functionSignature).hasMatch() + : m_signature == functionSignature; + } + + bool setSignature(const QString &s, QString *errorMessage = nullptr); + QString signature() const { return m_signature.isEmpty() ? m_signaturePattern.pattern() : m_signature; } QString toString() const; - QString signature; QString association; CodeSnipList snips; QVector argument_mods; private: + QString m_signature; + QRegularExpression m_signaturePattern; bool m_thread; bool m_allowThread; double m_version; -- cgit v1.2.3