diff options
Diffstat (limited to 'sources/shiboken6/ApiExtractor/parser')
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/codemodel.cpp | 1608 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/codemodel.h | 814 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/codemodel_enums.h | 64 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h | 85 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/enumvalue.cpp | 76 | ||||
-rw-r--r-- | sources/shiboken6/ApiExtractor/parser/enumvalue.h | 71 |
6 files changed, 2718 insertions, 0 deletions
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp new file mode 100644 index 000000000..76ce333ed --- /dev/null +++ b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp @@ -0,0 +1,1608 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + + +#include "codemodel.h" + +#include <sourcelocation.h> +#include <clangparser/clangutils.h> + +#include <algorithm> +#include <functional> +#include <iostream> +#include <QDebug> +#include <QDir> +#include <QtCore/QStack> + +// 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; +}; + +template <class T> +static QSharedPointer<T> findModelItem(const QVector<QSharedPointer<T> > &list, const QString &name) +{ + const auto it = std::find_if(list.cbegin(), list.cend(), ModelItemNamePredicate<T>(name)); + return it != list.cend() ? *it : QSharedPointer<T>(); +} + +// --------------------------------------------------------------------------- + +CodeModel::CodeModel() : m_globalNamespace(new _NamespaceModelItem(this)) +{ +} + +CodeModel::~CodeModel() = default; + +NamespaceModelItem CodeModel::globalNamespace() const +{ + return m_globalNamespace; +} + +void CodeModel::addFile(const FileModelItem &item) +{ + m_files.append(item); +} + +FileModelItem CodeModel::findFile(const QString &name) const +{ + return findModelItem(m_files, name); +} + +static CodeModelItem findRecursion(const ScopeModelItem &scope, + const QStringList &qualifiedName, int segment = 0) +{ + const QString &nameSegment = qualifiedName.at(segment); + if (segment == qualifiedName.size() - 1) { // Leaf item + if (ClassModelItem cs = scope->findClass(nameSegment)) + return cs; + if (EnumModelItem es = scope->findEnum(nameSegment)) + return es; + if (TypeDefModelItem tp = scope->findTypeDef(nameSegment)) + return tp; + if (TemplateTypeAliasModelItem tta = scope->findTemplateTypeAlias(nameSegment)) + return tta; + return CodeModelItem(); + } + if (auto nestedClass = scope->findClass(nameSegment)) + return findRecursion(nestedClass, qualifiedName, segment + 1); + if (auto namespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) { + for (const auto &nestedNamespace : namespaceItem->namespaces()) { + if (nestedNamespace->name() == nameSegment) { + if (auto item = findRecursion(nestedNamespace, qualifiedName, segment + 1)) + return item; + } + } + } + return CodeModelItem(); +} + +CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const +{ + return findRecursion(scope, qualifiedName); +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const CodeModel *m) +{ + QDebugStateSaver s(d); + d.noquote(); + d.nospace(); + d << "CodeModel("; + if (m) { + const NamespaceModelItem globalNamespaceP = m->globalNamespace(); + if (globalNamespaceP.data()) + globalNamespaceP->formatDebug(d); + } else { + d << '0'; + } + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +TypeInfo TypeInfo::combine(const TypeInfo &__lhs, const TypeInfo &__rhs) +{ + TypeInfo __result = __lhs; + + __result.setConstant(__result.isConstant() || __rhs.isConstant()); + __result.setVolatile(__result.isVolatile() || __rhs.isVolatile()); + if (__rhs.referenceType() > __result.referenceType()) + __result.setReferenceType(__rhs.referenceType()); + __result.m_indirections.append(__rhs.m_indirections); + __result.setArrayElements(__result.arrayElements() + __rhs.arrayElements()); + __result.m_instantiations.append(__rhs.m_instantiations); + + return __result; +} + +bool TypeInfo::isVoid() const +{ + return m_indirections.isEmpty() && m_referenceType == NoReference + && m_arguments.isEmpty() && m_arrayElements.isEmpty() + && m_instantiations.isEmpty() + && m_qualifiedName.size() == 1 + && m_qualifiedName.constFirst() == QLatin1String("void"); +} + +TypeInfo TypeInfo::resolveType(TypeInfo const &__type, const ScopeModelItem &__scope) +{ + CodeModel *__model = __scope->model(); + Q_ASSERT(__model != nullptr); + + return TypeInfo::resolveType(__model->findItem(__type.qualifiedName(), __scope), __type, __scope); +} + +TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, const ScopeModelItem &__scope) +{ + // Copy the type and replace with the proper qualified name. This + // only makes sence to do if we're actually getting a resolved + // type with a namespace. We only get this if the returned type + // has more than 2 entries in the qualified name... This test + // could be improved by returning if the type was found or not. + TypeInfo otherType(__type); + if (__item && __item->qualifiedName().size() > 1) { + otherType.setQualifiedName(__item->qualifiedName()); + } + + if (TypeDefModelItem __typedef = qSharedPointerDynamicCast<_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()) { + std::cerr << "** WARNING Bailing out recursion of " << __FUNCTION__ + << "() on " << qPrintable(__type.qualifiedName().join(QLatin1String("::"))) + << std::endl; + return otherType; + } + return resolveType(nextItem, combined, __scope); + } + + if (TemplateTypeAliasModelItem templateTypeAlias = qSharedPointerDynamicCast<_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(); + auto concreteInstantiations = otherType.instantiations(); + const int count = qMin(aliasInstantiations.size(), concreteInstantiations.size()); + for (int i = 0; i < count; ++i) + aliasInstantiations[i] = concreteInstantiations[i]; + combined.setInstantiations(aliasInstantiations); + const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope); + if (!nextItem) + return combined; + return resolveType(nextItem, combined, __scope); + } + + return otherType; +} + +// Handler for clang::parseTemplateArgumentList() that populates +// TypeInfo::m_instantiations +class TypeInfoTemplateArgumentHandler +{ +public: + explicit TypeInfoTemplateArgumentHandler(TypeInfo *t) + { + m_parseStack.append(t); + } + + void operator()(int level, QStringView name) + { + if (level > m_parseStack.size()) { + Q_ASSERT(!top()->m_instantiations.isEmpty()); + m_parseStack.push(&top()->m_instantiations.back()); + } + while (level < m_parseStack.size()) + m_parseStack.pop(); + TypeInfo instantiation; + instantiation.setQualifiedName(qualifiedName(name)); + top()->addInstantiation(instantiation); + } + +private: + TypeInfo *top() const { return m_parseStack.back(); } + + static QStringList qualifiedName(QStringView name) + { + QStringList result; + const auto nameParts = name.split(u"::"); + result.reserve(nameParts.size()); + for (const auto &p : nameParts) + result.append(p.toString()); + return result; + } + + QStack<TypeInfo *> m_parseStack; +}; + +QPair<int, int> TypeInfo::parseTemplateArgumentList(const QString &l, int from) +{ + return clang::parseTemplateArgumentList(l, clang::TemplateArgumentHandler(TypeInfoTemplateArgumentHandler(this)), from); +} + +QString TypeInfo::toString() const +{ + QString tmp; + if (isConstant()) + tmp += QLatin1String("const "); + + if (isVolatile()) + tmp += QLatin1String("volatile "); + + tmp += m_qualifiedName.join(QLatin1String("::")); + + if (const int instantiationCount = m_instantiations.size()) { + tmp += QLatin1Char('<'); + for (int i = 0; i < instantiationCount; ++i) { + if (i) + tmp += QLatin1String(", "); + tmp += m_instantiations.at(i).toString(); + } + if (tmp.endsWith(QLatin1Char('>'))) + tmp += QLatin1Char(' '); + tmp += QLatin1Char('>'); + } + + for (Indirection i : m_indirections) + tmp.append(indirectionKeyword(i)); + + switch (referenceType()) { + case NoReference: + break; + case LValueReference: + tmp += QLatin1Char('&'); + break; + case RValueReference: + tmp += QLatin1String("&&"); + break; + } + + if (isFunctionPointer()) { + tmp += QLatin1String(" (*)("); + for (int i = 0; i < m_arguments.count(); ++i) { + if (i != 0) + tmp += QLatin1String(", "); + + tmp += m_arguments.at(i).toString(); + } + tmp += QLatin1Char(')'); + } + + for (const QString &elt : m_arrayElements) { + tmp += QLatin1Char('['); + tmp += elt; + tmp += QLatin1Char(']'); + } + + return tmp; +} + +bool TypeInfo::operator==(const TypeInfo &other) const +{ + if (arrayElements().count() != other.arrayElements().count()) + return false; + +#if defined (RXX_CHECK_ARRAY_ELEMENTS) // ### it'll break + for (int i = 0; i < arrayElements().count(); ++i) { + QString elt1 = arrayElements().at(i).trimmed(); + QString elt2 = other.arrayElements().at(i).trimmed(); + + if (elt1 != elt2) + return false; + } +#endif + + return flags == other.flags + && m_qualifiedName == other.m_qualifiedName + && (!m_functionPointer || m_arguments == other.m_arguments) + && m_instantiations == other.m_instantiations; +} + +QString TypeInfo::indirectionKeyword(Indirection i) +{ + return i == Indirection::Pointer + ? QStringLiteral("*") : QStringLiteral("*const"); +} + +static inline QString constQualifier() { return QStringLiteral("const"); } +static inline QString volatileQualifier() { return QStringLiteral("volatile"); } + +bool TypeInfo::stripLeadingConst(QString *s) +{ + return stripLeadingQualifier(constQualifier(), s); +} + +bool TypeInfo::stripLeadingVolatile(QString *s) +{ + return stripLeadingQualifier(volatileQualifier(), s); +} + +bool TypeInfo::stripLeadingQualifier(const QString &qualifier, QString *s) +{ + // "const int x" + const int qualifierSize = qualifier.size(); + if (s->size() < qualifierSize + 1 || !s->startsWith(qualifier) + || !s->at(qualifierSize).isSpace()) { + return false; + } + s->remove(0, qualifierSize + 1); + while (!s->isEmpty() && s->at(0).isSpace()) + s->remove(0, 1); + return true; +} + +// Strip all const/volatile/*/& +void TypeInfo::stripQualifiers(QString *s) +{ + stripLeadingConst(s); + stripLeadingVolatile(s); + while (s->endsWith(QLatin1Char('&')) || s->endsWith(QLatin1Char('*')) + || s->endsWith(QLatin1Char(' '))) { + s->chop(1); + } +} + +// Helper functionality to simplify a raw standard type as returned by +// clang_getCanonicalType() for g++ standard containers from +// "std::__cxx11::list<int, std::allocator<int> >" or +// "std::__1::list<int, std::allocator<int> >" -> "std::list<int>". + +bool TypeInfo::isStdType() const +{ + return m_qualifiedName.size() > 1 + && m_qualifiedName.constFirst() == QLatin1String("std"); +} + +static inline bool discardStdType(const QString &name) +{ + return name == QLatin1String("allocator") || name == QLatin1String("less"); +} + +void TypeInfo::simplifyStdType() +{ + if (isStdType()) { + if (m_qualifiedName.at(1).startsWith(QLatin1String("__"))) + m_qualifiedName.removeAt(1); + for (int t = m_instantiations.size() - 1; t >= 0; --t) { + if (m_instantiations.at(t).isStdType()) { + if (discardStdType(m_instantiations.at(t).m_qualifiedName.constLast())) + m_instantiations.removeAt(t); + else + m_instantiations[t].simplifyStdType(); + } + } + } +} + +void TypeInfo::formatTypeSystemSignature(QTextStream &str) const +{ + if (m_constant) + str << "const "; + str << m_qualifiedName.join(QLatin1String("::")); + switch (m_referenceType) { + case NoReference: + break; + case LValueReference: + str << '&'; + break; + case RValueReference: + str << "&&"; + break; + } + for (auto i : m_indirections) { + switch (i) { + case Indirection::Pointer: + str << '*'; + break; + case Indirection::ConstPointer: + str << "* const"; + break; + } + } +} + +#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 &d) const +{ + d << '"'; + formatSequence(d, m_qualifiedName.begin(), m_qualifiedName.end(), "\", \""); + d << '"'; + if (m_constant) + d << ", [const]"; + if (m_volatile) + d << ", [volatile]"; + if (!m_indirections.isEmpty()) { + d << ", indirections="; + for (auto i : m_indirections) + d << ' ' << TypeInfo::indirectionKeyword(i); + } + switch (m_referenceType) { + case NoReference: + break; + case LValueReference: + d << ", [ref]"; + break; + case RValueReference: + d << ", [rvalref]"; + break; + } + if (!m_instantiations.isEmpty()) { + d << ", template<"; + formatSequence(d, m_instantiations.begin(), m_instantiations.end()); + d << '>'; + } + if (m_functionPointer) { + d << ", function ptr("; + formatSequence(d, m_arguments.begin(), m_arguments.end()); + d << ')'; + } + if (!m_arrayElements.isEmpty()) { + d << ", array[" << m_arrayElements.size() << "]["; + formatSequence(d, m_arrayElements.begin(), m_arrayElements.end()); + d << ']'; + } +} + +QDebug operator<<(QDebug d, const TypeInfo &t) +{ + QDebugStateSaver s(d); + const int verbosity = d.verbosity(); + d.noquote(); + d.nospace(); + d << "TypeInfo("; + if (verbosity > 2) + t.formatDebug(d); + else + d << t.toString(); + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +_CodeModelItem::_CodeModelItem(CodeModel *model, int kind) + : m_model(model), + m_kind(kind), + m_startLine(0), + m_startColumn(0), + m_endLine(0), + m_endColumn(0) +{ +} + +_CodeModelItem::_CodeModelItem(CodeModel *model, const QString &name, int kind) + : m_model(model), + m_kind(kind), + m_startLine(0), + m_startColumn(0), + m_endLine(0), + m_endColumn(0), + m_name(name) +{ +} + +_CodeModelItem::~_CodeModelItem() = default; + +int _CodeModelItem::kind() const +{ + return m_kind; +} + +QStringList _CodeModelItem::qualifiedName() const +{ + QStringList q = scope(); + + if (!name().isEmpty()) + q += name(); + + return q; +} + +QString _CodeModelItem::name() const +{ + return m_name; +} + +void _CodeModelItem::setName(const QString &name) +{ + m_name = name; +} + +QStringList _CodeModelItem::scope() const +{ + return m_scope; +} + +void _CodeModelItem::setScope(const QStringList &scope) +{ + m_scope = scope; +} + +QString _CodeModelItem::fileName() const +{ + return m_fileName; +} + +void _CodeModelItem::setFileName(const QString &fileName) +{ + m_fileName = fileName; +} + +FileModelItem _CodeModelItem::file() const +{ + return model()->findFile(fileName()); +} + +void _CodeModelItem::getStartPosition(int *line, int *column) +{ + *line = m_startLine; + *column = m_startColumn; +} + +void _CodeModelItem::setStartPosition(int line, int column) +{ + m_startLine = line; + m_startColumn = column; +} + +void _CodeModelItem::getEndPosition(int *line, int *column) +{ + *line = m_endLine; + *column = m_endColumn; +} + +void _CodeModelItem::setEndPosition(int line, int column) +{ + m_endLine = line; + m_endColumn = column; +} + +SourceLocation _CodeModelItem::sourceLocation() const +{ + return SourceLocation(m_fileName, m_startLine); +} + +#ifndef QT_NO_DEBUG_STREAM +template <class It> +static void formatPtrSequence(QDebug &d, It i1, It i2, const char *separator=", ") +{ + for (It i = i1; i != i2; ++i) { + if (i != i1) + d << separator; + d << i->data(); + } +} + +void _CodeModelItem::formatKind(QDebug &d, int k) +{ + switch (k) { + case Kind_Argument: + d << "ArgumentModelItem"; + break; + case Kind_Class: + d << "ClassModelItem"; + break; + case Kind_Enum: + d << "EnumModelItem"; + break; + case Kind_Enumerator: + d << "EnumeratorModelItem"; + break; + case Kind_File: + d << "FileModelItem"; + break; + case Kind_Function: + d << "FunctionModelItem"; + break; + case Kind_Member: + d << "MemberModelItem"; + break; + case Kind_Namespace: + d << "NamespaceModelItem"; + break; + case Kind_Variable: + d << "VariableModelItem"; + break; + case Kind_Scope: + d << "ScopeModelItem"; + break; + case Kind_TemplateParameter: + d << "TemplateParameter"; + break; + case Kind_TypeDef: + d << "TypeDefModelItem"; + break; + case Kind_TemplateTypeAlias: + d << "TemplateTypeAliasModelItem"; + break; + default: + d << "CodeModelItem"; + break; + } +} + +void _CodeModelItem::formatDebug(QDebug &d) const +{ + d << "(\"" << name() << '"'; + if (!m_scope.isEmpty()) { + d << ", scope="; + formatSequence(d, m_scope.cbegin(), m_scope.cend(), "::"); + } + if (!m_fileName.isEmpty()) { + d << ", file=\"" << QDir::toNativeSeparators(m_fileName); + if (m_startLine > 0) + d << ':' << m_startLine; + d << '"'; + } +} + +QDebug operator<<(QDebug d, const _CodeModelItem *t) +{ + QDebugStateSaver s(d); + d.noquote(); + d.nospace(); + if (!t) { + d << "CodeModelItem(0)"; + return d; + } + _CodeModelItem::formatKind(d, t->kind()); + t->formatDebug(d); + switch (t->kind()) { + case _CodeModelItem::Kind_Class: + d << " /* class " << t->name() << " */"; + break; + case _CodeModelItem::Kind_Namespace: + d << " /* namespace " << t->name() << " */"; + break; + } + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +_ClassModelItem::~_ClassModelItem() = default; + +TemplateParameterList _ClassModelItem::templateParameters() const +{ + return m_templateParameters; +} + +void _ClassModelItem::setTemplateParameters(const TemplateParameterList &templateParameters) +{ + m_templateParameters = templateParameters; +} + +void _ClassModelItem::addBaseClass(const QString &name, CodeModel::AccessPolicy 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) { + if (bc.name == name) + return true; + } + return false; +} + +void _ClassModelItem::setClassType(CodeModel::ClassType type) +{ + m_classType = type; +} + +CodeModel::ClassType _ClassModelItem::classType() const +{ + return m_classType; +} + +void _ClassModelItem::addPropertyDeclaration(const QString &propertyDeclaration) +{ + m_propertyDeclarations << propertyDeclaration; +} + +bool _ClassModelItem::isEmpty() const +{ + return _ScopeModelItem::isEmpty() && m_propertyDeclarations.isEmpty(); +} + +bool _ClassModelItem::isTemplate() const +{ + return !m_templateParameters.isEmpty(); +} + +#ifndef QT_NO_DEBUG_STREAM +template <class List> +static void formatModelItemList(QDebug &d, const char *prefix, const List &l, + const char *separator = ", ") +{ + if (const int size = l.size()) { + d << prefix << '[' << size << "]("; + for (int i = 0; i < size; ++i) { + if (i) + d << separator; + l.at(i)->formatDebug(d); + } + d << ')'; + } +} + +void _ClassModelItem::formatDebug(QDebug &d) const +{ + _ScopeModelItem::formatDebug(d); + if (!m_baseClasses.isEmpty()) { + if (m_final) + d << " [final]"; + d << ", inherits="; + d << ", inherits="; + for (int i = 0, size = m_baseClasses.size(); i < size; ++i) { + if (i) + d << ", "; + d << m_baseClasses.at(i).name << " (" << m_baseClasses.at(i).accessPolicy << ')'; + } + } + formatModelItemList(d, ", templateParameters=", m_templateParameters); + formatScopeItemsDebug(d); + if (!m_propertyDeclarations.isEmpty()) + d << ", Properties=" << m_propertyDeclarations; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +FunctionModelItem _ScopeModelItem::declaredFunction(const FunctionModelItem &item) +{ + for (const FunctionModelItem &fun : qAsConst(m_functions)) { + if (fun->name() == item->name() && fun->isSimilar(item)) + return fun; + + } + return FunctionModelItem(); +} + +_ScopeModelItem::~_ScopeModelItem() = default; + +void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration) +{ + m_enumsDeclarations << enumsDeclaration; +} + +void _ScopeModelItem::addClass(const ClassModelItem &item) +{ + m_classes.append(item); +} + +void _ScopeModelItem::addFunction(const FunctionModelItem &item) +{ + m_functions.append(item); +} + +void _ScopeModelItem::addVariable(const VariableModelItem &item) +{ + m_variables.append(item); +} + +void _ScopeModelItem::addTypeDef(const TypeDefModelItem &item) +{ + m_typeDefs.append(item); +} + +void _ScopeModelItem::addTemplateTypeAlias(const TemplateTypeAliasModelItem &item) +{ + m_templateTypeAliases.append(item); +} + +void _ScopeModelItem::addEnum(const EnumModelItem &item) +{ + m_enums.append(item); +} + +void _ScopeModelItem::appendScope(const _ScopeModelItem &other) +{ + m_classes += other.m_classes; + m_enums += other.m_enums; + m_typeDefs += other.m_typeDefs; + m_templateTypeAliases += other.m_templateTypeAliases; + m_variables += other.m_variables; + m_functions += other.m_functions; + m_enumsDeclarations += other.m_enumsDeclarations; +} + +bool _ScopeModelItem::isEmpty() const +{ + return m_classes.isEmpty() && m_enums.isEmpty() + && m_typeDefs.isEmpty() && m_templateTypeAliases.isEmpty() + && m_variables.isEmpty() && m_functions.isEmpty() + && m_enumsDeclarations.isEmpty(); +} + +/* This function removes MSVC export declarations of non-type template + * specializations (see below code from photon.h) for which + * clang_isCursorDefinition() returns true, causing them to be added as + * definitions of empty classes shadowing the template definition depending + * on QHash seed values. + +template <int N> class Tpl +{ +public: +... +}; + +#ifdef WIN32 +template class LIBSAMPLE_EXPORT Tpl<54>; +*/ +void _ScopeModelItem::purgeClassDeclarations() +{ + for (int 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 bool definitionFound = + std::any_of(m_classes.cbegin(), m_classes.cend(), + [definitionPrefix] (const ClassModelItem &c) { + return c->isTemplate() && !c->isEmpty() + && c->name().startsWith(definitionPrefix); + }); + if (definitionFound) + m_classes.removeAt(i); + } + } +} + +#ifndef QT_NO_DEBUG_STREAM +template <class Hash> +static void formatScopeHash(QDebug &d, const char *prefix, const Hash &h, + const char *separator = ", ", + bool trailingNewLine = false) +{ + if (!h.isEmpty()) { + d << prefix << '[' << h.size() << "]("; + const auto begin = h.cbegin(); + for (auto it = begin, end = h.cend(); it != end; ++it) { // Omit the names as they are repeated + if (it != begin) + d << separator; + d << it.value().data(); + } + d << ')'; + if (trailingNewLine) + d << '\n'; + } +} + +template <class List> +static void formatScopeList(QDebug &d, const char *prefix, const List &l, + const char *separator = ", ", + bool trailingNewLine = false) +{ + if (!l.isEmpty()) { + d << prefix << '[' << l.size() << "]("; + formatPtrSequence(d, l.begin(), l.end(), separator); + d << ')'; + if (trailingNewLine) + d << '\n'; + } +} + +void _ScopeModelItem::formatScopeItemsDebug(QDebug &d) const +{ + formatScopeList(d, ", classes=", m_classes, "\n", true); + formatScopeList(d, ", enums=", m_enums, "\n", true); + formatScopeList(d, ", aliases=", m_typeDefs, "\n", true); + formatScopeList(d, ", template type aliases=", m_templateTypeAliases, "\n", true); + formatScopeList(d, ", functions=", m_functions, "\n", true); + formatScopeList(d, ", variables=", m_variables); +} + +void _ScopeModelItem::formatDebug(QDebug &d) const +{ + _CodeModelItem::formatDebug(d); + formatScopeItemsDebug(d); +} +#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 +{ +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 + +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)); + return it != m_classes.end() ? *it : ClassModelItem(); +} + +VariableModelItem _ScopeModelItem::findVariable(const QString &name) const +{ + return findModelItem(m_variables, name); +} + +TypeDefModelItem _ScopeModelItem::findTypeDef(const QString &name) const +{ + return findModelItem(m_typeDefs, name); +} + +TemplateTypeAliasModelItem _ScopeModelItem::findTemplateTypeAlias(const QString &name) const +{ + return findModelItem(m_templateTypeAliases, name); +} + +EnumModelItem _ScopeModelItem::findEnum(const QString &name) const +{ + return findModelItem(m_enums, name); +} + +FunctionList _ScopeModelItem::findFunctions(const QString &name) const +{ + FunctionList result; + for (const FunctionModelItem &func : m_functions) { + if (func->name() == name) + result.append(func); + } + return result; +} + +// --------------------------------------------------------------------------- +_NamespaceModelItem::~_NamespaceModelItem() +{ +} + +void _NamespaceModelItem::addNamespace(NamespaceModelItem item) +{ + m_namespaces.append(item); +} + +NamespaceModelItem _NamespaceModelItem::findNamespace(const QString &name) const +{ + return findModelItem(m_namespaces, name); +} + +_FileModelItem::~_FileModelItem() = default; + +void _NamespaceModelItem::appendNamespace(const _NamespaceModelItem &other) +{ + appendScope(other); + m_namespaces += other.m_namespaces; +} + +#ifndef QT_NO_DEBUG_STREAM +void _NamespaceModelItem::formatDebug(QDebug &d) const +{ + _ScopeModelItem::formatDebug(d); + switch (m_type) { + case NamespaceType::Default: + break; + case NamespaceType::Anonymous: + d << ", anonymous"; + break; + case NamespaceType::Inline: + d << ", inline"; + break; + } + formatScopeList(d, ", namespaces=", m_namespaces); +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +_ArgumentModelItem::~_ArgumentModelItem() +{ +} + +TypeInfo _ArgumentModelItem::type() const +{ + return m_type; +} + +void _ArgumentModelItem::setType(const TypeInfo &type) +{ + m_type = type; +} + +bool _ArgumentModelItem::defaultValue() const +{ + return m_defaultValue; +} + +void _ArgumentModelItem::setDefaultValue(bool defaultValue) +{ + m_defaultValue = defaultValue; +} + +#ifndef QT_NO_DEBUG_STREAM +void _ArgumentModelItem::formatDebug(QDebug &d) const +{ + _CodeModelItem::formatDebug(d); + d << ", type=" << m_type; + if (m_defaultValue) + d << ", defaultValue=\"" << m_defaultValueExpression << '"'; +} +#endif // !QT_NO_DEBUG_STREAM +// --------------------------------------------------------------------------- +_FunctionModelItem::~_FunctionModelItem() = default; + +bool _FunctionModelItem::isSimilar(const FunctionModelItem &other) const +{ + if (name() != other->name()) + return false; + + if (isConstant() != other->isConstant()) + return false; + + if (isVariadics() != other->isVariadics()) + return false; + + if (arguments().count() != other->arguments().count()) + return false; + + // ### check the template parameters + + for (int i = 0; i < arguments().count(); ++i) { + ArgumentModelItem arg1 = arguments().at(i); + ArgumentModelItem arg2 = other->arguments().at(i); + + if (arg1->type() != arg2->type()) + return false; + } + + return true; +} + +ArgumentList _FunctionModelItem::arguments() const +{ + return m_arguments; +} + +void _FunctionModelItem::addArgument(const ArgumentModelItem& item) +{ + m_arguments.append(item); +} + +CodeModel::FunctionType _FunctionModelItem::functionType() const +{ + return m_functionType; +} + +void _FunctionModelItem::setFunctionType(CodeModel::FunctionType functionType) +{ + m_functionType = functionType; +} + +bool _FunctionModelItem::isVariadics() const +{ + return m_isVariadics; +} + +void _FunctionModelItem::setVariadics(bool isVariadics) +{ + m_isVariadics = isVariadics; +} + +bool _FunctionModelItem::isNoExcept() const +{ + return m_exceptionSpecification == ExceptionSpecification::NoExcept; +} + +ExceptionSpecification _FunctionModelItem::exceptionSpecification() const +{ + return m_exceptionSpecification; +} + +void _FunctionModelItem::setExceptionSpecification(ExceptionSpecification e) +{ + m_exceptionSpecification = e; +} + +bool _FunctionModelItem::isDeleted() const +{ + return m_isDeleted; +} + +void _FunctionModelItem::setDeleted(bool d) +{ + m_isDeleted = d; +} + +bool _FunctionModelItem::isDeprecated() const +{ + return m_isDeprecated; +} + +void _FunctionModelItem::setDeprecated(bool d) +{ + m_isDeprecated = d; +} + +bool _FunctionModelItem::isVirtual() const +{ + return m_isVirtual; +} + +void _FunctionModelItem::setVirtual(bool isVirtual) +{ + m_isVirtual = isVirtual; +} + +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 +{ + return m_isAbstract; +} + +void _FunctionModelItem::setAbstract(bool isAbstract) +{ + m_isAbstract = isAbstract; +} + +// Qt +bool _FunctionModelItem::isInvokable() const +{ + return m_isInvokable; +} + +void _FunctionModelItem::setInvokable(bool isInvokable) +{ + m_isInvokable = isInvokable; +} + +QString _FunctionModelItem::typeSystemSignature() const // For dumping out type system files +{ + QString result; + QTextStream str(&result); + str << name() << '('; + for (int a = 0, size = m_arguments.size(); a < size; ++a) { + if (a) + str << ','; + m_arguments.at(a)->type().formatTypeSystemSignature(str); + } + str << ')'; + return result; +} + +#ifndef QT_NO_DEBUG_STREAM +void _FunctionModelItem::formatDebug(QDebug &d) const +{ + _MemberModelItem::formatDebug(d); + d << ", type=" << m_functionType << ", exspec=" << int(m_exceptionSpecification); + if (m_isDeleted) + d << " [deleted!]"; + if (m_isInline) + d << " [inline]"; + if (m_isVirtual) + d << " [virtual]"; + if (m_isOverride) + d << " [override]"; + if (m_isDeprecated) + d << " [deprecated]"; + if (m_isFinal) + d << " [final]"; + if (m_isAbstract) + d << " [abstract]"; + if (m_isExplicit) + d << " [explicit]"; + if (m_isInvokable) + d << " [invokable]"; + formatModelItemList(d, ", arguments=", m_arguments); + if (m_isVariadics) + d << ",..."; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +TypeInfo _TypeDefModelItem::type() const +{ + return m_type; +} + +void _TypeDefModelItem::setType(const TypeInfo &type) +{ + m_type = type; +} + +#ifndef QT_NO_DEBUG_STREAM +void _TypeDefModelItem::formatDebug(QDebug &d) const +{ + _CodeModelItem::formatDebug(d); + d << ", type=" << m_type; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- + +_TemplateTypeAliasModelItem::_TemplateTypeAliasModelItem(CodeModel *model, int kind) + : _CodeModelItem(model, kind) {} + +_TemplateTypeAliasModelItem::_TemplateTypeAliasModelItem(CodeModel *model, const QString &name, int kind) + : _CodeModelItem(model, name, kind) {} + +TemplateParameterList _TemplateTypeAliasModelItem::templateParameters() const +{ + return m_templateParameters; +} + +void _TemplateTypeAliasModelItem::addTemplateParameter(const TemplateParameterModelItem &templateParameter) +{ + m_templateParameters.append(templateParameter); +} + +TypeInfo _TemplateTypeAliasModelItem::type() const +{ + return m_type; +} + +void _TemplateTypeAliasModelItem::setType(const TypeInfo &type) +{ + m_type = type; +} + +#ifndef QT_NO_DEBUG_STREAM +void _TemplateTypeAliasModelItem::formatDebug(QDebug &d) const +{ + _CodeModelItem::formatDebug(d); + d << ", <"; + for (int i = 0, count = m_templateParameters.size(); i < count; ++i) { + if (i) + d << ", "; + d << m_templateParameters.at(i)->name(); + } + d << ">, type=" << m_type; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +CodeModel::AccessPolicy _EnumModelItem::accessPolicy() const +{ + return m_accessPolicy; +} + +_EnumModelItem::~_EnumModelItem() = default; + +void _EnumModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) +{ + m_accessPolicy = accessPolicy; +} + +EnumeratorList _EnumModelItem::enumerators() const +{ + return m_enumerators; +} + +void _EnumModelItem::addEnumerator(const EnumeratorModelItem &item) +{ + m_enumerators.append(item); +} + +bool _EnumModelItem::isSigned() const +{ + return m_signed; +} + +void _EnumModelItem::setSigned(bool s) +{ + m_signed = s; +} + +#ifndef QT_NO_DEBUG_STREAM +void _EnumModelItem::formatDebug(QDebug &d) const +{ + _CodeModelItem::formatDebug(d); + switch (m_enumKind) { + case CEnum: + break; + case AnonymousEnum: + d << " (anonymous)"; + break; + case EnumClass: + d << " (class)"; + break; + } + if (!m_signed) + d << " (unsigned)"; + formatModelItemList(d, ", enumerators=", m_enumerators); +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +_EnumeratorModelItem::~_EnumeratorModelItem() = default; + +QString _EnumeratorModelItem::stringValue() const +{ + return m_stringValue; +} + +void _EnumeratorModelItem::setStringValue(const QString &value) +{ + m_stringValue = value; +} + +#ifndef QT_NO_DEBUG_STREAM +void _EnumeratorModelItem::formatDebug(QDebug &d) const +{ + _CodeModelItem::formatDebug(d); + d << ", value=" << m_value << ", stringValue=\"" << m_stringValue << '"'; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +_TemplateParameterModelItem::~_TemplateParameterModelItem() = default; + +TypeInfo _TemplateParameterModelItem::type() const +{ + return m_type; +} + +void _TemplateParameterModelItem::setType(const TypeInfo &type) +{ + m_type = type; +} + +bool _TemplateParameterModelItem::defaultValue() const +{ + return m_defaultValue; +} + +void _TemplateParameterModelItem::setDefaultValue(bool defaultValue) +{ + m_defaultValue = defaultValue; +} + +#ifndef QT_NO_DEBUG_STREAM +void _TemplateParameterModelItem::formatDebug(QDebug &d) const +{ + _CodeModelItem::formatDebug(d); + d << ", type=" << m_type; + if (m_defaultValue) + d << " [defaultValue]"; +} +#endif // !QT_NO_DEBUG_STREAM + +// --------------------------------------------------------------------------- +TypeInfo _MemberModelItem::type() const +{ + return m_type; +} + +void _MemberModelItem::setType(const TypeInfo &type) +{ + m_type = type; +} + +CodeModel::AccessPolicy _MemberModelItem::accessPolicy() const +{ + return m_accessPolicy; +} + +_MemberModelItem::~_MemberModelItem() = default; + +void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) +{ + m_accessPolicy = accessPolicy; +} + +bool _MemberModelItem::isStatic() const +{ + return m_isStatic; +} + +void _MemberModelItem::setStatic(bool isStatic) +{ + m_isStatic = isStatic; +} + +bool _MemberModelItem::isConstant() const +{ + return m_isConstant; +} + +void _MemberModelItem::setConstant(bool isConstant) +{ + m_isConstant = isConstant; +} + +bool _MemberModelItem::isVolatile() const +{ + return m_isVolatile; +} + +void _MemberModelItem::setVolatile(bool isVolatile) +{ + m_isVolatile = isVolatile; +} + +bool _MemberModelItem::isAuto() const +{ + return m_isAuto; +} + +void _MemberModelItem::setAuto(bool isAuto) +{ + m_isAuto = isAuto; +} + +bool _MemberModelItem::isFriend() const +{ + return m_isFriend; +} + +void _MemberModelItem::setFriend(bool isFriend) +{ + m_isFriend = isFriend; +} + +bool _MemberModelItem::isRegister() const +{ + return m_isRegister; +} + +void _MemberModelItem::setRegister(bool isRegister) +{ + m_isRegister = isRegister; +} + +bool _MemberModelItem::isExtern() const +{ + return m_isExtern; +} + +void _MemberModelItem::setExtern(bool isExtern) +{ + m_isExtern = isExtern; +} + +bool _MemberModelItem::isMutable() const +{ + return m_isMutable; +} + +void _MemberModelItem::setMutable(bool isMutable) +{ + m_isMutable = isMutable; +} + +#ifndef QT_NO_DEBUG_STREAM +void _MemberModelItem::formatDebug(QDebug &d) const +{ + _CodeModelItem::formatDebug(d); + switch (m_accessPolicy) { + case CodeModel::Public: + d << ", public"; + break; + case CodeModel::Protected: + d << ", protected"; + break; + case CodeModel::Private: + d << ", private"; + break; + } + d << ", type="; + if (m_isConstant) + d << "const "; + if (m_isVolatile) + d << "volatile "; + if (m_isStatic) + d << "static "; + if (m_isAuto) + d << "auto "; + if (m_isFriend) + d << "friend "; + if (m_isRegister) + d << "register "; + if (m_isExtern) + d << "extern "; + if (m_isMutable) + d << "mutable "; + d << m_type; + formatScopeList(d, ", templateParameters", m_templateParameters); +} +#endif // !QT_NO_DEBUG_STREAM + +// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.h b/sources/shiboken6/ApiExtractor/parser/codemodel.h new file mode 100644 index 000000000..13bc7cf36 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/parser/codemodel.h @@ -0,0 +1,814 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + + +#ifndef CODEMODEL_H +#define CODEMODEL_H + +#include "codemodel_fwd.h" +#include "codemodel_enums.h" +#include "enumvalue.h" + +#include <QtCore/QHash> +#include <QtCore/QPair> +#include <QtCore/QSet> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVector> + +QT_FORWARD_DECLARE_CLASS(QDebug) + +#define DECLARE_MODEL_NODE(k) \ + enum { __node_kind = Kind_##k }; + +class SourceLocation; + +class CodeModel +{ +public: + Q_DISABLE_COPY(CodeModel) + + enum AccessPolicy { + Public, + Protected, + Private + }; + + enum FunctionType { + Normal, + Constructor, + CopyConstructor, + MoveConstructor, + Destructor, + Signal, + Slot + }; + + enum ClassType { + Class, + Struct, + Union + }; + +public: + CodeModel(); + virtual ~CodeModel(); + + FileList files() const { return m_files; } + NamespaceModelItem globalNamespace() const; + + void addFile(const FileModelItem &item); + FileModelItem findFile(const QString &name) const; + + CodeModelItem findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const; + +private: + FileList m_files; + NamespaceModelItem m_globalNamespace; +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const CodeModel *m); +#endif + +class TypeInfo +{ + friend class TypeParser; +public: + using Indirections = QVector<Indirection>; + + TypeInfo() : flags(0), m_referenceType(NoReference) {} + + QStringList qualifiedName() const + { + return m_qualifiedName; + } + + void setQualifiedName(const QStringList &qualified_name) + { + m_qualifiedName = qualified_name; + } + + bool isVoid() const; + + bool isConstant() const + { + return m_constant; + } + + void setConstant(bool is) + { + m_constant = is; + } + + bool isVolatile() const + { + return m_volatile; + } + + void setVolatile(bool is) + { + m_volatile = is; + } + + ReferenceType referenceType() const { return m_referenceType; } + void setReferenceType(ReferenceType r) { m_referenceType = r; } + + Indirections indirectionsV() const { return m_indirections; } + void setIndirectionsV(const Indirections &i) { m_indirections = i; } + void addIndirection(Indirection i) { m_indirections.append(i); } + + // "Legacy", rename? + int indirections() const { return m_indirections.size(); } + + void setIndirections(int indirections) + { + m_indirections = Indirections(indirections, Indirection::Pointer); + } + + bool isFunctionPointer() const + { + return m_functionPointer; + } + void setFunctionPointer(bool is) + { + m_functionPointer = is; + } + + QStringList arrayElements() const + { + return m_arrayElements; + } + void setArrayElements(const QStringList &arrayElements) + { + m_arrayElements = arrayElements; + } + + void addArrayElement(const QString &a) { m_arrayElements.append(a); } + + QVector<TypeInfo> arguments() const { return m_arguments; } + + void setArguments(const QVector<TypeInfo> &arguments); + + void addArgument(const TypeInfo &arg) + { + m_arguments.append(arg); + } + + QVector<TypeInfo> instantiations() const { return m_instantiations; } + void setInstantiations(const QVector<TypeInfo> &i) { m_instantiations = i; } + void addInstantiation(const TypeInfo &i) { m_instantiations.append(i); } + void clearInstantiations() { m_instantiations.clear(); } + + bool isStdType() const; + + QPair<int, int> parseTemplateArgumentList(const QString &l, int from = 0); + + bool operator==(const TypeInfo &other) const; + + bool operator!=(const TypeInfo &other) const + { + return !(*this == other); + } + + // ### arrays and templates?? + + QString toString() const; + + static TypeInfo combine(const TypeInfo &__lhs, const TypeInfo &__rhs); + static TypeInfo resolveType(TypeInfo const &__type, const ScopeModelItem &__scope); + + void formatTypeSystemSignature(QTextStream &str) const; + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const; +#endif + + static QString indirectionKeyword(Indirection i); + + static bool stripLeadingConst(QString *s); + static bool stripLeadingVolatile(QString *s); + static bool stripLeadingQualifier(const QString &qualifier, QString *s); + static void stripQualifiers(QString *s); + + void simplifyStdType(); + +private: + friend class TypeInfoTemplateArgumentHandler; + + static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, const ScopeModelItem &__scope); + + QStringList m_qualifiedName; + QStringList m_arrayElements; + QVector<TypeInfo> m_arguments; + QVector<TypeInfo> m_instantiations; + Indirections m_indirections; + + union { + uint flags; + + struct { + uint m_constant: 1; + uint m_volatile: 1; + uint m_functionPointer: 1; + uint m_padding: 29; + }; + }; + + ReferenceType m_referenceType; +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const TypeInfo &t); +#endif + +class _CodeModelItem +{ + Q_DISABLE_COPY(_CodeModelItem) +public: + enum Kind { + /* These are bit-flags resembling inheritance */ + Kind_Scope = 0x1, + Kind_Namespace = 0x2 | Kind_Scope, + Kind_Member = 0x4, + Kind_Function = 0x8 | Kind_Member, + KindMask = 0xf, + + /* These are for classes that are not inherited from */ + FirstKind = 0x8, + Kind_Argument = 1 << FirstKind, + Kind_Class = 2 << FirstKind | Kind_Scope, + Kind_Enum = 3 << FirstKind, + Kind_Enumerator = 4 << FirstKind, + Kind_File = 5 << FirstKind | Kind_Namespace, + Kind_TemplateParameter = 7 << FirstKind, + Kind_TypeDef = 8 << FirstKind, + Kind_TemplateTypeAlias = 9 << FirstKind, + Kind_Variable = 10 << FirstKind | Kind_Member + }; + +public: + virtual ~_CodeModelItem(); + + int kind() const; + + QStringList qualifiedName() const; + + QString name() const; + void setName(const QString &name); + + QStringList scope() const; + void setScope(const QStringList &scope); + + QString fileName() const; + void setFileName(const QString &fileName); + + FileModelItem file() const; + + void getStartPosition(int *line, int *column); + int startLine() const { return m_startLine; } + void setStartPosition(int line, int column); + + void getEndPosition(int *line, int *column); + void setEndPosition(int line, int column); + + SourceLocation sourceLocation() const; + + inline CodeModel *model() const { return m_model; } + +#ifndef QT_NO_DEBUG_STREAM + static void formatKind(QDebug &d, int k); + virtual void formatDebug(QDebug &d) const; +#endif + +protected: + explicit _CodeModelItem(CodeModel *model, int kind); + explicit _CodeModelItem(CodeModel *model, const QString &name, int kind); + +private: + CodeModel *m_model; + int m_kind; + int m_startLine; + int m_startColumn; + int m_endLine; + int m_endColumn; + QString m_name; + QString m_fileName; + QStringList m_scope; +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const _CodeModelItem *t); +#endif + +class _ScopeModelItem: public _CodeModelItem +{ +public: + DECLARE_MODEL_NODE(Scope) + + ~_ScopeModelItem(); + + ClassList classes() const { return m_classes; } + EnumList enums() const { return m_enums; } + inline FunctionList functions() const { return m_functions; } + TypeDefList typeDefs() const { return m_typeDefs; } + TemplateTypeAliasList templateTypeAliases() const { return m_templateTypeAliases; } + VariableList variables() const { return m_variables; } + + void addClass(const ClassModelItem &item); + void addEnum(const EnumModelItem &item); + void addFunction(const FunctionModelItem &item); + void addTypeDef(const TypeDefModelItem &item); + void addTemplateTypeAlias(const TemplateTypeAliasModelItem &item); + 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; + + void addEnumsDeclaration(const QString &enumsDeclaration); + QStringList enumsDeclarations() const { return m_enumsDeclarations; } + + FunctionModelItem declaredFunction(const FunctionModelItem &item); + + bool isEmpty() const; + void purgeClassDeclarations(); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#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) {} + + void appendScope(const _ScopeModelItem &other); + +#ifndef QT_NO_DEBUG_STREAM + void formatScopeItemsDebug(QDebug &d) const; +#endif + +private: + ClassList m_classes; + EnumList m_enums; + TypeDefList m_typeDefs; + TemplateTypeAliasList m_templateTypeAliases; + VariableList m_variables; + FunctionList m_functions; + +private: + QStringList m_enumsDeclarations; +}; + +class _ClassModelItem: public _ScopeModelItem +{ +public: + DECLARE_MODEL_NODE(Class) + + struct BaseClass + { + QString name; + CodeModel::AccessPolicy accessPolicy = CodeModel::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) {} + ~_ClassModelItem(); + + QVector<BaseClass> baseClasses() const { return m_baseClasses; } + + void addBaseClass(const QString &name, CodeModel::AccessPolicy accessPolicy); + + TemplateParameterList templateParameters() const; + void setTemplateParameters(const TemplateParameterList &templateParameters); + + bool extendsClass(const QString &name) const; + + void setClassType(CodeModel::ClassType type); + CodeModel::ClassType classType() const; + + void addPropertyDeclaration(const QString &propertyDeclaration); + QStringList propertyDeclarations() const { return m_propertyDeclarations; } + + bool isFinal() const { return m_final; } + void setFinal(bool f) { m_final = f; } + + bool isEmpty() const; + bool isTemplate() const; + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + QVector<BaseClass> m_baseClasses; + TemplateParameterList m_templateParameters; + CodeModel::ClassType m_classType; + + QStringList m_propertyDeclarations; + bool m_final = false; +}; + +class _NamespaceModelItem: public _ScopeModelItem +{ +public: + 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) {} + ~_NamespaceModelItem(); + + const NamespaceList &namespaces() const { return m_namespaces; } + + NamespaceType type() const { return m_type; } + void setType(NamespaceType t) { m_type = t; } + + void addNamespace(NamespaceModelItem item); + + NamespaceModelItem findNamespace(const QString &name) const; + + void appendNamespace(const _NamespaceModelItem &other); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + NamespaceList m_namespaces; + NamespaceType m_type = NamespaceType::Default; +}; + +class _FileModelItem: public _NamespaceModelItem +{ +public: + 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) {} + ~_FileModelItem(); +}; + +class _ArgumentModelItem: public _CodeModelItem +{ +public: + 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) {} + ~_ArgumentModelItem(); + + TypeInfo type() const; + void setType(const TypeInfo &type); + + bool defaultValue() const; + void setDefaultValue(bool defaultValue); + + QString defaultValueExpression() const { return m_defaultValueExpression; } + void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; } + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + TypeInfo m_type; + QString m_defaultValueExpression; + bool m_defaultValue; +}; + +class _MemberModelItem: public _CodeModelItem +{ +public: + DECLARE_MODEL_NODE(Member) + + explicit _MemberModelItem(CodeModel *model, int kind = __node_kind) + : _CodeModelItem(model, kind), m_accessPolicy(CodeModel::Public), m_flags(0) {} + explicit _MemberModelItem(CodeModel *model, const QString &name, int kind = __node_kind) + : _CodeModelItem(model, name, kind), m_accessPolicy(CodeModel::Public), m_flags(0) {} + ~_MemberModelItem(); + + bool isConstant() const; + void setConstant(bool isConstant); + + bool isVolatile() const; + void setVolatile(bool isVolatile); + + bool isStatic() const; + void setStatic(bool isStatic); + + bool isAuto() const; + void setAuto(bool isAuto); + + bool isFriend() const; + void setFriend(bool isFriend); + + bool isRegister() const; + void setRegister(bool isRegister); + + bool isExtern() const; + void setExtern(bool isExtern); + + bool isMutable() const; + void setMutable(bool isMutable); + + CodeModel::AccessPolicy accessPolicy() const; + void setAccessPolicy(CodeModel::AccessPolicy accessPolicy); + + TemplateParameterList templateParameters() const { return m_templateParameters; } + void setTemplateParameters(const TemplateParameterList &templateParameters) { m_templateParameters = templateParameters; } + + TypeInfo type() const; + void setType(const TypeInfo &type); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + TemplateParameterList m_templateParameters; + TypeInfo m_type; + CodeModel::AccessPolicy m_accessPolicy; + union { + struct { + uint m_isConstant: 1; + uint m_isVolatile: 1; + uint m_isStatic: 1; + uint m_isAuto: 1; + uint m_isFriend: 1; + uint m_isRegister: 1; + uint m_isExtern: 1; + uint m_isMutable: 1; + }; + uint m_flags; + }; + +}; + +class _FunctionModelItem: public _MemberModelItem +{ +public: + 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) {} + ~_FunctionModelItem(); + + ArgumentList arguments() const; + + void addArgument(const ArgumentModelItem& item); + + CodeModel::FunctionType functionType() const; + void setFunctionType(CodeModel::FunctionType functionType); + + 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 isVariadics() const; + void setVariadics(bool isVariadics); + + + bool isSimilar(const FunctionModelItem &other) const; + + bool isNoExcept() const; + + ExceptionSpecification exceptionSpecification() const; + void setExceptionSpecification(ExceptionSpecification e); + + QString typeSystemSignature() const; // For dumping out type system files + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + ArgumentList m_arguments; + CodeModel::FunctionType m_functionType; + 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_isInvokable : 1; // Qt + }; + uint m_flags; + }; + ExceptionSpecification m_exceptionSpecification = ExceptionSpecification::Unknown; +}; + +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) {} +}; + +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) {} + + TypeInfo type() const; + void setType(const TypeInfo &type); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + TypeInfo m_type; +}; + +class _TemplateTypeAliasModelItem : public _CodeModelItem +{ +public: + DECLARE_MODEL_NODE(TemplateTypeAlias) + + explicit _TemplateTypeAliasModelItem(CodeModel *model, int kind = __node_kind); + explicit _TemplateTypeAliasModelItem(CodeModel *model, const QString &name, + int kind = __node_kind); + + TemplateParameterList templateParameters() const; + void addTemplateParameter(const TemplateParameterModelItem &templateParameter); + + TypeInfo type() const; + void setType(const TypeInfo &type); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + TemplateParameterList m_templateParameters; + TypeInfo m_type; +}; + +class _EnumModelItem: public _CodeModelItem +{ +public: + 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) {} + ~_EnumModelItem(); + + CodeModel::AccessPolicy accessPolicy() const; + void setAccessPolicy(CodeModel::AccessPolicy accessPolicy); + + bool hasValues() const { return !m_enumerators.isEmpty(); } + EnumeratorList enumerators() const; + void addEnumerator(const EnumeratorModelItem &item); + + EnumKind enumKind() const { return m_enumKind; } + void setEnumKind(EnumKind kind) { m_enumKind = kind; } + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + + bool isSigned() const; + void setSigned(bool s); + +private: + CodeModel::AccessPolicy m_accessPolicy = CodeModel::Public; + EnumeratorList m_enumerators; + EnumKind m_enumKind = CEnum; + bool m_signed = true; +}; + +class _EnumeratorModelItem: public _CodeModelItem +{ +public: + 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) {} + ~_EnumeratorModelItem(); + + QString stringValue() const; + void setStringValue(const QString &stringValue); + + EnumValue value() const { return m_value; } + void setValue(EnumValue v) { m_value = v; } + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + QString m_stringValue; + EnumValue m_value; +}; + +class _TemplateParameterModelItem: public _CodeModelItem +{ +public: + 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) {} + ~_TemplateParameterModelItem(); + + TypeInfo type() const; + void setType(const TypeInfo &type); + + bool defaultValue() const; + void setDefaultValue(bool defaultValue); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &d) const override; +#endif + +private: + TypeInfo m_type; + bool m_defaultValue; +}; + +#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 new file mode 100644 index 000000000..aebd59879 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef CODEMODEL_ENUMS_H +#define CODEMODEL_ENUMS_H + +enum ReferenceType { + NoReference, + LValueReference, + RValueReference +}; + +enum EnumKind { + CEnum, // Standard C: enum Foo { value1, value2 } + AnonymousEnum, // enum { value1, value2 } + EnumClass // C++ 11 : enum class Foo { value1, value2 } +}; + +enum class Indirection +{ + Pointer, // int * + ConstPointer // int *const +}; + +enum class ExceptionSpecification +{ + Unknown, + NoExcept, + Throws +}; + +enum class NamespaceType +{ + Default, + Anonymous, + Inline +}; + +#endif // CODEMODEL_ENUMS_H diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h new file mode 100644 index 000000000..87fea5cde --- /dev/null +++ b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + + +#ifndef CODEMODEL_FWD_H +#define CODEMODEL_FWD_H + +#include <QtCore/QVector> +#include <QtCore/QSharedPointer> + +// forward declarations +class CodeModel; +class _ArgumentModelItem; +class _ClassModelItem; +class _CodeModelItem; +class _EnumModelItem; +class _EnumeratorModelItem; +class _FileModelItem; +class _FunctionModelItem; +class _NamespaceModelItem; +class _ScopeModelItem; +class _TemplateParameterModelItem; +class _TypeDefModelItem; +class _TemplateTypeAliasModelItem; +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 ArgumentList = QVector<ArgumentModelItem>; +using ClassList = QVector<ClassModelItem>; +using ItemList = QVector<CodeModelItem>; +using EnumList = QVector<EnumModelItem>; +using EnumeratorList = QVector<EnumeratorModelItem>; +using FileList = QVector<FileModelItem>; +using FunctionList = QVector<FunctionModelItem>; +using NamespaceList = QVector<NamespaceModelItem>; +using ScopeList = QVector<ScopeModelItem>; +using TemplateParameterList = QVector<TemplateParameterModelItem>; +using TypeDefList = QVector<TypeDefModelItem>; +using TemplateTypeAliasList = QVector<TemplateTypeAliasModelItem>; +using VariableList = QVector<VariableModelItem>; +using MemberList = QVector<MemberModelItem>; + +#endif // CODEMODEL_FWD_H diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp new file mode 100644 index 000000000..513bb3532 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "enumvalue.h" + +#include <QtCore/QDebug> +#include <QtCore/QString> +#include <QtCore/QTextStream> + +QString EnumValue::toString() const +{ + return m_type == EnumValue::Signed + ? QString::number(m_value) : QString::number(m_unsignedValue); +} + +void EnumValue::setValue(qint64 v) +{ + m_value = v; + m_type = Signed; +} + +void EnumValue::setUnsignedValue(quint64 v) +{ + m_unsignedValue = v; + m_type = Unsigned; +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d,const EnumValue &v) +{ + QDebugStateSaver saver(d); + d.nospace(); + d.noquote(); + d << "EnumValue("; + if (v.m_type == EnumValue::Signed) + d << v.m_value; + else + d << v.m_unsignedValue << 'u'; + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM + +QTextStream &operator<<(QTextStream &s, const EnumValue &v) +{ + if (v.m_type == EnumValue::Signed) + s << v.m_value; + else + s << v.m_unsignedValue; + return s; +} diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.h b/sources/shiboken6/ApiExtractor/parser/enumvalue.h new file mode 100644 index 000000000..ea30c39bb --- /dev/null +++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef ENUMVALUE_H +#define ENUMVALUE_H + +#include <QtCore/QtGlobal> + +QT_FORWARD_DECLARE_CLASS(QDebug) +QT_FORWARD_DECLARE_CLASS(QString) +QT_FORWARD_DECLARE_CLASS(QTextStream) + +class EnumValue +{ +public: + enum Type + { + Signed, + Unsigned + }; + + QString toString() 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; } + + void setValue(qint64 v); + void setUnsignedValue(quint64 v); + +private: +#ifndef QT_NO_DEBUG_STREAM + friend QDebug operator<<(QDebug, const EnumValue &); +#endif + friend QTextStream &operator<<(QTextStream &, const EnumValue &); + + union + { + qint64 m_value = 0; + quint64 m_unsignedValue; + }; + Type m_type = Signed; +}; + +#endif // ENUMVALUE_H |