aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-10-29 16:23:52 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-10-30 13:04:23 +0000
commit021f8974a1784b37baaec4cfd1285dc44dfdab83 (patch)
treea4eba8de1a8180e958707c4791c547d965b40d44 /sources
parenta069b70ed6f1761e7d3efb96c9527614019b5561 (diff)
shiboken6: Consolidate argument type parsing of added functions
Use the same functionality that is used for argument type parsing of functions from the code model, which has a more powerful type search. This will for example enable specifying class template arguments (like QList::append(T)). Move the error handling from translateTypeStatic(TypeInfo,...) to the findTypeEntries() function, extracting a helper for the search, and use this in translateType(AddedFunction::TypeInfo,...). Task-number: PYSIDE-904 Task-number: PYSIDE-1339 Change-Id: I34428d76e811c3b1444a4d2ded0606e67c4dcf57 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources')
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp128
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h7
2 files changed, 73 insertions, 62 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index b6e68bfde..3bcc35048 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -1532,7 +1532,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
{
QString errorMessage;
- AbstractMetaType returnType = translateType(addedFunc->returnType(), &errorMessage);
+ AbstractMetaType returnType = translateType(addedFunc->returnType(), metaClass, &errorMessage);
if (!returnType) {
qCWarning(lcShiboken, "%s",
qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(),
@@ -1549,7 +1549,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
for (int i = 0; i < args.count(); ++i) {
const AddedFunction::TypeInfo& typeInfo = args.at(i).typeInfo;
- AbstractMetaType type = translateType(typeInfo, &errorMessage);
+ AbstractMetaType type = translateType(typeInfo, metaClass, &errorMessage);
if (Q_UNLIKELY(!type)) {
qCWarning(lcShiboken, "%s",
qPrintable(msgAddedFunctionInvalidArgType(addedFunc->name(),
@@ -1982,7 +1982,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
}
AbstractMetaType AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo,
- QString *errorMessage)
+ AbstractMetaClass *currentClass,
+ QString *errorMessage)
{
Q_ASSERT(!typeInfo.name.isEmpty());
TypeDatabase* typeDb = TypeDatabase::instance();
@@ -1992,14 +1993,11 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateType(const AddedFunction::
if (typeName == QLatin1String("void"))
return AbstractMetaType::createVoid();
- TypeEntry *type = typeDb->findType(typeName);
- if (!type)
- type = typeDb->findFlagsType(typeName);
-
+ const TypeEntry *type = nullptr;
// test if the type is a template, like a container
- bool isTemplate = false;
QStringList templateArgs;
- if (!type && typeInfo.name.contains(QLatin1Char('<'))) {
+ 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);
@@ -2014,29 +2012,17 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateType(const AddedFunction::
type = candidate;
}
}
- isTemplate = type != nullptr;
}
- if (!type) {
- QStringList candidates;
- const auto &entries = typeDb->entries();
- for (auto it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
- // Let's try to find the type in different scopes.
- if (it.key().endsWith(colonColon() + typeName))
- candidates.append(it.key());
- }
- QTextStream str(errorMessage);
- str << "Type '" << typeName << "' wasn't found in the type database.\n";
-
- if (candidates.isEmpty()) {
- str << "Declare it in the type system using the proper <*-type> tag.";
- } else {
- str << "Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n";
- candidates.sort();
- for (const QString& candidate : qAsConst(candidates))
- str << " " << candidate << '\n';
- }
- return {};
+ 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...
@@ -2045,9 +2031,10 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateType(const AddedFunction::
if (typeInfo.isReference)
metaType.setReferenceType(LValueReference);
metaType.setConstant(typeInfo.isConstant);
- if (isTemplate) {
+ if (!templateArgs.isEmpty()) {
for (const QString& templateArg : qAsConst(templateArgs)) {
- AbstractMetaType metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage);
+ AbstractMetaType metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg),
+ currentClass, errorMessage);
if (!metaArgType)
return {};
metaType.addInstantiation(metaArgType);
@@ -2071,11 +2058,11 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
return type;
}
-// Helper for translateTypeStatic()
-TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName,
- const QString &name,
- AbstractMetaClass *currentClass,
- AbstractMetaBuilderPrivate *d)
+// Helper for findTypeEntries/translateTypeStatic()
+TypeEntries AbstractMetaBuilderPrivate::findTypeEntriesHelper(const QString &qualifiedName,
+ const QString &name,
+ AbstractMetaClass *currentClass,
+ AbstractMetaBuilderPrivate *d)
{
// 5.1 - Try first using the current scope
if (currentClass) {
@@ -2117,6 +2104,46 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualified
return {};
}
+// Helper for translateTypeStatic() that calls findTypeEntriesHelper()
+// and does some error checking.
+TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName,
+ const QString &name,
+ AbstractMetaClass *currentClass,
+ AbstractMetaBuilderPrivate *d,
+ QString *errorMessage)
+{
+ const TypeEntries types = findTypeEntriesHelper(qualifiedName, name, currentClass, d);
+ if (types.isEmpty()) {
+ if (errorMessage != nullptr)
+ *errorMessage = msgCannotFindTypeEntry(qualifiedName);
+ return {};
+ }
+
+ if (types.size() == 1)
+ return types;
+
+ const auto typeEntryType = types.constFirst()->type();
+ const bool sameType = std::all_of(types.cbegin() + 1, types.cend(),
+ [typeEntryType](const TypeEntry *e) {
+ return e->type() == typeEntryType;
+ });
+
+ if (!sameType) {
+ if (errorMessage != nullptr)
+ *errorMessage = msgAmbiguousVaryingTypesFound(qualifiedName, types);
+ return {};
+ }
+ // Ambiguous primitive/smart pointer types are possible (when
+ // including type systems).
+ if (typeEntryType != TypeEntry::PrimitiveType
+ && typeEntryType != TypeEntry::SmartPointerType) {
+ if (errorMessage != nullptr)
+ *errorMessage = msgAmbiguousTypesFound(qualifiedName, types);
+ return {};
+ }
+ return types;
+}
+
// Reverse lookup of AbstractMetaType representing a template specialization
// found during traversing function arguments to its type system typedef'ed
// class.
@@ -2272,12 +2299,10 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
typeInfo.clearInstantiations();
}
- const TypeEntries types = findTypeEntries(qualifiedName, name, currentClass, d);
+ const TypeEntries types = findTypeEntries(qualifiedName, name, currentClass, d, errorMessageIn);
if (types.isEmpty()) {
- if (errorMessageIn) {
- *errorMessageIn =
- msgUnableToTranslateType(_typei, msgCannotFindTypeEntry(qualifiedName));
- }
+ if (errorMessageIn != nullptr)
+ *errorMessageIn = msgUnableToTranslateType(_typei, *errorMessageIn);
return {};
}
@@ -2313,25 +2338,6 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
metaType.addInstantiation(targType);
}
- if (types.size() > 1) {
- const bool sameType = std::all_of(types.cbegin() + 1, types.cend(),
- [typeEntryType](const TypeEntry *e) {
- return e->type() == typeEntryType; });
- if (!sameType) {
- if (errorMessageIn)
- *errorMessageIn = msgAmbiguousVaryingTypesFound(qualifiedName, types);
- return {};
- }
- // Ambiguous primitive/smart pointer types are possible (when
- // including type systems).
- if (typeEntryType != TypeEntry::PrimitiveType
- && typeEntryType != TypeEntry::SmartPointerType) {
- if (errorMessageIn)
- *errorMessageIn = msgAmbiguousTypesFound(qualifiedName, types);
- return {};
- }
- }
-
if (typeEntryType == TypeEntry::SmartPointerType) {
// Find a matching instantiation
if (metaType.instantiations().size() != 1) {
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
index 1854b8b56..2620effff 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
@@ -143,6 +143,7 @@ public:
AbstractMetaFunction *fnc, AbstractMetaClass *,
int argumentIndex);
AbstractMetaType translateType(const AddedFunction::TypeInfo &typeInfo,
+ AbstractMetaClass *currentClass,
QString *errorMessage);
AbstractMetaType translateType(const TypeInfo &type,
AbstractMetaClass *currentClass,
@@ -153,9 +154,13 @@ public:
AbstractMetaBuilderPrivate *d = nullptr,
TranslateTypeFlags flags = {},
QString *errorMessageIn = nullptr);
+ static TypeEntries findTypeEntriesHelper(const QString &qualifiedName, const QString &name,
+ AbstractMetaClass *currentClass = nullptr,
+ AbstractMetaBuilderPrivate *d = nullptr);
static TypeEntries findTypeEntries(const QString &qualifiedName, const QString &name,
AbstractMetaClass *currentClass = nullptr,
- AbstractMetaBuilderPrivate *d = nullptr);
+ AbstractMetaBuilderPrivate *d = nullptr,
+ QString *errorMessage = nullptr);
qint64 findOutValueFromString(const QString &stringValue, bool &ok);