aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-11-06 09:59:29 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-11-09 15:49:23 +0000
commit4ea3fcec20fdd80ae71cd69039e0ecae0a40653e (patch)
treea2364d5452dd232fce7361d4522b5fe2c38cfcc5
parent3428efa5f69d321bcacdd106b0e724ab99bb63ed (diff)
shiboken6: Replace AddedFunction::TypeInfo by TypeInfo
AddedFunction::TypeInfo was a stripped-down version of the code model's TypeInfo with its own, simplified parser. Replacing it by TypeInfo allows for removing the parser code and the entire AbstractMetaBuilderPrivate::translateType(AddedFunction::TypeInfo) branch. The more powerful TypeParser from the code model can then be used, allowing for more complex types in <add-function> or <declare-function>. As a drive by, replace the AddedFunction constructor by a static factory function, allowing to pass up parse errors. Change-Id: I33ad19e9b5ed30bd27898afe771401ddc98c8c73 Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp123
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h3
-rw-r--r--sources/shiboken6/ApiExtractor/messages.cpp11
-rw-r--r--sources/shiboken6/ApiExtractor/messages.h4
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.cpp179
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp107
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp9
8 files changed, 153 insertions, 315 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index b4787ec9c..f7c7f1292 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -65,55 +65,6 @@ static QString stripTemplateArgs(const QString &name)
return pos < 0 ? name : name.left(pos);
}
-static QStringList parseTemplateType(const QString &name) {
- int n = name.indexOf(QLatin1Char('<'));
- if (n <= 0) {
- // If name starts with '<' or contains an unmatched (i.e. any) '>', we
- // reject it
- if (n == 0 || name.count(QLatin1Char('>')))
- return QStringList();
- // Doesn't look like a template instantiation; just return the name
- return QStringList() << name;
- }
-
- // Split the type name into the template name and template arguments; the
- // part before the opening '<' is the template name
- //
- // Example:
- // "foo<A, bar<B, C>, D>" -> ( "foo", "A", "bar<B, C>", "D" )
- QStringList result;
- result << name.left(n).trimmed();
-
- // Extract template arguments
- int i, depth = 1;
- const int l = name.length();
- for (i = n + 1; i < l; ++i) {
- // Consume balanced '<'/'>' within a single argument so that we won't
- // split on ',' as part of a single argument which is itself a
- // multi-argument template type
- if (name[i] == QLatin1Char('<')) {
- ++depth;
- } else if (name[i] == QLatin1Char('>')) {
- if (--depth == 0)
- break;
- } else if (name[i] == QLatin1Char(',') && depth == 1) {
- // Encountered ',' in template argument list that is not within
- // another template name; add current argument to result and start
- // working on the next argument
- result << name.mid(n + 1, i - n - 1).trimmed();
- n = i;
- }
- }
- if (i >= l) // arg list not closed
- return QStringList();
- if (i + 1 < l) // arg list closed before end of name
- return QStringList();
-
- // Add final argument and return result
- result << name.mid(n + 1, i - n - 1).trimmed();
- return result;
-}
-
AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() :
m_logDirectory(QLatin1String(".") + QDir::separator())
{
@@ -1535,11 +1486,11 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
{
QString errorMessage;
- AbstractMetaType returnType = translateType(addedFunc->returnType(), metaClass, &errorMessage);
+ AbstractMetaType returnType = translateType(addedFunc->returnType(), metaClass, {}, &errorMessage);
if (!returnType) {
qCWarning(lcShiboken, "%s",
qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(),
- addedFunc->returnType().name,
+ addedFunc->returnType().qualifiedName(),
errorMessage,
metaClass)));
return nullptr;
@@ -1552,11 +1503,11 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
for (int i = 0; i < args.count(); ++i) {
const AddedFunction::Argument &arg = args.at(i);
- AbstractMetaType type = translateType(arg.typeInfo, metaClass, &errorMessage);
+ AbstractMetaType type = translateType(arg.typeInfo, metaClass, {}, &errorMessage);
if (Q_UNLIKELY(!type)) {
qCWarning(lcShiboken, "%s",
qPrintable(msgAddedFunctionInvalidArgType(addedFunc->name(),
- arg.typeInfo.name, i + 1,
+ arg.typeInfo.qualifiedName(), i + 1,
errorMessage,
metaClass)));
delete metaFunction;
@@ -1984,72 +1935,6 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return metaFunction;
}
-AbstractMetaType AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo,
- AbstractMetaClass *currentClass,
- QString *errorMessage)
-{
- Q_ASSERT(!typeInfo.name.isEmpty());
- TypeDatabase* typeDb = TypeDatabase::instance();
-
- QString typeName = typeInfo.name;
-
- if (typeName == QLatin1String("void"))
- return AbstractMetaType::createVoid();
-
- const TypeEntry *type = nullptr;
- // test if the type is a template, like a container
- QStringList templateArgs;
- if (!typeInfo.name.startsWith(QLatin1String("QFlags<"))
- && typeInfo.name.contains(QLatin1Char('<'))) {
- QStringList parsedType = parseTemplateType(typeInfo.name);
- if (parsedType.isEmpty()) {
- *errorMessage = QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name);
- return {};
- }
- const QString name = parsedType.takeFirst();
- templateArgs = parsedType;
- type = typeDb->findContainerType(name);
- if (!type) { // A template typedef?
- if (auto candidate = typeDb->findType(name)) {
- if (candidate->type() == TypeEntry::ObjectType || candidate->type() == TypeEntry::BasicValueType)
- type = candidate;
- }
- }
- }
-
- if (type == nullptr) {
- QString unqualifiedName = typeName;
- const int last = unqualifiedName.lastIndexOf(colonColon());
- if (last != -1)
- unqualifiedName.remove(0, last + 2);
- auto types = findTypeEntries(typeName, unqualifiedName, currentClass, this, errorMessage);
- if (types.isEmpty())
- return {};
- type = types.constFirst();
- }
-
- // These are only implicit and should not appear in code...
- AbstractMetaType metaType(type);
- metaType.setIndirections(typeInfo.indirections);
- if (typeInfo.isReference)
- metaType.setReferenceType(LValueReference);
- metaType.setConstant(typeInfo.isConstant);
- if (!templateArgs.isEmpty()) {
- for (const QString& templateArg : qAsConst(templateArgs)) {
- AbstractMetaType metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg),
- currentClass, errorMessage);
- if (!metaArgType)
- return {};
- metaType.addInstantiation(metaArgType);
- }
- metaType.setTypeUsagePattern(AbstractMetaType::ContainerPattern);
- } else {
- metaType.decideUsagePattern();
- }
-
- return metaType;
-}
-
static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaClass, const QString& qualifiedName)
{
const TypeEntry* type = nullptr;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
index 5b5f3e505..7792eb0fc 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
@@ -143,9 +143,6 @@ public:
QString fixDefaultValue(const ArgumentModelItem &item, const AbstractMetaType &type,
AbstractMetaFunction *fnc, AbstractMetaClass *,
int argumentIndex);
- AbstractMetaType translateType(const AddedFunction::TypeInfo &typeInfo,
- AbstractMetaClass *currentClass,
- QString *errorMessage);
AbstractMetaType translateType(const TypeInfo &type,
AbstractMetaClass *currentClass,
TranslateTypeFlags flags = {},
diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp
index 65012893a..aca801d53 100644
--- a/sources/shiboken6/ApiExtractor/messages.cpp
+++ b/sources/shiboken6/ApiExtractor/messages.cpp
@@ -114,7 +114,7 @@ static void msgFormatEnumType(Stream &str,
}
QString msgAddedFunctionInvalidArgType(const QString &addedFuncName,
- const QString &typeName,
+ const QStringList &typeName,
int pos, const QString &why,
const AbstractMetaClass *context)
{
@@ -122,20 +122,21 @@ QString msgAddedFunctionInvalidArgType(const QString &addedFuncName,
QTextStream str(&result);
if (context)
str << context->typeEntry()->sourceLocation();
- str << "Unable to translate type \"" << typeName << "\" of argument "
- << pos << " of added function \"" << addedFuncName << "\": " << why;
+ str << "Unable to translate type \"" << typeName.join(colonColon())
+ << "\" of argument " << pos << " of added function \""
+ << addedFuncName << "\": " << why;
return result;
}
QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName,
- const QString &typeName, const QString &why,
+ const QStringList &typeName, const QString &why,
const AbstractMetaClass *context)
{
QString result;
QTextStream str(&result);
if (context)
str << context->typeEntry()->sourceLocation();
- str << "Unable to translate return type \"" << typeName
+ str << "Unable to translate return type \"" << typeName.join(colonColon())
<< "\" of added function \"" << addedFuncName << "\": "
<< why;
return result;
diff --git a/sources/shiboken6/ApiExtractor/messages.h b/sources/shiboken6/ApiExtractor/messages.h
index 1e58a7fad..8292e491e 100644
--- a/sources/shiboken6/ApiExtractor/messages.h
+++ b/sources/shiboken6/ApiExtractor/messages.h
@@ -48,12 +48,12 @@ QT_FORWARD_DECLARE_CLASS(QFile)
QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)
QString msgAddedFunctionInvalidArgType(const QString &addedFuncName,
- const QString &typeName,
+ const QStringList &typeName,
int pos, const QString &why,
const AbstractMetaClass *context = nullptr);
QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName,
- const QString &typeName, const QString &why,
+ const QStringList &typeName, const QString &why,
const AbstractMetaClass *context = nullptr);
QString msgNoFunctionForModification(const AbstractMetaClass *klass,
diff --git a/sources/shiboken6/ApiExtractor/modifications.cpp b/sources/shiboken6/ApiExtractor/modifications.cpp
index a370a2e03..3f8b1e71f 100644
--- a/sources/shiboken6/ApiExtractor/modifications.cpp
+++ b/sources/shiboken6/ApiExtractor/modifications.cpp
@@ -29,6 +29,7 @@
#include "modifications.h"
#include "modifications_p.h"
#include "typedatabase.h"
+#include "typeparser.h"
#include "typesystem.h"
#include <QtCore/QDebug>
@@ -284,127 +285,70 @@ Arguments splitParameters(QStringView paramString, QString *errorMessage)
} // namespace AddedFunctionParser
-// ---------------------- AddedFunction
+AddedFunction::AddedFunction(const QString &name, const QList<Argument> &arguments,
+ const TypeInfo &returnType) :
+ m_name(name),
+ m_arguments(arguments),
+ m_returnType(returnType)
+{
+}
+
+AddedFunction::AddedFunctionPtr
+ AddedFunction::createAddedFunction(const QString &signatureIn, const QString &returnTypeIn,
+ QString *errorMessage)
-static AddedFunction::TypeInfo parseType(const QString& signature,
- int startPos = 0, int *endPos = nullptr,
- QString *argumentName = nullptr,
- QString *defaultValue = nullptr)
{
- AddedFunction::TypeInfo result;
- static const QRegularExpression regex(QLatin1String("\\w"));
- Q_ASSERT(regex.isValid());
- int length = signature.length();
- int start = signature.indexOf(regex, startPos);
- if (start == -1) {
- if (QStringView{signature}.mid(startPos + 1, 3) == QLatin1String("...")) { // varargs
- if (endPos)
- *endPos = startPos + 4;
- result.name = QLatin1String("...");
- } else { // error
- if (endPos)
- *endPos = length;
- }
- return result;
- }
+ errorMessage->clear();
- int cantStop = 0;
- QString paramString;
- QChar c;
- int i = start;
- for (; i < length; ++i) {
- c = signature[i];
- if (c == QLatin1Char('<'))
- cantStop++;
- if (c == QLatin1Char('>'))
- cantStop--;
- if (cantStop < 0)
- break; // FIXME: report error?
- if ((c == QLatin1Char(')') || c == QLatin1Char(',')) && !cantStop)
- break;
- paramString += signature[i];
- }
- if (endPos)
- *endPos = i;
-
- // Check default value
- if (paramString.contains(QLatin1Char('='))) {
- QStringList lst = paramString.split(QLatin1Char('='));
- paramString = lst[0].trimmed();
- if (defaultValue != nullptr)
- *defaultValue = lst[1].trimmed();
- }
+ QList<Argument> arguments;
+ const TypeInfo returnType = returnTypeIn.isEmpty()
+ ? TypeInfo::voidType()
+ : TypeParser::parse(returnTypeIn, errorMessage);
+ if (!errorMessage->isEmpty())
+ return {};
- // check constness
- if (paramString.startsWith(QLatin1String("const "))) {
- result.isConstant = true;
- paramString.remove(0, sizeof("const")/sizeof(char));
- paramString = paramString.trimmed();
- }
+ QStringView signature = QStringView{signatureIn}.trimmed();
- // Extract argument name from "T<bla,blub>* @foo@"
- const int nameStartPos = paramString.indexOf(QLatin1Char('@'));
- if (nameStartPos != -1) {
- const int nameEndPos = paramString.indexOf(QLatin1Char('@'), nameStartPos + 1);
- if (nameEndPos > nameStartPos) {
- if (argumentName)
- *argumentName = paramString.mid(nameStartPos + 1, nameEndPos - nameStartPos - 1);
- paramString.remove(nameStartPos, nameEndPos - nameStartPos + 1);
- paramString = paramString.trimmed();
- }
+ // Skip past "operator()(...)"
+ const int parenSearchStartPos = signature.startsWith(callOperator())
+ ? callOperator().size() : 0;
+ const int openParenPos = signature.indexOf(QLatin1Char('('), parenSearchStartPos);
+ if (openParenPos < 0) {
+ return AddedFunctionPtr(new AddedFunction(signature.toString(),
+ arguments, returnType));
}
- // check reference
- if (paramString.endsWith(QLatin1Char('&'))) {
- result.isReference = true;
- paramString.chop(1);
- paramString = paramString.trimmed();
+ const QString name = signature.left(openParenPos).trimmed().toString();
+ const int closingParenPos = signature.lastIndexOf(QLatin1Char(')'));
+ if (closingParenPos < 0) {
+ *errorMessage = QLatin1String("Missing closing parenthesis");
+ return {};
}
- // check Indirections
- while (paramString.endsWith(QLatin1Char('*'))) {
- result.indirections++;
- paramString.chop(1);
- paramString = paramString.trimmed();
- }
- result.name = paramString;
- return result;
-}
+ // Check for "foo() const"
+ bool isConst = false;
+ const int signatureLength = signature.length();
+ const int qualifierLength = signatureLength - closingParenPos - 1;
+ if (qualifierLength >= 5
+ && signature.right(qualifierLength).contains(QLatin1String("const"))) {
+ isConst = true;
+ }
-AddedFunction::AddedFunction(QString signature, const QString &returnType) :
- m_access(Public)
-{
- Q_ASSERT(!returnType.isEmpty());
- m_returnType = parseType(returnType);
- signature = signature.trimmed();
- // Skip past "operator()(...)"
- const int parenStartPos = signature.startsWith(callOperator())
- ? callOperator().size() : 0;
- int endPos = signature.indexOf(QLatin1Char('('), parenStartPos);
- if (endPos < 0) {
- m_isConst = false;
- m_name = signature;
- } else {
- m_name = signature.left(endPos).trimmed();
- int signatureLength = signature.length();
- while (endPos < signatureLength) {
- QString argumentName;
- QString defaultValue;
- TypeInfo arg = parseType(signature, endPos, &endPos, &argumentName, &defaultValue);
- if (!arg.name.isEmpty())
- m_arguments.append({arg, argumentName, defaultValue});
- // end of parameters...
- if (endPos >= signatureLength || signature[endPos] == QLatin1Char(')'))
- break;
- }
- // is const?
- m_isConst = QStringView{signature}.right(signatureLength - endPos).contains(QLatin1String("const"));
+ const auto paramString = signature.mid(openParenPos + 1, closingParenPos - openParenPos - 1);
+ const auto params = AddedFunctionParser::splitParameters(paramString, errorMessage);
+ if (params.isEmpty() && !errorMessage->isEmpty())
+ return {};
+ for (const auto &p : params) {
+ TypeInfo type = p.type == QLatin1String("...")
+ ? TypeInfo::varArgsType() : TypeParser::parse(p.type, errorMessage);
+ if (!errorMessage->isEmpty())
+ return {};
+ arguments.append({type, p.name, p.defaultValue});
}
-}
-AddedFunction::TypeInfo AddedFunction::TypeInfo::fromSignature(const QString& signature)
-{
- return parseType(signature);
+ AddedFunctionPtr result(new AddedFunction(name, arguments, returnType));
+ result->setConstant(isConst);
+ return result;
}
void DocModification::setCode(const QString &code)
@@ -529,23 +473,6 @@ QDebug operator<<(QDebug d, const FunctionModification &fm)
return d;
}
-QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "TypeInfo(";
- if (ti.isConstant)
- d << "const";
- if (ti.indirections)
- d << QByteArray(ti.indirections, '*');
- if (ti.isReference)
- d << " &";
- d << ti.name;
- d << ')';
- return d;
-}
-
QDebug operator<<(QDebug d, const AddedFunction::Argument &a)
{
QDebugStateSaver saver(d);
diff --git a/sources/shiboken6/ApiExtractor/modifications.h b/sources/shiboken6/ApiExtractor/modifications.h
index 3371f51ee..ecb464773 100644
--- a/sources/shiboken6/ApiExtractor/modifications.h
+++ b/sources/shiboken6/ApiExtractor/modifications.h
@@ -31,10 +31,12 @@
#include "typesystem_enums.h"
#include "typesystem_typedefs.h"
+#include "parser/typeinfo.h"
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QRegularExpression>
+#include <QtCore/QSharedPointer>
#include <QtCore/QString>
QT_BEGIN_NAMESPACE
@@ -393,6 +395,8 @@ struct FieldModification: public Modification
*/
struct AddedFunction
{
+ using AddedFunctionPtr = QSharedPointer<AddedFunction>;
+
/// Function access types.
enum Access {
InvalidAccess = 0,
@@ -400,22 +404,6 @@ struct AddedFunction
Public = 0x2
};
- /**
- * \internal
- * Internal struct used to store information about arguments and return type of the
- * functions added by the type system. This information is later used to create
- * AbstractMetaType and AbstractMetaArgument for the AbstractMetaFunctions.
- */
- struct TypeInfo {
- TypeInfo() = default;
- static TypeInfo fromSignature(const QString& signature);
-
- QString name;
- int indirections = 0;
- bool isConstant = false;
- bool isReference = false;
- };
-
struct Argument
{
TypeInfo typeInfo;
@@ -424,7 +412,13 @@ struct AddedFunction
};
/// Creates a new AddedFunction with a signature and a return type.
- explicit AddedFunction(QString signature, const QString &returnType);
+ explicit AddedFunction(const QString &name, const QList<Argument> &arguments,
+ const TypeInfo &returnType);
+
+ static AddedFunctionPtr createAddedFunction(const QString &signatureIn,
+ const QString &returnTypeIn,
+ QString *errorMessage);
+
AddedFunction() = default;
/// Returns the function name.
@@ -462,6 +456,7 @@ struct AddedFunction
{
return m_isConst;
}
+ void setConstant(bool c) { m_isConst = c; };
/// Set this method static.
void setStatic(bool value)
@@ -484,14 +479,13 @@ private:
QString m_name;
QList<Argument> m_arguments;
TypeInfo m_returnType;
- Access m_access = Protected;
+ Access m_access = Public;
bool m_isConst = false;
bool m_isStatic = false;
bool m_isDeclaration = false;
};
#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti);
QDebug operator<<(QDebug d, const AddedFunction::Argument &a);
QDebug operator<<(QDebug d, const AddedFunction &af);
#endif
diff --git a/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
index ca10cbfc6..20ca3ae6f 100644
--- a/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
@@ -38,41 +38,64 @@ void TestAddFunction::testParsingFuncNameAndConstness()
{
// generic test...
const char sig1[] = "func(type1, const type2, const type3* const)";
- AddedFunction f1(QLatin1String(sig1), QLatin1String("void"));
- QCOMPARE(f1.name(), QLatin1String("func"));
- QCOMPARE(f1.arguments().count(), 3);
- AddedFunction::TypeInfo retval = f1.returnType();
- QCOMPARE(retval.name, QLatin1String("void"));
- QCOMPARE(retval.indirections, 0);
- QCOMPARE(retval.isConstant, false);
- QCOMPARE(retval.isReference, false);
+ QString errorMessage;
+ auto f1 = AddedFunction::createAddedFunction(QLatin1String(sig1), QLatin1String("void"),
+ &errorMessage);
+ QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
+ QCOMPARE(f1->name(), QLatin1String("func"));
+ QCOMPARE(f1->arguments().count(), 3);
+ TypeInfo retval = f1->returnType();
+ QCOMPARE(retval.qualifiedName(), QStringList{QLatin1String("void")});
+ QCOMPARE(retval.indirections(), 0);
+ QCOMPARE(retval.isConstant(), false);
+ QCOMPARE(retval.referenceType(), NoReference);
// test with a ugly template as argument and other ugly stuff
const char sig2[] = " _fu__nc_ ( type1, const type2, const Abc<int& , C<char*> * > * *@my_name@, const type3* const ) const ";
- AddedFunction f2(QLatin1String(sig2), QLatin1String("const Abc<int& , C<char*> * > * *"));
- QCOMPARE(f2.name(), QLatin1String("_fu__nc_"));
- const auto &args = f2.arguments();
+ auto f2 = AddedFunction::createAddedFunction(QLatin1String(sig2),
+ QLatin1String("const Abc<int& , C<char*> * > * *"),
+ &errorMessage);
+ QVERIFY2(!f2.isNull(), qPrintable(errorMessage));
+ QCOMPARE(f2->name(), QLatin1String("_fu__nc_"));
+ const auto &args = f2->arguments();
QCOMPARE(args.count(), 4);
- retval = f2.returnType();
- QCOMPARE(retval.name, QLatin1String("Abc<int& , C<char*> * >"));
- QCOMPARE(retval.indirections, 2);
- QCOMPARE(retval.isConstant, true);
- QCOMPARE(retval.isReference, false);
- retval = args.at(2).typeInfo;
+ retval = f2->returnType();
+ QCOMPARE(retval.qualifiedName(), QStringList{QLatin1String("Abc")});
+ QCOMPARE(retval.instantiations().size(), 2);
+ QCOMPARE(retval.toString(), QLatin1String("const Abc<int&, C<char*>*>**"));
+ QCOMPARE(retval.indirections(), 2);
+ QCOMPARE(retval.isConstant(), true);
+ QCOMPARE(retval.referenceType(), NoReference);
QVERIFY(args.at(0).name.isEmpty());
QVERIFY(args.at(1).name.isEmpty());
+
QCOMPARE(args.at(2).name, QLatin1String("my_name"));
+ auto arg2Type = args.at(2).typeInfo;
+ QCOMPARE(arg2Type.qualifiedName(), QStringList{QLatin1String("Abc")});
+ QCOMPARE(arg2Type.instantiations().size(), 2);
+ QCOMPARE(arg2Type.toString(), QLatin1String("const Abc<int&, C<char*>*>**"));
+ QCOMPARE(arg2Type.indirections(), 2);
+ QCOMPARE(arg2Type.isConstant(), true);
+ QCOMPARE(arg2Type.referenceType(), NoReference);
+
QVERIFY(args.at(3).name.isEmpty());
- QCOMPARE(retval.name, QLatin1String("Abc<int& , C<char*> * >"));
- QCOMPARE(retval.indirections, 2);
- QCOMPARE(retval.isConstant, true);
- QCOMPARE(retval.isReference, false);
// function with no args.
const char sig3[] = "func()";
- AddedFunction f3(QLatin1String(sig3), QLatin1String("void"));
- QCOMPARE(f3.name(), QLatin1String("func"));
- QCOMPARE(f3.arguments().count(), 0);
+ auto f3 = AddedFunction::createAddedFunction(QLatin1String(sig3), QLatin1String("void"),
+ &errorMessage);
+ QVERIFY2(!f3.isNull(), qPrintable(errorMessage));
+ QCOMPARE(f3->name(), QLatin1String("func"));
+ QCOMPARE(f3->arguments().count(), 0);
+
+ // const call operator
+ const char sig4[] = "operator()(int)const";
+ auto f4 = AddedFunction::createAddedFunction(QLatin1String(sig4), QLatin1String("int"),
+ &errorMessage);
+ QVERIFY2(!f4.isNull(), qPrintable(errorMessage));
+ QCOMPARE(f4->name(), QLatin1String("operator()"));
+ QCOMPARE(f4->arguments().count(), 1);
+ QVERIFY(f4->isConstant());
}
void TestAddFunction::testAddFunction()
@@ -196,11 +219,13 @@ void TestAddFunction::testAddFunctionCodeSnippets()
void TestAddFunction::testAddFunctionWithoutParenteses()
{
const char sig1[] = "func";
- AddedFunction f1(QLatin1String(sig1), QLatin1String("void"));
-
- QCOMPARE(f1.name(), QLatin1String("func"));
- QCOMPARE(f1.arguments().count(), 0);
- QCOMPARE(f1.isConstant(), false);
+ QString errorMessage;
+ auto f1 = AddedFunction::createAddedFunction(QLatin1String(sig1), QLatin1String("void"),
+ &errorMessage);
+ QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
+ QCOMPARE(f1->name(), QLatin1String("func"));
+ QCOMPARE(f1->arguments().count(), 0);
+ QCOMPARE(f1->isConstant(), false);
const char cppCode[] = "struct A {};\n";
const char xmlCode[] = "\
@@ -226,11 +251,13 @@ void TestAddFunction::testAddFunctionWithoutParenteses()
void TestAddFunction::testAddFunctionWithDefaultArgs()
{
const char sig1[] = "func";
- AddedFunction f1(QLatin1String(sig1), QLatin1String("void"));
-
- QCOMPARE(f1.name(), QLatin1String("func"));
- QCOMPARE(f1.arguments().count(), 0);
- QCOMPARE(f1.isConstant(), false);
+ QString errorMessage;
+ auto f1 = AddedFunction::createAddedFunction(QLatin1String(sig1), QLatin1String("void"),
+ &errorMessage);
+ QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
+ QCOMPARE(f1->name(), QLatin1String("func"));
+ QCOMPARE(f1->arguments().count(), 0);
+ QCOMPARE(f1->isConstant(), false);
const char cppCode[] = "struct A { };\n";
const char xmlCode[] = "\
@@ -291,11 +318,13 @@ void TestAddFunction::testAddFunctionAtModuleLevel()
void TestAddFunction::testAddFunctionWithVarargs()
{
const char sig1[] = "func(int,char,...)";
- AddedFunction f1( QLatin1String(sig1), QLatin1String("void"));
-
- QCOMPARE(f1.name(), QLatin1String("func"));
- QCOMPARE(f1.arguments().count(), 3);
- QVERIFY(!f1.isConstant());
+ QString errorMessage;
+ auto f1 = AddedFunction::createAddedFunction(QLatin1String(sig1), QLatin1String("void"),
+ &errorMessage);
+ QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
+ QCOMPARE(f1->name(), QLatin1String("func"));
+ QCOMPARE(f1->arguments().count(), 3);
+ QVERIFY(!f1->isConstant());
const char cppCode[] = "struct A {};\n";
const char xmlCode[] = "\
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index 19f968d87..bb0cffdc0 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -2233,7 +2233,7 @@ bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &,
return false;
}
QString originalSignature;
- QString returnType = QLatin1String("void");
+ QString returnType;
bool staticFunction = false;
QString access;
int overloadNumber = TypeSystem::OverloadNumberUnset;
@@ -2266,7 +2266,12 @@ bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &,
return false;
}
- AddedFunctionPtr func(new AddedFunction(signature, returnType));
+ AddedFunctionPtr func = AddedFunction::createAddedFunction(signature, returnType, &errorString);
+ if (func.isNull()) {
+ m_error = errorString;
+ return false;
+ }
+
func->setStatic(staticFunction);
if (!signature.contains(QLatin1Char('(')))
signature += QLatin1String("()");