From 77e0dc0485953427320ed0b442ba24eef4f9d73b Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 10 Mar 2017 09:17:35 +0100 Subject: [PATCH] Fix support for enums and translations in list elements QQC uses valid constructs like ListElement { dayOfWeek: Locale.Sunday }, where the enums are resolved at type compilation time. Syntactically Locale.Sunday is a JS expression, but as scripts are not permitted for list elements, we must retain the values in string form when generating the binary (cache) qml representation. This is a forward port of commit 736f4f9c847d1102f6ac77674c831f0555ff445e from the qml compiler, and also matches QTRD-3226. Change-Id: I3e615f224d4ab222a50f3271735cb8f7a24f5f11 Reviewed-by: Erik Verbruggen --- tools/qmlcachegen/qmlcachegen.cpp | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index eb2986d957..9a68e2ac97 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -80,6 +80,39 @@ QString diagnosticErrorMessage(const QString &fileName, const QQmlJS::Diagnostic return message; } +// Ensure that ListElement objects keep all property assignments in their string form +static void annotateListElements(QmlIR::Document *document) +{ + QStringList listElementNames; + + foreach (const QV4::CompiledData::Import *import, document->imports) { + const QString uri = document->stringAt(import->uriIndex); + if (uri != QStringLiteral("QtQml.Models") && uri != QStringLiteral("QtQuick")) + continue; + + QString listElementName = QStringLiteral("ListElement"); + const QString qualifier = document->stringAt(import->qualifierIndex); + if (!qualifier.isEmpty()) { + listElementName.prepend(QLatin1Char('.')); + listElementName.prepend(qualifier); + } + listElementNames.append(listElementName); + } + + if (listElementNames.isEmpty()) + return; + + foreach (QmlIR::Object *object, document->objects) { + if (!listElementNames.contains(document->stringAt(object->inheritedTypeNameIndex))) + continue; + for (QmlIR::Binding *binding = object->firstBinding(); binding; binding = binding->next) { + if (binding->type != QV4::CompiledData::Binding::Type_Script) + continue; + binding->stringIndex = document->registerString(object->bindingAsString(document, binding->value.compiledScriptIndex)); + } + } +} + static bool compileQmlFile(const QString &inputFileName, const QString &outputFileName, QV4::EvalISelFactory *iselFactory, Error *error) { QmlIR::Document irDocument(/*debugMode*/false); @@ -111,6 +144,8 @@ static bool compileQmlFile(const QString &inputFileName, const QString &outputFi } } + annotateListElements(&irDocument); + { QmlIR::JSCodeGen v4CodeGen(/*empty input file name*/QString(), irDocument.code, &irDocument.jsModule, &irDocument.jsParserEngine, irDocument.program, /*import cache*/0, &irDocument.jsGenerator.stringTable); for (QmlIR::Object *object: qAsConst(irDocument.objects)) {