From 0e137b5969f73a980827058e724bcdd00a2e0802 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Wed, 2 Sep 2009 02:21:23 -0300 Subject: renamed PolymorphicData class to OverloadData, this should represent correctly the class' function; other relative renamings were also performed --- CMakeLists.txt | 6 +- cppgenerator.cpp | 134 +++++----- cppgenerator.h | 10 +- overloaddata.cpp | 383 +++++++++++++++++++++++++++++ overloaddata.h | 87 +++++++ polymorphicdata.cpp | 383 ----------------------------- polymorphicdata.h | 87 ------- tests/libsample/derived.cpp | 24 +- tests/libsample/derived.h | 20 +- tests/libsample/functions.cpp | 12 +- tests/libsample/functions.h | 12 +- tests/libsample/implicitconv.cpp | 24 +- tests/libsample/implicitconv.h | 18 +- tests/libsample/modifications.h | 26 +- tests/samplebinding/derived_test.py | 56 ++--- tests/samplebinding/implicitconv_test.py | 2 +- tests/samplebinding/modifications_test.py | 28 +-- tests/samplebinding/nondefaultctor_test.py | 1 - tests/samplebinding/typesystem_sample.xml | 22 +- 19 files changed, 667 insertions(+), 668 deletions(-) create mode 100644 overloaddata.cpp create mode 100644 overloaddata.h delete mode 100644 polymorphicdata.cpp delete mode 100644 polymorphicdata.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 319fd954d..b8e5c7901 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,11 +18,11 @@ set(shiboken_VERSION 0.1) set(CMAKE_BUILD_TYPE Debug) set(shiboken_SRC -shibokengenerator.cpp -headergenerator.cpp cppgenerator.cpp -polymorphicdata.cpp +headergenerator.cpp +overloaddata.cpp shiboken.cpp +shibokengenerator.cpp ) include_directories(${CMAKE_CURRENT_SOURCE_DIR} diff --git a/cppgenerator.cpp b/cppgenerator.cpp index 6d92b112e..c78eae86d 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -398,8 +398,8 @@ void CppGenerator::writeNonVirtualModifiedFunctionNative(QTextStream& s, const A void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFunctionList overloads) { - PolymorphicData polymorphicData(overloads); - const AbstractMetaFunction* rfunc = polymorphicData.referenceFunction(); + OverloadData overloadData(overloads); + const AbstractMetaFunction* rfunc = overloadData.referenceFunction(); QString className = rfunc->ownerClass()->qualifiedCppName(); s << "PyObject*" << endl; @@ -424,14 +424,14 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun s << INDENT << "if (!PyType_IsSubtype(type, &Py" << className << "_Type))" << endl; s << INDENT << INDENT << "return 0;" << endl << endl; - if (polymorphicData.maxArgs() > 0) { + if (overloadData.maxArgs() > 0) { s << endl << INDENT << "int numArgs = "; - writeArgumentsInitializer(s, polymorphicData); + writeArgumentsInitializer(s, overloadData); } writeCodeSnips(s, getCodeSnips(rfunc), CodeSnip::Beginning, TypeSystem::All, rfunc); - writePolymorphicDecisor(s, &polymorphicData); + writeOverloadedMethodDecisor(s, &overloadData); s << endl; s << INDENT << "self = Shiboken::PyBaseWrapper_New(type, &Py" << className << "_Type, cptr);" << endl; @@ -446,8 +446,8 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun writeCodeSnips(s, getCodeSnips(rfunc), CodeSnip::End, TypeSystem::All, rfunc); s << endl << INDENT << "return self;" << endl; - if (polymorphicData.maxArgs() > 0) - writeErrorSection(s, polymorphicData); + if (overloadData.maxArgs() > 0) + writeErrorSection(s, overloadData); s << '}' << endl << endl; } @@ -487,13 +487,13 @@ void CppGenerator::writeMinimalConstructorCallArguments(QTextStream& s, const Ab void CppGenerator::writeMethodWrapper(QTextStream& s, const AbstractMetaFunctionList overloads) { - PolymorphicData polymorphicData(overloads); - const AbstractMetaFunction* rfunc = polymorphicData.referenceFunction(); + OverloadData overloadData(overloads); + const AbstractMetaFunction* rfunc = overloadData.referenceFunction(); //DEBUG //if (rfunc->isOperatorOverload()) { // QString dumpFile = QString("%1_%2.dot").arg(m_packageName).arg(pythonOperatorFunctionName(rfunc)).toLower(); - // polymorphicData.dumpGraph(dumpFile); + // overloadData.dumpGraph(dumpFile); //} //DEBUG @@ -502,8 +502,8 @@ void CppGenerator::writeMethodWrapper(QTextStream& s, const AbstractMetaFunction // if (rfunc->isInplaceOperator()) // s << "/*" << endl; - int minArgs = polymorphicData.minArgs(); - int maxArgs = polymorphicData.maxArgs(); + int minArgs = overloadData.minArgs(); + int maxArgs = overloadData.maxArgs(); if (ShibokenGenerator::isReverseOperator(rfunc)) { minArgs--; maxArgs--; @@ -541,10 +541,10 @@ void CppGenerator::writeMethodWrapper(QTextStream& s, const AbstractMetaFunction if (minArgs == 0 && maxArgs == 1) s << "(arg == 0 ? 0 : 1);" << endl; else - writeArgumentsInitializer(s, polymorphicData); + writeArgumentsInitializer(s, overloadData); } - writePolymorphicDecisor(s, &polymorphicData); + writeOverloadedMethodDecisor(s, &overloadData); s << endl << INDENT << "if (PyErr_Occurred()"; if (rfunc->type() && !rfunc->isInplaceOperator()) @@ -569,26 +569,26 @@ void CppGenerator::writeMethodWrapper(QTextStream& s, const AbstractMetaFunction s << ';' << endl; if (maxArgs > 0) - writeErrorSection(s, polymorphicData); + writeErrorSection(s, overloadData); } s << '}' << endl << endl; } -void CppGenerator::writeArgumentsInitializer(QTextStream& s, PolymorphicData& polymorphicData) +void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overloadData) { - const AbstractMetaFunction* rfunc = polymorphicData.referenceFunction(); + const AbstractMetaFunction* rfunc = overloadData.referenceFunction(); s << "PyTuple_GET_SIZE(args);" << endl; s << INDENT << "PyObject* pyargs[] = {"; - s << QString(polymorphicData.maxArgs(), '0').split("", QString::SkipEmptyParts).join(", "); + s << QString(overloadData.maxArgs(), '0').split("", QString::SkipEmptyParts).join(", "); s << "};" << endl << endl; QStringList palist; - for (int i = 0; i < polymorphicData.maxArgs(); i++) + for (int i = 0; i < overloadData.maxArgs(); i++) palist << QString("&(pyargs[%1])").arg(i); QString pyargs = palist.join(", "); - QList invalidArgsLength = polymorphicData.invalidArgumentLengths(); + QList invalidArgsLength = overloadData.invalidArgumentLengths(); if (!invalidArgsLength.isEmpty()) { QStringList invArgsLen; foreach (int i, invalidArgsLength) @@ -605,7 +605,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, PolymorphicData& po funcName = rfunc->name(); s << INDENT << "if (!PyArg_UnpackTuple(args, \"" << funcName << "\", "; - s << polymorphicData.minArgs() << ", " << polymorphicData.maxArgs(); + s << overloadData.minArgs() << ", " << overloadData.maxArgs(); s << ", " << pyargs << "))" << endl; { Indentation indent(INDENT); @@ -614,9 +614,9 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, PolymorphicData& po s << endl; } -void CppGenerator::writeErrorSection(QTextStream& s, PolymorphicData& polymorphicData) +void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData) { - const AbstractMetaFunction* rfunc = polymorphicData.referenceFunction(); + const AbstractMetaFunction* rfunc = overloadData.referenceFunction(); s << endl << INDENT << cpythonFunctionName(rfunc) << "_TypeError:" << endl; Indentation indentation(INDENT); QString funcName; @@ -629,9 +629,9 @@ void CppGenerator::writeErrorSection(QTextStream& s, PolymorphicData& polymorphi s << INDENT << "return 0;" << endl; } -void CppGenerator::writeTypeCheck(QTextStream& s, const PolymorphicData* polyData, QString argumentName) +void CppGenerator::writeTypeCheck(QTextStream& s, const OverloadData* overloadData, QString argumentName) { - const AbstractMetaType* argType = polyData->argType(); + const AbstractMetaType* argType = overloadData->argType(); AbstractMetaFunctionList implicitConverters; if (argType->isValue()) { const AbstractMetaClass* metaClass = classes().findClass(argType->name()); @@ -640,15 +640,15 @@ void CppGenerator::writeTypeCheck(QTextStream& s, const PolymorphicData* polyDat } int alternativeNumericTypes = 0; - foreach (PolymorphicData* pd, polyData->polymorphicDataOnPosition(polyData->argPos())) { + foreach (OverloadData* pd, overloadData->overloadDataOnPosition(overloadData->argPos())) { if (!pd->argType()->isPrimitive()) continue; if (ShibokenGenerator::isNumber(pd->argType()->typeEntry())) alternativeNumericTypes++; } - // This condition trusts that the PolymorphicData object will arrange for - // PyInt type to be the last entry on a list of polymorphic argument data. + // This condition trusts that the OverloadData object will arrange for + // PyInt type to be the last entry on a list of overload argument data. bool numberType = alternativeNumericTypes == 1 || ShibokenGenerator::isPyInt(argType); if (implicitConverters.size() > 0) @@ -666,33 +666,33 @@ void CppGenerator::writeTypeCheck(QTextStream& s, const PolymorphicData* polyDat s << ')'; } -void CppGenerator::writePolymorphicDecisor(QTextStream& s, PolymorphicData* parentPolymorphicData) +void CppGenerator::writeOverloadedMethodDecisor(QTextStream& s, OverloadData* parentOverloadData) { - bool hasDefaultCall = parentPolymorphicData->nextArgumentHasDefaultValue(); - if (!hasDefaultCall && parentPolymorphicData->isHeadPolymorphicData()) { - foreach (const AbstractMetaFunction* func, parentPolymorphicData->overloads()) { - if (parentPolymorphicData->isFinalOccurrence(func)) { + bool hasDefaultCall = parentOverloadData->nextArgumentHasDefaultValue(); + if (!hasDefaultCall && parentOverloadData->isHeadOverloadData()) { + foreach (const AbstractMetaFunction* func, parentOverloadData->overloads()) { + if (parentOverloadData->isFinalOccurrence(func)) { hasDefaultCall = true; break; } } } - const AbstractMetaFunction* rfunc = parentPolymorphicData->referenceFunction(); + const AbstractMetaFunction* rfunc = parentOverloadData->referenceFunction(); - int minArgs = parentPolymorphicData->minArgs(); - int maxArgs = parentPolymorphicData->maxArgs(); + int minArgs = parentOverloadData->minArgs(); + int maxArgs = parentOverloadData->maxArgs(); if (ShibokenGenerator::isReverseOperator(rfunc)) { minArgs--; maxArgs--; } if (maxArgs == 0 - || (!parentPolymorphicData->isHeadPolymorphicData() - && (parentPolymorphicData->nextPolymorphicData().isEmpty() - || (!hasDefaultCall && parentPolymorphicData->overloads().size() == 1)))) { - const AbstractMetaFunction* func = parentPolymorphicData->overloads()[0]; - int removed = PolymorphicData::numberOfRemovedArguments(func); + || (!parentOverloadData->isHeadOverloadData() + && (parentOverloadData->nextOverloadData().isEmpty() + || (!hasDefaultCall && parentOverloadData->overloads().size() == 1)))) { + const AbstractMetaFunction* func = parentOverloadData->overloads()[0]; + int removed = OverloadData::numberOfRemovedArguments(func); writeMethodCall(s, func, func->arguments().size() - removed); return; } @@ -703,19 +703,19 @@ void CppGenerator::writePolymorphicDecisor(QTextStream& s, PolymorphicData* pare // can make a default call if (hasDefaultCall) { - s << "if (numArgs == " << parentPolymorphicData->argPos() + 1 << ") { // hasDefaultCall" << endl; + s << "if (numArgs == " << parentOverloadData->argPos() + 1 << ") { // hasDefaultCall" << endl; { Indentation indent(INDENT); - writeMethodCall(s, rfunc, parentPolymorphicData->argPos() + 1); + writeMethodCall(s, rfunc, parentOverloadData->argPos() + 1); } s << INDENT << "} else "; } // last occurrence of function signature - if (!parentPolymorphicData->isHeadPolymorphicData()) { - foreach (const AbstractMetaFunction* func, parentPolymorphicData->overloads()) { - if (parentPolymorphicData->isFinalOccurrence(func)) { - int lastArg = parentPolymorphicData->argPos() + 1; + if (!parentOverloadData->isHeadOverloadData()) { + foreach (const AbstractMetaFunction* func, parentOverloadData->overloads()) { + if (parentOverloadData->isFinalOccurrence(func)) { + int lastArg = parentOverloadData->argPos() + 1; s << "if (numArgs == " << lastArg << ") { // final:" << func->minimalSignature() << endl; { Indentation indent(INDENT); @@ -726,33 +726,33 @@ void CppGenerator::writePolymorphicDecisor(QTextStream& s, PolymorphicData* pare } } - foreach (PolymorphicData* polymorphicData, parentPolymorphicData->nextPolymorphicData()) { + foreach (OverloadData* overloadData, parentOverloadData->nextOverloadData()) { if (maxArgs > 0) { - bool signatureFound = polymorphicData->overloads().size() == 1 && - !polymorphicData->nextArgumentHasDefaultValue(); - const AbstractMetaFunction* func = polymorphicData->overloads()[0]; - QString pyArgName = varargs ? QString("pyargs[%1]").arg(polymorphicData->argPos()) : "arg"; + bool signatureFound = overloadData->overloads().size() == 1 && + !overloadData->nextArgumentHasDefaultValue(); + const AbstractMetaFunction* func = overloadData->overloads()[0]; + QString pyArgName = varargs ? QString("pyargs[%1]").arg(overloadData->argPos()) : "arg"; s << "if ("; if (signatureFound && varargs) { s << "numArgs == "; - s << func->arguments().size() - PolymorphicData::numberOfRemovedArguments(func); + s << func->arguments().size() - OverloadData::numberOfRemovedArguments(func); s << " && "; } - writeTypeCheck(s, polymorphicData, pyArgName); + writeTypeCheck(s, overloadData, pyArgName); - if (polymorphicData->argType()->isContainer() && - ((ContainerTypeEntry*)polymorphicData->argType()->typeEntry())->type() + if (overloadData->argType()->isContainer() && + ((ContainerTypeEntry*)overloadData->argType()->typeEntry())->type() == ContainerTypeEntry::PairContainer) { s << " && PySequence_Size(" << pyArgName << ") == 2"; } if (signatureFound && varargs) { - int numArgs = func->arguments().size() - PolymorphicData::numberOfRemovedArguments(func); - PolymorphicData* tmp = polymorphicData; - for (int i = polymorphicData->argPos() + 1; i < numArgs; i++) { - tmp = tmp->nextPolymorphicData()[0]; + int numArgs = func->arguments().size() - OverloadData::numberOfRemovedArguments(func); + OverloadData* tmp = overloadData; + for (int i = overloadData->argPos() + 1; i < numArgs; i++) { + tmp = tmp->nextOverloadData()[0]; s << " && "; writeTypeCheck(s, tmp, QString("pyargs[%1]").arg(i)); } @@ -760,11 +760,11 @@ void CppGenerator::writePolymorphicDecisor(QTextStream& s, PolymorphicData* pare s << ") {" << endl; { Indentation indent(INDENT); - int allRemoved = PolymorphicData::numberOfRemovedArguments(func); + int allRemoved = OverloadData::numberOfRemovedArguments(func); int lastArg = signatureFound ? func->arguments().size() - allRemoved - : polymorphicData->argPos() + 1; + : overloadData->argPos() + 1; int removed = 0; - for (int i = polymorphicData->argPos(); i < lastArg; i++) { + for (int i = overloadData->argPos(); i < lastArg; i++) { if (func->argumentRemoved(i + 1)) removed++; QString argName = QString("cpp_arg%1").arg(i); @@ -781,7 +781,7 @@ void CppGenerator::writePolymorphicDecisor(QTextStream& s, PolymorphicData* pare { Indentation indent(INDENT); - writePolymorphicDecisor(s, polymorphicData); + writeOverloadedMethodDecisor(s, overloadData); } s << INDENT << "} else "; @@ -1107,12 +1107,12 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl { Indentation indent(INDENT); foreach (AbstractMetaFunctionList overloads, cmpOverloads) { - PolymorphicData polyData(overloads); + OverloadData overloadData(overloads); const AbstractMetaFunction* rfunc = overloads[0]; // DEBUG // QString dumpFile = QString("%1_%2.dot").arg(rfunc->ownerClass()->name()).arg(pythonOperatorFunctionName(rfunc)).toLower(); - // polyData.dumpGraph(dumpFile); + // overloadData.dumpGraph(dumpFile); // DEBUG s << INDENT << "case " << ShibokenGenerator::pythonRichCompareOperatorId(rfunc) << ':' << endl; @@ -1192,7 +1192,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl void CppGenerator::writeMethodDefinition(QTextStream& s, const AbstractMetaFunctionList overloads) { - QPair minMax = PolymorphicData::getMinMaxArguments(overloads); + QPair minMax = OverloadData::getMinMaxArguments(overloads); const AbstractMetaFunction* func = overloads[0]; s << INDENT << "{const_cast(\"" << func->name() << "\"), (PyCFunction)"; diff --git a/cppgenerator.h b/cppgenerator.h index 1d054e209..594df2fd8 100644 --- a/cppgenerator.h +++ b/cppgenerator.h @@ -25,7 +25,7 @@ #define CPPGENERATOR_H #include "shibokengenerator.h" -#include "polymorphicdata.h" +#include "overloaddata.h" /** * The CppGenerator generate the implementations of C++ bindings classes. @@ -52,12 +52,12 @@ private: void writeDestructorWrapper(QTextStream& s, const AbstractMetaClass* metaClass); void writeMinimalConstructorCallArguments(QTextStream& s, const AbstractMetaClass* metaClass); void writeMethodWrapper(QTextStream &s, const AbstractMetaFunctionList overloads); - void writeArgumentsInitializer(QTextStream& s, PolymorphicData& polymorphicData); + void writeArgumentsInitializer(QTextStream& s, OverloadData& overloadData); - void writeErrorSection(QTextStream& s, PolymorphicData& polymorphicData); - void writeTypeCheck(QTextStream& s, const PolymorphicData* polyData, QString argumentName); + void writeErrorSection(QTextStream& s, OverloadData& overloadData); + void writeTypeCheck(QTextStream& s, const OverloadData* overloadData, QString argumentName); - void writePolymorphicDecisor(QTextStream& s, PolymorphicData* parentPolymorphicData); + void writeOverloadedMethodDecisor(QTextStream& s, OverloadData* parentOverloadData); void writeMethodCall(QTextStream& s, const AbstractMetaFunction* func, int lastArg = 0); void writeClassRegister(QTextStream& s, const AbstractMetaClass* metaClass); diff --git a/overloaddata.cpp b/overloaddata.cpp new file mode 100644 index 000000000..6355edba0 --- /dev/null +++ b/overloaddata.cpp @@ -0,0 +1,383 @@ +/* + * This file is part of the Shiboken Python Bindings Generator project. + * + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU 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 + * + */ + +#include +#include "overloaddata.h" +#include "shibokengenerator.h" + +// Prepare the information about overloaded methods signatures +OverloadData::OverloadData(const AbstractMetaFunctionList overloads) + : m_minArgs(256), m_maxArgs(0), m_argPos(-1), m_argType(0), + m_headOverloadData(this) +{ + foreach (const AbstractMetaFunction* func, overloads) { + m_overloads.append(func); + int argSize = func->arguments().size(); + if (m_minArgs > argSize) + m_minArgs = argSize; + else if (m_maxArgs < argSize) + m_maxArgs = argSize; + OverloadData* currentOverloadData = this; + foreach (const AbstractMetaArgument* arg, func->arguments()) { + if (func->argumentRemoved(arg->argumentIndex() + 1)) + continue; + currentOverloadData = currentOverloadData->addOverloadData(func, arg->type()); + } + } + + // Fix minArgs + if (minArgs() > maxArgs()) + m_headOverloadData->m_minArgs = maxArgs(); +} + +OverloadData::OverloadData(OverloadData* headOverloadData, const AbstractMetaFunction* func, + const AbstractMetaType* argType, int argPos) + : m_minArgs(256), m_maxArgs(0), m_argPos(argPos), m_argType(argType), + m_headOverloadData(headOverloadData) +{ + if (func) + this->addOverload(func); +} + +void OverloadData::addOverload(const AbstractMetaFunction* func) +{ + int origNumArgs = func->arguments().size(); + int removed = numberOfRemovedArguments(func); + int numArgs = origNumArgs - removed; + + if (numArgs > m_headOverloadData->m_maxArgs) + m_headOverloadData->m_maxArgs = numArgs; + + if (numArgs < m_headOverloadData->m_minArgs) + m_headOverloadData->m_minArgs = numArgs; + + for (int i = 0; m_headOverloadData->m_minArgs > 0 && i < origNumArgs; i++) { + if (func->argumentRemoved(i + 1)) + continue; + if (!func->arguments()[i]->defaultValueExpression().isEmpty()) { + int fixedArgIndex = i - removed; + if (fixedArgIndex < m_headOverloadData->m_minArgs) + m_headOverloadData->m_minArgs = fixedArgIndex; + } + } + + m_overloads.append(func); +} + +OverloadData* OverloadData::addOverloadData(const AbstractMetaFunction* func, + const AbstractMetaType* argType) +{ + OverloadData* overloadData = 0; + foreach (OverloadData* tmp, m_nextOverloadData) { + // TODO: 'const char *', 'char *' and 'char' will have the same TypeEntry? + if (tmp->m_argType->typeEntry() == argType->typeEntry()) { + tmp->addOverload(func); + overloadData = tmp; + continue; + } + } + + if (!overloadData) { + overloadData = new OverloadData(m_headOverloadData, func, argType, m_argPos + 1); + // The following code always put PyInt as the last element to be checked. + // This is useful to check the python argument as PyNumber instead of + // PyInt, but not getting in the way of other tipes of higher precision + // (e.g. PyFloat) + if (ShibokenGenerator::isPyInt(argType)) + m_nextOverloadData.append(overloadData); + else + m_nextOverloadData.prepend(overloadData); + } + + return overloadData; +} + +const AbstractMetaFunction* OverloadData::referenceFunction() const +{ + return m_overloads.at(0); +} + +const AbstractMetaArgument* OverloadData::argument(const AbstractMetaFunction* func) const +{ + if (isHeadOverloadData() || !m_overloads.contains(func)) + return 0; + + int argPos = 0; + int removed = 0; + for (int i = 0; argPos <= m_argPos; i++) { + if (func->argumentRemoved(i + 1)) + removed++; + else + argPos++; + } + + return func->arguments()[m_argPos + removed]; +} + +OverloadDataList OverloadData::overloadDataOnPosition(OverloadData* overloadData, int argPos) const +{ + OverloadDataList overloadDataList; + if (overloadData->argPos() == argPos) { + overloadDataList.append(overloadData); + } else if (overloadData->argPos() < argPos) { + foreach (OverloadData* pd, overloadData->nextOverloadData()) + overloadDataList += overloadDataOnPosition(pd, argPos); + } + return overloadDataList; +} + +OverloadDataList OverloadData::overloadDataOnPosition(int argPos) const +{ + OverloadDataList overloadDataList; + overloadDataList += overloadDataOnPosition(m_headOverloadData, argPos); + return overloadDataList; +} + +bool OverloadData::nextArgumentHasDefaultValue() const +{ + foreach (OverloadData* overloadData, m_nextOverloadData) { + if (overloadData->hasDefaultValue()) + return true; + } + return false; +} + +bool OverloadData::isFinalOccurrence(const AbstractMetaFunction* func) const +{ + foreach (const OverloadData* pd, m_nextOverloadData) { + if (pd->overloads().contains(func)) + return false; + } + return true; +} + +bool OverloadData::hasDefaultValue() const +{ + foreach (const AbstractMetaFunction* func, m_overloads) { + if (!func->arguments()[m_argPos]->defaultValueExpression().isEmpty()) + return true; + } + return false; +} + +QList OverloadData::invalidArgumentLengths() const +{ + QSet validArgLengths; + foreach (const AbstractMetaFunction* func, m_headOverloadData->m_overloads) { + validArgLengths << func->arguments().size(); + foreach (const AbstractMetaArgument* arg, func->arguments()) { + if (!arg->defaultValueExpression().isEmpty()) + validArgLengths << arg->argumentIndex(); + } + } + + QList invalidArgLengths; + for (int i = minArgs() + 1; i < maxArgs(); i++) { + if (!validArgLengths.contains(i)) + invalidArgLengths.append(i); + } + + return invalidArgLengths; +} + +int OverloadData::numberOfRemovedArguments(const AbstractMetaFunction* func, int finalArgPos) +{ + int removed = 0; + if (finalArgPos < 0) + finalArgPos = func->arguments().size(); + for (int i = 0; i < finalArgPos; i++) { + if (func->argumentRemoved(i + 1)) + removed++; + } + return removed; +} + +QPair OverloadData::getMinMaxArguments(const AbstractMetaFunctionList overloads) +{ + int minArgs = 10000; + int maxArgs = 0; + for (int i = 0; i < overloads.size(); i++) { + const AbstractMetaFunction* func = overloads[i]; + int origNumArgs = func->arguments().size(); + int removed = numberOfRemovedArguments(func); + int numArgs = origNumArgs - removed; + if (maxArgs < numArgs) + maxArgs = numArgs; + if (minArgs > numArgs) + minArgs = numArgs; + for (int j = 0; j < origNumArgs; j++) { + if (func->argumentRemoved(j + 1)) + continue; + int fixedArgIndex = j - removed; + if (fixedArgIndex < minArgs && !func->arguments()[j]->defaultValueExpression().isEmpty()) + minArgs = fixedArgIndex; + } + } + return QPair(minArgs, maxArgs); +} + +void OverloadData::dumpGraph(QString filename) const +{ + QFile file(filename); + if (file.open(QFile::WriteOnly)) { + QTextStream s(&file); + s << m_headOverloadData->dumpGraph(); + } +} + +QString OverloadData::dumpGraph() const +{ + QString indent(4, ' '); + QString result; + QTextStream s(&result); + if (m_argPos == -1) { + const AbstractMetaFunction* rfunc = referenceFunction(); + s << "digraph OverloadedFunction {" << endl; + s << indent << "graph [fontsize=12 fontname=freemono labelloc=t splines=true overlap=false rankdir=LR];" << endl; + + // Shows all function signatures + s << "legend [fontsize=9 fontname=freemono shape=rect label=\""; + foreach (const AbstractMetaFunction* func, overloads()) { + s << "f" << functionNumber(func) << " : "; + if (func->type()) + s << func->type()->cppSignature().replace('<', "<").replace('>', ">"); + else + s << "void"; + s << ' ' << func->minimalSignature().replace('<', "<").replace('>', ">") << "\\l"; + } + s << "\"];" << endl; + + // Function box title + s << indent << '"' << rfunc->name() << "\" [shape=plaintext style=\"filled,bold\" margin=0 fontname=freemono fillcolor=white penwidth=1 "; + s << "label=<"; + s << ""; + + // Function return type + s << ""; + + // Shows type changes for all function signatures + foreach (const AbstractMetaFunction* func, overloads()) { + if (func->typeReplaced(0).isEmpty()) + continue; + s << ""; + } + + // Minimum and maximum number of arguments + s << ""; + s << ""; + + if (rfunc->ownerClass()) { + if (rfunc->implementingClass() != rfunc->ownerClass()) + s << ""; + if (rfunc->declaringClass() != rfunc->ownerClass() && rfunc->declaringClass() != rfunc->implementingClass()) + s << ""; + } + + // Overloads for the signature to present point + s << ""; + + s << "
"; + if (rfunc->ownerClass()) + s << rfunc->ownerClass()->name() << "::"; + s << rfunc->name().replace('<', "<").replace('>', ">") << ""; + if (rfunc->isVirtual()) { + s << "
<<"; + if (rfunc->isAbstract()) + s << "pure "; + s << "virtual>>"; + } + s << "
original type"; + if (rfunc->type()) + s << rfunc->type()->cppSignature().replace('<', "<").replace('>', ">"); + else + s << "void"; + s << "
f" << functionNumber(func); + s << "-type"; + s << func->typeReplaced(0).replace('<', "<").replace('>', ">") << "
minArgs"; + s << minArgs() << "
maxArgs"; + s << maxArgs() << "
implementor" << rfunc->implementingClass()->name() << "
declarator" << rfunc->declaringClass()->name() << "
overloads"; + foreach (const AbstractMetaFunction* func, overloads()) + s << 'f' << functionNumber(func) << ' '; + s << "
> ];" << endl; + + foreach (const OverloadData* pd, nextOverloadData()) + s << indent << '"' << rfunc->name() << "\" -> " << pd->dumpGraph(); + + s << "}" << endl; + } else { + QString argId = QString("arg_%1").arg((ulong)this); + s << argId << ';' << endl; + + s << indent << '"' << argId << "\" [shape=\"plaintext\" style=\"filled,bold\" margin=\"0\" fontname=\"freemono\" fillcolor=\"white\" penwidth=1 "; + s << "label=<"; + + // Argument box title + s << ""; + + // Argument type information + s << ""; + + // Overloads for the signature to present point + s << ""; + + // Show default values (original and modified) for various functions + foreach (const AbstractMetaFunction* func, overloads()) { + const AbstractMetaArgument* arg = argument(func); + if (!arg) + continue; + if (!arg->defaultValueExpression().isEmpty() || + arg->defaultValueExpression() != arg->originalDefaultValueExpression()) { + s << ""; + } + if (arg->defaultValueExpression() != arg->originalDefaultValueExpression()) { + s << ""; + } + } + + s << "
"; + s << "arg #" << argPos() << "
type"; + s << argType()->cppSignature().replace("&", "&") << "
overloads"; + foreach (const AbstractMetaFunction* func, overloads()) + s << 'f' << functionNumber(func) << ' '; + s << "
f" << functionNumber(func); + s << "-default"; + s << arg->defaultValueExpression() << "
f" << functionNumber(func); + s << "-orig-default"; + s << arg->originalDefaultValueExpression() << "
>];" << endl; + + foreach (const OverloadData* pd, nextOverloadData()) + s << indent << argId << " -> " << pd->dumpGraph(); + } + return result; +} + +int OverloadData::functionNumber(const AbstractMetaFunction* func) const +{ + return m_headOverloadData->m_overloads.indexOf(func); +} + +OverloadData::~OverloadData() +{ + while (!m_nextOverloadData.isEmpty()) + delete m_nextOverloadData.takeLast(); +} diff --git a/overloaddata.h b/overloaddata.h new file mode 100644 index 000000000..508aca781 --- /dev/null +++ b/overloaddata.h @@ -0,0 +1,87 @@ +/* + * This file is part of the Shiboken Python Bindings Generator project. + * + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU 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 + * + */ + +#ifndef OVERLOADDATA_H +#define OVERLOADDATA_H + +#include +#include +#include + +class OverloadData; +typedef QList OverloadDataList; + +class OverloadData +{ +public: + OverloadData(const AbstractMetaFunctionList overloads); + + int minArgs() const { return m_headOverloadData->m_minArgs; } + int maxArgs() const { return m_headOverloadData->m_maxArgs; } + int argPos() const { return m_argPos; } + + const AbstractMetaType* argType() const { return m_argType; } + const AbstractMetaFunction* referenceFunction() const; + const AbstractMetaArgument* argument(const AbstractMetaFunction* func) const; + OverloadDataList overloadDataOnPosition(int argPos) const; + + bool isHeadOverloadData() const { return this == m_headOverloadData; } + bool hasDefaultValue() const; + bool nextArgumentHasDefaultValue() const; + bool isFinalOccurrence(const AbstractMetaFunction* func) const; + + QList overloads() const { return m_overloads; } + OverloadDataList nextOverloadData() const { return m_nextOverloadData; } + + QList invalidArgumentLengths() const; + + static int numberOfRemovedArguments(const AbstractMetaFunction* func, int finalArgPos = -1); + static QPair getMinMaxArguments(const AbstractMetaFunctionList overloads); + + void dumpGraph(QString filename) const; + QString dumpGraph() const; + + ~OverloadData(); + +private: + OverloadData(OverloadData* headOverloadData, const AbstractMetaFunction* func, + const AbstractMetaType* argType, int argPos); + + void addOverload(const AbstractMetaFunction* func); + OverloadData* addOverloadData(const AbstractMetaFunction* func, const AbstractMetaType* argType); + + int functionNumber(const AbstractMetaFunction* func) const; + OverloadDataList overloadDataOnPosition(OverloadData* overloadData, int argPos) const; + + int m_minArgs; + int m_maxArgs; + int m_argPos; + const AbstractMetaType* m_argType; + QList m_overloads; + + OverloadData* m_headOverloadData; + OverloadDataList m_nextOverloadData; +}; + + +#endif // OVERLOADDATA_H diff --git a/polymorphicdata.cpp b/polymorphicdata.cpp deleted file mode 100644 index 2121ba07d..000000000 --- a/polymorphicdata.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/* - * This file is part of the Shiboken Python Bindings Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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 - * General Public License for more details. - * - * You should have received a copy of the GNU 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 - * - */ - -#include -#include "polymorphicdata.h" -#include "shibokengenerator.h" - -// Prepare the information about polymorphic methods signatures -PolymorphicData::PolymorphicData(const AbstractMetaFunctionList overloads) - : m_minArgs(256), m_maxArgs(0), m_argPos(-1), m_argType(0), - m_headPolymorphicData(this) -{ - foreach (const AbstractMetaFunction* func, overloads) { - m_overloads.append(func); - int argSize = func->arguments().size(); - if (m_minArgs > argSize) - m_minArgs = argSize; - else if (m_maxArgs < argSize) - m_maxArgs = argSize; - PolymorphicData* currentPolymorphicData = this; - foreach (const AbstractMetaArgument* arg, func->arguments()) { - if (func->argumentRemoved(arg->argumentIndex() + 1)) - continue; - currentPolymorphicData = currentPolymorphicData->addPolymorphicData(func, arg->type()); - } - } - - // Fix minArgs - if (minArgs() > maxArgs()) - m_headPolymorphicData->m_minArgs = maxArgs(); -} - -PolymorphicData::PolymorphicData(PolymorphicData* headPolymorphicData, const AbstractMetaFunction* func, - const AbstractMetaType* argType, int argPos) - : m_minArgs(256), m_maxArgs(0), m_argPos(argPos), m_argType(argType), - m_headPolymorphicData(headPolymorphicData) -{ - if (func) - this->addPolymorphic(func); -} - -void PolymorphicData::addPolymorphic(const AbstractMetaFunction* func) -{ - int origNumArgs = func->arguments().size(); - int removed = numberOfRemovedArguments(func); - int numArgs = origNumArgs - removed; - - if (numArgs > m_headPolymorphicData->m_maxArgs) - m_headPolymorphicData->m_maxArgs = numArgs; - - if (numArgs < m_headPolymorphicData->m_minArgs) - m_headPolymorphicData->m_minArgs = numArgs; - - for (int i = 0; m_headPolymorphicData->m_minArgs > 0 && i < origNumArgs; i++) { - if (func->argumentRemoved(i + 1)) - continue; - if (!func->arguments()[i]->defaultValueExpression().isEmpty()) { - int fixedArgIndex = i - removed; - if (fixedArgIndex < m_headPolymorphicData->m_minArgs) - m_headPolymorphicData->m_minArgs = fixedArgIndex; - } - } - - m_overloads.append(func); -} - -PolymorphicData* PolymorphicData::addPolymorphicData(const AbstractMetaFunction* func, - const AbstractMetaType* argType) -{ - PolymorphicData* polymorphicData = 0; - foreach (PolymorphicData* tmp, m_nextPolymorphicData) { - // TODO: 'const char *', 'char *' and 'char' will have the same TypeEntry? - if (tmp->m_argType->typeEntry() == argType->typeEntry()) { - tmp->addPolymorphic(func); - polymorphicData = tmp; - continue; - } - } - - if (!polymorphicData) { - polymorphicData = new PolymorphicData(m_headPolymorphicData, func, argType, m_argPos + 1); - // The following code always put PyInt as the last element to be checked. - // This is useful to check the python argument as PyNumber instead of - // PyInt, but not getting in the way of other tipes of higher precision - // (e.g. PyFloat) - if (ShibokenGenerator::isPyInt(argType)) - m_nextPolymorphicData.append(polymorphicData); - else - m_nextPolymorphicData.prepend(polymorphicData); - } - - return polymorphicData; -} - -const AbstractMetaFunction* PolymorphicData::referenceFunction() const -{ - return m_overloads.at(0); -} - -const AbstractMetaArgument* PolymorphicData::argument(const AbstractMetaFunction* func) const -{ - if (isHeadPolymorphicData() || !m_overloads.contains(func)) - return 0; - - int argPos = 0; - int removed = 0; - for (int i = 0; argPos <= m_argPos; i++) { - if (func->argumentRemoved(i + 1)) - removed++; - else - argPos++; - } - - return func->arguments()[m_argPos + removed]; -} - -PolymorphicDataList PolymorphicData::polymorphicDataOnPosition(PolymorphicData* polyData, int argPos) const -{ - PolymorphicDataList polyDataList; - if (polyData->argPos() == argPos) { - polyDataList.append(polyData); - } else if (polyData->argPos() < argPos) { - foreach (PolymorphicData* pd, polyData->nextPolymorphicData()) - polyDataList += polymorphicDataOnPosition(pd, argPos); - } - return polyDataList; -} - -PolymorphicDataList PolymorphicData::polymorphicDataOnPosition(int argPos) const -{ - PolymorphicDataList polyDataList; - polyDataList += polymorphicDataOnPosition(m_headPolymorphicData, argPos); - return polyDataList; -} - -bool PolymorphicData::nextArgumentHasDefaultValue() const -{ - foreach (PolymorphicData* polymorphicData, m_nextPolymorphicData) { - if (polymorphicData->hasDefaultValue()) - return true; - } - return false; -} - -bool PolymorphicData::isFinalOccurrence(const AbstractMetaFunction* func) const -{ - foreach (const PolymorphicData* pd, m_nextPolymorphicData) { - if (pd->overloads().contains(func)) - return false; - } - return true; -} - -bool PolymorphicData::hasDefaultValue() const -{ - foreach (const AbstractMetaFunction* func, m_overloads) { - if (!func->arguments()[m_argPos]->defaultValueExpression().isEmpty()) - return true; - } - return false; -} - -QList PolymorphicData::invalidArgumentLengths() const -{ - QSet validArgLengths; - foreach (const AbstractMetaFunction* func, m_headPolymorphicData->m_overloads) { - validArgLengths << func->arguments().size(); - foreach (const AbstractMetaArgument* arg, func->arguments()) { - if (!arg->defaultValueExpression().isEmpty()) - validArgLengths << arg->argumentIndex(); - } - } - - QList invalidArgLengths; - for (int i = minArgs() + 1; i < maxArgs(); i++) { - if (!validArgLengths.contains(i)) - invalidArgLengths.append(i); - } - - return invalidArgLengths; -} - -int PolymorphicData::numberOfRemovedArguments(const AbstractMetaFunction* func, int finalArgPos) -{ - int removed = 0; - if (finalArgPos < 0) - finalArgPos = func->arguments().size(); - for (int i = 0; i < finalArgPos; i++) { - if (func->argumentRemoved(i + 1)) - removed++; - } - return removed; -} - -QPair PolymorphicData::getMinMaxArguments(const AbstractMetaFunctionList overloads) -{ - int minArgs = 10000; - int maxArgs = 0; - for (int i = 0; i < overloads.size(); i++) { - const AbstractMetaFunction* func = overloads[i]; - int origNumArgs = func->arguments().size(); - int removed = numberOfRemovedArguments(func); - int numArgs = origNumArgs - removed; - if (maxArgs < numArgs) - maxArgs = numArgs; - if (minArgs > numArgs) - minArgs = numArgs; - for (int j = 0; j < origNumArgs; j++) { - if (func->argumentRemoved(j + 1)) - continue; - int fixedArgIndex = j - removed; - if (fixedArgIndex < minArgs && !func->arguments()[j]->defaultValueExpression().isEmpty()) - minArgs = fixedArgIndex; - } - } - return QPair(minArgs, maxArgs); -} - -void PolymorphicData::dumpGraph(QString filename) const -{ - QFile file(filename); - if (file.open(QFile::WriteOnly)) { - QTextStream s(&file); - s << m_headPolymorphicData->dumpGraph(); - } -} - -QString PolymorphicData::dumpGraph() const -{ - QString indent(4, ' '); - QString result; - QTextStream s(&result); - if (m_argPos == -1) { - const AbstractMetaFunction* rfunc = referenceFunction(); - s << "digraph PolymorphicFunction {" << endl; - s << indent << "graph [fontsize=12 fontname=freemono labelloc=t splines=true overlap=false rankdir=LR];" << endl; - - // Shows all function signatures - s << "legend [fontsize=9 fontname=freemono shape=rect label=\""; - foreach (const AbstractMetaFunction* func, overloads()) { - s << "f" << functionNumber(func) << " : "; - if (func->type()) - s << func->type()->cppSignature().replace('<', "<").replace('>', ">"); - else - s << "void"; - s << ' ' << func->minimalSignature().replace('<', "<").replace('>', ">") << "\\l"; - } - s << "\"];" << endl; - - // Function box title - s << indent << '"' << rfunc->name() << "\" [shape=plaintext style=\"filled,bold\" margin=0 fontname=freemono fillcolor=white penwidth=1 "; - s << "label=<"; - s << ""; - - // Function return type - s << ""; - - // Shows type changes for all function signatures - foreach (const AbstractMetaFunction* func, overloads()) { - if (func->typeReplaced(0).isEmpty()) - continue; - s << ""; - } - - // Minimum and maximum number of arguments - s << ""; - s << ""; - - if (rfunc->ownerClass()) { - if (rfunc->implementingClass() != rfunc->ownerClass()) - s << ""; - if (rfunc->declaringClass() != rfunc->ownerClass() && rfunc->declaringClass() != rfunc->implementingClass()) - s << ""; - } - - // Overloads for the signature to present point - s << ""; - - s << "
"; - if (rfunc->ownerClass()) - s << rfunc->ownerClass()->name() << "::"; - s << rfunc->name().replace('<', "<").replace('>', ">") << ""; - if (rfunc->isVirtual()) { - s << "
<<"; - if (rfunc->isAbstract()) - s << "pure "; - s << "virtual>>"; - } - s << "
original type"; - if (rfunc->type()) - s << rfunc->type()->cppSignature().replace('<', "<").replace('>', ">"); - else - s << "void"; - s << "
f" << functionNumber(func); - s << "-type"; - s << func->typeReplaced(0).replace('<', "<").replace('>', ">") << "
minArgs"; - s << minArgs() << "
maxArgs"; - s << maxArgs() << "
implementor" << rfunc->implementingClass()->name() << "
declarator" << rfunc->declaringClass()->name() << "
overloads"; - foreach (const AbstractMetaFunction* func, overloads()) - s << 'f' << functionNumber(func) << ' '; - s << "
> ];" << endl; - - foreach (const PolymorphicData* pd, nextPolymorphicData()) - s << indent << '"' << rfunc->name() << "\" -> " << pd->dumpGraph(); - - s << "}" << endl; - } else { - QString argId = QString("arg_%1").arg((ulong)this); - s << argId << ';' << endl; - - s << indent << '"' << argId << "\" [shape=\"plaintext\" style=\"filled,bold\" margin=\"0\" fontname=\"freemono\" fillcolor=\"white\" penwidth=1 "; - s << "label=<"; - - // Argument box title - s << ""; - - // Argument type information - s << ""; - - // Overloads for the signature to present point - s << ""; - - // Show default values (original and modified) for various functions - foreach (const AbstractMetaFunction* func, overloads()) { - const AbstractMetaArgument* arg = argument(func); - if (!arg) - continue; - if (!arg->defaultValueExpression().isEmpty() || - arg->defaultValueExpression() != arg->originalDefaultValueExpression()) { - s << ""; - } - if (arg->defaultValueExpression() != arg->originalDefaultValueExpression()) { - s << ""; - } - } - - s << "
"; - s << "arg #" << argPos() << "
type"; - s << argType()->cppSignature().replace("&", "&") << "
overloads"; - foreach (const AbstractMetaFunction* func, overloads()) - s << 'f' << functionNumber(func) << ' '; - s << "
f" << functionNumber(func); - s << "-default"; - s << arg->defaultValueExpression() << "
f" << functionNumber(func); - s << "-orig-default"; - s << arg->originalDefaultValueExpression() << "
>];" << endl; - - foreach (const PolymorphicData* pd, nextPolymorphicData()) - s << indent << argId << " -> " << pd->dumpGraph(); - } - return result; -} - -int PolymorphicData::functionNumber(const AbstractMetaFunction* func) const -{ - return m_headPolymorphicData->m_overloads.indexOf(func); -} - -PolymorphicData::~PolymorphicData() -{ - while (!m_nextPolymorphicData.isEmpty()) - delete m_nextPolymorphicData.takeLast(); -} diff --git a/polymorphicdata.h b/polymorphicdata.h deleted file mode 100644 index a84c325f8..000000000 --- a/polymorphicdata.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the Shiboken Python Bindings Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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 - * General Public License for more details. - * - * You should have received a copy of the GNU 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 - * - */ - -#ifndef POLYMORPHICDATA_H -#define POLYMORPHICDATA_H - -#include -#include -#include - -class PolymorphicData; -typedef QList PolymorphicDataList; - -class PolymorphicData -{ -public: - PolymorphicData(const AbstractMetaFunctionList overloads); - - int minArgs() const { return m_headPolymorphicData->m_minArgs; } - int maxArgs() const { return m_headPolymorphicData->m_maxArgs; } - int argPos() const { return m_argPos; } - - const AbstractMetaType* argType() const { return m_argType; } - const AbstractMetaFunction* referenceFunction() const; - const AbstractMetaArgument* argument(const AbstractMetaFunction* func) const; - PolymorphicDataList polymorphicDataOnPosition(int argPos) const; - - bool isHeadPolymorphicData() const { return this == m_headPolymorphicData; } - bool hasDefaultValue() const; - bool nextArgumentHasDefaultValue() const; - bool isFinalOccurrence(const AbstractMetaFunction* func) const; - - QList overloads() const { return m_overloads; } - PolymorphicDataList nextPolymorphicData() const { return m_nextPolymorphicData; } - - QList invalidArgumentLengths() const; - - static int numberOfRemovedArguments(const AbstractMetaFunction* func, int finalArgPos = -1); - static QPair getMinMaxArguments(const AbstractMetaFunctionList overloads); - - void dumpGraph(QString filename) const; - QString dumpGraph() const; - - ~PolymorphicData(); - -private: - PolymorphicData(PolymorphicData* headPolymorphicData, const AbstractMetaFunction* func, - const AbstractMetaType* argType, int argPos); - - void addPolymorphic(const AbstractMetaFunction* func); - PolymorphicData* addPolymorphicData(const AbstractMetaFunction* func, const AbstractMetaType* argType); - - int functionNumber(const AbstractMetaFunction* func) const; - PolymorphicDataList polymorphicDataOnPosition(PolymorphicData* polyData, int argPos) const; - - int m_minArgs; - int m_maxArgs; - int m_argPos; - const AbstractMetaType* m_argType; - QList m_overloads; - - PolymorphicData* m_headPolymorphicData; - PolymorphicDataList m_nextPolymorphicData; -}; - - -#endif // POLYMORPHICDATA_H diff --git a/tests/libsample/derived.cpp b/tests/libsample/derived.cpp index 4aeafd5e5..5a27a6c2f 100644 --- a/tests/libsample/derived.cpp +++ b/tests/libsample/derived.cpp @@ -84,31 +84,31 @@ Derived::defaultValue(int n) return ((double) n) + 0.1; } -PolymorphicFuncEnum -Derived::polymorphic(int i, int d) +OverloadedFuncEnum +Derived::overloaded(int i, int d) { //cout << __PRETTY_FUNCTION__ << "[i = 0, d = 0]" << endl; - return PolymorphicFunc_ii; + return OverloadedFunc_ii; } -PolymorphicFuncEnum -Derived::polymorphic(double n) +OverloadedFuncEnum +Derived::overloaded(double n) { //cout << __PRETTY_FUNCTION__ << endl; - return PolymorphicFunc_d; + return OverloadedFunc_d; } -Derived::OtherPolymorphicFuncEnum -Derived::otherPolymorphic(int a, int b, bool c, double d) +Derived::OtherOverloadedFuncEnum +Derived::otherOverloaded(int a, int b, bool c, double d) { //cout << __PRETTY_FUNCTION__ << endl; - return OtherPolymorphicFunc_iibd; + return OtherOverloadedFunc_iibd; } -Derived::OtherPolymorphicFuncEnum -Derived::otherPolymorphic(int a, double b) +Derived::OtherOverloadedFuncEnum +Derived::otherOverloaded(int a, double b) { //cout << __PRETTY_FUNCTION__ << endl; - return OtherPolymorphicFunc_id; + return OtherOverloadedFunc_id; } diff --git a/tests/libsample/derived.h b/tests/libsample/derived.h index 624c66051..e12042f90 100644 --- a/tests/libsample/derived.h +++ b/tests/libsample/derived.h @@ -37,17 +37,17 @@ #include "abstract.h" -enum PolymorphicFuncEnum { - PolymorphicFunc_ii, - PolymorphicFunc_d +enum OverloadedFuncEnum { + OverloadedFunc_ii, + OverloadedFunc_d }; class Derived : public Abstract { public: - enum OtherPolymorphicFuncEnum { - OtherPolymorphicFunc_iibd, - OtherPolymorphicFunc_id + enum OtherOverloadedFuncEnum { + OtherOverloadedFunc_iibd, + OtherOverloadedFunc_id }; Derived(int id = -1); @@ -65,12 +65,12 @@ public: double defaultValue(int n = 0); // overloads - PolymorphicFuncEnum polymorphic(int i = 0, int d = 0); - PolymorphicFuncEnum polymorphic(double n); + OverloadedFuncEnum overloaded(int i = 0, int d = 0); + OverloadedFuncEnum overloaded(double n); // more overloads - OtherPolymorphicFuncEnum otherPolymorphic(int a, int b, bool c, double d); - OtherPolymorphicFuncEnum otherPolymorphic(int a, double b); + OtherOverloadedFuncEnum otherOverloaded(int a, int b, bool c, double d); + OtherOverloadedFuncEnum otherOverloaded(int a, double b); protected: const char* getClassName() { return className(); } diff --git a/tests/libsample/functions.cpp b/tests/libsample/functions.cpp index d8f27cf66..e1d909046 100644 --- a/tests/libsample/functions.cpp +++ b/tests/libsample/functions.cpp @@ -105,15 +105,15 @@ returnCString() return __PRETTY_FUNCTION__; } -GlobalPolyFuncEnum -polymorphicFunc(int val) +GlobalOverloadFuncEnum +overloadedFunc(int val) { - return GlobalPolyFunc_i; + return GlobalOverloadFunc_i; } -GlobalPolyFuncEnum -polymorphicFunc(double val) +GlobalOverloadFuncEnum +overloadedFunc(double val) { - return GlobalPolyFunc_d; + return GlobalOverloadFunc_d; } diff --git a/tests/libsample/functions.h b/tests/libsample/functions.h index fcb8bda8e..05753da3e 100644 --- a/tests/libsample/functions.h +++ b/tests/libsample/functions.h @@ -46,9 +46,9 @@ enum GlobalEnum { ThirdThing }; -enum GlobalPolyFuncEnum { - GlobalPolyFunc_i, - GlobalPolyFunc_d +enum GlobalOverloadFuncEnum { + GlobalOverloadFunc_i, + GlobalOverloadFunc_d }; void printSomething(); @@ -62,9 +62,9 @@ int countCharacters(const char* text); char* makeCString(); const char* returnCString(); -// Tests polymorphism on functions (!methods) -GlobalPolyFuncEnum polymorphicFunc(int val); -GlobalPolyFuncEnum polymorphicFunc(double val); +// Tests overloading on functions (!methods) +GlobalOverloadFuncEnum overloadedFunc(int val); +GlobalOverloadFuncEnum overloadedFunc(double val); #endif // FUNCTIONS_H diff --git a/tests/libsample/implicitconv.cpp b/tests/libsample/implicitconv.cpp index 3baf8ccd2..8e0d3f463 100644 --- a/tests/libsample/implicitconv.cpp +++ b/tests/libsample/implicitconv.cpp @@ -46,27 +46,27 @@ ImplicitConv::implicitConvDefault(ImplicitConv implicit) return implicit; } -ImplicitConv::ICPolymorphicFuncEnum -ImplicitConv::implicitConvPolymorphism(ImplicitConv implicit, int dummyArg) +ImplicitConv::ICOverloadedFuncEnum +ImplicitConv::implicitConvOverloading(ImplicitConv implicit, int dummyArg) { - return ImplicitConv::PolyFunc_Ii; + return ImplicitConv::OverFunc_Ii; } -ImplicitConv::ICPolymorphicFuncEnum -ImplicitConv::implicitConvPolymorphism(ImplicitConv implicit, bool dummyArg) +ImplicitConv::ICOverloadedFuncEnum +ImplicitConv::implicitConvOverloading(ImplicitConv implicit, bool dummyArg) { - return ImplicitConv::PolyFunc_Ib; + return ImplicitConv::OverFunc_Ib; } -ImplicitConv::ICPolymorphicFuncEnum -ImplicitConv::implicitConvPolymorphism(int dummyArg) +ImplicitConv::ICOverloadedFuncEnum +ImplicitConv::implicitConvOverloading(int dummyArg) { - return ImplicitConv::PolyFunc_i; + return ImplicitConv::OverFunc_i; } -ImplicitConv::ICPolymorphicFuncEnum -ImplicitConv::implicitConvPolymorphism(CtorEnum dummyArg) +ImplicitConv::ICOverloadedFuncEnum +ImplicitConv::implicitConvOverloading(CtorEnum dummyArg) { - return ImplicitConv::PolyFunc_C; + return ImplicitConv::OverFunc_C; } diff --git a/tests/libsample/implicitconv.h b/tests/libsample/implicitconv.h index 57566f89d..7d537fb13 100644 --- a/tests/libsample/implicitconv.h +++ b/tests/libsample/implicitconv.h @@ -45,11 +45,11 @@ public: CtorThree }; - enum ICPolymorphicFuncEnum { - PolyFunc_Ii, - PolyFunc_Ib, - PolyFunc_i, - PolyFunc_C + enum ICOverloadedFuncEnum { + OverFunc_Ii, + OverFunc_Ib, + OverFunc_i, + OverFunc_C }; ImplicitConv() : m_ctorEnum(CtorNone), m_objId(-1) {} @@ -64,10 +64,10 @@ public: static ImplicitConv implicitConvDefault(ImplicitConv implicit = CtorTwo); - static ICPolymorphicFuncEnum implicitConvPolymorphism(ImplicitConv implicit, int dummyArg); - static ICPolymorphicFuncEnum implicitConvPolymorphism(ImplicitConv implicit, bool dummyArg); - static ICPolymorphicFuncEnum implicitConvPolymorphism(int dummyArg); - static ICPolymorphicFuncEnum implicitConvPolymorphism(CtorEnum dummyArg); + static ICOverloadedFuncEnum implicitConvOverloading(ImplicitConv implicit, int dummyArg); + static ICOverloadedFuncEnum implicitConvOverloading(ImplicitConv implicit, bool dummyArg); + static ICOverloadedFuncEnum implicitConvOverloading(int dummyArg); + static ICOverloadedFuncEnum implicitConvOverloading(CtorEnum dummyArg); private: CtorEnum m_ctorEnum; diff --git a/tests/libsample/modifications.h b/tests/libsample/modifications.h index d6bca2d6d..87405f361 100644 --- a/tests/libsample/modifications.h +++ b/tests/libsample/modifications.h @@ -44,22 +44,22 @@ public: Modifications() {} ~Modifications() {} - enum PolymorphicModFunc { - PolymorphicNone, - Polymorphic_ibid, - Polymorphic_ibib, - Polymorphic_ibiP, - Polymorphic_ibii, - Polymorphic_ibPP + enum OverloadedModFunc { + OverloadedNone, + Overloaded_ibid, + Overloaded_ibib, + Overloaded_ibiP, + Overloaded_ibii, + Overloaded_ibPP }; - // those polymorphic methods should be heavily modified + // those overloaded methods should be heavily modified // to push the overload decisor to its limits - PolymorphicModFunc polymorphic(int a0, bool b0, int c0, double d0) { return Polymorphic_ibid; } - PolymorphicModFunc polymorphic(int a1, bool b1, int c1, bool d1) { return Polymorphic_ibib; } - PolymorphicModFunc polymorphic(int a2, bool b2, int c2, Point d2) { return Polymorphic_ibiP; } - PolymorphicModFunc polymorphic(int a3, bool b3, int c3 = 123, int d3 = 456) { return Polymorphic_ibii; } - PolymorphicModFunc polymorphic(int a4, bool b4, Point c4, Point d4) { return Polymorphic_ibPP; } + OverloadedModFunc overloaded(int a0, bool b0, int c0, double d0) { return Overloaded_ibid; } + OverloadedModFunc overloaded(int a1, bool b1, int c1, bool d1) { return Overloaded_ibib; } + OverloadedModFunc overloaded(int a2, bool b2, int c2, Point d2) { return Overloaded_ibiP; } + OverloadedModFunc overloaded(int a3, bool b3, int c3 = 123, int d3 = 456) { return Overloaded_ibii; } + OverloadedModFunc overloaded(int a4, bool b4, Point c4, Point d4) { return Overloaded_ibPP; } // 'ok' must be removed and the return value will be changed // to a tuple (PyObject*) containing the expected result plus diff --git a/tests/samplebinding/derived_test.py b/tests/samplebinding/derived_test.py index 22d49470f..f9ed1320f 100755 --- a/tests/samplebinding/derived_test.py +++ b/tests/samplebinding/derived_test.py @@ -6,7 +6,7 @@ import sys import unittest import sample -from sample import Abstract, Derived, PolymorphicFuncEnum +from sample import Abstract, Derived, OverloadedFuncEnum class Deviant(Derived): def __init__(self): @@ -32,45 +32,45 @@ class DerivedTest(unittest.TestCase): 'id_', 'pureVirtual', 'unpureVirtual']) self.assert_(inherited_methods.issubset(dir(Derived))) - def testPolymorphicMethodCall(self): - '''Test if the correct polymorphic method is being called.''' + def testOverloadedMethodCall(self): + '''Test if the correct overloaded method is being called.''' derived = Derived() - result = derived.polymorphic(1, 2) - self.assertEqual(type(result), PolymorphicFuncEnum) - self.assertEqual(result, sample.PolymorphicFunc_ii) + result = derived.overloaded(1, 2) + self.assertEqual(type(result), OverloadedFuncEnum) + self.assertEqual(result, sample.OverloadedFunc_ii) - result = derived.polymorphic(3) - self.assertEqual(type(result), PolymorphicFuncEnum) - self.assertEqual(result, sample.PolymorphicFunc_ii) + result = derived.overloaded(3) + self.assertEqual(type(result), OverloadedFuncEnum) + self.assertEqual(result, sample.OverloadedFunc_ii) - result = derived.polymorphic(4.4) - self.assertEqual(type(result), PolymorphicFuncEnum) - self.assertEqual(result, sample.PolymorphicFunc_d) + result = derived.overloaded(4.4) + self.assertEqual(type(result), OverloadedFuncEnum) + self.assertEqual(result, sample.OverloadedFunc_d) - def testOtherPolymorphicMethodCall(self): - '''Another test to check polymorphic method calling, just to double check.''' + def testOtherOverloadedMethodCall(self): + '''Another test to check overloaded method calling, just to double check.''' derived = Derived() - result = derived.otherPolymorphic(1, 2, True, 3.3) - self.assertEqual(type(result), Derived.OtherPolymorphicFuncEnum) - self.assertEqual(result, sample.Derived.OtherPolymorphicFunc_iibd) + result = derived.otherOverloaded(1, 2, True, 3.3) + self.assertEqual(type(result), Derived.OtherOverloadedFuncEnum) + self.assertEqual(result, sample.Derived.OtherOverloadedFunc_iibd) - result = derived.otherPolymorphic(1, 2.2) - self.assertEqual(type(result), Derived.OtherPolymorphicFuncEnum) - self.assertEqual(result, Derived.OtherPolymorphicFunc_id) + result = derived.otherOverloaded(1, 2.2) + self.assertEqual(type(result), Derived.OtherOverloadedFuncEnum) + self.assertEqual(result, Derived.OtherOverloadedFunc_id) - def testPolymorphicMethodCallWithDifferentNumericTypes(self): - '''Test if the correct polymorphic method accepts a different numeric type as argument.''' + def testOverloadedMethodCallWithDifferentNumericTypes(self): + '''Test if the correct overloaded method accepts a different numeric type as argument.''' derived = Derived() - result = derived.polymorphic(1.1, 2.2) - self.assertEqual(type(result), PolymorphicFuncEnum) - self.assertEqual(result, sample.PolymorphicFunc_ii) + result = derived.overloaded(1.1, 2.2) + self.assertEqual(type(result), OverloadedFuncEnum) + self.assertEqual(result, sample.OverloadedFunc_ii) - def testPolymorphicMethodCallWithWrongNumberOfArguments(self): - '''Test if a call to a polymorphic method with the wrong number of arguments raises an exception.''' + def testOverloadedMethodCallWithWrongNumberOfArguments(self): + '''Test if a call to an overloaded method with the wrong number of arguments raises an exception.''' derived = Derived() - self.assertRaises(TypeError, lambda : derived.otherPolymorphic(1, 2, True)) + self.assertRaises(TypeError, lambda : derived.otherOverloaded(1, 2, True)) def testReimplementedPureVirtualMethodCall(self): '''Test if a Python override of a implemented pure virtual method is correctly called from C++.''' diff --git a/tests/samplebinding/implicitconv_test.py b/tests/samplebinding/implicitconv_test.py index 30dd870e3..f3da5dcfb 100755 --- a/tests/samplebinding/implicitconv_test.py +++ b/tests/samplebinding/implicitconv_test.py @@ -11,7 +11,7 @@ class ImplicitConvTest(unittest.TestCase): '''Test case for implicit conversions''' def testImplicitConversions(self): - '''Test if polymorphic function call decisor takes implicit conversions into account.''' + '''Test if overloaded function call decisor takes implicit conversions into account.''' ic = ImplicitConv.implicitConvCommon(ImplicitConv()) self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorNone) diff --git a/tests/samplebinding/modifications_test.py b/tests/samplebinding/modifications_test.py index 33d420f37..1bd3003ed 100755 --- a/tests/samplebinding/modifications_test.py +++ b/tests/samplebinding/modifications_test.py @@ -26,12 +26,12 @@ class ModificationsTest(unittest.TestCase): def testClassMembersAvailability(self): '''Test if Modified class really have the expected members.''' - expected_members = set(['PolymorphicModFunc', 'PolymorphicNone', - 'Polymorphic_ibiP', 'Polymorphic_ibib', - 'Polymorphic_ibid', 'Polymorphic_ibii', + expected_members = set(['OverloadedModFunc', 'OverloadedNone', + 'Overloaded_ibiP', 'Overloaded_ibib', + 'Overloaded_ibid', 'Overloaded_ibii', 'calculateArea', 'doublePlus', 'increment', 'multiplyPointCoordsPlusValue', 'name', - 'pointToPair', 'polymorphic', 'power', + 'pointToPair', 'overloaded', 'power', 'timesTen']) self.assert_(expected_members.issubset(dir(Modifications))) @@ -98,17 +98,17 @@ class ModificationsTest(unittest.TestCase): self.assertEqual(type(result), float) self.assertEqual(result, 14.1) - def testPolymorphicMethodModifications(self): - '''Tests modifications to a polymorphic method''' - # polymorphic(int, bool[removed], int, double) - self.assertEqual(self.mods.polymorphic(1, 2, 3.1), Modifications.Polymorphic_ibid) - # polymorphic(int, bool, int[removed,default=321], int) - self.assertEqual(self.mods.polymorphic(1, True, 2), Modifications.Polymorphic_ibii) + def testOverloadedMethodModifications(self): + '''Tests modifications to an overloaded method''' + # overloaded(int, bool[removed], int, double) + self.assertEqual(self.mods.overloaded(1, 2, 3.1), Modifications.Overloaded_ibid) + # overloaded(int, bool, int[removed,default=321], int) + self.assertEqual(self.mods.overloaded(1, True, 2), Modifications.Overloaded_ibii) # the others weren't modified - self.assertEqual(self.mods.polymorphic(1, True, 2, False), Modifications.Polymorphic_ibib) - self.assertEqual(self.mods.polymorphic(1, False, 2, Point(3, 4)), Modifications.Polymorphic_ibiP) - self.assertRaises(TypeError, lambda : self.mods.polymorphic(1, True, Point(2, 3), Point(4, 5))) - self.assertEqual(self.mods.poly(1, True, Point(2, 3), Point(4, 5)), Modifications.Polymorphic_ibPP) + self.assertEqual(self.mods.overloaded(1, True, 2, False), Modifications.Overloaded_ibib) + self.assertEqual(self.mods.overloaded(1, False, 2, Point(3, 4)), Modifications.Overloaded_ibiP) + self.assertRaises(TypeError, lambda : self.mods.overloaded(1, True, Point(2, 3), Point(4, 5))) + self.assertEqual(self.mods.over(1, True, Point(2, 3), Point(4, 5)), Modifications.Overloaded_ibPP) if __name__ == '__main__': unittest.main() diff --git a/tests/samplebinding/nondefaultctor_test.py b/tests/samplebinding/nondefaultctor_test.py index 58a6442d8..dbb184eb3 100755 --- a/tests/samplebinding/nondefaultctor_test.py +++ b/tests/samplebinding/nondefaultctor_test.py @@ -16,7 +16,6 @@ class DerivedNonDefaultCtor (NonDefaultCtor): class NonDefaultCtorTest(unittest.TestCase): def testNonDefaultCtor(self): - '''Test if polymorphic function call decisor takes implicit conversions into account.''' c = NonDefaultCtor(2) # these functions returns NonDefaultCtor by value, so a PyObjecy is created every time self.assertNotEqual(c.returnMyself(), c) diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index b2378aaae..dc0d64d77 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -29,21 +29,21 @@ - - - + + + - + - + @@ -80,7 +80,7 @@ - + @@ -92,7 +92,7 @@ - + @@ -109,7 +109,7 @@ compile time error on the binding --> - +