diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-11-05 16:41:23 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-11-06 08:11:57 +0000 |
commit | 562edc619787d83b2d4418fa7a69c597a7b6945c (patch) | |
tree | 959812de4b3fc30b24a0e7637c5d917c53f1c676 /sources | |
parent | e21b3c5f6201c97a89b736cec17a1855870409e8 (diff) |
shiboken6: Split the abstractmetalang headers and sources
Split out enums, fields and functions. Only
AbstractMetaClass remains in abstractmetalang.h.
Change-Id: I49846f92fafc5969d83aa4a1767eb4ac23f39d1c
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources')
49 files changed, 2250 insertions, 2147 deletions
diff --git a/sources/shiboken6/ApiExtractor/CMakeLists.txt b/sources/shiboken6/ApiExtractor/CMakeLists.txt index 00a376496..6e53c72c9 100644 --- a/sources/shiboken6/ApiExtractor/CMakeLists.txt +++ b/sources/shiboken6/ApiExtractor/CMakeLists.txt @@ -7,11 +7,16 @@ set(CMAKE_AUTOMOC ON) set(apiextractor_SRC apiextractor.cpp +abstractmetaattributes.cpp abstractmetaargument.cpp abstractmetabuilder.cpp +abstractmetaenum.cpp +abstractmetafield.cpp +abstractmetafunction.cpp abstractmetatype.cpp abstractmetalang.cpp documentation.cpp +enclosingclassmixin.cpp fileout.cpp graph.cpp messages.cpp diff --git a/sources/shiboken6/ApiExtractor/abstractmetaattributes.cpp b/sources/shiboken6/ApiExtractor/abstractmetaattributes.cpp new file mode 100644 index 000000000..9e172893d --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetaattributes.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "abstractmetaattributes.h" + +#ifndef QT_NO_DEBUG_STREAM +# include <QtCore/QDebug> +# include <QtCore/QMetaEnum> +# include <QtCore/QMetaObject> +#endif + +AbstractMetaAttributes::AbstractMetaAttributes() = default; +AbstractMetaAttributes::~AbstractMetaAttributes() = default; + +void AbstractMetaAttributes::assignMetaAttributes(const AbstractMetaAttributes &other) +{ + m_attributes = other.m_attributes; + m_originalAttributes = other.m_originalAttributes; + m_doc = other.m_doc; +} + +#ifndef QT_NO_DEBUG_STREAM +void AbstractMetaAttributes::formatMetaAttributes(QDebug &d, AbstractMetaAttributes::Attributes value) +{ + static const int meIndex = AbstractMetaAttributes::staticMetaObject.indexOfEnumerator("Attribute"); + Q_ASSERT(meIndex >= 0); + const QMetaEnum me = AbstractMetaAttributes::staticMetaObject.enumerator(meIndex); + d << me.valueToKeys(value); +} + +QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "AbstractMetaAttributes("; + if (aa) + d << aa->attributes(); + else + d << '0'; + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken6/ApiExtractor/abstractmetaattributes.h b/sources/shiboken6/ApiExtractor/abstractmetaattributes.h new file mode 100644 index 000000000..137ed830a --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetaattributes.h @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef ABSTRACTMETAATTRIBUTES_H +#define ABSTRACTMETAATTRIBUTES_H + +#include "documentation.h" + +#include <QtCore/qobjectdefs.h> + +class AbstractMetaAttributes +{ + Q_GADGET +public: + Q_DISABLE_COPY(AbstractMetaAttributes) + + AbstractMetaAttributes(); + virtual ~AbstractMetaAttributes(); + + enum Attribute { + None = 0x00000000, + + Private = 0x00000001, + Protected = 0x00000002, + Public = 0x00000004, + Friendly = 0x00000008, + Visibility = 0x0000000f, + + Abstract = 0x00000020, + Static = 0x00000040, + + FinalInTargetLang = 0x00000080, + + GetterFunction = 0x00000400, + SetterFunction = 0x00000800, + + PropertyReader = 0x00004000, + PropertyWriter = 0x00008000, + PropertyResetter = 0x00010000, + + Invokable = 0x00040000, + + HasRejectedConstructor = 0x00080000, + HasRejectedDefaultConstructor = 0x00100000, + + FinalCppClass = 0x00200000, + VirtualCppMethod = 0x00400000, + OverriddenCppMethod = 0x00800000, + FinalCppMethod = 0x01000000, + // Add by meta builder (implicit constructors, inherited methods, etc) + AddedMethod = 0x02000000, + Deprecated = 0x04000000 + }; + Q_DECLARE_FLAGS(Attributes, Attribute) + Q_FLAG(Attribute) + + Attributes attributes() const { return m_attributes; } + + void setAttributes(Attributes attributes) { m_attributes = attributes; } + + Attributes originalAttributes() const { return m_originalAttributes; } + + void setOriginalAttributes(Attributes attributes) { m_originalAttributes = attributes; } + + Attributes visibility() const { return m_attributes & Visibility; } + + void setVisibility(Attributes visi) + { + m_attributes = (m_attributes & ~Visibility) | visi; + } + + void operator+=(Attribute attribute) + { + m_attributes |= attribute; + } + + void operator-=(Attribute attribute) + { + m_attributes &= ~attribute; + } + + bool isFinalInTargetLang() const + { + return m_attributes.testFlag(FinalInTargetLang); + } + + bool isAbstract() const + { + return m_attributes.testFlag(Abstract); + } + + bool isStatic() const + { + return m_attributes.testFlag(Static); + } + + bool isInvokable() const + { + return m_attributes.testFlag(Invokable); + } + + bool isPropertyReader() const + { + return m_attributes.testFlag(PropertyReader); + } + + bool isPropertyWriter() const + { + return m_attributes.testFlag(PropertyWriter); + } + + bool isPropertyResetter() const + { + return m_attributes.testFlag(PropertyResetter); + } + + bool isPrivate() const + { + return m_attributes.testFlag(Private); + } + + bool isProtected() const + { + return m_attributes.testFlag(Protected); + } + + bool isPublic() const + { + return m_attributes.testFlag(Public); + } + + bool isFriendly() const + { + return m_attributes.testFlag(Friendly); + } + + bool wasPrivate() const + { + return m_originalAttributes.testFlag(Private); + } + + bool wasPublic() const + { + return m_originalAttributes.testFlag(Public); + } + + void setDocumentation(const Documentation& doc) + { + m_doc = doc; + } + + Documentation documentation() const + { + return m_doc; + } + +#ifndef QT_NO_DEBUG_STREAM + static void formatMetaAttributes(QDebug &d, AbstractMetaAttributes::Attributes value); +#endif + +protected: + void assignMetaAttributes(const AbstractMetaAttributes &other); + +private: + Attributes m_attributes; + Attributes m_originalAttributes; + Documentation m_doc; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaAttributes::Attributes) + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa); +#endif + +#endif // ABSTRACTMETAATTRIBUTES_H diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp index dbbfd76ec..6a40fe580 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp @@ -27,6 +27,9 @@ ****************************************************************************/ #include "abstractmetabuilder_p.h" +#include "abstractmetaenum.h" +#include "abstractmetafield.h" +#include "abstractmetafunction.h" #include "messages.h" #include "propertyspec.h" #include "reporthandler.h" diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h index 2620effff..5b5f3e505 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h @@ -32,6 +32,7 @@ #include "abstractmetabuilder.h" #include "parser/codemodel_fwd.h" #include "abstractmetalang.h" +#include "abstractmetatype.h" #include "typesystem.h" #include "typeparser.h" diff --git a/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp b/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp new file mode 100644 index 000000000..21fa13a29 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "abstractmetaenum.h" +#include "typesystem.h" + +AbstractMetaEnum::AbstractMetaEnum() : + m_hasQenumsDeclaration(false), m_signed(true) +{ +} + +AbstractMetaEnum::~AbstractMetaEnum() +{ + qDeleteAll(m_enumValues); +} + +template <class String> +AbstractMetaEnumValue *findMatchingEnumValue(const AbstractMetaEnumValueList &list, const String &value) +{ + for (AbstractMetaEnumValue *enumValue : list) { + if (enumValue->name() == value) + return enumValue; + } + return nullptr; +} + +// Find enum values for "enum Enum { e1 }" either for "e1" or "Enum::e1" +AbstractMetaEnumValue *AbstractMetaEnum::findEnumValue(const QString &value) const +{ + if (isAnonymous()) + return findMatchingEnumValue(m_enumValues, value); + const int sepPos = value.indexOf(QLatin1String("::")); + if (sepPos == -1) + return findMatchingEnumValue(m_enumValues, value); + return name() == QStringView{value}.left(sepPos) + ? findMatchingEnumValue(m_enumValues, QStringView{value}.right(value.size() - sepPos - 2)) + : nullptr; +} + +QString AbstractMetaEnum::name() const +{ + return m_typeEntry->targetLangEntryName(); +} + +QString AbstractMetaEnum::qualifier() const +{ + return m_typeEntry->targetLangQualifier(); +} + +QString AbstractMetaEnum::package() const +{ + return m_typeEntry->targetLangPackage(); +} + +#ifndef QT_NO_DEBUG_STREAM + +static void formatMetaEnumValue(QDebug &d, const AbstractMetaEnumValue *v) +{ + const QString &name = v->stringValue(); + if (!name.isEmpty()) + d << name << '='; + d << v->value(); +} + +QDebug operator<<(QDebug d, const AbstractMetaEnumValue *v) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "AbstractMetaEnumValue("; + if (v) + formatMetaEnumValue(d, v); + else + d << '0'; + d << ')'; + return d; +} + +QDebug operator<<(QDebug d, const AbstractMetaEnum *ae) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "AbstractMetaEnum("; + if (ae) { + d << ae->fullName(); + if (!ae->isSigned()) + d << " (unsigned) "; + d << '['; + const AbstractMetaEnumValueList &values = ae->values(); + for (int i = 0, count = values.size(); i < count; ++i) { + if (i) + d << ' '; + formatMetaEnumValue(d, values.at(i)); + } + d << ']'; + } else { + d << '0'; + } + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken6/ApiExtractor/abstractmetaenum.h b/sources/shiboken6/ApiExtractor/abstractmetaenum.h new file mode 100644 index 000000000..dc6176fab --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetaenum.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef ABSTRACTMETAENUM_H +#define ABSTRACTMETAENUM_H + +#include "abstractmetalang_typedefs.h" +#include "abstractmetaattributes.h" +#include "enclosingclassmixin.h" +#include "parser/codemodel_enums.h" +#include "parser/enumvalue.h" + +#include <QtCore/QString> + +QT_FORWARD_DECLARE_CLASS(QDebug) + +class EnumTypeEntry; + +class AbstractMetaEnumValue +{ +public: + AbstractMetaEnumValue() = default; + + EnumValue value() const { return m_value; } + void setValue(EnumValue value) { m_value = value; } + + QString stringValue() const { return m_stringValue; } + void setStringValue(const QString &v) { m_stringValue = v; } + + QString name() const { return m_name; } + void setName(const QString &name) { m_name = name; } + + Documentation documentation() const { return m_doc; } + void setDocumentation(const Documentation& doc) { m_doc = doc; } + +private: + QString m_name; + QString m_stringValue; + + EnumValue m_value; + + Documentation m_doc; +}; + +class AbstractMetaEnum : public AbstractMetaAttributes, public EnclosingClassMixin +{ +public: + AbstractMetaEnum(); + ~AbstractMetaEnum(); + + const AbstractMetaEnumValueList &values() const { return m_enumValues; } + + void addEnumValue(AbstractMetaEnumValue *enumValue) + { + m_enumValues << enumValue; + } + + AbstractMetaEnumValue *findEnumValue(const QString &value) const; + + QString name() const; + + QString qualifier() const; + + QString package() const; + + QString fullName() const + { + return package() + QLatin1Char('.') + qualifier() + QLatin1Char('.') + name(); + } + + EnumKind enumKind() const { return m_enumKind; } + void setEnumKind(EnumKind kind) { m_enumKind = kind; } + + bool isAnonymous() const { return m_enumKind == AnonymousEnum; } + + // Has the enum been declared inside a Q_ENUMS() macro in its enclosing class? + bool hasQEnumsDeclaration() const { return m_hasQenumsDeclaration; } + void setHasQEnumsDeclaration(bool on) { m_hasQenumsDeclaration = on; } + + EnumTypeEntry *typeEntry() const { return m_typeEntry; } + + void setTypeEntry(EnumTypeEntry *entry) { m_typeEntry = entry; } + + bool isSigned() const { return m_signed; } + void setSigned(bool s) { m_signed = s; } + +private: + AbstractMetaEnumValueList m_enumValues; + EnumTypeEntry *m_typeEntry = nullptr; + + EnumKind m_enumKind = CEnum; + uint m_hasQenumsDeclaration : 1; + uint m_signed : 1; +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const AbstractMetaEnum *ae); +#endif + +#endif // ABSTRACTMETAENUM_H diff --git a/sources/shiboken6/ApiExtractor/abstractmetafield.cpp b/sources/shiboken6/ApiExtractor/abstractmetafield.cpp new file mode 100644 index 000000000..2b5f42b21 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetafield.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "abstractmetafield.h" +#include "abstractmetalang.h" +#include "abstractmetalang_helpers.h" +#include "modifications.h" +#include "typesystem.h" + +#include <QtCore/QDebug> + +AbstractMetaVariable::AbstractMetaVariable() = default; + +AbstractMetaVariable::~AbstractMetaVariable() = default; + +void AbstractMetaVariable::assignMetaVariable(const AbstractMetaVariable &other) +{ + m_originalName = other.m_originalName; + m_name = other.m_name; + m_type = other.m_type; + m_hasName = other.m_hasName; + m_doc = other.m_doc; +} + +AbstractMetaField::AbstractMetaField() = default; + +AbstractMetaField *AbstractMetaField::copy() const +{ + auto *returned = new AbstractMetaField; + returned->assignMetaVariable(*this); + returned->assignMetaAttributes(*this); + returned->setEnclosingClass(nullptr); + return returned; +} + +AbstractMetaField *AbstractMetaField::find(const AbstractMetaFieldList &haystack, + const QString &needle) +{ + return findByName(haystack, needle); +} + +/******************************************************************************* + * Indicates that this field has a modification that removes it + */ +bool AbstractMetaField::isModifiedRemoved(int types) const +{ + const FieldModificationList &mods = modifications(); + for (const FieldModification &mod : mods) { + if (!mod.isRemoveModifier()) + continue; + + if ((mod.removal & types) == types) + return true; + } + + return false; +} + +FieldModificationList AbstractMetaField::modifications() const +{ + const FieldModificationList &mods = enclosingClass()->typeEntry()->fieldModifications(); + FieldModificationList returned; + + for (const FieldModification &mod : mods) { + if (mod.name == name()) + returned += mod; + } + + return returned; +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const AbstractMetaVariable *av) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "AbstractMetaVariable("; + if (av) { + d << av->type().name() << ' ' << av->name(); + } else { + d << '0'; + } + d << ')'; + return d; +} + +void AbstractMetaField::formatDebug(QDebug &d) const +{ + AbstractMetaAttributes::formatMetaAttributes(d, attributes()); + d << ' ' << type().name() << " \"" << name() << '"'; +} + +QDebug operator<<(QDebug d, const AbstractMetaField *af) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "AbstractMetaField("; + if (af) + af->formatDebug(d); + else + d << '0'; + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken6/ApiExtractor/abstractmetafield.h b/sources/shiboken6/ApiExtractor/abstractmetafield.h new file mode 100644 index 000000000..3e7eb49a5 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetafield.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef ABSTRACTMETAFIELD_H +#define ABSTRACTMETAFIELD_H + +#include "abstractmetalang_typedefs.h" +#include "typesystem_enums.h" +#include "typesystem_typedefs.h" +#include "abstractmetaattributes.h" +#include "enclosingclassmixin.h" +#include "abstractmetatype.h" +#include "documentation.h" + +QT_FORWARD_DECLARE_CLASS(QDebug) + +class AbstractMetaVariable +{ + Q_DISABLE_COPY(AbstractMetaVariable) +public: + AbstractMetaVariable(); + + virtual ~AbstractMetaVariable(); + + const AbstractMetaType &type() const { return m_type; } + void setType(const AbstractMetaType &type) { m_type = type; } + + QString name() const { return m_name; } + void setName(const QString &name, bool realName = true) + { + m_name = name; + m_hasName = realName; + } + bool hasName() const { return m_hasName; } + + QString originalName() const { return m_originalName; } + void setOriginalName(const QString& name) { m_originalName = name; } + + Documentation documentation() const { return m_doc; } + void setDocumentation(const Documentation& doc) { m_doc = doc; } + +protected: + void assignMetaVariable(const AbstractMetaVariable &other); + +private: + QString m_originalName; + QString m_name; + AbstractMetaType m_type; + bool m_hasName = false; + + Documentation m_doc; +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const AbstractMetaVariable *av); +#endif + +class AbstractMetaField : public AbstractMetaVariable, public AbstractMetaAttributes, public EnclosingClassMixin +{ +public: + AbstractMetaField(); + + FieldModificationList modifications() const; + + bool isModifiedRemoved(int types = TypeSystem::All) const; + + using AbstractMetaVariable::setDocumentation; + using AbstractMetaVariable::documentation; + + AbstractMetaField *copy() const; + + static AbstractMetaField * + find(const AbstractMetaFieldList &haystack, const QString &needle); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const; +#endif +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const AbstractMetaField *af); +#endif + +#endif // ABSTRACTMETAFIELD_H diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp new file mode 100644 index 000000000..5d390ffa9 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp @@ -0,0 +1,900 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "abstractmetafunction.h" +#include "abstractmetalang.h" +#include "abstractmetalang_helpers.h" +#include "messages.h" +#include "propertyspec.h" +#include "reporthandler.h" +#include "typedatabase.h" +#include "typesystem.h" + +#include <QtCore/QDebug> + +AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) : + AbstractMetaFunction() +{ + m_addedFunction = addedFunc; + setConstant(addedFunc->isConstant()); + setName(addedFunc->name()); + setOriginalName(addedFunc->name()); + auto atts = attributes() | AbstractMetaAttributes::FinalInTargetLang; + switch (addedFunc->access()) { + case AddedFunction::InvalidAccess: + break; + case AddedFunction::Protected: + atts |= AbstractMetaAttributes::Protected; + break; + case AddedFunction::Public: + atts |= AbstractMetaAttributes::Public; + break; + } + if (addedFunc->isStatic()) + atts |= AbstractMetaFunction::Static; + setAttributes(atts); +} + +AbstractMetaFunction::AbstractMetaFunction() + : m_constant(false), + m_reverse(false), + m_explicit(false), + m_pointerOperator(false), + m_isCallOperator(false) +{ +} + +AbstractMetaFunction::~AbstractMetaFunction() = default; + +/******************************************************************************* + * Indicates that this function has a modification that removes it + */ +bool AbstractMetaFunction::isModifiedRemoved(int types) const +{ + const FunctionModificationList &mods = modifications(implementingClass()); + for (const FunctionModification &mod : mods) { + if (!mod.isRemoveModifier()) + continue; + + if ((mod.removal & types) == types) + return true; + } + + return false; +} + +bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const +{ + return compareTo(&other) & NameLessThan; +} + + +/*! + Returns a mask of CompareResult describing how this function is + compares to another function +*/ +AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const +{ + CompareResult result; + + // Enclosing class... + if (ownerClass() == other->ownerClass()) + result |= EqualImplementor; + + // Attributes + if (attributes() == other->attributes()) + result |= EqualAttributes; + + // Compare types + if (type().name() == other->type().name()) + result |= EqualReturnType; + + // Compare names + int cmp = originalName().compare(other->originalName()); + + if (cmp < 0) + result |= NameLessThan; + else if (!cmp) + result |= EqualName; + + // compare name after modification... + cmp = modifiedName().compare(other->modifiedName()); + if (!cmp) + result |= EqualModifiedName; + + // Compare arguments... + AbstractMetaArgumentList minArguments; + AbstractMetaArgumentList maxArguments; + if (arguments().size() < other->arguments().size()) { + minArguments = arguments(); + maxArguments = other->arguments(); + } else { + minArguments = other->arguments(); + maxArguments = arguments(); + } + + int minCount = minArguments.size(); + int maxCount = maxArguments.size(); + bool same = true; + for (int i = 0; i < maxCount; ++i) { + if (i < minCount) { + const AbstractMetaArgument &min_arg = minArguments.at(i); + const AbstractMetaArgument &max_arg = maxArguments.at(i); + if (min_arg.type().name() != max_arg.type().name() + && (min_arg.defaultValueExpression().isEmpty() || max_arg.defaultValueExpression().isEmpty())) { + same = false; + break; + } + } else { + if (maxArguments.at(i).defaultValueExpression().isEmpty()) { + same = false; + break; + } + } + } + + if (same) + result |= minCount == maxCount ? EqualArguments : EqualDefaultValueOverload; + + return result; +} + +AbstractMetaFunction *AbstractMetaFunction::copy() const +{ + auto *cpy = new AbstractMetaFunction; + cpy->assignMetaAttributes(*this); + cpy->setName(name()); + cpy->setOriginalName(originalName()); + cpy->setOwnerClass(ownerClass()); + cpy->setImplementingClass(implementingClass()); + cpy->setFunctionType(functionType()); + cpy->setDeclaringClass(declaringClass()); + cpy->setType(type()); + cpy->setConstant(isConstant()); + cpy->setExceptionSpecification(m_exceptionSpecification); + cpy->setAllowThreadModification(m_allowThreadModification); + cpy->setExceptionHandlingModification(m_exceptionHandlingModification); + cpy->m_addedFunction = m_addedFunction; + cpy->m_arguments = m_arguments; + + return cpy; +} + +bool AbstractMetaFunction::usesRValueReferences() const +{ + if (m_functionType == MoveConstructorFunction || m_functionType == MoveAssignmentOperatorFunction) + return true; + if (m_type.referenceType() == RValueReference) + return true; + for (const AbstractMetaArgument &a : m_arguments) { + if (a.type().referenceType() == RValueReference) + return true; + } + return false; +} + +QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStringList &resolvedArguments) const +{ + AbstractMetaArgumentList arguments = this->arguments(); + if (arguments.size() == resolvedArguments.size()) { + QString signature = name() + QLatin1Char('(') + resolvedArguments.join(QLatin1Char(',')) + QLatin1Char(')'); + return QStringList(TypeDatabase::normalizedSignature(signature)); + } + QStringList returned; + + const AbstractMetaArgument &argument = arguments.at(resolvedArguments.size()); + QStringList minimalTypeSignature = argument.type().minimalSignature().split(QLatin1String("::")); + for (int i = 0; i < minimalTypeSignature.size(); ++i) { + returned += introspectionCompatibleSignatures(QStringList(resolvedArguments) + << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join(QLatin1String("::"))); + } + + return returned; +} + +QString AbstractMetaFunction::signature() const +{ + if (m_cachedSignature.isEmpty()) { + m_cachedSignature = m_originalName; + + m_cachedSignature += QLatin1Char('('); + + for (int i = 0; i < m_arguments.count(); ++i) { + const AbstractMetaArgument &a = m_arguments.at(i); + const AbstractMetaType &t = a.type(); + if (!t.isVoid()) { + if (i > 0) + m_cachedSignature += QLatin1String(", "); + m_cachedSignature += t.cppSignature(); + // We need to have the argument names in the qdoc files + m_cachedSignature += QLatin1Char(' '); + m_cachedSignature += a.name(); + } else { + qCWarning(lcShiboken).noquote().nospace() + << QString::fromLatin1("No abstract meta type found for argument '%1' while" + "constructing signature for function '%2'.") + .arg(a.name(), name()); + } + } + m_cachedSignature += QLatin1Char(')'); + + if (isConstant()) + m_cachedSignature += QLatin1String(" const"); + } + return m_cachedSignature; +} + +bool AbstractMetaFunction::isUserAdded() const +{ + return !m_addedFunction.isNull() && !m_addedFunction->isDeclaration(); +} + +int AbstractMetaFunction::actualMinimumArgumentCount() const +{ + AbstractMetaArgumentList arguments = this->arguments(); + + int count = 0; + for (int i = 0; i < arguments.size(); ++i && ++count) { + if (argumentRemoved(i + 1)) + --count; + else if (!arguments.at(i).defaultValueExpression().isEmpty()) + break; + } + + return count; +} + +// Returns reference counts for argument at idx, or all arguments if idx == -2 +QVector<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const +{ + QVector<ReferenceCount> returned; + + const FunctionModificationList &mods = this->modifications(cls); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argumentMod : mod.argument_mods) { + if (argumentMod.index != idx && idx != -2) + continue; + returned += argumentMod.referenceCounts; + } + } + + return returned; +} + +ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, int idx) const +{ + const FunctionModificationList &mods = this->modifications(cls); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argumentMod : mod.argument_mods) { + if (argumentMod.index != idx) + continue; + return argumentMod.owner; + } + } + return ArgumentOwner(); +} + +QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, 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) + continue; + + for (const CodeSnip &snip : argumentModification.conversion_rules) { + if (snip.language == language && !snip.code().isEmpty()) + return snip.code(); + } + } + } + + 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 +{ + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { + if (argumentModification.index == key) { + if (argumentModification.removed) + return true; + } + } + } + + return false; +} + +const AbstractMetaClass *AbstractMetaFunction::targetLangOwner() const +{ + return m_class && m_class->isInvisibleNamespace() + ? m_class->targetLangEnclosingClass() : m_class; +} + +bool AbstractMetaFunction::isDeprecated() const +{ + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + if (modification.isDeprecated()) + return true; + } + return false; +} + +// Auto-detect whether a function should be wrapped into +// Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS, that is, temporarily release +// the GIL (global interpreter lock). Doing so is required for any thread-wait +// functions, anything that might call a virtual function (potentially +// reimplemented in Python), and recommended for lengthy I/O or similar. +// It has performance costs, though. +bool AbstractMetaFunction::autoDetectAllowThread() const +{ + // Disallow for simple getter functions. + const bool maybeGetter = m_constant != 0 && !isVoid() && m_arguments.isEmpty(); + return !maybeGetter; +} + +SourceLocation AbstractMetaFunction::sourceLocation() const +{ + return m_sourceLocation; +} + +void AbstractMetaFunction::setSourceLocation(const SourceLocation &sourceLocation) +{ + m_sourceLocation = sourceLocation; +} + +static inline TypeSystem::AllowThread allowThreadMod(const AbstractMetaClass *klass) +{ + return klass->typeEntry()->allowThread(); +} + +static inline bool hasAllowThreadMod(const AbstractMetaClass *klass) +{ + return allowThreadMod(klass) != TypeSystem::AllowThread::Unspecified; +} + +bool AbstractMetaFunction::allowThread() const +{ + auto allowThreadModification = m_allowThreadModification; + // If there is no modification on the function, check for a base class. + if (m_class && allowThreadModification == TypeSystem::AllowThread::Unspecified) { + if (auto base = recurseClassHierarchy(m_class, hasAllowThreadMod)) + allowThreadModification = allowThreadMod(base); + } + + bool result = true; + switch (allowThreadModification) { + case TypeSystem::AllowThread::Disallow: + result = false; + break; + case TypeSystem::AllowThread::Allow: + break; + case TypeSystem::AllowThread::Auto: + result = autoDetectAllowThread(); + break; + case TypeSystem::AllowThread::Unspecified: + result = false; + break; + } + if (!result && ReportHandler::isDebug(ReportHandler::MediumDebug)) + qCInfo(lcShiboken).noquote() << msgDisallowThread(this); + return result; +} + +TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, 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) + return argumentModification.ownerships.value(language, TypeSystem::InvalidOwnership); + } + } + + return TypeSystem::InvalidOwnership; +} + +bool AbstractMetaFunction::isRemovedFromAllLanguages(const AbstractMetaClass *cls) const +{ + return isRemovedFrom(cls, TypeSystem::All); +} + +bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSystem::Language language) const +{ + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + if ((modification.removal & language) == language) + return true; + } + + return false; +} + +QString AbstractMetaFunction::typeReplaced(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.modified_type.isEmpty()) { + return argumentModification.modified_type; + } + } + } + + return QString(); +} + +bool AbstractMetaFunction::isModifiedToArray(int argumentIndex) const +{ + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { + if (argumentModification.index == argumentIndex && argumentModification.array != 0) + return true; + } + } + return false; +} + +QString AbstractMetaFunction::minimalSignature() const +{ + if (!m_cachedMinimalSignature.isEmpty()) + return m_cachedMinimalSignature; + + QString minimalSignature = originalName() + QLatin1Char('('); + AbstractMetaArgumentList arguments = this->arguments(); + + for (int i = 0; i < arguments.count(); ++i) { + const AbstractMetaType &t = arguments.at(i).type(); + if (!t.isVoid()) { + if (i > 0) + minimalSignature += QLatin1Char(','); + minimalSignature += t.minimalSignature(); + } else { + qCWarning(lcShiboken).noquote().nospace() + << QString::fromLatin1("No abstract meta type found for argument '%1' while constructing" + " minimal signature for function '%2'.") + .arg(arguments.at(i).name(), name()); + } + } + minimalSignature += QLatin1Char(')'); + if (isConstant()) + minimalSignature += QLatin1String("const"); + + minimalSignature = TypeDatabase::normalizedSignature(minimalSignature); + m_cachedMinimalSignature = minimalSignature; + + return minimalSignature; +} + +QString AbstractMetaFunction::debugSignature() const +{ + QString result; + const bool isOverride = attributes() & AbstractMetaFunction::OverriddenCppMethod; + const bool isFinal = attributes() & AbstractMetaFunction::FinalCppMethod; + if (!isOverride && !isFinal && (attributes() & AbstractMetaFunction::VirtualCppMethod)) + result += QLatin1String("virtual "); + result += minimalSignature(); + if (isOverride) + result += QLatin1String(" override"); + if (isFinal) + result += QLatin1String(" final"); + return result; +} + +FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass *implementor) const +{ + if (!m_addedFunction.isNull()) + return m_addedFunction->modifications; + if (!implementor) + implementor = ownerClass(); + + if (!implementor) + return TypeDatabase::instance()->functionModifications(minimalSignature()); + + FunctionModificationList mods; + while (implementor) { + mods += implementor->typeEntry()->functionModifications(minimalSignature()); + if ((implementor == implementor->baseClass()) || + (implementor == implementingClass() && !mods.isEmpty())) { + break; + } + implementor = implementor->baseClass(); + } + return mods; +} + +QString AbstractMetaFunction::argumentName(int index, + bool /* create */, + const AbstractMetaClass * /* implementor */) const +{ + return m_arguments[--index].name(); +} + +bool AbstractMetaFunction::isCallOperator() const +{ + return m_name == QLatin1String("operator()"); +} + +bool AbstractMetaFunction::hasInjectedCode() const +{ + const FunctionModificationList &mods = modifications(ownerClass()); + for (const FunctionModification &mod : mods) { + if (mod.isCodeInjection()) + return true; + } + return false; +} + +CodeSnipList AbstractMetaFunction::injectedCodeSnips(TypeSystem::CodeSnipPosition position, TypeSystem::Language language) const +{ + CodeSnipList result; + const FunctionModificationList &mods = modifications(ownerClass()); + for (const FunctionModification &mod : mods) { + if (mod.isCodeInjection()) { + for (const CodeSnip &snip : mod.snips) { + if ((snip.language & language) && (snip.position == position || position == TypeSystem::CodeSnipPositionAny)) + result << snip; + } + } + } + return result; +} + +bool AbstractMetaFunction::hasSignatureModifications() const +{ + const FunctionModificationList &mods = modifications(); + for (const FunctionModification &mod : mods) { + if (mod.isRenameModifier()) + return true; + for (const ArgumentModification &argmod : mod.argument_mods) { + // since zero represents the return type and we're + // interested only in checking the function arguments, + // it will be ignored. + if (argmod.index > 0) + return true; + } + } + return false; +} + +bool AbstractMetaFunction::isConversionOperator(const QString &funcName) +{ + static const QRegularExpression opRegEx(QStringLiteral("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$")); + Q_ASSERT(opRegEx.isValid()); + return opRegEx.match(funcName).hasMatch(); +} + +ExceptionSpecification AbstractMetaFunction::exceptionSpecification() const +{ + return m_exceptionSpecification; +} + +void AbstractMetaFunction::setExceptionSpecification(ExceptionSpecification e) +{ + m_exceptionSpecification = e; +} + +static inline TypeSystem::ExceptionHandling exceptionMod(const AbstractMetaClass *klass) +{ + return klass->typeEntry()->exceptionHandling(); +} + +static inline bool hasExceptionMod(const AbstractMetaClass *klass) +{ + return exceptionMod(klass) != TypeSystem::ExceptionHandling::Unspecified; +} + +bool AbstractMetaFunction::generateExceptionHandling() const +{ + switch (m_functionType) { + case AbstractMetaFunction::CopyConstructorFunction: + case AbstractMetaFunction::MoveConstructorFunction: + case AbstractMetaFunction::AssignmentOperatorFunction: + case AbstractMetaFunction::MoveAssignmentOperatorFunction: + case AbstractMetaFunction::DestructorFunction: + return false; + default: + break; + } + + auto exceptionHandlingModification = m_exceptionHandlingModification; + // If there is no modification on the function, check for a base class. + if (m_class && exceptionHandlingModification == TypeSystem::ExceptionHandling::Unspecified) { + if (auto base = recurseClassHierarchy(m_class, hasExceptionMod)) + exceptionHandlingModification = exceptionMod(base); + } + + bool result = false; + switch (exceptionHandlingModification) { + case TypeSystem::ExceptionHandling::On: + result = true; + break; + case TypeSystem::ExceptionHandling::AutoDefaultToOn: + result = m_exceptionSpecification != ExceptionSpecification::NoExcept; + break; + case TypeSystem::ExceptionHandling::AutoDefaultToOff: + result = m_exceptionSpecification == ExceptionSpecification::Throws; + break; + case TypeSystem::ExceptionHandling::Unspecified: + case TypeSystem::ExceptionHandling::Off: + break; + } + return result; +} + +bool AbstractMetaFunction::isOperatorOverload(const QString &funcName) +{ + if (isConversionOperator(funcName)) + return true; + + static const QRegularExpression opRegEx(QLatin1String("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?" + "|\\+\\+|\\-\\-|&&|\\|\\||<<[=]?|>>[=]?|~" + "|\\[\\]|\\s+delete\\[?\\]?" + "|\\(\\)" + "|\\s+new\\[?\\]?)$")); + Q_ASSERT(opRegEx.isValid()); + return opRegEx.match(funcName).hasMatch(); +} + +bool AbstractMetaFunction::isCastOperator() const +{ + return originalName().startsWith(QLatin1String("operator ")); +} + +bool AbstractMetaFunction::isArithmeticOperator() const +{ + if (!isOperatorOverload()) + return false; + + QString name = originalName(); + + // It's a dereference operator! + if (name == QLatin1String("operator*") && m_arguments.isEmpty()) + return false; + + return name == QLatin1String("operator+") || name == QLatin1String("operator+=") + || name == QLatin1String("operator-") || name == QLatin1String("operator-=") + || name == QLatin1String("operator*") || name == QLatin1String("operator*=") + || name == QLatin1String("operator/") || name == QLatin1String("operator/=") + || name == QLatin1String("operator%") || name == QLatin1String("operator%=") + || name == QLatin1String("operator++") || name == QLatin1String("operator--"); +} + +bool AbstractMetaFunction::isBitwiseOperator() const +{ + if (!isOperatorOverload()) + return false; + + QString name = originalName(); + return name == QLatin1String("operator<<") || name == QLatin1String("operator<<=") + || name == QLatin1String("operator>>") || name == QLatin1String("operator>>=") + || name == QLatin1String("operator&") || name == QLatin1String("operator&=") + || name == QLatin1String("operator|") || name == QLatin1String("operator|=") + || name == QLatin1String("operator^") || name == QLatin1String("operator^=") + || name == QLatin1String("operator~"); +} + +bool AbstractMetaFunction::isComparisonOperator() const +{ + if (!isOperatorOverload()) + return false; + + QString name = originalName(); + return name == QLatin1String("operator<") || name == QLatin1String("operator<=") + || name == QLatin1String("operator>") || name == QLatin1String("operator>=") + || name == QLatin1String("operator==") || name == QLatin1String("operator!="); +} + +bool AbstractMetaFunction::isLogicalOperator() const +{ + if (!isOperatorOverload()) + return false; + + QString name = originalName(); + return name == QLatin1String("operator!") + || name == QLatin1String("operator&&") + || name == QLatin1String("operator||"); +} + +bool AbstractMetaFunction::isSubscriptOperator() const +{ + if (!isOperatorOverload()) + return false; + + return originalName() == QLatin1String("operator[]"); +} + +bool AbstractMetaFunction::isAssignmentOperator() const +{ + return m_functionType == AssignmentOperatorFunction + || m_functionType == MoveAssignmentOperatorFunction; +} + +bool AbstractMetaFunction::isOtherOperator() const +{ + if (!isOperatorOverload()) + return false; + + return !isArithmeticOperator() + && !isBitwiseOperator() + && !isComparisonOperator() + && !isLogicalOperator() + && !isConversionOperator() + && !isSubscriptOperator() + && !isAssignmentOperator(); +} + +int AbstractMetaFunction::arityOfOperator() const +{ + if (!isOperatorOverload() || isCallOperator()) + return -1; + + int arity = m_arguments.size(); + + // Operator overloads that are class members + // implicitly includes the instance and have + // one parameter less than their arity, + // so we increment it. + if (ownerClass() && arity < 2) + arity++; + + return arity; +} + +bool AbstractMetaFunction::isInplaceOperator() const +{ + if (!isOperatorOverload()) + return false; + + QString name = originalName(); + return name == QLatin1String("operator+=") || name == QLatin1String("operator&=") + || name == QLatin1String("operator-=") || name == QLatin1String("operator|=") + || name == QLatin1String("operator*=") || name == QLatin1String("operator^=") + || name == QLatin1String("operator/=") || name == QLatin1String("operator<<=") + || name == QLatin1String("operator%=") || name == QLatin1String("operator>>="); +} + +bool AbstractMetaFunction::isVirtual() const +{ + return attributes() & AbstractMetaAttributes::VirtualCppMethod; +} + +QString AbstractMetaFunction::modifiedName() const +{ + if (m_cachedModifiedName.isEmpty()) { + const FunctionModificationList &mods = modifications(implementingClass()); + for (const FunctionModification &mod : mods) { + if (mod.isRenameModifier()) { + m_cachedModifiedName = mod.renamedToName; + break; + } + } + if (m_cachedModifiedName.isEmpty()) + m_cachedModifiedName = name(); + } + return m_cachedModifiedName; +} + +AbstractMetaFunction * +AbstractMetaFunction::find(const AbstractMetaFunctionList &haystack, + const QString &needle) +{ + return findByName(haystack, needle); +} + +int AbstractMetaFunction::overloadNumber() const +{ + if (m_cachedOverloadNumber == TypeSystem::OverloadNumberUnset) { + m_cachedOverloadNumber = TypeSystem::OverloadNumberDefault; + const FunctionModificationList &mods = modifications(implementingClass()); + for (const FunctionModification &mod : mods) { + if (mod.overloadNumber() != TypeSystem::OverloadNumberUnset) { + m_cachedOverloadNumber = mod.overloadNumber(); + break; + } + } + } + return m_cachedOverloadNumber; +} + +#ifndef QT_NO_DEBUG_STREAM +void AbstractMetaFunction::formatDebugBrief(QDebug &d) const +{ + d << '"' << debugSignature() << '"'; +} + +void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const +{ + d << m_functionType << ' ' << m_type << ' ' << m_name; + switch (m_exceptionSpecification) { + case ExceptionSpecification::Unknown: + break; + case ExceptionSpecification::NoExcept: + d << " noexcept"; + break; + case ExceptionSpecification::Throws: + d << " throw(...)"; + break; + } + if (m_exceptionHandlingModification != TypeSystem::ExceptionHandling::Unspecified) + d << " exeption-mod " << int(m_exceptionHandlingModification); + d << '('; + for (int i = 0, count = m_arguments.size(); i < count; ++i) { + if (i) + d << ", "; + d << m_arguments.at(i); + } + d << "), signature=\"" << minimalSignature() << '"'; + if (m_constant) + d << " [const]"; + if (m_reverse) + d << " [reverse]"; + if (isUserAdded()) + d << " [userAdded]"; + if (m_explicit) + d << " [explicit]"; + if (attributes().testFlag(AbstractMetaAttributes::Deprecated)) + d << " [deprecated]"; + if (m_pointerOperator) + d << " [operator->]"; + if (m_isCallOperator) + d << " [operator()]"; + if (m_class) + d << " class: " << m_class->name(); + if (m_implementingClass) + d << " implementing class: " << m_implementingClass->name(); + if (m_declaringClass) + d << " declaring class: " << m_declaringClass->name(); +} + +QDebug operator<<(QDebug d, const AbstractMetaFunction *af) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "AbstractMetaFunction("; + if (af) { + if (d.verbosity() > 2) { + af->formatDebugVerbose(d); + } else { + d << "signature="; + af->formatDebugBrief(d); + } + } else { + d << '0'; + } + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.h b/sources/shiboken6/ApiExtractor/abstractmetafunction.h new file mode 100644 index 000000000..21dc19db2 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h @@ -0,0 +1,334 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef ABSTRACTMETAFUNCTION_H +#define ABSTRACTMETAFUNCTION_H + +#include "abstractmetalang_typedefs.h" +#include "abstractmetaargument.h" +#include "abstractmetaattributes.h" +#include "abstractmetatype.h" +#include "typesystem_enums.h" +#include "typesystem_typedefs.h" +#include "sourcelocation.h" + +QT_FORWARD_DECLARE_CLASS(QDebug) + +class FunctionTypeEntry; +class QPropertySpec; + +struct ArgumentOwner; +struct FieldModification; +struct FunctionModification; +struct ReferenceCount; + +class AbstractMetaFunction : public AbstractMetaAttributes +{ + Q_GADGET +public: + enum FunctionType { + ConstructorFunction, + CopyConstructorFunction, + MoveConstructorFunction, + AssignmentOperatorFunction, + MoveAssignmentOperatorFunction, + DestructorFunction, + NormalFunction, + SignalFunction, + EmptyFunction, + SlotFunction, + GlobalScopeFunction, + GetAttroFunction, + SetAttroFunction + }; + Q_ENUM(FunctionType) + + enum CompareResultFlag { + EqualName = 0x00000001, + EqualArguments = 0x00000002, + EqualAttributes = 0x00000004, + EqualImplementor = 0x00000008, + EqualReturnType = 0x00000010, + EqualDefaultValueOverload = 0x00000020, + EqualModifiedName = 0x00000040, + + NameLessThan = 0x00001000, + + PrettySimilar = EqualName | EqualArguments, + Equal = 0x0000001f, + NotEqual = 0x00001000 + }; + Q_DECLARE_FLAGS(CompareResult, CompareResultFlag) + Q_FLAG(CompareResultFlag) + + AbstractMetaFunction(); + explicit AbstractMetaFunction(const AddedFunctionPtr &addedFunc); + ~AbstractMetaFunction(); + + QString name() const { return m_name; } + void setName(const QString &name) { m_name = name; } + + QString originalName() const + { + return m_originalName.isEmpty() ? name() : m_originalName; + } + + void setOriginalName(const QString &name) { m_originalName = name; } + + bool isReverseOperator() const { return m_reverse; } + void setReverseOperator(bool reverse) { m_reverse = reverse; } + + /** + * Returns true if this is a operator and the "self" operand is a pointer. + * e.g. class Foo {}; operator+(SomeEnum, Foo*); + */ + bool isPointerOperator() const { return m_pointerOperator; } + void setPointerOperator(bool value) { m_pointerOperator = value; } + + + /** + * Says if the function (a constructor) was declared as explicit in C++. + * \return true if the function was declared as explicit in C++ + */ + bool isExplicit() const { return m_explicit; } + void setExplicit(bool isExplicit) { m_explicit = isExplicit; } + + static bool isConversionOperator(const QString& funcName); + + ExceptionSpecification exceptionSpecification() const; + void setExceptionSpecification(ExceptionSpecification e); + + bool generateExceptionHandling() const; + + bool isConversionOperator() const + { + return isConversionOperator(originalName()); + } + + static bool isOperatorOverload(const QString& funcName); + bool isOperatorOverload() const + { + return isOperatorOverload(originalName()); + } + bool isCastOperator() const; + + bool isArithmeticOperator() const; + bool isBitwiseOperator() const; + bool isComparisonOperator() const; + bool isLogicalOperator() const; + bool isSubscriptOperator() const; + bool isAssignmentOperator() const; // Assignment or move assignment + bool isOtherOperator() const; + + /** + * Informs the arity of the operator or -1 if the function is not + * an operator overload. + * /return the arity of the operator or -1 + */ + int arityOfOperator() const; + bool isUnaryOperator() const { return arityOfOperator() == 1; } + bool isBinaryOperator() const { return arityOfOperator() == 2; } + bool isInplaceOperator() const; + + bool isVirtual() const; + bool allowThread() const; + QString modifiedName() const; + + QString minimalSignature() const; + QString debugSignature() const; // including virtual/override/final, etc., for debugging only. + + bool isModifiedRemoved(int types = TypeSystem::All) const; + + bool isVoid() const { return m_type.isVoid(); } + + const AbstractMetaType &type() const { return m_type; } + void setType(const AbstractMetaType &type) { m_type = type; } + + // The class that has this function as a member. + const AbstractMetaClass *ownerClass() const { return m_class; } + void setOwnerClass(const AbstractMetaClass *cls) { m_class = cls; } + + // Owner excluding invisible namespaces + const AbstractMetaClass *targetLangOwner() const; + + // The first class in a hierarchy that declares the function + const AbstractMetaClass *declaringClass() const { return m_declaringClass; } + void setDeclaringClass(const AbstractMetaClass *cls) { m_declaringClass = cls; } + + // The class that actually implements this function + const AbstractMetaClass *implementingClass() const { return m_implementingClass; } + void setImplementingClass(const AbstractMetaClass *cls) { m_implementingClass = cls; } + + const AbstractMetaArgumentList &arguments() const { return m_arguments; } + AbstractMetaArgumentList &arguments() { return m_arguments; } + void setArguments(const AbstractMetaArgumentList &arguments) { m_arguments = arguments; } + void addArgument(const AbstractMetaArgument &argument) + { + m_arguments << argument; + } + int actualMinimumArgumentCount() const; + + bool isDeprecated() const; + bool isDestructor() const { return functionType() == DestructorFunction; } + bool isConstructor() const + { + return m_functionType == ConstructorFunction || m_functionType == CopyConstructorFunction + || m_functionType == MoveConstructorFunction; + } + bool isNormal() const + { + return functionType() == NormalFunction || isSlot() || isInGlobalScope(); + } + bool isInGlobalScope() const { return functionType() == GlobalScopeFunction; } + bool isSignal() const { return functionType() == SignalFunction; } + bool isSlot() const { return functionType() == SlotFunction; } + bool isEmptyFunction() const { return functionType() == EmptyFunction; } + FunctionType functionType() const { return m_functionType; } + void setFunctionType(FunctionType type) { m_functionType = type; } + + bool usesRValueReferences() const; + QStringList introspectionCompatibleSignatures(const QStringList &resolvedArguments = QStringList()) const; + QString signature() const; + + bool isConstant() const { return m_constant; } + void setConstant(bool constant) { m_constant = constant; } + + /// Returns true if the AbstractMetaFunction was added by the user via the type system description. + bool isUserAdded() const; + + QString toString() const { return m_name; } + + CompareResult compareTo(const AbstractMetaFunction *other) const; + + bool operator <(const AbstractMetaFunction &a) const; + + AbstractMetaFunction *copy() 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; + + // Returns the ownership rules for the given argument in the given context + TypeSystem::Ownership ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int idx) const; + + QString typeReplaced(int argument_index) const; + bool isModifiedToArray(int argumentIndex) const; + bool isRemovedFromAllLanguages(const AbstractMetaClass *) const; + bool isRemovedFrom(const AbstractMetaClass *, TypeSystem::Language language) const; + bool argumentRemoved(int) const; + /** + * Verifies if any modification to the function is an inject code. + * \return true if there is inject code modifications to the function. + */ + bool hasInjectedCode() const; + /** + * Returns a list of code snips for this function. + * The code snips can be filtered by position and language. + * \return list of code snips + */ + CodeSnipList injectedCodeSnips(TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny, + TypeSystem::Language language = TypeSystem::All) const; + + /** + * Verifies if any modification to the function alters/removes its + * arguments types or default values. + * \return true if there is some modification to function signature + */ + bool hasSignatureModifications() const; + FunctionModificationList modifications(const AbstractMetaClass* implementor = nullptr) const; + + /** + * Return the argument name if there is a modification the renamed value will be returned + */ + QString argumentName(int index, bool create = true, const AbstractMetaClass *cl = nullptr) const; + + QPropertySpec *propertySpec() const { return m_propertySpec; } + void setPropertySpec(QPropertySpec *spec) { m_propertySpec = spec; } + + FunctionTypeEntry* typeEntry() const { return m_typeEntry; } + + void setTypeEntry(FunctionTypeEntry* typeEntry) { m_typeEntry = typeEntry; } + + bool isCallOperator() const; + + static AbstractMetaFunction * + find(const AbstractMetaFunctionList &haystack, const QString &needle); + + // for the meta builder only + void setAllowThreadModification(TypeSystem::AllowThread am) + { m_allowThreadModification = am; } + void setExceptionHandlingModification(TypeSystem::ExceptionHandling em) + { m_exceptionHandlingModification = em; } + + int overloadNumber() const; + +#ifndef QT_NO_DEBUG_STREAM + void formatDebugBrief(QDebug &d) const; + void formatDebugVerbose(QDebug &d) const; +#endif + + SourceLocation sourceLocation() const; + void setSourceLocation(const SourceLocation &sourceLocation); + +private: + bool autoDetectAllowThread() const; + + QString m_name; + QString m_originalName; + mutable QString m_cachedMinimalSignature; + mutable QString m_cachedSignature; + mutable QString m_cachedModifiedName; + + FunctionTypeEntry* m_typeEntry = nullptr; + FunctionType m_functionType = NormalFunction; + AbstractMetaType m_type; + const AbstractMetaClass *m_class = nullptr; + const AbstractMetaClass *m_implementingClass = nullptr; + const AbstractMetaClass *m_declaringClass = nullptr; + QPropertySpec *m_propertySpec = nullptr; + AbstractMetaArgumentList m_arguments; + AddedFunctionPtr m_addedFunction; + SourceLocation m_sourceLocation; + uint m_constant : 1; + uint m_reverse : 1; + uint m_explicit : 1; + uint m_pointerOperator : 1; + uint m_isCallOperator : 1; + mutable int m_cachedOverloadNumber = TypeSystem::OverloadNumberUnset; + ExceptionSpecification m_exceptionSpecification = ExceptionSpecification::Unknown; + TypeSystem::AllowThread m_allowThreadModification = TypeSystem::AllowThread::Unspecified; + TypeSystem::ExceptionHandling m_exceptionHandlingModification = TypeSystem::ExceptionHandling::Unspecified; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::CompareResult) + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const AbstractMetaFunction *af); +#endif + +#endif // ABSTRACTMETAFUNCTION_H diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp index 30f879c5e..74075bd4a 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp @@ -27,993 +27,22 @@ ****************************************************************************/ #include "abstractmetalang.h" -#include "messages.h" +#include "abstractmetalang_helpers.h" +#include "abstractmetaenum.h" +#include "abstractmetafunction.h" +#include "abstractmetafield.h" #include "propertyspec.h" #include "reporthandler.h" #include "typedatabase.h" #include "typesystem.h" -#include <parser/codemodel.h> - -#ifndef QT_NO_DEBUG_STREAM -# include <QtCore/QMetaEnum> -# include <QtCore/QMetaObject> -#endif - -#include <QtCore/QRegularExpression> -#include <QtCore/QSharedData> -#include <QtCore/QStack> - -#include <algorithm> - -#include <algorithm> - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaAttributes("; - if (aa) - d << aa->attributes(); - else - d << '0'; - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -template <class MetaClass> -MetaClass *findByName(QVector<MetaClass *> haystack, QStringView needle) -{ - for (MetaClass *c : haystack) { - if (c->name() == needle) - return c; - } - return nullptr; -} - -// Helper for recursing the base classes of an AbstractMetaClass. -// Returns the class for which the predicate is true. -template <class Predicate> -const AbstractMetaClass *recurseClassHierarchy(const AbstractMetaClass *klass, - Predicate pred) -{ - if (pred(klass)) - return klass; - for (auto base : klass->baseClasses()) { - if (auto r = recurseClassHierarchy(base, pred)) - return r; - } - return nullptr; -} - -/******************************************************************************* - * AbstractMetaVariable - */ - -AbstractMetaVariable::AbstractMetaVariable() = default; - -AbstractMetaVariable::~AbstractMetaVariable() = default; - -void AbstractMetaVariable::assignMetaVariable(const AbstractMetaVariable &other) -{ - m_originalName = other.m_originalName; - m_name = other.m_name; - m_type = other.m_type; - m_hasName = other.m_hasName; - m_doc = other.m_doc; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaVariable *av) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaVariable("; - if (av) { - d << av->type().name() << ' ' << av->name(); - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* - * AbstractMetaAttributes - */ - -AbstractMetaAttributes::AbstractMetaAttributes() = default; -AbstractMetaAttributes::~AbstractMetaAttributes() = default; - -void AbstractMetaAttributes::assignMetaAttributes(const AbstractMetaAttributes &other) -{ - m_attributes = other.m_attributes; - m_originalAttributes = other.m_originalAttributes; - m_doc = other.m_doc; -} - -/******************************************************************************* - * AbstractMetaFunction - */ - -AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) : - AbstractMetaFunction() -{ - m_addedFunction = addedFunc; - setConstant(addedFunc->isConstant()); - setName(addedFunc->name()); - setOriginalName(addedFunc->name()); - auto atts = attributes() | AbstractMetaAttributes::FinalInTargetLang; - switch (addedFunc->access()) { - case AddedFunction::InvalidAccess: - break; - case AddedFunction::Protected: - atts |= AbstractMetaAttributes::Protected; - break; - case AddedFunction::Public: - atts |= AbstractMetaAttributes::Public; - break; - } - if (addedFunc->isStatic()) - atts |= AbstractMetaFunction::Static; - setAttributes(atts); -} - -AbstractMetaFunction::AbstractMetaFunction() - : m_constant(false), - m_reverse(false), - m_explicit(false), - m_pointerOperator(false), - m_isCallOperator(false) -{ -} - -AbstractMetaFunction::~AbstractMetaFunction() = default; - -/******************************************************************************* - * Indicates that this function has a modification that removes it - */ -bool AbstractMetaFunction::isModifiedRemoved(int types) const -{ - const FunctionModificationList &mods = modifications(implementingClass()); - for (const FunctionModification &mod : mods) { - if (!mod.isRemoveModifier()) - continue; - - if ((mod.removal & types) == types) - return true; - } - - return false; -} - -bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const -{ - return compareTo(&other) & NameLessThan; -} - - -/*! - Returns a mask of CompareResult describing how this function is - compares to another function -*/ -AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const -{ - CompareResult result; - - // Enclosing class... - if (ownerClass() == other->ownerClass()) - result |= EqualImplementor; - - // Attributes - if (attributes() == other->attributes()) - result |= EqualAttributes; - - // Compare types - if (type().name() == other->type().name()) - result |= EqualReturnType; - - // Compare names - int cmp = originalName().compare(other->originalName()); - - if (cmp < 0) - result |= NameLessThan; - else if (!cmp) - result |= EqualName; - - // compare name after modification... - cmp = modifiedName().compare(other->modifiedName()); - if (!cmp) - result |= EqualModifiedName; - - // Compare arguments... - AbstractMetaArgumentList minArguments; - AbstractMetaArgumentList maxArguments; - if (arguments().size() < other->arguments().size()) { - minArguments = arguments(); - maxArguments = other->arguments(); - } else { - minArguments = other->arguments(); - maxArguments = arguments(); - } - - int minCount = minArguments.size(); - int maxCount = maxArguments.size(); - bool same = true; - for (int i = 0; i < maxCount; ++i) { - if (i < minCount) { - const AbstractMetaArgument &min_arg = minArguments.at(i); - const AbstractMetaArgument &max_arg = maxArguments.at(i); - if (min_arg.type().name() != max_arg.type().name() - && (min_arg.defaultValueExpression().isEmpty() || max_arg.defaultValueExpression().isEmpty())) { - same = false; - break; - } - } else { - if (maxArguments.at(i).defaultValueExpression().isEmpty()) { - same = false; - break; - } - } - } - - if (same) - result |= minCount == maxCount ? EqualArguments : EqualDefaultValueOverload; - - return result; -} - -AbstractMetaFunction *AbstractMetaFunction::copy() const -{ - auto *cpy = new AbstractMetaFunction; - cpy->assignMetaAttributes(*this); - cpy->setName(name()); - cpy->setOriginalName(originalName()); - cpy->setOwnerClass(ownerClass()); - cpy->setImplementingClass(implementingClass()); - cpy->setFunctionType(functionType()); - cpy->setDeclaringClass(declaringClass()); - cpy->setType(type()); - cpy->setConstant(isConstant()); - cpy->setExceptionSpecification(m_exceptionSpecification); - cpy->setAllowThreadModification(m_allowThreadModification); - cpy->setExceptionHandlingModification(m_exceptionHandlingModification); - cpy->m_addedFunction = m_addedFunction; - cpy->m_arguments = m_arguments; - - return cpy; -} - -bool AbstractMetaFunction::usesRValueReferences() const -{ - if (m_functionType == MoveConstructorFunction || m_functionType == MoveAssignmentOperatorFunction) - return true; - if (m_type.referenceType() == RValueReference) - return true; - for (const AbstractMetaArgument &a : m_arguments) { - if (a.type().referenceType() == RValueReference) - return true; - } - return false; -} - -QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStringList &resolvedArguments) const -{ - AbstractMetaArgumentList arguments = this->arguments(); - if (arguments.size() == resolvedArguments.size()) { - QString signature = name() + QLatin1Char('(') + resolvedArguments.join(QLatin1Char(',')) + QLatin1Char(')'); - return QStringList(TypeDatabase::normalizedSignature(signature)); - } - QStringList returned; - - const AbstractMetaArgument &argument = arguments.at(resolvedArguments.size()); - QStringList minimalTypeSignature = argument.type().minimalSignature().split(QLatin1String("::")); - for (int i = 0; i < minimalTypeSignature.size(); ++i) { - returned += introspectionCompatibleSignatures(QStringList(resolvedArguments) - << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join(QLatin1String("::"))); - } - - return returned; -} - -QString AbstractMetaFunction::signature() const -{ - if (m_cachedSignature.isEmpty()) { - m_cachedSignature = m_originalName; - - m_cachedSignature += QLatin1Char('('); - - for (int i = 0; i < m_arguments.count(); ++i) { - const AbstractMetaArgument &a = m_arguments.at(i); - const AbstractMetaType &t = a.type(); - if (!t.isVoid()) { - if (i > 0) - m_cachedSignature += QLatin1String(", "); - m_cachedSignature += t.cppSignature(); - // We need to have the argument names in the qdoc files - m_cachedSignature += QLatin1Char(' '); - m_cachedSignature += a.name(); - } else { - qCWarning(lcShiboken).noquote().nospace() - << QString::fromLatin1("No abstract meta type found for argument '%1' while" - "constructing signature for function '%2'.") - .arg(a.name(), name()); - } - } - m_cachedSignature += QLatin1Char(')'); - - if (isConstant()) - m_cachedSignature += QLatin1String(" const"); - } - return m_cachedSignature; -} - -bool AbstractMetaFunction::isUserAdded() const -{ - return !m_addedFunction.isNull() && !m_addedFunction->isDeclaration(); -} - -int AbstractMetaFunction::actualMinimumArgumentCount() const -{ - AbstractMetaArgumentList arguments = this->arguments(); - - int count = 0; - for (int i = 0; i < arguments.size(); ++i && ++count) { - if (argumentRemoved(i + 1)) - --count; - else if (!arguments.at(i).defaultValueExpression().isEmpty()) - break; - } - - return count; -} - -// Returns reference counts for argument at idx, or all arguments if idx == -2 -QVector<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const -{ - QVector<ReferenceCount> returned; - - const FunctionModificationList &mods = this->modifications(cls); - for (const FunctionModification &mod : mods) { - for (const ArgumentModification &argumentMod : mod.argument_mods) { - if (argumentMod.index != idx && idx != -2) - continue; - returned += argumentMod.referenceCounts; - } - } - - return returned; -} - - -ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, int idx) const -{ - const FunctionModificationList &mods = this->modifications(cls); - for (const FunctionModification &mod : mods) { - for (const ArgumentModification &argumentMod : mod.argument_mods) { - if (argumentMod.index != idx) - continue; - return argumentMod.owner; - } - } - return ArgumentOwner(); -} - -QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, 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) - continue; - - for (const CodeSnip &snip : argumentModification.conversion_rules) { - if (snip.language == language && !snip.code().isEmpty()) - return snip.code(); - } - } - } - - 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 -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == key) { - if (argumentModification.removed) - return true; - } - } - } - - return false; -} - -const AbstractMetaClass *AbstractMetaFunction::targetLangOwner() const -{ - return m_class && m_class->isInvisibleNamespace() - ? m_class->targetLangEnclosingClass() : m_class; -} - -bool AbstractMetaFunction::isDeprecated() const -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - if (modification.isDeprecated()) - return true; - } - return false; -} - -// Auto-detect whether a function should be wrapped into -// Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS, that is, temporarily release -// the GIL (global interpreter lock). Doing so is required for any thread-wait -// functions, anything that might call a virtual function (potentially -// reimplemented in Python), and recommended for lengthy I/O or similar. -// It has performance costs, though. -bool AbstractMetaFunction::autoDetectAllowThread() const -{ - // Disallow for simple getter functions. - const bool maybeGetter = m_constant != 0 && !isVoid() && m_arguments.isEmpty(); - return !maybeGetter; -} - -SourceLocation AbstractMetaFunction::sourceLocation() const -{ - return m_sourceLocation; -} - -void AbstractMetaFunction::setSourceLocation(const SourceLocation &sourceLocation) -{ - m_sourceLocation = sourceLocation; -} - -static inline TypeSystem::AllowThread allowThreadMod(const AbstractMetaClass *klass) -{ - return klass->typeEntry()->allowThread(); -} - -static inline bool hasAllowThreadMod(const AbstractMetaClass *klass) -{ - return allowThreadMod(klass) != TypeSystem::AllowThread::Unspecified; -} - -bool AbstractMetaFunction::allowThread() const -{ - auto allowThreadModification = m_allowThreadModification; - // If there is no modification on the function, check for a base class. - if (m_class && allowThreadModification == TypeSystem::AllowThread::Unspecified) { - if (auto base = recurseClassHierarchy(m_class, hasAllowThreadMod)) - allowThreadModification = allowThreadMod(base); - } - - bool result = true; - switch (allowThreadModification) { - case TypeSystem::AllowThread::Disallow: - result = false; - break; - case TypeSystem::AllowThread::Allow: - break; - case TypeSystem::AllowThread::Auto: - result = autoDetectAllowThread(); - break; - case TypeSystem::AllowThread::Unspecified: - result = false; - break; - } - if (!result && ReportHandler::isDebug(ReportHandler::MediumDebug)) - qCInfo(lcShiboken).noquote() << msgDisallowThread(this); - return result; -} - -TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, 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) - return argumentModification.ownerships.value(language, TypeSystem::InvalidOwnership); - } - } - - return TypeSystem::InvalidOwnership; -} - -bool AbstractMetaFunction::isRemovedFromAllLanguages(const AbstractMetaClass *cls) const -{ - return isRemovedFrom(cls, TypeSystem::All); -} - -bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSystem::Language language) const -{ - const FunctionModificationList &modifications = this->modifications(cls); - for (const FunctionModification &modification : modifications) { - if ((modification.removal & language) == language) - return true; - } - - return false; - -} - -QString AbstractMetaFunction::typeReplaced(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.modified_type.isEmpty()) { - return argumentModification.modified_type; - } - } - } - - return QString(); -} - -bool AbstractMetaFunction::isModifiedToArray(int argumentIndex) const -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == argumentIndex && argumentModification.array != 0) - return true; - } - } - return false; -} - -QString AbstractMetaFunction::minimalSignature() const -{ - if (!m_cachedMinimalSignature.isEmpty()) - return m_cachedMinimalSignature; - - QString minimalSignature = originalName() + QLatin1Char('('); - AbstractMetaArgumentList arguments = this->arguments(); - - for (int i = 0; i < arguments.count(); ++i) { - const AbstractMetaType &t = arguments.at(i).type(); - if (!t.isVoid()) { - if (i > 0) - minimalSignature += QLatin1Char(','); - minimalSignature += t.minimalSignature(); - } else { - qCWarning(lcShiboken).noquote().nospace() - << QString::fromLatin1("No abstract meta type found for argument '%1' while constructing" - " minimal signature for function '%2'.") - .arg(arguments.at(i).name(), name()); - } - } - minimalSignature += QLatin1Char(')'); - if (isConstant()) - minimalSignature += QLatin1String("const"); - - minimalSignature = TypeDatabase::normalizedSignature(minimalSignature); - m_cachedMinimalSignature = minimalSignature; - - return minimalSignature; -} - -QString AbstractMetaFunction::debugSignature() const -{ - QString result; - const bool isOverride = attributes() & AbstractMetaFunction::OverriddenCppMethod; - const bool isFinal = attributes() & AbstractMetaFunction::FinalCppMethod; - if (!isOverride && !isFinal && (attributes() & AbstractMetaFunction::VirtualCppMethod)) - result += QLatin1String("virtual "); - result += minimalSignature(); - if (isOverride) - result += QLatin1String(" override"); - if (isFinal) - result += QLatin1String(" final"); - return result; -} - -FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass *implementor) const -{ - if (!m_addedFunction.isNull()) - return m_addedFunction->modifications; - if (!implementor) - implementor = ownerClass(); - - if (!implementor) - return TypeDatabase::instance()->functionModifications(minimalSignature()); - - FunctionModificationList mods; - while (implementor) { - mods += implementor->typeEntry()->functionModifications(minimalSignature()); - if ((implementor == implementor->baseClass()) || - (implementor == implementingClass() && !mods.isEmpty())) { - break; - } - implementor = implementor->baseClass(); - } - return mods; -} - -QString AbstractMetaFunction::argumentName(int index, - bool /* create */, - const AbstractMetaClass * /* implementor */) const -{ - return m_arguments[--index].name(); -} - -bool AbstractMetaFunction::isCallOperator() const -{ - return m_name == QLatin1String("operator()"); -} - -bool AbstractMetaFunction::hasInjectedCode() const -{ - const FunctionModificationList &mods = modifications(ownerClass()); - for (const FunctionModification &mod : mods) { - if (mod.isCodeInjection()) - return true; - } - return false; -} - -CodeSnipList AbstractMetaFunction::injectedCodeSnips(TypeSystem::CodeSnipPosition position, TypeSystem::Language language) const -{ - CodeSnipList result; - const FunctionModificationList &mods = modifications(ownerClass()); - for (const FunctionModification &mod : mods) { - if (mod.isCodeInjection()) { - for (const CodeSnip &snip : mod.snips) { - if ((snip.language & language) && (snip.position == position || position == TypeSystem::CodeSnipPositionAny)) - result << snip; - } - } - } - return result; -} - -bool AbstractMetaFunction::hasSignatureModifications() const -{ - const FunctionModificationList &mods = modifications(); - for (const FunctionModification &mod : mods) { - if (mod.isRenameModifier()) - return true; - for (const ArgumentModification &argmod : mod.argument_mods) { - // since zero represents the return type and we're - // interested only in checking the function arguments, - // it will be ignored. - if (argmod.index > 0) - return true; - } - } - return false; -} - -bool AbstractMetaFunction::isConversionOperator(const QString &funcName) -{ - static const QRegularExpression opRegEx(QStringLiteral("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$")); - Q_ASSERT(opRegEx.isValid()); - return opRegEx.match(funcName).hasMatch(); -} - -ExceptionSpecification AbstractMetaFunction::exceptionSpecification() const -{ - return m_exceptionSpecification; -} - -void AbstractMetaFunction::setExceptionSpecification(ExceptionSpecification e) -{ - m_exceptionSpecification = e; -} - -static inline TypeSystem::ExceptionHandling exceptionMod(const AbstractMetaClass *klass) -{ - return klass->typeEntry()->exceptionHandling(); -} - -static inline bool hasExceptionMod(const AbstractMetaClass *klass) -{ - return exceptionMod(klass) != TypeSystem::ExceptionHandling::Unspecified; -} - -bool AbstractMetaFunction::generateExceptionHandling() const -{ - switch (m_functionType) { - case AbstractMetaFunction::CopyConstructorFunction: - case AbstractMetaFunction::MoveConstructorFunction: - case AbstractMetaFunction::AssignmentOperatorFunction: - case AbstractMetaFunction::MoveAssignmentOperatorFunction: - case AbstractMetaFunction::DestructorFunction: - return false; - default: - break; - } - - auto exceptionHandlingModification = m_exceptionHandlingModification; - // If there is no modification on the function, check for a base class. - if (m_class && exceptionHandlingModification == TypeSystem::ExceptionHandling::Unspecified) { - if (auto base = recurseClassHierarchy(m_class, hasExceptionMod)) - exceptionHandlingModification = exceptionMod(base); - } - - bool result = false; - switch (exceptionHandlingModification) { - case TypeSystem::ExceptionHandling::On: - result = true; - break; - case TypeSystem::ExceptionHandling::AutoDefaultToOn: - result = m_exceptionSpecification != ExceptionSpecification::NoExcept; - break; - case TypeSystem::ExceptionHandling::AutoDefaultToOff: - result = m_exceptionSpecification == ExceptionSpecification::Throws; - break; - case TypeSystem::ExceptionHandling::Unspecified: - case TypeSystem::ExceptionHandling::Off: - break; - } - return result; -} - -bool AbstractMetaFunction::isOperatorOverload(const QString &funcName) -{ - if (isConversionOperator(funcName)) - return true; - - static const QRegularExpression opRegEx(QLatin1String("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?" - "|\\+\\+|\\-\\-|&&|\\|\\||<<[=]?|>>[=]?|~" - "|\\[\\]|\\s+delete\\[?\\]?" - "|\\(\\)" - "|\\s+new\\[?\\]?)$")); - Q_ASSERT(opRegEx.isValid()); - return opRegEx.match(funcName).hasMatch(); -} - -bool AbstractMetaFunction::isCastOperator() const -{ - return originalName().startsWith(QLatin1String("operator ")); -} - -bool AbstractMetaFunction::isArithmeticOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - - // It's a dereference operator! - if (name == QLatin1String("operator*") && m_arguments.isEmpty()) - return false; - - return name == QLatin1String("operator+") || name == QLatin1String("operator+=") - || name == QLatin1String("operator-") || name == QLatin1String("operator-=") - || name == QLatin1String("operator*") || name == QLatin1String("operator*=") - || name == QLatin1String("operator/") || name == QLatin1String("operator/=") - || name == QLatin1String("operator%") || name == QLatin1String("operator%=") - || name == QLatin1String("operator++") || name == QLatin1String("operator--"); -} - -bool AbstractMetaFunction::isBitwiseOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - return name == QLatin1String("operator<<") || name == QLatin1String("operator<<=") - || name == QLatin1String("operator>>") || name == QLatin1String("operator>>=") - || name == QLatin1String("operator&") || name == QLatin1String("operator&=") - || name == QLatin1String("operator|") || name == QLatin1String("operator|=") - || name == QLatin1String("operator^") || name == QLatin1String("operator^=") - || name == QLatin1String("operator~"); -} - -bool AbstractMetaFunction::isComparisonOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - return name == QLatin1String("operator<") || name == QLatin1String("operator<=") - || name == QLatin1String("operator>") || name == QLatin1String("operator>=") - || name == QLatin1String("operator==") || name == QLatin1String("operator!="); -} - -bool AbstractMetaFunction::isLogicalOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - return name == QLatin1String("operator!") - || name == QLatin1String("operator&&") - || name == QLatin1String("operator||"); -} - -bool AbstractMetaFunction::isSubscriptOperator() const -{ - if (!isOperatorOverload()) - return false; - - return originalName() == QLatin1String("operator[]"); -} - -bool AbstractMetaFunction::isAssignmentOperator() const -{ - return m_functionType == AssignmentOperatorFunction - || m_functionType == MoveAssignmentOperatorFunction; -} - -bool AbstractMetaFunction::isOtherOperator() const -{ - if (!isOperatorOverload()) - return false; - - return !isArithmeticOperator() - && !isBitwiseOperator() - && !isComparisonOperator() - && !isLogicalOperator() - && !isConversionOperator() - && !isSubscriptOperator() - && !isAssignmentOperator(); -} - -int AbstractMetaFunction::arityOfOperator() const -{ - if (!isOperatorOverload() || isCallOperator()) - return -1; - - int arity = m_arguments.size(); - - // Operator overloads that are class members - // implicitly includes the instance and have - // one parameter less than their arity, - // so we increment it. - if (ownerClass() && arity < 2) - arity++; - - return arity; -} - -bool AbstractMetaFunction::isInplaceOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - return name == QLatin1String("operator+=") || name == QLatin1String("operator&=") - || name == QLatin1String("operator-=") || name == QLatin1String("operator|=") - || name == QLatin1String("operator*=") || name == QLatin1String("operator^=") - || name == QLatin1String("operator/=") || name == QLatin1String("operator<<=") - || name == QLatin1String("operator%=") || name == QLatin1String("operator>>="); -} - -bool AbstractMetaFunction::isVirtual() const -{ - return attributes() & AbstractMetaAttributes::VirtualCppMethod; -} - -QString AbstractMetaFunction::modifiedName() const -{ - if (m_cachedModifiedName.isEmpty()) { - const FunctionModificationList &mods = modifications(implementingClass()); - for (const FunctionModification &mod : mods) { - if (mod.isRenameModifier()) { - m_cachedModifiedName = mod.renamedToName; - break; - } - } - if (m_cachedModifiedName.isEmpty()) - m_cachedModifiedName = name(); - } - return m_cachedModifiedName; -} +#include <QtCore/QDebug> bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b) { return a->signature() < b->signature(); } -AbstractMetaFunction * -AbstractMetaFunction::find(const AbstractMetaFunctionList &haystack, - const QString &needle) -{ - return findByName(haystack, needle); -} - -int AbstractMetaFunction::overloadNumber() const -{ - if (m_cachedOverloadNumber == TypeSystem::OverloadNumberUnset) { - m_cachedOverloadNumber = TypeSystem::OverloadNumberDefault; - const FunctionModificationList &mods = modifications(implementingClass()); - for (const FunctionModification &mod : mods) { - if (mod.overloadNumber() != TypeSystem::OverloadNumberUnset) { - m_cachedOverloadNumber = mod.overloadNumber(); - break; - } - } - } - return m_cachedOverloadNumber; -} - -#ifndef QT_NO_DEBUG_STREAM -static inline void formatMetaFunctionBrief(QDebug &d, const AbstractMetaFunction *af) -{ - d << '"' << af->debugSignature() << '"'; -} - -void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const -{ - d << m_functionType << ' ' << m_type << ' ' << m_name; - switch (m_exceptionSpecification) { - case ExceptionSpecification::Unknown: - break; - case ExceptionSpecification::NoExcept: - d << " noexcept"; - break; - case ExceptionSpecification::Throws: - d << " throw(...)"; - break; - } - if (m_exceptionHandlingModification != TypeSystem::ExceptionHandling::Unspecified) - d << " exeption-mod " << int(m_exceptionHandlingModification); - d << '('; - for (int i = 0, count = m_arguments.size(); i < count; ++i) { - if (i) - d << ", "; - d << m_arguments.at(i); - } - d << "), signature=\"" << minimalSignature() << '"'; - if (m_constant) - d << " [const]"; - if (m_reverse) - d << " [reverse]"; - if (isUserAdded()) - d << " [userAdded]"; - if (m_explicit) - d << " [explicit]"; - if (attributes().testFlag(AbstractMetaAttributes::Deprecated)) - d << " [deprecated]"; - if (m_pointerOperator) - d << " [operator->]"; - if (m_isCallOperator) - d << " [operator()]"; - if (m_class) - d << " class: " << m_class->name(); - if (m_implementingClass) - d << " implementing class: " << m_implementingClass->name(); - if (m_declaringClass) - d << " declaring class: " << m_declaringClass->name(); -} - -QDebug operator<<(QDebug d, const AbstractMetaFunction *af) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaFunction("; - if (af) { - if (d.verbosity() > 2) { - af->formatDebugVerbose(d); - } else { - d << "signature="; - formatMetaFunctionBrief(d, af); - } - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* - * AbstractMetaClass - */ - AbstractMetaClass::AbstractMetaClass() : m_hasVirtuals(false), m_isPolymorphic(false), @@ -1395,137 +424,6 @@ static bool functions_contains(const AbstractMetaFunctionList &l, const Abstract return false; } -AbstractMetaField::AbstractMetaField() = default; - -AbstractMetaField *AbstractMetaField::copy() const -{ - auto *returned = new AbstractMetaField; - returned->assignMetaVariable(*this); - returned->assignMetaAttributes(*this); - returned->setEnclosingClass(nullptr); - return returned; -} - -AbstractMetaField *AbstractMetaField::find(const AbstractMetaFieldList &haystack, - const QString &needle) -{ - return findByName(haystack, needle); -} -/******************************************************************************* - * Indicates that this field has a modification that removes it - */ -bool AbstractMetaField::isModifiedRemoved(int types) const -{ - const FieldModificationList &mods = modifications(); - for (const FieldModification &mod : mods) { - if (!mod.isRemoveModifier()) - continue; - - if ((mod.removal & types) == types) - return true; - } - - return false; -} - -FieldModificationList AbstractMetaField::modifications() const -{ - const FieldModificationList &mods = enclosingClass()->typeEntry()->fieldModifications(); - FieldModificationList returned; - - for (const FieldModification &mod : mods) { - if (mod.name == name()) - returned += mod; - } - - return returned; -} - -const AbstractMetaClass *EnclosingClassMixin::targetLangEnclosingClass() const -{ - auto result = m_enclosingClass; - while (result && !NamespaceTypeEntry::isVisibleScope(result->typeEntry())) - result = result->enclosingClass(); - return result; -} - -#ifndef QT_NO_DEBUG_STREAM -static void formatMetaAttributes(QDebug &d, AbstractMetaAttributes::Attributes value) -{ - static const int meIndex = AbstractMetaAttributes::staticMetaObject.indexOfEnumerator("Attribute"); - Q_ASSERT(meIndex >= 0); - const QMetaEnum me = AbstractMetaAttributes::staticMetaObject.enumerator(meIndex); - d << me.valueToKeys(value); -} - -static void formatMetaField(QDebug &d, const AbstractMetaField *af) -{ - formatMetaAttributes(d, af->attributes()); - d << ' ' << af->type().name() << " \"" << af->name() << '"'; -} - -QDebug operator<<(QDebug d, const AbstractMetaField *af) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaField("; - if (af) - formatMetaField(d, af); - else - d << '0'; - d << ')'; - return d; -} - -static void formatMetaEnumValue(QDebug &d, const AbstractMetaEnumValue *v) -{ - const QString &name = v->stringValue(); - if (!name.isEmpty()) - d << name << '='; - d << v->value(); -} - -QDebug operator<<(QDebug d, const AbstractMetaEnumValue *v) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaEnumValue("; - if (v) - formatMetaEnumValue(d, v); - else - d << '0'; - d << ')'; - return d; -} - -QDebug operator<<(QDebug d, const AbstractMetaEnum *ae) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaEnum("; - if (ae) { - d << ae->fullName(); - if (!ae->isSigned()) - d << " (unsigned) "; - d << '['; - const AbstractMetaEnumValueList &values = ae->values(); - for (int i = 0, count = values.size(); i < count; ++i) { - if (i) - d << ' '; - formatMetaEnumValue(d, values.at(i)); - } - d << ']'; - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - bool AbstractMetaClass::hasConstructors() const { return AbstractMetaClass::queryFirstFunction(m_functions, Constructors) != nullptr; @@ -2159,7 +1057,7 @@ void AbstractMetaClass::formatMembers(QDebug &d) const for (int i = 0; i < count; ++i) { if (i) d << ", "; - formatMetaFunctionBrief(d, m_functions.at(i)); + m_functions.at(i)->formatDebugBrief(d); } d << ')'; } @@ -2168,7 +1066,7 @@ void AbstractMetaClass::formatMembers(QDebug &d) const for (int i = 0; i < count; ++i) { if (i) d << ", "; - formatMetaField(d, m_fields.at(i)); + m_fields.at(i)->formatDebug(d); } d << ')'; } @@ -2201,56 +1099,3 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac) return d; } #endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* -* AbstractMetaEnum -*/ - -AbstractMetaEnum::AbstractMetaEnum() : - m_hasQenumsDeclaration(false), m_signed(true) -{ -} - -AbstractMetaEnum::~AbstractMetaEnum() -{ - qDeleteAll(m_enumValues); -} - -template <class String> -AbstractMetaEnumValue *findMatchingEnumValue(const AbstractMetaEnumValueList &list, const String &value) -{ - for (AbstractMetaEnumValue *enumValue : list) { - if (enumValue->name() == value) - return enumValue; - } - return nullptr; -} - -// Find enum values for "enum Enum { e1 }" either for "e1" or "Enum::e1" -AbstractMetaEnumValue *AbstractMetaEnum::findEnumValue(const QString &value) const -{ - if (isAnonymous()) - return findMatchingEnumValue(m_enumValues, value); - const int sepPos = value.indexOf(QLatin1String("::")); - if (sepPos == -1) - return findMatchingEnumValue(m_enumValues, value); - return name() == QStringView{value}.left(sepPos) - ? findMatchingEnumValue(m_enumValues, QStringView{value}.right(value.size() - sepPos - 2)) - : nullptr; -} - -QString AbstractMetaEnum::name() const -{ - return m_typeEntry->targetLangEntryName(); -} - -QString AbstractMetaEnum::qualifier() const -{ - return m_typeEntry->targetLangQualifier(); -} - -QString AbstractMetaEnum::package() const -{ - return m_typeEntry->targetLangPackage(); -} - diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h index 1fd2eb3ff..d41c0f976 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h @@ -30,826 +30,20 @@ #define ABSTRACTMETALANG_H #include "abstractmetalang_typedefs.h" -#include "abstractmetaargument.h" -#include "abstractmetatype.h" -#include "documentation.h" +#include "abstractmetaattributes.h" +#include "enclosingclassmixin.h" #include "sourcelocation.h" #include "typesystem_enums.h" #include "typesystem_typedefs.h" -#include "parser/codemodel_enums.h" -#include "parser/enumvalue.h" - #include <QtCore/qobjectdefs.h> #include <QtCore/QStringList> -#include <QtCore/QSharedDataPointer> QT_FORWARD_DECLARE_CLASS(QDebug) -class AbstractMeta; -class AbstractMetaClass; -class AbstractMetaField; -class AbstractMetaFunction; -class AbstractMetaVariable; -class AbstractMetaArgument; -class AbstractMetaEnumValue; -class AbstractMetaEnum; class QPropertySpec; - -class CodeSnip; class ComplexTypeEntry; class EnumTypeEntry; -class FlagsTypeEntry; -class FunctionTypeEntry; -class TypeEntry; - -struct ArgumentOwner; -struct FieldModification; -struct FunctionModification; -struct ReferenceCount; - -class AbstractMetaAttributes -{ - Q_GADGET -public: - Q_DISABLE_COPY(AbstractMetaAttributes) - - AbstractMetaAttributes(); - virtual ~AbstractMetaAttributes(); - - enum Attribute { - None = 0x00000000, - - Private = 0x00000001, - Protected = 0x00000002, - Public = 0x00000004, - Friendly = 0x00000008, - Visibility = 0x0000000f, - - Abstract = 0x00000020, - Static = 0x00000040, - - FinalInTargetLang = 0x00000080, - - GetterFunction = 0x00000400, - SetterFunction = 0x00000800, - - PropertyReader = 0x00004000, - PropertyWriter = 0x00008000, - PropertyResetter = 0x00010000, - - Invokable = 0x00040000, - - HasRejectedConstructor = 0x00080000, - HasRejectedDefaultConstructor = 0x00100000, - - FinalCppClass = 0x00200000, - VirtualCppMethod = 0x00400000, - OverriddenCppMethod = 0x00800000, - FinalCppMethod = 0x01000000, - // Add by meta builder (implicit constructors, inherited methods, etc) - AddedMethod = 0x02000000, - Deprecated = 0x04000000 - }; - Q_DECLARE_FLAGS(Attributes, Attribute) - Q_FLAG(Attribute) - - Attributes attributes() const - { - return m_attributes; - } - - void setAttributes(Attributes attributes) - { - m_attributes = attributes; - } - - Attributes originalAttributes() const - { - return m_originalAttributes; - } - - void setOriginalAttributes(Attributes attributes) - { - m_originalAttributes = attributes; - } - - Attributes visibility() const - { - return m_attributes & Visibility; - } - - void setVisibility(Attributes visi) - { - m_attributes = (m_attributes & ~Visibility) | visi; - } - - void operator+=(Attribute attribute) - { - m_attributes |= attribute; - } - - void operator-=(Attribute attribute) - { - m_attributes &= ~attribute; - } - - bool isFinalInTargetLang() const - { - return m_attributes & FinalInTargetLang; - } - - bool isAbstract() const - { - return m_attributes & Abstract; - } - - bool isStatic() const - { - return m_attributes & Static; - } - - bool isInvokable() const - { - return m_attributes & Invokable; - } - - bool isPropertyReader() const - { - return m_attributes & PropertyReader; - } - - bool isPropertyWriter() const - { - return m_attributes & PropertyWriter; - } - - bool isPropertyResetter() const - { - return m_attributes & PropertyResetter; - } - - bool isPrivate() const - { - return m_attributes & Private; - } - - bool isProtected() const - { - return m_attributes & Protected; - } - - bool isPublic() const - { - return m_attributes & Public; - } - - bool isFriendly() const - { - return m_attributes & Friendly; - } - - bool wasPrivate() const - { - return m_originalAttributes & Private; - } - - bool wasPublic() const - { - return m_originalAttributes & Public; - } - - void setDocumentation(const Documentation& doc) - { - m_doc = doc; - } - - Documentation documentation() const - { - return m_doc; - } - -protected: - void assignMetaAttributes(const AbstractMetaAttributes &other); - -private: - Attributes m_attributes; - Attributes m_originalAttributes; - Documentation m_doc; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaAttributes::Attributes) - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa); -#endif - -class AbstractMetaVariable -{ - Q_DISABLE_COPY(AbstractMetaVariable) -public: - AbstractMetaVariable(); - - virtual ~AbstractMetaVariable(); - - const AbstractMetaType &type() const - { - return m_type; - } - void setType(const AbstractMetaType &type) - { - m_type = type; - } - - QString name() const - { - return m_name; - } - void setName(const QString &name, bool realName = true) - { - m_name = name; - m_hasName = realName; - } - bool hasName() const - { - return m_hasName; - } - QString originalName() const - { - return m_originalName; - } - void setOriginalName(const QString& name) - { - m_originalName = name; - } - void setDocumentation(const Documentation& doc) - { - m_doc = doc; - } - Documentation documentation() const - { - return m_doc; - } - -protected: - void assignMetaVariable(const AbstractMetaVariable &other); - -private: - QString m_originalName; - QString m_name; - AbstractMetaType m_type; - bool m_hasName = false; - - Documentation m_doc; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaVariable *av); -#endif - -class EnclosingClassMixin { -public: - const AbstractMetaClass *enclosingClass() const { return m_enclosingClass; } - void setEnclosingClass(const AbstractMetaClass *cls) { m_enclosingClass = cls; } - const AbstractMetaClass *targetLangEnclosingClass() const; - -private: - const AbstractMetaClass *m_enclosingClass = nullptr; -}; - -class AbstractMetaField : public AbstractMetaVariable, public AbstractMetaAttributes, public EnclosingClassMixin -{ -public: - AbstractMetaField(); - - FieldModificationList modifications() const; - - bool isModifiedRemoved(int types = TypeSystem::All) const; - - using AbstractMetaVariable::setDocumentation; - using AbstractMetaVariable::documentation; - - AbstractMetaField *copy() const; - - static AbstractMetaField * - find(const AbstractMetaFieldList &haystack, const QString &needle); -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaField *af); -#endif - -class AbstractMetaFunction : public AbstractMetaAttributes -{ - Q_GADGET -public: - enum FunctionType { - ConstructorFunction, - CopyConstructorFunction, - MoveConstructorFunction, - AssignmentOperatorFunction, - MoveAssignmentOperatorFunction, - DestructorFunction, - NormalFunction, - SignalFunction, - EmptyFunction, - SlotFunction, - GlobalScopeFunction, - GetAttroFunction, - SetAttroFunction - }; - Q_ENUM(FunctionType) - - enum CompareResultFlag { - EqualName = 0x00000001, - EqualArguments = 0x00000002, - EqualAttributes = 0x00000004, - EqualImplementor = 0x00000008, - EqualReturnType = 0x00000010, - EqualDefaultValueOverload = 0x00000020, - EqualModifiedName = 0x00000040, - - NameLessThan = 0x00001000, - - PrettySimilar = EqualName | EqualArguments, - Equal = 0x0000001f, - NotEqual = 0x00001000 - }; - Q_DECLARE_FLAGS(CompareResult, CompareResultFlag) - Q_FLAG(CompareResultFlag) - - AbstractMetaFunction(); - explicit AbstractMetaFunction(const AddedFunctionPtr &addedFunc); - ~AbstractMetaFunction(); - - QString name() const - { - return m_name; - } - - void setName(const QString &name) - { - m_name = name; - } - - QString originalName() const - { - return m_originalName.isEmpty() ? name() : m_originalName; - } - - void setOriginalName(const QString &name) - { - m_originalName = name; - } - - void setReverseOperator(bool reverse) - { - m_reverse = reverse; - } - - bool isReverseOperator() const - { - return m_reverse; - } - - /** - * Returns true if this is a operator and the "self" operand is a pointer. - * e.g. class Foo {}; operator+(SomeEnum, Foo*); - */ - bool isPointerOperator() const - { - return m_pointerOperator; - } - - void setPointerOperator(bool value) - { - m_pointerOperator = value; - } - - void setExplicit(bool isExplicit) - { - m_explicit = isExplicit; - } - /** - * Says if the function (a constructor) was declared as explicit in C++. - * \return true if the function was declared as explicit in C++ - */ - bool isExplicit() const - { - return m_explicit; - } - - static bool isConversionOperator(const QString& funcName); - - ExceptionSpecification exceptionSpecification() const; - void setExceptionSpecification(ExceptionSpecification e); - - bool generateExceptionHandling() const; - - bool isConversionOperator() const - { - return isConversionOperator(originalName()); - } - - static bool isOperatorOverload(const QString& funcName); - bool isOperatorOverload() const - { - return isOperatorOverload(originalName()); - } - bool isCastOperator() const; - - bool isArithmeticOperator() const; - bool isBitwiseOperator() const; - bool isComparisonOperator() const; - bool isLogicalOperator() const; - bool isSubscriptOperator() const; - bool isAssignmentOperator() const; // Assignment or move assignment - bool isOtherOperator() const; - - /** - * Informs the arity of the operator or -1 if the function is not - * an operator overload. - * /return the arity of the operator or -1 - */ - int arityOfOperator() const; - bool isUnaryOperator() const { return arityOfOperator() == 1; } - bool isBinaryOperator() const { return arityOfOperator() == 2; } - bool isInplaceOperator() const; - - bool isVirtual() const; - bool allowThread() const; - QString modifiedName() const; - - QString minimalSignature() const; - QString debugSignature() const; // including virtual/override/final, etc., for debugging only. - - bool isModifiedRemoved(int types = TypeSystem::All) const; - - bool isVoid() const { return m_type.isVoid(); } - const AbstractMetaType &type() const - { - return m_type; - } - void setType(const AbstractMetaType &type) - { - m_type = type; - } - - // The class that has this function as a member. - const AbstractMetaClass *ownerClass() const - { - return m_class; - } - void setOwnerClass(const AbstractMetaClass *cls) - { - m_class = cls; - } - - // Owner excluding invisible namespaces - const AbstractMetaClass *targetLangOwner() const; - - // The first class in a hierarchy that declares the function - const AbstractMetaClass *declaringClass() const - { - return m_declaringClass; - } - void setDeclaringClass(const AbstractMetaClass *cls) - { - m_declaringClass = cls; - } - - // The class that actually implements this function - const AbstractMetaClass *implementingClass() const - { - return m_implementingClass; - } - void setImplementingClass(const AbstractMetaClass *cls) - { - m_implementingClass = cls; - } - - const AbstractMetaArgumentList &arguments() const - { - return m_arguments; - } - AbstractMetaArgumentList &arguments() - { - return m_arguments; - } - void setArguments(const AbstractMetaArgumentList &arguments) - { - m_arguments = arguments; - } - void addArgument(const AbstractMetaArgument &argument) - { - m_arguments << argument; - } - int actualMinimumArgumentCount() const; - - bool isDeprecated() const; - bool isDestructor() const - { - return functionType() == DestructorFunction; - } - bool isConstructor() const - { - return m_functionType == ConstructorFunction || m_functionType == CopyConstructorFunction - || m_functionType == MoveConstructorFunction; - } - bool isNormal() const - { - return functionType() == NormalFunction || isSlot() || isInGlobalScope(); - } - bool isInGlobalScope() const - { - return functionType() == GlobalScopeFunction; - } - bool isSignal() const - { - return functionType() == SignalFunction; - } - bool isSlot() const - { - return functionType() == SlotFunction; - } - bool isEmptyFunction() const - { - return functionType() == EmptyFunction; - } - FunctionType functionType() const - { - return m_functionType; - } - void setFunctionType(FunctionType type) - { - m_functionType = type; - } - - bool usesRValueReferences() const; - QStringList introspectionCompatibleSignatures(const QStringList &resolvedArguments = QStringList()) const; - QString signature() const; - - bool isConstant() const - { - return m_constant; - } - void setConstant(bool constant) - { - m_constant = constant; - } - - /// Returns true if the AbstractMetaFunction was added by the user via the type system description. - bool isUserAdded() const; - - QString toString() const - { - return m_name; - } - - CompareResult compareTo(const AbstractMetaFunction *other) const; - - bool operator <(const AbstractMetaFunction &a) const; - - AbstractMetaFunction *copy() 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; - - // Returns the ownership rules for the given argument in the given context - TypeSystem::Ownership ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int idx) const; - - QString typeReplaced(int argument_index) const; - bool isModifiedToArray(int argumentIndex) const; - bool isRemovedFromAllLanguages(const AbstractMetaClass *) const; - bool isRemovedFrom(const AbstractMetaClass *, TypeSystem::Language language) const; - bool argumentRemoved(int) const; - /** - * Verifies if any modification to the function is an inject code. - * \return true if there is inject code modifications to the function. - */ - bool hasInjectedCode() const; - /** - * Returns a list of code snips for this function. - * The code snips can be filtered by position and language. - * \return list of code snips - */ - CodeSnipList injectedCodeSnips(TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny, - TypeSystem::Language language = TypeSystem::All) const; - - /** - * Verifies if any modification to the function alters/removes its - * arguments types or default values. - * \return true if there is some modification to function signature - */ - bool hasSignatureModifications() const; - FunctionModificationList modifications(const AbstractMetaClass* implementor = nullptr) const; - - /** - * Return the argument name if there is a modification the renamed value will be returned - */ - QString argumentName(int index, bool create = true, const AbstractMetaClass *cl = nullptr) const; - - void setPropertySpec(QPropertySpec *spec) - { - m_propertySpec = spec; - } - - QPropertySpec *propertySpec() const - { - return m_propertySpec; - } - - FunctionTypeEntry* typeEntry() const - { - return m_typeEntry; - } - - void setTypeEntry(FunctionTypeEntry* typeEntry) - { - m_typeEntry = typeEntry; - } - - bool isCallOperator() const; - - static AbstractMetaFunction * - find(const AbstractMetaFunctionList &haystack, const QString &needle); - - // for the meta builder only - void setAllowThreadModification(TypeSystem::AllowThread am) - { m_allowThreadModification = am; } - void setExceptionHandlingModification(TypeSystem::ExceptionHandling em) - { m_exceptionHandlingModification = em; } - - int overloadNumber() const; - -#ifndef QT_NO_DEBUG_STREAM - void formatDebugVerbose(QDebug &d) const; -#endif - - SourceLocation sourceLocation() const; - void setSourceLocation(const SourceLocation &sourceLocation); - -private: - bool autoDetectAllowThread() const; - - QString m_name; - QString m_originalName; - mutable QString m_cachedMinimalSignature; - mutable QString m_cachedSignature; - mutable QString m_cachedModifiedName; - - FunctionTypeEntry* m_typeEntry = nullptr; - FunctionType m_functionType = NormalFunction; - AbstractMetaType m_type; - const AbstractMetaClass *m_class = nullptr; - const AbstractMetaClass *m_implementingClass = nullptr; - const AbstractMetaClass *m_declaringClass = nullptr; - QPropertySpec *m_propertySpec = nullptr; - AbstractMetaArgumentList m_arguments; - AddedFunctionPtr m_addedFunction; - SourceLocation m_sourceLocation; - uint m_constant : 1; - uint m_reverse : 1; - uint m_explicit : 1; - uint m_pointerOperator : 1; - uint m_isCallOperator : 1; - mutable int m_cachedOverloadNumber = TypeSystem::OverloadNumberUnset; - ExceptionSpecification m_exceptionSpecification = ExceptionSpecification::Unknown; - TypeSystem::AllowThread m_allowThreadModification = TypeSystem::AllowThread::Unspecified; - TypeSystem::ExceptionHandling m_exceptionHandlingModification = TypeSystem::ExceptionHandling::Unspecified; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::CompareResult) - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaFunction *af); -#endif - -class AbstractMetaEnumValue -{ -public: - AbstractMetaEnumValue() = default; - - EnumValue value() const - { - return m_value; - } - - void setValue(EnumValue value) - { - m_value = value; - } - - QString stringValue() const - { - return m_stringValue; - } - - void setStringValue(const QString &v) - { - m_stringValue = v; - } - - QString name() const - { - return m_name; - } - - void setName(const QString &name) - { - m_name = name; - } - - void setDocumentation(const Documentation& doc) - { - m_doc = doc; - } - - Documentation documentation() const - { - return m_doc; - } - -private: - QString m_name; - QString m_stringValue; - - EnumValue m_value; - - Documentation m_doc; -}; - -class AbstractMetaEnum : public AbstractMetaAttributes, public EnclosingClassMixin -{ -public: - AbstractMetaEnum(); - ~AbstractMetaEnum(); - - AbstractMetaEnumValueList values() const - { - return m_enumValues; - } - - void addEnumValue(AbstractMetaEnumValue *enumValue) - { - m_enumValues << enumValue; - } - - AbstractMetaEnumValue *findEnumValue(const QString &value) const; - - QString name() const; - - QString qualifier() const; - - QString package() const; - - QString fullName() const - { - return package() + QLatin1Char('.') + qualifier() + QLatin1Char('.') + name(); - } - - EnumKind enumKind() const { return m_enumKind; } - void setEnumKind(EnumKind kind) { m_enumKind = kind; } - - bool isAnonymous() const { return m_enumKind == AnonymousEnum; } - - // Has the enum been declared inside a Q_ENUMS() macro in its enclosing class? - void setHasQEnumsDeclaration(bool on) - { - m_hasQenumsDeclaration = on; - } - - bool hasQEnumsDeclaration() const - { - return m_hasQenumsDeclaration; - } - - EnumTypeEntry *typeEntry() const - { - return m_typeEntry; - } - - void setTypeEntry(EnumTypeEntry *entry) - { - m_typeEntry = entry; - } - - bool isSigned() const { return m_signed; } - void setSigned(bool s) { m_signed = s; } - -private: - AbstractMetaEnumValueList m_enumValues; - EnumTypeEntry *m_typeEntry = nullptr; - - EnumKind m_enumKind = CEnum; - uint m_hasQenumsDeclaration : 1; - uint m_signed : 1; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaEnum *ae); -#endif class AbstractMetaClass : public AbstractMetaAttributes, public EnclosingClassMixin { @@ -900,10 +94,7 @@ public: void fixFunctions(); - AbstractMetaFunctionList functions() const - { - return m_functions; - } + const AbstractMetaFunctionList &functions() const { return m_functions; } void setFunctions(const AbstractMetaFunctionList &functions); void addFunction(AbstractMetaFunction *function); @@ -920,51 +111,19 @@ public: void addDefaultConstructor(); void addDefaultCopyConstructor(bool isPrivate = false); - bool hasNonPrivateConstructor() const - { - return m_hasNonPrivateConstructor; - } - - void setHasNonPrivateConstructor(bool value) - { - m_hasNonPrivateConstructor = value; - } - - bool hasPrivateConstructor() const - { - return m_hasPrivateConstructor; - } - - void setHasPrivateConstructor(bool value) - { - m_hasPrivateConstructor = value; - } + bool hasNonPrivateConstructor() const { return m_hasNonPrivateConstructor; } + void setHasNonPrivateConstructor(bool value) { m_hasNonPrivateConstructor = value; } - bool hasPrivateDestructor() const - { - return m_hasPrivateDestructor; - } + bool hasPrivateConstructor() const { return m_hasPrivateConstructor; } + void setHasPrivateConstructor(bool value) { m_hasPrivateConstructor = value; } - void setHasPrivateDestructor(bool value) - { - m_hasPrivateDestructor = value; - } - - bool hasProtectedDestructor() const - { - return m_hasProtectedDestructor; - } - - void setHasProtectedDestructor(bool value) - { - m_hasProtectedDestructor = value; - } + bool hasPrivateDestructor() const { return m_hasPrivateDestructor; } + void setHasPrivateDestructor(bool value) { m_hasPrivateDestructor = value; } - bool hasVirtualDestructor() const - { - return m_hasVirtualDestructor; - } + bool hasProtectedDestructor() const { return m_hasProtectedDestructor; } + void setHasProtectedDestructor(bool value) { m_hasProtectedDestructor = value; } + bool hasVirtualDestructor() const { return m_hasVirtualDestructor; } void setHasVirtualDestructor(bool value); bool isConstructible() const @@ -1001,33 +160,15 @@ public: bool hasComparisonOperatorOverload() const; bool hasLogicalOperatorOverload() const; - AbstractMetaFieldList fields() const - { - return m_fields; - } - - void setFields(const AbstractMetaFieldList &fields) - { - m_fields = fields; - } - - void addField(AbstractMetaField *field) - { - m_fields << field; - } + const AbstractMetaFieldList &fields() const { return m_fields; } + void setFields(const AbstractMetaFieldList &fields) { m_fields = fields; } + void addField(AbstractMetaField *field) { m_fields << field; } AbstractMetaField *findField(const QString &name) const; const AbstractMetaEnumList &enums() const { return m_enums; } - void setEnums(const AbstractMetaEnumList &enums) - { - m_enums = enums; - } - - void addEnum(AbstractMetaEnum *e) - { - m_enums << e; - } + void setEnums(const AbstractMetaEnumList &enums) { m_enums = enums; } + void addEnum(AbstractMetaEnum *e) { m_enums << e; } AbstractMetaEnum *findEnum(const QString &enumName); AbstractMetaEnumValue *findEnumValue(const QString &enumName); @@ -1067,20 +208,9 @@ public: AbstractMetaClass *extendedNamespace() const { return m_extendedNamespace; } void setExtendedNamespace(AbstractMetaClass *e) { m_extendedNamespace = e; } - const AbstractMetaClassList& innerClasses() const - { - return m_innerClasses; - } - - void addInnerClass(AbstractMetaClass* cl) - { - m_innerClasses << cl; - } - - void setInnerClasses(const AbstractMetaClassList &innerClasses) - { - m_innerClasses = innerClasses; - } + const AbstractMetaClassList& innerClasses() const { return m_innerClasses; } + void addInnerClass(AbstractMetaClass* cl) { m_innerClasses << cl; } + void setInnerClasses(const AbstractMetaClassList &innerClasses) { m_innerClasses = innerClasses; } QString package() const; @@ -1103,10 +233,7 @@ public: * Says if the class that declares or inherits a virtual function. * \return true if the class implements or inherits any virtual methods */ - bool isPolymorphic() const - { - return m_isPolymorphic; - } + bool isPolymorphic() const { return m_isPolymorphic; } /** * Tells if this class has one or more functions that are protected. @@ -1127,79 +254,31 @@ public: bool hasProtectedMembers() const; - QVector<TypeEntry *> templateArguments() const - { - return m_templateArgs; - } - - void setTemplateArguments(const QVector<TypeEntry *> &args) - { - m_templateArgs = args; - } + const QVector<TypeEntry *> &templateArguments() const { return m_templateArgs; } + void setTemplateArguments(const QVector<TypeEntry *> &args) { m_templateArgs = args; } // only valid during metabuilder's run - QStringList baseClassNames() const - { - return m_baseClassNames; - } + const QStringList &baseClassNames() const { return m_baseClassNames; } + void setBaseClassNames(const QStringList &names) { m_baseClassNames = names; } - void setBaseClassNames(const QStringList &names) - { - m_baseClassNames = names; - } + const ComplexTypeEntry *typeEntry() const { return m_typeEntry; } + ComplexTypeEntry *typeEntry() { return m_typeEntry; } + void setTypeEntry(ComplexTypeEntry *type) { m_typeEntry = type; } - const ComplexTypeEntry *typeEntry() const - { - return m_typeEntry; - } + void setHasHashFunction(bool on) { m_hasHashFunction = on; } - ComplexTypeEntry *typeEntry() - { - return m_typeEntry; - } + bool hasHashFunction() const { return m_hasHashFunction; } - void setTypeEntry(ComplexTypeEntry *type) - { - m_typeEntry = type; - } + bool hasDefaultToStringFunction() const; - void setHasHashFunction(bool on) - { - m_hasHashFunction = on; - } + bool hasEqualsOperator() const { return m_hasEqualsOperator; } + void setHasEqualsOperator(bool on) { m_hasEqualsOperator = on; } - bool hasHashFunction() const - { - return m_hasHashFunction; - } - virtual bool hasDefaultToStringFunction() const; - - void setHasEqualsOperator(bool on) - { - m_hasEqualsOperator = on; - } - - bool hasEqualsOperator() const - { - return m_hasEqualsOperator; - } - - void setHasCloneOperator(bool on) - { - m_hasCloneOperator = on; - } - - bool hasCloneOperator() const - { - return m_hasCloneOperator; - } - - void addPropertySpec(QPropertySpec *spec) - { - m_propertySpecs << spec; - } + bool hasCloneOperator() const { return m_hasCloneOperator; } + void setHasCloneOperator(bool on) { m_hasCloneOperator = on; } const QVector<QPropertySpec *> &propertySpecs() const { return m_propertySpecs; } + void addPropertySpec(QPropertySpec *spec) { m_propertySpecs << spec; } QPropertySpec *propertySpecByName(const QString &name) const; QPropertySpec *propertySpecForRead(const QString &name) const; @@ -1225,15 +304,8 @@ public: void sortFunctions(); - const AbstractMetaClass *templateBaseClass() const - { - return m_templateBaseClass; - } - - void setTemplateBaseClass(const AbstractMetaClass *cls) - { - m_templateBaseClass = cls; - } + const AbstractMetaClass *templateBaseClass() const { return m_templateBaseClass; } + void setTemplateBaseClass(const AbstractMetaClass *cls) { m_templateBaseClass = cls; } bool hasTemplateBaseClassInstantiations() const; const AbstractMetaTypeList &templateBaseClassInstantiations() const; @@ -1242,31 +314,17 @@ public: void setTypeDef(bool typeDef) { m_isTypeDef = typeDef; } bool isTypeDef() const { return m_isTypeDef; } - void setStream(bool stream) - { - m_stream = stream; - } - - bool isStream() const - { - return m_stream; - } + bool isStream() const { return m_stream; } + void setStream(bool stream) { m_stream = stream; } + bool hasToStringCapability() const { return m_hasToStringCapability; } void setToStringCapability(bool value, uint indirections = 0) { m_hasToStringCapability = value; m_toStringCapabilityIndirections = indirections; } - bool hasToStringCapability() const - { - return m_hasToStringCapability; - } - - uint toStringCapabilityIndirections() const - { - return m_toStringCapabilityIndirections; - } + uint toStringCapabilityIndirections() const { return m_toStringCapabilityIndirections; } bool deleteInMainThread() const; diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h b/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h new file mode 100644 index 000000000..b38284b9e --- /dev/null +++ b/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef ABSTRACTMETALANG_HELPERS_H +#define ABSTRACTMETALANG_HELPERS_H + +template <class MetaClass> +MetaClass *findByName(QVector<MetaClass *> haystack, QStringView needle) +{ + for (MetaClass *c : haystack) { + if (c->name() == needle) + return c; + } + return nullptr; +} + +// Helper for recursing the base classes of an AbstractMetaClass. +// Returns the class for which the predicate is true. +template <class Predicate> +const AbstractMetaClass *recurseClassHierarchy(const AbstractMetaClass *klass, + Predicate pred) +{ + if (pred(klass)) + return klass; + for (auto base : klass->baseClasses()) { + if (auto r = recurseClassHierarchy(base, pred)) + return r; + } + return nullptr; +} + +#endif // ABSTRACTMETALANG_HELPERS_H diff --git a/sources/shiboken6/ApiExtractor/docparser.cpp b/sources/shiboken6/ApiExtractor/docparser.cpp index cb5d85074..295df5040 100644 --- a/sources/shiboken6/ApiExtractor/docparser.cpp +++ b/sources/shiboken6/ApiExtractor/docparser.cpp @@ -26,6 +26,9 @@ ** ****************************************************************************/ #include "docparser.h" +#include "abstractmetaenum.h" +#include "abstractmetafield.h" +#include "abstractmetafunction.h" #include "abstractmetalang.h" #include "messages.h" #include "reporthandler.h" diff --git a/sources/shiboken6/ApiExtractor/doxygenparser.cpp b/sources/shiboken6/ApiExtractor/doxygenparser.cpp index 01b8fc012..f6ffd3670 100644 --- a/sources/shiboken6/ApiExtractor/doxygenparser.cpp +++ b/sources/shiboken6/ApiExtractor/doxygenparser.cpp @@ -28,6 +28,9 @@ #include "doxygenparser.h" #include "abstractmetalang.h" +#include "abstractmetafield.h" +#include "abstractmetafunction.h" +#include "abstractmetaenum.h" #include "messages.h" #include "propertyspec.h" #include "reporthandler.h" diff --git a/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp b/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp new file mode 100644 index 000000000..5d6394f11 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "enclosingclassmixin.h" +#include "abstractmetalang.h" +#include "typesystem.h" + +const AbstractMetaClass *EnclosingClassMixin::targetLangEnclosingClass() const +{ + auto result = m_enclosingClass; + while (result && !NamespaceTypeEntry::isVisibleScope(result->typeEntry())) + result = result->enclosingClass(); + return result; +} diff --git a/sources/shiboken6/ApiExtractor/enclosingclassmixin.h b/sources/shiboken6/ApiExtractor/enclosingclassmixin.h new file mode 100644 index 000000000..61fbc816f --- /dev/null +++ b/sources/shiboken6/ApiExtractor/enclosingclassmixin.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef ENCLOSINGCLASSMIXIN_H +#define ENCLOSINGCLASSMIXIN_H + +class AbstractMetaClass; + +class EnclosingClassMixin { +public: + const AbstractMetaClass *enclosingClass() const { return m_enclosingClass; } + void setEnclosingClass(const AbstractMetaClass *cls) { m_enclosingClass = cls; } + const AbstractMetaClass *targetLangEnclosingClass() const; + +private: + const AbstractMetaClass *m_enclosingClass = nullptr; +}; + +#endif // ENCLOSINGCLASSMIXIN_H diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp index ab03a0102..65012893a 100644 --- a/sources/shiboken6/ApiExtractor/messages.cpp +++ b/sources/shiboken6/ApiExtractor/messages.cpp @@ -27,6 +27,9 @@ ****************************************************************************/ #include "messages.h" +#include "abstractmetaenum.h" +#include "abstractmetafield.h" +#include "abstractmetafunction.h" #include "abstractmetalang.h" #include "sourcelocation.h" #include "typedatabase.h" diff --git a/sources/shiboken6/ApiExtractor/qtdocparser.cpp b/sources/shiboken6/ApiExtractor/qtdocparser.cpp index 6df37fa51..9cc9f15e4 100644 --- a/sources/shiboken6/ApiExtractor/qtdocparser.cpp +++ b/sources/shiboken6/ApiExtractor/qtdocparser.cpp @@ -27,6 +27,9 @@ ****************************************************************************/ #include "qtdocparser.h" +#include "abstractmetaenum.h" +#include "abstractmetafield.h" +#include "abstractmetafunction.h" #include "abstractmetalang.h" #include "messages.h" #include "propertyspec.h" diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp index a1b4c708a..8e715866e 100644 --- a/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp @@ -30,6 +30,7 @@ #include "abstractmetabuilder.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp index 6fd25bc0b..0fab1bf07 100644 --- a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp @@ -29,6 +29,7 @@ #include "testabstractmetatype.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> #include <parser/codemodel.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp index 51088a040..bacdd4906 100644 --- a/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp @@ -29,6 +29,7 @@ #include "testaddfunction.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp index 1804ec61e..fd50bf2ba 100644 --- a/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp @@ -29,6 +29,8 @@ #include "testarrayargument.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetaenum.h> +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp index 3c33c7d1e..515eb520e 100644 --- a/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp @@ -30,6 +30,7 @@ #include <QtTest/QTest> #include "testutil.h" #include <abstractmetalang.h> +#include <abstractmetatype.h> #include <typesystem.h> void TestContainer::testContainerType() diff --git a/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp b/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp index 8e4eebcb5..b9345ddbc 100644 --- a/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp @@ -29,6 +29,7 @@ #include "testconversionoperator.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp index 786c3717e..7e98cdf40 100644 --- a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp @@ -29,6 +29,7 @@ #include "testdroptypeentries.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetaenum.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testenum.cpp b/sources/shiboken6/ApiExtractor/tests/testenum.cpp index cc5f93ad5..39bf7931a 100644 --- a/sources/shiboken6/ApiExtractor/tests/testenum.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testenum.cpp @@ -29,6 +29,8 @@ #include "testenum.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetaenum.h> +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp b/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp index b942ea9b5..6faf2db89 100644 --- a/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp @@ -29,7 +29,7 @@ #include "testfunctiontag.h" #include <QtTest/QTest> #include "testutil.h" -#include <abstractmetalang.h> +#include <abstractmetafunction.h> #include <typesystem.h> void TestFunctionTag::testFunctionTagForSpecificSignature() diff --git a/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp b/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp index 309314445..ef9699cad 100644 --- a/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp @@ -28,6 +28,7 @@ #include "testimplicitconversions.h" #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> #include <QtTest/QTest> diff --git a/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp index d88ad5397..99e33b81c 100644 --- a/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp @@ -29,6 +29,7 @@ #include "testmodifyfunction.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp b/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp index a4e506e8c..7702d37d9 100644 --- a/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp @@ -29,6 +29,7 @@ #include "testmultipleinheritance.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp b/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp index 43d4b2f33..defdc1b0e 100644 --- a/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp @@ -29,6 +29,7 @@ #include "testnestedtypes.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp index f6f930679..54984620b 100644 --- a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp @@ -29,6 +29,7 @@ #include "testnumericaltypedef.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp b/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp index 9d1dcc1ae..c13acbaeb 100644 --- a/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp @@ -29,6 +29,7 @@ #include "testrefcounttag.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp b/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp index 545c47c61..6cd719743 100644 --- a/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp @@ -29,6 +29,7 @@ #include "testreferencetopointer.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp b/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp index dd9b735a4..31a9e84a0 100644 --- a/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp @@ -29,6 +29,7 @@ #include "testremovefield.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafield.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp b/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp index 2ae6b105f..bd78ad80d 100644 --- a/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp @@ -29,6 +29,7 @@ #include "testremoveimplconv.h" #include "testutil.h" #include <QtTest/QTest> +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp b/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp index a6d28ccf5..3b9936571 100644 --- a/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp @@ -29,6 +29,7 @@ #include "testremoveoperatormethod.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp b/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp index 496b55aaa..66dd6edbf 100644 --- a/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp @@ -29,6 +29,7 @@ #include "testreverseoperators.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp index 807768236..54842a27d 100644 --- a/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp @@ -31,6 +31,8 @@ #include <QtCore/QTextStream> #include <QTemporaryFile> #include "testutil.h" +#include <abstractmetafield.h> +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp b/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp index 10bf35d59..0f257b472 100644 --- a/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp @@ -29,6 +29,7 @@ #include "testtyperevision.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetaenum.h> #include <abstractmetalang.h> #include <typesystem.h> #include <typedatabase.h> diff --git a/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp b/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp index 68681550f..d39819d0f 100644 --- a/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp @@ -29,6 +29,7 @@ #include "testvoidarg.h" #include <QtTest/QTest> #include "testutil.h" +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typesystem.h> diff --git a/sources/shiboken6/generator/generator.cpp b/sources/shiboken6/generator/generator.cpp index 72a5b9a2e..750d3c3a4 100644 --- a/sources/shiboken6/generator/generator.cpp +++ b/sources/shiboken6/generator/generator.cpp @@ -28,6 +28,9 @@ #include "generator.h" #include "ctypenames.h" +#include "abstractmetaenum.h" +#include "abstractmetafield.h" +#include "abstractmetafunction.h" #include "abstractmetalang.h" #include "parser/codemodel.h" #include "messages.h" diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp index 6d734e5e2..13d3e5d11 100644 --- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp +++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp @@ -28,6 +28,9 @@ #include "qtdocgenerator.h" #include "ctypenames.h" +#include <abstractmetaenum.h> +#include <abstractmetafield.h> +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <messages.h> #include <propertyspec.h> diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 82292b953..28994d073 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -32,6 +32,9 @@ #include "ctypenames.h" #include "fileout.h" #include "overloaddata.h" +#include <abstractmetaenum.h> +#include <abstractmetafield.h> +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <messages.h> #include <propertyspec.h> diff --git a/sources/shiboken6/generator/shiboken/headergenerator.cpp b/sources/shiboken6/generator/shiboken/headergenerator.cpp index d607ed643..4456c9c7c 100644 --- a/sources/shiboken6/generator/shiboken/headergenerator.cpp +++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp @@ -27,6 +27,9 @@ ****************************************************************************/ #include "headergenerator.h" +#include <abstractmetaenum.h> +#include <abstractmetafield.h> +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <typedatabase.h> #include <reporthandler.h> diff --git a/sources/shiboken6/generator/shiboken/overloaddata.cpp b/sources/shiboken6/generator/shiboken/overloaddata.cpp index 53fff9f25..2a00e5804 100644 --- a/sources/shiboken6/generator/shiboken/overloaddata.cpp +++ b/sources/shiboken6/generator/shiboken/overloaddata.cpp @@ -26,6 +26,7 @@ ** ****************************************************************************/ +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <reporthandler.h> #include <graph.h> diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index 5382b3a9f..8a2058443 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -28,6 +28,9 @@ #include "shibokengenerator.h" #include "ctypenames.h" +#include <abstractmetaenum.h> +#include <abstractmetafield.h> +#include <abstractmetafunction.h> #include <abstractmetalang.h> #include <messages.h> #include "overloaddata.h" |