aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-04-01 10:26:05 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-04-06 12:51:45 +0200
commite494b218824246f49784a481f634a9afeb82ee09 (patch)
tree5c83c63fdc8722270d2f0f9cb2bf23c4feac27ff
parent159c5f0f017c91f932a2061dbf6bdb4f71c247d4 (diff)
shiboken6/Type system parser: Use contiguous enum for StackElement
The old approach with the bit masks does not really scale and makes it hard to add new values. Replace by a contiguous enum with First/Last entries and check functions. Task-number: PYSIDE-454 Change-Id: If34942ce0d2e496f34a17a84a7c8406895cf1c16 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp74
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.h124
2 files changed, 108 insertions, 90 deletions
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index 4a615420e..9ab7118cc 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -118,6 +118,21 @@ static inline QString yesAttributeValue() { return QStringLiteral("yes"); }
static inline QString trueAttributeValue() { return QStringLiteral("true"); }
static inline QString falseAttributeValue() { return QStringLiteral("false"); }
+static bool isTypeEntry(StackElement el)
+{
+ return el >= StackElement::FirstTypeEntry && el <= StackElement::LastTypeEntry;
+}
+
+static bool isComplexTypeEntry(StackElement el)
+{
+ return el >= StackElement::FirstTypeEntry && el <= StackElement::LastComplexTypeEntry;
+}
+
+static bool isDocumentation(StackElement el)
+{
+ return el >= StackElement::FirstDocumentation && el <= StackElement::LastDocumentation;
+}
+
static QList<CustomConversion *> customConversionsForReview;
// Set a regular expression for rejection from text. By legacy, those are fixed
@@ -993,10 +1008,8 @@ bool TypeSystemParser::endElement(StackElement element)
break;
}
- if ((element & StackElement::TypeEntryMask) != 0
- || element == StackElement::Root) {
+ if (isTypeEntry(element) || element == StackElement::Root)
m_contextStack.pop();
- }
return true;
}
@@ -1112,7 +1125,7 @@ bool TypeSystemParser::characters(const String &ch)
return true;
}
- if ((type & StackElement::DocumentationMask) != 0)
+ if (isDocumentation(type))
m_contextStack.top()->docModifications.last().setCode(ch);
return true;
@@ -1891,11 +1904,11 @@ bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &,
bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &, StackElement topElement,
QXmlStreamAttributes *attributes)
{
- const auto validParent = StackElement::TypeEntryMask
- | StackElement::ModifyFunction
- | StackElement::ModifyField
- | StackElement::AddFunction;
- if ((topElement & validParent) == 0) {
+ const bool validParent = isTypeEntry(topElement)
+ || topElement == StackElement::ModifyFunction
+ || topElement == StackElement::ModifyField
+ || topElement == StackElement::AddFunction;
+ if (!validParent) {
m_error = u"inject-documentation must be inside modify-function, add-function"
"modify-field or other tags that creates a type"_qs;
return false;
@@ -1924,8 +1937,7 @@ bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &,
}
}
- QString signature = topElement & StackElement::TypeEntryMask
- ? QString() : m_currentSignature;
+ QString signature = isTypeEntry(topElement) ? QString() : m_currentSignature;
DocModification mod(mode, signature);
mod.setFormat(lang);
m_contextStack.top()->docModifications << mod;
@@ -1936,10 +1948,10 @@ bool TypeSystemParser::parseModifyDocumentation(const ConditionalStreamReader &,
StackElement topElement,
QXmlStreamAttributes *attributes)
{
- const auto validParent = StackElement::TypeEntryMask
- | StackElement::ModifyFunction
- | StackElement::ModifyField;
- if ((topElement & validParent) == 0) {
+ const bool validParent = isTypeEntry(topElement)
+ || topElement == StackElement::ModifyFunction
+ || topElement == StackElement::ModifyField;
+ if (!validParent) {
m_error = QLatin1String("modify-documentation must be inside modify-function, "
"modify-field or other tags that creates a type");
return false;
@@ -1952,7 +1964,7 @@ bool TypeSystemParser::parseModifyDocumentation(const ConditionalStreamReader &,
}
const QString xpath = attributes->takeAt(xpathIndex).value().toString();
- QString signature = (topElement & StackElement::TypeEntryMask) ? QString() : m_currentSignature;
+ QString signature = isTypeEntry(topElement) ? QString() : m_currentSignature;
m_contextStack.top()->docModifications
<< DocModification(xpath, signature);
return true;
@@ -2425,8 +2437,10 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
StackElement t,
QXmlStreamAttributes *attributes)
{
- if (!(topElement
- & (StackElement::ComplexTypeEntryMask | StackElement::Root | StackElement::ContainerTypeEntry))) {
+ const bool validParent = isComplexTypeEntry(topElement)
+ || topElement == StackElement::Root
+ || topElement == StackElement::ContainerTypeEntry;
+ if (!validParent) {
m_error = QString::fromLatin1("Add/Declare function requires a complex/container type or a root tag as parent"
", was=%1").arg(tagFromElement(topElement));
return false;
@@ -2510,7 +2524,7 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
bool TypeSystemParser::parseProperty(const ConditionalStreamReader &, StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if ((topElement & StackElement::ComplexTypeEntryMask) == 0) {
+ if (!isComplexTypeEntry(topElement)) {
m_error = QString::fromLatin1("Add property requires a complex type as parent"
", was=%1").arg(tagFromElement(topElement));
return false;
@@ -2545,7 +2559,10 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (!(topElement & StackElement::ComplexTypeEntryMask)) {
+ const bool validParent = isComplexTypeEntry(topElement)
+ || topElement == StackElement::TypedefTypeEntry
+ || topElement == StackElement::FunctionTypeEntry;
+ if (!validParent) {
m_error = QString::fromLatin1("Modify function requires complex type as parent"
", was=%1").arg(tagFromElement(topElement));
return false;
@@ -2809,7 +2826,7 @@ bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (!(topElement & StackElement::ComplexTypeEntryMask)
+ if (!isComplexTypeEntry(topElement)
&& (topElement != StackElement::AddFunction)
&& (topElement != StackElement::ModifyFunction)
&& (topElement != StackElement::Root)) {
@@ -2880,8 +2897,11 @@ bool TypeSystemParser::parseInclude(const ConditionalStreamReader &,
}
Include inc(location, fileName);
- if (topElement
- & (StackElement::ComplexTypeEntryMask | StackElement::PrimitiveTypeEntry)) {
+ if (isComplexTypeEntry(topElement)
+ || topElement == StackElement::PrimitiveTypeEntry
+ || topElement == StackElement::ContainerTypeEntry
+ || topElement == StackElement::SmartPointerTypeEntry
+ || topElement == StackElement::TypedefTypeEntry) {
entry->setInclude(inc);
} else if (topElement == StackElement::ExtraIncludes) {
entry->addExtraInclude(inc);
@@ -3033,10 +3053,8 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
return true;
}
- if ((element & StackElement::TypeEntryMask) != 0
- || element == StackElement::Root) {
+ if (isTypeEntry(element) || element == StackElement::Root)
m_contextStack.push(StackElementContextPtr(new StackElementContext()));
- }
if (m_contextStack.isEmpty()) {
m_error = msgNoRootTypeSystemEntry();
@@ -3046,7 +3064,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
const auto &top = m_contextStack.top();
const StackElement topElement = m_stack.value(m_stack.size() - 2, StackElement::None);
- if (element & StackElement::TypeEntryMask) {
+ if (isTypeEntry(element)) {
QString name;
if (element != StackElement::FunctionTypeEntry) {
const int nameIndex = indexOfAttribute(attributes, nameAttribute());
@@ -3242,7 +3260,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
}
const auto topParent = m_stack.value(m_stack.size() - 3, StackElement::None);
- if ((topParent & StackElement::TypeEntryMask) != 0) {
+ if (isTypeEntry(topParent)) {
const int replaceIndex = indexOfAttribute(attributes, replaceAttribute());
const bool replace = replaceIndex == -1
|| convertBoolean(attributes.takeAt(replaceIndex).value(),
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.h b/sources/shiboken6/ApiExtractor/typesystemparser.h
index d3fbd18cf..011521bc5 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.h
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.h
@@ -46,77 +46,77 @@ class TypeSystemEntityResolver;
class TypeDatabase;
enum class ParserState;
-enum class StackElement : uint64_t {
- None = 0x0,
+enum class StackElement {
+ None,
- // Type tags (0x1, ... , 0xff)
- ObjectTypeEntry = 0x1,
- ValueTypeEntry = 0x2,
- InterfaceTypeEntry = 0x3,
- NamespaceTypeEntry = 0x4,
- ComplexTypeEntryMask = 0x7,
+ // Type tags
+ ObjectTypeEntry,
+ FirstTypeEntry = ObjectTypeEntry,
+ ValueTypeEntry,
+ InterfaceTypeEntry,
+ NamespaceTypeEntry,
+ LastComplexTypeEntry = NamespaceTypeEntry,
- // Non-complex type tags (0x8, 0x9, ... , 0xf)
- PrimitiveTypeEntry = 0x8,
- EnumTypeEntry = 0x9,
- ContainerTypeEntry = 0xa,
- FunctionTypeEntry = 0xb,
- CustomTypeEntry = 0xc,
- SmartPointerTypeEntry = 0xd,
- TypedefTypeEntry = 0xe,
- TypeEntryMask = 0xf,
+ // Non-complex type tags
+ PrimitiveTypeEntry,
+ EnumTypeEntry,
+ ContainerTypeEntry,
+ FunctionTypeEntry,
+ CustomTypeEntry,
+ SmartPointerTypeEntry,
+ TypedefTypeEntry,
+ LastTypeEntry = TypedefTypeEntry,
// Documentation tags
- InjectDocumentation = 0x10,
- ModifyDocumentation = 0x20,
- DocumentationMask = 0xf0,
+ InjectDocumentation,
+ FirstDocumentation = InjectDocumentation,
+ ModifyDocumentation,
+ LastDocumentation = ModifyDocumentation,
- // Simple tags (0x100, 0x200, ... , 0xf00)
- ExtraIncludes = 0x0100,
- Include = 0x0200,
- ModifyFunction = 0x0300,
- ModifyField = 0x0400,
- Root = 0x0500,
- SuppressedWarning = 0x0900,
- Rejection = 0x0a00,
- LoadTypesystem = 0x0b00,
- RejectEnumValue = 0x0c00,
- Template = 0x0d00,
- InsertTemplate = 0x0e00,
- Replace = 0x0f00,
- AddFunction = 0x1000,
- DeclareFunction = 0x1100,
- NativeToTarget = 0x1200,
- TargetToNative = 0x1300,
- AddConversion = 0x1400,
- SystemInclude = 0x1500,
- Property = 0x1600,
- SimpleMask = 0x3f00,
+ // Simple tags
+ ExtraIncludes,
+ Include,
+ ModifyFunction,
+ ModifyField,
+ Root,
+ SuppressedWarning,
+ Rejection,
+ LoadTypesystem,
+ RejectEnumValue,
+ Template,
+ InsertTemplate,
+ Replace,
+ AddFunction,
+ DeclareFunction,
+ NativeToTarget,
+ TargetToNative,
+ AddConversion,
+ SystemInclude,
+ Property,
- // Code snip tags (0x1000, 0x2000, ... , 0xf000)
- InjectCode = 0x4000,
+ // Code snip tags
+ InjectCode,
- // Function modifier tags (0x010000, 0x020000, ... , 0xf00000)
- Rename = 0x040000, // (modify-argument)
- ModifyArgument = 0x080000,
- Thread = 0x100000,
- FunctionModifiers = 0xff0000,
+ // Function modifier tags
+ Rename, // (modify-argument)
+ ModifyArgument,
+ Thread,
- // Argument modifier tags (0x01000000 ... 0xf0000000)
- ConversionRule = 0x01000000,
- ReplaceType = 0x02000000,
- ReplaceDefaultExpression = 0x04000000,
- RemoveArgument = 0x08000000,
- DefineOwnership = 0x10000000,
- RemoveDefaultExpression = 0x20000000,
- NoNullPointers = 0x40000000,
- ReferenceCount = 0x80000000,
- ParentOwner = 0x90000000,
- Array = 0xA0000000,
- ArgumentModifiers = 0xff000000,
+ // Argument modifier tags
+ ConversionRule,
+ ReplaceType,
+ ReplaceDefaultExpression,
+ RemoveArgument,
+ DefineOwnership,
+ RemoveDefaultExpression,
+ NoNullPointers,
+ ReferenceCount,
+ ParentOwner,
+ Array,
+ ArgumentModifiers,
- ImportFile = 0x100000000,
- Unimplemented = 0x200000000
+ ImportFile,
+ Unimplemented
};
inline uint64_t operator&(StackElement s1, StackElement s2)