aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-10-11 13:59:46 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-10-13 14:03:41 +0200
commitf2a15482ddd289a36b04316a2b6ebed83eb017c5 (patch)
treeb2588d056ae5a80ac4b726571f6e1e3b0e362f8c /src/qml/compiler
parent4e645c7c33b03adf2d9161b00d00267add0aa373 (diff)
Add a Pragma for list assign behavior
[ChangeLog][QtQml] You can now specify the list property assignment behavior in QML using the "ListPropertyAssignBehavior" pragma. This is analogous to the macros you can use in C++. Fixes: QTBUG-93642 Change-Id: I9bdcf198031f1e24891f947b0990a3253d29a998 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp67
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h21
2 files changed, 70 insertions, 18 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index e6efec0b16..9605eda030 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -815,19 +815,43 @@ bool IRBuilder::visit(QQmlJS::AST::UiPragma *node)
{
Pragma *pragma = New<Pragma>();
- // For now the only valid pragma is Singleton, so lets validate the input
- if (!node->name.isNull())
- {
+ if (!node->name.isNull()) {
if (node->name == QStringLiteral("Singleton")) {
- pragma->type = Pragma::PragmaSingleton;
+ pragma->type = Pragma::Singleton;
} else if (node->name == QStringLiteral("Strict")) {
- pragma->type = Pragma::PragmaStrict;
+ pragma->type = Pragma::Strict;
+ } else if (node->name == QStringLiteral("ListPropertyAssignBehavior")) {
+ for (const Pragma *prev : _pragmas) {
+ if (prev->type != Pragma::ListPropertyAssignBehavior)
+ continue;
+ recordError(node->pragmaToken, QCoreApplication::translate(
+ "QQmlParser",
+ "Multiple list property assign behavior pragmas found"));
+ return false;
+ }
+
+ pragma->type = Pragma::ListPropertyAssignBehavior;
+ if (node->value == QStringLiteral("Replace")) {
+ pragma->listPropertyAssignBehavior = Pragma::Replace;
+ } else if (node->value == QStringLiteral("ReplaceIfNotDefault")) {
+ pragma->listPropertyAssignBehavior = Pragma::ReplaceIfNotDefault;
+ } else if (node->value == QStringLiteral("Append")) {
+ pragma->listPropertyAssignBehavior = Pragma::Append;
+ } else {
+ recordError(node->pragmaToken, QCoreApplication::translate(
+ "QQmlParser",
+ "Unknown list property assign behavior '%1' in pragma")
+ .arg(node->value));
+ return false;
+ }
} else {
- recordError(node->pragmaToken, QCoreApplication::translate("QQmlParser","Pragma requires a valid qualifier"));
+ recordError(node->pragmaToken, QCoreApplication::translate(
+ "QQmlParser", "Unknown pragma '%1'").arg(node->name));
return false;
}
} else {
- recordError(node->pragmaToken, QCoreApplication::translate("QQmlParser","Pragma requires a valid qualifier"));
+ recordError(node->pragmaToken, QCoreApplication::translate(
+ "QQmlParser", "Empty pragma found"));
return false;
}
@@ -1634,27 +1658,42 @@ bool IRBuilder::isRedundantNullInitializerForPropertyDeclaration(Property *prope
void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
{
+ using namespace QV4::CompiledData;
+
output.jsGenerator.stringTable.registerString(output.jsModule.fileName);
output.jsGenerator.stringTable.registerString(output.jsModule.finalUrl);
- QV4::CompiledData::Unit *jsUnit = nullptr;
+ Unit *jsUnit = nullptr;
// We may already have unit data if we're loading an ahead-of-time generated cache file.
if (output.javaScriptCompilationUnit.data) {
- jsUnit = const_cast<QV4::CompiledData::Unit *>(output.javaScriptCompilationUnit.data);
+ jsUnit = const_cast<Unit *>(output.javaScriptCompilationUnit.data);
output.javaScriptCompilationUnit.dynamicStrings = output.jsGenerator.stringTable.allStrings();
} else {
- QV4::CompiledData::Unit *createdUnit;
+ Unit *createdUnit;
jsUnit = createdUnit = output.jsGenerator.generateUnit();
// enable flag if we encountered pragma Singleton
for (Pragma *p : qAsConst(output.pragmas)) {
switch (p->type) {
- case Pragma::PragmaSingleton:
- createdUnit->flags |= QV4::CompiledData::Unit::IsSingleton;
+ case Pragma::Singleton:
+ createdUnit->flags |= Unit::IsSingleton;
break;
- case Pragma::PragmaStrict:
- createdUnit->flags |= QV4::CompiledData::Unit::IsStrict;
+ case Pragma::Strict:
+ createdUnit->flags |= Unit::IsStrict;
+ break;
+ case Pragma::ListPropertyAssignBehavior:
+ switch (p->listPropertyAssignBehavior) {
+ case Pragma::Replace:
+ createdUnit->flags |= Unit::ListPropertyAssignReplace;
+ break;
+ case Pragma::ReplaceIfNotDefault:
+ createdUnit->flags |= Unit::ListPropertyAssignReplaceIfNotDefault;
+ break;
+ case Pragma::Append:
+ // this is the default
+ break;
+ }
break;
}
}
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index fe6a9db750..036da04743 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -408,11 +408,24 @@ private:
struct Q_QMLCOMPILER_PRIVATE_EXPORT Pragma
{
- enum PragmaType {
- PragmaSingleton = 0x1,
- PragmaStrict = 0x2
+ enum PragmaType
+ {
+ Singleton,
+ Strict,
+ ListPropertyAssignBehavior,
+ };
+
+ enum ListPropertyAssignBehaviorValue
+ {
+ Append,
+ Replace,
+ ReplaceIfNotDefault,
};
- quint32 type;
+
+ PragmaType type;
+
+ // Could become a union with type as differentiator if necessary
+ ListPropertyAssignBehaviorValue listPropertyAssignBehavior;
QV4::CompiledData::Location location;
};