aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/generator
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/generator')
-rw-r--r--sources/shiboken2/generator/generator.cpp99
-rw-r--r--sources/shiboken2/generator/generator.h14
-rw-r--r--sources/shiboken2/generator/main.cpp221
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp956
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.h49
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp528
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.h14
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp82
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.h10
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp146
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.h14
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp533
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h28
13 files changed, 1682 insertions, 1012 deletions
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index d7f98a90f..71647a1c5 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -36,6 +36,7 @@
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
+#include <QtCore/QRegularExpression>
#include <QDebug>
#include <typedatabase.h>
@@ -48,18 +49,14 @@ struct Generator::GeneratorPrivate {
int numGenerated;
QStringList instantiatedContainersNames;
QStringList instantiatedSmartPointerNames;
- QList<const AbstractMetaType *> instantiatedContainers;
- QList<const AbstractMetaType *> instantiatedSmartPointers;
+ QVector<const AbstractMetaType *> instantiatedContainers;
+ QVector<const AbstractMetaType *> instantiatedSmartPointers;
};
Generator::Generator() : m_d(new GeneratorPrivate)
{
m_d->numGenerated = 0;
- m_d->instantiatedContainers = QList<const AbstractMetaType *>();
- m_d->instantiatedSmartPointers = QList<const AbstractMetaType *>();
- m_d->instantiatedContainersNames = QStringList();
- m_d->instantiatedSmartPointerNames = QStringList();
}
Generator::~Generator()
@@ -73,7 +70,7 @@ bool Generator::setup(const ApiExtractor& extractor, const QMap< QString, QStrin
TypeEntryHash allEntries = TypeDatabase::instance()->allEntries();
TypeEntry* entryFound = 0;
for (TypeEntryHash::const_iterator it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) {
- foreach (TypeEntry *entry, it.value()) {
+ for (TypeEntry *entry : it.value()) {
if (entry->type() == TypeEntry::TypeSystemType && entry->generateCode()) {
entryFound = entry;
break;
@@ -120,7 +117,8 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType
{
if (!type)
return;
- foreach (const AbstractMetaType* t, type->instantiations())
+ const AbstractMetaTypeList &instantiations = type->instantiations();
+ for (const AbstractMetaType* t : instantiations)
addInstantiatedContainersAndSmartPointers(t, context);
if (!type->typeEntry()->isContainer() && !type->typeEntry()->isSmartPointer())
return;
@@ -129,7 +127,7 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType
QString piece = isContainer ? QStringLiteral("container") : QStringLiteral("smart pointer");
QString warning =
QString::fromLatin1("Skipping instantiation of %1 '%2' because it has template"
- " arguments.").arg(piece).arg(type->originalTypeDescription());
+ " arguments.").arg(piece, type->originalTypeDescription());
if (!context.isEmpty())
warning.append(QStringLiteral(" Calling context: %1").arg(context));
@@ -156,7 +154,8 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType
void Generator::collectInstantiatedContainersAndSmartPointers(const AbstractMetaFunction *func)
{
addInstantiatedContainersAndSmartPointers(func->type(), func->signature());
- foreach (const AbstractMetaArgument* arg, func->arguments())
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments)
addInstantiatedContainersAndSmartPointers(arg->type(), func->signature());
}
@@ -164,35 +163,40 @@ void Generator::collectInstantiatedContainersAndSmartPointers(const AbstractMeta
{
if (!metaClass->typeEntry()->generateCode())
return;
- foreach (const AbstractMetaFunction* func, metaClass->functions())
+ const AbstractMetaFunctionList &funcs = metaClass->functions();
+ for (const AbstractMetaFunction *func : funcs)
collectInstantiatedContainersAndSmartPointers(func);
- foreach (const AbstractMetaField* field, metaClass->fields())
+ const AbstractMetaFieldList &fields = metaClass->fields();
+ for (const AbstractMetaField *field : fields)
addInstantiatedContainersAndSmartPointers(field->type(), field->name());
- foreach (AbstractMetaClass* innerClass, metaClass->innerClasses())
+ const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
+ for (AbstractMetaClass *innerClass : innerClasses)
collectInstantiatedContainersAndSmartPointers(innerClass);
}
void Generator::collectInstantiatedContainersAndSmartPointers()
{
- foreach (const AbstractMetaFunction* func, globalFunctions())
+ const AbstractMetaFunctionList &funcs = globalFunctions();
+ for (const AbstractMetaFunction *func : funcs)
collectInstantiatedContainersAndSmartPointers(func);
- foreach (const AbstractMetaClass* metaClass, classes())
+ const AbstractMetaClassList &classList = classes();
+ for (const AbstractMetaClass *metaClass : classList)
collectInstantiatedContainersAndSmartPointers(metaClass);
}
-QList<const AbstractMetaType*> Generator::instantiatedContainers() const
+QVector<const AbstractMetaType *> Generator::instantiatedContainers() const
{
return m_d->instantiatedContainers;
}
-QList<const AbstractMetaType*> Generator::instantiatedSmartPointers() const
+QVector<const AbstractMetaType*> Generator::instantiatedSmartPointers() const
{
return m_d->instantiatedSmartPointers;
}
-QMap< QString, QString > Generator::options() const
+Generator::OptionDescriptions Generator::options() const
{
- return QMap<QString, QString>();
+ return OptionDescriptions();
}
AbstractMetaClassList Generator::classes() const
@@ -215,12 +219,12 @@ AbstractMetaEnumList Generator::globalEnums() const
return m_d->apiextractor->globalEnums();
}
-QList<const PrimitiveTypeEntry*> Generator::primitiveTypes() const
+PrimitiveTypeEntryList Generator::primitiveTypes() const
{
return m_d->apiextractor->primitiveTypes();
}
-QList<const ContainerTypeEntry*> Generator::containerTypes() const
+ContainerTypeEntryList Generator::containerTypes() const
{
return m_d->apiextractor->containerTypes();
}
@@ -351,13 +355,14 @@ QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType *smartP
bool Generator::generate()
{
- foreach (AbstractMetaClass *cls, m_d->apiextractor->classes()) {
+ const AbstractMetaClassList &classList = m_d->apiextractor->classes();
+ for (AbstractMetaClass *cls : classList) {
GeneratorContext context(cls);
if (!generateFileForContext(context))
return false;
}
- foreach (const AbstractMetaType *type, instantiatedSmartPointers()) {
+ for (const AbstractMetaType *type : qAsConst(m_d->instantiatedSmartPointers)) {
AbstractMetaClass *smartPointerClass =
AbstractMetaClass::findClass(m_d->apiextractor->smartPointers(), type->name());
GeneratorContext context(smartPointerClass, type, true);
@@ -394,7 +399,8 @@ void Generator::replaceTemplateVariables(QString &code, const AbstractMetaFuncti
if (cpp_class)
code.replace(QLatin1String("%TYPE"), cpp_class->name());
- foreach (AbstractMetaArgument *arg, func->arguments())
+ const AbstractMetaArgumentList &argument = func->arguments();
+ for (AbstractMetaArgument *arg : argument)
code.replace(QLatin1Char('%') + QString::number(arg->argumentIndex() + 1), arg->name());
//template values
@@ -419,10 +425,11 @@ void Generator::replaceTemplateVariables(QString &code, const AbstractMetaFuncti
QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor)
{
// detect number of spaces before the first character
- QStringList lst(code.split(QLatin1Char('\n')));
- QRegExp nonSpaceRegex(QLatin1String("[^\\s]"));
+ const QStringList lst(code.split(QLatin1Char('\n')));
+ static const QRegularExpression nonSpaceRegex(QStringLiteral("[^\\s]"));
+ Q_ASSERT(nonSpaceRegex.isValid());
int spacesToRemove = 0;
- foreach(QString line, lst) {
+ for (const QString &line : lst) {
if (!line.trimmed().isEmpty()) {
spacesToRemove = line.indexOf(nonSpaceRegex);
if (spacesToRemove == -1)
@@ -431,11 +438,12 @@ QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor)
}
}
- static QRegExp emptyLine(QLatin1String("\\s*[\\r]?[\\n]?\\s*"));
+ static const QRegularExpression emptyLine(QStringLiteral("^\\s*[\\r]?[\\n]?\\s*$"));
+ Q_ASSERT(emptyLine.isValid());
- foreach(QString line, lst) {
- if (!line.isEmpty() && !emptyLine.exactMatch(line)) {
- while (line.end()->isSpace())
+ for (QString line : lst) {
+ if (!line.isEmpty() && !emptyLine.match(line).hasMatch()) {
+ while (line.constEnd()->isSpace())
line.chop(1);
int limit = 0;
for(int i = 0; i < spacesToRemove; ++i) {
@@ -507,9 +515,12 @@ bool Generator::isVoidPointer(const AbstractMetaType* type)
QString Generator::getFullTypeName(const TypeEntry* type) const
{
- return type->isCppPrimitive()
- ? type->qualifiedCppName()
- : (QLatin1String("::") + type->qualifiedCppName());
+ QString result = type->qualifiedCppName();
+ if (type->isArray())
+ type = static_cast<const ArrayTypeEntry *>(type)->nestedTypeEntry();
+ if (!type->isCppPrimitive())
+ result.prepend(QLatin1String("::"));
+ return result;
}
QString Generator::getFullTypeName(const AbstractMetaType* type) const
@@ -639,9 +650,9 @@ QString Generator::minimalConstructor(const AbstractMetaClass* metaClass) const
if (cType->hasDefaultConstructor())
return cType->defaultConstructor();
- AbstractMetaFunctionList constructors = metaClass->queryFunctions(AbstractMetaClass::Constructors);
+ const AbstractMetaFunctionList &constructors = metaClass->queryFunctions(AbstractMetaClass::Constructors);
int maxArgs = 0;
- foreach (const AbstractMetaFunction* ctor, constructors) {
+ for (const AbstractMetaFunction *ctor : constructors) {
if (ctor->isUserAdded() || ctor->isPrivate() || ctor->functionType() != AbstractMetaFunction::ConstructorFunction)
continue;
@@ -656,28 +667,29 @@ QString Generator::minimalConstructor(const AbstractMetaClass* metaClass) const
QString qualifiedCppName = metaClass->typeEntry()->qualifiedCppName();
QStringList templateTypes;
- foreach (TypeEntry* templateType, metaClass->templateArguments())
+ const QVector<TypeEntry *> &templateArguments = metaClass->templateArguments();
+ for (TypeEntry *templateType : templateArguments)
templateTypes << templateType->qualifiedCppName();
// Empty constructor.
if (maxArgs == 0)
return QLatin1String("::") + qualifiedCppName + QLatin1String("()");
- QList<const AbstractMetaFunction*> candidates;
+ QVector<const AbstractMetaFunction *> candidates;
// Constructors with C++ primitive types, enums or pointers only.
// Start with the ones with fewer arguments.
for (int i = 1; i <= maxArgs; ++i) {
- foreach (const AbstractMetaFunction* ctor, constructors) {
+ for (const AbstractMetaFunction *ctor : constructors) {
if (ctor->isUserAdded() || ctor->isPrivate() || ctor->functionType() != AbstractMetaFunction::ConstructorFunction)
continue;
- AbstractMetaArgumentList arguments = ctor->arguments();
+ const AbstractMetaArgumentList &arguments = ctor->arguments();
if (arguments.size() != i)
continue;
QStringList args;
- foreach (const AbstractMetaArgument* arg, arguments) {
+ for (const AbstractMetaArgument *arg : arguments) {
const TypeEntry* type = arg->type()->typeEntry();
if (type == metaClass->typeEntry()) {
args.clear();
@@ -715,9 +727,10 @@ QString Generator::minimalConstructor(const AbstractMetaClass* metaClass) const
// Constructors with C++ primitive types, enums, pointers, value types,
// and user defined primitive types.
// Builds the minimal constructor recursively.
- foreach (const AbstractMetaFunction* ctor, candidates) {
+ for (const AbstractMetaFunction *ctor : qAsConst(candidates)) {
QStringList args;
- foreach (const AbstractMetaArgument* arg, ctor->arguments()) {
+ const AbstractMetaArgumentList &arguments = ctor->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
if (arg->type()->typeEntry() == metaClass->typeEntry()) {
args.clear();
break;
diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h
index f734ff9d7..f0b2a5e41 100644
--- a/sources/shiboken2/generator/generator.h
+++ b/sources/shiboken2/generator/generator.h
@@ -30,6 +30,7 @@
#define GENERATOR_H
#include <abstractmetalang_typedefs.h>
+#include <typedatabase_typedefs.h>
#include <dependency.h>
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
@@ -136,6 +137,9 @@ private:
class Generator
{
public:
+ typedef QPair<QString, QString> OptionDescription;
+ typedef QVector<OptionDescription> OptionDescriptions;
+
/// Optiosn used around the generator code
enum Option {
NoOption = 0x00000000,
@@ -180,7 +184,7 @@ public:
bool setup(const ApiExtractor& extractor, const QMap<QString, QString> args);
- virtual QMap<QString, QString> options() const;
+ virtual OptionDescriptions options() const;
/// Returns the classes used to generate the binding code.
AbstractMetaClassList classes() const;
@@ -198,10 +202,10 @@ public:
AbstractMetaEnumList globalEnums() const;
/// Returns all primitive types found by APIExtractor
- QList<const PrimitiveTypeEntry*> primitiveTypes() const;
+ PrimitiveTypeEntryList primitiveTypes() const;
/// Returns all container types found by APIExtractor
- QList<const ContainerTypeEntry*> containerTypes() const;
+ ContainerTypeEntryList containerTypes() const;
/// Returns an AbstractMetaEnum for a given EnumTypeEntry, or NULL if not found.
const AbstractMetaEnum* findAbstractMetaEnum(const EnumTypeEntry* typeEntry) const;
@@ -388,8 +392,8 @@ protected:
*/
virtual QString subDirectoryForPackage(QString packageName = QString()) const;
- QList<const AbstractMetaType*> instantiatedContainers() const;
- QList<const AbstractMetaType*> instantiatedSmartPointers() const;
+ QVector<const AbstractMetaType*> instantiatedContainers() const;
+ QVector<const AbstractMetaType*> instantiatedSmartPointers() const;
static QString getSimplifiedContainerTypeName(const AbstractMetaType *type);
void addInstantiatedContainersAndSmartPointers(const AbstractMetaType *type,
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 874540e54..774775fb0 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -46,6 +46,12 @@
#define PATH_SPLITTER ":"
#endif
+static inline QString includePathOption() { return QStringLiteral("include-paths"); }
+static inline QString frameworkIncludePathOption() { return QStringLiteral("framework-include-paths"); }
+static inline QString typesystemPathOption() { return QStringLiteral("typesystem-paths"); }
+static inline QString helpOption() { return QStringLiteral("help"); }
+static const char helpHint[] = "Note: use --help or -h for more information.\n";
+
namespace {
class ArgsHandler
@@ -134,14 +140,17 @@ QString ArgsHandler::errorMessage() const
}
}
-static void printOptions(QTextStream& s, const QMap<QString, QString>& options)
+typedef Generator::OptionDescriptions OptionDescriptions;
+
+static void printOptions(QTextStream& s, const OptionDescriptions& options)
{
- QMap<QString, QString>::const_iterator it = options.constBegin();
s.setFieldAlignment(QTextStream::AlignLeft);
- for (; it != options.constEnd(); ++it) {
- s << " --";
+ for (const auto &od : options) {
+ s << ' ';
+ if (!od.first.startsWith(QLatin1Char('-')))
+ s << "--";
s.setFieldWidth(38);
- s << it.key() << it.value();
+ s << od.first << od.second;
s.setFieldWidth(0);
s << endl;
}
@@ -156,6 +165,7 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
return false;
QStringList includePaths;
+ QStringList frameworkIncludePaths;
QStringList typesystemPaths;
QStringList apiVersions;
@@ -176,6 +186,8 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
if (key == "include-path")
includePaths << QDir::toNativeSeparators(value);
+ else if (key == "framework-include-path")
+ frameworkIncludePaths << QDir::toNativeSeparators(value);
else if (key == "typesystem-path")
typesystemPaths << QDir::toNativeSeparators(value);
else if (key == "api-version")
@@ -189,10 +201,14 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
}
if (!includePaths.isEmpty())
- args.insert(QLatin1String("include-paths"), includePaths.join(QLatin1String(PATH_SPLITTER)));
+ args.insert(includePathOption(), includePaths.join(QLatin1String(PATH_SPLITTER)));
+
+ if (!frameworkIncludePaths.isEmpty())
+ args.insert(frameworkIncludePathOption(),
+ frameworkIncludePaths.join(QLatin1String(PATH_SPLITTER)));
if (!typesystemPaths.isEmpty())
- args.insert(QLatin1String("typesystem-paths"), typesystemPaths.join(QLatin1String(PATH_SPLITTER)));
+ args.insert(typesystemPathOption(), typesystemPaths.join(QLatin1String(PATH_SPLITTER)));
if (!apiVersions.isEmpty())
args.insert(QLatin1String("api-version"), apiVersions.join(QLatin1Char('|')));
return true;
@@ -202,11 +218,11 @@ static QMap<QString, QString> getInitializedArguments()
{
QMap<QString, QString> args;
QStringList arguments = QCoreApplication::arguments();
- QString appName = arguments.first();
+ QString appName = arguments.constFirst();
arguments.removeFirst();
QString projectFileName;
- foreach (const QString& arg, arguments) {
+ for (const QString &arg : qAsConst(arguments)) {
if (arg.startsWith(QLatin1String("--project-file"))) {
int split = arg.indexOf(QLatin1Char('='));
if (split > 0)
@@ -239,6 +255,55 @@ static QMap<QString, QString> getInitializedArguments()
return args;
}
+// Concatenate values of path arguments that can occur multiple times on the
+// command line.
+static void addPathOptionValue(const QString &option, const QString &value,
+ QMap<QString, QString> &args)
+{
+ const QMap<QString, QString>::iterator it = args.find(option);
+ if (it != args.end())
+ it.value().append(QLatin1String(PATH_SPLITTER) + value);
+ else
+ args.insert(option, value);
+}
+
+static void getCommandLineArg(QString arg, int &argNum, QMap<QString, QString> &args)
+{
+ if (arg.startsWith(QLatin1String("--"))) {
+ arg.remove(0, 2);
+ const int split = arg.indexOf(QLatin1Char('='));
+ if (split < 0) {
+ args.insert(arg, QString());
+ return;
+ }
+ const QString option = arg.left(split);
+ const QString value = arg.mid(split + 1).trimmed();
+ if (option == includePathOption() || option == frameworkIncludePathOption()
+ || option == typesystemPathOption()) {
+ addPathOptionValue(option, value, args);
+ } else {
+ args.insert(option, value);
+ }
+ return;
+ }
+ if (arg.startsWith(QLatin1Char('-'))) {
+ arg.remove(0, 1);
+ if (arg.startsWith(QLatin1Char('I'))) // Shorthand path arguments -I/usr/include...
+ addPathOptionValue(includePathOption(), arg.mid(1), args);
+ else if (arg.startsWith(QLatin1Char('F')))
+ addPathOptionValue(frameworkIncludePathOption(), arg.mid(1), args);
+ else if (arg.startsWith(QLatin1Char('T')))
+ addPathOptionValue(typesystemPathOption(), arg.mid(1), args);
+ else if (arg == QLatin1String("h"))
+ args.insert(helpOption(), QString());
+ else
+ args.insert(arg, QString());
+ return;
+ }
+ argNum++;
+ args.insert(QStringLiteral("arg-") + QString::number(argNum), arg);
+}
+
static QMap<QString, QString> getCommandLineArgs()
{
QMap<QString, QString> args = getInitializedArguments();
@@ -246,21 +311,9 @@ static QMap<QString, QString> getCommandLineArgs()
arguments.removeFirst();
int argNum = 0;
- foreach (const QString &carg, arguments) {
- const QString &arg = carg.trimmed();
- if (arg.startsWith(QLatin1String("--"))) {
- int split = arg.indexOf(QLatin1Char('='));
- if (split > 0)
- args[arg.mid(2).left(split-2)] = arg.mid(split + 1).trimmed();
- else
- args[arg.mid(2)] = QString();
- } else if (arg.startsWith(QLatin1Char('-'))) {
- args[arg.mid(1)] = QString();
- } else {
- argNum++;
- args[QString::fromLatin1("arg-%1").arg(argNum)] = arg;
- }
- }
+ for (const QString &carg : qAsConst(arguments))
+ getCommandLineArg(carg.trimmed(), argNum, args);
+
return args;
}
@@ -286,40 +339,47 @@ void printUsage()
s << "Usage:\n "
<< "shiboken [options] header-file typesystem-file\n\n"
<< "General options:\n";
- QMap<QString, QString> generalOptions;
- generalOptions.insert(QLatin1String("project-file=<file>"),
- QLatin1String("text file containing a description of the binding project. Replaces and overrides command line arguments"));
- generalOptions.insert(QLatin1String("debug-level=[sparse|medium|full]"),
- QLatin1String("Set the debug level"));
- generalOptions.insert(QLatin1String("silent"),
- QLatin1String("Avoid printing any message"));
- generalOptions.insert(QLatin1String("help"),
- QLatin1String("Display this help and exit"));
- generalOptions.insert(QLatin1String("no-suppress-warnings"),
- QLatin1String("Show all warnings"));
- generalOptions.insert(QLatin1String("output-directory=<path>"),
- QLatin1String("The directory where the generated files will be written"));
- generalOptions.insert(QLatin1String("include-paths=<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]"),
- QLatin1String("Include paths used by the C++ parser"));
- generalOptions.insert(QLatin1String("typesystem-paths=<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]"),
- QLatin1String("Paths used when searching for typesystems"));
- generalOptions.insert(QLatin1String("documentation-only"),
- QLatin1String("Do not generates any code, just the documentation"));
- generalOptions.insert(QLatin1String("license-file=<license-file>"),
- QLatin1String("File used for copyright headers of generated files"));
- generalOptions.insert(QLatin1String("version"),
- QLatin1String("Output version information and exit"));
- generalOptions.insert(QLatin1String("generator-set=<\"generator module\">"),
- QLatin1String("generator-set to be used. e.g. qtdoc"));
- generalOptions.insert(QLatin1String("api-version=<\"package mask\">,<\"version\">"),
- QLatin1String("Specify the supported api version used to generate the bindings"));
- generalOptions.insert(QLatin1String("drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""),
- QLatin1String("Semicolon separated list of type system entries (classes, namespaces, global functions and enums) to be dropped from generation."));
+ const QString pathSyntax = QLatin1String("<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]");
+ OptionDescriptions generalOptions = OptionDescriptions()
+ << qMakePair(QLatin1String("api-version=<\"package mask\">,<\"version\">"),
+ QLatin1String("Specify the supported api version used to generate the bindings"))
+ << qMakePair(QLatin1String("debug-level=[sparse|medium|full]"),
+ QLatin1String("Set the debug level"))
+ << qMakePair(QLatin1String("documentation-only"),
+ QLatin1String("Do not generates any code, just the documentation"))
+ << qMakePair(QLatin1String("drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""),
+ QLatin1String("Semicolon separated list of type system entries (classes, namespaces, global functions and enums) to be dropped from generation."))
+ << qMakePair(QLatin1String("-F") + pathSyntax, QString())
+ << qMakePair(QLatin1String("framework-include-paths=") + pathSyntax,
+ QLatin1String("Framework include paths used by the C++ parser"))
+ << qMakePair(QLatin1String("generator-set=<\"generator module\">"),
+ QLatin1String("generator-set to be used. e.g. qtdoc"))
+ << qMakePair(QLatin1String("-h"), QString())
+ << qMakePair(helpOption(),
+ QLatin1String("Display this help and exit"))
+ << qMakePair(QLatin1String("-I") + pathSyntax, QString())
+ << qMakePair(QLatin1String("include-paths=") + pathSyntax,
+ QLatin1String("Include paths used by the C++ parser"))
+ << qMakePair(QLatin1String("license-file=<license-file>"),
+ QLatin1String("File used for copyright headers of generated files"))
+ << qMakePair(QLatin1String("no-suppress-warnings"),
+ QLatin1String("Show all warnings"))
+ << qMakePair(QLatin1String("output-directory=<path>"),
+ QLatin1String("The directory where the generated files will be written"))
+ << qMakePair(QLatin1String("project-file=<file>"),
+ QLatin1String("text file containing a description of the binding project. Replaces and overrides command line arguments"))
+ << qMakePair(QLatin1String("silent"),
+ QLatin1String("Avoid printing any message"))
+ << qMakePair(QLatin1String("-T") + pathSyntax, QString())
+ << qMakePair(QLatin1String("typesystem-paths=") + pathSyntax,
+ QLatin1String("Paths used when searching for typesystems"))
+ << qMakePair(QLatin1String("version"),
+ QLatin1String("Output version information and exit"));
printOptions(s, generalOptions);
const Generators generators = shibokenGenerators() + docGenerators();
- foreach (const GeneratorPtr &generator, generators) {
- QMap<QString, QString> options = generator->options();
+ for (const GeneratorPtr &generator : generators) {
+ const OptionDescriptions options = generator->options();
if (!options.isEmpty()) {
s << endl << generator->name() << " options:\n";
printOptions(s, generator->options());
@@ -437,14 +497,13 @@ int main(int argc, char *argv[])
extractor.setSuppressWarnings(false);
if (argsHandler.argExists(QLatin1String("api-version"))) {
- QStringList versions = argsHandler.removeArg(QLatin1String("api-version")).split(QLatin1Char('|'));
- foreach (const QString &fullVersion, versions) {
+ const QStringList &versions = argsHandler.removeArg(QLatin1String("api-version")).split(QLatin1Char('|'));
+ for (const QString &fullVersion : versions) {
QStringList parts = fullVersion.split(QLatin1Char(','));
QString package;
QString version;
- // avoid constFirst to stay Qt 5.5 compatible
- package = parts.count() == 1 ? QLatin1String("*") : parts.first();
- version = parts.last();
+ package = parts.count() == 1 ? QLatin1String("*") : parts.constFirst();
+ version = parts.constLast();
if (!extractor.setApiVersion(package, version)) {
errorPrint(msgInvalidVersion(package, version));
return EXIT_FAILURE;
@@ -460,11 +519,29 @@ int main(int argc, char *argv[])
extractor.addTypesystemSearchPath(path.split(QLatin1String(PATH_SPLITTER)));
path = argsHandler.removeArg(QLatin1String("include-paths"));
- if (!path.isEmpty())
- extractor.addIncludePath(path.split(QLatin1String(PATH_SPLITTER)));
+ if (!path.isEmpty()) {
+ const QStringList includePathListList = path.split(QLatin1String(PATH_SPLITTER));
+ for (const QString &s : qAsConst(includePathListList)) {
+ const bool isFramework = false;
+ extractor.addIncludePath(HeaderPath(s, isFramework));
+ }
+ }
+
+ path = argsHandler.removeArg(QLatin1String("framework-include-paths"));
+ if (!path.isEmpty()) {
+ const QStringList frameworkPathList = path.split(QLatin1String(PATH_SPLITTER));
+ const bool isFramework = true;
+ for (const QString &s : qAsConst(frameworkPathList)) {
+ extractor.addIncludePath(HeaderPath(s, isFramework));
+ }
+ }
QString cppFileName = argsHandler.removeArg(QLatin1String("arg-1"));
QString typeSystemFileName = argsHandler.removeArg(QLatin1String("arg-2"));
+ QString messagePrefix = QFileInfo(typeSystemFileName).baseName();
+ if (messagePrefix.startsWith(QLatin1String("typesystem_")))
+ messagePrefix.remove(0, 11);
+ ReportHandler::setPrefix(QLatin1Char('(') + messagePrefix + QLatin1Char(')'));
/* Make sure to remove the project file's arguments (if any) and
* --project-file, also the arguments of each generator before
@@ -478,18 +555,20 @@ int main(int argc, char *argv[])
for ( ; it != projectFileArgs.constEnd(); ++it)
argsHandler.removeArg(it.key());
}
- foreach (const GeneratorPtr &generator, generators) {
- QMap<QString, QString> options = generator->options();
- if (!options.isEmpty()) {
- QMap<QString, QString>::const_iterator it = options.constBegin();
- for ( ; it != options.constEnd(); ++it)
- argsHandler.removeArg(it.key());
- }
+ for (const GeneratorPtr &generator : qAsConst(generators)) {
+ const OptionDescriptions &options = generator->options();
+ for (const auto &od : options)
+ argsHandler.removeArg(od.first);
}
if (!argsHandler.noArgs()) {
errorPrint(argsHandler.errorMessage());
- std::cout << "Note: use --help option for more information." << std::endl;
+ std::cout << helpHint;
+ return EXIT_FAILURE;
+ }
+
+ if (typeSystemFileName.isEmpty()) {
+ std::cout << "You must specify a Type System file." << std::endl << helpHint;
return EXIT_FAILURE;
}
@@ -505,7 +584,7 @@ int main(int argc, char *argv[])
qCDebug(lcShiboken) << extractor;
- foreach (const GeneratorPtr &g, generators) {
+ for (const GeneratorPtr &g : qAsConst(generators)) {
g->setOutputDirectory(outputDirectory);
g->setLicenseComment(licenseComment);
if (g->setup(extractor, args)) {
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index a7a176907..7cce97ae1 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -35,6 +35,7 @@
#include <typedatabase.h>
#include <algorithm>
#include <QtCore/QStack>
+#include <QtCore/QRegularExpression>
#include <QtCore/QTextStream>
#include <QtCore/QXmlStreamReader>
#include <QtCore/QFile>
@@ -46,36 +47,36 @@ static Indentor INDENT;
static bool shouldSkip(const AbstractMetaFunction* func)
{
- bool skipable = func->isConstructor()
- || func->isModifiedRemoved()
- || func->declaringClass() != func->ownerClass()
- || func->isCastOperator()
- || func->name() == QLatin1String("operator=");
-
- // Search a const clone
- if (!skipable && !func->isConstant()) {
- const AbstractMetaArgumentList funcArgs = func->arguments();
- foreach (AbstractMetaFunction* f, func->ownerClass()->functions()) {
- if (f != func
- && f->isConstant()
- && f->name() == func->name()
- && f->arguments().count() == funcArgs.count()) {
- // Compare each argument
- bool cloneFound = true;
-
- const AbstractMetaArgumentList fargs = f->arguments();
- for (int i = 0, max = funcArgs.count(); i < max; ++i) {
- if (funcArgs.at(i)->type()->typeEntry() != fargs.at(i)->type()->typeEntry()) {
- cloneFound = false;
- break;
- }
+ // Constructors go to separate section
+ if (DocParser::skipForQuery(func) || func->isConstructor())
+ return true;
+
+ // Search a const clone (QImage::bits() vs QImage::bits() const)
+ if (func->isConstant())
+ return false;
+
+ const AbstractMetaArgumentList funcArgs = func->arguments();
+ const AbstractMetaFunctionList &ownerFunctions = func->ownerClass()->functions();
+ for (AbstractMetaFunction *f : ownerFunctions) {
+ if (f != func
+ && f->isConstant()
+ && f->name() == func->name()
+ && f->arguments().count() == funcArgs.count()) {
+ // Compare each argument
+ bool cloneFound = true;
+
+ const AbstractMetaArgumentList fargs = f->arguments();
+ for (int i = 0, max = funcArgs.count(); i < max; ++i) {
+ if (funcArgs.at(i)->type()->typeEntry() != fargs.at(i)->type()->typeEntry()) {
+ cloneFound = false;
+ break;
}
- if (cloneFound)
- return true;
}
+ if (cloneFound)
+ return true;
}
}
- return skipable;
+ return false;
}
static bool functionSort(const AbstractMetaFunction* func1, const AbstractMetaFunction* func2)
@@ -83,28 +84,106 @@ static bool functionSort(const AbstractMetaFunction* func1, const AbstractMetaFu
return func1->name() < func2->name();
}
-static QString createRepeatedChar(int i, char c)
+class Pad
+{
+public:
+ explicit Pad(char c, int count) : m_char(c), m_count(count) {}
+
+ void write(QTextStream &str) const
+ {
+ for (int i = 0; i < m_count; ++i)
+ str << m_char;
+ }
+
+private:
+ const char m_char;
+ const int m_count;
+};
+
+inline QTextStream &operator<<(QTextStream &str, const Pad &pad)
{
- QString out;
- for (int j = 0; j < i; ++j)
- out += QLatin1Char(c);
+ pad.write(str);
+ return str;
+}
- return out;
+template <class String>
+static int writeEscapedRstText(QTextStream &str, const String &s)
+{
+ int escaped = 0;
+ for (const QChar &c : s) {
+ switch (c.unicode()) {
+ case '*':
+ case '`':
+ case '_':
+ case '\\':
+ str << '\\';
+ ++escaped;
+ break;
+ }
+ str << c;
+ }
+ return s.size() + escaped;
}
-static QString escape(QString str)
+class escape
{
- str.replace(QLatin1Char('*'), QLatin1String("\\*"));
- str.replace(QLatin1Char('_'), QLatin1String("\\_"));
+public:
+ explicit escape(const QStringRef &s) : m_string(s) {}
+
+ void write(QTextStream &str) const { writeEscapedRstText(str, m_string); }
+
+private:
+ const QStringRef m_string;
+};
+
+inline QTextStream &operator<<(QTextStream &str, const escape &e)
+{
+ e.write(str);
return str;
}
-static QString escape(const QStringRef& strref)
+// Return last character of a QString-buffered stream.
+static QChar lastChar(const QTextStream &str)
{
- QString str = strref.toString();
- return escape(str);
+ const QString *string = str.string();
+ Q_ASSERT(string);
+ return string->isEmpty() ? QChar() : *(string->crbegin());
}
+static QTextStream &ensureEndl(QTextStream &s)
+{
+ if (lastChar(s) != QLatin1Char('\n'))
+ s << endl;
+ return s;
+}
+
+static QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
+ const QString &tag, const QString &message)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "While handling <";
+ const QStringRef currentTag = reader.name();
+ if (currentTag.isEmpty())
+ str << tag;
+ else
+ str << currentTag;
+ str << "> in " << context << ", line "<< reader.lineNumber()
+ << ": " << message;
+ return result;
+}
+
+static QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &context,
+ const QString &tag, const QString &location, const QString &identifier,
+ const QString &fallback)
+{
+ QString message = QLatin1String("Falling back to \"")
+ + QDir::toNativeSeparators(fallback) + QLatin1String("\" for \"") + location
+ + QLatin1Char('"');
+ if (!identifier.isEmpty())
+ message += QLatin1String(" [") + identifier + QLatin1Char(']');
+ return msgTagWarning(reader, context, tag, message);
+}
QtXmlToSphinx::QtXmlToSphinx(QtDocGenerator* generator, const QString& doc, const QString& context)
: m_context(context), m_generator(generator), m_insideBold(false), m_insideItalic(false)
@@ -125,7 +204,7 @@ QtXmlToSphinx::QtXmlToSphinx(QtDocGenerator* generator, const QString& doc, cons
m_handlerMap.insert(QLatin1String("argument"), &QtXmlToSphinx::handleArgumentTag);
m_handlerMap.insert(QLatin1String("teletype"), &QtXmlToSphinx::handleArgumentTag);
m_handlerMap.insert(QLatin1String("link"), &QtXmlToSphinx::handleLinkTag);
- m_handlerMap.insert(QLatin1String("inlineimage"), &QtXmlToSphinx::handleImageTag);
+ m_handlerMap.insert(QLatin1String("inlineimage"), &QtXmlToSphinx::handleInlineImageTag);
m_handlerMap.insert(QLatin1String("image"), &QtXmlToSphinx::handleImageTag);
m_handlerMap.insert(QLatin1String("list"), &QtXmlToSphinx::handleListTag);
m_handlerMap.insert(QLatin1String("term"), &QtXmlToSphinx::handleTermTag);
@@ -197,34 +276,34 @@ QString QtXmlToSphinx::popOutputBuffer()
return strcpy;
}
-QString QtXmlToSphinx::expandFunction(const QString& function)
+QString QtXmlToSphinx::expandFunction(const QString& function) const
{
- QStringList functionSpec = function.split(QLatin1Char('.'));
- QString className = functionSpec.first();
- const AbstractMetaClass* metaClass = 0;
- foreach (const AbstractMetaClass* cls, m_generator->classes()) {
- if (cls->name() == className) {
- metaClass = cls;
- break;
+ const int firstDot = function.indexOf(QLatin1Char('.'));
+ const AbstractMetaClass *metaClass = nullptr;
+ if (firstDot != -1) {
+ const QStringRef className = function.leftRef(firstDot);
+ const AbstractMetaClassList &classes = m_generator->classes();
+ for (const AbstractMetaClass *cls : classes) {
+ if (cls->name() == className) {
+ metaClass = cls;
+ break;
+ }
}
}
- if (metaClass) {
- functionSpec.removeFirst();
- return metaClass->typeEntry()->qualifiedTargetLangName()
- + QLatin1Char('.') + functionSpec.join(QLatin1Char('.'));
- } else {
- return function;
- }
+ return metaClass
+ ? metaClass->typeEntry()->qualifiedTargetLangName()
+ + function.right(function.size() - firstDot)
+ : function;
}
-QString QtXmlToSphinx::resolveContextForMethod(const QString& methodName)
+QString QtXmlToSphinx::resolveContextForMethod(const QString& methodName) const
{
- // avoid constLast to stay Qt 5.5 compatible
- QString currentClass = m_context.split(QLatin1Char('.')).last();
+ const QStringRef currentClass = m_context.splitRef(QLatin1Char('.')).constLast();
const AbstractMetaClass* metaClass = 0;
- foreach (const AbstractMetaClass* cls, m_generator->classes()) {
+ const AbstractMetaClassList &classes = m_generator->classes();
+ for (const AbstractMetaClass *cls : classes) {
if (cls->name() == currentClass) {
metaClass = cls;
break;
@@ -233,13 +312,14 @@ QString QtXmlToSphinx::resolveContextForMethod(const QString& methodName)
if (metaClass) {
QList<const AbstractMetaFunction*> funcList;
- foreach (const AbstractMetaFunction* func, metaClass->queryFunctionsByName(methodName)) {
+ const AbstractMetaFunctionList &methods = metaClass->queryFunctionsByName(methodName);
+ for (const AbstractMetaFunction *func : methods) {
if (methodName == func->name())
funcList.append(func);
}
const AbstractMetaClass* implementingClass = 0;
- foreach (const AbstractMetaFunction* func, funcList) {
+ for (const AbstractMetaFunction *func : qAsConst(funcList)) {
implementingClass = func->implementingClass();
if (implementingClass->name() == currentClass)
break;
@@ -290,94 +370,115 @@ QString QtXmlToSphinx::transform(const QString& doc)
m_lastTagName = reader.name().toString();
}
}
+
+ if (!m_inlineImages.isEmpty()) {
+ // Write out inline image definitions stored in handleInlineImageTag().
+ m_output << endl;
+ for (const InlineImage &img : qAsConst(m_inlineImages))
+ m_output << ".. |" << img.tag << "| image:: " << img.href << endl;
+ m_output << endl;
+ m_inlineImages.clear();
+ }
+
m_output.flush();
QString retval = popOutputBuffer();
Q_ASSERT(m_buffers.isEmpty());
return retval;
}
-QString QtXmlToSphinx::readFromLocations(const QStringList& locations, const QString& path, const QString& identifier)
+static QString resolveFile(const QStringList &locations, const QString &path)
{
- QString result;
- bool ok;
- foreach (QString location, locations) {
+ for (QString location : locations) {
location.append(QLatin1Char('/'));
location.append(path);
- result = readFromLocation(location, identifier, &ok);
- if (ok)
- break;
+ if (QFileInfo::exists(location))
+ return location;
}
- if (!ok) {
- qCDebug(lcShiboken).noquote().nospace() << "Couldn't read code snippet file: {"
- << locations.join(QLatin1Char('|')) << '}' << path;
- }
- return result;
+ return QString();
+}
+QString QtXmlToSphinx::readFromLocations(const QStringList &locations, const QString &path,
+ const QString &identifier, QString *errorMessage)
+{
+ QString result;
+ const QString resolvedPath = resolveFile(locations, path);
+ if (resolvedPath.isEmpty()) {
+ QTextStream(errorMessage) << "Could not resolve \"" << path << "\" in \""
+ << locations.join(QLatin1String("\", \""));
+ return QString(); // null
+ }
+ qCDebug(lcShiboken).noquote().nospace() << "snippet file " << path
+ << " [" << identifier << ']' << " resolved to " << resolvedPath;
+ return readFromLocation(resolvedPath, identifier, errorMessage);
}
-QString QtXmlToSphinx::readFromLocation(const QString& location, const QString& identifier, bool* ok)
+QString QtXmlToSphinx::readFromLocation(const QString &location, const QString &identifier,
+ QString *errorMessage)
{
QFile inputFile;
inputFile.setFileName(location);
if (!inputFile.open(QIODevice::ReadOnly)) {
- if (!ok) {
- qCDebug(lcShiboken).noquote().nospace() << "Couldn't read code snippet file: "
- << QDir::toNativeSeparators(inputFile.fileName());
- } else {
- *ok = false;
- }
- return QString();
+ QTextStream(errorMessage) << "Could not read code snippet file: "
+ << QDir::toNativeSeparators(inputFile.fileName())
+ << ": " << inputFile.errorString();
+ return QString(); // null
}
- QRegExp searchString(QLatin1String("//!\\s*\\[") + identifier + QLatin1String("\\]"));
- QRegExp codeSnippetCode(QLatin1String("//!\\s*\\[[\\w\\d\\s]+\\]"));
- QString code;
+ QString code = QLatin1String(""); // non-null
+ if (identifier.isEmpty()) {
+ while (!inputFile.atEnd())
+ code += QString::fromUtf8(inputFile.readLine());
+ return code;
+ }
+
+ const QRegularExpression searchString(QLatin1String("//!\\s*\\[")
+ + identifier + QLatin1String("\\]"));
+ Q_ASSERT(searchString.isValid());
+ static const QRegularExpression codeSnippetCode(QLatin1String("//!\\s*\\[[\\w\\d\\s]+\\]"));
+ Q_ASSERT(codeSnippetCode.isValid());
- bool identifierIsEmpty = identifier.isEmpty();
bool getCode = false;
while (!inputFile.atEnd()) {
QString line = QString::fromUtf8(inputFile.readLine());
- if (identifierIsEmpty) {
- code += line;
- } else if (getCode && !line.contains(searchString)) {
+ if (getCode && !line.contains(searchString)) {
line.remove(codeSnippetCode);
code += line;
} else if (line.contains(searchString)) {
if (getCode)
break;
- else
- getCode = true;
+ getCode = true;
}
}
- if (!identifierIsEmpty && !getCode) {
- qCDebug(lcShiboken).noquote().nospace() << "Code snippet file found ("
- << location << "), but snippet " << identifier << " not found.";
+ if (!getCode) {
+ QTextStream(errorMessage) << "Code snippet file found ("
+ << QDir::toNativeSeparators(location) << "), but snippet ["
+ << identifier << "] not found.";
+ return QString(); // null
}
- if (ok)
- *ok = true;
return code;
}
void QtXmlToSphinx::handleHeadingTag(QXmlStreamReader& reader)
{
- static QString heading;
+ static int headingSize = 0;
static char type;
static char types[] = { '-', '^' };
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- uint typeIdx = reader.attributes().value(QLatin1String("level")).toString().toInt();
+ uint typeIdx = reader.attributes().value(QLatin1String("level")).toUInt();
if (typeIdx >= sizeof(types))
type = types[sizeof(types)-1];
else
type = types[typeIdx];
} else if (token == QXmlStreamReader::EndElement) {
- m_output << createRepeatedChar(heading.length(), type) << endl << endl;
+ m_output << Pad(type, headingSize) << endl << endl;
} else if (token == QXmlStreamReader::Characters) {
- heading = escape(reader.text()).trimmed();
- m_output << endl << endl << heading << endl;
+ m_output << endl << endl;
+ headingSize = writeEscapedRstText(m_output, reader.text().trimmed());
+ m_output << endl;
}
}
@@ -395,14 +496,14 @@ void QtXmlToSphinx::handleParaTag(QXmlStreamReader& reader)
m_output << INDENT << result << endl << endl;
} else if (token == QXmlStreamReader::Characters) {
- QString text = escape(reader.text());
- if (!m_output.string()->isEmpty()) {
+ const QStringRef text = reader.text();
+ const QChar end = lastChar(m_output);
+ if (!text.isEmpty() && INDENT.indent == 0 && !end.isNull()) {
QChar start = text[0];
- QChar end = m_output.string()->at(m_output.string()->length() - 1);
if ((end == QLatin1Char('*') || end == QLatin1Char('`')) && start != QLatin1Char(' ') && !start.isPunct())
m_output << '\\';
}
- m_output << INDENT << text;
+ m_output << INDENT << escape(text);
}
}
@@ -413,7 +514,7 @@ void QtXmlToSphinx::handleItalicTag(QXmlStreamReader& reader)
m_insideItalic = !m_insideItalic;
m_output << '*';
} else if (token == QXmlStreamReader::Characters) {
- m_output << escape(reader.text()).trimmed();
+ m_output << escape(reader.text().trimmed());
}
}
@@ -424,7 +525,7 @@ void QtXmlToSphinx::handleBoldTag(QXmlStreamReader& reader)
m_insideBold = !m_insideBold;
m_output << "**";
} else if (token == QXmlStreamReader::Characters) {
- m_output << escape(reader.text()).trimmed();
+ m_output << escape(reader.text().trimmed());
}
}
@@ -434,16 +535,102 @@ void QtXmlToSphinx::handleArgumentTag(QXmlStreamReader& reader)
if (token == QXmlStreamReader::StartElement || token == QXmlStreamReader::EndElement)
m_output << "``";
else if (token == QXmlStreamReader::Characters)
- m_output << reader.text().toString().trimmed();
+ m_output << reader.text().trimmed();
}
+static inline QString functionLinkType() { return QStringLiteral("function"); }
+static inline QString classLinkType() { return QStringLiteral("class"); }
+
+static inline QString fixLinkType(const QStringRef &type)
+{
+ // TODO: create a flag PROPERTY-AS-FUNCTION to ask if the properties
+ // are recognized as such or not in the binding
+ if (type == QLatin1String("property"))
+ return functionLinkType();
+ if (type == QLatin1String("typedef"))
+ return classLinkType();
+ return type.toString();
+}
+
+static inline QString linkSourceAttribute(const QString &type)
+{
+ if (type == functionLinkType() || type == classLinkType())
+ return QLatin1String("raw");
+ return type == QLatin1String("enum") || type == QLatin1String("page")
+ ? type : QLatin1String("href");
+}
+
+// "See also" links may appear as nested links:
+// <see-also>QAbstractXmlReceiver<link raw="isValid()" href="qxmlquery.html#isValid" type="function">isValid()</link>
+// which is handled in handleLinkTag
+// or direct text:
+// <see-also>rootIsDecorated()</see-also>
+// which is handled here.
+
void QtXmlToSphinx::handleSeeAlsoTag(QXmlStreamReader& reader)
{
- QXmlStreamReader::TokenType token = reader.tokenType();
- if (token == QXmlStreamReader::StartElement)
+ switch (reader.tokenType()) {
+ case QXmlStreamReader::StartElement:
m_output << INDENT << ".. seealso:: ";
- else if (token == QXmlStreamReader::EndElement)
+ break;
+ case QXmlStreamReader::Characters: {
+ // Direct embedded link: <see-also>rootIsDecorated()</see-also>
+ const QStringRef textR = reader.text().trimmed();
+ if (!textR.isEmpty()) {
+ const QString text = textR.toString();
+ if (m_seeAlsoContext.isNull()) {
+ const QString type = text.endsWith(QLatin1String("()"))
+ ? functionLinkType() : classLinkType();
+ m_seeAlsoContext.reset(handleLinkStart(type, text));
+ }
+ handleLinkText(m_seeAlsoContext.data(), text);
+ }
+ }
+ break;
+ case QXmlStreamReader::EndElement:
+ if (!m_seeAlsoContext.isNull()) { // direct, no nested </link> seen
+ handleLinkEnd(m_seeAlsoContext.data());
+ m_seeAlsoContext.reset();
+ }
m_output << endl;
+ break;
+ default:
+ break;
+ }
+}
+
+static inline QString fallbackPathAttribute() { return QStringLiteral("path"); }
+
+static inline bool snippetComparison()
+{
+ return ReportHandler::debugLevel() >= ReportHandler::FullDebug;
+}
+
+template <class Indent> // const char*/class Indentor
+void formatSnippet(QTextStream &str, Indent indent, const QString &snippet)
+{
+ const QVector<QStringRef> lines = snippet.splitRef(QLatin1Char('\n'));
+ for (const QStringRef &line : lines) {
+ if (!line.trimmed().isEmpty())
+ str << indent << line;
+ str << endl;
+ }
+}
+
+static QString msgSnippetComparison(const QString &location, const QString &identifier,
+ const QString &pythonCode, const QString &fallbackCode)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Python snippet " << location;
+ if (!identifier.isEmpty())
+ str << " [" << identifier << ']';
+ str << ":\n";
+ formatSnippet(str, " ", pythonCode);
+ str << "Corresponding fallback snippet:\n";
+ formatSnippet(str, " ", fallbackCode);
+ str << "-- end --\n";
+ return result;
}
void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
@@ -458,21 +645,38 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
}
QString location = reader.attributes().value(QLatin1String("location")).toString();
QString identifier = reader.attributes().value(QLatin1String("identifier")).toString();
- QString code = readFromLocations(m_generator->codeSnippetDirs(), location, identifier);
+ QString errorMessage;
+ const QString pythonCode =
+ readFromLocations(m_generator->codeSnippetDirs(), location, identifier, &errorMessage);
+ if (!errorMessage.isEmpty())
+ qCWarning(lcShiboken, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
+ // Fall back to C++ snippet when "path" attribute is present.
+ // Also read fallback snippet when comparison is desired.
+ QString fallbackCode;
+ if ((pythonCode.isNull() || snippetComparison())
+ && reader.attributes().hasAttribute(fallbackPathAttribute())) {
+ const QString fallback = reader.attributes().value(fallbackPathAttribute()).toString();
+ if (QFileInfo::exists(fallback)) {
+ if (pythonCode.isNull())
+ qCWarning(lcShiboken, "%s", qPrintable(msgFallbackWarning(reader, m_context, m_lastTagName, location, identifier, fallback)));
+ fallbackCode = readFromLocation(fallback, identifier, &errorMessage);
+ if (!errorMessage.isEmpty())
+ qCWarning(lcShiboken, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
+ }
+ }
+
+ if (!pythonCode.isEmpty() && !fallbackCode.isEmpty() && snippetComparison())
+ qCDebug(lcShiboken, "%s", qPrintable(msgSnippetComparison(location, identifier, pythonCode, fallbackCode)));
+
if (!consecutiveSnippet)
m_output << INDENT << "::\n\n";
Indentation indentation(INDENT);
- if (code.isEmpty()) {
+ const QString code = pythonCode.isNull() ? fallbackCode : pythonCode;
+ if (code.isEmpty())
m_output << INDENT << "<Code snippet \"" << location << ':' << identifier << "\" not found>" << endl;
- } else {
- foreach (const QString &line, code.split(QLatin1Char('\n'))) {
- if (!QString(line).trimmed().isEmpty())
- m_output << INDENT << line;
-
- m_output << endl;
- }
- }
+ else
+ formatSnippet(m_output, INDENT, code);
m_output << endl;
}
}
@@ -489,7 +693,7 @@ void QtXmlToSphinx::handleDotsTag(QXmlStreamReader& reader)
Indentation indentation(INDENT);
pushOutputBuffer();
m_output << INDENT;
- int indent = reader.attributes().value(QLatin1String("indent")).toString().toInt();
+ int indent = reader.attributes().value(QLatin1String("indent")).toInt();
for (int i = 0; i < indent; ++i)
m_output << ' ';
} else if (token == QXmlStreamReader::Characters) {
@@ -509,7 +713,7 @@ void QtXmlToSphinx::handleTableTag(QXmlStreamReader& reader)
// write the table on m_output
m_currentTable.enableHeader(m_tableHasHeader);
m_currentTable.normalize();
- m_output << m_currentTable;
+ m_output << ensureEndl << m_currentTable;
m_currentTable.clear();
}
}
@@ -537,8 +741,8 @@ void QtXmlToSphinx::handleItemTag(QXmlStreamReader& reader)
m_currentTable << TableRow();
TableRow& row = m_currentTable.last();
TableCell cell;
- cell.colSpan = reader.attributes().value(QLatin1String("colspan")).toString().toShort();
- cell.rowSpan = reader.attributes().value(QLatin1String("rowspan")).toString().toShort();
+ cell.colSpan = reader.attributes().value(QLatin1String("colspan")).toShort();
+ cell.rowSpan = reader.attributes().value(QLatin1String("rowspan")).toShort();
row << cell;
pushOutputBuffer();
} else if (token == QXmlStreamReader::EndElement) {
@@ -577,9 +781,9 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
if (!m_currentTable.isEmpty()) {
if (listType == QLatin1String("bullet")) {
m_output << endl;
- foreach (TableCell cell, m_currentTable.first()) {
- QStringList itemLines = cell.data.split(QLatin1Char('\n'));
- m_output << INDENT << "* " << itemLines.first() << endl;
+ for (const TableCell &cell : m_currentTable.constFirst()) {
+ const QVector<QStringRef> itemLines = cell.data.splitRef(QLatin1Char('\n'));
+ m_output << INDENT << "* " << itemLines.constFirst() << endl;
for (int i = 1, max = itemLines.count(); i < max; ++i)
m_output << INDENT << " " << itemLines[i] << endl;
}
@@ -587,7 +791,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
} else if (listType == QLatin1String("enum")) {
m_currentTable.enableHeader(m_tableHasHeader);
m_currentTable.normalize();
- m_output << m_currentTable;
+ m_output << ensureEndl << m_currentTable;
}
}
m_currentTable.clear();
@@ -596,115 +800,197 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
void QtXmlToSphinx::handleLinkTag(QXmlStreamReader& reader)
{
- static QString l_linktag;
- static QString l_linkref;
- static QString l_linktext;
- static QString l_linktagending;
- static QString l_type;
- QXmlStreamReader::TokenType token = reader.tokenType();
- if (token == QXmlStreamReader::StartElement) {
- l_linktagending = QLatin1String("` ");
- if (m_insideBold) {
- l_linktag.prepend(QLatin1String("**"));
- l_linktagending.append(QLatin1String("**"));
- } else if (m_insideItalic) {
- l_linktag.prepend(QLatin1Char('*'));
- l_linktagending.append(QLatin1Char('*'));
- }
- l_type = reader.attributes().value(QLatin1String("type")).toString();
-
- // TODO: create a flag PROPERTY-AS-FUNCTION to ask if the properties
- // are recognized as such or not in the binding
- if (l_type == QLatin1String("property"))
- l_type = QLatin1String("function");
-
- if (l_type == QLatin1String("typedef"))
- l_type = QLatin1String("class");
-
- QString linkSource;
- if (l_type == QLatin1String("function") || l_type == QLatin1String("class")) {
- linkSource = QLatin1String("raw");
- } else if (l_type == QLatin1String("enum")) {
- linkSource = QLatin1String("enum");
- } else if (l_type == QLatin1String("page")) {
- linkSource = QLatin1String("page");
+ switch (reader.tokenType()) {
+ case QXmlStreamReader::StartElement: {
+ // <link> embedded in <see-also> means the characters of <see-also> are no link.
+ m_seeAlsoContext.reset();
+ const QString type = fixLinkType(reader.attributes().value(QLatin1String("type")));
+ const QString ref = reader.attributes().value(linkSourceAttribute(type)).toString();
+ m_linkContext.reset(handleLinkStart(type, ref));
+ }
+ break;
+ case QXmlStreamReader::Characters:
+ Q_ASSERT(!m_linkContext.isNull());
+ handleLinkText(m_linkContext.data(), reader.text().toString());
+ break;
+ case QXmlStreamReader::EndElement:
+ Q_ASSERT(!m_linkContext.isNull());
+ handleLinkEnd(m_linkContext.data());
+ m_linkContext.reset();
+ break;
+ default:
+ break;
+ }
+}
+
+QtXmlToSphinx::LinkContext *QtXmlToSphinx::handleLinkStart(const QString &type, const QString &ref) const
+{
+ LinkContext *result = new LinkContext(ref, type);
+
+ result->linkTagEnding = QLatin1String("` ");
+ if (m_insideBold) {
+ result->linkTag.prepend(QLatin1String("**"));
+ result->linkTagEnding.append(QLatin1String("**"));
+ } else if (m_insideItalic) {
+ result->linkTag.prepend(QLatin1Char('*'));
+ result->linkTagEnding.append(QLatin1Char('*'));
+ }
+
+ result->linkRef.replace(QLatin1String("::"), QLatin1String("."));
+ result->linkRef.remove(QLatin1String("()"));
+
+ if (result->type == functionLinkType() && !m_context.isEmpty()) {
+ result->linkTag = QLatin1String(" :meth:`");
+ const QVector<QStringRef> rawlinklist = result->linkRef.splitRef(QLatin1Char('.'));
+ if (rawlinklist.size() == 1 || rawlinklist.constFirst() == m_context) {
+ QString context = resolveContextForMethod(rawlinklist.constLast().toString());
+ if (!result->linkRef.startsWith(context))
+ result->linkRef.prepend(context + QLatin1Char('.'));
} else {
- linkSource = QLatin1String("href");
+ result->linkRef = expandFunction(result->linkRef);
}
-
- l_linkref = reader.attributes().value(linkSource).toString();
- l_linkref.replace(QLatin1String("::"), QLatin1String("."));
- l_linkref.remove(QLatin1String("()"));
-
- if (l_type == QLatin1String("function") && !m_context.isEmpty()) {
- l_linktag = QLatin1String(" :meth:`");
- QStringList rawlinklist = l_linkref.split(QLatin1Char('.'));
- if (rawlinklist.size() == 1 || rawlinklist.first() == m_context) {
- QString context = resolveContextForMethod(rawlinklist.last());
- if (!l_linkref.startsWith(context))
- l_linkref.prepend(context + QLatin1Char('.'));
- } else {
- l_linkref = expandFunction(l_linkref);
+ } else if (result->type == functionLinkType() && m_context.isEmpty()) {
+ result->linkTag = QLatin1String(" :func:`");
+ } else if (result->type == classLinkType()) {
+ result->linkTag = QLatin1String(" :class:`");
+ if (const TypeEntry *type = TypeDatabase::instance()->findType(result->linkRef)) {
+ result->linkRef = type->qualifiedTargetLangName();
+ } else { // fall back to the old heuristic if the type wasn't found.
+ const QVector<QStringRef> rawlinklist = result->linkRef.splitRef(QLatin1Char('.'));
+ QStringList splittedContext = m_context.split(QLatin1Char('.'));
+ if (rawlinklist.size() == 1 || rawlinklist.constFirst() == splittedContext.constLast()) {
+ splittedContext.removeLast();
+ result->linkRef.prepend(QLatin1Char('~') + splittedContext.join(QLatin1Char('.'))
+ + QLatin1Char('.'));
}
- } else if (l_type == QLatin1String("function") && m_context.isEmpty()) {
- l_linktag = QLatin1String(" :func:`");
- } else if (l_type == QLatin1String("class")) {
- l_linktag = QLatin1String(" :class:`");
- TypeEntry* type = TypeDatabase::instance()->findType(l_linkref);
- if (type) {
- l_linkref = type->qualifiedTargetLangName();
- } else { // fall back to the old heuristic if the type wasn't found.
- QStringList rawlinklist = l_linkref.split(QLatin1Char('.'));
- QStringList splittedContext = m_context.split(QLatin1Char('.'));
- if (rawlinklist.size() == 1 || rawlinklist.first() == splittedContext.last()) {
- splittedContext.removeLast();
- l_linkref.prepend(QLatin1Char('~') + splittedContext.join(QLatin1Char('.'))
- + QLatin1Char('.'));
- }
- }
- } else if (l_type == QLatin1String("enum")) {
- l_linktag = QLatin1String(" :attr:`");
- } else if (l_type == QLatin1String("page") && l_linkref == m_generator->moduleName()) {
- l_linktag = QLatin1String(" :mod:`");
- } else {
- l_linktag = QLatin1String(" :ref:`");
}
+ } else if (result->type == QLatin1String("enum")) {
+ result->linkTag = QLatin1String(" :attr:`");
+ } else if (result->type == QLatin1String("page") && result->linkRef == m_generator->moduleName()) {
+ result->linkTag = QLatin1String(" :mod:`");
+ } else {
+ result->linkTag = QLatin1String(" :ref:`");
+ }
+ return result;
+}
- } else if (token == QXmlStreamReader::Characters) {
- QString linktext = reader.text().toString();
- linktext.replace(QLatin1String("::"), QLatin1String("."));
- // avoid constLast to stay Qt 5.5 compatible
- QString item = l_linkref.split(QLatin1Char('.')).last();
- if (l_linkref == linktext
- || (l_linkref + QLatin1String("()")) == linktext
- || item == linktext
- || (item + QLatin1String("()")) == linktext)
- l_linktext.clear();
- else
- l_linktext = linktext + QLatin1Char('<');
- } else if (token == QXmlStreamReader::EndElement) {
- if (!l_linktext.isEmpty())
- l_linktagending.prepend(QLatin1Char('>'));
- m_output << l_linktag << l_linktext << escape(l_linkref) << l_linktagending;
+void QtXmlToSphinx::handleLinkText(LinkContext *linkContext, QString linktext) const
+{
+ linktext.replace(QLatin1String("::"), QLatin1String("."));
+ const QStringRef item = linkContext->linkRef.splitRef(QLatin1Char('.')).constLast();
+ if (linkContext->linkRef == linktext
+ || (linkContext->linkRef + QLatin1String("()")) == linktext
+ || item == linktext
+ || (item + QLatin1String("()")) == linktext) {
+ linkContext->linkText.clear();
+ } else {
+ linkContext->linkText = linktext + QLatin1Char('<');
}
}
-void QtXmlToSphinx::handleImageTag(QXmlStreamReader& reader)
+void QtXmlToSphinx::handleLinkEnd(LinkContext *linkContext)
{
- QXmlStreamReader::TokenType token = reader.tokenType();
- if (token == QXmlStreamReader::StartElement) {
- QString href = reader.attributes().value(QLatin1String("href")).toString();
- QString packageName = m_generator->packageName();
- packageName.replace(QLatin1Char('.'), QLatin1Char('/'));
- QDir dir(m_generator->outputDirectory() + QLatin1Char('/') + packageName);
- QString imgPath = dir.relativeFilePath(m_generator->libSourceDir() + QLatin1String("/doc/src/"))
- + QLatin1Char('/') + href;
-
- if (reader.name() == QLatin1String("image"))
- m_output << INDENT << ".. image:: " << imgPath << endl << endl;
- else
- m_output << ".. image:: " << imgPath << ' ';
+ if (!linkContext->linkText.isEmpty())
+ linkContext->linkTagEnding.prepend(QLatin1Char('>'));
+ m_output << linkContext->linkTag << linkContext->linkText;
+ writeEscapedRstText(m_output, linkContext->linkRef);
+ m_output << linkContext->linkTagEnding;
+}
+
+// Copy images that are placed in a subdirectory "images" under the webxml files
+// by qdoc to a matching subdirectory under the "rst/PySide2/<module>" directory
+static bool copyImage(const QString &href, const QString &docDataDir,
+ const QString &context, const QString &outputDir,
+ QString *errorMessage)
+{
+ const QChar slash = QLatin1Char('/');
+ const int lastSlash = href.lastIndexOf(slash);
+ const QString imagePath = lastSlash != -1 ? href.left(lastSlash) : QString();
+ const QString imageFileName = lastSlash != -1 ? href.right(href.size() - lastSlash - 1) : href;
+ QFileInfo imageSource(docDataDir + slash + href);
+ if (!imageSource.exists()) {
+ QTextStream(errorMessage) << "Image " << href << " does not exist in "
+ << QDir::toNativeSeparators(docDataDir);
+ return false;
+ }
+ // Determine directory from context, "Pyside2.QtGui.QPainter" ->"Pyside2/QtGui".
+ // FIXME: Not perfect yet, should have knowledge about namespaces (DataVis3D) or
+ // nested classes "Pyside2.QtGui.QTouchEvent.QTouchPoint".
+ QString relativeTargetDir = context;
+ const int lastDot = relativeTargetDir.lastIndexOf(QLatin1Char('.'));
+ if (lastDot != -1)
+ relativeTargetDir.truncate(lastDot);
+ relativeTargetDir.replace(QLatin1Char('.'), slash);
+ if (!imagePath.isEmpty())
+ relativeTargetDir += slash + imagePath;
+
+ const QString targetDir = outputDir + slash + relativeTargetDir;
+ const QString targetFileName = targetDir + slash + imageFileName;
+ if (QFileInfo::exists(targetFileName))
+ return true;
+ if (!QFileInfo::exists(targetDir)) {
+ const QDir outDir(outputDir);
+ if (!outDir.mkpath(relativeTargetDir)) {
+ QTextStream(errorMessage) << "Cannot create " << QDir::toNativeSeparators(relativeTargetDir)
+ << " under " << QDir::toNativeSeparators(outputDir);
+ return false;
+ }
+ }
+
+ QFile source(imageSource.absoluteFilePath());
+ if (!source.copy(targetFileName)) {
+ QTextStream(errorMessage) << "Cannot copy " << QDir::toNativeSeparators(source.fileName())
+ << " to " << QDir::toNativeSeparators(targetFileName) << ": "
+ << source.errorString();
+ return false;
}
+ qCDebug(lcShiboken()).noquote().nospace() << __FUNCTION__ << " href=\""
+ << href << "\", context=\"" << context << "\", docDataDir=\""
+ << docDataDir << "\", outputDir=\"" << outputDir << "\", copied \""
+ << source.fileName() << "\"->\"" << targetFileName << '"';
+ return true;
+}
+
+bool QtXmlToSphinx::copyImage(const QString &href) const
+{
+ QString errorMessage;
+ const bool result =
+ ::copyImage(href, m_generator->docDataDir(), m_context,
+ m_generator->outputDirectory(), &errorMessage);
+ if (!result)
+ qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ return result;
+}
+
+void QtXmlToSphinx::handleImageTag(QXmlStreamReader& reader)
+{
+ if (reader.tokenType() != QXmlStreamReader::StartElement)
+ return;
+ const QString href = reader.attributes().value(QLatin1String("href")).toString();
+ if (copyImage(href))
+ m_output << INDENT << ".. image:: " << href << endl << endl;
+}
+
+void QtXmlToSphinx::handleInlineImageTag(QXmlStreamReader& reader)
+{
+ if (reader.tokenType() != QXmlStreamReader::StartElement)
+ return;
+ const QString href = reader.attributes().value(QLatin1String("href")).toString();
+ if (!copyImage(href))
+ return;
+ // Handle inline images by substitution references. Insert a unique tag
+ // enclosed by '|' and define it further down. Determine tag from the base
+ //file name with number.
+ QString tag = href;
+ int pos = tag.lastIndexOf(QLatin1Char('/'));
+ if (pos != -1)
+ tag.remove(0, pos + 1);
+ pos = tag.indexOf(QLatin1Char('.'));
+ if (pos != -1)
+ tag.truncate(pos);
+ tag += QString::number(m_inlineImages.size() + 1);
+ m_inlineImages.append(InlineImage{tag, href});
+ m_output << '|' << tag << '|' << ' ';
}
void QtXmlToSphinx::handleRawTag(QXmlStreamReader& reader)
@@ -714,8 +1000,8 @@ void QtXmlToSphinx::handleRawTag(QXmlStreamReader& reader)
QString format = reader.attributes().value(QLatin1String("format")).toString();
m_output << INDENT << ".. raw:: " << format.toLower() << endl << endl;
} else if (token == QXmlStreamReader::Characters) {
- QStringList lst(reader.text().toString().split(QLatin1Char('\n')));
- foreach(QString row, lst)
+ const QVector<QStringRef> lst(reader.text().split(QLatin1Char('\n')));
+ for (const QStringRef &row : lst)
m_output << INDENT << INDENT << row << endl;
} else if (token == QXmlStreamReader::EndElement) {
m_output << endl << endl;
@@ -726,12 +1012,11 @@ void QtXmlToSphinx::handleCodeTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- QString format = reader.attributes().value(QLatin1String("format")).toString();
m_output << INDENT << "::" << endl << endl;
INDENT.indent++;
} else if (token == QXmlStreamReader::Characters) {
- QStringList lst(reader.text().toString().split(QLatin1Char('\n')));
- foreach(QString row, lst)
+ const QVector<QStringRef> lst(reader.text().split(QLatin1Char('\n')));
+ for (const QStringRef &row : lst)
m_output << INDENT << INDENT << row << endl;
} else if (token == QXmlStreamReader::EndElement) {
m_output << endl << endl;
@@ -793,22 +1078,17 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::Characters) {
QString location = reader.text().toString();
- QString identifier;
location.prepend(m_generator->libSourceDir() + QLatin1Char('/'));
- QString code = readFromLocation(location, identifier);
-
+ QString errorMessage;
+ QString code = readFromLocation(location, QString(), &errorMessage);
+ if (!errorMessage.isEmpty())
+ qCWarning(lcShiboken(), "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
m_output << INDENT << "::\n\n";
Indentation indentation(INDENT);
- if (code.isEmpty()) {
+ if (code.isEmpty())
m_output << INDENT << "<Code snippet \"" << location << "\" not found>" << endl;
- } else {
- foreach (QString line, code.split(QLatin1Char('\n'))) {
- if (!QString(line).trimmed().isEmpty())
- m_output << INDENT << line;
-
- m_output << endl;
- }
- }
+ else
+ formatCode(m_output, code, INDENT);
m_output << endl;
}
}
@@ -877,13 +1157,14 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
}
// calc width and height of each column and row
- QVector<int> colWidths(table.first().count());
+ const int headerColumnCount = table.constFirst().count();
+ QVector<int> colWidths(headerColumnCount);
QVector<int> rowHeights(table.count());
for (int i = 0, maxI = table.count(); i < maxI; ++i) {
const QtXmlToSphinx::TableRow& row = table[i];
for (int j = 0, maxJ = std::min(row.count(), colWidths.size()); j < maxJ; ++j) {
- QStringList rowLines = row[j].data.split(QLatin1Char('\n')); // cache this would be a good idea
- foreach (QString str, rowLines)
+ const QVector<QStringRef> rowLines = row[j].data.splitRef(QLatin1Char('\n')); // cache this would be a good idea
+ for (const QStringRef &str : rowLines)
colWidths[j] = std::max(colWidths[j], str.count());
rowHeights[i] = std::max(rowHeights[i], row[j].data.count(QLatin1Char('\n')) + 1);
}
@@ -895,7 +1176,7 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
// create a horizontal line to be used later.
QString horizontalLine = QLatin1String("+");
for (int i = 0, max = colWidths.count(); i < max; ++i) {
- horizontalLine += createRepeatedChar(colWidths[i], '-');
+ horizontalLine += QString(colWidths.at(i), QLatin1Char('-'));
horizontalLine += QLatin1Char('+');
}
@@ -905,7 +1186,7 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
// print line
s << INDENT << '+';
- for (int col = 0, max = colWidths.count(); col < max; ++col) {
+ for (int col = 0; col < headerColumnCount; ++col) {
char c;
if (col >= row.length() || row[col].rowSpan == -1)
c = ' ';
@@ -913,16 +1194,17 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
c = '=';
else
c = '-';
- s << createRepeatedChar(colWidths[col], c) << '+';
+ s << Pad(c, colWidths.at(col)) << '+';
}
s << endl;
// Print the table cells
for (int rowLine = 0; rowLine < rowHeights[i]; ++rowLine) { // for each line in a row
- for (int j = 0, maxJ = std::min(row.count(), colWidths.size()); j < maxJ; ++j) { // for each column
+ int j = 0;
+ for (int maxJ = std::min(row.count(), headerColumnCount); j < maxJ; ++j) { // for each column
const QtXmlToSphinx::TableCell& cell = row[j];
- QStringList rowLines = cell.data.split(QLatin1Char('\n')); // FIXME: Cache this!!!
+ const QVector<QStringRef> rowLines = cell.data.splitRef(QLatin1Char('\n')); // FIXME: Cache this!!!
if (!j) // First column, so we need print the identation
s << INDENT;
@@ -930,10 +1212,13 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table)
s << '|';
else
s << ' ';
- s << qSetFieldWidth(colWidths[j]) << left;
- s << (rowLine < rowLines.count() ? rowLines[rowLine] : QString());
- s << qSetFieldWidth(0);
+ if (rowLine < rowLines.count())
+ s << qSetFieldWidth(colWidths[j]) << left << rowLines.at(rowLine) << qSetFieldWidth(0);
+ else
+ s << Pad(' ', colWidths.at(j));
}
+ for ( ; j < headerColumnCount; ++j) // pad
+ s << '|' << Pad(' ', colWidths.at(j));
s << '|' << endl;
}
}
@@ -975,8 +1260,8 @@ static QString getFuncName(const AbstractMetaFunction* cppFunc) {
hashInitialized = true;
}
- QHash<QString, QString>::const_iterator it = operatorsHash.find(cppFunc->name());
- QString result = it != operatorsHash.end() ? it.value() : cppFunc->name();
+ QHash<QString, QString>::const_iterator it = operatorsHash.constFind(cppFunc->name());
+ QString result = it != operatorsHash.cend() ? it.value() : cppFunc->name();
result.replace(QLatin1String("::"), QLatin1String("."));
return result;
}
@@ -1007,7 +1292,8 @@ QString QtDocGenerator::fileNameForContext(GeneratorContext &context) const
}
}
-void QtDocGenerator::writeFormatedText(QTextStream& s, const Documentation& doc, const AbstractMetaClass* metaClass)
+void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc,
+ const AbstractMetaClass *metaClass)
{
QString metaClassName;
@@ -1018,17 +1304,24 @@ void QtDocGenerator::writeFormatedText(QTextStream& s, const Documentation& doc,
QtXmlToSphinx x(this, doc.value(), metaClassName);
s << x;
} else {
- QStringList lines = doc.value().split(QLatin1Char('\n'));
- QRegExp regex(QLatin1String("\\S")); // non-space character
+ const QString &value = doc.value();
+ const QVector<QStringRef> lines = value.splitRef(QLatin1Char('\n'));
int typesystemIndentation = std::numeric_limits<int>().max();
- // check how many spaces must be removed from the begining of each line
- foreach (QString line, lines) {
- int idx = line.indexOf(regex);
- if (idx >= 0)
- typesystemIndentation = qMin(typesystemIndentation, idx);
+ // check how many spaces must be removed from the beginning of each line
+ for (const QStringRef &line : lines) {
+ const auto it = std::find_if(line.cbegin(), line.cend(),
+ [] (QChar c) { return !c.isSpace(); });
+ if (it != line.cend())
+ typesystemIndentation = qMin(typesystemIndentation, int(it - line.cbegin()));
+ }
+ if (typesystemIndentation == std::numeric_limits<int>().max())
+ typesystemIndentation = 0;
+ for (const QStringRef &line : lines) {
+ s << INDENT
+ << (typesystemIndentation > 0 && typesystemIndentation < line.size()
+ ? line.right(line.size() - typesystemIndentation) : line)
+ << endl;
}
- foreach (QString line, lines)
- s << INDENT << line.remove(0, typesystemIndentation) << endl;
}
s << endl;
@@ -1037,7 +1330,7 @@ void QtDocGenerator::writeFormatedText(QTextStream& s, const Documentation& doc,
static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaClass, const AbstractMetaClassList& allClasses)
{
AbstractMetaClassList res;
- foreach (AbstractMetaClass* c, allClasses) {
+ for (AbstractMetaClass *c : allClasses) {
if (c != metaClass && c->inheritsFrom(metaClass))
res << c;
}
@@ -1047,7 +1340,7 @@ static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaCl
s << "**Inherited by:** ";
QStringList classes;
- foreach (AbstractMetaClass* c, res)
+ for (AbstractMetaClass *c : qAsConst(res))
classes << QLatin1String(":ref:`") + getClassTargetFullName(c, false) + QLatin1Char('`');
s << classes.join(QLatin1String(", ")) << endl << endl;
}
@@ -1067,9 +1360,9 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex
s << ".. _" << className << ":" << endl << endl;
s << className << endl;
- s << createRepeatedChar(className.count(), '*') << endl << endl;
+ s << Pad('*', className.count()) << endl << endl;
- s << ".. inheritance-diagram:: " << className << endl
+ s << ".. inheritance-diagram:: " << getClassTargetFullName(metaClass, true) << endl
<< " :parts: 2" << endl << endl; // TODO: This would be a parameter in the future...
@@ -1084,12 +1377,13 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex
AbstractMetaFunctionList functionList = metaClass->functions();
qSort(functionList.begin(), functionList.end(), functionSort);
- s << "Detailed Description\n"
- "--------------------\n\n";
+ s << endl
+ << "Detailed Description\n"
+ "--------------------\n\n";
writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, metaClass, 0);
if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, metaClass, 0))
- writeFormatedText(s, metaClass->documentation(), metaClass);
+ writeFormattedText(s, metaClass->documentation(), metaClass);
if (!metaClass->isNamespace())
writeConstructors(s, metaClass);
@@ -1098,7 +1392,7 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex
writeFields(s, metaClass);
- foreach (AbstractMetaFunction* func, functionList) {
+ for (AbstractMetaFunction *func : qAsConst(functionList)) {
if (shouldSkip(func))
continue;
@@ -1121,7 +1415,8 @@ void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass*
QStringList slotList;
QStringList staticFunctionList;
- foreach (AbstractMetaFunction* func, cppClass->functions()) {
+ const AbstractMetaFunctionList &classFunctions = cppClass->functions();
+ for (AbstractMetaFunction *func : classFunctions) {
if (shouldSkip(func))
continue;
@@ -1157,9 +1452,9 @@ void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass*
if ((functionList.size() > 0) || (staticFunctionList.size() > 0)) {
QtXmlToSphinx::Table functionTable;
- QtXmlToSphinx::TableRow row;
- s << "Synopsis" << endl
+ s << endl
+ << "Synopsis" << endl
<< "--------" << endl << endl;
writeFunctionBlock(s, QLatin1String("Functions"), functionList);
@@ -1180,8 +1475,8 @@ void QtDocGenerator::writeFunctionBlock(QTextStream& s, const QString& title, QS
s << ".. container:: function_list" << endl << endl;
Indentation indentation(INDENT);
- foreach (QString func, functions)
- s << '*' << INDENT << func << endl;
+ for (const QString &func : qAsConst(functions))
+ s << INDENT << '*' << ' ' << func << endl;
s << endl << endl;
}
@@ -1191,9 +1486,10 @@ void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClas
{
static const QString section_title = QLatin1String(".. attribute:: ");
- foreach (AbstractMetaEnum* en, cppClass->enums()) {
+ const AbstractMetaEnumList &enums = cppClass->enums();
+ for (AbstractMetaEnum *en : enums) {
s << section_title << getClassTargetFullName(cppClass) << '.' << en->name() << endl << endl;
- writeFormatedText(s, en->documentation(), cppClass);
+ writeFormattedText(s, en->documentation(), cppClass);
if (en->typeEntry() && (en->typeEntry()->version() != 0))
s << ".. note:: This enum was introduced or modified in Qt " << en->typeEntry()->version() << endl;
@@ -1205,10 +1501,11 @@ void QtDocGenerator::writeFields(QTextStream& s, const AbstractMetaClass* cppCla
{
static const QString section_title = QLatin1String(".. attribute:: ");
- foreach (AbstractMetaField* field, cppClass->fields()) {
+ const AbstractMetaFieldList &fields = cppClass->fields();
+ for (AbstractMetaField *field : fields) {
s << section_title << getClassTargetFullName(cppClass) << "." << field->name() << endl << endl;
//TODO: request for member ‘documentation’ is ambiguous
- writeFormatedText(s, field->AbstractMetaAttributes::documentation(), cppClass);
+ writeFormattedText(s, field->AbstractMetaAttributes::documentation(), cppClass);
}
}
@@ -1218,14 +1515,15 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
static const QString sectionTitleSpace = QString(sectionTitle.size(), QLatin1Char(' '));
AbstractMetaFunctionList lst = cppClass->queryFunctions(AbstractMetaClass::Constructors | AbstractMetaClass::Visible);
+ for (int i = lst.size() - 1; i >= 0; --i) {
+ if (lst.at(i)->isModifiedRemoved() || lst.at(i)->functionType() == AbstractMetaFunction::MoveConstructorFunction)
+ lst.removeAt(i);
+ }
bool first = true;
QHash<QString, AbstractMetaArgument*> arg_map;
- foreach(AbstractMetaFunction* func, lst) {
- if (func->isModifiedRemoved())
- continue;
-
+ for (AbstractMetaFunction *func : qAsConst(lst)) {
if (first) {
first = false;
s << sectionTitle;
@@ -1233,8 +1531,8 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
s << sectionTitleSpace;
}
writeFunction(s, false, cppClass, func);
- foreach(AbstractMetaArgument* arg, func->arguments())
- {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (AbstractMetaArgument *arg : arguments) {
if (!arg_map.contains(arg->name())) {
arg_map.insert(arg->name(), arg);
}
@@ -1243,16 +1541,15 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
s << endl;
- foreach (AbstractMetaArgument* arg, arg_map.values()) {
+ for (QHash<QString, AbstractMetaArgument*>::const_iterator it = arg_map.cbegin(), end = arg_map.cend(); it != end; ++it) {
Indentation indentation(INDENT);
- writeParamerteType(s, cppClass, arg);
+ writeParameterType(s, cppClass, it.value());
}
s << endl;
- foreach (AbstractMetaFunction* func, lst) {
- writeFormatedText(s, func->documentation(), cppClass);
- }
+ for (AbstractMetaFunction *func : qAsConst(lst))
+ writeFormattedText(s, func->documentation(), cppClass);
}
QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* cppClass, const AbstractMetaFunction* func)
@@ -1260,7 +1557,8 @@ QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* cppClass, cons
QString ret;
int optArgs = 0;
- foreach (AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (AbstractMetaArgument *arg : arguments) {
if (func->argumentRemoved(arg->argumentIndex() + 1))
continue;
@@ -1311,7 +1609,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
invalidStrings << QLatin1String("*") << QLatin1String("//") << QLatin1String("/*") << QLatin1String("*/");
- foreach (CodeSnip snip, codeSnips) {
+ for (const CodeSnip &snip : codeSnips) {
if ((snip.position != position) ||
!(snip.language & language))
continue;
@@ -1325,14 +1623,13 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
break;
QString codeBlock = code.mid(startBlock, endBlock - startBlock);
- QStringList rows = codeBlock.split(QLatin1Char('\n'));
+ const QStringList rows = codeBlock.split(QLatin1Char('\n'));
int currenRow = 0;
int offset = 0;
- foreach(QString row, rows) {
- foreach(QString invalidString, invalidStrings) {
- row = row.remove(invalidString);
- }
+ for (QString row : rows) {
+ for (const QString &invalidString : qAsConst(invalidStrings))
+ row.remove(invalidString);
if (row.trimmed().size() == 0) {
if (currenRow == 0)
@@ -1370,7 +1667,8 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
Indentation indentation(INDENT);
bool didSomething = false;
- foreach (DocModification mod, cppClass->typeEntry()->docModifications()) {
+ const DocModificationList &mods = cppClass->typeEntry()->docModifications();
+ for (const DocModification &mod : mods) {
if (mod.mode() == mode) {
bool modOk = func ? mod.signature() == func->minimalSignature() : mod.signature().isEmpty();
@@ -1378,15 +1676,15 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
Documentation doc;
Documentation::Format fmt;
- if (mod.format == TypeSystem::NativeCode)
+ if (mod.format() == TypeSystem::NativeCode)
fmt = Documentation::Native;
- else if (mod.format == TypeSystem::TargetLangCode)
+ else if (mod.format() == TypeSystem::TargetLangCode)
fmt = Documentation::Target;
else
continue;
doc.setValue(mod.code() , fmt);
- writeFormatedText(s, doc, cppClass);
+ writeFormattedText(s, doc, cppClass);
didSomething = true;
}
}
@@ -1462,31 +1760,34 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType* type, cons
return strType;
}
-void QtDocGenerator::writeParamerteType(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaArgument* arg)
+void QtDocGenerator::writeParameterType(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaArgument* arg)
{
s << INDENT << ":param " << arg->name() << ": "
<< translateToPythonType(arg->type(), cppClass) << endl;
}
-void QtDocGenerator::writeFunctionParametersType(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func)
+void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass,
+ const AbstractMetaFunction *func)
{
Indentation indentation(INDENT);
s << endl;
- foreach (AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &funcArgs = func->arguments();
+ for (AbstractMetaArgument *arg : funcArgs) {
if (func->argumentRemoved(arg->argumentIndex() + 1))
continue;
- writeParamerteType(s, cppClass, arg);
+ writeParameterType(s, cppClass, arg);
}
if (!func->isConstructor() && func->type()) {
QString retType;
// check if the return type was modified
- foreach (FunctionModification mod, func->modifications()) {
- foreach (ArgumentModification argMod, mod.argument_mods) {
+ const FunctionModificationList &mods = func->modifications();
+ for (const FunctionModification &mod : mods) {
+ for (const ArgumentModification &argMod : mod.argument_mods) {
if (argMod.index == 0) {
retType = argMod.modified_type;
break;
@@ -1515,7 +1816,7 @@ void QtDocGenerator::writeFunction(QTextStream& s, bool writeDoc, const Abstract
s << endl;
writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, cppClass, func);
if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, cppClass, func))
- writeFormatedText(s, func->documentation(), cppClass);
+ writeFormattedText(s, func->documentation(), cppClass);
writeInjectDocumentation(s, TypeSystem::DocModificationAppend, cppClass, func);
}
}
@@ -1526,7 +1827,7 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4
TocMap tocMap;
QChar Q = QLatin1Char('Q');
QChar idx;
- foreach (QString item, items) {
+ for (QString item : items) {
if (item.isEmpty())
continue;
if (item.startsWith(Q) && item.length() > 1)
@@ -1551,7 +1852,7 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4
ss << "**" << it.key() << "**" << endl << endl;
i += 2; // a letter title is equivalent to two entries in space
- foreach (QString item, it.value()) {
+ for (const QString &item : qAsConst(it.value())) {
ss << "* :doc:`" << item << "`" << endl;
++i;
@@ -1595,7 +1896,7 @@ bool QtDocGenerator::finishGeneration()
QString title = it.key();
s << title << endl;
- s << createRepeatedChar(title.length(), '*') << endl << endl;
+ s << Pad('*', title.length()) << endl << endl;
/* Avoid showing "Detailed Description for *every* class in toc tree */
Indentation indentation(INDENT);
@@ -1628,7 +1929,7 @@ bool QtDocGenerator::finishGeneration()
s << INDENT << ".. toctree::" << endl;
Indentation deeperIndentation(INDENT);
s << INDENT << ":maxdepth: 1" << endl << endl;
- foreach (QString className, it.value())
+ for (const QString &className : qAsConst(it.value()))
s << INDENT << className << endl;
s << endl << endl;
}
@@ -1686,19 +1987,18 @@ bool QtDocGenerator::doSetup(const QMap<QString, QString>& args)
}
-QMap<QString, QString> QtDocGenerator::options() const
+Generator::OptionDescriptions QtDocGenerator::options() const
{
- QMap<QString, QString> options;
- options.insert(QLatin1String("doc-parser"),
- QLatin1String("The documentation parser used to interpret the documentation input files (qdoc3|doxygen)"));
- options.insert(QLatin1String("library-source-dir"),
- QLatin1String("Directory where library source code is located"));
- options.insert(QLatin1String("documentation-data-dir"),
- QLatin1String("Directory with XML files generated by documentation tool (qdoc3 or Doxygen)"));
- options.insert(QLatin1String("documentation-code-snippets-dir"),
- QLatin1String("Directory used to search code snippets used by the documentation"));
- options.insert(QLatin1String("documentation-extra-sections-dir"),
- QLatin1String("Directory used to search for extra documentation sections"));
- return options;
+ return OptionDescriptions()
+ << qMakePair(QLatin1String("doc-parser"),
+ QLatin1String("The documentation parser used to interpret the documentation input files (qdoc3|doxygen)"))
+ << qMakePair(QLatin1String("documentation-code-snippets-dir"),
+ QLatin1String("Directory used to search code snippets used by the documentation"))
+ << qMakePair(QLatin1String("documentation-data-dir"),
+ QLatin1String("Directory with XML files generated by documentation tool (qdoc3 or Doxygen)"))
+ << qMakePair(QLatin1String("documentation-extra-sections-dir"),
+ QLatin1String("Directory used to search for extra documentation sections"))
+ << qMakePair(QLatin1String("library-source-dir"),
+ QLatin1String("Directory where library source code is located"));
}
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
index fa8524b21..af26b7fab 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
@@ -30,6 +30,7 @@
#include <QtCore/QStack>
#include <QtCore/QHash>
+#include <QtCore/QScopedPointer>
#include <QtCore/QTextStream>
#include <QXmlStreamReader>
#include "generator.h"
@@ -48,6 +49,12 @@ class QtDocGenerator;
class QtXmlToSphinx
{
public:
+ struct InlineImage
+ {
+ QString tag;
+ QString href;
+ };
+
struct TableCell
{
short rowSpan;
@@ -101,8 +108,19 @@ public:
}
private:
- QString resolveContextForMethod(const QString& methodName);
- QString expandFunction(const QString& function);
+ struct LinkContext
+ {
+ LinkContext(const QString &ref, const QString &lType) : linkRef(ref), type(lType) {}
+
+ QString linkTag;
+ QString linkRef;
+ QString linkText;
+ QString linkTagEnding;
+ QString type;
+ };
+
+ QString resolveContextForMethod(const QString& methodName) const;
+ QString expandFunction(const QString& function) const;
QString transform(const QString& doc);
void handleHeadingTag(QXmlStreamReader& reader);
@@ -115,6 +133,7 @@ private:
void handleDotsTag(QXmlStreamReader& reader);
void handleLinkTag(QXmlStreamReader& reader);
void handleImageTag(QXmlStreamReader& reader);
+ void handleInlineImageTag(QXmlStreamReader& reader);
void handleListTag(QXmlStreamReader& reader);
void handleTermTag(QXmlStreamReader& reader);
void handleSuperScriptTag(QXmlStreamReader& reader);
@@ -133,6 +152,10 @@ private:
void handleUselessTag(QXmlStreamReader& reader);
void handleAnchorTag(QXmlStreamReader& reader);
+ LinkContext *handleLinkStart(const QString &type, const QString &ref) const;
+ void handleLinkText(LinkContext *linkContext, QString linktext) const;
+ void handleLinkEnd(LinkContext *linkContext);
+
typedef void (QtXmlToSphinx::*TagHandler)(QXmlStreamReader&);
QHash<QString, TagHandler> m_handlerMap;
QStack<TagHandler> m_handlers;
@@ -143,6 +166,8 @@ private:
Table m_currentTable;
+ QScopedPointer<LinkContext> m_linkContext; // for <link>
+ QScopedPointer<LinkContext> m_seeAlsoContext; // for <see-also>foo()</see-also>
bool m_tableHasHeader;
QString m_context;
QtDocGenerator* m_generator;
@@ -150,12 +175,16 @@ private:
bool m_insideItalic;
QString m_lastTagName;
QString m_opened_anchor;
+ QVector<InlineImage> m_inlineImages;
- QString readFromLocations(const QStringList& locations, const QString& path, const QString& identifier);
- QString readFromLocation(const QString& location, const QString& identifier, bool* ok = 0);
+ QString readFromLocations(const QStringList &locations, const QString &path,
+ const QString &identifier, QString *errorMessage);
+ QString readFromLocation(const QString &location, const QString &identifier,
+ QString *errorMessage);
void pushOutputBuffer();
QString popOutputBuffer();
void writeTable(Table& table);
+ bool copyImage(const QString &href) const;
};
inline QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx& xmlToSphinx)
@@ -179,6 +208,8 @@ public:
return m_libSourceDir;
}
+ QString docDataDir() const { return m_docDataDir; }
+
bool doSetup(const QMap<QString, QString>& args);
const char* name() const
@@ -186,7 +217,7 @@ public:
return "QtDocGenerator";
}
- QMap<QString, QString> options() const;
+ OptionDescriptions options() const;
QStringList codeSnippetDirs() const
{
@@ -209,13 +240,15 @@ private:
void writeArguments(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaFunction *func);
void writeFunctionSignature(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func);
void writeFunction(QTextStream& s, bool writeDoc, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func);
- void writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaFunction* func);
+ void writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass,
+ const AbstractMetaFunction* func);
void writeFunctionList(QTextStream& s, const AbstractMetaClass* cppClass);
void writeFunctionBlock(QTextStream& s, const QString& title, QStringList& functions);
- void writeParamerteType(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaArgument *arg);
+ void writeParameterType(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaArgument *arg);
void writeConstructors(QTextStream &s, const AbstractMetaClass *cppClass);
- void writeFormatedText(QTextStream& s, const Documentation& doc, const AbstractMetaClass* metaclass = 0);
+ void writeFormattedText(QTextStream &s, const Documentation &doc,
+ const AbstractMetaClass *metaclass = nullptr);
bool writeInjectDocumentation(QTextStream& s, TypeSystem::DocModificationMode mode, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func);
void writeDocSnips(QTextStream &s, const CodeSnipList &codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language);
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index ce74c9887..be42adb0f 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -36,6 +36,7 @@
#include <QtCore/QDir>
#include <QtCore/QMetaObject>
+#include <QtCore/QRegularExpression>
#include <QtCore/QTextStream>
#include <QtCore/QDebug>
#include <QMetaType>
@@ -153,13 +154,15 @@ QString CppGenerator::fileNameForContext(GeneratorContext &context) const
}
}
-QList<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass,
+QVector<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass,
uint queryIn)
{
// ( func_name, num_args ) => func_list
- QMap<QPair<QString, int >, AbstractMetaFunctionList> results;
+ typedef QMap<QPair<QString, int >, AbstractMetaFunctionList> ResultMap;
+ ResultMap results;
const AbstractMetaClass::OperatorQueryOptions query(queryIn);
- foreach (AbstractMetaFunction* func, metaClass->operatorOverloads(query)) {
+ const AbstractMetaFunctionList &funcs = metaClass->operatorOverloads(query);
+ for (AbstractMetaFunction *func : funcs) {
if (func->isModifiedRemoved()
|| func->usesRValueReferences()
|| func->name() == QLatin1String("operator[]")
@@ -176,7 +179,11 @@ QList<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(con
QPair<QString, int > op(func->name(), args);
results[op].append(func);
}
- return results.values();
+ QVector<AbstractMetaFunctionList> result;
+ result.reserve(results.size());
+ for (ResultMap::const_iterator it = results.cbegin(), end = results.cend(); it != end; ++it)
+ result.append(it.value());
+ return result;
}
bool CppGenerator::hasBoolCast(const AbstractMetaClass* metaClass) const
@@ -203,6 +210,13 @@ static const char includeQDebug[] =
"#endif\n"
"#include <QDebug>\n";
+static QString chopType(QString s)
+{
+ if (s.endsWith(QLatin1String("_Type")))
+ s.chop(5);
+ return s;
+}
+
/*!
Function used to write the class generated binding code on the buffer
\param s the output buffer
@@ -252,7 +266,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << endl << "// main header" << endl << "#include \"" << headerfile << '"' << endl;
s << endl << "// inner classes" << endl;
- foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) {
+ const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
+ for (AbstractMetaClass *innerClass : innerClasses) {
GeneratorContext innerClassContext(innerClass);
if (shouldGenerate(innerClass)) {
QString headerfile = fileNameForContext(innerClassContext);
@@ -262,16 +277,16 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
}
AbstractMetaEnumList classEnums = metaClass->enums();
- foreach (AbstractMetaClass* innerClass, metaClass->innerClasses())
+ for (AbstractMetaClass *innerClass : innerClasses)
lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass);
//Extra includes
s << endl << "// Extra includes" << endl;
- QList<Include> includes = metaClass->typeEntry()->extraIncludes();
- foreach (AbstractMetaEnum* cppEnum, classEnums)
+ QVector<Include> includes = metaClass->typeEntry()->extraIncludes();
+ for (AbstractMetaEnum *cppEnum : qAsConst(classEnums))
includes.append(cppEnum->typeEntry()->extraIncludes());
qSort(includes.begin(), includes.end());
- foreach (const Include &inc, includes)
+ for (const Include &inc : qAsConst(includes))
s << inc.toString() << endl;
s << endl;
@@ -324,15 +339,19 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << "}\n\n";
}
- foreach (const AbstractMetaFunction* func, filterFunctions(metaClass)) {
- if ((func->isPrivate() && !visibilityModifiedToPrivate(func))
- || (func->isModifiedRemoved() && !func->isAbstract()))
+ const AbstractMetaFunctionList &funcs = filterFunctions(metaClass);
+ for (const AbstractMetaFunction *func : funcs) {
+ const bool notAbstract = !func->isAbstract();
+ if ((func->isPrivate() && notAbstract && !visibilityModifiedToPrivate(func))
+ || (func->isModifiedRemoved() && notAbstract))
continue;
- if (func->functionType() == AbstractMetaFunction::ConstructorFunction && !func->isUserAdded())
+ if (func->functionType() == AbstractMetaFunction::ConstructorFunction && !func->isUserAdded()) {
writeConstructorNative(s, func);
- else if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
- && (func->isVirtual() || func->isAbstract()))
+ } else if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
+ && ((func->isVirtual() || func->isAbstract())
+ && (func->attributes() & AbstractMetaAttributes::FinalCppMethod) == 0)) {
writeVirtualMethodNative(s, func);
+ }
}
if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) {
@@ -357,7 +376,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
QSet<QString> seenSignatures;
- foreach (AbstractMetaFunction* func, it.value()) {
+ for (AbstractMetaFunction *func : it.value()) {
if (!func->isAssignmentOperator()
&& !func->usesRValueReferences()
&& !func->isCastOperator()
@@ -375,7 +394,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (overloads.isEmpty())
continue;
- const AbstractMetaFunction* rfunc = overloads.first();
+ const AbstractMetaFunction* rfunc = overloads.constFirst();
if (m_sequenceProtocol.contains(rfunc->name()) || m_mappingProtocol.contains(rfunc->name()))
continue;
@@ -411,7 +430,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
AbstractMetaType *pointerToInnerType =
buildAbstractMetaTypeFromString(pointerToInnerTypeName);
- AbstractMetaFunction *mutableRfunc = overloads.first();
+ AbstractMetaFunction *mutableRfunc = overloads.constFirst();
mutableRfunc->replaceType(pointerToInnerType);
} else if (smartPointerTypeEntry->refCountMethodName().isEmpty()
|| smartPointerTypeEntry->refCountMethodName() != rfunc->name()) {
@@ -434,8 +453,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
}
}
- QString className = cpythonTypeName(metaClass);
- className.remove(QRegExp(QLatin1String("_Type$")));
+ const QString className = chopType(cpythonTypeName(metaClass));
if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
writeCopyFunction(s, classContext);
@@ -484,15 +502,15 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
}
if (supportsNumberProtocol(metaClass) && !metaClass->typeEntry()->isSmartPointer()) {
- QList<AbstractMetaFunctionList> opOverloads = filterGroupedOperatorFunctions(
+ const QVector<AbstractMetaFunctionList> opOverloads = filterGroupedOperatorFunctions(
metaClass,
AbstractMetaClass::ArithmeticOp
| AbstractMetaClass::LogicalOp
| AbstractMetaClass::BitwiseOp);
- foreach (const AbstractMetaFunctionList &allOverloads, opOverloads) {
+ for (const AbstractMetaFunctionList &allOverloads : opOverloads) {
AbstractMetaFunctionList overloads;
- foreach (AbstractMetaFunction* func, allOverloads) {
+ for (AbstractMetaFunction *func : allOverloads) {
if (!func->isModifiedRemoved()
&& !func->isPrivate()
&& (func->ownerClass() == func->implementingClass() || func->isAbstract()))
@@ -521,7 +539,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
}
if (shouldGenerateGetSetList(metaClass) && !classContext.forSmartPointer()) {
- foreach (const AbstractMetaField* metaField, metaClass->fields()) {
+ const AbstractMetaFieldList &fields = metaClass->fields();
+ for (const AbstractMetaField *metaField : fields) {
if (metaField->isStatic())
continue;
writeGetterFunction(s, metaField, classContext);
@@ -532,7 +551,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << "// Getters and Setters for " << metaClass->name() << endl;
s << "static PyGetSetDef " << cpythonGettersSettersDefinitionName(metaClass) << "[] = {" << endl;
- foreach (const AbstractMetaField* metaField, metaClass->fields()) {
+ for (const AbstractMetaField *metaField : fields) {
if (metaField->isStatic())
continue;
@@ -562,7 +581,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
writeTypeDiscoveryFunction(s, metaClass);
- foreach (AbstractMetaEnum* cppEnum, classEnums) {
+ for (AbstractMetaEnum *cppEnum : qAsConst(classEnums)) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
@@ -593,7 +612,7 @@ void CppGenerator::writeConstructorNative(QTextStream& s, const AbstractMetaFunc
s << " : ";
writeFunctionCall(s, func);
s << " {" << endl;
- const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last();
+ const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
writeCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, func, lastArg);
s << INDENT << "// ... middle" << endl;
writeCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, func, lastArg);
@@ -614,7 +633,8 @@ static bool allArgumentsRemoved(const AbstractMetaFunction* func)
{
if (func->arguments().isEmpty())
return false;
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
if (!func->argumentRemoved(arg->argumentIndex() + 1))
return false;
}
@@ -666,19 +686,24 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
QString defaultReturnExpr;
if (retType) {
- foreach (const FunctionModification &mod, func->modifications()) {
- foreach (const ArgumentModification &argMod, mod.argument_mods) {
+ const FunctionModificationList &mods = func->modifications();
+ for (const FunctionModification &mod : mods) {
+ for (const ArgumentModification &argMod : mod.argument_mods) {
if (argMod.index == 0 && !argMod.replacedDefaultExpression.isEmpty()) {
- QRegExp regex(QLatin1String("%(\\d+)"));
+ static const QRegularExpression regex(QStringLiteral("%(\\d+)"));
+ Q_ASSERT(regex.isValid());
defaultReturnExpr = argMod.replacedDefaultExpression;
- int offset = 0;
- while ((offset = regex.indexIn(defaultReturnExpr, offset)) != -1) {
- int argId = regex.cap(1).toInt() - 1;
+ for (int offset = 0; ; ) {
+ const QRegularExpressionMatch match = regex.match(defaultReturnExpr, offset);
+ if (!match.hasMatch())
+ break;
+ const int argId = match.capturedRef(1).toInt() - 1;
if (argId < 0 || argId > func->arguments().count()) {
qCWarning(lcShiboken) << "The expression used in return value contains an invalid index.";
break;
}
- defaultReturnExpr.replace(regex.cap(0), func->arguments()[argId]->name());
+ defaultReturnExpr.replace(match.captured(0), func->arguments().at(argId)->name());
+ offset = match.capturedStart(1);
}
}
}
@@ -709,7 +734,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
//Write declaration/native injected code
if (func->hasInjectedCode()) {
CodeSnipList snips = func->injectedCodeSnips();
- const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last();
+ const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode, func, lastArg);
s << endl;
}
@@ -732,7 +757,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
CodeSnipList snips;
if (func->hasInjectedCode()) {
snips = func->injectedCodeSnips();
- const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last();
+ const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::ShellCode, func, lastArg);
s << endl;
}
@@ -764,7 +789,8 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
s << "PyTuple_New(0));" << endl;
} else {
QStringList argConversions;
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
if (func->argumentRemoved(arg->argumentIndex() + 1))
continue;
@@ -810,8 +836,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
bool invalidateReturn = false;
QSet<int> invalidateArgs;
- foreach (const FunctionModification &funcMod, func->modifications()) {
- foreach (const ArgumentModification &argMod, funcMod.argument_mods) {
+ const FunctionModificationList &mods = func->modifications();
+ for (const FunctionModification &funcMod : mods) {
+ for (const ArgumentModification &argMod : funcMod.argument_mods) {
if (argMod.resetAfterUse && !invalidateArgs.contains(argMod.index)) {
invalidateArgs.insert(argMod.index);
s << INDENT << "bool invalidateArg" << argMod.index;
@@ -830,7 +857,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
if (injectedCodeUsesPySelf(func))
s << INDENT << "PyObject* pySelf = BindingManager::instance().retrieveWrapper(this);" << endl;
- const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last();
+ const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, func, lastArg);
s << endl;
}
@@ -908,7 +935,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
Indentation indentation(INDENT);
s << INDENT << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR ".object());" << endl;
}
- foreach (int argIndex, invalidateArgs) {
+ for (int argIndex : qAsConst(invalidateArgs)) {
s << INDENT << "if (invalidateArg" << argIndex << ')' << endl;
Indentation indentation(INDENT);
s << INDENT << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" PYTHON_ARGS ", ";
@@ -916,8 +943,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
}
- foreach (const FunctionModification &funcMod, func->modifications()) {
- foreach (const ArgumentModification &argMod, funcMod.argument_mods) {
+ const FunctionModificationList &funcMods = func->modifications();
+ for (const FunctionModification &funcMod : funcMods) {
+ for (const ArgumentModification &argMod : funcMod.argument_mods) {
if (argMod.ownerships.contains(TypeSystem::NativeCode)
&& argMod.index == 0 && argMod.ownerships[TypeSystem::NativeCode] == TypeSystem::CppOwnership) {
s << INDENT << "if (Shiboken::Object::checkType(" PYTHON_RETURN_VAR "))" << endl;
@@ -929,7 +957,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
if (func->hasInjectedCode()) {
s << endl;
- const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last();
+ const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, func, lastArg);
}
@@ -1019,7 +1047,6 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry*
{
if (!enumType)
return;
- QString enumFlagName = enumType->isFlags() ? QLatin1String("flag") : QLatin1String("enum");
QString typeName = fixedCppTypeName(enumType);
QString enumPythonType = cpythonTypeNameExt(enumType);
QString cppTypeName = getFullTypeName(enumType).trimmed();
@@ -1043,7 +1070,8 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry*
code.clear();
- c << INDENT << "int castCppIn = *((" << cppTypeName << "*)cppIn);" << endl;
+ c << INDENT << "const int castCppIn = int(*reinterpret_cast<const "
+ << cppTypeName << " *>(cppIn));" << endl;
c << INDENT;
c << "return ";
if (enumType->isFlags())
@@ -1090,11 +1118,12 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
s << "// Type conversion functions." << endl << endl;
AbstractMetaEnumList classEnums = metaClass->enums();
- foreach (AbstractMetaClass* innerClass, metaClass->innerClasses())
+ const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
+ for (AbstractMetaClass *innerClass : innerClasses)
lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass);
if (!classEnums.isEmpty())
s << "// Python to C++ enum conversion." << endl;
- foreach (const AbstractMetaEnum* metaEnum, classEnums)
+ for (const AbstractMetaEnum *metaEnum : qAsConst(classEnums))
writeEnumConverterFunctions(s, metaEnum);
if (metaClass->isNamespace())
@@ -1204,7 +1233,8 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
// Implicit conversions.
AbstractMetaFunctionList implicitConvs;
if (!customConversion || !customConversion->replaceOriginalTargetToNativeConversions()) {
- foreach (AbstractMetaFunction* func, implicitConversions(metaClass->typeEntry())) {
+ const AbstractMetaFunctionList &allImplicitConvs = implicitConversions(metaClass->typeEntry());
+ for (AbstractMetaFunction *func : allImplicitConvs) {
if (!func->isUserAdded())
implicitConvs << func;
}
@@ -1214,7 +1244,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
s << "// Implicit conversions." << endl;
AbstractMetaType* targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass);
- foreach (const AbstractMetaFunction* conv, implicitConvs) {
+ for (const AbstractMetaFunction* conv : qAsConst(implicitConvs)) {
if (conv->isModifiedRemoved())
continue;
@@ -1229,7 +1259,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
// Constructor that does implicit conversion.
if (!conv->typeReplaced(1).isEmpty())
continue;
- const AbstractMetaType* sourceType = conv->arguments().first()->type();
+ const AbstractMetaType* sourceType = conv->arguments().constFirst()->type();
typeCheck = cpythonCheckFunction(sourceType);
bool isUserPrimitiveWithoutTargetLangName = isUserPrimitive(sourceType)
&& sourceType->typeEntry()->targetLangApiName() == sourceType->typeEntry()->name();
@@ -1273,7 +1303,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
}
const AbstractMetaType* sourceType = conv->isConversionOperator()
? buildAbstractMetaTypeFromAbstractMetaClass(conv->ownerClass())
- : conv->arguments().first()->type();
+ : conv->arguments().constFirst()->type();
writePythonToCppConversionFunctions(s, sourceType, targetType, typeCheck, toCppConv, toCppPreConv);
}
@@ -1288,7 +1318,7 @@ void CppGenerator::writeCustomConverterFunctions(QTextStream& s, const CustomCon
if (toCppConversions.isEmpty())
return;
s << "// Python to C++ conversions for type '" << customConversion->ownerType()->qualifiedCppName() << "'." << endl;
- foreach (CustomConversion::TargetToNativeConversion* toNative, toCppConversions)
+ for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions)
writePythonToCppConversionFunctions(s, toNative, customConversion->ownerType());
s << endl;
}
@@ -1368,7 +1398,8 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
// Add implicit conversions.
AbstractMetaFunctionList implicitConvs;
if (!customConversion || !customConversion->replaceOriginalTargetToNativeConversions()) {
- foreach (AbstractMetaFunction* func, implicitConversions(metaClass->typeEntry())) {
+ const AbstractMetaFunctionList &allImplicitConvs = implicitConversions(metaClass->typeEntry());
+ for (AbstractMetaFunction *func : allImplicitConvs) {
if (!func->isUserAdded())
implicitConvs << func;
}
@@ -1378,7 +1409,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
s << INDENT << "// Add implicit conversions to type converter." << endl;
AbstractMetaType* targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass);
- foreach (const AbstractMetaFunction* conv, implicitConvs) {
+ for (const AbstractMetaFunction *conv : qAsConst(implicitConvs)) {
if (conv->isModifiedRemoved())
continue;
const AbstractMetaType* sourceType;
@@ -1388,7 +1419,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
// Constructor that does implicit conversion.
if (!conv->typeReplaced(1).isEmpty())
continue;
- sourceType = conv->arguments().first()->type();
+ sourceType = conv->arguments().constFirst()->type();
}
QString toCpp = pythonToCppFunctionName(sourceType, targetType);
QString isConv = convertibleToCppFunctionName(sourceType, targetType);
@@ -1406,7 +1437,7 @@ void CppGenerator::writeCustomConverterRegister(QTextStream& s, const CustomConv
if (toCppConversions.isEmpty())
return;
s << INDENT << "// Add user defined implicit conversions to type converter." << endl;
- foreach (CustomConversion::TargetToNativeConversion* toNative, toCppConversions) {
+ for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions) {
QString toCpp = pythonToCppFunctionName(toNative, customConversion->ownerType());
QString isConv = convertibleToCppFunctionName(toNative, customConversion->ownerType());
writeAddPythonToCppConversion(s, converterVar, toCpp, isConv);
@@ -1516,8 +1547,10 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
QSet<QString> argNamesSet;
if (usePySideExtensions() && metaClass->isQObject()) {
// Write argNames variable with all known argument names.
- foreach (const AbstractMetaFunction* func, overloadData.overloads()) {
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const OverloadData::MetaFunctionList &overloads = overloadData.overloads();
+ for (const AbstractMetaFunction *func : overloads) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
if (arg->defaultValueExpression().isEmpty() || func->argumentRemoved(arg->argumentIndex() + 1))
continue;
argNamesSet << arg->name();
@@ -1595,7 +1628,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
// (first "1") and the flag indicating that the Python wrapper holds an C++ wrapper
// is marked as true (the second "1"). Otherwise the default values apply:
// Python owns it and C++ wrapper is false.
- if (shouldGenerateCppWrapper(overloads.first()->ownerClass()))
+ if (shouldGenerateCppWrapper(overloads.constFirst()->ownerClass()))
s << INDENT << "Shiboken::Object::setHasCppWrapper(sbkSelf, true);" << endl;
// Need to check if a wrapper for same pointer is already registered
// Caused by bug PYSIDE-217, where deleted objects' wrappers are not released
@@ -1621,8 +1654,9 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
// Constructor code injections, position=end
bool hasCodeInjectionsAtEnd = false;
- foreach(AbstractMetaFunction* func, overloads) {
- foreach (const CodeSnip &cs, func->injectedCodeSnips()) {
+ for (AbstractMetaFunction *func : overloads) {
+ const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips();
+ for (const CodeSnip &cs : injectedCodeSnips) {
if (cs.position == TypeSystem::CodeSnipPositionEnd) {
hasCodeInjectionsAtEnd = true;
break;
@@ -1632,9 +1666,10 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
if (hasCodeInjectionsAtEnd) {
// FIXME: C++ arguments are not available in code injection on constructor when position = end.
s << INDENT << "switch(overloadId) {" << endl;
- foreach(AbstractMetaFunction* func, overloads) {
+ for (AbstractMetaFunction *func : overloads) {
Indentation indent(INDENT);
- foreach (const CodeSnip &cs, func->injectedCodeSnips()) {
+ const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips();
+ for (const CodeSnip &cs : injectedCodeSnips) {
if (cs.position == TypeSystem::CodeSnipPositionEnd) {
s << INDENT << "case " << metaClass->functions().indexOf(func) << ':' << endl;
s << INDENT << '{' << endl;
@@ -1812,10 +1847,10 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overl
s << INDENT << '}';
}
}
- QList<int> invalidArgsLength = overloadData.invalidArgumentLengths();
+ const QVector<int> invalidArgsLength = overloadData.invalidArgumentLengths();
if (!invalidArgsLength.isEmpty()) {
QStringList invArgsLen;
- foreach (int i, invalidArgsLength)
+ for (int i : qAsConst(invalidArgsLength))
invArgsLen << QStringLiteral("numArgs == %1").arg(i);
if (usesNamedArguments && (!ownerClassIsQObject || minArgs > 0))
s << " else ";
@@ -1943,9 +1978,11 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData)
s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", \"" << funcName << "\", 0);" << endl;
} else {
QStringList overloadSignatures;
- foreach (const AbstractMetaFunction* f, overloadData.overloads()) {
+ const OverloadData::MetaFunctionList &overloads = overloadData.overloads();
+ for (const AbstractMetaFunction *f : overloads) {
QStringList args;
- foreach(AbstractMetaArgument* arg, f->arguments()) {
+ const AbstractMetaArgumentList &arguments = f->arguments();
+ for (AbstractMetaArgument *arg : arguments) {
QString strArg;
AbstractMetaType* argType = arg->type();
if (isCString(argType)) {
@@ -1961,7 +1998,9 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData)
strArg = QLatin1String("1-unicode");
} else {
strArg = ptp->name();
- strArg.remove(QRegExp(QLatin1String("^signed\\s+")));
+ static const QRegularExpression regex(QStringLiteral("^signed\\s+"));
+ Q_ASSERT(regex.isValid());
+ strArg.remove(regex);
if (strArg == QLatin1String("double"))
strArg = QLatin1String("float");
}
@@ -2043,9 +2082,13 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream& s, const QString& pyOb
static QString pythonToCppConverterForArgumentName(const QString& argumentName)
{
- static QRegExp pyArgsRegex(QLatin1String(PYTHON_ARGS"(\\[\\d+[-]?\\d*\\])"));
- pyArgsRegex.indexIn(argumentName);
- return QLatin1String(PYTHON_TO_CPP_VAR) + pyArgsRegex.cap(1);
+ static const QRegularExpression pyArgsRegex(QLatin1String(PYTHON_ARGS"(\\[\\d+[-]?\\d*\\])"));
+ Q_ASSERT(pyArgsRegex.isValid());
+ const QRegularExpressionMatch match = pyArgsRegex.match(argumentName);
+ QString result = QLatin1String(PYTHON_TO_CPP_VAR);
+ if (match.hasMatch())
+ result += match.captured(1);
+ return result;
}
void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber, QString customType, bool rejectNull)
@@ -2085,20 +2128,26 @@ static void checkTypeViability(const AbstractMetaFunction* func, const AbstractM
if (!type
|| !type->typeEntry()->isPrimitive()
|| type->indirections() == 0
+ || (type->indirections() == 1 && type->typeUsagePattern() == AbstractMetaType::NativePointerAsArrayPattern)
|| ShibokenGenerator::isCString(type)
|| func->argumentRemoved(argIdx)
|| !func->typeReplaced(argIdx).isEmpty()
|| !func->conversionRule(TypeSystem::All, argIdx).isEmpty()
|| func->hasInjectedCode())
return;
- QString prefix;
+ QString message;
+ QTextStream str(&message);
+ str << "There's no user provided way (conversion rule, argument"
+ " removal, custom code, etc) to handle the primitive ";
+ if (argIdx == 0)
+ str << "return type '" << type->cppSignature() << '\'';
+ else
+ str << "type '" << type->cppSignature() << "' of argument " << argIdx;
+ str << " in function '";
if (func->ownerClass())
- prefix = func->ownerClass()->qualifiedCppName() + QLatin1String("::");
- qCWarning(lcShiboken).noquote().nospace()
- << QString::fromLatin1("There's no user provided way (conversion rule, argument removal, custom code, etc) "
- "to handle the primitive %1 type '%2' in function '%3%4'.")
- .arg(argIdx == 0 ? QStringLiteral("return") : QStringLiteral("argument"),
- type->cppSignature(), prefix, func->signature());
+ str << func->ownerClass()->qualifiedCppName() << "::";
+ str << func->signature() << "'.";
+ qCWarning(lcShiboken).noquote().nospace() << message;
}
static void checkTypeViability(const AbstractMetaFunction* func)
@@ -2114,9 +2163,10 @@ static void checkTypeViability(const AbstractMetaFunction* func)
void CppGenerator::writeTypeCheck(QTextStream& s, const OverloadData* overloadData, QString argumentName)
{
QSet<const TypeEntry*> numericTypes;
-
- foreach (OverloadData* od, overloadData->previousOverloadData()->nextOverloadData()) {
- foreach (const AbstractMetaFunction* func, od->overloads()) {
+ const OverloadDataList &overloads = overloadData->previousOverloadData()->nextOverloadData();
+ for (OverloadData *od : overloads) {
+ const OverloadData::MetaFunctionList &odOverloads = od->overloads();
+ for (const AbstractMetaFunction *func : odOverloads) {
checkTypeViability(func);
const AbstractMetaType* argType = od->argument(func)->type();
if (!argType->isPrimitive())
@@ -2174,6 +2224,23 @@ const AbstractMetaType* CppGenerator::getArgumentType(const AbstractMetaFunction
return argType;
}
+static inline QString arrayHandleType(const AbstractMetaTypeCList &nestedArrayTypes)
+{
+ switch (nestedArrayTypes.size()) {
+ case 1:
+ return QStringLiteral("Shiboken::Conversions::ArrayHandle<")
+ + nestedArrayTypes.constLast()->minimalSignature()
+ + QLatin1Char('>');
+ case 2:
+ return QStringLiteral("Shiboken::Conversions::Array2Handle<")
+ + nestedArrayTypes.constLast()->minimalSignature()
+ + QStringLiteral(", ")
+ + QString::number(nestedArrayTypes.constFirst()->arrayElementCount())
+ + QLatin1Char('>');
+ }
+ return QString();
+}
+
void CppGenerator::writePythonToCppTypeConversion(QTextStream& s,
const AbstractMetaType* type,
const QString& pyIn,
@@ -2195,7 +2262,13 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream& s,
&& !isCppPrimitive(type)
&& isNotContainerEnumOrFlags
&& !(treatAsPointer || isPointerOrObjectType);
- QString typeName = getFullTypeNameWithoutModifiers(type);
+
+ const AbstractMetaTypeCList nestedArrayTypes = type->nestedArrayTypes();
+ const bool isCppPrimitiveArray = !nestedArrayTypes.isEmpty()
+ && nestedArrayTypes.constLast()->isCppPrimitive();
+ QString typeName = isCppPrimitiveArray
+ ? arrayHandleType(nestedArrayTypes)
+ : getFullTypeNameWithoutModifiers(type);
bool isProtectedEnum = false;
@@ -2212,7 +2285,9 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream& s,
}
s << INDENT << typeName;
- if (treatAsPointer || isPointerOrObjectType) {
+ if (isCppPrimitiveArray) {
+ s << ' ' << cppOut;
+ } else if (treatAsPointer || isPointerOrObjectType) {
s << "* " << cppOut;
if (!defaultValue.isEmpty())
s << " = " << defaultValue;
@@ -2280,7 +2355,7 @@ static void addConversionRuleCodeSnippet(CodeSnipList& snippetList, QString& rul
} else {
rule.replace(QLatin1String("%out"), outputName);
}
- CodeSnip snip(0, snippetLanguage);
+ CodeSnip snip(snippetLanguage);
snip.position = (snippetLanguage == TypeSystem::NativeCode) ? TypeSystem::CodeSnipPositionAny : TypeSystem::CodeSnipPositionBeginning;
snip.addCode(rule);
snippetList << snip;
@@ -2289,7 +2364,8 @@ static void addConversionRuleCodeSnippet(CodeSnipList& snippetList, QString& rul
void CppGenerator::writeConversionRule(QTextStream& s, const AbstractMetaFunction* func, TypeSystem::Language language)
{
CodeSnipList snippets;
- foreach (AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (AbstractMetaArgument *arg : arguments) {
QString rule = func->conversionRule(language, arg->argumentIndex() + 1);
addConversionRuleCodeSnippet(snippets, rule, language, TypeSystem::TargetLangCode,
arg->name(), arg->name());
@@ -2317,7 +2393,7 @@ void CppGenerator::writeOverloadedFunctionDecisor(QTextStream& s, const Overload
{
s << INDENT << "// Overloaded function decisor" << endl;
const AbstractMetaFunction* rfunc = overloadData.referenceFunction();
- QList<const AbstractMetaFunction*> functionOverloads = overloadData.overloadsWithoutRepetition();
+ const OverloadData::MetaFunctionList &functionOverloads = overloadData.overloadsWithoutRepetition();
for (int i = 0; i < functionOverloads.count(); i++)
s << INDENT << "// " << i << ": " << functionOverloads.at(i)->minimalSignature() << endl;
writeOverloadedFunctionDecisorEngine(s, &overloadData);
@@ -2351,7 +2427,8 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
// variable to be used further on this method on the conditional that identifies default
// method calls.
if (!hasDefaultCall) {
- foreach (const AbstractMetaFunction* func, parentOverloadData->overloads()) {
+ const OverloadData::MetaFunctionList &overloads = parentOverloadData->overloads();
+ for (const AbstractMetaFunction *func : overloads) {
if (parentOverloadData->isFinalOccurrence(func)) {
referenceFunction = func;
hasDefaultCall = true;
@@ -2392,6 +2469,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
// If the next argument has a default value the decisor can perform a method call;
// it just need to check if the number of arguments received from Python are equal
// to the number of parameters preceding the argument with the default value.
+ const OverloadDataList &overloads = parentOverloadData->nextOverloadData();
if (hasDefaultCall) {
isFirst = false;
int numArgs = parentOverloadData->argPos() + 1;
@@ -2399,7 +2477,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
{
Indentation indent(INDENT);
const AbstractMetaFunction* func = referenceFunction;
- foreach (OverloadData* overloadData, parentOverloadData->nextOverloadData()) {
+ for (OverloadData *overloadData : overloads) {
const AbstractMetaFunction* defValFunc = overloadData->getFunctionWithDefaultValue();
if (defValFunc) {
func = defValFunc;
@@ -2412,7 +2490,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
s << INDENT << '}';
}
- foreach (OverloadData* overloadData, parentOverloadData->nextOverloadData()) {
+ for (OverloadData *overloadData : overloads) {
bool signatureFound = overloadData->overloads().size() == 1
&& !overloadData->getFunctionWithDefaultValue()
&& !overloadData->findNextArgWithDefault();
@@ -2438,7 +2516,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
if (func->isConstructor() && func->arguments().count() == 1) {
const AbstractMetaClass* ownerClass = func->ownerClass();
const ComplexTypeEntry* baseContainerType = ownerClass->typeEntry()->baseContainerType();
- if (baseContainerType && baseContainerType == func->arguments().first()->type()->typeEntry() && isCopyable(ownerClass)) {
+ if (baseContainerType && baseContainerType == func->arguments().constFirst()->type()->typeEntry() && isCopyable(ownerClass)) {
tck << '!' << cpythonCheckFunction(ownerClass->typeEntry()) << pyArgName << ')' << endl;
Indentation indent(INDENT);
tck << INDENT << "&& ";
@@ -2453,17 +2531,17 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
if (od->nextOverloadData().isEmpty()
|| od->nextArgumentHasDefaultValue()
|| od->nextOverloadData().size() != 1
- || od->overloads().size() != od->nextOverloadData().first()->overloads().size()) {
+ || od->overloads().size() != od->nextOverloadData().constFirst()->overloads().size()) {
overloadData = od;
od = 0;
} else {
- od = od->nextOverloadData().first();
+ od = od->nextOverloadData().constFirst();
}
}
if (usePyArgs && signatureFound) {
AbstractMetaArgumentList args = refFunc->arguments();
- int lastArgIsVarargs = (int) (args.size() > 1 && args.last()->type()->isVarargs());
+ int lastArgIsVarargs = (int) (args.size() > 1 && args.constLast()->type()->isVarargs());
int numArgs = args.size() - OverloadData::numberOfRemovedArguments(refFunc) - lastArgIsVarargs;
typeChecks.prepend(QString::fromLatin1("numArgs %1 %2").arg(lastArgIsVarargs ? QLatin1String(">=") : QLatin1String("==")).arg(numArgs));
} else if (sequenceArgCount > 1) {
@@ -2501,13 +2579,13 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
void CppGenerator::writeFunctionCalls(QTextStream &s, const OverloadData &overloadData,
GeneratorContext &context)
{
- QList<const AbstractMetaFunction*> overloads = overloadData.overloadsWithoutRepetition();
+ const OverloadData::MetaFunctionList &overloads = overloadData.overloadsWithoutRepetition();
s << INDENT << "// Call function/method" << endl;
s << INDENT << (overloads.count() > 1 ? "switch (overloadId) " : "") << '{' << endl;
{
Indentation indent(INDENT);
if (overloads.count() == 1) {
- writeSingleFunctionCall(s, overloadData, overloads.first(), context);
+ writeSingleFunctionCall(s, overloadData, overloads.constFirst(), context);
} else {
for (int i = 0; i < overloads.count(); i++) {
const AbstractMetaFunction* func = overloads.at(i);
@@ -2818,21 +2896,22 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream& s, const Abs
QString code;
QTextStream c(&code);
c << INDENT << QString::fromLatin1("%1& cppOutRef = *((%1*)cppOut);").arg(cppTypeName) << endl;
- code.append(toCppConversions.first()->conversion());
+ code.append(toCppConversions.constFirst()->conversion());
for (int i = 0; i < containerType->instantiations().count(); ++i) {
const AbstractMetaType* type = containerType->instantiations().at(i);
QString typeName = getFullTypeName(type);
if (type->isValue() && isValueTypeWithCopyConstructorOnly(type)) {
- static QRegExp regex(QLatin1String(CONVERTTOCPP_REGEX));
- int pos = 0;
- while ((pos = regex.indexIn(code, pos)) != -1) {
- pos += regex.matchedLength();
- QStringList list = regex.capturedTexts();
- QString varName = list.at(1);
- QString leftCode = code.left(pos);
+ static const QRegularExpression regex(QLatin1String(CONVERTTOCPP_REGEX));
+ Q_ASSERT(regex.isValid());
+ for (int pos = 0; ; ) {
+ const QRegularExpressionMatch match = regex.match(code, pos);
+ if (!match.hasMatch())
+ break;
+ pos = match.capturedEnd();
+ const QString varName = match.captured(1);
QString rightCode = code.mid(pos);
rightCode.replace(varName, QLatin1Char('*') + varName);
- code = leftCode + rightCode;
+ code.replace(pos, code.size() - pos, rightCode);
}
typeName.append(QLatin1Char('*'));
}
@@ -2867,7 +2946,7 @@ void CppGenerator::writeAddPythonToCppConversion(QTextStream& s, const QString&
void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMetaFunction* func, bool usePyArgs)
{
- AbstractMetaArgumentList args = OverloadData::getArgumentsWithDefaultValues(func);
+ const AbstractMetaArgumentList &args = OverloadData::getArgumentsWithDefaultValues(func);
if (args.isEmpty())
return;
@@ -2878,7 +2957,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMe
{
Indentation indent(INDENT);
s << INDENT << "PyObject* ";
- foreach (const AbstractMetaArgument* arg, args) {
+ for (const AbstractMetaArgument *arg : args) {
int pyArgIndex = arg->argumentIndex() - OverloadData::numberOfRemovedArguments(func, arg->argumentIndex());
QString pyArgName = usePyArgs
? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(pyArgIndex)
@@ -2903,7 +2982,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMe
}
}
s << INDENT << '}' << endl;
- if (arg != args.last())
+ if (arg != args.constLast())
s << INDENT;
}
}
@@ -2953,7 +3032,8 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
{
s << INDENT << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << endl;
if (func->isConstructor()) {
- foreach (const CodeSnip &cs, func->injectedCodeSnips()) {
+ const CodeSnipList &snips = func->injectedCodeSnips();
+ for (const CodeSnip &cs : snips) {
if (cs.position == TypeSystem::CodeSnipPositionEnd) {
s << INDENT << "overloadId = " << func->ownerClass()->functions().indexOf(const_cast<AbstractMetaFunction* const>(func)) << ';' << endl;
break;
@@ -2990,7 +3070,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
removedArgs++;
}
} else if (maxArgs != 0 && !func->arguments().isEmpty()) {
- lastArg = func->arguments().last();
+ lastArg = func->arguments().constLast();
}
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode, func, lastArg);
@@ -3065,7 +3145,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
firstArg.remove(1, 1); // remove the de-reference operator
QString secondArg = QLatin1String(CPP_ARG0);
- if (!func->isUnaryOperator() && shouldDereferenceArgumentPointer(func->arguments().first())) {
+ if (!func->isUnaryOperator() && shouldDereferenceArgumentPointer(func->arguments().constFirst())) {
secondArg.prepend(QLatin1String("(*"));
secondArg.append(QLatin1Char(')'));
}
@@ -3255,11 +3335,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
bool hasReturnPolicy = false;
// Ownership transference between C++ and Python.
- QList<ArgumentModification> ownership_mods;
+ QVector<ArgumentModification> ownership_mods;
// Python object reference management.
- QList<ArgumentModification> refcount_mods;
- foreach (const FunctionModification &func_mod, func->modifications()) {
- foreach (const ArgumentModification &arg_mod, func_mod.argument_mods) {
+ QVector<ArgumentModification> refcount_mods;
+ const FunctionModificationList &funcMods = func->modifications();
+ for (const FunctionModification &func_mod : funcMods) {
+ for (const ArgumentModification &arg_mod : func_mod.argument_mods) {
if (!arg_mod.ownerships.isEmpty() && arg_mod.ownerships.contains(TypeSystem::TargetLangCode))
ownership_mods.append(arg_mod);
else if (!arg_mod.referenceCounts.isEmpty())
@@ -3273,7 +3354,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
if (!ownership_mods.isEmpty()) {
s << endl << INDENT << "// Ownership transferences." << endl;
- foreach (const ArgumentModification &arg_mod, ownership_mods) {
+ for (const ArgumentModification &arg_mod : qAsConst(ownership_mods)) {
const AbstractMetaClass* wrappedClass = 0;
QString pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass);
if (!wrappedClass) {
@@ -3304,8 +3385,8 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
} else if (!refcount_mods.isEmpty()) {
- foreach (const ArgumentModification &arg_mod, refcount_mods) {
- ReferenceCount refCount = arg_mod.referenceCounts.first();
+ for (const ArgumentModification &arg_mod : qAsConst(refcount_mods)) {
+ ReferenceCount refCount = arg_mod.referenceCounts.constFirst();
if (refCount.action != ReferenceCount::Set
&& refCount.action != ReferenceCount::Remove
&& refCount.action != ReferenceCount::Add) {
@@ -3331,7 +3412,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
s << INDENT << "Shiboken::Object::removeReference(";
s << "reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR "), \"";
- QString varName = arg_mod.referenceCounts.first().varName;
+ QString varName = arg_mod.referenceCounts.constFirst().varName;
if (varName.isEmpty())
varName = func->minimalSignature() + QString().number(arg_mod.index);
@@ -3349,15 +3430,15 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass* metaClass)
{
QStringList result;
- AbstractMetaClassList baseClases = getBaseClasses(metaClass);
+ const AbstractMetaClassList &baseClases = getBaseClasses(metaClass);
if (!baseClases.isEmpty()) {
- foreach (const AbstractMetaClass* baseClass, baseClases) {
+ for (const AbstractMetaClass *baseClass : baseClases) {
result.append(QString::fromLatin1("((size_t) static_cast<const %1*>(class_ptr)) - base")
.arg(baseClass->qualifiedCppName()));
result.append(QString::fromLatin1("((size_t) static_cast<const %1*>((%2*)((void*)class_ptr))) - base")
.arg(baseClass->qualifiedCppName(), metaClass->qualifiedCppName()));
}
- foreach (const AbstractMetaClass* baseClass, baseClases)
+ for (const AbstractMetaClass *baseClass : baseClases)
result.append(getAncestorMultipleInheritance(baseClass));
}
return result;
@@ -3366,7 +3447,7 @@ QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass
void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, const AbstractMetaClass* metaClass)
{
QString className = metaClass->qualifiedCppName();
- QStringList ancestors = getAncestorMultipleInheritance(metaClass);
+ const QStringList ancestors = getAncestorMultipleInheritance(metaClass);
s << "static int mi_offsets[] = { ";
for (int i = 0; i < ancestors.size(); i++)
s << "-1, ";
@@ -3382,7 +3463,7 @@ void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, c
s << INDENT << "const " << className << "* class_ptr = reinterpret_cast<const " << className << "*>(cptr);" << endl;
s << INDENT << "size_t base = (size_t) class_ptr;" << endl;
- foreach (const QString &ancestor, ancestors)
+ for (const QString &ancestor : ancestors)
s << INDENT << "offsets.insert(" << ancestor << ");" << endl;
s << endl;
@@ -3410,7 +3491,8 @@ void CppGenerator::writeSpecialCastFunction(QTextStream& s, const AbstractMetaCl
s << "{\n";
s << INDENT << className << "* me = reinterpret_cast< ::" << className << "*>(obj);\n";
bool firstClass = true;
- foreach (const AbstractMetaClass* baseClass, getAllAncestors(metaClass)) {
+ const AbstractMetaClassList &allAncestors = getAllAncestors(metaClass);
+ for (const AbstractMetaClass *baseClass : allAncestors) {
s << INDENT << (!firstClass ? "else " : "") << "if (desiredType == reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(baseClass->typeEntry()) << "))\n";
Indentation indent(INDENT);
s << INDENT << "return static_cast< ::" << baseClass->qualifiedCppName() << "*>(me);\n";
@@ -3528,10 +3610,11 @@ void CppGenerator::writeContainerConverterInitialization(QTextStream& s, const A
writeAddPythonToCppConversion(s, converterObject(type), toCpp, isConv);
}
-void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QList<const AbstractMetaClass*>& conversions)
+void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType,
+ const QVector<const AbstractMetaClass*>& conversions)
{
s << INDENT << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl;
- foreach (const AbstractMetaClass* sourceClass, conversions) {
+ for (const AbstractMetaClass *sourceClass : conversions) {
const QString converterVar = QLatin1String("reinterpret_cast<SbkObjectType *>(")
+ cppApiVariableName(externalType->targetLangPackage()) + QLatin1Char('[')
+ getTypeIndexVariableName(externalType) + QLatin1String("])");
@@ -3586,7 +3669,8 @@ bool CppGenerator::supportsSequenceProtocol(const AbstractMetaClass* metaClass)
bool CppGenerator::shouldGenerateGetSetList(const AbstractMetaClass* metaClass)
{
- foreach (AbstractMetaField* f, metaClass->fields()) {
+ const AbstractMetaFieldList &fields = metaClass->fields();
+ for (const AbstractMetaField *f : fields) {
if (!f->isStatic())
return true;
}
@@ -3604,11 +3688,11 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
QString tp_hash(QLatin1Char('0'));
QString tp_call = tp_hash;
QString cppClassName = metaClass->qualifiedCppName();
- QString className = cpythonTypeName(metaClass);
- className.remove(QRegExp(QLatin1String("_Type$")));
+ const QString className = chopType(cpythonTypeName(metaClass));
QString baseClassName(QLatin1Char('0'));
AbstractMetaFunctionList ctors;
- foreach (AbstractMetaFunction* f, metaClass->queryFunctions(AbstractMetaClass::Constructors)) {
+ const AbstractMetaFunctionList &allCtors = metaClass->queryFunctions(AbstractMetaClass::Constructors);
+ for (AbstractMetaFunction *f : allCtors) {
if (!f->isPrivate() && !f->isModifiedRemoved() && !classContext.forSmartPointer())
ctors.append(f);
}
@@ -3641,8 +3725,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
tp_dealloc = QLatin1String("&SbkDeallocQAppWrapper");
else
tp_dealloc = QLatin1String("&SbkDeallocWrapper");
- // avoid constFirst to stay Qt 5.5 compatible
- tp_init = (onlyPrivCtor || ctors.isEmpty()) ? QLatin1String("0") : cpythonFunctionName(ctors.first());
+ tp_init = (onlyPrivCtor || ctors.isEmpty()) ? QLatin1String("0") : cpythonFunctionName(ctors.constFirst());
}
QString tp_getattro(QLatin1Char('0'));
@@ -3679,7 +3762,8 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
// search for special functions
ShibokenGenerator::clearTpFuncs();
- foreach (AbstractMetaFunction* func, metaClass->functions()) {
+ const AbstractMetaFunctionList &funcs = metaClass->functions();
+ for (AbstractMetaFunction *func : funcs) {
if (m_tpFuncs.contains(func->name()))
m_tpFuncs[func->name()] = cpythonFunctionName(func);
}
@@ -3788,11 +3872,7 @@ void CppGenerator::writeMappingMethods(QTextStream &s,
const AbstractMetaClass *metaClass,
GeneratorContext &context)
{
-
- QMap<QString, QString> funcs;
-
- QHash< QString, QPair< QString, QString > >::const_iterator it = m_mappingProtocol.begin();
- for (; it != m_mappingProtocol.end(); ++it) {
+ for (auto it = m_mappingProtocol.cbegin(), end = m_mappingProtocol.cend(); it != end; ++it) {
const AbstractMetaFunction* func = metaClass->findFunction(it.key());
if (!func)
continue;
@@ -3806,7 +3886,7 @@ void CppGenerator::writeMappingMethods(QTextStream &s,
writeCppSelfDefinition(s, func, context);
- const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last();
+ const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, lastArg);
s << '}' << endl << endl;
}
@@ -3816,12 +3896,9 @@ void CppGenerator::writeSequenceMethods(QTextStream &s,
const AbstractMetaClass *metaClass,
GeneratorContext &context)
{
-
- QMap<QString, QString> funcs;
bool injectedCode = false;
- QHash< QString, QPair< QString, QString > >::const_iterator it = m_sequenceProtocol.begin();
- for (; it != m_sequenceProtocol.end(); ++it) {
+ for (auto it = m_sequenceProtocol.cbegin(), end = m_sequenceProtocol.cend(); it != end; ++it) {
const AbstractMetaFunction* func = metaClass->findFunction(it.key());
if (!func)
continue;
@@ -3836,7 +3913,7 @@ void CppGenerator::writeSequenceMethods(QTextStream &s,
writeCppSelfDefinition(s, func, context);
- const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last();
+ const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
writeCodeSnips(s, snips,TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, lastArg);
s << '}' << endl << endl;
}
@@ -3900,7 +3977,7 @@ void CppGenerator::writeTypeAsMappingDefinition(QTextStream& s, const AbstractMe
QString baseName = cpythonBaseName(metaClass);
s << INDENT << "memset(&" << baseName << "_TypeAsMapping, 0, sizeof(PyMappingMethods));" << endl;
- for (QHash<QString, QString>::const_iterator it = m_mpFuncs.cbegin(), end = m_mpFuncs.end(); it != end; ++it) {
+ for (auto it = m_mpFuncs.cbegin(), end = m_mpFuncs.cend(); it != end; ++it) {
const QString &mpName = it.key();
if (funcs[mpName].isEmpty())
continue;
@@ -3936,13 +4013,13 @@ void CppGenerator::writeTypeAsNumberDefinition(QTextStream& s, const AbstractMet
nb.insert(QLatin1String("__ixor__"), QString());
nb.insert(QLatin1String("__ior__"), QString());
- QList<AbstractMetaFunctionList> opOverloads =
+ const QVector<AbstractMetaFunctionList> opOverloads =
filterGroupedOperatorFunctions(metaClass,
AbstractMetaClass::ArithmeticOp
| AbstractMetaClass::LogicalOp
| AbstractMetaClass::BitwiseOp);
- foreach (const AbstractMetaFunctionList &opOverload, opOverloads) {
+ for (const AbstractMetaFunctionList &opOverload : opOverloads) {
const AbstractMetaFunction* rfunc = opOverload[0];
QString opName = ShibokenGenerator::pythonOperatorFunctionName(rfunc);
nb[opName] = cpythonFunctionName(rfunc);
@@ -4001,8 +4078,7 @@ void CppGenerator::writeTpClearFunction(QTextStream& s, const AbstractMetaClass*
void CppGenerator::writeCopyFunction(QTextStream &s, GeneratorContext &context)
{
const AbstractMetaClass *metaClass = context.metaClass();
- QString className = cpythonTypeName(metaClass);
- className.remove(QRegExp(QLatin1String("_Type$")));
+ const QString className = chopType(cpythonTypeName(metaClass));
s << "static PyObject* " << className << "___copy__(PyObject* " PYTHON_SELF_VAR ")" << endl;
s << "{" << endl;
writeCppSelfDefinition(s, context, false, true);
@@ -4181,7 +4257,8 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
s << INDENT << "switch (op) {" << endl;
{
Indentation indent(INDENT);
- foreach (const AbstractMetaFunctionList &overloads, filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ComparisonOp)) {
+ const QVector<AbstractMetaFunctionList> &groupedFuncs = filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ComparisonOp);
+ for (const AbstractMetaFunctionList &overloads : groupedFuncs) {
const AbstractMetaFunction* rfunc = overloads[0];
QString operatorId = ShibokenGenerator::pythonRichCompareOperatorId(rfunc);
@@ -4193,15 +4270,16 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
op = op.right(op.size() - QLatin1String("operator").size());
int alternativeNumericTypes = 0;
- foreach (const AbstractMetaFunction* func, overloads) {
+ for (const AbstractMetaFunction *func : overloads) {
if (!func->isStatic() &&
- ShibokenGenerator::isNumber(func->arguments()[0]->type()->typeEntry()))
+ ShibokenGenerator::isNumber(func->arguments().at(0)->type()->typeEntry()))
alternativeNumericTypes++;
}
bool first = true;
OverloadData overloadData(overloads, this);
- foreach (OverloadData* od, overloadData.nextOverloadData()) {
+ const OverloadDataList &nextOverloads = overloadData.nextOverloadData();
+ for (OverloadData *od : nextOverloads) {
const AbstractMetaFunction* func = od->referenceFunction();
if (func->isStatic())
continue;
@@ -4227,7 +4305,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
// If the function is user added, use the inject code
if (func->isUserAdded()) {
CodeSnipList snips = func->injectedCodeSnips();
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, func->arguments().last());
+ writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, func->arguments().constLast());
} else {
QString expression = QString::fromLatin1("%1%2 %3 (%4" CPP_ARG0 ")")
.arg(func->isPointerOperator() ? QLatin1String("&") : QString(),
@@ -4308,7 +4386,7 @@ void CppGenerator::writeMethodDefinitionEntry(QTextStream& s, const AbstractMeta
void CppGenerator::writeMethodDefinition(QTextStream& s, const AbstractMetaFunctionList overloads)
{
Q_ASSERT(!overloads.isEmpty());
- const AbstractMetaFunction* func = overloads.first();
+ const AbstractMetaFunction* func = overloads.constFirst();
if (m_tpFuncs.contains(func->name()))
return;
@@ -4349,18 +4427,10 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
int idx = overloads.length() - 1;
bool multiple = idx > 0;
-// after merging, the #if may be removed!
-#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
for (const AbstractMetaFunction *f : overloads) {
QStringList args;
const AbstractMetaArgumentList &arguments = f->arguments();
- for (AbstractMetaArgument *arg : arguments) {
-#else
- foreach (const AbstractMetaFunction *f, overloads) {
- QStringList args;
- const AbstractMetaArgumentList &arguments = f->arguments();
- foreach (const AbstractMetaArgument *arg, arguments) {
-#endif
+ for (const AbstractMetaArgument *arg : arguments) {
QString strArg = resolveRetOrArgType(arg->type());
if (!arg->defaultValueExpression().isEmpty()) {
strArg += QLatin1Char('=');
@@ -4378,9 +4448,8 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
// now calculate the return type.
s << funcName << '(' << args.join(QLatin1Char(',')) << ')';
AbstractMetaType *returnType = getTypeWithoutContainer(f->type());
- if (returnType) {
+ if (returnType)
s << "->" << resolveRetOrArgType(returnType);
- }
s << endl;
}
}
@@ -4390,7 +4459,7 @@ void CppGenerator::writeEnumsInitialization(QTextStream& s, AbstractMetaEnumList
if (enums.isEmpty())
return;
s << INDENT << "// Initialization of enums." << endl << endl;
- foreach (const AbstractMetaEnum* cppEnum, enums) {
+ for (const AbstractMetaEnum *cppEnum : qAsConst(enums)) {
if (cppEnum->isPrivate())
continue;
writeEnumInitialization(s, cppEnum);
@@ -4402,6 +4471,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
const AbstractMetaClass* enclosingClass = getProperEnclosingClassForEnum(cppEnum);
const AbstractMetaClass* upper = enclosingClass ? enclosingClass->enclosingClass() : 0;
bool hasUpperEnclosingClass = upper && upper->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass;
+ const EnumTypeEntry *enumTypeEntry = cppEnum->typeEntry();
QString enclosingObjectVariable;
if (enclosingClass)
enclosingObjectVariable = QLatin1Char('&') + cpythonTypeName(enclosingClass);
@@ -4414,14 +4484,17 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
s << (cppEnum->isAnonymous() ? "anonymous enum identified by enum value" : "enum");
s << " '" << cppEnum->name() << "'." << endl;
+ QString enumVarTypeObj;
if (!cppEnum->isAnonymous()) {
- FlagsTypeEntry* flags = cppEnum->typeEntry()->flags();
+ FlagsTypeEntry* flags = enumTypeEntry->flags();
if (flags) {
s << INDENT << cpythonTypeNameExt(flags) << " = PySide::QFlags::create(\"" << flags->flagsName() << "\", &"
<< cpythonEnumName(cppEnum) << "_as_number);" << endl;
}
- s << INDENT << cpythonTypeNameExt(cppEnum->typeEntry()) << " = Shiboken::Enum::";
+ enumVarTypeObj = cpythonTypeNameExt(enumTypeEntry);
+
+ s << INDENT << enumVarTypeObj << " = Shiboken::Enum::";
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnum" : "createGlobalEnum");
s << '(' << enclosingObjectVariable << ',' << endl;
{
@@ -4441,8 +4514,9 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
}
}
- foreach (const AbstractMetaEnumValue* enumValue, cppEnum->values()) {
- if (cppEnum->typeEntry()->isEnumValueRejected(enumValue->name()))
+ const AbstractMetaEnumValueList &enumValues = cppEnum->values();
+ for (const AbstractMetaEnumValue *enumValue : enumValues) {
+ if (enumTypeEntry->isEnumValueRejected(enumValue->name()))
continue;
QString enumValueText;
@@ -4450,12 +4524,16 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
enumValueText = QLatin1String("(long) ");
if (cppEnum->enclosingClass())
enumValueText += cppEnum->enclosingClass()->qualifiedCppName() + QLatin1String("::");
+ // Fully qualify the value which is required for C++ 11 enum classes.
+ if (!cppEnum->isAnonymous())
+ enumValueText += cppEnum->name() + QLatin1String("::");
enumValueText += enumValue->name();
} else {
enumValueText += QString::number(enumValue->value());
}
- if (cppEnum->isAnonymous()) {
+ switch (enumTypeEntry->enumKind()) {
+ case EnumTypeEntry::AnonymousEnum:
if (enclosingClass || hasUpperEnclosingClass) {
s << INDENT << '{' << endl;
{
@@ -4478,15 +4556,27 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
s << INDENT << "return " << m_currentErrorCode << ';' << endl;
}
}
- } else {
+ break;
+ case EnumTypeEntry::CEnum: {
s << INDENT << "if (!Shiboken::Enum::";
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" : "createGlobalEnumItem");
- s << '(' << cpythonTypeNameExt(cppEnum->typeEntry()) << ',' << endl;
+ s << '(' << enumVarTypeObj << ',' << endl;
Indentation indent(INDENT);
s << INDENT << enclosingObjectVariable << ", \"" << enumValue->name() << "\", ";
s << enumValueText << "))" << endl;
s << INDENT << "return " << m_currentErrorCode << ';' << endl;
}
+ break;
+ case EnumTypeEntry::EnumClass: {
+ s << INDENT << "if (!Shiboken::Enum::createScopedEnumItem("
+ << enumVarTypeObj << ',' << endl;
+ Indentation indent(INDENT);
+ s << INDENT << enumVarTypeObj<< ", \"" << enumValue->name() << "\", "
+ << enumValueText << "))" << endl
+ << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ }
+ break;
+ }
}
writeEnumConverterInitialization(s, cppEnum);
@@ -4500,10 +4590,12 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
void CppGenerator::writeSignalInitialization(QTextStream& s, const AbstractMetaClass* metaClass)
{
// Try to check something and print some warnings
- foreach (const AbstractMetaFunction* cppSignal, metaClass->cppSignalFunctions()) {
+ const AbstractMetaFunctionList &signalFuncs = metaClass->cppSignalFunctions();
+ for (const AbstractMetaFunction *cppSignal : signalFuncs) {
if (cppSignal->declaringClass() != metaClass)
continue;
- foreach (AbstractMetaArgument* arg, cppSignal->arguments()) {
+ const AbstractMetaArgumentList &arguments = cppSignal->arguments();
+ for (AbstractMetaArgument *arg : arguments) {
AbstractMetaType* metaType = arg->type();
const QByteArray origType =
QMetaObject::normalizedType(qPrintable(metaType->originalTypeDescription()));
@@ -4704,9 +4796,8 @@ void CppGenerator::writeClassRegister(QTextStream &s,
s << "// Multiple signatures have their index \"n:\" in front." << endl;
s << "const char " << initFunctionName << "_SignaturesString[] = \"\"" << endl;
QString line;
- while (signatureStream.readLineInto(&line)) {
+ while (signatureStream.readLineInto(&line))
s << INDENT << '"' << line << "\\n\"" << endl;
- }
s << ';' << endl << endl;
s << "void init_" << initFunctionName;
s << "(PyObject* " << enclosingObjectVariable << ")" << endl;
@@ -4747,7 +4838,7 @@ void CppGenerator::writeClassRegister(QTextStream &s,
if (metaClass->baseClassNames().size() > 1) {
s << INDENT << "PyObject* " << pyTypeBasesVariable << " = PyTuple_Pack(" << baseClasses.size() << ',' << endl;
QStringList bases;
- foreach (const AbstractMetaClass* base, baseClasses)
+ for (const AbstractMetaClass *base : baseClasses)
bases << QLatin1String("(PyObject*)") + cpythonTypeNameExt(base->typeEntry());
Indentation indent(INDENT);
QString separator;
@@ -4842,7 +4933,8 @@ void CppGenerator::writeClassRegister(QTextStream &s,
}
AbstractMetaEnumList classEnums = metaClass->enums();
- foreach (AbstractMetaClass* innerClass, metaClass->innerClasses())
+ const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
+ for (AbstractMetaClass *innerClass : innerClasses)
lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass);
ErrorCode errorCode(QString::null);
@@ -4852,7 +4944,8 @@ void CppGenerator::writeClassRegister(QTextStream &s,
writeSignalInitialization(s, metaClass);
// Write static fields
- foreach (const AbstractMetaField* field, metaClass->fields()) {
+ const AbstractMetaFieldList &fields = metaClass->fields();
+ for (const AbstractMetaField *field : fields) {
if (!field->isStatic())
continue;
s << INDENT << QLatin1String("PyDict_SetItemString(") + cpythonTypeName(metaClass) + QLatin1String(".super.ht_type.tp_dict, \"");
@@ -4897,7 +4990,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont
const AbstractMetaClass* enclosingClass = metaClass->enclosingClass();
while (enclosingClass) {
if (enclosingClass->typeEntry()->generateCode())
- nameVariants << (enclosingClass->name() + QLatin1String("::") + nameVariants.last());
+ nameVariants << (enclosingClass->name() + QLatin1String("::") + nameVariants.constLast());
enclosingClass = enclosingClass->enclosingClass();
}
@@ -4912,7 +5005,8 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont
bool canBeValue = false;
if (!isObjectType(metaClass)) {
// check if there's a empty ctor
- foreach (AbstractMetaFunction* func, metaClass->functions()) {
+ const AbstractMetaFunctionList &funcs = metaClass->functions();
+ for (AbstractMetaFunction *func : funcs) {
if (func->isConstructor() && !func->arguments().count()) {
canBeValue = true;
break;
@@ -4921,7 +5015,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont
}
if (canBeValue) {
- foreach (const QString &name, nameVariants) {
+ for (const QString &name : qAsConst(nameVariants)) {
if (name == QLatin1String("iterator")) {
qCWarning(lcShiboken).noquote().nospace()
<< QString::fromLatin1("%1:%2 FIXME:\n"
@@ -4935,9 +5029,10 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont
}
}
- foreach (AbstractMetaEnum* metaEnum, metaClass->enums()) {
+ const AbstractMetaEnumList &enums = metaClass->enums();
+ for (AbstractMetaEnum *metaEnum : enums) {
if (!metaEnum->isPrivate() && !metaEnum->isAnonymous()) {
- foreach (const QString &name, nameVariants)
+ for (const QString &name : qAsConst(nameVariants))
s << INDENT << "qRegisterMetaType< ::" << metaEnum->typeEntry()->qualifiedCppName() << " >(\"" << name << "::" << metaEnum->name() << "\");" << endl;
if (metaEnum->typeEntry()->flags()) {
@@ -4965,8 +5060,8 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream& s, const AbstractMeta
s << INDENT << "return cptr;" << endl;
}
} else if (metaClass->isPolymorphic()) {
- AbstractMetaClassList ancestors = getAllAncestors(metaClass);
- foreach (AbstractMetaClass* ancestor, ancestors) {
+ const AbstractMetaClassList &ancestors = getAllAncestors(metaClass);
+ for (AbstractMetaClass *ancestor : ancestors) {
if (ancestor->baseClass())
continue;
if (ancestor->isPolymorphic()) {
@@ -5077,7 +5172,8 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &conte
}
s << INDENT << '}' << endl;
- foreach (const AbstractMetaFunction* func, getMethodsWithBothStaticAndNonStaticMethods(metaClass)) {
+ const AbstractMetaFunctionList &funcs = getMethodsWithBothStaticAndNonStaticMethods(metaClass);
+ for (const AbstractMetaFunction *func : funcs) {
QString defName = cpythonMethodDefinitionName(func);
s << INDENT << "static PyMethodDef non_static_" << defName << " = {" << endl;
{
@@ -5172,7 +5268,7 @@ bool CppGenerator::finishGeneration()
const FunctionGroupMap &functionGroups = getFunctionGroups();
for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
- foreach (AbstractMetaFunction* func, it.value()) {
+ for (AbstractMetaFunction *func : it.value()) {
if (!func->isModifiedRemoved()) {
overloads.append(func);
if (func->typeEntry())
@@ -5203,7 +5299,7 @@ bool CppGenerator::finishGeneration()
}
const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies);
- foreach (const AbstractMetaClass* cls, lst) {
+ for (const AbstractMetaClass *cls : lst){
if (!shouldGenerate(cls))
continue;
@@ -5219,7 +5315,8 @@ bool CppGenerator::finishGeneration()
}
// Initialize smart pointer types.
- foreach (const AbstractMetaType *metaType, instantiatedSmartPointers()) {
+ const QVector<const AbstractMetaType *> &smartPtrs = instantiatedSmartPointers();
+ for (const AbstractMetaType *metaType : smartPtrs) {
GeneratorContext context(0, metaType, true);
QString initFunctionName = getInitFunctionName(context);
s_classInitDecl << "void init_" << initFunctionName << "(PyObject* module);" << endl;
@@ -5255,13 +5352,14 @@ bool CppGenerator::finishGeneration()
}
s << "#include \"" << getModuleHeaderFileName() << '"' << endl << endl;
- foreach (const Include& include, includes)
+ for (const Include &include : qAsConst(includes))
s << include;
s << endl;
// Global enums
AbstractMetaEnumList globalEnums = this->globalEnums();
- foreach (const AbstractMetaClass* metaClass, classes()) {
+ const AbstractMetaClassList &classList = classes();
+ for (const AbstractMetaClass *metaClass : classList) {
const AbstractMetaClass* encClass = metaClass->enclosingClass();
if (encClass && encClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)
continue;
@@ -5273,13 +5371,13 @@ bool CppGenerator::finishGeneration()
//Extra includes
s << endl << "// Extra includes" << endl;
- QList<Include> extraIncludes;
+ QVector<Include> extraIncludes;
if (moduleEntry)
extraIncludes = moduleEntry->extraIncludes();
- foreach (AbstractMetaEnum* cppEnum, globalEnums)
+ for (AbstractMetaEnum *cppEnum : qAsConst(globalEnums))
extraIncludes.append(cppEnum->typeEntry()->extraIncludes());
qSort(extraIncludes.begin(), extraIncludes.end());
- foreach (const Include& inc, extraIncludes)
+ for (const Include &inc : qAsConst(extraIncludes))
s << inc;
s << endl;
@@ -5334,7 +5432,7 @@ bool CppGenerator::finishGeneration()
s << "// Enum definitions ";
s << "------------------------------------------------------------" << endl;
- foreach (const AbstractMetaEnum* cppEnum, globalEnums) {
+ for (const AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
writeEnumConverterFunctions(s, cppEnum);
@@ -5350,10 +5448,10 @@ bool CppGenerator::finishGeneration()
}
}
- QStringList requiredModules = typeDb->requiredTargetImports();
+ const QStringList &requiredModules = typeDb->requiredTargetImports();
if (!requiredModules.isEmpty())
s << "// Required modules' type and converter arrays." << endl;
- foreach (const QString& requiredModule, requiredModules) {
+ for (const QString &requiredModule : requiredModules) {
s << "PyTypeObject** " << cppApiVariableName(requiredModule) << ';' << endl;
s << "SbkConverter** " << convertersVariableName(requiredModule) << ';' << endl;
}
@@ -5367,7 +5465,7 @@ bool CppGenerator::finishGeneration()
for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
const TypeEntry *externalType = it.key();
s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl;
- foreach (const AbstractMetaClass* sourceClass, extendedConverters[externalType]) {
+ for (const AbstractMetaClass *sourceClass : it.value()) {
AbstractMetaType* sourceType = buildAbstractMetaTypeFromAbstractMetaClass(sourceClass);
AbstractMetaType* targetType = buildAbstractMetaTypeFromTypeEntry(externalType);
writePythonToCppConversionFunctions(s, sourceType, targetType);
@@ -5375,10 +5473,10 @@ bool CppGenerator::finishGeneration()
}
}
- QList<const CustomConversion*> typeConversions = getPrimitiveCustomConversions();
+ const QVector<const CustomConversion *> &typeConversions = getPrimitiveCustomConversions();
if (!typeConversions.isEmpty()) {
s << endl << "// Primitive Type converters." << endl << endl;
- foreach (const CustomConversion* conversion, typeConversions) {
+ for (const CustomConversion *conversion : typeConversions) {
s << "// C++ to Python conversion for type '" << conversion->ownerType()->qualifiedCppName() << "'." << endl;
writeCppToPythonFunction(s, conversion);
writeCustomConverterFunctions(s, conversion);
@@ -5386,10 +5484,10 @@ bool CppGenerator::finishGeneration()
s << endl;
}
- QList<const AbstractMetaType*> containers = instantiatedContainers();
+ const QVector<const AbstractMetaType *> &containers = instantiatedContainers();
if (!containers.isEmpty()) {
s << "// Container Type converters." << endl << endl;
- foreach (const AbstractMetaType* container, containers) {
+ for (const AbstractMetaType *container : containers) {
s << "// C++ to Python conversion for type '" << container->cppSignature() << "'." << endl;
writeContainerConverterFunctions(s, container);
}
@@ -5426,7 +5524,7 @@ bool CppGenerator::finishGeneration()
s << endl;
}
- foreach (const QString& requiredModule, typeDb->requiredTargetImports()) {
+ for (const QString& requiredModule : requiredModules) {
s << INDENT << "{" << endl;
{
Indentation indentation(INDENT);
@@ -5468,7 +5566,7 @@ bool CppGenerator::finishGeneration()
if (!typeConversions.isEmpty()) {
s << endl;
- foreach (const CustomConversion* conversion, typeConversions) {
+ for (const CustomConversion *conversion : typeConversions) {
writePrimitiveConverterInitialization(s, conversion);
s << endl;
}
@@ -5476,7 +5574,7 @@ bool CppGenerator::finishGeneration()
if (!containers.isEmpty()) {
s << endl;
- foreach (const AbstractMetaType* container, containers) {
+ for (const AbstractMetaType *container : containers) {
writeContainerConverterInitialization(s, container);
s << endl;
}
@@ -5493,7 +5591,8 @@ bool CppGenerator::finishGeneration()
writeEnumsInitialization(s, globalEnums);
s << INDENT << "// Register primitive types converters." << endl;
- foreach(const PrimitiveTypeEntry* pte, primitiveTypes()) {
+ const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
+ for (const PrimitiveTypeEntry *pte : primitiveTypeList) {
if (!pte->generateCode() || !pte->isCppPrimitive())
continue;
const TypeEntry *referencedType = pte->basicReferencedTypeEntry();
@@ -5534,7 +5633,7 @@ bool CppGenerator::finishGeneration()
}
if (usePySideExtensions()) {
- foreach (AbstractMetaEnum* metaEnum, globalEnums)
+ for (AbstractMetaEnum *metaEnum : qAsConst(globalEnums))
if (!metaEnum->isAnonymous()) {
s << INDENT << "qRegisterMetaType< ::" << metaEnum->typeEntry()->qualifiedCppName() << " >(\"" << metaEnum->name() << "\");" << endl;
}
@@ -5547,9 +5646,8 @@ bool CppGenerator::finishGeneration()
s << "// Multiple signatures have their index \"n:\" in front." << endl;
s << "const char " << moduleName() << "_SignaturesString[] = \"\"" << endl;
QString line;
- while (signatureStream.readLineInto(&line)) {
+ while (signatureStream.readLineInto(&line))
s << INDENT << '"' << line << "\\n\"" << endl;
- }
s << ';' << endl;
// finish the rest of __signature__ initialization.
s << INDENT << "FinishSignatureInitialization(module, " << moduleName()
@@ -5693,7 +5791,7 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &
s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = " CPP_SELF_VAR "->begin();" << endl;
s << INDENT << "for (Py_ssize_t pos = 0; pos < _i; pos++) _item++;" << endl;
- const AbstractMetaType* itemType = metaClass->templateBaseClassInstantiations().first();
+ const AbstractMetaType* itemType = metaClass->templateBaseClassInstantiations().constFirst();
s << INDENT << "return ";
writeToPythonConversion(s, itemType, metaClass, QLatin1String("*_item"));
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h
index 4877a1694..cce1842ab 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.h
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h
@@ -39,12 +39,12 @@ class CppGenerator : public ShibokenGenerator
public:
CppGenerator();
protected:
- QString fileNamePrefix() const;
- QString fileNameForContext(GeneratorContext &context) const;
- QList<AbstractMetaFunctionList> filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass,
- uint query);
- void generateClass(QTextStream& s, GeneratorContext &classContext);
- bool finishGeneration();
+ QString fileNamePrefix() const override;
+ QString fileNameForContext(GeneratorContext &context) const override;
+ QVector<AbstractMetaFunctionList> filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass,
+ uint query);
+ void generateClass(QTextStream& s, GeneratorContext &classContext) override;
+ bool finishGeneration() override;
private:
void writeConstructorNative(QTextStream& s, const AbstractMetaFunction* func);
@@ -291,7 +291,7 @@ private:
void writeEnumConverterInitialization(QTextStream& s, const TypeEntry* enumType);
void writeEnumConverterInitialization(QTextStream& s, const AbstractMetaEnum* metaEnum);
void writeContainerConverterInitialization(QTextStream& s, const AbstractMetaType* type);
- void writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QList<const AbstractMetaClass*>& conversions);
+ void writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QVector<const AbstractMetaClass*>& conversions);
void writeParentChildManagement(QTextStream& s, const AbstractMetaFunction* func, bool userHeuristicForReturn);
bool writeParentChildManagement(QTextStream& s, const AbstractMetaFunction* func, int argIndex, bool userHeuristicPolicy);
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index 7158c370b..a033cb69a 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -35,7 +35,6 @@
#include <QtCore/QDir>
#include <QtCore/QTextStream>
#include <QtCore/QVariant>
-#include <QtCore/QRegExp>
#include <QtCore/QDebug>
QString HeaderGenerator::fileNamePrefix() const
@@ -139,15 +138,15 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
s << endl << '{' << endl << "public:" << endl;
- bool hasVirtualFunction = false;
- foreach (AbstractMetaFunction *func, filterFunctions(metaClass)) {
- if (func->isVirtual())
- hasVirtualFunction = true;
- writeFunction(s, func);
+ const AbstractMetaFunctionList &funcs = filterFunctions(metaClass);
+ for (AbstractMetaFunction *func : funcs) {
+ if ((func->attributes() & AbstractMetaAttributes::FinalCppMethod) == 0)
+ writeFunction(s, func);
}
if (avoidProtectedHack() && metaClass->hasProtectedFields()) {
- foreach (AbstractMetaField* field, metaClass->fields()) {
+ const AbstractMetaFieldList &fields = metaClass->fields();
+ for (AbstractMetaField *field : fields) {
if (!field->isProtected())
continue;
writeProtectedFieldAccessors(s, field);
@@ -162,8 +161,6 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
if (avoidProtectedHack() && metaClass->hasPrivateDestructor())
s << "// C++11: need to declare (unimplemented) destructor because "
"the base class destructor is private." << endl;
- if (metaClass->hasVirtualDestructor() || hasVirtualFunction)
- s << "virtual ";
s << '~' << wrapperName << "();" << endl;
}
@@ -172,8 +169,8 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
&& usePySideExtensions() && metaClass->isQObject()) {
s << "public:\n";
- s << INDENT << "virtual int qt_metacall(QMetaObject::Call call, int id, void** args);" << endl;
- s << INDENT << "virtual void* qt_metacast(const char* _clname);" << endl;
+ s << INDENT << "int qt_metacall(QMetaObject::Call call, int id, void** args) override;" << endl;
+ s << INDENT << "void* qt_metacast(const char* _clname) override;" << endl;
}
if (m_inheritedOverloads.size()) {
@@ -228,7 +225,8 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
s << func->ownerClass()->qualifiedCppName() << "::";
s << func->originalName() << '(';
QStringList args;
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
QString argName = arg->name();
const TypeEntry* enumTypeEntry = 0;
if (arg->type()->isFlags())
@@ -244,8 +242,9 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
}
// pure virtual functions need a default implementation
- if ((func->isPrivate() && !visibilityModifiedToPrivate(func))
- || (func->isModifiedRemoved() && !func->isAbstract()))
+ const bool notAbstract = !func->isAbstract();
+ if ((func->isPrivate() && notAbstract && !visibilityModifiedToPrivate(func))
+ || (func->isModifiedRemoved() && notAbstract))
return;
if (avoidProtectedHack() && func->ownerClass()->hasPrivateDestructor()
@@ -256,15 +255,18 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
s << INDENT;
Options virtualOption = Generator::OriginalTypeDescription;
- if (func->isVirtual() || func->isAbstract())
- s << "virtual ";
- else if (!func->hasSignatureModifications())
+ const bool virtualFunc = func->isVirtual() || func->isAbstract();
+ if (!virtualFunc && !func->hasSignatureModifications())
virtualOption = Generator::NoOption;
- s << functionSignature(func, QString(), QString(), virtualOption) << ';' << endl;
+ s << functionSignature(func, QString(), QString(), virtualOption);
+ if (virtualFunc)
+ s << " override";
+ s << ';' << endl;
// Check if this method hide other methods in base classes
- foreach (const AbstractMetaFunction* f, func->ownerClass()->functions()) {
+ const AbstractMetaFunctionList &ownerFuncs = func->ownerClass()->functions();
+ for (const AbstractMetaFunction *f : ownerFuncs) {
if (f != func
&& !f->isConstructor()
&& !f->isPrivate()
@@ -317,7 +319,8 @@ void HeaderGenerator::writeTypeIndexDefine(QTextStream& s, const AbstractMetaCla
if (!metaClass->typeEntry()->generateCode())
return;
writeTypeIndexDefineLine(s, metaClass->typeEntry());
- foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) {
+ const AbstractMetaEnumList &enums = metaClass->enums();
+ for (const AbstractMetaEnum *metaEnum : enums) {
if (metaEnum->isPrivate())
continue;
writeTypeIndexDefineLine(s, metaEnum->typeEntry());
@@ -341,18 +344,20 @@ bool HeaderGenerator::finishGeneration()
macrosStream << "// Type indices" << endl;
AbstractMetaEnumList globalEnums = this->globalEnums();
- foreach (const AbstractMetaClass* metaClass, classes()) {
+ const AbstractMetaClassList &classList = classes();
+ for (const AbstractMetaClass *metaClass : classList) {
writeTypeIndexDefine(macrosStream, metaClass);
lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
}
- foreach (const AbstractMetaEnum* metaEnum, globalEnums)
+ for (const AbstractMetaEnum *metaEnum : qAsConst(globalEnums))
writeTypeIndexDefineLine(macrosStream, metaEnum->typeEntry());
// Write the smart pointer define indexes.
int smartPointerCountIndex = getMaxTypeIndex();
int smartPointerCount = 0;
- foreach (const AbstractMetaType *metaType, instantiatedSmartPointers()) {
+ const QVector<const AbstractMetaType *> &instantiatedSmartPtrs = instantiatedSmartPointers();
+ for (const AbstractMetaType *metaType : instantiatedSmartPtrs) {
QString variableName = getTypeIndexVariableName(metaType);
macrosStream << "#define ";
macrosStream.setFieldWidth(60);
@@ -378,9 +383,9 @@ bool HeaderGenerator::finishGeneration()
// TODO-CONVERTER ------------------------------------------------------------------------------
// Using a counter would not do, a fix must be made to APIExtractor's getTypeIndex().
macrosStream << "// Converter indices" << endl;
- QList<const PrimitiveTypeEntry*> primitives = primitiveTypes();
+ const PrimitiveTypeEntryList &primitives = primitiveTypes();
int pCount = 0;
- foreach (const PrimitiveTypeEntry* ptype, primitives) {
+ for (const PrimitiveTypeEntry *ptype : primitives) {
/* Note: do not generate indices for typedef'd primitive types
* as they'll use the primitive type converters instead, so we
* don't need to create any other.
@@ -391,7 +396,8 @@ bool HeaderGenerator::finishGeneration()
_writeTypeIndexDefineLine(macrosStream, getTypeIndexVariableName(ptype), pCount++);
}
- foreach (const AbstractMetaType* container, instantiatedContainers()) {
+ const QVector<const AbstractMetaType *> &containers = instantiatedContainers();
+ for (const AbstractMetaType *container : containers) {
//_writeTypeIndexDefineLine(macrosStream, getTypeIndexVariableName(container), pCount);
// DEBUG
QString variableName = getTypeIndexVariableName(container);
@@ -412,7 +418,7 @@ bool HeaderGenerator::finishGeneration()
// TODO-CONVERTER ------------------------------------------------------------------------------
macrosStream << "// Macros for type check" << endl;
- foreach (const AbstractMetaEnum* cppEnum, globalEnums) {
+ for (const AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
includes << cppEnum->typeEntry()->include();
@@ -420,7 +426,7 @@ bool HeaderGenerator::finishGeneration()
writeSbkTypeFunction(typeFunctions, cppEnum);
}
- foreach (AbstractMetaClass* metaClass, classes()) {
+ for (AbstractMetaClass *metaClass : classList) {
if (!shouldGenerate(metaClass))
continue;
@@ -428,7 +434,8 @@ bool HeaderGenerator::finishGeneration()
const TypeEntry* classType = metaClass->typeEntry();
includes << classType->include();
- foreach (const AbstractMetaEnum* cppEnum, metaClass->enums()) {
+ const AbstractMetaEnumList &enums = metaClass->enums();
+ for (const AbstractMetaEnum *cppEnum : enums) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
EnumTypeEntry* enumType = cppEnum->typeEntry();
@@ -441,7 +448,7 @@ bool HeaderGenerator::finishGeneration()
writeSbkTypeFunction(typeFunctions, metaClass);
}
- foreach (const AbstractMetaType *metaType, instantiatedSmartPointers()) {
+ for (const AbstractMetaType *metaType : instantiatedSmartPtrs) {
const TypeEntry *classType = metaType->typeEntry();
includes << classType->include();
writeSbkTypeFunction(typeFunctions, metaType);
@@ -477,25 +484,27 @@ bool HeaderGenerator::finishGeneration()
QStringList requiredTargetImports = TypeDatabase::instance()->requiredTargetImports();
if (!requiredTargetImports.isEmpty()) {
s << "// Module Includes" << endl;
- foreach (const QString& requiredModule, requiredTargetImports)
+ for (const QString &requiredModule : qAsConst(requiredTargetImports))
s << "#include <" << getModuleHeaderFileName(requiredModule) << ">" << endl;
s << endl;
}
s << "// Binded library includes" << endl;
- foreach (const Include& include, includes)
+ for (const Include &include : qAsConst(includes))
s << include;
if (!primitiveTypes().isEmpty()) {
s << "// Conversion Includes - Primitive Types" << endl;
- foreach (const PrimitiveTypeEntry* ptype, primitiveTypes())
+ const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
+ for (const PrimitiveTypeEntry *ptype : primitiveTypeList)
s << ptype->include();
s << endl;
}
if (!containerTypes().isEmpty()) {
s << "// Conversion Includes - Container Types" << endl;
- foreach (const ContainerTypeEntry* ctype, containerTypes())
+ const ContainerTypeEntryList &containerTypeList = containerTypes();
+ for (const ContainerTypeEntry *ctype : containerTypeList)
s << ctype->include();
s << endl;
}
@@ -560,13 +569,14 @@ void HeaderGenerator::writeSbkTypeFunction(QTextStream &s, const AbstractMetaTyp
void HeaderGenerator::writeInheritedOverloads(QTextStream& s)
{
- foreach (const AbstractMetaFunction* func, m_inheritedOverloads) {
+ for (const AbstractMetaFunction *func : qAsConst(m_inheritedOverloads)) {
s << INDENT << "inline ";
s << functionSignature(func, QString(), QString(), Generator::EnumAsInts|Generator::OriginalTypeDescription) << " { ";
s << (func->type() ? "return " : "");
s << func->ownerClass()->qualifiedCppName() << "::" << func->originalName() << '(';
QStringList args;
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
QString argName = arg->name();
const TypeEntry* enumTypeEntry = 0;
if (arg->type()->isFlags())
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.h b/sources/shiboken2/generator/shiboken2/headergenerator.h
index 72dcbf69f..d9dc8ffe8 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.h
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.h
@@ -41,12 +41,12 @@ class AbstractMetaFunction;
class HeaderGenerator : public ShibokenGenerator
{
public:
- QMap<QString, QString> options() const { return QMap<QString, QString>(); }
+ OptionDescriptions options() const override { return OptionDescriptions(); }
protected:
- QString fileNamePrefix() const;
- QString fileNameForContext(GeneratorContext &context) const;
- void generateClass(QTextStream& s, GeneratorContext &classContext);
- bool finishGeneration();
+ QString fileNamePrefix() const override;
+ QString fileNameForContext(GeneratorContext &context) const override;
+ void generateClass(QTextStream& s, GeneratorContext &classContext) override;
+ bool finishGeneration() override;
private:
void writeCopyCtor(QTextStream &s, const AbstractMetaClass* metaClass) const;
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index 8731fe911..3340ee957 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -53,7 +53,8 @@ static QString getTypeName(const AbstractMetaType* type)
QString typeName = typeEntry->name();
if (typeEntry->isContainer()) {
QStringList types;
- foreach (const AbstractMetaType* cType, type->instantiations()) {
+ const AbstractMetaTypeList &instantiations = type->instantiations();
+ for (const AbstractMetaType *cType : instantiations) {
const TypeEntry *typeEntry = getReferencedTypeEntry(cType->typeEntry());
types << typeEntry->name();
}
@@ -93,7 +94,7 @@ static bool typesAreEqual(const AbstractMetaType* typeA, const AbstractMetaType*
*/
struct OverloadSortData
{
- OverloadSortData() : counter(0) {};
+ OverloadSortData() : counter(0) {}
/**
* Adds a typeName into the type map without associating it with
@@ -141,10 +142,11 @@ static QString getImplicitConversionTypeName(const AbstractMetaType* containerTy
else if (function->isConversionOperator())
impConv = function->ownerClass()->typeEntry()->name();
else
- impConv = getTypeName(function->arguments().first()->type());
+ impConv = getTypeName(function->arguments().constFirst()->type());
QStringList types;
- foreach (const AbstractMetaType* otherType, containerType->instantiations())
+ const AbstractMetaTypeList &instantiations = containerType->instantiations();
+ for (const AbstractMetaType *otherType : instantiations)
types << (otherType == instantiation ? impConv : getTypeName(otherType));
const ContainerTypeEntry* containerTypeEntry = dynamic_cast<const ContainerTypeEntry*>(containerType->typeEntry());
@@ -153,7 +155,7 @@ static QString getImplicitConversionTypeName(const AbstractMetaType* containerTy
}
static QString msgCyclicDependency(const QString &funcName, const QString &graphName,
- const QList<const AbstractMetaFunction *> &involvedConversions)
+ const OverloadData::MetaFunctionList &involvedConversions)
{
QString result;
QTextStream str(&result);
@@ -209,7 +211,7 @@ void OverloadData::sortNextOverloads()
<< QLatin1String("long");
// sort the children overloads
- foreach(OverloadData *ov, m_nextOverloadData)
+ for (OverloadData *ov : qAsConst(m_nextOverloadData))
ov->sortNextOverloads();
if (m_nextOverloadData.size() <= 1)
@@ -218,7 +220,7 @@ void OverloadData::sortNextOverloads()
// Populates the OverloadSortData object containing map and reverseMap, to map type names to ids,
// these ids will be used by the topological sort algorithm, because is easier and faster to work
// with graph sorting using integers.
- foreach(OverloadData* ov, m_nextOverloadData) {
+ for (OverloadData *ov : qAsConst(m_nextOverloadData)) {
sortData.mapType(ov);
const QString typeName(getTypeName(ov));
@@ -240,7 +242,8 @@ void OverloadData::sortNextOverloads()
qstringIndex = sortData.lastProcessedItemId();
}
- foreach (const AbstractMetaType* instantiation, ov->argType()->instantiations()) {
+ const AbstractMetaTypeList &instantiations = ov->argType()->instantiations();
+ for (const AbstractMetaType *instantiation : instantiations) {
// Add dependencies for type instantiation of container.
QString typeName = getTypeName(instantiation);
sortData.mapType(typeName);
@@ -251,10 +254,11 @@ void OverloadData::sortNextOverloads()
// as Point must come before the PointF instantiation, or else list<Point> will never
// be called. In the case of primitive types, list<double> must come before list<int>.
if (instantiation->isPrimitive() && (signedIntegerPrimitives.contains(instantiation->name()))) {
- foreach (const QString& primitive, nonIntegerPrimitives)
+ for (const QString &primitive : qAsConst(nonIntegerPrimitives))
sortData.mapType(getImplicitConversionTypeName(ov->argType(), instantiation, 0, primitive));
} else {
- foreach (const AbstractMetaFunction* function, m_generator->implicitConversions(instantiation))
+ const AbstractMetaFunctionList &funcs = m_generator->implicitConversions(instantiation);
+ for (const AbstractMetaFunction *function : funcs)
sortData.mapType(getImplicitConversionTypeName(ov->argType(), instantiation, function));
}
}
@@ -287,20 +291,21 @@ void OverloadData::sortNextOverloads()
QStringList classesWithIntegerImplicitConversion;
- QList<const AbstractMetaFunction *> involvedConversions;
+ MetaFunctionList involvedConversions;
- foreach(OverloadData* ov, m_nextOverloadData) {
+ for (OverloadData *ov : qAsConst(m_nextOverloadData)) {
const AbstractMetaType* targetType = ov->argType();
const QString targetTypeEntryName(getTypeName(ov));
int targetTypeId = sortData.map[targetTypeEntryName];
// Process implicit conversions
- foreach(AbstractMetaFunction* function, m_generator->implicitConversions(targetType)) {
+ const AbstractMetaFunctionList &functions = m_generator->implicitConversions(targetType);
+ for (AbstractMetaFunction *function : functions) {
QString convertibleType;
if (function->isConversionOperator())
convertibleType = function->ownerClass()->typeEntry()->name();
else
- convertibleType = getTypeName(function->arguments().first()->type());
+ convertibleType = getTypeName(function->arguments().constFirst()->type());
if (convertibleType == QLatin1String("int") || convertibleType == QLatin1String("unsigned int"))
classesWithIntegerImplicitConversion << targetTypeEntryName;
@@ -318,9 +323,10 @@ void OverloadData::sortNextOverloads()
}
// Process inheritance relationships
- if (targetType->isValue() || targetType->isObject()) {
+ if (targetType->isValue() || targetType->isObject() || targetType->isQObject()) {
const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), targetType->typeEntry());
- foreach (const AbstractMetaClass* ancestor, m_generator->getAllAncestors(metaClass)) {
+ const AbstractMetaClassList &ancestors = m_generator->getAllAncestors(metaClass);
+ for (const AbstractMetaClass *ancestor : ancestors) {
QString ancestorTypeName = ancestor->typeEntry()->name();
if (!sortData.map.contains(ancestorTypeName))
continue;
@@ -331,7 +337,8 @@ void OverloadData::sortNextOverloads()
}
// Process template instantiations
- foreach (const AbstractMetaType* instantiation, targetType->instantiations()) {
+ const AbstractMetaTypeList &instantiations = targetType->instantiations();
+ for (const AbstractMetaType *instantiation : instantiations) {
if (sortData.map.contains(getTypeName(instantiation))) {
int convertible = sortData.map[getTypeName(instantiation)];
@@ -339,14 +346,15 @@ void OverloadData::sortNextOverloads()
graph.addEdge(convertible, targetTypeId);
if (instantiation->isPrimitive() && (signedIntegerPrimitives.contains(instantiation->name()))) {
- foreach (const QString& primitive, nonIntegerPrimitives) {
+ for (const QString &primitive : qAsConst(nonIntegerPrimitives)) {
QString convertibleTypeName = getImplicitConversionTypeName(ov->argType(), instantiation, 0, primitive);
if (!graph.containsEdge(targetTypeId, sortData.map[convertibleTypeName])) // Avoid cyclic dependency.
graph.addEdge(sortData.map[convertibleTypeName], targetTypeId);
}
} else {
- foreach (const AbstractMetaFunction* function, m_generator->implicitConversions(instantiation)) {
+ const AbstractMetaFunctionList &funcs = m_generator->implicitConversions(instantiation);
+ for (const AbstractMetaFunction *function : funcs) {
QString convertibleTypeName = getImplicitConversionTypeName(ov->argType(), instantiation, function);
if (!graph.containsEdge(targetTypeId, sortData.map[convertibleTypeName])) { // Avoid cyclic dependency.
graph.addEdge(sortData.map[convertibleTypeName], targetTypeId);
@@ -396,22 +404,22 @@ void OverloadData::sortNextOverloads()
if (sortData.map.contains(QLatin1String("QString")) && sortData.map.contains(QLatin1String("QByteArray")))
graph.addEdge(sortData.map[QLatin1String("QString")], sortData.map[QLatin1String("QByteArray")]);
- foreach(OverloadData* ov, m_nextOverloadData) {
+ for (OverloadData *ov : qAsConst(m_nextOverloadData)) {
const AbstractMetaType* targetType = ov->argType();
if (!targetType->isEnum())
continue;
QString targetTypeEntryName = getTypeName(targetType);
// Enum values must precede types implicitly convertible from "int" or "unsigned int".
- foreach (const QString& implicitFromInt, classesWithIntegerImplicitConversion)
+ for (const QString &implicitFromInt : qAsConst(classesWithIntegerImplicitConversion))
graph.addEdge(sortData.map[targetTypeEntryName], sortData.map[implicitFromInt]);
}
// Special case for double(int i) (not tracked by m_generator->implicitConversions
- foreach (const QString& signedIntegerName, signedIntegerPrimitives) {
+ for (const QString &signedIntegerName : qAsConst(signedIntegerPrimitives)) {
if (sortData.map.contains(signedIntegerName)) {
- foreach (const QString& nonIntegerName, nonIntegerPrimitives) {
+ for (const QString &nonIntegerName : qAsConst(nonIntegerPrimitives)) {
if (sortData.map.contains(nonIntegerName))
graph.addEdge(sortData.map[nonIntegerName], sortData.map[signedIntegerName]);
}
@@ -419,7 +427,7 @@ void OverloadData::sortNextOverloads()
}
// sort the overloads topologically based on the dependency graph.
- QLinkedList<int> unmappedResult = graph.topologicalSort();
+ const QLinkedList<int> unmappedResult = graph.topologicalSort();
if (unmappedResult.isEmpty()) {
QString funcName = referenceFunction()->name();
if (referenceFunction()->ownerClass())
@@ -427,16 +435,15 @@ void OverloadData::sortNextOverloads()
// Dump overload graph
QString graphName = QDir::tempPath() + QLatin1Char('/') + funcName + QLatin1String(".dot");
- QHash<QString, int>::const_iterator it = sortData.map.begin();
QHash<int, QString> nodeNames;
- for (; it != sortData.map.end(); ++it)
+ for (auto it = sortData.map.cbegin(), end = sortData.map.cend(); it != end; ++it)
nodeNames.insert(it.value(), it.key());
graph.dumpDot(nodeNames, graphName);
qCWarning(lcShiboken).noquote() << qPrintable(msgCyclicDependency(funcName, graphName, involvedConversions));
}
m_nextOverloadData.clear();
- foreach(int i, unmappedResult) {
+ for (int i : unmappedResult) {
if (!sortData.reverseMap[i])
continue;
m_nextOverloadData << sortData.reverseMap[i];
@@ -464,7 +471,7 @@ OverloadData::OverloadData(const AbstractMetaFunctionList& overloads, const Shib
: m_minArgs(256), m_maxArgs(0), m_argPos(-1), m_argType(0),
m_headOverloadData(this), m_previousOverloadData(0), m_generator(generator)
{
- foreach (const AbstractMetaFunction* func, overloads) {
+ for (const AbstractMetaFunction *func : overloads) {
m_overloads.append(func);
int argSize = func->arguments().size() - numberOfRemovedArguments(func);
if (m_minArgs > argSize)
@@ -472,7 +479,8 @@ OverloadData::OverloadData(const AbstractMetaFunctionList& overloads, const Shib
else if (m_maxArgs < argSize)
m_maxArgs = argSize;
OverloadData* currentOverloadData = this;
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
if (func->argumentRemoved(arg->argumentIndex() + 1))
continue;
currentOverloadData = currentOverloadData->addOverloadData(func, arg);
@@ -512,7 +520,7 @@ void OverloadData::addOverload(const AbstractMetaFunction* func)
for (int i = 0; m_headOverloadData->m_minArgs > 0 && i < origNumArgs; i++) {
if (func->argumentRemoved(i + 1))
continue;
- if (!ShibokenGenerator::getDefaultValue(func, func->arguments()[i]).isEmpty()) {
+ if (!ShibokenGenerator::getDefaultValue(func, func->arguments().at(i)).isEmpty()) {
int fixedArgIndex = i - removed;
if (fixedArgIndex < m_headOverloadData->m_minArgs)
m_headOverloadData->m_minArgs = fixedArgIndex;
@@ -528,7 +536,7 @@ OverloadData* OverloadData::addOverloadData(const AbstractMetaFunction* func,
const AbstractMetaType* argType = arg->type();
OverloadData* overloadData = 0;
if (!func->isOperatorOverload()) {
- foreach (OverloadData* tmp, m_nextOverloadData) {
+ for (OverloadData *tmp : qAsConst(m_nextOverloadData)) {
// TODO: 'const char *', 'char *' and 'char' will have the same TypeEntry?
// If an argument have a type replacement, then we should create a new overloaddata
@@ -560,7 +568,7 @@ OverloadData* OverloadData::addOverloadData(const AbstractMetaFunction* func,
QStringList OverloadData::returnTypes() const
{
QSet<QString> retTypes;
- foreach (const AbstractMetaFunction* func, m_overloads) {
+ for (const AbstractMetaFunction *func : m_overloads) {
if (!func->typeReplaced(0).isEmpty())
retTypes << func->typeReplaced(0);
else if (func->type() && !func->argumentRemoved(0))
@@ -579,9 +587,9 @@ bool OverloadData::hasNonVoidReturnType() const
bool OverloadData::hasVarargs() const
{
- foreach (const AbstractMetaFunction* func, m_overloads) {
+ for (const AbstractMetaFunction *func : m_overloads) {
AbstractMetaArgumentList args = func->arguments();
- if (args.size() > 1 && args.last()->type()->isVarargs())
+ if (args.size() > 1 && args.constLast()->type()->isVarargs())
return true;
}
return false;
@@ -589,7 +597,7 @@ bool OverloadData::hasVarargs() const
bool OverloadData::hasAllowThread() const
{
- foreach (const AbstractMetaFunction* func, m_overloads) {
+ for (const AbstractMetaFunction *func : m_overloads) {
if (func->allowThread())
return true;
}
@@ -598,7 +606,7 @@ bool OverloadData::hasAllowThread() const
bool OverloadData::hasStaticFunction(const AbstractMetaFunctionList& overloads)
{
- foreach (const AbstractMetaFunction* func, overloads) {
+ for (const AbstractMetaFunction *func : qAsConst(overloads)) {
if (func->isStatic())
return true;
}
@@ -607,7 +615,7 @@ bool OverloadData::hasStaticFunction(const AbstractMetaFunctionList& overloads)
bool OverloadData::hasStaticFunction() const
{
- foreach (const AbstractMetaFunction* func, m_overloads) {
+ for (const AbstractMetaFunction *func : m_overloads) {
if (func->isStatic())
return true;
}
@@ -616,7 +624,7 @@ bool OverloadData::hasStaticFunction() const
bool OverloadData::hasInstanceFunction(const AbstractMetaFunctionList& overloads)
{
- foreach (const AbstractMetaFunction* func, overloads) {
+ for (const AbstractMetaFunction *func : qAsConst(overloads)) {
if (!func->isStatic())
return true;
}
@@ -625,7 +633,7 @@ bool OverloadData::hasInstanceFunction(const AbstractMetaFunctionList& overloads
bool OverloadData::hasInstanceFunction() const
{
- foreach (const AbstractMetaFunction* func, m_overloads) {
+ for (const AbstractMetaFunction *func : m_overloads) {
if (!func->isStatic())
return true;
}
@@ -644,7 +652,7 @@ bool OverloadData::hasStaticAndInstanceFunctions() const
const AbstractMetaFunction* OverloadData::referenceFunction() const
{
- return m_overloads.first();
+ return m_overloads.constFirst();
}
const AbstractMetaArgument* OverloadData::argument(const AbstractMetaFunction* func) const
@@ -661,7 +669,7 @@ const AbstractMetaArgument* OverloadData::argument(const AbstractMetaFunction* f
argPos++;
}
- return func->arguments()[m_argPos + removed];
+ return func->arguments().at(m_argPos + removed);
}
OverloadDataList OverloadData::overloadDataOnPosition(OverloadData* overloadData, int argPos) const
@@ -670,7 +678,8 @@ OverloadDataList OverloadData::overloadDataOnPosition(OverloadData* overloadData
if (overloadData->argPos() == argPos) {
overloadDataList.append(overloadData);
} else if (overloadData->argPos() < argPos) {
- foreach (OverloadData* pd, overloadData->nextOverloadData())
+ const OverloadDataList &data = overloadData->nextOverloadData();
+ for (OverloadData *pd : data)
overloadDataList += overloadDataOnPosition(pd, argPos);
}
return overloadDataList;
@@ -685,7 +694,7 @@ OverloadDataList OverloadData::overloadDataOnPosition(int argPos) const
bool OverloadData::nextArgumentHasDefaultValue() const
{
- foreach (OverloadData* overloadData, m_nextOverloadData) {
+ for (OverloadData *overloadData : m_nextOverloadData) {
if (overloadData->getFunctionWithDefaultValue())
return true;
}
@@ -698,7 +707,8 @@ static OverloadData* _findNextArgWithDefault(OverloadData* overloadData)
return overloadData;
OverloadData* result = 0;
- foreach (OverloadData* odata, overloadData->nextOverloadData()) {
+ const OverloadDataList &data = overloadData->nextOverloadData();
+ for (OverloadData *odata : data) {
OverloadData* tmp = _findNextArgWithDefault(odata);
if (!result || (tmp && result->argPos() > tmp->argPos()))
result = tmp;
@@ -713,20 +723,20 @@ OverloadData* OverloadData::findNextArgWithDefault()
bool OverloadData::isFinalOccurrence(const AbstractMetaFunction* func) const
{
- foreach (const OverloadData* pd, m_nextOverloadData) {
+ for (const OverloadData *pd : m_nextOverloadData) {
if (pd->overloads().contains(func))
return false;
}
return true;
}
-QList<const AbstractMetaFunction*> OverloadData::overloadsWithoutRepetition() const
+OverloadData::MetaFunctionList OverloadData::overloadsWithoutRepetition() const
{
- QList<const AbstractMetaFunction*> overloads = m_overloads;
- foreach (const AbstractMetaFunction* func, m_overloads) {
+ MetaFunctionList overloads = m_overloads;
+ for (const AbstractMetaFunction *func : m_overloads) {
if (func->minimalSignature().endsWith(QLatin1String("const")))
continue;
- foreach (const AbstractMetaFunction* f, overloads) {
+ for (const AbstractMetaFunction *f : qAsConst(overloads)) {
if ((func->minimalSignature() + QLatin1String("const")) == f->minimalSignature()) {
overloads.removeOne(f);
break;
@@ -738,23 +748,23 @@ QList<const AbstractMetaFunction*> OverloadData::overloadsWithoutRepetition() co
const AbstractMetaFunction* OverloadData::getFunctionWithDefaultValue() const
{
- foreach (const AbstractMetaFunction* func, m_overloads) {
+ for (const AbstractMetaFunction *func : m_overloads) {
int removedArgs = 0;
for (int i = 0; i <= m_argPos + removedArgs; i++) {
if (func->argumentRemoved(i + 1))
removedArgs++;
}
- if (!ShibokenGenerator::getDefaultValue(func, func->arguments()[m_argPos + removedArgs]).isEmpty())
+ if (!ShibokenGenerator::getDefaultValue(func, func->arguments().at(m_argPos + removedArgs)).isEmpty())
return func;
}
return 0;
}
-QList<int> OverloadData::invalidArgumentLengths() const
+QVector<int> OverloadData::invalidArgumentLengths() const
{
QSet<int> validArgLengths;
- foreach (const AbstractMetaFunction* func, m_headOverloadData->m_overloads) {
+ for (const AbstractMetaFunction *func : qAsConst(m_headOverloadData->m_overloads)) {
const AbstractMetaArgumentList args = func->arguments();
int offset = 0;
for (int i = 0; i < args.size(); ++i) {
@@ -768,7 +778,7 @@ QList<int> OverloadData::invalidArgumentLengths() const
validArgLengths << args.size() - offset;
}
- QList<int> invalidArgLengths;
+ QVector<int> invalidArgLengths;
for (int i = minArgs() + 1; i < maxArgs(); i++) {
if (!validArgLengths.contains(i))
invalidArgLengths.append(i);
@@ -811,7 +821,7 @@ QPair<int, int> OverloadData::getMinMaxArguments(const AbstractMetaFunctionList&
if (func->argumentRemoved(j + 1))
continue;
int fixedArgIndex = j - removed;
- if (fixedArgIndex < minArgs && !ShibokenGenerator::getDefaultValue(func, func->arguments()[j]).isEmpty())
+ if (fixedArgIndex < minArgs && !ShibokenGenerator::getDefaultValue(func, func->arguments().at(j)).isEmpty())
minArgs = fixedArgIndex;
}
}
@@ -821,7 +831,7 @@ QPair<int, int> OverloadData::getMinMaxArguments(const AbstractMetaFunctionList&
bool OverloadData::isSingleArgument(const AbstractMetaFunctionList& overloads)
{
bool singleArgument = true;
- foreach (const AbstractMetaFunction* func, overloads) {
+ for (const AbstractMetaFunction *func : overloads) {
if (func->arguments().size() - numberOfRemovedArguments(func) != 1) {
singleArgument = false;
break;
@@ -859,7 +869,7 @@ QString OverloadData::dumpGraph() const
// Shows all function signatures
s << "legend [fontsize=9 fontname=freemono shape=rect label=\"";
- foreach (const AbstractMetaFunction* func, overloads()) {
+ for (const AbstractMetaFunction *func : m_overloads) {
s << "f" << functionNumber(func) << " : ";
if (func->type())
s << toHtml(func->type()->cppSignature());
@@ -893,7 +903,7 @@ QString OverloadData::dumpGraph() const
s << "</td></tr>";
// Shows type changes for all function signatures
- foreach (const AbstractMetaFunction* func, overloads()) {
+ for (const AbstractMetaFunction *func : m_overloads) {
if (func->typeReplaced(0).isEmpty())
continue;
s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
@@ -916,13 +926,13 @@ QString OverloadData::dumpGraph() const
// Overloads for the signature to present point
s << "<tr><td bgcolor=\"gray\" align=\"right\">overloads</td><td bgcolor=\"gray\" align=\"left\">";
- foreach (const AbstractMetaFunction* func, overloads())
+ for (const AbstractMetaFunction *func : m_overloads)
s << 'f' << functionNumber(func) << ' ';
s << "</td></tr>";
s << "</table>> ];" << endl;
- foreach (const OverloadData* pd, nextOverloadData())
+ for (const OverloadData *pd : m_nextOverloadData)
s << indent << '"' << rfunc->name() << "\" -> " << pd->dumpGraph();
s << "}" << endl;
@@ -948,12 +958,12 @@ QString OverloadData::dumpGraph() const
// Overloads for the signature to present point
s << "<tr><td bgcolor=\"gray\" align=\"right\">overloads</td><td bgcolor=\"gray\" align=\"left\">";
- foreach (const AbstractMetaFunction* func, overloads())
+ for (const AbstractMetaFunction *func : m_overloads)
s << 'f' << functionNumber(func) << ' ';
s << "</td></tr>";
// Show default values (original and modified) for various functions
- foreach (const AbstractMetaFunction* func, overloads()) {
+ for (const AbstractMetaFunction *func : m_overloads) {
const AbstractMetaArgument* arg = argument(func);
if (!arg)
continue;
@@ -973,7 +983,7 @@ QString OverloadData::dumpGraph() const
s << "</table>>];" << endl;
- foreach (const OverloadData* pd, nextOverloadData())
+ for (const OverloadData *pd : m_nextOverloadData)
s << indent << argId << " -> " << pd->dumpGraph();
}
return result;
@@ -1004,7 +1014,7 @@ bool OverloadData::hasArgumentWithDefaultValue(const AbstractMetaFunctionList& o
{
if (OverloadData::getMinMaxArguments(overloads).second == 0)
return false;
- foreach (const AbstractMetaFunction* func, overloads) {
+ for (const AbstractMetaFunction *func : overloads) {
if (hasArgumentWithDefaultValue(func))
return true;
}
@@ -1015,7 +1025,7 @@ bool OverloadData::hasArgumentWithDefaultValue() const
{
if (maxArgs() == 0)
return false;
- foreach (const AbstractMetaFunction* func, overloads()) {
+ for (const AbstractMetaFunction *func : m_overloads) {
if (hasArgumentWithDefaultValue(func))
return true;
}
@@ -1024,7 +1034,8 @@ bool OverloadData::hasArgumentWithDefaultValue() const
bool OverloadData::hasArgumentWithDefaultValue(const AbstractMetaFunction* func)
{
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
if (func->argumentRemoved(arg->argumentIndex() + 1))
continue;
if (!ShibokenGenerator::getDefaultValue(func, arg).isEmpty())
@@ -1036,7 +1047,8 @@ bool OverloadData::hasArgumentWithDefaultValue(const AbstractMetaFunction* func)
AbstractMetaArgumentList OverloadData::getArgumentsWithDefaultValues(const AbstractMetaFunction* func)
{
AbstractMetaArgumentList args;
- foreach (AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (AbstractMetaArgument *arg : arguments) {
if (ShibokenGenerator::getDefaultValue(func, arg).isEmpty()
|| func->argumentRemoved(arg->argumentIndex() + 1))
continue;
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.h b/sources/shiboken2/generator/shiboken2/overloaddata.h
index 959b96d0b..2d815f6bb 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.h
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.h
@@ -30,19 +30,21 @@
#define OVERLOADDATA_H
#include <abstractmetalang_typedefs.h>
-#include <QtCore/QList>
#include <QtCore/QBitArray>
+#include <QtCore/QVector>
QT_FORWARD_DECLARE_CLASS(QDebug)
class ShibokenGenerator;
class OverloadData;
-typedef QList<OverloadData*> OverloadDataList;
+typedef QVector<OverloadData *> OverloadDataList;
class OverloadData
{
public:
+ typedef QVector<const AbstractMetaFunction *> MetaFunctionList;
+
OverloadData(const AbstractMetaFunctionList& overloads, const ShibokenGenerator* generator);
~OverloadData();
@@ -100,12 +102,12 @@ public:
bool isFinalOccurrence(const AbstractMetaFunction* func) const;
/// Returns the list of overloads removing repeated constant functions (ex.: "foo()" and "foo()const", the second is removed).
- QList<const AbstractMetaFunction*> overloadsWithoutRepetition() const;
- const QList<const AbstractMetaFunction*>& overloads() const { return m_overloads; }
+ MetaFunctionList overloadsWithoutRepetition() const;
+ const MetaFunctionList& overloads() const { return m_overloads; }
OverloadDataList nextOverloadData() const { return m_nextOverloadData; }
OverloadData* previousOverloadData() const { return m_previousOverloadData; }
- QList<int> invalidArgumentLengths() const;
+ QVector<int> invalidArgumentLengths() const;
static int numberOfRemovedArguments(const AbstractMetaFunction* func, int finalArgPos = -1);
static QPair<int, int> getMinMaxArguments(const AbstractMetaFunctionList& overloads);
@@ -146,7 +148,7 @@ private:
int m_argPos;
const AbstractMetaType* m_argType;
QString m_argTypeReplaced;
- QList<const AbstractMetaFunction*> m_overloads;
+ MetaFunctionList m_overloads;
OverloadData* m_headOverloadData;
OverloadDataList m_nextOverloadData;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 670659854..d64719bb8 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -35,6 +35,7 @@
#include <QtCore/QDir>
#include <QtCore/QDebug>
+#include <QtCore/QRegularExpression>
#include <limits>
#include <memory>
@@ -54,22 +55,51 @@ QHash<QString, QString> ShibokenGenerator::m_formatUnits = QHash<QString, QStrin
QHash<QString, QString> ShibokenGenerator::m_tpFuncs = QHash<QString, QString>();
QStringList ShibokenGenerator::m_knownPythonTypes = QStringList();
-static QString resolveScopePrefix(const AbstractMetaClass* scope, const QString& value)
+static QRegularExpression placeHolderRegex(int index)
{
- if (!scope)
- return QString();
+ return QRegularExpression(QLatin1Char('%') + QString::number(index) + QStringLiteral("\\b"));
+}
+// Return a prefix to fully qualify value, eg:
+// resolveScopePrefix("Class::NestedClass::Enum::Value1", "Enum::Value1")
+// -> "Class::NestedClass::")
+static QString resolveScopePrefix(const QStringList &scopeList, const QString &value)
+{
QString name;
- QStringList parts = scope->qualifiedCppName().split(QLatin1String("::"), QString::SkipEmptyParts);
- for(int i = (parts.size() - 1) ; i >= 0; i--) {
- if (!value.startsWith(parts[i] + QLatin1String("::")))
- name = parts[i] + QLatin1String("::") + name;
- else
+ for (int i = scopeList.size() - 1 ; i >= 0; --i) {
+ const QString prefix = scopeList.at(i) + QLatin1String("::");
+ if (value.startsWith(prefix))
name.clear();
+ else
+ name.prepend(prefix);
}
-
return name;
}
+
+static inline QStringList splitClassScope(const AbstractMetaClass *scope)
+{
+ return scope->qualifiedCppName().split(QLatin1String("::"), QString::SkipEmptyParts);
+}
+
+static QString resolveScopePrefix(const AbstractMetaClass *scope, const QString &value)
+{
+ return scope
+ ? resolveScopePrefix(splitClassScope(scope), value)
+ : QString();
+}
+
+static QString resolveScopePrefix(const AbstractMetaEnum *metaEnum,
+ const QString &value)
+{
+ QStringList parts;
+ if (const AbstractMetaClass *scope = metaEnum->enclosingClass())
+ parts.append(splitClassScope(scope));
+ // Fully qualify the value which is required for C++ 11 enum classes.
+ if (!metaEnum->isAnonymous())
+ parts.append(metaEnum->name());
+ return resolveScopePrefix(parts, value);
+}
+
ShibokenGenerator::ShibokenGenerator() : Generator()
{
if (m_pythonPrimitiveTypeName.isEmpty())
@@ -87,10 +117,10 @@ ShibokenGenerator::ShibokenGenerator() : Generator()
m_typeSystemConvName[TypeSystemIsConvertibleFunction] = QLatin1String("isConvertible");
m_typeSystemConvName[TypeSystemToCppFunction] = QLatin1String("toCpp");
m_typeSystemConvName[TypeSystemToPythonFunction] = QLatin1String("toPython");
- m_typeSystemConvRegEx[TypeSystemCheckFunction] = QRegExp(QLatin1String(CHECKTYPE_REGEX));
- m_typeSystemConvRegEx[TypeSystemIsConvertibleFunction] = QRegExp(QLatin1String(ISCONVERTIBLE_REGEX));
- m_typeSystemConvRegEx[TypeSystemToPythonFunction] = QRegExp(QLatin1String(CONVERTTOPYTHON_REGEX));
- m_typeSystemConvRegEx[TypeSystemToCppFunction] = QRegExp(QLatin1String(CONVERTTOCPP_REGEX));
+ m_typeSystemConvRegEx[TypeSystemCheckFunction] = QRegularExpression(QLatin1String(CHECKTYPE_REGEX));
+ m_typeSystemConvRegEx[TypeSystemIsConvertibleFunction] = QRegularExpression(QLatin1String(ISCONVERTIBLE_REGEX));
+ m_typeSystemConvRegEx[TypeSystemToPythonFunction] = QRegularExpression(QLatin1String(CONVERTTOPYTHON_REGEX));
+ m_typeSystemConvRegEx[TypeSystemToCppFunction] = QRegularExpression(QLatin1String(CONVERTTOCPP_REGEX));
}
ShibokenGenerator::~ShibokenGenerator()
@@ -115,36 +145,34 @@ void ShibokenGenerator::initPrimitiveTypesCorrespondences()
// PyBool
m_pythonPrimitiveTypeName.insert(QLatin1String("bool"), QLatin1String("PyBool"));
+ const char *charTypes[] = {
+ "char", "signed char", "unsigned char"
+ };
+ for (const char *charType : charTypes)
+ m_pythonPrimitiveTypeName.insert(QLatin1String(charType), QStringLiteral("SbkChar"));
+
// PyInt
- m_pythonPrimitiveTypeName.insert(QLatin1String("char"), QLatin1String("SbkChar"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("signed char"), QLatin1String("SbkChar"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("unsigned char"), QLatin1String("SbkChar"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("int"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("signed int"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("uint"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("unsigned int"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("short"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("ushort"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("signed short"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("signed short int"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("unsigned short"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("unsigned short int"), QLatin1String("PyInt"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("long"), QLatin1String("PyInt"));
+ const char *intTypes[] = {
+ "int", "signed int", "uint", "unsigned int",
+ "short", "ushort", "signed short", "signed short int",
+ "unsigned short", "unsigned short", "unsigned short int",
+ "long"
+ };
+ for (const char *intType : intTypes)
+ m_pythonPrimitiveTypeName.insert(QLatin1String(intType), QStringLiteral("PyInt"));
// PyFloat
m_pythonPrimitiveTypeName.insert(QLatin1String("double"), QLatin1String("PyFloat"));
m_pythonPrimitiveTypeName.insert(QLatin1String("float"), QLatin1String("PyFloat"));
// PyLong
- m_pythonPrimitiveTypeName.insert(QLatin1String("unsigned long"), QLatin1String("PyLong"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("signed long"), QLatin1String("PyLong"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("ulong"), QLatin1String("PyLong"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("unsigned long int"), QLatin1String("PyLong"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("long long"), QLatin1String("PyLong"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("__int64"), QLatin1String("PyLong"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("unsigned long long"), QLatin1String("PyLong"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("unsigned __int64"), QLatin1String("PyLong"));
- m_pythonPrimitiveTypeName.insert(QLatin1String("size_t"), QLatin1String("PyLong"));
+ const char *longTypes[] = {
+ "unsigned long", "signed long", "ulong", "unsigned long int",
+ "long long", "__int64",
+ "unsigned long long", "unsigned __int64", "size_t"
+ };
+ for (const char *longType : longTypes)
+ m_pythonPrimitiveTypeName.insert(QLatin1String(longType), QStringLiteral("PyLong"));
// Python operators
m_pythonOperators.clear();
@@ -237,13 +265,16 @@ QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType*
bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass* metaClass) const
{
+ if (metaClass->isNamespace() || (metaClass->attributes() & AbstractMetaAttributes::FinalCppClass))
+ return false;
bool result = metaClass->isPolymorphic() || metaClass->hasVirtualDestructor();
if (avoidProtectedHack()) {
result = result || metaClass->hasProtectedFields() || metaClass->hasProtectedDestructor();
if (!result && metaClass->hasProtectedFunctions()) {
int protectedFunctions = 0;
int protectedOperators = 0;
- foreach (const AbstractMetaFunction* func, metaClass->functions()) {
+ const AbstractMetaFunctionList &funcs = metaClass->functions();
+ for (const AbstractMetaFunction *func : funcs) {
if (!func->isProtected() || func->isSignal() || func->isModifiedRemoved())
continue;
else if (func->isOperatorOverload())
@@ -256,7 +287,7 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass* metaCl
} else {
result = result && !metaClass->hasPrivateDestructor();
}
- return result && !metaClass->isNamespace();
+ return result;
}
void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList& enumList, const AbstractMetaClass* metaClass)
@@ -265,7 +296,8 @@ void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumLi
return;
if (metaClass->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass) {
- foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) {
+ const AbstractMetaEnumList &enums = metaClass->enums();
+ for (const AbstractMetaEnum *metaEnum : enums) {
if (metaEnum->isPrivate() || metaEnum->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass)
continue;
if (!enumList.contains(const_cast<AbstractMetaEnum*>(metaEnum)))
@@ -409,32 +441,91 @@ static QString cpythonEnumFlagsName(QString moduleName, QString qualifiedCppName
return result;
}
+// Return the scope for fully qualifying the enumeration including trailing "::".
static QString searchForEnumScope(const AbstractMetaClass* metaClass, const QString& value)
{
- QString enumValueName = value.trimmed();
-
if (!metaClass)
return QString();
-
- foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) {
- foreach (const AbstractMetaEnumValue* enumValue, metaEnum->values()) {
- if (enumValueName == enumValue->name())
- return metaClass->qualifiedCppName();
- }
+ const AbstractMetaEnumList &enums = metaClass->enums();
+ for (const AbstractMetaEnum *metaEnum : enums) {
+ if (metaEnum->findEnumValue(value))
+ return resolveScopePrefix(metaEnum, value);
}
// PYSIDE-331: We need to also search the base classes.
- QString ret = searchForEnumScope(metaClass->enclosingClass(), enumValueName);
+ QString ret = searchForEnumScope(metaClass->enclosingClass(), value);
if (ret.isEmpty())
- ret = searchForEnumScope(metaClass->baseClass(), enumValueName);
+ ret = searchForEnumScope(metaClass->baseClass(), value);
return ret;
}
+// Handle QFlags<> for guessScopeForDefaultValue()
+QString ShibokenGenerator::guessScopeForDefaultFlagsValue(const AbstractMetaFunction *func,
+ const AbstractMetaArgument *arg,
+ const QString &value) const
+{
+ // Numeric values -> "Options(42)"
+ static const QRegularExpression numberRegEx(QStringLiteral("^\\d+$")); // Numbers to flags
+ Q_ASSERT(numberRegEx.isValid());
+ if (numberRegEx.match(value).hasMatch()) {
+ QString typeName = translateTypeForWrapperMethod(arg->type(), func->implementingClass());
+ if (arg->type()->isConstant())
+ typeName.remove(0, sizeof("const ") / sizeof(char) - 1);
+ switch (arg->type()->referenceType()) {
+ case NoReference:
+ break;
+ case LValueReference:
+ typeName.chop(1);
+ break;
+ case RValueReference:
+ typeName.chop(2);
+ break;
+ }
+ return typeName + QLatin1Char('(') + value + QLatin1Char(')');
+ }
+
+ // "Options(Option1 | Option2)" -> "Options(Class::Enum::Option1 | Class::Enum::Option2)"
+ static const QRegularExpression enumCombinationRegEx(QStringLiteral("^([A-Za-z_][\\w:]*)\\(([^,\\(\\)]*)\\)$")); // FlagName(EnumItem|EnumItem|...)
+ Q_ASSERT(enumCombinationRegEx.isValid());
+ const QRegularExpressionMatch match = enumCombinationRegEx.match(value);
+ if (match.hasMatch()) {
+ const QString expression = match.captured(2).trimmed();
+ if (expression.isEmpty())
+ return value;
+ const QStringList enumItems = expression.split(QLatin1Char('|'));
+ const QString scope = searchForEnumScope(func->implementingClass(),
+ enumItems.constFirst().trimmed());
+ if (scope.isEmpty())
+ return value;
+ QString result;
+ QTextStream str(&result);
+ str << match.captured(1) << '('; // Flag name
+ for (int i = 0, size = enumItems.size(); i < size; ++i) {
+ if (i)
+ str << '|';
+ str << scope << enumItems.at(i).trimmed();
+ }
+ str << ')';
+ return result;
+ }
+ // A single flag "Option1" -> "Class::Enum::Option1"
+ return searchForEnumScope(func->implementingClass(), value) + value;
+}
+
/*
* This function uses some heuristics to find out the scope for a given
- * argument default value. New situations may arise in the future and
+ * argument default value since they must be fully qualified when used outside the class:
+ * class A {
+ * enum Enum { e1, e1 };
+ * void foo(Enum e = e1);
+ * }
+ * should be qualified to:
+ * A::Enum cppArg0 = A::Enum::e1;
+ *
+ * New situations may arise in the future and
* this method should be updated, do it with care.
*/
-QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction* func, const AbstractMetaArgument* arg)
+QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction *func,
+ const AbstractMetaArgument *arg) const
{
QString value = getDefaultValue(func, arg);
@@ -444,64 +535,35 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction*
if (isPointer(arg->type()))
return value;
- static QRegExp enumValueRegEx(QLatin1String("^([A-Za-z_]\\w*)?$"));
- QString prefix;
- QString suffix;
+ static const QRegularExpression enumValueRegEx(QStringLiteral("^([A-Za-z_]\\w*)?$"));
+ Q_ASSERT(enumValueRegEx.isValid());
+ // Do not qualify macros by class name, eg QSGGeometry(..., int t = GL_UNSIGNED_SHORT);
+ static const QRegularExpression macroRegEx(QStringLiteral("^[A-Z_][A-Z0-9_]*$"));
+ Q_ASSERT(macroRegEx.isValid());
+ if (arg->type()->isPrimitive() && macroRegEx.match(value).hasMatch())
+ return value;
+ QString prefix;
if (arg->type()->isEnum()) {
- const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(arg->type());
- if (metaEnum)
- prefix = resolveScopePrefix(metaEnum->enclosingClass(), value);
+ if (const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(arg->type()))
+ prefix = resolveScopePrefix(metaEnum, value);
} else if (arg->type()->isFlags()) {
- static QRegExp numberRegEx(QLatin1String("^\\d+$")); // Numbers to flags
- if (numberRegEx.exactMatch(value)) {
- QString typeName = translateTypeForWrapperMethod(arg->type(), func->implementingClass());
- if (arg->type()->isConstant())
- typeName.remove(0, sizeof("const ") / sizeof(char) - 1);
- switch (arg->type()->referenceType()) {
- case NoReference:
- break;
- case LValueReference:
- typeName.chop(1);
- break;
- case RValueReference:
- typeName.chop(2);
- break;
- }
- prefix = typeName + QLatin1Char('(');
- suffix = QLatin1Char(')');
- }
-
- static QRegExp enumCombinationRegEx(QLatin1String("^([A-Za-z_][\\w:]*)\\(([^,\\(\\)]*)\\)$")); // FlagName(EnumItem|EnumItem|...)
- if (prefix.isEmpty() && enumCombinationRegEx.indexIn(value) != -1) {
- QString flagName = enumCombinationRegEx.cap(1);
- QStringList enumItems = enumCombinationRegEx.cap(2).split(QLatin1Char('|'));
- QString scope = searchForEnumScope(func->implementingClass(), enumItems.first());
- if (!scope.isEmpty())
- scope.append(QLatin1String("::"));
-
- QStringList fixedEnumItems;
- foreach (const QString& enumItem, enumItems)
- fixedEnumItems << QString(scope + enumItem);
-
- if (!fixedEnumItems.isEmpty()) {
- prefix = flagName + QLatin1Char('(');
- value = fixedEnumItems.join(QLatin1Char('|'));
- suffix = QLatin1Char(')');
- }
- }
+ value = guessScopeForDefaultFlagsValue(func, arg, value);
} else if (arg->type()->typeEntry()->isValue()) {
const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes(), arg->type()->typeEntry());
- if (enumValueRegEx.exactMatch(value)&& value != QLatin1String("NULL"))
+ if (enumValueRegEx.match(value).hasMatch() && value != QLatin1String("NULL"))
prefix = resolveScopePrefix(metaClass, value);
} else if (arg->type()->isPrimitive() && arg->type()->name() == QLatin1String("int")) {
- if (enumValueRegEx.exactMatch(value) && func->implementingClass())
+ if (enumValueRegEx.match(value).hasMatch() && func->implementingClass())
prefix = resolveScopePrefix(func->implementingClass(), value);
} else if(arg->type()->isPrimitive()) {
- static QRegExp unknowArgumentRegEx(QLatin1String("^(?:[A-Za-z_][\\w:]*\\()?([A-Za-z_]\\w*)(?:\\))?$")); // [PrimitiveType(] DESIREDNAME [)]
- if (unknowArgumentRegEx.indexIn(value) != -1 && func->implementingClass()) {
- foreach (const AbstractMetaField* field, func->implementingClass()->fields()) {
- if (unknowArgumentRegEx.cap(1).trimmed() == field->name()) {
+ static const QRegularExpression unknowArgumentRegEx(QStringLiteral("^(?:[A-Za-z_][\\w:]*\\()?([A-Za-z_]\\w*)(?:\\))?$")); // [PrimitiveType(] DESIREDNAME [)]
+ Q_ASSERT(unknowArgumentRegEx.isValid());
+ const QRegularExpressionMatch match = unknowArgumentRegEx.match(value);
+ if (match.hasMatch() && func->implementingClass()) {
+ const AbstractMetaFieldList &fields = func->implementingClass()->fields();
+ for (const AbstractMetaField *field : fields) {
+ if (match.captured(1).trimmed() == field->name()) {
QString fieldName = field->name();
if (field->isStatic()) {
prefix = resolveScopePrefix(func->implementingClass(), value);
@@ -510,7 +572,7 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction*
} else {
fieldName.prepend(QLatin1String(CPP_SELF_VAR "->"));
}
- value.replace(unknowArgumentRegEx.cap(1), fieldName);
+ value.replace(match.captured(1), fieldName);
break;
}
}
@@ -519,9 +581,6 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction*
if (!prefix.isEmpty())
value.prepend(prefix);
- if (!suffix.isEmpty())
- value.append(suffix);
-
return value;
}
@@ -622,8 +681,9 @@ bool ShibokenGenerator::shouldRejectNullPointerArgument(const AbstractMetaFuncti
return false;
if (func->argumentRemoved(argIndex + 1))
return false;
- foreach (const FunctionModification &funcMod, func->modifications()) {
- foreach (const ArgumentModification &argMod, funcMod.argument_mods) {
+ const FunctionModificationList &mods = func->modifications();
+ for (const FunctionModification &funcMod : mods) {
+ for (const ArgumentModification &argMod : funcMod.argument_mods) {
if (argMod.index == argIndex + 1 && argMod.noNullPointers)
return true;
}
@@ -635,7 +695,8 @@ QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction* func,
{
QString result;
const char objType = (incRef ? 'O' : 'N');
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
if (func->argumentRemoved(arg->argumentIndex() + 1))
continue;
@@ -758,6 +819,13 @@ QString ShibokenGenerator::converterObject(const AbstractMetaType* type)
return QLatin1String("Shiboken::Conversions::PrimitiveTypeConverter<const char*>()");
if (isVoidPointer(type))
return QLatin1String("Shiboken::Conversions::PrimitiveTypeConverter<void*>()");
+ const AbstractMetaTypeCList nestedArrayTypes = type->nestedArrayTypes();
+ if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast()->isCppPrimitive()) {
+ return QStringLiteral("Shiboken::Conversions::ArrayTypeConverter<")
+ + nestedArrayTypes.constLast()->minimalSignature()
+ + QLatin1String(">(") + QString::number(nestedArrayTypes.size())
+ + QLatin1Char(')');
+ }
if (type->typeEntry()->isContainer()) {
return convertersVariableName(type->typeEntry()->targetLangPackage())
+ QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']');
@@ -983,10 +1051,12 @@ bool ShibokenGenerator::isValueTypeWithCopyConstructorOnly(const AbstractMetaCla
{
if (!metaClass || !metaClass->typeEntry()->isValue())
return false;
+ if ((metaClass->attributes() & AbstractMetaAttributes::HasRejectedConstructor) != 0)
+ return false;
AbstractMetaFunctionList ctors = metaClass->queryFunctions(AbstractMetaClass::Constructors);
if (ctors.count() != 1)
return false;
- return ctors.first()->functionType() == AbstractMetaFunction::CopyConstructorFunction;
+ return ctors.constFirst()->functionType() == AbstractMetaFunction::CopyConstructorFunction;
}
bool ShibokenGenerator::isValueTypeWithCopyConstructorOnly(const TypeEntry* type) const
@@ -1054,7 +1124,8 @@ bool ShibokenGenerator::shouldDereferenceAbstractMetaTypePointer(const AbstractM
bool ShibokenGenerator::visibilityModifiedToPrivate(const AbstractMetaFunction* func)
{
- foreach (const FunctionModification &mod, func->modifications()) {
+ const FunctionModificationList &mods = func->modifications();
+ for (const FunctionModification &mod : mods) {
if (mod.modifiers & Modification::Private)
return true;
}
@@ -1089,7 +1160,7 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType
|| type == ContainerTypeEntry::StackContainer
|| type == ContainerTypeEntry::SetContainer
|| type == ContainerTypeEntry::QueueContainer) {
- const AbstractMetaType* type = metaType->instantiations().first();
+ const AbstractMetaType* type = metaType->instantiations().constFirst();
if (isPointerToWrapperType(type)) {
typeCheck += QString::fromLatin1("checkSequenceTypes(%1, ").arg(cpythonTypeNameExt(type));
} else if (isWrapperType(type)) {
@@ -1105,8 +1176,8 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType
|| type == ContainerTypeEntry::MultiHashContainer
|| type == ContainerTypeEntry::PairContainer) {
QString pyType = (type == ContainerTypeEntry::PairContainer) ? QLatin1String("Pair") : QLatin1String("Dict");
- const AbstractMetaType* firstType = metaType->instantiations().first();
- const AbstractMetaType* secondType = metaType->instantiations().last();
+ const AbstractMetaType* firstType = metaType->instantiations().constFirst();
+ const AbstractMetaType* secondType = metaType->instantiations().constLast();
if (isPointerToWrapperType(firstType) && isPointerToWrapperType(secondType)) {
typeCheck += QString::fromLatin1("check%1Types(%2, %3, ").arg(pyType)
.arg(cpythonTypeNameExt(firstType), cpythonTypeNameExt(secondType));
@@ -1208,8 +1279,8 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType*
return customCheck;
}
+ QString result = QLatin1String("Shiboken::Conversions::");
if (isWrapperType(metaType)) {
- QString result = QLatin1String("Shiboken::Conversions::");
if (isPointer(metaType) || isValueTypeWithCopyConstructorOnly(metaType))
result += QLatin1String("isPythonToCppPointerConvertible");
else if (metaType->referenceType() == LValueReference)
@@ -1220,8 +1291,18 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType*
+ cpythonTypeNameExt(metaType) + QLatin1String("), ");
return result;
}
- return QStringLiteral("Shiboken::Conversions::isPythonToCppConvertible(%1, ")
- .arg(converterObject(metaType));
+ result += QLatin1String("isPythonToCppConvertible(") + converterObject(metaType);
+ // Write out array sizes if known
+ const AbstractMetaTypeCList nestedArrayTypes = metaType->nestedArrayTypes();
+ if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast()->isCppPrimitive()) {
+ const int dim1 = metaType->arrayElementCount();
+ const int dim2 = nestedArrayTypes.constFirst()->isArray()
+ ? nestedArrayTypes.constFirst()->arrayElementCount() : -1;
+ result += QLatin1String(", ") + QString::number(dim1)
+ + QLatin1String(", ") + QString::number(dim2);
+ }
+ result += QLatin1String(", ");
+ return result;
}
QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaArgument *metaArg, bool genericNumberType)
@@ -1306,12 +1387,14 @@ QString ShibokenGenerator::argumentString(const AbstractMetaFunction *func,
arg = modified_type.replace(QLatin1Char('$'), QLatin1Char('.'));
if (!(options & Generator::SkipName)) {
- arg += QLatin1Char(' ');
- arg += argument->name();
+ // "int a", "int a[]"
+ const int arrayPos = arg.indexOf(QLatin1Char('['));
+ if (arrayPos != -1)
+ arg.insert(arrayPos, QLatin1Char(' ') + argument->name());
+ else
+ arg.append(QLatin1Char(' ') + argument->name());
}
- QList<ReferenceCount> referenceCounts;
- referenceCounts = func->referenceCounts(func->implementingClass(), argument->argumentIndex() + 1);
if ((options & Generator::SkipDefaultValues) != Generator::SkipDefaultValues &&
!argument->originalDefaultValueExpression().isEmpty())
{
@@ -1445,7 +1528,8 @@ void ShibokenGenerator::writeUnusedVariableCast(QTextStream& s, const QString& v
AbstractMetaFunctionList ShibokenGenerator::filterFunctions(const AbstractMetaClass* metaClass)
{
AbstractMetaFunctionList result;
- foreach (AbstractMetaFunction *func, metaClass->functions()) {
+ const AbstractMetaFunctionList &funcs = metaClass->functions();
+ for (AbstractMetaFunction *func : funcs) {
if (func->isSignal() || func->isDestructor() || func->usesRValueReferences()
|| (func->isModifiedRemoved() && !func->isAbstract()
&& (!avoidProtectedHack() || !func->isProtected())))
@@ -1458,11 +1542,13 @@ AbstractMetaFunctionList ShibokenGenerator::filterFunctions(const AbstractMetaCl
ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverters() const
{
ExtendedConverterData extConvs;
- foreach (const AbstractMetaClass* metaClass, classes()) {
+ const AbstractMetaClassList &classList = classes();
+ for (const AbstractMetaClass *metaClass : classList) {
// Use only the classes for the current module.
if (!shouldGenerate(metaClass))
continue;
- foreach (AbstractMetaFunction* convOp, metaClass->operatorOverloads(AbstractMetaClass::ConversionOp)) {
+ const AbstractMetaFunctionList &overloads = metaClass->operatorOverloads(AbstractMetaClass::ConversionOp);
+ for (AbstractMetaFunction *convOp : overloads) {
// Get only the conversion operators that return a type from another module,
// that are value-types and were not removed in the type system.
const TypeEntry* convType = convOp->type()->typeEntry();
@@ -1476,10 +1562,11 @@ ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverter
return extConvs;
}
-QList<const CustomConversion*> ShibokenGenerator::getPrimitiveCustomConversions()
+QVector<const CustomConversion *> ShibokenGenerator::getPrimitiveCustomConversions()
{
- QList<const CustomConversion*> conversions;
- foreach (const PrimitiveTypeEntry* type, primitiveTypes()) {
+ QVector<const CustomConversion*> conversions;
+ const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
+ for (const PrimitiveTypeEntry *type : primitiveTypeList) {
if (!shouldGenerateTypeEntry(type) || !isUserPrimitive(type) || !type->customConversion())
continue;
@@ -1522,7 +1609,7 @@ QString ShibokenGenerator::getCodeSnippets(const CodeSnipList& codeSnips,
{
QString code;
QTextStream c(&code);
- foreach (const CodeSnip &snip, codeSnips) {
+ for (const CodeSnip &snip : codeSnips) {
if ((position != TypeSystem::CodeSnipPositionAny && snip.position != position) || !(snip.language & language))
continue;
QString snipCode;
@@ -1623,6 +1710,17 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
s << INDENT << "// End of code injection" << endl;
}
+static QString msgWrongIndex(const char *varName, const QString &capture, const AbstractMetaFunction *func)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Wrong index for " << varName << " variable (" << capture << ") on ";
+ if (const AbstractMetaClass *c = func->implementingClass())
+ str << c->name() << "::";
+ str << func->signature();
+ return result;
+}
+
void ShibokenGenerator::writeCodeSnips(QTextStream& s,
const CodeSnipList& codeSnips,
TypeSystem::CodeSnipPosition position,
@@ -1647,15 +1745,18 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
// Replace %PYARG_# variables.
code.replace(QLatin1String("%PYARG_0"), QLatin1String(PYTHON_RETURN_VAR));
- static QRegExp pyArgsRegex(QLatin1String("%PYARG_(\\d+)"));
+ static const QRegularExpression pyArgsRegex(QStringLiteral("%PYARG_(\\d+)"));
+ Q_ASSERT(pyArgsRegex.isValid());
if (language == TypeSystem::TargetLangCode) {
if (usePyArgs) {
code.replace(pyArgsRegex, QLatin1String(PYTHON_ARGS"[\\1-1]"));
} else {
- static QRegExp pyArgsRegexCheck(QLatin1String("%PYARG_([2-9]+)"));
- if (pyArgsRegexCheck.indexIn(code) != -1) {
+ static const QRegularExpression pyArgsRegexCheck(QStringLiteral("%PYARG_([2-9]+)"));
+ Q_ASSERT(pyArgsRegexCheck.isValid());
+ const QRegularExpressionMatch match = pyArgsRegexCheck.match(code);
+ if (match.hasMatch()) {
qCWarning(lcShiboken).noquote().nospace()
- << "Wrong index for %PYARG variable (" << pyArgsRegexCheck.cap(1) << ") on " << func->signature();
+ << msgWrongIndex("%PYARG", match.captured(1), func);
return;
}
code.replace(QLatin1String("%PYARG_1"), QLatin1String(PYTHON_ARG));
@@ -1663,25 +1764,27 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
} else {
// Replaces the simplest case of attribution to a
// Python argument on the binding virtual method.
- static QRegExp pyArgsAttributionRegex(QLatin1String("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)"));
+ static const QRegularExpression pyArgsAttributionRegex(QStringLiteral("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)"));
+ Q_ASSERT(pyArgsAttributionRegex.isValid());
code.replace(pyArgsAttributionRegex, QLatin1String("PyTuple_SET_ITEM(" PYTHON_ARGS ", \\1-1, \\2)"));
code.replace(pyArgsRegex, QLatin1String("PyTuple_GET_ITEM(" PYTHON_ARGS ", \\1-1)"));
}
// Replace %ARG#_TYPE variables.
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
QString argTypeVar = QStringLiteral("%ARG%1_TYPE").arg(arg->argumentIndex() + 1);
QString argTypeVal = arg->type()->cppSignature();
code.replace(argTypeVar, argTypeVal);
}
- int pos = 0;
- static QRegExp cppArgTypeRegexCheck(QLatin1String("%ARG(\\d+)_TYPE"));
- while ((pos = cppArgTypeRegexCheck.indexIn(code, pos)) != -1) {
+ static const QRegularExpression cppArgTypeRegexCheck(QStringLiteral("%ARG(\\d+)_TYPE"));
+ Q_ASSERT(cppArgTypeRegexCheck.isValid());
+ QRegularExpressionMatchIterator rit = cppArgTypeRegexCheck.globalMatch(code);
+ while (rit.hasNext()) {
+ QRegularExpressionMatch match = rit.next();
qCWarning(lcShiboken).noquote().nospace()
- << "Wrong index for %ARG#_TYPE variable (" << cppArgTypeRegexCheck.cap(1)
- << ") on " << func->signature();
- pos += cppArgTypeRegexCheck.matchedLength();
+ << msgWrongIndex("%ARG#_TYPE", match.captured(1), func);
}
// Replace template variable for return variable name.
@@ -1762,17 +1865,17 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
// Replaces template %ARGUMENT_NAMES and %# variables by argument variables and values.
// Replaces template variables %# for individual arguments.
- ArgumentVarReplacementList argReplacements = getArgumentReplacement(func, usePyArgs, language, lastArg);
+ const ArgumentVarReplacementList &argReplacements = getArgumentReplacement(func, usePyArgs, language, lastArg);
QStringList args;
- foreach (const ArgumentVarReplacementPair &pair, argReplacements) {
+ for (const ArgumentVarReplacementPair &pair : argReplacements) {
if (pair.second.startsWith(QLatin1String(CPP_ARG_REMOVED)))
continue;
args << pair.second;
}
code.replace(QLatin1String("%ARGUMENT_NAMES"), args.join(QLatin1String(", ")));
- foreach (const ArgumentVarReplacementPair &pair, argReplacements) {
+ for (const ArgumentVarReplacementPair &pair : argReplacements) {
const AbstractMetaArgument* arg = pair.first;
int idx = arg->argumentIndex() + 1;
AbstractMetaType* type = arg->type();
@@ -1789,7 +1892,7 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
if (type->referenceType() == LValueReference || isPointer(type))
code.replace(QString::fromLatin1("%%1.").arg(idx), replacement + QLatin1String("->"));
}
- code.replace(QRegExp(QString::fromLatin1("%%1\\b").arg(idx)), pair.second);
+ code.replace(placeHolderRegex(idx), pair.second);
}
if (language == TypeSystem::NativeCode) {
@@ -1811,7 +1914,8 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
// dispatcher.
bool hasProtectedOverload = false;
if (func->isUserAdded()) {
- foreach (const AbstractMetaFunction* f, getFunctionOverloads(func->ownerClass(), func->name()))
+ const AbstractMetaFunctionList &funcs = getFunctionOverloads(func->ownerClass(), func->name());
+ for (const AbstractMetaFunction *f : funcs)
hasProtectedOverload |= f->isProtected();
}
@@ -1842,8 +1946,9 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
// and false if it is a variable.
static bool isVariable(const QString& code)
{
- static QRegExp expr(QLatin1String("\\s*\\*?\\s*[A-Za-z_][A-Za-z_0-9.]*\\s*(?:\\[[^\\[]+\\])*"));
- return expr.exactMatch(code.trimmed());
+ static const QRegularExpression expr(QStringLiteral("^\\s*\\*?\\s*[A-Za-z_][A-Za-z_0-9.]*\\s*(?:\\[[^\\[]+\\])*$"));
+ Q_ASSERT(expr.isValid());
+ return expr.match(code.trimmed()).hasMatch();
}
// A miniature normalizer that puts a type string into a format
@@ -1893,14 +1998,13 @@ static QString getConverterTypeSystemVariableArgument(const QString& code, int p
typedef QPair<QString, QString> StringPair;
void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable, QString& code)
{
- QRegExp& regex = m_typeSystemConvRegEx[converterVariable];
- int pos = 0;
- QList<StringPair> replacements;
- while ((pos = regex.indexIn(code, pos)) != -1) {
- pos += regex.matchedLength();
- QStringList list = regex.capturedTexts();
- QString conversionString = list.first();
- QString conversionTypeName = list.last();
+ QVector<StringPair> replacements;
+ QRegularExpressionMatchIterator rit = m_typeSystemConvRegEx[converterVariable].globalMatch(code);
+ while (rit.hasNext()) {
+ const QRegularExpressionMatch match = rit.next();
+ const QStringList list = match.capturedTexts();
+ QString conversionString = list.constFirst();
+ QString conversionTypeName = list.constLast();
const AbstractMetaType* conversionType = buildAbstractMetaTypeFromString(conversionTypeName);
if (!conversionType) {
qFatal(qPrintable(QString::fromLatin1("Could not find type '%1' for use in '%2' conversion. "
@@ -1912,14 +2016,14 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
QTextStream c(&conversion);
switch (converterVariable) {
case TypeSystemToCppFunction: {
- int end = pos - list.first().count();
+ int end = match.capturedStart();
int start = end;
while (start > 0 && code.at(start) != QLatin1Char('\n'))
--start;
while (code.at(start).isSpace())
++start;
QString varType = code.mid(start, end - start);
- conversionString = varType + list.first();
+ conversionString = varType + list.constFirst();
varType = miniNormalizer(varType);
QString varName = list.at(1).trimmed();
if (!varType.isEmpty()) {
@@ -1941,7 +2045,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
} else {
prefix = QLatin1Char('&');
}
- QString arg = getConverterTypeSystemVariableArgument(code, pos);
+ QString arg = getConverterTypeSystemVariableArgument(code, match.capturedEnd());
conversionString += arg;
c << arg << ", " << prefix << '(' << varName << ')';
break;
@@ -1961,7 +2065,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
if (conversion.isEmpty())
conversion = cpythonToPythonConversionFunction(conversionType);
default: {
- QString arg = getConverterTypeSystemVariableArgument(code, pos);
+ QString arg = getConverterTypeSystemVariableArgument(code, match.capturedEnd());
conversionString += arg;
if (converterVariable == TypeSystemToPythonFunction && !isVariable(arg)) {
qFatal(qPrintable(QString::fromLatin1("Only variables are acceptable as argument to %%CONVERTTOPYTHON type system variable on code snippet: '%1'")
@@ -1977,14 +2081,14 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
}
replacements.append(qMakePair(conversionString, conversion));
}
- foreach (const StringPair &rep, replacements)
+ for (const StringPair &rep : qAsConst(replacements))
code.replace(rep.first, rep.second);
}
bool ShibokenGenerator::injectedCodeUsesCppSelf(const AbstractMetaFunction* func)
{
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode);
- foreach (const CodeSnip &snip, snips) {
+ for (const CodeSnip &snip : qAsConst(snips)) {
if (snip.code().contains(QLatin1String("%CPPSELF")))
return true;
}
@@ -1994,7 +2098,7 @@ bool ShibokenGenerator::injectedCodeUsesCppSelf(const AbstractMetaFunction* func
bool ShibokenGenerator::injectedCodeUsesPySelf(const AbstractMetaFunction* func)
{
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::NativeCode);
- foreach (const CodeSnip &snip, snips) {
+ for (const CodeSnip &snip : qAsConst(snips)) {
if (snip.code().contains(QLatin1String("%PYSELF")))
return true;
}
@@ -2010,7 +2114,7 @@ bool ShibokenGenerator::injectedCodeCallsCppFunction(const AbstractMetaFunction*
wrappedCtorCall = QStringLiteral("new %1(").arg(wrapperName(func->ownerClass()));
}
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode);
- foreach (const CodeSnip &snip, snips) {
+ for (const CodeSnip &snip : qAsConst(snips)) {
if (snip.code().contains(QLatin1String("%FUNCTION_NAME(")) || snip.code().contains(funcCall)
|| (func->isConstructor()
&& ((func->ownerClass()->isPolymorphic() && snip.code().contains(wrappedCtorCall))
@@ -2023,10 +2127,11 @@ bool ShibokenGenerator::injectedCodeCallsCppFunction(const AbstractMetaFunction*
bool ShibokenGenerator::injectedCodeCallsPythonOverride(const AbstractMetaFunction* func)
{
- static QRegExp overrideCallRegexCheck(QLatin1String("PyObject_Call\\s*\\(\\s*%PYTHON_METHOD_OVERRIDE\\s*,"));
+ static const QRegularExpression overrideCallRegexCheck(QStringLiteral("PyObject_Call\\s*\\(\\s*%PYTHON_METHOD_OVERRIDE\\s*,"));
+ Q_ASSERT(overrideCallRegexCheck.isValid());
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::NativeCode);
- foreach (const CodeSnip &snip, snips) {
- if (overrideCallRegexCheck.indexIn(snip.code()) != -1)
+ for (const CodeSnip &snip : qAsConst(snips)) {
+ if (snip.code().contains(overrideCallRegexCheck))
return true;
}
return false;
@@ -2034,15 +2139,17 @@ bool ShibokenGenerator::injectedCodeCallsPythonOverride(const AbstractMetaFuncti
bool ShibokenGenerator::injectedCodeHasReturnValueAttribution(const AbstractMetaFunction* func, TypeSystem::Language language)
{
- static QRegExp retValAttributionRegexCheck_native(QLatin1String("%0\\s*=[^=]\\s*.+"));
- static QRegExp retValAttributionRegexCheck_target(QLatin1String("%PYARG_0\\s*=[^=]\\s*.+"));
+ static const QRegularExpression retValAttributionRegexCheck_native(QStringLiteral("%0\\s*=[^=]\\s*.+"));
+ Q_ASSERT(retValAttributionRegexCheck_native.isValid());
+ static const QRegularExpression retValAttributionRegexCheck_target(QStringLiteral("%PYARG_0\\s*=[^=]\\s*.+"));
+ Q_ASSERT(retValAttributionRegexCheck_target.isValid());
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, language);
- foreach (const CodeSnip &snip, snips) {
+ for (const CodeSnip &snip : qAsConst(snips)) {
if (language == TypeSystem::TargetLangCode) {
- if (retValAttributionRegexCheck_target.indexIn(snip.code()) != -1)
+ if (snip.code().contains(retValAttributionRegexCheck_target))
return true;
} else {
- if (retValAttributionRegexCheck_native.indexIn(snip.code()) != -1)
+ if (snip.code().contains(retValAttributionRegexCheck_native))
return true;
}
}
@@ -2052,11 +2159,10 @@ bool ShibokenGenerator::injectedCodeHasReturnValueAttribution(const AbstractMeta
bool ShibokenGenerator::injectedCodeUsesArgument(const AbstractMetaFunction* func, int argumentIndex)
{
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny);
- foreach (const CodeSnip &snip, snips) {
+ const QRegularExpression argRegEx = placeHolderRegex(argumentIndex + 1);
+ for (const CodeSnip &snip : qAsConst(snips)) {
QString code = snip.code();
- if (code.contains(QLatin1String("%ARGUMENT_NAMES")))
- return true;
- if (code.contains(QRegExp(QStringLiteral("%%1\\b").arg(argumentIndex + 1))))
+ if (code.contains(QLatin1String("%ARGUMENT_NAMES")) || code.contains(argRegEx))
return true;
}
return false;
@@ -2083,7 +2189,7 @@ bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* meta
const FunctionGroupMap &functionGroup = getFunctionGroups(metaClass);
for (FunctionGroupMapIt it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
- foreach (AbstractMetaFunction* func, it.value()) {
+ for (AbstractMetaFunction *func : qAsConst(it.value())) {
if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved()
|| func->isPrivate() || func->ownerClass() != func->implementingClass()
|| func->isConstructor() || func->isOperatorOverload())
@@ -2114,7 +2220,7 @@ AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStatic
const FunctionGroupMap &functionGroups = getFunctionGroups(metaClass);
for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
- foreach (AbstractMetaFunction* func, it.value()) {
+ for (AbstractMetaFunction *func : qAsConst(it.value())) {
if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved()
|| func->isPrivate() || func->ownerClass() != func->implementingClass()
|| func->isConstructor() || func->isOperatorOverload())
@@ -2124,7 +2230,7 @@ AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStatic
if (overloads.isEmpty())
continue;
if (OverloadData::hasStaticAndInstanceFunctions(overloads))
- methods.append(overloads.first());
+ methods.append(overloads.constFirst());
}
}
return methods;
@@ -2134,7 +2240,8 @@ AbstractMetaClassList ShibokenGenerator::getBaseClasses(const AbstractMetaClass*
{
AbstractMetaClassList baseClasses;
if (metaClass) {
- foreach (const QString &parent, metaClass->baseClassNames()) {
+ const QStringList &baseClassNames = metaClass->baseClassNames();
+ for (const QString &parent : baseClassNames) {
AbstractMetaClass *clazz = AbstractMetaClass::findClass(classes(), parent);
if (clazz)
baseClasses << clazz;
@@ -2157,7 +2264,7 @@ AbstractMetaClassList ShibokenGenerator::getAllAncestors(const AbstractMetaClass
AbstractMetaClassList result;
if (metaClass) {
AbstractMetaClassList baseClasses = getBaseClasses(metaClass);
- foreach (AbstractMetaClass* base, baseClasses) {
+ for (AbstractMetaClass *base : qAsConst(baseClasses)) {
result.append(base);
result.append(getAllAncestors(base));
}
@@ -2268,7 +2375,7 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ
metaType->setReferenceType(refType);
metaType->setConstant(isConst);
metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern);
- foreach (const QString& instantiation, instantiatedTypes) {
+ for (const QString &instantiation : qAsConst(instantiatedTypes)) {
AbstractMetaType* tmplArgType = buildAbstractMetaTypeFromString(instantiation);
metaType->addInstantiation(tmplArgType);
}
@@ -2303,7 +2410,7 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromAbstractMetaClass(
static void dumpFunction(AbstractMetaFunctionList lst)
{
qDebug() << "DUMP FUNCTIONS: ";
- foreach (AbstractMetaFunction *func, lst)
+ for (AbstractMetaFunction *func : qAsConst(lst))
qDebug() << "*" << func->ownerClass()->name()
<< func->signature()
<< "Private: " << func->isPrivate()
@@ -2331,7 +2438,7 @@ QMap< QString, AbstractMetaFunctionList > ShibokenGenerator::getFunctionGroups(c
AbstractMetaFunctionList lst = scope ? scope->functions() : globalFunctions();
QMap<QString, AbstractMetaFunctionList> results;
- foreach (AbstractMetaFunction* func, lst) {
+ for (AbstractMetaFunction *func : qAsConst(lst)) {
if (isGroupable(func))
results[func->name()].append(func);
}
@@ -2370,7 +2477,7 @@ AbstractMetaFunctionList ShibokenGenerator::getFunctionOverloads(const AbstractM
AbstractMetaFunctionList results;
QSet<QString> seenSignatures;
- foreach (AbstractMetaFunction* func, lst) {
+ for (AbstractMetaFunction *func : qAsConst(lst)) {
if (func->name() != functionName)
continue;
if (isGroupable(func)) {
@@ -2387,9 +2494,10 @@ QPair< int, int > ShibokenGenerator::getMinMaxArguments(const AbstractMetaFuncti
int minArgs = std::numeric_limits<int>::max();
int maxArgs = 0;
- foreach (const AbstractMetaFunction* func, overloads) {
+ for (const AbstractMetaFunction* func : qAsConst(overloads)) {
int numArgs = 0;
- foreach (const AbstractMetaArgument* arg, func->arguments()) {
+ const AbstractMetaArgumentList &arguments = func->arguments();
+ for (const AbstractMetaArgument *arg : arguments) {
if (!func->argumentRemoved(arg->argumentIndex() + 1))
numArgs++;
}
@@ -2399,27 +2507,26 @@ QPair< int, int > ShibokenGenerator::getMinMaxArguments(const AbstractMetaFuncti
return qMakePair(minArgs, maxArgs);
}
-QMap<QString, QString> ShibokenGenerator::options() const
+Generator::OptionDescriptions ShibokenGenerator::options() const
{
- QMap<QString, QString> opts(Generator::options());
- opts.insert(QLatin1String(AVOID_PROTECTED_HACK),
- QLatin1String("Avoid the use of the '#define protected public' hack."));
- opts.insert(QLatin1String(PARENT_CTOR_HEURISTIC),
- QLatin1String("Enable heuristics to detect parent relationship on constructors."));
- opts.insert(QLatin1String(RETURN_VALUE_HEURISTIC),
- QLatin1String("Enable heuristics to detect parent relationship on return values (USE WITH CAUTION!)"));
- opts.insert(QLatin1String(ENABLE_PYSIDE_EXTENSIONS),
- QLatin1String("Enable PySide extensions, such as support for signal/slots, use this if you are creating a binding for a Qt-based library."));
- opts.insert(QLatin1String(DISABLE_VERBOSE_ERROR_MESSAGES),
- QLatin1String("Disable verbose error messages. Turn the python code hard to debug but safe few kB on the generated bindings."));
- opts.insert(QLatin1String(USE_ISNULL_AS_NB_NONZERO),
- QLatin1String("If a class have an isNull()const method, it will be used to compute the value of boolean casts"));
- return opts;
+ return OptionDescriptions()
+ << qMakePair(QLatin1String(AVOID_PROTECTED_HACK),
+ QLatin1String("Avoid the use of the '#define protected public' hack."))
+ << qMakePair(QLatin1String(DISABLE_VERBOSE_ERROR_MESSAGES),
+ QLatin1String("Disable verbose error messages. Turn the python code hard to debug but safe few kB on the generated bindings."))
+ << qMakePair(QLatin1String(PARENT_CTOR_HEURISTIC),
+ QLatin1String("Enable heuristics to detect parent relationship on constructors."))
+ << qMakePair(QLatin1String(ENABLE_PYSIDE_EXTENSIONS),
+ QLatin1String("Enable PySide extensions, such as support for signal/slots, use this if you are creating a binding for a Qt-based library."))
+ << qMakePair(QLatin1String(RETURN_VALUE_HEURISTIC),
+ QLatin1String("Enable heuristics to detect parent relationship on return values (USE WITH CAUTION!)"))
+ << qMakePair(QLatin1String(USE_ISNULL_AS_NB_NONZERO),
+ QLatin1String("If a class have an isNull()const method, it will be used to compute the value of boolean casts"));
}
static void getCode(QStringList& code, const CodeSnipList& codeSnips)
{
- foreach (const CodeSnip& snip, codeSnips)
+ for (const CodeSnip &snip : qAsConst(codeSnips))
code.append(snip.code());
}
@@ -2438,7 +2545,7 @@ static void getCode(QStringList& code, const TypeEntry* type)
if (toCppConversions.isEmpty())
return;
- foreach (CustomConversion::TargetToNativeConversion* toNative, toCppConversions)
+ for (CustomConversion::TargetToNativeConversion *toNative : qAsConst(toCppConversions))
code.append(toNative->conversion());
}
@@ -2453,20 +2560,23 @@ bool ShibokenGenerator::doSetup(const QMap<QString, QString>& args)
TypeDatabase* td = TypeDatabase::instance();
QStringList snips;
- foreach (const PrimitiveTypeEntry* type, primitiveTypes())
+ const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
+ for (const PrimitiveTypeEntry *type : primitiveTypeList)
getCode(snips, type);
- foreach (const ContainerTypeEntry* type, containerTypes())
+ const ContainerTypeEntryList &containerTypeList = containerTypes();
+ for (const ContainerTypeEntry *type : containerTypeList)
getCode(snips, type);
- foreach (const AbstractMetaClass* metaClass, classes())
+ const AbstractMetaClassList &classList = classes();
+ for (const AbstractMetaClass *metaClass : classList)
getCode(snips, metaClass->typeEntry());
getCode(snips, td->findType(packageName()));
const FunctionGroupMap &functionGroups = getFunctionGroups();
for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
- foreach (AbstractMetaFunction* func, it.value())
+ for (AbstractMetaFunction *func : it.value())
getCode(snips, func->injectedCodeSnips());
}
- foreach (const QString& code, snips) {
+ for (const QString &code : qAsConst(snips)) {
collectContainerTypesFromConverterMacros(code, true);
collectContainerTypesFromConverterMacros(code, false);
}
@@ -2536,7 +2646,8 @@ QString ShibokenGenerator::convertersVariableName(const QString& moduleName) con
static QString processInstantiationsVariableName(const AbstractMetaType* type)
{
QString res = QLatin1Char('_') + _fixedCppTypeName(type->typeEntry()->qualifiedCppName()).toUpper();
- foreach (const AbstractMetaType* instantiation, type->instantiations()) {
+ const AbstractMetaTypeList &instantiations = type->instantiations();
+ for (const AbstractMetaType *instantiation : instantiations) {
res += instantiation->isContainer()
? processInstantiationsVariableName(instantiation)
: QLatin1Char('_') + _fixedCppTypeName(instantiation->cppSignature()).toUpper();
@@ -2551,7 +2662,8 @@ QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass* met
return QString();
QString base = _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper();
QString instantiations;
- foreach (const AbstractMetaType* instantiation, metaClass->templateBaseClassInstantiations())
+ const AbstractMetaTypeList &templateBaseClassInstantiations = metaClass->templateBaseClassInstantiations();
+ for (const AbstractMetaType *instantiation : templateBaseClassInstantiations)
instantiations += processInstantiationsVariableName(instantiation);
return QString::fromLatin1("SBK_%1%2_IDX").arg(base, instantiations);
}
@@ -2615,8 +2727,9 @@ QString ShibokenGenerator::getDefaultValue(const AbstractMetaFunction* func, co
return arg->defaultValueExpression();
//Check modifications
- foreach(FunctionModification m, func->modifications()) {
- foreach(ArgumentModification am, m.argument_mods) {
+ const FunctionModificationList &mods = func->modifications();
+ for (const FunctionModification &m : mods) {
+ for (const ArgumentModification &am : m.argument_mods) {
if (am.index == (arg->argumentIndex() + 1))
return am.replacedDefaultExpression;
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index d36962cf1..5ed7f79f6 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -56,6 +56,8 @@
#include "typesystem.h"
+#include <QtCore/QRegularExpression>
+
class DocParser;
class CodeSnip;
class OverloadData;
@@ -132,7 +134,7 @@ public:
void writeArgumentNames(QTextStream &s,
const AbstractMetaFunction* func,
- Options options = NoOption) const;
+ Options options = NoOption) const override;
/**
* Function used to write the fucntion arguments on the class buffer.
@@ -143,32 +145,32 @@ public:
*/
void writeFunctionArguments(QTextStream &s,
const AbstractMetaFunction* func,
- Options options = NoOption) const;
+ Options options = NoOption) const override;
QString functionReturnType(const AbstractMetaFunction* func, Options options = NoOption) const;
/// Utility function for writeCodeSnips.
typedef QPair<const AbstractMetaArgument*, QString> ArgumentVarReplacementPair;
- typedef QList<ArgumentVarReplacementPair> ArgumentVarReplacementList;
+ typedef QVector<ArgumentVarReplacementPair> ArgumentVarReplacementList;
ArgumentVarReplacementList getArgumentReplacement(const AbstractMetaFunction* func,
bool usePyArgs, TypeSystem::Language language,
const AbstractMetaArgument* lastArg);
/// Write user's custom code snippets at class or module level.
void writeCodeSnips(QTextStream& s,
- const QList<CodeSnip>& codeSnips,
+ const QVector<CodeSnip> & codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language,
const AbstractMetaClass* context = 0);
/// Write user's custom code snippets at function level.
void writeCodeSnips(QTextStream& s,
- const QList<CodeSnip>& codeSnips,
+ const QVector<CodeSnip> & codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language,
const AbstractMetaFunction* func,
const AbstractMetaArgument* lastArg = 0);
/// Returns a string with the user's custom code snippets that comply with \p position and \p language.
- QString getCodeSnippets(const QList<CodeSnip>& codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language);
+ QString getCodeSnippets(const QVector<CodeSnip> & codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language);
/// Replaces variables for the user's custom code at global or class level.
void processCodeSnip(QString& code, const AbstractMetaClass* context = 0);
@@ -409,7 +411,11 @@ public:
QString cpythonWrapperCPtr(const TypeEntry* type, QString argName);
/// Guesses the scope to where belongs an argument's default value.
- QString guessScopeForDefaultValue(const AbstractMetaFunction* func, const AbstractMetaArgument* arg);
+ QString guessScopeForDefaultValue(const AbstractMetaFunction *func,
+ const AbstractMetaArgument *arg) const;
+ QString guessScopeForDefaultFlagsValue(const AbstractMetaFunction *func,
+ const AbstractMetaArgument *arg,
+ const QString &value) const;
QString cpythonEnumName(const EnumTypeEntry* enumEntry);
QString cpythonEnumName(const AbstractMetaEnum* metaEnum);
@@ -428,7 +434,7 @@ public:
QString extendedIsConvertibleFunctionName(const TypeEntry* targetType) const;
QString extendedToCppFunctionName(const TypeEntry* targetType) const;
- QMap< QString, QString > options() const;
+ OptionDescriptions options() const override;
/// Returns true if the user enabled the so called "parent constructor heuristic".
bool useCtorHeuristic() const;
@@ -513,12 +519,12 @@ protected:
// All data about extended converters: the type entries of the target type, and a
// list of AbstractMetaClasses accepted as argument for the conversion.
- typedef QHash<const TypeEntry*, QList<const AbstractMetaClass*> > ExtendedConverterData;
+ typedef QHash<const TypeEntry *, QVector<const AbstractMetaClass *> > ExtendedConverterData;
/// Returns all extended conversions for the current module.
ExtendedConverterData getExtendedConverters() const;
/// Returns a list of converters for the non wrapper types of the current module.
- QList<const CustomConversion*> getPrimitiveCustomConversions();
+ QVector<const CustomConversion *> getPrimitiveCustomConversions();
/// Returns true if the Python wrapper for the received OverloadData must accept a list of arguments.
static bool pythonFunctionWrapperUsesListOfArguments(const OverloadData& overloadData);
@@ -549,7 +555,7 @@ private:
/// Type system converter variable replacement names and regular expressions.
QString m_typeSystemConvName[TypeSystemConverterVariables];
- QRegExp m_typeSystemConvRegEx[TypeSystemConverterVariables];
+ QRegularExpression m_typeSystemConvRegEx[TypeSystemConverterVariables];
};
#endif // SHIBOKENGENERATOR_H