diff options
author | Chris Adams <christopher.adams@nokia.com> | 2011-11-02 10:21:37 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-01 02:40:06 +0100 |
commit | fdbdbbdd4ff05d1ceb7667227db5b14687a77c96 (patch) | |
tree | 6f738ccc1d784a8dc18bff15cdbcb8e6973c48e8 /src/declarative/qml/qdeclarativecompiler.cpp | |
parent | f304dd6fbb9d901c0a72609dc3c384eab4935f93 (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.cpp | 89 |
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()); |