1
/*
2
 * This file is part of the API Extractor project.
3
 *
4
 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
5
 *
6
 * Contact: PySide team <contact@pyside.org>
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * version 2 as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
 * 02110-1301 USA
21
 *
22
 */
23
24
#ifndef ABSTRACTMETABUILDER_H
25
#define ABSTRACTMETABUILDER_H
26
27
#include "parser/codemodel.h"
28
#include "abstractmetalang.h"
29
#include "typesystem.h"
30
#include "typeparser.h"
31
32
#include <QSet>
33
#include <QFileInfo>
34
35
class TypeDatabase;
36
37
class APIEXTRACTOR_API AbstractMetaBuilder
38
{
39
public:
40
    enum RejectReason {
41
        NotInTypeSystem,
42
        GenerationDisabled,
43
        RedefinedToNotClass,
44
        UnmatchedArgumentType,
45
        UnmatchedReturnType,
46
        ApiIncompatible,
47
        NoReason
48
    };
49
50
    AbstractMetaBuilder();
51
    virtual ~AbstractMetaBuilder();
52
53
    AbstractMetaClassList classes() const
54
    {
55
        return m_metaClasses;
56
    }
57
    AbstractMetaClassList templates() const
58
    {
59
        return m_templates;
60
    }
61
    /**
62
    *   Sorts a list of classes topologically, if an AbstractMetaClass object
63
    *   is passed the list of classes will be its inner classes, otherwise
64
    *   the list will be the module global classes.
65
    *   \return a list of classes sorted topologically
66
    */
67
    AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClass* cppClass = 0) const;
68
69
    FileModelItem model() const
70
    {
71
        return m_dom;
72
    }
73
74
    void setModel(FileModelItem item)
75
    {
76
        m_dom = item;
77
    }
78
79
    ScopeModelItem popScope()
80
    {
81
        return m_scopes.takeLast();
82
    }
83
84
    void pushScope(ScopeModelItem item)
85
    {
86
        m_scopes << item;
87
    }
88
89
    ScopeModelItem currentScope() const
90
    {
91
        return m_scopes.last();
92
    }
93
94
    void dumpLog();
95
96
    bool build(QIODevice* input);
97
    void setLogDirectory(const QString& logDir);
98
99
    void figureOutEnumValuesForClass(AbstractMetaClass *metaClass, QSet<AbstractMetaClass *> *classes);
100
    int figureOutEnumValue(const QString &name, int value, AbstractMetaEnum *meta_enum, AbstractMetaFunction *metaFunction = 0);
101
    void figureOutEnumValues();
102
    void figureOutDefaultEnumArguments();
103
104
    void addAbstractMetaClass(AbstractMetaClass *cls);
105
    AbstractMetaClass *traverseTypeAlias(TypeAliasModelItem item);
106
    AbstractMetaClass *traverseClass(ClassModelItem item);
107
    AbstractMetaClass* currentTraversedClass(ScopeModelItem item);
108
    void traverseScopeMembers(ScopeModelItem item, AbstractMetaClass* metaClass);
109
    void traverseClassMembers(ClassModelItem scopeItem);
110
    void traverseNamespaceMembers(NamespaceModelItem scopeItem);
111
    bool setupInheritance(AbstractMetaClass *metaClass);
112
    AbstractMetaClass *traverseNamespace(NamespaceModelItem item);
113
    AbstractMetaEnum *traverseEnum(EnumModelItem item, AbstractMetaClass *enclosing, const QSet<QString> &enumsDeclarations);
114
    void traverseEnums(ScopeModelItem item, AbstractMetaClass *parent, const QStringList &enumsDeclarations);
115
    void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent);
116
    void applyFunctionModifications(AbstractMetaFunction* func);
117
    void traverseFields(ScopeModelItem item, AbstractMetaClass *parent);
118
    void traverseStreamOperator(FunctionModelItem functionItem);
119
    void traverseOperatorFunction(FunctionModelItem item);
120
    AbstractMetaFunction* traverseFunction(const AddedFunction& addedFunc);
121
    AbstractMetaFunction* traverseFunction(const AddedFunction& addedFunc, AbstractMetaClass* metaClass);
122
    AbstractMetaFunction *traverseFunction(FunctionModelItem function);
123
    AbstractMetaField *traverseField(VariableModelItem field, const AbstractMetaClass *cls);
124
    void checkFunctionModifications();
125
    void registerHashFunction(FunctionModelItem functionItem);
126
    void registerToStringCapability(FunctionModelItem functionItem);
127
128
    /**
129
     *   A conversion operator function should not have its owner class as
130
     *   its return type, but unfortunately it does. This function fixes the
131
     *   return type of operator functions of this kind making the return type
132
     *   be the same as it is supposed to generate when used in C++.
133
     *   If the returned type is a wrapped C++ class, this method also adds the
134
     *   conversion operator to the collection of external conversions of the
135
     *   said class.
136
     *   \param metaFunction conversion operator function to be fixed.
137
     */
138
    void fixReturnTypeOfConversionOperator(AbstractMetaFunction* metaFunction);
139
140
    void parseQ_Property(AbstractMetaClass *metaClass, const QStringList &declarations);
