From f98ebe34e17fcf955a77b35b098b5be81dc6c7d8 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 24 Nov 2011 14:43:09 +1000 Subject: [PATCH] Rewrite Connections signal handlers at compile time. Task-number: QTBUG-22726 Change-Id: I039d54661bbf7d44912c894bf0cc1d70023a9187 Reviewed-by: Aaron Kennedy --- src/declarative/qml/qdeclarativecompiler.cpp | 6 ++++++ src/declarative/qml/qdeclarativecompiler_p.h | 1 + src/declarative/qml/qdeclarativecustomparser.cpp | 9 +++++++++ src/declarative/qml/qdeclarativecustomparser_p.h | 1 + src/declarative/qml/qdeclarativeexpression.cpp | 6 ++++++ src/declarative/qml/qdeclarativeexpression_p.h | 2 ++ src/declarative/util/qdeclarativeconnections.cpp | 18 +++++++++++++----- 7 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index a2eae79..9b80c2c 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -2494,6 +2494,12 @@ int QDeclarativeCompiler::rewriteBinding(const QDeclarativeScript::Variant& valu return output->indexForString(rewrite); } +QString QDeclarativeCompiler::rewriteSignalHandler(const QString &handler, const QString &name) +{ + QDeclarativeRewrite::RewriteSignalHandler rewriteSignalHandler; + return rewriteSignalHandler(handler, name); +} + // Ensures that the dynamic meta specification on obj is valid bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeScript::Object *obj) { diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index 1ee5afb..9a67f32 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -280,6 +280,7 @@ public: int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum const QMetaObject *resolveType(const QString& name) const; // for QDeclarativeCustomParser::resolveType int rewriteBinding(const QDeclarativeScript::Variant& value, const QString& name); // for QDeclarativeCustomParser::rewriteBinding + QString rewriteSignalHandler(const QString &handler, const QString &name); // for QDeclarativeCustomParser::rewriteSignalHandler private: typedef QDeclarativeCompiledData::Instruction Instruction; diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp index 9d643d3..788a670 100644 --- a/src/declarative/qml/qdeclarativecustomparser.cpp +++ b/src/declarative/qml/qdeclarativecustomparser.cpp @@ -307,4 +307,13 @@ QDeclarativeBinding::Identifier QDeclarativeCustomParser::rewriteBinding(const Q return compiler->rewriteBinding(value, name); } +/*! + Returns a rewritten \a handler. \a name + is used as the name of the rewritten function. +*/ +QString QDeclarativeCustomParser::rewriteSignalHandler(const QString &handler, const QString &name) +{ + return compiler->rewriteSignalHandler(handler, name); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h index 83e1319..5a9220a 100644 --- a/src/declarative/qml/qdeclarativecustomparser_p.h +++ b/src/declarative/qml/qdeclarativecustomparser_p.h @@ -143,6 +143,7 @@ protected: const QMetaObject *resolveType(const QString&) const; QDeclarativeBinding::Identifier rewriteBinding(const QDeclarativeScript::Variant&, const QString&); + QString rewriteSignalHandler(const QString&, const QString&); private: QList exceptions; diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 0895ffa..bf2552d 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -158,6 +158,12 @@ QDeclarativeExpressionPrivate::evalFunction(QDeclarativeContextData *ctxt, QObje return qPersistentNew(v8::Local::Cast(result)); } +QDeclarativeExpression *QDeclarativeExpressionPrivate::create(QDeclarativeContextData *ctxt, QObject *object, const QString &expr, bool isRewritten, + const QString &url, int lineNumber) +{ + return new QDeclarativeExpression(ctxt, object, expr, isRewritten, url, lineNumber, *new QDeclarativeExpressionPrivate); +} + /*! \class QDeclarativeExpression \since 4.7 diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index bfe031f..7a2bda2 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -193,6 +193,8 @@ public: static v8::Persistent evalFunction(QDeclarativeContextData *ctxt, QObject *scope, const QString &code, const QString &filename, int line, v8::Persistent *qmlscope = 0); + static QDeclarativeExpression *create(QDeclarativeContextData *, QObject *, const QString &, bool, + const QString &, int); bool expressionFunctionValid:1; bool extractExpressionFromFunction:1; diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp index aa944f3..ee2c6ed 100644 --- a/src/declarative/util/qdeclarativeconnections.cpp +++ b/src/declarative/util/qdeclarativeconnections.cpp @@ -41,7 +41,7 @@ #include "qdeclarativeconnections_p.h" -#include +#include #include #include #include @@ -225,7 +225,7 @@ QDeclarativeConnectionsParser::compile(const QList(value); if (v.isScript()) { ds << propName; - ds << v.asScript(); + ds << rewriteSignalHandler(v.asScript(), propName); ds << propLine; } else { error(props.at(ii), QDeclarativeConnections::tr("Connections: script expected")); @@ -265,10 +265,18 @@ void QDeclarativeConnections::connectSignals() if (prop.isValid() && (prop.type() & QDeclarativeProperty::SignalProperty)) { QDeclarativeBoundSignal *signal = new QDeclarativeBoundSignal(target(), prop.method(), this); - QDeclarativeExpression *expression = new QDeclarativeExpression(qmlContext(this), 0, script); + + QString location; + QDeclarativeContextData *ctxtdata = 0; QDeclarativeData *ddata = QDeclarativeData::get(this); - if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) - expression->setSourceLocation(ddata->outerContext->url.toString(), line); + if (ddata) { + ctxtdata = ddata->outerContext; + if (ctxtdata && !ctxtdata->url.isEmpty()) + location = ddata->outerContext->url.toString(); + } + + QDeclarativeExpression *expression = ctxtdata ? + QDeclarativeExpressionPrivate::create(ctxtdata, 0, script, true, location, line) : 0; signal->setExpression(expression); d->boundsignals += signal; } else { -- 1.7.2.5