aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp11
-rw-r--r--tests/auto/qml/qqmllanguage/data/customParserEvaluateEnum.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp78
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h8
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp9
5 files changed, 108 insertions, 3 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 56e5d7183d..cedbc92f8e 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -947,8 +947,9 @@ void QQmlCodeGenerator::setBindingValue(QV4::CompiledData::Binding *binding, QQm
if (_propertyDeclaration && (_propertyDeclaration->flags & QV4::CompiledData::Property::IsReadOnly))
binding->flags |= QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration;
- if (QQmlJS::AST::ExpressionStatement *stmt = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement *>(statement)) {
- QQmlJS::AST::ExpressionNode *expr = stmt->expression;
+ QQmlJS::AST::ExpressionStatement *exprStmt = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement *>(statement);
+ if (exprStmt) {
+ QQmlJS::AST::ExpressionNode * const expr = exprStmt->expression;
if (QQmlJS::AST::StringLiteral *lit = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(expr)) {
binding->type = QV4::CompiledData::Binding::Type_String;
binding->stringIndex = registerString(lit->value.toString());
@@ -982,7 +983,11 @@ void QQmlCodeGenerator::setBindingValue(QV4::CompiledData::Binding *binding, QQm
expr->disableAcceleratedLookups = false;
const int index = bindingsTarget()->functionsAndExpressions->append(expr);
binding->value.compiledScriptIndex = index;
- binding->stringIndex = registerString(asStringRef(statement).toString());
+
+ QQmlJS::AST::Node *nodeForString = statement;
+ if (exprStmt)
+ nodeForString = exprStmt->expression;
+ binding->stringIndex = registerString(asStringRef(nodeForString).toString());
}
}
diff --git a/tests/auto/qml/qqmllanguage/data/customParserEvaluateEnum.qml b/tests/auto/qml/qqmllanguage/data/customParserEvaluateEnum.qml
new file mode 100644
index 0000000000..7583f7041b
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/customParserEvaluateEnum.qml
@@ -0,0 +1,5 @@
+import Test 1.0
+import QtQml 2.0
+MyCustomParserWithEnumType {
+ foo: MyEnum1Class.A_13;
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index 98a803a594..b18e6133cb 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -68,6 +68,7 @@ void registerTypes()
qmlRegisterType<MySubclass>("Test",1,0,"MySubclass");
qmlRegisterCustomType<MyCustomParserType>("Test", 1, 0, "MyCustomParserType", new MyCustomParserTypeParser);
+ qmlRegisterCustomType<MyCustomParserType>("Test", 1, 0, "MyCustomParserWithEnumType", new EnumSupportingCustomParser);
qmlRegisterTypeNotAvailable("Test",1,0,"UnavailableType", "UnavailableType is unavailable for testing");
@@ -177,3 +178,80 @@ void CustomBinding::componentComplete()
QQmlPropertyPrivate::setBinding(property, binding);
}
}
+
+
+QByteArray EnumSupportingCustomParser::compile(const QList<QQmlCustomParserProperty> &props)
+{
+ if (props.count() != 1) {
+ error(QStringLiteral("Custom parser invoked incorrectly for unit test"));
+ return QByteArray();
+ }
+ QQmlCustomParserProperty prop = props.first();
+ if (prop.name() != QStringLiteral("foo")) {
+ error(QStringLiteral("Custom parser invoked with the wrong property name"));
+ return QByteArray();
+ }
+
+ if (prop.assignedValues().count() != 1) {
+ error(QStringLiteral("Custom parser invoked with the wrong property values. Expected only one."));
+ return QByteArray();
+ }
+
+ QVariant firstValue = prop.assignedValues().first();
+ if (firstValue.userType() != qMetaTypeId<QQmlScript::Variant>()) {
+ error(QStringLiteral("Custom parser invoked with the wrong property value. Expected value instead of object or so"));
+ return QByteArray();
+ }
+ QQmlScript::Variant value = qvariant_cast<QQmlScript::Variant>(firstValue);
+ if (!value.isScript()) {
+ error(QStringLiteral("Custom parser invoked with the wrong property value. Expected script that evaluates to enum"));
+ return QByteArray();
+ }
+ QByteArray script = value.asScript().toUtf8();
+ bool ok;
+ int v = evaluateEnum(script, &ok);
+ if (!ok) {
+ error(QStringLiteral("Custom parser invoked with the wrong property value. Script did not evaluate to enum"));
+ return QByteArray();
+ }
+ if (v != MyEnum1Class::A_13) {
+ error(QStringLiteral("Custom parser invoked with the wrong property value. Enum value is not the expected value."));
+ return QByteArray();
+ }
+
+ return QByteArray();
+}
+
+QByteArray EnumSupportingCustomParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
+{
+ Q_UNUSED(qmlUnit)
+
+ if (bindings.count() != 1) {
+ error(bindings.first(), QStringLiteral("Custom parser invoked incorrectly for unit test"));
+ return QByteArray();
+ }
+
+ const QV4::CompiledData::Binding *binding = bindings.first();
+ if (qmlUnit->header.stringAt(binding->propertyNameIndex) != QStringLiteral("foo")) {
+ error(binding, QStringLiteral("Custom parser invoked with the wrong property name"));
+ return QByteArray();
+ }
+
+ if (binding->type != QV4::CompiledData::Binding::Type_Script) {
+ error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Expected script that evaluates to enum"));
+ return QByteArray();
+ }
+ QByteArray script = qmlUnit->header.stringAt(binding->stringIndex).toUtf8();
+ bool ok;
+ int v = evaluateEnum(script, &ok);
+ if (!ok) {
+ error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Script did not evaluate to enum"));
+ return QByteArray();
+ }
+ if (v != MyEnum1Class::A_13) {
+ error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Enum value is not the expected value."));
+ return QByteArray();
+ }
+
+ return QByteArray();
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 0416258075..27ad340256 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -723,6 +723,14 @@ public:
void setCustomData(QObject *, const QByteArray &) {}
};
+class EnumSupportingCustomParser : public QQmlCustomParser
+{
+public:
+ QByteArray compile(const QList<QQmlCustomParserProperty> &props);
+ QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
+ void setCustomData(QObject *, const QByteArray &) {}
+};
+
class MyParserStatus : public QObject, public QQmlParserStatus
{
Q_INTERFACES(QQmlParserStatus)
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 34270bf1de..826bd124b7 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -215,6 +215,7 @@ private slots:
void compositeSingletonRegistered();
void customParserBindingScopes();
+ void customParserEvaluateEnum();
private:
QQmlEngine engine;
@@ -3547,6 +3548,14 @@ void tst_qqmllanguage::customParserBindingScopes()
QCOMPARE(child->property("testProperty").toInt(), 42);
}
+void tst_qqmllanguage::customParserEvaluateEnum()
+{
+ QQmlComponent component(&engine, testFile("customParserEvaluateEnum.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"