141
    void setupEquals(AbstractMetaClass *metaClass);
142
    void setupComparable(AbstractMetaClass *metaClass);
143
    void setupClonable(AbstractMetaClass *cls);
144
    void setupExternalConversion(AbstractMetaClass* cls);
145
    void setupFunctionDefaults(AbstractMetaFunction *metaFunction, AbstractMetaClass *metaClass);
146
147
    QString fixDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
148
                                  AbstractMetaFunction *fnc, AbstractMetaClass *,
149
                                  int argumentIndex);
150
    AbstractMetaType* translateType(double vr, const AddedFunction::TypeInfo& typeInfo);
151
    AbstractMetaType *translateType(const TypeInfo &type, bool *ok, bool resolveType = true, bool resolveScope = true);
152
153
    int findOutValueFromString(const QString& stringValue, bool& ok);
154
155
    void decideUsagePattern(AbstractMetaType *type);
156
157
    const AbstractMetaFunctionList globalFunctions() const
158
    {
159
        return m_globalFunctions;
160
    }
161
162
    const AbstractMetaEnumList globalEnums() const
163
    {
164
        return m_globalEnums;
165
    }
166
167
    AbstractMetaClassList getBaseClasses(const AbstractMetaClass* metaClass) const;
168
    bool ancestorHasPrivateCopyConstructor(const AbstractMetaClass* metaClass) const;
169
170
    bool inheritTemplate(AbstractMetaClass *subclass,
171
                         const AbstractMetaClass *templateClass,
172
                         const TypeParser::Info &info);
173
    AbstractMetaType *inheritTemplateType(const QList<AbstractMetaType *> &templateTypes, const AbstractMetaType *metaType, bool *ok = 0);
174
175
    bool isQObject(const QString &qualifiedName);
176
    bool isEnum(const QStringList &qualifiedName);
177
178
    void fixQObjectForScope(TypeDatabase* types, NamespaceModelItem item);
179
180
    // QtScript
181
    QSet<QString> qtMetaTypeDeclaredTypeNames() const
182
    {
183
        return m_qmetatypeDeclaredTypenames;
184
    }
185
186
    /**
187
    *   AbstractMetaBuilder should know what's the global header being used,
188
    *   so any class declared under this header wont have the include file
189
    *   filled.
190
    */
191
    void setGlobalHeader(const QString& globalHeader);
192
193
protected:
194
    AbstractMetaClass *argumentToClass(ArgumentModelItem);
195
196
    virtual AbstractMetaClass *createMetaClass()
197
    {
198
        return new AbstractMetaClass();
199
    }
200
201
    virtual AbstractMetaEnum *createMetaEnum()
202
    {
203
        return new AbstractMetaEnum();
204
    }
205
206
    virtual AbstractMetaEnumValue *createMetaEnumValue()
207
    {
208
        return new AbstractMetaEnumValue();
209
    }
210
211
    virtual AbstractMetaField *createMetaField()
212
    {
213
        return new AbstractMetaField();
214
    }
215
216
    virtual AbstractMetaFunction *createMetaFunction()
217
    {
218
        return new AbstractMetaFunction();
219
    }
220
221
    virtual AbstractMetaArgument *createMetaArgument()
222
    {
223
        return new AbstractMetaArgument();
224
    }
225
226
    virtual AbstractMetaType *createMetaType()
227
    {
228
        return new AbstractMetaType();
229
    }
230
231
    FileModelItem m_dom;
232
233
private:
234
    void sortLists();
235
    AbstractMetaArgumentList reverseList(const AbstractMetaArgumentList& list);
236
    void setInclude(TypeEntry* te, const QString& fileName) const;
237
    void fixArgumentNames(AbstractMetaFunction* func);
238
    void fillAddedFunctions(AbstractMetaClass* metaClass);
239
240
    AbstractMetaClassList m_metaClasses;
241
    AbstractMetaClassList m_templates;
242
    AbstractMetaFunctionList m_globalFunctions;
243
    AbstractMetaEnumList m_globalEnums;
244
245
    QSet<const TypeEntry *> m_usedTypes;
246
247
    QMap<QString, RejectReason> m_rejectedClasses;
248
    QMap<QString, RejectReason> m_rejectedEnums;
249
    QMap<QString, RejectReason> m_rejectedFunctions;
250
    QMap<QString, RejectReason> m_rejectedFields;
251
252
    QList<AbstractMetaEnum *> m_enums;
253
254
    QList<QPair<AbstractMetaArgument *, AbstractMetaFunction *> > m_enumDefaultArguments;
255
256
    QHash<QString, AbstractMetaEnumValue *> m_enumValues;
257
258
    AbstractMetaClass *m_currentClass;
259
    QList<ScopeModelItem> m_scopes;
260
    QString m_namespacePrefix;
261
262
    QSet<AbstractMetaClass *> m_setupInheritanceDone;
263
264
    // QtScript
265
    QSet<QString> m_qmetatypeDeclaredTypenames;
266
267
    QString m_logDirectory;
268
    QFileInfo m_globalHeader;
269
};
270
271
#endif // ABSTRACTMETBUILDER_H