diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-10-11 13:59:46 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-10-13 14:03:41 +0200 |
commit | f2a15482ddd289a36b04316a2b6ebed83eb017c5 (patch) | |
tree | b2588d056ae5a80ac4b726571f6e1e3b0e362f8c /src/qml/compiler | |
parent | 4e645c7c33b03adf2d9161b00d00267add0aa373 (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.cpp | 67 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 21 |
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; }; |