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 <fabian.kosmale@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Ulf Hermann
2019-08-29 10:38:36 +02:00
parent 1bf23a6c74
commit b5b1367b0b
4 changed files with 29 additions and 41 deletions

View File

@@ -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<const char *>(&len), sizeof(len));
hash.addData(reinterpret_cast<const char *>(key.constData()), len * sizeof(QChar));
}
len = m_values.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
foreach (int value, m_values)
hash.addData(reinterpret_cast<const char *>(&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;
}

View File

@@ -43,7 +43,6 @@ namespace LanguageUtils {
class LANGUAGEUTILS_EXPORT FakeMetaEnum {
QString m_name;
QStringList m_keys;
QList<int> 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;

View File

@@ -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);
}

View File

@@ -649,39 +649,34 @@ void TypeDescriptionReader::readEnumValues(AST::UiScriptBinding *ast, LanguageUt
return;
}
ExpressionStatement *expStmt = AST::cast<ExpressionStatement *>(ast->statement);
auto *expStmt = AST::cast<ExpressionStatement *>(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<ObjectPattern *>(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<PatternProperty *>(it->property);
if (assignement) {
StringLiteralPropertyName *propName = AST::cast<StringLiteralPropertyName *>(assignement->name);
NumericLiteral *value = AST::cast<NumericLiteral *>(assignement->initializer);
UnaryMinusExpression *minus = AST::cast<UnaryMinusExpression *>(assignement->initializer);
if (minus)
value = AST::cast<NumericLiteral *>(minus->expression);
if (!propName || !value) {
addError(objectLit->firstSourceLocation(), tr("Expected object literal to contain only 'string: number' elements."));
continue;
if (auto *objectLit = AST::cast<ObjectPattern *>(expStmt->expression)) {
for (PatternPropertyList *it = objectLit->properties; it; it = it->next) {
if (PatternProperty *assignement = it->property) {
if (auto *name = AST::cast<StringLiteralPropertyName *>(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<PatternPropertyList *>(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<ArrayPattern *>(expStmt->expression)) {
for (PatternElementList *it = arrayLit->elements; it; it = it->next) {
if (PatternElement *element = it->element) {
if (auto *name = AST::cast<StringLiteral *>(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."));
}
}