From 97c21311a1de5bca7b97a0a1ae81bb651afa41c8 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 10 Jan 2014 14:46:33 +0100 Subject: [new compiler] Preliminary support for script string properties These should later get resolved at compile time, like enum assignments. Change-Id: I2f40c8d13330d2a101f79af12fe708f466eef225 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4compileddata.cpp | 51 ++++++++++++++++++++++++++++++++++++ src/qml/compiler/qv4compileddata_p.h | 1 + src/qml/qml/qqmlbinding.cpp | 3 ++- src/qml/qml/qqmlobjectcreator.cpp | 19 ++++++++++++++ src/qml/qml/qqmlscriptstring.h | 2 ++ 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index ce0c7abf9e..9eac0e678d 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -193,6 +193,57 @@ QString Binding::valueAsString(const Unit *unit) const return QString(); } +//reverse of Lexer::singleEscape() +static QString escapedString(const QString &string) +{ + QString tmp = QLatin1String("\""); + for (int i = 0; i < string.length(); ++i) { + const QChar &c = string.at(i); + switch (c.unicode()) { + case 0x08: + tmp += QLatin1String("\\b"); + break; + case 0x09: + tmp += QLatin1String("\\t"); + break; + case 0x0A: + tmp += QLatin1String("\\n"); + break; + case 0x0B: + tmp += QLatin1String("\\v"); + break; + case 0x0C: + tmp += QLatin1String("\\f"); + break; + case 0x0D: + tmp += QLatin1String("\\r"); + break; + case 0x22: + tmp += QLatin1String("\\\""); + break; + case 0x27: + tmp += QLatin1String("\\\'"); + break; + case 0x5C: + tmp += QLatin1String("\\\\"); + break; + default: + tmp += c; + break; + } + } + tmp += QLatin1Char('\"'); + return tmp; +} + +QString Binding::valueAsScriptString(const Unit *unit) const +{ + if (type == Type_String) + return escapedString(unit->stringAt(stringIndex)); + else + return valueAsString(unit); +} + } } diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 91033b02ea..c069111b91 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -296,6 +296,7 @@ struct Binding Location location; QString valueAsString(const Unit *unit) const; + QString valueAsScriptString(const Unit *unit) const; double valueAsNumber() const { if (type == Type_Number) diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 9e2fb07066..9b83feebb4 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -146,7 +146,8 @@ QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlConte typeData->release(); } - } + } else + code = scriptPrivate->script; setNotifyOnValueChanged(true); QQmlAbstractExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context)); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index e880289d9d..15f57f0761 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -53,6 +53,7 @@ #include #include #include +#include QT_USE_NAMESPACE @@ -649,6 +650,24 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI return true; } + // ### resolve this at compile time + if (property && property->propType == qMetaTypeId()) { + QQmlScriptString ss(binding->valueAsScriptString(&qmlUnit->header), context->asQQmlContext(), _scopeObject); + ss.d.data()->bindingId = QQmlBinding::Invalid; + ss.d.data()->lineNumber = binding->location.line; + ss.d.data()->columnNumber = binding->location.column; + ss.d.data()->isStringLiteral = binding->type == QV4::CompiledData::Binding::Type_String; + ss.d.data()->isNumberLiteral = binding->type == QV4::CompiledData::Binding::Type_Number; + ss.d.data()->numberValue = binding->valueAsNumber(); + + QQmlPropertyPrivate::WriteFlags propertyWriteFlags = QQmlPropertyPrivate::BypassInterceptor | + QQmlPropertyPrivate::RemoveBindingOnAliasWrite; + int propertyWriteStatus = -1; + void *argv[] = { &ss, 0, &propertyWriteStatus, &propertyWriteFlags }; + QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + return true; + } + QObject *createdSubObject = 0; if (binding->type == QV4::CompiledData::Binding::Type_Object) { createdSubObject = createInstance(binding->value.objectIndex, _qobject); diff --git a/src/qml/qml/qqmlscriptstring.h b/src/qml/qml/qqmlscriptstring.h index 5421ef95fc..b192be8b77 100644 --- a/src/qml/qml/qqmlscriptstring.h +++ b/src/qml/qml/qqmlscriptstring.h @@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE class QObject; class QQmlContext; class QQmlScriptStringPrivate; +class QmlObjectCreator; class Q_QML_EXPORT QQmlScriptString { public: @@ -74,6 +75,7 @@ private: QQmlScriptString(const QString &script, QQmlContext *context, QObject *scope); QSharedDataPointer d; + friend class QmlObjectCreator; friend class QQmlScriptStringPrivate; friend class QQmlVME; friend class QQmlExpression; -- cgit v1.2.3