diff options
-rw-r--r-- | CMakeLists.txt | 12 | ||||
-rw-r--r-- | apiextractor.cpp | 243 | ||||
-rw-r--r-- | apiextractor.h | 35 | ||||
-rw-r--r-- | fileout.h | 2 | ||||
-rw-r--r-- | generator.cpp | 146 | ||||
-rw-r--r-- | generator.h | 358 | ||||
-rw-r--r-- | typesystem.cpp | 78 | ||||
-rw-r--r-- | typesystem.h | 3 |
8 files changed, 66 insertions, 811 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8de46e16e..5072bf4d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,6 @@ docparser.cpp doxygenparser.cpp qtdocparser.cpp fileout.cpp -generator.cpp reporthandler.cpp typeparser.cpp typesystem.cpp @@ -59,13 +58,7 @@ parser/rpp/preprocessor.cpp ) qt4_add_resources(apiextractor_RCCS_SRC generator.qrc) - -set(apiextractor_MOC_HEADERS - fileout.h - generator.h -) - -qt4_wrap_cpp(apiextractor_MOC_SRC ${apiextractor_MOC_HEADERS}) +qt4_automoc(apiextractor_SRC) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} @@ -76,7 +69,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${LIBXML2_INCLUDE_DIRS} ) -add_library(apiextractor SHARED ${apiextractor_SRC} ${apiextractor_MOC_SRC} ${apiextractor_RCCS_SRC}) +add_library(apiextractor SHARED ${apiextractor_SRC} ${apiextractor_RCCS_SRC}) target_link_libraries(apiextractor ${Boost_GRAPH_LIBRARY} ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTXMLPATTERNS_LIBRARY} ${QT_QTXML_LIBRARY}) set_target_properties(apiextractor PROPERTIES SOVERSION ${apiextractor_VERSION}) @@ -103,7 +96,6 @@ add_custom_target(dist set(root_HEADERS abstractmetalang.h -generator.h apiextractor.h reporthandler.h typesystem.h diff --git a/apiextractor.cpp b/apiextractor.cpp index d2ef9ee23..8c7ea145e 100644 --- a/apiextractor.cpp +++ b/apiextractor.cpp @@ -22,8 +22,9 @@ */ #include "apiextractor.h" -#include <QtCore/QDir> -#include <QtCore/QDebug> +#include <QDir> +#include <QDebug> +#include <QTemporaryFile> #include <iostream> #include "reporthandler.h" @@ -31,207 +32,79 @@ #include "fileout.h" #include "parser/rpp/pp.h" #include "abstractmetabuilder.h" -#include "generator.h" #include "apiextractorversion.h" static bool preprocess(const QString& sourceFile, - const QString& targetFile, - const QString& commandLineIncludes); + QFile& targetFile, + const QStringList& includes); -ApiExtractor::ApiExtractor(int argc, char** argv) : m_versionHandler(0) +ApiExtractor::ApiExtractor() { - m_programName = argv[0]; - // store args in m_args map - int argNum = 0; - for (int i = 1; i < argc; ++i) { - QString arg(argv[i]); - arg = arg.trimmed(); - if (arg.startsWith("--")) { - int split = arg.indexOf("="); - if (split > 0) - m_args[arg.mid(2).left(split-2)] = arg.mid(split + 1).trimmed(); - else - m_args[arg.mid(2)] = QString(); - } else if (arg.startsWith("-")) { - m_args[arg.mid(1)] = QString(); - } else { - argNum++; - m_args[QString("arg-%1").arg(argNum)] = arg; - } - } - // Environment TYPESYSTEMPATH QString envTypesystemPaths = getenv("TYPESYSTEMPATH"); - TypeDatabase::instance()->addTypesystemPath(envTypesystemPaths); + if (!envTypesystemPaths.isEmpty()) + TypeDatabase::instance()->addTypesystemPath(envTypesystemPaths); ReportHandler::setContext("ApiExtractor"); } ApiExtractor::~ApiExtractor() { - qDeleteAll(m_generators); } -void ApiExtractor::addGenerator(Generator* generator) +void ApiExtractor::addTypesystemSearchPath ( const QString& path ) { - m_generators << generator; + TypeDatabase::instance()->addTypesystemPath(path); } -bool ApiExtractor::parseGeneralArgs() +void ApiExtractor::addIncludePath ( const QString& path ) { - // set debug level - if (m_args.contains("silent")) { - ReportHandler::setSilent(true); - } else if (m_args.contains("debug-level")) { - QString level = m_args.value("debug-level"); - if (level == "sparse") - ReportHandler::setDebugLevel(ReportHandler::SparseDebug); - else if (level == "medium") - ReportHandler::setDebugLevel(ReportHandler::MediumDebug); - else if (level == "full") - ReportHandler::setDebugLevel(ReportHandler::FullDebug); - } - - if (m_args.contains("no-suppress-warnings")) { - TypeDatabase *db = TypeDatabase::instance(); - db->setSuppressWarnings(false); - } - - if (m_args.contains("dummy")) - FileOut::dummy = true; - - if (m_args.contains("diff")) - FileOut::diff = true; - - if (m_args.count() == 1) - return false; - - if (m_args.contains("typesystem-paths")) - TypeDatabase::instance()->addTypesystemPath(m_args.value("typesystem-paths")); - - m_globalHeaderFileName = m_args.value("arg-1"); - m_typeSystemFileName = m_args.value("arg-2"); - if (m_args.contains("arg-3")) - return false; - - if (m_globalHeaderFileName.isEmpty() || m_typeSystemFileName.isEmpty()) - return false; - return true; + m_includePaths << path; } -int ApiExtractor::exec() +void ApiExtractor::setCppFileName(const QString& cppFileName) { - if (m_args.contains("version")) { - if (m_versionHandler) - m_versionHandler("ApiExtractor v" APIEXTRACTOR_VERSION); - else - std::cout << m_programName << " using ApiExtractor v" APIEXTRACTOR_VERSION << std::endl; - return 0; - } else if (!parseGeneralArgs()) { - printUsage(); - return 1; - } - - QLatin1String ppFileName(".preprocessed.tmp"); - - if (!TypeDatabase::instance()->parseFile(m_typeSystemFileName)) - std::cerr << "Cannot parse file: " << qPrintable(m_typeSystemFileName); - - if (!preprocess(m_globalHeaderFileName, ppFileName, m_args.value("include-paths"))) { - std::cerr << "Preprocessor failed on file: " << qPrintable(m_globalHeaderFileName); - return 1; - } - - QString licenseComment; - if (m_args.contains("license-file") && !m_args.value("license-file").isEmpty()) { - QString license_filename = m_args.value("license-file"); - if (QFile::exists(license_filename)) { - QFile license_file(license_filename); - if (license_file.open(QIODevice::ReadOnly)) - licenseComment = license_file.readAll(); - } else { - std::cerr << "Couldn't find the file containing the license heading: "; - std::cerr << qPrintable(license_filename); - return 1; - } - } - - AbstractMetaBuilder builder; - QFile ppFile(ppFileName); - builder.build(&ppFile); + m_cppFileName = cppFileName; +} - QString outputDirectory = m_args.contains("output-directory") ? m_args["output-directory"] : "out"; - bool docOnly = m_args.contains("documentation-only"); - foreach (Generator* g, m_generators) { - bool docGen = g->type() == Generator::DocumentationType; - bool missingDocInfo = m_args["library-source-dir"].isEmpty() - || m_args["documentation-data-dir"].isEmpty(); - if ((!docGen && docOnly) || (docGen && missingDocInfo)) { - std::cout << "Skipping " << g->name() << std::endl; - continue; - } - g->setOutputDirectory(outputDirectory); - g->setLicenseComment(licenseComment); - g->setBuilder(&builder); - std::cout << "Running " << g->name() << std::endl; - if (g->prepareGeneration(m_args)) - g->generate(); - } +void ApiExtractor::setTypeSystem(const QString& typeSystemFileName) +{ + m_typeSystemFileName = typeSystemFileName; +} - std::cout << "Done, " << ReportHandler::warningCount(); - std::cout << " warnings (" << ReportHandler::suppressedCount() << " known issues)"; - std::cout << std::endl; - return 0; +void ApiExtractor::setDebugLevel(ReportHandler::DebugLevel debugLevel) +{ + ReportHandler::setDebugLevel(debugLevel); } -static void printOptions(QTextStream& s, const QMap<QString, QString>& options) { - QMap<QString, QString>::const_iterator it = options.constBegin(); - s.setFieldAlignment(QTextStream::AlignLeft); - for (; it != options.constEnd(); ++it) { - s << " --"; - s.setFieldWidth(38); - s << it.key() << it.value(); - s.setFieldWidth(0); - s << endl; - } +void ApiExtractor::setSupressWarnings ( bool value ) +{ + TypeDatabase::instance()->setSuppressWarnings(value); } -void ApiExtractor::printUsage() +bool ApiExtractor::run() { - #if defined(Q_OS_WIN32) - #define PATHSPLITTER ";" - #else - #define PATHSPLITTER ":" - #endif - QTextStream s(stdout); - s << "Usage:\n " - << m_programName << " [options] header-file typesystem-file\n\n" - "General options:\n"; - QMap<QString, QString> generalOptions; - generalOptions.insert("debug-level=[sparse|medium|full]", "Set the debug level"); - generalOptions.insert("silent", "Avoid printing any message"); - generalOptions.insert("help", "Display this help and exit"); - generalOptions.insert("no-suppress-warnings", "Show all warnings"); - generalOptions.insert("output-directory=[dir]", "The directory where the generated files will be written"); - generalOptions.insert("include-paths=<path>[" PATHSPLITTER "<path>" PATHSPLITTER "...]", "Include paths used by the C++ parser"); - generalOptions.insert("typesystem-paths=<path>[" PATHSPLITTER "<path>" PATHSPLITTER "...]", "Paths used when searching for typesystems"); - generalOptions.insert("documentation-only", "Do not generates any code, just the documentation"); - generalOptions.insert("license-file=[licensefile]", "File used for copyright headers of generated files"); - generalOptions.insert("version", "Output version information and exit"); - printOptions(s, generalOptions); + if (m_builder) + return false; + // read typesystem + if (!TypeDatabase::instance()->parseFile(m_typeSystemFileName)) { + std::cerr << "Cannot parse file: " << qPrintable(m_typeSystemFileName); + return false; + } - foreach (Generator* generator, m_generators) { - QMap<QString, QString> options = generator->options(); - if (!options.isEmpty()) { - s << endl << generator->name() << " options:\n"; - printOptions(s, generator->options()); - } + QTemporaryFile ppFile; + // run rpp pre-processor + if (!preprocess(m_cppFileName, ppFile, m_includePaths)) { + std::cerr << "Preprocessor failed on file: " << qPrintable(m_cppFileName); + return 1; } + m_builder = new AbstractMetaBuilder; + m_builder->build(&ppFile); + return true; } - static bool preprocess(const QString& sourceFile, - const QString& targetFile, - const QString& commandLineIncludes) + QFile& targetFile, + const QStringList& includes) { rpp::pp_environment env; rpp::pp preprocess(env); @@ -250,26 +123,8 @@ static bool preprocess(const QString& sourceFile, file.close(); preprocess.operator()(ba.constData(), ba.constData() + ba.size(), null_out); - QStringList includes; - -#if defined(Q_OS_WIN32) - char *pathSplitter = const_cast<char *>(";"); -#else - char *pathSplitter = const_cast<char *>(":"); -#endif - - // Environment INCLUDE - QString includePath = getenv("INCLUDE"); - if (!includePath.isEmpty()) - includes += includePath.split(pathSplitter); - - // Includes from the command line - if (!commandLineIncludes.isEmpty()) - includes += commandLineIncludes.split(pathSplitter); - - includes << QLatin1String("."); - includes << QLatin1String("/usr/include"); - + preprocess.push_include_path("."); + preprocess.push_include_path("/usr/include"); foreach (QString include, includes) preprocess.push_include_path(QDir::convertSeparators(include).toStdString()); @@ -294,14 +149,12 @@ static bool preprocess(const QString& sourceFile, QDir::setCurrent(currentDir); - QFile f(targetFile); - if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) { - std::cerr << "Failed to write preprocessed file: " << qPrintable(targetFile) << std::endl; + if (!targetFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + std::cerr << "Failed to write preprocessed file: " << qPrintable(targetFile.fileName()) << std::endl; return false; } - f.write(result.c_str(), result.length()); - + targetFile.write(result.c_str(), result.length()); return true; } diff --git a/apiextractor.h b/apiextractor.h index 301e8cdd3..cc98cd15a 100644 --- a/apiextractor.h +++ b/apiextractor.h @@ -24,36 +24,31 @@ #ifndef APIEXTRACTOR_H #define APIEXTRACTOR_H -#include <QLinkedList> -#include <QMap> -#include <QString> +#include "reporthandler.h" +#include <QStringList> -class Generator; +class AbstractMetaBuilder; +class QIODevice; class ApiExtractor { public: - ApiExtractor(int argc, char** argv); + ApiExtractor(); ~ApiExtractor(); - void addGenerator(Generator* generator); - void setVersionHandler(void (*versionHandler)(const char*)) - { - m_versionHandler = versionHandler; - } - - int exec(); + void setTypeSystem(const QString& typeSystemFileName); + void setCppFileName(const QString& cppFileName); + void setDebugLevel(ReportHandler::DebugLevel debugLevel); + void setSupressWarnings(bool value); + void addTypesystemSearchPath(const QString& path); + void addIncludePath(const QString& path); + bool run(); private: - QLinkedList<Generator*> m_generators; - QMap<QString, QString> m_args; QString m_typeSystemFileName; - QString m_globalHeaderFileName; - const char* m_programName; - void (*m_versionHandler)(const char*); - - bool parseGeneralArgs(); - void printUsage(); + QString m_cppFileName; + QStringList m_includePaths; + AbstractMetaBuilder* m_builder; // disable copy ApiExtractor(const ApiExtractor&); @@ -30,8 +30,6 @@ class FileOut : public QObject { - Q_OBJECT - private: QByteArray tmp; QString name; diff --git a/generator.cpp b/generator.cpp deleted file mode 100644 index 46de409c9..000000000 --- a/generator.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of the API Extractor project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team <contact@pyside.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "generator.h" -#include "reporthandler.h" -#include "fileout.h" - -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QFileInfo> -#include <QDebug> -#include "abstractmetabuilder.h" - -Generator::Generator() : m_numGenerated(0), m_numGeneratedWritten(0) -{} - -Generator::~Generator() -{ -} - -void Generator::setBuilder(AbstractMetaBuilder* builder) -{ - m_globalEnums = builder->globalEnums(); - m_globalFunctions = builder->globalFunctions(); - m_classes = builder->classes(); - m_primitiveTypes = TypeDatabase::instance()->primitiveTypes(); - m_containerTypes = TypeDatabase::instance()->containerTypes(); - foreach (const AbstractMetaClass* cppClass, m_classes) { - if (m_packageName.isEmpty() - && cppClass->typeEntry()->generateCode() - && !cppClass->package().isEmpty()) { - m_packageName = cppClass->package(); - break; - } - } - // does anyone use this? - m_qmetatypeDeclaredTypenames = builder->qtMetaTypeDeclaredTypeNames(); -} - -void Generator::generate() -{ - if (m_classes.isEmpty()) { - ReportHandler::warning(QString("%1: no classes, skipping") - .arg(metaObject()->className())); - return; - } - - foreach (AbstractMetaClass *cls, m_classes) { - if (!shouldGenerate(cls)) - continue; - - QString fileName = fileNameForClass(cls); - if (fileName.isNull()) - continue; - ReportHandler::debugSparse(QString("generating: %1").arg(fileName)); - - FileOut fileOut(outputDirectory() + '/' + subDirectoryForClass(cls) + '/' + fileName); - generateClass(fileOut.stream, cls); - - if (fileOut.done()) - ++m_numGeneratedWritten; - ++m_numGenerated; - } - finishGeneration(); -} - -bool Generator::shouldGenerate(const AbstractMetaClass* metaClass) const -{ - return metaClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang; -} - -void Generator::verifyDirectoryFor(const QFile &file) -{ - QDir dir = QFileInfo(file).dir(); - if (!dir.exists()) { - if (!dir.mkpath(dir.absolutePath())) - ReportHandler::warning(QString("unable to create directory '%1'") - .arg(dir.absolutePath())); - } -} - -bool Generator::hasDefaultConstructor(const AbstractMetaType *type) -{ - QString full_name = type->typeEntry()->qualifiedTargetLangName(); - QString class_name = type->typeEntry()->targetLangName(); - - foreach (const AbstractMetaClass *cls, m_classes) { - if (cls->typeEntry()->qualifiedTargetLangName() == full_name) { - AbstractMetaFunctionList functions = cls->functions(); - foreach (const AbstractMetaFunction *function, functions) { - if (function->arguments().isEmpty() && function->name() == class_name) - return true; - } - return false; - } - } - return false; -} - -void Generator::replaceTemplateVariables(QString &code, const AbstractMetaFunction *func) -{ - const AbstractMetaClass *cpp_class = func->ownerClass(); - code.replace("%TYPE", cpp_class->name()); - - foreach (AbstractMetaArgument *arg, func->arguments()) - code.replace("%" + QString::number(arg->argumentIndex() + 1), arg->argumentName()); - - //template values - code.replace("%RETURN_TYPE", translateType(func->type(), cpp_class)); - code.replace("%FUNCTION_NAME", func->originalName()); - - if (code.contains("%ARGUMENT_NAMES")) { - QString str; - QTextStream aux_stream(&str); - writeArgumentNames(aux_stream, func, Generator::SkipRemovedArguments); - code.replace("%ARGUMENT_NAMES", str); - } - - if (code.contains("%ARGUMENTS")) { - QString str; - QTextStream aux_stream(&str); - writeFunctionArguments(aux_stream, func, Generator::SkipDefaultValues | Generator::SkipRemovedArguments); - code.replace("%ARGUMENTS", str); - } -} - diff --git a/generator.h b/generator.h deleted file mode 100644 index 0be9e6c73..000000000 --- a/generator.h +++ /dev/null @@ -1,358 +0,0 @@ -/* - * This file is part of the API Extractor project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team <contact@pyside.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef GENERATOR_H -#define GENERATOR_H - -#include <QtCore/QObject> -#include <QtCore/QDir> -#include "abstractmetalang.h" - -class AbstractMetaBuilder; -class QFile; - -/** - * Base class for all generators. The default implementations does nothing, - * you must subclass this to create your own generators. - */ -class Generator : public QObject -{ - Q_OBJECT - - Q_PROPERTY(QString outputDirectory READ outputDirectory WRITE setOutputDirectory); - -public: - enum GeneratorType { - CodeType, - DocumentationType - }; - /// Optiosn used around the generator code - enum Option { - NoOption = 0x00000000, - BoxedPrimitive = 0x00000001, - ExcludeConst = 0x00000002, - ExcludeReference = 0x00000004, - UseNativeIds = 0x00000008, - - EnumAsInts = 0x00000010, - SkipName = 0x00000020, - NoCasts = 0x00000040, - SkipReturnType = 0x00000080, - OriginalName = 0x00000100, - ShowStatic = 0x00000200, - UnderscoreSpaces = 0x00000400, - ForceEnumCast = 0x00000800, - ArrayAsPointer = 0x00001000, - VirtualCall = 0x00002000, - SkipTemplateParameters = 0x00004000, - SkipAttributes = 0x00008000, - OriginalTypeDescription = 0x00010000, - SkipRemovedArguments = 0x00020000, - IncludeDefaultExpression = 0x00040000, - NoReturnStatement = 0x00080000, - NoBlockedSlot = 0x00100000, - - SuperCall = 0x00200000, - - GlobalRefJObject = 0x00100000, - - SkipDefaultValues = 0x00400000, - - WriteSelf = 0x00800000, - ExcludeMethodConst = 0x01000000, - - ForceValueType = ExcludeReference | ExcludeConst - }; - - Generator(); - virtual ~Generator(); - - void setBuilder(AbstractMetaBuilder* builder); - /** - * Returns the generator name. - */ - virtual const char* name() const - { - return "<Unnamed>"; - } - - virtual QMap<QString, QString> options() const - { - return QMap<QString, QString>(); - } - - /** - * The Generator identifies itself through this method, - * as a CodeType generator or a DocumentationType generator. - * If not reimplemented this method the Generator will be - * of CodeType. - * /return a GeneratorType value identifying the kind of - * generator this is - */ - virtual GeneratorType type() const - { - return CodeType; - } - - /// Returns the classes used to generate the binding code. - AbstractMetaClassList classes() const - { - return m_classes; - } - - AbstractMetaFunctionList globalFunctions() const - { - return m_globalFunctions; - } - - AbstractMetaEnumList globalEnums() const - { - return m_globalEnums; - } - - QList<const PrimitiveTypeEntry*> primitiveTypes() const - { - return m_primitiveTypes; - } - - QList<const ContainerTypeEntry*> containerTypes() const - { - return m_containerTypes; - } - - /// Returns the output directory - QString outputDirectory() const - { - return m_outDir; - } - - /// Set the output directory - void setOutputDirectory(const QString &outDir) - { - m_outDir = outDir; - } - - virtual bool prepareGeneration(const QMap<QString, QString>& args) = 0; - /** - * Start the code generation, be sure to call setClasses before callign this method. - * For each class it creates a QTextStream, call the write method with the current - * class and the associated text stream, then write the text stream contents if needed. - * \see #write - */ - void generate(); - - /// Returns the number of generated items - int numGenerated() - { - return m_numGenerated; - } - - /// Returns the number of generated items written - int numGeneratedAndWritten() - { - return m_numGeneratedWritten; - } - - /// Returns true if the generator should generate any code for the AbstractMetaClass - virtual bool shouldGenerate(const AbstractMetaClass *) const; - - /// Returns the subdirectory used to write the binding code of an AbstractMetaClass. - virtual QString subDirectoryForClass(const AbstractMetaClass* clazz) const = 0; - - /** - * Translate metatypes to binding source format. - * \param metatype a pointer to metatype - * \param context the current meta class - * \param option some extra options - * \return the metatype translated to binding source format - */ - virtual QString translateType(const AbstractMetaType *metatype, - const AbstractMetaClass *context, - int option = NoOption) const = 0; - - /** - * Function used to write the fucntion arguments on the class buffer. - * \param s the class output buffer - * \param metafunction the pointer to metafunction information - * \param count the number of function arguments - * \param options some extra options used during the parser - */ - virtual void writeFunctionArguments(QTextStream &s, - const AbstractMetaFunction *metafunction, - uint options = 0) const = 0; - - virtual void writeArgumentNames(QTextStream &s, - const AbstractMetaFunction *metafunction, - uint options = 0) const = 0; - - void replaceTemplateVariables(QString &code, const AbstractMetaFunction *func); - - bool hasDefaultConstructor(const AbstractMetaType *type); - - // QtScript - QSet<QString> qtMetaTypeDeclaredTypeNames() const - { - return m_qmetatypeDeclaredTypenames; - } - - /** - * Returns the license comment to be prepended to each source file generated. - */ - QString licenseComment() - { - return m_licenseComment; - } - - /** - * Sets the license comment to be prepended to each source file generated. - */ - void setLicenseComment(const QString &licenseComment) - { - m_licenseComment = licenseComment; - } - - /** - * Returns the package name. - */ - QString packageName() - { - return m_packageName; - } - - /** - * Sets the package name. - */ - void setPackageName(const QString &packageName) - { - m_packageName = packageName; - } - - /** - * Retrieves the name of the currently processed module. While package name - * is a complete package idetification, e.g. 'PySide.QtCore', a module name - * represents the last part of the package, e.g. 'QtCore'. - * If the target language separates the modules with characters other than - * dots ('.') the generator subclass must overload this method. - * /return a string representing the last part of a package name - */ - virtual QString moduleName() - { - return QString(m_packageName).remove(0, m_packageName.lastIndexOf('.') + 1); - } - -protected: - QString m_packageName; - - /** - * Returns the file name used to write the binding code of an AbstractMetaClass. - * /param metaClass the AbstractMetaClass for which the file name must be - * returned - * /return the file name used to write the binding code for the class - */ - virtual QString fileNameForClass(const AbstractMetaClass* metaClass) const = 0; - - /** - * Returns the subdirectory path for a given package - * (aka module, aka library) name. - * If the target language separates the package modules with characters other - * than dots ('.') the generator subclass must overload this method. - * /param packageName complete package name for which to return the subdirectory path - * or nothing the use the name of the currently processed package - * /return a string representing the subdirectory path for the given package - */ - virtual QString subDirectoryForPackage(QString packageName = QString()) const - { - if (packageName.isEmpty()) - packageName = m_packageName; - return QString(packageName).replace(".", QDir::separator()); - } - - /** - * Write the bindding code for an AbstractMetaClass. - * This is called by the default implementation of generate method. - * \param s text stream to write the generated output - * \param metaClass the class that should be generated - */ - virtual void generateClass(QTextStream& s, const AbstractMetaClass* metaClass) = 0; - virtual void finishGeneration() = 0; - - void verifyDirectoryFor(const QFile &file); - - int m_numGenerated; - int m_numGeneratedWritten; - -private: - AbstractMetaClassList m_classes; - AbstractMetaFunctionList m_globalFunctions; - AbstractMetaEnumList m_globalEnums; - QString m_outDir; - - QList<const PrimitiveTypeEntry*> m_primitiveTypes; - QList<const ContainerTypeEntry*> m_containerTypes; - - // QtScript - QSet<QString> m_qmetatypeDeclaredTypenames; - - // License comment - QString m_licenseComment; -}; - -/** -* Utility class to store the identation level, use it in a QTextStream. -*/ -class Indentor -{ -public: - Indentor(): - indent(0) {} - int indent; -}; - -/** -* Class that use the RAII idiom to set and unset the identation level. -*/ -class Indentation -{ -public: - Indentation(Indentor &indentor) : indentor(indentor) - { - indentor.indent++; - } - ~Indentation() - { - indentor.indent--; - } - -private: - Indentor &indentor; -}; - -inline QTextStream &operator <<(QTextStream &s, const Indentor &indentor) -{ - for (int i = 0; i < indentor.indent; ++i) - s << " "; - return s; -} - -#endif // GENERATOR_H - diff --git a/typesystem.cpp b/typesystem.cpp index 2a17d703b..6475db065 100644 --- a/typesystem.cpp +++ b/typesystem.cpp @@ -22,10 +22,7 @@ */ #include "typesystem.h" -#include "generator.h" - -#include <reporthandler.h> - +#include "reporthandler.h" #include <Qt/QtXml> QString strings_Object = QLatin1String("Object"); @@ -1923,79 +1920,6 @@ QString fixCppTypeName(const QString &name) return name; } -QString formattedCodeHelper(QTextStream &s, Indentor &indentor, QStringList &lines) -{ - bool multilineComment = false; - bool lastEmpty = true; - QString lastLine; - while (!lines.isEmpty()) { - const QString line = lines.takeFirst().trimmed(); - if (line.isEmpty()) { - if (!lastEmpty) - s << endl; - lastEmpty = true; - continue; - } else - lastEmpty = false; - - if (line.startsWith("/*")) - multilineComment = true; - - if (multilineComment) { - s << indentor; - if (line.startsWith("*")) - s << " "; - s << line << endl; - if (line.endsWith("*/")) - multilineComment = false; - } else if (line.startsWith("}")) - return line; - else if (line.endsWith("")) { - s << indentor << line << endl; - return 0; - } else if (line.endsWith("{")) { - s << indentor << line << endl; - QString tmp; - { - Indentation indent(indentor); - tmp = formattedCodeHelper(s, indentor, lines); - } - if (!tmp.isNull()) - s << indentor << tmp << endl; - - lastLine = tmp; - continue; - } else { - s << indentor; - if (!lastLine.isEmpty() && - !lastLine.endsWith(";") && - !line.startsWith("@") && - !line.startsWith("//") && - !lastLine.startsWith("//") && - !lastLine.endsWith("}") && - !line.startsWith("{")) - s << " "; - s << line << endl; - } - lastLine = line; - } - return 0; -} - - -QTextStream &CodeSnip::formattedCode(QTextStream &s, Indentor &indentor) const -{ - QStringList lst(code().split("\n")); - while (!lst.isEmpty()) { - QString tmp = formattedCodeHelper(s, indentor, lst); - if (!tmp.isNull()) - s << indentor << tmp << endl; - - } - s.flush(); - return s; -} - QString TemplateInstance::expandCode() const { TemplateEntry *templateEntry = TypeDatabase::instance()->findTemplate(m_name); diff --git a/typesystem.h b/typesystem.h index f03fd04ee..f96e60836 100644 --- a/typesystem.h +++ b/typesystem.h @@ -248,9 +248,6 @@ public: CodeSnip() : language(TypeSystem::TargetLangCode) { } CodeSnip(TypeSystem::Language lang) : language(lang) { } - // Very simple, easy to make code ugly if you try - QTextStream &formattedCode(QTextStream &s, Indentor &indentor) const; - TypeSystem::Language language; Position position; ArgumentMap argumentMap; |