From b5b1367b0b37133c9666a5d20c95d53e5e6d6a43 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 29 Aug 2019 10:38:36 +0200 Subject: [PATCH] Accept arrays as enum descriptions in qmltypes files We don't use the values at all and they are hard to determine statically. Qt >= 5.15 will generated arrays instead of objects. Change-Id: I3b3bbd427c49e649ca3f9cef51c89b32e830eb66 Reviewed-by: Fabian Kosmale Reviewed-by: Thomas Hartmann --- src/libs/languageutils/fakemetaobject.cpp | 14 ++--- src/libs/languageutils/fakemetaobject.h | 3 +- src/libs/qmljs/qmljsfindexportedcpptypes.cpp | 2 +- src/libs/qmljs/qmljstypedescriptionreader.cpp | 51 +++++++++---------- 4 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/libs/languageutils/fakemetaobject.cpp b/src/libs/languageutils/fakemetaobject.cpp index 1a6579b6e33..3d8866972b4 100644 --- a/src/libs/languageutils/fakemetaobject.cpp +++ b/src/libs/languageutils/fakemetaobject.cpp @@ -44,8 +44,8 @@ QString FakeMetaEnum::name() const void FakeMetaEnum::setName(const QString &name) { m_name = name; } -void FakeMetaEnum::addKey(const QString &key, int value) -{ m_keys.append(key); m_values.append(value); } +void FakeMetaEnum::addKey(const QString &key) +{ m_keys.append(key); } QString FakeMetaEnum::key(int index) const { return m_keys.at(index); } @@ -71,10 +71,6 @@ void FakeMetaEnum::addToHash(QCryptographicHash &hash) const hash.addData(reinterpret_cast(&len), sizeof(len)); hash.addData(reinterpret_cast(key.constData()), len * sizeof(QChar)); } - len = m_values.size(); - hash.addData(reinterpret_cast(&len), sizeof(len)); - foreach (int value, m_values) - hash.addData(reinterpret_cast(&value), sizeof(value)); } QString FakeMetaEnum::describe(int baseIndent) const @@ -82,16 +78,14 @@ QString FakeMetaEnum::describe(int baseIndent) const QString newLine = QString::fromLatin1("\n") + QString::fromLatin1(" ").repeated(baseIndent); QString res = QLatin1String("Enum "); res += name(); - res += QLatin1String(":{"); + res += QLatin1String(": ["); for (int i = 0; i < keyCount(); ++i) { res += newLine; res += QLatin1String(" "); res += key(i); - res += QLatin1String(": "); - res += QString::number(m_values.value(i, -1)); } res += newLine; - res += QLatin1Char('}'); + res += QLatin1Char(']'); return res; } diff --git a/src/libs/languageutils/fakemetaobject.h b/src/libs/languageutils/fakemetaobject.h index 543d80b45c9..a629ebedf8f 100644 --- a/src/libs/languageutils/fakemetaobject.h +++ b/src/libs/languageutils/fakemetaobject.h @@ -43,7 +43,6 @@ namespace LanguageUtils { class LANGUAGEUTILS_EXPORT FakeMetaEnum { QString m_name; QStringList m_keys; - QList m_values; public: FakeMetaEnum(); @@ -54,7 +53,7 @@ public: QString name() const; void setName(const QString &name); - void addKey(const QString &key, int value); + void addKey(const QString &key); QString key(int index) const; int keyCount() const; QStringList keys() const; diff --git a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp index 7ba890e17a2..7b3749ab519 100644 --- a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp +++ b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp @@ -737,7 +737,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject( Symbol *enumMember = e->memberAt(j); if (!enumMember->name()) continue; - metaEnum.addKey(namePrinter.prettyName(enumMember->name()), 0); + metaEnum.addKey(namePrinter.prettyName(enumMember->name())); } fmo->addEnum(metaEnum); } diff --git a/src/libs/qmljs/qmljstypedescriptionreader.cpp b/src/libs/qmljs/qmljstypedescriptionreader.cpp index 895922a1eb8..152432ca7be 100644 --- a/src/libs/qmljs/qmljstypedescriptionreader.cpp +++ b/src/libs/qmljs/qmljstypedescriptionreader.cpp @@ -649,39 +649,34 @@ void TypeDescriptionReader::readEnumValues(AST::UiScriptBinding *ast, LanguageUt return; } - ExpressionStatement *expStmt = AST::cast(ast->statement); + auto *expStmt = AST::cast(ast->statement); if (!expStmt) { - addError(ast->statement->firstSourceLocation(), tr("Expected object literal after colon.")); + addError(ast->statement->firstSourceLocation(), tr("Expected expression after colon.")); return; } - ObjectPattern *objectLit = AST::cast(expStmt->expression); - if (!objectLit) { - addError(expStmt->firstSourceLocation(), tr("Expected object literal after colon.")); - return; - } - - for (PatternPropertyList *it = objectLit->properties; it; it = it->next) { - PatternProperty *assignement = AST::cast(it->property); - if (assignement) { - StringLiteralPropertyName *propName = AST::cast(assignement->name); - NumericLiteral *value = AST::cast(assignement->initializer); - UnaryMinusExpression *minus = AST::cast(assignement->initializer); - if (minus) - value = AST::cast(minus->expression); - if (!propName || !value) { - addError(objectLit->firstSourceLocation(), tr("Expected object literal to contain only 'string: number' elements.")); - continue; + if (auto *objectLit = AST::cast(expStmt->expression)) { + for (PatternPropertyList *it = objectLit->properties; it; it = it->next) { + if (PatternProperty *assignement = it->property) { + if (auto *name = AST::cast(assignement->name)) { + fme->addKey(name->id.toString()); + continue; + } } - - double v = value->value; - if (minus) - v = -v; - fme->addKey(propName->id.toString(), v); - continue; + addError(it->firstSourceLocation(), tr("Expected strings as enum keys.")); } - PatternPropertyList *getterSetter = AST::cast(it->next); - if (getterSetter) - addError(objectLit->firstSourceLocation(), tr("Enum should not contain getter and setters, but only 'string: number' elements.")); + } else if (auto *arrayLit = AST::cast(expStmt->expression)) { + for (PatternElementList *it = arrayLit->elements; it; it = it->next) { + if (PatternElement *element = it->element) { + if (auto *name = AST::cast(element->initializer)) { + fme->addKey(name->value.toString()); + continue; + } + } + addError(it->firstSourceLocation(), tr("Expected strings as enum keys.")); + } + } else { + addError(ast->statement->firstSourceLocation(), + tr("Expected either array or object literal as enum definition.")); } }