From f3f401315774687f74caa4f5aeb7ec8ef2d5587c Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Sat, 20 Apr 2019 11:40:19 +0200 Subject: Avoid too much stickiness when using --reuse-build We had some unwanted cache effects and needed to manually remove certain files before building. Otherwise it could happen that a build pretended to be ok, although there was a bug that prevented generation of the ".pyi" files. Further investigation showed: Using option "--reuse-build" with "no" and then with "yes" creates errors in the signature module. This makes "reuse-build" useless in this case. We now add an "a" to "pyside3d_build" as "pside3da_build" if "--limited-api=yes" was given. (different proposals welcome.) That solved most of the stickiness problems. A left-over lock directory is removed now, since it would prevent re-computation of the .pyi files. This is implemented by a recursive call to the script, where the subprocess does the work and the main process checks if there was a crash and removes the lock. The "--skip" parameter of generate_pyi.py was refined: When set, it is checked if the time stamp of all imported modules is less than the ".pyi" file time stamp. Only then the generation is skipped. By editing any involved python file, the ".pyi" files will be regenerated. Task-number: PYSIDE-560 Change-Id: I1b1d8ffbc58db3d4b38bf65e3795efcad7e7870c Reviewed-by: Alexandru Croitor --- sources/shiboken2/libshiboken/embed/embedding_generator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/libshiboken/embed/embedding_generator.py b/sources/shiboken2/libshiboken/embed/embedding_generator.py index b6bfb1467..77aa5c329 100644 --- a/sources/shiboken2/libshiboken/embed/embedding_generator.py +++ b/sources/shiboken2/libshiboken/embed/embedding_generator.py @@ -92,7 +92,7 @@ def create_zipfile(limited_api): flag = '-b' if sys.version_info >= (3,) else '' os.chdir(work_dir) - # Limited API: Remove all left-over py[co] files first, in case we use '--reuse-build'. + # Remove all left-over py[co] and other files first, in case we use '--reuse-build'. # Note that we could improve that with the PyZipfile function to use .pyc files # in different folders, but that makes only sense when COIN allows us to have # multiple Python versions in parallel. @@ -100,9 +100,9 @@ def create_zipfile(limited_api): for root, dirs, files in os.walk(work_dir): for name in files: fpath = os.path.join(root, name) - if name.endswith(".pyc") or name.endswith(".pyo"): + ew = name.endswith + if ew(".pyc") or ew(".pyo") or ew(".zip") or ew(".inc"): os.remove(fpath) - # We copy every Python file into this dir, but only for the right version. # For testing in the source dir, we need to filter. if sys.version_info[0] == 3: -- cgit v1.2.3 From f332f2e8e66a5fa67b302893a13f0be3687ccc38 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 25 Apr 2019 14:57:12 +0200 Subject: shiboken: Refactor progress message output handling In class ReportHandler, replace the step counting by a simple pair of startProgress()/endProgress() functions that check for warnings and print the appropriate terminator. Module name and timestamp are now also printed. Add a few more messages and give proper names to the generators. Change-Id: I92b4ef2854b824fbba3d371417edc1f88561a2cb Reviewed-by: Cristian Maureira-Fredes --- .../shiboken2/ApiExtractor/abstractmetabuilder.cpp | 39 ++++++------ sources/shiboken2/ApiExtractor/reporthandler.cpp | 72 ++++++++++------------ sources/shiboken2/ApiExtractor/reporthandler.h | 11 +--- sources/shiboken2/generator/main.cpp | 5 +- .../shiboken2/generator/shiboken2/cppgenerator.h | 3 + .../generator/shiboken2/headergenerator.h | 3 + 6 files changed, 65 insertions(+), 68 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 6e95e79e7..7e998d315 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -428,20 +428,20 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) // Start the generation... const ClassList &typeValues = dom->classes(); - ReportHandler::setProgressReference(typeValues); + + ReportHandler::startProgress("Generating class model (" + + QByteArray::number(typeValues.size()) + ")..."); for (const ClassModelItem &item : typeValues) { - ReportHandler::progress(QStringLiteral("Generating class model (%1)...") - .arg(typeValues.size())); if (AbstractMetaClass *cls = traverseClass(dom, item, nullptr)) addAbstractMetaClass(cls, item.data()); } // We need to know all global enums const EnumList &enums = dom->enums(); - ReportHandler::setProgressReference(enums); + + ReportHandler::startProgress("Generating enum model (" + + QByteArray::number(enums.size()) + ")..."); for (const EnumModelItem &item : enums) { - ReportHandler::progress(QStringLiteral("Generating enum model (%1)...") - .arg(enums.size())); AbstractMetaEnum *metaEnum = traverseEnum(item, 0, QSet()); if (metaEnum) { if (metaEnum->typeEntry()->generateCode()) @@ -450,10 +450,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } const auto &namespaceTypeValues = dom->namespaces(); - ReportHandler::setProgressReference(namespaceTypeValues); + ReportHandler::startProgress("Generating namespace model (" + + QByteArray::number(namespaceTypeValues.size()) + ")..."); for (const NamespaceModelItem &item : namespaceTypeValues) { - ReportHandler::progress(QStringLiteral("Generating namespace model (%1)...") - .arg(namespaceTypeValues.size())); if (AbstractMetaClass *metaClass = traverseNamespace(dom, item)) addAbstractMetaClass(metaClass, item.data()); } @@ -461,10 +460,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. const TypeDefList typeDefs = dom->typeDefs(); - ReportHandler::setProgressReference(typeDefs); + ReportHandler::startProgress("Resolving typedefs (" + + QByteArray::number(typeDefs.size()) + ")..."); for (const TypeDefModelItem &typeDef : typeDefs) { - ReportHandler::progress(QStringLiteral("Resolving typedefs (%1)...") - .arg(typeDefs.size())); if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, nullptr)) addAbstractMetaClass(cls, typeDef.data()); } @@ -506,16 +504,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) m_globalFunctions << metaFunc; } - ReportHandler::setProgressReference(m_metaClasses); + ReportHandler::startProgress("Fixing class inheritance..."); for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { - ReportHandler::progress(QLatin1String("Fixing class inheritance...")); if (!cls->isInterface() && !cls->isNamespace()) setupInheritance(cls); } - ReportHandler::setProgressReference(m_metaClasses); + ReportHandler::startProgress("Detecting inconsistencies in class model..."); for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { - ReportHandler::progress(QLatin1String("Detecting inconsistencies in class model...")); cls->fixFunctions(); if (!cls->typeEntry()) { @@ -538,8 +534,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + QLatin1String("$ConcreteWrapper")); } const auto &allEntries = types->entries(); - ReportHandler::progress(QStringLiteral("Detecting inconsistencies in typesystem (%1)...") - .arg(allEntries.size())); + + ReportHandler::startProgress("Detecting inconsistencies in typesystem (" + + QByteArray::number(allEntries.size()) + ")..."); for (auto it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) { TypeEntry *entry = it.value(); if (!entry->isPrimitive()) { @@ -638,8 +635,12 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) traverseStreamOperator(item, nullptr); } + ReportHandler::startProgress("Checking inconsistencies in function modifications..."); + checkFunctionModifications(); + ReportHandler::startProgress("Writing log files..."); + // sort all classes topologically m_metaClasses = classesTopologicalSorted(m_metaClasses); @@ -673,6 +674,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } m_itemToClass.clear(); + + ReportHandler::endProgress(); } static bool metaEnumLessThan(const AbstractMetaEnum *e1, const AbstractMetaEnum *e2) diff --git a/sources/shiboken2/ApiExtractor/reporthandler.cpp b/sources/shiboken2/ApiExtractor/reporthandler.cpp index 6ff5b8d03..c0c323029 100644 --- a/sources/shiboken2/ApiExtractor/reporthandler.cpp +++ b/sources/shiboken2/ApiExtractor/reporthandler.cpp @@ -52,22 +52,13 @@ static int m_warningCount = 0; static int m_suppressedCount = 0; static ReportHandler::DebugLevel m_debugLevel = ReportHandler::NoDebug; static QSet m_reportedWarnings; -static QString m_progressBuffer; static QString m_prefix; -static int m_step_size = 0; -static int m_step = -1; +static bool m_withinProgress = false; static int m_step_warning = 0; static QElapsedTimer m_timer; Q_LOGGING_CATEGORY(lcShiboken, "qt.shiboken") -static void printProgress() -{ - std::printf("%s", m_progressBuffer.toUtf8().data()); - std::fflush(stdout); - m_progressBuffer.clear(); -} - void ReportHandler::install() { qInstallMessageHandler(ReportHandler::messageOutput); @@ -94,12 +85,6 @@ int ReportHandler::warningCount() return m_warningCount; } -void ReportHandler::setProgressReference(int max) -{ - m_step_size = max; - m_step = -1; -} - bool ReportHandler::isSilent() { return m_silent; @@ -136,38 +121,45 @@ void ReportHandler::messageOutput(QtMsgType type, const QMessageLogContext &cont fprintf(stderr, "%s\n", qPrintable(qFormatLogMessage(type, context, message))); } -void ReportHandler::progress(const QString& str, ...) +static QByteArray timeStamp() +{ + const qint64 elapsed = m_timer.elapsed(); + return elapsed > 5000 + ? QByteArray::number(elapsed / 1000) + 's' + : QByteArray::number(elapsed) + "ms"; +} + +void ReportHandler::startProgress(const QByteArray& str) { if (m_silent) return; - if (m_step == -1) { - QTextStream buf(&m_progressBuffer); - buf.setFieldWidth(45); - buf.setFieldAlignment(QTextStream::AlignLeft); - buf << str; - printProgress(); - m_step = 0; - } - m_step++; - if (m_step >= m_step_size) { - if (m_step_warning == 0) { - m_progressBuffer = QLatin1String("[" COLOR_GREEN "OK" COLOR_END "]\n"); - } else { - m_progressBuffer = QLatin1String("[" COLOR_YELLOW "WARNING" COLOR_END "]\n"); - } - printProgress(); - m_step_warning = 0; - } + if (m_withinProgress) + endProgress(); + + m_withinProgress = true; + const auto ts = '[' + timeStamp() + ']'; + std::printf("%s %8s %-60s", qPrintable(m_prefix), ts.constData(), str.constData()); + std::fflush(stdout); +} + +void ReportHandler::endProgress() +{ + if (m_silent) + return; + + m_withinProgress = false; + const char *endMessage = m_step_warning == 0 + ? "[" COLOR_GREEN "OK" COLOR_END "]\n" + : "[" COLOR_YELLOW "WARNING" COLOR_END "]\n"; + std::fputs(endMessage, stdout); + std::fflush(stdout); + m_step_warning = 0; } QByteArray ReportHandler::doneMessage() { - QByteArray result = "Done, " + m_prefix.toUtf8() + ' '; - const qint64 elapsed = m_timer.elapsed(); - result += elapsed > 5000 - ? QByteArray::number(elapsed / 1000) + 's' - : QByteArray::number(elapsed) + "ms"; + QByteArray result = "Done, " + m_prefix.toUtf8() + ' ' + timeStamp(); if (m_warningCount) result += ", " + QByteArray::number(m_warningCount) + " warnings"; if (m_suppressedCount) diff --git a/sources/shiboken2/ApiExtractor/reporthandler.h b/sources/shiboken2/ApiExtractor/reporthandler.h index 8f97cb506..08ab7d23c 100644 --- a/sources/shiboken2/ApiExtractor/reporthandler.h +++ b/sources/shiboken2/ApiExtractor/reporthandler.h @@ -48,15 +48,8 @@ public: static int suppressedCount(); - template - static void setProgressReference(T collection) - { - setProgressReference(collection.count()); - } - - static void setProgressReference(int max); - - static void progress(const QString &str, ...); + static void startProgress(const QByteArray &str); + static void endProgress(); static bool isDebug(DebugLevel level) { return debugLevel() >= level; } diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp index 9beaf47c7..ac576d657 100644 --- a/sources/shiboken2/generator/main.cpp +++ b/sources/shiboken2/generator/main.cpp @@ -624,7 +624,10 @@ int main(int argc, char *argv[]) for (const GeneratorPtr &g : qAsConst(generators)) { g->setOutputDirectory(outputDirectory); g->setLicenseComment(licenseComment); - if (!g->setup(extractor) || !g->generate()) { + ReportHandler::startProgress(QByteArray("Running ") + g->name() + "..."); + const bool ok = g->setup(extractor) && g->generate(); + ReportHandler::endProgress(); + if (!ok) { errorPrint(QLatin1String("Error running generator: ") + QLatin1String(g->name()) + QLatin1Char('.')); return EXIT_FAILURE; diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h index d2e04dba2..519e12b7b 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.h +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h @@ -38,6 +38,9 @@ class CppGenerator : public ShibokenGenerator { public: CppGenerator(); + + const char *name() const override { return "Source generator"; } + protected: QString fileNameSuffix() const override; QString fileNameForContext(GeneratorContext &context) const override; diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.h b/sources/shiboken2/generator/shiboken2/headergenerator.h index 821531aab..f59e0fd9a 100644 --- a/sources/shiboken2/generator/shiboken2/headergenerator.h +++ b/sources/shiboken2/generator/shiboken2/headergenerator.h @@ -42,6 +42,9 @@ class HeaderGenerator : public ShibokenGenerator { public: OptionDescriptions options() const override { return OptionDescriptions(); } + + const char *name() const override { return "Header generator"; } + protected: QString fileNameSuffix() const override; QString fileNameForContext(GeneratorContext &context) const override; -- cgit v1.2.3 From e83e07dd9fba3a2c69afe07cbee70346a1ee6ec8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 26 Apr 2019 09:31:48 +0200 Subject: shiboken/Generators: Cache class information lists per class The function ShibokenGenerator::getFunctionGroups(class) is called many times for each function during code generation and causes a slowdown for the OpenGL version function classes, which have 1000 member functions. Split away getGlobalFunctionGroups() for the case scope=0 and introduce a global-static cache for class information that is more involved to determine for use by the various generators. Speeds up the generation of the QtGui module including the OpenGL version functions from 420s to 90s. Task-number: PYSIDE-955 Change-Id: I6b6aa35ef2197aa9cddbf339db9eb0220932f361 Reviewed-by: Christian Tismer --- .../shiboken2/generator/shiboken2/cppgenerator.cpp | 13 +-- .../generator/shiboken2/shibokengenerator.cpp | 96 ++++++++++++++++------ .../generator/shiboken2/shibokengenerator.h | 10 ++- 3 files changed, 89 insertions(+), 30 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 29220c739..67f8f1a7b 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -453,8 +453,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) s << endl << "// Target ---------------------------------------------------------" << endl << endl; s << "extern \"C\" {" << endl; - const FunctionGroupMap &functionGroups = getFunctionGroups(metaClass); - for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { + const auto &functionGroups = getFunctionGroups(metaClass); + for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; QSet seenSignatures; bool staticEncountered = false; @@ -5404,8 +5404,8 @@ bool CppGenerator::finishGeneration() Indentation indent(INDENT); - const FunctionGroupMap &functionGroups = getFunctionGroups(); - for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { + const auto functionGroups = getGlobalFunctionGroups(); + for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; for (AbstractMetaFunction *func : it.value()) { if (!func->isModifiedRemoved()) { @@ -5824,7 +5824,10 @@ bool CppGenerator::writeParentChildManagement(QTextStream& s, const AbstractMeta const int numArgs = func->arguments().count(); bool ctorHeuristicEnabled = func->isConstructor() && useCtorHeuristic() && useHeuristicPolicy; - bool usePyArgs = pythonFunctionWrapperUsesListOfArguments(OverloadData(getFunctionGroups(func->implementingClass())[func->name()], this)); + const auto &groups = func->implementingClass() + ? getFunctionGroups(func->implementingClass()) + : getGlobalFunctionGroups(); + bool usePyArgs = pythonFunctionWrapperUsesListOfArguments(OverloadData(groups[func->name()], this)); ArgumentOwner argOwner = getArgumentOwner(func, argIndex); ArgumentOwner::Action action = argOwner.action; diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index 002ab8cfb..12efb68c3 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -118,6 +118,16 @@ static QString resolveScopePrefix(const AbstractMetaEnum *metaEnum, return resolveScopePrefix(parts, value); } +struct GeneratorClassInfoCacheEntry +{ + ShibokenGenerator::FunctionGroups functionGroups; + bool needsGetattroFunction = false; +}; + +using GeneratorClassInfoCache = QHash; + +Q_GLOBAL_STATIC(GeneratorClassInfoCache, generatorClassInfoCache) + ShibokenGenerator::ShibokenGenerator() { if (m_pythonPrimitiveTypeName.isEmpty()) @@ -1739,7 +1749,10 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, argsRemoved++; } - OverloadData od(getFunctionGroups(func->implementingClass())[func->name()], this); + const auto &groups = func->implementingClass() + ? getFunctionGroups(func->implementingClass()) + : getGlobalFunctionGroups(); + OverloadData od(groups[func->name()], this); bool usePyArgs = pythonFunctionWrapperUsesListOfArguments(od); // Replace %PYARG_# variables. @@ -2174,17 +2187,19 @@ bool ShibokenGenerator::hasMultipleInheritanceInAncestry(const AbstractMetaClass return hasMultipleInheritanceInAncestry(metaClass->baseClass()); } -typedef QMap FunctionGroupMap; -typedef FunctionGroupMap::const_iterator FunctionGroupMapIt; - bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* metaClass) +{ + return getGeneratorClassInfo(metaClass).needsGetattroFunction; +} + +bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass* metaClass) { if (!metaClass) return false; if (metaClass->typeEntry()->isSmartPointer()) return true; - const FunctionGroupMap &functionGroup = getFunctionGroups(metaClass); - for (FunctionGroupMapIt it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) { + const auto &functionGroup = getFunctionGroups(metaClass); + for (auto it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; for (AbstractMetaFunction *func : qAsConst(it.value())) { if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved() @@ -2212,8 +2227,8 @@ AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStatic { AbstractMetaFunctionList methods; if (metaClass) { - const FunctionGroupMap &functionGroups = getFunctionGroups(metaClass); - for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { + const auto &functionGroups = getFunctionGroups(metaClass); + for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; for (AbstractMetaFunction *func : qAsConst(it.value())) { if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved() @@ -2358,23 +2373,56 @@ static bool isGroupable(const AbstractMetaFunction* func) return true; } -QMap< QString, AbstractMetaFunctionList > ShibokenGenerator::getFunctionGroups(const AbstractMetaClass* scope) +ShibokenGenerator::FunctionGroups ShibokenGenerator::getGlobalFunctionGroups() const { - AbstractMetaFunctionList lst = scope ? scope->functions() : globalFunctions(); + const AbstractMetaFunctionList &lst = globalFunctions(); + FunctionGroups results; + for (AbstractMetaFunction *func : lst) { + if (isGroupable(func)) + results[func->name()].append(func); + } + return results; +} - QMap results; - for (AbstractMetaFunction *func : qAsConst(lst)) { +const GeneratorClassInfoCacheEntry &ShibokenGenerator::getGeneratorClassInfo(const AbstractMetaClass *scope) +{ + auto cache = generatorClassInfoCache(); + auto it = cache->find(scope); + if (it == cache->end()) { + it = cache->insert(scope, {}); + it.value().functionGroups = getFunctionGroupsImpl(scope); + it.value().needsGetattroFunction = classNeedsGetattroFunctionImpl(scope); + } + return it.value(); +} + +ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroups(const AbstractMetaClass *scope) +{ + Q_ASSERT(scope); + return getGeneratorClassInfo(scope).functionGroups; +} + +ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroupsImpl(const AbstractMetaClass *scope) +{ + const AbstractMetaFunctionList &lst = scope->functions(); + + FunctionGroups results; + for (AbstractMetaFunction *func : lst) { if (isGroupable(func)) { - AbstractMetaFunctionList &list = results[func->name()]; - // If there are virtuals methods in the mix (PYSIDE-570, - // QFileSystemModel::index(QString,int) and - // QFileSystemModel::index(int,int,QModelIndex)) override, make sure - // the overriding method of the most-derived class is seen first - // and inserted into the "seenSignatures" set. - if (func->isVirtual()) - list.prepend(func); - else - list.append(func); + auto it = results.find(func->name()); + if (it == results.end()) { + results.insert(func->name(), AbstractMetaFunctionList(1, func)); + } else { + // If there are virtuals methods in the mix (PYSIDE-570, + // QFileSystemModel::index(QString,int) and + // QFileSystemModel::index(int,int,QModelIndex)) override, make sure + // the overriding method of the most-derived class is seen first + // and inserted into the "seenSignatures" set. + if (func->isVirtual()) + it.value().prepend(func); + else + it.value().append(func); + } } } return results; @@ -2503,8 +2551,8 @@ bool ShibokenGenerator::doSetup() Q_ASSERT(moduleEntry); getCode(snips, moduleEntry); - const FunctionGroupMap &functionGroups = getFunctionGroups(); - for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { + const auto &functionGroups = getGlobalFunctionGroups(); + for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { for (AbstractMetaFunction *func : it.value()) getCode(snips, func->injectedCodeSnips()); } diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h index 80b172778..ebfc059de 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h @@ -54,6 +54,7 @@ extern const char *END_ALLOW_THREADS; class DocParser; class CodeSnip; class OverloadData; +struct GeneratorClassInfoCacheEntry; QT_FORWARD_DECLARE_CLASS(QTextStream) @@ -63,6 +64,8 @@ QT_FORWARD_DECLARE_CLASS(QTextStream) class ShibokenGenerator : public Generator { public: + using FunctionGroups = QMap; // Sorted + ShibokenGenerator(); ~ShibokenGenerator() override; @@ -99,7 +102,8 @@ protected: * Example of return value: { "foo" -> ["foo(int)", "foo(int, long)], "bar" -> "bar(double)"} * \param scope Where to search for functions, null means all global functions. */ - QMap getFunctionGroups(const AbstractMetaClass* scope = 0); + FunctionGroups getGlobalFunctionGroups() const; + static FunctionGroups getFunctionGroups(const AbstractMetaClass *scope); /** * Returns all different inherited overloads of func, and includes func as well. @@ -440,6 +444,10 @@ protected: static QStringList m_knownPythonTypes; private: + static const GeneratorClassInfoCacheEntry &getGeneratorClassInfo(const AbstractMetaClass *scope); + static FunctionGroups getFunctionGroupsImpl(const AbstractMetaClass *scope); + static bool classNeedsGetattroFunctionImpl(const AbstractMetaClass *metaClass); + QString translateTypeForWrapperMethod(const AbstractMetaType* cType, const AbstractMetaClass* context, Options opt = NoOption) const; -- cgit v1.2.3 From 67f389a79d08f7835d7f226836008e3384e7dd77 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 30 Apr 2019 09:00:14 +0200 Subject: shiboken documentation: Move TOC to index page Change-Id: I0f7c6a303cb0d404c42ae96f067eece1442c4a33 Reviewed-by: Cristian Maureira-Fredes --- sources/shiboken2/doc/contents.rst | 18 ------------------ sources/shiboken2/doc/index.rst | 19 +++++++++++++++---- 2 files changed, 15 insertions(+), 22 deletions(-) delete mode 100644 sources/shiboken2/doc/contents.rst (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/doc/contents.rst b/sources/shiboken2/doc/contents.rst deleted file mode 100644 index 7cdc0063e..000000000 --- a/sources/shiboken2/doc/contents.rst +++ /dev/null @@ -1,18 +0,0 @@ -Table of contents -***************** -.. toctree:: - :maxdepth: 3 - - overview.rst - samplebinding.rst - commandlineoptions.rst - projectfile.rst - typesystemvariables.rst - typeconverters.rst - codeinjectionsemantics.rst - sequenceprotocol.rst - ownership.rst - wordsofadvice.rst - shibokenmodule.rst - faq.rst - typesystem.rst diff --git a/sources/shiboken2/doc/index.rst b/sources/shiboken2/doc/index.rst index 4cc5b204e..9403293ac 100644 --- a/sources/shiboken2/doc/index.rst +++ b/sources/shiboken2/doc/index.rst @@ -18,11 +18,22 @@ properly handle the data structures or types. The final outcome of this process is a set of wrappers written in CPython, which can be used as a module in your python code. -Refer to the following topics for more information and examples: +Table of contents +***************** .. toctree:: :maxdepth: 1 - overview - samplebinding - contents + overview.rst + samplebinding.rst + commandlineoptions.rst + projectfile.rst + typesystemvariables.rst + typeconverters.rst + codeinjectionsemantics.rst + sequenceprotocol.rst + ownership.rst + wordsofadvice.rst + shibokenmodule.rst + faq.rst + typesystem.rst -- cgit v1.2.3 From 4281bc61bdb7dad335d0f83eece249217e57af60 Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Mon, 29 Apr 2019 15:22:18 +0200 Subject: Use PyUnicode_GetLength instead of PyUnicode_GetSize The function PyUnicode_GetSize is deprecated. Change-Id: I0bc0acd35424f29e1f5154deb0429dab5a4aabd4 Reviewed-by: Friedemann Kleint Reviewed-by: Christian Tismer --- sources/shiboken2/libshiboken/pep384impl.h | 5 +++++ sources/shiboken2/libshiboken/pep384impl_doc.rst | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h index ffbc570a8..93f718988 100644 --- a/sources/shiboken2/libshiboken/pep384impl.h +++ b/sources/shiboken2/libshiboken/pep384impl.h @@ -201,7 +201,12 @@ LIBSHIBOKEN_API int Pep_GetVerboseFlag(void); LIBSHIBOKEN_API char *_PepUnicode_AsString(PyObject *); +#if PY_VERSION_HEX < 0x03000000 #define PyUnicode_GET_SIZE(op) PyUnicode_GetSize((PyObject *)(op)) +#else +// PyUnicode_GetSize is deprecated in favor of PyUnicode_GetLength +#define PyUnicode_GET_SIZE(op) PyUnicode_GetLength((PyObject *)(op)) +#endif #else #define _PepUnicode_AsString PyUnicode_AsUTF8 diff --git a/sources/shiboken2/libshiboken/pep384impl_doc.rst b/sources/shiboken2/libshiboken/pep384impl_doc.rst index ab286dd3e..2f3b7ea97 100644 --- a/sources/shiboken2/libshiboken/pep384impl_doc.rst +++ b/sources/shiboken2/libshiboken/pep384impl_doc.rst @@ -70,7 +70,8 @@ supported. We redefined it as macro ``Py_VerboseFlag`` which calls ``Pep_Verbose unicodeobject.h --------------- -The macro ``PyUnicode_GET_SIZE`` was redefined to call into ``PyUnicode_GetSize``. +The macro ``PyUnicode_GET_SIZE`` was redefined to call into ``PyUnicode_GetSize`` +for Python 2, and ``PyUnicode_GetLength`` for Python 3. Function ``_PyUnicode_AsString`` is unavailable and was replaced by a macro that calls ``_PepUnicode_AsString``. The implementation was a bit involved, and it would be better to change the code and replace this function. -- cgit v1.2.3 From ce8123b19ac37b114030bda7494508c361b97be5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 30 Apr 2019 10:52:20 +0200 Subject: shiboken: Refactor code generating multiple inheritance - Remove the check function hasMultipleInheritanceInAncestry(), which is nearly identical to getMultipleInheritingClass(). - Modernize the generated code to use C++ casts, uintptr_t and streamline Change-Id: I68f52c2cbf1a589fd31c9c73919365176c56932e Reviewed-by: Christian Tismer --- .../shiboken2/generator/shiboken2/cppgenerator.cpp | 37 ++++++++++------------ .../generator/shiboken2/shibokengenerator.cpp | 11 +------ .../generator/shiboken2/shibokengenerator.h | 6 ++-- 3 files changed, 20 insertions(+), 34 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 67f8f1a7b..4b0b99317 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -330,8 +330,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) // The multiple inheritance initialization function // needs the 'set' class from C++ STL. - if (hasMultipleInheritanceInAncestry(metaClass)) - s << "#include " << endl; + if (getMultipleInheritingClass(metaClass) != nullptr) + s << "#include \n#include \n"; if (metaClass->generateExceptionHandling()) s << "#include " << endl; @@ -3553,11 +3553,18 @@ QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass const AbstractMetaClassList &baseClases = getBaseClasses(metaClass); if (!baseClases.isEmpty()) { for (const AbstractMetaClass *baseClass : baseClases) { - result.append(QString::fromLatin1("((size_t) static_cast(class_ptr)) - base") - .arg(baseClass->qualifiedCppName())); - result.append(QString::fromLatin1("((size_t) static_cast((%2*)((void*)class_ptr))) - base") - .arg(baseClass->qualifiedCppName(), metaClass->qualifiedCppName())); + QString offset; + QTextStream(&offset) << "reinterpret_cast(static_castqualifiedCppName() << "*>(class_ptr)) - base"; + result.append(offset); + offset.clear(); + QTextStream(&offset) << "reinterpret_cast(static_castqualifiedCppName() << "*>(static_castqualifiedCppName() + << "*>(static_cast(class_ptr)))) - base"; + result.append(offset); } + for (const AbstractMetaClass *baseClass : baseClases) result.append(getAncestorMultipleInheritance(baseClass)); } @@ -3579,25 +3586,17 @@ void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, c { Indentation indent(INDENT); s << INDENT << "std::set offsets;" << endl; - s << INDENT << "std::set::iterator it;" << endl; - s << INDENT << "const " << className << "* class_ptr = reinterpret_cast(cptr);" << endl; - s << INDENT << "size_t base = (size_t) class_ptr;" << endl; + s << INDENT << "const auto* class_ptr = reinterpret_cast(cptr);" << endl; + s << INDENT << "const auto base = reinterpret_cast(class_ptr);" << endl; for (const QString &ancestor : ancestors) - s << INDENT << "offsets.insert(" << ancestor << ");" << endl; + s << INDENT << "offsets.insert(int(" << ancestor << "));" << endl; s << endl; s << INDENT << "offsets.erase(0);" << endl; s << endl; - s << INDENT << "int i = 0;" << endl; - s << INDENT << "for (it = offsets.begin(); it != offsets.end(); it++) {" << endl; - { - Indentation indent(INDENT); - s << INDENT << "mi_offsets[i] = *it;" << endl; - s << INDENT << "i++;" << endl; - } - s << INDENT << '}' << endl; + s << INDENT << "std::copy(offsets.cbegin(), offsets.cend(), mi_offsets);\n"; } s << INDENT << '}' << endl; s << INDENT << "return mi_offsets;" << endl; @@ -3748,8 +3747,6 @@ void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const Ty QString CppGenerator::multipleInheritanceInitializerFunctionName(const AbstractMetaClass* metaClass) { - if (!hasMultipleInheritanceInAncestry(metaClass)) - return QString(); return cpythonBaseName(metaClass->typeEntry()) + QLatin1String("_mi_init"); } diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index 12efb68c3..44405c700 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -2178,15 +2178,6 @@ bool ShibokenGenerator::injectedCodeUsesArgument(const AbstractMetaFunction* fun return false; } -bool ShibokenGenerator::hasMultipleInheritanceInAncestry(const AbstractMetaClass* metaClass) -{ - if (!metaClass || metaClass->baseClassNames().isEmpty()) - return false; - if (metaClass->baseClassNames().size() > 1) - return true; - return hasMultipleInheritanceInAncestry(metaClass->baseClass()); -} - bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* metaClass) { return getGeneratorClassInfo(metaClass).needsGetattroFunction; @@ -2269,7 +2260,7 @@ AbstractMetaClassList ShibokenGenerator::getBaseClasses(const AbstractMetaClass* const AbstractMetaClass* ShibokenGenerator::getMultipleInheritingClass(const AbstractMetaClass* metaClass) { if (!metaClass || metaClass->baseClassNames().isEmpty()) - return 0; + return nullptr; if (metaClass->baseClassNames().size() > 1) return metaClass; return getMultipleInheritingClass(metaClass->baseClass()); diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h index ebfc059de..f5f291526 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h @@ -183,8 +183,8 @@ protected: Options options = NoOption, int arg_count = -1) const; - /// Returns true if there are cases of multiple inheritance in any of its ancestors. - bool hasMultipleInheritanceInAncestry(const AbstractMetaClass* metaClass); + /// Returns the top-most class that has multiple inheritance in the ancestry. + static const AbstractMetaClass *getMultipleInheritingClass(const AbstractMetaClass* metaClass); /// Returns true if the class needs to have a getattro function. bool classNeedsGetattroFunction(const AbstractMetaClass* metaClass); @@ -198,8 +198,6 @@ protected: /// Returns a list of parent classes for a given class. AbstractMetaClassList getBaseClasses(const AbstractMetaClass* metaClass) const; - const AbstractMetaClass* getMultipleInheritingClass(const AbstractMetaClass* metaClass); - void writeToPythonConversion(QTextStream& s, const AbstractMetaType* type, const AbstractMetaClass* context, const QString& argumentName); void writeToCppConversion(QTextStream& s, const AbstractMetaType* type, const AbstractMetaClass* context, const QString& inArgName, const QString& outArgName); -- cgit v1.2.3 From 06e53faac0b1bcdffc966e0676a39a5f50f93592 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 30 Apr 2019 12:42:49 +0200 Subject: shiboken: Fix some spelling errors in function names getMultipleIheritanceFunction() -> getMultipleInheritanceFunction() copyMultimpleheritance() -> copyMultipleInheritance() Change-Id: If15b1ec12b6037ac8cff9941e09a281bc219fa20 Reviewed-by: Christian Tismer --- sources/shiboken2/generator/shiboken2/cppgenerator.cpp | 4 ++-- sources/shiboken2/libshiboken/basewrapper.cpp | 4 ++-- sources/shiboken2/libshiboken/basewrapper.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 4b0b99317..58788d5ef 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -1726,7 +1726,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun } { Indentation indentation(INDENT); - s << INDENT << "Shiboken::ObjectType::copyMultimpleheritance(type, myType);" << endl; + s << INDENT << "Shiboken::ObjectType::copyMultipleInheritance(type, myType);" << endl; } if (!metaClass->isAbstract()) s << INDENT << '}' << endl << endl; @@ -5047,7 +5047,7 @@ void CppGenerator::writeClassRegister(QTextStream &s, if (miClass == metaClass) { s << multipleInheritanceInitializerFunctionName(miClass) << ";" << endl; } else { - s << "Shiboken::ObjectType::getMultipleIheritanceFunction(reinterpret_cast("; + s << "Shiboken::ObjectType::getMultipleInheritanceFunction(reinterpret_cast("; s << cpythonTypeNameExt(miClass->typeEntry()) << "));" << endl; } s << INDENT << "Shiboken::ObjectType::setMultipleInheritanceFunction("; diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp index 3a043d849..6ea793a79 100644 --- a/sources/shiboken2/libshiboken/basewrapper.cpp +++ b/sources/shiboken2/libshiboken/basewrapper.cpp @@ -711,7 +711,7 @@ void setTypeDiscoveryFunctionV2(SbkObjectType* type, TypeDiscoveryFuncV2 func) PepType_SOTP(type)->type_discovery = func; } -void copyMultimpleheritance(SbkObjectType* type, SbkObjectType* other) +void copyMultipleInheritance(SbkObjectType *type, SbkObjectType *other) { PepType_SOTP(type)->mi_init = PepType_SOTP(other)->mi_init; PepType_SOTP(type)->mi_offsets = PepType_SOTP(other)->mi_offsets; @@ -723,7 +723,7 @@ void setMultipleInheritanceFunction(SbkObjectType* type, MultipleInheritanceInit PepType_SOTP(type)->mi_init = function; } -MultipleInheritanceInitFunction getMultipleIheritanceFunction(SbkObjectType* type) +MultipleInheritanceInitFunction getMultipleInheritanceFunction(SbkObjectType *type) { return PepType_SOTP(type)->mi_init; } diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h index d12b7222b..55445b026 100644 --- a/sources/shiboken2/libshiboken/basewrapper.h +++ b/sources/shiboken2/libshiboken/basewrapper.h @@ -184,9 +184,9 @@ LIBSHIBOKEN_API void setOriginalName(SbkObjectType* self, const char* nam LIBSHIBOKEN_API const char* getOriginalName(SbkObjectType* self); LIBSHIBOKEN_API void setTypeDiscoveryFunctionV2(SbkObjectType* self, TypeDiscoveryFuncV2 func); -LIBSHIBOKEN_API void copyMultimpleheritance(SbkObjectType* self, SbkObjectType* other); +LIBSHIBOKEN_API void copyMultipleInheritance(SbkObjectType *self, SbkObjectType *other); LIBSHIBOKEN_API void setMultipleInheritanceFunction(SbkObjectType* self, MultipleInheritanceInitFunction func); -LIBSHIBOKEN_API MultipleInheritanceInitFunction getMultipleIheritanceFunction(SbkObjectType* self); +LIBSHIBOKEN_API MultipleInheritanceInitFunction getMultipleInheritanceFunction(SbkObjectType *self); LIBSHIBOKEN_API void setDestructorFunction(SbkObjectType* self, ObjectDestructor func); -- cgit v1.2.3