1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the tools applications of the Qt Toolkit.
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
29#ifndef MOC_H
30#define MOC_H
31
32#include "parser.h"
33#include <qstringlist.h>
34#include <qmap.h>
35#include <qpair.h>
36#include <qjsondocument.h>
37#include <qjsonarray.h>
38#include <qjsonobject.h>
39#include <qversionnumber.h>
40#include <stdio.h>
41#include <ctype.h>
42
43QT_BEGIN_NAMESPACE
44
45struct QMetaObject;
46
47struct Type
48{
49 enum ReferenceType { NoReference, Reference, RValueReference, Pointer };
50
51 inline Type() : isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
52 inline explicit Type(const QByteArray &_name)
53 : name(_name), rawName(name), isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
54 QByteArray name;
55 //When used as a return type, the type name may be modified to remove the references.
56 // rawName is the type as found in the function signature
57 QByteArray rawName;
58 uint isVolatile : 1;
59 uint isScoped : 1;
60 Token firstToken;
61 ReferenceType referenceType;
62};
63Q_DECLARE_TYPEINFO(Type, Q_MOVABLE_TYPE);
64
65struct ClassDef;
66struct EnumDef
67{
68 QByteArray name;
69 QByteArray enumName;
70 QList<QByteArray> values;
71 bool isEnumClass; // c++11 enum class
72 EnumDef() : isEnumClass(false) {}
73 QJsonObject toJson(const ClassDef &cdef) const;
74};
75Q_DECLARE_TYPEINFO(EnumDef, Q_MOVABLE_TYPE);
76
77struct ArgumentDef
78{
79 ArgumentDef() : isDefault(false) {}
80 Type type;
81 QByteArray rightType, normalizedType, name;
82 QByteArray typeNameForCast; // type name to be used in cast from void * in metacall
83 bool isDefault;
84
85 QJsonObject toJson() const;
86};
87Q_DECLARE_TYPEINFO(ArgumentDef, Q_MOVABLE_TYPE);
88
89struct FunctionDef
90{
91 Type type;
92 QList<ArgumentDef> arguments;
93 QByteArray normalizedType;
94 QByteArray tag;
95 QByteArray name;
96 QByteArray inPrivateClass;
97
98 enum Access { Private, Protected, Public };
99 Access access = Private;
100 int revision = 0;
101
102 bool isConst = false;
103 bool isVirtual = false;
104 bool isStatic = false;
105 bool inlineCode = false;
106 bool wasCloned = false;
107
108 bool returnTypeIsVolatile = false;
109
110 bool isCompat = false;
111 bool isInvokable = false;
112 bool isScriptable = false;
113 bool isSlot = false;
114 bool isSignal = false;
115 bool isPrivateSignal = false;
116 bool isConstructor = false;
117 bool isDestructor = false;
118 bool isAbstract = false;
119 bool isRawSlot = false;
120
121 QJsonObject toJson() const;
122 static void accessToJson(QJsonObject *obj, Access acs);
123};
124Q_DECLARE_TYPEINFO(FunctionDef, Q_MOVABLE_TYPE);
125
126struct PropertyDef
127{
128 bool stdCppSet() const {
129 QByteArray s("set");
130 s += toupper(name[0]);
131 s += name.mid(1);
132 return (s == write);
133 }
134
135 QByteArray name, type, member, read, write, bind, reset, designable, scriptable, stored, user, notify, inPrivateClass;
136 int notifyId = -1; // -1 means no notifyId, >= 0 means signal defined in this class, < -1 means signal not defined in this class
137 enum Specification { ValueSpec, ReferenceSpec, PointerSpec };
138 Specification gspec = ValueSpec;
139 int revision = 0;
140 bool constant = false;
141 bool final = false;
142 bool required = false;
143
144 int location = -1; // token index, used for error reporting
145
146 QJsonObject toJson() const;
147};
148Q_DECLARE_TYPEINFO(PropertyDef, Q_MOVABLE_TYPE);
149
150struct PrivateQPropertyDef
151{
152 Type type;
153 QByteArray name;
154 QByteArray setter;
155 QByteArray accessor;
156 QByteArray storage;
157};
158Q_DECLARE_TYPEINFO(PrivateQPropertyDef, Q_MOVABLE_TYPE);
159
160struct ClassInfoDef
161{
162 QByteArray name;
163 QByteArray value;
164};
165Q_DECLARE_TYPEINFO(ClassInfoDef, Q_MOVABLE_TYPE);
166
167struct BaseDef {
168 QByteArray classname;
169 QByteArray qualified;
170 QList<ClassInfoDef> classInfoList;
171 QMap<QByteArray, bool> enumDeclarations;
172 QList<EnumDef> enumList;
173 QMap<QByteArray, QByteArray> flagAliases;
174 int begin = 0;
175 int end = 0;
176};
177
178struct ClassDef : BaseDef {
179 QList<QPair<QByteArray, FunctionDef::Access>> superclassList;
180
181 struct Interface
182 {
183 Interface() { } // for QList, don't use
184 inline explicit Interface(const QByteArray &_className)
185 : className(_className) {}
186 QByteArray className;
187 QByteArray interfaceId;
188 };
189 QList<QList<Interface>> interfaceList;
190
191 struct PluginData {
192 QByteArray iid;
193 QByteArray uri;
194 QMap<QString, QJsonArray> metaArgs;
195 QJsonDocument metaData;
196 } pluginData;
197
198 QList<FunctionDef> constructorList;
199 QList<FunctionDef> signalList, slotList, methodList, publicList;
200 QList<QByteArray> nonClassSignalList;
201 QList<PropertyDef> propertyList;
202 int revisionedMethods = 0;
203
204 bool hasQObject = false;
205 bool hasQGadget = false;
206 bool hasQNamespace = false;
207 bool requireCompleteMethodTypes = false;
208
209 QJsonObject toJson() const;
210};
211Q_DECLARE_TYPEINFO(ClassDef, Q_MOVABLE_TYPE);
212Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE);
213
214struct NamespaceDef : BaseDef {
215 bool hasQNamespace = false;
216 bool doGenerate = false;
217};
218Q_DECLARE_TYPEINFO(NamespaceDef, Q_MOVABLE_TYPE);
219
220class Moc : public Parser
221{
222public:
223 Moc()
224 : noInclude(false), mustIncludeQPluginH(false), requireCompleteTypes(false)
225 {}
226
227 QByteArray filename;
228
229 bool noInclude;
230 bool mustIncludeQPluginH;
231 bool requireCompleteTypes;
232 QByteArray includePath;
233 QList<QByteArray> includeFiles;
234 QList<ClassDef> classList;
235 QMap<QByteArray, QByteArray> interface2IdMap;
236 QList<QByteArray> metaTypes;
237 // map from class name to fully qualified name
238 QHash<QByteArray, QByteArray> knownQObjectClasses;
239 QHash<QByteArray, QByteArray> knownGadgets;
240 QMap<QString, QJsonArray> metaArgs;
241 QList<QString> parsedPluginMetadataFiles;
242
243 void parse();
244 void generate(FILE *out, FILE *jsonOutput);
245
246 bool parseClassHead(ClassDef *def);
247 inline bool inClass(const ClassDef *def) const {
248 return index > def->begin && index < def->end - 1;
249 }
250
251 inline bool inNamespace(const NamespaceDef *def) const {
252 return index > def->begin && index < def->end - 1;
253 }
254
255 Type parseType();
256
257 bool parseEnum(EnumDef *def);
258
259 bool parseFunction(FunctionDef *def, bool inMacro = false);
260 bool parseMaybeFunction(const ClassDef *cdef, FunctionDef *def);
261
262 void parseSlots(ClassDef *def, FunctionDef::Access access);
263 void parseSignals(ClassDef *def);
264 void parseProperty(ClassDef *def);
265 void parsePluginData(ClassDef *def);
266 void createPropertyDef(PropertyDef &def);
267 void parsePropertyAttributes(PropertyDef &propDef);
268 void parseEnumOrFlag(BaseDef *def, bool isFlag);
269 void parseFlag(BaseDef *def);
270 enum class EncounteredQmlMacro {Yes, No};
271 EncounteredQmlMacro parseClassInfo(BaseDef *def);
272 void parseClassInfo(ClassDef *def);
273 void parseInterfaces(ClassDef *def);
274 void parseDeclareInterface();
275 void parseDeclareMetatype();
276 void parseMocInclude();
277 void parseSlotInPrivate(ClassDef *def, FunctionDef::Access access);
278 QByteArray parsePropertyAccessor();
279 void parsePrivateProperty(ClassDef *def);
280
281 void parseFunctionArguments(FunctionDef *def);
282
283 QByteArray lexemUntil(Token);
284 bool until(Token);
285
286 // test for Q_INVOCABLE, Q_SCRIPTABLE, etc. and set the flags
287 // in FunctionDef accordingly
288 bool testFunctionAttribute(FunctionDef *def);
289 bool testFunctionAttribute(Token tok, FunctionDef *def);
290 bool testFunctionRevision(FunctionDef *def);
291 QTypeRevision parseRevision();
292
293 bool skipCxxAttributes();
294
295 void checkSuperClasses(ClassDef *def);
296 void checkProperties(ClassDef* cdef);
297};
298
299inline QByteArray noRef(const QByteArray &type)
300{
301 if (type.endsWith('&')) {
302 if (type.endsWith("&&"))
303 return type.left(type.length()-2);
304 return type.left(type.length()-1);
305 }
306 return type;
307}
308
309QT_END_NAMESPACE
310
311#endif // MOC_H
312