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.cpp693
1 files changed, 323 insertions, 370 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index a040f3caa..f1f01e02c 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -28,6 +28,7 @@
#include "abstractmetalang.h"
#include "messages.h"
+#include "propertyspec.h"
#include "reporthandler.h"
#include "typedatabase.h"
#include "typesystem.h"
@@ -80,19 +81,57 @@ const AbstractMetaClass *recurseClassHierarchy(const AbstractMetaClass *klass,
{
if (pred(klass))
return klass;
- if (auto base = klass->baseClass()) {
+ for (auto base : klass->baseClasses()) {
if (auto r = recurseClassHierarchy(base, pred))
return r;
}
- const auto interfaces = klass->interfaces();
- for (auto i : interfaces) {
- if (auto r = recurseClassHierarchy(i, pred))
- return r;
- }
return nullptr;
}
/*******************************************************************************
+ * Documentation
+ */
+
+Documentation::Documentation(const QString &value, Documentation::Type t, Documentation::Format fmt)
+{
+ setValue(value, t, fmt);
+}
+
+bool Documentation::isEmpty() const
+{
+ for (int i = 0; i < Type::Last; i++) {
+ if (!m_data.value(static_cast<Type>(i)).isEmpty())
+ return false;
+ }
+ return true;
+}
+
+QString Documentation::value(Documentation::Type t) const
+{
+ return m_data.value(t);
+}
+
+void Documentation::setValue(const QString &value, Documentation::Type t, Documentation::Format fmt)
+{
+ const QString v = value.trimmed();
+ if (v.isEmpty())
+ m_data.remove(t);
+ else
+ m_data[t] = value.trimmed();
+ m_format = fmt;
+}
+
+Documentation::Format Documentation::format() const
+{
+ return m_format;
+}
+
+void Documentation::setFormat(Documentation::Format f)
+{
+ m_format = f;
+}
+
+/*******************************************************************************
* AbstractMetaVariable
*/
@@ -147,7 +186,8 @@ void AbstractMetaAttributes::assignMetaAttributes(const AbstractMetaAttributes &
* AbstractMetaType
*/
-AbstractMetaType::AbstractMetaType() :
+AbstractMetaType::AbstractMetaType(const TypeEntry *t) :
+ m_typeEntry(t),
m_constant(false),
m_volatile(false),
m_cppInstantiation(true),
@@ -166,19 +206,9 @@ QString AbstractMetaType::package() const
return m_typeEntry->targetLangPackage();
}
-static QString lastNameSegment(QString name)
-{
- const int index = name.lastIndexOf(QStringLiteral("::"));
- if (index >= 0)
- name.remove(0, index + 2);
- return name;
-}
-
QString AbstractMetaType::name() const
{
- if (m_name.isEmpty())
- m_name = lastNameSegment(m_typeEntry->targetLangName());
- return m_name;
+ return m_typeEntry->targetLangEntryName();
}
QString AbstractMetaType::fullName() const
@@ -188,7 +218,7 @@ QString AbstractMetaType::fullName() const
AbstractMetaType *AbstractMetaType::copy() const
{
- auto *cpy = new AbstractMetaType;
+ auto *cpy = new AbstractMetaType(typeEntry());
cpy->setTypeUsagePattern(typeUsagePattern());
cpy->setConstant(isConstant());
@@ -202,8 +232,6 @@ AbstractMetaType *AbstractMetaType::copy() const
cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : nullptr);
- cpy->setTypeEntry(typeEntry());
-
return cpy;
}
@@ -256,11 +284,16 @@ AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const
return result;
}
-bool AbstractMetaType::isConstRef() const
+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())
@@ -273,25 +306,31 @@ QString AbstractMetaType::pythonSignature() const
// PYSIDE-921: Handle container returntypes correctly.
// This is now a clean reimplementation.
if (m_cachedPythonSignature.isEmpty())
- m_cachedPythonSignature = formatPythonSignature(false);
+ m_cachedPythonSignature = formatPythonSignature();
return m_cachedPythonSignature;
}
AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const
{
- if (m_typeEntry->isTemplateArgument() || m_referenceType == RValueReference)
- return InvalidPattern;
+ if (m_typeEntry->isTemplateArgument())
+ return TemplateArgument;
+
+ if (m_typeEntry->type() == TypeEntry::ConstantValueType)
+ return NonTypeTemplateArgument;
- if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || isConstRef()))
+ if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef()))
return PrimitivePattern;
- if (m_typeEntry->isVoid())
- return NativePointerPattern;
+ if (m_typeEntry->isVoid()) {
+ return m_arrayElementCount < 0 && m_referenceType == NoReference
+ && m_indirections.isEmpty() && m_constant == 0 && m_volatile == 0
+ ? VoidPattern : NativePointerPattern;
+ }
if (m_typeEntry->isVarargs())
return VarargsPattern;
- if (m_typeEntry->isEnum() && (actualIndirections() == 0 || isConstRef()))
+ if (m_typeEntry->isEnum() && (actualIndirections() == 0 || passByConstRef()))
return EnumPattern;
if (m_typeEntry->isObject()) {
@@ -306,7 +345,7 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con
if (m_typeEntry->isSmartPointer() && indirections() == 0)
return SmartPointerPattern;
- if (m_typeEntry->isFlags() && (actualIndirections() == 0 || isConstRef()))
+ if (m_typeEntry->isFlags() && (actualIndirections() == 0 || passByConstRef()))
return FlagsPattern;
if (m_typeEntry->isArray())
@@ -315,10 +354,6 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con
if (m_typeEntry->isValue())
return indirections() == 1 ? ValuePointerPattern : ValuePattern;
- if (ReportHandler::isDebug(ReportHandler::FullDebug)) {
- qCDebug(lcShiboken)
- << QStringLiteral("native pointer pattern for '%1'").arg(cppSignature());
- }
return NativePointerPattern;
}
@@ -352,26 +387,43 @@ bool AbstractMetaType::hasTemplateChildren() const
return false;
}
-bool AbstractMetaType::equals(const AbstractMetaType &rhs) const
+bool AbstractMetaType::compare(const AbstractMetaType &rhs, ComparisonFlags flags) const
{
- if (m_typeEntry != rhs.m_typeEntry || m_constant != rhs.m_constant
- || m_referenceType != rhs.m_referenceType
+ 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->equals(*rhs.m_arrayElementType))) {
+ || (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)->equals(*rhs.m_instantiations.at(i)))
+ if (!m_instantiations.at(i)->compare(*rhs.m_instantiations.at(i), flags))
return false;
}
return true;
}
+AbstractMetaType *AbstractMetaType::createVoid()
+{
+ static const TypeEntry *voidTypeEntry = TypeDatabase::instance()->findType(QLatin1String("void"));
+ Q_ASSERT(voidTypeEntry);
+ auto *metaType = new AbstractMetaType(voidTypeEntry);
+ metaType->decideUsagePattern();
+ return metaType;
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaType *at)
{
@@ -528,7 +580,7 @@ bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const
*/
AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const
{
- CompareResult result = nullptr;
+ CompareResult result;
// Enclosing class...
if (ownerClass() == other->ownerClass())
@@ -604,8 +656,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const
cpy->setImplementingClass(implementingClass());
cpy->setFunctionType(functionType());
cpy->setDeclaringClass(declaringClass());
- if (type())
- cpy->setType(type()->copy());
+ cpy->setType(type()->copy());
cpy->setConstant(isConstant());
cpy->setExceptionSpecification(m_exceptionSpecification);
cpy->setAllowThreadModification(m_allowThreadModification);
@@ -615,8 +666,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const
for (AbstractMetaArgument *arg : m_arguments)
cpy->addArgument(arg->copy());
- Q_ASSERT((!type() && !cpy->type())
- || (type()->instantiations() == cpy->type()->instantiations()));
+ Q_ASSERT(type()->instantiations() == cpy->type()->instantiations());
return cpy;
}
@@ -625,7 +675,7 @@ bool AbstractMetaFunction::usesRValueReferences() const
{
if (m_functionType == MoveConstructorFunction || m_functionType == MoveAssignmentOperatorFunction)
return true;
- if (m_type && m_type->referenceType() == RValueReference)
+ if (m_type->referenceType() == RValueReference)
return true;
for (const AbstractMetaArgument *a : m_arguments) {
if (a->type()->referenceType() == RValueReference)
@@ -765,6 +815,12 @@ bool AbstractMetaFunction::argumentRemoved(int key) const
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());
@@ -784,11 +840,20 @@ bool AbstractMetaFunction::isDeprecated() const
bool AbstractMetaFunction::autoDetectAllowThread() const
{
// Disallow for simple getter functions.
- const bool maybeGetter = m_constant != 0 && m_type != nullptr
- && m_arguments.isEmpty();
+ 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();
@@ -816,12 +881,14 @@ bool AbstractMetaFunction::allowThread() const
case TypeSystem::AllowThread::Allow:
break;
case TypeSystem::AllowThread::Auto:
- case TypeSystem::AllowThread::Unspecified:
result = autoDetectAllowThread();
break;
+ case TypeSystem::AllowThread::Unspecified:
+ result = false;
+ break;
}
- if (!result)
- qCDebug(lcShiboken).noquote() << msgDisallowThread(this);
+ if (!result && ReportHandler::isDebug(ReportHandler::MediumDebug))
+ qCInfo(lcShiboken).noquote() << msgDisallowThread(this);
return result;
}
@@ -945,9 +1012,6 @@ FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaC
(implementor == implementingClass() && !mods.isEmpty())) {
break;
}
- const AbstractMetaClassList &interfaces = implementor->interfaces();
- for (const AbstractMetaClass *interface : interfaces)
- mods += this->modifications(interface);
implementor = implementor->baseClass();
}
return mods;
@@ -1237,6 +1301,21 @@ AbstractMetaFunction::find(const AbstractMetaFunctionList &haystack,
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)
{
@@ -1339,8 +1418,8 @@ AbstractMetaClass::~AbstractMetaClass()
qDeleteAll(m_functions);
qDeleteAll(m_fields);
qDeleteAll(m_enums);
- if (hasTemplateBaseClassInstantiations())
- qDeleteAll(templateBaseClassInstantiations());
+ qDeleteAll(m_propertySpecs);
+ qDeleteAll(m_baseTemplateInstantiations);
}
/*******************************************************************************
@@ -1362,44 +1441,6 @@ bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
}
/*******************************************************************************
- * Constructs an interface based on the functions and enums in this
- * class and returns it...
- */
-AbstractMetaClass *AbstractMetaClass::extractInterface()
-{
- Q_ASSERT(typeEntry()->designatedInterface());
-
- if (!m_extractedInterface) {
- auto *iface = new AbstractMetaClass;
- iface->setAttributes(attributes());
- iface->setBaseClass(nullptr);
-
- iface->setTypeEntry(typeEntry()->designatedInterface());
-
- for (AbstractMetaFunction *function : qAsConst(m_functions)) {
- if (!function->isConstructor())
- iface->addFunction(function->copy());
- }
-
-// iface->setEnums(enums());
-// setEnums(AbstractMetaEnumList());
-
- for (const AbstractMetaField *field : qAsConst(m_fields)) {
- if (field->isPublic()) {
- AbstractMetaField *new_field = field->copy();
- new_field->setEnclosingClass(iface);
- iface->addField(new_field);
- }
- }
-
- m_extractedInterface = iface;
- addInterface(iface);
- }
-
- return m_extractedInterface;
-}
-
-/*******************************************************************************
* Returns a list of all the functions with a given name
*/
AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const
@@ -1421,10 +1462,6 @@ AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const
{
FunctionQueryOptions default_flags = NormalFunctions | Visible | NotRemovedFromTargetLang;
- // Interfaces don't implement functions
- if (isInterface())
- default_flags |= ClassImplements;
-
// Only public functions in final classes
// default_flags |= isFinal() ? WasPublic : 0;
FunctionQueryOptions public_flags;
@@ -1547,16 +1584,6 @@ void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions)
}
}
-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"));
@@ -1577,7 +1604,7 @@ void AbstractMetaClass::addFunction(AbstractMetaFunction *function)
else
Q_ASSERT(false); //memory leak
- m_hasVirtuals |= function->isVirtual() || hasVirtualDestructor();
+ m_hasVirtuals |= function->isVirtual();
m_isPolymorphic |= m_hasVirtuals;
m_hasNonpublic |= !function->isPublic();
}
@@ -1598,14 +1625,22 @@ bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const
QString AbstractMetaClass::name() const
{
- return lastNameSegment(m_typeEntry->targetLangName());
+ 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)
{
- m_baseClass = baseClass;
- if (baseClass)
+ if (baseClass) {
+ m_baseClasses.prepend(baseClass);
m_isPolymorphic |= baseClass->isPolymorphic();
+ }
}
QString AbstractMetaClass::package() const
@@ -1613,14 +1648,17 @@ QString AbstractMetaClass::package() const
return m_typeEntry->targetLangPackage();
}
-bool AbstractMetaClass::isInterface() const
+bool AbstractMetaClass::isNamespace() const
{
- return m_typeEntry->isInterface();
+ return m_typeEntry->isNamespace();
}
-bool AbstractMetaClass::isNamespace() const
+// Is an invisible namespaces whose functions/enums
+// should be mapped to the global space.
+bool AbstractMetaClass::isInvisibleNamespace() const
{
- return m_typeEntry->isNamespace();
+ return m_typeEntry->isNamespace() && m_typeEntry->generateCode()
+ && !NamespaceTypeEntry::isVisibleScope(m_typeEntry);
}
static bool qObjectPredicate(const AbstractMetaClass *c)
@@ -1671,6 +1709,15 @@ bool AbstractMetaClass::hasProtectedMembers() const
return hasProtectedFields() || hasProtectedFunctions();
}
+QPropertySpec *AbstractMetaClass::propertySpecByName(const QString &name) const
+{
+ for (auto propertySpec : m_propertySpecs) {
+ if (name == propertySpec->name())
+ return propertySpec;
+ }
+ return nullptr;
+}
+
QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const
{
for (const auto &propertySpec : m_propertySpecs) {
@@ -1698,35 +1745,27 @@ QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) cons
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);
+ return m_templateBaseClass != nullptr && !m_baseTemplateInstantiations.isEmpty();
}
-AbstractMetaTypeList AbstractMetaClass::templateBaseClassInstantiations() const
+const AbstractMetaTypeList &AbstractMetaClass::templateBaseClassInstantiations() const
{
- if (!templateBaseClass())
- return AbstractMetaTypeList();
- return metaClassBaseTemplateInstantiations()->value(this);
+ return m_baseTemplateInstantiations;
}
-void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList &instantiations)
+void AbstractMetaClass::setTemplateBaseClassInstantiations(const AbstractMetaTypeList &instantiations)
{
- if (!templateBaseClass())
- return;
- metaClassBaseTemplateInstantiations()->insert(this, instantiations);
+ Q_ASSERT(m_templateBaseClass != nullptr);
+ m_baseTemplateInstantiations = instantiations;
}
// Does any of the base classes require deletion in the main thread?
bool AbstractMetaClass::deleteInMainThread() const
{
return typeEntry()->deleteInMainThread()
- || (m_baseClass && m_baseClass->deleteInMainThread());
+ || (!m_baseClasses.isEmpty() && m_baseClasses.constFirst()->deleteInMainThread());
}
static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
@@ -1740,12 +1779,6 @@ static bool functions_contains(const AbstractMetaFunctionList &l, const Abstract
AbstractMetaField::AbstractMetaField() = default;
-AbstractMetaField::~AbstractMetaField()
-{
- delete m_setter;
- delete m_getter;
-}
-
AbstractMetaField *AbstractMetaField::copy() const
{
auto *returned = new AbstractMetaField;
@@ -1777,55 +1810,6 @@ bool AbstractMetaField::isModifiedRemoved(int types) const
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();
@@ -1839,32 +1823,12 @@ FieldModificationList AbstractMetaField::modifications() const
return returned;
}
-const AbstractMetaFunction *AbstractMetaField::setter() const
+const AbstractMetaClass *EnclosingClassMixin::targetLangEnclosingClass() 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 AbstractMetaFunction *AbstractMetaField::getter() const
-{
- if (!m_getter) {
- m_getter = createXetter(this,
- name(),
- AbstractMetaAttributes::GetterFunction);
- m_getter->setType(type());
- }
-
- return m_getter;
+ auto result = m_enclosingClass;
+ while (result && !NamespaceTypeEntry::isVisibleScope(result->typeEntry()))
+ result = result->enclosingClass();
+ return result;
}
#ifndef QT_NO_DEBUG_STREAM
@@ -1967,6 +1931,7 @@ bool AbstractMetaClass::hasPrivateCopyConstructor() const
void AbstractMetaClass::addDefaultConstructor()
{
auto *f = new AbstractMetaFunction;
+ f->setType(AbstractMetaType::createVoid());
f->setOriginalName(name());
f->setName(name());
f->setOwnerClass(this);
@@ -1985,14 +1950,14 @@ void AbstractMetaClass::addDefaultConstructor()
void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate)
{
auto f = new AbstractMetaFunction;
+ f->setType(AbstractMetaType::createVoid());
f->setOriginalName(name());
f->setName(name());
f->setOwnerClass(this);
f->setFunctionType(AbstractMetaFunction::CopyConstructorFunction);
f->setDeclaringClass(this);
- auto argType = new AbstractMetaType;
- argType->setTypeEntry(typeEntry());
+ auto argType = new AbstractMetaType(typeEntry());
argType->setReferenceType(LValueReference);
argType->setConstant(true);
argType->setTypeUsagePattern(AbstractMetaType::ValuePattern);
@@ -2014,6 +1979,13 @@ void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate)
addFunction(f);
}
+void AbstractMetaClass::setHasVirtualDestructor(bool value)
+{
+ m_hasVirtualDestructor = value;
+ if (value)
+ m_hasVirtuals = m_isPolymorphic = 1;
+}
+
bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const
{
return functions_contains(m_functions, f);
@@ -2096,6 +2068,16 @@ bool AbstractMetaClass::queryFunction(const AbstractMetaFunction *f, FunctionQue
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;
}
@@ -2136,57 +2118,6 @@ AbstractMetaFunctionList AbstractMetaClass::cppSignalFunctions() const
return queryFunctions(Signals | Visible | NotRemovedFromTargetLang);
}
-/**
- * Adds the specified interface to this class by adding all the
- * functions in the interface to this class.
- */
-void AbstractMetaClass::addInterface(AbstractMetaClass *interface)
-{
- Q_ASSERT(!m_interfaces.contains(interface));
- m_interfaces << interface;
-
- m_isPolymorphic |= interface->isPolymorphic();
-
- if (m_extractedInterface && m_extractedInterface != interface)
- m_extractedInterface->addInterface(interface);
-
-
-#if 0
- const AbstractMetaFunctionList &funcs = interface->functions();
- for (AbstractMetaFunction *function : funcs)
- if (!hasFunction(function) && !function->isConstructor()) {
- AbstractMetaFunction *cpy = function->copy();
- cpy->setImplementingClass(this);
-
- // Setup that this function is an interface class.
- cpy->setInterfaceClass(interface);
- *cpy += AbstractMetaAttributes::InterfaceFunction;
-
- // Copy the modifications in interface into the implementing classes.
- const FunctionModificationList &mods = function->modifications(interface);
- for (const FunctionModification &mod : mods)
- m_typeEntry->addFunctionModification(mod);
-
- // It should be mostly safe to assume that when we implement an interface
- // we don't "pass on" pure virtual functions to our sublcasses...
-// *cpy -= AbstractMetaAttributes::Abstract;
-
- addFunction(cpy);
- }
-#endif
-
-}
-
-
-void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces)
-{
- m_interfaces = interfaces;
- for (const AbstractMetaClass *interface : interfaces) {
- if (interface)
- m_isPolymorphic |= interface->isPolymorphic();
- }
-}
-
AbstractMetaField *AbstractMetaClass::findField(const QString &name) const
{
return AbstractMetaField::find(m_fields, name);
@@ -2196,10 +2127,6 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
{
if (AbstractMetaEnum *e = findByName(m_enums, enumName))
return e;
-
- if (typeEntry()->designatedInterface())
- return extractInterface()->findEnum(enumName);
-
return nullptr;
}
@@ -2212,16 +2139,37 @@ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValue
if (AbstractMetaEnumValue *v = e->findEnumValue(enumValueName))
return v;
}
-
- if (typeEntry()->designatedInterface())
- return extractInterface()->findEnumValue(enumValueName);
-
if (baseClass())
return baseClass()->findEnumValue(enumValueName);
return nullptr;
}
+void AbstractMetaClass::getEnumsToBeGenerated(AbstractMetaEnumList *enumList) const
+{
+ for (AbstractMetaEnum *metaEnum : m_enums) {
+ if (!metaEnum->isPrivate() && metaEnum->typeEntry()->generateCode())
+ enumList->append(metaEnum);
+ }
+}
+
+void AbstractMetaClass::getEnumsFromInvisibleNamespacesToBeGenerated(AbstractMetaEnumList *enumList) const
+{
+ if (isNamespace()) {
+ invisibleNamespaceRecursion([enumList](AbstractMetaClass *c) {
+ c->getEnumsToBeGenerated(enumList);
+ });
+ }
+}
+
+void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(AbstractMetaFunctionList *funcList) const
+{
+ if (isNamespace()) {
+ invisibleNamespaceRecursion([funcList](AbstractMetaClass *c) {
+ funcList->append(c->functions());
+ });
+ }
+}
static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType *type)
{
@@ -2238,8 +2186,7 @@ static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractM
}
if (type->hasInstantiations()) {
- const AbstractMetaTypeList &instantiations = type->instantiations();
- for (const AbstractMetaType *instantiation : instantiations)
+ for (const AbstractMetaType *instantiation : type->instantiations())
addExtraIncludeForType(metaClass, instantiation);
}
}
@@ -2262,32 +2209,23 @@ void AbstractMetaClass::fixFunctions()
m_functionsFixed = true;
- AbstractMetaClass *superClass = baseClass();
AbstractMetaFunctionList funcs = functions();
- if (superClass)
+ for (auto superClass : m_baseClasses) {
superClass->fixFunctions();
- int iface_idx = 0;
- while (superClass || iface_idx < interfaces().size()) {
// 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;
- if (superClass) {
- // 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;
- } else {
- superFuncs = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::NormalFunctions);
- AbstractMetaFunctionList virtuals = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
- superFuncs += virtuals;
+ // 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)) {
@@ -2416,11 +2354,6 @@ void AbstractMetaClass::fixFunctions()
(*copy) += AddedMethod;
funcs.append(copy);
}
-
- if (superClass)
- superClass = superClass->baseClass();
- else
- iface_idx++;
}
bool hasPrivateConstructors = false;
@@ -2519,7 +2452,7 @@ QString AbstractMetaType::formatSignature(bool minimal) const
return result;
}
-QString AbstractMetaType::formatPythonSignature(bool minimal) const
+QString AbstractMetaType::formatPythonSignature() const
{
/*
* This is a version of the above, more suitable for Python.
@@ -2530,6 +2463,7 @@ QString AbstractMetaType::formatPythonSignature(bool minimal) const
* 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.
+ * Smart pointer instantiations: Drop the package
*/
QString result;
if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern)
@@ -2538,25 +2472,25 @@ QString AbstractMetaType::formatPythonSignature(bool minimal) const
// NativePointerAsArrayPattern indicates when we have <array> in XML.
// if (m_typeEntry->isPrimitive() && isConstant())
// result += QLatin1String("const ");
- if (!m_typeEntry->isPrimitive() && !package().isEmpty())
+ if (!m_typeEntry->isPrimitive() && !m_typeEntry->isSmartPointer() && !package().isEmpty())
result += package() + QLatin1Char('.');
if (isArray()) {
// Build nested array dimensions a[2][3] in correct order
- result += m_arrayElementType->formatPythonSignature(true);
+ 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()->qualifiedCppName();
+ 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(true);
+ result += m_instantiations.at(i)->formatPythonSignature();
}
result += QLatin1Char(']');
}
@@ -2586,28 +2520,18 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const AbstractMetaClassList &class
{
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);
+ auto scopeEntry = entry->parent();
+ AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes, scopeEntry);
if (!metaClass) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("AbstractMeta::findEnum(), unknown class '%1' in '%2'")
- .arg(className, entry->qualifiedCppName());
+ .arg(scopeEntry->qualifiedCppName(), entry->qualifiedCppName());
return nullptr;
}
+ QString qualifiedName = entry->qualifiedCppName();
+ const int pos = qualifiedName.lastIndexOf(QLatin1String("::"));
+ const QString enumName = pos > 0 ? qualifiedName.mid(pos + 2) : qualifiedName;
return metaClass->findEnum(enumName);
}
@@ -2673,6 +2597,82 @@ AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &cla
}
#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 << ">\"";
+ }
+ if (const int count = m_propertySpecs.size()) {
+ d << ", properties (" << count << "): [";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << ", ";
+ m_propertySpecs.at(i)->formatDebug(d);
+ }
+ 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 << ')';
+ }
+}
+
+SourceLocation AbstractMetaClass::sourceLocation() const
+{
+ return m_sourceLocation;
+}
+
+void AbstractMetaClass::setSourceLocation(const SourceLocation &sourceLocation)
+{
+ m_sourceLocation = sourceLocation;
+}
+
QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
{
QDebugStateSaver saver(d);
@@ -2680,57 +2680,9 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
d.nospace();
d << "AbstractMetaClass(";
if (ac) {
- d << '"' << ac->fullName() << '"';
- if (ac->attributes() & AbstractMetaAttributes::FinalCppClass)
- d << " [final]";
- if (ac->attributes().testFlag(AbstractMetaAttributes::Deprecated))
- d << " [deprecated]";
- if (ac->m_baseClass)
- d << ", inherits \"" << ac->m_baseClass->name() << '"';
- if (ac->m_templateBaseClass)
- d << ", inherits template \"" << ac->m_templateBaseClass->name() << '"';
- const AbstractMetaEnumList &enums = ac->enums();
- if (!enums.isEmpty())
- d << ", enums[" << enums.size() << "]=" << enums;
- const AbstractMetaFunctionList &functions = ac->functions();
- if (!functions.isEmpty()) {
- const int count = functions.size();
- d << ", functions=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
-#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
- if (d.verbosity() > 2)
- d << functions.at(i);
- else
-#endif
- formatMetaFunctionBrief(d, functions.at(i));
- }
- d << ')';
- }
- const AbstractMetaFieldList &fields = ac->fields();
- if (!fields.isEmpty()) {
- const int count = fields.size();
- d << ", fields=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- formatMetaField(d, fields.at(i));
- }
- d << ')';
- }
- const auto &templateArguments = ac->templateArguments();
- if (const int count = templateArguments.size()) {
- d << ", templateArguments=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- d << templateArguments.at(i);
- }
- d << ')';
- }
-
-
+ ac->format(d);
+ if (d.verbosity() > 2)
+ ac->formatMembers(d);
} else {
d << '0';
}
@@ -2778,7 +2730,7 @@ AbstractMetaEnumValue *AbstractMetaEnum::findEnumValue(const QString &value) con
QString AbstractMetaEnum::name() const
{
- return m_typeEntry->targetLangName();
+ return m_typeEntry->targetLangEntryName();
}
QString AbstractMetaEnum::qualifier() const
@@ -2790,3 +2742,4 @@ QString AbstractMetaEnum::package() const
{
return m_typeEntry->targetLangPackage();
}
+