aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-11-09 10:40:29 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-11-10 14:14:59 +0100
commit3681ae61aaab836d26ad227911c3bfca92322f12 (patch)
tree0d368fe6dd1b434f4e3838224c4e9c732abada1f
parent2a71960d3ff3640b3dcb0c1b1eb004bbb3eaea4d (diff)
shiboken6: Enable specifying namespaces for smart pointer instantiations
[ChangeLog][shiboken6] It is now possible to specify a namespace for a smart pointer instantiation. Task-number: PYSIDE-454 Change-Id: I9b61c3514211108fd7009e1776ae4fb8988c576b Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractor.cpp38
-rw-r--r--sources/shiboken6/ApiExtractor/messages.cpp5
-rw-r--r--sources/shiboken6/ApiExtractor/messages.h2
-rw-r--r--sources/shiboken6/doc/typesystem_specifying_types.rst1
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp6
-rw-r--r--sources/shiboken6/tests/libsmart/smart.h1
-rw-r--r--sources/shiboken6/tests/libsmart/smart_test.h13
-rw-r--r--sources/shiboken6/tests/smartbinding/CMakeLists.txt1
-rw-r--r--sources/shiboken6/tests/smartbinding/smart_pointer_test.py1
-rw-r--r--sources/shiboken6/tests/smartbinding/typesystem_smart.xml6
10 files changed, 68 insertions, 6 deletions
diff --git a/sources/shiboken6/ApiExtractor/apiextractor.cpp b/sources/shiboken6/ApiExtractor/apiextractor.cpp
index 43c48882f..15b074d4d 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractor.cpp
@@ -12,6 +12,7 @@
#include "abstractmetalang.h"
#include "codesnip.h"
#include "exception.h"
+#include "messages.h"
#include "modifications.h"
#include "reporthandler.h"
#include "typedatabase.h"
@@ -20,6 +21,7 @@
#include "primitivetypeentry.h"
#include "smartpointertypeentry.h"
#include "typedefentry.h"
+#include "namespacetypeentry.h"
#include "typesystemtypeentry.h"
#include "qtcompat.h"
@@ -508,14 +510,35 @@ void ApiExtractorPrivate::addInstantiatedSmartPointer(InstantiationCollectContex
auto *ste = static_cast<const SmartPointerTypeEntry *>(smp.smartPointer->typeEntry());
QString name = ste->getTargetName(smp.type);
auto *parentTypeEntry = ste->parent();
+ InheritTemplateFlags flags;
+
+ auto colonPos = name.lastIndexOf(u"::");
+ const bool withinNameSpace = colonPos != -1;
+ if (withinNameSpace) { // user defined
+ const QString nameSpace = name.left(colonPos);
+ name.remove(0, colonPos + 2);
+ const auto nameSpaces = TypeDatabase::instance()->findNamespaceTypes(nameSpace);
+ if (nameSpaces.isEmpty())
+ throw Exception(msgNamespaceNotFound(name));
+ parentTypeEntry = nameSpaces.constFirst();
+ } else {
+ flags.setFlag(InheritTemplateFlag::SetEnclosingClass);
+ }
+
auto *typedefEntry = new TypedefEntry(name, ste->name(), ste->version(), parentTypeEntry);
typedefEntry->setTargetLangPackage(ste->targetLangPackage());
auto *instantiationEntry = TypeDatabase::initializeTypeDefEntry(typedefEntry, ste);
smp.specialized = ApiExtractor::inheritTemplateClass(instantiationEntry, smp.smartPointer,
- {instantiatedType},
- InheritTemplateFlag::SetEnclosingClass);
+ {instantiatedType}, flags);
Q_ASSERT(smp.specialized);
+ if (withinNameSpace) { // move class to desired namespace
+ auto *enclClass = AbstractMetaClass::findClass(m_builder->classes(), parentTypeEntry);
+ Q_ASSERT(enclClass);
+ auto *specialized = const_cast<AbstractMetaClass *>(smp.specialized);
+ specialized->setEnclosingClass(enclClass);
+ enclClass->addInnerClass(specialized);
+ }
if (instantiationEntry->isComplex()) {
addOwnerModification(smp.specialized->queryFunctions(FunctionQueryOption::Constructors),
@@ -550,8 +573,15 @@ ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(Instantiation
collectInstantiatedContainersAndSmartPointers(context, func);
for (const AbstractMetaField &field : metaClass->fields())
addInstantiatedContainersAndSmartPointers(context, field.type(), field.name());
- for (auto *innerClass : metaClass->innerClasses())
- collectInstantiatedContainersAndSmartPointers(context, innerClass);
+
+ // The list of inner classes might be extended when smart pointer
+ // instantiations are specified to be in namespaces.
+ auto &innerClasses = metaClass->innerClasses();
+ for (auto i = innerClasses.size() - 1; i >= 0; --i) {
+ auto *innerClass = innerClasses.at(i);
+ if (!innerClass->typeEntry()->isSmartPointer())
+ collectInstantiatedContainersAndSmartPointers(context, innerClass);
+ }
}
void
diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp
index 5fbd6c8aa..f9dad4d50 100644
--- a/sources/shiboken6/ApiExtractor/messages.cpp
+++ b/sources/shiboken6/ApiExtractor/messages.cpp
@@ -255,6 +255,11 @@ QString msgNamespaceNoTypeEntry(const NamespaceModelItem &item,
return result;
}
+QString msgNamespaceNotFound(const QString &name)
+{
+ return u"namespace '"_s + name + u"' not found."_s;
+}
+
QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te)
{
QString result = u"Ambiguous types of varying types found for \""_s + qualifiedName
diff --git a/sources/shiboken6/ApiExtractor/messages.h b/sources/shiboken6/ApiExtractor/messages.h
index 1d40dc76c..6b4ce2711 100644
--- a/sources/shiboken6/ApiExtractor/messages.h
+++ b/sources/shiboken6/ApiExtractor/messages.h
@@ -67,6 +67,8 @@ QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
QString msgNamespaceNoTypeEntry(const NamespaceModelItem &item,
const QString &fullName);
+QString msgNamespaceNotFound(const QString &name);
+
QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te);
QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntries &te);
diff --git a/sources/shiboken6/doc/typesystem_specifying_types.rst b/sources/shiboken6/doc/typesystem_specifying_types.rst
index b43c66732..f7409f3b3 100644
--- a/sources/shiboken6/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken6/doc/typesystem_specifying_types.rst
@@ -665,6 +665,7 @@ smart-pointer-type
found in the code will be generated. The type name might optionally
be followed an equal sign and the Python type name, for example
``instantiations="int=IntPtr,double=DoublePtr"``.
+ It is also possible to specify a namespace delimited by ``::``.
The *optional* attribute **type** specifies the type:
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index dea6550f7..d259ce82c 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -6635,9 +6635,13 @@ bool CppGenerator::finishGeneration()
// Initialize smart pointer types.
for (const auto &smp : api().instantiatedSmartPointers()) {
GeneratorContext context = contextForSmartPointer(smp.specialized, smp.type);
+ auto *enclosingClass = context.metaClass()->enclosingClass();
+ auto *enclosingTypeEntry = enclosingClass != nullptr
+ ? enclosingClass->typeEntry()
+ : smp.type.typeEntry()->targetLangEnclosingEntry();
writeInitFunc(s_classInitDecl, s_classPythonDefines,
getInitFunctionName(context),
- smp.type.typeEntry()->targetLangEnclosingEntry());
+ enclosingTypeEntry);
includes << smp.type.instantiations().constFirst().typeEntry()->include();
}
diff --git a/sources/shiboken6/tests/libsmart/smart.h b/sources/shiboken6/tests/libsmart/smart.h
index 9819ef43d..1f610b302 100644
--- a/sources/shiboken6/tests/libsmart/smart.h
+++ b/sources/shiboken6/tests/libsmart/smart.h
@@ -8,6 +8,7 @@
#include "smart_integer.h"
#include "smart_obj.h"
#include "smart_registry.h"
+#include "smart_test.h"
#include "stdsharedptrtestbench.h"
#include "stdoptionaltestbench.h"
#include "stduniqueptrtestbench.h"
diff --git a/sources/shiboken6/tests/libsmart/smart_test.h b/sources/shiboken6/tests/libsmart/smart_test.h
new file mode 100644
index 000000000..89d8cbc7c
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart_test.h
@@ -0,0 +1,13 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SMART_TEST_H
+#define SMART_TEST_H
+
+namespace Test {
+
+enum DummyEnum { Dummy1, Dummy2 };
+
+}
+
+#endif // SMART_TEST_H
diff --git a/sources/shiboken6/tests/smartbinding/CMakeLists.txt b/sources/shiboken6/tests/smartbinding/CMakeLists.txt
index 577c8936f..b15967781 100644
--- a/sources/shiboken6/tests/smartbinding/CMakeLists.txt
+++ b/sources/shiboken6/tests/smartbinding/CMakeLists.txt
@@ -26,6 +26,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_int_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/stdoptionaltestbench_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/stduniqueptrtestbench_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/stduniqueptrvirtualmethodtester_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/test_wrapper.cpp
)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/smart-binding.txt.in"
diff --git a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
index 5401d77d7..1bec3a286 100644
--- a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
+++ b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
@@ -233,6 +233,7 @@ class SmartPointerTests(unittest.TestCase):
integer2 = o.createSharedPtrInteger2()
# User defined name
self.assertEqual(type(integer2).__name__, "SmartInteger2Ptr")
+ self.assertTrue("smart.Test.SmartInteger2Ptr" in repr(type(integer2)))
self.assertEqual(integer2.value(), 456)
# pass Smart<Integer2> to a function that accepts Smart<Integer>
diff --git a/sources/shiboken6/tests/smartbinding/typesystem_smart.xml b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
index 74bfc28f1..261d5f15d 100644
--- a/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
+++ b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
@@ -28,7 +28,7 @@
-->
<smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount"
null-check-method="isNull"
- instantiations="Integer,Smart::Integer2=SmartInteger2Ptr,Obj"/>
+ instantiations="Integer,Smart::Integer2=Test::SmartInteger2Ptr,Obj"/>
<object-type name="Obj" />
<value-type name="Integer" />
@@ -74,4 +74,8 @@
<object-type name="StdUniquePtrTestBench"/>
<object-type name="StdUniquePtrVirtualMethodTester"/>
+ <namespace-type name="Test">
+ <enum-type name="DummyEnum"/>
+ </namespace-type>
+
</typesystem>