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 <erik.verbruggen@qt.io>
This commit is contained in:
Simon Hausmann 2017-03-10 09:17:35 +01:00
parent 182469fc85
commit 77e0dc0485
1 changed files with 35 additions and 0 deletions

View File

@ -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)) {