aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/modifications.cpp
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 /sources/shiboken6/ApiExtractor/modifications.cpp
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>
Diffstat (limited to 'sources/shiboken6/ApiExtractor/modifications.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.cpp179
1 files changed, 53 insertions, 126 deletions
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);