aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-11-05 11:14:21 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-11-06 08:11:53 +0000
commite21b3c5f6201c97a89b736cec17a1855870409e8 (patch)
treefedbbd89e2112346109a9cd0c1c07a252fe92556
parentb70183a78ed7a478ae9f2af19bd84535a8e69320 (diff)
shiboken6: Split out modification classes from typesystem
Change Modification::Modifiers to be a QFlags and remove unused functions. Change-Id: Ia4a6b9ef06415275b33891cb04772780cd7f2d65 Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/shiboken6/ApiExtractor/CMakeLists.txt1
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.cpp471
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.h539
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp465
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.h510
5 files changed, 1016 insertions, 970 deletions
diff --git a/sources/shiboken6/ApiExtractor/CMakeLists.txt b/sources/shiboken6/ApiExtractor/CMakeLists.txt
index ec9c55364..00a376496 100644
--- a/sources/shiboken6/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken6/ApiExtractor/CMakeLists.txt
@@ -15,6 +15,7 @@ documentation.cpp
fileout.cpp
graph.cpp
messages.cpp
+modifications.cpp
propertyspec.cpp
reporthandler.cpp
sourcelocation.cpp
diff --git a/sources/shiboken6/ApiExtractor/modifications.cpp b/sources/shiboken6/ApiExtractor/modifications.cpp
new file mode 100644
index 000000000..54b30f041
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/modifications.cpp
@@ -0,0 +1,471 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 "modifications.h"
+#include "typedatabase.h"
+#include "typesystem.h"
+
+#include <QtCore/QDebug>
+
+#include <algorithm>
+#include <limits>
+
+static inline QString callOperator() { return QStringLiteral("operator()"); }
+
+QString TemplateInstance::expandCode() const
+{
+ TemplateEntry *templateEntry = TypeDatabase::instance()->findTemplate(m_name);
+ if (!templateEntry)
+ qFatal("<insert-template> referring to non-existing template '%s'.", qPrintable(m_name));
+
+ QString code = templateEntry->code();
+ for (auto it = replaceRules.cbegin(), end = replaceRules.cend(); it != end; ++it)
+ code.replace(it.key(), it.value());
+ while (!code.isEmpty() && code.at(code.size() - 1).isSpace())
+ code.chop(1);
+ QString result = QLatin1String("// TEMPLATE - ") + m_name + QLatin1String(" - START");
+ if (!code.startsWith(QLatin1Char('\n')))
+ result += QLatin1Char('\n');
+ result += code;
+ result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END\n");
+ return result;
+}
+
+// ---------------------- CodeSnipFragment
+QString CodeSnipFragment::code() const
+{
+ return m_instance ? m_instance->expandCode() : m_code;
+}
+
+// ---------------------- CodeSnipAbstract
+QString CodeSnipAbstract::code() const
+{
+ QString res;
+ for (const CodeSnipFragment &codeFrag : codeList)
+ res.append(codeFrag.code());
+
+ return res;
+}
+
+void CodeSnipAbstract::addCode(const QString &code)
+{
+ codeList.append(CodeSnipFragment(fixSpaces(code)));
+}
+
+static inline int firstNonBlank(QStringView s)
+{
+ const auto it = std::find_if(s.cbegin(), s.cend(),
+ [] (QChar c) { return !c.isSpace(); });
+ return int(it - s.cbegin());
+}
+
+static inline bool isEmpty(QStringView s)
+{
+ return s.isEmpty()
+ || std::all_of(s.cbegin(), s.cend(),
+ [] (QChar c) { return c.isSpace(); });
+}
+
+QString CodeSnipAbstract::dedent(const QString &code)
+{
+ if (code.isEmpty())
+ return code;
+ // Right trim if indent=0, or trim if single line
+ if (!code.at(0).isSpace() || !code.contains(QLatin1Char('\n')))
+ return code.trimmed();
+ const auto lines = QStringView{code}.split(QLatin1Char('\n'));
+ int spacesToRemove = std::numeric_limits<int>::max();
+ for (const auto &line : lines) {
+ if (!isEmpty(line)) {
+ const int nonSpacePos = firstNonBlank(line);
+ if (nonSpacePos < spacesToRemove)
+ spacesToRemove = nonSpacePos;
+ if (spacesToRemove == 0)
+ return code;
+ }
+ }
+ QString result;
+ for (const auto &line : lines) {
+ if (!isEmpty(line) && spacesToRemove < line.size())
+ result += line.mid(spacesToRemove).toString();
+ result += QLatin1Char('\n');
+ }
+ return result;
+}
+
+QString CodeSnipAbstract::fixSpaces(QString code)
+{
+ code.remove(QLatin1Char('\r'));
+ // Check for XML <tag>\n<space>bla...
+ if (code.startsWith(QLatin1String("\n ")))
+ code.remove(0, 1);
+ while (!code.isEmpty() && code.back().isSpace())
+ code.chop(1);
+ code = dedent(code);
+ if (!code.isEmpty() && !code.endsWith(QLatin1Char('\n')))
+ code.append(QLatin1Char('\n'));
+ return code;
+}
+
+// Prepend a line to the code, observing indentation
+void CodeSnipAbstract::prependCode(QString *code, QString firstLine)
+{
+ while (!code->isEmpty() && code->front() == QLatin1Char('\n'))
+ code->remove(0, 1);
+ if (!code->isEmpty() && code->front().isSpace()) {
+ const int indent = firstNonBlank(*code);
+ firstLine.prepend(QString(indent, QLatin1Char(' ')));
+ }
+ if (!firstLine.endsWith(QLatin1Char('\n')))
+ firstLine += QLatin1Char('\n');
+ code->prepend(firstLine);
+}
+
+// ---------------------- Modification
+QString Modification::accessModifierString() const
+{
+ if (isPrivate()) return QLatin1String("private");
+ if (isProtected()) return QLatin1String("protected");
+ if (isPublic()) return QLatin1String("public");
+ if (isFriendly()) return QLatin1String("friendly");
+ return QString();
+}
+
+// ---------------------- FunctionModification
+bool FunctionModification::setSignature(const QString &s, QString *errorMessage)
+{
+ if (s.startsWith(QLatin1Char('^'))) {
+ m_signaturePattern.setPattern(s);
+ if (!m_signaturePattern.isValid()) {
+ if (errorMessage) {
+ *errorMessage = QLatin1String("Invalid signature pattern: \"")
+ + s + QLatin1String("\": ") + m_signaturePattern.errorString();
+ }
+ return false;
+ }
+ } else {
+ m_signature = s;
+ }
+ return true;
+}
+
+// ---------------------- AddedFunction
+
+static AddedFunction::TypeInfo parseType(const QString& signature,
+ int startPos = 0, int *endPos = nullptr,
+ QString *argumentName = nullptr,
+ QString *defaultValue = nullptr)
+{
+ AddedFunction::TypeInfo result;
+ static const QRegularExpression regex(QLatin1String("\\w"));
+ Q_ASSERT(regex.isValid());
+ int length = signature.length();
+ int start = signature.indexOf(regex, startPos);
+ if (start == -1) {
+ if (QStringView{signature}.mid(startPos + 1, 3) == QLatin1String("...")) { // varargs
+ if (endPos)
+ *endPos = startPos + 4;
+ result.name = QLatin1String("...");
+ } else { // error
+ if (endPos)
+ *endPos = length;
+ }
+ return result;
+ }
+
+ int cantStop = 0;
+ QString paramString;
+ QChar c;
+ int i = start;
+ for (; i < length; ++i) {
+ c = signature[i];
+ if (c == QLatin1Char('<'))
+ cantStop++;
+ if (c == QLatin1Char('>'))
+ cantStop--;
+ if (cantStop < 0)
+ break; // FIXME: report error?
+ if ((c == QLatin1Char(')') || c == QLatin1Char(',')) && !cantStop)
+ break;
+ paramString += signature[i];
+ }
+ if (endPos)
+ *endPos = i;
+
+ // Check default value
+ if (paramString.contains(QLatin1Char('='))) {
+ QStringList lst = paramString.split(QLatin1Char('='));
+ paramString = lst[0].trimmed();
+ if (defaultValue != nullptr)
+ *defaultValue = lst[1].trimmed();
+ }
+
+ // check constness
+ if (paramString.startsWith(QLatin1String("const "))) {
+ result.isConstant = true;
+ paramString.remove(0, sizeof("const")/sizeof(char));
+ paramString = paramString.trimmed();
+ }
+
+ // Extract argument name from "T<bla,blub>* @foo@"
+ const int nameStartPos = paramString.indexOf(QLatin1Char('@'));
+ if (nameStartPos != -1) {
+ const int nameEndPos = paramString.indexOf(QLatin1Char('@'), nameStartPos + 1);
+ if (nameEndPos > nameStartPos) {
+ if (argumentName)
+ *argumentName = paramString.mid(nameStartPos + 1, nameEndPos - nameStartPos - 1);
+ paramString.remove(nameStartPos, nameEndPos - nameStartPos + 1);
+ paramString = paramString.trimmed();
+ }
+ }
+
+ // check reference
+ if (paramString.endsWith(QLatin1Char('&'))) {
+ result.isReference = true;
+ paramString.chop(1);
+ paramString = paramString.trimmed();
+ }
+ // check Indirections
+ while (paramString.endsWith(QLatin1Char('*'))) {
+ result.indirections++;
+ paramString.chop(1);
+ paramString = paramString.trimmed();
+ }
+ result.name = paramString;
+
+ return result;
+}
+
+AddedFunction::AddedFunction(QString signature, const QString &returnType) :
+ m_access(Public)
+{
+ Q_ASSERT(!returnType.isEmpty());
+ m_returnType = parseType(returnType);
+ signature = signature.trimmed();
+ // Skip past "operator()(...)"
+ const int parenStartPos = signature.startsWith(callOperator())
+ ? callOperator().size() : 0;
+ int endPos = signature.indexOf(QLatin1Char('('), parenStartPos);
+ if (endPos < 0) {
+ m_isConst = false;
+ m_name = signature;
+ } else {
+ m_name = signature.left(endPos).trimmed();
+ int signatureLength = signature.length();
+ while (endPos < signatureLength) {
+ QString argumentName;
+ QString defaultValue;
+ TypeInfo arg = parseType(signature, endPos, &endPos, &argumentName, &defaultValue);
+ if (!arg.name.isEmpty())
+ m_arguments.append({arg, argumentName, defaultValue});
+ // end of parameters...
+ if (endPos >= signatureLength || signature[endPos] == QLatin1Char(')'))
+ break;
+ }
+ // is const?
+ m_isConst = QStringView{signature}.right(signatureLength - endPos).contains(QLatin1String("const"));
+ }
+}
+
+AddedFunction::TypeInfo AddedFunction::TypeInfo::fromSignature(const QString& signature)
+{
+ return parseType(signature);
+}
+
+void DocModification::setCode(const QString &code)
+{
+ m_code = CodeSnipAbstract::fixSpaces(code);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const ReferenceCount &r)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "ReferenceCount(" << r.varName << ", action=" << r.action << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const CodeSnip &s)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "CodeSnip(language=" << s.language << ", position=" << s.position << ", \"";
+ for (const auto &f : s.codeList) {
+ const QString &code = f.code();
+ const auto lines = QStringView{code}.split(QLatin1Char('\n'));
+ for (int i = 0, size = lines.size(); i < size; ++i) {
+ if (i)
+ d << "\\n";
+ d << lines.at(i).trimmed();
+ }
+ }
+ d << '"';
+ if (!s.argumentMap.isEmpty()) {
+ d << ", argumentMap{";
+ for (auto it = s.argumentMap.cbegin(), end = s.argumentMap.cend(); it != end; ++it)
+ d << it.key() << "->\"" << it.value() << '"';
+ d << '}';
+ }
+ d << ')';
+ return d;
+}
+
+void Modification::formatDebug(QDebug &d) const
+{
+ d << "modifiers=" << modifiers;
+ if (removal)
+ d << ", removal";
+ if (!renamedToName.isEmpty())
+ d << ", renamedToName=\"" << renamedToName << '"';
+}
+
+void FunctionModification::formatDebug(QDebug &d) const
+{
+ if (m_signature.isEmpty())
+ d << "pattern=\"" << m_signaturePattern.pattern();
+ else
+ d << "signature=\"" << m_signature;
+ d << "\", ";
+ Modification::formatDebug(d);
+ if (!association.isEmpty())
+ d << ", association=\"" << association << '"';
+ if (m_allowThread != TypeSystem::AllowThread::Unspecified)
+ d << ", allowThread=" << int(m_allowThread);
+ if (m_thread)
+ d << ", thread";
+ if (m_exceptionHandling != TypeSystem::ExceptionHandling::Unspecified)
+ d << ", exceptionHandling=" << int(m_exceptionHandling);
+ if (!snips.isEmpty())
+ d << ", snips=(" << snips << ')';
+ if (!argument_mods.isEmpty())
+ d << ", argument_mods=(" << argument_mods << ')';
+}
+
+QDebug operator<<(QDebug d, const ArgumentOwner &a)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "ArgumentOwner(index=" << a.index << ", action=" << a.action << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const ArgumentModification &a)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "ArgumentModification(index=" << a.index;
+ if (a.removedDefaultExpression)
+ d << ", removedDefaultExpression";
+ if (a.removed)
+ d << ", removed";
+ if (a.noNullPointers)
+ d << ", noNullPointers";
+ if (a.array)
+ d << ", array";
+ if (!a.referenceCounts.isEmpty())
+ d << ", referenceCounts=" << a.referenceCounts;
+ if (!a.modified_type.isEmpty())
+ d << ", modified_type=\"" << a.modified_type << '"';
+ if (!a.replace_value.isEmpty())
+ d << ", replace_value=\"" << a.replace_value << '"';
+ if (!a.replacedDefaultExpression.isEmpty())
+ d << ", replacedDefaultExpression=\"" << a.replacedDefaultExpression << '"';
+ if (!a.ownerships.isEmpty())
+ d << ", ownerships=" << a.ownerships;
+ if (!a.renamed_to.isEmpty())
+ d << ", renamed_to=\"" << a.renamed_to << '"';
+ d << ", owner=" << a.owner << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const FunctionModification &fm)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "FunctionModification(";
+ fm.formatDebug(d);
+ d << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "TypeInfo(";
+ if (ti.isConstant)
+ d << "const";
+ if (ti.indirections)
+ d << QByteArray(ti.indirections, '*');
+ if (ti.isReference)
+ d << " &";
+ d << ti.name;
+ d << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const AddedFunction::Argument &a)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "Argument(";
+ d << a.typeInfo;
+ if (!a.name.isEmpty())
+ d << ' ' << a.name;
+ if (!a.defaultValue.isEmpty())
+ d << " = " << a.defaultValue;
+ d << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const AddedFunction &af)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "AddedFunction(";
+ if (af.access() == AddedFunction::Protected)
+ d << "protected";
+ if (af.isStatic())
+ d << " static";
+ d << af.returnType() << ' ' << af.name() << '(' << af.arguments() << ')';
+ if (af.isConstant())
+ d << " const";
+ if (af.isDeclaration())
+ d << " [declaration]";
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/ApiExtractor/modifications.h b/sources/shiboken6/ApiExtractor/modifications.h
new file mode 100644
index 000000000..3371f51ee
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/modifications.h
@@ -0,0 +1,539 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 MODIFICATIONS_H
+#define MODIFICATIONS_H
+
+#include "typesystem_enums.h"
+#include "typesystem_typedefs.h"
+
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QRegularExpression>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+class QDebug;
+QT_END_NAMESPACE
+
+using ArgumentMap = QMap<int, QString>;
+
+class TemplateInstance
+{
+public:
+ explicit TemplateInstance(const QString &name) : m_name(name) {}
+
+ void addReplaceRule(const QString &name, const QString &value)
+ {
+ replaceRules[name] = value;
+ }
+
+ QString expandCode() const;
+
+ QString name() const
+ {
+ return m_name;
+ }
+
+private:
+ const QString m_name;
+ QHash<QString, QString> replaceRules;
+};
+
+struct ReferenceCount
+{
+ enum Action { // 0x01 - 0xff
+ Invalid = 0x00,
+ Add = 0x01,
+ AddAll = 0x02,
+ Remove = 0x04,
+ Set = 0x08,
+ Ignore = 0x10,
+
+ ActionsMask = 0xff,
+
+ Padding = 0xffffffff
+ };
+
+ QString varName;
+ Action action = Invalid;
+};
+
+struct ArgumentOwner
+{
+ enum Action {
+ Invalid = 0x00,
+ Add = 0x01,
+ Remove = 0x02
+ };
+ enum {
+ InvalidIndex = -2,
+ ThisIndex = -1,
+ ReturnIndex = 0,
+ FirstArgumentIndex = 1
+ };
+
+ Action action = Invalid;
+ int index = InvalidIndex;
+};
+
+class CodeSnipFragment
+{
+public:
+ CodeSnipFragment() = default;
+ explicit CodeSnipFragment(const QString &code) : m_code(code) {}
+ explicit CodeSnipFragment(TemplateInstance *instance) : m_instance(instance) {}
+
+ QString code() const;
+
+private:
+ QString m_code;
+ TemplateInstance *m_instance = nullptr;
+};
+
+class CodeSnipAbstract
+{
+public:
+ QString code() const;
+
+ void addCode(const QString &code);
+ void addCode(QStringView code) { addCode(code.toString()); }
+
+ void addTemplateInstance(TemplateInstance *ti)
+ {
+ codeList.append(CodeSnipFragment(ti));
+ }
+
+ QList<CodeSnipFragment> codeList;
+
+ static QString fixSpaces(QString code);
+ static QString dedent(const QString &code);
+ static void prependCode(QString *code, QString firstLine);
+};
+
+class CustomFunction : public CodeSnipAbstract
+{
+public:
+ explicit CustomFunction(const QString &n = QString()) : name(n) {}
+
+ QString name;
+ QString paramName;
+};
+
+class TemplateEntry : public CodeSnipAbstract
+{
+public:
+ explicit TemplateEntry(const QString &name) : m_name(name) {}
+
+ QString name() const
+ {
+ return m_name;
+ }
+
+private:
+ QString m_name;
+};
+
+class CodeSnip : public CodeSnipAbstract
+{
+public:
+ CodeSnip() = default;
+ explicit CodeSnip(TypeSystem::Language lang) : language(lang) {}
+
+ TypeSystem::Language language = TypeSystem::TargetLangCode;
+ TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny;
+ ArgumentMap argumentMap;
+};
+
+struct ArgumentModification
+{
+ ArgumentModification() : removedDefaultExpression(false), removed(false),
+ noNullPointers(false), resetAfterUse(false), array(false) {}
+ explicit ArgumentModification(int idx) : index(idx), removedDefaultExpression(false), removed(false),
+ noNullPointers(false), resetAfterUse(false), array(false) {}
+
+ // Should the default expression be removed?
+
+
+ // Reference count flags for this argument
+ QList<ReferenceCount> referenceCounts;
+
+ // The text given for the new type of the argument
+ QString modified_type;
+
+ QString replace_value;
+
+ // The text of the new default expression of the argument
+ QString replacedDefaultExpression;
+
+ // The new definition of ownership for a specific argument
+ QHash<TypeSystem::Language, TypeSystem::Ownership> ownerships;
+
+ // Different conversion rules
+ CodeSnipList conversion_rules;
+
+ //QObject parent(owner) of this argument
+ ArgumentOwner owner;
+
+ //New name
+ QString renamed_to;
+
+ // The index of this argument
+ int index = -1;
+
+ uint removedDefaultExpression : 1;
+ uint removed : 1;
+ uint noNullPointers : 1;
+ uint resetAfterUse : 1;
+ uint array : 1; // consider "int*" to be "int[]"
+};
+
+struct Modification
+{
+ enum ModifierFlag {
+ InvalidModifier = 0x0000,
+ Private = 0x0001,
+ Protected = 0x0002,
+ Public = 0x0003,
+ Friendly = 0x0004,
+ AccessModifierMask = 0x000f,
+
+ Final = 0x0010,
+ NonFinal = 0x0020,
+ FinalMask = Final | NonFinal,
+
+ Readable = 0x0100,
+ Writable = 0x0200,
+
+ CodeInjection = 0x1000,
+ Rename = 0x2000,
+ Deprecated = 0x4000,
+ ReplaceExpression = 0x8000
+ };
+
+ Q_DECLARE_FLAGS(Modifiers, ModifierFlag);
+
+ bool isAccessModifier() const
+ {
+ return (modifiers & AccessModifierMask) != 0;
+ }
+ Modifiers accessModifier() const
+ {
+ return modifiers & AccessModifierMask;
+ }
+ bool isPrivate() const
+ {
+ return accessModifier() == Private;
+ }
+ bool isProtected() const
+ {
+ return accessModifier() == Protected;
+ }
+ bool isPublic() const
+ {
+ return accessModifier() == Public;
+ }
+ bool isFriendly() const
+ {
+ return accessModifier() == Friendly;
+ }
+ bool isFinal() const
+ {
+ return modifiers.testFlag(Final);
+ }
+ bool isNonFinal() const
+ {
+ return modifiers.testFlag(NonFinal);
+ }
+ QString accessModifierString() const;
+
+ bool isDeprecated() const
+ {
+ return modifiers.testFlag(Deprecated);
+ }
+
+ void setRenamedTo(const QString &name)
+ {
+ renamedToName = name;
+ }
+ QString renamedTo() const
+ {
+ return renamedToName;
+ }
+ bool isRenameModifier() const
+ {
+ return modifiers.testFlag(Rename);
+ }
+
+ bool isRemoveModifier() const
+ {
+ return removal != TypeSystem::NoLanguage;
+ }
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const;
+#endif
+
+ QString renamedToName;
+ Modifiers modifiers;
+ TypeSystem::Language removal = TypeSystem::NoLanguage;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Modification::Modifiers)
+
+struct FunctionModification: public Modification
+{
+ using AllowThread = TypeSystem::AllowThread;
+
+ bool isCodeInjection() const
+ {
+ return modifiers.testFlag(CodeInjection);
+ }
+ void setIsThread(bool flag)
+ {
+ m_thread = flag;
+ }
+ bool isThread() const
+ {
+ return m_thread;
+ }
+
+ AllowThread allowThread() const { return m_allowThread; }
+ void setAllowThread(AllowThread allow) { m_allowThread = allow; }
+
+ bool matches(const QString &functionSignature) const
+ {
+ return m_signature.isEmpty()
+ ? m_signaturePattern.match(functionSignature).hasMatch()
+ : m_signature == functionSignature;
+ }
+
+ bool setSignature(const QString &s, QString *errorMessage = nullptr);
+ QString signature() const { return m_signature.isEmpty() ? m_signaturePattern.pattern() : m_signature; }
+
+ void setOriginalSignature(const QString &s) { m_originalSignature = s; }
+ QString originalSignature() const { return m_originalSignature; }
+
+ TypeSystem::ExceptionHandling exceptionHandling() const { return m_exceptionHandling; }
+ void setExceptionHandling(TypeSystem::ExceptionHandling e) { m_exceptionHandling = e; }
+
+ int overloadNumber() const { return m_overloadNumber; }
+ void setOverloadNumber(int overloadNumber) { m_overloadNumber = overloadNumber; }
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const;
+#endif
+
+ QString association;
+ CodeSnipList snips;
+
+ QList<ArgumentModification> argument_mods;
+
+private:
+ QString m_signature;
+ QString m_originalSignature;
+ QRegularExpression m_signaturePattern;
+ int m_overloadNumber = TypeSystem::OverloadNumberUnset;
+ bool m_thread = false;
+ AllowThread m_allowThread = AllowThread::Unspecified;
+ TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const ReferenceCount &);
+QDebug operator<<(QDebug d, const ArgumentOwner &a);
+QDebug operator<<(QDebug d, const ArgumentModification &a);
+QDebug operator<<(QDebug d, const FunctionModification &fm);
+#endif
+
+struct FieldModification: public Modification
+{
+ bool isReadable() const
+ {
+ return modifiers.testFlag(Readable);
+ }
+ bool isWritable() const
+ {
+ return modifiers.testFlag(Writable);
+ }
+
+ QString name;
+};
+
+/**
+* \internal
+* Struct used to store information about functions added by the typesystem.
+* This info will be used later to create a fake AbstractMetaFunction which
+* will be inserted into the right AbstractMetaClass.
+*/
+struct AddedFunction
+{
+ /// Function access types.
+ enum Access {
+ InvalidAccess = 0,
+ Protected = 0x1,
+ Public = 0x2
+ };
+
+ /**
+ * \internal
+ * Internal struct used to store information about arguments and return type of the
+ * functions added by the type system. This information is later used to create
+ * AbstractMetaType and AbstractMetaArgument for the AbstractMetaFunctions.
+ */
+ struct TypeInfo {
+ TypeInfo() = default;
+ static TypeInfo fromSignature(const QString& signature);
+
+ QString name;
+ int indirections = 0;
+ bool isConstant = false;
+ bool isReference = false;
+ };
+
+ struct Argument
+ {
+ TypeInfo typeInfo;
+ QString name;
+ QString defaultValue;
+ };
+
+ /// Creates a new AddedFunction with a signature and a return type.
+ explicit AddedFunction(QString signature, const QString &returnType);
+ AddedFunction() = default;
+
+ /// Returns the function name.
+ QString name() const
+ {
+ return m_name;
+ }
+
+ /// Set the function access type.
+ void setAccess(Access access)
+ {
+ m_access = access;
+ }
+
+ /// Returns the function access type.
+ Access access() const
+ {
+ return m_access;
+ }
+
+ /// Returns the function return type.
+ TypeInfo returnType() const
+ {
+ return m_returnType;
+ }
+
+ /// Returns a list of argument type infos.
+ const QList<Argument> &arguments() const
+ {
+ return m_arguments;
+ }
+
+ /// Returns true if this is a constant method.
+ bool isConstant() const
+ {
+ return m_isConst;
+ }
+
+ /// Set this method static.
+ void setStatic(bool value)
+ {
+ m_isStatic = value;
+ }
+
+ /// Returns true if this is a static method.
+ bool isStatic() const
+ {
+ return m_isStatic;
+ }
+
+ bool isDeclaration() const { return m_isDeclaration; } // <declare-function>
+ void setDeclaration(bool value) { m_isDeclaration = value; }
+
+ FunctionModificationList modifications;
+
+private:
+ QString m_name;
+ QList<Argument> m_arguments;
+ TypeInfo m_returnType;
+ Access m_access = Protected;
+ bool m_isConst = false;
+ bool m_isStatic = false;
+ bool m_isDeclaration = false;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti);
+QDebug operator<<(QDebug d, const AddedFunction::Argument &a);
+QDebug operator<<(QDebug d, const AddedFunction &af);
+#endif
+
+class DocModification
+{
+public:
+ DocModification() = default;
+ explicit DocModification(const QString& xpath, const QString& signature) :
+ m_xpath(xpath), m_signature(signature) {}
+ explicit DocModification(TypeSystem::DocModificationMode mode, const QString& signature) :
+ m_signature(signature), m_mode(mode) {}
+
+ void setCode(const QString& code);
+ void setCode(QStringView code) { setCode(code.toString()); }
+
+ QString code() const
+ {
+ return m_code;
+ }
+ QString xpath() const
+ {
+ return m_xpath;
+ }
+ QString signature() const
+ {
+ return m_signature;
+ }
+ TypeSystem::DocModificationMode mode() const
+ {
+ return m_mode;
+ }
+
+ TypeSystem::Language format() const { return m_format; }
+ void setFormat(TypeSystem::Language f) { m_format = f; }
+
+private:
+ QString m_code;
+ QString m_xpath;
+ QString m_signature;
+ TypeSystem::DocModificationMode m_mode = TypeSystem::DocModificationXPathReplace;
+ TypeSystem::Language m_format = TypeSystem::NativeCode;
+};
+
+#endif // MODIFICATIONS_H
diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp
index b13f26464..a7a042c62 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystem.cpp
@@ -33,9 +33,6 @@
#include <QtCore/QRegularExpression>
#include <QtCore/QSet>
-#include <algorithm>
-#include <limits>
-
static QString strings_Object = QLatin1String("Object");
static QString strings_String = QLatin1String("String");
static QString strings_char = QLatin1String("char");
@@ -83,15 +80,6 @@ void TypeEntry::addExtraInclude(const Include &newInclude)
m_extraIncludes.append(newInclude);
}
-QString Modification::accessModifierString() const
-{
- if (isPrivate()) return QLatin1String("private");
- if (isProtected()) return QLatin1String("protected");
- if (isPublic()) return QLatin1String("public");
- if (isFriendly()) return QLatin1String("friendly");
- return QString();
-}
-
FunctionModificationList ComplexTypeEntry::functionModifications(const QString &signature) const
{
FunctionModificationList lst;
@@ -198,454 +186,6 @@ TypeEntry *FlagsTypeEntry::clone() const
FlagsTypeEntry::FlagsTypeEntry(const FlagsTypeEntry &) = default;
-QString TemplateInstance::expandCode() const
-{
- TemplateEntry *templateEntry = TypeDatabase::instance()->findTemplate(m_name);
- if (!templateEntry)
- qFatal("<insert-template> referring to non-existing template '%s'.", qPrintable(m_name));
-
- QString code = templateEntry->code();
- for (auto it = replaceRules.cbegin(), end = replaceRules.cend(); it != end; ++it)
- code.replace(it.key(), it.value());
- while (!code.isEmpty() && code.at(code.size() - 1).isSpace())
- code.chop(1);
- QString result = QLatin1String("// TEMPLATE - ") + m_name + QLatin1String(" - START");
- if (!code.startsWith(QLatin1Char('\n')))
- result += QLatin1Char('\n');
- result += code;
- result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END\n");
- return result;
-}
-
-
-QString CodeSnipAbstract::code() const
-{
- QString res;
- for (const CodeSnipFragment &codeFrag : codeList)
- res.append(codeFrag.code());
-
- return res;
-}
-
-void CodeSnipAbstract::addCode(const QString &code)
-{
- codeList.append(CodeSnipFragment(fixSpaces(code)));
-}
-
-static inline int firstNonBlank(QStringView s)
-{
- const auto it = std::find_if(s.cbegin(), s.cend(),
- [] (QChar c) { return !c.isSpace(); });
- return int(it - s.cbegin());
-}
-
-static inline bool isEmpty(QStringView s)
-{
- return s.isEmpty()
- || std::all_of(s.cbegin(), s.cend(),
- [] (QChar c) { return c.isSpace(); });
-}
-
-QString CodeSnipAbstract::dedent(const QString &code)
-{
- if (code.isEmpty())
- return code;
- // Right trim if indent=0, or trim if single line
- if (!code.at(0).isSpace() || !code.contains(QLatin1Char('\n')))
- return code.trimmed();
- const auto lines = QStringView{code}.split(QLatin1Char('\n'));
- int spacesToRemove = std::numeric_limits<int>::max();
- for (const auto &line : lines) {
- if (!isEmpty(line)) {
- const int nonSpacePos = firstNonBlank(line);
- if (nonSpacePos < spacesToRemove)
- spacesToRemove = nonSpacePos;
- if (spacesToRemove == 0)
- return code;
- }
- }
- QString result;
- for (const auto &line : lines) {
- if (!isEmpty(line) && spacesToRemove < line.size())
- result += line.mid(spacesToRemove).toString();
- result += QLatin1Char('\n');
- }
- return result;
-}
-
-QString CodeSnipAbstract::fixSpaces(QString code)
-{
- code.remove(QLatin1Char('\r'));
- // Check for XML <tag>\n<space>bla...
- if (code.startsWith(QLatin1String("\n ")))
- code.remove(0, 1);
- while (!code.isEmpty() && code.back().isSpace())
- code.chop(1);
- code = dedent(code);
- if (!code.isEmpty() && !code.endsWith(QLatin1Char('\n')))
- code.append(QLatin1Char('\n'));
- return code;
-}
-
-// Prepend a line to the code, observing indentation
-void CodeSnipAbstract::prependCode(QString *code, QString firstLine)
-{
- while (!code->isEmpty() && code->front() == QLatin1Char('\n'))
- code->remove(0, 1);
- if (!code->isEmpty() && code->front().isSpace()) {
- const int indent = firstNonBlank(*code);
- firstLine.prepend(QString(indent, QLatin1Char(' ')));
- }
- if (!firstLine.endsWith(QLatin1Char('\n')))
- firstLine += QLatin1Char('\n');
- code->prepend(firstLine);
-}
-
-QString CodeSnipFragment::code() const
-{
- return m_instance ? m_instance->expandCode() : m_code;
-}
-
-bool FunctionModification::setSignature(const QString &s, QString *errorMessage)
-{
- if (s.startsWith(QLatin1Char('^'))) {
- m_signaturePattern.setPattern(s);
- if (!m_signaturePattern.isValid()) {
- if (errorMessage) {
- *errorMessage = QLatin1String("Invalid signature pattern: \"")
- + s + QLatin1String("\": ") + m_signaturePattern.errorString();
- }
- return false;
- }
- } else {
- m_signature = s;
- }
- return true;
-}
-
-QString FunctionModification::toString() const
-{
- QString str = signature() + QLatin1String("->");
- if (modifiers & AccessModifierMask) {
- switch (modifiers & AccessModifierMask) {
- case Private: str += QLatin1String("private"); break;
- case Protected: str += QLatin1String("protected"); break;
- case Public: str += QLatin1String("public"); break;
- case Friendly: str += QLatin1String("friendly"); break;
- }
- }
-
- if (modifiers & Final) str += QLatin1String("final");
- if (modifiers & NonFinal) str += QLatin1String("non-final");
-
- if (modifiers & Readable) str += QLatin1String("readable");
- if (modifiers & Writable) str += QLatin1String("writable");
-
- if (modifiers & CodeInjection) {
- for (const CodeSnip &s : snips) {
- str += QLatin1String("\n//code injection:\n");
- str += s.code();
- }
- }
-
- if (modifiers & Rename) str += QLatin1String("renamed:") + renamedToName;
-
- if (modifiers & Deprecated) str += QLatin1String("deprecate");
-
- if (modifiers & ReplaceExpression) str += QLatin1String("replace-expression");
-
- return str;
-}
-
-static AddedFunction::TypeInfo parseType(const QString& signature,
- int startPos = 0, int *endPos = nullptr,
- QString *argumentName = nullptr,
- QString *defaultValue = nullptr)
-{
- AddedFunction::TypeInfo result;
- static const QRegularExpression regex(QLatin1String("\\w"));
- Q_ASSERT(regex.isValid());
- int length = signature.length();
- int start = signature.indexOf(regex, startPos);
- if (start == -1) {
- if (QStringView{signature}.mid(startPos + 1, 3) == QLatin1String("...")) { // varargs
- if (endPos)
- *endPos = startPos + 4;
- result.name = QLatin1String("...");
- } else { // error
- if (endPos)
- *endPos = length;
- }
- return result;
- }
-
- int cantStop = 0;
- QString paramString;
- QChar c;
- int i = start;
- for (; i < length; ++i) {
- c = signature[i];
- if (c == QLatin1Char('<'))
- cantStop++;
- if (c == QLatin1Char('>'))
- cantStop--;
- if (cantStop < 0)
- break; // FIXME: report error?
- if ((c == QLatin1Char(')') || c == QLatin1Char(',')) && !cantStop)
- break;
- paramString += signature[i];
- }
- if (endPos)
- *endPos = i;
-
- // Check default value
- if (paramString.contains(QLatin1Char('='))) {
- QStringList lst = paramString.split(QLatin1Char('='));
- paramString = lst[0].trimmed();
- if (defaultValue != nullptr)
- *defaultValue = lst[1].trimmed();
- }
-
- // check constness
- if (paramString.startsWith(QLatin1String("const "))) {
- result.isConstant = true;
- paramString.remove(0, sizeof("const")/sizeof(char));
- paramString = paramString.trimmed();
- }
-
- // Extract argument name from "T<bla,blub>* @foo@"
- const int nameStartPos = paramString.indexOf(QLatin1Char('@'));
- if (nameStartPos != -1) {
- const int nameEndPos = paramString.indexOf(QLatin1Char('@'), nameStartPos + 1);
- if (nameEndPos > nameStartPos) {
- if (argumentName)
- *argumentName = paramString.mid(nameStartPos + 1, nameEndPos - nameStartPos - 1);
- paramString.remove(nameStartPos, nameEndPos - nameStartPos + 1);
- paramString = paramString.trimmed();
- }
- }
-
- // check reference
- if (paramString.endsWith(QLatin1Char('&'))) {
- result.isReference = true;
- paramString.chop(1);
- paramString = paramString.trimmed();
- }
- // check Indirections
- while (paramString.endsWith(QLatin1Char('*'))) {
- result.indirections++;
- paramString.chop(1);
- paramString = paramString.trimmed();
- }
- result.name = paramString;
-
- return result;
-}
-
-AddedFunction::AddedFunction(QString signature, const QString &returnType) :
- m_access(Public)
-{
- Q_ASSERT(!returnType.isEmpty());
- m_returnType = parseType(returnType);
- signature = signature.trimmed();
- // Skip past "operator()(...)"
- const int parenStartPos = signature.startsWith(callOperator())
- ? callOperator().size() : 0;
- int endPos = signature.indexOf(QLatin1Char('('), parenStartPos);
- if (endPos < 0) {
- m_isConst = false;
- m_name = signature;
- } else {
- m_name = signature.left(endPos).trimmed();
- int signatureLength = signature.length();
- while (endPos < signatureLength) {
- QString argumentName;
- QString defaultValue;
- TypeInfo arg = parseType(signature, endPos, &endPos, &argumentName, &defaultValue);
- if (!arg.name.isEmpty())
- m_arguments.append({arg, argumentName, defaultValue});
- // end of parameters...
- if (endPos >= signatureLength || signature[endPos] == QLatin1Char(')'))
- break;
- }
- // is const?
- m_isConst = QStringView{signature}.right(signatureLength - endPos).contains(QLatin1String("const"));
- }
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const ReferenceCount &r)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "ReferenceCount(" << r.varName << ", action=" << r.action << ')';
- return d;
-}
-
-QDebug operator<<(QDebug d, const CodeSnip &s)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "CodeSnip(language=" << s.language << ", position=" << s.position << ", \"";
- for (const auto &f : s.codeList) {
- const QString &code = f.code();
- const auto lines = QStringView{code}.split(QLatin1Char('\n'));
- for (int i = 0, size = lines.size(); i < size; ++i) {
- if (i)
- d << "\\n";
- d << lines.at(i).trimmed();
- }
- }
- d << '"';
- if (!s.argumentMap.isEmpty()) {
- d << ", argumentMap{";
- for (auto it = s.argumentMap.cbegin(), end = s.argumentMap.cend(); it != end; ++it)
- d << it.key() << "->\"" << it.value() << '"';
- d << '}';
- }
- d << ')';
- return d;
-}
-
-void Modification::formatDebug(QDebug &d) const
-{
- d << "modifiers=" << Qt::hex << Qt::showbase << modifiers << Qt::noshowbase << Qt::dec;
- if (removal)
- d << ", removal";
- if (!renamedToName.isEmpty())
- d << ", renamedToName=\"" << renamedToName << '"';
-}
-
-void FunctionModification::formatDebug(QDebug &d) const
-{
- if (m_signature.isEmpty())
- d << "pattern=\"" << m_signaturePattern.pattern();
- else
- d << "signature=\"" << m_signature;
- d << "\", ";
- Modification::formatDebug(d);
- if (!association.isEmpty())
- d << ", association=\"" << association << '"';
- if (m_allowThread != TypeSystem::AllowThread::Unspecified)
- d << ", allowThread=" << int(m_allowThread);
- if (m_thread)
- d << ", thread";
- if (m_exceptionHandling != TypeSystem::ExceptionHandling::Unspecified)
- d << ", exceptionHandling=" << int(m_exceptionHandling);
- if (!snips.isEmpty())
- d << ", snips=(" << snips << ')';
- if (!argument_mods.isEmpty())
- d << ", argument_mods=(" << argument_mods << ')';
-}
-
-QDebug operator<<(QDebug d, const ArgumentOwner &a)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "ArgumentOwner(index=" << a.index << ", action=" << a.action << ')';
- return d;
-}
-
-QDebug operator<<(QDebug d, const ArgumentModification &a)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "ArgumentModification(index=" << a.index;
- if (a.removedDefaultExpression)
- d << ", removedDefaultExpression";
- if (a.removed)
- d << ", removed";
- if (a.noNullPointers)
- d << ", noNullPointers";
- if (a.array)
- d << ", array";
- if (!a.referenceCounts.isEmpty())
- d << ", referenceCounts=" << a.referenceCounts;
- if (!a.modified_type.isEmpty())
- d << ", modified_type=\"" << a.modified_type << '"';
- if (!a.replace_value.isEmpty())
- d << ", replace_value=\"" << a.replace_value << '"';
- if (!a.replacedDefaultExpression.isEmpty())
- d << ", replacedDefaultExpression=\"" << a.replacedDefaultExpression << '"';
- if (!a.ownerships.isEmpty())
- d << ", ownerships=" << a.ownerships;
- if (!a.renamed_to.isEmpty())
- d << ", renamed_to=\"" << a.renamed_to << '"';
- d << ", owner=" << a.owner << ')';
- return d;
-}
-
-QDebug operator<<(QDebug d, const FunctionModification &fm)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "FunctionModification(";
- fm.formatDebug(d);
- d << ')';
- return d;
-}
-
-QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "TypeInfo(";
- if (ti.isConstant)
- d << "const";
- if (ti.indirections)
- d << QByteArray(ti.indirections, '*');
- if (ti.isReference)
- d << " &";
- d << ti.name;
- d << ')';
- return d;
-}
-
-QDebug operator<<(QDebug d, const AddedFunction::Argument &a)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "Argument(";
- d << a.typeInfo;
- if (!a.name.isEmpty())
- d << ' ' << a.name;
- if (!a.defaultValue.isEmpty())
- d << " = " << a.defaultValue;
- d << ')';
- return d;
-}
-
-QDebug operator<<(QDebug d, const AddedFunction &af)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "AddedFunction(";
- if (af.access() == AddedFunction::Protected)
- d << "protected";
- if (af.isStatic())
- d << " static";
- d << af.returnType() << ' ' << af.name() << '(' << af.arguments() << ')';
- if (af.isConstant())
- d << " const";
- if (af.isDeclaration())
- d << " [declaration]";
- return d;
-}
-#endif // !QT_NO_DEBUG_STREAM
-
-AddedFunction::TypeInfo AddedFunction::TypeInfo::fromSignature(const QString& signature)
-{
- return parseType(signature);
-}
-
static QString buildName(const QString &entryName, const TypeEntry *parent)
{
return parent == nullptr || parent->type() == TypeEntry::TypeSystemType
@@ -1274,8 +814,3 @@ TypeEntry *ObjectTypeEntry::clone() const
}
ObjectTypeEntry::ObjectTypeEntry(const ObjectTypeEntry &) = default;
-
-void DocModification::setCode(const QString &code)
-{
- m_code = CodeSnipAbstract::fixSpaces(code);
-}
diff --git a/sources/shiboken6/ApiExtractor/typesystem.h b/sources/shiboken6/ApiExtractor/typesystem.h
index 1a401558a..561969542 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.h
+++ b/sources/shiboken6/ApiExtractor/typesystem.h
@@ -31,6 +31,7 @@
#include "typesystem_enums.h"
#include "typesystem_typedefs.h"
+#include "modifications.h"
#include "include.h"
#include "sourcelocation.h"
@@ -47,516 +48,15 @@
extern const char *TARGET_CONVERSION_RULE_FLAG;
extern const char *NATIVE_CONVERSION_RULE_FLAG;
-class AbstractMetaType;
+class CustomConversion;
+class FlagsTypeEntry;
+class TypeSystemTypeEntry;
+
QT_BEGIN_NAMESPACE
class QDebug;
class QTextStream;
QT_END_NAMESPACE
-class EnumTypeEntry;
-class FlagsTypeEntry;
-
-using ArgumentMap = QMap<int, QString>;
-
-class TemplateInstance;
-
-struct ReferenceCount
-{
- enum Action { // 0x01 - 0xff
- Invalid = 0x00,
- Add = 0x01,
- AddAll = 0x02,
- Remove = 0x04,
- Set = 0x08,
- Ignore = 0x10,
-
- ActionsMask = 0xff,
-
- Padding = 0xffffffff
- };
-
- QString varName;
- Action action = Invalid;
-};
-
-struct ArgumentOwner
-{
- enum Action {
- Invalid = 0x00,
- Add = 0x01,
- Remove = 0x02
- };
- enum {
- InvalidIndex = -2,
- ThisIndex = -1,
- ReturnIndex = 0,
- FirstArgumentIndex = 1
- };
-
- Action action = Invalid;
- int index = InvalidIndex;
-};
-
-class CodeSnipFragment
-{
-public:
- CodeSnipFragment() = default;
- explicit CodeSnipFragment(const QString &code) : m_code(code) {}
- explicit CodeSnipFragment(TemplateInstance *instance) : m_instance(instance) {}
-
- QString code() const;
-
-private:
- QString m_code;
- TemplateInstance *m_instance = nullptr;
-};
-
-class CodeSnipAbstract
-{
-public:
- QString code() const;
-
- void addCode(const QString &code);
- void addCode(QStringView code) { addCode(code.toString()); }
-
- void addTemplateInstance(TemplateInstance *ti)
- {
- codeList.append(CodeSnipFragment(ti));
- }
-
- QVector<CodeSnipFragment> codeList;
-
- static QString fixSpaces(QString code);
- static QString dedent(const QString &code);
- static void prependCode(QString *code, QString firstLine);
-};
-
-class CustomFunction : public CodeSnipAbstract
-{
-public:
- explicit CustomFunction(const QString &n = QString()) : name(n) {}
-
- QString name;
- QString paramName;
-};
-
-class TemplateEntry : public CodeSnipAbstract
-{
-public:
- explicit TemplateEntry(const QString &name) : m_name(name) {}
-
- QString name() const
- {
- return m_name;
- }
-
-private:
- QString m_name;
-};
-
-class TemplateInstance
-{
-public:
- explicit TemplateInstance(const QString &name) : m_name(name) {}
-
- void addReplaceRule(const QString &name, const QString &value)
- {
- replaceRules[name] = value;
- }
-
- QString expandCode() const;
-
- QString name() const
- {
- return m_name;
- }
-
-private:
- const QString m_name;
- QHash<QString, QString> replaceRules;
-};
-
-
-class CodeSnip : public CodeSnipAbstract
-{
-public:
- CodeSnip() = default;
- explicit CodeSnip(TypeSystem::Language lang) : language(lang) {}
-
- TypeSystem::Language language = TypeSystem::TargetLangCode;
- TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny;
- ArgumentMap argumentMap;
-};
-
-struct ArgumentModification
-{
- ArgumentModification() : removedDefaultExpression(false), removed(false),
- noNullPointers(false), resetAfterUse(false), array(false) {}
- explicit ArgumentModification(int idx) : index(idx), removedDefaultExpression(false), removed(false),
- noNullPointers(false), resetAfterUse(false), array(false) {}
-
- // Should the default expression be removed?
-
-
- // Reference count flags for this argument
- QVector<ReferenceCount> referenceCounts;
-
- // The text given for the new type of the argument
- QString modified_type;
-
- QString replace_value;
-
- // The text of the new default expression of the argument
- QString replacedDefaultExpression;
-
- // The new definition of ownership for a specific argument
- QHash<TypeSystem::Language, TypeSystem::Ownership> ownerships;
-
- // Different conversion rules
- CodeSnipList conversion_rules;
-
- //QObject parent(owner) of this argument
- ArgumentOwner owner;
-
- //New name
- QString renamed_to;
-
- // The index of this argument
- int index = -1;
-
- uint removedDefaultExpression : 1;
- uint removed : 1;
- uint noNullPointers : 1;
- uint resetAfterUse : 1;
- uint array : 1; // consider "int*" to be "int[]"
-};
-
-struct Modification
-{
- enum Modifiers : uint {
- InvalidModifier = 0x0000,
- Private = 0x0001,
- Protected = 0x0002,
- Public = 0x0003,
- Friendly = 0x0004,
- AccessModifierMask = 0x000f,
-
- Final = 0x0010,
- NonFinal = 0x0020,
- FinalMask = Final | NonFinal,
-
- Readable = 0x0100,
- Writable = 0x0200,
-
- CodeInjection = 0x1000,
- Rename = 0x2000,
- Deprecated = 0x4000,
- ReplaceExpression = 0x8000
- };
-
- bool isAccessModifier() const
- {
- return modifiers & AccessModifierMask;
- }
- Modifiers accessModifier() const
- {
- return Modifiers(modifiers & AccessModifierMask);
- }
- bool isPrivate() const
- {
- return accessModifier() == Private;
- }
- bool isProtected() const
- {
- return accessModifier() == Protected;
- }
- bool isPublic() const
- {
- return accessModifier() == Public;
- }
- bool isFriendly() const
- {
- return accessModifier() == Friendly;
- }
- bool isFinal() const
- {
- return modifiers & Final;
- }
- bool isNonFinal() const
- {
- return modifiers & NonFinal;
- }
- QString accessModifierString() const;
-
- bool isDeprecated() const
- {
- return modifiers & Deprecated;
- }
-
- void setRenamedTo(const QString &name)
- {
- renamedToName = name;
- }
- QString renamedTo() const
- {
- return renamedToName;
- }
- bool isRenameModifier() const
- {
- return modifiers & Rename;
- }
-
- bool isRemoveModifier() const
- {
- return removal != TypeSystem::NoLanguage;
- }
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const;
-#endif
-
- QString renamedToName;
- uint modifiers = 0;
- TypeSystem::Language removal = TypeSystem::NoLanguage;
-};
-
-struct FunctionModification: public Modification
-{
- using AllowThread = TypeSystem::AllowThread;
-
- bool isCodeInjection() const
- {
- return modifiers & CodeInjection;
- }
- void setIsThread(bool flag)
- {
- m_thread = flag;
- }
- bool isThread() const
- {
- return m_thread;
- }
-
- AllowThread allowThread() const { return m_allowThread; }
- void setAllowThread(AllowThread allow) { m_allowThread = allow; }
-
- bool matches(const QString &functionSignature) const
- {
- return m_signature.isEmpty()
- ? m_signaturePattern.match(functionSignature).hasMatch()
- : m_signature == functionSignature;
- }
-
- bool setSignature(const QString &s, QString *errorMessage = nullptr);
- QString signature() const { return m_signature.isEmpty() ? m_signaturePattern.pattern() : m_signature; }
-
- void setOriginalSignature(const QString &s) { m_originalSignature = s; }
- QString originalSignature() const { return m_originalSignature; }
-
- TypeSystem::ExceptionHandling exceptionHandling() const { return m_exceptionHandling; }
- void setExceptionHandling(TypeSystem::ExceptionHandling e) { m_exceptionHandling = e; }
-
- int overloadNumber() const { return m_overloadNumber; }
- void setOverloadNumber(int overloadNumber) { m_overloadNumber = overloadNumber; }
-
- QString toString() const;
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const;
-#endif
-
- QString association;
- CodeSnipList snips;
-
- QVector<ArgumentModification> argument_mods;
-
-private:
- QString m_signature;
- QString m_originalSignature;
- QRegularExpression m_signaturePattern;
- int m_overloadNumber = TypeSystem::OverloadNumberUnset;
- bool m_thread = false;
- AllowThread m_allowThread = AllowThread::Unspecified;
- TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const ReferenceCount &);
-QDebug operator<<(QDebug d, const ArgumentOwner &a);
-QDebug operator<<(QDebug d, const ArgumentModification &a);
-QDebug operator<<(QDebug d, const FunctionModification &fm);
-#endif
-
-struct FieldModification: public Modification
-{
- bool isReadable() const
- {
- return modifiers & Readable;
- }
- bool isWritable() const
- {
- return modifiers & Writable;
- }
-
- QString name;
-};
-
-/**
-* \internal
-* Struct used to store information about functions added by the typesystem.
-* This info will be used later to create a fake AbstractMetaFunction which
-* will be inserted into the right AbstractMetaClass.
-*/
-struct AddedFunction
-{
- /// Function access types.
- enum Access {
- InvalidAccess = 0,
- Protected = 0x1,
- Public = 0x2
- };
-
- /**
- * \internal
- * Internal struct used to store information about arguments and return type of the
- * functions added by the type system. This information is later used to create
- * AbstractMetaType and AbstractMetaArgument for the AbstractMetaFunctions.
- */
- struct TypeInfo {
- TypeInfo() = default;
- static TypeInfo fromSignature(const QString& signature);
-
- QString name;
- int indirections = 0;
- bool isConstant = false;
- bool isReference = false;
- };
-
- struct Argument
- {
- TypeInfo typeInfo;
- QString name;
- QString defaultValue;
- };
-
- /// Creates a new AddedFunction with a signature and a return type.
- explicit AddedFunction(QString signature, const QString &returnType);
- AddedFunction() = default;
-
- /// Returns the function name.
- QString name() const
- {
- return m_name;
- }
-
- /// Set the function access type.
- void setAccess(Access access)
- {
- m_access = access;
- }
-
- /// Returns the function access type.
- Access access() const
- {
- return m_access;
- }
-
- /// Returns the function return type.
- TypeInfo returnType() const
- {
- return m_returnType;
- }
-
- /// Returns a list of argument type infos.
- const QVector<Argument> &arguments() const
- {
- return m_arguments;
- }
-
- /// Returns true if this is a constant method.
- bool isConstant() const
- {
- return m_isConst;
- }
-
- /// Set this method static.
- void setStatic(bool value)
- {
- m_isStatic = value;
- }
-
- /// Returns true if this is a static method.
- bool isStatic() const
- {
- return m_isStatic;
- }
-
- bool isDeclaration() const { return m_isDeclaration; } // <declare-function>
- void setDeclaration(bool value) { m_isDeclaration = value; }
-
- FunctionModificationList modifications;
-
-private:
- QString m_name;
- QVector<Argument> m_arguments;
- TypeInfo m_returnType;
- Access m_access = Protected;
- bool m_isConst = false;
- bool m_isStatic = false;
- bool m_isDeclaration = false;
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti);
-QDebug operator<<(QDebug d, const AddedFunction::Argument &a);
-QDebug operator<<(QDebug d, const AddedFunction &af);
-#endif
-
-class ObjectTypeEntry;
-
-class DocModification
-{
-public:
- DocModification() = default;
- explicit DocModification(const QString& xpath, const QString& signature) :
- m_xpath(xpath), m_signature(signature) {}
- explicit DocModification(TypeSystem::DocModificationMode mode, const QString& signature) :
- m_signature(signature), m_mode(mode) {}
-
- void setCode(const QString& code);
- void setCode(QStringView code) { setCode(code.toString()); }
-
- QString code() const
- {
- return m_code;
- }
- QString xpath() const
- {
- return m_xpath;
- }
- QString signature() const
- {
- return m_signature;
- }
- TypeSystem::DocModificationMode mode() const
- {
- return m_mode;
- }
-
- TypeSystem::Language format() const { return m_format; }
- void setFormat(TypeSystem::Language f) { m_format = f; }
-
-private:
- QString m_code;
- QString m_xpath;
- QString m_signature;
- TypeSystem::DocModificationMode m_mode = TypeSystem::DocModificationXPathReplace;
- TypeSystem::Language m_format = TypeSystem::NativeCode;
-};
-
-class CustomConversion;
-class TypeSystemTypeEntry;
-
struct TypeSystemProperty
{
bool isValid() const { return !name.isEmpty() && !read.isEmpty() && !type.isEmpty(); }