aboutsummaryrefslogtreecommitdiffstats
path: root/generator
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-07-29 01:48:02 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:17:06 -0300
commit34395eeb8c57f2225c7f20b9e20f9d92f2131ce7 (patch)
treec81d6dec4f2087f4b3d48c93f0cf523a1bf6dc6f /generator
parent0c99d3754d54cf9f9e6f8c7c608534bdcad4a3e3 (diff)
Added a method to retrieve a function's argument type
The method in question is CppGenerator::getArgumentType(), and it resolves any type modification made in the type system. Also remove an unused convenience method for writeArgumentConversion, and unused variable on rich comparison writer function.
Diffstat (limited to 'generator')
-rw-r--r--generator/cppgenerator.cpp83
-rw-r--r--generator/cppgenerator.h22
-rw-r--r--generator/shibokengenerator.cpp15
-rw-r--r--generator/shibokengenerator.h7
4 files changed, 81 insertions, 46 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index cfa54f1f8..b37f7e087 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -1576,6 +1576,32 @@ void CppGenerator::writeArgumentConversion(QTextStream& s,
writePythonToCppTypeConversion(s, argType, pyArgName, argName, context, defaultValue);
}
+const AbstractMetaType* CppGenerator::getArgumentType(const AbstractMetaFunction* func, int argPos, bool* newType)
+{
+ *newType = false;
+
+ if (argPos < 0 || argPos > func->arguments().size()) {
+ ReportHandler::warning(QString("Argument index for function '%1' out of range.").arg(func->signature()));
+ return 0;
+ }
+
+ const AbstractMetaType* argType = 0;
+ QString typeReplaced = func->typeReplaced(argPos);
+ if (typeReplaced.isEmpty()) {
+ argType = (argPos == 0) ? func->type() : func->arguments().at(argPos-1)->type();
+ } else {
+ argType = buildAbstractMetaTypeFromString(typeReplaced);
+ *newType = (bool)argType;
+ }
+ if (!argType && !m_knownPythonTypes.contains(typeReplaced)) {
+ ReportHandler::warning(QString("Unknown type '%1' used as argument type replacement "\
+ "in function '%2', the generated code may be broken.")
+ .arg(typeReplaced)
+ .arg(func->signature()));
+ }
+ return argType;
+}
+
void CppGenerator::writePythonToCppTypeConversion(QTextStream& s,
const AbstractMetaType* type,
const QString& pyIn,
@@ -1838,34 +1864,32 @@ void CppGenerator::writeSingleFunctionCall(QTextStream& s, const OverloadData& o
writeNamedArgumentResolution(s, func, usePyArgs);
int removedArgs = 0;
- for (int i = 0; i < func->arguments().count(); i++) {
- if (func->argumentRemoved(i + 1)) {
+ for (int argIdx = 0; argIdx < func->arguments().count(); ++argIdx) {
+ if (func->argumentRemoved(argIdx + 1)) {
removedArgs++;
continue;
}
- if (!func->conversionRule(TypeSystem::NativeCode, i + 1).isEmpty())
+ if (!func->conversionRule(TypeSystem::NativeCode, argIdx + 1).isEmpty())
continue;
- const AbstractMetaArgument* arg = func->arguments().at(i);
+ bool newType;
+ const AbstractMetaType* argType = getArgumentType(func, argIdx + 1, &newType);
+
+ if (!argType)
+ continue;
- QString typeReplaced = func->typeReplaced(arg->argumentIndex() + 1);
- const AbstractMetaType* argType = 0;
std::auto_ptr<const AbstractMetaType> argType_autoptr;
- if (typeReplaced.isEmpty()) {
- argType = arg->type();
- } else {
- argType = buildAbstractMetaTypeFromString(typeReplaced);
+ if (newType)
argType_autoptr = std::auto_ptr<const AbstractMetaType>(argType);
- }
- if (argType) {
- QString argName = QString(CPP_ARG"%1").arg(i - removedArgs);
- QString pyArgName = usePyArgs ? QString("pyargs[%1]").arg(i - removedArgs) : "arg";
- QString defaultValue = guessScopeForDefaultValue(func, arg);
+ int argPos = argIdx - removedArgs;
+ QString argName = QString(CPP_ARG"%1").arg(argPos);
+ QString pyArgName = usePyArgs ? QString("pyargs[%1]").arg(argPos) : "arg";
+ const AbstractMetaArgument* arg = func->arguments().at(argIdx);
+ QString defaultValue = guessScopeForDefaultValue(func, arg);
- writeArgumentConversion(s, argType, argName, pyArgName, implementingClass, defaultValue);
- }
+ writeArgumentConversion(s, argType, argName, pyArgName, implementingClass, defaultValue);
}
s << endl;
@@ -3001,30 +3025,23 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl
}
bool first = true;
- bool comparesWithSameType = false;
OverloadData overloadData(overloads, this);
foreach (OverloadData* data, overloadData.nextOverloadData()) {
const AbstractMetaFunction* func = data->referenceFunction();
if (func->isStatic())
continue;
- QString typeReplaced = func->typeReplaced(1);
- const AbstractMetaType* type = 0;
- if (typeReplaced.isEmpty())
- type = func->arguments()[0]->type();
- else
- type = buildAbstractMetaTypeFromString(typeReplaced);
+ bool newType;
+ const AbstractMetaType* argType = getArgumentType(func, 1, &newType);
- if (!type) {
- ReportHandler::warning("Unknown type (" + typeReplaced + ") used in type replacement in function "
- + func->signature() + ", the generated code will be broken !!!");
+ if (!argType)
continue;
- }
- bool numberType = alternativeNumericTypes == 1 || ShibokenGenerator::isPyInt(type);
+ std::auto_ptr<const AbstractMetaType> argType_autoptr;
+ if (newType)
+ argType_autoptr = std::auto_ptr<const AbstractMetaType>(argType);
- if (!comparesWithSameType)
- comparesWithSameType = type->typeEntry() == metaClass->typeEntry();
+ bool numberType = alternativeNumericTypes == 1 || ShibokenGenerator::isPyInt(argType);
if (!first) {
s << " else ";
@@ -3033,11 +3050,11 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl
s << INDENT;
}
- s << "if (" << cpythonIsConvertibleFunction(type, numberType) << "(arg)) {" << endl;
+ s << "if (" << cpythonIsConvertibleFunction(argType, numberType) << "(arg)) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "// " << func->signature() << endl;
- writeArgumentConversion(s, type, "cppArg0", "arg", metaClass);
+ writeArgumentConversion(s, argType, "cppArg0", "arg", metaClass);
// If the function is user added, use the inject code
if (func->isUserAdded()) {
diff --git a/generator/cppgenerator.h b/generator/cppgenerator.h
index df3a6604f..19e8f0c50 100644
--- a/generator/cppgenerator.h
+++ b/generator/cppgenerator.h
@@ -86,14 +86,19 @@ private:
const QString& argName, const QString& pyArgName,
const AbstractMetaClass* context = 0,
const QString& defaultValue = QString());
- /// Convenience method to call writeArgumentConversion with an AbstractMetaArgument instead of an AbstractMetaType.
- void writeArgumentConversion(QTextStream& s, const AbstractMetaArgument* arg,
- const QString& argName, const QString& pyArgName,
- const AbstractMetaClass* context = 0,
- const QString& defaultValue = QString())
- {
- writeArgumentConversion(s, arg->type(), argName, pyArgName, context, defaultValue);
- }
+
+ /**
+ * Returns the AbstractMetaType for a function argument.
+ * If the argument type was modified in the type system, this method will
+ * try to build a new type based on the type name defined in the type system.
+ * \param func The function which owns the argument.
+ * \param argPos Argument position in the function signature.
+ * Note that the position 0 represents the return value, and the function
+ * parameters start counting on 1.
+ * \param newType It is set to true if the type returned is a new object that must be deallocated.
+ * \return The type of the argument indicated by \p argPos.
+ */
+ const AbstractMetaType* getArgumentType(const AbstractMetaFunction* func, int argPos, bool* newType);
void writePythonToCppTypeConversion(QTextStream& s,
const AbstractMetaType* type,
@@ -240,4 +245,3 @@ private:
};
#endif // CPPGENERATOR_H
-
diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp
index 90aed9780..c85acaca6 100644
--- a/generator/shibokengenerator.cpp
+++ b/generator/shibokengenerator.cpp
@@ -45,6 +45,7 @@ QHash<QString, QString> ShibokenGenerator::m_pythonPrimitiveTypeName = QHash<QSt
QHash<QString, QString> ShibokenGenerator::m_pythonOperators = QHash<QString, QString>();
QHash<QString, QString> ShibokenGenerator::m_formatUnits = QHash<QString, QString>();
QHash<QString, QString> ShibokenGenerator::m_tpFuncs = QHash<QString, QString>();
+QStringList ShibokenGenerator::m_knownPythonTypes = QStringList();
static QString resolveScopePrefix(const AbstractMetaClass* scope, const QString& value)
@@ -70,6 +71,9 @@ ShibokenGenerator::ShibokenGenerator() : Generator()
if (m_tpFuncs.isEmpty())
ShibokenGenerator::clearTpFuncs();
+
+ if (m_knownPythonTypes.isEmpty())
+ ShibokenGenerator::initKnownPythonTypes();
}
void ShibokenGenerator::clearTpFuncs()
@@ -178,6 +182,15 @@ void ShibokenGenerator::initPrimitiveTypesCorrespondences()
m_formatUnits.insert("float", "f");
}
+void ShibokenGenerator::initKnownPythonTypes()
+{
+ m_knownPythonTypes.clear();
+ m_knownPythonTypes << "PyBool" << "PyInt" << "PyFloat" << "PyLong";
+ m_knownPythonTypes << "PyObject" << "PyString" << "PyBuffer";
+ m_knownPythonTypes << "PySequence" << "PyTuple" << "PyList" << "PyDict";
+ m_knownPythonTypes << "PyObject*" << "PyObject *" << "PyTupleObject*";
+}
+
QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType* cType,
const AbstractMetaClass* context,
Options options) const
@@ -1849,4 +1862,4 @@ QString ShibokenGenerator::getDefaultValue(const AbstractMetaFunction* func, co
}
}
return QString();
-} \ No newline at end of file
+}
diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h
index 2dd6b5d07..433c283c4 100644
--- a/generator/shibokengenerator.h
+++ b/generator/shibokengenerator.h
@@ -375,15 +375,16 @@ protected:
static QHash<QString, QString> m_pythonOperators;
static QHash<QString, QString> m_formatUnits;
static QHash<QString, QString> m_tpFuncs;
+ static QStringList m_knownPythonTypes;
void clearTpFuncs();
const char* name() const { return "Shiboken"; }
- /**
- * Initialize correspondences between primitive and Python types
- */
+ /// Initializes correspondences between primitive and Python types.
static void initPrimitiveTypesCorrespondences();
+ /// Initializes a list of Python known type names.
+ static void initKnownPythonTypes();
void writeFunctionCall(QTextStream& s,
const AbstractMetaFunction* metaFunc,