aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlcompiler.cpp14
-rw-r--r--src/qml/qml/qqmlcompiler_p.h2
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp14
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h2
-rw-r--r--src/qml/qml/qquicklistmodel.cpp5
-rw-r--r--tests/auto/qml/qqmlecmascript/data/enums.3.qml5
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h2
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp2
-rw-r--r--tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp6
9 files changed, 36 insertions, 16 deletions
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 5df02d0bc1..2bb99ddbab 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -2517,8 +2517,9 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
if (isIntProp) {
// Allow enum assignment to ints.
- int enumval = evaluateEnum(typeName, enumValue.toUtf8());
- if (enumval != -1) {
+ bool ok;
+ int enumval = evaluateEnum(typeName, enumValue.toUtf8(), &ok);
+ if (ok) {
v->type = Value::Literal;
v->value = QQmlScript::Variant((double)enumval);
*isAssignment = true;
@@ -2565,8 +2566,10 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
}
// Similar logic to above, but not knowing target property.
-int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue) const
+int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue, bool *ok) const
{
+ Q_ASSERT_X(ok, "QQmlCompiler::evaluateEnum", "ok must not be a null pointer");
+ *ok = false;
QQmlType *type = 0;
if (scope != QLatin1String("Qt")) {
unit->imports().resolveType(scope, &type, 0, 0, 0, 0);
@@ -2577,9 +2580,8 @@ int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray&
const QMetaObject *mo = type ? type->metaObject() : StaticQtMetaObject::get();
int i = mo->enumeratorCount();
while (i--) {
- bool ok;
- int v = mo->enumerator(i).keyToValue(enumValue.constData(), &ok);
- if (ok)
+ int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
+ if (*ok)
return v;
}
return -1;
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h
index 4b730c2e20..b919b53207 100644
--- a/src/qml/qml/qqmlcompiler_p.h
+++ b/src/qml/qml/qqmlcompiler_p.h
@@ -295,7 +295,7 @@ public:
static bool isAttachedPropertyName(const QHashedStringRef &);
static bool isSignalPropertyName(const QHashedStringRef &);
- int evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue) const; // for QQmlCustomParser::evaluateEnum
+ int evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue, bool *ok) const; // for QQmlCustomParser::evaluateEnum
const QMetaObject *resolveType(const QString& name) const; // for QQmlCustomParser::resolveType
int rewriteBinding(const QQmlScript::Variant& value, const QString& name); // for QQmlCustomParser::rewriteBinding
QString rewriteSignalHandler(const QQmlScript::Variant& value, const QString &name); // for QQmlCustomParser::rewriteSignalHandler
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index f020376360..7c7a2f5611 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -279,18 +279,22 @@ void QQmlCustomParser::error(const QQmlCustomParserNode& node, const QString& de
}
/*!
- If \a script is a simply enum expression (eg. Text.AlignLeft),
- returns the integer equivalent (eg. 1).
+ If \a script is a simple enum expression (eg. Text.AlignLeft),
+ returns the integer equivalent (eg. 1), and sets \a ok to true.
- Otherwise, returns -1.
+ Otherwise sets \a ok to false.
+
+ A valid \a ok must be provided, or the function will assert.
*/
-int QQmlCustomParser::evaluateEnum(const QByteArray& script) const
+int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
{
+ Q_ASSERT_X(ok, "QQmlCustomParser::evaluateEnum", "ok must not be a null pointer");
+ *ok = false;
int dot = script.indexOf('.');
if (dot == -1)
return -1;
- return compiler->evaluateEnum(QString::fromUtf8(script.left(dot)), script.mid(dot+1));
+ return compiler->evaluateEnum(QString::fromUtf8(script.left(dot)), script.mid(dot+1), ok);
}
/*!
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index 0207797ce9..b8cc9f7644 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -137,7 +137,7 @@ protected:
void error(const QQmlCustomParserProperty&, const QString& description);
void error(const QQmlCustomParserNode&, const QString& description);
- int evaluateEnum(const QByteArray&) const;
+ int evaluateEnum(const QByteArray&, bool *ok) const;
const QMetaObject *resolveType(const QString&) const;
diff --git a/src/qml/qml/qquicklistmodel.cpp b/src/qml/qml/qquicklistmodel.cpp
index 461d4d8610..52ef2ab61f 100644
--- a/src/qml/qml/qquicklistmodel.cpp
+++ b/src/qml/qml/qquicklistmodel.cpp
@@ -2229,8 +2229,9 @@ bool QQuickListModelParser::compileProperty(const QQmlCustomParserProperty &prop
d[0] = char(QQmlScript::Variant::Invalid); // marks empty list
} else {
QByteArray script = variant.asScript().toUtf8();
- int v = evaluateEnum(script);
- if (v<0) {
+ bool ok;
+ int v = evaluateEnum(script, &ok);
+ if (!ok) {
using namespace QQmlJS;
AST::Node *node = variant.asAST();
AST::StringLiteral *literal = 0;
diff --git a/tests/auto/qml/qqmlecmascript/data/enums.3.qml b/tests/auto/qml/qqmlecmascript/data/enums.3.qml
index c77d635a1e..fd3432fc9f 100644
--- a/tests/auto/qml/qqmlecmascript/data/enums.3.qml
+++ b/tests/auto/qml/qqmlecmascript/data/enums.3.qml
@@ -19,6 +19,9 @@ Item {
property int h: Namespace.MyQmlObject.EnumValue3
property int i: Namespace.MyQmlObject.EnumValue4
+ // -1 enum
+ property int j: MyQmlObject.EnumValue5
+
// Count the onChanged signals to see whether
// they're assigned as literals or via bindings
property int ac: 0
@@ -29,6 +32,7 @@ Item {
property int fc: 0
property int hc: 0
property int ic: 0
+ property int jc: 0
onAChanged: ac++
onBChanged: bc++
@@ -38,4 +42,5 @@ Item {
onFChanged: fc++
onHChanged: hc++
onIChanged: ic++
+ onJChanged: jc++
}
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index 8f3804a05b..ab44d5986e 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -111,7 +111,7 @@ public:
MyQmlObject(): myinvokableObject(0), m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13), m_intProperty(0), m_buttons(0) {}
enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 };
- enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3 };
+ enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3, EnumValue5 = -1 };
bool trueProperty() const { return true; }
bool falseProperty() const { return false; }
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index d344758147..c429ffaa4b 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -983,6 +983,7 @@ void tst_qqmlecmascript::enums()
QCOMPARE(object->property("f").toInt(), 3);
QCOMPARE(object->property("h").toInt(), 2);
QCOMPARE(object->property("i").toInt(), 3);
+ QCOMPARE(object->property("j").toInt(), -1);
// count of change signals
QCOMPARE(object->property("ac").toInt(), 0);
@@ -993,6 +994,7 @@ void tst_qqmlecmascript::enums()
QCOMPARE(object->property("fc").toInt(), 0);
QCOMPARE(object->property("hc").toInt(), 1); // namespace -> binding
QCOMPARE(object->property("ic").toInt(), 1); // namespace -> binding
+ QCOMPARE(object->property("jc").toInt(), 0);
delete object;
}
diff --git a/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp b/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
index 4c4aa4801f..89e88869e3 100644
--- a/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
+++ b/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
@@ -41,6 +41,7 @@
#include <qtest.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquicktext_p.h>
+#include <QtQuick/private/qquickanimation_p.h>
#include <QtQml/private/qqmlengine_p.h>
#include <QtQml/private/qquicklistmodel_p.h>
#include <QtQml/private/qqmlexpression_p.h>
@@ -228,6 +229,11 @@ void tst_qquicklistmodel::static_types_data()
<< QVariant(double(Qt::AlignBottom))
<< QString();
+ QTest::newRow("negative enum")
+ << "ListElement { foo: Animation.Infinite }"
+ << QVariant(double(QQuickAbstractAnimation::Infinite))
+ << QString();
+
QTest::newRow("role error")
<< "ListElement { foo: 1 } ListElement { foo: 'string' }"
<< QVariant()