aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-24 14:24:06 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-24 14:24:09 +0200
commit8b892f71b749a623724ccecca881972a33c9d559 (patch)
tree88d7a2371481cafd559d4895efa41b6f166ed8ac /sources/shiboken2
parentfff6ea0059b7394869166a01674a9afa230bc3a9 (diff)
parenta7038d87ba6ec3b2beeee166930c24f290f6478f (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/CMakeLists.txt78
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp431
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.h2
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h45
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp42
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h19
-rw-r--r--sources/shiboken2/ApiExtractor/apiextractor.cpp1
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h2
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp56
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h6
-rw-r--r--sources/shiboken2/ApiExtractor/tests/CMakeLists.txt24
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp37
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp5
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp107
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h25
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_p.h7
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_typedefs.h4
-rw-r--r--sources/shiboken2/CMakeLists.txt18
-rw-r--r--sources/shiboken2/doc/typesystem_specifying_types.rst24
-rw-r--r--sources/shiboken2/generator/CMakeLists.txt33
-rw-r--r--sources/shiboken2/generator/generator.cpp4
-rw-r--r--sources/shiboken2/generator/main.cpp6
-rw-r--r--sources/shiboken2/generator/qtdoc/CMakeLists.txt21
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp2
-rw-r--r--sources/shiboken2/generator/shiboken2/CMakeLists.txt28
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp39
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp2
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp5
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h2
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp30
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.h2
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h1
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp252
-rw-r--r--sources/shiboken2/libshiboken/signature.h4
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt18
-rw-r--r--sources/shiboken2/shibokenmodule/__init__.py.in21
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py1
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py3
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py14
-rw-r--r--sources/shiboken2/tests/CMakeLists.txt3
-rw-r--r--sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt5
-rw-r--r--sources/shiboken2/tests/libminimal/CMakeLists.txt4
-rw-r--r--sources/shiboken2/tests/libother/CMakeLists.txt8
-rw-r--r--sources/shiboken2/tests/libsample/CMakeLists.txt4
-rw-r--r--sources/shiboken2/tests/libsmart/CMakeLists.txt4
-rw-r--r--sources/shiboken2/tests/minimalbinding/CMakeLists.txt11
-rw-r--r--sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml2
-rw-r--r--sources/shiboken2/tests/otherbinding/CMakeLists.txt17
-rw-r--r--sources/shiboken2/tests/otherbinding/typesystem_other.xml2
-rw-r--r--sources/shiboken2/tests/samplebinding/CMakeLists.txt11
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml2
-rw-r--r--sources/shiboken2/tests/smartbinding/CMakeLists.txt11
-rw-r--r--sources/shiboken2/tests/smartbinding/typesystem_smart.xml2
55 files changed, 741 insertions, 774 deletions
diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt
index 4c0ac7b30..147fda377 100644
--- a/sources/shiboken2/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt
@@ -2,30 +2,8 @@ project(apiextractor)
cmake_minimum_required(VERSION 3.1)
cmake_policy(VERSION 3.1)
-find_package(LibXml2 2.6.32)
-find_package(LibXslt 1.1.19)
-option(DISABLE_DOCSTRINGS "Disable documentation extraction." FALSE)
-
-set (USE_LIBXSLT 0)
-if (NOT DISABLE_DOCSTRINGS)
- if (LIBXSLT_FOUND AND LIBXML2_FOUND)
- add_definitions(-DHAVE_LIBXSLT)
- set (USE_LIBXSLT 1)
- else()
- message(WARNING "libxslt and/or libxml not found, falling back to QtXmlPatterns (QTBUG-66925)")
- endif()
-endif()
-
-if(BUILD_TESTS)
- set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests)
-endif ()
-
-set(QT_USE_QTCORE 1)
-set(QT_USE_QTXML 1)
-add_definitions(-DQT_PLUGIN)
-add_definitions(-DQT_SHARED)
-add_definitions(-DRXX_ALLOCATOR_INIT_0)
+set(CMAKE_AUTOMOC ON)
set(apiextractor_SRC
apiextractor.cpp
@@ -50,45 +28,37 @@ parser/codemodel.cpp
parser/enumvalue.cpp
)
-set(APIEXTRACTOR_EXTRA_INCLUDES ${CLANG_EXTRA_INCLUDES})
-set(APIEXTRACTOR_EXTRA_LIBRARIES ${CLANG_EXTRA_LIBRARIES})
+add_library(apiextractor STATIC ${apiextractor_SRC})
+target_include_directories(apiextractor PRIVATE ${CLANG_EXTRA_INCLUDES}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/parser
+ ${CMAKE_CURRENT_SOURCE_DIR}/parser/rpp)
+target_link_libraries(apiextractor PUBLIC Qt5::Core)
+target_link_libraries(apiextractor PRIVATE ${CLANG_EXTRA_LIBRARIES})
if (NOT DISABLE_DOCSTRINGS)
- set(apiextractor_SRC
- ${apiextractor_SRC}
- docparser.cpp
- doxygenparser.cpp
- qtdocparser.cpp
- )
- set(APIEXTRACTOR_EXTRA_INCLUDES ${APIEXTRACTOR_EXTRA_INCLUDES})
- set(APIEXTRACTOR_EXTRA_LIBRARIES ${APIEXTRACTOR_EXTRA_LIBRARIES})
- if (USE_LIBXSLT)
- list(APPEND APIEXTRACTOR_EXTRA_INCLUDES ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
- list(APPEND APIEXTRACTOR_EXTRA_LIBRARIES ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES})
+ target_sources(apiextractor PRIVATE docparser.cpp
+ doxygenparser.cpp
+ qtdocparser.cpp)
+ target_link_libraries(apiextractor PUBLIC Qt5::Xml Qt5::XmlPatterns)
+
+ if (LIBXSLT_FOUND AND LIBXML2_FOUND)
+ target_compile_definitions(apiextractor PUBLIC HAVE_LIBXSLT)
+ target_include_directories(apiextractor
+ PRIVATE ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
+ target_link_libraries(apiextractor
+ PRIVATE ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES})
+ else()
+ message(WARNING
+ "libxslt and/or libxml not found, falling back to QtXmlPatterns (QTBUG-66925)")
endif()
endif()
set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
-set(CMAKE_AUTOMOC ON)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/parser
- ${CMAKE_CURRENT_SOURCE_DIR}/parser/rpp
- ${APIEXTRACTOR_EXTRA_INCLUDES}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Xml_INCLUDE_DIRS}
- )
-
-add_library(apiextractor STATIC ${apiextractor_SRC} ${apiextractor_RCCS_SRC})
-target_link_libraries(apiextractor
- ${Qt5Xml_LIBRARIES}
- ${Qt5XmlPatterns_LIBRARIES}
- ${APIEXTRACTOR_EXTRA_LIBRARIES}
- )
-
if (BUILD_TESTS)
+ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests)
enable_testing()
add_subdirectory(tests)
endif()
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index e62a2a78a..6e95e79e7 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -111,7 +111,7 @@ static QStringList parseTemplateType(const QString& name) {
return result;
}
-AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() : m_currentClass(0),
+AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() :
m_logDirectory(QLatin1String(".") + QDir::separator()),
m_skipDeprecated(false)
{
@@ -192,7 +192,7 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications()
QString name = signature.trimmed();
name.truncate(name.indexOf(QLatin1Char('(')));
- AbstractMetaClass *clazz = AbstractMetaClass::findClass(m_metaClasses, centry->qualifiedCppName());
+ AbstractMetaClass *clazz = AbstractMetaClass::findClass(m_metaClasses, centry);
if (!clazz)
continue;
@@ -223,13 +223,14 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications()
}
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentModelItem &argument)
+AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentModelItem &argument,
+ AbstractMetaClass *currentClass)
{
AbstractMetaClass* returned = 0;
- AbstractMetaType *type = translateType(argument->type());
+ AbstractMetaType *type = translateType(argument->type(), currentClass);
if (type && type->typeEntry() && type->typeEntry()->isComplex()) {
const TypeEntry *entry = type->typeEntry();
- returned = AbstractMetaClass::findClass(m_metaClasses, entry->name());
+ returned = AbstractMetaClass::findClass(m_metaClasses, entry);
}
delete type;
return returned;
@@ -238,11 +239,12 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentMod
/**
* Checks the argument of a hash function and flags the type if it is a complex type
*/
-void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &function_item)
+void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &function_item,
+ AbstractMetaClass *currentClass)
{
ArgumentList arguments = function_item->arguments();
if (arguments.size() == 1) {
- if (AbstractMetaClass *cls = argumentToClass(arguments.at(0)))
+ if (AbstractMetaClass *cls = argumentToClass(arguments.at(0), currentClass))
cls->setHasHashFunction(true);
}
}
@@ -251,13 +253,14 @@ void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &f
* Check if a class has a debug stream operator that can be used as toString
*/
-void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelItem &function_item)
+void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelItem &function_item,
+ AbstractMetaClass *currentClass)
{
ArgumentList arguments = function_item->arguments();
if (arguments.size() == 2) {
if (arguments.at(0)->type().toString() == QLatin1String("QDebug")) {
const ArgumentModelItem &arg = arguments.at(1);
- if (AbstractMetaClass *cls = argumentToClass(arg)) {
+ if (AbstractMetaClass *cls = argumentToClass(arg, currentClass)) {
if (arg->type().indirections() < 2)
cls->setToStringCapability(true);
}
@@ -265,28 +268,28 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelI
}
}
-void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelItem &item)
+void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelItem &item,
+ AbstractMetaClass *currentClass)
{
if (item->accessPolicy() != CodeModel::Public)
return;
ArgumentList arguments = item->arguments();
- AbstractMetaClass* baseoperandClass;
bool firstArgumentIsSelf = true;
bool unaryOperator = false;
- baseoperandClass = argumentToClass(arguments.at(0));
+ auto baseoperandClass = argumentToClass(arguments.at(0), currentClass);
if (arguments.size() == 1) {
unaryOperator = true;
} else if (!baseoperandClass
|| !(baseoperandClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang)) {
- baseoperandClass = argumentToClass(arguments.at(1));
+ baseoperandClass = argumentToClass(arguments.at(1), currentClass);
firstArgumentIsSelf = false;
} else {
- AbstractMetaType *type = translateType(item->type());
+ AbstractMetaType *type = translateType(item->type(), currentClass);
const TypeEntry *retType = type ? type->typeEntry() : nullptr;
- AbstractMetaClass* otherArgClass = argumentToClass(arguments.at(1));
+ AbstractMetaClass *otherArgClass = argumentToClass(arguments.at(1), currentClass);
if (otherArgClass && retType
&& (retType->isValue() || retType->isObject())
&& retType != baseoperandClass->typeEntry()
@@ -298,9 +301,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
}
if (baseoperandClass) {
- AbstractMetaClass* oldCurrentClass = m_currentClass;
- m_currentClass = baseoperandClass;
- AbstractMetaFunction *metaFunction = traverseFunction(item);
+ AbstractMetaFunction *metaFunction = traverseFunction(item, baseoperandClass);
if (metaFunction) {
// Strip away first argument, since that is the containing object
AbstractMetaArgumentList arguments = metaFunction->arguments();
@@ -333,22 +334,19 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
} else {
delete metaFunction;
}
-
- m_currentClass = oldCurrentClass;
}
}
-void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item)
+void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item,
+ AbstractMetaClass *currentClass)
{
ArgumentList arguments = item->arguments();
if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
- AbstractMetaClass* streamClass = argumentToClass(arguments.at(0));
- AbstractMetaClass* streamedClass = argumentToClass(arguments.at(1));
+ AbstractMetaClass *streamClass = argumentToClass(arguments.at(0), currentClass);
+ AbstractMetaClass *streamedClass = argumentToClass(arguments.at(1), currentClass);
if (streamClass && streamedClass && (streamClass->isStream())) {
- AbstractMetaClass *oldCurrentClass = m_currentClass;
- m_currentClass = streamedClass;
- AbstractMetaFunction *streamFunction = traverseFunction(item);
+ AbstractMetaFunction *streamFunction = traverseFunction(item, streamedClass);
if (streamFunction) {
streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
@@ -385,7 +383,6 @@ void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
else
funcClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
- m_currentClass = oldCurrentClass;
} else {
delete streamFunction;
}
@@ -394,27 +391,6 @@ void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
}
}
-void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom,
- const TypeDatabase *types,
- const NamespaceModelItem &scope)
-{
- const ClassList &scopeClasses = scope->classes();
- for (const ClassModelItem &item : scopeClasses) {
- QString qualifiedName = item->qualifiedName().join(colonColon());
- TypeEntry* entry = types->findType(qualifiedName);
- if (entry) {
- if (isQObject(dom, qualifiedName) && entry->isComplex())
- static_cast<ComplexTypeEntry *>(entry)->setQObject(true);
- }
- }
-
- const NamespaceList &namespaces = scope->namespaces();
- for (const NamespaceModelItem &n : namespaces) {
- if (scope != n)
- fixQObjectForScope(dom, types, n);
- }
-}
-
void AbstractMetaBuilderPrivate::sortLists()
{
for (AbstractMetaClass *cls : qAsConst(m_metaClasses))
@@ -450,17 +426,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
pushScope(dom);
- // fix up QObject's in the type system..
- fixQObjectForScope(dom, types, dom);
-
// Start the generation...
const ClassList &typeValues = dom->classes();
ReportHandler::setProgressReference(typeValues);
for (const ClassModelItem &item : typeValues) {
ReportHandler::progress(QStringLiteral("Generating class model (%1)...")
.arg(typeValues.size()));
- if (AbstractMetaClass *cls = traverseClass(dom, item))
- addAbstractMetaClass(cls);
+ if (AbstractMetaClass *cls = traverseClass(dom, item, nullptr))
+ addAbstractMetaClass(cls, item.data());
}
// We need to know all global enums
@@ -481,9 +454,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
for (const NamespaceModelItem &item : namespaceTypeValues) {
ReportHandler::progress(QStringLiteral("Generating namespace model (%1)...")
.arg(namespaceTypeValues.size()));
- AbstractMetaClass *metaClass = traverseNamespace(dom, item);
- if (metaClass)
- m_metaClasses << metaClass;
+ if (AbstractMetaClass *metaClass = traverseNamespace(dom, item))
+ addAbstractMetaClass(metaClass, item.data());
}
// Go through all typedefs to see if we have defined any
@@ -493,8 +465,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
for (const TypeDefModelItem &typeDef : typeDefs) {
ReportHandler::progress(QStringLiteral("Resolving typedefs (%1)...")
.arg(typeDefs.size()));
- if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef))
- addAbstractMetaClass(cls);
+ if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, nullptr))
+ addAbstractMetaClass(cls, typeDef.data());
}
traverseTypesystemTypedefs();
@@ -515,7 +487,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
if (!funcEntry || !funcEntry->generateCode())
continue;
- AbstractMetaFunction* metaFunc = traverseFunction(func);
+ AbstractMetaFunction* metaFunc = traverseFunction(func, nullptr);
if (!metaFunc)
continue;
@@ -579,7 +551,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
&& !entry->isCustom()
&& !entry->isVariant()
&& (entry->generateCode() & TypeEntry::GenerateTargetLang)
- && !AbstractMetaClass::findClass(m_metaClasses, entry->qualifiedCppName())) {
+ && !AbstractMetaClass::findClass(m_metaClasses, entry)) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("type '%1' is specified in typesystem, but not defined. This could potentially lead to compilation errors.")
.arg(entry->qualifiedCppName());
@@ -622,13 +594,13 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
{
const FunctionList &hashFunctions = dom->findFunctions(QLatin1String("qHash"));
for (const FunctionModelItem &item : hashFunctions)
- registerHashFunction(item);
+ registerHashFunction(item, nullptr);
}
{
const FunctionList &streamOps = dom->findFunctions(QLatin1String("operator<<"));
for (const FunctionModelItem &item : streamOps)
- registerToStringCapability(item);
+ registerToStringCapability(item, nullptr);
}
{
@@ -656,14 +628,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
binaryOperators.append(dom->findFunctions(QStringLiteral("operator>")));
for (const FunctionModelItem &item : qAsConst(binaryOperators))
- traverseOperatorFunction(item);
+ traverseOperatorFunction(item, nullptr);
}
{
const FunctionList streamOperators = dom->findFunctions(QLatin1String("operator<<"))
+ dom->findFunctions(QLatin1String("operator>>"));
for (const FunctionModelItem &item : streamOperators)
- traverseStreamOperator(item);
+ traverseStreamOperator(item, nullptr);
}
checkFunctionModifications();
@@ -688,21 +660,19 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
sortLists();
- m_currentClass = 0;
-
// Functions added to the module on the type system.
const AddedFunctionList &globalUserFunctions = types->globalUserFunctions();
- for (const AddedFunction &addedFunc : globalUserFunctions) {
+ for (const AddedFunctionPtr &addedFunc : globalUserFunctions) {
AbstractMetaFunction* metaFunc = traverseFunction(addedFunc);
if (Q_UNLIKELY(!metaFunc)) {
qFatal("Unable to traverse added global function \"%s\".",
- qPrintable(addedFunc.name()));
+ qPrintable(addedFunc->name()));
}
metaFunc->setFunctionType(AbstractMetaFunction::NormalFunction);
m_globalFunctions << metaFunc;
}
- std::puts("");
+ m_itemToClass.clear();
}
static bool metaEnumLessThan(const AbstractMetaEnum *e1, const AbstractMetaEnum *e2)
@@ -742,9 +712,11 @@ void AbstractMetaBuilder::setLogDirectory(const QString& logDir)
d->m_logDirectory.append(QDir::separator());
}
-void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls)
+void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls,
+ const _CodeModelItem *item)
{
cls->setOriginalAttributes(cls->attributes());
+ m_itemToClass.insert(item, cls);
if (cls->typeEntry()->isContainer()) {
m_templates << cls;
} else if (cls->typeEntry()->isSmartPointer()) {
@@ -763,9 +735,10 @@ void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls)
AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModelItem &dom,
const NamespaceModelItem &namespaceItem)
{
- QString namespaceName =
- (!m_namespacePrefix.isEmpty() ? m_namespacePrefix + colonColon() : QString())
- + namespaceItem->name();
+ QString namespaceName = currentScope()->qualifiedName().join(colonColon());
+ if (!namespaceName.isEmpty())
+ namespaceName.append(colonColon());
+ namespaceName.append(namespaceItem->name());
NamespaceTypeEntry *type = TypeDatabase::instance()->findNamespaceType(namespaceName);
if (TypeDatabase::instance()->isClassRejected(namespaceName)) {
@@ -784,8 +757,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
*metaClass += AbstractMetaAttributes::Public;
- m_currentClass = metaClass;
-
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
qCDebug(lcShiboken)
<< QStringLiteral("namespace '%1.%2'").arg(metaClass->package(), namespaceItem->name());
@@ -794,15 +765,14 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
traverseEnums(namespaceItem, metaClass, namespaceItem->enumsDeclarations());
pushScope(namespaceItem);
- m_namespacePrefix = currentScope()->qualifiedName().join(colonColon());
const ClassList &classes = namespaceItem->classes();
for (const ClassModelItem &cls : classes) {
- AbstractMetaClass* mjc = traverseClass(dom, cls);
+ AbstractMetaClass* mjc = traverseClass(dom, cls, metaClass);
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
- addAbstractMetaClass(mjc);
+ addAbstractMetaClass(mjc, cls.data());
}
}
@@ -810,11 +780,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
// specific typedefs to be used as classes.
const TypeDefList typeDefs = namespaceItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- AbstractMetaClass *cls = traverseTypeDef(dom, typeDef);
+ AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass);
if (cls) {
metaClass->addInnerClass(cls);
cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls);
+ addAbstractMetaClass(cls, typeDef.data());
}
}
@@ -824,14 +794,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
- addAbstractMetaClass(mjc);
+ addAbstractMetaClass(mjc, ni.data());
}
}
- m_currentClass = 0;
-
popScope();
- m_namespacePrefix = currentScope()->qualifiedName().join(colonColon());
if (!type->include().isValid())
setInclude(type, namespaceItem->fileName());
@@ -872,8 +839,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
QString enumName = enumItem->name();
QString className;
- if (m_currentClass)
- className = m_currentClass->typeEntry()->qualifiedCppName();
+ if (enclosing)
+ className = enclosing->typeEntry()->qualifiedCppName();
QString rejectReason;
if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) {
@@ -883,8 +850,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
return 0;
}
- const bool rejectionWarning = !m_currentClass
- || (m_currentClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang);
+ const bool rejectionWarning = !enclosing
+ || (enclosing->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang);
if (!typeEntry) {
if (rejectionWarning)
@@ -983,15 +950,16 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
}
AbstractMetaClass* AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &dom,
- const TypeDefModelItem &typeDef)
+ const TypeDefModelItem &typeDef,
+ AbstractMetaClass *currentClass)
{
TypeDatabase* types = TypeDatabase::instance();
QString className = stripTemplateArgs(typeDef->name());
QString fullClassName = className;
// we have an inner class
- if (m_currentClass) {
- fullClassName = stripTemplateArgs(m_currentClass->typeEntry()->qualifiedCppName())
+ if (currentClass) {
+ fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName())
+ colonColon() + fullClassName;
}
@@ -1011,9 +979,6 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
if (!type)
return 0;
- if (type->isObject())
- static_cast<ObjectTypeEntry *>(type)->setQObject(isQObject(dom, stripTemplateArgs(typeDef->type().qualifiedName().join(colonColon()))));
-
AbstractMetaClass *metaClass = new AbstractMetaClass;
metaClass->setTypeDef(true);
metaClass->setTypeEntry(type);
@@ -1041,19 +1006,20 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs()
metaClass->setBaseClassNames(QStringList(te->sourceType()));
*metaClass += AbstractMetaAttributes::Public;
fillAddedFunctions(metaClass);
- addAbstractMetaClass(metaClass);
+ addAbstractMetaClass(metaClass, nullptr);
}
}
AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem &dom,
- const ClassModelItem &classItem)
+ const ClassModelItem &classItem,
+ AbstractMetaClass *currentClass)
{
QString className = stripTemplateArgs(classItem->name());
QString fullClassName = className;
// we have inner an class
- if (m_currentClass) {
- fullClassName = stripTemplateArgs(m_currentClass->typeEntry()->qualifiedCppName())
+ if (currentClass) {
+ fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName())
+ colonColon() + fullClassName;
}
@@ -1076,9 +1042,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
return 0;
}
- if (type->isObject())
- ((ObjectTypeEntry*)type)->setQObject(isQObject(dom, fullClassName));
-
AbstractMetaClass *metaClass = new AbstractMetaClass;
metaClass->setTypeEntry(type);
@@ -1097,9 +1060,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
if (type->stream())
metaClass->setStream(true);
- AbstractMetaClass* oldCurrentClass = m_currentClass;
- m_currentClass = metaClass;
-
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
const QString message = type->isContainer()
? QStringLiteral("container: '%1'").arg(fullClassName)
@@ -1126,11 +1086,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
{
const ClassList &innerClasses = classItem->classes();
for (const ClassModelItem &ci : innerClasses) {
- AbstractMetaClass *cl = traverseClass(dom, ci);
+ AbstractMetaClass *cl = traverseClass(dom, ci, metaClass);
if (cl) {
cl->setEnclosingClass(metaClass);
metaClass->addInnerClass(cl);
- m_metaClasses << cl;
+ addAbstractMetaClass(cl, ci.data());
}
}
@@ -1140,16 +1100,13 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
// specific typedefs to be used as classes.
const TypeDefList typeDefs = classItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- AbstractMetaClass *cls = traverseTypeDef(dom, typeDef);
+ AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass);
if (cls) {
cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls);
+ addAbstractMetaClass(cls, typeDef.data());
}
}
-
- m_currentClass = oldCurrentClass;
-
// Set the default include file name
if (!type->include().isValid())
setInclude(type, classItem->fileName());
@@ -1170,48 +1127,22 @@ void AbstractMetaBuilderPrivate::traverseScopeMembers(ScopeModelItem item,
traverseClassMembers(ci);
}
-AbstractMetaClass* AbstractMetaBuilderPrivate::currentTraversedClass(ScopeModelItem item)
-{
- QString className = stripTemplateArgs(item->name());
- QString fullClassName = className;
-
- // This is an inner class
- if (m_currentClass)
- fullClassName = stripTemplateArgs(m_currentClass->typeEntry()->qualifiedCppName()) + colonColon() + fullClassName;
-
- AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, fullClassName);
- if (!metaClass)
- metaClass = AbstractMetaClass::findClass(m_templates, fullClassName);
-
- if (!metaClass)
- metaClass = AbstractMetaClass::findClass(m_smartPointers, fullClassName);
- return metaClass;
-}
-
void AbstractMetaBuilderPrivate::traverseClassMembers(ClassModelItem item)
{
- AbstractMetaClass* metaClass = currentTraversedClass(item);
+ AbstractMetaClass* metaClass = m_itemToClass.value(item.data());
if (!metaClass)
return;
- AbstractMetaClass* oldCurrentClass = m_currentClass;
- m_currentClass = metaClass;
-
// Class members
traverseScopeMembers(item, metaClass);
-
- m_currentClass = oldCurrentClass;
}
void AbstractMetaBuilderPrivate::traverseNamespaceMembers(NamespaceModelItem item)
{
- AbstractMetaClass* metaClass = currentTraversedClass(item);
+ AbstractMetaClass* metaClass = m_itemToClass.value(item.data());
if (!metaClass)
return;
- AbstractMetaClass* oldCurrentClass = m_currentClass;
- m_currentClass = metaClass;
-
// Namespace members
traverseScopeMembers(item, metaClass);
@@ -1219,7 +1150,6 @@ void AbstractMetaBuilderPrivate::traverseNamespaceMembers(NamespaceModelItem ite
for (const NamespaceModelItem &ni : item->namespaces())
traverseNamespaceMembers(ni);
- m_currentClass = oldCurrentClass;
}
static inline QString fieldSignatureWithType(const VariableModelItem &field)
@@ -1234,10 +1164,10 @@ static inline QString qualifiedFieldSignatureWithType(const QString &className,
}
AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModelItem &field,
- const AbstractMetaClass *cls)
+ AbstractMetaClass *cls)
{
QString fieldName = field->name();
- QString className = m_currentClass->typeEntry()->qualifiedCppName();
+ QString className = cls->typeEntry()->qualifiedCppName();
// Ignore friend decl.
if (field->isFriend())
@@ -1259,14 +1189,14 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModel
metaField->setEnclosingClass(cls);
TypeInfo fieldType = field->type();
- AbstractMetaType *metaType = translateType(fieldType);
+ AbstractMetaType *metaType = translateType(fieldType, cls);
if (!metaType) {
const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(colonColon());
- if (m_currentClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang) {
+ if (cls->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("skipping field '%1::%2' with unmatched type '%3'")
- .arg(m_currentClass->name(), fieldName, type);
+ .arg(cls->name(), fieldName, type);
}
delete metaField;
return 0;
@@ -1369,14 +1299,15 @@ static bool _compareAbstractMetaFunctions(const AbstractMetaFunction* func, cons
}
AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem,
- AbstractMetaClass::Attributes *constructorAttributes)
+ AbstractMetaClass::Attributes *constructorAttributes,
+ AbstractMetaClass *currentClass)
{
*constructorAttributes = 0;
AbstractMetaFunctionList result;
const FunctionList &scopeFunctionList = scopeItem->functions();
result.reserve(scopeFunctionList.size());
for (const FunctionModelItem &function : scopeFunctionList) {
- if (AbstractMetaFunction *metaFunction = traverseFunction(function)) {
+ if (AbstractMetaFunction *metaFunction = traverseFunction(function, currentClass)) {
result.append(metaFunction);
} else if (function->functionType() == CodeModel::Constructor) {
auto arguments = function->arguments();
@@ -1416,7 +1347,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
{
AbstractMetaAttributes::Attributes constructorAttributes;
const AbstractMetaFunctionList functions =
- classFunctionList(scopeItem, &constructorAttributes);
+ classFunctionList(scopeItem, &constructorAttributes, metaClass);
metaClass->setAttributes(metaClass->attributes() | constructorAttributes);
for (AbstractMetaFunction *metaFunction : functions){
@@ -1477,12 +1408,6 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
.arg(metaFunction->name(), metaClass->name());
}
- if (metaFunction->isSignal() && !metaClass->isQObject()) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("signal '%1' in non-QObject class '%2'")
- .arg(metaFunction->name(), metaClass->name());
- }
-
if (metaFunction->isConversionOperator())
fixReturnTypeOfConversionOperator(metaFunction);
@@ -1506,10 +1431,10 @@ void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass
{
// Add the functions added by the typesystem
const AddedFunctionList &addedFunctions = metaClass->typeEntry()->addedFunctions();
- for (const AddedFunction &addedFunc : addedFunctions) {
+ for (const AddedFunctionPtr &addedFunc : addedFunctions) {
if (!traverseFunction(addedFunc, metaClass)) {
qFatal("Unable to traverse function \"%s\" added to \"%s\".",
- qPrintable(addedFunc.name()), qPrintable(metaClass->name()));
+ qPrintable(addedFunc->name()), qPrintable(metaClass->name()));
}
}
}
@@ -1663,29 +1588,19 @@ void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
}
}
-AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunction& addedFunc)
+AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc)
{
return traverseFunction(addedFunc, 0);
}
-AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunction& addedFunc,
+AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc,
AbstractMetaClass *metaClass)
{
- AbstractMetaFunction *metaFunction = new AbstractMetaFunction;
- metaFunction->setConstant(addedFunc.isConstant());
- metaFunction->setName(addedFunc.name());
- metaFunction->setOriginalName(addedFunc.name());
- AbstractMetaClass::Attributes visibility =
- addedFunc.access() == AddedFunction::Public
- ? AbstractMetaAttributes::Public : AbstractMetaAttributes::Protected;
- metaFunction->setVisibility(visibility);
- metaFunction->setUserAdded(true);
- AbstractMetaAttributes::Attribute isStatic = addedFunc.isStatic() ? AbstractMetaFunction::Static : AbstractMetaFunction::None;
- metaFunction->setAttributes(metaFunction->attributes() | AbstractMetaAttributes::FinalInTargetLang | isStatic);
- metaFunction->setType(translateType(addedFunc.returnType()));
-
-
- QVector<AddedFunction::TypeInfo> args = addedFunc.arguments();
+ AbstractMetaFunction *metaFunction = new AbstractMetaFunction(addedFunc);
+ metaFunction->setType(translateType(addedFunc->returnType()));
+
+
+ QVector<AddedFunction::TypeInfo> args = addedFunc->arguments();
AbstractMetaArgumentList metaArguments;
for (int i = 0; i < args.count(); ++i) {
@@ -1695,7 +1610,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
if (Q_UNLIKELY(!type)) {
qCWarning(lcShiboken,
"Unable to translate type \"%s\" of argument %d of added function \"%s\".",
- qPrintable(typeInfo.name), i + 1, qPrintable(addedFunc.name()));
+ qPrintable(typeInfo.name), i + 1, qPrintable(addedFunc->name()));
delete metaFunction;
return nullptr;
}
@@ -1734,11 +1649,11 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
//use relace-default-expression for set default value
QString replacedExpression;
- if (m_currentClass)
- replacedExpression = metaFunction->replacedDefaultExpression(m_currentClass, i + 1);
+ if (metaClass)
+ replacedExpression = metaFunction->replacedDefaultExpression(metaClass, i + 1);
if (!replacedExpression.isEmpty()) {
- if (!metaFunction->removedDefaultExpression(m_currentClass, i + 1)) {
+ if (!metaFunction->removedDefaultExpression(metaClass, i + 1)) {
metaArg->setDefaultValueExpression(replacedExpression);
metaArg->setOriginalDefaultValueExpression(replacedExpression);
}
@@ -1747,7 +1662,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
metaFunction->setOriginalAttributes(metaFunction->attributes());
if (!metaArguments.isEmpty())
- fixArgumentNames(metaFunction, metaFunction->modifications(m_currentClass));
+ fixArgumentNames(metaFunction, metaFunction->modifications(metaClass));
if (metaClass) {
const AbstractMetaArgumentList fargs = metaFunction->arguments();
@@ -1864,20 +1779,21 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func
return true;
}
-AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem)
+AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem,
+ AbstractMetaClass *currentClass)
{
if (functionItem->isDeleted() || !functionItem->templateParameters().isEmpty())
return nullptr;
QString functionName = functionItem->name();
QString className;
- if (m_currentClass) {
+ if (currentClass) {
// Clang: Skip qt_metacast(), qt_metacall(), expanded from Q_OBJECT
// and overridden metaObject(), QGADGET helpers
if (functionName == QLatin1String("qt_check_for_QGADGET_macro")
|| functionName.startsWith(QLatin1String("qt_meta"))) {
return nullptr;
}
- className = m_currentClass->typeEntry()->qualifiedCppName();
+ className = currentClass->typeEntry()->qualifiedCppName();
if (functionName == QLatin1String("metaObject") && className != QLatin1String("QObject"))
return nullptr;
}
@@ -1960,7 +1876,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
break;
case AbstractMetaFunction::ConstructorFunction:
metaFunction->setExplicit(functionItem->isExplicit());
- metaFunction->setName(m_currentClass->name());
+ metaFunction->setName(currentClass->name());
break;
default: {
TypeInfo returnType = functionItem->type();
@@ -1973,7 +1889,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
AbstractMetaType *type = nullptr;
if (!returnType.isVoid()) {
- type = translateType(returnType, true, &errorMessage);
+ type = translateType(returnType, currentClass, true, &errorMessage);
if (!type) {
const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
qCWarning(lcShiboken, "%s",
@@ -2009,12 +1925,12 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- AbstractMetaType *metaType = translateType(arg->type(), true, &errorMessage);
+ AbstractMetaType *metaType = translateType(arg->type(), currentClass, true, &errorMessage);
if (!metaType) {
// If an invalid argument has a default value, simply remove it
if (arg->defaultValue()) {
- if (!m_currentClass
- || (m_currentClass->typeEntry()->codeGeneration()
+ if (!currentClass
+ || (currentClass->typeEntry()->codeGeneration()
& TypeEntry::GenerateTargetLang)) {
qCWarning(lcShiboken).noquote().nospace()
<< "Stripping argument #" << (i + 1) << " of "
@@ -2046,7 +1962,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
metaFunction->setArguments(metaArguments);
- const FunctionModificationList functionMods = metaFunction->modifications(m_currentClass);
+ const FunctionModificationList functionMods = metaFunction->modifications(currentClass);
for (const FunctionModification &mod : functionMods) {
if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified)
@@ -2062,8 +1978,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
//use relace-default-expression for set default value
QString replacedExpression;
- if (m_currentClass) {
- replacedExpression = metaFunction->replacedDefaultExpression(m_currentClass, i + 1);
+ if (currentClass) {
+ replacedExpression = metaFunction->replacedDefaultExpression(currentClass, i + 1);
} else {
if (!functionMods.isEmpty()) {
QVector<ArgumentModification> argMods = functionMods.constFirst().argument_mods;
@@ -2075,10 +1991,10 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
bool hasDefaultValue = false;
if (arg->defaultValue() || !replacedExpression.isEmpty()) {
QString expr = arg->defaultValueExpression();
- expr = fixDefaultValue(arg, metaArg->type(), metaFunction, m_currentClass, i);
+ expr = fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i);
metaArg->setOriginalDefaultValueExpression(expr);
- if (metaFunction->removedDefaultExpression(m_currentClass, i + 1)) {
+ if (metaFunction->removedDefaultExpression(currentClass, i + 1)) {
expr.clear();
} else if (!replacedExpression.isEmpty()) {
expr = replacedExpression;
@@ -2092,7 +2008,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
&& !metaArg->hasName()
&& !metaFunction->isOperatorOverload()
&& !metaFunction->isSignal()
- && metaFunction->argumentName(i+1, false, m_currentClass).isEmpty()) {
+ && metaFunction->argumentName(i + 1, false, currentClass).isEmpty()) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("Argument %1 on function '%2::%3' has default expression but does not have name.")
.arg(i+1).arg(className, metaFunction->minimalSignature());
@@ -2110,9 +2026,9 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
}
// Determine class special functions
- if (m_currentClass && metaFunction->arguments().size() == 1) {
+ if (currentClass && metaFunction->arguments().size() == 1) {
const AbstractMetaType *argType = metaFunction->arguments().constFirst()->type();
- if (argType->typeEntry() == m_currentClass->typeEntry() && argType->indirections() == 0) {
+ if (argType->typeEntry() == currentClass->typeEntry() && argType->indirections() == 0) {
if (metaFunction->name() == QLatin1String("operator=")) {
switch (argType->referenceType()) {
case NoReference:
@@ -2212,10 +2128,11 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
}
AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
bool resolveType,
QString *errorMessage)
{
- return translateTypeStatic(_typei, m_currentClass, this, resolveType, errorMessage);
+ return translateTypeStatic(_typei, currentClass, this, resolveType, errorMessage);
}
AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
@@ -2575,38 +2492,6 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite
return expr;
}
-bool AbstractMetaBuilderPrivate::isQObject(const FileModelItem &dom, const QString &qualifiedName)
-{
- if (qualifiedName == QLatin1String("QObject"))
- return true;
-
- ClassModelItem classItem = dom->findClass(qualifiedName);
-
- if (!classItem) {
- QStringList names = qualifiedName.split(colonColon());
- NamespaceModelItem ns = dom;
- for (int i = 0; i < names.size() - 1 && ns; ++i)
- ns = ns->findNamespace(names.at(i));
- if (ns && names.size() >= 2)
- classItem = ns->findClass(names.at(names.size() - 1));
- }
-
- if (!classItem)
- return false;
-
- if (classItem->extendsClass(QLatin1String("QObject")))
- return true;
-
- const QVector<_ClassModelItem::BaseClass> &baseClasses = classItem->baseClasses();
- for (const _ClassModelItem::BaseClass &baseClass : baseClasses) {
- if (isQObject(dom, baseClass.name))
- return true;
- }
-
- return false;
-}
-
-
bool AbstractMetaBuilderPrivate::isEnum(const FileModelItem &dom, const QStringList& qualified_name)
{
CodeModelItem item = dom->model()->findItem(qualified_name, dom);
@@ -2910,21 +2795,19 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
void AbstractMetaBuilderPrivate::parseQ_Property(AbstractMetaClass *metaClass,
const QStringList &declarations)
{
- for (int i = 0; i < declarations.size(); ++i) {
- const QString &p = declarations.at(i);
-
- QStringList l = p.split(QLatin1Char(' '));
+ const QStringList scopes = currentScope()->qualifiedName();
+ for (int i = 0; i < declarations.size(); ++i) {
+ const auto propertyTokens = declarations.at(i).splitRef(QLatin1Char(' '));
- QStringList qualifiedScopeName = currentScope()->qualifiedName();
- AbstractMetaType* type = 0;
- QString scope;
- for (int j = qualifiedScopeName.size(); j >= 0; --j) {
- scope = j > 0 ? QStringList(qualifiedScopeName.mid(0, j)).join(colonColon()) + colonColon() : QString();
+ AbstractMetaType *type = nullptr;
+ for (int j = scopes.size(); j >= 0; --j) {
+ QStringList qualifiedName = scopes.mid(0, j);
+ qualifiedName.append(propertyTokens.at(0).toString());
TypeInfo info;
- info.setQualifiedName((scope + l.at(0)).split(colonColon()));
+ info.setQualifiedName(qualifiedName);
- type = translateType(info);
+ type = translateType(info, metaClass);
if (type)
break;
}
@@ -2932,23 +2815,23 @@ void AbstractMetaBuilderPrivate::parseQ_Property(AbstractMetaClass *metaClass,
if (!type) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("Unable to decide type of property: '%1' in class '%2'")
- .arg(l.at(0), metaClass->name());
+ .arg(propertyTokens.at(0).toString(), metaClass->name());
continue;
}
QPropertySpec* spec = new QPropertySpec(type->typeEntry());
- spec->setName(l.at(1));
+ spec->setName(propertyTokens.at(1).toString());
spec->setIndex(i);
- for (int pos = 2; pos + 1 < l.size(); pos += 2) {
- if (l.at(pos) == QLatin1String("READ"))
- spec->setRead(l.at(pos + 1));
- else if (l.at(pos) == QLatin1String("WRITE"))
- spec->setWrite(l.at(pos + 1));
- else if (l.at(pos) == QLatin1String("DESIGNABLE"))
- spec->setDesignable(l.at(pos + 1));
- else if (l.at(pos) == QLatin1String("RESET"))
- spec->setReset(l.at(pos + 1));
+ for (int pos = 2; pos + 1 < propertyTokens.size(); pos += 2) {
+ if (propertyTokens.at(pos) == QLatin1String("READ"))
+ spec->setRead(propertyTokens.at(pos + 1).toString());
+ else if (propertyTokens.at(pos) == QLatin1String("WRITE"))
+ spec->setWrite(propertyTokens.at(pos + 1).toString());
+ else if (propertyTokens.at(pos) == QLatin1String("DESIGNABLE"))
+ spec->setDesignable(propertyTokens.at(pos + 1).toString());
+ else if (propertyTokens.at(pos) == QLatin1String("RESET"))
+ spec->setReset(propertyTokens.at(pos + 1).toString());
}
metaClass->addPropertySpec(spec);
@@ -3214,16 +3097,60 @@ void AbstractMetaBuilder::setGlobalHeader(const QString& globalHeader)
d->m_globalHeader = QFileInfo(globalHeader);
}
+void AbstractMetaBuilder::setHeaderPaths(const HeaderPaths &hp)
+{
+ for (const auto & h: hp) {
+ if (h.type != HeaderType::Framework && h.type != HeaderType::FrameworkSystem)
+ d->m_headerPaths.append(QFile::decodeName(h.path));
+ }
+}
+
void AbstractMetaBuilder::setSkipDeprecated(bool value)
{
d->m_skipDeprecated = value;
}
+// PYSIDE-975: When receiving an absolute path name from the code model, try
+// to resolve it against the include paths set on shiboken in order to recreate
+// relative paths like #include <foo/bar.h>.
+
+static inline bool isFileSystemSlash(QChar c)
+{
+ return c == QLatin1Char('/') || c == QLatin1Char('\\');
+}
+
+static bool matchHeader(const QString &headerPath, const QString &fileName)
+{
+#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN)
+ static const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
+#else
+ static const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
+#endif
+ const int pathSize = headerPath.size();
+ return fileName.size() > pathSize
+ && isFileSystemSlash(fileName.at(pathSize))
+ && fileName.startsWith(headerPath, caseSensitivity);
+}
+
void AbstractMetaBuilderPrivate::setInclude(TypeEntry *te, const QString &fileName) const
{
- QFileInfo info(fileName);
- if (m_globalHeader.fileName() != info.fileName())
- te->setInclude(Include(Include::IncludePath, info.fileName()));
+ auto it = m_resolveIncludeHash.find(fileName);
+ if (it == m_resolveIncludeHash.end()) {
+ QFileInfo info(fileName);
+ if (m_globalHeader.fileName() == info.fileName())
+ return;
+
+ int bestMatchLength = 0;
+ for (const auto &headerPath : m_headerPaths) {
+ if (headerPath.size() > bestMatchLength && matchHeader(headerPath, fileName))
+ bestMatchLength = headerPath.size();
+ }
+ const QString include = bestMatchLength > 0
+ ? fileName.right(fileName.size() - bestMatchLength - 1)
+ : info.fileName();
+ it = m_resolveIncludeHash.insert(fileName, {Include::IncludePath, include});
+ }
+ te->setInclude(it.value());
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index ed89060ac..1789ca2aa 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -30,6 +30,7 @@
#define ABSTRACTMETABUILDER_H
#include "abstractmetalang_typedefs.h"
+#include "header_paths.h"
#include "dependency.h"
#include "clangparser/compilersupport.h"
@@ -85,6 +86,7 @@ public:
* filled.
*/
void setGlobalHeader(const QString& globalHeader);
+ void setHeaderPaths(const HeaderPaths &h);
void setSkipDeprecated(bool value);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index d8203a586..3c0039f0e 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -60,15 +60,17 @@ public:
ScopeModelItem currentScope() const { return m_scopes.constLast(); }
- AbstractMetaClass *argumentToClass(const ArgumentModelItem &);
+ AbstractMetaClass *argumentToClass(const ArgumentModelItem &,
+ AbstractMetaClass *currentClass);
- void addAbstractMetaClass(AbstractMetaClass *cls);
+ void addAbstractMetaClass(AbstractMetaClass *cls, const _CodeModelItem *item);
AbstractMetaClass *traverseTypeDef(const FileModelItem &dom,
- const TypeDefModelItem &typeDef);
+ const TypeDefModelItem &typeDef,
+ AbstractMetaClass *currentClass);
void traverseTypesystemTypedefs();
AbstractMetaClass *traverseClass(const FileModelItem &dom,
- const ClassModelItem &item);
- AbstractMetaClass *currentTraversedClass(ScopeModelItem item);
+ const ClassModelItem &item,
+ AbstractMetaClass *currentClass);
void traverseScopeMembers(ScopeModelItem item, AbstractMetaClass *metaClass);
void traverseClassMembers(ClassModelItem scopeItem);
void traverseNamespaceMembers(NamespaceModelItem scopeItem);
@@ -80,24 +82,30 @@ public:
void traverseEnums(const ScopeModelItem &item, AbstractMetaClass *parent,
const QStringList &enumsDeclarations);
AbstractMetaFunctionList classFunctionList(const ScopeModelItem &scopeItem,
- AbstractMetaClass::Attributes *constructorAttributes);
+ AbstractMetaClass::Attributes *constructorAttributes,
+ AbstractMetaClass *currentClass);
AbstractMetaFunctionList templateClassFunctionList(const ScopeModelItem &scopeItem,
AbstractMetaClass *metaClass,
bool *constructorRejected);
void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent);
void applyFunctionModifications(AbstractMetaFunction* func);
void traverseFields(const ScopeModelItem &item, AbstractMetaClass *parent);
- void traverseStreamOperator(const FunctionModelItem &functionItem);
- void traverseOperatorFunction(const FunctionModelItem &item);
- AbstractMetaFunction* traverseFunction(const AddedFunction &addedFunc);
- AbstractMetaFunction* traverseFunction(const AddedFunction &addedFunc,
+ void traverseStreamOperator(const FunctionModelItem &functionItem,
+ AbstractMetaClass *currentClass);
+ void traverseOperatorFunction(const FunctionModelItem &item,
+ AbstractMetaClass *currentClass);
+ AbstractMetaFunction* traverseFunction(const AddedFunctionPtr &addedFunc);
+ AbstractMetaFunction* traverseFunction(const AddedFunctionPtr &addedFunc,
AbstractMetaClass *metaClass);
- AbstractMetaFunction *traverseFunction(const FunctionModelItem &function);
+ AbstractMetaFunction *traverseFunction(const FunctionModelItem &function,
+ AbstractMetaClass *currentClass);
AbstractMetaField *traverseField(const VariableModelItem &field,
- const AbstractMetaClass *cls);
+ AbstractMetaClass *cls);
void checkFunctionModifications();
- void registerHashFunction(const FunctionModelItem &functionItem);
- void registerToStringCapability(const FunctionModelItem &functionItem);
+ void registerHashFunction(const FunctionModelItem &functionItem,
+ AbstractMetaClass *currentClass);
+ void registerToStringCapability(const FunctionModelItem &functionItem,
+ AbstractMetaClass *currentClass);
/**
* A conversion operator function should not have its owner class as
@@ -124,6 +132,7 @@ public:
int argumentIndex);
AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo);
AbstractMetaType *translateType(const TypeInfo &type,
+ AbstractMetaClass *currentClass,
bool resolveType = true,
QString *errorMessage = nullptr);
static AbstractMetaType *translateTypeStatic(const TypeInfo &type,
@@ -149,9 +158,6 @@ public:
bool isQObject(const FileModelItem &dom, const QString &qualifiedName);
bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName);
- void fixQObjectForScope(const FileModelItem &dom, const TypeDatabase *types,
- const NamespaceModelItem &item);
-
void sortLists();
AbstractMetaArgumentList reverseList(const AbstractMetaArgumentList &list);
void setInclude(TypeEntry *te, const QString &fileName) const;
@@ -163,6 +169,7 @@ public:
AbstractMetaClassList m_metaClasses;
AbstractMetaClassList m_templates;
AbstractMetaClassList m_smartPointers;
+ QHash<const _CodeModelItem *, AbstractMetaClass *> m_itemToClass;
AbstractMetaFunctionList m_globalFunctions;
AbstractMetaEnumList m_globalEnums;
@@ -175,14 +182,14 @@ public:
QHash<const TypeEntry *, AbstractMetaEnum *> m_enums;
- AbstractMetaClass *m_currentClass;
QList<ScopeModelItem> m_scopes;
- QString m_namespacePrefix;
QSet<AbstractMetaClass *> m_setupInheritanceDone;
QString m_logDirectory;
QFileInfo m_globalHeader;
+ QStringList m_headerPaths;
+ mutable QHash<QString, Include> m_resolveIncludeHash;
bool m_skipDeprecated;
};
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 95f8048cd..512efef58 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -288,8 +288,7 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con
if (m_typeEntry->isObject()) {
if (indirections() == 0 && m_referenceType == NoReference)
return ValuePattern;
- return static_cast<const ComplexTypeEntry *>(m_typeEntry)->isQObject()
- ? QObjectPattern : ObjectPattern;
+ return ObjectPattern;
}
if (m_typeEntry->isContainer() && indirections() == 0)
@@ -322,8 +321,7 @@ void AbstractMetaType::decideUsagePattern()
// const-references to pointers can be passed as pointers
setReferenceType(NoReference);
setConstant(false);
- pattern = static_cast<const ComplexTypeEntry *>(m_typeEntry)->isQObject()
- ? QObjectPattern : ObjectPattern;
+ pattern = ObjectPattern;
}
setTypeUsagePattern(pattern);
}
@@ -454,10 +452,32 @@ QDebug operator<<(QDebug d, const AbstractMetaArgument *aa)
* AbstractMetaFunction
*/
+AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) :
+ AbstractMetaFunction()
+{
+ m_addedFunction = addedFunc;
+ setConstant(addedFunc->isConstant());
+ setName(addedFunc->name());
+ setOriginalName(addedFunc->name());
+ auto atts = attributes() | AbstractMetaAttributes::FinalInTargetLang;
+ switch (addedFunc->access()) {
+ case AddedFunction::InvalidAccess:
+ break;
+ case AddedFunction::Protected:
+ atts |= AbstractMetaAttributes::Protected;
+ break;
+ case AddedFunction::Public:
+ atts |= AbstractMetaAttributes::Public;
+ break;
+ }
+ if (addedFunc->isStatic())
+ atts |= AbstractMetaFunction::Static;
+ setAttributes(atts);
+}
+
AbstractMetaFunction::AbstractMetaFunction()
: m_constant(false),
m_reverse(false),
- m_userAdded(false),
m_explicit(false),
m_pointerOperator(false),
m_isCallOperator(false)
@@ -581,6 +601,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const
cpy->setExceptionSpecification(m_exceptionSpecification);
cpy->setAllowThreadModification(m_allowThreadModification);
cpy->setExceptionHandlingModification(m_exceptionHandlingModification);
+ cpy->m_addedFunction = m_addedFunction;
for (AbstractMetaArgument *arg : m_arguments)
cpy->addArgument(arg->copy());
@@ -944,6 +965,8 @@ QString AbstractMetaFunction::debugSignature() const
FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass* implementor) const
{
+ if (!m_addedFunction.isNull())
+ return m_addedFunction->modifications;
if (!implementor)
implementor = ownerClass();
@@ -1281,7 +1304,7 @@ void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const
d << " [const]";
if (m_reverse)
d << " [reverse]";
- if (m_userAdded)
+ if (isUserAdded())
d << " [userAdded]";
if (m_explicit)
d << " [explicit]";
@@ -1636,9 +1659,14 @@ bool AbstractMetaClass::isNamespace() const
return m_typeEntry->isNamespace();
}
+static bool qObjectPredicate(const AbstractMetaClass *c)
+{
+ return c->qualifiedCppName() == QLatin1String("QObject");
+}
+
bool AbstractMetaClass::isQObject() const
{
- return m_typeEntry->isQObject();
+ return qObjectPredicate(this) || recurseClassHierarchy(this, qObjectPredicate) != nullptr;
}
QString AbstractMetaClass::qualifiedCppName() const
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 0c652a39a..ef4cef2b4 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -301,7 +301,6 @@ public:
EnumPattern,
ValuePattern,
ObjectPattern,
- QObjectPattern,
ValuePointerPattern,
NativePointerPattern,
NativePointerAsArrayPattern, // "int*" as "int[]"
@@ -376,12 +375,6 @@ public:
return m_pattern == EnumPattern;
}
- // returns true if the type is used as a QObject *
- bool isQObject() const
- {
- return m_pattern == QObjectPattern;
- }
-
// returns true if the type is used as an object, e.g. Xxx *
bool isObject() const
{
@@ -790,6 +783,7 @@ public:
Q_FLAG(CompareResultFlag)
AbstractMetaFunction();
+ explicit AbstractMetaFunction(const AddedFunctionPtr &addedFunc);
~AbstractMetaFunction();
QString name() const
@@ -1010,14 +1004,7 @@ public:
}
/// Returns true if the AbstractMetaFunction was added by the user via the type system description.
- bool isUserAdded() const
- {
- return m_userAdded;
- }
- void setUserAdded(bool userAdded)
- {
- m_userAdded = userAdded;
- }
+ bool isUserAdded() const { return !m_addedFunction.isNull(); }
QString toString() const
{
@@ -1125,9 +1112,9 @@ private:
const AbstractMetaClass *m_declaringClass = nullptr;
QPropertySpec *m_propertySpec = nullptr;
AbstractMetaArgumentList m_arguments;
+ AddedFunctionPtr m_addedFunction;
uint m_constant : 1;
uint m_reverse : 1;
- uint m_userAdded : 1;
uint m_explicit : 1;
uint m_pointerOperator : 1;
uint m_isCallOperator : 1;
diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp
index e301d891f..fbe7664e9 100644
--- a/sources/shiboken2/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken2/ApiExtractor/apiextractor.cpp
@@ -224,6 +224,7 @@ bool ApiExtractor::run()
m_builder->setLogDirectory(m_logDirectory);
m_builder->setGlobalHeader(m_cppFileName);
m_builder->setSkipDeprecated(m_skipDeprecated);
+ m_builder->setHeaderPaths(m_includePaths);
QByteArrayList arguments;
arguments.reserve(m_includePaths.size() + 1);
for (const HeaderPath &headerPath : qAsConst(m_includePaths))
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index fa4c75743..fdae2359b 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -167,6 +167,12 @@ QString msgSkippingFunction(const FunctionModelItem &functionItem,
return result;
}
+QString msgCannotResolveEntity(const QString &name, const QString &reason)
+{
+ return QLatin1String("Cannot resolve entity \"") + name
+ + QLatin1String("\": ") + reason;
+}
+
QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason)
{
return function + QLatin1String(": Cannot use parameter ")
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
index 539332aef..30b13fbf8 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -68,6 +68,8 @@ QString msgUnmatchedReturnType(const FunctionModelItem &functionItem,
QString msgSkippingFunction(const FunctionModelItem &functionItem,
const QString &signature, const QString &why);
+QString msgCannotResolveEntity(const QString &name, const QString &reason);
+
QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason);
QString msgUnableToTranslateType(const QString &t, const QString &why);
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index 8bc9b24ac..9a845b04a 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -83,37 +83,35 @@ FileModelItem CodeModel::findFile(const QString &name) const
return findModelItem(m_files, name);
}
-CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, CodeModelItem scope) const
-{
- for (int i = 0; i < qualifiedName.size(); ++i) {
- // ### Extend to look for members etc too.
- const QString &name = qualifiedName.at(i);
-
- if (NamespaceModelItem ns = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) {
- if (NamespaceModelItem tmp_ns = ns->findNamespace(name)) {
- scope = tmp_ns;
- continue;
- }
- }
-
- if (ScopeModelItem ss = qSharedPointerDynamicCast<_ScopeModelItem>(scope)) {
- if (ClassModelItem cs = ss->findClass(name)) {
- scope = cs;
- } else if (EnumModelItem es = ss->findEnum(name)) {
- if (i == qualifiedName.size() - 1)
- return es;
- } else if (TypeDefModelItem tp = ss->findTypeDef(name)) {
- if (i == qualifiedName.size() - 1)
- return tp;
- } else {
- // If we don't find the name in the scope chain we
- // need to return an empty item to indicate failure...
- return CodeModelItem();
+static CodeModelItem findRecursion(const ScopeModelItem &scope,
+ const QStringList &qualifiedName, int segment = 0)
+{
+ const QString &nameSegment = qualifiedName.at(segment);
+ if (segment == qualifiedName.size() - 1) { // Leaf item
+ if (ClassModelItem cs = scope->findClass(nameSegment))
+ return cs;
+ if (EnumModelItem es = scope->findEnum(nameSegment))
+ return es;
+ if (TypeDefModelItem tp = scope->findTypeDef(nameSegment))
+ return tp;
+ return CodeModelItem();
+ }
+ if (auto nestedClass = scope->findClass(nameSegment))
+ return findRecursion(nestedClass, qualifiedName, segment + 1);
+ if (auto namespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) {
+ for (const auto &nestedNamespace : namespaceItem->namespaces()) {
+ if (nestedNamespace->name() == nameSegment) {
+ if (auto item = findRecursion(nestedNamespace, qualifiedName, segment + 1))
+ return item;
}
}
}
+ return CodeModelItem();
+}
- return scope;
+CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const
+{
+ return findRecursion(scope, qualifiedName);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -160,7 +158,7 @@ bool TypeInfo::isVoid() const
&& m_qualifiedName.constFirst() == QLatin1String("void");
}
-TypeInfo TypeInfo::resolveType(TypeInfo const &__type, CodeModelItem __scope)
+TypeInfo TypeInfo::resolveType(TypeInfo const &__type, const ScopeModelItem &__scope)
{
CodeModel *__model = __scope->model();
Q_ASSERT(__model != 0);
@@ -168,7 +166,7 @@ TypeInfo TypeInfo::resolveType(TypeInfo const &__type, CodeModelItem __scope)
return TypeInfo::resolveType(__model->findItem(__type.qualifiedName(), __scope), __type, __scope);
}
-TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, CodeModelItem __scope)
+TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, const ScopeModelItem &__scope)
{
// Copy the type and replace with the proper qualified name. This
// only makes sence to do if we're actually getting a resolved
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index 0296a8cb2..64415e07b 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -82,7 +82,7 @@ public:
void addFile(FileModelItem item);
FileModelItem findFile(const QString &name) const;
- CodeModelItem findItem(const QStringList &qualifiedName, CodeModelItem scope) const;
+ CodeModelItem findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const;
private:
FileList m_files;
@@ -202,7 +202,7 @@ public:
QString toString() const;
static TypeInfo combine(const TypeInfo &__lhs, const TypeInfo &__rhs);
- static TypeInfo resolveType(TypeInfo const &__type, CodeModelItem __scope);
+ static TypeInfo resolveType(TypeInfo const &__type, const ScopeModelItem &__scope);
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const;
@@ -219,7 +219,7 @@ public:
private:
friend class TypeInfoTemplateArgumentHandler;
- static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, CodeModelItem __scope);
+ static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, const ScopeModelItem &__scope);
QStringList m_qualifiedName;
QStringList m_arrayElements;
diff --git a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
index e100ef493..a36cc17de 100644
--- a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
@@ -1,9 +1,3 @@
-find_package(Qt5Core)
-find_package(Qt5Gui)
-find_package(Qt5Test)
-find_package(Qt5Xml)
-find_package(Qt5XmlPatterns)
-
set(CMAKE_AUTORCC ON)
macro(declare_test testname)
@@ -15,19 +9,13 @@ macro(declare_test testname)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${testname}.qrc")
list(APPEND SOURCES "${testname}.qrc")
endif ()
+
add_executable(${testname} ${SOURCES})
- include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
- ${apiextractor_SOURCE_DIR}
- ${Qt5Test_INCLUDE_DIRS}
- )
- link_directories(${APIEXTRACTOR_EXTRA_LINK_DIRECTORIES})
- target_link_libraries(${testname}
- ${Qt5XmlPatterns_LIBRARIES}
- ${Qt5Test_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- apiextractor)
+ target_include_directories(${testname} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${apiextractor_SOURCE_DIR}
+ )
+ target_link_libraries(${testname} PRIVATE apiextractor Qt5::Test)
add_test(${testname} ${testname})
if (INSTALL_TESTS)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${testname}
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
index fc67ebba5..63434b3a5 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
@@ -85,7 +85,6 @@ void TestAbstractMetaType::testConstCharPtrType()
QVERIFY(!rtype->isObject());
QVERIFY(!rtype->isPrimitive()); // const char* differs from char, so it's not considered a primitive type by apiextractor
QVERIFY(rtype->isNativePointer());
- QVERIFY(!rtype->isQObject());
QCOMPARE(rtype->referenceType(), NoReference);
QVERIFY(!rtype->isValue());
QVERIFY(!rtype->isValuePointer());
@@ -159,7 +158,6 @@ void TestAbstractMetaType::testCharType()
QVERIFY(!rtype->isObject());
QVERIFY(rtype->isPrimitive());
QVERIFY(!rtype->isNativePointer());
- QVERIFY(!rtype->isQObject());
QCOMPARE(rtype->referenceType(), NoReference);
QVERIFY(!rtype->isValue());
QVERIFY(!rtype->isValuePointer());
diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
index db49942c9..8c443527e 100644
--- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
@@ -71,26 +71,32 @@ void TestAddFunction::testParsingFuncNameAndConstness()
void TestAddFunction::testAddFunction()
{
- const char cppCode[] = "struct B {}; struct A { void a(int); };\n";
- const char xmlCode[] = "\
- <typesystem package='Foo'>\n\
- <primitive-type name='int'/>\n\
- <primitive-type name='float'/>\n\
- <value-type name='B'/>\n\
- <value-type name='A'>\n\
- <add-function signature='b(int, float = 4.6, const B&amp;)' return-type='int' access='protected'>\n\
- </add-function>\n\
- </value-type>\n\
- </typesystem>\n";
+ const char cppCode[] = R"CPP(
+struct B {};
+struct A {
+ void a(int);
+};)CPP";
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <primitive-type name='int'/>
+ <primitive-type name='float'/>
+ <value-type name='B'/>
+ <value-type name='A'>
+ <add-function signature='b(int, float = 4.6, const B&amp;)' return-type='int' access='protected'/>
+ <add-function signature='operator()(int)' return-type='int' access='public'/>
+ </value-type>
+</typesystem>)XML";
+
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
TypeDatabase* typeDb = TypeDatabase::instance();
AbstractMetaClassList classes = builder->classes();
const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
QVERIFY(classA);
- QCOMPARE(classA->functions().count(), 4); // default ctor, default copy ctor, func a() and the added function
+ QCOMPARE(classA->functions().count(), 5); // default ctor, default copy ctor, func a() and the added functions
- AbstractMetaFunction* addedFunc = classA->functions().last();
+ auto addedFunc = classA->findFunction(QLatin1String("b"));
+ QVERIFY(addedFunc);
QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Protected);
QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
QVERIFY(addedFunc->isUserAdded());
@@ -109,6 +115,9 @@ void TestAddFunction::testAddFunction()
QCOMPARE(args[0]->type()->typeEntry(), returnType->typeEntry());
QCOMPARE(args[1]->defaultValueExpression(), QLatin1String("4.6"));
QCOMPARE(args[2]->type()->typeEntry(), typeDb->findType(QLatin1String("B")));
+
+ auto addedCallOperator = classA->findFunction(QLatin1String("operator()"));
+ QVERIFY(addedCallOperator);
}
void TestAddFunction::testAddFunctionConstructor()
@@ -265,7 +274,7 @@ void TestAddFunction::testAddFunctionAtModuleLevel()
QCOMPARE(addedFuncs.size(), 1);
- FunctionModificationList mods = typeDb->functionModifications(QLatin1String("func(int,int)"));
+ const FunctionModificationList mods = addedFuncs.constFirst()->modifications;
QCOMPARE(mods.size(), 1);
QVERIFY(mods.first().isCodeInjection());
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 4ce2790f5..a8c69d376 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -430,8 +430,8 @@ void TypeDatabase::addGlobalUserFunctions(const AddedFunctionList &functions)
AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const
{
AddedFunctionList addedFunctions;
- for (const AddedFunction &func : m_globalUserFunctions) {
- if (func.name() == name)
+ for (const AddedFunctionPtr &func : m_globalUserFunctions) {
+ if (func->name() == name)
addedFunctions.append(func);
}
return addedFunctions;
@@ -802,7 +802,6 @@ void ComplexTypeEntry::formatDebug(QDebug &d) const
{
TypeEntry::formatDebug(d);
FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
- FORMAT_BOOL("QObject", m_qobject)
FORMAT_BOOL("polymorphicBase", m_polymorphicBase)
FORMAT_BOOL("genericClass", m_genericClass)
FORMAT_BOOL("deleteInMainThread", m_deleteInMainThread)
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index ad97e40ee..318a52e2e 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -40,6 +40,7 @@
#include <QtCore/QStringAlgorithms>
#include <QtCore/QXmlStreamAttributes>
#include <QtCore/QXmlStreamReader>
+#include <QtCore/QXmlStreamEntityResolver>
#include <algorithm>
@@ -105,6 +106,8 @@ static inline QString yesAttributeValue() { return QStringLiteral("yes"); }
static inline QString trueAttributeValue() { return QStringLiteral("true"); }
static inline QString falseAttributeValue() { return QStringLiteral("false"); }
+static inline QString callOperator() { return QStringLiteral("operator()"); }
+
static QVector<CustomConversion *> customConversionsForReview;
// Set a regular expression for rejection from text. By legacy, those are fixed
@@ -437,12 +440,75 @@ static QString msgUnusedAttributes(const QStringRef &tag, const QXmlStreamAttrib
return result;
}
+// QXmlStreamEntityResolver::resolveEntity(publicId, systemId) is not
+// implemented; resolve via undeclared entities instead.
+class TypeSystemEntityResolver : public QXmlStreamEntityResolver
+{
+public:
+ explicit TypeSystemEntityResolver(const QString &currentPath) :
+ m_currentPath(currentPath) {}
+
+ QString resolveUndeclaredEntity(const QString &name) override;
+
+private:
+ QString readFile(const QString &entityName, QString *errorMessage) const;
+
+ const QString m_currentPath;
+ QHash<QString, QString> m_cache;
+};
+
+QString TypeSystemEntityResolver::readFile(const QString &entityName, QString *errorMessage) const
+{
+ QString fileName = entityName;
+ if (!fileName.contains(QLatin1Char('.')))
+ fileName += QLatin1String(".xml");
+ QString path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath);
+ if (!QFileInfo::exists(path)) // PySide2-specific hack
+ fileName.prepend(QLatin1String("typesystem_"));
+ path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath);
+ if (!QFileInfo::exists(path)) {
+ *errorMessage = QLatin1String("Unable to resolve: ") + entityName;
+ return QString();
+ }
+ QFile file(path);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ *errorMessage = msgCannotOpenForReading(file);
+ return QString();
+ }
+ QString result = QString::fromUtf8(file.readAll()).trimmed();
+ // Remove license header comments on which QXmlStreamReader chokes
+ if (result.startsWith(QLatin1String("<!--"))) {
+ const int commentEnd = result.indexOf(QLatin1String("-->"));
+ if (commentEnd != -1) {
+ result.remove(0, commentEnd + 3);
+ result = result.trimmed();
+ }
+ }
+ return result;
+}
+
+QString TypeSystemEntityResolver::resolveUndeclaredEntity(const QString &name)
+{
+ auto it = m_cache.find(name);
+ if (it == m_cache.end()) {
+ QString errorMessage;
+ it = m_cache.insert(name, readFile(name, &errorMessage));
+ if (it.value().isEmpty()) { // The parser will fail and display the line number.
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgCannotResolveEntity(name, errorMessage)));
+ }
+ }
+ return it.value();
+}
+
Handler::Handler(TypeDatabase *database, bool generate) :
m_database(database),
m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
{
}
+Handler::~Handler() = default;
+
static QString readerFileName(const QXmlStreamReader &reader)
{
const QFile *file = qobject_cast<const QFile *>(reader.device());
@@ -582,6 +648,8 @@ bool Handler::parse(QXmlStreamReader &reader)
const QString fileName = readerFileName(reader);
if (!fileName.isEmpty())
m_currentPath = QFileInfo(fileName).absolutePath();
+ m_entityResolver.reset(new TypeSystemEntityResolver(m_currentPath));
+ reader.setEntityResolver(m_entityResolver.data());
while (!reader.atEnd()) {
switch (reader.readNext()) {
@@ -674,6 +742,17 @@ bool Handler::endElement(const QStringRef &localName)
}
}
break;
+ case StackElement::AddFunction: {
+ // Leaving add-function: Assign all modifications to the added function
+ StackElementContext *top = m_contextStack.top();
+ const int modIndex = top->addedFunctionModificationIndex;
+ top->addedFunctionModificationIndex = -1;
+ Q_ASSERT(modIndex >= 0);
+ Q_ASSERT(!top->addedFunctions.isEmpty());
+ while (modIndex < top->functionMods.size())
+ top->addedFunctions.last()->modifications.append(top->functionMods.takeAt(modIndex));
+ }
+ break;
case StackElement::NativeToTarget:
case StackElement::AddConversion: {
CustomConversion* customConversion = static_cast<TypeEntry*>(m_current->entry)->customConversion();
@@ -2009,8 +2088,8 @@ bool Handler::parseAddFunction(const QXmlStreamReader &,
return false;
}
- AddedFunction func(signature, returnType);
- func.setStatic(staticFunction);
+ AddedFunctionPtr func(new AddedFunction(signature, returnType));
+ func->setStatic(staticFunction);
if (!signature.contains(QLatin1Char('(')))
signature += QLatin1String("()");
m_currentSignature = signature;
@@ -2021,10 +2100,12 @@ bool Handler::parseAddFunction(const QXmlStreamReader &,
m_error = QString::fromLatin1("Bad access type '%1'").arg(access);
return false;
}
- func.setAccess(a);
+ func->setAccess(a);
}
m_contextStack.top()->addedFunctions << func;
+ m_contextStack.top()->addedFunctionModificationIndex =
+ m_contextStack.top()->functionMods.size();
FunctionModification mod;
if (!mod.setSignature(m_currentSignature, &m_error))
@@ -3231,7 +3312,10 @@ AddedFunction::AddedFunction(QString signature, const QString &returnType) :
Q_ASSERT(!returnType.isEmpty());
m_returnType = parseType(returnType);
signature = signature.trimmed();
- int endPos = signature.indexOf(QLatin1Char('('));
+ // Skip past "operator()(...)"
+ const int parenStartPos = signature.startsWith(callOperator())
+ ? callOperator().size() : 0;
+ int endPos = signature.indexOf(QLatin1Char('('), parenStartPos);
if (endPos < 0) {
m_isConst = false;
m_name = signature;
@@ -3413,7 +3497,6 @@ ComplexTypeEntry::ComplexTypeEntry(const QString &name, TypeEntry::Type t,
const QVersionNumber &vr) :
TypeEntry(name, t, vr),
m_qualifiedCppName(name),
- m_qobject(false),
m_polymorphicBase(false),
m_genericClass(false),
m_deleteInMainThread(false)
@@ -3483,6 +3566,20 @@ static const QSet<QString> &primitiveCppTypes()
return result;
}
+void TypeEntry::setInclude(const Include &inc)
+{
+ // This is a workaround for preventing double inclusion of the QSharedPointer implementation
+ // header, which does not use header guards. In the previous parser this was not a problem
+ // because the Q_QDOC define was set, and the implementation header was never included.
+ if (inc.name().endsWith(QLatin1String("qsharedpointer_impl.h"))) {
+ QString path = inc.name();
+ path.remove(QLatin1String("_impl"));
+ m_include = Include(inc.type(), path);
+ } else {
+ m_include = inc;
+ }
+}
+
bool TypeEntry::isCppPrimitive() const
{
if (!isPrimitive())
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 96d0bb5fd..f089bb6e0 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -476,6 +476,8 @@ struct AddedFunction
return m_isStatic;
}
+ FunctionModificationList modifications;
+
private:
QString m_name;
QVector<TypeInfo> m_arguments;
@@ -835,16 +837,7 @@ public:
{
return m_include;
}
- void setInclude(const Include &inc)
- {
- // This is a workaround for preventing double inclusion of the QSharedPointer implementation
- // header, which does not use header guards. In the previous parser this was not a problem
- // because the Q_QDOC define was set, and the implementation header was never included.
- if (inc.name() == QLatin1String("qsharedpointer_impl.h"))
- m_include = Include(inc.type(), QLatin1String("qsharedpointer.h"));
- else
- m_include = inc;
- }
+ void setInclude(const Include &inc);
// Replace conversionRule arg to CodeSnip in future version
/// Set the type convertion rule
@@ -1278,7 +1271,7 @@ public:
{
m_addedFunctions = addedFunctions;
}
- void addNewFunction(const AddedFunction &addedFunction)
+ void addNewFunction(const AddedFunctionPtr &addedFunction)
{
m_addedFunctions << addedFunction;
}
@@ -1293,15 +1286,6 @@ public:
return m_fieldMods;
}
- bool isQObject() const
- {
- return m_qobject;
- }
- void setQObject(bool qobject)
- {
- m_qobject = qobject;
- }
-
QString defaultSuperclass() const
{
return m_defaultSuperclass;
@@ -1419,7 +1403,6 @@ private:
QString m_qualifiedCppName;
QString m_targetLangName;
- uint m_qobject : 1;
uint m_polymorphicBase : 1;
uint m_genericClass : 1;
uint m_deleteInMainThread : 1;
diff --git a/sources/shiboken2/ApiExtractor/typesystem_p.h b/sources/shiboken2/ApiExtractor/typesystem_p.h
index a119b2a97..f6b0717f4 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_p.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_p.h
@@ -29,11 +29,13 @@
#define TYPESYSTEM_P_H
#include <QStack>
+#include <QtCore/QScopedPointer>
#include "typesystem.h"
QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)
+class TypeSystemEntityResolver;
class TypeDatabase;
class StackElement
{
@@ -132,12 +134,16 @@ struct StackElementContext
FunctionModificationList functionMods;
FieldModificationList fieldMods;
DocModificationList docModifications;
+ int addedFunctionModificationIndex = -1;
};
class Handler
{
public:
+ Q_DISABLE_COPY(Handler)
+
Handler(TypeDatabase* database, bool generate);
+ ~Handler();
bool parse(QXmlStreamReader &reader);
@@ -255,6 +261,7 @@ private:
QString m_currentSignature;
QString m_currentPath;
+ QScopedPointer<TypeSystemEntityResolver> m_entityResolver;
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
index dc6e5cbcc..5cea587ed 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
@@ -31,6 +31,7 @@
#include <QtCore/QHash>
#include <QtCore/QList>
+#include <QtCore/QSharedPointer>
#include <QtCore/QVector>
class CodeSnip;
@@ -40,7 +41,8 @@ struct AddedFunction;
struct FieldModification;
struct FunctionModification;
-typedef QVector<AddedFunction> AddedFunctionList;
+using AddedFunctionPtr = QSharedPointer<AddedFunction>;
+using AddedFunctionList = QVector<AddedFunctionPtr>;
typedef QVector<CodeSnip> CodeSnipList;
typedef QVector<DocModification> DocModificationList;
typedef QVector<FieldModification> FieldModificationList;
diff --git a/sources/shiboken2/CMakeLists.txt b/sources/shiboken2/CMakeLists.txt
index 1e52c4297..12429c657 100644
--- a/sources/shiboken2/CMakeLists.txt
+++ b/sources/shiboken2/CMakeLists.txt
@@ -11,10 +11,24 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/data/")
include(helpers)
include(shiboken_helpers)
-find_package(Qt5 5.12 REQUIRED COMPONENTS Core Xml XmlPatterns)
-
option(BUILD_TESTS "Build tests." TRUE)
option(USE_PYTHON_VERSION "Use specific python version to build shiboken2." "")
+option(DISABLE_DOCSTRINGS "Disable documentation extraction." FALSE)
+
+find_package(Qt5 5.12 REQUIRED COMPONENTS Core)
+find_package(Qt5Xml 5.12)
+find_package(Qt5XmlPatterns 5.12)
+find_package(LibXml2 2.6.32)
+find_package(LibXslt 1.1.19)
+if(BUILD_TESTS)
+ find_package(Qt5Test 5.12 REQUIRED)
+endif()
+
+if(NOT Qt5XmlPatterns_FOUND OR NOT Qt5Xml_FOUND)
+ set(DISABLE_DOCSTRINGS TRUE)
+ message(WARNING
+ "Documentation will not be built due to missing dependency (no Qt5XmlPatterns found).")
+endif()
# Don't display "up-to-date / install" messages when installing, to reduce visual clutter.
if (QUIET_BUILD)
diff --git a/sources/shiboken2/doc/typesystem_specifying_types.rst b/sources/shiboken2/doc/typesystem_specifying_types.rst
index f4016bc2c..ac1121461 100644
--- a/sources/shiboken2/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken2/doc/typesystem_specifying_types.rst
@@ -3,6 +3,30 @@ Specifying Types
.. _typesystem:
+Including Snippets
+^^^^^^^^^^^^^^^^^^
+
+There might be repetitive XML code, for example function modifications that
+need to be done on classes that are not related by type inheritance.
+It is possible to split out such snippets and include them via an entity reference.
+
+.. code-block:: xml
+
+ <typesystem>
+ <object-type name="A">
+ &common_function_modifications;
+ </object-type>
+ <object-type name="B">
+ &common_function_modifications;
+ </object-type>
+ </typesystem>
+
+The entity name is interpreted as file name (with suffix **xml**) appended and resolved
+in the type system paths passed as command line argument.
+
+Note that this is not a standard externally parsed entity due to the limitations
+of the underlying parser.
+
typesystem
^^^^^^^^^^
diff --git a/sources/shiboken2/generator/CMakeLists.txt b/sources/shiboken2/generator/CMakeLists.txt
index 943e8d19b..745c366f5 100644
--- a/sources/shiboken2/generator/CMakeLists.txt
+++ b/sources/shiboken2/generator/CMakeLists.txt
@@ -1,8 +1,5 @@
project(shibokengenerator)
-find_package(Qt5Xml)
-find_package(Qt5XmlPatterns)
-
set(shiboken2_SRC
generator.cpp
shiboken2/cppgenerator.cpp
@@ -12,29 +9,23 @@ shiboken2/shibokengenerator.cpp
main.cpp
)
-if (NOT DISABLE_DOCSTRINGS)
- set(shiboken2_SRC ${shiboken2_SRC} qtdoc/qtdocgenerator.cpp)
- add_definitions(-DDOCSTRINGS_ENABLED)
-endif()
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/shiboken2
+add_executable(shiboken2 ${shiboken2_SRC})
+add_executable(Shiboken2::shiboken2 ALIAS shiboken2)
+add_dependencies(shiboken2 apiextractor)
+set_target_properties(shiboken2 PROPERTIES OUTPUT_NAME shiboken2${shiboken2_SUFFIX})
+target_include_directories(shiboken2 PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/shiboken2
${CMAKE_CURRENT_SOURCE_DIR}/qtdoc
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${apiextractor_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5XmlPatterns_INCLUDE_DIRS}
)
-
-add_executable(shiboken2 ${shiboken2_SRC})
-add_executable(Shiboken2::shiboken2 ALIAS shiboken2)
-add_dependencies(shiboken2 apiextractor)
-set_target_properties(shiboken2 PROPERTIES OUTPUT_NAME shiboken2${shiboken2_SUFFIX})
-target_link_libraries(shiboken2
- apiextractor
- ${Qt5Core_LIBRARIES}
- ${Qt5XmlPatterns_LIBRARIES}
- )
+target_link_libraries(shiboken2 apiextractor Qt5::Core)
+if (NOT DISABLE_DOCSTRINGS)
+ target_sources(shiboken2 PRIVATE qtdoc/qtdocgenerator.cpp)
+ target_compile_definitions(shiboken2 PUBLIC DOCSTRINGS_ENABLED)
+ target_link_libraries(shiboken2 Qt5::XmlPatterns)
+endif()
configure_file(shibokenconfig.h.in "${CMAKE_CURRENT_BINARY_DIR}/shibokenconfig.h" @ONLY)
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index 91e940f51..87758e533 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -421,7 +421,7 @@ bool Generator::generate()
for (const AbstractMetaType *type : qAsConst(m_d->instantiatedSmartPointers)) {
AbstractMetaClass *smartPointerClass =
- AbstractMetaClass::findClass(m_d->apiextractor->smartPointers(), type->name());
+ AbstractMetaClass::findClass(m_d->apiextractor->smartPointers(), type->typeEntry());
GeneratorContext context(smartPointerClass, type, true);
if (!generateFileForContext(context))
return false;
@@ -538,7 +538,7 @@ bool Generator::isObjectType(const TypeEntry* type)
}
bool Generator::isObjectType(const ComplexTypeEntry* type)
{
- return type->isObject() || type->isQObject();
+ return type->isObject();
}
bool Generator::isObjectType(const AbstractMetaClass* metaClass)
{
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 094990b64..1817f6b03 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -373,8 +373,10 @@ static void parseIncludePathOption(const QString &option, HeaderType headerType,
const QStringList includePathListList =
it.value().split(pathSplitter, QString::SkipEmptyParts);
args.erase(it);
- for (const QString &s : includePathListList)
- extractor.addIncludePath(HeaderPath{QFile::encodeName(s), headerType});
+ for (const QString &s : includePathListList) {
+ auto path = QFile::encodeName(QDir::cleanPath(s));
+ extractor.addIncludePath(HeaderPath{path, headerType});
+ }
}
}
diff --git a/sources/shiboken2/generator/qtdoc/CMakeLists.txt b/sources/shiboken2/generator/qtdoc/CMakeLists.txt
deleted file mode 100644
index 1361ba8f1..000000000
--- a/sources/shiboken2/generator/qtdoc/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-project(qtdoc_generator)
-
-set(qtdoc_generator_SRC
-qtdocgenerator.cpp
-)
-
-include_directories(${generators_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${APIEXTRACTOR_INCLUDE_DIR})
-add_executable(docgenerator main.cpp)
-set_target_properties(docgenerator PROPERTIES OUTPUT_NAME docgenerator${generator_SUFFIX})
-
-target_link_libraries(docgenerator ${Qt5Core_LIBRARES})
-
-add_library(qtdoc_generator SHARED ${qtdoc_generator_SRC})
-target_link_libraries(qtdoc_generator ${APIEXTRACTOR_LIBRARY} ${Qt5Core_LIBRARES} genrunner)
-set_property(TARGET qtdoc_generator PROPERTY PREFIX "")
-
-install(TARGETS qtdoc_generator DESTINATION ${generator_plugin_DIR})
-install(TARGETS docgenerator DESTINATION bin)
-
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 05729f4b5..6abfde7c9 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -1872,7 +1872,7 @@ QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* /* cppClass */
defValue.replace(QLatin1String("::"), QLatin1String("."));
if (defValue == QLatin1String("nullptr"))
defValue = none();
- else if (defValue == QLatin1String("0") && (arg->type()->isQObject() || arg->type()->isObject()))
+ else if (defValue == QLatin1String("0") && arg->type()->isObject())
defValue = none();
}
ret += QLatin1Char('=') + defValue;
diff --git a/sources/shiboken2/generator/shiboken2/CMakeLists.txt b/sources/shiboken2/generator/shiboken2/CMakeLists.txt
deleted file mode 100644
index 5c1b612dd..000000000
--- a/sources/shiboken2/generator/shiboken2/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-project(shibokengenerator)
-
-set(shiboken_SRC
-../generator.cpp
-cppgenerator.cpp
-headergenerator.cpp
-overloaddata.cpp
-shibokengenerator.cpp
-main.cpp
-)
-
-include_directories(${generators_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
- ${APIEXTRACTOR_INCLUDE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- )
-
-add_executable(shiboken2 ${shiboken_SRC})
-set_target_properties(shiboken2 PROPERTIES OUTPUT_NAME shiboken2${shiboken_SUFFIX})
-target_link_libraries(shiboken2
- ${APIEXTRACTOR_LIBRARY}
- ${Qt5Core_LIBRARIES}
- )
-
-configure_file(shibokenconfig.h.in "${CMAKE_CURRENT_BINARY_DIR}/shibokenconfig.h" @ONLY)
-
-install(TARGETS shiboken2 DESTINATION bin)
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 2fedf9ae1..29220c739 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -664,7 +664,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << NULL_PTR;
s << "}," << endl;
}
- s << INDENT << '{' << NULL_PTR << "} // Sentinel" << endl;
+ s << INDENT << '{' << NULL_PTR << "} // Sentinel" << endl;
s << "};" << endl << endl;
}
@@ -907,7 +907,6 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
QTextStream ac(&argConv);
const PrimitiveTypeEntry* argType = (const PrimitiveTypeEntry*) arg->type()->typeEntry();
bool convert = argType->isObject()
- || arg->type()->isQObject()
|| argType->isValue()
|| arg->type()->isValuePointer()
|| arg->type()->isNativePointer()
@@ -3076,7 +3075,7 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction* func, in
AbstractMetaType *returnType = getTypeWithoutContainer(funcType);
if (returnType) {
pyArgName = QLatin1String(PYTHON_RETURN_VAR);
- *wrappedClass = AbstractMetaClass::findClass(classes(), returnType->typeEntry()->name());
+ *wrappedClass = AbstractMetaClass::findClass(classes(), returnType->typeEntry());
} else {
QString message = QLatin1String("Invalid Argument index (0, return value) on function modification: ")
+ (funcType ? funcType->name() : QLatin1String("void")) + QLatin1Char(' ');
@@ -3090,7 +3089,7 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction* func, in
AbstractMetaType* argType = getTypeWithoutContainer(func->arguments().at(realIndex)->type());
if (argType) {
- *wrappedClass = AbstractMetaClass::findClass(classes(), argType->typeEntry()->name());
+ *wrappedClass = AbstractMetaClass::findClass(classes(), argType->typeEntry());
if (argIndex == 1
&& !func->isConstructor()
&& OverloadData::isSingleArgument(getFunctionGroups(func->implementingClass())[func->name()]))
@@ -4925,11 +4924,11 @@ void CppGenerator::writeClassRegister(QTextStream &s,
// PYSIDE-510: Create a signatures string for the introspection feature.
s << "// The signatures string for the functions." << endl;
s << "// Multiple signatures have their index \"n:\" in front." << endl;
- s << "const char " << initFunctionName << "_SignaturesString[] = \"\"" << endl;
+ s << "static const char *" << initFunctionName << "_SignatureStrings[] = {" << endl;
QString line;
while (signatureStream.readLineInto(&line))
- s << INDENT << '"' << line << "\\n\"" << endl;
- s << ';' << endl << endl;
+ s << INDENT << '"' << line << "\"," << endl;
+ s << INDENT << NULL_PTR << "}; // Sentinel" << endl << endl;
s << "void init_" << initFunctionName;
s << "(PyObject* " << enclosingObjectVariable << ")" << endl;
s << '{' << endl;
@@ -4982,8 +4981,8 @@ void CppGenerator::writeClassRegister(QTextStream &s,
// 4:typeSpec
s << INDENT << '&' << chopType(pyTypeName) << "_spec," << endl;
- // 5:signaturesString
- s << INDENT << initFunctionName << "_SignaturesString," << endl;
+ // 5:signatureStrings
+ s << INDENT << initFunctionName << "_SignatureStrings," << endl;
// 6:cppObjDtor
s << INDENT;
@@ -5657,7 +5656,17 @@ bool CppGenerator::finishGeneration()
s << " /* m_clear */ nullptr," << endl;
s << " /* m_free */ nullptr" << endl;
s << "};" << endl << endl;
- s << "#endif" << endl;
+ s << "#endif" << endl << endl;
+
+ // PYSIDE-510: Create a signatures string for the introspection feature.
+ s << "// The signatures string for the global functions." << endl;
+ s << "// Multiple signatures have their index \"n:\" in front." << endl;
+ s << "static const char *" << moduleName() << "_SignatureStrings[] = {" << endl;
+ QString line;
+ while (signatureStream.readLineInto(&line))
+ s << INDENT << '"' << line << "\"," << endl;
+ s << INDENT << NULL_PTR << "}; // Sentinel" << endl << endl;
+
s << "SBK_MODULE_INIT_FUNCTION_BEGIN(" << moduleName() << ")" << endl;
ErrorCode errorCode(QLatin1String("SBK_MODULE_INIT_ERROR"));
@@ -5788,17 +5797,9 @@ bool CppGenerator::finishGeneration()
s << INDENT << "PySide::registerCleanupFunction(cleanTypesAttributes);" << endl << endl;
}
- // PYSIDE-510: Create a signatures string for the introspection feature.
- s << "// The signatures string for the global functions." << endl;
- s << "// Multiple signatures have their index \"n:\" in front." << endl;
- s << "const char " << moduleName() << "_SignaturesString[] = \"\"" << endl;
- QString line;
- while (signatureStream.readLineInto(&line))
- s << INDENT << '"' << line << "\\n\"" << endl;
- s << ';' << endl;
// finish the rest of __signature__ initialization.
s << INDENT << "FinishSignatureInitialization(module, " << moduleName()
- << "_SignaturesString);" << endl;
+ << "_SignatureStrings);" << endl;
if (usePySideExtensions()) {
// initialize the qApp module.
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index 9f0ac51e5..becd66879 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -322,7 +322,7 @@ void OverloadData::sortNextOverloads()
}
// Process inheritance relationships
- if (targetType->isValue() || targetType->isObject() || targetType->isQObject()) {
+ if (targetType->isValue() || targetType->isObject()) {
const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), targetType->typeEntry());
const AbstractMetaClassList &ancestors = m_generator->getAllAncestors(metaClass);
for (const AbstractMetaClass *ancestor : ancestors) {
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index b5069db14..002ab8cfb 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -373,7 +373,7 @@ QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClas
return fullClassName;
}
-QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func) //WS
+QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func)
{
QString funcName;
if (func->isOperatorOverload())
@@ -729,8 +729,7 @@ QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction* func,
if (!func->typeReplaced(arg->argumentIndex() + 1).isEmpty()) {
result += QLatin1Char(objType);
- } else if (arg->type()->isQObject()
- || arg->type()->isObject()
+ } else if (arg->type()->isObject()
|| arg->type()->isValue()
|| arg->type()->isValuePointer()
|| arg->type()->isNativePointer()
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index d2c4b3292..80b172778 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -216,7 +216,7 @@ protected:
QString wrapperName(const AbstractMetaType *metaType) const;
QString fullPythonClassName(const AbstractMetaClass *metaClass);
- QString fullPythonFunctionName(const AbstractMetaFunction *func); //WS
+ QString fullPythonFunctionName(const AbstractMetaFunction *func);
static QString protectedEnumSurrogateName(const AbstractMetaEnum* metaEnum);
static QString protectedFieldGetterName(const AbstractMetaField* field);
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index a008fece8..3a043d849 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -744,18 +744,14 @@ introduceWrapperType(PyObject *enclosingObject,
const char *typeName,
const char *originalName,
PyType_Spec *typeSpec,
- const char *signaturesString,
+ const char *signatureStrings[],
ObjectDestructor cppObjDtor,
SbkObjectType *baseType,
PyObject *baseTypes,
unsigned wrapperFlags)
{
- if (baseType) {
- typeSpec->slots[0].pfunc = reinterpret_cast<void *>(baseType);
- }
- else {
- typeSpec->slots[0].pfunc = reinterpret_cast<void *>(SbkObject_TypeF());
- }
+ typeSpec->slots[0].pfunc = reinterpret_cast<void *>(baseType ? baseType : SbkObject_TypeF());
+
PyObject *heaptype = PyType_FromSpecWithBases(typeSpec, baseTypes);
Py_TYPE(heaptype) = SbkObjectType_TypeF();
Py_INCREF(Py_TYPE(heaptype));
@@ -769,7 +765,7 @@ introduceWrapperType(PyObject *enclosingObject,
}
}
// PYSIDE-510: Here is the single change to support signatures.
- if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signaturesString) < 0)
+ if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signatureStrings) < 0)
return nullptr;
initPrivateData(type);
@@ -779,20 +775,14 @@ introduceWrapperType(PyObject *enclosingObject,
setOriginalName(type, originalName);
setDestructorFunction(type, cppObjDtor);
+ PyObject *ob_type = reinterpret_cast<PyObject *>(type);
- if (wrapperFlags & InnerClass) {
- if (PyDict_SetItemString(enclosingObject, typeName, reinterpret_cast<PyObject *>(type)) == 0)
- return type;
- else
- return nullptr;
- }
+ if (wrapperFlags & InnerClass)
+ return PyDict_SetItemString(enclosingObject, typeName, ob_type) == 0 ? type : nullptr;
- //PyModule_AddObject steals type's reference.
- Py_INCREF(reinterpret_cast<PyObject *>(type));
- if (PyModule_AddObject(enclosingObject, typeName, reinterpret_cast<PyObject *>(type)) == 0) {
- return type;
- }
- return nullptr;
+ // PyModule_AddObject steals type's reference.
+ Py_INCREF(ob_type);
+ return PyModule_AddObject(enclosingObject, typeName, ob_type) == 0 ? type : nullptr;
}
void setSubTypeInitHook(SbkObjectType* type, SubTypeInitHook func)
diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h
index e1cc64ba9..d12b7222b 100644
--- a/sources/shiboken2/libshiboken/basewrapper.h
+++ b/sources/shiboken2/libshiboken/basewrapper.h
@@ -219,7 +219,7 @@ LIBSHIBOKEN_API SbkObjectType *introduceWrapperType(PyObject *enclosingObject,
const char *typeName,
const char *originalName,
PyType_Spec *typeSpec,
- const char *signaturesString,
+ const char *signatureStrings[],
ObjectDestructor cppObjDtor,
SbkObjectType *baseType,
PyObject *baseTypes,
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index d883677ce..ffbc570a8 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -316,6 +316,7 @@ LIBSHIBOKEN_API void PyBuffer_Release(Pep_buffer *view);
#else
#define Pep_buffer Py_buffer
+#define PepType_AS_BUFFER(type) ((type)->tp_as_buffer)
#endif /* Py_LIMITED_API */
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index dea4c9b09..3defca7d2 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -46,7 +46,6 @@ extern "C"
/*
* The documentation is located in file signature_doc.rst
*/
-
#include "signature.h"
#include <structmember.h>
@@ -62,6 +61,7 @@ extern "C"
#define PYTHON_NEEDS_ITERATOR_FLAG (!PYTHON_IS_PYTHON3)
#define PYTHON_EXPOSES_METHODDESCR (PYTHON_IS_PYTHON3)
#define PYTHON_NO_TYPE_IN_FUNCTIONS (!PYTHON_IS_PYTHON3 || Py_LIMITED_API)
+#define PYTHON_HAS_INT_AND_LONG (!PYTHON_IS_PYTHON3)
// These constants are still in use:
#define PYTHON_USES_D_COMMON (PY_VERSION_HEX >= 0x03020000)
@@ -72,15 +72,15 @@ typedef struct safe_globals_struc {
PyObject *arg_dict;
PyObject *map_dict;
// init part 2: run module
- PyObject *sigparse_func;
- PyObject *createsig_func;
+ PyObject *pyside_type_init_func;
+ PyObject *create_signature_func;
PyObject *seterror_argument_func;
PyObject *make_helptext_func;
} safe_globals_struc, *safe_globals;
static safe_globals pyside_globals = 0;
-static PyObject *GetClassKey(PyObject *ob);
+static PyObject *GetTypeKey(PyObject *ob);
static PyObject *GetSignature_Function(PyObject *, const char *);
static PyObject *GetSignature_TypeMod(PyObject *, const char *);
@@ -101,8 +101,8 @@ CreateSignature(PyObject *props, PyObject *key)
* This is so much simpler than using all the attributes explicitly
* to support '_signature_is_functionlike()'.
*/
- return PyObject_CallFunction(pyside_globals->createsig_func,
- (char *)"(OO)", props, key);
+ return PyObject_CallFunction(pyside_globals->create_signature_func,
+ const_cast<char *>("(OO)"), props, key);
}
static PyObject *
@@ -139,10 +139,10 @@ _get_class_of_cf(PyObject *ob_cf)
}
}
- PyObject *typemod = (PyType_Check(selftype) || PyModule_Check(selftype))
- ? selftype : (PyObject *)Py_TYPE(selftype);
- Py_INCREF(typemod);
- return typemod;
+ PyObject *obtype_mod = (PyType_Check(selftype) || PyModule_Check(selftype))
+ ? selftype : reinterpret_cast<PyObject *>(Py_TYPE(selftype));
+ Py_INCREF(obtype_mod);
+ return obtype_mod;
}
static PyObject *
@@ -198,24 +198,24 @@ static PyObject *
compute_name_key(PyObject *ob)
{
if (PyType_Check(ob))
- return GetClassKey(ob);
+ return GetTypeKey(ob);
Shiboken::AutoDecRef func_name(get_funcname(ob));
- Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob)));
+ Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOfFunc(ob)));
return Py_BuildValue("(OO)", type_key.object(), func_name.object());
}
static int
build_name_key_to_func(PyObject *obtype)
{
- PyTypeObject *type = (PyTypeObject *)obtype;
+ PyTypeObject *type = reinterpret_cast<PyTypeObject *>(obtype);
PyMethodDef *meth = type->tp_methods;
if (meth == 0)
return 0;
- Shiboken::AutoDecRef type_key(GetClassKey(obtype));
- for (; meth->ml_name != NULL; meth++) {
- Shiboken::AutoDecRef func(PyCFunction_NewEx(meth, obtype, NULL));
+ Shiboken::AutoDecRef type_key(GetTypeKey(obtype));
+ for (; meth->ml_name != nullptr; meth++) {
+ Shiboken::AutoDecRef func(PyCFunction_NewEx(meth, obtype, nullptr));
Shiboken::AutoDecRef func_name(get_funcname(func));
Shiboken::AutoDecRef name_key(Py_BuildValue("(OO)", type_key.object(), func_name.object()));
if (func.isNull() || name_key.isNull()
@@ -240,7 +240,7 @@ name_key_to_func(PyObject *ob)
PyObject *ret = PyDict_GetItem(pyside_globals->map_dict, name_key);
if (ret == nullptr) {
// do a lazy initialization
- Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob)));
+ Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOfFunc(ob)));
PyObject *type = PyDict_GetItem(pyside_globals->map_dict,
type_key);
if (type == nullptr)
@@ -274,10 +274,10 @@ pyside_wd_get___signature__(PyObject *ob, const char *modifier)
}
static PyObject *
-pyside_tp_get___signature__(PyObject *typemod, const char *modifier)
+pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
{
init_module_2();
- return GetSignature_TypeMod(typemod, modifier);
+ return GetSignature_TypeMod(obtype_mod, modifier);
}
// forward
@@ -285,13 +285,13 @@ static PyObject *
GetSignature_Cached(PyObject *props, const char *sig_kind, const char *modifier);
static PyObject *
-GetClassKey(PyObject *ob)
+GetTypeKey(PyObject *ob)
{
assert(PyType_Check(ob) || PyModule_Check(ob));
/*
- * We obtain a unique key using the module name and the class name.
+ * We obtain a unique key using the module name and the type name.
*
- * The class name is a bit funny when modules are nested.
+ * The type name is a bit funny when modules are nested.
* Example:
*
* "sample.Photon.ValueIdentity" is a class.
@@ -326,32 +326,32 @@ TypeKey_to_PropsDict(PyObject *type_key, PyObject *obtype)
empty_dict = PyDict_New();
dict = empty_dict;
}
- if (PyTuple_Check(dict))
- dict = PySide_BuildSignatureProps(obtype);
+ if (!PyDict_Check(dict))
+ dict = PySide_BuildSignatureProps(type_key);
return dict;
}
static PyObject *
-GetSignature_Function(PyObject *ob_func, const char *modifier)
+GetSignature_Function(PyObject *obfunc, const char *modifier)
{
// make sure that we look into PyCFunction, only...
- if (Py_TYPE(ob_func) == PepFunction_TypePtr)
+ if (Py_TYPE(obfunc) == PepFunction_TypePtr)
Py_RETURN_NONE;
- Shiboken::AutoDecRef typemod(GetClassOfFunc(ob_func));
- Shiboken::AutoDecRef type_key(GetClassKey(typemod));
+ Shiboken::AutoDecRef obtype_mod(GetClassOfFunc(obfunc));
+ Shiboken::AutoDecRef type_key(GetTypeKey(obtype_mod));
if (type_key.isNull())
Py_RETURN_NONE;
- PyObject *dict = TypeKey_to_PropsDict(type_key, typemod);
+ PyObject *dict = TypeKey_to_PropsDict(type_key, obtype_mod);
if (dict == nullptr)
return nullptr;
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob_func, "__name__"));
+ Shiboken::AutoDecRef func_name(PyObject_GetAttrString(obfunc, "__name__"));
PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr;
if (props == nullptr)
Py_RETURN_NONE;
- int flags = PyCFunction_GET_FLAGS(ob_func);
+ int flags = PyCFunction_GET_FLAGS(obfunc);
const char *sig_kind;
- if (PyModule_Check(typemod))
+ if (PyModule_Check(obtype_mod))
sig_kind = "function";
else if (flags & METH_CLASS)
sig_kind = "classmethod";
@@ -367,7 +367,7 @@ GetSignature_Wrapper(PyObject *ob, const char *modifier)
{
Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
Shiboken::AutoDecRef objclass(PyObject_GetAttrString(ob, "__objclass__"));
- Shiboken::AutoDecRef class_key(GetClassKey(objclass));
+ Shiboken::AutoDecRef class_key(GetTypeKey(objclass));
if (func_name.isNull() || objclass.isNull() || class_key.isNull())
return nullptr;
@@ -384,7 +384,7 @@ static PyObject *
GetSignature_TypeMod(PyObject *ob, const char *modifier)
{
Shiboken::AutoDecRef ob_name(PyObject_GetAttrString(ob, "__name__"));
- Shiboken::AutoDecRef ob_key(GetClassKey(ob));
+ Shiboken::AutoDecRef ob_key(GetTypeKey(ob));
PyObject *dict = TypeKey_to_PropsDict(ob_key, ob);
if (dict == nullptr)
@@ -430,9 +430,9 @@ static safe_globals_struc *
init_phase_1(void)
{
{
- safe_globals_struc *p = (safe_globals_struc *)
- malloc(sizeof(safe_globals_struc));
- if (p == NULL)
+ safe_globals_struc *p = reinterpret_cast<safe_globals_struc *>
+ (malloc(sizeof(safe_globals_struc)));
+ if (p == nullptr)
goto error;
/*
* Initializing module signature_bootstrap.
@@ -479,7 +479,6 @@ init_phase_1(void)
PyObject *mdict = PyModule_GetDict(p->helper_module);
if (PyDict_SetItemString(mdict, "__builtins__", PyEval_GetBuiltins()) < 0)
goto error;
-
/*
* Unpack an embedded ZIP file with more signature modules.
* They will be loaded later with the zipimporter.
@@ -488,11 +487,13 @@ init_phase_1(void)
const char **block_ptr = (const char **)PySide_CompressedSignaturePackage;
int npieces = 0;
PyObject *piece, *zipped_string_sequence = PyList_New(0);
+ if (zipped_string_sequence == nullptr)
+ return nullptr;
for (; **block_ptr != 0; ++block_ptr) {
npieces++;
// we avoid the string/unicode dilemma by not using PyString_XXX:
piece = Py_BuildValue("s", *block_ptr);
- if (piece == NULL || PyList_Append(zipped_string_sequence, piece) < 0)
+ if (piece == nullptr || PyList_Append(zipped_string_sequence, piece) < 0)
goto error;
}
if (PyDict_SetItemString(mdict, "zipstring_sequence", zipped_string_sequence) < 0)
@@ -501,12 +502,12 @@ init_phase_1(void)
// build a dict for diverse mappings
p->map_dict = PyDict_New();
- if (p->map_dict == NULL)
+ if (p->map_dict == nullptr)
goto error;
// build a dict for the prepared arguments
p->arg_dict = PyDict_New();
- if (p->arg_dict == NULL
+ if (p->arg_dict == nullptr
|| PyObject_SetAttrString(p->helper_module, "pyside_arg_dict", p->arg_dict) < 0)
goto error;
return p;
@@ -514,7 +515,7 @@ init_phase_1(void)
error:
PyErr_Print();
PyErr_SetString(PyExc_SystemError, "could not initialize part 1");
- return NULL;
+ return nullptr;
}
static int
@@ -524,7 +525,7 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
PyMethodDef *ml;
// The single function to be called, but maybe more to come.
- for (ml = methods; ml->ml_name != NULL; ml++) {
+ for (ml = methods; ml->ml_name != nullptr; ml++) {
PyObject *v = PyCFunction_NewEx(ml, nullptr, nullptr);
if (v == nullptr
|| PyObject_SetAttrString(p->helper_module, ml->ml_name, v) != 0)
@@ -532,24 +533,24 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
Py_DECREF(v);
}
PyObject *bootstrap_func = PyObject_GetAttrString(p->helper_module, "bootstrap");
- if (bootstrap_func == NULL)
+ if (bootstrap_func == nullptr)
goto error;
// The return value of the bootstrap function is the loader module.
- PyObject *loader = PyObject_CallFunction(bootstrap_func, (char *)"()");
+ PyObject *loader = PyObject_CallFunction(bootstrap_func, const_cast<char *>("()"));
if (loader == nullptr)
goto error;
// now the loader should be initialized
- p->sigparse_func = PyObject_GetAttrString(loader, "pyside_type_init");
- if (p->sigparse_func == NULL)
+ p->pyside_type_init_func = PyObject_GetAttrString(loader, "pyside_type_init");
+ if (p->pyside_type_init_func == nullptr)
goto error;
- p->createsig_func = PyObject_GetAttrString(loader, "create_signature");
- if (p->createsig_func == NULL)
+ p->create_signature_func = PyObject_GetAttrString(loader, "create_signature");
+ if (p->create_signature_func == nullptr)
goto error;
p->seterror_argument_func = PyObject_GetAttrString(loader, "seterror_argument");
- if (p->seterror_argument_func == NULL)
+ if (p->seterror_argument_func == nullptr)
goto error;
p->make_helptext_func = PyObject_GetAttrString(loader, "make_helptext");
- if (p->make_helptext_func == NULL)
+ if (p->make_helptext_func == nullptr)
goto error;
return 0;
}
@@ -568,7 +569,7 @@ _fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_gsp)
*/
PyGetSetDef *gsp = type->tp_getset;
if (gsp != nullptr) {
- for (; gsp->name != NULL; gsp++) {
+ for (; gsp->name != nullptr; gsp++) {
if (strcmp(gsp->name, name) == 0) {
new_gsp->set = gsp->set;
new_gsp->doc = gsp->doc;
@@ -592,7 +593,7 @@ add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **old_descr)
assert(PyType_Check(type));
PyType_Ready(type);
PyObject *dict = type->tp_dict;
- for (; gsp->name != NULL; gsp++) {
+ for (; gsp->name != nullptr; gsp++) {
PyObject *have_descr = PyDict_GetItemString(dict, gsp->name);
if (have_descr != nullptr) {
assert(strcmp(gsp->name, "__doc__") == 0);
@@ -730,7 +731,7 @@ get_signature(PyObject *self, PyObject *args)
init_module_1();
if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier))
- return NULL;
+ return nullptr;
if (Py_TYPE(ob) == PepFunction_TypePtr)
Py_RETURN_NONE;
@@ -784,15 +785,17 @@ PySide_PatchTypes(void)
static int init_done = 0;
if (!init_done) {
- Shiboken::AutoDecRef md(PyObject_GetAttrString((PyObject *)&PyString_Type, "split")); // method-descriptor
- Shiboken::AutoDecRef wd(PyObject_GetAttrString((PyObject *)Py_TYPE(Py_True), "__add__")); // wrapper-descriptor
- if (md.isNull() || wd.isNull()
- || PyType_Ready(Py_TYPE(md)) < 0
+ Shiboken::AutoDecRef meth_descr(PyObject_GetAttrString(
+ reinterpret_cast<PyObject *>(&PyString_Type), "split"));
+ Shiboken::AutoDecRef wrap_descr(PyObject_GetAttrString(
+ reinterpret_cast<PyObject *>(Py_TYPE(Py_True)), "__add__"));
+ if (meth_descr.isNull() || wrap_descr.isNull()
+ || PyType_Ready(Py_TYPE(meth_descr)) < 0
|| add_more_getsets(PepMethodDescr_TypePtr, new_PyMethodDescr_getsets, &old_md_doc_descr) < 0
|| add_more_getsets(&PyCFunction_Type, new_PyCFunction_getsets, &old_cf_doc_descr) < 0
|| add_more_getsets(PepStaticMethod_TypePtr, new_PyStaticMethod_getsets, &old_sm_doc_descr) < 0
|| add_more_getsets(&PyType_Type, new_PyType_getsets, &old_tp_doc_descr) < 0
- || add_more_getsets(Py_TYPE(wd), new_PyWrapperDescr_getsets, &old_wd_doc_descr) < 0
+ || add_more_getsets(Py_TYPE(wrap_descr), new_PyWrapperDescr_getsets, &old_wd_doc_descr) < 0
)
return -1;
#ifndef _WIN32
@@ -819,52 +822,32 @@ init_module_1(void)
}
static int
-PySide_BuildSignatureArgs(PyObject *module, PyObject *type,
- const char *signatures)
+PySide_BuildSignatureArgs(PyObject *obtype_mod, const char *signatures[])
{
- PyObject *type_key, *arg_tup;
-
init_module_1();
- arg_tup = Py_BuildValue("(Os)", type, signatures);
- if (arg_tup == NULL)
- return -1;
- /*
- * We either get a module name or the dict of an EnclosingObject.
- * We can ignore the EnclosingObject since we get full name info
- * from the type.
- */
- if (!PyModule_Check(module))
- assert(PyDict_Check(module));
+ Shiboken::AutoDecRef type_key(GetTypeKey(obtype_mod));
/*
- * Normally, we would now just call the Python function with the
- * arguments and then continue processing.
- * But it is much better to delay the second part until it is
- * really needed. Why?
- *
- * - by doing it late, we save initialization time when no signatures
- * are requested,
- * - by calling the python function late, we can freely import PySide
- * without recursion problems.
+ * PYSIDE-996: Avoid string overflow in MSVC, which has a limit of
+ * 2**15 unicode characters (64 K memory).
+ * Instead of one huge string, we take a ssize_t that is the
+ * address of a string array. It will not be turned into a real
+ * string list until really used by Python. This is quite optimal.
*/
- type_key = GetClassKey(type);
- if (type_key == nullptr)
- return -1;
- if (PyDict_SetItem(pyside_globals->arg_dict, type_key, arg_tup) < 0)
+ Shiboken::AutoDecRef numkey(Py_BuildValue("n", signatures));
+ if (type_key.isNull() || numkey.isNull()
+ || PyDict_SetItem(pyside_globals->arg_dict, type_key, numkey) < 0)
return -1;
/*
- * We record also a mapping from type key to type. This helps to lazily
- * initialize the Py_LIMITED_API in name_key_to_func().
+ * We record also a mapping from type key to type/module. This helps to
+ * lazily initialize the Py_LIMITED_API in name_key_to_func().
*/
-
- if (PyDict_SetItem(pyside_globals->map_dict, type_key, type) < 0)
- return -1;
- return 0;
+ return PyDict_SetItem(pyside_globals->map_dict, type_key, obtype_mod) == 0 ? 0 : -1;
}
static PyMethodDef signature_methods[] = {
{"get_signature", (PyCFunction)get_signature, METH_VARARGS,
"get the __signature__, but pass an optional string parameter"},
- {NULL, NULL}
+ {nullptr, nullptr}
};
static void
@@ -881,7 +864,26 @@ init_module_2(void)
}
static PyObject *
-PySide_BuildSignatureProps(PyObject *classmod)
+_address_to_stringlist(PyObject *numkey)
+{
+ ssize_t address = PyNumber_AsSsize_t(numkey, PyExc_ValueError);
+ if (address == -1 && PyErr_Occurred())
+ return nullptr;
+ char **sig_strings = reinterpret_cast<char **>(address);
+ PyObject *res_list = PyList_New(0);
+ if (res_list == nullptr)
+ return nullptr;
+ for (; *sig_strings != nullptr; ++sig_strings) {
+ char *sig_str = *sig_strings;
+ Shiboken::AutoDecRef pystr(Py_BuildValue("s", sig_str));
+ if (pystr.isNull() || PyList_Append(res_list, pystr) < 0)
+ return nullptr;
+ }
+ return res_list;
+}
+
+static PyObject *
+PySide_BuildSignatureProps(PyObject *type_key)
{
/*
* Here is the second part of the function.
@@ -890,13 +892,16 @@ PySide_BuildSignatureProps(PyObject *classmod)
* them by the function result.
*/
init_module_2();
- Shiboken::AutoDecRef type_key(GetClassKey(classmod));
- if (type_key.isNull())
+ if (type_key == nullptr)
+ return nullptr;
+ PyObject *numkey = PyDict_GetItem(pyside_globals->arg_dict, type_key);
+ Shiboken::AutoDecRef strings(_address_to_stringlist(numkey));
+ if (strings.isNull())
return nullptr;
- PyObject *arg_tup = PyDict_GetItem(pyside_globals->arg_dict, type_key);
- if (arg_tup == nullptr)
+ Shiboken::AutoDecRef arg_tup(Py_BuildValue("(OO)", type_key, strings.object()));
+ if (arg_tup.isNull())
return nullptr;
- PyObject *dict = PyObject_CallObject(pyside_globals->sigparse_func, arg_tup);
+ PyObject *dict = PyObject_CallObject(pyside_globals->pyside_type_init_func, arg_tup);
if (dict == nullptr) {
if (PyErr_Occurred())
return nullptr;
@@ -905,44 +910,27 @@ PySide_BuildSignatureProps(PyObject *classmod)
empty_dict = PyDict_New();
return empty_dict;
}
-
// We replace the arguments by the result dict.
if (PyDict_SetItem(pyside_globals->arg_dict, type_key, dict) < 0)
return nullptr;
return dict;
}
-int
-SbkSpecial_Type_Ready(PyObject *module, PyTypeObject *type,
- const char *signatures)
-{
- int ret;
- if (PyType_Ready(type) < 0)
- return -1;
- ret = PySide_BuildSignatureArgs(module, (PyObject *)type, signatures);
- if (ret < 0) {
- PyErr_Print();
- PyErr_SetNone(PyExc_ImportError);
- }
- return ret;
-}
-
static int _finish_nested_classes(PyObject *dict);
static int _build_func_to_type(PyObject *obtype);
static int
-PySide_FinishSignatures(PyObject *module, const char *signatures)
+PySide_FinishSignatures(PyObject *module, const char *signatures[])
{
/*
* Initialization of module functions and resolving of static methods.
*/
-
const char *name = PyModule_GetName(module);
- if (name == NULL)
+ if (name == nullptr)
return -1;
// we abuse the call for types, since they both have a __name__ attribute.
- if (PySide_BuildSignatureArgs(module, module, signatures) < 0)
+ if (PySide_BuildSignatureArgs(module, signatures) < 0)
return -1;
/*
@@ -972,7 +960,7 @@ _finish_nested_classes(PyObject *obdict)
PyTypeObject *subtype;
Py_ssize_t pos = 0;
- if (obdict == NULL)
+ if (obdict == nullptr)
return -1;
while (PyDict_Next(obdict, &pos, &key, &value)) {
if (PyType_Check(value)) {
@@ -1011,7 +999,7 @@ _build_func_to_type(PyObject *obtype)
if (meth == 0)
return 0;
- for (; meth->ml_name != NULL; meth++) {
+ for (; meth->ml_name != nullptr; meth++) {
/*
* It is possible that a method is overwritten by another
* attribute with the same name. This case was obviously provoked
@@ -1027,7 +1015,7 @@ _build_func_to_type(PyObject *obtype)
PyObject *descr = PyDict_GetItemString(dict, meth->ml_name);
const char *look_attr = meth->ml_flags & METH_STATIC ? "__func__" : "__name__";
int check_name = meth->ml_flags & METH_STATIC ? 0 : 1;
- if (descr == NULL)
+ if (descr == nullptr)
return -1;
// We first check all methods if one is hidden by something else.
@@ -1036,7 +1024,8 @@ _build_func_to_type(PyObject *obtype)
if (look.isNull()
|| (check_name && PyObject_RichCompareBool(look, given, Py_EQ) != 1)) {
PyErr_Clear();
- Shiboken::AutoDecRef cfunc(PyCFunction_NewEx(meth, (PyObject*)type, NULL));
+ Shiboken::AutoDecRef cfunc(PyCFunction_NewEx(meth,
+ reinterpret_cast<PyObject*>(type), nullptr));
if (cfunc.isNull())
return -1;
if (meth->ml_flags & METH_STATIC)
@@ -1069,8 +1058,23 @@ _build_func_to_type(PyObject *obtype)
return 0;
}
+int
+SbkSpecial_Type_Ready(PyObject *module, PyTypeObject *type,
+ const char *signatures[])
+{
+ if (PyType_Ready(type) < 0)
+ return -1;
+ PyObject *ob_type = reinterpret_cast<PyObject *>(type);
+ int ret = PySide_BuildSignatureArgs(ob_type, signatures);
+ if (ret < 0) {
+ PyErr_Print();
+ PyErr_SetNone(PyExc_ImportError);
+ }
+ return ret;
+}
+
void
-FinishSignatureInitialization(PyObject *module, const char *signatures)
+FinishSignatureInitialization(PyObject *module, const char *signatures[])
{
/*
* This function is called at the very end of a module initialization.
diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h
index c850698a6..6b477c52e 100644
--- a/sources/shiboken2/libshiboken/signature.h
+++ b/sources/shiboken2/libshiboken/signature.h
@@ -45,8 +45,8 @@
extern "C"
{
-LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *); //WS
-LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *);
+LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *[]);
+LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *[]);
LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *);
} // extern "C"
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index 61c38c5d7..09731240f 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -3,14 +3,9 @@ project(shibokenmodule)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/shibokenmodule.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/shibokenmodule.txt" @ONLY)
+set(sample_SRC ${CMAKE_CURRENT_BINARY_DIR}/shiboken2/shiboken2_module_wrapper.cpp)
-set(sample_SRC
-${CMAKE_CURRENT_BINARY_DIR}/shiboken2/shiboken2_module_wrapper.cpp
-)
-
-set(shibokenmodule_TYPESYSTEM
-${CMAKE_CURRENT_SOURCE_DIR}/typesystem_shiboken.xml
-)
+set(shibokenmodule_TYPESYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_shiboken.xml)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
@@ -24,19 +19,16 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'shiboken2'..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(shibokenmodule MODULE ${sample_SRC})
+target_include_directories(shibokenmodule PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR})
set_property(TARGET shibokenmodule PROPERTY PREFIX "")
set_property(TARGET shibokenmodule PROPERTY OUTPUT_NAME "shiboken2${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET shibokenmodule PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(shibokenmodule
- libshiboken)
+target_link_libraries(shibokenmodule PUBLIC libshiboken)
add_dependencies(shibokenmodule shiboken2)
create_generator_target(shibokenmodule)
diff --git a/sources/shiboken2/shibokenmodule/__init__.py.in b/sources/shiboken2/shibokenmodule/__init__.py.in
index 066fd3584..ed6ce5623 100644
--- a/sources/shiboken2/shibokenmodule/__init__.py.in
+++ b/sources/shiboken2/shibokenmodule/__init__.py.in
@@ -3,7 +3,26 @@ __version_info__ = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboke
# PYSIDE-932: Python 2 cannot import 'zipfile' for embedding while being imported, itself.
# We simply pre-load all imports for the signature extension.
-import sys, zipfile, base64, marshal, io, contextlib
+# Also, PyInstaller seems not always to be reliable in finding modules.
+# We explicitly import everything that is needed:
+import sys
+import os
+import zipfile
+import base64
+import marshal
+import io
+import contextlib
+import textwrap
+import traceback
+import types
+import struct
+import re
+import tempfile
+import keyword
+import functools
+if sys.version_info[0] == 3:
+ # PyInstaller seems to sometimes fail:
+ import typing
from .shiboken2 import *
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index a564aedb9..6c76483a0 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -119,7 +119,6 @@ from shibokensupport import signature
signature.get_signature = signature_bootstrap.get_signature
del signature_bootstrap
-
def _get_modname(mod):
return mod.__spec__.name if getattr(mod, "__spec__", None) else mod.__name__
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 9a8ee4c4e..306103304 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -418,6 +418,9 @@ def init_QtCore():
"PySide2.QtCore.quint32": int,
"PySide2.QtCore.quint64": int,
"PySide2.QtCore.quint8": int,
+ "PySide2.QtCore.short": int,
+ "PySide2.QtCore.unsigned short": int,
+ "PySide2.QtCore.signed char": Char,
"PySide2.QtCore.uchar": Char,
"PySide2.QtCore.unsigned char": Char, # 5.9
"PySide2.QtCore.long": int,
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 09e78f1b0..72ca35757 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -224,7 +224,6 @@ def _resolve_type(thing, line):
return _resolve_value(thing, None, line)
def calculate_props(line):
- line = line.strip()
res = _parse_line(line)
arglist = res["arglist"]
annotations = {}
@@ -257,8 +256,7 @@ def calculate_props(line):
props["multi"] = res["multi"]
return props
-def fixup_multilines(sig_str):
- lines = list(line.strip() for line in sig_str.strip().splitlines())
+def fixup_multilines(lines):
res = []
multi_lines = []
for line in lines:
@@ -282,15 +280,11 @@ def fixup_multilines(sig_str):
res.append(line)
return res
-def pyside_type_init(typemod, sig_str):
+def pyside_type_init(type_key, sig_strings):
dprint()
- if type(typemod) is types.ModuleType:
- dprint("Initialization of module '{}'".format(typemod.__name__))
- else:
- dprint("Initialization of type '{}.{}'".format(typemod.__module__,
- typemod.__name__))
+ dprint("Initialization of type key '{}'".format(type_key))
update_mapping()
- lines = fixup_multilines(sig_str)
+ lines = fixup_multilines(sig_strings)
ret = {}
multi_props = []
for line in lines:
diff --git a/sources/shiboken2/tests/CMakeLists.txt b/sources/shiboken2/tests/CMakeLists.txt
index c06c56f6d..085a4344c 100644
--- a/sources/shiboken2/tests/CMakeLists.txt
+++ b/sources/shiboken2/tests/CMakeLists.txt
@@ -1,6 +1,3 @@
-find_package(Qt5 REQUIRED COMPONENTS Core)
-include_directories(${Qt5Core_INCLUDE_DIRS})
-
add_subdirectory(libminimal)
if(NOT DEFINED MINIMAL_TESTS)
add_subdirectory(libsample)
diff --git a/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt b/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
index af18cb3c8..7c6d60fe2 100644
--- a/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
+++ b/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
@@ -1,5 +1,6 @@
add_executable(dumpcodemodel main.cpp)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${apiextractor_SOURCE_DIR} ${Qt5Core_INCLUDE_DIRS})
+target_include_directories(dumpcodemodel
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${apiextractor_SOURCE_DIR})
-target_link_libraries(dumpcodemodel apiextractor ${Qt5Core_LIBRARIES})
+target_link_libraries(dumpcodemodel PUBLIC apiextractor Qt5::Core)
diff --git a/sources/shiboken2/tests/libminimal/CMakeLists.txt b/sources/shiboken2/tests/libminimal/CMakeLists.txt
index a25892571..f906bdb84 100644
--- a/sources/shiboken2/tests/libminimal/CMakeLists.txt
+++ b/sources/shiboken2/tests/libminimal/CMakeLists.txt
@@ -6,8 +6,8 @@ listuser.cpp
typedef.cpp
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-add_definitions("-DLIBMINIMAL_BUILD")
add_library(libminimal SHARED ${libminimal_SRC})
+target_include_directories(libminimal PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libminimal PRIVATE LIBMINIMAL_BUILD)
set_property(TARGET libminimal PROPERTY PREFIX "")
diff --git a/sources/shiboken2/tests/libother/CMakeLists.txt b/sources/shiboken2/tests/libother/CMakeLists.txt
index 9b3cf5552..6aba91e13 100644
--- a/sources/shiboken2/tests/libother/CMakeLists.txt
+++ b/sources/shiboken2/tests/libother/CMakeLists.txt
@@ -7,12 +7,10 @@ otherobjecttype.cpp
othermultiplederived.cpp
)
-add_definitions("-DLIBOTHER_BUILD")
add_library(libother SHARED ${libother_SRC})
+target_include_directories(libother PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libother PRIVATE LIBOTHER_BUILD)
+target_link_libraries(libother PUBLIC libsample)
set_property(TARGET libother PROPERTY PREFIX "")
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${libsample_SOURCE_DIR}
- ${libsample_SOURCE_DIR}/..)
-target_link_libraries(libother libsample)
diff --git a/sources/shiboken2/tests/libsample/CMakeLists.txt b/sources/shiboken2/tests/libsample/CMakeLists.txt
index ae3d40312..170829fbc 100644
--- a/sources/shiboken2/tests/libsample/CMakeLists.txt
+++ b/sources/shiboken2/tests/libsample/CMakeLists.txt
@@ -51,8 +51,8 @@ expression.cpp
filter.cpp
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-add_definitions("-DLIBSAMPLE_BUILD")
add_library(libsample SHARED ${libsample_SRC})
+target_include_directories(libsample PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libsample PRIVATE LIBSAMPLE_BUILD)
set_property(TARGET libsample PROPERTY PREFIX "")
diff --git a/sources/shiboken2/tests/libsmart/CMakeLists.txt b/sources/shiboken2/tests/libsmart/CMakeLists.txt
index 66c27cdae..152c57f25 100644
--- a/sources/shiboken2/tests/libsmart/CMakeLists.txt
+++ b/sources/shiboken2/tests/libsmart/CMakeLists.txt
@@ -4,8 +4,8 @@ set(libsmart_SRC
smart.cpp
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-add_definitions("-DLIBSMART_BUILD")
add_library(libsmart SHARED ${libsmart_SRC})
+target_include_directories(libsmart PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libsmart PRIVATE LIBSMART_BUILD)
set_property(TARGET libsmart PROPERTY PREFIX "")
diff --git a/sources/shiboken2/tests/minimalbinding/CMakeLists.txt b/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
index 7301e1882..ffeb086a0 100644
--- a/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
@@ -24,18 +24,13 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'minimal' test binding..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libminimal_SOURCE_DIR}
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(minimal MODULE ${minimal_SRC})
+target_include_directories(minimal PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(minimal PUBLIC libminimal libshiboken)
set_property(TARGET minimal PROPERTY PREFIX "")
set_property(TARGET minimal PROPERTY OUTPUT_NAME "minimal${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET minimal PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(minimal
- libminimal
- libshiboken)
+
create_generator_target(minimal)
diff --git a/sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml b/sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml
index 968b27c53..03b88a970 100644
--- a/sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml
+++ b/sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="minimal">
<primitive-type name="bool"/>
<primitive-type name="int"/>
diff --git a/sources/shiboken2/tests/otherbinding/CMakeLists.txt b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
index 44855e297..bc5c4bdad 100644
--- a/sources/shiboken2/tests/otherbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
@@ -26,26 +26,17 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'other' test binding..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libother_SOURCE_DIR}
- ${libsample_SOURCE_DIR}
- ${libsample_SOURCE_DIR}/..
- ${sample_BINARY_DIR}
- ${sample_BINARY_DIR}/sample
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(other MODULE ${other_SRC})
+target_include_directories(other PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${sample_BINARY_DIR}/sample)
+target_link_libraries(other PUBLIC libother libsample libshiboken)
set_property(TARGET other PROPERTY PREFIX "")
set_property(TARGET other PROPERTY OUTPUT_NAME "other${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET other PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(other
- libother
- libsample
- libshiboken)
+
add_dependencies(other sample)
create_generator_target(other)
diff --git a/sources/shiboken2/tests/otherbinding/typesystem_other.xml b/sources/shiboken2/tests/otherbinding/typesystem_other.xml
index 63ccdd518..2932dafb3 100644
--- a/sources/shiboken2/tests/otherbinding/typesystem_other.xml
+++ b/sources/shiboken2/tests/otherbinding/typesystem_other.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="other">
<load-typesystem name="typesystem_sample.xml" generate="no" />
diff --git a/sources/shiboken2/tests/samplebinding/CMakeLists.txt b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
index 9ecbd98e6..61090d30e 100644
--- a/sources/shiboken2/tests/samplebinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
@@ -137,19 +137,14 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'sample' test binding..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libsample_SOURCE_DIR}
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(sample MODULE ${sample_SRC})
+target_include_directories(sample PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(sample PUBLIC libsample libshiboken)
set_property(TARGET sample PROPERTY PREFIX "")
set_property(TARGET sample PROPERTY OUTPUT_NAME "sample${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET sample PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(sample
- libsample
- libshiboken)
+
create_generator_target(sample)
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 78ceaab43..19b4948a1 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="sample">
<suppress-warning text="Duplicate type entry: 'sample'" />
<suppress-warning text="Duplicate type entry: 'SampleNamespace'" />
diff --git a/sources/shiboken2/tests/smartbinding/CMakeLists.txt b/sources/shiboken2/tests/smartbinding/CMakeLists.txt
index ed6bcef0a..88a7bc059 100644
--- a/sources/shiboken2/tests/smartbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/smartbinding/CMakeLists.txt
@@ -27,19 +27,14 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'smart' test binding..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libsmart_SOURCE_DIR}
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(smart MODULE ${smart_SRC})
+target_include_directories(smart PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(smart PUBLIC libsmart libshiboken)
set_property(TARGET smart PROPERTY PREFIX "")
set_property(TARGET smart PROPERTY OUTPUT_NAME "smart${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET smart PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(smart
- libsmart
- libshiboken)
+
create_generator_target(smart)
diff --git a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
index aea1c2f73..0bb485957 100644
--- a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
+++ b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="smart">
<primitive-type name="int" />
<primitive-type name="char" />