From de6d78fe3d7a41d0b6ef56363e82ffc8fb75119a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 12 Apr 2019 15:24:51 +0200 Subject: shiboken: Fix code injection not working for operator functions Searching for the function modifications of the operator function by signature failed due to the internally changed signature. Store the function modification list of user-added-functions directly in struct AddedFunction instead of the type entry of the containing class. In AbstractMetaFunction, replace the bool m_userAdded flag by a shared pointer to the AddedFunction and use that to retrieve the modifications (injected code snippets) for the user-added functions instead of searching for them by function signature. Task-number: PYSIDE-995 Change-Id: Ic4d0b257f141a450df26563d33beb397b6209d91 Reviewed-by: Qt CI Bot Reviewed-by: Cristian Maureira-Fredes --- .../shiboken2/ApiExtractor/abstractmetabuilder.cpp | 12 +-------- .../shiboken2/ApiExtractor/abstractmetalang.cpp | 29 ++++++++++++++++++++-- sources/shiboken2/ApiExtractor/abstractmetalang.h | 12 +++------ .../ApiExtractor/tests/testaddfunction.cpp | 2 +- sources/shiboken2/ApiExtractor/typesystem.cpp | 13 ++++++++++ sources/shiboken2/ApiExtractor/typesystem.h | 2 ++ sources/shiboken2/ApiExtractor/typesystem_p.h | 1 + 7 files changed, 48 insertions(+), 23 deletions(-) diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 8373889d4..6e95e79e7 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1596,17 +1596,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc, AbstractMetaClass *metaClass) { - AbstractMetaFunction *metaFunction = new AbstractMetaFunction; - metaFunction->setConstant(addedFunc->isConstant()); - metaFunction->setName(addedFunc->name()); - metaFunction->setOriginalName(addedFunc->name()); - AbstractMetaClass::Attributes visibility = - addedFunc->access() == AddedFunction::Public - ? AbstractMetaAttributes::Public : AbstractMetaAttributes::Protected; - metaFunction->setVisibility(visibility); - metaFunction->setUserAdded(true); - AbstractMetaAttributes::Attribute isStatic = addedFunc->isStatic() ? AbstractMetaFunction::Static : AbstractMetaFunction::None; - metaFunction->setAttributes(metaFunction->attributes() | AbstractMetaAttributes::FinalInTargetLang | isStatic); + AbstractMetaFunction *metaFunction = new AbstractMetaFunction(addedFunc); metaFunction->setType(translateType(addedFunc->returnType())); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index 00d2ffb89..512efef58 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -452,10 +452,32 @@ QDebug operator<<(QDebug d, const AbstractMetaArgument *aa) * AbstractMetaFunction */ +AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) : + AbstractMetaFunction() +{ + m_addedFunction = addedFunc; + setConstant(addedFunc->isConstant()); + setName(addedFunc->name()); + setOriginalName(addedFunc->name()); + auto atts = attributes() | AbstractMetaAttributes::FinalInTargetLang; + switch (addedFunc->access()) { + case AddedFunction::InvalidAccess: + break; + case AddedFunction::Protected: + atts |= AbstractMetaAttributes::Protected; + break; + case AddedFunction::Public: + atts |= AbstractMetaAttributes::Public; + break; + } + if (addedFunc->isStatic()) + atts |= AbstractMetaFunction::Static; + setAttributes(atts); +} + AbstractMetaFunction::AbstractMetaFunction() : m_constant(false), m_reverse(false), - m_userAdded(false), m_explicit(false), m_pointerOperator(false), m_isCallOperator(false) @@ -579,6 +601,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const cpy->setExceptionSpecification(m_exceptionSpecification); cpy->setAllowThreadModification(m_allowThreadModification); cpy->setExceptionHandlingModification(m_exceptionHandlingModification); + cpy->m_addedFunction = m_addedFunction; for (AbstractMetaArgument *arg : m_arguments) cpy->addArgument(arg->copy()); @@ -942,6 +965,8 @@ QString AbstractMetaFunction::debugSignature() const FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass* implementor) const { + if (!m_addedFunction.isNull()) + return m_addedFunction->modifications; if (!implementor) implementor = ownerClass(); @@ -1279,7 +1304,7 @@ void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const d << " [const]"; if (m_reverse) d << " [reverse]"; - if (m_userAdded) + if (isUserAdded()) d << " [userAdded]"; if (m_explicit) d << " [explicit]"; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 4dbae94d2..ef4cef2b4 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -783,6 +783,7 @@ public: Q_FLAG(CompareResultFlag) AbstractMetaFunction(); + explicit AbstractMetaFunction(const AddedFunctionPtr &addedFunc); ~AbstractMetaFunction(); QString name() const @@ -1003,14 +1004,7 @@ public: } /// Returns true if the AbstractMetaFunction was added by the user via the type system description. - bool isUserAdded() const - { - return m_userAdded; - } - void setUserAdded(bool userAdded) - { - m_userAdded = userAdded; - } + bool isUserAdded() const { return !m_addedFunction.isNull(); } QString toString() const { @@ -1118,9 +1112,9 @@ private: const AbstractMetaClass *m_declaringClass = nullptr; QPropertySpec *m_propertySpec = nullptr; AbstractMetaArgumentList m_arguments; + AddedFunctionPtr m_addedFunction; uint m_constant : 1; uint m_reverse : 1; - uint m_userAdded : 1; uint m_explicit : 1; uint m_pointerOperator : 1; uint m_isCallOperator : 1; diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp index db49942c9..53b9467b1 100644 --- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp @@ -265,7 +265,7 @@ void TestAddFunction::testAddFunctionAtModuleLevel() QCOMPARE(addedFuncs.size(), 1); - FunctionModificationList mods = typeDb->functionModifications(QLatin1String("func(int,int)")); + const FunctionModificationList mods = addedFuncs.constFirst()->modifications; QCOMPARE(mods.size(), 1); QVERIFY(mods.first().isCodeInjection()); diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index e35c997d0..079be5377 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -674,6 +674,17 @@ bool Handler::endElement(const QStringRef &localName) } } break; + case StackElement::AddFunction: { + // Leaving add-function: Assign all modifications to the added function + StackElementContext *top = m_contextStack.top(); + const int modIndex = top->addedFunctionModificationIndex; + top->addedFunctionModificationIndex = -1; + Q_ASSERT(modIndex >= 0); + Q_ASSERT(!top->addedFunctions.isEmpty()); + while (modIndex < top->functionMods.size()) + top->addedFunctions.last()->modifications.append(top->functionMods.takeAt(modIndex)); + } + break; case StackElement::NativeToTarget: case StackElement::AddConversion: { CustomConversion* customConversion = static_cast(m_current->entry)->customConversion(); @@ -2025,6 +2036,8 @@ bool Handler::parseAddFunction(const QXmlStreamReader &, } m_contextStack.top()->addedFunctions << func; + m_contextStack.top()->addedFunctionModificationIndex = + m_contextStack.top()->functionMods.size(); FunctionModification mod; if (!mod.setSignature(m_currentSignature, &m_error)) diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index e2123ea4f..f089bb6e0 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -476,6 +476,8 @@ struct AddedFunction return m_isStatic; } + FunctionModificationList modifications; + private: QString m_name; QVector m_arguments; diff --git a/sources/shiboken2/ApiExtractor/typesystem_p.h b/sources/shiboken2/ApiExtractor/typesystem_p.h index a119b2a97..df1390cc3 100644 --- a/sources/shiboken2/ApiExtractor/typesystem_p.h +++ b/sources/shiboken2/ApiExtractor/typesystem_p.h @@ -132,6 +132,7 @@ struct StackElementContext FunctionModificationList functionMods; FieldModificationList fieldMods; DocModificationList docModifications; + int addedFunctionModificationIndex = -1; }; class Handler -- cgit v1.2.3