aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/typesystemparser_p.h
blob: 4d9d4fd926209c2e80d902edea2ce0ba9e3d129a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPESYSTEMPARSER_H
#define TYPESYSTEMPARSER_H

#include "typesystem.h"
#include "containertypeentry.h"
#include "typedatabase.h"
#include "typedatabase_p.h"
#include "typesystem_typedefs.h"
#include "codesnip.h"

#include <QtCore/QStack>
#include <QtCore/QHash>
#include <QtCore/QScopedPointer>

#include <memory>
#include <optional>

QT_FORWARD_DECLARE_CLASS(QVersionNumber)
QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)

class ConditionalStreamReader;

class TypeSystemEntityResolver;
class TypeDatabase;

class FlagsTypeEntry;
class TypeSystemTypeEntry;
class ValueTypeEntry;
class EnumTypeEntry;

enum class ParserState;

enum class StackElement {
            None,

            // Type tags
            ObjectTypeEntry,
            FirstTypeEntry = ObjectTypeEntry,
            ValueTypeEntry,
            InterfaceTypeEntry,
            NamespaceTypeEntry,
            LastComplexTypeEntry = NamespaceTypeEntry,

            // Non-complex type tags
            PrimitiveTypeEntry,
            EnumTypeEntry,
            ContainerTypeEntry,
            FunctionTypeEntry,
            CustomTypeEntry,
            SmartPointerTypeEntry,
            TypedefTypeEntry,
            LastTypeEntry = TypedefTypeEntry,

            // Documentation tags
            InjectDocumentation,
            FirstDocumentation = InjectDocumentation,
            ModifyDocumentation,
            LastDocumentation = ModifyDocumentation,

            // Simple tags
            ExtraIncludes,
            Include,
            ModifyFunction,
            ModifyField,
            Root,
            SuppressedWarning,
            Rejection,
            LoadTypesystem,
            RejectEnumValue,
            Template,
            InsertTemplate,
            Replace,
            AddFunction,
            AddPyMethodDef,
            DeclareFunction,
            NativeToTarget,
            TargetToNative,
            AddConversion,
            SystemInclude,
            Property,

            // Code snip tags
            InjectCode,

            // Function modifier tags
            Rename, // (modify-argument)
            ModifyArgument,
            Thread,

            // Argument modifier tags
            ConversionRule,
            ReplaceType,
            ReplaceDefaultExpression,
            RemoveArgument,
            DefineOwnership,
            RemoveDefaultExpression,
            NoNullPointers,
            ReferenceCount,
            ParentOwner,
            Array,
            ArgumentModifiers,

            ImportFile,
            OpaqueContainer,
            Configuration,
            Unimplemented
};

inline uint64_t operator&(StackElement s1, StackElement s2)
{
    return uint64_t(s1) & uint64_t(s2);
}

inline StackElement operator|(StackElement s1, StackElement s2)
{
    return StackElement(uint64_t(s1) | uint64_t(s2));
}

struct StackElementContext
{
    CodeSnipList conversionCodeSnips;
    AddedFunctionList addedFunctions;
    FunctionModificationList functionMods;
    FieldModificationList fieldMods;
    DocModificationList docModifications;
    TypeEntryPtr entry;
    int addedFunctionModificationIndex = -1;
};

class TypeSystemParser
{
public:
    Q_DISABLE_COPY_MOVE(TypeSystemParser)

    using StackElementContextPtr = std::shared_ptr<StackElementContext>;
    using ContextStack = QStack<StackElementContextPtr>;

    explicit TypeSystemParser(const std::shared_ptr<TypeDatabaseParserContext> &context,
                              bool generate);
    ~TypeSystemParser();

    bool parse(ConditionalStreamReader &reader);

    QString errorString() const { return m_error; }

private:
    struct Snippet
    {
        QString content;
        QString fileName;
        QString snippetLabel;
    };

