diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2010-12-22 14:58:37 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:12:50 -0300 |
commit | bda44c2851c04183e1e92dccf9a43b949d0b2b0b (patch) | |
tree | c653238f1d006320a6579f6e086c71663158bdad /generator | |
parent | 2e4e0d4e91c561986a96a08b0dbee53984811155 (diff) |
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>
Diffstat (limited to 'generator')
-rw-r--r-- | generator/cppgenerator.cpp | 42 | ||||
-rw-r--r-- | generator/headergenerator.cpp | 9 | ||||
-rw-r--r-- | generator/shibokengenerator.cpp | 32 | ||||
-rw-r--r-- | generator/shibokengenerator.h | 5 |
4 files changed, 73 insertions, 15 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index 4d24416f8..152510235 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; @@ -2915,10 +2919,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 @@ -2984,7 +2989,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 { @@ -3336,12 +3341,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); @@ -3542,10 +3551,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) @@ -3575,13 +3593,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; @@ -3659,12 +3677,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 7a49a8c41..9a28cdb94 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 697c89e58..2647e634b 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 74396eb0e..ade04662d 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); |