aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativecompiler.cpp
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2011-11-02 10:21:37 +1000
committerQt by Nokia <qt-info@nokia.com>2011-12-01 02:40:06 +0100
commitfdbdbbdd4ff05d1ceb7667227db5b14687a77c96 (patch)
tree6f738ccc1d784a8dc18bff15cdbcb8e6973c48e8 /src/declarative/qml/qdeclarativecompiler.cpp
parentf304dd6fbb9d901c0a72609dc3c384eab4935f93 (diff)
Add support for assigning literal value to sequence property
It is a language semantic that we allow clients to assign a single value to a sequence/list property (assuming that the types match). Now that we support sequence types, this commit adds support for this semantic by determining whether the built-in type of the literal corresponds to the associated sequence (eg, int for QList<int>, qreal for QList<qreal>, bool for QList<bool>, QString for QStringList etc). Similarly, some value types can be constructed from literal string values (via string converters) and these need to be handled also. Task-number: QTBUG-18062 Task-number: QTBUG-21770 Change-Id: Iacd91b2af122cd8f20b7df2fa6056a7d7c52bf53 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/declarative/qml/qdeclarativecompiler.cpp')
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 9b80c2cad1..3b47e208eb 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -72,6 +72,12 @@
#include <QtCore/qdebug.h>
#include <QtCore/qdatetime.h>
+Q_DECLARE_METATYPE(QList<int>)
+Q_DECLARE_METATYPE(QList<qreal>)
+Q_DECLARE_METATYPE(QList<bool>)
+Q_DECLARE_METATYPE(QList<QString>)
+Q_DECLARE_METATYPE(QList<QUrl>)
+
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
@@ -235,6 +241,9 @@ bool QDeclarativeCompiler::testLiteralAssignment(QDeclarativeScript::Property *p
case QVariant::String:
if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected"));
break;
+ case QVariant::StringList: // we expect a string literal. A string list is not a literal assignment.
+ if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string or string list expected"));
+ break;
case QVariant::ByteArray:
if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: byte array expected"));
break;
@@ -344,6 +353,41 @@ bool QDeclarativeCompiler::testLiteralAssignment(QDeclarativeScript::Property *p
break;
default:
{
+ // check if assigning a literal value to a list property.
+ // in each case, check the singular, since an Array of the specified type
+ // will not go via this literal assignment codepath.
+ if (type == qMetaTypeId<QList<qreal> >()) {
+ if (!v->value.isNumber()) {
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: real or array of reals expected"));
+ }
+ break;
+ } else if (type == qMetaTypeId<QList<int> >()) {
+ bool ok = v->value.isNumber();
+ if (ok) {
+ double n = v->value.asNumber();
+ if (double(int(n)) != n)
+ ok = false;
+ }
+ if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: int or array of ints expected"));
+ break;
+ } else if (type == qMetaTypeId<QList<bool> >()) {
+ if (!v->value.isBoolean()) {
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: bool or array of bools expected"));
+ }
+ break;
+ } else if (type == qMetaTypeId<QList<QString> >()) { // we expect a string literal. A string list is not a literal assignment.
+ if (!v->value.isString()) {
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: string or array of strings expected"));
+ }
+ break;
+ } else if (type == qMetaTypeId<QList<QUrl> >()) {
+ if (!v->value.isString()) {
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: url or array of urls expected"));
+ }
+ break;
+ }
+
+ // otherwise, check for existence of string converter to custom type
QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type);
if (!converter)
COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName((QVariant::Type)type))));
@@ -440,6 +484,14 @@ void QDeclarativeCompiler::genLiteralAssignment(QDeclarativeScript::Property *pr
output->addInstruction(instr);
}
break;
+ case QVariant::StringList:
+ {
+ Instruction::StoreStringList instr;
+ instr.propertyIndex = prop->index;
+ instr.value = output->indexForString(v->value.asString());
+ output->addInstruction(instr);
+ }
+ break;
case QVariant::ByteArray:
{
Instruction::StoreByteArray instr;
@@ -638,6 +690,43 @@ void QDeclarativeCompiler::genLiteralAssignment(QDeclarativeScript::Property *pr
break;
default:
{
+ // generate single literal value assignment to a list property if required
+ if (type == qMetaTypeId<QList<qreal> >()) {
+ Instruction::StoreDoubleQList instr;
+ instr.propertyIndex = prop->index;
+ instr.value = v->value.asNumber();
+ output->addInstruction(instr);
+ break;
+ } else if (type == qMetaTypeId<QList<int> >()) {
+ Instruction::StoreIntegerQList instr;
+ instr.propertyIndex = prop->index;
+ instr.value = int(v->value.asNumber());
+ output->addInstruction(instr);
+ break;
+ } else if (type == qMetaTypeId<QList<bool> >()) {
+ Instruction::StoreBoolQList instr;
+ bool b = v->value.asBoolean();
+ instr.propertyIndex = prop->index;
+ instr.value = b;
+ output->addInstruction(instr);
+ break;
+ } else if (type == qMetaTypeId<QList<QUrl> >()) {
+ Instruction::StoreUrlQList instr;
+ QString string = v->value.asString();
+ QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string));
+ instr.propertyIndex = prop->index;
+ instr.value = output->indexForUrl(u);
+ output->addInstruction(instr);
+ break;
+ } else if (type == qMetaTypeId<QList<QString> >()) {
+ Instruction::StoreStringQList instr;
+ instr.propertyIndex = prop->index;
+ instr.value = output->indexForString(v->value.asString());
+ output->addInstruction(instr);
+ break;
+ }
+
+ // otherwise, generate custom type literal assignment
Instruction::AssignCustomType instr;
instr.propertyIndex = prop->index;
instr.primitive = output->indexForString(v->value.asString());