aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-01-10 14:46:33 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-17 08:10:07 +0100
commit97c21311a1de5bca7b97a0a1ae81bb651afa41c8 (patch)
tree4bc8403d7fb4cfa367acc2fb848bdbeec45480a8
parentb92f33cddd3f2c4e35a9237791135dcc47a26985 (diff)
[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 <lars.knoll@digia.com>
-rw-r--r--src/qml/compiler/qv4compileddata.cpp51
-rw-r--r--src/qml/compiler/qv4compileddata_p.h1
-rw-r--r--src/qml/qml/qqmlbinding.cpp3
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp19
-rw-r--r--src/qml/qml/qqmlscriptstring.h2
5 files changed, 75 insertions, 1 deletions
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 <private/qqmlcomponentattached_p.h>
#include <private/qqmlcomponent_p.h>
#include <private/qqmlcustomparser_p.h>
+#include <private/qqmlscriptstring_p.h>
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>()) {
+ 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<QQmlScriptStringPrivate> d;
+ friend class QmlObjectCreator;
friend class QQmlScriptStringPrivate;
friend class QQmlVME;
friend class QQmlExpression;