diff options
Diffstat (limited to 'sources/shiboken6/ApiExtractor/parser')
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/codemodel.cpp | 550 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/codemodel.h | 245 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/codemodel_enums.h | 44 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h | 62 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/enumvalue.cpp | 88 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/enumvalue.h | 49 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/typeinfo.cpp | 168 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/typeinfo.h | 57 |
8 files changed, 685 insertions, 578 deletions
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp index 82f5e1a2c..259a706dc 100644 --- a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp +++ b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp @@ -1,61 +1,29 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "codemodel.h" #include <sourcelocation.h> +#include <debughelpers_p.h> #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QRegularExpression> #include <algorithm> -#include <functional> -#include <iostream> -// Predicate to find an item by name in a list of QSharedPointer<Item> -template <class T> class ModelItemNamePredicate -{ -public: - explicit ModelItemNamePredicate(const QString &name) : m_name(name) {} - bool operator()(const QSharedPointer<T> &item) const { return item->name() == m_name; } - -private: - const QString m_name; -}; +using namespace Qt::StringLiterals; template <class T> -static QSharedPointer<T> findModelItem(const QList<QSharedPointer<T> > &list, const QString &name) +static std::shared_ptr<T> findModelItem(const QList<std::shared_ptr<T> > &list, + QAnyStringView name) { - const auto it = std::find_if(list.cbegin(), list.cend(), ModelItemNamePredicate<T>(name)); - return it != list.cend() ? *it : QSharedPointer<T>(); + using ItemPtr = std::shared_ptr<T>; + auto pred = [name](const ItemPtr &item) { return item->name() == name; }; + const auto it = std::find_if(list.cbegin(), list.cend(), pred); + return it != list.cend() ? *it : ItemPtr{}; } // --------------------------------------------------------------------------- @@ -76,7 +44,7 @@ void CodeModel::addFile(const FileModelItem &item) m_files.append(item); } -FileModelItem CodeModel::findFile(const QString &name) const +FileModelItem CodeModel::findFile(QAnyStringView name) const { return findModelItem(m_files, name); } @@ -94,11 +62,11 @@ static CodeModelItem findRecursion(const ScopeModelItem &scope, return tp; if (TemplateTypeAliasModelItem tta = scope->findTemplateTypeAlias(nameSegment)) return tta; - return CodeModelItem(); + return {}; } if (auto nestedClass = scope->findClass(nameSegment)) return findRecursion(nestedClass, qualifiedName, segment + 1); - if (auto namespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) { + if (auto namespaceItem = std::dynamic_pointer_cast<_NamespaceModelItem>(scope)) { for (const auto &nestedNamespace : namespaceItem->namespaces()) { if (nestedNamespace->name() == nameSegment) { if (auto item = findRecursion(nestedNamespace, qualifiedName, segment + 1)) @@ -106,7 +74,7 @@ static CodeModelItem findRecursion(const ScopeModelItem &scope, } } } - return CodeModelItem(); + return {}; } CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) @@ -143,7 +111,7 @@ QDebug operator<<(QDebug d, const CodeModel *m) d << "CodeModel("; if (m) { const NamespaceModelItem globalNamespaceP = m->globalNamespace(); - if (globalNamespaceP.data()) + if (globalNamespaceP) globalNamespaceP->formatDebug(d); } else { d << '0'; @@ -256,27 +224,27 @@ SourceLocation _CodeModelItem::sourceLocation() const return SourceLocation(m_fileName, m_startLine); } -#ifndef QT_NO_DEBUG_STREAM -template <class It> -void formatSequence(QDebug &d, It i1, It i2, const char *separator=", ") +const _ScopeModelItem *_CodeModelItem::enclosingScope() const { - for (It i = i1; i != i2; ++i) { - if (i != i1) - d << separator; - d << *i; - } + return m_enclosingScope; } -template <class It> -static void formatPtrSequence(QDebug &d, It i1, It i2, const char *separator=", ") +void _CodeModelItem::setEnclosingScope(const _ScopeModelItem *s) +{ + m_enclosingScope = s; +} + +_ScopeModelItem::_ScopeModelItem(CodeModel *model, int kind) + : _CodeModelItem(model, kind) +{ +} + +_ScopeModelItem::_ScopeModelItem(CodeModel *model, const QString &name, int kind) + : _CodeModelItem(model, name, kind) { - for (It i = i1; i != i2; ++i) { - if (i != i1) - d << separator; - d << i->data(); - } } +#ifndef QT_NO_DEBUG_STREAM void _CodeModelItem::formatKind(QDebug &d, int k) { switch (k) { @@ -377,14 +345,6 @@ void _ClassModelItem::setTemplateParameters(const TemplateParameterList &templat m_templateParameters = templateParameters; } -void _ClassModelItem::addBaseClass(const QString &name, Access accessPolicy) -{ - _ClassModelItem::BaseClass baseClass; - baseClass.name = name; - baseClass.accessPolicy = accessPolicy; - m_baseClasses.append(baseClass); -} - bool _ClassModelItem::extendsClass(const QString &name) const { for (const BaseClass &bc : m_baseClasses) { @@ -394,6 +354,16 @@ bool _ClassModelItem::extendsClass(const QString &name) const return false; } +_ClassModelItem::_ClassModelItem(CodeModel *model, int kind) + : _ScopeModelItem(model, kind) +{ +} + +_ClassModelItem::_ClassModelItem(CodeModel *model, const QString &name, int kind) + : _ScopeModelItem(model, name, kind) +{ +} + const QList<_ClassModelItem::UsingMember> &_ClassModelItem::usingMembers() const { return m_usingMembers; @@ -436,9 +406,9 @@ template <class List> static void formatModelItemList(QDebug &d, const char *prefix, const List &l, const char *separator = ", ") { - if (const int size = l.size()) { + if (const auto size = l.size()) { d << prefix << '[' << size << "]("; - for (int i = 0; i < size; ++i) { + for (qsizetype i = 0; i < size; ++i) { if (i) d << separator; l.at(i)->formatDebug(d); @@ -455,7 +425,7 @@ void _ClassModelItem::formatDebug(QDebug &d) const d << " [final]"; d << ", inherits="; d << ", inherits="; - for (int i = 0, size = m_baseClasses.size(); i < size; ++i) { + for (qsizetype i = 0, size = m_baseClasses.size(); i < size; ++i) { if (i) d << ", "; d << m_baseClasses.at(i).name << " (" << m_baseClasses.at(i).accessPolicy << ')'; @@ -474,12 +444,12 @@ void _ClassModelItem::formatDebug(QDebug &d) const // --------------------------------------------------------------------------- FunctionModelItem _ScopeModelItem::declaredFunction(const FunctionModelItem &item) { - for (const FunctionModelItem &fun : qAsConst(m_functions)) { + for (const FunctionModelItem &fun : std::as_const(m_functions)) { if (fun->name() == item->name() && fun->isSimilar(item)) return fun; } - return FunctionModelItem(); + return {}; } _ScopeModelItem::~_ScopeModelItem() = default; @@ -492,30 +462,54 @@ void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration) void _ScopeModelItem::addClass(const ClassModelItem &item) { m_classes.append(item); + item->setEnclosingScope(this); } void _ScopeModelItem::addFunction(const FunctionModelItem &item) { m_functions.append(item); + item->setEnclosingScope(this); } void _ScopeModelItem::addVariable(const VariableModelItem &item) { m_variables.append(item); + item->setEnclosingScope(this); } void _ScopeModelItem::addTypeDef(const TypeDefModelItem &item) { m_typeDefs.append(item); + item->setEnclosingScope(this); } void _ScopeModelItem::addTemplateTypeAlias(const TemplateTypeAliasModelItem &item) { m_templateTypeAliases.append(item); + item->setEnclosingScope(this); +} + +qsizetype _ScopeModelItem::indexOfEnum(const QString &name) const +{ + for (qsizetype i = 0, size = m_enums.size(); i < size; ++i) { + if (m_enums.at(i)->name() == name) + return i; + } + return -1; } void _ScopeModelItem::addEnum(const EnumModelItem &item) { + item->setEnclosingScope(this); + // A forward declaration of an enum ("enum class Foo;") is undistinguishable + // from an enum without values ("enum class QCborTag {}"), so, add all + // enums and replace existing ones without values by ones with values. + const int index = indexOfEnum(item->name()); + if (index >= 0) { + if (item->hasValues() && !m_enums.at(index)->hasValues()) + m_enums[index] = item; + return; + } m_enums.append(item); } @@ -555,12 +549,12 @@ template class LIBSAMPLE_EXPORT Tpl<54>; */ void _ScopeModelItem::purgeClassDeclarations() { - for (int i = m_classes.size() - 1; i >= 0; --i) { + for (auto i = m_classes.size() - 1; i >= 0; --i) { auto klass = m_classes.at(i); // For an empty class, check if there is a matching template // definition, and remove it if this is the case. if (!klass->isTemplate() && klass->isEmpty()) { - const QString definitionPrefix = klass->name() + QLatin1Char('<'); + const QString definitionPrefix = klass->name() + u'<'; const bool definitionFound = std::any_of(m_classes.cbegin(), m_classes.cend(), [definitionPrefix] (const ClassModelItem &c) { @@ -624,57 +618,135 @@ void _ScopeModelItem::formatDebug(QDebug &d) const } #endif // !QT_NO_DEBUG_STREAM -namespace { // Predicate to match a non-template class name against the class list. // "Vector" should match "Vector" as well as "Vector<T>" (as seen for methods // from within the class "Vector"). -class ClassNamePredicate +static bool matchClassNameNonTemplatePart(const ClassModelItem &item, const QString &name) { -public: - explicit ClassNamePredicate(const QString &name) : m_name(name) {} - bool operator()(const ClassModelItem &item) const - { - const QString &itemName = item->name(); - if (!itemName.startsWith(m_name)) - return false; - return itemName.size() == m_name.size() || itemName.at(m_name.size()) == QLatin1Char('<'); - } - -private: - const QString m_name; -}; -} // namespace + const QString &itemName = item->name(); + if (!itemName.startsWith(name)) + return false; + return itemName.size() == name.size() || itemName.at(name.size()) == u'<'; +} ClassModelItem _ScopeModelItem::findClass(const QString &name) const { // A fully qualified template is matched by name only - const ClassList::const_iterator it = name.contains(QLatin1Char('<')) - ? std::find_if(m_classes.begin(), m_classes.end(), ModelItemNamePredicate<_ClassModelItem>(name)) - : std::find_if(m_classes.begin(), m_classes.end(), ClassNamePredicate(name)); + const ClassList::const_iterator it = name.contains(u'<') + ? std::find_if(m_classes.begin(), m_classes.end(), + [&name](const ClassModelItem &item) { + return item->name() == name; }) + : std::find_if(m_classes.begin(), m_classes.end(), + [&name](const ClassModelItem &item) { + return matchClassNameNonTemplatePart(item, name); }); return it != m_classes.end() ? *it : ClassModelItem(); } -VariableModelItem _ScopeModelItem::findVariable(const QString &name) const +VariableModelItem _ScopeModelItem::findVariable(QAnyStringView name) const { return findModelItem(m_variables, name); } -TypeDefModelItem _ScopeModelItem::findTypeDef(const QString &name) const +TypeDefModelItem _ScopeModelItem::findTypeDef(QAnyStringView name) const { return findModelItem(m_typeDefs, name); } -TemplateTypeAliasModelItem _ScopeModelItem::findTemplateTypeAlias(const QString &name) const +TemplateTypeAliasModelItem _ScopeModelItem::findTemplateTypeAlias(QAnyStringView name) const { return findModelItem(m_templateTypeAliases, name); } -EnumModelItem _ScopeModelItem::findEnum(const QString &name) const +EnumModelItem _ScopeModelItem::findEnum(QAnyStringView name) const { return findModelItem(m_enums, name); } -FunctionList _ScopeModelItem::findFunctions(const QString &name) const +_ScopeModelItem::FindEnumByValueReturn + _ScopeModelItem::findEnumByValueHelper(QStringView fullValue, + QStringView enumValue) const +{ + const bool unqualified = fullValue.size() == enumValue.size(); + QString scopePrefix = scope().join(u"::"); + if (!scopePrefix.isEmpty()) + scopePrefix += u"::"_s; + scopePrefix += name() + u"::"_s; + + for (const auto &e : m_enums) { + const auto index = e->indexOfValue(enumValue); + if (index != -1) { + QString fullyQualifiedName = scopePrefix; + if (e->enumKind() != AnonymousEnum) + fullyQualifiedName += e->name() + u"::"_s; + fullyQualifiedName += e->enumerators().at(index)->name(); + if (unqualified || fullyQualifiedName.endsWith(fullValue)) + return {e, fullyQualifiedName}; + // For standard enums, check the name without enum name + if (e->enumKind() == CEnum) { + const QString qualifiedName = + scopePrefix + e->enumerators().at(index)->name(); + if (qualifiedName.endsWith(fullValue)) + return {e, fullyQualifiedName}; + } + } + } + + return {}; +} + +// Helper to recursively find the scope of an enum value +_ScopeModelItem::FindEnumByValueReturn + _ScopeModelItem::findEnumByValueRecursion(const _ScopeModelItem *scope, + QStringView fullValue, + QStringView enumValue, + bool searchSiblingNamespaces) +{ + if (const auto e = scope->findEnumByValueHelper(fullValue, enumValue)) + return e; + + if (auto *enclosingScope = scope->enclosingScope()) { + // The enclosing scope may have several sibling namespaces of that name. + if (searchSiblingNamespaces && scope->kind() == Kind_Namespace) { + if (auto *enclosingNamespace = dynamic_cast<const _NamespaceModelItem *>(enclosingScope)) { + for (const auto &sibling : enclosingNamespace->namespaces()) { + if (sibling.get() != scope && sibling->name() == scope->name()) { + if (const auto e = findEnumByValueRecursion(sibling.get(), + fullValue, enumValue, false)) { + return e; + } + } + } + } + } + + if (const auto e = findEnumByValueRecursion(enclosingScope, fullValue, enumValue)) + return e; + } + + // PYSIDE-331: We need to also search the base classes. + if (auto *classItem = dynamic_cast<const _ClassModelItem *>(scope)) { + for (const auto &base : classItem->baseClasses()) { + if (base.klass) { + auto *c = base.klass.get(); + if (const auto e = findEnumByValueRecursion(c, fullValue, enumValue)) + return e; + } + } + } + + return {}; +} + +_ScopeModelItem::FindEnumByValueReturn + _ScopeModelItem::findEnumByValue(QStringView value) const +{ + const auto lastQualifier = value.lastIndexOf(u"::"); + const auto enumValue = lastQualifier == -1 + ? value : value.mid(lastQualifier + 2); + return findEnumByValueRecursion(this, value, enumValue); +} + +FunctionList _ScopeModelItem::findFunctions(QAnyStringView name) const { FunctionList result; for (const FunctionModelItem &func : m_functions) { @@ -685,16 +757,25 @@ FunctionList _ScopeModelItem::findFunctions(const QString &name) const } // --------------------------------------------------------------------------- -_NamespaceModelItem::~_NamespaceModelItem() +_NamespaceModelItem::_NamespaceModelItem(CodeModel *model, int kind) + : _ScopeModelItem(model, kind) { } +_NamespaceModelItem::_NamespaceModelItem(CodeModel *model, const QString &name, int kind) + : _ScopeModelItem(model, name, kind) +{ +} + +_NamespaceModelItem::~_NamespaceModelItem() = default; + void _NamespaceModelItem::addNamespace(NamespaceModelItem item) { + item->setEnclosingScope(this); m_namespaces.append(item); } -NamespaceModelItem _NamespaceModelItem::findNamespace(const QString &name) const +NamespaceModelItem _NamespaceModelItem::findNamespace(QAnyStringView name) const { return findModelItem(m_namespaces, name); } @@ -726,10 +807,18 @@ void _NamespaceModelItem::formatDebug(QDebug &d) const #endif // !QT_NO_DEBUG_STREAM // --------------------------------------------------------------------------- -_ArgumentModelItem::~_ArgumentModelItem() +_ArgumentModelItem::_ArgumentModelItem(CodeModel *model, int kind) + : _CodeModelItem(model, kind) { } +_ArgumentModelItem::_ArgumentModelItem(CodeModel *model, const QString &name, int kind) + : _CodeModelItem(model, name, kind) +{ +} + +_ArgumentModelItem::~_ArgumentModelItem() = default; + TypeInfo _ArgumentModelItem::type() const { return m_type; @@ -750,11 +839,23 @@ void _ArgumentModelItem::setDefaultValue(bool defaultValue) m_defaultValue = defaultValue; } +bool _ArgumentModelItem::scopeResolution() const +{ + return m_scopeResolution; +} + +void _ArgumentModelItem::setScopeResolution(bool v) +{ + m_scopeResolution = v; +} + #ifndef QT_NO_DEBUG_STREAM void _ArgumentModelItem::formatDebug(QDebug &d) const { _CodeModelItem::formatDebug(d); d << ", type=" << m_type; + if (m_scopeResolution) + d << ", [m_scope resolution]"; if (m_defaultValue) d << ", defaultValue=\"" << m_defaultValueExpression << '"'; } @@ -773,12 +874,12 @@ bool _FunctionModelItem::isSimilar(const FunctionModelItem &other) const if (isVariadics() != other->isVariadics()) return false; - if (arguments().count() != other->arguments().count()) + if (arguments().size() != other->arguments().size()) return false; // ### check the template parameters - for (int i = 0; i < arguments().count(); ++i) { + for (qsizetype i = 0; i < arguments().size(); ++i) { ArgumentModelItem arg1 = arguments().at(i); ArgumentModelItem arg2 = other->arguments().at(i); @@ -789,6 +890,16 @@ bool _FunctionModelItem::isSimilar(const FunctionModelItem &other) const return true; } +_FunctionModelItem::_FunctionModelItem(CodeModel *model, int kind) + : _MemberModelItem(model, kind), m_flags(0) +{ +} + +_FunctionModelItem::_FunctionModelItem(CodeModel *model, const QString &name, int kind) + : _MemberModelItem(model, name, kind), m_flags(0) +{ +} + ArgumentList _FunctionModelItem::arguments() const { return m_arguments; @@ -819,55 +930,76 @@ void _FunctionModelItem::setVariadics(bool isVariadics) m_isVariadics = isVariadics; } -bool _FunctionModelItem::isDefaultConstructor() const +bool _FunctionModelItem::scopeResolution() const { - return m_functionType == CodeModel::Constructor - && (m_arguments.isEmpty() || m_arguments.constFirst()->defaultValue()); + return m_scopeResolution; } -bool _FunctionModelItem::isNoExcept() const +void _FunctionModelItem::setScopeResolution(bool v) { - return m_exceptionSpecification == ExceptionSpecification::NoExcept; + m_scopeResolution = v; } -ExceptionSpecification _FunctionModelItem::exceptionSpecification() const +bool _FunctionModelItem::isDefaultConstructor() const { - return m_exceptionSpecification; + return m_functionType == CodeModel::Constructor + && (m_arguments.isEmpty() || m_arguments.constFirst()->defaultValue()); } -void _FunctionModelItem::setExceptionSpecification(ExceptionSpecification e) +bool _FunctionModelItem::isSpaceshipOperator() const { - m_exceptionSpecification = e; + return m_functionType == CodeModel::ComparisonOperator + && name() == u"operator<=>"; } -bool _FunctionModelItem::isDeleted() const +bool _FunctionModelItem::isNoExcept() const { - return m_isDeleted; + return m_exceptionSpecification == ExceptionSpecification::NoExcept; } -void _FunctionModelItem::setDeleted(bool d) +bool _FunctionModelItem::isOperator() const { - m_isDeleted = d; + bool result = false; + switch (m_functionType) { + case CodeModel::CallOperator: + case CodeModel::ConversionOperator: + case CodeModel::DereferenceOperator: + case CodeModel::ReferenceOperator: + case CodeModel::ArrowOperator: + case CodeModel::ArithmeticOperator: + case CodeModel::IncrementOperator: + case CodeModel::DecrementOperator: + case CodeModel::BitwiseOperator: + case CodeModel::LogicalOperator: + case CodeModel::ShiftOperator: + case CodeModel::SubscriptOperator: + case CodeModel::ComparisonOperator: + result = true; + break; + default: + break; + } + return result; } -bool _FunctionModelItem::isDeprecated() const +ExceptionSpecification _FunctionModelItem::exceptionSpecification() const { - return m_isDeprecated; + return m_exceptionSpecification; } -void _FunctionModelItem::setDeprecated(bool d) +void _FunctionModelItem::setExceptionSpecification(ExceptionSpecification e) { - m_isDeprecated = d; + m_exceptionSpecification = e; } -bool _FunctionModelItem::isVirtual() const +bool _FunctionModelItem::isDeleted() const { - return m_isVirtual; + return m_isDeleted; } -void _FunctionModelItem::setVirtual(bool isVirtual) +void _FunctionModelItem::setDeleted(bool d) { - m_isVirtual = isVirtual; + m_isDeleted = d; } bool _FunctionModelItem::isInline() const @@ -875,60 +1007,19 @@ bool _FunctionModelItem::isInline() const return m_isInline; } -bool _FunctionModelItem::isOverride() const -{ - return m_isOverride; -} - -void _FunctionModelItem::setOverride(bool o) -{ - m_isOverride = o; -} - -bool _FunctionModelItem::isFinal() const -{ - return m_isFinal; -} - -void _FunctionModelItem::setFinal(bool f) -{ - m_isFinal = f; -} - void _FunctionModelItem::setInline(bool isInline) { m_isInline = isInline; } -bool _FunctionModelItem::isExplicit() const -{ - return m_isExplicit; -} - -void _FunctionModelItem::setExplicit(bool isExplicit) -{ - m_isExplicit = isExplicit; -} - -bool _FunctionModelItem::isAbstract() const +bool _FunctionModelItem::isHiddenFriend() const { - return m_isAbstract; + return m_isHiddenFriend; } -void _FunctionModelItem::setAbstract(bool isAbstract) +void _FunctionModelItem::setHiddenFriend(bool f) { - m_isAbstract = isAbstract; -} - -// Qt -bool _FunctionModelItem::isInvokable() const -{ - return m_isInvokable; -} - -void _FunctionModelItem::setInvokable(bool isInvokable) -{ - m_isInvokable = isInvokable; + m_isHiddenFriend = f; } QString _FunctionModelItem::typeSystemSignature() const // For dumping out type system files @@ -936,7 +1027,7 @@ QString _FunctionModelItem::typeSystemSignature() const // For dumping out type QString result; QTextStream str(&result); str << name() << '('; - for (int a = 0, size = m_arguments.size(); a < size; ++a) { + for (qsizetype a = 0, size = m_arguments.size(); a < size; ++a) { if (a) str << ','; m_arguments.at(a)->type().formatTypeSystemSignature(str); @@ -980,6 +1071,7 @@ static const NameFunctionTypeHash &nameToOperatorFunction() {u"operator>=", CodeModel::ComparisonOperator}, {u"operator==", CodeModel::ComparisonOperator}, {u"operator!=", CodeModel::ComparisonOperator}, + {u"operator<=>", CodeModel::ComparisonOperator}, {u"operator!", CodeModel::LogicalOperator}, {u"operator&&", CodeModel::LogicalOperator}, {u"operator||", CodeModel::LogicalOperator}, @@ -1054,20 +1146,22 @@ void _FunctionModelItem::formatDebug(QDebug &d) const d << " [deleted!]"; if (m_isInline) d << " [inline]"; - if (m_isVirtual) + if (m_attributes.testFlag(FunctionAttribute::Virtual)) d << " [virtual]"; - if (m_isOverride) + if (m_attributes.testFlag(FunctionAttribute::Override)) d << " [override]"; - if (m_isDeprecated) + if (m_attributes.testFlag(FunctionAttribute::Deprecated)) d << " [deprecated]"; - if (m_isFinal) + if (m_attributes.testFlag(FunctionAttribute::Final)) d << " [final]"; - if (m_isAbstract) + if (m_attributes.testFlag(FunctionAttribute::Abstract)) d << " [abstract]"; - if (m_isExplicit) + if (m_attributes.testFlag(FunctionAttribute::Explicit)) d << " [explicit]"; if (m_isInvokable) d << " [invokable]"; + if (m_scopeResolution) + d << " [scope resolution]"; formatModelItemList(d, ", arguments=", m_arguments); if (m_isVariadics) d << ",..."; @@ -1075,6 +1169,16 @@ void _FunctionModelItem::formatDebug(QDebug &d) const #endif // !QT_NO_DEBUG_STREAM // --------------------------------------------------------------------------- +_TypeDefModelItem::_TypeDefModelItem(CodeModel *model, int kind) + : _CodeModelItem(model, kind) +{ +} + +_TypeDefModelItem::_TypeDefModelItem(CodeModel *model, const QString &name, int kind) + : _CodeModelItem(model, name, kind) +{ +} + TypeInfo _TypeDefModelItem::type() const { return m_type; @@ -1126,7 +1230,7 @@ void _TemplateTypeAliasModelItem::formatDebug(QDebug &d) const { _CodeModelItem::formatDebug(d); d << ", <"; - for (int i = 0, count = m_templateParameters.size(); i < count; ++i) { + for (qsizetype i = 0, count = m_templateParameters.size(); i < count; ++i) { if (i) d << ", "; d << m_templateParameters.at(i)->name(); @@ -1136,6 +1240,16 @@ void _TemplateTypeAliasModelItem::formatDebug(QDebug &d) const #endif // !QT_NO_DEBUG_STREAM // --------------------------------------------------------------------------- +_EnumModelItem::_EnumModelItem(CodeModel *model, const QString &name, int kind) + : _CodeModelItem(model, name, kind) +{ +} + +_EnumModelItem::_EnumModelItem(CodeModel *model, int kind) + : _CodeModelItem(model, kind) +{ +} + Access _EnumModelItem::accessPolicy() const { return m_accessPolicy; @@ -1158,6 +1272,15 @@ void _EnumModelItem::addEnumerator(const EnumeratorModelItem &item) m_enumerators.append(item); } +qsizetype _EnumModelItem::indexOfValue(QStringView value) const +{ + for (qsizetype i = 0, size = m_enumerators.size(); i < size; ++i) { + if (m_enumerators.at(i)->name() == value) + return i; + } + return -1; +} + bool _EnumModelItem::isSigned() const { return m_signed; @@ -1168,6 +1291,26 @@ void _EnumModelItem::setSigned(bool s) m_signed = s; } +QString _EnumModelItem::underlyingType() const +{ + return m_underlyingType; +} + +void _EnumModelItem::setUnderlyingType(const QString &underlyingType) +{ + m_underlyingType = underlyingType; +} + +bool _EnumModelItem::isDeprecated() const +{ + return m_deprecated; +} + +void _EnumModelItem::setDeprecated(bool d) +{ + m_deprecated = d; +} + #ifndef QT_NO_DEBUG_STREAM void _EnumModelItem::formatDebug(QDebug &d) const { @@ -1182,6 +1325,8 @@ void _EnumModelItem::formatDebug(QDebug &d) const d << " (class)"; break; } + if (m_deprecated) + d << " (deprecated)"; if (!m_signed) d << " (unsigned)"; formatModelItemList(d, ", enumerators=", m_enumerators); @@ -1191,6 +1336,16 @@ void _EnumModelItem::formatDebug(QDebug &d) const // --------------------------------------------------------------------------- _EnumeratorModelItem::~_EnumeratorModelItem() = default; +_EnumeratorModelItem::_EnumeratorModelItem(CodeModel *model, int kind) + : _CodeModelItem(model, kind) +{ +} + +_EnumeratorModelItem::_EnumeratorModelItem(CodeModel *model, const QString &name, int kind) + : _CodeModelItem(model, name, kind) +{ +} + QString _EnumeratorModelItem::stringValue() const { return m_stringValue; @@ -1201,17 +1356,40 @@ void _EnumeratorModelItem::setStringValue(const QString &value) m_stringValue = value; } +bool _EnumeratorModelItem::isDeprecated() const +{ + return m_deprecated; +} + +void _EnumeratorModelItem::setDeprecated(bool d) +{ + m_deprecated = d; +} + #ifndef QT_NO_DEBUG_STREAM void _EnumeratorModelItem::formatDebug(QDebug &d) const { _CodeModelItem::formatDebug(d); d << ", value=" << m_value << ", stringValue=\"" << m_stringValue << '"'; + if (m_deprecated) + d << " (deprecated)"; } #endif // !QT_NO_DEBUG_STREAM // --------------------------------------------------------------------------- _TemplateParameterModelItem::~_TemplateParameterModelItem() = default; +_TemplateParameterModelItem::_TemplateParameterModelItem(CodeModel *model, int kind) + : _CodeModelItem(model, kind) +{ +} + +_TemplateParameterModelItem::_TemplateParameterModelItem(CodeModel *model, + const QString &name, int kind) + : _CodeModelItem(model, name, kind) +{ +} + TypeInfo _TemplateParameterModelItem::type() const { return m_type; @@ -1275,6 +1453,16 @@ void _MemberModelItem::setStatic(bool isStatic) m_isStatic = isStatic; } +_MemberModelItem::_MemberModelItem(CodeModel *model, int kind) + : _CodeModelItem(model, kind), m_flags(0) +{ +} + +_MemberModelItem::_MemberModelItem(CodeModel *model, const QString &name, int kind) + : _CodeModelItem(model, name, kind), m_flags(0) +{ +} + bool _MemberModelItem::isConstant() const { return m_isConstant; diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.h b/sources/shiboken6/ApiExtractor/parser/codemodel.h index 75ad60aaf..b31c09163 100644 --- a/sources/shiboken6/ApiExtractor/parser/codemodel.h +++ b/sources/shiboken6/ApiExtractor/parser/codemodel.h @@ -1,31 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef CODEMODEL_H @@ -37,13 +12,14 @@ #include "typeinfo.h" #include <QtCore/QHash> -#include <QtCore/QPair> #include <QtCore/QSet> #include <QtCore/QString> #include <QtCore/QStringList> #include <QtCore/QList> +#include <QtCore/QWeakPointer> #include <optional> +#include <utility> QT_FORWARD_DECLARE_CLASS(QDebug) @@ -56,7 +32,7 @@ class CodeModel { Q_GADGET public: - Q_DISABLE_COPY(CodeModel) + Q_DISABLE_COPY_MOVE(CodeModel) enum FunctionType { Normal, @@ -98,7 +74,7 @@ public: NamespaceModelItem globalNamespace() const; void addFile(const FileModelItem &item); - FileModelItem findFile(const QString &name) const; + FileModelItem findFile(QAnyStringView name) const; static CodeModelItem findItem(const QStringList &qualifiedName, const ScopeModelItem &scope); @@ -115,8 +91,9 @@ QDebug operator<<(QDebug d, const CodeModel *m); class _CodeModelItem { - Q_DISABLE_COPY(_CodeModelItem) public: + Q_DISABLE_COPY_MOVE(_CodeModelItem) + enum Kind { /* These are bit-flags resembling inheritance */ Kind_Scope = 0x1, @@ -167,6 +144,9 @@ public: inline CodeModel *model() const { return m_model; } + const _ScopeModelItem *enclosingScope() const; + void setEnclosingScope(const _ScopeModelItem *s); + #ifndef QT_NO_DEBUG_STREAM static void formatKind(QDebug &d, int k); virtual void formatDebug(QDebug &d) const; @@ -178,6 +158,7 @@ protected: private: CodeModel *m_model; + const _ScopeModelItem *m_enclosingScope = nullptr; int m_kind; int m_startLine; int m_startColumn; @@ -195,12 +176,13 @@ QDebug operator<<(QDebug d, const _CodeModelItem *t); class _ScopeModelItem: public _CodeModelItem { public: + Q_DISABLE_COPY_MOVE(_ScopeModelItem) DECLARE_MODEL_NODE(Scope) ~_ScopeModelItem(); ClassList classes() const { return m_classes; } - EnumList enums() const { return m_enums; } + const EnumList &enums() const { return m_enums; } inline const FunctionList &functions() const { return m_functions; } TypeDefList typeDefs() const { return m_typeDefs; } TemplateTypeAliasList templateTypeAliases() const { return m_templateTypeAliases; } @@ -214,11 +196,21 @@ public: void addVariable(const VariableModelItem &item); ClassModelItem findClass(const QString &name) const; - EnumModelItem findEnum(const QString &name) const; - FunctionList findFunctions(const QString &name) const; - TypeDefModelItem findTypeDef(const QString &name) const; - TemplateTypeAliasModelItem findTemplateTypeAlias(const QString &name) const; - VariableModelItem findVariable(const QString &name) const; + EnumModelItem findEnum(QAnyStringView name) const; + + struct FindEnumByValueReturn + { + operator bool() const { return bool(item); } + + EnumModelItem item; + QString qualifiedName; + }; + FindEnumByValueReturn findEnumByValue(QStringView value) const; + + FunctionList findFunctions(QAnyStringView name) const; + TypeDefModelItem findTypeDef(QAnyStringView name) const; + TemplateTypeAliasModelItem findTemplateTypeAlias(QAnyStringView name) const; + VariableModelItem findVariable(QAnyStringView name) const; void addEnumsDeclaration(const QString &enumsDeclaration); QStringList enumsDeclarations() const { return m_enumsDeclarations; } @@ -233,10 +225,9 @@ public: #endif protected: - explicit _ScopeModelItem(CodeModel *model, int kind = __node_kind) - : _CodeModelItem(model, kind) {} - explicit _ScopeModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _CodeModelItem(model, name, kind) {} + explicit _ScopeModelItem(CodeModel *model, int kind = __node_kind); + explicit _ScopeModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); void appendScope(const _ScopeModelItem &other); @@ -245,6 +236,15 @@ protected: #endif private: + qsizetype indexOfEnum(const QString &name) const; + + FindEnumByValueReturn findEnumByValueHelper(QStringView fullValue, + QStringView value) const; + static FindEnumByValueReturn + findEnumByValueRecursion(const _ScopeModelItem *scope, + QStringView fullValue, QStringView value, + bool searchSiblingNamespaces = true); + ClassList m_classes; EnumList m_enums; TypeDefList m_typeDefs; @@ -259,11 +259,13 @@ private: class _ClassModelItem: public _ScopeModelItem { public: + Q_DISABLE_COPY_MOVE(_ClassModelItem) DECLARE_MODEL_NODE(Class) struct BaseClass { QString name; + ClassModelItem klass; // Might be null in case of templates Access accessPolicy = Access::Public; }; @@ -274,19 +276,18 @@ public: Access access = Access::Public; }; - explicit _ClassModelItem(CodeModel *model, int kind = __node_kind) - : _ScopeModelItem(model, kind), m_classType(CodeModel::Class) {} - explicit _ClassModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _ScopeModelItem(model, name, kind), m_classType(CodeModel::Class) {} + explicit _ClassModelItem(CodeModel *model, int kind = __node_kind); + explicit _ClassModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); ~_ClassModelItem(); - QList<BaseClass> baseClasses() const { return m_baseClasses; } + const QList<BaseClass> &baseClasses() const { return m_baseClasses; } const QList<UsingMember> &usingMembers() const; void addUsingMember(const QString &className, const QString &memberName, Access accessPolicy); - void addBaseClass(const QString &name, Access accessPolicy); + void addBaseClass(const BaseClass &b) { m_baseClasses.append(b); } TemplateParameterList templateParameters() const; void setTemplateParameters(const TemplateParameterList &templateParameters); @@ -313,7 +314,7 @@ private: QList<BaseClass> m_baseClasses; QList<UsingMember> m_usingMembers; TemplateParameterList m_templateParameters; - CodeModel::ClassType m_classType; + CodeModel::ClassType m_classType = CodeModel::Class; QStringList m_propertyDeclarations; bool m_final = false; @@ -322,12 +323,12 @@ private: class _NamespaceModelItem: public _ScopeModelItem { public: + Q_DISABLE_COPY_MOVE(_NamespaceModelItem) DECLARE_MODEL_NODE(Namespace) - explicit _NamespaceModelItem(CodeModel *model, int kind = __node_kind) - : _ScopeModelItem(model, kind) {} - explicit _NamespaceModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _ScopeModelItem(model, name, kind) {} + explicit _NamespaceModelItem(CodeModel *model, int kind = __node_kind); + explicit _NamespaceModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); ~_NamespaceModelItem(); const NamespaceList &namespaces() const { return m_namespaces; } @@ -337,7 +338,7 @@ public: void addNamespace(NamespaceModelItem item); - NamespaceModelItem findNamespace(const QString &name) const; + NamespaceModelItem findNamespace(QAnyStringView name) const; void appendNamespace(const _NamespaceModelItem &other); @@ -353,24 +354,23 @@ private: class _FileModelItem: public _NamespaceModelItem { public: + Q_DISABLE_COPY_MOVE(_FileModelItem) DECLARE_MODEL_NODE(File) - explicit _FileModelItem(CodeModel *model, int kind = __node_kind) - : _NamespaceModelItem(model, kind) {} - explicit _FileModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _NamespaceModelItem(model, name, kind) {} + using _NamespaceModelItem::_NamespaceModelItem; + ~_FileModelItem(); }; class _ArgumentModelItem: public _CodeModelItem { public: + Q_DISABLE_COPY_MOVE(_ArgumentModelItem) DECLARE_MODEL_NODE(Argument) - explicit _ArgumentModelItem(CodeModel *model, int kind = __node_kind) - : _CodeModelItem(model, kind), m_defaultValue(false) {} - explicit _ArgumentModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _CodeModelItem(model, name, kind), m_defaultValue(false) {} + explicit _ArgumentModelItem(CodeModel *model, int kind = __node_kind); + explicit _ArgumentModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); ~_ArgumentModelItem(); TypeInfo type() const; @@ -382,6 +382,10 @@ public: QString defaultValueExpression() const { return m_defaultValueExpression; } void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; } + // Argument type has scope resolution "::ArgumentType" + bool scopeResolution() const; + void setScopeResolution(bool v); + #ifndef QT_NO_DEBUG_STREAM void formatDebug(QDebug &d) const override; #endif @@ -389,18 +393,19 @@ public: private: TypeInfo m_type; QString m_defaultValueExpression; - bool m_defaultValue; + bool m_defaultValue = false; + bool m_scopeResolution = false; }; class _MemberModelItem: public _CodeModelItem { public: + Q_DISABLE_COPY_MOVE(_MemberModelItem) DECLARE_MODEL_NODE(Member) - explicit _MemberModelItem(CodeModel *model, int kind = __node_kind) - : _CodeModelItem(model, kind), m_accessPolicy(Access::Public), m_flags(0) {} - explicit _MemberModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _CodeModelItem(model, name, kind), m_accessPolicy(Access::Public), m_flags(0) {} + explicit _MemberModelItem(CodeModel *model, int kind = __node_kind); + explicit _MemberModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); ~_MemberModelItem(); bool isConstant() const; @@ -443,7 +448,7 @@ public: private: TemplateParameterList m_templateParameters; TypeInfo m_type; - Access m_accessPolicy; + Access m_accessPolicy = Access::Public; union { struct { uint m_isConstant: 1; @@ -463,12 +468,12 @@ private: class _FunctionModelItem: public _MemberModelItem { public: + Q_DISABLE_COPY_MOVE(_FunctionModelItem) DECLARE_MODEL_NODE(Function) - explicit _FunctionModelItem(CodeModel *model, int kind = __node_kind) - : _MemberModelItem(model, kind), m_functionType(CodeModel::Normal), m_flags(0) {} - explicit _FunctionModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _MemberModelItem(model, name, kind), m_functionType(CodeModel::Normal), m_flags(0) {} + explicit _FunctionModelItem(CodeModel *model, int kind = __node_kind); + explicit _FunctionModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); ~_FunctionModelItem(); ArgumentList arguments() const; @@ -480,42 +485,34 @@ public: static std::optional<CodeModel::FunctionType> functionTypeFromName(QStringView name); + FunctionAttributes attributes() const { return m_attributes; } + void setAttributes(FunctionAttributes a) { m_attributes = a; } + void setAttribute(FunctionAttribute a, bool on = true) { m_attributes.setFlag(a, on); } + bool isDeleted() const; void setDeleted(bool d); - bool isDeprecated() const; - void setDeprecated(bool d); - - bool isVirtual() const; - void setVirtual(bool isVirtual); - - bool isOverride() const; - void setOverride(bool o); - - bool isFinal() const; - void setFinal(bool f); - bool isInline() const; void setInline(bool isInline); - bool isExplicit() const; - void setExplicit(bool isExplicit); - - bool isInvokable() const; // Qt - void setInvokable(bool isInvokable); // Qt - - bool isAbstract() const; - void setAbstract(bool isAbstract); + bool isHiddenFriend() const; + void setHiddenFriend(bool f); bool isVariadics() const; void setVariadics(bool isVariadics); + bool scopeResolution() const; // Return type has scope resolution "::ReturnType" + void setScopeResolution(bool v); + bool isDefaultConstructor() const; + bool isSpaceshipOperator() const; bool isSimilar(const FunctionModelItem &other) const; bool isNoExcept() const; + bool isOperator() const; + ExceptionSpecification exceptionSpecification() const; void setExceptionSpecification(ExceptionSpecification e); @@ -532,19 +529,16 @@ private: CodeModel::FunctionType _determineTypeHelper() const; ArgumentList m_arguments; - CodeModel::FunctionType m_functionType; + FunctionAttributes m_attributes; + CodeModel::FunctionType m_functionType = CodeModel::Normal; union { struct { uint m_isDeleted: 1; - uint m_isVirtual: 1; - uint m_isOverride: 1; - uint m_isFinal: 1; - uint m_isDeprecated: 1; uint m_isInline: 1; - uint m_isAbstract: 1; - uint m_isExplicit: 1; uint m_isVariadics: 1; + uint m_isHiddenFriend: 1; uint m_isInvokable : 1; // Qt + uint m_scopeResolution: 1; }; uint m_flags; }; @@ -556,10 +550,7 @@ class _VariableModelItem: public _MemberModelItem public: DECLARE_MODEL_NODE(Variable) - explicit _VariableModelItem(CodeModel *model, int kind = __node_kind) - : _MemberModelItem(model, kind) {} - explicit _VariableModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _MemberModelItem(model, name, kind) {} + using _MemberModelItem::_MemberModelItem; }; class _TypeDefModelItem: public _CodeModelItem @@ -567,10 +558,9 @@ class _TypeDefModelItem: public _CodeModelItem public: DECLARE_MODEL_NODE(TypeDef) - explicit _TypeDefModelItem(CodeModel *model, int kind = __node_kind) - : _CodeModelItem(model, kind) {} - explicit _TypeDefModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _CodeModelItem(model, name, kind) {} + explicit _TypeDefModelItem(CodeModel *model, int kind = __node_kind); + explicit _TypeDefModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); TypeInfo type() const; void setType(const TypeInfo &type); @@ -610,12 +600,11 @@ private: class _EnumModelItem: public _CodeModelItem { public: + Q_DISABLE_COPY_MOVE(_EnumModelItem) DECLARE_MODEL_NODE(Enum) - explicit _EnumModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _CodeModelItem(model, name, kind) {} - explicit _EnumModelItem(CodeModel *model, int kind = __node_kind) - : _CodeModelItem(model, kind) {} + explicit _EnumModelItem(CodeModel *model, const QString &name, int kind = __node_kind); + explicit _EnumModelItem(CodeModel *model, int kind = __node_kind); ~_EnumModelItem(); Access accessPolicy() const; @@ -628,29 +617,39 @@ public: EnumKind enumKind() const { return m_enumKind; } void setEnumKind(EnumKind kind) { m_enumKind = kind; } + qsizetype indexOfValue(QStringView value) const; + #ifndef QT_NO_DEBUG_STREAM void formatDebug(QDebug &d) const override; #endif + bool isDeprecated() const; + void setDeprecated(bool d); + bool isSigned() const; void setSigned(bool s); + QString underlyingType() const; + void setUnderlyingType(const QString &underlyingType); + private: + QString m_underlyingType; Access m_accessPolicy = Access::Public; EnumeratorList m_enumerators; EnumKind m_enumKind = CEnum; + bool m_deprecated = false; bool m_signed = true; }; class _EnumeratorModelItem: public _CodeModelItem { public: + Q_DISABLE_COPY_MOVE(_EnumeratorModelItem) DECLARE_MODEL_NODE(Enumerator) - explicit _EnumeratorModelItem(CodeModel *model, int kind = __node_kind) - : _CodeModelItem(model, kind) {} - explicit _EnumeratorModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _CodeModelItem(model, name, kind) {} + explicit _EnumeratorModelItem(CodeModel *model, int kind = __node_kind); + explicit _EnumeratorModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); ~_EnumeratorModelItem(); QString stringValue() const; @@ -659,6 +658,9 @@ public: EnumValue value() const { return m_value; } void setValue(EnumValue v) { m_value = v; } + bool isDeprecated() const; + void setDeprecated(bool d); + #ifndef QT_NO_DEBUG_STREAM void formatDebug(QDebug &d) const override; #endif @@ -666,17 +668,18 @@ public: private: QString m_stringValue; EnumValue m_value; + bool m_deprecated = false; }; class _TemplateParameterModelItem: public _CodeModelItem { public: + Q_DISABLE_COPY_MOVE(_TemplateParameterModelItem) DECLARE_MODEL_NODE(TemplateParameter) - explicit _TemplateParameterModelItem(CodeModel *model, int kind = __node_kind) - : _CodeModelItem(model, kind), m_defaultValue(false) {} - explicit _TemplateParameterModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _CodeModelItem(model, name, kind), m_defaultValue(false) {} + explicit _TemplateParameterModelItem(CodeModel *model, int kind = __node_kind); + explicit _TemplateParameterModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); ~_TemplateParameterModelItem(); TypeInfo type() const; @@ -691,9 +694,7 @@ public: private: TypeInfo m_type; - bool m_defaultValue; + bool m_defaultValue = false; }; #endif // CODEMODEL_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h b/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h index 4f5121a08..e5c429bd0 100644 --- a/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h +++ b/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h @@ -1,34 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef CODEMODEL_ENUMS_H #define CODEMODEL_ENUMS_H +#include <QtCore/qflags.h> + enum ReferenceType { NoReference, LValueReference, @@ -68,4 +45,17 @@ enum class Access Public }; +enum class FunctionAttribute { + Abstract = 0x00000001, + Static = 0x00000002, + Virtual = 0x00000004, + Override = 0x00000008, + Final = 0x00000010, + Deprecated = 0x00000020, // Code annotation + Explicit = 0x00000040, // Constructor +}; + +Q_DECLARE_FLAGS(FunctionAttributes, FunctionAttribute) +Q_DECLARE_OPERATORS_FOR_FLAGS(FunctionAttributes) + #endif // CODEMODEL_ENUMS_H diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h index b138f2a2f..f0a25c9db 100644 --- a/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h +++ b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h @@ -1,38 +1,14 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef CODEMODEL_FWD_H #define CODEMODEL_FWD_H #include <QtCore/QList> -#include <QtCore/QSharedPointer> + +#include <memory> // forward declarations class CodeModel; @@ -52,20 +28,20 @@ class _VariableModelItem; class _MemberModelItem; class TypeInfo; -using ArgumentModelItem = QSharedPointer<_ArgumentModelItem>; -using ClassModelItem = QSharedPointer<_ClassModelItem>; -using CodeModelItem = QSharedPointer<_CodeModelItem>; -using EnumModelItem = QSharedPointer<_EnumModelItem>; -using EnumeratorModelItem = QSharedPointer<_EnumeratorModelItem>; -using FileModelItem = QSharedPointer<_FileModelItem>; -using FunctionModelItem = QSharedPointer<_FunctionModelItem>; -using NamespaceModelItem = QSharedPointer<_NamespaceModelItem>; -using ScopeModelItem = QSharedPointer<_ScopeModelItem>; -using TemplateParameterModelItem = QSharedPointer<_TemplateParameterModelItem>; -using TypeDefModelItem = QSharedPointer<_TypeDefModelItem>; -using TemplateTypeAliasModelItem = QSharedPointer<_TemplateTypeAliasModelItem>; -using VariableModelItem = QSharedPointer<_VariableModelItem>; -using MemberModelItem = QSharedPointer<_MemberModelItem>; +using ArgumentModelItem = std::shared_ptr<_ArgumentModelItem>; +using ClassModelItem = std::shared_ptr<_ClassModelItem>; +using CodeModelItem = std::shared_ptr<_CodeModelItem>; +using EnumModelItem = std::shared_ptr<_EnumModelItem>; +using EnumeratorModelItem = std::shared_ptr<_EnumeratorModelItem>; +using FileModelItem = std::shared_ptr<_FileModelItem>; +using FunctionModelItem = std::shared_ptr<_FunctionModelItem>; +using NamespaceModelItem = std::shared_ptr<_NamespaceModelItem>; +using ScopeModelItem = std::shared_ptr<_ScopeModelItem>; +using TemplateParameterModelItem = std::shared_ptr<_TemplateParameterModelItem>; +using TypeDefModelItem = std::shared_ptr<_TypeDefModelItem>; +using TemplateTypeAliasModelItem = std::shared_ptr<_TemplateTypeAliasModelItem>; +using VariableModelItem = std::shared_ptr<_VariableModelItem>; +using MemberModelItem = std::shared_ptr<_MemberModelItem>; using ArgumentList = QList<ArgumentModelItem>; using ClassList = QList<ClassModelItem>; diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp index 2ee7398ea..3749e16a8 100644 --- a/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp +++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "enumvalue.h" @@ -32,12 +7,34 @@ #include <QtCore/QString> #include <QtCore/QTextStream> +using namespace Qt::StringLiterals; + QString EnumValue::toString() const { return m_type == EnumValue::Signed ? QString::number(m_value) : QString::number(m_unsignedValue); } +QString EnumValue::toHex(int fieldWidth) const +{ + QString result; + QTextStream str(&result); + // Note: Qt goofes up formatting of negative padded hex numbers, it ends up + // with "0x00-1". Write '-' before. + if (isNegative()) + str << '-'; + str << "0x" << Qt::hex; + if (fieldWidth) { + str.setFieldWidth(fieldWidth); + str.setPadChar(u'0'); + } + if (m_type == EnumValue::Signed) + str << qAbs(m_value); + else + str << m_unsignedValue; + return result; +} + void EnumValue::setValue(qint64 v) { m_value = v; @@ -50,11 +47,37 @@ void EnumValue::setUnsignedValue(quint64 v) m_type = Unsigned; } -bool EnumValue::equals(const EnumValue &rhs) const +EnumValue EnumValue::toUnsigned() const { - if (m_type != rhs.m_type) + if (m_type == Unsigned) + return *this; + EnumValue result; + result.setUnsignedValue(m_value < 0 ? quint64(-m_value) : quint64(m_value)); + return result; +} + +bool comparesEqual(const EnumValue &lhs, const EnumValue &rhs) noexcept +{ + if (lhs.m_type != rhs.m_type) return false; - return m_type == Signed ? m_value == rhs.m_value : m_unsignedValue == rhs.m_unsignedValue; + return lhs.m_type == EnumValue::Signed + ? lhs.m_value == rhs.m_value : lhs.m_unsignedValue == rhs.m_unsignedValue; +} + +void EnumValue::formatDebugHex(QDebug &d) const +{ + d << "0x" << Qt::hex; + formatDebug(d); + d << Qt::dec; +} + +void EnumValue::formatDebug(QDebug &d) const +{ + + if (m_type == EnumValue::Signed) + d << m_value; + else + d << m_unsignedValue << 'u'; } #ifndef QT_NO_DEBUG_STREAM @@ -64,10 +87,7 @@ QDebug operator<<(QDebug d,const EnumValue &v) d.nospace(); d.noquote(); d << "EnumValue("; - if (v.m_type == EnumValue::Signed) - d << v.m_value; - else - d << v.m_unsignedValue << 'u'; + v.formatDebug(d); d << ')'; return d; } diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.h b/sources/shiboken6/ApiExtractor/parser/enumvalue.h index 3cd7d01a4..bbd5a712d 100644 --- a/sources/shiboken6/ApiExtractor/parser/enumvalue.h +++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.h @@ -1,35 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef ENUMVALUE_H #define ENUMVALUE_H -#include <QtCore/QtGlobal> +#include <QtCore/qtypes.h> +#include <QtCore/qtclasshelpermacros.h> +#include <QtCore/QtCompare> QT_FORWARD_DECLARE_CLASS(QDebug) QT_FORWARD_DECLARE_CLASS(QString) @@ -45,18 +22,29 @@ public: }; QString toString() const; + QString toHex(int fieldWidth = 0) const; Type type() { return m_type; } qint64 value() const { return m_value; } quint64 unsignedValue() const { return m_unsignedValue; } bool isNullValue() const { return m_type == Signed ? m_value == 0 : m_unsignedValue == 0u; } + bool isNegative() const { return m_type == Signed && m_value < 0; } void setValue(qint64 v); void setUnsignedValue(quint64 v); + EnumValue toUnsigned() const; + bool equals(const EnumValue &rhs) const; + void formatDebug(QDebug &d) const; + void formatDebugHex(QDebug &d) const; + private: + friend bool comparesEqual(const EnumValue &lhs, + const EnumValue &rhs) noexcept; + Q_DECLARE_EQUALITY_COMPARABLE(EnumValue) + #ifndef QT_NO_DEBUG_STREAM friend QDebug operator<<(QDebug, const EnumValue &); #endif @@ -70,9 +58,4 @@ private: Type m_type = Signed; }; -inline bool operator==(const EnumValue &e1, const EnumValue &e2) -{ return e1.equals(e2); } -inline bool operator!=(const EnumValue &e1, const EnumValue &e2) -{ return !e1.equals(e2); } - #endif // ENUMVALUE_H diff --git a/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp b/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp index e3fdeac84..f8c5c31d8 100644 --- a/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp +++ b/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp @@ -1,37 +1,15 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "typeinfo.h" #include "codemodel.h" #include <clangparser/clangutils.h> +#include <debughelpers_p.h> + +#include "qtcompat.h" #include <QtCore/QDebug> #include <QtCore/QStack> @@ -39,6 +17,8 @@ #include <iostream> +using namespace Qt::StringLiterals; + class TypeInfoData : public QSharedData { @@ -67,10 +47,10 @@ public: }; }; - ReferenceType m_referenceType; + ReferenceType m_referenceType = NoReference; }; -TypeInfoData::TypeInfoData() : flags(0), m_referenceType(NoReference) +TypeInfoData::TypeInfoData() : flags(0) { } @@ -81,9 +61,8 @@ TypeInfo::TypeInfo() : d(new TypeInfoData) TypeInfo::~TypeInfo() = default; TypeInfo::TypeInfo(const TypeInfo &) = default; TypeInfo& TypeInfo::operator=(const TypeInfo &) = default; -TypeInfo::TypeInfo(TypeInfo &&) = default; -TypeInfo& TypeInfo::operator=(TypeInfo &&) = default; - +TypeInfo::TypeInfo(TypeInfo &&) noexcept = default; +TypeInfo &TypeInfo::operator=(TypeInfo &&) noexcept = default; static inline TypeInfo createType(const QString &name) { @@ -94,13 +73,13 @@ static inline TypeInfo createType(const QString &name) TypeInfo TypeInfo::voidType() { - static const TypeInfo result = createType(QLatin1String("void")); + static const TypeInfo result = createType(u"void"_s); return result; } TypeInfo TypeInfo::varArgsType() { - static const TypeInfo result = createType(QLatin1String("...")); + static const TypeInfo result = createType(u"..."_s); return result; } @@ -119,7 +98,7 @@ TypeInfo TypeInfo::combine(const TypeInfo &__lhs, const TypeInfo &__rhs) __result.setArrayElements(__result.arrayElements() + __rhs.arrayElements()); - const auto instantiations = __rhs.instantiations(); + const auto &instantiations = __rhs.instantiations(); for (const auto &i : instantiations) __result.addInstantiation(i); @@ -148,7 +127,7 @@ bool TypeInfoData::isVoid() const && m_arguments.isEmpty() && m_arrayElements.isEmpty() && m_instantiations.isEmpty() && m_qualifiedName.size() == 1 - && m_qualifiedName.constFirst() == QLatin1String("void"); + && m_qualifiedName.constFirst() == u"void"; } bool TypeInfo::isVoid() const @@ -287,6 +266,12 @@ void TypeInfo::clearInstantiations() d->m_instantiations.clear(); } +bool TypeInfo::isPlain() const +{ + return d->m_constant == 0 && d->m_volatile == 0 && d->m_referenceType == NoReference + && d->m_indirections.isEmpty() && d->m_arrayElements.isEmpty(); +} + TypeInfo TypeInfo::resolveType(TypeInfo const &__type, const ScopeModelItem &__scope) { CodeModel *__model = __scope->model(); @@ -307,34 +292,34 @@ TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, con otherType.setQualifiedName(__item->qualifiedName()); } - if (TypeDefModelItem __typedef = qSharedPointerDynamicCast<_TypeDefModelItem>(__item)) { + if (TypeDefModelItem __typedef = std::dynamic_pointer_cast<_TypeDefModelItem>(__item)) { const TypeInfo combined = TypeInfo::combine(__typedef->type(), otherType); const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope); if (!nextItem) return combined; // PYSIDE-362, prevent recursion on opaque structs like // typedef struct xcb_connection_t xcb_connection_t; - if (nextItem.data() ==__item.data()) { + if (nextItem.get() ==__item.get()) { std::cerr << "** WARNING Bailing out recursion of " << __FUNCTION__ - << "() on " << qPrintable(__type.qualifiedName().join(QLatin1String("::"))) + << "() on " << qPrintable(__type.qualifiedName().join(u"::"_s)) << std::endl; return otherType; } return resolveType(nextItem, combined, __scope); } - if (TemplateTypeAliasModelItem templateTypeAlias = qSharedPointerDynamicCast<_TemplateTypeAliasModelItem>(__item)) { + if (TemplateTypeAliasModelItem templateTypeAlias = std::dynamic_pointer_cast<_TemplateTypeAliasModelItem>(__item)) { TypeInfo combined = TypeInfo::combine(templateTypeAlias->type(), otherType); // For the alias "template<typename T> using QList = QVector<T>" with // other="QList<int>", replace the instantiations to obtain "QVector<int>". auto aliasInstantiations = templateTypeAlias->type().instantiations(); const auto &concreteInstantiations = otherType.instantiations(); - const int count = qMin(aliasInstantiations.size(), concreteInstantiations.size()); - for (int i = 0; i < count; ++i) - aliasInstantiations[i] = concreteInstantiations[i]; + const auto count = qMin(aliasInstantiations.size(), concreteInstantiations.size()); + for (qsizetype i = 0; i < count; ++i) + aliasInstantiations[i] = concreteInstantiations.at(i); combined.setInstantiations(aliasInstantiations); - const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope); + const CodeModelItem nextItem = CodeModel::findItem(combined.qualifiedName(), __scope); if (!nextItem) return combined; return resolveType(nextItem, combined, __scope); @@ -362,6 +347,10 @@ public: while (level < m_parseStack.size()) m_parseStack.pop(); TypeInfo instantiation; + if (name.startsWith(u"const ")) { + instantiation.setConstant(true); + name = name.mid(6); + } instantiation.setQualifiedName(qualifiedName(name)); top()->addInstantiation(instantiation); } @@ -382,7 +371,8 @@ private: QStack<TypeInfo *> m_parseStack; }; -QPair<int, int> TypeInfo::parseTemplateArgumentList(const QString &l, int from) +std::pair<qsizetype, qsizetype> + TypeInfo::parseTemplateArgumentList(const QString &l, qsizetype from) { return clang::parseTemplateArgumentList(l, clang::TemplateArgumentHandler(TypeInfoTemplateArgumentHandler(this)), from); } @@ -391,23 +381,23 @@ QString TypeInfo::toString() const { QString tmp; if (isConstant()) - tmp += QLatin1String("const "); + tmp += u"const "_s; if (isVolatile()) - tmp += QLatin1String("volatile "); + tmp += u"volatile "_s; - tmp += d->m_qualifiedName.join(QLatin1String("::")); + tmp += d->m_qualifiedName.join(u"::"_s); - if (const int instantiationCount = d->m_instantiations.size()) { - tmp += QLatin1Char('<'); - for (int i = 0; i < instantiationCount; ++i) { + if (const auto instantiationCount = d->m_instantiations.size()) { + tmp += u'<'; + for (qsizetype i = 0; i < instantiationCount; ++i) { if (i) - tmp += QLatin1String(", "); + tmp += u", "_s; tmp += d->m_instantiations.at(i).toString(); } - if (tmp.endsWith(QLatin1Char('>'))) - tmp += QLatin1Char(' '); - tmp += QLatin1Char('>'); + if (tmp.endsWith(u'>')) + tmp += u' '; + tmp += u'>'; } for (Indirection i : d->m_indirections) @@ -417,40 +407,37 @@ QString TypeInfo::toString() const case NoReference: break; case LValueReference: - tmp += QLatin1Char('&'); + tmp += u'&'; break; case RValueReference: - tmp += QLatin1String("&&"); + tmp += u"&&"_s; break; } if (isFunctionPointer()) { - tmp += QLatin1String(" (*)("); - for (int i = 0; i < d->m_arguments.count(); ++i) { + tmp += u" (*)("_s; + for (qsizetype i = 0; i < d->m_arguments.size(); ++i) { if (i != 0) - tmp += QLatin1String(", "); + tmp += u", "_s; tmp += d->m_arguments.at(i).toString(); } - tmp += QLatin1Char(')'); + tmp += u')'; } - for (const QString &elt : d->m_arrayElements) { - tmp += QLatin1Char('['); - tmp += elt; - tmp += QLatin1Char(']'); - } + for (const QString &elt : d->m_arrayElements) + tmp += u'[' + elt + u']'; return tmp; } bool TypeInfoData::equals(const TypeInfoData &other) const { - if (m_arrayElements.count() != other.m_arrayElements.count()) + if (m_arrayElements.size() != other.m_arrayElements.size()) return false; #if defined (RXX_CHECK_ARRAY_ELEMENTS) // ### it'll break - for (int i = 0; i < arrayElements().count(); ++i) { + for (qsizetype i = 0; i < arrayElements().size(); ++i) { QString elt1 = arrayElements().at(i).trimmed(); QString elt2 = other.arrayElements().at(i).trimmed(); @@ -465,34 +452,31 @@ bool TypeInfoData::equals(const TypeInfoData &other) const && m_instantiations == other.m_instantiations; } -bool TypeInfo::equals(const TypeInfo &other) const + +bool comparesEqual(const TypeInfo &lhs, const TypeInfo &rhs) noexcept { - return d.data() == other.d.data() || d->equals(*other.d); + return lhs.d.data() == rhs.d.data() || lhs.d->equals(*rhs.d); } QString TypeInfo::indirectionKeyword(Indirection i) { - return i == Indirection::Pointer - ? QStringLiteral("*") : QStringLiteral("*const"); + return i == Indirection::Pointer ? "*"_L1 : "*const"_L1; } -static inline QString constQualifier() { return QStringLiteral("const"); } -static inline QString volatileQualifier() { return QStringLiteral("volatile"); } - bool TypeInfo::stripLeadingConst(QString *s) { - return stripLeadingQualifier(constQualifier(), s); + return stripLeadingQualifier("const"_L1, s); } bool TypeInfo::stripLeadingVolatile(QString *s) { - return stripLeadingQualifier(volatileQualifier(), s); + return stripLeadingQualifier("volatile"_L1, s); } -bool TypeInfo::stripLeadingQualifier(const QString &qualifier, QString *s) +bool TypeInfo::stripLeadingQualifier(QLatin1StringView qualifier, QString *s) { // "const int x" - const int qualifierSize = qualifier.size(); + const auto qualifierSize = qualifier.size(); if (s->size() < qualifierSize + 1 || !s->startsWith(qualifier) || !s->at(qualifierSize).isSpace()) { return false; @@ -508,10 +492,8 @@ void TypeInfo::stripQualifiers(QString *s) { stripLeadingConst(s); stripLeadingVolatile(s); - while (s->endsWith(QLatin1Char('&')) || s->endsWith(QLatin1Char('*')) - || s->endsWith(QLatin1Char(' '))) { + while (s->endsWith(u'&') || s->endsWith(u'*') || s->endsWith(u' ')) s->chop(1); - } } // Helper functionality to simplify a raw standard type as returned by @@ -522,7 +504,7 @@ void TypeInfo::stripQualifiers(QString *s) bool TypeInfoData::isStdType() const { return m_qualifiedName.size() > 1 - && m_qualifiedName.constFirst() == QLatin1String("std"); + && m_qualifiedName.constFirst() == u"std"; } bool TypeInfo::isStdType() const @@ -532,15 +514,15 @@ bool TypeInfo::isStdType() const static inline bool discardStdType(const QString &name) { - return name == QLatin1String("allocator") || name == QLatin1String("less"); + return name == u"allocator" || name == u"less"; } void TypeInfoData::simplifyStdType() { Q_ASSERT(isStdType()); - if (m_qualifiedName.at(1).startsWith(QLatin1String("__"))) + if (m_qualifiedName.at(1).startsWith(u"__")) m_qualifiedName.removeAt(1); - for (int t = m_instantiations.size() - 1; t >= 0; --t) { + for (auto t = m_instantiations.size() - 1; t >= 0; --t) { if (m_instantiations.at(t).isStdType()) { if (discardStdType(m_instantiations.at(t).qualifiedName().constLast())) m_instantiations.removeAt(t); @@ -560,7 +542,7 @@ void TypeInfo::formatTypeSystemSignature(QTextStream &str) const { if (d->m_constant) str << "const "; - str << d->m_qualifiedName.join(QLatin1String("::")); + str << d->m_qualifiedName.join(u"::"_s); switch (d->m_referenceType) { case NoReference: break; @@ -584,16 +566,6 @@ void TypeInfo::formatTypeSystemSignature(QTextStream &str) const } #ifndef QT_NO_DEBUG_STREAM -template <class It> -void formatSequence(QDebug &d, It i1, It i2, const char *separator=", ") -{ - for (It i = i1; i != i2; ++i) { - if (i != i1) - d << separator; - d << *i; - } -} - void TypeInfo::formatDebug(QDebug &debug) const { debug << '"'; diff --git a/sources/shiboken6/ApiExtractor/parser/typeinfo.h b/sources/shiboken6/ApiExtractor/parser/typeinfo.h index 38e585726..e4f363b67 100644 --- a/sources/shiboken6/ApiExtractor/parser/typeinfo.h +++ b/sources/shiboken6/ApiExtractor/parser/typeinfo.h @@ -1,31 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef TYPEINFO_H #define TYPEINFO_H @@ -35,8 +10,11 @@ #include <QtCore/QString> #include <QtCore/QSharedDataPointer> +#include <QtCore/QtCompare> #include <QtCore/QStringList> +#include <utility> + QT_FORWARD_DECLARE_CLASS(QDebug) QT_FORWARD_DECLARE_CLASS(QTextStream) @@ -53,8 +31,8 @@ public: ~TypeInfo(); TypeInfo(const TypeInfo &); TypeInfo& operator=(const TypeInfo &); - TypeInfo(TypeInfo &&); - TypeInfo& operator=(TypeInfo &&); + TypeInfo(TypeInfo &&) noexcept; + TypeInfo &operator=(TypeInfo &&) noexcept; static TypeInfo voidType(); static TypeInfo varArgsType(); @@ -102,11 +80,12 @@ public: void addInstantiation(const TypeInfo &i); void clearInstantiations(); - bool isStdType() const; + bool isPlain() const; // neither const,volatile, no indirections/references, array - QPair<int, int> parseTemplateArgumentList(const QString &l, int from = 0); + bool isStdType() const; - bool equals(const TypeInfo &other) const; + std::pair<qsizetype, qsizetype> + parseTemplateArgumentList(const QString &l, qsizetype from = 0); // ### arrays and templates?? @@ -125,12 +104,16 @@ public: static bool stripLeadingConst(QString *s); static bool stripLeadingVolatile(QString *s); - static bool stripLeadingQualifier(const QString &qualifier, QString *s); + static bool stripLeadingQualifier(QLatin1StringView qualifier, QString *s); static void stripQualifiers(QString *s); void simplifyStdType(); private: + friend bool comparesEqual(const TypeInfo &lhs, + const TypeInfo &rhs) noexcept; + Q_DECLARE_EQUALITY_COMPARABLE(TypeInfo) + QSharedDataPointer<TypeInfoData> d; friend class TypeInfoTemplateArgumentHandler; @@ -138,12 +121,6 @@ private: static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, const ScopeModelItem &__scope); }; -inline bool operator==(const TypeInfo &t1, const TypeInfo &t2) -{ return t1.equals(t2); } - -inline bool operator!=(const TypeInfo &t1, const TypeInfo &t2) -{ return !t1.equals(t2); } - #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const TypeInfo &t); #endif |