aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/typesystemparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/typesystemparser.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp1316
1 files changed, 764 insertions, 552 deletions
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index d91fa9193..2b686e997 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -2,22 +2,19 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "typesystemparser_p.h"
+#include "anystringview_helpers.h"
+#include "addedfunction.h"
#include "codesnip.h"
#include "enumtypeentry.h"
-#include "enumvaluetypeentry.h"
-#include "arraytypeentry.h"
-#include "constantvaluetypeentry.h"
#include "containertypeentry.h"
#include "customconversion.h"
#include "customtypenentry.h"
-#include "enumtypeentry.h"
#include "flagstypeentry.h"
#include "functiontypeentry.h"
#include "namespacetypeentry.h"
#include "objecttypeentry.h"
#include "primitivetypeentry.h"
#include "smartpointertypeentry.h"
-#include "templateargumententry.h"
#include "typedefentry.h"
#include "typesystemtypeentry.h"
#include "valuetypeentry.h"
@@ -49,76 +46,84 @@
using namespace Qt::StringLiterals;
-static inline QString allowThreadAttribute() { return QStringLiteral("allow-thread"); }
-static inline QString colonColon() { return QStringLiteral("::"); }
-static inline QString checkFunctionAttribute() { return QStringLiteral("check-function"); }
-static inline QString copyableAttribute() { return QStringLiteral("copyable"); }
-static inline QString accessAttribute() { return QStringLiteral("access"); }
-static inline QString actionAttribute() { return QStringLiteral("action"); }
-static inline QString quoteAfterLineAttribute() { return QStringLiteral("quote-after-line"); }
-static inline QString quoteBeforeLineAttribute() { return QStringLiteral("quote-before-line"); }
-static inline QString textAttribute() { return QStringLiteral("text"); }
-static inline QString nameAttribute() { return QStringLiteral("name"); }
-static inline QString sinceAttribute() { return QStringLiteral("since"); }
-static inline QString untilAttribute() { return QStringLiteral("until"); }
-static inline QString defaultSuperclassAttribute() { return QStringLiteral("default-superclass"); }
-static inline QString deleteInMainThreadAttribute() { return QStringLiteral("delete-in-main-thread"); }
-static inline QString deprecatedAttribute() { return QStringLiteral("deprecated"); }
-static inline QString disableWrapperAttribute() { return QStringLiteral("disable-wrapper"); }
-static inline QString exceptionHandlingAttribute() { return QStringLiteral("exception-handling"); }
-static inline QString extensibleAttribute() { return QStringLiteral("extensible"); }
-static inline QString fileNameAttribute() { return QStringLiteral("file-name"); }
-static inline QString flagsAttribute() { return QStringLiteral("flags"); }
-static inline QString forceAbstractAttribute() { return QStringLiteral("force-abstract"); }
-static inline QString forceIntegerAttribute() { return QStringLiteral("force-integer"); }
-static inline QString formatAttribute() { return QStringLiteral("format"); }
-static inline QString generateUsingAttribute() { return QStringLiteral("generate-using"); }
-static inline QString generateFunctionsAttribute() { return QStringLiteral("generate-functions"); }
-static inline QString classAttribute() { return QStringLiteral("class"); }
-static inline QString generateAttribute() { return QStringLiteral("generate"); }
-static inline QString generateGetSetDefAttribute() { return QStringLiteral("generate-getsetdef"); }
-static inline QString genericClassAttribute() { return QStringLiteral("generic-class"); }
-static inline QString indexAttribute() { return QStringLiteral("index"); }
-static inline QString invalidateAfterUseAttribute() { return QStringLiteral("invalidate-after-use"); }
-static inline QString isNullAttribute() { return QStringLiteral("isNull"); }
-static inline QString locationAttribute() { return QStringLiteral("location"); }
-static inline QString modifiedTypeAttribute() { return QStringLiteral("modified-type"); }
-static inline QString operatorBoolAttribute() { return QStringLiteral("operator-bool"); }
-static inline QString parentManagementAttribute() { return QStringLiteral("parent-management"); }
-static inline QString pyiTypeAttribute() { return QStringLiteral("pyi-type"); }
-static inline QString overloadNumberAttribute() { return QStringLiteral("overload-number"); }
-static inline QString ownershipAttribute() { return QStringLiteral("owner"); }
-static inline QString packageAttribute() { return QStringLiteral("package"); }
-static inline QString positionAttribute() { return QStringLiteral("position"); }
-static inline QString preferredConversionAttribute() { return QStringLiteral("preferred-conversion"); }
-static inline QString preferredTargetLangTypeAttribute() { return QStringLiteral("preferred-target-lang-type"); }
-static inline QString qtMetaTypeAttribute() { return QStringLiteral("qt-register-metatype"); }
-static inline QString removeAttribute() { return QStringLiteral("remove"); }
-static inline QString renameAttribute() { return QStringLiteral("rename"); }
-static inline QString readAttribute() { return QStringLiteral("read"); }
-static inline QString targetLangNameAttribute() { return QStringLiteral("target-lang-name"); }
-static inline QString writeAttribute() { return QStringLiteral("write"); }
-static inline QString opaqueContainerFieldAttribute() { return QStringLiteral("opaque-container"); }
-static inline QString replaceAttribute() { return QStringLiteral("replace"); }
-static inline QString toAttribute() { return QStringLiteral("to"); }
-static inline QString signatureAttribute() { return QStringLiteral("signature"); }
-static inline QString snippetAttribute() { return QStringLiteral("snippet"); }
-static inline QString snakeCaseAttribute() { return QStringLiteral("snake-case"); }
-static inline QString staticAttribute() { return QStringLiteral("static"); }
-static inline QString classmethodAttribute() { return QStringLiteral("classmethod"); }
-static inline QString threadAttribute() { return QStringLiteral("thread"); }
-static inline QString sourceAttribute() { return QStringLiteral("source"); }
-static inline QString streamAttribute() { return QStringLiteral("stream"); }
-static inline QString privateAttribute() { return QStringLiteral("private"); }
-static inline QString xPathAttribute() { return QStringLiteral("xpath"); }
-static inline QString virtualSlotAttribute() { return QStringLiteral("virtual-slot"); }
-static inline QString visibleAttribute() { return QStringLiteral("visible"); }
-static inline QString enumIdentifiedByValueAttribute() { return QStringLiteral("identified-by-value"); }
-
-static inline QString noAttributeValue() { return QStringLiteral("no"); }
-static inline QString yesAttributeValue() { return QStringLiteral("yes"); }
-static inline QString trueAttributeValue() { return QStringLiteral("true"); }
-static inline QString falseAttributeValue() { return QStringLiteral("false"); }
+constexpr auto allowThreadAttribute = "allow-thread"_L1;
+constexpr auto checkFunctionAttribute = "check-function"_L1;
+constexpr auto copyableAttribute = "copyable"_L1;
+constexpr auto accessAttribute = "access"_L1;
+constexpr auto actionAttribute = "action"_L1;
+constexpr auto quoteAfterLineAttribute = "quote-after-line"_L1;
+constexpr auto quoteBeforeLineAttribute = "quote-before-line"_L1;
+constexpr auto textAttribute = "text"_L1;
+constexpr auto nameAttribute = "name"_L1;
+constexpr auto sinceAttribute = "since"_L1;
+constexpr auto untilAttribute = "until"_L1;
+constexpr auto defaultSuperclassAttribute = "default-superclass"_L1;
+constexpr auto deleteInMainThreadAttribute = "delete-in-main-thread"_L1;
+constexpr auto deprecatedAttribute = "deprecated"_L1;
+constexpr auto disableWrapperAttribute = "disable-wrapper"_L1;
+constexpr auto docFileAttribute = "doc-file"_L1;
+constexpr auto exceptionHandlingAttribute = "exception-handling"_L1;
+constexpr auto extensibleAttribute = "extensible"_L1;
+constexpr auto fileNameAttribute = "file-name"_L1;
+constexpr auto fileAttribute = "file"_L1;
+constexpr auto flagsAttribute = "flags"_L1;
+constexpr auto forceAbstractAttribute = "force-abstract"_L1;
+constexpr auto forceIntegerAttribute = "force-integer"_L1;
+constexpr auto formatAttribute = "format"_L1;
+constexpr auto generateUsingAttribute = "generate-using"_L1;
+constexpr auto generateFunctionsAttribute = "generate-functions"_L1;
+constexpr auto classAttribute = "class"_L1;
+constexpr auto generateAttribute = "generate"_L1;
+constexpr auto generateGetSetDefAttribute = "generate-getsetdef"_L1;
+constexpr auto genericClassAttribute = "generic-class"_L1;
+constexpr auto indexAttribute = "index"_L1;
+constexpr auto invalidateAfterUseAttribute = "invalidate-after-use"_L1;
+constexpr auto isNullAttribute = "isNull"_L1;
+constexpr auto locationAttribute = "location"_L1;
+constexpr auto modifiedTypeAttribute = "modified-type"_L1;
+constexpr auto opaqueContainerAttribute = "opaque-containers"_L1;
+constexpr auto operatorBoolAttribute = "operator-bool"_L1;
+constexpr auto parentManagementAttribute = "parent-management"_L1;
+constexpr auto pyiTypeAttribute = "pyi-type"_L1;
+constexpr auto overloadNumberAttribute = "overload-number"_L1;
+constexpr auto ownershipAttribute = "owner"_L1;
+constexpr auto packageAttribute = "package"_L1;
+constexpr auto polymorphicBaseAttribute = "polymorphic-base"_L1;
+constexpr auto positionAttribute = "position"_L1;
+constexpr auto preferredConversionAttribute = "preferred-conversion"_L1;
+constexpr auto preferredTargetLangTypeAttribute = "preferred-target-lang-type"_L1;
+constexpr auto pythonEnumTypeAttribute = "python-type"_L1;
+constexpr auto pythonOverrideAttribute = "python-override"_L1;
+constexpr auto cppEnumTypeAttribute = "cpp-type"_L1;
+constexpr auto qtMetaObjectFunctionsAttribute = "qt-metaobject"_L1;
+constexpr auto qtMetaTypeAttribute = "qt-register-metatype"_L1;
+constexpr auto removeAttribute = "remove"_L1;
+constexpr auto renameAttribute = "rename"_L1;
+constexpr auto readAttribute = "read"_L1;
+constexpr auto targetLangNameAttribute = "target-lang-name"_L1;
+constexpr auto writeAttribute = "write"_L1;
+constexpr auto opaqueContainerFieldAttribute = "opaque-container"_L1;
+constexpr auto replaceAttribute = "replace"_L1;
+constexpr auto toAttribute = "to"_L1;
+constexpr auto signatureAttribute = "signature"_L1;
+constexpr auto snippetAttribute = "snippet"_L1;
+constexpr auto snakeCaseAttribute = "snake-case"_L1;
+constexpr auto staticAttribute = "static"_L1;
+constexpr auto classmethodAttribute = "classmethod"_L1;
+constexpr auto threadAttribute = "thread"_L1;
+constexpr auto sourceAttribute = "source"_L1;
+constexpr auto streamAttribute = "stream"_L1;
+constexpr auto privateAttribute = "private"_L1;
+constexpr auto xPathAttribute = "xpath"_L1;
+constexpr auto virtualSlotAttribute = "virtual-slot"_L1;
+constexpr auto visibleAttribute = "visible"_L1;
+constexpr auto enumIdentifiedByValueAttribute = "identified-by-value"_L1;
+constexpr auto subModuleOfAttribute = "submodule-of"_L1;
+
+constexpr auto noAttributeValue = "no"_L1;
+constexpr auto yesAttributeValue = "yes"_L1;
+constexpr auto trueAttributeValue = "true"_L1;
+constexpr auto falseAttributeValue = "false"_L1;
static bool isTypeEntry(StackElement el)
{
@@ -135,7 +140,7 @@ static bool isDocumentation(StackElement el)
return el >= StackElement::FirstDocumentation && el <= StackElement::LastDocumentation;
}
-static QList<CustomConversion *> customConversionsForReview;
+static QList<CustomConversionPtr> customConversionsForReview;
// Set a regular expression for rejection from text. By legacy, those are fixed
// strings, except for '*' meaning 'match all'. Enclosing in "^..$"
@@ -148,7 +153,7 @@ static bool setRejectionRegularExpression(const QString &patternIn,
if (patternIn.startsWith(u'^') && patternIn.endsWith(u'$'))
pattern = patternIn;
else if (patternIn == u"*")
- pattern = QStringLiteral("^.*$");
+ pattern = "^.*$"_L1;
else
pattern = u'^' + QRegularExpression::escape(patternIn) + u'$';
re->setPattern(pattern);
@@ -159,15 +164,20 @@ static bool setRejectionRegularExpression(const QString &patternIn,
return true;
}
+static inline bool hasFileSnippetAttributes(const QXmlStreamAttributes *attributes)
+{
+ return attributes->hasAttribute(fileAttribute);
+}
+
// Extract a snippet from a file within annotation "// @snippet label".
std::optional<QString>
extractSnippet(const QString &code, const QString &snippetLabel)
{
if (snippetLabel.isEmpty())
return code;
- const QString pattern = QStringLiteral(R"(^\s*//\s*@snippet\s+)")
+ const QString pattern = R"(^\s*//\s*@snippet\s+)"_L1
+ QRegularExpression::escape(snippetLabel)
- + QStringLiteral(R"(\s*$)");
+ + R"(\s*$)"_L1;
const QRegularExpression snippetRe(pattern);
Q_ASSERT(snippetRe.isValid());
@@ -176,7 +186,7 @@ std::optional<QString>
QString result;
const auto lines = QStringView{code}.split(u'\n');
for (const auto &line : lines) {
- if (snippetRe.match(line).hasMatch()) {
+ if (snippetRe.matchView(line).hasMatch()) {
foundLabel = true;
useLine = !useLine;
if (!useLine)
@@ -189,48 +199,31 @@ std::optional<QString>
return CodeSnipAbstract::fixSpaces(result);
}
-template <class EnumType, Qt::CaseSensitivity cs = Qt::CaseInsensitive>
+template <class EnumType>
struct EnumLookup
{
QStringView name;
EnumType value;
};
-template <class EnumType, Qt::CaseSensitivity cs>
-bool operator==(const EnumLookup<EnumType, cs> &e1, const EnumLookup<EnumType, cs> &e2)
-{
- return e1.name.compare(e2.name, cs) == 0;
-}
-
-template <class EnumType, Qt::CaseSensitivity cs>
-bool operator<(const EnumLookup<EnumType, cs> &e1, const EnumLookup<EnumType, cs> &e2)
-{
- return e1.name.compare(e2.name, cs) < 0;
-}
-
// Helper macros to define lookup functions that take a QStringView needle
// and an optional default return value.
#define ENUM_LOOKUP_BEGIN(EnumType, caseSensitivity, functionName) \
static std::optional<EnumType> functionName(QStringView needle) \
{ \
- using HaystackEntry = EnumLookup<EnumType, caseSensitivity>; \
- static const HaystackEntry haystack[] =
-
-#define ENUM_LOOKUP_LINEAR_SEARCH() \
- const auto end = haystack + sizeof(haystack) / sizeof(haystack[0]); \
- const auto it = std::find(haystack, end, HaystackEntry{needle, {} }); \
+ using HaystackEntry = EnumLookup<EnumType>; \
+ constexpr auto cs = caseSensitivity; \
+ static constexpr HaystackEntry haystack[] =
+
+#define ENUM_LOOKUP_LINEAR_SEARCH \
+ auto pred = [cs, needle](const HaystackEntry &he) { \
+ return he.name.compare(needle, cs) == 0; \
+ }; \
+ auto end = std::cend(haystack); \
+ auto it = std::find_if(std::cbegin(haystack), end, pred); \
if (it != end) \
return it->value; \
- return {}; \
-}
-
-#define ENUM_LOOKUP_BINARY_SEARCH() \
- const auto end = haystack + sizeof(haystack) / sizeof(haystack[0]); \
- const HaystackEntry needleEntry{needle, {} }; \
- const auto lb = std::lower_bound(haystack, end, needleEntry); \
- if (lb != end && *lb == needleEntry) \
- return lb->value; \
- return {}; \
+ return std::nullopt; \
}
ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive,
@@ -242,7 +235,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive,
{u"no", TypeSystem::AllowThread::Disallow},
{u"false", TypeSystem::AllowThread::Disallow},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::BoolCast, Qt::CaseInsensitive,
@@ -253,7 +246,17 @@ ENUM_LOOKUP_BEGIN(TypeSystem::BoolCast, Qt::CaseInsensitive,
{u"no", TypeSystem::BoolCast::Disabled},
{u"false", TypeSystem::BoolCast::Disabled},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
+
+ENUM_LOOKUP_BEGIN(TypeSystem::PythonEnumType, Qt::CaseSensitive,
+ pythonEnumTypeFromAttribute)
+ {
+ {u"Enum", TypeSystem::PythonEnumType::Enum},
+ {u"IntEnum", TypeSystem::PythonEnumType::IntEnum},
+ {u"Flag", TypeSystem::PythonEnumType::Flag},
+ {u"IntFlag", TypeSystem::PythonEnumType::IntFlag},
+ };
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::QtMetaTypeRegistration, Qt::CaseSensitive,
qtMetaTypeFromAttribute)
@@ -264,7 +267,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::QtMetaTypeRegistration, Qt::CaseSensitive,
{u"no", TypeSystem::QtMetaTypeRegistration::Disabled},
{u"false", TypeSystem::QtMetaTypeRegistration::Disabled},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
languageFromAttribute)
@@ -274,7 +277,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
{u"shell", TypeSystem::ShellCode}, // coloca no header, mas antes da declaracao da classe
{u"target", TypeSystem::TargetLangCode} // em algum lugar do cpp
};
-ENUM_LOOKUP_BINARY_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::Ownership, Qt::CaseInsensitive,
ownershipFromFromAttribute)
@@ -283,7 +286,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::Ownership, Qt::CaseInsensitive,
{u"c++", TypeSystem::CppOwnership},
{u"default", TypeSystem::DefaultOwnership}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(AddedFunction::Access, Qt::CaseInsensitive,
addedFunctionAccessFromAttribute)
@@ -291,7 +294,7 @@ ENUM_LOOKUP_BEGIN(AddedFunction::Access, Qt::CaseInsensitive,
{u"public", AddedFunction::Public},
{u"protected", AddedFunction::Protected},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(FunctionModification::ModifierFlag, Qt::CaseSensitive,
modifierFromAttribute)
@@ -299,12 +302,11 @@ ENUM_LOOKUP_BEGIN(FunctionModification::ModifierFlag, Qt::CaseSensitive,
{u"private", FunctionModification::Private},
{u"public", FunctionModification::Public},
{u"protected", FunctionModification::Protected},
- {u"friendly", FunctionModification::Friendly},
{u"rename", FunctionModification::Rename},
{u"final", FunctionModification::Final},
{u"non-final", FunctionModification::NonFinal}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(ReferenceCount::Action, Qt::CaseInsensitive,
referenceCountFromAttribute)
@@ -315,7 +317,7 @@ ENUM_LOOKUP_BEGIN(ReferenceCount::Action, Qt::CaseInsensitive,
{u"set", ReferenceCount::Set},
{u"ignore", ReferenceCount::Ignore}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(ArgumentOwner::Action, Qt::CaseInsensitive,
argumentOwnerActionFromAttribute)
@@ -323,16 +325,17 @@ ENUM_LOOKUP_BEGIN(ArgumentOwner::Action, Qt::CaseInsensitive,
{u"add", ArgumentOwner::Add},
{u"remove", ArgumentOwner::Remove}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::CodeSnipPosition, Qt::CaseInsensitive,
codeSnipPositionFromAttribute)
{
{u"beginning", TypeSystem::CodeSnipPositionBeginning},
{u"end", TypeSystem::CodeSnipPositionEnd},
- {u"declaration", TypeSystem::CodeSnipPositionDeclaration}
+ {u"declaration", TypeSystem::CodeSnipPositionDeclaration},
+ {u"override", TypeSystem::CodeSnipPositionPyOverride}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(Include::IncludeType, Qt::CaseInsensitive,
locationFromAttribute)
@@ -341,7 +344,7 @@ ENUM_LOOKUP_BEGIN(Include::IncludeType, Qt::CaseInsensitive,
{u"local", Include::LocalPath},
{u"target", Include::TargetLangImport}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
docModificationFromAttribute)
@@ -350,7 +353,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
{u"prepend", TypeSystem::DocModificationPrepend},
{u"replace", TypeSystem::DocModificationReplace}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(ContainerTypeEntry::ContainerKind, Qt::CaseSensitive,
containerTypeFromAttribute)
@@ -366,9 +369,10 @@ ENUM_LOOKUP_BEGIN(ContainerTypeEntry::ContainerKind, Qt::CaseSensitive,
{u"multi-map", ContainerTypeEntry::MultiMapContainer},
{u"hash", ContainerTypeEntry::MapContainer},
{u"multi-hash", ContainerTypeEntry::MultiMapContainer},
- {u"pair", ContainerTypeEntry::PairContainer}
+ {u"pair", ContainerTypeEntry::PairContainer},
+ {u"span", ContainerTypeEntry::SpanContainer}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeRejection::MatchType, Qt::CaseSensitive,
typeRejectionFromAttribute)
@@ -380,7 +384,7 @@ ENUM_LOOKUP_BEGIN(TypeRejection::MatchType, Qt::CaseSensitive,
{u"argument-type", TypeRejection::ArgumentType},
{u"return-type", TypeRejection::ReturnType}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive,
exceptionHandlingFromAttribute)
@@ -392,7 +396,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive,
{u"yes", TypeSystem::ExceptionHandling::On},
{u"true", TypeSystem::ExceptionHandling::On},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::SmartPointerType, Qt::CaseSensitive,
smartPointerTypeFromAttribute)
@@ -402,7 +406,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::SmartPointerType, Qt::CaseSensitive,
{u"value-handle", TypeSystem::SmartPointerType::ValueHandle},
{u"shared", TypeSystem::SmartPointerType::Shared}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
template <class EnumType>
static std::optional<EnumType>
@@ -431,6 +435,7 @@ static const StackElementHash &stackElementHash()
{u"add-function", StackElement::AddFunction},
{u"add-pymethoddef", StackElement::AddPyMethodDef},
{u"array", StackElement::Array},
+ {u"configuration", StackElement::Configuration},
{u"container-type", StackElement::ContainerTypeEntry},
{u"conversion-rule", StackElement::ConversionRule},
{u"custom-constructor", StackElement::Unimplemented},
@@ -456,6 +461,7 @@ static const StackElementHash &stackElementHash()
{u"native-to-target", StackElement::NativeToTarget},
{u"no-null-pointer", StackElement::NoNullPointers},
{u"object-type", StackElement::ObjectTypeEntry},
+ {u"opaque-container", StackElement::OpaqueContainer},
{u"parent", StackElement::ParentOwner},
{u"primitive-type", StackElement::PrimitiveTypeEntry},
{u"property", StackElement::Property},
@@ -511,7 +517,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::SnakeCase, Qt::CaseSensitive,
{u"true", TypeSystem::SnakeCase::Enabled},
{u"both", TypeSystem::SnakeCase::Both},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::Visibility, Qt::CaseSensitive,
visibilityFromAttribute)
@@ -522,12 +528,12 @@ ENUM_LOOKUP_BEGIN(TypeSystem::Visibility, Qt::CaseSensitive,
{u"yes", TypeSystem::Visibility::Visible},
{u"true", TypeSystem::Visibility::Visible},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
static int indexOfAttribute(const QXmlStreamAttributes &atts,
- QStringView name)
+ QAnyStringView name)
{
- for (int i = 0, size = atts.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = atts.size(); i < size; ++i) {
if (atts.at(i).qualifiedName() == name)
return i;
}
@@ -558,7 +564,7 @@ static QString msgUnusedAttributes(QStringView tag, const QXmlStreamAttributes &
QString result;
QTextStream str(&result);
str << attributes.size() << " attributes(s) unused on <" << tag << ">: ";
- for (int i = 0, size = attributes.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = attributes.size(); i < size; ++i) {
if (i)
str << ", ";
str << attributes.at(i);
@@ -593,17 +599,17 @@ QString TypeSystemEntityResolver::readFile(const QString &entityName, QString *e
path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath);
if (!QFileInfo::exists(path)) {
*errorMessage = u"Unable to resolve: "_s + entityName;
- return QString();
+ return {};
}
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
*errorMessage = msgCannotOpenForReading(file);
- return QString();
+ return {};
}
QString result = QString::fromUtf8(file.readAll()).trimmed();
// Remove license header comments on which QXmlStreamReader chokes
if (result.startsWith(u"<!--")) {
- const int commentEnd = result.indexOf(u"-->");
+ const auto commentEnd = result.indexOf(u"-->");
if (commentEnd != -1) {
result.remove(0, commentEnd + 3);
result = result.trimmed();
@@ -638,7 +644,7 @@ enum class ParserState
Template
};
-TypeSystemParser::TypeSystemParser(const QSharedPointer<TypeDatabaseParserContext> &context,
+TypeSystemParser::TypeSystemParser(const std::shared_ptr<TypeDatabaseParserContext> &context,
bool generate) :
m_context(context),
m_generate(generate ? TypeEntry::GenerateCode : TypeEntry::GenerateForSubclass)
@@ -681,7 +687,7 @@ static QString msgReaderError(const ConditionalStreamReader &reader, const QStri
}
static QString msgUnimplementedElementWarning(const ConditionalStreamReader &reader,
- QStringView name)
+ QAnyStringView name)
{
QString message;
QTextStream(&message) << "The element \"" << name
@@ -706,7 +712,7 @@ static inline QString msgUnimplementedAttributeWarning(const ConditionalStreamRe
static QString
msgUnimplementedAttributeValueWarning(const ConditionalStreamReader &reader,
- QStringView name, QStringView value)
+ QAnyStringView name, QAnyStringView value)
{
QString message;
QTextStream(&message) << "The value \"" << value
@@ -723,21 +729,22 @@ static inline
attribute.value());
}
-static bool addRejection(TypeDatabase *database, QXmlStreamAttributes *attributes,
+static bool addRejection(TypeDatabase *database, bool generate, QXmlStreamAttributes *attributes,
QString *errorMessage)
{
- const int classIndex = indexOfAttribute(*attributes, classAttribute());
+ const auto classIndex = indexOfAttribute(*attributes, classAttribute);
if (classIndex == -1) {
- *errorMessage = msgMissingAttribute(classAttribute());
+ *errorMessage = msgMissingAttribute(classAttribute);
return false;
}
TypeRejection rejection;
+ rejection.generate = generate;
const QString className = attributes->takeAt(classIndex).value().toString();
if (!setRejectionRegularExpression(className, &rejection.className, errorMessage))
return false;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto &attribute = attributes->at(i);
const auto name = attribute.qualifiedName();
const auto typeOpt = typeRejectionFromAttribute(name);
@@ -864,13 +871,14 @@ bool TypeSystemParser::endElement(StackElement element)
if (m_generate == TypeEntry::GenerateCode) {
TypeDatabase::instance()->addGlobalUserFunctions(top->addedFunctions);
TypeDatabase::instance()->addGlobalUserFunctionModifications(top->functionMods);
- for (CustomConversion *customConversion : qAsConst(customConversionsForReview)) {
- const CustomConversion::TargetToNativeConversions &toNatives = customConversion->targetToNativeConversions();
- for (CustomConversion::TargetToNativeConversion *toNative : toNatives)
- toNative->setSourceType(m_context->db->findType(toNative->sourceTypeName()));
+ for (const auto &customConversion : std::as_const(customConversionsForReview)) {
+ TargetToNativeConversions &toNatives =
+ customConversion->targetToNativeConversions();
+ for (auto &toNative : toNatives)
+ toNative.setSourceType(m_context->db->findType(toNative.sourceTypeName()));
}
}
- purgeEmptyCodeSnips(&top->entry->codeSnips());
+ purgeEmptyCodeSnips(&std::static_pointer_cast<TypeSystemTypeEntry>(top->entry)->codeSnips());
break;
case StackElement::FunctionTypeEntry:
TypeDatabase::instance()->addGlobalUserFunctionModifications(top->functionMods);
@@ -882,7 +890,7 @@ bool TypeSystemParser::endElement(StackElement element)
case StackElement::NamespaceTypeEntry: {
Q_ASSERT(top->entry);
Q_ASSERT(top->entry->isComplex());
- auto *centry = static_cast<ComplexTypeEntry *>(top->entry);
+ auto centry = std::static_pointer_cast<ComplexTypeEntry>(top->entry);
purgeEmptyCodeSnips(&centry->codeSnips());
centry->setAddedFunctions(top->addedFunctions);
centry->setFunctionModifications(top->functionMods);
@@ -892,12 +900,15 @@ bool TypeSystemParser::endElement(StackElement element)
break;
case StackElement::TypedefTypeEntry: {
- auto *centry = static_cast<TypedefEntry *>(top->entry)->target();
+ auto centry = std::static_pointer_cast<TypedefEntry>(top->entry)->target();
centry->setAddedFunctions(centry->addedFunctions() + top->addedFunctions);
centry->setFunctionModifications(centry->functionModifications() + top->functionMods);
centry->setFieldModifications(centry->fieldModifications() + top->fieldMods);
- centry->setCodeSnips(centry->codeSnips() + top->entry->codeSnips());
centry->setDocModification(centry->docModifications() + top->docModifications);
+ if (top->entry->isComplex()) {
+ auto cte = std::static_pointer_cast<const ComplexTypeEntry>(top->entry);
+ centry->setCodeSnips(centry->codeSnips() + cte->codeSnips());
+ }
}
break;
@@ -909,29 +920,30 @@ bool TypeSystemParser::endElement(StackElement element)
Q_ASSERT(modIndex >= 0);
Q_ASSERT(!top->addedFunctions.isEmpty());
while (modIndex < top->functionMods.size())
- top->addedFunctions.last()->modifications.append(top->functionMods.takeAt(modIndex));
+ top->addedFunctions.last()->modifications().append(top->functionMods.takeAt(modIndex));
}
break;
case StackElement::NativeToTarget:
case StackElement::AddConversion:
switch (parserState()) {
case ParserState::PrimitiveTypeNativeToTargetConversion:
- case ParserState::PrimitiveTypeTargetToNativeConversion:
- if (auto *customConversion = top->entry->customConversion()) {
- QString code = top->conversionCodeSnips.constLast().code();
- if (element == StackElement::AddConversion) {
- if (customConversion->targetToNativeConversions().isEmpty()) {
- m_error = u"CustomConversion's target to native conversions missing."_s;
- return false;
- }
- customConversion->targetToNativeConversions().last()->setConversion(code);
- } else {
- customConversion->setNativeToTargetConversion(code);
+ case ParserState::PrimitiveTypeTargetToNativeConversion: {
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (!customConversion) {
+ m_error = msgMissingCustomConversion(top->entry);
+ return false;
+ }
+ QString code = top->conversionCodeSnips.constLast().code();
+ if (element == StackElement::AddConversion) {
+ if (customConversion->targetToNativeConversions().isEmpty()) {
+ m_error = u"CustomConversion's target to native conversions missing."_s;
+ return false;
}
+ customConversion->targetToNativeConversions().last().setConversion(code);
} else {
- m_error = u"CustomConversion object is missing."_s;
- return false;
+ customConversion->setNativeToTargetConversion(code);
}
+ }
break;
case ParserState::ArgumentNativeToTargetConversion: {
@@ -953,8 +965,6 @@ bool TypeSystemParser::endElement(StackElement element)
break;
case StackElement::EnumTypeEntry:
- top->entry->setDocModification(top->docModifications);
- top->docModifications = DocModificationList();
m_currentEnum = nullptr;
break;
case StackElement::Template:
@@ -1055,10 +1065,13 @@ CodeSnipAbstract *TypeSystemParser::injectCodeTarget(qsizetype offset) const
return &funcMod.snips().last();
}
case ParserState::TypeEntryCodeInjection:
+ Q_ASSERT(top->entry->isComplex());
+ return &std::static_pointer_cast<ComplexTypeEntry>(top->entry)->codeSnips().last();
case ParserState::TypeSystemCodeInjection:
- return &top->entry->codeSnips().last();
+ Q_ASSERT(top->entry->isTypeSystem());
+ return &std::static_pointer_cast<TypeSystemTypeEntry>(top->entry)->codeSnips().last();
case ParserState::Template:
- return m_templateEntry;
+ return m_templateEntry.get();
default:
break;
}
@@ -1092,15 +1105,22 @@ bool TypeSystemParser::characters(const String &ch)
return true;
}
- if (isDocumentation(type))
- m_contextStack.top()->docModifications.last().setCode(ch);
+ if (isDocumentation(type)) {
+ const bool isAddedFunction = m_stack.value(m_stack.size() - 2, StackElement::None)
+ == StackElement::AddFunction;
+ const auto &top = m_contextStack.top();
+ auto &docModifications = isAddedFunction
+ ? top->addedFunctions.last()->docModifications()
+ : top->docModifications;
+ docModifications.last().setCode(ch);
+ }
return true;
}
bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
{
- const QString fileName = atts.value(nameAttribute()).toString();
+ const QString fileName = atts.value(nameAttribute).toString();
if (fileName.isEmpty()) {
m_error = u"Required attribute 'name' missing for include-file tag."_s;
return false;
@@ -1115,11 +1135,11 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
}
}
- const auto quoteFrom = atts.value(quoteAfterLineAttribute());
+ const auto quoteFrom = atts.value(quoteAfterLineAttribute);
bool foundFromOk = quoteFrom.isEmpty();
bool from = quoteFrom.isEmpty();
- const auto quoteTo = atts.value(quoteBeforeLineAttribute());
+ const auto quoteTo = atts.value(quoteBeforeLineAttribute);
bool foundToOk = quoteTo.isEmpty();
bool to = true;
@@ -1139,10 +1159,10 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
}
}
if (!foundFromOk || !foundToOk) {
- QString fromError = QStringLiteral("Could not find quote-after-line='%1' in file '%2'.")
- .arg(quoteFrom.toString(), fileName);
- QString toError = QStringLiteral("Could not find quote-before-line='%1' in file '%2'.")
- .arg(quoteTo.toString(), fileName);
+ QString fromError = QString::fromLatin1("Could not find quote-after-line='%1' in file '%2'.")
+ .arg(quoteFrom.toString(), fileName);
+ QString toError = QString::fromLatin1("Could not find quote-before-line='%1' in file '%2'.")
+ .arg(quoteTo.toString(), fileName);
if (!foundToOk)
m_error = toError;
@@ -1156,29 +1176,27 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
return true;
}
-static bool convertBoolean(QStringView value, const QString &attributeName, bool defaultValue)
+static bool convertBoolean(QStringView value, QAnyStringView attributeName, bool defaultValue)
{
- if (value.compare(trueAttributeValue(), Qt::CaseInsensitive) == 0
- || value.compare(yesAttributeValue(), Qt::CaseInsensitive) == 0) {
+ if (value.compare(trueAttributeValue, Qt::CaseInsensitive) == 0
+ || value.compare(yesAttributeValue, Qt::CaseInsensitive) == 0) {
return true;
}
- if (value.compare(falseAttributeValue(), Qt::CaseInsensitive) == 0
- || value.compare(noAttributeValue(), Qt::CaseInsensitive) == 0) {
+ if (value.compare(falseAttributeValue, Qt::CaseInsensitive) == 0
+ || value.compare(noAttributeValue, Qt::CaseInsensitive) == 0) {
return false;
}
- const QString warn = QStringLiteral("Boolean value '%1' not supported in attribute '%2'. Use 'yes' or 'no'. Defaulting to '%3'.")
- .arg(value)
- .arg(attributeName,
- defaultValue ? yesAttributeValue() : noAttributeValue());
-
- qCWarning(lcShiboken).noquote().nospace() << warn;
+ qCWarning(lcShiboken).noquote().nospace() << "Boolean value '" << value
+ << "' not supported in attribute '" << attributeName
+ << "'. Use 'yes' or 'no'. Defaulting to '"
+ << (defaultValue ? yesAttributeValue : noAttributeValue) << "'.";
return defaultValue;
}
static bool convertRemovalAttribute(QStringView value)
{
return value == u"all" // Legacy
- || convertBoolean(value, removeAttribute(), false);
+ || convertBoolean(value, removeAttribute, false);
}
// Check whether an entry should be dropped, allowing for dropping the module
@@ -1188,7 +1206,7 @@ static bool shouldDropTypeEntry(const TypeDatabase *db,
QString name)
{
for (auto i = stack.size() - 1; i >= 0; --i) {
- if (auto *entry = stack.at(i)->entry) {
+ if (auto entry = stack.at(i)->entry) {
if (entry->type() == TypeEntry::TypeSystemType) {
if (db->shouldDropTypeEntry(name)) // Unqualified
return true;
@@ -1204,7 +1222,7 @@ static bool shouldDropTypeEntry(const TypeDatabase *db,
static QString checkSignatureError(const QString& signature, const QString& tag)
{
QString funcName = signature.left(signature.indexOf(u'(')).trimmed();
- static const QRegularExpression whiteSpace(QStringLiteral("\\s"));
+ static const QRegularExpression whiteSpace("\\s"_L1);
Q_ASSERT(whiteSpace.isValid());
if (!funcName.startsWith(u"operator ") && funcName.contains(whiteSpace)) {
return QString::fromLatin1("Error in <%1> tag signature attribute '%2'.\n"
@@ -1215,7 +1233,7 @@ static QString checkSignatureError(const QString& signature, const QString& tag)
return QString();
}
-inline const TypeEntry *TypeSystemParser::currentParentTypeEntry() const
+inline TypeEntryCPtr TypeSystemParser::currentParentTypeEntry() const
{
const auto size = m_contextStack.size();
return size > 1 ? m_contextStack.at(size - 2)->entry : nullptr;
@@ -1224,7 +1242,7 @@ inline const TypeEntry *TypeSystemParser::currentParentTypeEntry() const
bool TypeSystemParser::checkRootElement()
{
for (auto i = m_contextStack.size() - 1; i >= 0; --i) {
- auto *e = m_contextStack.at(i)->entry;
+ auto e = m_contextStack.at(i)->entry;
if (e && e->isTypeSystem())
return true;
}
@@ -1232,7 +1250,7 @@ bool TypeSystemParser::checkRootElement()
return false;
}
-static TypeEntry *findViewedType(const QString &name)
+static TypeEntryPtr findViewedType(const QString &name)
{
const auto range = TypeDatabase::instance()->entries().equal_range(name);
for (auto i = range.first; i != range.second; ++i) {
@@ -1249,20 +1267,21 @@ static TypeEntry *findViewedType(const QString &name)
return nullptr;
}
-bool TypeSystemParser::applyCommonAttributes(const ConditionalStreamReader &reader, TypeEntry *type,
+bool TypeSystemParser::applyCommonAttributes(const ConditionalStreamReader &reader,
+ const TypeEntryPtr &type,
QXmlStreamAttributes *attributes)
{
type->setSourceLocation(SourceLocation(m_currentFile,
reader.lineNumber()));
type->setCodeGeneration(m_generate);
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == u"revision") {
type->setRevision(attributes->takeAt(i).value().toInt());
} else if (name == u"view-on") {
const QString name = attributes->takeAt(i).value().toString();
- TypeEntry *views = findViewedType(name);
- if (views == nullptr) {
+ TypeEntryPtr views = findViewedType(name);
+ if (!views) {
m_error = msgCannotFindView(name, type->name());
return false;
}
@@ -1272,55 +1291,55 @@ bool TypeSystemParser::applyCommonAttributes(const ConditionalStreamReader &read
return true;
}
-CustomTypeEntry *TypeSystemParser::parseCustomTypeEntry(const ConditionalStreamReader &,
+CustomTypeEntryPtr TypeSystemParser::parseCustomTypeEntry(const ConditionalStreamReader &,
const QString &name,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto *result = new CustomTypeEntry(name, since, m_contextStack.top()->entry);
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ auto result = std::make_shared<CustomTypeEntry>(name, since, m_contextStack.top()->entry);
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == checkFunctionAttribute())
+ if (name == checkFunctionAttribute)
result->setCheckFunction(attributes->takeAt(i).value().toString());
}
return result;
}
-FlagsTypeEntry *
+FlagsTypeEntryPtr
TypeSystemParser::parseFlagsEntry(const ConditionalStreamReader &reader,
- EnumTypeEntry *enumEntry, QString flagName,
+ const EnumTypeEntryPtr &enumEntry, QString flagName,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto ftype = new FlagsTypeEntry(u"QFlags<"_s + enumEntry->name() + u'>',
- since,
- currentParentTypeEntry()->typeSystemTypeEntry());
+ auto ftype = std::make_shared<FlagsTypeEntry>(u"QFlags<"_s + enumEntry->name() + u'>',
+ since,
+ typeSystemTypeEntry(currentParentTypeEntry()));
ftype->setOriginator(enumEntry);
ftype->setTargetLangPackage(enumEntry->targetLangPackage());
// Try toenumEntry get the guess the qualified flag name
- if (!flagName.contains(colonColon())) {
+ if (!flagName.contains(u"::"_s)) {
auto eq = enumEntry->qualifier();
if (!eq.isEmpty())
- flagName.prepend(eq + colonColon());
+ flagName.prepend(eq + u"::"_s);
}
ftype->setOriginalName(flagName);
if (!applyCommonAttributes(reader, ftype, attributes))
return nullptr;
- QStringList lst = flagName.split(colonColon());
+ QStringList lst = flagName.split(u"::"_s);
const QString name = lst.takeLast();
const QString targetLangFlagName = lst.join(u'.');
const QString &targetLangQualifier = enumEntry->targetLangQualifier();
if (targetLangFlagName != targetLangQualifier) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("enum %1 and flags %2 (%3) differ in qualifiers")
- .arg(targetLangQualifier, lst.value(0), targetLangFlagName);
+ qCWarning(lcShiboken, "enum %s and flags %s (%s) differ in qualifiers",
+ qPrintable(targetLangQualifier), qPrintable(lst.value(0)),
+ qPrintable(targetLangFlagName));
}
ftype->setFlagsName(name);
@@ -1337,7 +1356,7 @@ FlagsTypeEntry *
return ftype;
}
-SmartPointerTypeEntry *
+SmartPointerTypeEntryPtr
TypeSystemParser::parseSmartPointerEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
@@ -1351,7 +1370,7 @@ SmartPointerTypeEntry *
QString nullCheckMethod;
QString resetMethod;
QString instantiations;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == u"type") {
const auto attribute = attributes->takeAt(i);
@@ -1400,8 +1419,9 @@ SmartPointerTypeEntry *
return nullptr;
}
- auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType,
- refCountMethodName, since, currentParentTypeEntry());
+ auto type = std::make_shared<SmartPointerTypeEntry>(name, getter, smartPointerType,
+ refCountMethodName, since,
+ currentParentTypeEntry());
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
applyComplexTypeAttributes(reader, type, attributes);
@@ -1412,29 +1432,29 @@ SmartPointerTypeEntry *
return type;
}
-PrimitiveTypeEntry *
+PrimitiveTypeEntryPtr
TypeSystemParser::parsePrimitiveTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto *type = new PrimitiveTypeEntry(name, since, currentParentTypeEntry());
+ auto type = std::make_shared<PrimitiveTypeEntry>(name, since, currentParentTypeEntry());
QString targetLangApiName;
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == targetLangNameAttribute()) {
+ if (name == targetLangNameAttribute) {
type->setTargetLangName(attributes->takeAt(i).value().toString());
} else if (name == u"target-lang-api-name") {
targetLangApiName = attributes->takeAt(i).value().toString();
- } else if (name == preferredConversionAttribute()) {
+ } else if (name == preferredConversionAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == preferredTargetLangTypeAttribute()) {
+ } else if (name == preferredTargetLangTypeAttribute) {
const bool v = convertBoolean(attributes->takeAt(i).value(),
- preferredTargetLangTypeAttribute(), true);
+ preferredTargetLangTypeAttribute, true);
type->setPreferredTargetLangType(v);
} else if (name == u"default-constructor") {
type->setDefaultConstructor(attributes->takeAt(i).value().toString());
@@ -1442,40 +1462,53 @@ PrimitiveTypeEntry *
}
if (!targetLangApiName.isEmpty()) {
- auto *e = m_context->db->findType(targetLangApiName);
- if (e == nullptr || !e->isCustom()) {
+ auto e = m_context->db->findType(targetLangApiName);
+ if (!e || !e->isCustom()) {
m_error = msgInvalidTargetLanguageApiName(targetLangApiName);
return nullptr;
}
- type->setTargetLangApiType(static_cast<CustomTypeEntry *>(e));
+ type->setTargetLangApiType(std::static_pointer_cast<CustomTypeEntry>(e));
}
type->setTargetLangPackage(m_defaultPackage);
return type;
}
// "int:QList_int;QString:QList_QString"
-static bool parseOpaqueContainers(QStringView s, ContainerTypeEntry *cte)
+bool TypeSystemParser::parseOpaqueContainers(QStringView s, OpaqueContainers *result)
{
const auto entries = s.split(u';');
for (const auto &entry : entries) {
const auto values = entry.split(u':');
- if (values.size() != 2)
- return false;
- QString instantiation = values.at(0).trimmed().toString();
- QString name = values.at(1).trimmed().toString();
- cte->addOpaqueContainer({instantiation, name});
+ if (values.size() != 2) {
+ m_error = u"Error parsing the opaque container attribute: \""_s
+ + s.toString() + u"\"."_s;
+ return false;
+ }
+ OpaqueContainer oc;
+ oc.name = values.at(1).trimmed().toString();
+ const auto instantiations = values.at(0).split(u',', Qt::SkipEmptyParts);
+ for (const auto &instantiationV : instantiations) {
+ QString instantiation = instantiationV.trimmed().toString();
+ // Fix to match AbstractMetaType::signature() which is used for matching
+ // "Foo*" -> "Foo *"
+ const auto asteriskPos = instantiation.indexOf(u'*');
+ if (asteriskPos > 0 && !instantiation.at(asteriskPos - 1).isSpace())
+ instantiation.insert(asteriskPos, u' ');
+ oc.instantiations.append(instantiation);
+ }
+ result->append(oc);
}
return true;
}
-ContainerTypeEntry *
+ContainerTypeEntryPtr
TypeSystemParser::parseContainerTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- const int typeIndex = indexOfAttribute(*attributes, u"type");
+ const auto typeIndex = indexOfAttribute(*attributes, u"type");
if (typeIndex == -1) {
m_error = u"no 'type' attribute specified"_s;
return nullptr;
@@ -1487,40 +1520,61 @@ ContainerTypeEntry *
return nullptr;
}
attributes->removeAt(typeIndex);
- auto *type = new ContainerTypeEntry(name, containerTypeOpt.value(),
- since, currentParentTypeEntry());
+ auto type = std::make_shared<ContainerTypeEntry>(name, containerTypeOpt.value(),
+ since, currentParentTypeEntry());
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
applyComplexTypeAttributes(reader, type, attributes);
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == u"opaque-containers") {
+ if (name == opaqueContainerAttribute) {
const auto attribute = attributes->takeAt(i);
- if (!parseOpaqueContainers(attribute.value(), type)) {
- m_error = u"Error parsing the opaque container attribute: \""_s
- + attribute.value().toString() + u"\"."_s;
+ OpaqueContainers oc;
+ if (!parseOpaqueContainers(attribute.value(), &oc))
return nullptr;
- }
+ type->appendOpaqueContainers(oc);
}
}
return type;
}
-EnumTypeEntry *
+bool TypeSystemParser::parseOpaqueContainerElement(QXmlStreamAttributes *attributes)
+{
+ QString containerName;
+ OpaqueContainers oc;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == nameAttribute) {
+ containerName = attributes->takeAt(i).value().toString();
+ } else if (name == opaqueContainerAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ if (!parseOpaqueContainers(attribute.value(), &oc))
+ return false;
+ }
+ }
+ if (containerName.isEmpty()) {
+ m_error = msgMissingAttribute(nameAttribute);
+ return false;
+ }
+ m_context->opaqueContainerHash[containerName].append(oc);
+ return true;
+}
+
+EnumTypeEntryPtr
TypeSystemParser::parseEnumTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto *entry = new EnumTypeEntry(name, since, currentParentTypeEntry());
+ auto entry = std::make_shared<EnumTypeEntry>(name, since, currentParentTypeEntry());
applyCommonAttributes(reader, entry, attributes);
entry->setTargetLangPackage(m_defaultPackage);
QString flagNames;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == u"upper-bound") {
qCWarning(lcShiboken, "%s",
@@ -1528,13 +1582,26 @@ EnumTypeEntry *
} else if (name == u"lower-bound") {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == forceIntegerAttribute()) {
+ } else if (name == docFileAttribute) {
+ entry->setDocFile(attributes->takeAt(i).value().toString());
+ } else if (name == forceIntegerAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == extensibleAttribute()) {
+ } else if (name == pythonEnumTypeAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ const auto typeOpt = pythonEnumTypeFromAttribute(attribute.value());
+ if (typeOpt.has_value()) {
+ entry->setPythonEnumType(typeOpt.value());
+ } else {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ } else if (name == cppEnumTypeAttribute) {
+ entry->setCppType(attributes->takeAt(i).value().toString());
+ } else if (name == extensibleAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == flagsAttribute()) {
+ } else if (name == flagsAttribute) {
flagNames = attributes->takeAt(i).value().toString();
}
}
@@ -1549,17 +1616,17 @@ EnumTypeEntry *
}
-NamespaceTypeEntry *
+NamespaceTypeEntryPtr
TypeSystemParser::parseNamespaceTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- std::unique_ptr<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since, currentParentTypeEntry()));
+ auto result = std::make_shared<NamespaceTypeEntry>(name, since, currentParentTypeEntry());
auto visibility = TypeSystem::Visibility::Unspecified;
- applyCommonAttributes(reader, result.get(), attributes);
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ applyCommonAttributes(reader, result, attributes);
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto attributeName = attributes->at(i).qualifiedName();
if (attributeName == u"files") {
const QString pattern = attributes->takeAt(i).value().toString();
@@ -1573,7 +1640,7 @@ NamespaceTypeEntry *
const auto extendsPackageName = attributes->at(i).value();
auto allEntries = TypeDatabase::instance()->findNamespaceTypes(name);
auto extendsIt = std::find_if(allEntries.cbegin(), allEntries.cend(),
- [extendsPackageName] (const NamespaceTypeEntry *e) {
+ [extendsPackageName] (const NamespaceTypeEntryCPtr &e) {
return e->targetLangPackage() == extendsPackageName;
});
if (extendsIt == allEntries.cend()) {
@@ -1582,7 +1649,7 @@ NamespaceTypeEntry *
}
result->setExtends(*extendsIt);
attributes->removeAt(i);
- } else if (attributeName == visibleAttribute()) {
+ } else if (attributeName == visibleAttribute) {
const auto attribute = attributes->takeAt(i);
const auto visibilityOpt = visibilityFromAttribute(attribute.value());
if (!visibilityOpt.has_value()) {
@@ -1590,35 +1657,36 @@ NamespaceTypeEntry *
return nullptr;
}
visibility = visibilityOpt.value();
- } else if (attributeName == generateAttribute()) {
- if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true))
+ } else if (attributeName == generateAttribute) {
+ if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute, true))
visibility = TypeSystem::Visibility::Invisible;
- } else if (attributeName == generateUsingAttribute()) {
- result->setGenerateUsing(convertBoolean(attributes->takeAt(i).value(), generateUsingAttribute(), true));
+ } else if (attributeName == generateUsingAttribute) {
+ result->setGenerateUsing(convertBoolean(attributes->takeAt(i).value(),
+ generateUsingAttribute, true));
}
}
if (visibility != TypeSystem::Visibility::Unspecified)
result->setVisibility(visibility);
// Handle legacy "generate" before the common handling
- applyComplexTypeAttributes(reader, result.get(), attributes);
+ applyComplexTypeAttributes(reader, result, attributes);
if (result->extends() && !result->hasPattern()) {
m_error = msgExtendingNamespaceRequiresPattern(name);
- return nullptr;
+ return {};
}
- return result.release();
+ return result;
}
-ValueTypeEntry *
+ValueTypeEntryPtr
TypeSystemParser::parseValueTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto *typeEntry = new ValueTypeEntry(name, since, currentParentTypeEntry());
+ auto typeEntry = std::make_shared<ValueTypeEntry>(name, since, currentParentTypeEntry());
if (!applyCommonAttributes(reader, typeEntry, attributes))
return nullptr;
applyComplexTypeAttributes(reader, typeEntry, attributes);
@@ -1629,7 +1697,7 @@ ValueTypeEntry *
return typeEntry;
}
-FunctionTypeEntry *
+FunctionTypeEntryPtr
TypeSystemParser::parseFunctionTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
@@ -1637,50 +1705,56 @@ FunctionTypeEntry *
if (!checkRootElement())
return nullptr;
- QString signature;
- TypeSystem::SnakeCase snakeCase = TypeSystem::SnakeCase::Disabled;
+ FunctionModification mod;
+ const auto oldAttributesSize = attributes->size();
+ if (!parseModifyFunctionAttributes(attributes, &mod))
+ return nullptr;
+ const bool hasModification = attributes->size() < oldAttributesSize;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ QString originalSignature;
+ QString docFile;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == signatureAttribute()) {
- signature = TypeDatabase::normalizedSignature(attributes->takeAt(i).value().toString());
- } else if (name == snakeCaseAttribute()) {
- const auto attribute = attributes->takeAt(i);
- const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
- if (!snakeCaseOpt.has_value()) {
- m_error = msgInvalidAttributeValue(attribute);
- return nullptr;
- }
- snakeCase = snakeCaseOpt.value();
- }
+ if (name == signatureAttribute)
+ originalSignature = attributes->takeAt(i).value().toString().simplified();
+ else if (name == docFileAttribute)
+ docFile = attributes->takeAt(i).value().toString();
}
+ const QString signature = TypeDatabase::normalizedSignature(originalSignature);
if (signature.isEmpty()) {
- m_error = msgMissingAttribute(signatureAttribute());
+ m_error = msgMissingAttribute(signatureAttribute);
return nullptr;
}
- TypeEntry *existingType = m_context->db->findType(name);
+ if (hasModification) {
+ mod.setOriginalSignature(originalSignature);
+ mod.setSignature(signature);
+ m_contextStack.top()->functionMods << mod;
+ }
+
+ TypeEntryPtr existingType = m_context->db->findType(name);
if (!existingType) {
- auto *result = new FunctionTypeEntry(name, signature, since, currentParentTypeEntry());
- result->setSnakeCase(snakeCase);
+ auto result = std::make_shared<FunctionTypeEntry>(name, signature, since,
+ currentParentTypeEntry());
+ result->setTargetLangPackage(m_defaultPackage);
+ result->setDocFile(docFile);
applyCommonAttributes(reader, result, attributes);
return result;
}
if (existingType->type() != TypeEntry::FunctionType) {
- m_error = QStringLiteral("%1 expected to be a function, but isn't! Maybe it was already declared as a class or something else.")
- .arg(name);
+ m_error = name + " expected to be a function, but isn't! Maybe it was already declared as a class or something else."_L1;
return nullptr;
}
- auto *result = reinterpret_cast<FunctionTypeEntry *>(existingType);
+ auto result = std::static_pointer_cast<FunctionTypeEntry>(existingType);
result->addSignature(signature);
return result;
}
-TypedefEntry *
+TypedefEntryPtr
TypeSystemParser::parseTypedefEntry(const ConditionalStreamReader &reader,
const QString &name, StackElement topElement,
const QVersionNumber &since,
@@ -1693,13 +1767,14 @@ TypedefEntry *
m_error = u"typedef entries must be nested in namespaces or type system."_s;
return nullptr;
}
- const int sourceIndex = indexOfAttribute(*attributes, sourceAttribute());
+ const auto sourceIndex = indexOfAttribute(*attributes, sourceAttribute);
if (sourceIndex == -1) {
- m_error = msgMissingAttribute(sourceAttribute());
+ m_error = msgMissingAttribute(sourceAttribute);
return nullptr;
}
const QString sourceType = attributes->takeAt(sourceIndex).value().toString();
- auto result = new TypedefEntry(name, sourceType, since, currentParentTypeEntry());
+ auto result = std::make_shared<TypedefEntry>(name, sourceType, since,
+ currentParentTypeEntry());
if (!applyCommonAttributes(reader, result, attributes))
return nullptr;
applyComplexTypeAttributes(reader, result, attributes);
@@ -1707,7 +1782,7 @@ TypedefEntry *
}
void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader &reader,
- ComplexTypeEntry *ctype,
+ const ComplexTypeEntryPtr &ctype,
QXmlStreamAttributes *attributes) const
{
bool generate = true;
@@ -1716,36 +1791,40 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
auto allowThread = m_allowThread;
QString package = m_defaultPackage;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == streamAttribute()) {
- ctype->setStream(convertBoolean(attributes->takeAt(i).value(), streamAttribute(), false));
- } else if (name == privateAttribute()) {
+ if (name == streamAttribute) {
+ ctype->setStream(convertBoolean(attributes->takeAt(i).value(), streamAttribute, false));
+ } else if (name == privateAttribute) {
ctype->setPrivate(convertBoolean(attributes->takeAt(i).value(),
- privateAttribute(), false));
- } else if (name == generateAttribute()) {
- generate = convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true);
- } else if (name ==packageAttribute()) {
+ privateAttribute, false));
+ } else if (name == generateAttribute) {
+ generate = convertBoolean(attributes->takeAt(i).value(), generateAttribute, true);
+ } else if (name ==packageAttribute) {
package = attributes->takeAt(i).value().toString();
- } else if (name == defaultSuperclassAttribute()) {
+ } else if (name == defaultSuperclassAttribute) {
ctype->setDefaultSuperclass(attributes->takeAt(i).value().toString());
- } else if (name == genericClassAttribute()) {
+ } else if (name == genericClassAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- const bool v = convertBoolean(attributes->takeAt(i).value(), genericClassAttribute(), false);
+ const bool v = convertBoolean(attributes->takeAt(i).value(),
+ genericClassAttribute, false);
ctype->setGenericClass(v);
- } else if (name == targetLangNameAttribute()) {
+ } else if (name == targetLangNameAttribute) {
ctype->setTargetLangName(attributes->takeAt(i).value().toString());
- } else if (name == u"polymorphic-base") {
- ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
+ } else if (name == polymorphicBaseAttribute) {
+ const bool v = convertBoolean(attributes->takeAt(i).value(),
+ polymorphicBaseAttribute, false);
+ ctype->setIsPolymorphicBase(v);
} else if (name == u"polymorphic-name-function") {
ctype->setPolymorphicNameFunction(attributes->takeAt(i).value().toString());
} else if (name == u"polymorphic-id-expression") {
ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
- } else if (name == copyableAttribute()) {
- const bool v = convertBoolean(attributes->takeAt(i).value(), copyableAttribute(), false);
+ } else if (name == copyableAttribute) {
+ const bool v = convertBoolean(attributes->takeAt(i).value(),
+ copyableAttribute, false);
ctype->setCopyable(v ? ComplexTypeEntry::CopyableSet : ComplexTypeEntry::NonCopyableSet);
- } else if (name == exceptionHandlingAttribute()) {
+ } else if (name == exceptionHandlingAttribute) {
const auto attribute = attributes->takeAt(i);
const auto exceptionOpt = exceptionHandlingFromAttribute(attribute.value());
if (exceptionOpt.has_value()) {
@@ -1754,7 +1833,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == allowThreadAttribute()) {
+ } else if (name == allowThreadAttribute) {
const auto attribute = attributes->takeAt(i);
const auto allowThreadOpt = allowThreadFromAttribute(attribute.value());
if (allowThreadOpt.has_value()) {
@@ -1768,19 +1847,25 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
} else if (name == u"hash-function") {
ctype->setHashFunction(attributes->takeAt(i).value().toString());
- } else if (name == forceAbstractAttribute()) {
- if (convertBoolean(attributes->takeAt(i).value(), forceAbstractAttribute(), false))
+ } else if (name == forceAbstractAttribute) {
+ if (convertBoolean(attributes->takeAt(i).value(), forceAbstractAttribute, false))
ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::ForceAbstract);
- } else if (name == deprecatedAttribute()) {
- if (convertBoolean(attributes->takeAt(i).value(), deprecatedAttribute(), false))
+ } else if (name == deprecatedAttribute) {
+ if (convertBoolean(attributes->takeAt(i).value(), deprecatedAttribute, false))
ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::Deprecated);
- } else if (name == disableWrapperAttribute()) {
- if (convertBoolean(attributes->takeAt(i).value(), disableWrapperAttribute(), false))
+ } else if (name == disableWrapperAttribute) {
+ if (convertBoolean(attributes->takeAt(i).value(), disableWrapperAttribute, false))
ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::DisableWrapper);
- } else if (name == deleteInMainThreadAttribute()) {
- if (convertBoolean(attributes->takeAt(i).value(), deleteInMainThreadAttribute(), false))
+ } else if (name == deleteInMainThreadAttribute) {
+ if (convertBoolean(attributes->takeAt(i).value(), deleteInMainThreadAttribute, false))
ctype->setDeleteInMainThread(true);
- } else if (name == generateFunctionsAttribute()) {
+ } else if (name == qtMetaObjectFunctionsAttribute) {
+ if (!convertBoolean(attributes->takeAt(i).value(),
+ qtMetaObjectFunctionsAttribute, true)) {
+ ctype->setTypeFlags(ctype->typeFlags()
+ | ComplexTypeEntry::DisableQtMetaObjectFunctions);
+ }
+ } else if (name == generateFunctionsAttribute) {
const auto names = attributes->takeAt(i).value();
const auto nameList = names.split(u';', Qt::SkipEmptyParts);
QSet<QString> nameSet;
@@ -1789,7 +1874,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
ctype->setGenerateFunctions(nameSet);
} else if (name == u"target-type") {
ctype->setTargetType(attributes->takeAt(i).value().toString());
- } else if (name == snakeCaseAttribute()) {
+ } else if (name == snakeCaseAttribute) {
const auto attribute = attributes->takeAt(i);
const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
if (snakeCaseOpt.has_value()) {
@@ -1798,7 +1883,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == isNullAttribute()) {
+ } else if (name == isNullAttribute) {
const auto attribute = attributes->takeAt(i);
const auto boolCastOpt = boolCastFromAttribute(attribute.value());
if (boolCastOpt.has_value()) {
@@ -1807,7 +1892,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == operatorBoolAttribute()) {
+ } else if (name == operatorBoolAttribute) {
const auto attribute = attributes->takeAt(i);
const auto boolCastOpt = boolCastFromAttribute(attribute.value());
if (boolCastOpt.has_value()) {
@@ -1816,7 +1901,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == qtMetaTypeAttribute()) {
+ } else if (name == qtMetaTypeAttribute) {
const auto attribute = attributes->takeAt(i);
const auto qtMetaTypeOpt = qtMetaTypeFromAttribute(attribute.value());
if (qtMetaTypeOpt.has_value()) {
@@ -1825,9 +1910,9 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == parentManagementAttribute()) {
+ } else if (name == parentManagementAttribute) {
const auto attribute = attributes->takeAt(i);
- if (convertBoolean(attribute.value(), parentManagementAttribute(), false))
+ if (convertBoolean(attribute.value(), parentManagementAttribute, false))
ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::ParentManagement);
ComplexTypeEntry::setParentManagementEnabled(true);
}
@@ -1848,23 +1933,49 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
ctype->setCodeGeneration(TypeEntry::GenerationDisabled);
}
+bool TypeSystemParser::parseConfiguration(StackElement topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!isComplexTypeEntry(topElement)
+ && topElement != StackElement::EnumTypeEntry) {
+ m_error = u"<configuration> must be nested into a complex or enum type entry."_s;
+ return false;
+ }
+ QString condition;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == u"condition") {
+ condition = attributes->takeAt(i).value().toString();
+ }
+ }
+ if (condition.isEmpty()) {
+ m_error = u"<configuration> requires a \"condition\" attribute."_s;
+ return false;
+ }
+ const auto topEntry = m_contextStack.top()->entry;
+ const auto configurableEntry = std::dynamic_pointer_cast<ConfigurableTypeEntry>(topEntry);
+ Q_ASSERT(configurableEntry);
+ configurableEntry->setConfigCondition(condition);
+ return true;
+}
+
bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &,
QString *name, QXmlStreamAttributes *attributes)
{
QString signature;
QString rename;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == signatureAttribute()) {
+ if (name == signatureAttribute) {
// Do not remove as it is needed for the type entry later on
- signature = attributes->at(i).value().toString();
- } else if (name == renameAttribute()) {
+ signature = attributes->at(i).value().toString().simplified();
+ } else if (name == renameAttribute) {
rename = attributes->takeAt(i).value().toString();
}
}
if (signature.isEmpty()) {
- m_error = msgMissingAttribute(signatureAttribute());
+ m_error = msgMissingAttribute(signatureAttribute);
return false;
}
@@ -1897,10 +2008,11 @@ bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &,
bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &, StackElement topElement,
QXmlStreamAttributes *attributes)
{
+ const bool isAddFunction = topElement == StackElement::AddFunction;
const bool validParent = isTypeEntry(topElement)
|| topElement == StackElement::ModifyFunction
|| topElement == StackElement::ModifyField
- || topElement == StackElement::AddFunction;
+ || isAddFunction;
if (!validParent) {
m_error = u"inject-documentation must be inside modify-function, add-function"
"modify-field or other tags that creates a type"_s;
@@ -1909,7 +2021,7 @@ bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &,
TypeSystem::DocModificationMode mode = TypeSystem::DocModificationReplace;
TypeSystem::Language lang = TypeSystem::NativeCode;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == u"mode") {
const auto attribute = attributes->takeAt(i);
@@ -1919,7 +2031,7 @@ bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &,
return false;
}
mode = modeOpt.value();
- } else if (name == formatAttribute()) {
+ } else if (name == formatAttribute) {
const auto attribute = attributes->takeAt(i);
const auto langOpt = languageFromAttribute(attribute.value());
if (!langOpt.has_value()) {
@@ -1933,7 +2045,17 @@ bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &,
QString signature = isTypeEntry(topElement) ? QString() : m_currentSignature;
DocModification mod(mode, signature);
mod.setFormat(lang);
- m_contextStack.top()->docModifications << mod;
+ if (hasFileSnippetAttributes(attributes)) {
+ const auto snippetOptional = readFileSnippet(attributes);
+ if (!snippetOptional.has_value())
+ return false;
+ mod.setCode(snippetOptional.value().content);
+ }
+ auto &top = m_contextStack.top();
+ if (isAddFunction)
+ top->addedFunctions.last()->addDocModification(mod);
+ else
+ top->docModifications << mod;
return true;
}
@@ -1946,13 +2068,13 @@ bool TypeSystemParser::parseModifyDocumentation(const ConditionalStreamReader &,
|| topElement == StackElement::ModifyField;
if (!validParent) {
m_error = u"modify-documentation must be inside modify-function, "
- "modify-field or other tags that creates a type"_qs;
+ "modify-field or other tags that creates a type"_s;
return false;
}
- const int xpathIndex = indexOfAttribute(*attributes, xPathAttribute());
+ const auto xpathIndex = indexOfAttribute(*attributes, xPathAttribute);
if (xpathIndex == -1) {
- m_error = msgMissingAttribute(xPathAttribute());
+ m_error = msgMissingAttribute(xPathAttribute);
return false;
}
@@ -1964,19 +2086,22 @@ bool TypeSystemParser::parseModifyDocumentation(const ConditionalStreamReader &,
}
// m_exceptionHandling
-TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamReader &,
+TypeSystemTypeEntryPtr TypeSystemParser::parseRootElement(const ConditionalStreamReader &,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
TypeSystem::SnakeCase snakeCase = TypeSystem::SnakeCase::Unspecified;
+ QString subModuleOf;
+ QString namespaceBegin;
+ QString namespaceEnd;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == packageAttribute()) {
+ if (name == packageAttribute) {
m_defaultPackage = attributes->takeAt(i).value().toString();
- } else if (name == defaultSuperclassAttribute()) {
+ } else if (name == defaultSuperclassAttribute) {
m_defaultSuperclass = attributes->takeAt(i).value().toString();
- } else if (name == exceptionHandlingAttribute()) {
+ } else if (name == exceptionHandlingAttribute) {
const auto attribute = attributes->takeAt(i);
const auto exceptionOpt = exceptionHandlingFromAttribute(attribute.value());
if (exceptionOpt.has_value()) {
@@ -1985,7 +2110,7 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamR
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == allowThreadAttribute()) {
+ } else if (name == allowThreadAttribute) {
const auto attribute = attributes->takeAt(i);
const auto allowThreadOpt = allowThreadFromAttribute(attribute.value());
if (allowThreadOpt.has_value()) {
@@ -1994,7 +2119,7 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamR
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == snakeCaseAttribute()) {
+ } else if (name == snakeCaseAttribute) {
const auto attribute = attributes->takeAt(i);
const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
if (snakeCaseOpt.has_value()) {
@@ -2003,25 +2128,36 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamR
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
+ } else if (name == subModuleOfAttribute) {
+ subModuleOf = attributes->takeAt(i).value().toString();
+ } else if (name == "namespace-begin"_L1) {
+ namespaceBegin = attributes->takeAt(i).value().toString();
+ } else if (name == "namespace-end"_L1) {
+ namespaceEnd = attributes->takeAt(i).value().toString();
}
}
if (m_defaultPackage.isEmpty()) { // Extending default, see addBuiltInContainerTypes()
- auto *moduleEntry = const_cast<TypeSystemTypeEntry *>(m_context->db->defaultTypeSystemType());
+ auto moduleEntry = std::const_pointer_cast<TypeSystemTypeEntry>(m_context->db->defaultTypeSystemType());
Q_ASSERT(moduleEntry);
m_defaultPackage = moduleEntry->name();
return moduleEntry;
}
- auto *moduleEntry =
- const_cast<TypeSystemTypeEntry *>(m_context->db->findTypeSystemType(m_defaultPackage));
- const bool add = moduleEntry == nullptr;
+ auto moduleEntry =
+ std::const_pointer_cast<TypeSystemTypeEntry>(m_context->db->findTypeSystemType(m_defaultPackage));
+ const bool add = !moduleEntry;
if (add) {
- moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since,
- currentParentTypeEntry());
+ moduleEntry.reset(new TypeSystemTypeEntry(m_defaultPackage, since,
+ currentParentTypeEntry()));
+ moduleEntry->setSubModule(subModuleOf);
}
moduleEntry->setCodeGeneration(m_generate);
moduleEntry->setSnakeCase(snakeCase);
+ if (!namespaceBegin.isEmpty())
+ moduleEntry->setNamespaceBegin(namespaceBegin);
+ if (!namespaceEnd.isEmpty())
+ moduleEntry->setNamespaceEnd(namespaceEnd);
if ((m_generate == TypeEntry::GenerateForSubclass ||
m_generate == TypeEntry::GenerateNothing) && !m_defaultPackage.isEmpty())
@@ -2037,12 +2173,12 @@ bool TypeSystemParser::loadTypesystem(const ConditionalStreamReader &,
{
QString typeSystemName;
bool generateChild = true;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute())
+ if (name == nameAttribute)
typeSystemName = attributes->takeAt(i).value().toString();
- else if (name == generateAttribute())
- generateChild = convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true);
+ else if (name == generateAttribute)
+ generateChild = convertBoolean(attributes->takeAt(i).value(), generateAttribute, true);
}
if (typeSystemName.isEmpty()) {
m_error = u"No typesystem name specified"_s;
@@ -2063,9 +2199,9 @@ bool TypeSystemParser::parseRejectEnumValue(const ConditionalStreamReader &,
m_error = u"<reject-enum-value> node must be used inside a <enum-type> node"_s;
return false;
}
- const int nameIndex = indexOfAttribute(*attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(*attributes, nameAttribute);
if (nameIndex == -1) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
m_currentEnum->addEnumValueRejection(attributes->takeAt(nameIndex).value().toString());
@@ -2080,7 +2216,7 @@ bool TypeSystemParser::parseReplaceArgumentType(const ConditionalStreamReader &,
m_error = u"Type replacement can only be specified for argument modifications"_s;
return false;
}
- const int modifiedTypeIndex = indexOfAttribute(*attributes, modifiedTypeAttribute());
+ const auto modifiedTypeIndex = indexOfAttribute(*attributes, modifiedTypeAttribute);
if (modifiedTypeIndex == -1) {
m_error = u"Type replacement requires 'modified-type' attribute"_s;
return false;
@@ -2106,9 +2242,9 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
QString sourceFile;
QString snippetLabel;
TypeSystem::Language lang = TypeSystem::NativeCode;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == classAttribute()) {
+ if (name == classAttribute) {
const auto languageAttribute = attributes->takeAt(i);
const auto langOpt = languageFromAttribute(languageAttribute.value());
if (!langOpt.has_value()) {
@@ -2118,7 +2254,7 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
lang = langOpt.value();
} else if (name == u"file") {
sourceFile = attributes->takeAt(i).value().toString();
- } else if (name == snippetAttribute()) {
+ } else if (name == snippetAttribute) {
snippetLabel = attributes->takeAt(i).value().toString();
}
}
@@ -2131,14 +2267,18 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
return true;
}
- if (top->entry->hasTargetConversionRule() || top->entry->hasCustomConversion()) {
- m_error = u"Types can have only one conversion rule"_s;
- return false;
+ ValueTypeEntryPtr valueTypeEntry;
+ if (top->entry->isValue()) {
+ valueTypeEntry = std::static_pointer_cast<ValueTypeEntry>(top->entry);
+ if (valueTypeEntry->hasTargetConversionRule() || valueTypeEntry->hasCustomConversion()) {
+ m_error = u"Types can have only one conversion rule"_s;
+ return false;
+ }
}
// The old conversion rule tag that uses a file containing the conversion
// will be kept temporarily for compatibility reasons. FIXME PYSIDE7: Remove
- if (!sourceFile.isEmpty()) {
+ if (valueTypeEntry != nullptr && !sourceFile.isEmpty()) {
if (m_generate != TypeEntry::GenerateForSubclass
&& m_generate != TypeEntry::GenerateNothing) {
qWarning(lcShiboken, "Specifying conversion rules by \"file\" is deprecated.");
@@ -2156,12 +2296,18 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
m_error = msgCannotFindSnippet(sourceFile, snippetLabel);
return false;
}
- top->entry->setTargetConversionRule(conversionRuleOptional.value());
+ valueTypeEntry->setTargetConversionRule(conversionRuleOptional.value());
}
return true;
}
- auto *customConversion = new CustomConversion(top->entry);
+ auto customConversion = std::make_shared<CustomConversion>(top->entry);
+ if (top->entry->isPrimitive())
+ std::static_pointer_cast<PrimitiveTypeEntry>(top->entry)->setCustomConversion(customConversion);
+ else if (top->entry->isContainer())
+ std::static_pointer_cast<ContainerTypeEntry>(top->entry)->setCustomConversion(customConversion);
+ else if (top->entry->isValue())
+ std::static_pointer_cast<ValueTypeEntry>(top->entry)->setCustomConversion(customConversion);
customConversionsForReview.append(customConversion);
return true;
}
@@ -2175,7 +2321,7 @@ bool TypeSystemParser::parseNativeToTarget(const ConditionalStreamReader &,
return false;
}
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
m_contextStack.top()->conversionCodeSnips.append(snip);
return true;
@@ -2192,7 +2338,7 @@ bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
QString sourceTypeName;
QString typeCheck;
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
const auto &top = m_contextStack.top();
@@ -2201,7 +2347,7 @@ bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
if (parserState() == ParserState::ArgumentTargetToNativeConversion)
return true;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == u"type")
sourceTypeName = attributes->takeAt(i).value().toString();
@@ -2213,7 +2359,12 @@ bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
m_error = u"Target to Native conversions must specify the input type with the 'type' attribute."_s;
return false;
}
- top->entry->customConversion()->addTargetToNativeConversion(sourceTypeName, typeCheck);
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (!customConversion) {
+ m_error = msgMissingCustomConversion(top->entry);
+ return false;
+ }
+ customConversion->addTargetToNativeConversion(sourceTypeName, typeCheck);
return true;
}
@@ -2222,7 +2373,7 @@ static bool parseIndex(const QString &index, int *result, QString *errorMessage)
bool ok = false;
*result = index.toInt(&ok);
if (!ok)
- *errorMessage = QStringLiteral("Cannot convert '%1' to integer").arg(index);
+ *errorMessage = QString::fromLatin1("Cannot convert '%1' to integer").arg(index);
return ok;
}
@@ -2255,22 +2406,22 @@ bool TypeSystemParser::parseModifyArgument(const ConditionalStreamReader &,
QString renameTo;
QString pyiType;
bool resetAfterUse = false;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == indexAttribute()) {
+ if (name == indexAttribute) {
index = attributes->takeAt(i).value().toString();
- } else if (name == invalidateAfterUseAttribute()) {
+ } else if (name == invalidateAfterUseAttribute) {
resetAfterUse = convertBoolean(attributes->takeAt(i).value(),
- invalidateAfterUseAttribute(), false);
- } else if (name == renameAttribute()) {
+ invalidateAfterUseAttribute, false);
+ } else if (name == renameAttribute) {
renameTo = attributes->takeAt(i).value().toString();
- } else if (name == pyiTypeAttribute()) {
+ } else if (name == pyiTypeAttribute) {
pyiType = attributes->takeAt(i).value().toString();
}
}
if (index.isEmpty()) {
- m_error = msgMissingAttribute(indexAttribute());
+ m_error = msgMissingAttribute(indexAttribute);
return false;
}
@@ -2318,9 +2469,9 @@ bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &,
TypeSystem::Language lang = TypeSystem::TargetLangCode;
std::optional<TypeSystem::Ownership> ownershipOpt;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == classAttribute()) {
+ if (name == classAttribute) {
const auto classAttribute = attributes->takeAt(i);
const auto langOpt = languageFromAttribute(classAttribute.value());
if (!langOpt.has_value() || langOpt.value() == TypeSystem::ShellCode) {
@@ -2328,7 +2479,7 @@ bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &,
return false;
}
lang = langOpt.value();
- } else if (name == ownershipAttribute()) {
+ } else if (name == ownershipAttribute) {
const auto attribute = attributes->takeAt(i);
ownershipOpt = ownershipFromFromAttribute(attribute.value());
if (!ownershipOpt.has_value()) {
@@ -2339,7 +2490,7 @@ bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &,
}
if (!ownershipOpt.has_value()) {
- m_error = QStringLiteral("unspecified ownership");
+ m_error = "unspecified ownership"_L1;
return false;
}
auto &lastArgMod = m_contextStack.top()->functionMods.last().argument_mods().last();
@@ -2366,9 +2517,9 @@ bool TypeSystemParser::parseRename(const ConditionalStreamReader &,
return false;
}
- const int toIndex = indexOfAttribute(*attributes, toAttribute());
+ const auto toIndex = indexOfAttribute(*attributes, toAttribute);
if (toIndex == -1) {
- m_error = msgMissingAttribute(toAttribute());
+ m_error = msgMissingAttribute(toAttribute);
return false;
}
const QString renamed_to = attributes->takeAt(toIndex).value().toString();
@@ -2380,22 +2531,22 @@ bool TypeSystemParser::parseModifyField(const ConditionalStreamReader &,
QXmlStreamAttributes *attributes)
{
FieldModification fm;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute()) {
+ if (name == nameAttribute) {
fm.setName(attributes->takeAt(i).value().toString());
- } else if (name == removeAttribute()) {
+ } else if (name == removeAttribute) {
fm.setRemoved(convertRemovalAttribute(attributes->takeAt(i).value()));
- } else if (name == opaqueContainerFieldAttribute()) {
+ } else if (name == opaqueContainerFieldAttribute) {
fm.setOpaqueContainer(convertBoolean(attributes->takeAt(i).value(),
- opaqueContainerFieldAttribute(), false));
- } else if (name == readAttribute()) {
- fm.setReadable(convertBoolean(attributes->takeAt(i).value(), readAttribute(), true));
- } else if (name == writeAttribute()) {
- fm.setWritable(convertBoolean(attributes->takeAt(i).value(), writeAttribute(), true));
- } else if (name == renameAttribute()) {
+ opaqueContainerFieldAttribute, false));
+ } else if (name == readAttribute) {
+ fm.setReadable(convertBoolean(attributes->takeAt(i).value(), readAttribute, true));
+ } else if (name == writeAttribute) {
+ fm.setWritable(convertBoolean(attributes->takeAt(i).value(), writeAttribute, true));
+ } else if (name == renameAttribute) {
fm.setRenamedToName(attributes->takeAt(i).value().toString());
- } else if (name == snakeCaseAttribute()) {
+ } else if (name == snakeCaseAttribute) {
const auto attribute = attributes->takeAt(i);
const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
if (snakeCaseOpt.has_value()) {
@@ -2407,7 +2558,7 @@ bool TypeSystemParser::parseModifyField(const ConditionalStreamReader &,
}
}
if (fm.name().isEmpty()) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
m_contextStack.top()->fieldMods << fm;
@@ -2439,29 +2590,37 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
", was=%1").arg(tagFromElement(topElement));
return false;
}
+
+ FunctionModification mod;
+ if (!(t == StackElement::AddFunction
+ ? parseBasicModifyFunctionAttributes(attributes, &mod)
+ : parseModifyFunctionAttributes(attributes, &mod))) {
+ return false;
+ }
+
QString originalSignature;
QString returnType;
bool staticFunction = false;
bool classMethod = false;
+ bool pythonOverride = false;
QString access;
- int overloadNumber = TypeSystem::OverloadNumberUnset;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == u"signature") {
- originalSignature = attributes->takeAt(i).value().toString();
+ if (name == signatureAttribute) {
+ originalSignature = attributes->takeAt(i).value().toString().simplified();
} else if (name == u"return-type") {
returnType = attributes->takeAt(i).value().toString();
- } else if (name == staticAttribute()) {
+ } else if (name == staticAttribute) {
staticFunction = convertBoolean(attributes->takeAt(i).value(),
- staticAttribute(), false);
- } else if (name == classmethodAttribute()) {
+ staticAttribute, false);
+ } else if (name == classmethodAttribute) {
classMethod = convertBoolean(attributes->takeAt(i).value(),
- classmethodAttribute(), false);
- } else if (name == accessAttribute()) {
+ classmethodAttribute, false);
+ } else if (name == accessAttribute) {
access = attributes->takeAt(i).value().toString();
- } else if (name == overloadNumberAttribute()) {
- if (!parseOverloadNumber(attributes->takeAt(i), &overloadNumber, &m_error))
- return false;
+ } else if (name == pythonOverrideAttribute) {
+ pythonOverride = convertBoolean(attributes->takeAt(i).value(),
+ pythonOverrideAttribute, false);
}
}
@@ -2478,13 +2637,15 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
}
AddedFunctionPtr func = AddedFunction::createAddedFunction(signature, returnType, &errorString);
- if (func.isNull()) {
+ if (!func) {
m_error = errorString;
return false;
}
func->setStatic(staticFunction);
func->setClassMethod(classMethod);
+ func->setPythonOverride(pythonOverride);
+ func->setTargetLangPackage(m_defaultPackage);
// Create signature for matching modifications
signature = TypeDatabase::normalizedSignature(originalSignature);
@@ -2506,8 +2667,6 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
m_contextStack.top()->addedFunctionModificationIndex =
m_contextStack.top()->functionMods.size();
- FunctionModification mod;
- mod.setOverloadNumber(overloadNumber);
if (!mod.setSignature(m_currentSignature, &m_error))
return false;
mod.setOriginalSignature(originalSignature);
@@ -2526,9 +2685,9 @@ bool TypeSystemParser::parseAddPyMethodDef(const ConditionalStreamReader &,
}
TypeSystemPyMethodDefEntry def;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute()) {
+ if (name == nameAttribute) {
def.name = attributes->takeAt(i).value().toString();
} else if (name == u"doc") {
def.doc = attributes->takeAt(i).value().toString();
@@ -2551,7 +2710,7 @@ bool TypeSystemParser::parseAddPyMethodDef(const ConditionalStreamReader &,
m_error = u"add-pymethoddef requires at least a name and a function attribute"_s;
return false;
}
- static_cast<ComplexTypeEntry *>(m_contextStack.top()->entry)->addPyMethodDef(def);
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addPyMethodDef(def);
return true;
}
@@ -2565,9 +2724,9 @@ bool TypeSystemParser::parseProperty(const ConditionalStreamReader &, StackEleme
}
TypeSystemProperty property;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute()) {
+ if (name == nameAttribute) {
property.name = attributes->takeAt(i).value().toString();
} else if (name == u"get") {
property.read = attributes->takeAt(i).value().toString();
@@ -2575,17 +2734,78 @@ bool TypeSystemParser::parseProperty(const ConditionalStreamReader &, StackEleme
property.type = attributes->takeAt(i).value().toString();
} else if (name == u"set") {
property.write = attributes->takeAt(i).value().toString();
- } else if (name == generateGetSetDefAttribute()) {
+ } else if (name == generateGetSetDefAttribute) {
property.generateGetSetDef =
convertBoolean(attributes->takeAt(i).value(),
- generateGetSetDefAttribute(), false);
+ generateGetSetDefAttribute, false);
}
}
if (!property.isValid()) {
m_error = u"<property> element is missing required attibutes (name/type/get)."_s;
return false;
}
- static_cast<ComplexTypeEntry *>(m_contextStack.top()->entry)->addProperty(property);
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addProperty(property);
+ return true;
+}
+
+// Parse basic attributes applicable to <add-function>/<declare-function>/<function>
+// and <modify-function> (all that is not done by injected code).
+bool TypeSystemParser::parseBasicModifyFunctionAttributes(QXmlStreamAttributes *attributes,
+ FunctionModification *mod)
+{
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == overloadNumberAttribute) {
+ int overloadNumber = TypeSystem::OverloadNumberUnset;
+ if (!parseOverloadNumber(attributes->takeAt(i), &overloadNumber, &m_error))
+ return false;
+ mod->setOverloadNumber(overloadNumber);
+ }
+ }
+ return true;
+}
+
+// Parse attributes applicable to <declare-function>/<function>
+// and <modify-function>.
+bool TypeSystemParser::parseModifyFunctionAttributes(QXmlStreamAttributes *attributes,
+ FunctionModification *mod)
+{
+ if (!parseBasicModifyFunctionAttributes(attributes, mod))
+ return false;
+
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == allowThreadAttribute) {
+ const QXmlStreamAttribute attribute = attributes->takeAt(i);
+ const auto allowThreadOpt = allowThreadFromAttribute(attribute.value());
+ if (!allowThreadOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
+ }
+ mod->setAllowThread(allowThreadOpt.value());
+ } else if (name == exceptionHandlingAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ const auto exceptionOpt = exceptionHandlingFromAttribute(attribute.value());
+ if (!exceptionOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
+ }
+ mod->setExceptionHandling(exceptionOpt.value());
+ } else if (name == snakeCaseAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
+ if (!snakeCaseOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
+ }
+ mod->setSnakeCase(snakeCaseOpt.value());
+ } else if (name == deprecatedAttribute) {
+ const bool deprecated = convertBoolean(attributes->takeAt(i).value(),
+ deprecatedAttribute, false);
+ mod->setModifierFlag(deprecated ? FunctionModification::Deprecated
+ : FunctionModification::Undeprecated);
+ }
+ }
return true;
}
@@ -2603,61 +2823,24 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
}
QString originalSignature;
+ FunctionModification mod;
+ if (!parseModifyFunctionAttributes(attributes, &mod))
+ return false;
+
QString access;
bool removed = false;
QString rename;
- bool deprecated = false;
- bool isThread = false;
- int overloadNumber = TypeSystem::OverloadNumberUnset;
- TypeSystem::ExceptionHandling exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
- TypeSystem::AllowThread allowThread = TypeSystem::AllowThread::Unspecified;
- TypeSystem::SnakeCase snakeCase = TypeSystem::SnakeCase::Unspecified;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == u"signature") {
- originalSignature = attributes->takeAt(i).value().toString();
- } else if (name == accessAttribute()) {
+ if (name == signatureAttribute) {
+ originalSignature = attributes->takeAt(i).value().toString().simplified();
+ } else if (name == accessAttribute) {
access = attributes->takeAt(i).value().toString();
- } else if (name == renameAttribute()) {
+ } else if (name == renameAttribute) {
rename = attributes->takeAt(i).value().toString();
- } else if (name == removeAttribute()) {
+ } else if (name == removeAttribute) {
removed = convertRemovalAttribute(attributes->takeAt(i).value());
- } else if (name == deprecatedAttribute()) {
- deprecated = convertBoolean(attributes->takeAt(i).value(),
- deprecatedAttribute(), false);
- } else if (name == threadAttribute()) {
- isThread = convertBoolean(attributes->takeAt(i).value(),
- threadAttribute(), false);
- } else if (name == allowThreadAttribute()) {
- const QXmlStreamAttribute attribute = attributes->takeAt(i);
- const auto allowThreadOpt = allowThreadFromAttribute(attribute.value());
- if (!allowThreadOpt.has_value()) {
- m_error = msgInvalidAttributeValue(attribute);
- return false;
- }
- allowThread = allowThreadOpt.value();
- } else if (name == exceptionHandlingAttribute()) {
- const auto attribute = attributes->takeAt(i);
- const auto exceptionOpt = exceptionHandlingFromAttribute(attribute.value());
- if (exceptionOpt.has_value()) {
- exceptionHandling = exceptionOpt.value();
- } else {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgInvalidAttributeValue(attribute)));
- }
- } else if (name == overloadNumberAttribute()) {
- if (!parseOverloadNumber(attributes->takeAt(i), &overloadNumber, &m_error))
- return false;
- } else if (name == snakeCaseAttribute()) {
- const auto attribute = attributes->takeAt(i);
- const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
- if (snakeCaseOpt.has_value()) {
- snakeCase = snakeCaseOpt.value();
- } else {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgInvalidAttributeValue(attribute)));
- }
- } else if (name == virtualSlotAttribute()) {
+ } else if (name == virtualSlotAttribute || name == threadAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
}
@@ -2666,7 +2849,7 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
// Child of global <function>
const auto &top = m_contextStack.top();
if (originalSignature.isEmpty() && top->entry->isFunction()) {
- auto f = static_cast<const FunctionTypeEntry *>(top->entry);
+ auto f = std::static_pointer_cast<const FunctionTypeEntry>(top->entry);
originalSignature = f->signatures().value(0);
}
@@ -2682,13 +2865,9 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
return false;
}
- FunctionModification mod;
if (!mod.setSignature(signature, &m_error))
return false;
mod.setOriginalSignature(originalSignature);
- mod.setExceptionHandling(exceptionHandling);
- mod.setOverloadNumber(overloadNumber);
- mod.setSnakeCase(snakeCase);
m_currentSignature = signature;
if (!access.isEmpty()) {
@@ -2698,17 +2877,14 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
return false;
}
const FunctionModification::ModifierFlag m = modifierFlagOpt.value();
- if (m == FunctionModification::Final || m == FunctionModification::NonFinal) {
+ if (m == FunctionModification::NonFinal) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeValueWarning(reader,
- accessAttribute(), access)));
+ accessAttribute, access)));
}
mod.setModifierFlag(m);
}
- if (deprecated)
- mod.setModifierFlag(FunctionModification::Deprecated);
-
mod.setRemoved(removed);
if (!rename.isEmpty()) {
@@ -2716,10 +2892,6 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
mod.setModifierFlag(FunctionModification::Rename);
}
- mod.setIsThread(isThread);
- if (allowThread != TypeSystem::AllowThread::Unspecified)
- mod.setAllowThread(allowThread);
-
top->functionMods << mod;
return true;
}
@@ -2732,7 +2904,7 @@ bool TypeSystemParser::parseReplaceDefaultExpression(const ConditionalStreamRead
m_error = u"Replace default expression only allowed as child of argument modification"_s;
return false;
}
- const int withIndex = indexOfAttribute(*attributes, u"with");
+ const auto withIndex = indexOfAttribute(*attributes, u"with");
if (withIndex == -1 || attributes->at(withIndex).value().isEmpty()) {
m_error = u"Default expression replaced with empty string. Use remove-default-expression instead."_s;
return false;
@@ -2753,9 +2925,9 @@ bool TypeSystemParser::parseReferenceCount(const ConditionalStreamReader &reader
}
ReferenceCount rc;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == actionAttribute()) {
+ if (name == actionAttribute) {
const QXmlStreamAttribute attribute = attributes->takeAt(i);
const auto actionOpt = referenceCountFromAttribute(attribute.value());
if (!actionOpt.has_value()) {
@@ -2790,13 +2962,13 @@ bool TypeSystemParser::parseParentOwner(const ConditionalStreamReader &,
return false;
}
ArgumentOwner ao;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == indexAttribute()) {
+ if (name == indexAttribute) {
const QString index = attributes->takeAt(i).value().toString();
if (!parseArgumentIndex(index, &ao.index, &m_error))
return false;
- } else if (name == actionAttribute()) {
+ } else if (name == actionAttribute) {
const auto action = attributes->takeAt(i);
const auto actionOpt = argumentOwnerActionFromAttribute(action.value());
if (!actionOpt.has_value()) {
@@ -2810,46 +2982,62 @@ bool TypeSystemParser::parseParentOwner(const ConditionalStreamReader &,
return true;
}
-bool TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip)
+std::optional<TypeSystemParser::Snippet>
+ TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes)
{
- QString fileName;
- QString snippetLabel;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ Snippet result;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == u"file") {
- fileName = attributes->takeAt(i).value().toString();
- } else if (name == snippetAttribute()) {
- snippetLabel = attributes->takeAt(i).value().toString();
+ if (name == fileAttribute) {
+ result.fileName = attributes->takeAt(i).value().toString();
+ } else if (name == snippetAttribute) {
+ result.snippetLabel = attributes->takeAt(i).value().toString();
}
}
- if (fileName.isEmpty())
- return true;
- const QString resolved = m_context->db->modifiedTypesystemFilepath(fileName, m_currentPath);
+ if (result.fileName.isEmpty()) {
+ m_error = "Snippet missing file name"_L1;
+ return std::nullopt;
+ }
+ const QString resolved = m_context->db->modifiedTypesystemFilepath(result.fileName,
+ m_currentPath);
if (!QFile::exists(resolved)) {
m_error = u"File for inject code not exist: "_s
- + QDir::toNativeSeparators(fileName);
- return false;
+ + QDir::toNativeSeparators(result.fileName);
+ return std::nullopt;
}
QFile codeFile(resolved);
if (!codeFile.open(QIODevice::Text | QIODevice::ReadOnly)) {
m_error = msgCannotOpenForReading(codeFile);
- return false;
+ return std::nullopt;
}
- const auto codeOptional = extractSnippet(QString::fromUtf8(codeFile.readAll()), snippetLabel);
+ const auto contentOptional = extractSnippet(QString::fromUtf8(codeFile.readAll()),
+ result.snippetLabel);
codeFile.close();
- if (!codeOptional.has_value()) {
- m_error = msgCannotFindSnippet(resolved, snippetLabel);
- return false;
+ if (!contentOptional.has_value()) {
+ m_error = msgCannotFindSnippet(resolved, result.snippetLabel);
+ return std::nullopt;
}
+ result.content = contentOptional.value();
+ return result;
+}
+
+bool TypeSystemParser::readCodeSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip)
+{
+ if (!hasFileSnippetAttributes(attributes))
+ return true; // Expecting inline content.
+ const auto snippetOptional = readFileSnippet(attributes);
+ if (!snippetOptional.has_value())
+ return false;
+ const auto snippet = snippetOptional.value();
- QString source = fileName;
- if (!snippetLabel.isEmpty())
- source += u" ("_s + snippetLabel + u')';
+ QString source = snippet.fileName;
+ if (!snippet.snippetLabel.isEmpty())
+ source += " ("_L1 + snippet.snippetLabel + u')';
QString content;
QTextStream str(&content);
str << "// ========================================================================\n"
"// START of custom code block [file: "
- << source << "]\n" << codeOptional.value()
+ << source << "]\n" << snippet.content
<< "// END of custom code block [file: " << source
<< "]\n// ========================================================================\n";
snip->addCode(content);
@@ -2871,11 +3059,11 @@ bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionBeginning;
TypeSystem::Language lang = TypeSystem::TargetLangCode;
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == classAttribute()) {
+ if (name == classAttribute) {
const auto attribute = attributes->takeAt(i);
const auto langOpt = languageFromAttribute(attribute.value());
if (!langOpt.has_value()) {
@@ -2883,7 +3071,7 @@ bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
return false;
}
lang = langOpt.value();
- } else if (name == positionAttribute()) {
+ } else if (name == positionAttribute) {
const auto attribute = attributes->takeAt(i);
const auto positionOpt = codeSnipPositionFromAttribute(attribute.value());
if (!positionOpt.has_value()) {
@@ -2897,29 +3085,36 @@ bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
snip.position = position;
snip.language = lang;
- if (topElement == StackElement::ModifyFunction
- || topElement == StackElement::AddFunction) {
+ switch (topElement) {
+ case StackElement::ModifyFunction:
+ case StackElement::AddFunction: {
FunctionModification &mod = m_contextStack.top()->functionMods.last();
mod.appendSnip(snip);
if (!snip.code().isEmpty())
mod.setModifierFlag(FunctionModification::CodeInjection);
- } else {
- m_contextStack.top()->entry->addCodeSnip(snip);
+ }
+ break;
+ case StackElement::Root:
+ std::static_pointer_cast<TypeSystemTypeEntry>(m_contextStack.top()->entry)->addCodeSnip(snip);
+ break;
+ default:
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addCodeSnip(snip);
+ break;
}
return true;
}
bool TypeSystemParser::parseInclude(const ConditionalStreamReader &,
StackElement topElement,
- TypeEntry *entry, QXmlStreamAttributes *attributes)
+ const TypeEntryPtr &entry, QXmlStreamAttributes *attributes)
{
QString fileName;
Include::IncludeType location = Include::IncludePath;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == fileNameAttribute()) {
+ if (name == fileNameAttribute) {
fileName = attributes->takeAt(i).value().toString();
- } else if (name == locationAttribute()) {
+ } else if (name == locationAttribute) {
const auto attribute = attributes->takeAt(i);
const auto locationOpt = locationFromAttribute(attribute.value());
if (!locationOpt.has_value()) {
@@ -2949,12 +3144,12 @@ bool TypeSystemParser::parseInclude(const ConditionalStreamReader &,
bool TypeSystemParser::parseSystemInclude(const ConditionalStreamReader &,
QXmlStreamAttributes *attributes)
{
- const int index = indexOfAttribute(*attributes, fileNameAttribute());
+ const auto index = indexOfAttribute(*attributes, fileNameAttribute);
if (index == -1) {
- m_error = msgMissingAttribute(fileNameAttribute());
+ m_error = msgMissingAttribute(fileNameAttribute);
return false;
}
- TypeDatabase::instance()->addSystemInclude(attributes->takeAt(index).value().toString());
+ TypeDatabase::instance()->addForceProcessSystemInclude(attributes->takeAt(index).value().toString());
return true;
}
@@ -2972,9 +3167,9 @@ TemplateInstance *
"conversion-rule, native-to-target or add-conversion tags."_s;
return nullptr;
}
- const int nameIndex = indexOfAttribute(*attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(*attributes, nameAttribute);
if (nameIndex == -1) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return nullptr;
}
return new TemplateInstance(attributes->takeAt(nameIndex).value().toString());
@@ -2989,11 +3184,11 @@ bool TypeSystemParser::parseReplace(const ConditionalStreamReader &,
}
QString from;
QString to;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == u"from")
from = attributes->takeAt(i).value().toString();
- else if (name == toAttribute())
+ else if (name == toAttribute)
to = attributes->takeAt(i).value().toString();
}
m_templateInstance->addReplaceRule(from, to);
@@ -3010,7 +3205,7 @@ bool TypeSystemParser::checkDuplicatedTypeEntry(const ConditionalStreamReader &r
{
if (t == StackElement::PrimitiveTypeEntry || t == StackElement::FunctionTypeEntry)
return true;
- const auto *duplicated = m_context->db->findType(name);
+ const auto duplicated = m_context->db->findType(name);
if (!duplicated || duplicated->isNamespace())
return true;
if (duplicated->isBuiltIn()) {
@@ -3047,14 +3242,14 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
QXmlStreamAttributes attributes = reader.attributes();
VersionRange versionRange;
- for (int i = attributes.size() - 1; i >= 0; --i) {
+ for (auto i = attributes.size() - 1; i >= 0; --i) {
const auto name = attributes.at(i).qualifiedName();
- if (name == sinceAttribute()) {
+ if (name == sinceAttribute) {
if (!parseVersion(attributes.takeAt(i).value().toString(),
m_defaultPackage, &versionRange.since, &m_error)) {
return false;
}
- } else if (name == untilAttribute()) {
+ } else if (name == untilAttribute) {
if (!parseVersion(attributes.takeAt(i).value().toString(),
m_defaultPackage, &versionRange.until, &m_error)) {
return false;
@@ -3063,7 +3258,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
}
if (!m_defaultPackage.isEmpty() && !versionRange.isNull()) {
- TypeDatabase* td = TypeDatabase::instance();
+ auto *td = TypeDatabase::instance();
if (!td->checkApiVersion(m_defaultPackage, versionRange)) {
++m_ignoreDepth;
return true;
@@ -3088,7 +3283,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
}
if (isTypeEntry(element) || element == StackElement::Root)
- m_contextStack.push(StackElementContextPtr(new StackElementContext()));
+ m_contextStack.push(std::make_shared<StackElementContext>());
if (m_contextStack.isEmpty()) {
m_error = msgNoRootTypeSystemEntry();
@@ -3101,11 +3296,11 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
if (isTypeEntry(element)) {
QString name;
if (element != StackElement::FunctionTypeEntry) {
- const int nameIndex = indexOfAttribute(attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(attributes, nameAttribute);
if (nameIndex != -1) {
name = attributes.takeAt(nameIndex).value().toString();
} else if (element != StackElement::EnumTypeEntry) { // anonymous enum?
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
}
@@ -3118,7 +3313,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
if (m_context->db->hasDroppedTypeEntries()) {
const QString identifier = element == StackElement::FunctionTypeEntry
- ? attributes.value(signatureAttribute()).toString() : name;
+ ? attributes.value(signatureAttribute).toString().simplified() : name;
if (shouldDropTypeEntry(m_context->db, m_contextStack, identifier)) {
m_currentDroppedEntryDepth = 1;
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
@@ -3142,14 +3337,15 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
// types (which we need to do in order to support fake meta objects)
if (element != StackElement::PrimitiveTypeEntry
&& element != StackElement::FunctionTypeEntry) {
- TypeEntry *tmp = m_context->db->findType(name);
+ TypeEntryPtr tmp = m_context->db->findType(name);
if (tmp && !tmp->isNamespace())
qCWarning(lcShiboken).noquote().nospace()
<< "Duplicate type entry: '" << name << '\'';
}
if (element == StackElement::EnumTypeEntry) {
- const int enumIdentifiedByIndex = indexOfAttribute(attributes, enumIdentifiedByValueAttribute());
+ const auto enumIdentifiedByIndex =
+ indexOfAttribute(attributes, enumIdentifiedByValueAttribute);
const QString identifiedByValue = enumIdentifiedByIndex != -1
? attributes.takeAt(enumIdentifiedByIndex).value().toString() : QString();
if (name.isEmpty()) {
@@ -3208,7 +3404,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
case StackElement::InterfaceTypeEntry: {
if (!checkRootElement())
return false;
- auto *ce = new ObjectTypeEntry(name, versionRange.since, currentParentTypeEntry());
+ auto ce = std::make_shared<ObjectTypeEntry>(name, versionRange.since, currentParentTypeEntry());
top->entry = ce;
applyCommonAttributes(reader, top->entry, &attributes);
applyComplexTypeAttributes(reader, ce, &attributes);
@@ -3256,7 +3452,8 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
|| element == StackElement::ConversionRule
|| element == StackElement::AddFunction
|| element == StackElement::DeclareFunction
- || element == StackElement::Template;
+ || element == StackElement::Template
+ || element == StackElement::OpaqueContainer;
if (!topLevel && m_stack.at(m_stack.size() - 2) == StackElement::Root) {
m_error = u"Tag requires parent: '"_s + tagName.toString() + u'\'';
@@ -3295,11 +3492,16 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
const auto topParent = m_stack.value(m_stack.size() - 3, StackElement::None);
if (isTypeEntry(topParent)) {
- const int replaceIndex = indexOfAttribute(attributes, replaceAttribute());
+ const auto replaceIndex = indexOfAttribute(attributes, replaceAttribute);
const bool replace = replaceIndex == -1
|| convertBoolean(attributes.takeAt(replaceIndex).value(),
- replaceAttribute(), true);
- top->entry->customConversion()->setReplaceOriginalTargetToNativeConversions(replace);
+ replaceAttribute, true);
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (!customConversion) {
+ m_error = msgMissingCustomConversion(top->entry);
+ return false;
+ }
+ customConversion->setReplaceOriginalTargetToNativeConversions(replace);
}
}
break;
@@ -3320,14 +3522,17 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
return false;
break;
case StackElement::SuppressedWarning: {
- const int textIndex = indexOfAttribute(attributes, textAttribute());
+ const auto textIndex = indexOfAttribute(attributes, textAttribute);
if (textIndex == -1) {
qCWarning(lcShiboken) << "Suppressed warning with no text specified";
} else {
const QString suppressedWarning =
attributes.takeAt(textIndex).value().toString();
- if (!m_context->db->addSuppressedWarning(suppressedWarning, &m_error))
+ if (!m_context->db->addSuppressedWarning(suppressedWarning,
+ m_generate == TypeEntry::GenerateCode,
+ &m_error)) {
return false;
+ }
}
}
break;
@@ -3396,32 +3601,39 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
return false;
break;
case StackElement::Rejection:
- if (!addRejection(m_context->db, &attributes, &m_error))
+ if (!addRejection(m_context->db, m_generate == TypeEntry::GenerateCode,
+ &attributes, &m_error)) {
return false;
+ }
break;
case StackElement::SystemInclude:
if (!parseSystemInclude(reader, &attributes))
return false;
break;
case StackElement::Template: {
- const int nameIndex = indexOfAttribute(attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(attributes, nameAttribute);
if (nameIndex == -1) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
- m_templateEntry =
- new TemplateEntry(attributes.takeAt(nameIndex).value().toString());
+ m_templateEntry.reset(new TemplateEntry(attributes.takeAt(nameIndex).value().toString()));
}
break;
case StackElement::InsertTemplate:
m_templateInstance.reset(parseInsertTemplate(reader, topElement, &attributes));
- if (m_templateInstance.isNull())
+ if (!m_templateInstance)
return false;
break;
case StackElement::Replace:
if (!parseReplace(reader, topElement, &attributes))
return false;
break;
+ case StackElement::OpaqueContainer:
+ if (!parseOpaqueContainerElement(&attributes))
+ case StackElement::Configuration:
+ if (!parseConfiguration(topElement, &attributes))
+ return false;
+ break;
default:
break; // nada
}