diff options
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 56 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler_p.h | 4 | ||||
-rw-r--r-- | src/declarative/qml/qmlscriptparser.cpp | 3 |
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()); |