aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor/abstractmetalang.cpp')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp2707
1 files changed, 0 insertions, 2707 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
deleted file mode 100644
index 390143cda..000000000
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ /dev/null
@@ -1,2707 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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 "abstractmetalang.h"
-#include "messages.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/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()
-{
- delete m_type;
-}
-
-void AbstractMetaVariable::assignMetaVariable(const AbstractMetaVariable &other)
-{
- m_originalName = other.m_originalName;
- m_name = other.m_name;
- m_type = other.m_type->copy();
- 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;
-}
-
-/*******************************************************************************
- * AbstractMetaType
- */
-
-AbstractMetaType::AbstractMetaType() :
- m_constant(false),
- m_volatile(false),
- m_cppInstantiation(true),
- m_reserved(0)
-{
-}
-
-AbstractMetaType::~AbstractMetaType()
-{
- qDeleteAll(m_children);
- m_instantiations.clear();
-}
-
-QString AbstractMetaType::package() const
-{
- return m_typeEntry->targetLangPackage();
-}
-
-QString AbstractMetaType::name() const
-{
- return m_typeEntry->targetLangEntryName();
-}
-
-QString AbstractMetaType::fullName() const
-{
- return m_typeEntry->qualifiedTargetLangName();
-}
-
-AbstractMetaType *AbstractMetaType::copy() const
-{
- auto *cpy = new AbstractMetaType;
-
- cpy->setTypeUsagePattern(typeUsagePattern());
- cpy->setConstant(isConstant());
- cpy->setVolatile(isVolatile());
- cpy->setReferenceType(referenceType());
- cpy->setIndirectionsV(indirectionsV());
- cpy->setInstantiations(instantiations());
- cpy->setArrayElementCount(arrayElementCount());
- cpy->setOriginalTypeDescription(originalTypeDescription());
- cpy->setOriginalTemplateType(originalTemplateType() ? originalTemplateType()->copy() : nullptr);
-
- cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : nullptr);
-
- cpy->setTypeEntry(typeEntry());
-
- return cpy;
-}
-
-// For applying the <array> function argument modification: change into a type
-// where "int *" becomes "int[]".
-bool AbstractMetaType::applyArrayModification(QString *errorMessage)
-{
- if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) {
- *errorMessage = QLatin1String("<array> modification already applied.");
- return false;
- }
- if (m_arrayElementType != nullptr) {
- QTextStream(errorMessage) << "The type \"" << cppSignature()
- << "\" is an array of " << m_arrayElementType->name() << '.';
- return false;
- }
- if (m_indirections.isEmpty()) {
- QTextStream(errorMessage) << "The type \"" << cppSignature()
- << "\" does not have indirections.";
- return false;
- }
- // Element type to be used for ArrayHandle<>, strip constness.
- auto elementType = copy();
- elementType->m_indirections.pop_front();
- elementType->setConstant(false);
- elementType->setVolatile(false);
- elementType->decideUsagePattern();
- m_arrayElementType = elementType;
- setTypeUsagePattern(AbstractMetaType::NativePointerAsArrayPattern);
- return true;
-}
-
-AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const
-{
- AbstractMetaTypeCList result;
- switch (m_pattern) {
- case ArrayPattern:
- for (const AbstractMetaType *t = this; t->typeUsagePattern() == ArrayPattern; ) {
- const AbstractMetaType *elt = t->arrayElementType();
- result.append(elt);
- t = elt;
- }
- break;
- case NativePointerAsArrayPattern:
- result.append(m_arrayElementType);
- break;
- default:
- break;
- }
- return result;
-}
-
-bool AbstractMetaType::passByConstRef() const
-{
- return isConstant() && m_referenceType == LValueReference && indirections() == 0;
-}
-
-bool AbstractMetaType::passByValue() const
-{
- return m_referenceType == NoReference && indirections() == 0;
-}
-
-QString AbstractMetaType::cppSignature() const
-{
- if (m_cachedCppSignature.isEmpty())
- m_cachedCppSignature = formatSignature(false);
- return m_cachedCppSignature;
-}
-
-QString AbstractMetaType::pythonSignature() const
-{
- // PYSIDE-921: Handle container returntypes correctly.
- // This is now a clean reimplementation.
- if (m_cachedPythonSignature.isEmpty())
- m_cachedPythonSignature = formatPythonSignature();
- return m_cachedPythonSignature;
-}
-
-AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const
-{
- if (m_typeEntry->isTemplateArgument() || m_referenceType == RValueReference)
- return InvalidPattern;
-
- if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef()))
- return PrimitivePattern;
-
- if (m_typeEntry->isVoid())
- return NativePointerPattern;
-
- if (m_typeEntry->isVarargs())
- return VarargsPattern;
-
- if (m_typeEntry->isEnum() && (actualIndirections() == 0 || passByConstRef()))
- return EnumPattern;
-
- if (m_typeEntry->isObject()) {
- if (indirections() == 0 && m_referenceType == NoReference)
- return ValuePattern;
- return ObjectPattern;
- }
-
- if (m_typeEntry->isContainer() && indirections() == 0)
- return ContainerPattern;
-
- if (m_typeEntry->isSmartPointer() && indirections() == 0)
- return SmartPointerPattern;
-
- if (m_typeEntry->isFlags() && (actualIndirections() == 0 || passByConstRef()))
- return FlagsPattern;
-
- if (m_typeEntry->isArray())
- return ArrayPattern;
-
- if (m_typeEntry->isValue())
- return indirections() == 1 ? ValuePointerPattern : ValuePattern;
-
- return NativePointerPattern;
-}
-
-void AbstractMetaType::decideUsagePattern()
-{
- TypeUsagePattern pattern = determineUsagePattern();
- if (m_typeEntry->isObject() && indirections() == 1
- && m_referenceType == LValueReference && isConstant()) {
- // const-references to pointers can be passed as pointers
- setReferenceType(NoReference);
- setConstant(false);
- pattern = ObjectPattern;
- }
- setTypeUsagePattern(pattern);
-}
-
-bool AbstractMetaType::hasTemplateChildren() const
-{
- QStack<AbstractMetaType *> children;
- children << m_children;
-
- // Recursively iterate over the children / descendants of the type, to check if any of them
- // corresponds to a template argument type.
- while (!children.isEmpty()) {
- AbstractMetaType *child = children.pop();
- if (child->typeEntry()->isTemplateArgument())
- return true;
- children << child->m_children;
- }
-
- return false;
-}
-
-bool AbstractMetaType::compare(const AbstractMetaType &rhs, ComparisonFlags flags) const
-{
- if (m_typeEntry != rhs.m_typeEntry
- || m_indirections != rhs.m_indirections
- || m_instantiations.size() != rhs.m_instantiations.size()
- || m_arrayElementCount != rhs.m_arrayElementCount) {
- return false;
- }
-
- if (m_constant != rhs.m_constant || m_referenceType != rhs.m_referenceType) {
- if (!flags.testFlag(ConstRefMatchesValue)
- || !(passByValue() || passByConstRef())
- || !(rhs.passByValue() || rhs.passByConstRef())) {
- return false;
- }
- }
-
- if ((m_arrayElementType != nullptr) != (rhs.m_arrayElementType != nullptr)
- || (m_arrayElementType != nullptr && !m_arrayElementType->compare(*rhs.m_arrayElementType, flags))) {
- return false;
- }
- for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
- if (!m_instantiations.at(i)->compare(*rhs.m_instantiations.at(i), flags))
- return false;
- }
- return true;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const AbstractMetaType *at)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "AbstractMetaType(";
- if (at) {
- d << at->name();
- if (d.verbosity() > 2) {
- d << ", typeEntry=" << at->typeEntry() << ", signature=\""
- << at->cppSignature() << "\", pattern="
- << at->typeUsagePattern();
- const auto indirections = at->indirectionsV();
- if (!indirections.isEmpty()) {
- d << ", indirections=";
- for (auto i : indirections)
- d << ' ' << TypeInfo::indirectionKeyword(i);
- }
- if (at->referenceType())
- d << ", reftype=" << at->referenceType();
- if (at->isConstant())
- d << ", [const]";
- if (at->isVolatile())
- d << ", [volatile]";
- if (at->isArray()) {
- d << ", array of \"" << at->arrayElementType()->cppSignature()
- << "\", arrayElementCount=" << at->arrayElementCount();
- }
- const auto &instantiations = at->instantiations();
- if (const int instantiationsSize = instantiations.size()) {
- d << ", instantiations[" << instantiationsSize << "]=<";
- for (int i = 0; i < instantiationsSize; ++i) {
- if (i)
- d << ", ";
- d << instantiations.at(i);
- }
- }
- d << '>';
- }
- } else {
- d << '0';
- }
- d << ')';
- return d;
-}
-#endif // !QT_NO_DEBUG_STREAM
-
-/*******************************************************************************
- * AbstractMetaArgument
- */
-
-AbstractMetaArgument::AbstractMetaArgument() = default;
-
-void AbstractMetaArgument::assignMetaArgument(const AbstractMetaArgument &other)
-{
- assignMetaVariable(other);
- m_expression = other.m_expression;
- m_originalExpression = other.m_originalExpression;
- m_argumentIndex = other.m_argumentIndex;
-}
-
-AbstractMetaArgument *AbstractMetaArgument::copy() const
-{
- auto *copy = new AbstractMetaArgument;
- copy->assignMetaArgument(*this);
- return copy;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const AbstractMetaArgument *aa)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "AbstractMetaArgument(";
- if (aa)
- d << aa->toString();
- else
- d << '0';
- d << ')';
- return d;
-}
-#endif // !QT_NO_DEBUG_STREAM
-
-/*******************************************************************************
- * 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()
-{
- qDeleteAll(m_arguments);
- delete m_type;
-}
-
-/*******************************************************************************
- * 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
- AbstractMetaType *t = type();
- AbstractMetaType *ot = other->type();
- if ((!t && !ot) || ((t && ot && t->name() == ot->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());
- if (type())
- cpy->setType(type()->copy());
- cpy->setConstant(isConstant());
- cpy->setExceptionSpecification(m_exceptionSpecification);
- cpy->setAllowThreadModification(m_allowThreadModification);
- cpy->setExceptionHandlingModification(m_exceptionHandlingModification);
- cpy->m_addedFunction = m_addedFunction;
-
- for (AbstractMetaArgument *arg : m_arguments)
- cpy->addArgument(arg->copy());
-
- Q_ASSERT((!type() && !cpy->type())
- || (type()->instantiations() == cpy->type()->instantiations()));
-
- return cpy;
-}
-
-bool AbstractMetaFunction::usesRValueReferences() const
-{
- if (m_functionType == MoveConstructorFunction || m_functionType == MoveAssignmentOperatorFunction)
- return true;
- if (m_type && 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;
-
- 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) {
- AbstractMetaArgument *a = m_arguments.at(i);
- AbstractMetaType *t = a->type();
- if (t) {
- 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;
-}
-
-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;
-}
-
-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 && m_type != nullptr
- && m_arguments.isEmpty();
- return !maybeGetter;
-}
-
-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) {
- AbstractMetaType *t = arguments.at(i)->type();
- if (t) {
- 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;
-}
-
-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);
-}
-
-#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 QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
- if (d.verbosity() > 2) {
- af->formatDebugVerbose(d);
- } else {
-#endif
- d << "signature=";
- formatMetaFunctionBrief(d, af);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
- }
-#endif
- } else {
- d << '0';
- }
- d << ')';
- return d;
-}
-#endif // !QT_NO_DEBUG_STREAM
-
-/*******************************************************************************
- * AbstractMetaClass
- */
-
-AbstractMetaClass::AbstractMetaClass()
- : m_hasVirtuals(false),
- m_isPolymorphic(false),
- m_hasNonpublic(false),
- m_hasNonPrivateConstructor(false),
- m_hasPrivateConstructor(false),
- m_functionsFixed(false),
- m_hasPrivateDestructor(false),
- m_hasProtectedDestructor(false),
- m_hasVirtualDestructor(false),
- m_hasHashFunction(false),
- m_hasEqualsOperator(false),
- m_hasCloneOperator(false),
- m_isTypeDef(false),
- m_hasToStringCapability(false)
-{
-}
-
-AbstractMetaClass::~AbstractMetaClass()
-{
- qDeleteAll(m_functions);
- qDeleteAll(m_fields);
- qDeleteAll(m_enums);
- if (hasTemplateBaseClassInstantiations())
- qDeleteAll(templateBaseClassInstantiations());
-}
-
-/*******************************************************************************
- * Returns true if this class is a subclass of the given class
- */
-bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
-{
- Q_ASSERT(cls);
-
- const AbstractMetaClass *clazz = this;
- while (clazz) {
- if (clazz == cls)
- return true;
-
- clazz = clazz->baseClass();
- }
-
- return false;
-}
-
-/*******************************************************************************
- * Returns a list of all the functions with a given name
- */
-AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const
-{
- AbstractMetaFunctionList returned;
- for (AbstractMetaFunction *function : m_functions) {
- if (function->name() == name)
- returned.append(function);
- }
-
- return returned;
-}
-
-/*******************************************************************************
- * Returns a list of all the functions retrieved during parsing which should
- * be added to the API.
- */
-AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const
-{
- FunctionQueryOptions default_flags = NormalFunctions | Visible | NotRemovedFromTargetLang;
-
- // Only public functions in final classes
- // default_flags |= isFinal() ? WasPublic : 0;
- FunctionQueryOptions public_flags;
- if (isFinalInTargetLang())
- public_flags |= WasPublic;
-
- // Constructors
- AbstractMetaFunctionList returned = queryFunctions(Constructors | default_flags | public_flags);
-
- // Final functions
- returned += queryFunctions(FinalInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags);
-
- // Virtual functions
- returned += queryFunctions(VirtualInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags);
-
- // Static functions
- returned += queryFunctions(StaticFunctions | default_flags | public_flags);
-
- // Empty, private functions, since they aren't caught by the other ones
- returned += queryFunctions(Empty | Invisible);
-
- return returned;
-}
-
-AbstractMetaFunctionList AbstractMetaClass::implicitConversions() const
-{
- if (!hasCloneOperator() && !hasExternalConversionOperators())
- return AbstractMetaFunctionList();
-
- AbstractMetaFunctionList returned;
- const AbstractMetaFunctionList list = queryFunctions(Constructors) + externalConversionOperators();
-
- // Exclude anything that uses rvalue references, be it a move
- // constructor "QPolygon(QPolygon &&)" or something else like
- // "QPolygon(QVector<QPoint> &&)".
- for (AbstractMetaFunction *f : list) {
- if ((f->actualMinimumArgumentCount() == 1 || f->arguments().size() == 1 || f->isConversionOperator())
- && !f->isExplicit()
- && f->functionType() != AbstractMetaFunction::CopyConstructorFunction
- && !f->usesRValueReferences()
- && !f->isModifiedRemoved()
- && (f->originalAttributes() & Public)) {
- returned += f;
- }
- }
- return returned;
-}
-
-AbstractMetaFunctionList AbstractMetaClass::operatorOverloads(OperatorQueryOptions query) const
-{
- const AbstractMetaFunctionList &list = queryFunctions(OperatorOverloads | Visible);
- AbstractMetaFunctionList returned;
- for (AbstractMetaFunction *f : list) {
- if (((query & ArithmeticOp) && f->isArithmeticOperator())
- || ((query & BitwiseOp) && f->isBitwiseOperator())
- || ((query & ComparisonOp) && f->isComparisonOperator())
- || ((query & LogicalOp) && f->isLogicalOperator())
- || ((query & SubscriptionOp) && f->isSubscriptOperator())
- || ((query & AssignmentOp) && f->isAssignmentOperator())
- || ((query & ConversionOp) && f->isConversionOperator())
- || ((query & OtherOp) && f->isOtherOperator()))
- returned += f;
- }
-
- return returned;
-}
-
-bool AbstractMetaClass::hasArithmeticOperatorOverload() const
-{
- for (const AbstractMetaFunction *f : m_functions) {
- if (f->ownerClass() == f->implementingClass() && f->isArithmeticOperator() && !f->isPrivate())
- return true;
- }
- return false;
-}
-
-bool AbstractMetaClass::hasBitwiseOperatorOverload() const
-{
- for (const AbstractMetaFunction *f : m_functions) {
- if (f->ownerClass() == f->implementingClass() && f->isBitwiseOperator() && !f->isPrivate())
- return true;
- }
- return false;
-}
-
-bool AbstractMetaClass::hasComparisonOperatorOverload() const
-{
- for (const AbstractMetaFunction *f : m_functions) {
- if (f->ownerClass() == f->implementingClass() && f->isComparisonOperator() && !f->isPrivate())
- return true;
- }
- return false;
-}
-
-bool AbstractMetaClass::hasLogicalOperatorOverload() const
-{
- for (const AbstractMetaFunction *f : m_functions) {
- if (f->ownerClass() == f->implementingClass() && f->isLogicalOperator() && !f->isPrivate())
- return true;
- }
- return false;
-}
-
-void AbstractMetaClass::sortFunctions()
-{
- std::sort(m_functions.begin(), m_functions.end(), function_sorter);
-}
-
-void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions)
-{
- m_functions = functions;
-
- // Functions must be sorted by name before next loop
- sortFunctions();
-
- for (AbstractMetaFunction *f : qAsConst(m_functions)) {
- f->setOwnerClass(this);
- if (!f->isPublic())
- m_hasNonpublic = true;
- }
-}
-
-bool AbstractMetaClass::hasFieldAccessors() const
-{
- for (const AbstractMetaField *field : m_fields) {
- if (field->getter() || field->setter())
- return true;
- }
-
- return false;
-}
-
-bool AbstractMetaClass::hasDefaultToStringFunction() const
-{
- const AbstractMetaFunctionList &funcs = queryFunctionsByName(QLatin1String("toString"));
- for (const AbstractMetaFunction *f : funcs) {
- if (!f->actualMinimumArgumentCount())
- return true;
- }
- return false;
-}
-
-void AbstractMetaClass::addFunction(AbstractMetaFunction *function)
-{
- Q_ASSERT(!function->signature().startsWith(QLatin1Char('(')));
- function->setOwnerClass(this);
-
- if (!function->isDestructor())
- m_functions << function;
- else
- Q_ASSERT(false); //memory leak
-
- m_hasVirtuals |= function->isVirtual();
- m_isPolymorphic |= m_hasVirtuals;
- m_hasNonpublic |= !function->isPublic();
-}
-
-bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const
-{
- if (!other->isSignal())
- return false;
-
- for (const AbstractMetaFunction *f : m_functions) {
- if (f->isSignal() && f->compareTo(other) & AbstractMetaFunction::EqualName)
- return other->modifiedName() == f->modifiedName();
- }
-
- return false;
-}
-
-
-QString AbstractMetaClass::name() const
-{
- return m_typeEntry->targetLangEntryName();
-}
-
-void AbstractMetaClass::addBaseClass(AbstractMetaClass *baseClass)
-{
- Q_ASSERT(baseClass);
- m_baseClasses.append(baseClass);
- m_isPolymorphic |= baseClass->isPolymorphic();
-}
-
-void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass)
-{
- if (baseClass) {
- m_baseClasses.prepend(baseClass);
- m_isPolymorphic |= baseClass->isPolymorphic();
- }
-}
-
-QString AbstractMetaClass::package() const
-{
- return m_typeEntry->targetLangPackage();
-}
-
-bool AbstractMetaClass::isNamespace() const
-{
- return m_typeEntry->isNamespace();
-}
-
-static bool qObjectPredicate(const AbstractMetaClass *c)
-{
- return c->qualifiedCppName() == QLatin1String("QObject");
-}
-
-bool AbstractMetaClass::isQObject() const
-{
- return qObjectPredicate(this) || recurseClassHierarchy(this, qObjectPredicate) != nullptr;
-}
-
-QString AbstractMetaClass::qualifiedCppName() const
-{
- return m_typeEntry->qualifiedCppName();
-}
-
-bool AbstractMetaClass::hasFunction(const QString &str) const
-{
- return findFunction(str);
-}
-
-const AbstractMetaFunction *AbstractMetaClass::findFunction(const QString &functionName) const
-{
- return AbstractMetaFunction::find(m_functions, functionName);
-}
-
-bool AbstractMetaClass::hasProtectedFunctions() const
-{
- for (AbstractMetaFunction *func : m_functions) {
- if (func->isProtected())
- return true;
- }
- return false;
-}
-
-bool AbstractMetaClass::hasProtectedFields() const
-{
- for (const AbstractMetaField *field : m_fields) {
- if (field->isProtected())
- return true;
- }
- return false;
-}
-
-bool AbstractMetaClass::hasProtectedMembers() const
-{
- return hasProtectedFields() || hasProtectedFunctions();
-}
-
-QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const
-{
- for (const auto &propertySpec : m_propertySpecs) {
- if (name == propertySpec->read())
- return propertySpec;
- }
- return nullptr;
-}
-
-QPropertySpec *AbstractMetaClass::propertySpecForWrite(const QString &name) const
-{
- for (const auto &propertySpec : m_propertySpecs) {
- if (name == propertySpec->write())
- return propertySpec;
- }
- return nullptr;
-}
-
-QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) const
-{
- for (const auto &propertySpec : m_propertySpecs) {
- if (name == propertySpec->reset())
- return propertySpec;
- }
- return nullptr;
-}
-
-using AbstractMetaClassBaseTemplateInstantiationsMap = QHash<const AbstractMetaClass *, AbstractMetaTypeList>;
-Q_GLOBAL_STATIC(AbstractMetaClassBaseTemplateInstantiationsMap, metaClassBaseTemplateInstantiations);
-
-bool AbstractMetaClass::hasTemplateBaseClassInstantiations() const
-{
- if (!templateBaseClass())
- return false;
- return metaClassBaseTemplateInstantiations()->contains(this);
-}
-
-AbstractMetaTypeList AbstractMetaClass::templateBaseClassInstantiations() const
-{
- if (!templateBaseClass())
- return AbstractMetaTypeList();
- return metaClassBaseTemplateInstantiations()->value(this);
-}
-
-void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList &instantiations)
-{
- if (!templateBaseClass())
- return;
- metaClassBaseTemplateInstantiations()->insert(this, instantiations);
-}
-
-// Does any of the base classes require deletion in the main thread?
-bool AbstractMetaClass::deleteInMainThread() const
-{
- return typeEntry()->deleteInMainThread()
- || (!m_baseClasses.isEmpty() && m_baseClasses.constFirst()->deleteInMainThread());
-}
-
-static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
-{
- for (const AbstractMetaFunction *f : l) {
- if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar)
- return true;
- }
- return false;
-}
-
-AbstractMetaField::AbstractMetaField() = default;
-
-AbstractMetaField::~AbstractMetaField()
-{
- delete m_setter;
- delete m_getter;
-}
-
-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;
-}
-
-static QString upCaseFirst(const QString &str)
-{
- Q_ASSERT(!str.isEmpty());
- QString s = str;
- s[0] = s.at(0).toUpper();
- return s;
-}
-
-static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QString &name,
- AbstractMetaAttributes::Attributes type)
-{
- auto *f = new AbstractMetaFunction;
-
- f->setName(name);
- f->setOriginalName(name);
- f->setOwnerClass(g->enclosingClass());
- f->setImplementingClass(g->enclosingClass());
- f->setDeclaringClass(g->enclosingClass());
-
- AbstractMetaAttributes::Attributes attr = AbstractMetaAttributes::FinalInTargetLang | type;
- if (g->isStatic())
- attr |= AbstractMetaAttributes::Static;
- if (g->isPublic())
- attr |= AbstractMetaAttributes::Public;
- else if (g->isProtected())
- attr |= AbstractMetaAttributes::Protected;
- else
- attr |= AbstractMetaAttributes::Private;
- f->setAttributes(attr);
- f->setOriginalAttributes(attr);
-
- const FieldModificationList &mods = g->modifications();
- for (const FieldModification &mod : mods) {
- if (mod.isRenameModifier())
- f->setName(mod.renamedTo());
- if (mod.isAccessModifier()) {
- if (mod.isPrivate())
- f->setVisibility(AbstractMetaAttributes::Private);
- else if (mod.isProtected())
- f->setVisibility(AbstractMetaAttributes::Protected);
- else if (mod.isPublic())
- f->setVisibility(AbstractMetaAttributes::Public);
- else if (mod.isFriendly())
- f->setVisibility(AbstractMetaAttributes::Friendly);
- }
- }
- return f;
-}
-
-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 AbstractMetaFunction *AbstractMetaField::setter() const
-{
- if (!m_setter) {
- m_setter = createXetter(this,
- QLatin1String("set") + upCaseFirst(name()),
- AbstractMetaAttributes::SetterFunction);
- AbstractMetaArgumentList arguments;
- auto *argument = new AbstractMetaArgument;
- argument->setType(type()->copy());
- argument->setName(name());
- arguments.append(argument);
- m_setter->setArguments(arguments);
- }
- return m_setter;
-}
-
-const AbstractMetaClass *EnclosingClassMixin::targetLangEnclosingClass() const
-{
- auto result = m_enclosingClass;
- while (result && !NamespaceTypeEntry::isVisibleScope(result->typeEntry()))
- result = result->enclosingClass();
- return result;
-}
-
-const AbstractMetaFunction *AbstractMetaField::getter() const
-{
- if (!m_getter) {
- m_getter = createXetter(this,
- name(),
- AbstractMetaAttributes::GetterFunction);
- m_getter->setType(type());
- }
-
- return m_getter;
-}
-
-#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;
-}
-
-const AbstractMetaFunction *AbstractMetaClass::copyConstructor() const
-{
- for (const AbstractMetaFunction *f : m_functions) {
- if (f->functionType() == AbstractMetaFunction::CopyConstructorFunction)
- return f;
- }
- return nullptr;
-}
-
-bool AbstractMetaClass::hasPrivateCopyConstructor() const
-{
- const AbstractMetaFunction *copyCt = copyConstructor();
- return copyCt && copyCt->isPrivate();
-}
-
-void AbstractMetaClass::addDefaultConstructor()
-{
- auto *f = new AbstractMetaFunction;
- f->setOriginalName(name());
- f->setName(name());
- f->setOwnerClass(this);
- f->setFunctionType(AbstractMetaFunction::ConstructorFunction);
- f->setArguments(AbstractMetaArgumentList());
- f->setDeclaringClass(this);
-
- f->setAttributes(Public | FinalInTargetLang | AddedMethod);
- f->setImplementingClass(this);
- f->setOriginalAttributes(f->attributes());
-
- addFunction(f);
- this->setHasNonPrivateConstructor(true);
-}
-
-void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate)
-{
- auto f = new AbstractMetaFunction;
- f->setOriginalName(name());
- f->setName(name());
- f->setOwnerClass(this);
- f->setFunctionType(AbstractMetaFunction::CopyConstructorFunction);
- f->setDeclaringClass(this);
-
- auto argType = new AbstractMetaType;
- argType->setTypeEntry(typeEntry());
- argType->setReferenceType(LValueReference);
- argType->setConstant(true);
- argType->setTypeUsagePattern(AbstractMetaType::ValuePattern);
-
- auto arg = new AbstractMetaArgument;
- arg->setType(argType);
- arg->setName(name());
- f->addArgument(arg);
-
- AbstractMetaAttributes::Attributes attr = FinalInTargetLang | AddedMethod;
- if (isPrivate)
- attr |= AbstractMetaAttributes::Private;
- else
- attr |= AbstractMetaAttributes::Public;
- f->setAttributes(attr);
- f->setImplementingClass(this);
- f->setOriginalAttributes(f->attributes());
-
- addFunction(f);
-}
-
-void AbstractMetaClass::setHasVirtualDestructor(bool value)
-{
- m_hasVirtualDestructor = value;
- if (value)
- m_hasVirtuals = m_isPolymorphic = 1;
-}
-
-bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const
-{
- return functions_contains(m_functions, f);
-}
-
-bool AbstractMetaClass::generateExceptionHandling() const
-{
- return queryFirstFunction(m_functions, AbstractMetaClass::Visible
- | AbstractMetaClass::GenerateExceptionHandling) != nullptr;
-}
-/* Goes through the list of functions and returns a list of all
- functions matching all of the criteria in \a query.
- */
-
-bool AbstractMetaClass::queryFunction(const AbstractMetaFunction *f, FunctionQueryOptions query)
-{
- if ((query & NotRemovedFromTargetLang)
- && f->isRemovedFrom(f->implementingClass(), TypeSystem::TargetLangCode)) {
- return false;
- }
-
- if ((query & NotRemovedFromTargetLang) && f->isVirtual()
- && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode)) {
- return false;
- }
-
- if ((query & Visible) && f->isPrivate())
- return false;
-
- if ((query & VirtualInTargetLangFunctions) && f->isFinalInTargetLang())
- return false;
-
- if ((query & Invisible) && !f->isPrivate())
- return false;
-
- if ((query & Empty) && !f->isEmptyFunction())
- return false;
-
- if ((query & WasPublic) && !f->wasPublic())
- return false;
-
- if ((query & ClassImplements) && f->ownerClass() != f->implementingClass())
- return false;
-
- if ((query & FinalInTargetLangFunctions) && !f->isFinalInTargetLang())
- return false;
-
- if ((query & VirtualInCppFunctions) && !f->isVirtual())
- return false;
-
- if ((query & Signals) && (!f->isSignal()))
- return false;
-
- if ((query & Constructors) && (!f->isConstructor() || f->ownerClass() != f->implementingClass()))
- return false;
-
- if (!(query & Constructors) && f->isConstructor())
- return false;
-
- // Destructors are never included in the functions of a class currently
- /*
- if ((query & Destructors) && (!f->isDestructor()
- || f->ownerClass() != f->implementingClass())
- || f->isDestructor() && (query & Destructors) == 0) {
- return false;
- }*/
-
- if ((query & StaticFunctions) && (!f->isStatic() || f->isSignal()))
- return false;
-
- if ((query & NonStaticFunctions) && (f->isStatic()))
- return false;
-
- if ((query & NormalFunctions) && (f->isSignal()))
- return false;
-
- if ((query & OperatorOverloads) && !f->isOperatorOverload())
- return false;
-
- if ((query & GenerateExceptionHandling) && !f->generateExceptionHandling())
- return false;
-
- if (query.testFlag(GetAttroFunction)
- && f->functionType() != AbstractMetaFunction::GetAttroFunction) {
- return false;
- }
-
- if (query.testFlag(SetAttroFunction)
- && f->functionType() != AbstractMetaFunction::SetAttroFunction) {
- return false;
- }
-
- return true;
-}
-
-AbstractMetaFunctionList AbstractMetaClass::queryFunctionList(const AbstractMetaFunctionList &list,
- FunctionQueryOptions query)
-{
- AbstractMetaFunctionList result;
- for (AbstractMetaFunction *f : list) {
- if (queryFunction(f, query))
- result.append(f);
- }
- return result;
-}
-
-const AbstractMetaFunction *AbstractMetaClass::queryFirstFunction(const AbstractMetaFunctionList &list,
- FunctionQueryOptions query)
-{
- AbstractMetaFunctionList result;
- for (AbstractMetaFunction *f : list) {
- if (queryFunction(f, query))
- return f;
- }
- return nullptr;
-}
-
-AbstractMetaFunctionList AbstractMetaClass::queryFunctions(FunctionQueryOptions query) const
-{
- return AbstractMetaClass::queryFunctionList(m_functions, query);
-}
-
-bool AbstractMetaClass::hasSignals() const
-{
- return queryFirstFunction(m_functions, Signals | Visible | NotRemovedFromTargetLang) != nullptr;
-}
-
-AbstractMetaFunctionList AbstractMetaClass::cppSignalFunctions() const
-{
- return queryFunctions(Signals | Visible | NotRemovedFromTargetLang);
-}
-
-AbstractMetaField *AbstractMetaClass::findField(const QString &name) const
-{
- return AbstractMetaField::find(m_fields, name);
-}
-
-AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
-{
- if (AbstractMetaEnum *e = findByName(m_enums, enumName))
- return e;
- return nullptr;
-}
-
-/*! Recursively searches for the enum value named \a enumValueName in
- this class and its superclasses and interfaces.
-*/
-AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValueName)
-{
- for (AbstractMetaEnum *e : qAsConst(m_enums)) {
- if (AbstractMetaEnumValue *v = e->findEnumValue(enumValueName))
- return v;
- }
- if (baseClass())
- return baseClass()->findEnumValue(enumValueName);
-
- return nullptr;
-}
-
-
-static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType *type)
-{
- if (!type)
- return;
-
- Q_ASSERT(metaClass);
- const TypeEntry *entry = (type ? type->typeEntry() : nullptr);
- if (entry && entry->isComplex()) {
- const auto *centry = static_cast<const ComplexTypeEntry *>(entry);
- ComplexTypeEntry *class_entry = metaClass->typeEntry();
- if (class_entry && centry->include().isValid())
- class_entry->addExtraInclude(centry->include());
- }
-
- if (type->hasInstantiations()) {
- const AbstractMetaTypeList &instantiations = type->instantiations();
- for (const AbstractMetaType *instantiation : instantiations)
- addExtraIncludeForType(metaClass, instantiation);
- }
-}
-
-static void addExtraIncludesForFunction(AbstractMetaClass *metaClass, const AbstractMetaFunction *meta_function)
-{
- Q_ASSERT(metaClass);
- Q_ASSERT(meta_function);
- addExtraIncludeForType(metaClass, meta_function->type());
-
- const AbstractMetaArgumentList &arguments = meta_function->arguments();
- for (AbstractMetaArgument *argument : arguments)
- addExtraIncludeForType(metaClass, argument->type());
-}
-
-void AbstractMetaClass::fixFunctions()
-{
- if (m_functionsFixed)
- return;
-
- m_functionsFixed = true;
-
- AbstractMetaFunctionList funcs = functions();
-
- for (auto superClass : m_baseClasses) {
- superClass->fixFunctions();
- // Since we always traverse the complete hierarchy we are only
- // interrested in what each super class implements, not what
- // we may have propagated from their base classes again.
- AbstractMetaFunctionList superFuncs;
- // Super classes can never be final
- if (superClass->isFinalInTargetLang()) {
- qCWarning(lcShiboken).noquote().nospace()
- << "Final class '" << superClass->name() << "' set to non-final, as it is extended by other classes";
- *superClass -= AbstractMetaAttributes::FinalInTargetLang;
- }
- superFuncs = superClass->queryFunctions(AbstractMetaClass::ClassImplements);
- AbstractMetaFunctionList virtuals = superClass->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
- superFuncs += virtuals;
-
- QSet<AbstractMetaFunction *> funcsToAdd;
- for (auto sf : qAsConst(superFuncs)) {
- if (sf->isRemovedFromAllLanguages(sf->implementingClass()))
- continue;
-
- // skip functions added in base classes
- if (sf->isUserAdded() && sf->declaringClass() != this)
- continue;
-
- // we generally don't care about private functions, but we have to get the ones that are
- // virtual in case they override abstract functions.
- bool add = (sf->isNormal() || sf->isSignal() || sf->isEmptyFunction());
- for (AbstractMetaFunction *f : funcs) {
- if (f->isRemovedFromAllLanguages(f->implementingClass()))
- continue;
-
-
- const AbstractMetaFunction::CompareResult cmp = f->compareTo(sf);
-
- if (cmp & AbstractMetaFunction::EqualModifiedName) {
- add = false;
- if (cmp & AbstractMetaFunction::EqualArguments) {
- // Same function, propegate virtual...
- if (!(cmp & AbstractMetaFunction::EqualAttributes)) {
- if (!f->isEmptyFunction()) {
- if (!sf->isFinalInTargetLang() && f->isFinalInTargetLang()) {
- *f -= AbstractMetaAttributes::FinalInTargetLang;
- }
-#if 0
- if (!f->isFinalInTargetLang() && f->isPrivate()) {
- f->setFunctionType(AbstractMetaFunction::EmptyFunction);
- f->setVisibility(AbstractMetaAttributes::Protected);
- *f += AbstractMetaAttributes::FinalInTargetLang;
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("private virtual function '%1' in '%2'")
- .arg(f->signature(), f->implementingClass()->name());
- }
-#endif
- }
- }
-
- if (f->visibility() != sf->visibility()) {
- QString warn = QStringLiteral("visibility of function '%1' modified in class '%2'")
- .arg(f->name(), name());
- qCWarning(lcShiboken).noquote().nospace() << warn;
-#if 0
- // If new visibility is private, we can't
- // do anything. If it isn't, then we
- // prefer the parent class's visibility
- // setting for the function.
- if (!f->isPrivate() && !sf->isPrivate())
- f->setVisibility(sf->visibility());
-#endif
- // Private overrides of abstract functions have to go into the class or
- // the subclasses will not compile as non-abstract classes.
- // But they don't need to be implemented, since they can never be called.
- if (f->isPrivate()) {
- f->setFunctionType(AbstractMetaFunction::EmptyFunction);
- *f += AbstractMetaAttributes::FinalInTargetLang;
- }
- }
-
- // Set the class which first declares this function, afawk
- f->setDeclaringClass(sf->declaringClass());
-
- if (sf->isFinalInTargetLang() && !sf->isPrivate() && !f->isPrivate() && !sf->isStatic() && !f->isStatic()) {
- // Shadowed funcion, need to make base class
- // function non-virtual
- if (f->implementingClass() != sf->implementingClass() && f->implementingClass()->inheritsFrom(sf->implementingClass())) {
-
- // Check whether the superclass method has been redefined to non-final
-
- bool hasNonFinalModifier = false;
- bool isBaseImplPrivate = false;
- const FunctionModificationList &mods = sf->modifications(sf->implementingClass());
- for (const FunctionModification &mod : mods) {
- if (mod.isNonFinal()) {
- hasNonFinalModifier = true;
- break;
- }
- if (mod.isPrivate()) {
- isBaseImplPrivate = true;
- break;
- }
- }
-
- if (!hasNonFinalModifier && !isBaseImplPrivate) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("Shadowing: %1::%2 and %3::%4")
- .arg(sf->implementingClass()->name(), sf->signature(),
- f->implementingClass()->name(), f->signature());
- }
- }
- }
-
- }
-
- if (cmp & AbstractMetaFunction::EqualDefaultValueOverload) {
- AbstractMetaArgumentList arguments;
- if (f->arguments().size() < sf->arguments().size())
- arguments = sf->arguments();
- else
- arguments = f->arguments();
- //TODO: fix this
- //for (int i=0; i<arguments.size(); ++i)
- // arguments[i]->setDefaultValueExpression("<#>" + QString());
- }
-
-
- // Otherwise we have function shadowing and we can
- // skip the thing...
- } else if (cmp & AbstractMetaFunction::EqualName && !sf->isSignal()) {
- // In the case of function shadowing where the function name has been altered to
- // avoid conflict, we don't copy in the original.
- add = false;
- }
- }
-
- if (add)
- funcsToAdd << sf;
- }
-
- for (AbstractMetaFunction *f : qAsConst(funcsToAdd)) {
- AbstractMetaFunction *copy = f->copy();
- (*copy) += AddedMethod;
- funcs.append(copy);
- }
- }
-
- bool hasPrivateConstructors = false;
- bool hasPublicConstructors = false;
- for (AbstractMetaFunction *func : qAsConst(funcs)) {
- const FunctionModificationList &mods = func->modifications(this);
- for (const FunctionModification &mod : mods) {
- if (mod.isRenameModifier()) {
- func->setName(mod.renamedTo());
- }
- }
-
- // Make sure class is abstract if one of the functions is
- if (func->isAbstract()) {
- (*this) += AbstractMetaAttributes::Abstract;
- (*this) -= AbstractMetaAttributes::FinalInTargetLang;
- }
-
- if (func->isConstructor()) {
- if (func->isPrivate())
- hasPrivateConstructors = true;
- else
- hasPublicConstructors = true;
- }
-
-
-
- // Make sure that we include files for all classes that are in use
-
- if (!func->isRemovedFrom(this, TypeSystem::ShellCode))
- addExtraIncludesForFunction(this, func);
- }
-
- if (hasPrivateConstructors && !hasPublicConstructors) {
- (*this) += AbstractMetaAttributes::Abstract;
- (*this) -= AbstractMetaAttributes::FinalInTargetLang;
- }
-
- setFunctions(funcs);
-}
-
-static inline QString formatArraySize(int e)
-{
- QString result;
- result += QLatin1Char('[');
- if (e >= 0)
- result += QString::number(e);
- result += QLatin1Char(']');
- return result;
-}
-
-QString AbstractMetaType::formatSignature(bool minimal) const
-{
- QString result;
- if (isConstant())
- result += QLatin1String("const ");
- if (isVolatile())
- result += QLatin1String("volatile ");
- if (isArray()) {
- // Build nested array dimensions a[2][3] in correct order
- result += m_arrayElementType->minimalSignature();
- const int arrayPos = result.indexOf(QLatin1Char('['));
- if (arrayPos != -1)
- result.insert(arrayPos, formatArraySize(m_arrayElementCount));
- else
- result.append(formatArraySize(m_arrayElementCount));
- } else {
- result += typeEntry()->qualifiedCppName();
- }
- if (!m_instantiations.isEmpty()) {
- result += QLatin1Char('<');
- if (minimal)
- result += QLatin1Char(' ');
- for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
- if (i > 0)
- result += QLatin1Char(',');
- result += m_instantiations.at(i)->minimalSignature();
- }
- result += QLatin1String(" >");
- }
-
- if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference))
- result += QLatin1Char(' ');
- for (Indirection i : m_indirections)
- result += TypeInfo::indirectionKeyword(i);
- switch (referenceType()) {
- case NoReference:
- break;
- case LValueReference:
- result += QLatin1Char('&');
- break;
- case RValueReference:
- result += QLatin1String("&&");
- break;
- }
- return result;
-}
-
-QString AbstractMetaType::formatPythonSignature() const
-{
- /*
- * This is a version of the above, more suitable for Python.
- * We avoid extra keywords that are not needed in Python.
- * We prepend the package name, unless it is a primitive type.
- *
- * Primitive types like 'int', 'char' etc.:
- * When we have a primitive with an indirection, we use that '*'
- * character for later postprocessing, since those indirections
- * need to be modified into a result tuple.
- */
- QString result;
- if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern)
- result += QLatin1String("array ");
- // We no longer use the "const" qualifier for heuristics. Instead,
- // NativePointerAsArrayPattern indicates when we have <array> in XML.
- // if (m_typeEntry->isPrimitive() && isConstant())
- // result += QLatin1String("const ");
- if (!m_typeEntry->isPrimitive() && !package().isEmpty())
- result += package() + QLatin1Char('.');
- if (isArray()) {
- // Build nested array dimensions a[2][3] in correct order
- result += m_arrayElementType->formatPythonSignature();
- const int arrayPos = result.indexOf(QLatin1Char('['));
- if (arrayPos != -1)
- result.insert(arrayPos, formatArraySize(m_arrayElementCount));
- else
- result.append(formatArraySize(m_arrayElementCount));
- } else {
- result += typeEntry()->targetLangName();
- }
- if (!m_instantiations.isEmpty()) {
- result += QLatin1Char('[');
- for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
- if (i > 0)
- result += QLatin1String(", ");
- result += m_instantiations.at(i)->formatPythonSignature();
- }
- result += QLatin1Char(']');
- }
- if (m_typeEntry->isPrimitive())
- for (Indirection i : m_indirections)
- result += TypeInfo::indirectionKeyword(i);
- // If it is a flags type, we replace it with the full name:
- // "PySide2.QtCore.Qt.ItemFlags" instead of "PySide2.QtCore.QFlags<Qt.ItemFlag>"
- if (m_typeEntry->isFlags())
- result = fullName();
- result.replace(QLatin1String("::"), QLatin1String("."));
- return result;
-}
-
-bool AbstractMetaType::isCppPrimitive() const
-{
- return m_pattern == PrimitivePattern && m_typeEntry->isCppPrimitive();
-}
-
-/*******************************************************************************
- * Other stuff...
- */
-
-
-AbstractMetaEnum *AbstractMetaClass::findEnum(const AbstractMetaClassList &classes,
- const EnumTypeEntry *entry)
-{
- Q_ASSERT(entry->isEnum());
-
- QString qualifiedName = entry->qualifiedCppName();
- int pos = qualifiedName.lastIndexOf(QLatin1String("::"));
-
- QString enumName;
- QString className;
-
- if (pos > 0) {
- enumName = qualifiedName.mid(pos + 2);
- className = qualifiedName.mid(0, pos);
- } else {
- enumName = qualifiedName;
- className = TypeDatabase::globalNamespaceClassName(entry);
- }
-
- AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes, className);
- if (!metaClass) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("AbstractMeta::findEnum(), unknown class '%1' in '%2'")
- .arg(className, entry->qualifiedCppName());
- return nullptr;
- }
-
- return metaClass->findEnum(enumName);
-}
-
-AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const AbstractMetaClassList &classes,
- const QString &name)
-{
- const QVector<QStringRef> lst = name.splitRef(QLatin1String("::"));
-
- if (lst.size() > 1) {
- const QStringRef &prefixName = lst.at(0);
- const QStringRef &enumName = lst.at(1);
- if (AbstractMetaClass *cl = findClass(classes, prefixName.toString()))
- return cl->findEnumValue(enumName.toString());
- }
-
- for (AbstractMetaClass *metaClass : classes) {
- if (AbstractMetaEnumValue *enumValue = metaClass->findEnumValue(name))
- return enumValue;
- }
-
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("no matching enum '%1'").arg(name);
- return nullptr;
-}
-
-/*!
- * Searches the list after a class that mathces \a name; either as
- * C++, Target language base name or complete Target language package.class name.
- */
-
-AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
- const QString &name)
-{
- if (name.isEmpty())
- return nullptr;
-
- for (AbstractMetaClass *c : classes) {
- if (c->qualifiedCppName() == name)
- return c;
- }
-
- for (AbstractMetaClass *c : classes) {
- if (c->fullName() == name)
- return c;
- }
-
- for (AbstractMetaClass *c : classes) {
- if (c->name() == name)
- return c;
- }
-
- return nullptr;
-}
-
-AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
- const TypeEntry *typeEntry)
-{
- for (AbstractMetaClass *c : classes) {
- if (c->typeEntry() == typeEntry)
- return c;
- }
- return nullptr;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-
-void AbstractMetaClass::format(QDebug &d) const
-{
- if (d.verbosity() > 2)
- d << static_cast<const void *>(this) << ", ";
- d << '"' << qualifiedCppName();
- if (const int count = m_templateArgs.size()) {
- for (int i = 0; i < count; ++i)
- d << (i ? ',' : '<') << m_templateArgs.at(i)->qualifiedCppName();
- d << '>';
- }
- d << '"';
- if (isNamespace())
- d << " [namespace]";
- if (attributes() & AbstractMetaAttributes::FinalCppClass)
- d << " [final]";
- if (attributes().testFlag(AbstractMetaAttributes::Deprecated))
- d << " [deprecated]";
- if (!m_baseClasses.isEmpty()) {
- d << ", inherits ";
- for (auto b : m_baseClasses)
- d << " \"" << b->name() << '"';
- }
- if (auto templateBase = templateBaseClass()) {
- const auto instantiatedTypes = templateBaseClassInstantiations();
- d << ", instantiates \"" << templateBase->name();
- for (int i = 0, count = instantiatedTypes.size(); i < count; ++i)
- d << (i ? ',' : '<') << instantiatedTypes.at(i)->name();
- d << ">\"";
- }
-}
-
-void AbstractMetaClass::formatMembers(QDebug &d) const
-{
- if (!m_enums.isEmpty())
- d << ", enums[" << m_enums.size() << "]=" << m_enums;
- if (!m_functions.isEmpty()) {
- const int count = m_functions.size();
- d << ", functions=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- formatMetaFunctionBrief(d, m_functions.at(i));
- }
- d << ')';
- }
- if (const int count = m_fields.size()) {
- d << ", fields=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- formatMetaField(d, m_fields.at(i));
- }
- d << ')';
- }
-}
-
-QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "AbstractMetaClass(";
- if (ac) {
- ac->format(d);
- if (d.verbosity() > 2)
- ac->formatMembers(d);
- } else {
- d << '0';
- }
- d << ')';
- 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() == value.leftRef(sepPos)
- ? findMatchingEnumValue(m_enumValues, value.rightRef(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();
-}