summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-06-01 11:20:14 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-06-01 18:32:55 +0000
commit7f798dfc9fc6e3e9756f06f0fedc821e16f1320a (patch)
tree661fcaf9bd38082dc950466bcc7e5a24620c5b1c
parent4e468d77de10c7bd6e76b59a37cecb5151a80626 (diff)
shiboken: Streamline the type parsing code
Replace struct TypeParser::Info by TypeInfo and remove TypeParser::Info. Move method TypeParser::Info::instantiationName() to TypeInfo for this purpose. Change TypeParser::parse() to return TypeInfo. Task-number: QTBUG-672 Change-Id: I123d5bf378ad146867b571e47e31ae08a92b2504 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp100
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h5
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp14
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h3
-rw-r--r--sources/shiboken2/ApiExtractor/typeparser.cpp126
-rw-r--r--sources/shiboken2/ApiExtractor/typeparser.h25
6 files changed, 87 insertions, 186 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index d76c788e..fa9f78ca 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -1612,7 +1612,7 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
// we only support our own containers and ONLY if there is only one baseclass
if (baseClasses.size() == 1 && baseClasses.constFirst().contains(QLatin1Char('<'))) {
- TypeParser::Info info;
+ TypeInfo info;
ComplexTypeEntry* baseContainerType;
AbstractMetaClass* templ = findTemplateClass(baseClasses.constFirst(), metaClass, &info, &baseContainerType);
if (templ) {
@@ -2343,8 +2343,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
return nullptr;
QString errorMessage;
- TypeParser::Info typeInfo = TypeParser::parse(typei.toString(), &errorMessage);
- if (typeInfo.is_busted) {
+ TypeInfo typeInfo = TypeParser::parse(typei.toString(), &errorMessage);
+ if (typeInfo.qualifiedName().isEmpty()) {
qWarning().noquote().nospace() << "Unable to translate type \"" << _typei.toString()
<< "\": " << errorMessage;
return 0;
@@ -2354,43 +2354,43 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
// 2.1 Handle char arrays with unspecified size (aka "const char[]") as "const char*" with
// NativePointerPattern usage.
bool oneDimensionalArrayOfUnspecifiedSize =
- typeInfo.arrays.size() == 1
- && typeInfo.arrays[0].isEmpty();
+ typeInfo.arrayElements().size() == 1
+ && typeInfo.arrayElements().at(0).isEmpty();
bool isConstCharStarCase =
oneDimensionalArrayOfUnspecifiedSize
- && typeInfo.qualified_name.size() == 1
- && typeInfo.qualified_name[0] == QStringLiteral("char")
- && typeInfo.indirections == 0
- && typeInfo.is_constant == 1
- && typeInfo.is_busted == 0
- && typeInfo.referenceType == NoReference
- && typeInfo.template_instantiations.size() == 0;
+ && typeInfo.qualifiedName().size() == 1
+ && typeInfo.qualifiedName().at(0) == QStringLiteral("char")
+ && typeInfo.indirections() == 0
+ && typeInfo.isConstant()
+ && typeInfo.referenceType() == NoReference
+ && typeInfo.arguments().isEmpty();
if (isConstCharStarCase)
- typeInfo.indirections += typeInfo.arrays.size();
+ typeInfo.setIndirections(typeInfo.indirections() + typeInfo.arrayElements().size());
// 2.2 Handle regular arrays.
- if (typeInfo.arrays.size() > 0 && !isConstCharStarCase) {
+ if (!typeInfo.arrayElements().isEmpty() && !isConstCharStarCase) {
TypeInfo newInfo;
- //newInfo.setArguments(typei.arguments());
- newInfo.setIndirections(typei.indirections());
- newInfo.setConstant(typei.isConstant());
- newInfo.setFunctionPointer(typei.isFunctionPointer());
- newInfo.setQualifiedName(typei.qualifiedName());
- newInfo.setReferenceType(typei.referenceType());
- newInfo.setVolatile(typei.isVolatile());
+ //newInfo.setArguments(typeInfo.arguments());
+ newInfo.setIndirections(typeInfo.indirections());
+ newInfo.setConstant(typeInfo.isConstant());
+ newInfo.setFunctionPointer(typeInfo.isFunctionPointer());
+ newInfo.setQualifiedName(typeInfo.qualifiedName());
+ newInfo.setReferenceType(typeInfo.referenceType());
+ newInfo.setVolatile(typeInfo.isVolatile());
AbstractMetaType *elementType = translateType(newInfo);
if (!elementType)
return nullptr;
- for (int i = typeInfo.arrays.size() - 1; i >= 0; --i) {
+ for (int i = typeInfo.arrayElements().size() - 1; i >= 0; --i) {
AbstractMetaType *arrayType = new AbstractMetaType;
arrayType->setArrayElementType(elementType);
- if (!typeInfo.arrays.at(i).isEmpty()) {
+ const QString &arrayElement = typeInfo.arrayElements().at(i);
+ if (!arrayElement.isEmpty()) {
bool _ok;
- const qint64 elems = findOutValueFromString(typeInfo.arrays.at(i), _ok);
+ const qint64 elems = findOutValueFromString(arrayElement, _ok);
if (_ok)
arrayType->setArrayElementCount(int(elems));
}
@@ -2403,7 +2403,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
return elementType;
}
- QStringList qualifierList = typeInfo.qualified_name;
+ QStringList qualifierList = typeInfo.qualifiedName();
if (qualifierList.isEmpty()) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("horribly broken type '%1'").arg(_typei.toString());
@@ -2468,21 +2468,16 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
AbstractMetaType *metaType = new AbstractMetaType;
metaType->setTypeEntry(type);
- metaType->setIndirections(typeInfo.indirections);
- metaType->setReferenceType(typeInfo.referenceType);
- metaType->setConstant(typeInfo.is_constant);
+ metaType->setIndirections(typeInfo.indirections());
+ metaType->setReferenceType(typeInfo.referenceType());
+ metaType->setConstant(typeInfo.isConstant());
metaType->setOriginalTypeDescription(_typei.toString());
- for (const TypeParser::Info &ta : qAsConst(typeInfo.template_instantiations)) {
- TypeInfo info;
- info.setConstant(ta.is_constant);
- info.setReferenceType(ta.referenceType);
- info.setIndirections(ta.indirections);
-
- info.setFunctionPointer(false);
- info.setQualifiedName(ta.instantiationName().split(colonColon()));
-
- AbstractMetaType *targType = translateType(info);
+ const auto &templateArguments = typeInfo.arguments();
+ for (int t = 0, size = templateArguments.size(); t < size; ++t) {
+ TypeInfo ti = templateArguments.at(t);
+ ti.setQualifiedName(ti.instantiationName());
+ AbstractMetaType *targType = translateType(ti);
if (!targType) {
delete metaType;
return nullptr;
@@ -2671,13 +2666,9 @@ bool AbstractMetaBuilderPrivate::isEnum(const FileModelItem &dom, const QStringL
AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString &name,
const AbstractMetaClass *context,
- TypeParser::Info *info,
+ TypeInfo *info,
ComplexTypeEntry **baseContainerType) const
{
- TypeParser::Info localInfo;
- if (!info)
- info = &localInfo;
-
TypeDatabase* types = TypeDatabase::instance();
QStringList scope = context->typeEntry()->qualifiedCppName().split(colonColon());
@@ -2686,14 +2677,15 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString &
for (int i = scope.size(); i >= 0; --i) {
QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join(colonColon()) + colonColon() : QString();
QString completeName = prefix + name;
- const TypeParser::Info parsed = TypeParser::parse(completeName, &errorMessage);
- if (parsed.is_busted) {
+ const TypeInfo parsed = TypeParser::parse(completeName, &errorMessage);
+ QString qualifiedName = parsed.qualifiedName().join(colonColon());
+ if (qualifiedName.isEmpty()) {
qWarning().noquote().nospace() << "Unable to parse type \"" << completeName
<< "\" while looking for template \"" << name << "\": " << errorMessage;
continue;
}
- *info = parsed;
- QString qualifiedName = info->qualified_name.join(colonColon());
+ if (info)
+ *info = parsed;
AbstractMetaClass* templ = 0;
for (AbstractMetaClass *c : qAsConst(m_templates)) {
@@ -2795,9 +2787,9 @@ AbstractMetaType* AbstractMetaBuilderPrivate::inheritTemplateType(const QVector<
bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
const AbstractMetaClass *templateClass,
- const TypeParser::Info &info)
+ const TypeInfo &info)
{
- QVector<TypeParser::Info> targs = info.template_instantiations;
+ QVector<TypeInfo> targs = info.arguments();
QVector<AbstractMetaType *> templateTypes;
if (subclass->isTypeDef()) {
@@ -2810,8 +2802,8 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
subclass->setHasVirtualDestructor(templateClass->hasVirtualDestructor());
}
- for (const TypeParser::Info &i : qAsConst(targs)) {
- QString typeName = i.qualified_name.join(colonColon());
+ for (const TypeInfo &i : qAsConst(targs)) {
+ QString typeName = i.qualifiedName().join(colonColon());
QStringList possibleNames;
possibleNames << subclass->qualifiedCppName() + colonColon() + typeName;
possibleNames << templateClass->qualifiedCppName() + colonColon() + typeName;
@@ -2831,9 +2823,9 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
if (t) {
AbstractMetaType *temporaryType = new AbstractMetaType;
temporaryType->setTypeEntry(t);
- temporaryType->setConstant(i.is_constant);
- temporaryType->setReferenceType(i.referenceType);
- temporaryType->setIndirections(i.indirections);
+ temporaryType->setConstant(i.isConstant());
+ temporaryType->setReferenceType(i.referenceType());
+ temporaryType->setIndirections(i.indirections());
temporaryType->decideUsagePattern();
templateTypes << temporaryType;
} else {
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 95973446..1f4e209d 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -122,18 +122,17 @@ public:
AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo);
AbstractMetaType *translateType(const TypeInfo &type,
bool resolveType = true);
-
qint64 findOutValueFromString(const QString &stringValue, bool &ok);
AbstractMetaClass *findTemplateClass(const QString& name, const AbstractMetaClass *context,
- TypeParser::Info *info = Q_NULLPTR,
+ TypeInfo *info = Q_NULLPTR,
ComplexTypeEntry **baseContainerType = Q_NULLPTR) const;
AbstractMetaClassList getBaseClasses(const AbstractMetaClass *metaClass) const;
bool ancestorHasPrivateCopyConstructor(const AbstractMetaClass *metaClass) const;
bool inheritTemplate(AbstractMetaClass *subclass,
const AbstractMetaClass *templateClass,
- const TypeParser::Info &info);
+ const TypeInfo &info);
AbstractMetaType *inheritTemplateType(const QVector<AbstractMetaType *> &templateTypes,
const AbstractMetaType *metaType,
bool *ok = Q_NULLPTR);
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index 0af4905f..60a69933 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -238,6 +238,20 @@ QString TypeInfo::toString() const
return tmp;
}
+QStringList TypeInfo::instantiationName() const
+{
+ QStringList result = m_qualifiedName;
+ if (const int argumentCount = m_arguments.size()) {
+ QString &last = result.last();
+ for (int i = 0; i < argumentCount; ++i) {
+ last += i ? QLatin1String(", ") : QLatin1String("< ");
+ last += m_arguments.at(i).toString();
+ }
+ last += QLatin1String(" >");
+ }
+ return result;
+}
+
bool TypeInfo::operator==(const TypeInfo &other) const
{
if (arrayElements().count() != other.arrayElements().count())
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index d0d7b677..d93aa10d 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -98,6 +98,7 @@ QDebug operator<<(QDebug d, const CodeModel *m);
class TypeInfo
{
+ friend class TypeParser;
public:
TypeInfo() : flags(0), m_referenceType(NoReference) {}
@@ -184,6 +185,8 @@ public:
QString toString() const;
+ QStringList instantiationName() const;
+
static TypeInfo combine(const TypeInfo &__lhs, const TypeInfo &__rhs);
static TypeInfo resolveType(TypeInfo const &__type, CodeModelItem __scope);
diff --git a/sources/shiboken2/ApiExtractor/typeparser.cpp b/sources/shiboken2/ApiExtractor/typeparser.cpp
index 9ef4be34..02c85421 100644
--- a/sources/shiboken2/ApiExtractor/typeparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typeparser.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "typeparser.h"
+#include <codemodel.h>
#include <QtCore/QDebug>
#include <QtCore/QStack>
@@ -155,19 +156,12 @@ QString Scanner::msgParseError(const QString &why) const
+ QString(m_chars, m_length) + QStringLiteral("\": ") + why;
}
-static TypeParser::Info invalidInfo()
-{
- TypeParser::Info result;
- result.is_busted = true;
- return result;
-}
-
-TypeParser::Info TypeParser::parse(const QString &str, QString *errorMessage)
+TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
{
Scanner scanner(str);
- Info info;
- QStack<Info *> stack;
+ TypeInfo info;
+ QStack<TypeInfo *> stack;
stack.push(&info);
bool colon_prefix = false;
@@ -177,7 +171,7 @@ TypeParser::Info TypeParser::parse(const QString &str, QString *errorMessage)
Scanner::Token tok = scanner.nextToken(errorMessage);
while (tok != Scanner::NoToken) {
if (tok == Scanner::InvalidToken)
- return invalidInfo();
+ return TypeInfo();
// switch (tok) {
// case Scanner::StarToken: printf(" - *\n"); break;
@@ -197,16 +191,16 @@ TypeParser::Info TypeParser::parse(const QString &str, QString *errorMessage)
switch (tok) {
case Scanner::StarToken:
- ++stack.top()->indirections;
+ ++stack.top()->m_indirections;
break;
case Scanner::AmpersandToken:
- switch (stack.top()->referenceType) {
+ switch (stack.top()->referenceType()) {
case NoReference:
- stack.top()->referenceType = LValueReference;
+ stack.top()->setReferenceType(LValueReference);
break;
case LValueReference:
- stack.top()->referenceType = RValueReference;
+ stack.top()->setReferenceType(RValueReference);
break;
case RValueReference:
const QString message = scanner.msgParseError(QStringLiteral("Too many '&' qualifiers"));
@@ -214,18 +208,18 @@ TypeParser::Info TypeParser::parse(const QString &str, QString *errorMessage)
*errorMessage = message;
else
qWarning().noquote().nospace() << message;
- return invalidInfo();
+ return TypeInfo();
}
break;
case Scanner::LessThanToken:
- stack.top()->template_instantiations << Info();
- stack.push(&stack.top()->template_instantiations.last());
+ stack.top()->m_arguments << TypeInfo();
+ stack.push(&stack.top()->m_arguments.last());
break;
case Scanner::CommaToken:
stack.pop();
- stack.top()->template_instantiations << Info();
- stack.push(&stack.top()->template_instantiations.last());
+ stack.top()->m_arguments << TypeInfo();
+ stack.push(&stack.top()->m_arguments.last());
break;
case Scanner::GreaterThanToken:
@@ -237,7 +231,7 @@ TypeParser::Info TypeParser::parse(const QString &str, QString *errorMessage)
break;
case Scanner::ConstToken:
- stack.top()->is_constant = true;
+ stack.top()->m_constant = true;
break;
case Scanner::OpenParenToken: // function pointers not supported
@@ -247,17 +241,17 @@ TypeParser::Info TypeParser::parse(const QString &str, QString *errorMessage)
*errorMessage = message;
else
qWarning().noquote().nospace() << message;
- return invalidInfo();
+ return TypeInfo();
}
case Scanner::Identifier:
if (in_array) {
array = scanner.identifier();
- } else if (colon_prefix || stack.top()->qualified_name.isEmpty()) {
- stack.top()->qualified_name << scanner.identifier();
+ } else if (colon_prefix || stack.top()->m_qualifiedName.isEmpty()) {
+ stack.top()->m_qualifiedName << scanner.identifier();
colon_prefix = false;
} else {
- stack.top()->qualified_name.last().append(QLatin1Char(' ') + scanner.identifier());
+ stack.top()->m_qualifiedName.last().append(QLatin1Char(' ') + scanner.identifier());
}
break;
@@ -267,7 +261,7 @@ TypeParser::Info TypeParser::parse(const QString &str, QString *errorMessage)
case Scanner::SquareEnd:
in_array = false;
- stack.top()->arrays += array;
+ stack.top()->m_arrayElements += array;
break;
@@ -280,83 +274,3 @@ TypeParser::Info TypeParser::parse(const QString &str, QString *errorMessage)
return info;
}
-
-QString TypeParser::Info::instantiationName() const
-{
- QString s(qualified_name.join(QLatin1String("::")));
- if (!template_instantiations.isEmpty()) {
- QStringList insts;
- for (const Info &info : template_instantiations)
- insts << info.toString();
- s += QLatin1String("< ") + insts.join(QLatin1String(", ")) + QLatin1String(" >");
- }
-
- return s;
-}
-
-QString TypeParser::Info::toString() const
-{
- QString s;
-
- if (is_constant)
- s += QLatin1String("const ");
- s += instantiationName();
- for (int i = 0; i < arrays.size(); ++i)
- s += QLatin1Char('[') + arrays.at(i) + QLatin1Char(']');
- s += QString(indirections, QLatin1Char('*'));
- switch (referenceType) {
- case NoReference:
- break;
- case LValueReference:
- s += QLatin1Char('&');
- break;
- case RValueReference:
- s += QLatin1String("&&");
- break;
- }
- return s;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-
-static void formatTypeInfo(QDebug &d, const TypeParser::Info &i)
-{
- if (i.is_busted) {
- d << "busted";
- return;
- }
-
- d << '"' << i.qualified_name << '"';
- if (!i.arrays.isEmpty()) {
- d << ", arrays=";
- for (const QString &a : i.arrays)
- d << '[' << a << ']';
- }
- if (!i.template_instantiations.isEmpty()) {
- d << ", template_instantiations=[";
- for (int t = 0, size = i.template_instantiations.size(); t < size; ++t) {
- if (t)
- d << ", ";
- formatTypeInfo(d, i.template_instantiations.at(t));
- }
- d << ']';
- }
- if (i.referenceType != NoReference)
- d << ", refType=" << i.referenceType;
- if (i.is_constant)
- d << ", [const]";
- if (i.indirections > 0)
- d << ", indirections=" << i.indirections;
-}
-
-QDebug operator<<(QDebug d, const TypeParser::Info &i)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "TypeParser::Info(";
- formatTypeInfo(d, i);
- d << ')';
- return d;
-}
-#endif // !QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/typeparser.h b/sources/shiboken2/ApiExtractor/typeparser.h
index e51a2c21..3b538017 100644
--- a/sources/shiboken2/ApiExtractor/typeparser.h
+++ b/sources/shiboken2/ApiExtractor/typeparser.h
@@ -31,36 +31,15 @@
#include "parser/codemodel_enums.h"
-#include <QtCore/QList>
#include <QtCore/QString>
-#include <QtCore/QStringList>
#include <QtCore/QVector>
-QT_FORWARD_DECLARE_CLASS(QDebug)
+class TypeInfo;
class TypeParser
{
public:
- struct Info
- {
- Info() : referenceType(NoReference), is_constant(false), is_busted(false), indirections(0) { }
- QStringList qualified_name;
- QStringList arrays;
- QVector<Info> template_instantiations;
- ReferenceType referenceType;
- uint is_constant : 1;
- uint is_busted : 1;
- uint indirections : 6;
-
- QString toString() const;
- QString instantiationName() const;
- };
-
- static Info parse(const QString &str, QString *errorMessage = Q_NULLPTR);
+ static TypeInfo parse(const QString &str, QString *errorMessage = nullptr);
};
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const TypeParser::Info &);
-#endif
-
#endif // TYPEPARSER_H