    bool parseXml(ConditionalStreamReader &reader);
    bool setupSmartPointerInstantiations();
    bool startElement(const ConditionalStreamReader &reader, StackElement element);
    SmartPointerTypeEntryPtr parseSmartPointerEntry(const ConditionalStreamReader &,
                                                  const QString &name,
                                                  const QVersionNumber &since,
                                                  QXmlStreamAttributes *attributes);
    bool endElement(StackElement element);
    template <class String> // QString/QStringRef
    bool characters(const String &ch);

    bool importFileElement(const QXmlStreamAttributes &atts);

    TypeEntryCPtr currentParentTypeEntry() const;
    bool checkRootElement();
    bool applyCommonAttributes(const ConditionalStreamReader &reader,
                               const TypeEntryPtr &type,
                               QXmlStreamAttributes *attributes);
    PrimitiveTypeEntryPtr
        parsePrimitiveTypeEntry(const ConditionalStreamReader &, const QString &name,
                                const QVersionNumber &since, QXmlStreamAttributes *);
    CustomTypeEntryPtr
        parseCustomTypeEntry(const ConditionalStreamReader &, const QString &name,
                             const QVersionNumber &since, QXmlStreamAttributes *);
    bool parseOpaqueContainers(QStringView s, OpaqueContainers *result);
    ContainerTypeEntryPtr
        parseContainerTypeEntry(const ConditionalStreamReader &, const QString &name,
                                 const QVersionNumber &since, QXmlStreamAttributes *);
    bool parseOpaqueContainerElement(QXmlStreamAttributes *attributes);
    EnumTypeEntryPtr
        parseEnumTypeEntry(const ConditionalStreamReader &, const QString &name,
                           const QVersionNumber &since, QXmlStreamAttributes *);
    FlagsTypeEntryPtr
        parseFlagsEntry(const ConditionalStreamReader &, const EnumTypeEntryPtr &enumEntry,
                        QString flagName, const QVersionNumber &since,
                        QXmlStreamAttributes *);

    NamespaceTypeEntryPtr
        parseNamespaceTypeEntry(const ConditionalStreamReader &,
                                const QString &name, const QVersionNumber &since,
                                QXmlStreamAttributes *attributes);

