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

source code of qtbase/src/tools/moc/moc.h