summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qmlcompiler.cpp56
-rw-r--r--src/declarative/qml/qmlcompiler_p.h4
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp3
3 files changed, 61 insertions, 2 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 53ea18e..9df9b40 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -2029,6 +2029,14 @@ bool QmlCompiler::buildPropertyLiteralAssignment(QmlParser::Property *prop,
if (v->value.isScript()) {
+ //optimization for <Type>.<EnumValue> enum assignments
+ bool isEnumAssignment = false;
+ COMPILE_CHECK(testQualifiedEnumAssignment(obj->metaObject()->property(prop->index), obj, v, &isEnumAssignment));
+ if (isEnumAssignment) {
+ v->type = Value::Literal;
+ return true;
+ }
+
COMPILE_CHECK(buildBinding(v, prop, ctxt));
v->type = Value::PropertyBinding;
@@ -2043,6 +2051,50 @@ bool QmlCompiler::buildPropertyLiteralAssignment(QmlParser::Property *prop,
return true;
}
+bool QmlCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop,
+ QmlParser::Object *obj,
+ QmlParser::Value *v,
+ bool *isAssignment)
+{
+ *isAssignment = false;
+ if (!prop.isEnumType())
+ return true;
+
+ if (!prop.isWritable())
+ COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
+
+ QString string = v->value.asString();
+ if (!string.at(0).isUpper())
+ return true;
+
+ QStringList parts = string.split(QLatin1Char('.'));
+ if (parts.count() != 2)
+ return true;
+
+ QString typeName = parts.at(0);
+ QmlType *type = 0;
+ QmlEnginePrivate::get(engine)->resolveType(unit->imports, typeName.toUtf8(),
+ &type, 0, 0, 0, 0);
+
+ if (!type || obj->typeName != type->qmlTypeName())
+ return true;
+
+ QString enumValue = parts.at(1);
+ int value;
+ if (prop.isFlagType()) {
+ value = prop.enumerator().keysToValue(enumValue.toUtf8().constData());
+ } else
+ value = prop.enumerator().keyToValue(enumValue.toUtf8().constData());
+ if (value == -1)
+ return true;
+
+ v->type = Value::Literal;
+ v->value = QmlParser::Variant(enumValue);
+ *isAssignment = true;
+
+ return true;
+}
+
// Ensures that the dynamic meta specification on obj is valid
bool QmlCompiler::checkDynamicMeta(QmlParser::Object *obj)
{
@@ -2344,10 +2396,10 @@ bool QmlCompiler::compileAlias(QMetaObjectBuilder &builder,
QStringList alias = astNodeToStringList(node);
if (alias.count() != 1 && alias.count() != 2)
- COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QmlCompiler","Invalid alias location"));
+ COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QmlCompiler","Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>"));
if (!compileState.ids.contains(alias.at(0)))
- COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QmlCompiler","Invalid alias location"));
+ COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QmlCompiler","Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0)));
Object *idObject = compileState.ids[alias.at(0)];
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index d734a12..108505f 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -219,6 +219,10 @@ private:
bool doesPropertyExist(QmlParser::Property *prop, QmlParser::Object *obj);
bool testLiteralAssignment(const QMetaProperty &prop,
QmlParser::Value *value);
+ bool testQualifiedEnumAssignment(const QMetaProperty &prop,
+ QmlParser::Object *obj,
+ QmlParser::Value *value,
+ bool *isAssignment);
enum DynamicMetaMode { IgnoreAliases, ResolveAliases, ForceCreation };
bool mergeDynamicMetaProperties(QmlParser::Object *obj);
bool buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode);
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index 35234ec..a24ef51 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -600,6 +600,9 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
if (node->expression) { // default value
property.defaultValue = new Property;
property.defaultValue->parent = _stateStack.top().object;
+ property.defaultValue->location =
+ location(node->expression->firstSourceLocation(),
+ node->expression->lastSourceLocation());
Value *value = new Value;
value->location = location(node->expression->firstSourceLocation(),
node->expression->lastSourceLocation());