aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/abstractmetalang.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.cpp841
1 files changed, 460 insertions, 381 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
index 080257346..fb49cc9d0 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
@@ -1,36 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "abstractmetalang.h"
+#include "anystringview_helpers.h"
#include "abstractmetalang_helpers.h"
+#include "abstractmetaargument.h"
#include "abstractmetaenum.h"
#include "abstractmetafunction.h"
+#include "abstractmetatype.h"
#include "abstractmetafield.h"
+#include "parser/codemodel.h"
#include "documentation.h"
#include "messages.h"
#include "modifications.h"
@@ -38,13 +17,18 @@
#include "reporthandler.h"
#include "sourcelocation.h"
#include "typedatabase.h"
-#include "typesystem.h"
+#include "enumtypeentry.h"
+#include "namespacetypeentry.h"
#include "usingmember.h"
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <algorithm>
+using namespace Qt::StringLiterals;
+
bool function_sorter(const AbstractMetaFunctionCPtr &a, const AbstractMetaFunctionCPtr &b)
{
return a->signature() < b->signature();
@@ -66,24 +50,30 @@ public:
m_hasPrivateDestructor(false),
m_hasProtectedDestructor(false),
m_hasVirtualDestructor(false),
- m_hasHashFunction(false),
- m_hasEqualsOperator(false),
- m_hasCloneOperator(false),
m_isTypeDef(false),
m_hasToStringCapability(false),
+ m_valueTypeWithCopyConstructorOnly(false),
m_hasCachedWrapper(false)
{
}
void addFunction(const AbstractMetaFunctionCPtr &function);
+ static AbstractMetaFunction *
+ createFunction(const QString &name, AbstractMetaFunction::FunctionType t,
+ Access access, const AbstractMetaArgumentList &arguments,
+ const AbstractMetaType &returnType, const AbstractMetaClassPtr &q);
void addConstructor(AbstractMetaFunction::FunctionType t,
Access access,
const AbstractMetaArgumentList &arguments,
- AbstractMetaClass *q);
- void addUsingConstructors(AbstractMetaClass *q);
- bool isUsingMember(const AbstractMetaClass *c, const QString &memberName,
+ const AbstractMetaClassPtr &q);
+ void addUsingConstructors(const AbstractMetaClassPtr &q);
+ void sortFunctions();
+ void setFunctions(const AbstractMetaFunctionCList &functions,
+ const AbstractMetaClassCPtr &q);
+ bool isUsingMember(const AbstractMetaClassCPtr &c, const QString &memberName,
Access minimumAccess) const;
bool hasConstructors() const;
+ qsizetype indexOfProperty(const QString &name) const;
uint m_hasVirtuals : 1;
uint m_isPolymorphic : 1;
@@ -97,33 +87,33 @@ public:
uint m_hasPrivateDestructor : 1;
uint m_hasProtectedDestructor : 1;
uint m_hasVirtualDestructor : 1;
- uint m_hasHashFunction : 1;
- uint m_hasEqualsOperator : 1;
- uint m_hasCloneOperator : 1;
uint m_isTypeDef : 1;
uint m_hasToStringCapability : 1;
+ uint m_valueTypeWithCopyConstructorOnly : 1;
mutable uint m_hasCachedWrapper : 1;
Documentation m_doc;
- const AbstractMetaClass *m_enclosingClass = nullptr;
- AbstractMetaClass *m_defaultSuperclass = nullptr;
- AbstractMetaClassList m_baseClasses; // Real base classes after setting up inheritance
+ AbstractMetaClassCPtr m_enclosingClass;
+ AbstractMetaClassCPtr m_defaultSuperclass;
+ AbstractMetaClassCList m_baseClasses; // Real base classes after setting up inheritance
AbstractMetaTypeList m_baseTemplateInstantiations;
- const AbstractMetaClass *m_extendedNamespace = nullptr;
+ AbstractMetaClassCPtr m_extendedNamespace;
- const AbstractMetaClass *m_templateBaseClass = nullptr;
+ AbstractMetaClassCPtr m_templateBaseClass;
AbstractMetaFunctionCList m_functions;
+ AbstractMetaFunctionCList m_userAddedPythonOverrides;
AbstractMetaFieldList m_fields;
AbstractMetaEnumList m_enums;
QList<QPropertySpec> m_propertySpecs;
- AbstractMetaClassList m_innerClasses;
+ AbstractMetaClassCList m_innerClasses;
+ QString m_hashFunction;
AbstractMetaFunctionCList m_externalConversionOperators;
QStringList m_baseClassNames; // Base class names from C++, including rejected
- TypeEntries m_templateArgs;
- ComplexTypeEntry *m_typeEntry = nullptr;
+ TypeEntryCList m_templateArgs;
+ ComplexTypeEntryPtr m_typeEntry;
SourceLocation m_sourceLocation;
UsingMembers m_usingMembers;
@@ -160,24 +150,6 @@ void AbstractMetaClass::operator-=(AbstractMetaClass::Attribute attribute)
d->m_attributes.setFlag(attribute, false);
}
-/*******************************************************************************
- * Returns true if this class is a subclass of the given class
- */
-bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
-{
- Q_ASSERT(cls);
-
- const AbstractMetaClass *clazz = this;
- while (clazz) {
- if (clazz == cls)
- return true;
-
- clazz = clazz->baseClass();
- }
-
- return false;
-}
-
bool AbstractMetaClass::isPolymorphic() const
{
return d->m_isPolymorphic;
@@ -206,29 +178,16 @@ AbstractMetaFunctionCList AbstractMetaClass::functionsInTargetLang() const
FunctionQueryOptions default_flags = FunctionQueryOption::NormalFunctions
| FunctionQueryOption::Visible | FunctionQueryOption::NotRemoved;
- // Only public functions in final classes
- // default_flags |= isFinal() ? WasPublic : 0;
- FunctionQueryOptions public_flags;
- if (isFinalInTargetLang())
- public_flags |= FunctionQueryOption::WasPublic;
-
// Constructors
- AbstractMetaFunctionCList returned = queryFunctions(FunctionQueryOption::Constructors
- | default_flags | public_flags);
-
- // Final functions
- returned += queryFunctions(FunctionQueryOption::FinalInTargetLangFunctions
- | FunctionQueryOption::NonStaticFunctions
- | default_flags | public_flags);
+ AbstractMetaFunctionCList returned = queryFunctions(FunctionQueryOption::AnyConstructor
+ | default_flags);
- // Virtual functions
- returned += queryFunctions(FunctionQueryOption::VirtualInTargetLangFunctions
- | FunctionQueryOption::NonStaticFunctions
- | default_flags | public_flags);
+ returned += queryFunctions(FunctionQueryOption::NonStaticFunctions
+ | default_flags);
// Static functions
returned += queryFunctions(FunctionQueryOption::StaticFunctions
- | default_flags | public_flags);
+ | default_flags);
// Empty, private functions, since they aren't caught by the other ones
returned += queryFunctions(FunctionQueryOption::Empty | FunctionQueryOption::Invisible);
@@ -238,7 +197,7 @@ AbstractMetaFunctionCList AbstractMetaClass::functionsInTargetLang() const
AbstractMetaFunctionCList AbstractMetaClass::implicitConversions() const
{
- if (!hasCloneOperator() && !hasExternalConversionOperators())
+ if (!isCopyConstructible() && !hasExternalConversionOperators())
return {};
AbstractMetaFunctionCList returned;
@@ -250,7 +209,6 @@ AbstractMetaFunctionCList AbstractMetaClass::implicitConversions() const
for (const auto &f : list) {
if ((f->actualMinimumArgumentCount() == 1 || f->arguments().size() == 1 || f->isConversionOperator())
&& !f->isExplicit()
- && f->functionType() != AbstractMetaFunction::CopyConstructorFunction
&& !f->usesRValueReferences()
&& !f->isModifiedRemoved()
&& f->wasPublic()) {
@@ -348,15 +306,15 @@ bool AbstractMetaClass::hasStaticFields() const
void AbstractMetaClass::sortFunctions()
{
- std::sort(d->m_functions.begin(), d->m_functions.end(), function_sorter);
+ d->sortFunctions();
}
-const AbstractMetaClass *AbstractMetaClass::templateBaseClass() const
+AbstractMetaClassCPtr AbstractMetaClass::templateBaseClass() const
{
return d->m_templateBaseClass;
}
-void AbstractMetaClass::setTemplateBaseClass(const AbstractMetaClass *cls)
+void AbstractMetaClass::setTemplateBaseClass(const AbstractMetaClassCPtr &cls)
{
d->m_templateBaseClass = cls;
}
@@ -366,48 +324,29 @@ const AbstractMetaFunctionCList &AbstractMetaClass::functions() const
return d->m_functions;
}
-void AbstractMetaClass::setFunctions(const AbstractMetaFunctionCList &functions)
-{
- d->m_functions = functions;
-
- // Functions must be sorted by name before next loop
- sortFunctions();
-
- for (const auto &f : qAsConst(d->m_functions)) {
- qSharedPointerConstCast<AbstractMetaFunction>(f)->setOwnerClass(this);
- if (!f->isPublic())
- d->m_hasNonpublic = true;
- }
-}
-
-bool AbstractMetaClass::hasDefaultToStringFunction() const
+const AbstractMetaFunctionCList &AbstractMetaClass::userAddedPythonOverrides() const
{
- const auto &funcs = queryFunctionsByName(QLatin1String("toString"));
- for (const auto &f : funcs) {
- if (!f->actualMinimumArgumentCount())
- return true;
- }
- return false;
+ return d->m_userAddedPythonOverrides;
}
-bool AbstractMetaClass::hasEqualsOperator() const
+void AbstractMetaClassPrivate::sortFunctions()
{
- return d->m_hasEqualsOperator;
+ std::sort(m_functions.begin(), m_functions.end(), function_sorter);
}
-void AbstractMetaClass::setHasEqualsOperator(bool on)
+void AbstractMetaClassPrivate::setFunctions(const AbstractMetaFunctionCList &functions,
+ const AbstractMetaClassCPtr &q)
{
- d->m_hasEqualsOperator = on;
-}
+ m_functions = functions;
-bool AbstractMetaClass::hasCloneOperator() const
-{
- return d->m_hasCloneOperator;
-}
+ // Functions must be sorted by name before next loop
+ sortFunctions();
-void AbstractMetaClass::setHasCloneOperator(bool on)
-{
- d->m_hasCloneOperator = on;
+ for (const auto &f : std::as_const(m_functions)) {
+ std::const_pointer_cast<AbstractMetaFunction>(f)->setOwnerClass(q);
+ if (!f->isPublic())
+ m_hasNonpublic = true;
+ }
}
const QList<QPropertySpec> &AbstractMetaClass::propertySpecs() const
@@ -420,9 +359,16 @@ void AbstractMetaClass::addPropertySpec(const QPropertySpec &spec)
d->m_propertySpecs << spec;
}
+void AbstractMetaClass::setPropertyDocumentation(const QString &name, const Documentation &doc)
+{
+ const auto index = d->indexOfProperty(name);
+ if (index >= 0)
+ d->m_propertySpecs[index].setDocumentation(doc);
+}
+
void AbstractMetaClassPrivate::addFunction(const AbstractMetaFunctionCPtr &function)
{
- Q_ASSERT(!function->signature().startsWith(QLatin1Char('(')));
+ Q_ASSERT(!function->signature().startsWith(u'('));
if (!function->isDestructor())
m_functions << function;
@@ -432,12 +378,31 @@ void AbstractMetaClassPrivate::addFunction(const AbstractMetaFunctionCPtr &funct
m_hasVirtuals |= function->isVirtual();
m_isPolymorphic |= m_hasVirtuals;
m_hasNonpublic |= !function->isPublic();
+ m_hasNonPrivateConstructor |= !function->isPrivate()
+ && function->functionType() == AbstractMetaFunction::ConstructorFunction;
}
-void AbstractMetaClass::addFunction(const AbstractMetaFunctionCPtr &function)
+void AbstractMetaClass::addFunction(const AbstractMetaClassPtr &klass,
+ const AbstractMetaFunctionCPtr &function)
{
- qSharedPointerConstCast<AbstractMetaFunction>(function)->setOwnerClass(this);
- d->addFunction(function);
+ auto nonConstF = std::const_pointer_cast<AbstractMetaFunction>(function);
+ nonConstF->setOwnerClass(klass);
+
+ // Set the default value of the declaring class. This may be changed
+ // in fixFunctions later on
+ nonConstF->setDeclaringClass(klass);
+
+ // Some of the queries below depend on the implementing class being set
+ // to function properly. Such as function modifications
+ nonConstF->setImplementingClass(klass);
+
+ if (function->isUserAddedPythonOverride()) {
+ nonConstF->setConstant(false);
+ nonConstF->setCppAttribute(FunctionAttribute::Static);
+ klass->d->m_userAddedPythonOverrides.append(function);
+ } else {
+ klass->d->addFunction(function);
+ }
}
bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const
@@ -475,32 +440,32 @@ QString AbstractMetaClass::baseClassName() const
}
// Attribute "default-superclass"
-AbstractMetaClass *AbstractMetaClass::defaultSuperclass() const
+AbstractMetaClassCPtr AbstractMetaClass::defaultSuperclass() const
{
return d->m_defaultSuperclass;
}
-void AbstractMetaClass::setDefaultSuperclass(AbstractMetaClass *s)
+void AbstractMetaClass::setDefaultSuperclass(const AbstractMetaClassPtr &s)
{
d->m_defaultSuperclass = s;
}
-AbstractMetaClass *AbstractMetaClass::baseClass() const
+AbstractMetaClassCPtr AbstractMetaClass::baseClass() const
{
return d->m_baseClasses.value(0, nullptr);
}
-const AbstractMetaClassList &AbstractMetaClass::baseClasses() const
+const AbstractMetaClassCList &AbstractMetaClass::baseClasses() const
{
Q_ASSERT(inheritanceDone() || !needsInheritanceSetup());
return d->m_baseClasses;
}
// base classes including "defaultSuperclass".
-AbstractMetaClassList AbstractMetaClass::typeSystemBaseClasses() const
+AbstractMetaClassCList AbstractMetaClass::typeSystemBaseClasses() const
{
- AbstractMetaClassList result = d->m_baseClasses;
- if (d->m_defaultSuperclass != nullptr) {
+ AbstractMetaClassCList result = d->m_baseClasses;
+ if (d->m_defaultSuperclass) {
result.removeAll(d->m_defaultSuperclass);
result.prepend(d->m_defaultSuperclass);
}
@@ -508,25 +473,25 @@ AbstractMetaClassList AbstractMetaClass::typeSystemBaseClasses() const
}
// Recursive list of all base classes including defaultSuperclass
-AbstractMetaClassList AbstractMetaClass::allTypeSystemAncestors() const
+AbstractMetaClassCList AbstractMetaClass::allTypeSystemAncestors() const
{
- AbstractMetaClassList result;
- const AbstractMetaClassList baseClasses = typeSystemBaseClasses();
- for (AbstractMetaClass *base : baseClasses) {
+ AbstractMetaClassCList result;
+ const auto baseClasses = typeSystemBaseClasses();
+ for (const auto &base : baseClasses) {
result.append(base);
result.append(base->allTypeSystemAncestors());
}
return result;
}
-void AbstractMetaClass::addBaseClass(AbstractMetaClass *baseClass)
+void AbstractMetaClass::addBaseClass(const AbstractMetaClassCPtr &baseClass)
{
Q_ASSERT(baseClass);
d->m_baseClasses.append(baseClass);
d->m_isPolymorphic |= baseClass->isPolymorphic();
}
-void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass)
+void AbstractMetaClass::setBaseClass(const AbstractMetaClassCPtr &baseClass)
{
if (baseClass) {
d->m_baseClasses.prepend(baseClass);
@@ -534,27 +499,27 @@ void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass)
}
}
-const AbstractMetaClass *AbstractMetaClass::extendedNamespace() const
+AbstractMetaClassCPtr AbstractMetaClass::extendedNamespace() const
{
return d->m_extendedNamespace;
}
-void AbstractMetaClass::setExtendedNamespace(const AbstractMetaClass *e)
+void AbstractMetaClass::setExtendedNamespace(const AbstractMetaClassCPtr &e)
{
d->m_extendedNamespace = e;
}
-const AbstractMetaClassList &AbstractMetaClass::innerClasses() const
+const AbstractMetaClassCList &AbstractMetaClass::innerClasses() const
{
return d->m_innerClasses;
}
-void AbstractMetaClass::addInnerClass(AbstractMetaClass *cl)
+void AbstractMetaClass::addInnerClass(const AbstractMetaClassPtr &cl)
{
d->m_innerClasses << cl;
}
-void AbstractMetaClass::setInnerClasses(const AbstractMetaClassList &innerClasses)
+void AbstractMetaClass::setInnerClasses(const AbstractMetaClassCList &innerClasses)
{
d->m_innerClasses = innerClasses;
}
@@ -577,19 +542,19 @@ bool AbstractMetaClass::isInvisibleNamespace() const
&& !NamespaceTypeEntry::isVisibleScope(d->m_typeEntry);
}
-static bool qObjectPredicate(const AbstractMetaClass *c)
-{
- return c->qualifiedCppName() == QLatin1String("QObject");
-}
-
-bool AbstractMetaClass::isQObject() const
+bool AbstractMetaClass::isInlineNamespace() const
{
- return qObjectPredicate(this) || recurseClassHierarchy(this, qObjectPredicate) != nullptr;
+ bool result = false;
+ if (d->m_typeEntry->isNamespace()) {
+ const auto nte = std::static_pointer_cast<const NamespaceTypeEntry>(d->m_typeEntry);
+ result = nte->isInlineNamespace();
+ }
+ return result;
}
bool AbstractMetaClass::isQtNamespace() const
{
- return isNamespace() && name() == QLatin1String("Qt");
+ return isNamespace() && name() == u"Qt";
}
QString AbstractMetaClass::qualifiedCppName() const
@@ -599,15 +564,15 @@ QString AbstractMetaClass::qualifiedCppName() const
bool AbstractMetaClass::hasFunction(const QString &str) const
{
- return !findFunction(str).isNull();
+ return bool(findFunction(str));
}
-AbstractMetaFunctionCPtr AbstractMetaClass::findFunction(const QString &functionName) const
+AbstractMetaFunctionCPtr AbstractMetaClass::findFunction(QAnyStringView functionName) const
{
return AbstractMetaFunction::find(d->m_functions, functionName);
}
-AbstractMetaFunctionCList AbstractMetaClass::findFunctions(const QString &functionName) const
+AbstractMetaFunctionCList AbstractMetaClass::findFunctions(QAnyStringView functionName) const
{
AbstractMetaFunctionCList result;
std::copy_if(d->m_functions.cbegin(), d->m_functions.cend(),
@@ -640,15 +605,6 @@ AbstractMetaFunctionCPtr AbstractMetaClass::findQtIsNullMethod() const
return *it;
}
-bool AbstractMetaClass::hasProtectedFunctions() const
-{
- for (const auto &func : d->m_functions) {
- if (func->isProtected())
- return true;
- }
- return false;
-}
-
bool AbstractMetaClass::hasProtectedFields() const
{
for (const AbstractMetaField &field : d->m_fields) {
@@ -658,17 +614,12 @@ bool AbstractMetaClass::hasProtectedFields() const
return false;
}
-bool AbstractMetaClass::hasProtectedMembers() const
-{
- return hasProtectedFields() || hasProtectedFunctions();
-}
-
-const TypeEntries &AbstractMetaClass::templateArguments() const
+const TypeEntryCList &AbstractMetaClass::templateArguments() const
{
return d->m_templateArgs;
}
-void AbstractMetaClass::setTemplateArguments(const TypeEntries &args)
+void AbstractMetaClass::setTemplateArguments(const TypeEntryCList &args)
{
d->m_templateArgs = args;
}
@@ -683,36 +634,41 @@ void AbstractMetaClass::setBaseClassNames(const QStringList &names)
d->m_baseClassNames = names;
}
-const ComplexTypeEntry *AbstractMetaClass::typeEntry() const
+ComplexTypeEntryCPtr AbstractMetaClass::typeEntry() const
{
return d->m_typeEntry;
}
-ComplexTypeEntry *AbstractMetaClass::typeEntry()
+ComplexTypeEntryPtr AbstractMetaClass::typeEntry()
{
return d->m_typeEntry;
}
-void AbstractMetaClass::setTypeEntry(ComplexTypeEntry *type)
+void AbstractMetaClass::setTypeEntry(const ComplexTypeEntryPtr &type)
{
d->m_typeEntry = type;
}
-void AbstractMetaClass::setHasHashFunction(bool on)
+QString AbstractMetaClass::hashFunction() const
{
- d->m_hasHashFunction = on;
+ return d->m_hashFunction;
+}
+
+void AbstractMetaClass::setHashFunction(const QString &f)
+{
+ d->m_hashFunction = f;
}
bool AbstractMetaClass::hasHashFunction() const
{
- return d->m_hasHashFunction;
+ return !d->m_hashFunction.isEmpty();
}
// Search whether a functions is a property setter/getter/reset
AbstractMetaClass::PropertyFunctionSearchResult
AbstractMetaClass::searchPropertyFunction(const QString &name) const
{
- for (int i = 0, size = d->m_propertySpecs.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = d->m_propertySpecs.size(); i < size; ++i) {
const auto &propertySpec = d->m_propertySpecs.at(i);
if (name == propertySpec.read())
return PropertyFunctionSearchResult{i, PropertyFunction::Read};
@@ -720,6 +676,8 @@ AbstractMetaClass::PropertyFunctionSearchResult
return PropertyFunctionSearchResult{i, PropertyFunction::Write};
if (name == propertySpec.reset())
return PropertyFunctionSearchResult{i, PropertyFunction::Reset};
+ if (name == propertySpec.notify())
+ return PropertyFunctionSearchResult{i, PropertyFunction::Notify};
}
return PropertyFunctionSearchResult{-1, PropertyFunction::Read};
}
@@ -727,10 +685,9 @@ AbstractMetaClass::PropertyFunctionSearchResult
std::optional<QPropertySpec>
AbstractMetaClass::propertySpecByName(const QString &name) const
{
- for (const auto &propertySpec : d->m_propertySpecs) {
- if (name == propertySpec.name())
- return propertySpec;
- }
+ const auto index = d->indexOfProperty(name);
+ if (index >= 0)
+ return d->m_propertySpecs.at(index);
return {};
}
@@ -812,7 +769,16 @@ bool AbstractMetaClass::deleteInMainThread() const
bool AbstractMetaClassPrivate::hasConstructors() const
{
return AbstractMetaClass::queryFirstFunction(m_functions,
- FunctionQueryOption::Constructors) != nullptr;
+ FunctionQueryOption::AnyConstructor) != nullptr;
+}
+
+qsizetype AbstractMetaClassPrivate::indexOfProperty(const QString &name) const
+{
+ for (qsizetype i = 0; i < m_propertySpecs.size(); ++i) {
+ if (m_propertySpecs.at(i).name() == name)
+ return i;
+ }
+ return -1;
}
bool AbstractMetaClass::hasConstructors() const
@@ -837,51 +803,95 @@ bool AbstractMetaClass::hasCopyConstructor() const
bool AbstractMetaClass::hasPrivateCopyConstructor() const
{
const auto copyCt = copyConstructor();
- return !copyCt.isNull() && copyCt->isPrivate();
+ return copyCt && copyCt->isPrivate();
}
void AbstractMetaClassPrivate::addConstructor(AbstractMetaFunction::FunctionType t,
Access access,
const AbstractMetaArgumentList &arguments,
- AbstractMetaClass *q)
+ const AbstractMetaClassPtr &q)
{
- auto *f = new AbstractMetaFunction;
- f->setType(AbstractMetaType::createVoid());
- f->setOriginalName(q->name());
- f->setName(q->name());
- f->setOwnerClass(q);
- f->setFunctionType(t);
- f->setArguments(arguments);
- f->setDeclaringClass(q);
- f->setAccess(access);
+ auto *f = createFunction(q->name(), t, access, arguments, AbstractMetaType::createVoid(), q);
if (access != Access::Private)
m_hasNonPrivateConstructor = true;
- f->setAttributes(AbstractMetaFunction::FinalInTargetLang
- | AbstractMetaFunction::AddedMethod);
- f->setImplementingClass(q);
-
+ f->setAttributes(AbstractMetaFunction::AddedMethod);
addFunction(AbstractMetaFunctionCPtr(f));
}
-void AbstractMetaClass::addDefaultConstructor()
+void AbstractMetaClass::addDefaultConstructor(const AbstractMetaClassPtr &klass)
{
- d->addConstructor(AbstractMetaFunction::ConstructorFunction,
- Access::Public, {}, this);
+ klass->d->addConstructor(AbstractMetaFunction::ConstructorFunction,
+ Access::Public, {}, klass);
}
-void AbstractMetaClass::addDefaultCopyConstructor()
+void AbstractMetaClass::addDefaultCopyConstructor(const AbstractMetaClassPtr &klass)
{
- AbstractMetaType argType(typeEntry());
+ AbstractMetaType argType(klass->typeEntry());
argType.setReferenceType(LValueReference);
argType.setConstant(true);
argType.setTypeUsagePattern(AbstractMetaType::ValuePattern);
AbstractMetaArgument arg;
arg.setType(argType);
- arg.setName(name());
+ arg.setName(klass->name());
+
+ klass->d->addConstructor(AbstractMetaFunction::CopyConstructorFunction,
+ Access::Public, {arg}, klass);
+}
+
+AbstractMetaFunction *
+ AbstractMetaClassPrivate::createFunction(const QString &name,
+ AbstractMetaFunction::FunctionType t,
+ Access access,
+ const AbstractMetaArgumentList &arguments,
+ const AbstractMetaType &returnType,
+ const AbstractMetaClassPtr &q)
+{
+ auto *f = new AbstractMetaFunction(name);
+ f->setType(returnType);
+ f->setOwnerClass(q);
+ f->setFunctionType(t);
+ f->setArguments(arguments);
+ f->setDeclaringClass(q);
+ f->setAccess(access);
+ f->setImplementingClass(q);
+ return f;
+}
- d->addConstructor(AbstractMetaFunction::CopyConstructorFunction,
- Access::Public, {arg}, this);
+static AbstractMetaType boolType()
+{
+ auto boolType = TypeDatabase::instance()->findType(u"bool"_s);
+ Q_ASSERT(boolType);
+ AbstractMetaType result(boolType);
+ result.decideUsagePattern();
+ return result;
+}
+
+// Helper to synthesize comparison operators from a spaceship operator. Since
+// shiboken also generates code for comparing to different types, this fits
+// better than of handling it in the generator code.
+void AbstractMetaClass::addSynthesizedComparisonOperators(const AbstractMetaClassPtr &c)
+{
+ static const auto returnType = boolType();
+
+ AbstractMetaType selfType(c->typeEntry());
+ selfType.setConstant(true);
+ selfType.setReferenceType(LValueReference);
+ selfType.decideUsagePattern();
+ AbstractMetaArgument selfArgument;
+ selfArgument.setType(selfType);
+ selfArgument.setName(u"rhs"_s);
+ AbstractMetaArgumentList arguments(1, selfArgument);
+
+ static const char *operators[]
+ = {"operator==", "operator!=", "operator<", "operator<=", "operator>", "operator>="};
+ for (auto *op : operators) {
+ auto *f = AbstractMetaClassPrivate::createFunction(QLatin1StringView(op),
+ AbstractMetaFunction::ComparisonOperator,
+ Access::Public, arguments,
+ returnType, c);
+ c->d->addFunction(AbstractMetaFunctionCPtr(f));
+ }
}
bool AbstractMetaClass::hasNonPrivateConstructor() const
@@ -974,6 +984,8 @@ bool AbstractMetaClass::isDefaultConstructible() const
// (non-ref or not const value).
static bool defaultConstructibleField(const AbstractMetaField &f)
{
+ if (f.isStatic())
+ return true;
const auto &type = f.type();
return type.referenceType() == NoReference
&& !(type.indirections() == 0 && type.isConstant()); // no const values
@@ -984,7 +996,7 @@ bool AbstractMetaClass::isImplicitlyDefaultConstructible() const
return std::all_of(d->m_fields.cbegin(), d->m_fields.cend(),
defaultConstructibleField)
&& std::all_of(d->m_baseClasses.cbegin(), d->m_baseClasses.cend(),
- [] (const AbstractMetaClass *c) {
+ [] (const AbstractMetaClassCPtr &c) {
return c->isDefaultConstructible();
});
}
@@ -992,6 +1004,7 @@ bool AbstractMetaClass::isImplicitlyDefaultConstructible() const
static bool canAddDefaultConstructorHelper(const AbstractMetaClass *cls)
{
return !cls->isNamespace()
+ && !cls->hasDeletedDefaultConstructor()
&& !cls->attributes().testFlag(AbstractMetaClass::HasRejectedConstructor)
&& !cls->hasPrivateDestructor();
}
@@ -1018,7 +1031,7 @@ bool AbstractMetaClass::isImplicitlyCopyConstructible() const
{
// Fields are currently not considered
return std::all_of(d->m_baseClasses.cbegin(), d->m_baseClasses.cend(),
- [] (const AbstractMetaClass *c) {
+ [] (const AbstractMetaClassCPtr &c) {
return c->isCopyConstructible();
});
}
@@ -1033,6 +1046,21 @@ bool AbstractMetaClass::canAddDefaultCopyConstructor() const
return isImplicitlyCopyConstructible();
}
+static bool classHasParentManagement(const AbstractMetaClassCPtr &c)
+{
+ const auto flags = c->typeEntry()->typeFlags();
+ return flags.testFlag(ComplexTypeEntry::ParentManagement);
+}
+
+TypeEntryCPtr parentManagementEntry(const AbstractMetaClassCPtr &klass)
+{
+ if (klass->typeEntry()->isObject()) {
+ if (auto c = recurseClassHierarchy(klass, classHasParentManagement))
+ return c->typeEntry();
+ }
+ return nullptr;
+}
+
bool AbstractMetaClass::generateExceptionHandling() const
{
return queryFirstFunction(d->m_functions, FunctionQueryOption::Visible
@@ -1097,7 +1125,7 @@ void AbstractMetaClass::addUsingMember(const UsingMember &um)
d->m_usingMembers.append(um);
}
-bool AbstractMetaClassPrivate::isUsingMember(const AbstractMetaClass *c,
+bool AbstractMetaClassPrivate::isUsingMember(const AbstractMetaClassCPtr &c,
const QString &memberName,
Access minimumAccess) const
{
@@ -1108,13 +1136,21 @@ bool AbstractMetaClassPrivate::isUsingMember(const AbstractMetaClass *c,
return it != m_usingMembers.cend() && it->access >= minimumAccess;
}
-bool AbstractMetaClass::isUsingMember(const AbstractMetaClass *c,
+bool AbstractMetaClass::isUsingMember(const AbstractMetaClassCPtr &c,
const QString &memberName,
Access minimumAccess) const
{
return d->isUsingMember(c, memberName, minimumAccess);
}
+bool AbstractMetaClass::hasUsingMemberFor(const QString &memberName) const
+{
+ return std::any_of(d->m_usingMembers.cbegin(), d->m_usingMembers.cend(),
+ [&memberName](const UsingMember &um) {
+ return um.memberName == memberName;
+ });
+}
+
/* Goes through the list of functions and returns a list of all
functions matching all of the criteria in \a query.
*/
@@ -1131,35 +1167,32 @@ bool AbstractMetaClass::queryFunction(const AbstractMetaFunction *f, FunctionQue
if (query.testFlag(FunctionQueryOption::Visible) && f->isPrivate())
return false;
- if (query.testFlag(FunctionQueryOption::VirtualInTargetLangFunctions) && f->isFinalInTargetLang())
- return false;
-
if (query.testFlag(FunctionQueryOption::Invisible) && !f->isPrivate())
return false;
if (query.testFlag(FunctionQueryOption::Empty) && !f->isEmptyFunction())
return false;
- if (query.testFlag(FunctionQueryOption::WasPublic) && !f->wasPublic())
- return false;
-
if (query.testFlag(FunctionQueryOption::ClassImplements) && f->ownerClass() != f->implementingClass())
return false;
- if (query.testFlag(FunctionQueryOption::FinalInTargetLangFunctions) && !f->isFinalInTargetLang())
- return false;
-
if (query.testFlag(FunctionQueryOption::VirtualInCppFunctions) && !f->isVirtual())
return false;
if (query.testFlag(FunctionQueryOption::Signals) && (!f->isSignal()))
return false;
- if (query.testFlag(FunctionQueryOption::Constructors)
+ if (query.testFlag(FunctionQueryOption::AnyConstructor)
&& (!f->isConstructor() || f->ownerClass() != f->implementingClass())) {
return false;
}
+ if (query.testFlag(FunctionQueryOption::Constructors)
+ && (f->functionType() != AbstractMetaFunction::ConstructorFunction
+ || f->ownerClass() != f->implementingClass())) {
+ return false;
+ }
+
if (query.testFlag(FunctionQueryOption::CopyConstructor)
&& (!f->isCopyConstructor() || f->ownerClass() != f->implementingClass())) {
return false;
@@ -1206,7 +1239,7 @@ AbstractMetaFunctionCList AbstractMetaClass::queryFunctionList(const AbstractMet
{
AbstractMetaFunctionCList result;
for (const auto &f : list) {
- if (queryFunction(f.data(), query))
+ if (queryFunction(f.get(), query))
result.append(f);
}
return result;
@@ -1216,7 +1249,7 @@ AbstractMetaFunctionCPtr AbstractMetaClass::queryFirstFunction(const AbstractMet
FunctionQueryOptions query)
{
for (const auto &f : list) {
- if (queryFunction(f.data(), query))
+ if (queryFunction(f.get(), query))
return f;
}
return {};
@@ -1243,7 +1276,7 @@ AbstractMetaFunctionCList AbstractMetaClass::cppSignalFunctions() const
}
std::optional<AbstractMetaField>
- AbstractMetaClass::findField(const QString &name) const
+ AbstractMetaClass::findField(QStringView name) const
{
return AbstractMetaField::find(d->m_fields, name);
}
@@ -1284,7 +1317,7 @@ std::optional<AbstractMetaEnum>
std::optional<AbstractMetaEnumValue>
AbstractMetaClass::findEnumValue(const QString &enumValueName) const
{
- for (const AbstractMetaEnum &e : qAsConst(d->m_enums)) {
+ for (const AbstractMetaEnum &e : std::as_const(d->m_enums)) {
auto v = e.findEnumValue(enumValueName);
if (v.has_value())
return v;
@@ -1306,7 +1339,7 @@ void AbstractMetaClass::getEnumsToBeGenerated(AbstractMetaEnumList *enumList) co
void AbstractMetaClass::getEnumsFromInvisibleNamespacesToBeGenerated(AbstractMetaEnumList *enumList) const
{
if (isNamespace()) {
- invisibleNamespaceRecursion([enumList](AbstractMetaClass *c) {
+ invisibleNamespaceRecursion([enumList](const AbstractMetaClassCPtr &c) {
c->getEnumsToBeGenerated(enumList);
});
}
@@ -1315,7 +1348,7 @@ void AbstractMetaClass::getEnumsFromInvisibleNamespacesToBeGenerated(AbstractMet
void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(AbstractMetaFunctionCList *funcList) const
{
if (isNamespace()) {
- invisibleNamespaceRecursion([funcList](AbstractMetaClass *c) {
+ invisibleNamespaceRecursion([funcList](const AbstractMetaClassCPtr &c) {
funcList->append(c->functions());
});
}
@@ -1323,19 +1356,19 @@ void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(Abstrac
QString AbstractMetaClass::fullName() const
{
- return package() + QLatin1Char('.') + d->m_typeEntry->targetLangName();
+ return package() + u'.' + d->m_typeEntry->targetLangName();
}
-static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType &type)
+static void addExtraIncludeForType(const AbstractMetaClassPtr &metaClass,
+ const AbstractMetaType &type)
{
Q_ASSERT(metaClass);
- const TypeEntry *entry = type.typeEntry();
- if (entry && entry->isComplex()) {
- const auto *centry = static_cast<const ComplexTypeEntry *>(entry);
- ComplexTypeEntry *class_entry = metaClass->typeEntry();
- if (class_entry && centry->include().isValid())
- class_entry->addExtraInclude(centry->include());
+ const auto entry = type.typeEntry();
+
+ if (entry && entry->include().isValid()) {
+ const auto class_entry = metaClass->typeEntry();
+ class_entry->addArgumentInclude(entry->include());
}
if (type.hasInstantiations()) {
@@ -1344,7 +1377,7 @@ static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractM
}
}
-static void addExtraIncludesForFunction(AbstractMetaClass *metaClass,
+static void addExtraIncludesForFunction(const AbstractMetaClassPtr &metaClass,
const AbstractMetaFunctionCPtr &meta_function)
{
Q_ASSERT(metaClass);
@@ -1352,8 +1385,12 @@ static void addExtraIncludesForFunction(AbstractMetaClass *metaClass,
addExtraIncludeForType(metaClass, meta_function->type());
const AbstractMetaArgumentList &arguments = meta_function->arguments();
- for (const AbstractMetaArgument &argument : arguments)
- addExtraIncludeForType(metaClass, argument.type());
+ for (const AbstractMetaArgument &argument : arguments) {
+ const auto &type = argument.type();
+ addExtraIncludeForType(metaClass, type);
+ if (argument.modifiedType() != type)
+ addExtraIncludeForType(metaClass, argument.modifiedType());
+ }
}
static bool addSuperFunction(const AbstractMetaFunctionCPtr &f)
@@ -1375,7 +1412,7 @@ static bool addSuperFunction(const AbstractMetaFunctionCPtr &f)
// Add constructors imported via "using" from the base classes. This is not
// needed for normal hidden inherited member functions since we generate a
// cast to the base class to call them into binding code.
-void AbstractMetaClassPrivate::addUsingConstructors(AbstractMetaClass *q)
+void AbstractMetaClassPrivate::addUsingConstructors(const AbstractMetaClassPtr &q)
{
// Restricted to the non-constructor case currently to avoid
// having to compare the parameter lists of existing constructors.
@@ -1384,14 +1421,13 @@ void AbstractMetaClassPrivate::addUsingConstructors(AbstractMetaClass *q)
return;
}
- for (auto superClass : m_baseClasses) {
+ for (const auto &superClass : m_baseClasses) {
// Find any "using base-constructor" directives
if (isUsingMember(superClass, superClass->name(), Access::Protected)) {
// Add to derived class with parameter lists.
const auto ctors = superClass->queryFunctions(FunctionQueryOption::Constructors);
for (const auto &ctor : ctors) {
- if (ctor->functionType() == AbstractMetaFunction::ConstructorFunction
- && !ctor->isPrivate()) {
+ if (!ctor->isPrivate()) {
addConstructor(AbstractMetaFunction::ConstructorFunction,
ctor->access(), ctor->arguments(), q);
}
@@ -1400,50 +1436,61 @@ void AbstractMetaClassPrivate::addUsingConstructors(AbstractMetaClass *q)
}
}
-void AbstractMetaClass::fixFunctions()
+static inline bool isSignal(const AbstractMetaFunctionCPtr &f)
+{
+ return f->isSignal();
+}
+
+void AbstractMetaClass::fixFunctions(const AbstractMetaClassPtr &klass)
{
+ auto *d = klass->d.data();
if (d->m_functionsFixed)
return;
d->m_functionsFixed = true;
- AbstractMetaFunctionCList funcs = functions();
+ AbstractMetaFunctionCList funcs = klass->functions();
AbstractMetaFunctionCList nonRemovedFuncs;
nonRemovedFuncs.reserve(funcs.size());
- d->addUsingConstructors(this);
+ d->addUsingConstructors(klass);
- for (const auto &f : qAsConst(funcs)) {
+ for (const auto &f : std::as_const(funcs)) {
// Fishy: Setting up of implementing/declaring/base classes changes
// the applicable modifications; clear cached ones.
- qSharedPointerConstCast<AbstractMetaFunction>(f)->clearModificationsCache();
+ std::const_pointer_cast<AbstractMetaFunction>(f)->clearModificationsCache();
if (!f->isModifiedRemoved())
nonRemovedFuncs.append(f);
}
- for (auto superClass : d->m_baseClasses) {
- superClass->fixFunctions();
+ for (const auto &superClassC : d->m_baseClasses) {
+ for (const auto &pof : superClassC->userAddedPythonOverrides()) {
+ auto *clonedPof = pof->copy();
+ clonedPof->setOwnerClass(klass);
+ d->m_userAddedPythonOverrides.append(AbstractMetaFunctionCPtr{clonedPof});
+ }
+
+ auto superClass = std::const_pointer_cast<AbstractMetaClass>(superClassC);
+ AbstractMetaClass::fixFunctions(superClass);
// Since we always traverse the complete hierarchy we are only
// interrested in what each super class implements, not what
// we may have propagated from their base classes again.
AbstractMetaFunctionCList superFuncs;
- // Super classes can never be final
- if (superClass->isFinalInTargetLang()) {
- qCWarning(lcShiboken).noquote().nospace()
- << "Final class '" << superClass->name() << "' set to non-final, as it is extended by other classes";
- *superClass -= AbstractMetaClass::FinalInTargetLang;
- }
superFuncs = superClass->queryFunctions(FunctionQueryOption::ClassImplements);
+ // We are not interested in signals as no bindings are generated for them;
+ // they cause documentation warnings.
+ superFuncs.erase(std::remove_if(superFuncs.begin(), superFuncs.end(), isSignal),
+ superFuncs.end());
const auto virtuals = superClass->queryFunctions(FunctionQueryOption::VirtualInCppFunctions);
superFuncs += virtuals;
QSet<AbstractMetaFunctionCPtr> funcsToAdd;
- for (const auto &sf : qAsConst(superFuncs)) {
+ for (const auto &sf : std::as_const(superFuncs)) {
if (sf->isModifiedRemoved())
continue;
// skip functions added in base classes
- if (sf->isUserAdded() && sf->declaringClass() != this)
+ if (sf->isUserAdded() && sf->declaringClass() != klass)
continue;
// Skip base class comparison operators declared as members (free
@@ -1454,35 +1501,25 @@ void AbstractMetaClass::fixFunctions()
// we generally don't care about private functions, but we have to get the ones that are
// virtual in case they override abstract functions.
bool add = addSuperFunction(sf);
- for (const auto &cf : qAsConst(nonRemovedFuncs)) {
- AbstractMetaFunctionPtr f(qSharedPointerConstCast<AbstractMetaFunction>(cf));
- const AbstractMetaFunction::CompareResult cmp = cf->compareTo(sf.data());
+ for (const auto &cf : std::as_const(nonRemovedFuncs)) {
+ AbstractMetaFunctionPtr f(std::const_pointer_cast<AbstractMetaFunction>(cf));
+ const AbstractMetaFunction::CompareResult cmp = cf->compareTo(sf.get());
if (cmp & AbstractMetaFunction::EqualModifiedName) {
add = false;
if (cmp & AbstractMetaFunction::EqualArguments) {
- // Same function, propegate virtual...
- if (!(cmp & AbstractMetaFunction::EqualAttributes)) {
- if (!f->isEmptyFunction()) {
- if (!sf->isFinalInTargetLang() && f->isFinalInTargetLang()) {
- *f -= AbstractMetaFunction::FinalInTargetLang;
- }
-#if 0
- if (!f->isFinalInTargetLang() && f->isPrivate()) {
- f->setFunctionType(AbstractMetaFunction::EmptyFunction);
- f->setVisibility(AbstractMetaAttributes::Protected);
- *f += AbstractMetaAttributes::FinalInTargetLang;
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("private virtual function '%1' in '%2'")
- .arg(f->signature(), f->implementingClass()->name());
- }
-#endif
- }
+ // Set "override" in case it was not spelled out (since it
+ // is then not detected by clang parsing).
+ const auto attributes = cf->cppAttributes();
+ if (attributes.testFlag(FunctionAttribute::Virtual)
+ && !attributes.testFlag(FunctionAttribute::Override)
+ && !attributes.testFlag(FunctionAttribute::Final)) {
+ f->setCppAttribute(FunctionAttribute::Override);
}
if (f->access() != sf->access()) {
qCWarning(lcShiboken, "%s",
- qPrintable(msgFunctionVisibilityModified(this, f.data())));
+ qPrintable(msgFunctionVisibilityModified(klass, f.get())));
#if 0
// If new visibility is private, we can't
// do anything. If it isn't, then we
@@ -1494,43 +1531,12 @@ void AbstractMetaClass::fixFunctions()
// Private overrides of abstract functions have to go into the class or
// the subclasses will not compile as non-abstract classes.
// But they don't need to be implemented, since they can never be called.
- if (f->isPrivate()) {
+ if (f->isPrivate())
f->setFunctionType(AbstractMetaFunction::EmptyFunction);
- *f += AbstractMetaFunction::FinalInTargetLang;
- }
}
// Set the class which first declares this function, afawk
f->setDeclaringClass(sf->declaringClass());
-
- if (sf->isFinalInTargetLang() && !sf->isPrivate() && !f->isPrivate() && !sf->isStatic() && !f->isStatic()) {
- // Shadowed funcion, need to make base class
- // function non-virtual
- if (f->implementingClass() != sf->implementingClass() && f->implementingClass()->inheritsFrom(sf->implementingClass())) {
-
- // Check whether the superclass method has been redefined to non-final
-
- bool hasNonFinalModifier = false;
- bool isBaseImplPrivate = false;
- const FunctionModificationList &mods = sf->modifications(sf->implementingClass());
- for (const FunctionModification &mod : mods) {
- if (mod.isNonFinal()) {
- hasNonFinalModifier = true;
- break;
- }
- if (mod.isPrivate()) {
- isBaseImplPrivate = true;
- break;
- }
- }
-
- if (!hasNonFinalModifier && !isBaseImplPrivate) {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgShadowingFunction(sf.data(), f.data())));
- }
- }
- }
-
}
if (cmp & AbstractMetaFunction::EqualDefaultValueOverload) {
@@ -1558,7 +1564,7 @@ void AbstractMetaClass::fixFunctions()
funcsToAdd << sf;
}
- for (const auto &f : qAsConst(funcsToAdd)) {
+ for (const auto &f : std::as_const(funcsToAdd)) {
AbstractMetaFunction *copy = f->copy();
(*copy) += AbstractMetaFunction::AddedMethod;
funcs.append(AbstractMetaFunctionCPtr(copy));
@@ -1567,16 +1573,19 @@ void AbstractMetaClass::fixFunctions()
bool hasPrivateConstructors = false;
bool hasPublicConstructors = false;
- for (const auto &func : qAsConst(funcs)) {
- for (const auto &mod : func->modifications(this)) {
+ // Apply modifications after the declaring class has been set
+ for (const auto &func : std::as_const(funcs)) {
+ auto ncFunc = std::const_pointer_cast<AbstractMetaFunction>(func);
+ for (const auto &mod : func->modifications(klass)) {
if (mod.isRenameModifier())
- qSharedPointerConstCast<AbstractMetaFunction>(func)->setName(mod.renamedToName());
+ ncFunc->setName(mod.renamedToName());
}
+ ncFunc->applyTypeModifications();
// Make sure class is abstract if one of the functions is
if (func->isAbstract()) {
- (*this) += AbstractMetaClass::Abstract;
- (*this) -= AbstractMetaClass::FinalInTargetLang;
+ (*klass) += AbstractMetaClass::Abstract;
+ (*klass) -= AbstractMetaClass::FinalInTargetLang;
}
if (func->isConstructor()) {
@@ -1589,15 +1598,15 @@ void AbstractMetaClass::fixFunctions()
// Make sure that we include files for all classes that are in use
- addExtraIncludesForFunction(this, func);
+ addExtraIncludesForFunction(klass, func);
}
if (hasPrivateConstructors && !hasPublicConstructors) {
- (*this) += AbstractMetaClass::Abstract;
- (*this) -= AbstractMetaClass::FinalInTargetLang;
+ (*klass) += AbstractMetaClass::Abstract;
+ (*klass) -= AbstractMetaClass::FinalInTargetLang;
}
- setFunctions(funcs);
+ d->setFunctions(funcs, klass);
}
bool AbstractMetaClass::needsInheritanceSetup() const
@@ -1606,6 +1615,7 @@ bool AbstractMetaClass::needsInheritanceSetup() const
switch (d->m_typeEntry->type()) {
case TypeEntry::NamespaceType:
case TypeEntry::SmartPointerType:
+ case TypeEntry::ContainerType:
return false;
default:
break;
@@ -1628,26 +1638,6 @@ bool AbstractMetaClass::inheritanceDone() const
* Other stuff...
*/
-
-std::optional<AbstractMetaEnum>
- AbstractMetaClass::findEnum(const AbstractMetaClassList &classes,
- const EnumTypeEntry *entry)
-{
- Q_ASSERT(entry->isEnum());
-
- auto scopeEntry = entry->parent();
- AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes, scopeEntry);
- if (!metaClass) {
- qCWarning(lcShiboken, "%s", qPrintable(msgClassOfEnumNotFound(entry)));
- return {};
- }
-
- QString qualifiedName = entry->qualifiedCppName();
- const int pos = qualifiedName.lastIndexOf(QLatin1String("::"));
- const QString enumName = pos > 0 ? qualifiedName.mid(pos + 2) : qualifiedName;
- return metaClass->findEnum(enumName);
-}
-
std::optional<AbstractMetaEnumValue>
AbstractMetaClass::findEnumValue(const AbstractMetaClassList &classes,
const QString &name)
@@ -1657,11 +1647,11 @@ std::optional<AbstractMetaEnumValue>
if (lst.size() > 1) {
const auto &prefixName = lst.at(0);
const auto &enumName = lst.at(1);
- if (AbstractMetaClass *cl = findClass(classes, prefixName.toString()))
+ if (auto cl = findClass(classes, prefixName))
return cl->findEnumValue(enumName.toString());
}
- for (AbstractMetaClass *metaClass : classes) {
+ for (const auto &metaClass : classes) {
auto enumValue = metaClass->findEnumValue(name);
if (enumValue.has_value())
return enumValue;
@@ -1675,12 +1665,12 @@ std::optional<AbstractMetaEnumValue>
/// Target language base name or complete Target language package.class name.
template <class It>
-static It findClassHelper(It begin, It end, const QString &name)
+static It findClassHelper(It begin, It end, QAnyStringView name)
{
if (name.isEmpty() || begin == end)
return end;
- if (name.contains(u'.')) { // Search target lang name
+ if (asv_contains(name,'.')) { // Search target lang name
for (auto it = begin; it != end; ++it) {
if ((*it)->fullName() == name)
return it;
@@ -1693,7 +1683,7 @@ static It findClassHelper(It begin, It end, const QString &name)
return it;
}
- if (name.contains(u"::")) // Qualified, cannot possibly match name
+ if (asv_contains(name, "::")) // Qualified, cannot possibly match name
return end;
for (auto it = begin; it != end; ++it) {
@@ -1704,32 +1694,32 @@ static It findClassHelper(It begin, It end, const QString &name)
return end;
}
-AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
- const QString &name)
+AbstractMetaClassPtr AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
+ QAnyStringView name)
{
auto it =findClassHelper(classes.cbegin(), classes.cend(), name);
return it != classes.cend() ? *it : nullptr;
}
-const AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
- const QString &name)
+AbstractMetaClassCPtr AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
+ QAnyStringView name)
{
auto it = findClassHelper(classes.cbegin(), classes.cend(), name);
return it != classes.cend() ? *it : nullptr;
}
-AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
- const TypeEntry *typeEntry)
+AbstractMetaClassPtr AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
+ const TypeEntryCPtr &typeEntry)
{
- for (AbstractMetaClass *c : classes) {
+ for (AbstractMetaClassPtr c : classes) {
if (c->typeEntry() == typeEntry)
return c;
}
return nullptr;
}
-const AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
- const TypeEntry *typeEntry)
+AbstractMetaClassCPtr AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
+ const TypeEntryCPtr &typeEntry)
{
for (auto c : classes) {
if (c->typeEntry() == typeEntry)
@@ -1738,13 +1728,42 @@ const AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassCLi
return nullptr;
}
-const AbstractMetaClass *AbstractMetaClass::findBaseClass(const QString &qualifiedName) const
+/// Returns true if this class is a subclass of the given class
+bool inheritsFrom(const AbstractMetaClassCPtr &c, const AbstractMetaClassCPtr &cls)
{
- if (d->m_templateBaseClass != nullptr
- && d->m_templateBaseClass->qualifiedCppName() == qualifiedName) {
- return d->m_templateBaseClass;
+ Q_ASSERT(cls != nullptr);
+
+ if (c == cls || c->templateBaseClass() == cls)
+ return true;
+
+ return bool(recurseClassHierarchy(c, [cls](const AbstractMetaClassCPtr &c) {
+ return cls.get() == c.get();
+ }));
+}
+
+bool inheritsFrom(const AbstractMetaClassCPtr &c, QAnyStringView name)
+{
+ if (c->qualifiedCppName() == name)
+ return true;
+
+ if (c->templateBaseClass() != nullptr
+ && c->templateBaseClass()->qualifiedCppName() == name) {
+ return true;
}
- return recurseClassHierarchy(this, [&qualifiedName](const AbstractMetaClass *c) {
+
+ return bool(recurseClassHierarchy(c, [&name](const AbstractMetaClassCPtr &c) {
+ return c->qualifiedCppName() == name;
+ }));
+}
+
+AbstractMetaClassCPtr findBaseClass(const AbstractMetaClassCPtr &c,
+ const QString &qualifiedName)
+{
+ auto tp = c->templateBaseClass();
+ if (tp && tp->qualifiedCppName() == qualifiedName)
+ return tp;
+
+ return recurseClassHierarchy(c, [&qualifiedName](const AbstractMetaClassCPtr &c) {
return c->qualifiedCppName() == qualifiedName;
});
}
@@ -1761,21 +1780,35 @@ bool AbstractMetaClass::isCopyable() const
return false;
auto copyable = d->m_typeEntry->copyable();
return copyable == ComplexTypeEntry::CopyableSet
- || (copyable == ComplexTypeEntry::Unknown && hasCloneOperator());
+ || (copyable == ComplexTypeEntry::Unknown && isCopyConstructible());
}
bool AbstractMetaClass::isValueTypeWithCopyConstructorOnly() const
{
- if (!typeEntry()->isValue())
+ return d->m_valueTypeWithCopyConstructorOnly;
+}
+
+void AbstractMetaClass::setValueTypeWithCopyConstructorOnly(bool v)
+{
+ d->m_valueTypeWithCopyConstructorOnly = v;
+}
+
+bool AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(const AbstractMetaClassCPtr &c,
+ bool avoidProtectedHack)
+{
+
+ if (!c->typeEntry()->isValue())
return false;
- if (attributes().testFlag(AbstractMetaClass::HasRejectedDefaultConstructor))
+ if (c->attributes().testFlag(AbstractMetaClass::HasRejectedDefaultConstructor))
return false;
- const auto ctors = queryFunctions(FunctionQueryOption::Constructors);
+ const auto ctors = c->queryFunctions(FunctionQueryOption::AnyConstructor);
bool copyConstructorFound = false;
for (const auto &ctor : ctors) {
switch (ctor->functionType()) {
case AbstractMetaFunction::ConstructorFunction:
- return false;
+ if (!ctor->isPrivate() && (ctor->isPublic() || !avoidProtectedHack))
+ return false;
+ break;
case AbstractMetaFunction::CopyConstructorFunction:
copyConstructorFound = true;
break;
@@ -1796,8 +1829,8 @@ void AbstractMetaClass::format(QDebug &debug) const
if (debug.verbosity() > 2)
debug << static_cast<const void *>(this) << ", ";
debug << '"' << qualifiedCppName();
- if (const int count = d->m_templateArgs.size()) {
- for (int i = 0; i < count; ++i)
+ if (const auto count = d->m_templateArgs.size()) {
+ for (qsizetype i = 0; i < count; ++i)
debug << (i ? ',' : '<') << d->m_templateArgs.at(i)->qualifiedCppName();
debug << '>';
}
@@ -1808,9 +1841,25 @@ void AbstractMetaClass::format(QDebug &debug) const
debug << " [final]";
if (attributes().testFlag(AbstractMetaClass::Deprecated))
debug << " [deprecated]";
+
+ if (d->m_hasPrivateConstructor)
+ debug << " [private constructor]";
+ if (d->m_hasDeletedDefaultConstructor)
+ debug << " [deleted default constructor]";
+ if (d->m_hasDeletedCopyConstructor)
+ debug << " [deleted copy constructor]";
+ if (d->m_hasPrivateDestructor)
+ debug << " [private destructor]";
+ if (d->m_hasProtectedDestructor)
+ debug << " [protected destructor]";
+ if (d->m_hasVirtualDestructor)
+ debug << " [virtual destructor]";
+ if (d->m_valueTypeWithCopyConstructorOnly)
+ debug << " [value type with copy constructor only]";
+
if (!d->m_baseClasses.isEmpty()) {
debug << ", inherits ";
- for (auto b : d->m_baseClasses)
+ for (const auto &b : d->m_baseClasses)
debug << " \"" << b->name() << '"';
}
@@ -1825,13 +1874,13 @@ void AbstractMetaClass::format(QDebug &debug) const
if (auto templateBase = templateBaseClass()) {
const auto &instantiatedTypes = templateBaseClassInstantiations();
debug << ", instantiates \"" << templateBase->name();
- for (int i = 0, count = instantiatedTypes.size(); i < count; ++i)
+ for (qsizetype i = 0, count = instantiatedTypes.size(); i < count; ++i)
debug << (i ? ',' : '<') << instantiatedTypes.at(i).name();
debug << ">\"";
}
- if (const int count = d->m_propertySpecs.size()) {
+ if (const auto count = d->m_propertySpecs.size()) {
debug << ", properties (" << count << "): [";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
if (i)
debug << ", ";
d->m_propertySpecs.at(i).formatDebug(debug);
@@ -1845,18 +1894,18 @@ void AbstractMetaClass::formatMembers(QDebug &debug) const
if (!d->m_enums.isEmpty())
debug << ", enums[" << d->m_enums.size() << "]=" << d->m_enums;
if (!d->m_functions.isEmpty()) {
- const int count = d->m_functions.size();
+ const auto count = d->m_functions.size();
debug << ", functions=[" << count << "](";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
if (i)
debug << ", ";
d->m_functions.at(i)->formatDebugBrief(debug);
}
debug << ')';
}
- if (const int count = d->m_fields.size()) {
+ if (const auto count = d->m_fields.size()) {
debug << ", fields=[" << count << "](";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
if (i)
debug << ", ";
d->m_fields.at(i).formatDebug(debug);
@@ -1875,6 +1924,18 @@ void AbstractMetaClass::setSourceLocation(const SourceLocation &sourceLocation)
d->m_sourceLocation = sourceLocation;
}
+AbstractMetaClassCList allBaseClasses(const AbstractMetaClassCPtr metaClass)
+{
+ AbstractMetaClassCList result;
+ recurseClassHierarchy(metaClass, [&result] (const AbstractMetaClassCPtr &c) {
+ if (!result.contains(c))
+ result.append(c);
+ return false;
+ });
+ result.removeFirst(); // remove self
+ return result;
+}
+
QDebug operator<<(QDebug debug, const UsingMember &d)
{
QDebugStateSaver saver(debug);
@@ -1885,20 +1946,38 @@ QDebug operator<<(QDebug debug, const UsingMember &d)
return debug;
}
-QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
+void formatMetaClass(QDebug &ddebug, const AbstractMetaClass *ac)
{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "AbstractMetaClass(";
- if (ac) {
- ac->format(d);
- if (d.verbosity() > 2)
- ac->formatMembers(d);
+ QDebugStateSaver saver(ddebug);
+ ddebug.noquote();
+ ddebug.nospace();
+ ddebug << "AbstractMetaClass(";
+ if (ac != nullptr) {
+ ac->format(ddebug);
+ if (ddebug.verbosity() > 2)
+ ac->formatMembers(ddebug);
} else {
- d << '0';
+ ddebug << '0';
}
- d << ')';
+ ddebug << ')';
+}
+
+QDebug operator<<(QDebug d, const AbstractMetaClassCPtr &ac)
+{
+ formatMetaClass(d, ac.get());
+ return d;
+}
+
+QDebug operator<<(QDebug d, const AbstractMetaClassPtr &ac)
+{
+ formatMetaClass(d, ac.get());
return d;
}
+
+QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
+{
+ formatMetaClass(d, ac);
+ return d;
+}
+
#endif // !QT_NO_DEBUG_STREAM