| 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 GENERATOR_H |
| 25 |
#define GENERATOR_H |
| 26 |
|
| 27 |
#include <QtCore/QObject> |
| 28 |
#include <QtCore/QDir> |
| 29 |
#include <QtCore/QLinkedList> |
| 30 |
#include <abstractmetalang.h> |
| 31 |
#include "generatorrunnermacros.h" |
| 32 |
|
| 33 |
class ApiExtractor; |
| 34 |
class AbstractMetaBuilder; |
| 35 |
class QFile; |
| 36 |
|
| 37 |
#define EXPORT_GENERATOR_PLUGIN(X)\ |
| 38 |
extern "C" GENRUNNER_EXPORT void getGenerators(GeneratorList* list)\ |
| 39 |
{\ |
| 40 |
*list << X;\ |
| 41 |
}\ |
| 42 |
|
| 43 |
GENRUNNER_API |
| 44 |
QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor); |
| 45 |
GENRUNNER_API |
| 46 |
void verifyDirectoryFor(const QFile &file); |
| 47 |
|
| 48 |
GENRUNNER_API QString getClassTargetFullName(const AbstractMetaClass* metaClass, bool includePackageName = true); |
| 49 |
GENRUNNER_API QString getClassTargetFullName(const AbstractMetaEnum* metaEnum, bool includePackageName = true); |
| 50 |
|
| 51 |
/** |
| 52 |
* Base class for all generators. The default implementations does nothing, |
| 53 |
* you must subclass this to create your own generators. |
| 54 |
*/ |
| 55 |
class GENRUNNER_API Generator |
| 56 |
{ |
| 57 |
public: |
| 58 |
/// Optiosn used around the generator code |
| 59 |
enum Option { |
| 60 |
NoOption = 0x00000000, |
| 61 |
BoxedPrimitive = 0x00000001, |
| 62 |
ExcludeConst = 0x00000002, |
| 63 |
ExcludeReference = 0x00000004, |
| 64 |
UseNativeIds = 0x00000008, |
| 65 |
|
| 66 |
EnumAsInts = 0x00000010, |
| 67 |
SkipName = 0x00000020, |
| 68 |
NoCasts = 0x00000040, |
| 69 |
SkipReturnType = 0x00000080, |
| 70 |
OriginalName = 0x00000100, |
| 71 |
ShowStatic = 0x00000200, |
| 72 |
UnderscoreSpaces = 0x00000400, |
| 73 |
ForceEnumCast = 0x00000800, |
| 74 |
ArrayAsPointer = 0x00001000, |
| 75 |
VirtualCall = 0x00002000, |
| 76 |
SkipTemplateParameters = 0x00004000, |
| 77 |
SkipAttributes = 0x00008000, |
| 78 |
OriginalTypeDescription = 0x00010000, |
| 79 |
SkipRemovedArguments = 0x00020000, |
| 80 |
IncludeDefaultExpression = 0x00040000, |
| 81 |
NoReturnStatement = 0x00080000, |
| 82 |
NoBlockedSlot = 0x00100000, |
| 83 |
|
| 84 |
SuperCall = 0x00200000, |
| 85 |
|
| 86 |
GlobalRefJObject = 0x00100000, |
| 87 |
|
| 88 |
SkipDefaultValues = 0x00400000, |
| 89 |
|
| 90 |
WriteSelf = 0x00800000, |
| 91 |
ExcludeMethodConst = 0x01000000, |
| 92 |
|
| 93 |
ForceValueType = ExcludeReference | ExcludeConst |
| 94 |
}; |
| 95 |
Q_DECLARE_FLAGS(Options, Option) |
| 96 |
|
| 97 |
Generator(); |
| 98 |
virtual ~Generator(); |
| 99 |
|
| 100 |
bool setup(const ApiExtractor& extractor, const QMap<QString, QString> args); |
| 101 |
|
| 102 |
virtual QMap<QString, QString> options() const; |
| 103 |
|
| 104 |
/// Returns the classes used to generate the binding code. |
| 105 |
AbstractMetaClassList classes() const; |
| 106 |
|
| 107 |
/// Returns all global functions found by APIExtractor |
| 108 |
AbstractMetaFunctionList globalFunctions() const; |
| 109 |
|
| 110 |
/// Returns all global enums found by APIExtractor |
| 111 |
AbstractMetaEnumList globalEnums() const; |
| 112 |
|
| 113 |
/// Returns all primitive types found by APIExtractor |
| 114 |
QList<const PrimitiveTypeEntry*> primitiveTypes() const; |
| 115 |
|
| 116 |
/// Returns all container types found by APIExtractor |
| 117 |
QList<const ContainerTypeEntry*> containerTypes() const; |
| 118 |
|
| 119 |
/// Returns an AbstractMetaEnum for a given EnumTypeEntry, or NULL if not found. |
| 120 |
const AbstractMetaEnum* findAbstractMetaEnum(const EnumTypeEntry* typeEntry) const; |
| 121 |
|
| 122 |
/// Returns an AbstractMetaEnum for a given TypeEntry that is an EnumTypeEntry, or NULL if not found. |
| 123 |
const AbstractMetaEnum* findAbstractMetaEnum(const TypeEntry* typeEntry) const; |
| 124 |
|
| 125 |
/// Returns an AbstractMetaEnum for the enum related to a given FlagsTypeEntry, or NULL if not found. |
| 126 |
const AbstractMetaEnum* findAbstractMetaEnum(const FlagsTypeEntry* typeEntry) const; |
| 127 |
|
| 128 |
/// Returns an AbstractMetaEnum for a given AbstractMetaType that holds an EnumTypeEntry, or NULL if not found. |
| 129 |
const AbstractMetaEnum* findAbstractMetaEnum(const AbstractMetaType* metaType) const; |
| 130 |
|
| 131 |
/// Returns the output directory |
| 132 |
QString outputDirectory() const; |
| 133 |
|
| 134 |
/// Set the output directory |
| 135 |
void setOutputDirectory(const QString &outDir); |
| 136 |
|
| 137 |
/** |
| 138 |
* Start the code generation, be sure to call setClasses before callign this method. |
| 139 |
* For each class it creates a QTextStream, call the write method with the current |
| 140 |
* class and the associated text stream, then write the text stream contents if needed. |
| 141 |
* \see #write |
| 142 |
*/ |
| 143 |
void generate(); |
| 144 |
|
| 145 |
/// Returns the number of generated items |
| 146 |
int numGenerated() const; |
| 147 |
|
| 148 |
/// Returns the number of generated items written |
| 149 |
int numGeneratedAndWritten() const; |
| 150 |
|
| 151 |
/// Returns the generator's name. Used for cosmetic purposes. |
| 152 |
virtual const char* name() const = 0; |
| 153 |
|
| 154 |
/// Returns true if the generator should generate any code for the TypeEntry. |
| 155 |
bool shouldGenerateTypeEntry(const TypeEntry*) const; |
| 156 |
|
| 157 |
/// Returns true if the generator should generate any code for the AbstractMetaClass. |
| 158 |
virtual bool shouldGenerate(const AbstractMetaClass *) const; |
| 159 |
|
| 160 |
/// Returns the subdirectory used to write the binding code of an AbstractMetaClass. |
| 161 |
virtual QString subDirectoryForClass(const AbstractMetaClass* clazz) const; |
| 162 |
|
| 163 |
/** |
| 164 |
* Translate metatypes to binding source format. |
| 165 |
* \param metatype a pointer to metatype |
| 166 |
* \param context the current meta class |
| 167 |
* \param option some extra options |
| 168 |
* \return the metatype translated to binding source format |
| 169 |
*/ |
| 170 |
QString translateType(const AbstractMetaType *metatype, |
| 171 |
const AbstractMetaClass *context, |
| 172 |
Options options = NoOption) const; |
| 173 |
|
| 174 |
/** |
| 175 |
* Function used to write the fucntion arguments on the class buffer. |
| 176 |
* \param s the class output buffer |
| 177 |
* \param metafunction the pointer to metafunction information |
| 178 |
* \param count the number of function arguments |
| 179 |
* \param options some extra options used during the parser |
| 180 |
*/ |
| 181 |
virtual void writeFunctionArguments(QTextStream &s, |
| 182 |
const AbstractMetaFunction *metafunction, |
| 183 |
Options options = NoOption) const = 0; |
| 184 |
|
| 185 |
virtual void writeArgumentNames(QTextStream &s, |
| 186 |
const AbstractMetaFunction *metafunction, |
| 187 |
Options options = NoOption) const = 0; |
| 188 |
|
| 189 |
void replaceTemplateVariables(QString &code, const AbstractMetaFunction *func); |
| 190 |
|
| 191 |
// QtScript |
| 192 |
QSet<QString> qtMetaTypeDeclaredTypeNames() const; |
| 193 |
|
| 194 |
/** |
| 195 |
* Returns the license comment to be prepended to each source file generated. |
| 196 |
*/ |
| 197 |
QString licenseComment() const; |
| 198 |
|
| 199 |
/** |
| 200 |
* Sets the license comment to be prepended to each source file generated. |
| 201 |
*/ |
| 202 |
void setLicenseComment(const QString &licenseComment); |
| 203 |
|
| 204 |
/** |
| 205 |
* Returns the package name. |
| 206 |
*/ |
| 207 |
QString packageName() const; |
| 208 |
|
| 209 |
/** |
| 210 |
* Retrieves the name of the currently processed module. |
| 211 |
* While package name is a complete package idetification, e.g. 'PySide.QtCore', |
| 212 |
* a module name represents the last part of the package, e.g. 'QtCore'. |
| 213 |
* If the target language separates the modules with characters other than |
| 214 |
* dots ('.') the generator subclass must overload this method. |
| 215 |
* \return a string representing the last part of a package name |
| 216 |
*/ |
| 217 |
virtual QString moduleName() const; |
| 218 |
|
| 219 |
/** |
| 220 |
* Retrieves a list of constructors used in implicit conversions |
| 221 |
* available on the given type. The TypeEntry must be a value-type |
| 222 |
* or else it will return an empty list. |
| 223 |
* \param type a TypeEntry that is expected to be a value-type |
| 224 |
* \return a list of constructors that could be used as implicit converters |
| 225 |
*/ |
| 226 |
AbstractMetaFunctionList implicitConversions(const TypeEntry* type) const; |
| 227 |
|
| 228 |
/// Convenience function for implicitConversions(const TypeEntry* type). |
| 229 |
AbstractMetaFunctionList implicitConversions(const AbstractMetaType* metaType) const; |
| 230 |
|
| 231 |
/// Check if type is a pointer. |
| 232 |
static bool isPointer(const AbstractMetaType* type); |
| 233 |
|
| 234 |
/// Tells if the type or class is an Object (or QObject) Type. |
| 235 |
static bool isObjectType(const TypeEntry* type); |
| 236 |
static bool isObjectType(const ComplexTypeEntry* type); |
| 237 |
static bool isObjectType(const AbstractMetaType* metaType); |
| 238 |
static bool isObjectType(const AbstractMetaClass* metaClass); |
| 239 |
|
| 240 |
/// Returns true if the type is a C string (const char*). |
| 241 |
static bool isCString(const AbstractMetaType* type); |
| 242 |
/// Returns true if the type is a void pointer. |
| 243 |
static bool isVoidPointer(const AbstractMetaType* type); |
| 244 |
|
| 245 |
// Returns the full name of the type. |
| 246 |
QString getFullTypeName(const TypeEntry* type) const; |
| 247 |
QString getFullTypeName(const AbstractMetaType* type) const; |
| 248 |
QString getFullTypeName(const AbstractMetaClass* metaClass) const; |
| 249 |
|
| 250 |
/** |
| 251 |
* Returns the full qualified C++ name for an AbstractMetaType, but removing modifiers |
| 252 |
* as 'const', '&', and '*' (except if the class is not derived from a template). |
| 253 |
* This is useful for instantiated templates. |
| 254 |
*/ |
| 255 |
QString getFullTypeNameWithoutModifiers(const AbstractMetaType* type) const; |
| 256 |
|
| 257 |
/** |
| 258 |
* Tries to build a minimal constructor for the type. |
| 259 |
* It will check first for a user defined default constructor. |
| 260 |
* Returns a null string if it fails. |
| 261 |
*/ |
| 262 |
QString minimalConstructor(const TypeEntry* type) const; |
| 263 |
QString minimalConstructor(const AbstractMetaType* type) const; |
| 264 |
QString minimalConstructor(const AbstractMetaClass* metaClass) const; |
| 265 |
protected: |
| 266 |
/** |
| 267 |
* Returns the file name used to write the binding code of an AbstractMetaClass. |
| 268 |
* \param metaClass the AbstractMetaClass for which the file name must be |
| 269 |
* returned |
| 270 |
* \return the file name used to write the binding code for the class |
| 271 |
*/ |
| 272 |
virtual QString fileNameForClass(const AbstractMetaClass* metaClass) const = 0; |
| 273 |
|
| 274 |
|
| 275 |
virtual bool doSetup(const QMap<QString, QString>& args) = 0; |
| 276 |
|
| 277 |
/** |
| 278 |
* Write the bindding code for an AbstractMetaClass. |
| 279 |
* This is called by generate method. |
| 280 |
* \param s text stream to write the generated output |
| 281 |
* \param metaClass the class that should be generated |
| 282 |
*/ |
| 283 |
virtual void generateClass(QTextStream& s, const AbstractMetaClass* metaClass) = 0; |
| 284 |
virtual void finishGeneration() = 0; |
| 285 |
|
| 286 |
/** |
| 287 |
* Returns the subdirectory path for a given package |
| 288 |
* (aka module, aka library) name. |
| 289 |
* If the target language separates the package modules with characters other |
| 290 |
* than dots ('.') the generator subclass must overload this method. |
| 291 |
* /param packageName complete package name for which to return the subdirectory path |
| 292 |
* or nothing the use the name of the currently processed package |
| 293 |
* /return a string representing the subdirectory path for the given package |
| 294 |
*/ |
| 295 |
virtual QString subDirectoryForPackage(QString packageName = QString()) const; |
| 296 |
|
| 297 |
QList<const AbstractMetaType*> instantiatedContainers() const; |
| 298 |
|
| 299 |
static QString getSimplifiedContainerTypeName(const AbstractMetaType* type); |
| 300 |
void addInstantiatedContainers(const AbstractMetaType* type); |
| 301 |
|
| 302 |
private: |
| 303 |
struct GeneratorPrivate; |
| 304 |
GeneratorPrivate* m_d; |
| 305 |
void collectInstantiatedContainers(const AbstractMetaFunction* func); |
| 306 |
void collectInstantiatedContainers(const AbstractMetaClass* metaClass); |
| 307 |
void collectInstantiatedContainers(); |
| 308 |
}; |
| 309 |
|
| 310 |
Q_DECLARE_OPERATORS_FOR_FLAGS(Generator::Options) |
| 311 |
typedef QLinkedList<Generator*> GeneratorList; |
| 312 |
|
| 313 |
/** |
| 314 |
* Utility class to store the identation level, use it in a QTextStream. |
| 315 |
*/ |
| 316 |
class GENRUNNER_API Indentor |
| 317 |
{ |
| 318 |
public: |
| 319 |
Indentor() : indent(0) {} |
| 320 |
int indent; |
| 321 |
}; |
| 322 |
|
| 323 |
/** |
| 324 |
* Class that use the RAII idiom to set and unset the identation level. |
| 325 |
*/ |
| 326 |
class GENRUNNER_API Indentation |
| 327 |
{ |
| 328 |
public: |
| 329 |
Indentation(Indentor &indentor) : indentor(indentor) |
| 330 |
{ |
| 331 |
indentor.indent++; |
| 332 |
} |
| 333 |
~Indentation() |
| 334 |
{ |
| 335 |
indentor.indent--; |
| 336 |
} |
| 337 |
|
| 338 |
private: |
| 339 |
Indentor &indentor; |
| 340 |
}; |
| 341 |
|
| 342 |
GENRUNNER_API inline QTextStream &operator <<(QTextStream &s, const Indentor &indentor) |
| 343 |
{ |
| 344 |
for (int i = 0; i < indentor.indent; ++i) |
| 345 |
s << " "; |
| 346 |
return s; |
| 347 |
} |
| 348 |
|
| 349 |
#endif // GENERATOR_H |