summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2010-12-22 14:58:37 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2010-12-23 11:03:04 -0300
commit1f28cdd2994f9a60e05ce887ad5568e3a9c648e9 (patch)
tree5ed35322e068795a932e6e4e7c26501434a91902
parentec2ca67a1b93b5890dacaa3683c0a6079906bd5b (diff)
downloadshiboken-1f28cdd2994f9a60e05ce887ad5568e3a9c648e9.tar.gz
shiboken-1f28cdd2994f9a60e05ce887ad5568e3a9c648e9.tar.xz
shiboken-1f28cdd2994f9a60e05ce887ad5568e3a9c648e9.zip
Added support for promoting enums from removed namespaces to upper scope.
Classes in namespaces marked not to be generated are always moved to upper scopes, the current modification add this same behaviour to enums. Tests were also added. Reviewed by Lauro Moura <lauro.neto@openbossa.org> Reviewed by Renato Ara├║jo <renato.filho@openbossa.org>
-rw-r--r--generator/cppgenerator.cpp42
-rw-r--r--generator/headergenerator.cpp9
-rw-r--r--generator/shibokengenerator.cpp32
-rw-r--r--generator/shibokengenerator.h5
-rw-r--r--tests/libsample/removednamespaces.h62
-rw-r--r--tests/samplebinding/CMakeLists.txt1
-rw-r--r--tests/samplebinding/enumfromremovednamespace_test.py49
-rw-r--r--tests/samplebinding/global.h1
-rw-r--r--tests/samplebinding/typesystem_sample.xml15
9 files changed, 201 insertions, 15 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index de4c9234..cd5f3078 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -244,10 +244,14 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl
}
}
+ AbstractMetaEnumList classEnums = metaClass->enums();
+ foreach (AbstractMetaClass* innerClass, metaClass->innerClasses())
+ lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass);
+
//Extra includes
s << endl << "// Extra includes" << endl;
QList<Include> includes = metaClass->typeEntry()->extraIncludes();
- foreach (AbstractMetaEnum* cppEnum, metaClass->enums())
+ foreach (AbstractMetaEnum* cppEnum, classEnums)
includes.append(cppEnum->typeEntry()->extraIncludes());
qSort(includes.begin(), includes.end());
foreach (Include inc, includes)
@@ -465,7 +469,7 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl
writeTypeDiscoveryFunction(s, metaClass);
- foreach (AbstractMetaEnum* cppEnum, metaClass->enums()) {
+ foreach (AbstractMetaEnum* cppEnum, classEnums) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
@@ -2913,10 +2917,11 @@ void CppGenerator::writeMethodDefinition(QTextStream& s, const AbstractMetaFunct
void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnum* cppEnum)
{
+ const AbstractMetaClass* enclosingClass = getProperEnclosingClassForEnum(cppEnum);
QString cpythonName = cpythonEnumName(cppEnum);
QString addFunction;
- if (cppEnum->enclosingClass())
- addFunction = "PyDict_SetItemString(" + cpythonTypeName(cppEnum->enclosingClass()) + ".super.ht_type.tp_dict,";
+ if (enclosingClass)
+ addFunction = "PyDict_SetItemString(" + cpythonTypeName(enclosingClass) + ".super.ht_type.tp_dict,";
else if (cppEnum->isAnonymous())
addFunction = "PyModule_AddIntConstant(module,";
else
@@ -2982,7 +2987,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
if (!cppEnum->isAnonymous()) {
s << INDENT << "enumItem = Shiboken::Enum::newItem(" << cpythonName << "," << enumValueText;
s << ", \"" << enumValue->name() << "\");" << endl;
- } else if (cppEnum->enclosingClass()) {
+ } else if (enclosingClass) {
s << INDENT << "enumItem = PyInt_FromLong(" << enumValueText << ");" << endl;
shouldDecrefNumber = true;
} else {
@@ -3338,12 +3343,16 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m
s << INDENT << "((PyObject*)&" << pyTypeName << "));" << endl << endl;
}
- if (!metaClass->enums().isEmpty()) {
+ AbstractMetaEnumList classEnums = metaClass->enums();
+ foreach (AbstractMetaClass* innerClass, metaClass->innerClasses())
+ lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass);
+
+ if (!classEnums.isEmpty()) {
s << INDENT << "// Initialize enums" << endl;
s << INDENT << "PyObject* enumItem;" << endl << endl;
}
- foreach (const AbstractMetaEnum* cppEnum, metaClass->enums()) {
+ foreach (const AbstractMetaEnum* cppEnum, classEnums) {
if (cppEnum->isPrivate())
continue;
writeEnumInitialization(s, cppEnum);
@@ -3544,10 +3553,19 @@ void CppGenerator::finishGeneration()
s << include;
s << endl;
+ // Global enums
+ AbstractMetaEnumList globalEnums = this->globalEnums();
+ foreach (const AbstractMetaClass* metaClass, classes()) {
+ const AbstractMetaClass* encClass = metaClass->enclosingClass();
+ if (encClass && encClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)
+ continue;
+ lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
+ }
+
//Extra includes
s << endl << "// Extra includes" << endl;
QList<Include> includes;
- foreach (AbstractMetaEnum* cppEnum, globalEnums())
+ foreach (AbstractMetaEnum* cppEnum, globalEnums)
includes.append(cppEnum->typeEntry()->extraIncludes());
qSort(includes.begin(), includes.end());
foreach (Include inc, includes)
@@ -3577,13 +3595,13 @@ void CppGenerator::finishGeneration()
s << "------------------------------------------------------------" << endl;
s << classInitDecl << endl;
- if (!globalEnums().isEmpty()) {
+ if (!globalEnums.isEmpty()) {
QString converterImpl;
QTextStream convImpl(&converterImpl);
s << "// Enum definitions ";
s << "------------------------------------------------------------" << endl;
- foreach (const AbstractMetaEnum* cppEnum, globalEnums()) {
+ foreach (const AbstractMetaEnum* cppEnum, globalEnums) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
s << endl;
@@ -3661,12 +3679,12 @@ void CppGenerator::finishGeneration()
}
s << endl;
- if (!globalEnums().isEmpty()) {
+ if (!globalEnums.isEmpty()) {
s << INDENT << "// Initialize enums" << endl;
s << INDENT << "PyObject* enumItem;" << endl << endl;
}
- foreach (const AbstractMetaEnum* cppEnum, globalEnums()) {
+ foreach (const AbstractMetaEnum* cppEnum, globalEnums) {
if (cppEnum->isPrivate())
continue;
writeEnumInitialization(s, cppEnum);
diff --git a/generator/headergenerator.cpp b/generator/headergenerator.cpp
index 7a49a8c4..9a28cdb9 100644
--- a/generator/headergenerator.cpp
+++ b/generator/headergenerator.cpp
@@ -311,9 +311,12 @@ void HeaderGenerator::finishGeneration()
macrosStream << "// Type indices" << endl;
int idx = 0;
- foreach (const AbstractMetaClass* metaClass, classes())
+ AbstractMetaEnumList globalEnums = this->globalEnums();
+ foreach (const AbstractMetaClass* metaClass, classes()) {
writeTypeIndexDefine(macrosStream, metaClass, idx);
- foreach (const AbstractMetaEnum* metaEnum, globalEnums())
+ lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
+ }
+ foreach (const AbstractMetaEnum* metaEnum, globalEnums)
writeTypeIndexDefineLine(macrosStream, metaEnum->typeEntry(), idx);
macrosStream << "#define ";
macrosStream.setFieldWidth(60);
@@ -324,7 +327,7 @@ void HeaderGenerator::finishGeneration()
macrosStream << "extern PyTypeObject** " << cppApiVariableName() << ';' << endl << endl;
macrosStream << "// Macros for type check" << endl;
- foreach (const AbstractMetaEnum* cppEnum, globalEnums()) {
+ foreach (const AbstractMetaEnum* cppEnum, globalEnums) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
includes << cppEnum->typeEntry()->include();
diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp
index 697c89e5..2647e634 100644
--- a/generator/shibokengenerator.cpp
+++ b/generator/shibokengenerator.cpp
@@ -216,6 +216,38 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass* metaCl
return result && !metaClass->isNamespace();
}
+void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList& enumList, const AbstractMetaClass* metaClass)
+{
+ if (!metaClass)
+ return;
+
+ if (metaClass->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass) {
+ foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) {
+ if (metaEnum->isPrivate() || metaEnum->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass)
+ continue;
+ if (!enumList.contains(const_cast<AbstractMetaEnum*>(metaEnum)))
+ enumList.append(const_cast<AbstractMetaEnum*>(metaEnum));
+ }
+ lookForEnumsInClassesNotToBeGenerated(enumList, metaClass->enclosingClass());
+ }
+}
+
+static const AbstractMetaClass* getProperEnclosingClass(const AbstractMetaClass* metaClass)
+{
+ if (!metaClass)
+ return 0;
+
+ if (metaClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)
+ return metaClass;
+
+ return getProperEnclosingClass(metaClass->enclosingClass());
+}
+
+const AbstractMetaClass* ShibokenGenerator::getProperEnclosingClassForEnum(const AbstractMetaEnum* metaEnum)
+{
+ return getProperEnclosingClass(metaEnum->enclosingClass());
+}
+
QString ShibokenGenerator::wrapperName(const AbstractMetaClass* metaClass)
{
if (shouldGenerateCppWrapper(metaClass)) {
diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h
index 74396eb0..ade04662 100644
--- a/generator/shibokengenerator.h
+++ b/generator/shibokengenerator.h
@@ -209,6 +209,11 @@ public:
/// Verifies if the class should have a C++ wrapper generated for it, instead of only a Python wrapper.
static bool shouldGenerateCppWrapper(const AbstractMetaClass* metaClass);
+ /// Adds enums eligible for generation from classes/namespaces marked not to be generated.
+ static void lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList& enumList, const AbstractMetaClass* metaClass);
+ /// Returns the enclosing class for an enum, or NULL if it should be global.
+ const AbstractMetaClass* getProperEnclosingClassForEnum(const AbstractMetaEnum* metaEnum);
+
static QString wrapperName(const AbstractMetaClass* metaClass);
static QString fullPythonFunctionName(const AbstractMetaFunction* func);
diff --git a/tests/libsample/removednamespaces.h b/tests/libsample/removednamespaces.h
new file mode 100644
index 00000000..93c3fb80
--- /dev/null
+++ b/tests/libsample/removednamespaces.h
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the Shiboken Python Binding Generator project.
+ *
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef REMOVEDNAMESPACE_H
+#define REMOVEDNAMESPACE_H
+
+#include "libsamplemacros.h"
+
+namespace RemovedNamespace1
+{
+
+enum RemovedNamespace1_Enum {
+ RemovedNamespace1_Enum_Value0
+};
+
+enum {
+ RemovedNamespace1_AnonymousEnum_Value0
+};
+
+namespace RemovedNamespace2 {
+ enum RemovedNamespace2_Enum {
+ RemovedNamespace2_Enum_Value0
+ };
+}
+
+}
+
+namespace UnremovedNamespace
+{
+namespace RemovedNamespace3
+{
+ enum RemovedNamespace3_Enum {
+ RemovedNamespace3_Enum_Value0
+ };
+
+ enum {
+ RemovedNamespace3_AnonymousEnum_Value0
+ };
+}
+}
+
+#endif // REMOVEDNAMESPACE_H
+
diff --git a/tests/samplebinding/CMakeLists.txt b/tests/samplebinding/CMakeLists.txt
index 052e246a..8e7daf3c 100644
--- a/tests/samplebinding/CMakeLists.txt
+++ b/tests/samplebinding/CMakeLists.txt
@@ -76,6 +76,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/sonofmderived1_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/str_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/strlist_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/time_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/unremovednamespace_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/virtualdaughter_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/virtualdtor_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/virtualmethods_wrapper.cpp
diff --git a/tests/samplebinding/enumfromremovednamespace_test.py b/tests/samplebinding/enumfromremovednamespace_test.py
new file mode 100644
index 00000000..4fd29582
--- /dev/null
+++ b/tests/samplebinding/enumfromremovednamespace_test.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+# -*- coding: utf-8 -*-
+#
+# This file is part of the Shiboken Python Bindings Generator project.
+#
+# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+#
+# Contact: PySide team <contact@pyside.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# version 2.1 as published by the Free Software Foundation. Please
+# review the following information to ensure the GNU Lesser General
+# Public License version 2.1 requirements will be met:
+# http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+# #
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+import unittest
+
+import sample
+
+class TestEnumFromRemovedNamespace(unittest.TestCase):
+ def testEnumPromotedToGlobal(self):
+ sample.RemovedNamespace1_Enum
+ sample.RemovedNamespace1_Enum_Value0
+ sample.RemovedNamespace1_AnonymousEnum_Value0
+ sample.RemovedNamespace2_Enum
+ sample.RemovedNamespace2_Enum_Value0
+
+ def testEnumPromotedToUpperNamespace(self):
+ sample.UnremovedNamespace
+ sample.UnremovedNamespace.RemovedNamespace3_Enum
+ sample.UnremovedNamespace.RemovedNamespace3_Enum_Value0
+ sample.UnremovedNamespace.RemovedNamespace3_AnonymousEnum_Value0
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/samplebinding/global.h b/tests/samplebinding/global.h
index 90cae083..95094f7d 100644
--- a/tests/samplebinding/global.h
+++ b/tests/samplebinding/global.h
@@ -36,6 +36,7 @@
#include "privatedtor.h"
#include "protected.h"
#include "reference.h"
+#include "removednamespaces.h"
#include "samplenamespace.h"
#include "simplefile.h"
#include "size.h"
diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml
index ae6f61b9..67956bc0 100644
--- a/tests/samplebinding/typesystem_sample.xml
+++ b/tests/samplebinding/typesystem_sample.xml
@@ -124,6 +124,21 @@
</add-function>
</namespace-type>
+ <namespace-type name="RemovedNamespace1" generate='no'>
+ <enum-type name="RemovedNamespace1_Enum" />
+ <namespace-type name="RemovedNamespace2" generate='no'>
+ <enum-type name="RemovedNamespace2_Enum" />
+ </namespace-type>
+ <enum-type identified-by-value="RemovedNamespace1_AnonymousEnum_Value0" />
+ </namespace-type>
+
+ <namespace-type name="UnremovedNamespace">
+ <namespace-type name="RemovedNamespace3" generate='no'>
+ <enum-type name="RemovedNamespace3_Enum" />
+ <enum-type identified-by-value="RemovedNamespace3_AnonymousEnum_Value0" />
+ </namespace-type>
+ </namespace-type>
+
<value-type name="IntList" />
<object-type name="Abstract">