diff options
Diffstat (limited to 'sources/shiboken2/ApiExtractor/abstractmetalang.cpp')
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetalang.cpp | 978 |
1 files changed, 337 insertions, 641 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index b861f1b2f..840466108 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -26,8 +26,6 @@ ** ****************************************************************************/ -#include <QStack> - #include "abstractmetalang.h" #include "reporthandler.h" #include "typedatabase.h" @@ -38,6 +36,9 @@ # include <QtCore/QMetaObject> #endif +#include <QtCore/QRegularExpression> +#include <QtCore/QStack> + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa) { @@ -58,7 +59,14 @@ QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa) * AbstractMetaVariable */ -AbstractMetaVariable::AbstractMetaVariable(const AbstractMetaVariable &other) +AbstractMetaVariable::AbstractMetaVariable() = default; + +AbstractMetaVariable::~AbstractMetaVariable() +{ + delete m_type; +} + +void AbstractMetaVariable::assignMetaVariable(const AbstractMetaVariable &other) { m_originalName = other.m_originalName; m_name = other.m_name; @@ -85,20 +93,28 @@ QDebug operator<<(QDebug d, const AbstractMetaVariable *av) #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_typeEntry(0), - m_arrayElementCount(0), - m_arrayElementType(0), - m_originalTemplateType(0), - m_pattern(InvalidPattern), +AbstractMetaType::AbstractMetaType() : m_constant(false), m_cppInstantiation(true), m_indirections(0), - m_reserved(0), - m_referenceType(NoReference) + m_reserved(0) { } @@ -113,11 +129,18 @@ 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.isNull()) - // avoid constLast to stay Qt 5.5 compatible - m_name = m_typeEntry->targetLangName().split(QLatin1String("::")).last(); + m_name = lastNameSegment(m_typeEntry->targetLangName()); return m_name; } @@ -146,41 +169,30 @@ AbstractMetaType *AbstractMetaType::copy() const return cpy; } -QString AbstractMetaType::cppSignature() const +AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const { - if (m_cachedCppSignature.isEmpty()) { - if (isConstant()) - m_cachedCppSignature += QLatin1String("const "); - - m_cachedCppSignature += typeEntry()->qualifiedCppName(); - - if (hasInstantiationInCpp()) { - AbstractMetaTypeList types = instantiations(); - m_cachedCppSignature += QLatin1Char('<'); - for (int i = 0; i < types.count(); ++i) { - if (i > 0) - m_cachedCppSignature += QLatin1String(", "); - m_cachedCppSignature += types[i]->cppSignature(); - } - m_cachedCppSignature += QLatin1String(" >"); - } - - if (indirections() || m_referenceType != NoReference) { - m_cachedCppSignature += QLatin1Char(' '); - if (indirections()) - m_cachedCppSignature += QString(indirections(), QLatin1Char('*')); - switch (referenceType()) { - case NoReference: - break; - case LValueReference: - m_cachedCppSignature += QLatin1Char('&'); - break; - case RValueReference: - m_cachedCppSignature += QLatin1String("&&"); - break; - } + 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; +} + +QString AbstractMetaType::cppSignature() const +{ + if (m_cachedCppSignature.isEmpty()) + m_cachedCppSignature = formatSignature(false); return m_cachedCppSignature; } @@ -200,30 +212,6 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con if (m_typeEntry->isVarargs()) return VarargsPattern; - if (m_typeEntry->isString() && indirections() == 0 - && (isConstant() == (m_referenceType == LValueReference) - || isConstant())) { - return StringPattern; - } - - if (m_typeEntry->isChar() - && indirections() == 0 - && isConstant() == (m_referenceType == LValueReference)) { - return CharPattern; - } - - if (m_typeEntry->isJObjectWrapper() - && indirections() == 0 - && isConstant() == (m_referenceType == LValueReference)) { - return JObjectWrapperPattern; - } - - if (m_typeEntry->isVariant() - && indirections() == 0 - && isConstant() == (m_referenceType == LValueReference)) { - return VariantPattern; - } - if (m_typeEntry->isEnum() && actualIndirections() == 0) return EnumPattern; @@ -247,11 +235,6 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con if (m_typeEntry->isArray()) return ArrayPattern; - if (m_typeEntry->isThread()) { - Q_ASSERT(indirections() == 1); - return ThreadPattern; - } - if (m_typeEntry->isValue()) return indirections() == 1 ? ValuePointerPattern : ValuePattern; @@ -279,7 +262,7 @@ void AbstractMetaType::decideUsagePattern() bool AbstractMetaType::hasTemplateChildren() const { QStack<AbstractMetaType *> children; - children << m_children.toVector(); + children << m_children; // Recursively iterate over the children / descendants of the type, to check if any of them // corresponds to a template argument type. @@ -287,7 +270,7 @@ bool AbstractMetaType::hasTemplateChildren() const AbstractMetaType *child = children.pop(); if (child->typeEntry()->isTemplateArgument()) return true; - children << child->m_children.toVector(); + children << child->m_children; } return false; @@ -300,10 +283,26 @@ QDebug operator<<(QDebug d, const AbstractMetaType *at) d.noquote(); d.nospace(); d << "AbstractMetaType("; - if (at) + if (at) { d << at->name(); - else + if (d.verbosity() > 2) { + d << ", typeEntry=" << at->typeEntry() << ", signature=\"" + << at->cppSignature() << "\", pattern=" + << at->typeUsagePattern(); + if (at->indirections()) + d << ", indirections=" << at->indirections(); + if (at->referenceType()) + d << ", reftype=" << at->referenceType(); + if (at->isConstant()) + d << ", [const]"; + if (at->isArray()) { + d << ", array of \"" << at->arrayElementType()->cppSignature() + << "\", arrayElementCount=" << at->arrayElementCount(); + } + } + } else { d << '0'; + } d << ')'; return d; } @@ -312,9 +311,22 @@ QDebug operator<<(QDebug d, const AbstractMetaType *at) /******************************************************************************* * 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 { - return new AbstractMetaArgument(*this); + AbstractMetaArgument *copy = new AbstractMetaArgument; + copy->assignMetaArgument(*this); + return copy; } #ifndef QT_NO_DEBUG_STREAM @@ -336,6 +348,17 @@ QDebug operator<<(QDebug d, const AbstractMetaArgument *aa) /******************************************************************************* * AbstractMetaFunction */ + +AbstractMetaFunction::AbstractMetaFunction() + : m_constant(false), + m_reverse(false), + m_userAdded(false), + m_explicit(false), + m_pointerOperator(false), + m_isCallOperator(false) +{ +} + AbstractMetaFunction::~AbstractMetaFunction() { qDeleteAll(m_arguments); @@ -347,8 +370,8 @@ AbstractMetaFunction::~AbstractMetaFunction() */ bool AbstractMetaFunction::isModifiedRemoved(int types) const { - FunctionModificationList mods = modifications(implementingClass()); - foreach (const FunctionModification &mod, mods) { + const FunctionModificationList &mods = modifications(implementingClass()); + for (const FunctionModification &mod : mods) { if (!mod.isRemoveModifier()) continue; @@ -359,64 +382,6 @@ bool AbstractMetaFunction::isModifiedRemoved(int types) const return false; } -bool AbstractMetaFunction::needsCallThrough() const -{ - if (ownerClass()->isInterface()) - return false; - if (referenceCounts(implementingClass()).size() > 0) - return true; - if (argumentsHaveNativeId() || !isStatic()) - return true; - - foreach (const AbstractMetaArgument *arg, arguments()) { - if (arg->type()->isArray() || arg->type()->isTargetLangEnum() || arg->type()->isTargetLangFlags()) - return true; - } - - if (type() && (type()->isArray() || type()->isTargetLangEnum() || type()->isTargetLangFlags())) - return true; - - for (int i = -1; i <= arguments().size(); ++i) { - TypeSystem::Ownership owner = this->ownership(implementingClass(), TypeSystem::TargetLangCode, i); - if (owner != TypeSystem::InvalidOwnership) - return true; - } - - return false; -} - -bool AbstractMetaFunction::needsSuppressUncheckedWarning() const -{ - for (int i = -1; i <= arguments().size(); ++i) { - QList<ReferenceCount> referenceCounts = this->referenceCounts(implementingClass(), i); - foreach (const ReferenceCount &referenceCount, referenceCounts) { - if (referenceCount.action != ReferenceCount::Set) - return true; - } - } - return false; -} - -QString AbstractMetaFunction::marshalledName() const -{ - QString returned = QLatin1String("__qt_") + name(); - AbstractMetaArgumentList arguments = this->arguments(); - foreach (const AbstractMetaArgument *arg, arguments) { - returned += QLatin1Char('_'); - if (arg->type()->isNativePointer()) { - returned += QLatin1String("nativepointer"); - } else if (arg->type()->isIntegerEnum() || arg->type()->isIntegerFlags()) { - returned += QLatin1String("int"); - } else { - QString a = arg->type()->name(); - a.replace(QLatin1String("[]"), QLatin1String("_3")); - a.replace(QLatin1Char('.'), QLatin1Char('_')); - returned += a; - } - } - return returned; -} - bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const { return compareTo(&other) & NameLessThan; @@ -498,19 +463,18 @@ AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const Abstra AbstractMetaFunction *AbstractMetaFunction::copy() const { AbstractMetaFunction *cpy = new AbstractMetaFunction; + cpy->assignMetaAttributes(*this); cpy->setName(name()); cpy->setOriginalName(originalName()); cpy->setOwnerClass(ownerClass()); cpy->setImplementingClass(implementingClass()); cpy->setFunctionType(functionType()); - cpy->setAttributes(attributes()); cpy->setDeclaringClass(declaringClass()); if (type()) cpy->setType(type()->copy()); cpy->setConstant(isConstant()); - cpy->setOriginalAttributes(originalAttributes()); - foreach (AbstractMetaArgument *arg, arguments()) + for (AbstractMetaArgument *arg : m_arguments) cpy->addArgument(arg->copy()); Q_ASSERT((!type() && !cpy->type()) @@ -525,7 +489,7 @@ bool AbstractMetaFunction::usesRValueReferences() const return true; if (m_type && m_type->referenceType() == RValueReference) return true; - foreach (const AbstractMetaArgument *a, m_arguments) { + for (const AbstractMetaArgument *a : m_arguments) { if (a->type()->referenceType() == RValueReference) return true; } @@ -600,13 +564,13 @@ int AbstractMetaFunction::actualMinimumArgumentCount() const } // Returns reference counts for argument at idx, or all arguments if idx == -2 -QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const +QVector<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const { - QList<ReferenceCount> returned; + QVector<ReferenceCount> returned; - FunctionModificationList mods = this->modifications(cls); - foreach (const FunctionModification &mod, mods) { - foreach (const ArgumentModification &argumentMod, mod.argument_mods) { + 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; @@ -619,9 +583,9 @@ QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaCl ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, int idx) const { - FunctionModificationList mods = this->modifications(cls); - foreach (const FunctionModification &mod, mods) { - foreach (const ArgumentModification &argumentMod, mod.argument_mods) { + 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; @@ -633,9 +597,9 @@ ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass *cls, int key) const { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key && !argumentModification.replacedDefaultExpression.isEmpty()) { return argumentModification.replacedDefaultExpression; @@ -648,9 +612,9 @@ QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls, int key) const { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key && argumentModification.removedDefaultExpression) { return true; @@ -661,77 +625,15 @@ bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls return false; } -bool AbstractMetaFunction::resetObjectAfterUse(int argumentIdx) const -{ - const AbstractMetaClass *cls = declaringClass(); - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { - if (argumentModification.index == argumentIdx && argumentModification.resetAfterUse) - return true; - } - } - - return false; -} - -QString AbstractMetaFunction::nullPointerDefaultValue(const AbstractMetaClass *mainClass, int argumentIdx) const -{ - Q_ASSERT(nullPointersDisabled(mainClass, argumentIdx)); - - const AbstractMetaClass *cls = mainClass; - if (!cls) - cls = implementingClass(); - - do { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { - if (argumentModification.index == argumentIdx - && argumentModification.noNullPointers) { - return argumentModification.nullPointerDefaultValue; - } - } - } - cls = cls->baseClass(); - } while (cls && !mainClass); // Once when mainClass, or once for all base classes of implementing class - - return QString(); - -} - -bool AbstractMetaFunction::nullPointersDisabled(const AbstractMetaClass *mainClass, int argumentIdx) const -{ - const AbstractMetaClass *cls = mainClass; - if (!cls) - cls = implementingClass(); - - do { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { - if (argumentModification.index == argumentIdx - && argumentModification.noNullPointers) { - return true; - } - } - } - - cls = cls->baseClass(); - } while (cls && !mainClass); // Once when mainClass, or once for all base classes of implementing class - - return false; -} - QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index != key) continue; - foreach (const CodeSnip &snip, argumentModification.conversion_rules) { + for (const CodeSnip &snip : argumentModification.conversion_rules) { if (snip.language == language && !snip.code().isEmpty()) return snip.code(); } @@ -743,9 +645,9 @@ QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int QString AbstractMetaFunction::argumentReplaced(int key) const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key && !argumentModification.replace_value.isEmpty()) return argumentModification.replace_value; } @@ -757,9 +659,9 @@ QString AbstractMetaFunction::argumentReplaced(int key) const // FIXME If we remove a arg. in the method at the base class, it will not reflect here. bool AbstractMetaFunction::argumentRemoved(int key) const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + 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; @@ -772,8 +674,8 @@ bool AbstractMetaFunction::argumentRemoved(int key) const bool AbstractMetaFunction::isVirtualSlot() const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { if (modification.isVirtualSlot()) return true; } @@ -781,51 +683,20 @@ bool AbstractMetaFunction::isVirtualSlot() const return false; } -bool AbstractMetaFunction::disabledGarbageCollection(const AbstractMetaClass *cls, int key) const -{ - typedef QHash<TypeSystem::Language, TypeSystem::Ownership>::const_iterator OwnershipMapIt; - - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { - if (argumentModification.index != key) - continue; - - for (OwnershipMapIt it = argumentModification.ownerships.cbegin(), end = argumentModification.ownerships.cend(); it != end; ++it) { - if (it.value() == TypeSystem::CppOwnership) - return true; - } - - } - } - - return false; -} - bool AbstractMetaFunction::isDeprecated() const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { if (modification.isDeprecated()) return true; } return false; } -bool AbstractMetaFunction::isThread() const -{ - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - if (modification.isThread()) - return true; - } - return false; -} - bool AbstractMetaFunction::allowThread() const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { if (modification.allowThread()) return true; } @@ -835,9 +706,9 @@ bool AbstractMetaFunction::allowThread() const TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int key) const { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + 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); } @@ -853,8 +724,8 @@ bool AbstractMetaFunction::isRemovedFromAllLanguages(const AbstractMetaClass *cl bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSystem::Language language) const { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { if ((modification.removal & language) == language) return true; } @@ -865,9 +736,9 @@ bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSyste QString AbstractMetaFunction::typeReplaced(int key) const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + 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; @@ -909,6 +780,21 @@ QString AbstractMetaFunction::minimalSignature() const 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 (!implementor) @@ -923,19 +809,14 @@ FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaC if ((implementor == implementor->baseClass()) || (implementor == implementingClass() && (mods.size() > 0))) break; - foreach (const AbstractMetaClass* interface, implementor->interfaces()) { + const AbstractMetaClassList &interfaces = implementor->interfaces(); + for (const AbstractMetaClass *interface : interfaces) mods += this->modifications(interface); - } implementor = implementor->baseClass(); } return mods; } -bool AbstractMetaFunction::hasModifications(const AbstractMetaClass *implementor) const -{ - return !modifications(implementor).isEmpty(); -} - QString AbstractMetaFunction::argumentName(int index, bool /* create */, const AbstractMetaClass * /* implementor */) const @@ -950,7 +831,8 @@ bool AbstractMetaFunction::isCallOperator() const bool AbstractMetaFunction::hasInjectedCode() const { - foreach (const FunctionModification &mod, modifications(ownerClass())) { + const FunctionModificationList &mods = modifications(ownerClass()); + for (const FunctionModification &mod : mods) { if (mod.isCodeInjection()) return true; } @@ -960,12 +842,12 @@ bool AbstractMetaFunction::hasInjectedCode() const CodeSnipList AbstractMetaFunction::injectedCodeSnips(TypeSystem::CodeSnipPosition position, TypeSystem::Language language) const { CodeSnipList result; - foreach (const FunctionModification &mod, modifications(ownerClass())) { + const FunctionModificationList &mods = modifications(ownerClass()); + for (const FunctionModification &mod : mods) { if (mod.isCodeInjection()) { - QList<CodeSnip>::const_iterator it = mod.snips.constBegin(); - for (;it != mod.snips.constEnd(); ++it) { - if ((it->language & language) && (it->position == position || position == TypeSystem::CodeSnipPositionAny)) - result << *it; + for (const CodeSnip &snip : mod.snips) { + if ((snip.language & language) && (snip.position == position || position == TypeSystem::CodeSnipPositionAny)) + result << snip; } } } @@ -974,10 +856,11 @@ CodeSnipList AbstractMetaFunction::injectedCodeSnips(TypeSystem::CodeSnipPositio bool AbstractMetaFunction::hasSignatureModifications() const { - foreach (const FunctionModification &mod, modifications()) { + const FunctionModificationList &mods = modifications(); + for (const FunctionModification &mod : mods) { if (mod.isRenameModifier()) return true; - foreach (const ArgumentModification &argmod, mod.argument_mods) { + 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. @@ -990,8 +873,9 @@ bool AbstractMetaFunction::hasSignatureModifications() const bool AbstractMetaFunction::isConversionOperator(QString funcName) { - static QRegExp opRegEx(QLatin1String("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$")); - return opRegEx.indexIn(funcName) > -1; + static const QRegularExpression opRegEx(QStringLiteral("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$")); + Q_ASSERT(opRegEx.isValid()); + return opRegEx.match(funcName).hasMatch(); } bool AbstractMetaFunction::isOperatorOverload(QString funcName) @@ -999,12 +883,13 @@ bool AbstractMetaFunction::isOperatorOverload(QString funcName) if (isConversionOperator(funcName)) return true; - static QRegExp opRegEx(QLatin1String("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?" + static const QRegularExpression opRegEx(QLatin1String("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?" "|\\+\\+|\\-\\-|&&|\\|\\||<<[=]?|>>[=]?|~" "|\\[\\]|\\s+delete\\[?\\]?" "|\\(\\)" "|\\s+new\\[?\\]?)$")); - return opRegEx.indexIn(funcName) > -1; + Q_ASSERT(opRegEx.isValid()); + return opRegEx.match(funcName).hasMatch(); } bool AbstractMetaFunction::isCastOperator() const @@ -1127,14 +1012,14 @@ bool AbstractMetaFunction::isInplaceOperator() const bool AbstractMetaFunction::isVirtual() const { - return !isFinal() && !isSignal() && !isStatic() && !isFinalInCpp() && !isConstructor(); + return attributes() & AbstractMetaAttributes::VirtualCppMethod; } QString AbstractMetaFunction::modifiedName() const { if (m_cachedModifiedName.isEmpty()) { - FunctionModificationList mods = modifications(implementingClass()); - foreach (const FunctionModification &mod, mods) { + const FunctionModificationList &mods = modifications(implementingClass()); + for (const FunctionModification &mod : mods) { if (mod.isRenameModifier()) { m_cachedModifiedName = mod.renamedToName; break; @@ -1146,46 +1031,6 @@ QString AbstractMetaFunction::modifiedName() const return m_cachedModifiedName; } -QString AbstractMetaFunction::targetLangSignature(bool minimal) const -{ - QString s; - - // Attributes... - if (!minimal) { - // Return type - if (type()) - s += type()->name() + QLatin1Char(' '); - else - s += QLatin1String("void "); - } - - s += modifiedName(); - s += QLatin1Char('('); - - int j = 0; - for (int i = 0; i < m_arguments.size(); ++i) { - if (argumentRemoved(i + 1)) - continue; - if (j) { - s += QLatin1Char(','); - if (!minimal) - s += QLatin1Char(' '); - } - s += m_arguments.at(i)->type()->name(); - - if (!minimal) { - s += QLatin1Char(' '); - s += m_arguments.at(i)->name(); - } - ++j; - } - - s += QLatin1Char(')'); - - return s; -} - - bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b) { return a->signature() < b->signature(); @@ -1194,7 +1039,7 @@ bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b) #ifndef QT_NO_DEBUG_STREAM static inline void formatMetaFunctionBrief(QDebug &d, const AbstractMetaFunction *af) { - d << '"' << af->minimalSignature() << '"'; + d << '"' << af->debugSignature() << '"'; } void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const @@ -1208,8 +1053,6 @@ void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const d << "), signature=\"" << minimalSignature() << '"'; if (m_constant) d << " [const]"; - if (m_invalid) - d << " [invalid]"; if (m_reverse) d << " [reverse]"; if (m_userAdded) @@ -1256,15 +1099,34 @@ QDebug operator<<(QDebug d, const AbstractMetaFunction *af) /******************************************************************************* * AbstractMetaClass */ + +AbstractMetaClass::AbstractMetaClass() + : m_hasVirtuals(false), + m_isPolymorphic(false), + m_hasNonpublic(false), + m_hasVirtualSlots(false), + m_hasNonPrivateConstructor(false), + m_hasPrivateConstructor(false), + m_functionsFixed(false), + m_hasPrivateDestructor(false), + m_hasProtectedDestructor(false), + m_hasVirtualDestructor(false), + m_forceShellClass(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()) { - foreach (AbstractMetaType* inst, templateBaseClassInstantiations()) - delete inst; - } + if (hasTemplateBaseClassInstantiations()) + qDeleteAll(templateBaseClassInstantiations()); } /******************************************************************************* @@ -1300,7 +1162,7 @@ AbstractMetaClass *AbstractMetaClass::extractInterface() iface->setTypeEntry(typeEntry()->designatedInterface()); - foreach (AbstractMetaFunction *function, functions()) { + for (AbstractMetaFunction *function : qAsConst(m_functions)) { if (!function->isConstructor()) iface->addFunction(function->copy()); } @@ -1308,7 +1170,7 @@ AbstractMetaClass *AbstractMetaClass::extractInterface() // iface->setEnums(enums()); // setEnums(AbstractMetaEnumList()); - foreach (const AbstractMetaField *field, fields()) { + for (const AbstractMetaField *field : qAsConst(m_fields)) { if (field->isPublic()) { AbstractMetaField *new_field = field->copy(); new_field->setEnclosingClass(iface); @@ -1329,8 +1191,7 @@ AbstractMetaClass *AbstractMetaClass::extractInterface() AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const { AbstractMetaFunctionList returned; - AbstractMetaFunctionList functions = this->functions(); - foreach (AbstractMetaFunction *function, functions) { + for (AbstractMetaFunction *function : m_functions) { if (function->name() == name) returned.append(function); } @@ -1353,7 +1214,7 @@ AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const // Only public functions in final classes // default_flags |= isFinal() ? WasPublic : 0; FunctionQueryOptions public_flags; - if (isFinal()) + if (isFinalInTargetLang()) public_flags |= WasPublic; // Constructors @@ -1374,33 +1235,18 @@ AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const return returned; } -AbstractMetaFunctionList AbstractMetaClass::virtualFunctions() const -{ - AbstractMetaFunctionList list = functionsInShellClass(); - - AbstractMetaFunctionList returned; - foreach (AbstractMetaFunction *f, list) { - if (!f->isFinalInCpp() || f->isVirtualSlot()) - returned += f; - } - - return returned; -} - AbstractMetaFunctionList AbstractMetaClass::implicitConversions() const { if (!hasCloneOperator() && !hasExternalConversionOperators()) return AbstractMetaFunctionList(); AbstractMetaFunctionList returned; - AbstractMetaFunctionList list = queryFunctions(Constructors); - - list.append(externalConversionOperators()); + 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> &&)". - foreach (AbstractMetaFunction *f, list) { + for (AbstractMetaFunction *f : list) { if ((f->actualMinimumArgumentCount() == 1 || f->arguments().size() == 1 || f->isConversionOperator()) && !f->isExplicit() && f->functionType() != AbstractMetaFunction::CopyConstructorFunction @@ -1415,9 +1261,9 @@ AbstractMetaFunctionList AbstractMetaClass::implicitConversions() const AbstractMetaFunctionList AbstractMetaClass::operatorOverloads(OperatorQueryOptions query) const { - AbstractMetaFunctionList list = queryFunctions(OperatorOverloads | Visible); + const AbstractMetaFunctionList &list = queryFunctions(OperatorOverloads | Visible); AbstractMetaFunctionList returned; - foreach (AbstractMetaFunction *f, list) { + for (AbstractMetaFunction *f : list) { if (((query & ArithmeticOp) && f->isArithmeticOperator()) || ((query & BitwiseOp) && f->isBitwiseOperator()) || ((query & ComparisonOp) && f->isComparisonOperator()) @@ -1432,18 +1278,9 @@ AbstractMetaFunctionList AbstractMetaClass::operatorOverloads(OperatorQueryOptio return returned; } -bool AbstractMetaClass::hasOperatorOverload() const -{ - foreach (const AbstractMetaFunction *f, m_functions) { - if (f->ownerClass() == f->implementingClass() && f->isOperatorOverload() && !f->isPrivate()) - return true; - } - return false; -} - bool AbstractMetaClass::hasArithmeticOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isArithmeticOperator() && !f->isPrivate()) return true; } @@ -1452,7 +1289,7 @@ bool AbstractMetaClass::hasArithmeticOperatorOverload() const bool AbstractMetaClass::hasBitwiseOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isBitwiseOperator() && !f->isPrivate()) return true; } @@ -1461,7 +1298,7 @@ bool AbstractMetaClass::hasBitwiseOperatorOverload() const bool AbstractMetaClass::hasComparisonOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isComparisonOperator() && !f->isPrivate()) return true; } @@ -1470,79 +1307,13 @@ bool AbstractMetaClass::hasComparisonOperatorOverload() const bool AbstractMetaClass::hasLogicalOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isLogicalOperator() && !f->isPrivate()) return true; } return false; } -bool AbstractMetaClass::hasSubscriptOperatorOverload() const -{ - foreach (const AbstractMetaFunction *f, m_functions) { - if (f->ownerClass() == f->implementingClass() && f->isSubscriptOperator() && !f->isPrivate()) - return true; - } - return false; -} - -bool AbstractMetaClass::hasAssignmentOperatorOverload() const -{ - foreach (const AbstractMetaFunction *f, m_functions) { - if (f->ownerClass() == f->implementingClass() && f->isAssignmentOperator() && !f->isPrivate()) - return true; - } - return false; -} - -bool AbstractMetaClass::hasConversionOperatorOverload() const -{ - foreach (const AbstractMetaFunction *f, m_functions) { - if (f->ownerClass() == f->implementingClass() && f->isConversionOperator() && !f->isPrivate()) - return true; - } - return false; -} - -/******************************************************************************* - * Returns a list of all functions that should be declared and implemented in - * the shell class which is generated as a wrapper on top of the actual C++ class - */ -AbstractMetaFunctionList AbstractMetaClass::functionsInShellClass() const -{ - // Only functions and only protected and public functions - FunctionQueryOptions default_flags = NormalFunctions | Visible | WasVisible | NotRemovedFromShell; - - // All virtual functions - AbstractMetaFunctionList returned = queryFunctions(VirtualFunctions | default_flags); - - // All functions explicitly set to be implemented by the shell class - // (mainly superclass functions that are hidden by other declarations) - returned += queryFunctions(ForcedShellFunctions | default_flags); - - // All functions explicitly set to be virtual slots - returned += queryFunctions(VirtualSlots | default_flags); - - return returned; -} - -/******************************************************************************* - * Returns a list of all functions that require a public override function to - * be generated in the shell class. This includes all functions that were originally - * protected in the superclass. - */ -AbstractMetaFunctionList AbstractMetaClass::publicOverrideFunctions() const -{ - return queryFunctions(NormalFunctions | WasProtected | FinalInCppFunctions | NotRemovedFromTargetLang) - + queryFunctions(Signals | WasProtected | FinalInCppFunctions | NotRemovedFromTargetLang); -} - -AbstractMetaFunctionList AbstractMetaClass::virtualOverrideFunctions() const -{ - return queryFunctions(NormalFunctions | NonEmptyFunctions | Visible | VirtualInCppFunctions | NotRemovedFromShell) + - queryFunctions(Signals | NonEmptyFunctions | Visible | VirtualInCppFunctions | NotRemovedFromShell); -} - void AbstractMetaClass::sortFunctions() { qSort(m_functions.begin(), m_functions.end(), function_sorter); @@ -1555,46 +1326,19 @@ void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions) // Functions must be sorted by name before next loop sortFunctions(); - QString currentName; - bool hasVirtuals = false; - AbstractMetaFunctionList finalFunctions; - foreach (AbstractMetaFunction *f, m_functions) { + for (AbstractMetaFunction *f : qAsConst(m_functions)) { f->setOwnerClass(this); m_hasVirtualSlots = m_hasVirtualSlots || f->isVirtualSlot(); m_hasVirtuals = m_hasVirtuals || f->isVirtualSlot() || hasVirtualDestructor(); m_isPolymorphic = m_isPolymorphic || m_hasVirtuals; m_hasNonpublic = m_hasNonpublic || !f->isPublic(); - - // If we have non-virtual overloads of a virtual function, we have to implement - // all the overloads in the shell class to override the hiding rule - if (currentName == f->name()) { - hasVirtuals = hasVirtuals || !f->isFinal(); - if (f->isFinal()) - finalFunctions += f; - } else { - if (hasVirtuals && finalFunctions.size() > 0) { - foreach (AbstractMetaFunction *final_function, finalFunctions) { - *final_function += AbstractMetaAttributes::ForceShellImplementation; - - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("hiding of function '%1' in class '%2'") - .arg(final_function->name(), name()); - } - } - - hasVirtuals = !f->isFinal(); - finalFunctions.clear(); - if (f->isFinal()) - finalFunctions += f; - currentName = f->name(); - } } } bool AbstractMetaClass::hasFieldAccessors() const { - foreach (const AbstractMetaField *field, fields()) { + for (const AbstractMetaField *field : m_fields) { if (field->getter() || field->setter()) return true; } @@ -1604,7 +1348,8 @@ bool AbstractMetaClass::hasFieldAccessors() const bool AbstractMetaClass::hasDefaultToStringFunction() const { - foreach (AbstractMetaFunction *f, queryFunctionsByName(QLatin1String("toString"))) { + const AbstractMetaFunctionList &funcs = queryFunctionsByName(QLatin1String("toString")); + for (const AbstractMetaFunction *f : funcs) { if (!f->actualMinimumArgumentCount()) return true; } @@ -1622,7 +1367,7 @@ void AbstractMetaClass::addFunction(AbstractMetaFunction *function) Q_ASSERT(false); //memory leak m_hasVirtualSlots |= function->isVirtualSlot(); - m_hasVirtuals |= !function->isFinal() || function->isVirtualSlot() || hasVirtualDestructor(); + m_hasVirtuals |= function->isVirtual() || function->isVirtualSlot() || hasVirtualDestructor(); m_isPolymorphic |= m_hasVirtuals; m_hasNonpublic |= !function->isPublic(); } @@ -1632,7 +1377,7 @@ bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const if (!other->isSignal()) return false; - foreach (const AbstractMetaFunction *f, functions()) { + for (const AbstractMetaFunction *f : m_functions) { if (f->isSignal() && f->compareTo(other) & AbstractMetaFunction::EqualName) return other->modifiedName() == f->modifiedName(); } @@ -1643,7 +1388,7 @@ bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const QString AbstractMetaClass::name() const { - return QString(m_typeEntry->targetLangName()).split(QLatin1String("::")).last(); + return lastNameSegment(m_typeEntry->targetLangName()); } void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass) @@ -1685,7 +1430,7 @@ bool AbstractMetaClass::hasFunction(const QString &str) const const AbstractMetaFunction* AbstractMetaClass::findFunction(const QString& functionName) const { - foreach (const AbstractMetaFunction *f, functions()) { + for (const AbstractMetaFunction *f : m_functions) { if (f->name() == functionName) return f; } @@ -1694,7 +1439,7 @@ const AbstractMetaFunction* AbstractMetaClass::findFunction(const QString& funct bool AbstractMetaClass::hasProtectedFunctions() const { - foreach (AbstractMetaFunction *func, m_functions) { + for (AbstractMetaFunction *func : m_functions) { if (func->isProtected()) return true; } @@ -1703,7 +1448,7 @@ bool AbstractMetaClass::hasProtectedFunctions() const bool AbstractMetaClass::hasProtectedFields() const { - foreach (const AbstractMetaField *field, fields()) { + for (const AbstractMetaField *field : m_fields) { if (field->isProtected()) return true; } @@ -1715,15 +1460,6 @@ bool AbstractMetaClass::hasProtectedMembers() const return hasProtectedFields() || hasProtectedFunctions(); } -bool AbstractMetaClass::generateShellClass() const -{ - return m_forceShellClass || - (!isFinal() - && (hasVirtualFunctions() - || hasProtectedFunctions() - || hasFieldAccessors())); -} - QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const { for (int i = 0; i < m_propertySpecs.size(); ++i) @@ -1775,16 +1511,14 @@ void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList& static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func) { - foreach (const AbstractMetaFunction *f, l) { + for (const AbstractMetaFunction *f : l) { if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar) return true; } return false; } -AbstractMetaField::AbstractMetaField() : m_getter(0), m_setter(0), m_class(0) -{ -} +AbstractMetaField::AbstractMetaField() = default; AbstractMetaField::~AbstractMetaField() { @@ -1795,12 +1529,9 @@ AbstractMetaField::~AbstractMetaField() AbstractMetaField *AbstractMetaField::copy() const { AbstractMetaField *returned = new AbstractMetaField; - returned->setEnclosingClass(0); - returned->setAttributes(attributes()); - returned->setName(name()); - returned->setType(type()->copy()); - returned->setOriginalAttributes(originalAttributes()); - + returned->assignMetaVariable(*this); + returned->assignMetaAttributes(*this); + returned->setEnclosingClass(nullptr); return returned; } @@ -1809,8 +1540,8 @@ AbstractMetaField *AbstractMetaField::copy() const */ bool AbstractMetaField::isModifiedRemoved(int types) const { - FieldModificationList mods = modifications(); - foreach (const FieldModification &mod, mods) { + const FieldModificationList &mods = modifications(); + for (const FieldModification &mod : mods) { if (!mod.isRemoveModifier()) continue; @@ -1840,9 +1571,7 @@ static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QStr f->setImplementingClass(g->enclosingClass()); f->setDeclaringClass(g->enclosingClass()); - AbstractMetaAttributes::Attributes attr = AbstractMetaAttributes::Native - | AbstractMetaAttributes::Final - | type; + AbstractMetaAttributes::Attributes attr = AbstractMetaAttributes::FinalInTargetLang | type; if (g->isStatic()) attr |= AbstractMetaAttributes::Static; if (g->isPublic()) @@ -1854,8 +1583,8 @@ static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QStr f->setAttributes(attr); f->setOriginalAttributes(attr); - FieldModificationList mods = g->modifications(); - foreach (const FieldModification &mod, mods) { + const FieldModificationList &mods = g->modifications(); + for (const FieldModification &mod : mods) { if (mod.isRenameModifier()) f->setName(mod.renamedTo()); if (mod.isAccessModifier()) { @@ -1874,10 +1603,10 @@ static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QStr FieldModificationList AbstractMetaField::modifications() const { - FieldModificationList mods = enclosingClass()->typeEntry()->fieldModifications(); + const FieldModificationList &mods = enclosingClass()->typeEntry()->fieldModifications(); FieldModificationList returned; - foreach (const FieldModification &mod, mods) { + for (const FieldModification &mod : mods) { if (mod.name == name()) returned += mod; } @@ -1994,7 +1723,8 @@ bool AbstractMetaClass::hasConstructors() const bool AbstractMetaClass::hasCopyConstructor() const { - foreach (const AbstractMetaFunction* ctor, queryFunctions(Constructors)) { + const AbstractMetaFunctionList &ctors = queryFunctions(Constructors); + for (const AbstractMetaFunction* ctor : ctors) { if (ctor->functionType() == AbstractMetaFunction::CopyConstructorFunction) return true; } @@ -2003,7 +1733,8 @@ bool AbstractMetaClass::hasCopyConstructor() const bool AbstractMetaClass::hasPrivateCopyConstructor() const { - foreach (const AbstractMetaFunction* ctor, queryFunctions(Constructors)) { + const AbstractMetaFunctionList &ctors = queryFunctions(Constructors); + for (const AbstractMetaFunction *ctor : ctors) { if (ctor->functionType() == AbstractMetaFunction::CopyConstructorFunction && ctor->isPrivate()) return true; } @@ -2020,10 +1751,7 @@ void AbstractMetaClass::addDefaultConstructor() f->setArguments(AbstractMetaArgumentList()); f->setDeclaringClass(this); - AbstractMetaAttributes::Attributes attr = AbstractMetaAttributes::Native; - attr |= AbstractMetaAttributes::Public; - attr |= AbstractMetaAttributes::Final; - f->setAttributes(attr); + f->setAttributes(AbstractMetaAttributes::Public | AbstractMetaAttributes::FinalInTargetLang); f->setImplementingClass(this); f->setOriginalAttributes(f->attributes()); @@ -2051,8 +1779,7 @@ void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate) arg->setName(name()); f->addArgument(arg); - AbstractMetaAttributes::Attributes attr = AbstractMetaAttributes::Native; - attr |= AbstractMetaAttributes::Final; + AbstractMetaAttributes::Attributes attr = AbstractMetaAttributes::FinalInTargetLang; if (isPrivate) attr |= AbstractMetaAttributes::Private; else @@ -2077,21 +1804,11 @@ AbstractMetaFunctionList AbstractMetaClass::queryFunctions(FunctionQueryOptions { AbstractMetaFunctionList functions; - foreach (AbstractMetaFunction *f, m_functions) { - - if ((query & VirtualSlots) && !f->isVirtualSlot()) - continue; - + for (AbstractMetaFunction *f : m_functions) { if ((query & NotRemovedFromTargetLang) && f->isRemovedFrom(f->implementingClass(), TypeSystem::TargetLangCode)) continue; - if ((query & NotRemovedFromTargetLang) && !f->isFinal() && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode)) - continue; - - if ((query & NotRemovedFromShell) && f->isRemovedFrom(f->implementingClass(), TypeSystem::ShellCode)) - continue; - - if ((query & NotRemovedFromShell) && !f->isFinal() && f->isRemovedFrom(f->declaringClass(), TypeSystem::ShellCode)) + if ((query & NotRemovedFromTargetLang) && f->isVirtual() && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode)) continue; if ((query & Visible) && f->isPrivate()) @@ -2109,35 +1826,18 @@ AbstractMetaFunctionList AbstractMetaClass::queryFunctions(FunctionQueryOptions if ((query & WasPublic) && !f->wasPublic()) continue; - if ((query & WasVisible) && f->wasPrivate()) - continue; - - if ((query & WasProtected) && !f->wasProtected()) - continue; - if ((query & ClassImplements) && f->ownerClass() != f->implementingClass()) continue; - if ((query & Inconsistent) && (f->isFinalInTargetLang() || !f->isFinalInCpp() || f->isStatic())) - continue; - if ((query & FinalInTargetLangFunctions) && !f->isFinalInTargetLang()) continue; - if ((query & FinalInCppFunctions) && !f->isFinalInCpp()) - continue; - - if ((query & VirtualInCppFunctions) && f->isFinalInCpp()) + if ((query & VirtualInCppFunctions) && !f->isVirtual()) continue; if ((query & Signals) && (!f->isSignal())) continue; - if ((query & ForcedShellFunctions) && - (!f->isForcedShellImplementation() || !f->isFinal())) { - continue; - } - if ((query & Constructors) && (!f->isConstructor() || f->ownerClass() != f->implementingClass())) continue; @@ -2152,24 +1852,15 @@ AbstractMetaFunctionList AbstractMetaClass::queryFunctions(FunctionQueryOptions continue; }*/ - if ((query & VirtualFunctions) && (f->isFinal() || f->isSignal() || f->isStatic())) - continue; - if ((query & StaticFunctions) && (!f->isStatic() || f->isSignal())) continue; if ((query & NonStaticFunctions) && (f->isStatic())) continue; - if ((query & NonEmptyFunctions) && (f->isEmptyFunction())) - continue; - if ((query & NormalFunctions) && (f->isSignal())) continue; - if ((query & AbstractFunctions) && !f->isAbstract()) - continue; - if ((query & OperatorOverloads) && !f->isOperatorOverload()) continue; @@ -2199,8 +1890,10 @@ void AbstractMetaClass::addInterface(AbstractMetaClass *interface) if (m_extractedInterface && m_extractedInterface != interface) m_extractedInterface->addInterface(interface); + #if 0 - foreach (AbstractMetaFunction *function, interface->functions()) + const AbstractMetaFunctionList &funcs = interface->functions(); + for (AbstractMetaFunction *function : funcs) if (!hasFunction(function) && !function->isConstructor()) { AbstractMetaFunction *cpy = function->copy(); cpy->setImplementingClass(this); @@ -2210,8 +1903,8 @@ void AbstractMetaClass::addInterface(AbstractMetaClass *interface) *cpy += AbstractMetaAttributes::InterfaceFunction; // Copy the modifications in interface into the implementing classes. - FunctionModificationList mods = function->modifications(interface); - foreach (const FunctionModification &mod, mods) + 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 @@ -2228,7 +1921,7 @@ void AbstractMetaClass::addInterface(AbstractMetaClass *interface) void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces) { m_interfaces = interfaces; - foreach (const AbstractMetaClass* interface, interfaces) { + for (const AbstractMetaClass *interface : interfaces) { if (interface) m_isPolymorphic |= interface->isPolymorphic(); } @@ -2237,7 +1930,7 @@ void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces) AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName) { - foreach (AbstractMetaEnum *e, m_enums) { + for (AbstractMetaEnum *e : qAsConst(m_enums)) { if (e->name() == enumName) return e; } @@ -2257,10 +1950,11 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName) */ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValueName, AbstractMetaEnum *meta_enum) { - foreach (AbstractMetaEnum *e, m_enums) { + for (AbstractMetaEnum *e : qAsConst(m_enums)) { if (e != meta_enum) continue; - foreach (AbstractMetaEnumValue *v, e->values()) { + const AbstractMetaEnumValueList &values = e->values(); + for (AbstractMetaEnumValue *v : values) { if (v->name() == enumValueName) return v; } @@ -2284,8 +1978,9 @@ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValue */ AbstractMetaEnum *AbstractMetaClass::findEnumForValue(const QString &enumValueName) { - foreach (AbstractMetaEnum *e, m_enums) { - foreach (AbstractMetaEnumValue *v, e->values()) { + for (AbstractMetaEnum *e : qAsConst(m_enums)) { + const AbstractMetaEnumValueList &values = e->values(); + for (AbstractMetaEnumValue *v : values) { if (v->name() == enumValueName) return e; } @@ -2316,8 +2011,8 @@ static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractM } if (type->hasInstantiations()) { - AbstractMetaTypeList instantiations = type->instantiations(); - foreach (const AbstractMetaType *instantiation, instantiations) + const AbstractMetaTypeList &instantiations = type->instantiations(); + for (const AbstractMetaType *instantiation : instantiations) addExtraIncludeForType(metaClass, instantiation); } } @@ -2328,9 +2023,9 @@ static void addExtraIncludesForFunction(AbstractMetaClass *metaClass, const Abst Q_ASSERT(meta_function); addExtraIncludeForType(metaClass, meta_function->type()); - AbstractMetaArgumentList arguments = meta_function->arguments(); - foreach (AbstractMetaArgument *argument, arguments) - addExtraIncludeForType(metaClass, argument->type()); + const AbstractMetaArgumentList &arguments = meta_function->arguments(); + for (AbstractMetaArgument *argument : arguments) + addExtraIncludeForType(metaClass, argument->type()); } void AbstractMetaClass::fixFunctions() @@ -2395,9 +2090,6 @@ void AbstractMetaClass::fixFunctions() // Same function, propegate virtual... if (!(cmp & AbstractMetaFunction::EqualAttributes)) { if (!f->isEmptyFunction()) { - if (!sf->isFinalInCpp() && f->isFinalInCpp()) { - *f -= AbstractMetaAttributes::FinalInCpp; - } if (!sf->isFinalInTargetLang() && f->isFinalInTargetLang()) { *f -= AbstractMetaAttributes::FinalInTargetLang; } @@ -2432,7 +2124,6 @@ void AbstractMetaClass::fixFunctions() if (f->isPrivate()) { f->setFunctionType(AbstractMetaFunction::EmptyFunction); *f += AbstractMetaAttributes::FinalInTargetLang; - *f += AbstractMetaAttributes::FinalInCpp; } } @@ -2448,8 +2139,8 @@ void AbstractMetaClass::fixFunctions() bool hasNonFinalModifier = false; bool isBaseImplPrivate = false; - FunctionModificationList mods = sf->modifications(sf->implementingClass()); - foreach (const FunctionModification &mod, mods) { + const FunctionModificationList &mods = sf->modifications(sf->implementingClass()); + for (const FunctionModification &mod : mods) { if (mod.isNonFinal()) { hasNonFinalModifier = true; break; @@ -2495,7 +2186,7 @@ void AbstractMetaClass::fixFunctions() funcsToAdd << sf; } - foreach (AbstractMetaFunction *f, funcsToAdd) + for (AbstractMetaFunction *f : qAsConst(funcsToAdd)) funcs << f->copy(); if (superClass) @@ -2506,9 +2197,9 @@ void AbstractMetaClass::fixFunctions() bool hasPrivateConstructors = false; bool hasPublicConstructors = false; - foreach (AbstractMetaFunction *func, funcs) { - FunctionModificationList mods = func->modifications(this); - foreach (const FunctionModification &mod, mods) { + for (AbstractMetaFunction *func : qAsConst(funcs)) { + const FunctionModificationList &mods = func->modifications(this); + for (const FunctionModification &mod : mods) { if (mod.isRenameModifier()) { func->setName(mod.renamedTo()); } @@ -2517,7 +2208,7 @@ void AbstractMetaClass::fixFunctions() // Make sure class is abstract if one of the functions is if (func->isAbstract()) { (*this) += AbstractMetaAttributes::Abstract; - (*this) -= AbstractMetaAttributes::Final; + (*this) -= AbstractMetaAttributes::FinalInTargetLang; } if (func->isConstructor()) { @@ -2537,75 +2228,72 @@ void AbstractMetaClass::fixFunctions() if (hasPrivateConstructors && !hasPublicConstructors) { (*this) += AbstractMetaAttributes::Abstract; - (*this) -= AbstractMetaAttributes::Final; - } - - foreach (AbstractMetaFunction *f1, funcs) { - foreach (AbstractMetaFunction *f2, funcs) { - if (f1 != f2) { - const AbstractMetaFunction::CompareResult cmp = f1->compareTo(f2); - if ((cmp & AbstractMetaFunction::EqualName) - && !f1->isFinalInCpp() - && f2->isFinalInCpp()) { - *f2 += AbstractMetaAttributes::FinalOverload; - } - } - } + (*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::minimalSignature() const +QString AbstractMetaType::formatSignature(bool minimal) const { - QString minimalSignature; + QString result; if (isConstant()) - minimalSignature += QLatin1String("const "); - minimalSignature += typeEntry()->qualifiedCppName(); - if (hasInstantiations()) { - AbstractMetaTypeList instantiations = this->instantiations(); - minimalSignature += QLatin1String("< "); - for (int i = 0; i < instantiations.size(); ++i) { + result += QLatin1String("const "); + 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) - minimalSignature += QLatin1Char(','); - minimalSignature += instantiations[i]->minimalSignature(); + result += QLatin1Char(','); + result += m_instantiations.at(i)->minimalSignature(); } - minimalSignature += QLatin1String(" >"); + result += QLatin1String(" >"); } - for (int j = 0; j < indirections(); ++j) - minimalSignature += QLatin1Char('*'); + if (!minimal && (m_indirections != 0 || m_referenceType != NoReference)) + result += QLatin1Char(' '); + if (m_indirections) + result += QString(m_indirections, QLatin1Char('*')); switch (referenceType()) { case NoReference: break; case LValueReference: - minimalSignature += QLatin1Char('&'); + result += QLatin1Char('&'); break; case RValueReference: - minimalSignature += QLatin1String("&&"); + result += QLatin1String("&&"); break; } - - return minimalSignature; -} - -bool AbstractMetaType::hasNativeId() const -{ - return (isQObject() || isValue() || isObject()) && typeEntry()->isNativeIdBased(); -} - -bool AbstractMetaType::isTargetLangEnum() const -{ - return isEnum() && !static_cast<const EnumTypeEntry *>(typeEntry())->forceInteger(); + return result; } -bool AbstractMetaType::isTargetLangFlags() const +bool AbstractMetaType::isCppPrimitive() const { - return isFlags() && !static_cast<const FlagsTypeEntry *>(typeEntry())->forceInteger(); + return m_pattern == PrimitivePattern && m_typeEntry->isCppPrimitive(); } - /******************************************************************************* * Other stuff... */ @@ -2641,15 +2329,6 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const AbstractMetaClassList &class return metaClass->findEnum(enumName); } -AbstractMetaEnumValue *AbstractMetaEnumValueList::find(const QString &name) const -{ - for (int i = 0; i < size(); ++i) { - if (name == at(i)->name()) - return at(i); - } - return 0; -} - AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const AbstractMetaClassList &classes, const QString &name) { @@ -2664,8 +2343,9 @@ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const AbstractMetaClassL return cl->findEnumValue(enumName, 0); } - foreach (AbstractMetaClass* metaClass, classes) { - foreach(AbstractMetaEnum* metaEnum, metaClass->enums()) { + for (AbstractMetaClass *metaClass : classes) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (AbstractMetaEnum *metaEnum : enums) { AbstractMetaEnumValue* enumValue = metaClass->findEnumValue(name, metaEnum); if (enumValue) return enumValue; @@ -2688,17 +2368,17 @@ AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &cla if (name.isEmpty()) return 0; - foreach (AbstractMetaClass *c, classes) { + for (AbstractMetaClass *c : classes) { if (c->qualifiedCppName() == name) return c; } - foreach (AbstractMetaClass *c, classes) { + for (AbstractMetaClass *c : classes) { if (c->fullName() == name) return c; } - foreach (AbstractMetaClass *c, classes) { + for (AbstractMetaClass *c : classes) { if (c->name() == name) return c; } @@ -2709,7 +2389,7 @@ AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &cla AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes, const TypeEntry* typeEntry) { - foreach (AbstractMetaClass* c, classes) { + for (AbstractMetaClass* c : classes) { if (c->typeEntry() == typeEntry) return c; } @@ -2725,6 +2405,8 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac) d << "AbstractMetaClass("; if (ac) { d << '"' << ac->fullName() << '"'; + if (ac->attributes() & AbstractMetaAttributes::FinalCppClass) + d << " [final]"; if (ac->m_baseClass) d << ", inherits \"" << ac->m_baseClass->name() << '"'; const AbstractMetaEnumList &enums = ac->enums(); @@ -2765,6 +2447,20 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac) } #endif // !QT_NO_DEBUG_STREAM +/******************************************************************************* +* AbstractMetaEnum +*/ + +AbstractMetaEnum::AbstractMetaEnum() : + m_hasQenumsDeclaration(false) +{ +} + +AbstractMetaEnum::~AbstractMetaEnum() +{ + qDeleteAll(m_enumValues); +} + QString AbstractMetaEnum::name() const { return m_typeEntry->targetLangName(); |