diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-11-04 12:34:17 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-11-04 12:42:35 +0100 |
commit | 1704567d7ad0d21dd3b588af7aad40cd244c1799 (patch) | |
tree | 932b42988e482f01125dcbf4d470e9a56107689a /sources/shiboken2/ApiExtractor | |
parent | 1d77cd18510412242384c5b37a00efd5b6ce8a26 (diff) | |
parent | c98ef56544cd54661b61529829caf6a799a1a94f (diff) |
Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
12 files changed, 209 insertions, 169 deletions
diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt index c8a5fb336..c2a4c208e 100644 --- a/sources/shiboken2/ApiExtractor/CMakeLists.txt +++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt @@ -30,6 +30,22 @@ parser/enumvalue.cpp xmlutils.cpp ) +find_package(Qt5XmlPatterns 5.12) +find_package(Qt5Xml 5.12) +find_package(LibXml2 2.6.32) +find_package(LibXslt 1.1.19) + +set(HAS_LIBXSLT 0) +if (LIBXSLT_FOUND AND LIBXML2_FOUND) + set(HAS_LIBXSLT 1) +endif() + +if(NOT Qt5XmlPatterns_FOUND AND NOT HAS_LIBXSLT) + set(DISABLE_DOCSTRINGS TRUE) + message(WARNING + "Documentation will not be built due to missing dependency (no Qt5XmlPatterns found).") +endif() + add_library(apiextractor STATIC ${apiextractor_SRC}) target_include_directories(apiextractor PRIVATE ${CLANG_EXTRA_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} @@ -68,6 +84,7 @@ target_compile_definitions(apiextractor PRIVATE CMAKE_CXX_COMPILER="${CMAKE_CXX_ set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE) if (BUILD_TESTS) + find_package(Qt5Test 5.12 REQUIRED) set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) enable_testing() add_subdirectory(tests) diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 9c930dcdc..ae3cdd86b 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -248,6 +248,15 @@ void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &f } } +void AbstractMetaBuilderPrivate::registerToStringCapabilityIn(const NamespaceModelItem &nsItem) +{ + const FunctionList &streamOps = nsItem->findFunctions(QLatin1String("operator<<")); + for (const FunctionModelItem &item : streamOps) + registerToStringCapability(item, nullptr); + for (const NamespaceModelItem &ni : nsItem->namespaces()) + registerToStringCapabilityIn(ni); +} + /** * Check if a class has a debug stream operator that can be used as toString */ @@ -261,7 +270,7 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelI const ArgumentModelItem &arg = arguments.at(1); if (AbstractMetaClass *cls = argumentToClass(arg, currentClass)) { if (arg->type().indirections() < 2) - cls->setToStringCapability(true); + cls->setToStringCapability(true, arg->type().indirections()); } } } @@ -503,8 +512,12 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) ReportHandler::startProgress("Fixing class inheritance..."); for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { - if (!cls->isInterface() && !cls->isNamespace()) + if (!cls->isInterface() && !cls->isNamespace()) { setupInheritance(cls); + if (!cls->hasVirtualDestructor() && cls->baseClass() + && cls->baseClass()->hasVirtualDestructor()) + cls->setHasVirtualDestructor(true); + } } ReportHandler::startProgress("Detecting inconsistencies in class model..."); @@ -591,11 +604,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) registerHashFunction(item, nullptr); } - { - const FunctionList &streamOps = dom->findFunctions(QLatin1String("operator<<")); - for (const FunctionModelItem &item : streamOps) - registerToStringCapability(item, nullptr); - } + registerToStringCapabilityIn(dom); { FunctionList binaryOperators = dom->findFunctions(QStringLiteral("operator==")); @@ -1612,6 +1621,26 @@ void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem, } } +static void applyDefaultExpressionModifications(const FunctionModificationList &functionMods, + int i, AbstractMetaArgument *metaArg) +{ + // use replace/remove-default-expression for set default value + for (const auto &modification : functionMods) { + for (const auto &argumentModification : modification.argument_mods) { + if (argumentModification.index == i + 1) { + if (argumentModification.removedDefaultExpression) { + metaArg->setDefaultValueExpression(QString()); + break; + } + if (!argumentModification.replacedDefaultExpression.isEmpty()) { + metaArg->setDefaultValueExpression(argumentModification.replacedDefaultExpression); + break; + } + } + } + } +} + AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc) { return traverseFunction(addedFunc, nullptr); @@ -1670,20 +1699,13 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu // Find the correct default values + const FunctionModificationList functionMods = metaFunction->modifications(metaClass); for (int i = 0; i < metaArguments.size(); ++i) { AbstractMetaArgument* metaArg = metaArguments.at(i); - //use relace-default-expression for set default value - QString replacedExpression; - if (metaClass) - replacedExpression = metaFunction->replacedDefaultExpression(metaClass, i + 1); - - if (!replacedExpression.isEmpty()) { - if (!metaFunction->removedDefaultExpression(metaClass, i + 1)) { - metaArg->setDefaultValueExpression(replacedExpression); - metaArg->setOriginalDefaultValueExpression(replacedExpression); - } - } + // use replace-default-expression for set default value + applyDefaultExpressionModifications(functionMods, i, metaArg); + metaArg->setOriginalDefaultValueExpression(metaArg->defaultValueExpression()); // appear unmodified } metaFunction->setOriginalAttributes(metaFunction->attributes()); @@ -1915,7 +1937,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio AbstractMetaType *type = nullptr; if (!returnType.isVoid()) { - type = translateType(returnType, currentClass, true, &errorMessage); + type = translateType(returnType, currentClass, {}, &errorMessage); if (!type) { const QString reason = msgUnmatchedReturnType(functionItem, errorMessage); qCWarning(lcShiboken, "%s", @@ -1951,7 +1973,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return nullptr; } - AbstractMetaType *metaType = translateType(arg->type(), currentClass, true, &errorMessage); + AbstractMetaType *metaType = translateType(arg->type(), currentClass, {}, &errorMessage); if (!metaType) { // If an invalid argument has a default value, simply remove it if (arg->defaultValue()) { @@ -2002,35 +2024,16 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio const ArgumentModelItem &arg = arguments.at(i); AbstractMetaArgument* metaArg = metaArguments.at(i); - //use relace-default-expression for set default value - QString replacedExpression; - if (currentClass) { - replacedExpression = metaFunction->replacedDefaultExpression(currentClass, i + 1); - } else { - if (!functionMods.isEmpty()) { - QVector<ArgumentModification> argMods = functionMods.constFirst().argument_mods; - if (!argMods.isEmpty()) - replacedExpression = argMods.constFirst().replacedDefaultExpression; - } - } + const QString originalDefaultExpression = + fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i); - bool hasDefaultValue = false; - if (arg->defaultValue() || !replacedExpression.isEmpty()) { - QString expr = arg->defaultValueExpression(); - expr = fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i); - metaArg->setOriginalDefaultValueExpression(expr); + metaArg->setOriginalDefaultValueExpression(originalDefaultExpression); + metaArg->setDefaultValueExpression(originalDefaultExpression); - if (metaFunction->removedDefaultExpression(currentClass, i + 1)) { - expr.clear(); - } else if (!replacedExpression.isEmpty()) { - expr = replacedExpression; - } - metaArg->setDefaultValueExpression(expr); - hasDefaultValue = !expr.isEmpty(); - } + applyDefaultExpressionModifications(functionMods, i, metaArg); //Check for missing argument name - if (hasDefaultValue + if (!metaArg->defaultValueExpression().isEmpty() && !metaArg->hasName() && !metaFunction->isOperatorOverload() && !metaFunction->isSignal() @@ -2155,22 +2158,27 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei, AbstractMetaClass *currentClass, - bool resolveType, + TranslateTypeFlags flags, QString *errorMessage) { - return translateTypeStatic(_typei, currentClass, this, resolveType, errorMessage); + return translateTypeStatic(_typei, currentClass, this, flags, errorMessage); } AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei, AbstractMetaClass *currentClass, AbstractMetaBuilderPrivate *d, - bool resolveType, + TranslateTypeFlags flags, QString *errorMessageIn) { // 1. Test the type info without resolving typedefs in case this is present in the // type system + const bool resolveType = !flags.testFlag(AbstractMetaBuilder::DontResolveType); if (resolveType) { - if (AbstractMetaType *resolved = translateTypeStatic(_typei, currentClass, d, false, errorMessageIn)) + AbstractMetaType *resolved = + translateTypeStatic(_typei, currentClass, d, + flags | AbstractMetaBuilder::DontResolveType, + errorMessageIn); + if (resolved) return resolved; } @@ -2229,7 +2237,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo newInfo.setReferenceType(typeInfo.referenceType()); newInfo.setVolatile(typeInfo.isVolatile()); - AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, true, &errorMessage); + AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage); if (!elementType) { if (errorMessageIn) { errorMessage.prepend(QLatin1String("Unable to translate array element: ")); @@ -2340,7 +2348,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo const auto &templateArguments = typeInfo.instantiations(); for (int t = 0, size = templateArguments.size(); t < size; ++t) { const TypeInfo &ti = templateArguments.at(t); - AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, true, &errorMessage); + AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage); if (!targType) { if (errorMessageIn) *errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage); @@ -2362,17 +2370,17 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, AbstractMetaClass *currentClass, - bool resolveType, + TranslateTypeFlags flags, QString *errorMessage) { return AbstractMetaBuilderPrivate::translateTypeStatic(_typei, currentClass, - nullptr, resolveType, + nullptr, flags, errorMessage); } AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t, AbstractMetaClass *currentClass, - bool resolveType, + TranslateTypeFlags flags, QString *errorMessageIn) { QString errorMessage; @@ -2385,7 +2393,7 @@ AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t, qCWarning(lcShiboken, "%s", qPrintable(errorMessage)); return nullptr; } - return translateType(typeInfo, currentClass, resolveType, errorMessageIn); + return translateType(typeInfo, currentClass, flags, errorMessageIn); } qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValue, bool &ok) @@ -2431,10 +2439,10 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite AbstractMetaClass *implementingClass, int /* argumentIndex */) { - QString functionName = fnc->name(); - QString className = implementingClass ? implementingClass->qualifiedCppName() : QString(); - QString expr = item->defaultValueExpression(); + if (expr.isEmpty()) + return expr; + if (type) { if (type->isPrimitive()) { if (type->name() == QLatin1String("boolean")) { @@ -2508,11 +2516,12 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite } } } else { + const QString className = implementingClass ? implementingClass->qualifiedCppName() : QString(); qCWarning(lcShiboken).noquote().nospace() << QStringLiteral("undefined type for default value '%3' of argument in function '%1', class '%2'") - .arg(functionName, className, item->defaultValueExpression()); + .arg(fnc->name(), className, item->defaultValueExpression()); - expr = QString(); + expr.clear(); } return expr; diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h index 1789ca2aa..93b9d9fd2 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h @@ -90,13 +90,18 @@ public: void setSkipDeprecated(bool value); + enum TranslateTypeFlag { + DontResolveType = 0x1 + }; + Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag); + static AbstractMetaType *translateType(const TypeInfo &_typei, AbstractMetaClass *currentClass = nullptr, - bool resolveType = true, + TranslateTypeFlags flags = {}, QString *errorMessage = nullptr); static AbstractMetaType *translateType(const QString &t, AbstractMetaClass *currentClass = nullptr, - bool resolveType = true, + TranslateTypeFlags flags = {}, QString *errorMessage = nullptr); @@ -109,6 +114,8 @@ private: AbstractMetaBuilderPrivate *d; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaBuilder::TranslateTypeFlags); + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const AbstractMetaBuilder &ab); #endif diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index fec2eddb9..30df236d6 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -43,6 +43,8 @@ class TypeDatabase; class AbstractMetaBuilderPrivate { public: + using TranslateTypeFlags = AbstractMetaBuilder::TranslateTypeFlags; + Q_DISABLE_COPY(AbstractMetaBuilderPrivate) AbstractMetaBuilderPrivate(); @@ -56,7 +58,7 @@ public: void dumpLog() const; AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClassList &classList, const Dependencies &additionalDependencies = Dependencies()) const; - ScopeModelItem popScope() { return m_scopes.takeLast(); } + NamespaceModelItem popScope() { return m_scopes.takeLast(); } void pushScope(const NamespaceModelItem &item); @@ -106,6 +108,7 @@ public: void checkFunctionModifications(); void registerHashFunction(const FunctionModelItem &functionItem, AbstractMetaClass *currentClass); + void registerToStringCapabilityIn(const NamespaceModelItem &namespaceItem); void registerToStringCapability(const FunctionModelItem &functionItem, AbstractMetaClass *currentClass); @@ -135,12 +138,12 @@ public: AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo); AbstractMetaType *translateType(const TypeInfo &type, AbstractMetaClass *currentClass, - bool resolveType = true, + TranslateTypeFlags flags = {}, QString *errorMessage = nullptr); static AbstractMetaType *translateTypeStatic(const TypeInfo &type, AbstractMetaClass *current, AbstractMetaBuilderPrivate *d = nullptr, - bool resolveType = true, + TranslateTypeFlags flags = {}, QString *errorMessageIn = nullptr); qint64 findOutValueFromString(const QString &stringValue, bool &ok); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index 4ca448d50..99e9d01a3 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -731,37 +731,6 @@ ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, return ArgumentOwner(); } - -QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass *cls, int key) const -{ - const FunctionModificationList &modifications = this->modifications(cls); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == key - && !argumentModification.replacedDefaultExpression.isEmpty()) { - return argumentModification.replacedDefaultExpression; - } - } - } - - return QString(); -} - -bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls, int key) const -{ - const FunctionModificationList &modifications = this->modifications(cls); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == key - && argumentModification.removedDefaultExpression) { - return true; - } - } - } - - return false; -} - QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const { const FunctionModificationList &modifications = this->modifications(declaringClass()); @@ -780,19 +749,6 @@ QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int return QString(); } -QString AbstractMetaFunction::argumentReplaced(int key) const -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == key && !argumentModification.replace_value.isEmpty()) - return argumentModification.replace_value; - } - } - - return QString(); -} - // FIXME If we remove a arg. in the method at the base class, it will not reflect here. bool AbstractMetaFunction::argumentRemoved(int key) const { diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 7f0f9fbaa..077191471 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -671,7 +671,9 @@ public: } bool hasDefaultValueExpression() const - { return !m_originalExpression.isEmpty() || !m_expression.isEmpty(); } + { return !m_expression.isEmpty(); } + bool hasOriginalDefaultValueExpression() const + { return !m_originalExpression.isEmpty(); } bool hasUnmodifiedDefaultValueExpression() const { return !m_originalExpression.isEmpty() && m_originalExpression == m_expression; } bool hasModifiedDefaultValueExpression() const @@ -1020,8 +1022,6 @@ public: AbstractMetaFunction *copy() const; - QString replacedDefaultExpression(const AbstractMetaClass *cls, int idx) const; - bool removedDefaultExpression(const AbstractMetaClass *cls, int idx) const; QString conversionRule(TypeSystem::Language language, int idx) const; QVector<ReferenceCount> referenceCounts(const AbstractMetaClass *cls, int idx = -2) const; ArgumentOwner argumentOwner(const AbstractMetaClass *cls, int idx) const; @@ -1034,9 +1034,6 @@ public: bool isRemovedFromAllLanguages(const AbstractMetaClass *) const; bool isRemovedFrom(const AbstractMetaClass *, TypeSystem::Language language) const; bool argumentRemoved(int) const; - - QString argumentReplaced(int key) const; - /** * Verifies if any modification to the function is an inject code. * \return true if there is inject code modifications to the function. @@ -1695,9 +1692,10 @@ public: return m_stream; } - void setToStringCapability(bool value) + void setToStringCapability(bool value, uint indirections = 0) { m_hasToStringCapability = value; + m_toStringCapabilityIndirections = indirections; } bool hasToStringCapability() const @@ -1705,6 +1703,11 @@ public: return m_hasToStringCapability; } + uint toStringCapabilityIndirections() const + { + return m_toStringCapabilityIndirections; + } + bool deleteInMainThread() const; static AbstractMetaClass *findClass(const AbstractMetaClassList &classes, @@ -1757,6 +1760,7 @@ private: // FunctionModelItem m_qDebugStreamFunction; bool m_stream = false; + uint m_toStringCapabilityIndirections = 0; }; Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaClass::FunctionQueryOptions) diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp index 98b493c67..b85a022b3 100644 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp @@ -47,11 +47,12 @@ void TestAbstractMetaClass::testClassName() void TestAbstractMetaClass::testClassNameUnderNamespace() { const char* cppCode ="namespace Namespace { class ClassName {}; }\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <namespace-type name=\"Namespace\"/>\n\ - <value-type name=\"Namespace::ClassName\"/>\n\ - </typesystem>\n"; + const char* xmlCode = R"XML( + <typesystem package="Foo"> + <namespace-type name="Namespace"> + <value-type name="ClassName"/> + </namespace-type> + </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); @@ -201,11 +202,12 @@ void TestAbstractMetaClass::testDefaultValues() class B {};\n\ void method(B b = B());\n\ };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'/>\n\ - <value-type name='A::B'/>\n\ - </typesystem>\n"; + const char* xmlCode = R"XML( + <typesystem package="Foo"> + <value-type name='A'> + <value-type name='B'/> + </value-type> + </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); @@ -224,17 +226,17 @@ void TestAbstractMetaClass::testModifiedDefaultValues() class B {};\n\ void method(B b = B());\n\ };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'>\n\ - <modify-function signature='method(A::B)'>\n\ - <modify-argument index='1'>\n\ - <replace-default-expression with='Hello'/>\n\ - </modify-argument>\n\ - </modify-function>\n\ - </value-type>\n\ - <value-type name='A::B'/>\n\ - </typesystem>\n"; + const char* xmlCode = R"XML( + <typesystem package="Foo"> + <value-type name='A'> + <modify-function signature='method(A::B)'> + <modify-argument index='1'> + <replace-default-expression with='Hello'/> + </modify-argument> + </modify-function> + <value-type name='B'/> + </value-type> + </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); @@ -254,11 +256,12 @@ void TestAbstractMetaClass::testInnerClassOfAPolymorphicOne() class B {};\n\ virtual void method();\n\ };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <object-type name='A'/>\n\ - <value-type name='A::B'/>\n\ - </typesystem>\n"; + const char* xmlCode = R"XML( + <typesystem package="Foo"> + <object-type name='A'> + <value-type name='B'/> + </object-type> + </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); @@ -281,11 +284,12 @@ void TestAbstractMetaClass::testForwardDeclaredInnerClass() public:\n\ void foo();\n\ };\n"; - const char xmlCode[] = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'/>\n\ - <value-type name='A::B'/>\n\ - </typesystem>\n"; + const char xmlCode[] = R"XML( + <typesystem package="Foo"> + <value-type name='A'> + <value-type name='B'/> + </value-type> + </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp index c438e0c37..aeca2d3f4 100644 --- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp @@ -71,8 +71,8 @@ void TestCodeInjections::testReadFile() <value-type name='A'>\n\ <conversion-rule ") + attribute + QLatin1String("/>\n\ <inject-code class='target' ") + attribute + QLatin1String("/>\n\ + <value-type name='B'/>\n\ </value-type>\n\ - <value-type name='A::B'/>\n\ </typesystem>\n"); QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().constData())); QVERIFY(!builder.isNull()); diff --git a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp index f4204e9b9..0eee8af24 100644 --- a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp @@ -69,6 +69,39 @@ void TestDtorInformation::testDtorIsVirtual() QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasVirtualDestructor(), true); } +void TestDtorInformation::testDtorFromBaseIsVirtual() +{ + const char* cppCode = R"CPP(class ControlBase { public: ~ControlBase() {} }; +class Control : public ControlBase {}; +class SubjectBase { public: virtual ~SubjectBase() {} }; +class Subject : public SubjectBase {}; +)CPP"; + const char* xmlCode = R"XML(<typesystem package="Foo"><value-type name="ControlBase"/> +<value-type name="Control"/>" +<value-type name="SubjectBase"/>" +<value-type name="Subject"/> +</typesystem> +)XML"; + QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); + QVERIFY(!builder.isNull()); + AbstractMetaClassList classes = builder->classes(); + QCOMPARE(classes.count(), 4); + + auto klass = AbstractMetaClass::findClass(classes, QLatin1String("ControlBase")); + QVERIFY(klass); + QVERIFY(!klass->hasVirtualDestructor()); + klass = AbstractMetaClass::findClass(classes, QLatin1String("Control")); + QVERIFY(klass); + QVERIFY(!klass->hasVirtualDestructor()); + + klass = AbstractMetaClass::findClass(classes, QLatin1String("SubjectBase")); + QVERIFY(klass); + QVERIFY(klass->hasVirtualDestructor()); + klass = AbstractMetaClass::findClass(classes, QLatin1String("Subject")); + QVERIFY(klass); + QVERIFY(klass->hasVirtualDestructor()); +} + void TestDtorInformation::testClassWithVirtualDtorIsPolymorphic() { const char* cppCode ="class Control { public: virtual ~Control() {} }; class Subject { protected: virtual ~Subject() {} };"; diff --git a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h index 068ef4952..0a57dd8d1 100644 --- a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h +++ b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h @@ -40,6 +40,7 @@ private slots: void testDtorIsPrivate(); void testDtorIsProtected(); void testDtorIsVirtual(); + void testDtorFromBaseIsVirtual(); void testClassWithVirtualDtorIsPolymorphic(); }; diff --git a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp index 2e5a5759a..2203f3648 100644 --- a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp @@ -44,13 +44,15 @@ void TestResolveType::testResolveReturnTypeFromParentScope() C* method();\n\ };\n\ };"; - const char* xmlCode = "\n\ - <typesystem package='Foo'>\n\ - <namespace-type name='A'/>\n\ - <value-type name='A::B'/>\n\ - <value-type name='A::B::C'/>\n\ - <value-type name='A::D'/>\n\ - </typesystem>"; + const char* xmlCode = R"XML( + <typesystem package='Foo'> + <namespace-type name='A'> + <value-type name='B'> + <value-type name='C'/> + </value-type> + <value-type name='D'/> + </namespace-type> + </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp index 59b601f3b..5191cb38d 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp @@ -63,9 +63,10 @@ namespace Internet { <typesystem package='Package.Internet'> <load-typesystem name='%1' generate='no'/> <container-type name='QList' type='list'/> - <namespace-type name='Internet' generate='no'/> - <value-type name='Internet::Url'/> - <value-type name='Internet::Bookmarks'/> + <namespace-type name='Internet' generate='no'> + <value-type name='Url'/> + <value-type name='Bookmarks'/> + </namespace-type> </typesystem>)XML").arg(file.fileName()); QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, qPrintable(xmlCode1), false)); @@ -97,11 +98,12 @@ namespace Namespace { const char xmlCode[] = R"XML( <typesystem package="Package"> <container-type name='QList' type='list'/> - <namespace-type name='Namespace'/> - <enum-type name='Namespace::SomeEnum'/> + <namespace-type name='Namespace'> + <enum-type name='SomeEnum'/> + <object-type name='A' generate='no'/> + <object-type name='B'/> + </namespace-type> <object-type name='Base'/> - <object-type name='Namespace::A' generate='no'/> - <object-type name='Namespace::B'/> </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); @@ -211,8 +213,9 @@ struct List { const char xmlCode[] = R"XML( <typesystem package='Package'> - <container-type name='List' type='list'/> - <value-type name='List::Iterator'/> + <container-type name='List' type='list'> + <value-type name='Iterator'/> + </container-type> </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); @@ -324,11 +327,12 @@ template<SomeEnum type> struct Future {}; const char xmlCode[] = R"XML( <typesystem package='Package'> - <namespace-type name='Namespace'/> - <enum-type name='Namespace::SomeEnum'/> - <value-type name='Namespace::A' generate='no'/> - <value-type name='Namespace::B'/> - <value-type name='Namespace::Future' generate='no'/> + <namespace-type name='Namespace'> + <enum-type name='SomeEnum'/> + <value-type name='A' generate='no'/> + <value-type name='B'/> + <value-type name='Future' generate='no'/> + </namespace-type> </typesystem>)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); |