diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-05-06 21:19:07 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-05-06 21:19:07 +0200 |
commit | 91b93e1021ccc06d13e0d66a43bf7f9063faeff3 (patch) | |
tree | f5270164466b42367d4df63d723b3a4db4d7d0fe /sources/shiboken2 | |
parent | edae6185cef9c0ddd7c7c88bfa97c5043ba0d78a (diff) | |
parent | 06f97eca45ddadf4f04229cf14d5dc0bbd867316 (diff) |
Merge remote-tracking branch 'origin/5.12' into 5.13
Change-Id: Ia87a2e46bb051f1cccf3b7ba988aeb5eb32c0f0e
Diffstat (limited to 'sources/shiboken2')
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp | 39 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/reporthandler.cpp | 72 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/reporthandler.h | 11 | ||||
-rw-r--r-- | sources/shiboken2/doc/contents.rst | 18 | ||||
-rw-r--r-- | sources/shiboken2/doc/index.rst | 19 | ||||
-rw-r--r-- | sources/shiboken2/generator/main.cpp | 5 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/cppgenerator.cpp | 54 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/cppgenerator.h | 3 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/headergenerator.h | 3 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/shibokengenerator.cpp | 103 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/shibokengenerator.h | 16 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/basewrapper.cpp | 4 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/basewrapper.h | 4 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/embed/embedding_generator.py | 6 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/pep384impl.h | 5 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/pep384impl_doc.rst | 3 |
16 files changed, 203 insertions, 162 deletions
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<QString>()); 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<QString> 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 <typename T> - 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/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 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.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 29220c739..58788d5ef 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 <set>" << endl; + if (getMultipleInheritingClass(metaClass) != nullptr) + s << "#include <algorithm>\n#include <set>\n"; if (metaClass->generateExceptionHandling()) s << "#include <exception>" << endl; @@ -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<QString> seenSignatures; bool staticEncountered = false; @@ -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; @@ -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<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())); + QString offset; + QTextStream(&offset) << "reinterpret_cast<uintptr_t>(static_cast<const " + << baseClass->qualifiedCppName() << "*>(class_ptr)) - base"; + result.append(offset); + offset.clear(); + QTextStream(&offset) << "reinterpret_cast<uintptr_t>(static_cast<const " + << baseClass->qualifiedCppName() << "*>(static_cast<const " + << metaClass->qualifiedCppName() + << "*>(static_cast<const void*>(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<int> offsets;" << endl; - s << INDENT << "std::set<int>::iterator it;" << endl; - s << INDENT << "const " << className << "* class_ptr = reinterpret_cast<const " << className << "*>(cptr);" << endl; - s << INDENT << "size_t base = (size_t) class_ptr;" << endl; + s << INDENT << "const auto* class_ptr = reinterpret_cast<const " << className << "*>(cptr);" << endl; + s << INDENT << "const auto base = reinterpret_cast<uintptr_t>(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"); } @@ -5050,7 +5047,7 @@ void CppGenerator::writeClassRegister(QTextStream &s, if (miClass == metaClass) { s << multipleInheritanceInitializerFunctionName(miClass) << ";" << endl; } else { - s << "Shiboken::ObjectType::getMultipleIheritanceFunction(reinterpret_cast<SbkObjectType*>("; + s << "Shiboken::ObjectType::getMultipleInheritanceFunction(reinterpret_cast<SbkObjectType*>("; s << cpythonTypeNameExt(miClass->typeEntry()) << "));" << endl; } s << INDENT << "Shiboken::ObjectType::setMultipleInheritanceFunction("; @@ -5404,8 +5401,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 +5821,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/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; diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index 002ab8cfb..44405c700 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<const AbstractMetaClass *, GeneratorClassInfoCacheEntry>; + +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. @@ -2165,26 +2178,19 @@ bool ShibokenGenerator::injectedCodeUsesArgument(const AbstractMetaFunction* fun return false; } -bool ShibokenGenerator::hasMultipleInheritanceInAncestry(const AbstractMetaClass* metaClass) +bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* metaClass) { - if (!metaClass || metaClass->baseClassNames().isEmpty()) - return false; - if (metaClass->baseClassNames().size() > 1) - return true; - return hasMultipleInheritanceInAncestry(metaClass->baseClass()); + return getGeneratorClassInfo(metaClass).needsGetattroFunction; } -typedef QMap<QString, AbstractMetaFunctionList> FunctionGroupMap; -typedef FunctionGroupMap::const_iterator FunctionGroupMapIt; - -bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* metaClass) +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 +2218,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() @@ -2254,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()); @@ -2358,23 +2364,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<QString, AbstractMetaFunctionList> 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 +2542,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..f5f291526 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<QString, AbstractMetaFunctionList>; // 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<QString, AbstractMetaFunctionList> 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. @@ -179,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); @@ -194,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); @@ -440,6 +442,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; 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); 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: 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. |