aboutsummaryrefslogtreecommitdiffstats
path: root/overloaddata.cpp
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-10-29 11:51:53 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-10-30 14:24:20 -0300
commitcb4b14c179887735ffa925ea01de333c3ed41677 (patch)
treeacdcc074079d3b7ca368ad9c108b82b40dffd841 /overloaddata.cpp
parent10b5327e02c3ce3f7339226c6289ce0daf230d95 (diff)
improved OverloadData class to sort the alternative arguments putting
the primitive types first and moving down the wrapper objects with more implicit converversions; this ordering scheme is needed to avoid unnecessary (and sometimes wrong) conversions
Diffstat (limited to 'overloaddata.cpp')
-rw-r--r--overloaddata.cpp48
1 files changed, 37 insertions, 11 deletions
diff --git a/overloaddata.cpp b/overloaddata.cpp
index 6355edba0..48e7e27ce 100644
--- a/overloaddata.cpp
+++ b/overloaddata.cpp
@@ -25,10 +25,15 @@
#include "overloaddata.h"
#include "shibokengenerator.h"
+static bool overloadDataLessThan(const OverloadData* o1, const OverloadData* o2)
+{
+ return o1->argTypeWeight() < o2->argTypeWeight();
+}
+
// Prepare the information about overloaded methods signatures
-OverloadData::OverloadData(const AbstractMetaFunctionList overloads)
+OverloadData::OverloadData(const AbstractMetaFunctionList overloads, const ShibokenGenerator* generator)
: m_minArgs(256), m_maxArgs(0), m_argPos(-1), m_argType(0),
- m_headOverloadData(this)
+ m_headOverloadData(this), m_generator(generator)
{
foreach (const AbstractMetaFunction* func, overloads) {
m_overloads.append(func);
@@ -45,6 +50,11 @@ OverloadData::OverloadData(const AbstractMetaFunctionList overloads)
}
}
+ // Sort the overload possibilities so that the overload decisor code goes for the most
+ // important cases first, based on the weight system defined in OverloadData::addOverloadData
+ if (m_nextOverloadData.size() > 1)
+ qSort(m_nextOverloadData.begin(), m_nextOverloadData.end(), overloadDataLessThan);
+
// Fix minArgs
if (minArgs() > maxArgs())
m_headOverloadData->m_minArgs = maxArgs();
@@ -85,7 +95,7 @@ void OverloadData::addOverload(const AbstractMetaFunction* func)
}
OverloadData* OverloadData::addOverloadData(const AbstractMetaFunction* func,
- const AbstractMetaType* argType)
+ const AbstractMetaType* argType)
{
OverloadData* overloadData = 0;
foreach (OverloadData* tmp, m_nextOverloadData) {
@@ -99,14 +109,30 @@ OverloadData* OverloadData::addOverloadData(const AbstractMetaFunction* func,
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);
+ overloadData->m_generator = this->m_generator;
+
+ // The following code sets weights to the types of the possible arguments
+ // following the current one.
+ // The rule is: native strings goes first, followed by the primitive types
+ // (among those the most precise have more priority), and finally the wrapped C++
+ // types are ordered based on how many implicit conversions they have (the ones who
+ // have more go to the end).
+ if (ShibokenGenerator::isPyInt(argType)) {
+ overloadData->m_argTypeWeight = -1;
+ } else if (argType->isPrimitive()) {
+ if (argType->typeEntry()->name() == "double" || argType->typeEntry()->name() == "float")
+ overloadData->m_argTypeWeight = -3;
+ else
+ overloadData->m_argTypeWeight = -2;
+ } else if (argType->name() == "char" && argType->isNativePointer()) {
+ overloadData->m_argTypeWeight = -4;
+ } else if (argType->typeEntry()->isValue() || argType->typeEntry()->isObject()) {
+ overloadData->m_argTypeWeight = m_generator->implicitConversions(argType).size();
+ } else {
+ overloadData->m_argTypeWeight = 0;
+ }
+
+ m_nextOverloadData.append(overloadData);
}
return overloadData;