1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt for Python.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 #ifndef TYPESYSTEMPARSER_H
29 #define TYPESYSTEMPARSER_H
30 
31 #include "typesystem.h"
32 
33 #include <QtCore/QStack>
34 #include <QtCore/QHash>
35 #include <QtCore/QScopedPointer>
36 
37 QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
38 QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)
39 
40 class TypeSystemEntityResolver;
41 class TypeDatabase;
42 class StackElement
43 {
44     public:
45         enum ElementType {
46             None = 0x0,
47 
48             // Type tags (0x1, ... , 0xff)
49             ObjectTypeEntry             = 0x1,
50             ValueTypeEntry              = 0x2,
51             InterfaceTypeEntry          = 0x3,
52             NamespaceTypeEntry          = 0x4,
53             ComplexTypeEntryMask        = 0x7,
54 
55             // Non-complex type tags (0x8, 0x9, ... , 0xf)
56             PrimitiveTypeEntry          = 0x8,
57             EnumTypeEntry               = 0x9,
58             ContainerTypeEntry          = 0xa,
59             FunctionTypeEntry           = 0xb,
60             CustomTypeEntry             = 0xc,
61             SmartPointerTypeEntry       = 0xd,
62             TypedefTypeEntry            = 0xe,
63             TypeEntryMask               = 0xf,
64 
65             // Documentation tags
66             InjectDocumentation         = 0x10,
67             ModifyDocumentation         = 0x20,
68             DocumentationMask           = 0xf0,
69 
70             // Simple tags (0x100, 0x200, ... , 0xf00)
71             ExtraIncludes               = 0x0100,
72             Include                     = 0x0200,
73             ModifyFunction              = 0x0300,
74             ModifyField                 = 0x0400,
75             Root                        = 0x0500,
76             CustomMetaConstructor       = 0x0600,
77             CustomMetaDestructor        = 0x0700,
78             ArgumentMap                 = 0x0800,
79             SuppressedWarning           = 0x0900,
80             Rejection                   = 0x0a00,
81             LoadTypesystem              = 0x0b00,
82             RejectEnumValue             = 0x0c00,
83             Template                    = 0x0d00,
84             TemplateInstanceEnum        = 0x0e00,
85             Replace                     = 0x0f00,
86             AddFunction                 = 0x1000,
87             NativeToTarget              = 0x1100,
88             TargetToNative              = 0x1200,
89             AddConversion               = 0x1300,
90             SystemInclude               = 0x1400,
91             Property                    = 0x1500,
92             SimpleMask                  = 0x3f00,
93 
94             // Code snip tags (0x1000, 0x2000, ... , 0xf000)
95             InjectCode                  = 0x4000,
96             InjectCodeInFunction        = 0x8000,
97             CodeSnipMask                = 0xc000,
98 
99             // Function modifier tags (0x010000, 0x020000, ... , 0xf00000)
100             Access                      = 0x010000,
101             Removal                     = 0x020000,
102             Rename                      = 0x040000,
103             ModifyArgument              = 0x080000,
104             Thread                      = 0x100000,
105             FunctionModifiers           = 0xff0000,
106 
107             // Argument modifier tags (0x01000000 ... 0xf0000000)
108             ConversionRule              = 0x01000000,
109             ReplaceType                 = 0x02000000,
110             ReplaceDefaultExpression    = 0x04000000,
111             RemoveArgument              = 0x08000000,
112             DefineOwnership             = 0x10000000,
113             RemoveDefaultExpression     = 0x20000000,
114             NoNullPointers              = 0x40000000,
115             ReferenceCount              = 0x80000000,
116             ParentOwner                 = 0x90000000,
117             Array                       = 0xA0000000,
118             ArgumentModifiers           = 0xff000000
119         };
120 
StackElement(StackElement * p)121         StackElement(StackElement *p) : entry(nullptr), type(None), parent(p) { }
122 
123         TypeEntry* entry;
124         ElementType type;
125         StackElement *parent;
126 
127         union {
128             TemplateInstance* templateInstance;
129             TemplateEntry* templateEntry;
130             CustomFunction* customFunction;
131         } value;
132 };
133 
134 struct StackElementContext
135 {
136     CodeSnipList codeSnips;
137     AddedFunctionList addedFunctions;
138     FunctionModificationList functionMods;
139     FieldModificationList fieldMods;
140     DocModificationList docModifications;
141     int addedFunctionModificationIndex = -1;
142 };
143 
144 class TypeSystemParser
145 {
146 public:
147     Q_DISABLE_COPY(TypeSystemParser)
148 
149     TypeSystemParser(TypeDatabase* database, bool generate);
150     ~TypeSystemParser();
151 
152     bool parse(QXmlStreamReader &reader);
153 
errorString()154     QString errorString() const { return m_error; }
155 
156 private:
157     bool parseXml(QXmlStreamReader &reader);
158     bool setupSmartPointerInstantiations();
159     bool startElement(const QXmlStreamReader &reader);
160     SmartPointerTypeEntry *parseSmartPointerEntry(const QXmlStreamReader &,
161                                                   const QString &name,
162                                                   const QVersionNumber &since,
163                                                   QXmlStreamAttributes *attributes);
164     bool endElement(const QStringRef& localName);
165     template <class String> // QString/QStringRef
166     bool characters(const String &ch);
167 
168     bool importFileElement(const QXmlStreamAttributes &atts);
169 
170     const TypeEntry *currentParentTypeEntry() const;
171     bool checkRootElement();
172     void applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type,
173                                QXmlStreamAttributes *attributes) const;
174     PrimitiveTypeEntry *
175         parsePrimitiveTypeEntry(const QXmlStreamReader &, const QString &name,
176                                 const QVersionNumber &since, QXmlStreamAttributes *);
177     ContainerTypeEntry *
178         parseContainerTypeEntry(const QXmlStreamReader &, const QString &name,
179                                  const QVersionNumber &since, QXmlStreamAttributes *);
180     EnumTypeEntry *
181         parseEnumTypeEntry(const QXmlStreamReader &, const QString &name,
182                            const QVersionNumber &since, QXmlStreamAttributes *);
183     FlagsTypeEntry *
184         parseFlagsEntry(const QXmlStreamReader &, EnumTypeEntry *enumEntry,
185                         QString flagName, const QVersionNumber &since,
186                         QXmlStreamAttributes *);
187 
188     NamespaceTypeEntry *
189         parseNamespaceTypeEntry(const QXmlStreamReader &,
190                                 const QString &name, const QVersionNumber &since,
191                                 QXmlStreamAttributes *attributes);
192 
193     ValueTypeEntry *
194         parseValueTypeEntry(const QXmlStreamReader &, const QString &name,
195                             const QVersionNumber &since, QXmlStreamAttributes *);
196     FunctionTypeEntry *
197         parseFunctionTypeEntry(const QXmlStreamReader &, const QString &name,
198                                const QVersionNumber &since, QXmlStreamAttributes *);
199     TypedefEntry *
200         parseTypedefEntry(const QXmlStreamReader &, const QString &name,
201                           const QVersionNumber &since, QXmlStreamAttributes *);
202     void applyComplexTypeAttributes(const QXmlStreamReader &, ComplexTypeEntry *ctype,
203                                     QXmlStreamAttributes *) const;
204     bool parseRenameFunction(const QXmlStreamReader &, QString *name,
205                              QXmlStreamAttributes *);
206     bool parseInjectDocumentation(const QXmlStreamReader &, QXmlStreamAttributes *);
207     bool parseModifyDocumentation(const QXmlStreamReader &, QXmlStreamAttributes *);
208     TypeSystemTypeEntry *
209         parseRootElement(const QXmlStreamReader &, const QVersionNumber &since,
210                          QXmlStreamAttributes *);
211     bool loadTypesystem(const QXmlStreamReader &, QXmlStreamAttributes *);
212     bool parseRejectEnumValue(const QXmlStreamReader &, QXmlStreamAttributes *);
213     bool parseReplaceArgumentType(const QXmlStreamReader &, const StackElement &topElement,
214                                   QXmlStreamAttributes *);
215     bool parseCustomConversion(const QXmlStreamReader &, const StackElement &topElement,
216                                QXmlStreamAttributes *);
217     bool parseAddConversion(const QXmlStreamReader &, const StackElement &topElement,
218                             QXmlStreamAttributes *);
219     bool parseNativeToTarget(const QXmlStreamReader &, const StackElement &topElement,
220                              QXmlStreamAttributes *attributes);
221     bool parseModifyArgument(const QXmlStreamReader &, const StackElement &topElement,
222                              QXmlStreamAttributes *attributes);
223     bool parseNoNullPointer(const QXmlStreamReader &, const StackElement &topElement,
224                             QXmlStreamAttributes *attributes);
225     bool parseDefineOwnership(const QXmlStreamReader &, const StackElement &topElement,
226                               QXmlStreamAttributes *);
227     bool parseArgumentMap(const QXmlStreamReader &, const StackElement &topElement,
228                           QXmlStreamAttributes *);
229     bool parseRemoval(const QXmlStreamReader &, const StackElement &topElement,
230                       QXmlStreamAttributes *);
231     bool parseRename(const QXmlStreamReader &, StackElement::ElementType type,
232                      const StackElement &topElement, QXmlStreamAttributes *);
233     bool parseModifyField(const QXmlStreamReader &, QXmlStreamAttributes *);
234     bool parseAddFunction(const QXmlStreamReader &, const StackElement &topElement,
235                           QXmlStreamAttributes *);
236     bool parseProperty(const QXmlStreamReader &, const StackElement &topElement,
237                        QXmlStreamAttributes *);
238     bool parseModifyFunction(const QXmlStreamReader &, const StackElement &topElement,
239                              QXmlStreamAttributes *);
240     bool parseReplaceDefaultExpression(const QXmlStreamReader &,
241                                        const StackElement &topElement, QXmlStreamAttributes *);
242     CustomFunction *
243         parseCustomMetaConstructor(const QXmlStreamReader &,
244                                    StackElement::ElementType type,
245                                    const StackElement &topElement, QXmlStreamAttributes *);
246      bool parseReferenceCount(const QXmlStreamReader &, const StackElement &topElement,
247                               QXmlStreamAttributes *);
248      bool parseParentOwner(const QXmlStreamReader &, const StackElement &topElement,
249                            QXmlStreamAttributes *);
250      bool readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip);
251      bool parseInjectCode(const QXmlStreamReader &, const StackElement &topElement,
252                           StackElement* element, QXmlStreamAttributes *);
253      bool parseInclude(const QXmlStreamReader &, const StackElement &topElement,
254                        TypeEntry *entry, QXmlStreamAttributes *);
255      bool parseSystemInclude(const QXmlStreamReader &, QXmlStreamAttributes *);
256      TemplateInstance
257          *parseTemplateInstanceEnum(const QXmlStreamReader &, const StackElement &topElement,
258                                     QXmlStreamAttributes *);
259      bool parseReplace(const QXmlStreamReader &, const StackElement &topElement,
260                        StackElement *element, QXmlStreamAttributes *);
261 
262     TypeDatabase* m_database;
263     StackElement* m_current = nullptr;
264     StackElement* m_currentDroppedEntry = nullptr;
265     int m_currentDroppedEntryDepth = 0;
266     int m_ignoreDepth = 0;
267     QString m_defaultPackage;
268     QString m_defaultSuperclass;
269     TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
270     TypeSystem::AllowThread m_allowThread = TypeSystem::AllowThread::Unspecified;
271     QString m_error;
272     const TypeEntry::CodeGeneration m_generate;
273 
274     EnumTypeEntry* m_currentEnum = nullptr;
275     QStack<StackElementContext*> m_contextStack;
276 
277     QString m_currentSignature;
278     QString m_currentPath;
279     QString m_currentFile;
280     QScopedPointer<TypeSystemEntityResolver> m_entityResolver;
281     QHash<SmartPointerTypeEntry *, QString> m_smartPointerInstantiations;
282 };
283 
284 #endif // TYPESYSTEMPARSER_H
285