aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-09-06 11:49:35 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-09-09 20:06:23 +0200
commit47885c3c9d1ca4eb13daf79a0f6c73c8fce350cc (patch)
treeeed3cfe07669d40431178287f43d191e3bcec15e
parentaec162c77194898eb04fff83036e8157db3eb051 (diff)
shiboken6: Split out node classes from OverloadData
OverloadData represents a tree, the root node of which has the list of all functions and a list of children, which represent an argument/type combination. This was all in one class, where it was unclear which member function or member variable was applicable to the node type. To fix this, split out a root node class and an argument node class. Rename nextOverloadData() to children() and previousOverloadData() to parent() to make the relationship clearer. Task-number: PYSIDE-1653 Change-Id: Ife63e78604bc42c08cc8cd0056d1c810060ba886 Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp80
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h10
-rw-r--r--sources/shiboken6/generator/shiboken/overloaddata.cpp477
-rw-r--r--sources/shiboken6/generator/shiboken/overloaddata.h155
4 files changed, 409 insertions, 313 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index aac949459..bc173d8a6 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -2467,15 +2467,16 @@ static void checkTypeViability(const AbstractMetaFunctionCPtr &func)
checkTypeViability(func, func->arguments().at(i).type(), i + 1);
}
-void CppGenerator::writeTypeCheck(TextStream &s, const OverloadData *overloadData,
+void CppGenerator::writeTypeCheck(TextStream &s,
+ const QSharedPointer<OverloadDataNode> &overloadData,
const QString &argumentName) const
{
QSet<const TypeEntry *> numericTypes;
- const OverloadDataList &overloads = overloadData->previousOverloadData()->nextOverloadData();
- for (OverloadData *od : overloads) {
- for (const auto &func : od->overloads()) {
+ const OverloadDataList &siblings = overloadData->parent()->children();
+ for (const auto &sibling : siblings) {
+ for (const auto &func : sibling->overloads()) {
checkTypeViability(func);
- const AbstractMetaType &argType = od->argument(func)->type();
+ const AbstractMetaType &argType = sibling->argument(func)->type();
if (!argType.isPrimitive())
continue;
if (ShibokenGenerator::isNumber(argType.typeEntry()))
@@ -2779,7 +2780,7 @@ void CppGenerator::writeOverloadedFunctionDecisor(TextStream &s, const OverloadD
s << decl->name() << "::";
s << func->signatureComment() << '\n';
}
- writeOverloadedFunctionDecisorEngine(s, &overloadData);
+ writeOverloadedFunctionDecisorEngine(s, overloadData, &overloadData);
s << '\n';
// Ensure that the direct overload that called this reverse
@@ -2800,10 +2801,11 @@ void CppGenerator::writeOverloadedFunctionDecisor(TextStream &s, const OverloadD
}
void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
- const OverloadData *parentOverloadData) const
+ const OverloadData &overloadData,
+ const OverloadDataRootNode *node) const
{
- bool hasDefaultCall = parentOverloadData->nextArgumentHasDefaultValue();
- auto referenceFunction = parentOverloadData->referenceFunction();
+ bool hasDefaultCall = node->nextArgumentHasDefaultValue();
+ auto referenceFunction = node->referenceFunction();
// If the next argument has not an argument with a default value, it is still possible
// that one of the overloads for the current overload data has its final occurrence here.
@@ -2811,8 +2813,8 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
// variable to be used further on this method on the conditional that identifies default
// method calls.
if (!hasDefaultCall) {
- for (const auto &func : parentOverloadData->overloads()) {
- if (parentOverloadData->isFinalOccurrence(func)) {
+ for (const auto &func : node->overloads()) {
+ if (node->isFinalOccurrence(func)) {
referenceFunction = func;
hasDefaultCall = true;
break;
@@ -2820,13 +2822,13 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
}
}
- int maxArgs = parentOverloadData->maxArgs();
+ const int maxArgs = overloadData.maxArgs();
// Python constructors always receive multiple arguments.
- const bool usePyArgs = parentOverloadData->pythonFunctionWrapperUsesListOfArguments();
+ const bool usePyArgs = overloadData.pythonFunctionWrapperUsesListOfArguments();
// Functions without arguments are identified right away.
if (maxArgs == 0) {
- s << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(referenceFunction)
+ s << "overloadId = " << overloadData.functionNumber(referenceFunction)
<< "; // " << referenceFunction->minimalSignature() << '\n';
return;
@@ -2834,15 +2836,15 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
// To decide if a method call is possible at this point the current overload
// data object cannot be the head, since it is just an entry point, or a root,
// for the tree of arguments and it does not represent a valid method call.
- if (!parentOverloadData->isHeadOverloadData()) {
- bool isLastArgument = parentOverloadData->nextOverloadData().isEmpty();
- bool signatureFound = parentOverloadData->overloads().size() == 1;
+ if (!node->isRoot()) {
+ const bool isLastArgument = node->children().isEmpty();
+ const bool signatureFound = node->overloads().size() == 1;
// The current overload data describes the last argument of a signature,
// so the method can be identified right now.
if (isLastArgument || (signatureFound && !hasDefaultCall)) {
- const auto func = parentOverloadData->referenceFunction();
- s << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(func)
+ const auto func = node->referenceFunction();
+ s << "overloadId = " << overloadData.functionNumber(func)
<< "; // " << func->minimalSignature() << '\n';
return;
}
@@ -2853,40 +2855,40 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
// If the next argument has a default value the decisor can perform a method call;
// it just need to check if the number of arguments received from Python are equal
// to the number of parameters preceding the argument with the default value.
- const OverloadDataList &overloads = parentOverloadData->nextOverloadData();
+ const OverloadDataList &children = node->children();
if (hasDefaultCall) {
isFirst = false;
- int numArgs = parentOverloadData->argPos() + 1;
+ int numArgs = node->argPos() + 1;
s << "if (numArgs == " << numArgs << ") {\n";
{
Indentation indent(s);
auto func = referenceFunction;
- for (OverloadData *overloadData : overloads) {
- const auto defValFunc = overloadData->getFunctionWithDefaultValue();
+ for (const auto &child : children) {
+ const auto defValFunc = child->getFunctionWithDefaultValue();
if (!defValFunc.isNull()) {
func = defValFunc;
break;
}
}
- s << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(func)
+ s << "overloadId = " << overloadData.functionNumber(func)
<< "; // " << func->minimalSignature() << '\n';
}
s << '}';
}
- for (OverloadData *overloadData : overloads) {
- bool signatureFound = overloadData->overloads().size() == 1
- && !overloadData->getFunctionWithDefaultValue()
- && !overloadData->findNextArgWithDefault();
+ for (auto child : children) {
+ bool signatureFound = child->overloads().size() == 1
+ && !child->getFunctionWithDefaultValue()
+ && !child->findNextArgWithDefault();
- const auto refFunc = overloadData->referenceFunction();
+ const auto refFunc = child->referenceFunction();
QStringList typeChecks;
QString pyArgName = (usePyArgs && maxArgs > 1)
- ? pythonArgsAt(overloadData->argPos())
+ ? pythonArgsAt(child->argPos())
: QLatin1String(PYTHON_ARG);
- OverloadData *od = overloadData;
+ auto od = child;
int startArg = od->argPos();
int sequenceArgCount = 0;
while (od && !od->argType().isVarargs()) {
@@ -2913,14 +2915,14 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
sequenceArgCount++;
- if (od->nextOverloadData().isEmpty()
+ if (od->children().isEmpty()
|| od->nextArgumentHasDefaultValue()
- || od->nextOverloadData().size() != 1
- || od->overloads().size() != od->nextOverloadData().constFirst()->overloads().size()) {
- overloadData = od;
+ || od->children().size() != 1
+ || od->overloads().size() != od->children().constFirst()->overloads().size()) {
+ child = od;
od = nullptr;
} else {
- od = od->nextOverloadData().constFirst();
+ od = od->children().constFirst();
}
}
@@ -2958,7 +2960,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
s << ") {\n";
{
Indentation indent(s);
- writeOverloadedFunctionDecisorEngine(s, overloadData);
+ writeOverloadedFunctionDecisorEngine(s, overloadData, child.data());
}
s << "}";
}
@@ -4922,8 +4924,8 @@ void CppGenerator::writeRichCompareFunction(TextStream &s,
bool first = true;
OverloadData overloadData(overloads, api());
- const OverloadDataList &nextOverloads = overloadData.nextOverloadData();
- for (OverloadData *od : nextOverloads) {
+ const OverloadDataList &nextOverloads = overloadData.children();
+ for (const auto &od : nextOverloads) {
const auto func = od->referenceFunction();
if (func->isStatic())
continue;
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index b1628ff8b..a2e977545 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -32,6 +32,11 @@
#include "shibokengenerator.h"
#include "abstractmetalang_enums.h"
+#include <QtCore/QSharedPointer>
+
+class OverloadDataNode;
+class OverloadDataRootNode;
+
/**
* The CppGenerator generate the implementations of C++ bindings classes.
*/
@@ -121,7 +126,7 @@ private:
void writeTypeCheck(TextStream &s, AbstractMetaType argType, const QString &argumentName,
bool isNumber = false, const QString &customType = QString(),
bool rejectNull = false) const;
- void writeTypeCheck(TextStream& s, const OverloadData *overloadData,
+ void writeTypeCheck(TextStream& s, const QSharedPointer<OverloadDataNode> &overloadData,
const QString &argumentName) const;
static void writeTypeDiscoveryFunction(TextStream &s, const AbstractMetaClass *metaClass);
@@ -204,7 +209,8 @@ private:
void writeOverloadedFunctionDecisor(TextStream &s, const OverloadData &overloadData) const;
/// Recursive auxiliar method to the other writeOverloadedFunctionDecisor.
void writeOverloadedFunctionDecisorEngine(TextStream &s,
- const OverloadData *parentOverloadData) const;
+ const OverloadData &overloadData,
+ const OverloadDataRootNode *node) const;
/// Writes calls to all the possible method/function overloads.
void writeFunctionCalls(TextStream &s,
diff --git a/sources/shiboken6/generator/shiboken/overloaddata.cpp b/sources/shiboken6/generator/shiboken/overloaddata.cpp
index 2a1acad9a..137a37aeb 100644
--- a/sources/shiboken6/generator/shiboken/overloaddata.cpp
+++ b/sources/shiboken6/generator/shiboken/overloaddata.cpp
@@ -70,7 +70,7 @@ static QString getTypeName(const AbstractMetaType &type)
return typeName;
}
-static QString getTypeName(const OverloadData *ov)
+static QString getTypeName(const OverloadDataNodePtr &ov)
{
return ov->hasArgumentTypeReplace() ? ov->argumentTypeReplaced() : getTypeName(ov->argType());
}
@@ -145,19 +145,19 @@ static QString msgCyclicDependency(const QString &funcName, const QString &graph
return result;
}
-static inline int overloadNumber(const OverloadData *o)
+static inline int overloadNumber(const OverloadDataNodePtr &o)
{
return o->referenceFunction()->overloadNumber();
}
-bool OverloadData::sortByOverloadNumberModification()
+static bool sortByOverloadNumberModification(OverloadDataList &list)
{
- if (std::all_of(m_nextOverloadData.cbegin(), m_nextOverloadData.cend(),
- [](const OverloadData *o) { return overloadNumber(o) == TypeSystem::OverloadNumberDefault; })) {
+ if (std::all_of(list.cbegin(), list.cend(),
+ [](const OverloadDataNodePtr &o) { return overloadNumber(o) == TypeSystem::OverloadNumberDefault; })) {
return false;
}
- std::stable_sort(m_nextOverloadData.begin(), m_nextOverloadData.end(),
- [] (const OverloadData *o1, const OverloadData *o2) {
+ std::stable_sort(list.begin(), list.end(),
+ [] (const OverloadDataNodePtr &o1, const OverloadDataNodePtr &o2) {
return overloadNumber(o1) < overloadNumber(o2);
});
return true;
@@ -175,7 +175,7 @@ using OverloadGraph = Graph<QString>;
*
* Side effects: Modifies m_nextOverloadData
*/
-void OverloadData::sortNextOverloads()
+void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
{
QHash<QString, OverloadDataList> typeToOverloads;
@@ -193,10 +193,10 @@ void OverloadData::sortNextOverloads()
static const QStringList signedIntegerPrimitives{intT(), shortT(), longT(), longLongT()};
// sort the children overloads
- for (OverloadData *ov : qAsConst(m_nextOverloadData))
- ov->sortNextOverloads();
+ for (const auto &ov : qAsConst(m_children))
+ ov->sortNextOverloads(api);
- if (m_nextOverloadData.size() <= 1 || sortByOverloadNumberModification())
+ if (m_children.size() <= 1 || sortByOverloadNumberModification(m_children))
return;
// Populates the OverloadSortData object containing map and reverseMap, to map type names to ids,
@@ -204,7 +204,7 @@ void OverloadData::sortNextOverloads()
// with graph sorting using integers.
OverloadGraph graph;
- for (OverloadData *ov : qAsConst(m_nextOverloadData)) {
+ for (const auto &ov : qAsConst(m_children)) {
const QString typeName = getTypeName(ov);
auto it = typeToOverloads.find(typeName);
if (it == typeToOverloads.end()) {
@@ -238,7 +238,7 @@ void OverloadData::sortNextOverloads()
for (const QString &primitive : qAsConst(nonIntegerPrimitives))
graph.addNode(getImplicitConversionTypeName(ov->argType(), instantiation, nullptr, primitive));
} else {
- const auto &funcs = m_api.implicitConversions(instantiation);
+ const auto &funcs = api.implicitConversions(instantiation);
for (const auto &function : funcs)
graph.addNode(getImplicitConversionTypeName(ov->argType(), instantiation, function));
}
@@ -265,12 +265,12 @@ void OverloadData::sortNextOverloads()
AbstractMetaFunctionCList involvedConversions;
- for (OverloadData *ov : qAsConst(m_nextOverloadData)) {
+ for (const auto &ov : qAsConst(m_children)) {
const AbstractMetaType &targetType = ov->argType();
const QString targetTypeEntryName = getTypeName(ov);
// Process implicit conversions
- const auto &functions = m_api.implicitConversions(targetType);
+ const auto &functions = api.implicitConversions(targetType);
for (const auto &function : functions) {
QString convertibleType;
if (function->isConversionOperator())
@@ -293,7 +293,7 @@ void OverloadData::sortNextOverloads()
// Process inheritance relationships
if (targetType.isValue() || targetType.isObject()) {
- auto metaClass = AbstractMetaClass::findClass(m_api.classes(),
+ auto metaClass = AbstractMetaClass::findClass(api.classes(),
targetType.typeEntry());
const AbstractMetaClassList &ancestors = metaClass->allTypeSystemAncestors();
for (const AbstractMetaClass *ancestor : ancestors) {
@@ -322,7 +322,7 @@ void OverloadData::sortNextOverloads()
}
} else {
- const auto &funcs = m_api.implicitConversions(instantiation);
+ const auto &funcs = api.implicitConversions(instantiation);
for (const auto &function : funcs) {
QString convertibleTypeName =
getImplicitConversionTypeName(ov->argType(), instantiation, function);
@@ -373,7 +373,7 @@ void OverloadData::sortNextOverloads()
if (graph.hasNode(qStringT()) && graph.hasNode(qByteArrayT()))
graph.addEdge(qStringT(), qByteArrayT());
- for (OverloadData *ov : qAsConst(m_nextOverloadData)) {
+ for (const auto &ov : qAsConst(m_children)) {
const AbstractMetaType &targetType = ov->argType();
if (!targetType.isEnum())
continue;
@@ -399,8 +399,8 @@ void OverloadData::sortNextOverloads()
const auto unmappedResult = graph.topologicalSort();
if (!unmappedResult.isValid()) {
QString funcName = referenceFunction()->name();
- if (referenceFunction()->ownerClass())
- funcName.prepend(referenceFunction()->ownerClass()->name() + QLatin1Char('.'));
+ if (auto owner = referenceFunction()->ownerClass())
+ funcName.prepend(owner->name() + QLatin1Char('.'));
// Dump overload graph
QString graphName = QDir::tempPath() + QLatin1Char('/') + funcName + QLatin1String(".dot");
@@ -414,12 +414,12 @@ void OverloadData::sortNextOverloads()
qCWarning(lcShiboken, "%s", qPrintable(msgCyclicDependency(funcName, graphName, cyclic, involvedConversions)));
}
- m_nextOverloadData.clear();
+ m_children.clear();
for (const auto &typeName : unmappedResult.result) {
const auto oit = typeToOverloads.constFind(typeName);
if (oit != typeToOverloads.cend()) {
std::copy(oit.value().crbegin(), oit.value().crend(),
- std::back_inserter(m_nextOverloadData));
+ std::back_inserter(m_children));
}
}
}
@@ -443,11 +443,16 @@ static std::pair<int, int> getMinMaxArgs(const AbstractMetaFunctionCPtr &func)
return {minArgs, maxArgs};
}
+const OverloadDataRootNode *OverloadDataNode::parent() const
+{
+ return m_parent;
+}
+
/**
* Root constructor for OverloadData
*
* This constructor receives the list of overloads for a given function and iterates generating
- * the graph of OverloadData instances. Each OverloadData instance references an argument/type
+ * the graph of OverloadData instances. Each OverloadDataNode instance references an argument/type
* combination.
*
* Example:
@@ -461,8 +466,8 @@ static std::pair<int, int> getMinMaxArgs(const AbstractMetaFunctionCPtr &func)
*
*/
OverloadData::OverloadData(const AbstractMetaFunctionCList &overloads,
- const ApiExtractorResult &api)
- : m_argType(), m_overloads(overloads), m_headOverloadData(this), m_api(api)
+ const ApiExtractorResult &api) :
+ OverloadDataRootNode(overloads)
{
for (const auto &func : overloads) {
const auto minMaxArgs = getMinMaxArgs(func);
@@ -470,49 +475,52 @@ OverloadData::OverloadData(const AbstractMetaFunctionCList &overloads,
m_minArgs = minMaxArgs.first;
if (minMaxArgs.second > m_maxArgs)
m_maxArgs = minMaxArgs.second;
- OverloadData *currentOverloadData = this;
+ OverloadDataRootNode *currentOverloadData = this;
const AbstractMetaArgumentList &arguments = func->arguments();
for (const AbstractMetaArgument &arg : arguments) {
if (func->argumentRemoved(arg.argumentIndex() + 1))
continue;
- currentOverloadData = currentOverloadData->addOverloadData(func, arg);
+ currentOverloadData = currentOverloadData->addOverloadDataNode(func, arg);
}
}
// Sort the overload possibilities so that the overload decisor code goes for the most
// important cases first, based on the topological order of the implicit conversions
- sortNextOverloads();
+ sortNextOverloads(api);
}
-OverloadData::OverloadData(OverloadData *headOverloadData, const AbstractMetaFunctionCPtr &func,
- const AbstractMetaType &argType, int argPos,
- const ApiExtractorResult &api) :
- m_argType(argType), m_headOverloadData(headOverloadData), m_api(api),
+OverloadDataNode::OverloadDataNode(const AbstractMetaFunctionCPtr &func,
+ OverloadDataRootNode *parent,
+ const AbstractMetaType &argType, int argPos,
+ const QString argTypeReplaced) :
+ m_argType(argType),
+ m_argTypeReplaced(argTypeReplaced),
+ m_parent(parent),
m_argPos(argPos)
{
if (func)
this->addOverload(func);
}
-void OverloadData::addOverload(const AbstractMetaFunctionCPtr &func)
+void OverloadDataNode::addOverload(const AbstractMetaFunctionCPtr &func)
{
m_overloads.append(func);
}
-OverloadData *OverloadData::addOverloadData(const AbstractMetaFunctionCPtr &func,
- const AbstractMetaArgument &arg)
+OverloadDataNode *OverloadDataRootNode::addOverloadDataNode(const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaArgument &arg)
{
const AbstractMetaType &argType = arg.type();
- OverloadData *overloadData = nullptr;
+ OverloadDataNodePtr overloadData;
if (!func->isOperatorOverload()) {
- for (OverloadData *tmp : qAsConst(m_nextOverloadData)) {
+ for (const auto &tmp : qAsConst(m_children)) {
// TODO: 'const char *', 'char *' and 'char' will have the same TypeEntry?
// If an argument have a type replacement, then we should create a new overloaddata
// for it, unless the next argument also have a identical type replacement.
- QString replacedArg = func->typeReplaced(tmp->m_argPos + 1);
- bool argsReplaced = !replacedArg.isEmpty() || !tmp->m_argTypeReplaced.isEmpty();
- if ((!argsReplaced && typesAreEqual(tmp->m_argType, argType))
+ QString replacedArg = func->typeReplaced(tmp->argPos() + 1);
+ bool argsReplaced = !replacedArg.isEmpty() || tmp->hasArgumentTypeReplace();
+ if ((!argsReplaced && typesAreEqual(tmp->argType(), argType))
|| (argsReplaced && replacedArg == tmp->argumentTypeReplaced())) {
tmp->addOverload(func);
overloadData = tmp;
@@ -520,17 +528,15 @@ OverloadData *OverloadData::addOverloadData(const AbstractMetaFunctionCPtr &func
}
}
- if (!overloadData) {
- overloadData = new OverloadData(m_headOverloadData, func, argType, m_argPos + 1, m_api);
- overloadData->m_previousOverloadData = this;
+ if (overloadData.isNull()) {
QString typeReplaced = func->typeReplaced(arg.argumentIndex() + 1);
-
- if (!typeReplaced.isEmpty())
- overloadData->m_argTypeReplaced = typeReplaced;
- m_nextOverloadData.append(overloadData);
+ const int argpos = argPos() + 1;
+ overloadData.reset(new OverloadDataNode(func, this, argType, argpos,
+ typeReplaced));
+ m_children.append(overloadData);
}
- return overloadData;
+ return overloadData.data();
}
bool OverloadData::hasNonVoidReturnType() const
@@ -622,14 +628,21 @@ bool OverloadData::hasStaticAndInstanceFunctions() const
return OverloadData::hasStaticFunction() && OverloadData::hasInstanceFunction();
}
-AbstractMetaFunctionCPtr OverloadData::referenceFunction() const
+OverloadDataRootNode::OverloadDataRootNode(const AbstractMetaFunctionCList &o) :
+ m_overloads(o)
+{
+}
+
+OverloadDataRootNode::~OverloadDataRootNode() = default;
+
+AbstractMetaFunctionCPtr OverloadDataRootNode::referenceFunction() const
{
return m_overloads.constFirst();
}
-const AbstractMetaArgument *OverloadData::argument(const AbstractMetaFunctionCPtr &func) const
+const AbstractMetaArgument *OverloadDataNode::argument(const AbstractMetaFunctionCPtr &func) const
{
- if (isHeadOverloadData() || !m_overloads.contains(func))
+ if (isRoot() || !m_overloads.contains(func))
return nullptr;
int argPos = 0;
@@ -644,53 +657,54 @@ const AbstractMetaArgument *OverloadData::argument(const AbstractMetaFunctionCPt
return &func->arguments().at(m_argPos + removed);
}
-bool OverloadData::nextArgumentHasDefaultValue() const
+bool OverloadDataRootNode::nextArgumentHasDefaultValue() const
{
- for (OverloadData *overloadData : m_nextOverloadData) {
+ for (const auto &overloadData : m_children) {
if (!overloadData->getFunctionWithDefaultValue().isNull())
return true;
}
return false;
}
-static OverloadData *_findNextArgWithDefault(OverloadData *overloadData)
+static const OverloadDataRootNode *_findNextArgWithDefault(const OverloadDataRootNode *overloadData)
{
if (!overloadData->getFunctionWithDefaultValue().isNull())
return overloadData;
- OverloadData *result = nullptr;
- const OverloadDataList &data = overloadData->nextOverloadData();
- for (OverloadData *odata : data) {
- OverloadData *tmp = _findNextArgWithDefault(odata);
+ const OverloadDataRootNode *result = nullptr;
+ const OverloadDataList &data = overloadData->children();
+ for (const auto &odata : data) {
+ const auto *tmp = _findNextArgWithDefault(odata.data());
if (!result || (tmp && result->argPos() > tmp->argPos()))
result = tmp;
}
return result;
}
-OverloadData *OverloadData::findNextArgWithDefault()
+const OverloadDataRootNode *OverloadDataRootNode::findNextArgWithDefault()
{
return _findNextArgWithDefault(this);
}
-bool OverloadData::isFinalOccurrence(const AbstractMetaFunctionCPtr &func) const
+bool OverloadDataRootNode::isFinalOccurrence(const AbstractMetaFunctionCPtr &func) const
{
- for (const OverloadData *pd : m_nextOverloadData) {
+ for (const auto &pd : m_children) {
if (pd->overloads().contains(func))
return false;
}
return true;
}
-AbstractMetaFunctionCPtr OverloadData::getFunctionWithDefaultValue() const
+AbstractMetaFunctionCPtr OverloadDataRootNode::getFunctionWithDefaultValue() const
{
+ const int argpos = argPos();
for (const auto &func : m_overloads) {
int removedArgs = 0;
- for (int i = 0; i <= m_argPos + removedArgs; i++) {
+ for (int i = 0; i <= argpos + removedArgs; i++) {
if (func->argumentRemoved(i + 1))
removedArgs++;
}
- if (func->arguments().at(m_argPos + removedArgs).hasDefaultValueExpression())
+ if (func->arguments().at(argpos + removedArgs).hasDefaultValueExpression())
return func;
}
return {};
@@ -700,7 +714,7 @@ QList<int> OverloadData::invalidArgumentLengths() const
{
QSet<int> validArgLengths;
- for (const auto &func : qAsConst(m_headOverloadData->m_overloads)) {
+ for (const auto &func : m_overloads) {
const AbstractMetaArgumentList args = func->arguments();
int offset = 0;
for (int i = 0; i < args.size(); ++i) {
@@ -715,7 +729,7 @@ QList<int> OverloadData::invalidArgumentLengths() const
}
QList<int> invalidArgLengths;
- for (int i = minArgs() + 1; i < maxArgs(); i++) {
+ for (int i = m_minArgs + 1; i < m_maxArgs; i++) {
if (!validArgLengths.contains(i))
invalidArgLengths.append(i);
}
@@ -760,11 +774,19 @@ void OverloadData::dumpGraph(const QString &filename) const
{
QFile file(filename);
if (file.open(QFile::WriteOnly)) {
- TextStream s(&file);
- s << m_headOverloadData->dumpGraph();
+ QTextStream s(&file);
+ dumpRootGraph(s, m_minArgs, m_maxArgs);
}
}
+QString OverloadData::dumpGraph() const
+{
+ QString result;
+ QTextStream s(&result);
+ dumpRootGraph(s, m_minArgs, m_maxArgs);
+ return result;
+}
+
static inline QString toHtml(QString s)
{
s.replace(QLatin1Char('<'), QLatin1String("&lt;"));
@@ -773,140 +795,136 @@ static inline QString toHtml(QString s)
return s;
}
-QString OverloadData::dumpGraph() const
+void OverloadDataRootNode::dumpRootGraph(QTextStream &s, int minArgs, int maxArgs) const
{
- QString result;
- QTextStream s(&result);
- if (m_argPos == -1) {
- const auto rfunc = referenceFunction();
- s << "digraph OverloadedFunction {\n";
- s << " graph [fontsize=12 fontname=freemono labelloc=t splines=true overlap=false rankdir=LR];\n";
-
- // Shows all function signatures
- s << "legend [fontsize=9 fontname=freemono shape=rect label=\"";
- for (const auto &func : m_overloads) {
- s << "f" << functionNumber(func) << " : "
- << toHtml(func->type().cppSignature())
- << ' ' << toHtml(func->minimalSignature()) << "\\l";
- }
- s << "\"];\n";
-
- // Function box title
- s << " \"" << rfunc->name() << "\" [shape=plaintext style=\"filled,bold\" margin=0 fontname=freemono fillcolor=white penwidth=1 ";
- s << "label=<<table border=\"0\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">";
- s << "<tr><td bgcolor=\"black\" align=\"center\" cellpadding=\"6\" colspan=\"2\"><font color=\"white\">";
- if (rfunc->ownerClass())
- s << rfunc->ownerClass()->name() << "::";
- s << toHtml(rfunc->name()) << "</font>";
- if (rfunc->isVirtual()) {
- s << "<br/><font color=\"white\" point-size=\"10\">&lt;&lt;";
- if (rfunc->isAbstract())
- s << "pure ";
- s << "virtual&gt;&gt;</font>";
- }
- s << "</td></tr>";
-
- // Function return type
- s << "<tr><td bgcolor=\"gray\" align=\"right\">original type</td><td bgcolor=\"gray\" align=\"left\">"
- << toHtml(rfunc->type().cppSignature())
- << "</td></tr>";
+ const auto rfunc = referenceFunction();
+ s << "digraph OverloadedFunction {\n";
+ s << " graph [fontsize=12 fontname=freemono labelloc=t splines=true overlap=false rankdir=LR];\n";
- // Shows type changes for all function signatures
- for (const auto &func : m_overloads) {
- if (func->typeReplaced(0).isEmpty())
- continue;
- s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
- s << "-type</td><td bgcolor=\"gray\" align=\"left\">";
- s << toHtml(func->typeReplaced(0)) << "</td></tr>";
- }
+ // Shows all function signatures
+ s << "legend [fontsize=9 fontname=freemono shape=rect label=\"";
+ for (const auto &func : m_overloads) {
+ s << "f" << functionNumber(func) << " : "
+ << toHtml(func->type().cppSignature())
+ << ' ' << toHtml(func->minimalSignature()) << "\\l";
+ }
+ s << "\"];\n";
+
+ // Function box title
+ s << " \"" << rfunc->name() << "\" [shape=plaintext style=\"filled,bold\" margin=0 fontname=freemono fillcolor=white penwidth=1 ";
+ s << "label=<<table border=\"0\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">";
+ s << "<tr><td bgcolor=\"black\" align=\"center\" cellpadding=\"6\" colspan=\"2\"><font color=\"white\">";
+ if (rfunc->ownerClass())
+ s << rfunc->ownerClass()->name() << "::";
+ s << toHtml(rfunc->name()) << "</font>";
+ if (rfunc->isVirtual()) {
+ s << "<br/><font color=\"white\" point-size=\"10\">&lt;&lt;";
+ if (rfunc->isAbstract())
+ s << "pure ";
+ s << "virtual&gt;&gt;</font>";
+ }
+ s << "</td></tr>";
- // Minimum and maximum number of arguments
- s << "<tr><td bgcolor=\"gray\" align=\"right\">minArgs</td><td bgcolor=\"gray\" align=\"left\">";
- s << minArgs() << "</td></tr>";
- s << "<tr><td bgcolor=\"gray\" align=\"right\">maxArgs</td><td bgcolor=\"gray\" align=\"left\">";
- s << maxArgs() << "</td></tr>";
-
- if (rfunc->ownerClass()) {
- if (rfunc->implementingClass() != rfunc->ownerClass())
- s << "<tr><td align=\"right\">implementor</td><td align=\"left\">" << rfunc->implementingClass()->name() << "</td></tr>";
- if (rfunc->declaringClass() != rfunc->ownerClass() && rfunc->declaringClass() != rfunc->implementingClass())
- s << "<tr><td align=\"right\">declarator</td><td align=\"left\">" << rfunc->declaringClass()->name() << "</td></tr>";
- }
+ // Function return type
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">original type</td><td bgcolor=\"gray\" align=\"left\">"
+ << toHtml(rfunc->type().cppSignature())
+ << "</td></tr>";
- // Overloads for the signature to present point
- s << "<tr><td bgcolor=\"gray\" align=\"right\">overloads</td><td bgcolor=\"gray\" align=\"left\">";
- for (const auto &func : m_overloads)
- s << 'f' << functionNumber(func) << ' ';
- s << "</td></tr>";
+ // Shows type changes for all function signatures
+ for (const auto &func : m_overloads) {
+ if (func->typeReplaced(0).isEmpty())
+ continue;
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
+ s << "-type</td><td bgcolor=\"gray\" align=\"left\">";
+ s << toHtml(func->typeReplaced(0)) << "</td></tr>";
+ }
- s << "</table>> ];\n";
+ // Minimum and maximum number of arguments
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">minArgs</td><td bgcolor=\"gray\" align=\"left\">";
+ s << minArgs << "</td></tr>";
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">maxArgs</td><td bgcolor=\"gray\" align=\"left\">";
+ s << maxArgs << "</td></tr>";
+
+ if (rfunc->ownerClass()) {
+ if (rfunc->implementingClass() != rfunc->ownerClass())
+ s << "<tr><td align=\"right\">implementor</td><td align=\"left\">" << rfunc->implementingClass()->name() << "</td></tr>";
+ if (rfunc->declaringClass() != rfunc->ownerClass() && rfunc->declaringClass() != rfunc->implementingClass())
+ s << "<tr><td align=\"right\">declarator</td><td align=\"left\">" << rfunc->declaringClass()->name() << "</td></tr>";
+ }
- for (const OverloadData *pd : m_nextOverloadData)
- s << " \"" << rfunc->name() << "\" -> " << pd->dumpGraph();
+ // Overloads for the signature to present point
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">overloads</td><td bgcolor=\"gray\" align=\"left\">";
+ for (const auto &func : m_overloads)
+ s << 'f' << functionNumber(func) << ' ';
+ s << "</td></tr>";
- s << "}\n";
- } else {
- QString argId = QLatin1String("arg_") + QString::number(quintptr(this));
- s << argId << ";\n";
+ s << "</table>> ];\n";
- s << " \"" << argId << "\" [shape=\"plaintext\" style=\"filled,bold\" margin=\"0\" fontname=\"freemono\" fillcolor=\"white\" penwidth=1 ";
- s << "label=<<table border=\"0\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">";
+ for (const auto &pd : m_children) {
+ s << " \"" << rfunc->name() << "\" -> ";
+ pd->dumpNodeGraph(s);
+ }
- // Argument box title
- s << "<tr><td bgcolor=\"black\" align=\"left\" cellpadding=\"2\" colspan=\"2\">";
- s << "<font color=\"white\" point-size=\"11\">arg #" << argPos() << "</font></td></tr>";
+ s << "}\n";
+}
- // Argument type information
- QString type = hasArgumentTypeReplace() ? argumentTypeReplaced() : argType().cppSignature();
- s << "<tr><td bgcolor=\"gray\" align=\"right\">type</td><td bgcolor=\"gray\" align=\"left\">";
- s << toHtml(type) << "</td></tr>";
- if (hasArgumentTypeReplace()) {
- s << "<tr><td bgcolor=\"gray\" align=\"right\">orig. type</td><td bgcolor=\"gray\" align=\"left\">";
- s << toHtml(argType().cppSignature()) << "</td></tr>";
- }
+void OverloadDataNode::dumpNodeGraph(QTextStream &s) const
+{
+ QString argId = QLatin1String("arg_") + QString::number(quintptr(this));
+ s << argId << ";\n";
+
+ s << " \"" << argId << "\" [shape=\"plaintext\" style=\"filled,bold\" margin=\"0\" fontname=\"freemono\" fillcolor=\"white\" penwidth=1 ";
+ s << "label=<<table border=\"0\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">";
+
+ // Argument box title
+ s << "<tr><td bgcolor=\"black\" align=\"left\" cellpadding=\"2\" colspan=\"2\">";
+ s << "<font color=\"white\" point-size=\"11\">arg #" << argPos() << "</font></td></tr>";
+
+ // Argument type information
+ QString type = hasArgumentTypeReplace() ? argumentTypeReplaced() : argType().cppSignature();
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">type</td><td bgcolor=\"gray\" align=\"left\">";
+ s << toHtml(type) << "</td></tr>";
+ if (hasArgumentTypeReplace()) {
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">orig. type</td><td bgcolor=\"gray\" align=\"left\">";
+ s << toHtml(argType().cppSignature()) << "</td></tr>";
+ }
- // Overloads for the signature to present point
- s << "<tr><td bgcolor=\"gray\" align=\"right\">overloads</td><td bgcolor=\"gray\" align=\"left\">";
- for (const auto &func : m_overloads)
- s << 'f' << functionNumber(func) << ' ';
- s << "</td></tr>";
+ // Overloads for the signature to present point
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">overloads</td><td bgcolor=\"gray\" align=\"left\">";
+ for (const auto &func : m_overloads)
+ s << 'f' << functionNumber(func) << ' ';
+ s << "</td></tr>";
- // Show default values (original and modified) for various functions
- for (const auto &func : m_overloads) {
- const AbstractMetaArgument *arg = argument(func);
- if (!arg)
- continue;
- QString argDefault = arg->defaultValueExpression();
- if (!argDefault.isEmpty() ||
- argDefault != arg->originalDefaultValueExpression()) {
- s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
- s << "-default</td><td bgcolor=\"gray\" align=\"left\">";
- s << argDefault << "</td></tr>";
- }
- if (argDefault != arg->originalDefaultValueExpression()) {
- s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
- s << "-orig-default</td><td bgcolor=\"gray\" align=\"left\">";
- s << arg->originalDefaultValueExpression() << "</td></tr>";
- }
+ // Show default values (original and modified) for various functions
+ for (const auto &func : m_overloads) {
+ const AbstractMetaArgument *arg = argument(func);
+ if (!arg)
+ continue;
+ QString argDefault = arg->defaultValueExpression();
+ if (!argDefault.isEmpty() ||
+ argDefault != arg->originalDefaultValueExpression()) {
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
+ s << "-default</td><td bgcolor=\"gray\" align=\"left\">";
+ s << argDefault << "</td></tr>";
+ }
+ if (argDefault != arg->originalDefaultValueExpression()) {
+ s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
+ s << "-orig-default</td><td bgcolor=\"gray\" align=\"left\">";
+ s << arg->originalDefaultValueExpression() << "</td></tr>";
}
+ }
- s << "</table>>];\n";
+ s << "</table>>];\n";
- for (const OverloadData *pd : m_nextOverloadData)
- s << " " << argId << " -> " << pd->dumpGraph();
+ for (const auto &pd : m_children) {
+ s << " " << argId << " -> ";
+ pd->dumpNodeGraph(s);
}
- return result;
-}
-
-int OverloadData::functionNumber(const AbstractMetaFunctionCPtr &func) const
-{
- return m_headOverloadData->m_overloads.indexOf(func);
}
-OverloadData::~OverloadData()
+int OverloadDataRootNode::functionNumber(const AbstractMetaFunctionCPtr &func) const
{
- while (!m_nextOverloadData.isEmpty())
- delete m_nextOverloadData.takeLast();
+ return m_overloads.indexOf(func);
}
bool OverloadData::pythonFunctionWrapperUsesListOfArguments() const
@@ -924,16 +942,6 @@ bool OverloadData::pythonFunctionWrapperUsesListOfArguments() const
|| hasArgumentWithDefaultValue();
}
-bool OverloadData::hasArgumentTypeReplace() const
-{
- return !m_argTypeReplaced.isEmpty();
-}
-
-QString OverloadData::argumentTypeReplaced() const
-{
- return m_argTypeReplaced;
-}
-
bool OverloadData::hasArgumentWithDefaultValue() const
{
if (maxArgs() == 0)
@@ -971,9 +979,9 @@ AbstractMetaArgumentList OverloadData::getArgumentsWithDefaultValues(const Abstr
}
#ifndef QT_NO_DEBUG_STREAM
-void OverloadData::formatDebug(QDebug &d) const
+
+void OverloadDataRootNode::formatReferenceFunction(QDebug &d) const
{
- const qsizetype count = m_overloads.size();
auto refFunc = referenceFunction();
d << '"';
if (auto owner = refFunc->ownerClass())
@@ -981,36 +989,73 @@ void OverloadData::formatDebug(QDebug &d) const
d << refFunc->minimalSignature() << '"';
if (m_overloads.constFirst()->isReverseOperator())
d << " [reverseop]";
- d << ", argType=" << m_argType << ", minArgs=" << m_minArgs << ", maxArgs=" << m_maxArgs
- << ", argPos=" << m_argPos;
- if (!m_argTypeReplaced.isEmpty())
- d << ", argTypeReplaced=\"" << m_argTypeReplaced << '"';
+}
+void OverloadDataRootNode::formatOverloads(QDebug &d) const
+{
+ const qsizetype count = m_overloads.size();
+ d << ", overloads[" << count << ']';
if (count < 2)
return;
- d << "\", overloads[" << count << "]=(";
- const int oldVerbosity = d.verbosity();
- d.setVerbosity(3);
- for (int i = 0; i < count; ++i) {
- if (i)
- d << '\n';
- d << m_overloads.at(i).data();
- }
- d.setVerbosity(oldVerbosity);
- d << ')';
+ d << "=(";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << '\n';
+ d << m_overloads.at(i)->signature();
+ }
+ d << ')';
}
-QDebug operator<<(QDebug d, const OverloadData *od)
+void OverloadDataRootNode::formatNextOverloadData(QDebug &d) const
+{
+ const qsizetype count = m_children.size();
+ d << ", next[" << count << ']';
+ if (d.verbosity() >= 3) {
+ d << "=(";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << '\n';
+ m_children.at(i)->formatDebug(d);
+ }
+ d << ')';
+ }
+}
+
+void OverloadDataRootNode::formatDebug(QDebug &d) const
+{
+ formatReferenceFunction(d);
+ formatOverloads(d);
+ formatNextOverloadData(d);
+}
+
+void OverloadDataNode::formatDebug(QDebug &d) const
+{
+ d << "OverloadDataNode(";
+ formatReferenceFunction(d);
+ d << ", argType=" << m_argType << ", argPos=" << m_argPos;
+ if (!m_argTypeReplaced.isEmpty())
+ d << ", argTypeReplaced=\"" << m_argTypeReplaced << '"';
+ formatOverloads(d);
+ formatNextOverloadData(d);
+ d << ')';
+}
+
+void OverloadData::formatDebug(QDebug &d) const
+{
+ d << "OverloadData(";
+ formatReferenceFunction(d);
+ d << ", minArgs=" << m_minArgs << ", maxArgs=" << m_maxArgs;
+ formatOverloads(d);
+ formatNextOverloadData(d);
+ d << ')';
+}
+
+QDebug operator<<(QDebug d, const OverloadData &od)
{
QDebugStateSaver saver(d);
d.noquote();
d.nospace();
- d << "OverloadData(";
- if (od)
- od->formatDebug(d);
- else
- d << '0';
- d << ')';
+ od.formatDebug(d);
return d;
}
#endif // !QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/generator/shiboken/overloaddata.h b/sources/shiboken6/generator/shiboken/overloaddata.h
index d9c5bd24c..fb367b259 100644
--- a/sources/shiboken6/generator/shiboken/overloaddata.h
+++ b/sources/shiboken6/generator/shiboken/overloaddata.h
@@ -33,25 +33,113 @@
#include <QtCore/QBitArray>
#include <QtCore/QList>
+#include <QtCore/QSharedPointer>
QT_FORWARD_DECLARE_CLASS(QDebug)
+QT_FORWARD_DECLARE_CLASS(QTextStream)
-class OverloadData;
-using OverloadDataList = QList<OverloadData *>;
+class OverloadDataNode;
+using OverloadDataNodePtr = QSharedPointer<OverloadDataNode>;
+using OverloadDataList = QList<OverloadDataNodePtr>;
-class OverloadData
+/// The root node of OverloadData. It contains all functions
+class OverloadDataRootNode
{
public:
- OverloadData(const AbstractMetaFunctionCList &overloads,
- const ApiExtractorResult &api);
- ~OverloadData();
+ virtual ~OverloadDataRootNode();
- int minArgs() const { return m_headOverloadData->m_minArgs; }
- int maxArgs() const { return m_headOverloadData->m_maxArgs; }
- int argPos() const { return m_argPos; }
+ OverloadDataRootNode(const OverloadDataRootNode &) = delete;
+ OverloadDataRootNode &operator=(const OverloadDataRootNode &) = delete;
+ OverloadDataRootNode(OverloadDataRootNode &&) = delete;
+ OverloadDataRootNode &operator=(OverloadDataRootNode &&) = delete;
+
+ virtual int argPos() const { return -1; }
+ virtual const OverloadDataRootNode *parent() const { return nullptr; }
+
+ bool isRoot() const { return parent() == nullptr; }
+
+ AbstractMetaFunctionCPtr referenceFunction() const;
+
+ const AbstractMetaFunctionCList &overloads() const { return m_overloads; }
+ const OverloadDataList &children() const { return m_children; }
+
+ bool nextArgumentHasDefaultValue() const;
+
+ /// Returns the function that has a default value at the current OverloadData argument position, otherwise returns null.
+ AbstractMetaFunctionCPtr getFunctionWithDefaultValue() const;
+
+ /// Returns the nearest occurrence, including this instance, of an argument with a default value.
+ const OverloadDataRootNode *findNextArgWithDefault();
+ bool isFinalOccurrence(const AbstractMetaFunctionCPtr &func) const;
+
+ int functionNumber(const AbstractMetaFunctionCPtr &func) const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ virtual void formatDebug(QDebug &d) const;
+#endif
+
+ OverloadDataNode *addOverloadDataNode(const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaArgument &arg);
+
+protected:
+ OverloadDataRootNode(const AbstractMetaFunctionCList &o= {});
+
+ void dumpRootGraph(QTextStream &s, int minArgs, int maxArgs) const;
+ void sortNextOverloads(const ApiExtractorResult &api);
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatReferenceFunction(QDebug &d) const;
+ void formatOverloads(QDebug &d) const;
+ void formatNextOverloadData(QDebug &d) const;
+#endif
+
+ AbstractMetaFunctionCList m_overloads;
+ OverloadDataList m_children;
+};
+
+/// OverloadDataNode references an argument/type combination.
+class OverloadDataNode : public OverloadDataRootNode
+{
+public:
+ explicit OverloadDataNode(const AbstractMetaFunctionCPtr &func,
+ OverloadDataRootNode *parent,
+ const AbstractMetaType &argType, int argPos,
+ const QString argTypeReplaced = {});
+ void addOverload(const AbstractMetaFunctionCPtr &func);
+
+ int argPos() const override { return m_argPos; }
+ const OverloadDataRootNode *parent() const override;
+ void dumpNodeGraph(QTextStream &s) const;
const AbstractMetaType &argType() const { return m_argType; }
+ bool hasArgumentTypeReplace() const { return !m_argTypeReplaced.isEmpty(); }
+ const QString &argumentTypeReplaced() const { return m_argTypeReplaced; }
+
+ const AbstractMetaArgument *argument(const AbstractMetaFunctionCPtr &func) const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ AbstractMetaType m_argType;
+ QString m_argTypeReplaced;
+ OverloadDataRootNode *m_parent = nullptr;
+
+ int m_argPos = -1;
+};
+
+class OverloadData : public OverloadDataRootNode
+{
+public:
+ explicit OverloadData(const AbstractMetaFunctionCList &overloads,
+ const ApiExtractorResult &api);
+
+ int minArgs() const { return m_minArgs; }
+ int maxArgs() const { return m_maxArgs; }
+
/// Returns true if any of the overloads for the current OverloadData has a return type different from void.
bool hasNonVoidReturnType() const;
@@ -82,27 +170,6 @@ public:
/// Returns true if among the overloads passed as argument there are static and non-static methods altogether.
static bool hasStaticAndInstanceFunctions(const AbstractMetaFunctionCList &overloads);
- AbstractMetaFunctionCPtr referenceFunction() const;
- const AbstractMetaArgument *argument(const AbstractMetaFunctionCPtr &func) const;
- OverloadDataList overloadDataOnPosition(int argPos) const;
-
- bool isHeadOverloadData() const { return this == m_headOverloadData; }
-
- /// Returns the root OverloadData object that represents all the overloads.
- OverloadData *headOverloadData() const { return m_headOverloadData; }
-
- /// Returns the function that has a default value at the current OverloadData argument position, otherwise returns null.
- AbstractMetaFunctionCPtr getFunctionWithDefaultValue() const;
-
- bool nextArgumentHasDefaultValue() const;
- /// Returns the nearest occurrence, including this instance, of an argument with a default value.
- OverloadData *findNextArgWithDefault();
- bool isFinalOccurrence(const AbstractMetaFunctionCPtr &func) const;
-
- const AbstractMetaFunctionCList &overloads() const { return m_overloads; }
- OverloadDataList nextOverloadData() const { return m_nextOverloadData; }
- OverloadData *previousOverloadData() const { return m_previousOverloadData; }
-
QList<int> invalidArgumentLengths() const;
static int numberOfRemovedArguments(const AbstractMetaFunctionCPtr &func);
@@ -116,9 +183,6 @@ public:
/// Returns true if a list of arguments is used (METH_VARARGS)
bool pythonFunctionWrapperUsesListOfArguments() const;
- bool hasArgumentTypeReplace() const;
- QString argumentTypeReplaced() const;
-
bool hasArgumentWithDefaultValue() const;
static bool hasArgumentWithDefaultValue(const AbstractMetaFunctionCPtr &func);
@@ -126,37 +190,16 @@ public:
static AbstractMetaArgumentList getArgumentsWithDefaultValues(const AbstractMetaFunctionCPtr &func);
#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &) const;
+ void formatDebug(QDebug &) const override;
#endif
private:
- OverloadData(OverloadData *headOverloadData, const AbstractMetaFunctionCPtr &func,
- const AbstractMetaType &argType, int argPos,
- const ApiExtractorResult &api);
-
- void addOverload(const AbstractMetaFunctionCPtr &func);
- OverloadData *addOverloadData(const AbstractMetaFunctionCPtr &func, const AbstractMetaArgument &arg);
-
- void sortNextOverloads();
- bool sortByOverloadNumberModification();
-
- int functionNumber(const AbstractMetaFunctionCPtr &func) const;
-
- AbstractMetaType m_argType;
- QString m_argTypeReplaced;
- AbstractMetaFunctionCList m_overloads;
-
- OverloadData *m_headOverloadData = nullptr;
- OverloadDataList m_nextOverloadData;
- OverloadData *m_previousOverloadData = nullptr;
- const ApiExtractorResult m_api;
int m_minArgs = 256;
int m_maxArgs = 0;
- int m_argPos = -1;
};
#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug, const OverloadData *);
+QDebug operator<<(QDebug, const OverloadData &);
#endif
#endif // OVERLOADDATA_H