aboutsummaryrefslogtreecommitdiff
path: root/tests/GenerateSipBindings
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2017-01-14 22:13:49 +0000
committerStephen Kelly <steveire@gmail.com>2017-01-15 11:18:50 +0000
commit636d6acc7adf8bf7169d38833340161dc42d3484 (patch)
tree2ff1bbefa5808aec21e902b10c9547e359067604 /tests/GenerateSipBindings
parent8c347c61abafa68e247ff4664ae658cfa15af932 (diff)
downloadextra-cmake-modules-636d6acc7adf8bf7169d38833340161dc42d3484.tar.gz
extra-cmake-modules-636d6acc7adf8bf7169d38833340161dc42d3484.tar.bz2
Bindings: Fix handling of forward declarations
It is not appropriate to decorate each forward declaration with the SIP attribute /External/. That is only needed for forward declarations of types which are defined in a different module. Local forward declarations can be omitted from the sip code. In sip code, a forward declaration followed later by a full class definition is an error. Omit forward declarations unless they are decorated with the external attribute. Introduce a rules database for consumers to decorate them with the attribute as required.
Diffstat (limited to 'tests/GenerateSipBindings')
-rw-r--r--tests/GenerateSipBindings/CMakeLists.txt19
-rw-r--r--tests/GenerateSipBindings/cpplib.cpp40
-rw-r--r--tests/GenerateSipBindings/cpplib.h26
-rw-r--r--tests/GenerateSipBindings/external_lib.cpp13
-rw-r--r--tests/GenerateSipBindings/external_lib.h12
-rw-r--r--tests/GenerateSipBindings/rules_SipTest.py8
-rw-r--r--tests/GenerateSipBindings/testscript.py16
7 files changed, 121 insertions, 13 deletions
diff --git a/tests/GenerateSipBindings/CMakeLists.txt b/tests/GenerateSipBindings/CMakeLists.txt
index 223b2fed..c223bcef 100644
--- a/tests/GenerateSipBindings/CMakeLists.txt
+++ b/tests/GenerateSipBindings/CMakeLists.txt
@@ -10,8 +10,15 @@ set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
set(CMAKE_CXX_STANDARD 14)
+add_library(ExternalLib SHARED external_lib.cpp)
+target_link_libraries(ExternalLib PUBLIC Qt5::Core)
+target_compile_features(ExternalLib PUBLIC cxx_nullptr)
+
add_library(CppLib SHARED cpplib.cpp)
-target_link_libraries(CppLib PUBLIC Qt5::Core)
+target_link_libraries(CppLib
+ PUBLIC Qt5::Core
+ PRIVATE ExternalLib
+)
target_compile_features(CppLib PUBLIC cxx_nullptr)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../find-modules)
@@ -19,6 +26,16 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../find-modules)
find_package(PythonModuleGeneration REQUIRED)
ecm_generate_python_binding(
+ TARGET ExternalLib
+ PYTHONNAMESPACE PyTest
+ MODULENAME ExternalLib
+ SIP_DEPENDS
+ QtCore/QtCoremod.sip
+ HEADERS
+ external_lib.h
+)
+
+ecm_generate_python_binding(
TARGET CppLib
PYTHONNAMESPACE PyTest
MODULENAME CppLib
diff --git a/tests/GenerateSipBindings/cpplib.cpp b/tests/GenerateSipBindings/cpplib.cpp
index 8dc7492b..524a0936 100644
--- a/tests/GenerateSipBindings/cpplib.cpp
+++ b/tests/GenerateSipBindings/cpplib.cpp
@@ -1,6 +1,8 @@
#include "cpplib.h"
+#include "external_lib.h"
+
MyObject::MyObject(QObject* parent)
: QObject(parent)
{
@@ -65,19 +67,21 @@ int MyObject::groups(unsigned int maxCount) const
return maxCount;
}
-class FwdDecl
+int MyObject::externalFwdDecl(const ExternalFwdDecl& f)
{
+ return f.getValue();
+}
-};
-
-int MyObject::fwdDecl(const FwdDecl&)
+int MyObject::externalFwdDeclRef(ExternalFwdDecl& f)
{
- return 42;
+ return f.getValue();
}
-int MyObject::fwdDeclRef(FwdDecl&)
+int MyObject::localDeclListDecl(const QList<LocalFwdDecl>& l)
{
- return 42;
+ return std::accumulate(l.begin(), l.end(), 0, [](int current, LocalFwdDecl const& next){
+ return current + next.getValue();
+ });
}
int MyObject::const_parameters(const int input, QObject* const obj) const
@@ -86,6 +90,28 @@ int MyObject::const_parameters(const int input, QObject* const obj) const
return input / 2;
}
+int MyObject::localFwdDecl(const LocalFwdDecl& f)
+{
+ return f.getValue();
+}
+
+int MyObject::localListDecl(const QList<int>& l)
+{
+ return std::accumulate(l.begin(), l.end(), 0);
+}
+
+LocalFwdDecl::LocalFwdDecl(int value)
+ : m_value(value)
+{
+
+}
+
+int LocalFwdDecl::getValue() const
+{
+ return m_value;
+}
+
+
NonCopyable::NonCopyable()
: mNum(new int(42))
{
diff --git a/tests/GenerateSipBindings/cpplib.h b/tests/GenerateSipBindings/cpplib.h
index 9b9adcba..3ae9448a 100644
--- a/tests/GenerateSipBindings/cpplib.h
+++ b/tests/GenerateSipBindings/cpplib.h
@@ -10,7 +10,10 @@
#include <functional>
-class FwdDecl;
+class ExternalFwdDecl;
+class LocalFwdDecl;
+
+template<typename T> class QList;
class MyObject : public QObject
{
@@ -46,8 +49,14 @@ public:
int const_parameters(const int input, QObject* const obj = 0) const;
- int fwdDecl(const FwdDecl& f);
- int fwdDeclRef(FwdDecl& f);
+ int externalFwdDecl(const ExternalFwdDecl& f);
+ int externalFwdDeclRef(ExternalFwdDecl& f);
+
+ int localFwdDecl(const LocalFwdDecl& f);
+
+ int localListDecl(const QList<int>& l);
+
+ int localDeclListDecl(const QList<LocalFwdDecl>& l);
mode_t dummyFunc(QObject* parent) { return 0; }
@@ -77,6 +86,17 @@ private Q_SLOTS:
void privateSlot2();
};
+class LocalFwdDecl
+{
+public:
+ LocalFwdDecl(int value);
+
+ int getValue() const;
+
+private:
+ int m_value;
+};
+
class NonCopyable
{
public:
diff --git a/tests/GenerateSipBindings/external_lib.cpp b/tests/GenerateSipBindings/external_lib.cpp
new file mode 100644
index 00000000..a08125ff
--- /dev/null
+++ b/tests/GenerateSipBindings/external_lib.cpp
@@ -0,0 +1,13 @@
+
+#include "external_lib.h"
+
+ExternalFwdDecl::ExternalFwdDecl(int value)
+ : m_value(value)
+{
+
+}
+
+int ExternalFwdDecl::getValue() const
+{
+ return m_value;
+}
diff --git a/tests/GenerateSipBindings/external_lib.h b/tests/GenerateSipBindings/external_lib.h
new file mode 100644
index 00000000..f5ea38b2
--- /dev/null
+++ b/tests/GenerateSipBindings/external_lib.h
@@ -0,0 +1,12 @@
+
+#pragma once
+
+class ExternalFwdDecl
+{
+public:
+ ExternalFwdDecl(int value);
+
+ int getValue() const;
+private:
+ int m_value;
+};
diff --git a/tests/GenerateSipBindings/rules_SipTest.py b/tests/GenerateSipBindings/rules_SipTest.py
index ad3fcb64..c570a039 100644
--- a/tests/GenerateSipBindings/rules_SipTest.py
+++ b/tests/GenerateSipBindings/rules_SipTest.py
@@ -10,10 +10,13 @@ def local_container_rules():
[".*", "Shared", ".*", ".*", ".*", rules_engine.discard_QSharedData_base]
]
+def local_forward_declaration_rules():
+ return [
+ [".*", "ExternalFwdDecl", ".*", rules_engine.mark_forward_declaration_external]
+ ]
+
def local_function_rules():
return [
- ["MyObject", "fwdDecl", ".*", ".*", ".*", rules_engine.function_discard],
- ["MyObject", "fwdDeclRef", ".*", ".*", ".*", rules_engine.function_discard],
["TypedefUser", "setTagPattern", ".*", ".*", ".*", rules_engine.function_discard],
]
@@ -34,6 +37,7 @@ class RuleSet(Qt5Ruleset.RuleSet):
def __init__(self):
Qt5Ruleset.RuleSet.__init__(self)
self._container_db = rules_engine.ContainerRuleDb(lambda: local_container_rules() + Qt5Ruleset.container_rules())
+ self._forward_declaration_db = rules_engine.ForwardDeclarationRuleDb(lambda: local_forward_declaration_rules() + Qt5Ruleset.forward_declaration_rules())
self._fn_db = rules_engine.FunctionRuleDb(lambda: local_function_rules() + Qt5Ruleset.function_rules())
self._typedef_db = rules_engine.TypedefRuleDb(lambda: local_typedef_rules() + Qt5Ruleset.typedef_rules())
self._modulecode = rules_engine.ModuleCodeDb({
diff --git a/tests/GenerateSipBindings/testscript.py b/tests/GenerateSipBindings/testscript.py
index 9faea837..9e12bd17 100644
--- a/tests/GenerateSipBindings/testscript.py
+++ b/tests/GenerateSipBindings/testscript.py
@@ -26,6 +26,22 @@ assert(mo.const_parameters(30, mo) == 10)
assert(mo.qtEnumTest(QtCore.Qt.MatchContains | QtCore.Qt.MatchStartsWith) == 3)
assert(mo.localEnumTest(PyTest.CppLib.MyObject.Val2) == 2)
+lfd = PyTest.CppLib.LocalFwdDecl(18)
+
+assert(mo.localFwdDecl(lfd) == 18)
+
+import PyTest.ExternalLib
+
+efd = PyTest.ExternalLib.ExternalFwdDecl(18)
+
+assert(mo.externalFwdDecl(efd) == 18)
+
+assert(mo.localListDecl([1, 5, 7]) == 13)
+
+lfdl = [PyTest.CppLib.LocalFwdDecl(3), PyTest.CppLib.LocalFwdDecl(6)]
+
+assert(mo.localDeclListDecl(lfdl) == 9)
+
#
# Verify that an enum with attributes can be read.
#