diff options
Diffstat (limited to 'sources/shiboken2')
9 files changed, 112 insertions, 31 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 4566ed3bc..2d546cadd 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1613,9 +1613,22 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc, AbstractMetaClass *metaClass) { - auto *metaFunction = new AbstractMetaFunction(addedFunc); - metaFunction->setType(translateType(addedFunc->returnType())); + QString errorMessage; + AbstractMetaType *returnType = nullptr; + if (addedFunc->returnType().name != QLatin1String("void")) { + returnType = translateType(addedFunc->returnType(), &errorMessage); + if (!returnType) { + qCWarning(lcShiboken, "%s", + qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(), + addedFunc->returnType().name, + errorMessage))); + return nullptr; + } + } + + auto metaFunction = new AbstractMetaFunction(addedFunc); + metaFunction->setType(returnType); const auto &args = addedFunc->arguments(); AbstractMetaArgumentList metaArguments; @@ -1623,11 +1636,12 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu for (int i = 0; i < args.count(); ++i) { const AddedFunction::TypeInfo& typeInfo = args.at(i).typeInfo; auto *metaArg = new AbstractMetaArgument; - AbstractMetaType *type = translateType(typeInfo); + AbstractMetaType *type = translateType(typeInfo, &errorMessage); if (Q_UNLIKELY(!type)) { - qCWarning(lcShiboken, - "Unable to translate type \"%s\" of argument %d of added function \"%s\".", - qPrintable(typeInfo.name), i + 1, qPrintable(addedFunc->name())); + qCWarning(lcShiboken, "%s", + qPrintable(msgAddedFunctionInvalidArgType(addedFunc->name(), + typeInfo.name, i + 1, + errorMessage))); delete metaFunction; return nullptr; } @@ -2041,7 +2055,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return metaFunction; } -AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo) +AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo, + QString *errorMessage) { Q_ASSERT(!typeInfo.name.isEmpty()); TypeDatabase* typeDb = TypeDatabase::instance(); @@ -2053,6 +2068,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: return nullptr; type = typeDb->findType(typeName); + if (!type) + type = typeDb->findFlagsType(typeName); // test if the type is a template, like a container bool isTemplate = false; @@ -2060,12 +2077,11 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: if (!type && typeInfo.name.contains(QLatin1Char('<'))) { const QStringList& parsedType = parseTemplateType(typeInfo.name); if (parsedType.isEmpty()) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name); - } else { - templateArgs = parsedType.mid(1); - isTemplate = (type = typeDb->findContainerType(parsedType[0])); + *errorMessage = QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name); + return nullptr; } + templateArgs = parsedType.mid(1); + isTemplate = (type = typeDb->findContainerType(parsedType[0])); } if (!type) { @@ -2076,20 +2092,18 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: if (it.key().endsWith(colonColon() + typeName)) candidates.append(it.key()); } - - QString msg = QStringLiteral("Type '%1' wasn't found in the type database.\n").arg(typeName); + QTextStream str(errorMessage); + str << "Type '" << typeName << "' wasn't found in the type database.\n"; if (candidates.isEmpty()) { - qFatal("%sDeclare it in the type system using the proper <*-type> tag.", - qPrintable(msg)); - } - - msg += QLatin1String("Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n"); - candidates.sort(); - for (const QString& candidate : qAsConst(candidates)) { - msg += QLatin1String(" ") + candidate + QLatin1Char('\n'); + str << "Declare it in the type system using the proper <*-type> tag."; + } else { + str << "Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n"; + candidates.sort(); + for (const QString& candidate : qAsConst(candidates)) + str << " " << candidate << '\n'; } - qFatal("%s", qPrintable(msg)); + return nullptr; } auto *metaType = new AbstractMetaType; @@ -2100,7 +2114,12 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: metaType->setConstant(typeInfo.isConstant); if (isTemplate) { for (const QString& templateArg : qAsConst(templateArgs)) { - AbstractMetaType *metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg)); + AbstractMetaType *metaArgType = nullptr; + if (templateArg != QLatin1String("void")) { + metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); + if (!metaArgType) + return nullptr; + } metaType->addInstantiation(metaArgType); } metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index b381a62cd..be73697f0 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -136,7 +136,8 @@ public: QString fixDefaultValue(const ArgumentModelItem &item, AbstractMetaType *type, AbstractMetaFunction *fnc, AbstractMetaClass *, int argumentIndex); - AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo); + AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo, + QString *errorMessage); AbstractMetaType *translateType(const TypeInfo &type, AbstractMetaClass *currentClass, TranslateTypeFlags flags = {}, diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index 0ce7df00a..ad694eb4f 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -1582,7 +1582,7 @@ void AbstractMetaClass::addFunction(AbstractMetaFunction *function) else Q_ASSERT(false); //memory leak - m_hasVirtuals |= function->isVirtual() || hasVirtualDestructor(); + m_hasVirtuals |= function->isVirtual(); m_isPolymorphic |= m_hasVirtuals; m_hasNonpublic |= !function->isPublic(); } @@ -2019,6 +2019,13 @@ void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate) addFunction(f); } +void AbstractMetaClass::setHasVirtualDestructor(bool value) +{ + m_hasVirtualDestructor = value; + if (value) + m_hasVirtuals = m_isPolymorphic = 1; +} + bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const { return functions_contains(m_functions, f); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 2ae1b6d21..166e7d0cb 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -1374,10 +1374,7 @@ public: return m_hasVirtualDestructor; } - void setHasVirtualDestructor(bool value) - { - m_hasVirtualDestructor = value; - } + void setHasVirtualDestructor(bool value); bool isConstructible() const { diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp index 546e9c4ed..0eb3c607f 100644 --- a/sources/shiboken2/ApiExtractor/messages.cpp +++ b/sources/shiboken2/ApiExtractor/messages.cpp @@ -107,6 +107,28 @@ static void msgFormatEnumType(Stream &str, str << " (class: " << className << ')'; } +QString msgAddedFunctionInvalidArgType(const QString &addedFuncName, + const QString &typeName, + int pos, const QString &why) +{ + QString result; + QTextStream str(&result); + str << "Unable to translate type \"" << typeName << "\" of argument " + << pos << " of added function \"" << addedFuncName << "\": " << why; + return result; +} + +QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName, + const QString &typeName, const QString &why) +{ + QString result; + QTextStream str(&result); + str << "Unable to translate return type \"" << typeName + << "\" of added function \"" << addedFuncName << "\": " + << why; + return result; +} + QString msgNoEnumTypeEntry(const EnumModelItem &enumItem, const QString &className) { diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h index 2b7b75ba0..ad0553fbc 100644 --- a/sources/shiboken2/ApiExtractor/messages.h +++ b/sources/shiboken2/ApiExtractor/messages.h @@ -45,6 +45,13 @@ QT_FORWARD_DECLARE_CLASS(QDir) QT_FORWARD_DECLARE_CLASS(QFile) QT_FORWARD_DECLARE_CLASS(QXmlStreamReader) +QString msgAddedFunctionInvalidArgType(const QString &addedFuncName, + const QString &typeName, + int pos, const QString &why); + +QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName, + const QString &typeName, const QString &why); + QString msgNoFunctionForModification(const QString &signature, const QString &originalSignature, const QString &className, diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp index b85a022b3..f2e15fdb0 100644 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp @@ -195,6 +195,33 @@ public: QCOMPARE(funcC->implementingClass(), c); } +void TestAbstractMetaClass::testVirtualBase() +{ + const char cppCode[] =R"CPP( +class Base { +public: + virtual ~Base() = default; +}; +class Derived : public Base {}; +)CPP"; + + const char xmlCode[] = R"XML( +<typesystem package="Foo"> + <object-type name='Base'/> + <object-type name='Derived'/> +</typesystem> +)XML"; + QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); + QVERIFY(!builder.isNull()); + AbstractMetaClassList classes = builder->classes(); + auto base = AbstractMetaClass::findClass(classes, QLatin1String("Base")); + QVERIFY(base); + QVERIFY(base->isPolymorphic()); + auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived")); + QVERIFY(derived); + QVERIFY(derived->isPolymorphic()); +} + void TestAbstractMetaClass::testDefaultValues() { const char* cppCode ="\ diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h index cb0b6693e..e19973625 100644 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h +++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h @@ -40,6 +40,7 @@ private slots: void testClassName(); void testClassNameUnderNamespace(); void testVirtualMethods(); + void testVirtualBase(); void testDefaultValues(); void testModifiedDefaultValues(); void testInnerClassOfAPolymorphicOne(); diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py index 3b0825049..24e75e42c 100644 --- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py @@ -116,7 +116,7 @@ def build_brace_pattern(level, separators=""): | {so} {replacer} {sc} | {co} {replacer} {cc} | {ao} {replacer} {ac} - )* + )+ ) """) no_braces_q = "[^{all}{qu}{bs}]*".format(**locals()) |