1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef MOC_H
43 #define MOC_H
44 
45 #include "parser.h"
46 #include <QStringList>
47 #include <QMap>
48 #include <QPair>
49 #include <stdio.h>
50 #include <ctype.h>
51 
52 QT_BEGIN_NAMESPACE
53 
54 struct QMetaObject;
55 
56 struct Type
57 {
58     enum ReferenceType { NoReference, Reference, RValueReference, Pointer };
59 
TypeType60     inline Type() : isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
TypeType61     inline explicit Type(const QByteArray &_name) : name(_name), isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
62     QByteArray name;
63     uint isVolatile : 1;
64     uint isScoped : 1;
65     Token firstToken;
66     ReferenceType referenceType;
67 };
68 
69 struct EnumDef
70 {
71     QByteArray name;
72     QList<QByteArray> values;
73 };
74 
75 struct ArgumentDef
76 {
ArgumentDefArgumentDef77     ArgumentDef() : isDefault(false) {}
78     Type type;
79     QByteArray rightType, normalizedType, name;
80     QByteArray typeNameForCast; // type name to be used in cast from void * in metacall
81     bool isDefault;
82 };
83 
84 struct FunctionDef
85 {
FunctionDefFunctionDef86     FunctionDef(): returnTypeIsVolatile(false), access(Private), isConst(false), isVirtual(false), isStatic(false),
87                    inlineCode(false), wasCloned(false), isCompat(false), isInvokable(false),
88                    isScriptable(false), isSlot(false), isSignal(false),
89                    isConstructor(false), isDestructor(false), isAbstract(false), revision(0) {}
90     Type type;
91     QByteArray normalizedType;
92     QByteArray tag;
93     QByteArray name;
94     bool returnTypeIsVolatile;
95 
96     QList<ArgumentDef> arguments;
97 
98     enum Access { Private, Protected, Public };
99     Access access;
100     bool isConst;
101     bool isVirtual;
102     bool isStatic;
103     bool inlineCode;
104     bool wasCloned;
105 
106     QByteArray inPrivateClass;
107     bool isCompat;
108     bool isInvokable;
109     bool isScriptable;
110     bool isSlot;
111     bool isSignal;
112     bool isConstructor;
113     bool isDestructor;
114     bool isAbstract;
115 
116     int revision;
117 };
118 
119 struct PropertyDef
120 {
PropertyDefPropertyDef121     PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec), revision(0){}
122     QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass;
123     int notifyId;
124     bool constant;
125     bool final;
126     enum Specification  { ValueSpec, ReferenceSpec, PointerSpec };
127     Specification gspec;
stdCppSetPropertyDef128     bool stdCppSet() const {
129         QByteArray s("set");
130         s += toupper(name[0]);
131         s += name.mid(1);
132         return (s == write);
133     }
134     int revision;
135 };
136 
137 
138 struct ClassInfoDef
139 {
140     QByteArray name;
141     QByteArray value;
142 };
143 
144 struct ClassDef {
ClassDefClassDef145     ClassDef():
146         hasQObject(false), hasQGadget(false), notifyableProperties(0)
147         , revisionedMethods(0), revisionedProperties(0), begin(0), end(0){}
148     QByteArray classname;
149     QByteArray qualified;
150     QList<QPair<QByteArray, FunctionDef::Access> > superclassList;
151 
152     struct Interface
153     {
InterfaceClassDef::Interface154         inline explicit Interface(const QByteArray &_className)
155             : className(_className) {}
156         QByteArray className;
157         QByteArray interfaceId;
158     };
159     QList<QList<Interface> >interfaceList;
160 
161     bool hasQObject;
162     bool hasQGadget;
163 
164     QList<FunctionDef> constructorList;
165     QList<FunctionDef> signalList, slotList, methodList, publicList;
166     int notifyableProperties;
167     QList<PropertyDef> propertyList;
168     QList<ClassInfoDef> classInfoList;
169     QMap<QByteArray, bool> enumDeclarations;
170     QList<EnumDef> enumList;
171     QMap<QByteArray, QByteArray> flagAliases;
172     int revisionedMethods;
173     int revisionedProperties;
174 
175     int begin;
176     int end;
177 };
178 
179 struct NamespaceDef {
180     QByteArray name;
181     int begin;
182     int end;
183 };
184 
185 class Moc : public Parser
186 {
187 public:
Moc()188     Moc()
189         : noInclude(false), generatedCode(false), mustIncludeQMetaTypeH(false)
190         {}
191 
192     QByteArray filename;
193 
194     bool noInclude;
195     bool generatedCode;
196     bool mustIncludeQMetaTypeH;
197     QByteArray includePath;
198     QList<QByteArray> includeFiles;
199     QList<ClassDef> classList;
200     QMap<QByteArray, QByteArray> interface2IdMap;
201     QList<QByteArray> metaTypes;
202     QSet<QByteArray> knownQObjectClasses;
203 
204     void parse();
205     void generate(FILE *out);
206     QList<QMetaObject*> generate(bool ignoreProperties);
207 
208     bool parseClassHead(ClassDef *def);
inClass(const ClassDef * def)209     inline bool inClass(const ClassDef *def) const {
210         return index > def->begin && index < def->end - 1;
211     }
212 
inNamespace(const NamespaceDef * def)213     inline bool inNamespace(const NamespaceDef *def) const {
214         return index > def->begin && index < def->end - 1;
215     }
216 
217     Type parseType();
218 
219     bool parseEnum(EnumDef *def);
220 
221     bool parseFunction(FunctionDef *def, bool inMacro = false);
222     bool parseMaybeFunction(const ClassDef *cdef, FunctionDef *def);
223 
224     void parseSlots(ClassDef *def, FunctionDef::Access access);
225     void parseSignals(ClassDef *def);
226     void parseProperty(ClassDef *def);
227     void createPropertyDef(PropertyDef &def);
228     void parseEnumOrFlag(ClassDef *def, bool isFlag);
229     void parseFlag(ClassDef *def);
230     void parseClassInfo(ClassDef *def);
231     void parseInterfaces(ClassDef *def);
232     void parseDeclareInterface();
233     void parseDeclareMetatype();
234     void parseSlotInPrivate(ClassDef *def, FunctionDef::Access access);
235     void parsePrivateProperty(ClassDef *def);
236 
237     void parseFunctionArguments(FunctionDef *def);
238 
239     QByteArray lexemUntil(Token);
240     bool until(Token);
241 
242     // test for Q_INVOCABLE, Q_SCRIPTABLE, etc. and set the flags
243     // in FunctionDef accordingly
244     bool testFunctionAttribute(FunctionDef *def);
245     bool testFunctionAttribute(Token tok, FunctionDef *def);
246     bool testFunctionRevision(FunctionDef *def);
247 
248     void checkSuperClasses(ClassDef *def);
249     void checkProperties(ClassDef* cdef);
250 };
251 
noRef(const QByteArray & type)252 inline QByteArray noRef(const QByteArray &type)
253 {
254     if (type.endsWith('&')) {
255         if (type.endsWith("&&"))
256             return type.left(type.length()-2);
257         return type.left(type.length()-1);
258     }
259     return type;
260 }
261 
262 QT_END_NAMESPACE
263 
264 #endif // MOC_H
265