aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-07-03 12:10:50 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-07-11 19:01:35 +0000
commitbec70b8845b9d642dc2cd29b8c85e8d06b107ea3 (patch)
treee08bcde1f5868f7849ffb5e8230764676ec89033 /sources/shiboken2
parent5b682a6bceec3f43a984a028afe242950a2d82d7 (diff)
shiboken: Streamline type parsing
Extract a static AbstractMetaType *AbstractMetaBuilder::translateType() method from the existing AbstractMetaBuilderPrivate::translateType() which can be passed the current class. Internally, add a AbstractMetaBuilderPrivate::translateTypeStatic() method that takes AbstractMetaBuilderPrivate parameter. Use that in conjunction with the TypeParse code to remove the type parsing code in ShibokenGenerator::buildAbstractMetaTypeFromString(). Task-number: PYSIDE-672 Change-Id: Ia17f0eb542099dcb843a59708110fc9d90fab12f Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp130
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.h12
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h9
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp119
4 files changed, 146 insertions, 124 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 5e7afbc09..4c7077ae2 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -2255,14 +2255,51 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
return type;
}
+static QString msgUnableToTranslateType(const QString &t, const QString &why)
+{
+ return QLatin1String("Unable to translate type \"")
+ + t + QLatin1String("\": ") + why;
+}
+
+static inline QString msgUnableToTranslateType(const TypeInfo &typeInfo,
+ const QString &why)
+{
+ return msgUnableToTranslateType(typeInfo.toString(), why);
+}
+
+static inline QString msgCannotFindTypeEntry(const QString &t)
+{
+ return QLatin1String("Cannot find type entry for \"") + t + QLatin1String("\".");
+}
+
+static inline QString msgCannotTranslateTemplateArgument(int i,
+ const TypeInfo &typeInfo,
+ const QString &why)
+{
+ QString result;
+ QTextStream(&result) << "Unable to translate template argument "
+ << (i + 1) << typeInfo.toString() << ": " << why;
+ return result;
+}
+
AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
- bool resolveType)
+ bool resolveType,
+ QString *errorMessage)
+{
+ return translateTypeStatic(_typei, m_currentClass, this, resolveType, errorMessage);
+}
+
+AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
+ AbstractMetaBuilderPrivate *d,
+ bool resolveType,
+ QString *errorMessageIn)
{
// 1. Test the type info without resolving typedefs in case this is present in the
// type system
TypeInfo typei;
if (resolveType) {
- if (AbstractMetaType *resolved = translateType(_typei, false))
+ if (AbstractMetaType *resolved = translateTypeStatic(_typei, currentClass, d, false, errorMessageIn))
return resolved;
}
@@ -2274,23 +2311,29 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
// the global scope when they are referenced from inside a namespace.
// This is a work around to fix this bug since fixing it in resolveType
// seemed non-trivial
- int i = m_scopes.size() - 1;
+ int i = d ? d->m_scopes.size() - 1 : -1;
while (i >= 0) {
- typei = TypeInfo::resolveType(_typei, m_scopes.at(i--));
+ typei = TypeInfo::resolveType(_typei, d->m_scopes.at(i--));
if (typei.qualifiedName().join(colonColon()) != _typei.qualifiedName().join(colonColon()))
break;
}
}
- if (typei.isFunctionPointer())
+ if (typei.isFunctionPointer()) {
+ if (errorMessageIn)
+ *errorMessageIn = msgUnableToTranslateType(_typei, QLatin1String("Unsupported function pointer."));
return nullptr;
+ }
QString errorMessage;
TypeInfo typeInfo = TypeParser::parse(typei.toString(), &errorMessage);
if (typeInfo.qualifiedName().isEmpty()) {
- qWarning().noquote().nospace() << "Unable to translate type \"" << _typei.toString()
- << "\": " << errorMessage;
+ errorMessage = msgUnableToTranslateType(_typei, errorMessage);
+ if (errorMessageIn)
+ *errorMessageIn = errorMessage;
+ else
+ qCWarning(lcShiboken,"%s", qPrintable(errorMessage));
return 0;
}
@@ -2324,9 +2367,14 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
newInfo.setReferenceType(typeInfo.referenceType());
newInfo.setVolatile(typeInfo.isVolatile());
- AbstractMetaType *elementType = translateType(newInfo);
- if (!elementType)
+ AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, true, &errorMessage);
+ if (!elementType) {
+ if (errorMessageIn) {
+ errorMessage.prepend(QLatin1String("Unable to translate array element: "));
+ *errorMessageIn = msgUnableToTranslateType(_typei, errorMessage);
+ }
return nullptr;
+ }
for (int i = typeInfo.arrayElements().size() - 1; i >= 0; --i) {
AbstractMetaType *arrayType = new AbstractMetaType;
@@ -2334,7 +2382,9 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
const QString &arrayElement = typeInfo.arrayElements().at(i);
if (!arrayElement.isEmpty()) {
bool _ok;
- const qint64 elems = findOutValueFromString(arrayElement, _ok);
+ const qint64 elems = d
+ ? d->findOutValueFromString(arrayElement, _ok)
+ : arrayElement.toLongLong(&_ok, 0);
if (_ok)
arrayType->setArrayElementCount(int(elems));
}
@@ -2349,8 +2399,11 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
QStringList qualifierList = typeInfo.qualifiedName();
if (qualifierList.isEmpty()) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("horribly broken type '%1'").arg(_typei.toString());
+ errorMessage = msgUnableToTranslateType(_typei, QLatin1String("horribly broken type"));
+ if (errorMessageIn)
+ *errorMessageIn = errorMessage;
+ else
+ qCWarning(lcShiboken,"%s", qPrintable(errorMessage));
return nullptr;
}
@@ -2367,12 +2420,12 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
// 5. Try to find the type
// 5.1 - Try first using the current scope
- if (m_currentClass) {
- type = findTypeEntryUsingContext(m_currentClass, qualifiedName);
+ if (currentClass) {
+ type = findTypeEntryUsingContext(currentClass, qualifiedName);
// 5.1.1 - Try using the class parents' scopes
- if (!type && !m_currentClass->baseClassNames().isEmpty()) {
- const AbstractMetaClassList &baseClasses = getBaseClasses(m_currentClass);
+ if (!type && d && !currentClass->baseClassNames().isEmpty()) {
+ const AbstractMetaClassList &baseClasses = d->getBaseClasses(currentClass);
for (const AbstractMetaClass *cls : baseClasses) {
type = findTypeEntryUsingContext(cls, qualifiedName);
if (type)
@@ -2395,19 +2448,25 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
// 8. No? Check if the current class is a template and this type is one
// of the parameters.
- if (!type && m_currentClass) {
- const QVector<TypeEntry *> &template_args = m_currentClass->templateArguments();
+ if (!type && currentClass) {
+ const QVector<TypeEntry *> &template_args = currentClass->templateArguments();
for (TypeEntry *te : template_args) {
if (te->name() == qualifiedName)
type = te;
}
}
- if (!type)
+ if (!type) {
+ if (errorMessageIn) {
+ *errorMessageIn =
+ msgUnableToTranslateType(_typei, msgCannotFindTypeEntry(qualifiedName));
+ }
return nullptr;
+ }
// Used to for diagnostics later...
- m_usedTypes << type;
+ if (d)
+ d->m_usedTypes << type;
// These are only implicit and should not appear in code...
Q_ASSERT(!type->isInterface());
@@ -2422,8 +2481,10 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
const auto &templateArguments = typeInfo.instantiations();
for (int t = 0, size = templateArguments.size(); t < size; ++t) {
TypeInfo ti = templateArguments.at(t);
- AbstractMetaType *targType = translateType(ti);
+ AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, true, &errorMessage);
if (!targType) {
+ if (errorMessageIn)
+ *errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage);
delete metaType;
return nullptr;
}
@@ -2440,6 +2501,33 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
return metaType;
}
+AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
+ bool resolveType,
+ QString *errorMessage)
+{
+ return AbstractMetaBuilderPrivate::translateTypeStatic(_typei, currentClass,
+ nullptr, resolveType,
+ errorMessage);
+}
+
+AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t,
+ AbstractMetaClass *currentClass,
+ bool resolveType,
+ QString *errorMessageIn)
+{
+ QString errorMessage;
+ TypeInfo typeInfo = TypeParser::parse(t, &errorMessage);
+ if (typeInfo.qualifiedName().isEmpty()) {
+ errorMessage = msgUnableToTranslateType(t, errorMessage);
+ if (errorMessageIn)
+ *errorMessageIn = errorMessage;
+ else
+ qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ return nullptr;
+ }
+ return translateType(typeInfo, currentClass, resolveType, errorMessageIn);
+}
qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValue, bool &ok)
{
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index a0ca71b94..bea2ac4c0 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -38,7 +38,9 @@ QT_FORWARD_DECLARE_CLASS(QIODevice)
class AbstractMetaBuilderPrivate;
class AbstractMetaClass;
+class AbstractMetaType;
class AbstractMetaEnumValue;
+class TypeInfo;
class AbstractMetaBuilder
{
@@ -83,6 +85,16 @@ public:
*/
void setGlobalHeader(const QString& globalHeader);
+ static AbstractMetaType *translateType(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass = nullptr,
+ bool resolveType = true,
+ QString *errorMessage = nullptr);
+ static AbstractMetaType *translateType(const QString &t,
+ AbstractMetaClass *currentClass = nullptr,
+ bool resolveType = true,
+ QString *errorMessage = nullptr);
+
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const;
#endif
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 59e3cfc94..7d4e280bd 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -123,7 +123,14 @@ public:
int argumentIndex);
AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo);
AbstractMetaType *translateType(const TypeInfo &type,
- bool resolveType = true);
+ bool resolveType = true,
+ QString *errorMessage = nullptr);
+ static AbstractMetaType *translateTypeStatic(const TypeInfo &type,
+ AbstractMetaClass *current,
+ AbstractMetaBuilderPrivate *d = nullptr,
+ bool resolveType = true,
+ QString *errorMessageIn = nullptr);
+
qint64 findOutValueFromString(const QString &stringValue, bool &ok);
AbstractMetaClass *findTemplateClass(const QString& name, const AbstractMetaClass *context,
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 80096cbf2..50368574a 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -31,6 +31,7 @@
#include "overloaddata.h"
#include <reporthandler.h>
#include <typedatabase.h>
+#include <abstractmetabuilder.h>
#include <iostream>
#include <QtCore/QDir>
@@ -2262,6 +2263,12 @@ bool ShibokenGenerator::isCopyable(const AbstractMetaClass *metaClass)
return false;
}
+static inline QString msgCannotBuildMetaType(const QString &s)
+{
+ return QLatin1String("Unable to build meta type for \"")
+ + s + QLatin1String("\": ");
+}
+
AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature,
QString *errorMessage)
{
@@ -2269,110 +2276,18 @@ AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ
if (typeSignature.startsWith(QLatin1String("::")))
typeSignature.remove(0, 2);
- if (m_metaTypeFromStringCache.contains(typeSignature))
- return m_metaTypeFromStringCache.value(typeSignature);
-
- QString typeString = typeSignature;
- bool isConst = typeString.startsWith(QLatin1String("const "));
- if (isConst)
- typeString.remove(0, sizeof("const ") / sizeof(char) - 1);
-
- ReferenceType refType = NoReference;
- if (typeString.endsWith(QLatin1String("&&"))) {
- refType = RValueReference;
- typeString.chop(2);
- typeString = typeString.trimmed();
- } else if (typeString.endsWith(QLatin1Char('&'))) {
- refType = LValueReference;
- typeString.chop(1);
- typeString = typeString.trimmed();
- }
-
- int indirections = 0;
- while (typeString.endsWith(QLatin1Char('*'))) {
- ++indirections;
- typeString.chop(1);
- typeString = typeString.trimmed();
- }
-
- if (typeString.startsWith(QLatin1String("::")))
- typeString.remove(0, 2);
-
- QString adjustedTypeName = typeString;
- AbstractMetaTypeList instantiations;
- int lpos = typeString.indexOf(QLatin1Char('<'));
- if (lpos > -1) {
- QStringList instantiatedTypes;
- int rpos = typeString.lastIndexOf(QLatin1Char('>'));
- if ((lpos != -1) && (rpos != -1)) {
- QString type = typeString.mid(lpos + 1, rpos - lpos - 1);
- int depth = 0;
- int start = 0;
- for (int i = 0; i < type.count(); ++i) {
- if (type.at(i) == QLatin1Char('<')) {
- ++depth;
- } else if (type.at(i) == QLatin1Char('>')) {
- --depth;
- } else if (type.at(i) == QLatin1Char(',') && depth == 0) {
- instantiatedTypes << type.mid(start, i - start).trimmed();
- start = i + 1;
- }
- }
- instantiatedTypes << type.mid(start).trimmed();
- adjustedTypeName.truncate(lpos);
- }
- for (const QString &instantiatedType : qAsConst(instantiatedTypes)) {
- AbstractMetaType *tmplArgType = buildAbstractMetaTypeFromString(instantiatedType);
- if (!tmplArgType) {
- if (errorMessage) {
- QTextStream(errorMessage) << "Cannot find template type \""
- << instantiatedType << "\" for \"" << typeSignature << "\".";
- }
- return nullptr;
- }
- instantiations.append(tmplArgType);
- }
- }
-
- TypeEntry *typeEntry = nullptr;
- AbstractMetaType::TypeUsagePattern pattern = AbstractMetaType::InvalidPattern;
-
- if (instantiations.size() == 1
- && instantiations.at(0)->typeUsagePattern() == AbstractMetaType::EnumPattern
- && adjustedTypeName == QLatin1String("QFlags")) {
- pattern = AbstractMetaType::FlagsPattern;
- typeEntry = TypeDatabase::instance()->findType(typeSignature);
- } else {
- typeEntry = TypeDatabase::instance()->findType(adjustedTypeName);
- }
-
- if (!typeEntry) {
- if (errorMessage) {
- QTextStream(errorMessage) << "Cannot find type \"" << adjustedTypeName
- << "\" for \"" << typeSignature << "\".";
+ auto it = m_metaTypeFromStringCache.find(typeSignature);
+ if (it == m_metaTypeFromStringCache.end()) {
+ AbstractMetaType *metaType =
+ AbstractMetaBuilder::translateType(typeSignature, nullptr, true, errorMessage);
+ if (Q_UNLIKELY(!metaType)) {
+ if (errorMessage)
+ errorMessage->prepend(msgCannotBuildMetaType(typeSignature));
+ return nullptr;
}
- return nullptr;
+ it = m_metaTypeFromStringCache.insert(typeSignature, metaType);
}
-
- AbstractMetaType *metaType = new AbstractMetaType();
- metaType->setTypeEntry(typeEntry);
- metaType->setIndirections(indirections);
- metaType->setReferenceType(refType);
- metaType->setConstant(isConst);
- metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern);
- switch (pattern) {
- case AbstractMetaType::FlagsPattern:
- metaType->setTypeUsagePattern(pattern);
- break;
- default:
- metaType->setInstantiations(instantiations);
- metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern);
- metaType->decideUsagePattern();
- break;
- }
-
- m_metaTypeFromStringCache.insert(typeSignature, metaType);
- return metaType;
+ return it.value();
}
AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(const TypeEntry* typeEntry)