    ValueTypeEntryPtr
        parseValueTypeEntry(const ConditionalStreamReader &, const QString &name,
                            const QVersionNumber &since, QXmlStreamAttributes *);
    FunctionTypeEntryPtr
        parseFunctionTypeEntry(const ConditionalStreamReader &, const QString &name,
                               const QVersionNumber &since, QXmlStreamAttributes *);
    TypedefEntryPtr
        parseTypedefEntry(const ConditionalStreamReader &, const QString &name,
                          StackElement topElement,
                          const QVersionNumber &since, QXmlStreamAttributes *);
    void applyComplexTypeAttributes(const ConditionalStreamReader &, const ComplexTypeEntryPtr &ctype,
                                    QXmlStreamAttributes *) const;
    bool parseConfiguration(StackElement topElement,
                            QXmlStreamAttributes *attributes);
    bool parseRenameFunction(const ConditionalStreamReader &, QString *name,
                             QXmlStreamAttributes *);
    bool parseInjectDocumentation(const ConditionalStreamReader &, StackElement topElement,
                                  QXmlStreamAttributes *);
    bool parseModifyDocumentation(const ConditionalStreamReader &, StackElement topElement,
                                  QXmlStreamAttributes *);
    TypeSystemTypeEntryPtr
        parseRootElement(const ConditionalStreamReader &, const QVersionNumber &since,
                         QXmlStreamAttributes *);
    bool loadTypesystem(const ConditionalStreamReader &, QXmlStreamAttributes *);
    bool parseRejectEnumValue(const ConditionalStreamReader &, QXmlStreamAttributes *);
    bool parseReplaceArgumentType(const ConditionalStreamReader &, StackElement topElement,
                                  QXmlStreamAttributes *);
    bool parseCustomConversion(const ConditionalStreamReader &, StackElement topElement,
                               QXmlStreamAttributes *);
    bool parseAddConversion(const ConditionalStreamReader &, StackElement topElement,
                            QXmlStreamAttributes *);
    bool parseNativeToTarget(const ConditionalStreamReader &, StackElement topElement,
                             QXmlStreamAttributes *attributes);
    bool parseModifyArgument(const ConditionalStreamReader &, StackElement topElement,
                             QXmlStreamAttributes *attributes);
    bool parseNoNullPointer(const ConditionalStreamReader &, StackElement topElement,
                            QXmlStreamAttributes *attributes);
    bool parseDefineOwnership(const ConditionalStreamReader &, StackElement topElement,
                              QXmlStreamAttributes *);
    bool parseRename(const ConditionalStreamReader &, StackElement topElement,
                     QXmlStreamAttributes *);
    bool parseModifyField(const ConditionalStreamReader &, QXmlStreamAttributes *);
    bool parseAddFunction(const ConditionalStreamReader &, StackElement topElement,
                          StackElement t, QXmlStreamAttributes *);
    bool parseAddPyMethodDef(const ConditionalStreamReader &,
                             StackElement topElement, QXmlStreamAttributes *attributes);
    bool parseProperty(const ConditionalStreamReader &, StackElement topElement,
                       QXmlStreamAttributes *);
    bool parseBasicModifyFunctionAttributes(QXmlStreamAttributes *,
                                            FunctionModification *mod);
    bool parseModifyFunctionAttributes(QXmlStreamAttributes *,
                                       FunctionModification *mod);
    bool parseModifyFunction(const ConditionalStreamReader &, StackElement topElement,
                             QXmlStreamAttributes *);
    bool parseReplaceDefaultExpression(const ConditionalStreamReader &,
                                       StackElement topElement, QXmlStreamAttributes *);
     bool parseReferenceCount(const ConditionalStreamReader &, StackElement topElement,
                              QXmlStreamAttributes *);
     bool parseParentOwner(const ConditionalStreamReader &, StackElement topElement,
                           QXmlStreamAttributes *);
     std::optional<Snippet> readFileSnippet(QXmlStreamAttributes *attributes);
     bool readCodeSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip);
     bool parseInjectCode(const ConditionalStreamReader &, StackElement topElement, QXmlStreamAttributes *);
     bool parseInclude(const ConditionalStreamReader &, StackElement topElement,
                       const TypeEntryPtr &entry, QXmlStreamAttributes *);
     bool parseSystemInclude(const ConditionalStreamReader &, QXmlStreamAttributes *);
     TemplateInstance
         *parseInsertTemplate(const ConditionalStreamReader &, StackElement topElement,
                              QXmlStreamAttributes *);
     bool parseReplace(const ConditionalStreamReader &, StackElement topElement,
                       QXmlStreamAttributes *);
     bool checkDuplicatedTypeEntry(const ConditionalStreamReader &reader,
                                   StackElement t, const QString &name) const;
     ParserState parserState(qsizetype offset = 0) const;
     CodeSnipAbstract *injectCodeTarget(qsizetype offset = 0) const;

    std::shared_ptr<TypeDatabaseParserContext> m_context;
    QStack<StackElement> m_stack;
    int m_currentDroppedEntryDepth = 0;
    int m_ignoreDepth = 0;
    QString m_defaultPackage;
    QString m_defaultSuperclass;
    TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
    TypeSystem::AllowThread m_allowThread = TypeSystem::AllowThread::Unspecified;
    QString m_error;
    const TypeEntry::CodeGeneration m_generate;

    EnumTypeEntryPtr m_currentEnum;
    TemplateInstancePtr m_templateInstance;
    TemplateEntryPtr m_templateEntry;
    ContextStack m_contextStack;

    QString m_currentSignature;
    QString m_currentPath;
    QString m_currentFile;
    QScopedPointer<TypeSystemEntityResolver> m_entityResolver;
};

#endif // TYPESYSTEMPARSER_H