aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp7
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp18
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h1
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp39
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h12
6 files changed, 65 insertions, 14 deletions
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 <abstractmetalang.h>
#include <typesystem.h>
+void TestModifyFunction::testRenameArgument_data()
+{
+ QTest::addColumn<QByteArray>("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[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='int'/>\n\
<object-type name='A'>\n\
- <modify-function signature='method(int)'>\n\
+ <modify-function signature='";
+ const char xmlCode2[] = "'>\n\
<modify-argument index='1'>\n\
<rename to='otherArg'/>\n\
</modify-argument>\n\
</modify-function>\n\
</object-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+
+ const QByteArray xmlCode = QByteArray(xmlCode1) + pattern + QByteArray(xmlCode2);
+ QScopedPointer<AbstractMetaBuilder> 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<ArgumentModification> argument_mods;
private:
+ QString m_signature;
+ QRegularExpression m_signaturePattern;
bool m_thread;
bool m_allowThread;
double m_version;