diff options
Diffstat (limited to 'src/declarative/qml/qdeclarativeexpression.cpp')
-rw-r--r-- | src/declarative/qml/qdeclarativeexpression.cpp | 982 |
1 files changed, 0 insertions, 982 deletions
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp deleted file mode 100644 index 1a4c486931..0000000000 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ /dev/null @@ -1,982 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdeclarativeexpression.h" -#include "qdeclarativeexpression_p.h" - -#include "qdeclarativeengine_p.h" -#include "qdeclarativecontext_p.h" -#include "qdeclarativerewrite_p.h" -#include "qdeclarativescriptstring_p.h" -#include "qdeclarativecompiler_p.h" - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e) -{ - if (!e) return false; - - if (e->inProgressCreations == 0) return false; // Not in construction - - if (prevError) return true; // Already in error chain - - prevError = &e->erroredBindings; - nextError = e->erroredBindings; - e->erroredBindings = this; - if (nextError) nextError->prevError = &nextError; - - return true; -} - -QDeclarativeJavaScriptExpression::QDeclarativeJavaScriptExpression(VTable *v) -: m_vtable(v) -{ -} - -QDeclarativeJavaScriptExpression::~QDeclarativeJavaScriptExpression() -{ - clearGuards(); -} - -static QDeclarativeJavaScriptExpression::VTable QDeclarativeExpressionPrivate_jsvtable = { - QDeclarativeExpressionPrivate::expressionIdentifier, - QDeclarativeExpressionPrivate::expressionChanged -}; - -QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate() -: QDeclarativeJavaScriptExpression(&QDeclarativeExpressionPrivate_jsvtable), - expressionFunctionValid(true), expressionFunctionRewritten(false), - extractExpressionFromFunction(false), line(-1), dataRef(0) -{ -} - -QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() -{ - qPersistentDispose(v8qmlscope); - qPersistentDispose(v8function); - if (dataRef) dataRef->release(); - dataRef = 0; -} - -void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, - QObject *me) -{ - expression = expr; - - QDeclarativeAbstractExpression::setContext(ctxt); - setScopeObject(me); - expressionFunctionValid = false; - expressionFunctionRewritten = false; -} - -void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, v8::Handle<v8::Function> func, - QObject *me) -{ - QDeclarativeAbstractExpression::setContext(ctxt); - setScopeObject(me); - - v8function = qPersistentNew<v8::Function>(func); - setUseSharedContext(false); - expressionFunctionValid = true; - expressionFunctionRewritten = false; - extractExpressionFromFunction = true; -} - -void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, - bool isRewritten, QObject *me, const QString &srcUrl, - int lineNumber, int columnNumber) -{ - url = srcUrl; - line = lineNumber; - column = columnNumber; - - expression = expr; - - expressionFunctionValid = false; - expressionFunctionRewritten = isRewritten; - - QDeclarativeAbstractExpression::setContext(ctxt); - setScopeObject(me); -} - -void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QByteArray &expr, - bool isRewritten, QObject *me, const QString &srcUrl, - int lineNumber, int columnNumber) -{ - url = srcUrl; - line = lineNumber; - column = columnNumber; - - if (isRewritten) { - expressionFunctionValid = true; - expressionFunctionRewritten = true; - v8function = evalFunction(ctxt, me, expr.constData(), expr.length(), - srcUrl, lineNumber, &v8qmlscope); - setUseSharedContext(false); - - expressionUtf8 = expr; - } else { - expression = QString::fromUtf8(expr); - - expressionFunctionValid = false; - expressionFunctionRewritten = isRewritten; - } - - QDeclarativeAbstractExpression::setContext(ctxt); - setScopeObject(me); -} - -// Callee owns the persistent handle -v8::Persistent<v8::Function> -QDeclarativeExpressionPrivate::evalFunction(QDeclarativeContextData *ctxt, QObject *scope, - const char *code, int codeLength, - const QString &filename, int line, - v8::Persistent<v8::Object> *qmlscope) -{ - QDeclarativeEngine *engine = ctxt->engine; - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - - v8::HandleScope handle_scope; - v8::Context::Scope ctxtscope(ep->v8engine()->context()); - - v8::TryCatch tc; - v8::Local<v8::Object> scopeobject = ep->v8engine()->qmlScope(ctxt, scope); - v8::Local<v8::Script> script = ep->v8engine()->qmlModeCompile(code, codeLength, filename, line); - if (tc.HasCaught()) { - QDeclarativeError error; - error.setDescription(QLatin1String("Exception occurred during function compilation")); - error.setLine(line); - error.setUrl(QUrl::fromLocalFile(filename)); - v8::Local<v8::Message> message = tc.Message(); - if (!message.IsEmpty()) - QDeclarativeExpressionPrivate::exceptionToError(message, error); - ep->warning(error); - return v8::Persistent<v8::Function>(); - } - v8::Local<v8::Value> result = script->Run(scopeobject); - if (tc.HasCaught()) { - QDeclarativeError error; - error.setDescription(QLatin1String("Exception occurred during function evaluation")); - error.setLine(line); - error.setUrl(QUrl::fromLocalFile(filename)); - v8::Local<v8::Message> message = tc.Message(); - if (!message.IsEmpty()) - QDeclarativeExpressionPrivate::exceptionToError(message, error); - ep->warning(error); - return v8::Persistent<v8::Function>(); - } - if (qmlscope) *qmlscope = qPersistentNew<v8::Object>(scopeobject); - return qPersistentNew<v8::Function>(v8::Local<v8::Function>::Cast(result)); -} - -// Callee owns the persistent handle -v8::Persistent<v8::Function> -QDeclarativeExpressionPrivate::evalFunction(QDeclarativeContextData *ctxt, QObject *scope, - const QString &code, const QString &filename, int line, - v8::Persistent<v8::Object> *qmlscope) -{ - QDeclarativeEngine *engine = ctxt->engine; - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - - v8::HandleScope handle_scope; - v8::Context::Scope ctxtscope(ep->v8engine()->context()); - - v8::TryCatch tc; - v8::Local<v8::Object> scopeobject = ep->v8engine()->qmlScope(ctxt, scope); - v8::Local<v8::Script> script = ep->v8engine()->qmlModeCompile(code, filename, line); - if (tc.HasCaught()) { - QDeclarativeError error; - error.setDescription(QLatin1String("Exception occurred during function compilation")); - error.setLine(line); - error.setUrl(QUrl::fromLocalFile(filename)); - v8::Local<v8::Message> message = tc.Message(); - if (!message.IsEmpty()) - QDeclarativeExpressionPrivate::exceptionToError(message, error); - ep->warning(error); - return v8::Persistent<v8::Function>(); - } - v8::Local<v8::Value> result = script->Run(scopeobject); - if (tc.HasCaught()) { - QDeclarativeError error; - error.setDescription(QLatin1String("Exception occurred during function evaluation")); - error.setLine(line); - error.setUrl(QUrl::fromLocalFile(filename)); - v8::Local<v8::Message> message = tc.Message(); - if (!message.IsEmpty()) - QDeclarativeExpressionPrivate::exceptionToError(message, error); - ep->warning(error); - return v8::Persistent<v8::Function>(); - } - if (qmlscope) *qmlscope = qPersistentNew<v8::Object>(scopeobject); - return qPersistentNew<v8::Function>(v8::Local<v8::Function>::Cast(result)); -} - -QDeclarativeExpression * -QDeclarativeExpressionPrivate::create(QDeclarativeContextData *ctxt, QObject *object, - const QString &expr, bool isRewritten, - const QString &url, int lineNumber, int columnNumber) -{ - return new QDeclarativeExpression(ctxt, object, expr, isRewritten, url, lineNumber, columnNumber, *new QDeclarativeExpressionPrivate); -} - -/*! - \class QDeclarativeExpression - \since 4.7 - \brief The QDeclarativeExpression class evaluates JavaScript in a QML context. - - For example, given a file \c main.qml like this: - - \qml - import QtQuick 2.0 - - Item { - width: 200; height: 200 - } - \endqml - - The following code evaluates a JavaScript expression in the context of the - above QML: - - \code - QDeclarativeEngine *engine = new QDeclarativeEngine; - QDeclarativeComponent component(engine, QUrl::fromLocalFile("main.qml")); - - QObject *myObject = component.create(); - QDeclarativeExpression *expr = new QDeclarativeExpression(engine->rootContext(), myObject, "width * 2"); - int result = expr->evaluate().toInt(); // result = 400 - \endcode -*/ - -/*! - Create an invalid QDeclarativeExpression. - - As the expression will not have an associated QDeclarativeContext, this will be a - null expression object and its value will always be an invalid QVariant. - */ -QDeclarativeExpression::QDeclarativeExpression() -: QObject(*new QDeclarativeExpressionPrivate, 0) -{ -} - -/*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, - QObject *object, const QString &expr, bool isRewritten, - const QString &url, int lineNumber, int columnNumber, - QDeclarativeExpressionPrivate &dd) -: QObject(dd, 0) -{ - Q_D(QDeclarativeExpression); - d->init(ctxt, expr, isRewritten, object, url, lineNumber, columnNumber); -} - -/*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, - QObject *object, const QByteArray &expr, - bool isRewritten, - const QString &url, int lineNumber, int columnNumber, - QDeclarativeExpressionPrivate &dd) -: QObject(dd, 0) -{ - Q_D(QDeclarativeExpression); - d->init(ctxt, expr, isRewritten, object, url, lineNumber, columnNumber); -} - -/*! - Create a QDeclarativeExpression object that is a child of \a parent. - - The \script provides the expression to be evaluated, the context to evaluate it in, - and the scope object to evaluate it with. - - This constructor is functionally equivalent to the following, but in most cases - is more efficient. - \code - QDeclarativeExpression expression(script.context(), script.scopeObject(), script.script(), parent); - \endcode - - \sa QDeclarativeScriptString -*/ -QDeclarativeExpression::QDeclarativeExpression(const QDeclarativeScriptString &script, QObject *parent) -: QObject(*new QDeclarativeExpressionPrivate, parent) -{ - Q_D(QDeclarativeExpression); - bool defaultConstruction = false; - - int id = script.d.data()->bindingId; - if (id < 0) { - defaultConstruction = true; - } else { - QDeclarativeContextData *ctxtdata = QDeclarativeContextData::get(script.context()); - - QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(script.context()->engine()); - QDeclarativeCompiledData *cdata = 0; - QDeclarativeTypeData *typeData = 0; - if (engine && ctxtdata && !ctxtdata->url.isEmpty()) { - typeData = engine->typeLoader.get(ctxtdata->url); - cdata = typeData->compiledData(); - } - - if (cdata) - d->init(ctxtdata, cdata->primitives.at(id), true, script.scopeObject(), - cdata->name, script.d.data()->lineNumber, script.d.data()->columnNumber); - else - defaultConstruction = true; - - if (cdata) - cdata->release(); - if (typeData) - typeData->release(); - } - - if (defaultConstruction) - d->init(QDeclarativeContextData::get(script.context()), script.script(), script.scopeObject()); -} - -/*! - Create a QDeclarativeExpression object that is a child of \a parent. - - The \a expression JavaScript will be executed in the \a ctxt QDeclarativeContext. - If specified, the \a scope object's properties will also be in scope during - the expression's execution. -*/ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, - QObject *scope, - const QString &expression, - QObject *parent) -: QObject(*new QDeclarativeExpressionPrivate, parent) -{ - Q_D(QDeclarativeExpression); - d->init(QDeclarativeContextData::get(ctxt), expression, scope); -} - -/*! - \internal -*/ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope, - const QString &expression) -: QObject(*new QDeclarativeExpressionPrivate, 0) -{ - Q_D(QDeclarativeExpression); - d->init(ctxt, expression, scope); -} - -/*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope, - const QString &expression, QDeclarativeExpressionPrivate &dd) -: QObject(dd, 0) -{ - Q_D(QDeclarativeExpression); - d->init(ctxt, expression, scope); -} - -/*! - \internal - - To avoid exposing v8 in the public API, functionPtr must be a pointer to a v8::Handle<v8::Function>. - For example: - v8::Handle<v8::Function> function; - new QDeclarativeExpression(ctxt, scope, &function, ...); - */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope, void *functionPtr, - QDeclarativeExpressionPrivate &dd) -: QObject(dd, 0) -{ - v8::Handle<v8::Function> function = *(v8::Handle<v8::Function> *)functionPtr; - - Q_D(QDeclarativeExpression); - d->init(ctxt, function, scope); -} - -/*! - Destroy the QDeclarativeExpression instance. -*/ -QDeclarativeExpression::~QDeclarativeExpression() -{ -} - -/*! - Returns the QDeclarativeEngine this expression is associated with, or 0 if there - is no association or the QDeclarativeEngine has been destroyed. -*/ -QDeclarativeEngine *QDeclarativeExpression::engine() const -{ - Q_D(const QDeclarativeExpression); - return d->context()?d->context()->engine:0; -} - -/*! - Returns the QDeclarativeContext this expression is associated with, or 0 if there - is no association or the QDeclarativeContext has been destroyed. -*/ -QDeclarativeContext *QDeclarativeExpression::context() const -{ - Q_D(const QDeclarativeExpression); - QDeclarativeContextData *data = d->context(); - return data?data->asQDeclarativeContext():0; -} - -/*! - Returns the expression string. -*/ -QString QDeclarativeExpression::expression() const -{ - Q_D(const QDeclarativeExpression); - if (d->extractExpressionFromFunction && context()->engine()) { - QV8Engine *v8engine = QDeclarativeEnginePrivate::getV8Engine(context()->engine()); - v8::HandleScope handle_scope; - v8::Context::Scope scope(v8engine->context()); - - return v8engine->toString(v8::Handle<v8::Value>(d->v8function)); - } else if (!d->expressionUtf8.isEmpty()) { - return QString::fromUtf8(d->expressionUtf8); - } else { - return d->expression; - } -} - -/*! - Set the expression to \a expression. -*/ -void QDeclarativeExpression::setExpression(const QString &expression) -{ - Q_D(QDeclarativeExpression); - - d->resetNotifyOnValueChanged(); - d->expression = expression; - d->expressionUtf8.clear(); - d->expressionFunctionValid = false; - d->expressionFunctionRewritten = false; - qPersistentDispose(d->v8function); - qPersistentDispose(d->v8qmlscope); -} - -void QDeclarativeExpressionPrivate::exceptionToError(v8::Handle<v8::Message> message, - QDeclarativeError &error) -{ - Q_ASSERT(!message.IsEmpty()); - - v8::Handle<v8::Value> name = message->GetScriptResourceName(); - v8::Handle<v8::String> description = message->Get(); - int lineNumber = message->GetLineNumber(); - - v8::Local<v8::String> file = name->IsString()?name->ToString():v8::Local<v8::String>(); - if (file.IsEmpty() || file->Length() == 0) - error.setUrl(QUrl(QLatin1String("<Unknown File>"))); - else - error.setUrl(QUrl(QV8Engine::toStringStatic(file))); - - error.setLine(lineNumber); - error.setColumn(-1); - - QString qDescription = QV8Engine::toStringStatic(description); - if (qDescription.startsWith(QLatin1String("Uncaught "))) - qDescription = qDescription.mid(9 /* strlen("Uncaught ") */); - - error.setDescription(qDescription); -} - -void QDeclarativeJavaScriptExpression::setNotifyOnValueChanged(bool v) -{ - activeGuards.setFlagValue(v); - if (!v) clearGuards(); -} - -void QDeclarativeJavaScriptExpression::resetNotifyOnValueChanged() -{ - clearGuards(); -} - -v8::Local<v8::Value> -QDeclarativeJavaScriptExpression::evaluate(QDeclarativeContextData *context, - v8::Handle<v8::Function> function, bool *isUndefined) -{ - Q_ASSERT(context && context->engine); - - if (function.IsEmpty() || function->IsUndefined()) { - if (isUndefined) *isUndefined = true; - return v8::Local<v8::Value>(); - } - - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); - - Q_ASSERT(notifyOnValueChanged() || activeGuards.isEmpty()); - GuardCapture capture(context->engine, this); - - QDeclarativeEnginePrivate::PropertyCapture *lastPropertyCapture = ep->propertyCapture; - ep->propertyCapture = notifyOnValueChanged()?&capture:0; - - - if (notifyOnValueChanged()) - capture.guards.copyAndClearPrepend(activeGuards); - - QDeclarativeContextData *lastSharedContext = 0; - QObject *lastSharedScope = 0; - - bool sharedContext = useSharedContext(); - - // All code that follows must check with watcher before it accesses data members - // incase we have been deleted. - DeleteWatcher watcher(this); - - if (sharedContext) { - lastSharedContext = ep->sharedContext; - lastSharedScope = ep->sharedScope; - ep->sharedContext = context; - ep->sharedScope = scopeObject(); - } - - v8::Local<v8::Value> result; - { - v8::TryCatch try_catch; - v8::Handle<v8::Object> This = ep->v8engine()->global(); - if (scopeObject() && requiresThisObject()) { - v8::Handle<v8::Value> value = ep->v8engine()->newQObject(scopeObject()); - if (value->IsObject()) This = v8::Handle<v8::Object>::Cast(value); - } - - result = function->Call(This, 0, 0); - - if (isUndefined) - *isUndefined = try_catch.HasCaught() || result->IsUndefined(); - - if (watcher.wasDeleted()) { - } else if (try_catch.HasCaught()) { - v8::Context::Scope scope(ep->v8engine()->context()); - v8::Local<v8::Message> message = try_catch.Message(); - if (!message.IsEmpty()) { - QDeclarativeExpressionPrivate::exceptionToError(message, delayedError()->error); - } else { - if (hasDelayedError()) delayedError()->error = QDeclarativeError(); - } - } else { - if (hasDelayedError()) delayedError()->error = QDeclarativeError(); - } - } - - if (sharedContext) { - ep->sharedContext = lastSharedContext; - ep->sharedScope = lastSharedScope; - } - - if (capture.errorString) { - for (int ii = 0; ii < capture.errorString->count(); ++ii) - qWarning("%s", qPrintable(capture.errorString->at(ii))); - delete capture.errorString; - capture.errorString = 0; - } - - while (Guard *g = capture.guards.takeFirst()) - g->Delete(); - - ep->propertyCapture = lastPropertyCapture; - - return result; -} - -void QDeclarativeJavaScriptExpression::GuardCapture::captureProperty(QDeclarativeNotifier *n) -{ - if (expression) { - - // Try and find a matching guard - while (!guards.isEmpty() && !guards.first()->isConnected(n)) - guards.takeFirst()->Delete(); - - Guard *g = 0; - if (!guards.isEmpty()) { - g = guards.takeFirst(); - g->cancelNotify(); - Q_ASSERT(g->isConnected(n)); - } else { - g = Guard::New(expression, engine); - g->connect(n); - } - - expression->activeGuards.prepend(g); - } -} - -void QDeclarativeJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c, int n) -{ - if (expression) { - if (n == -1) { - if (!errorString) { - errorString = new QStringList; - QString preamble = QLatin1String("QDeclarativeExpression: Expression ") + - expression->m_vtable->expressionIdentifier(expression) + - QLatin1String(" depends on non-NOTIFYable properties:"); - errorString->append(preamble); - } - - const QMetaObject *metaObj = o->metaObject(); - QMetaProperty metaProp = metaObj->property(c); - - QString error = QLatin1String(" ") + - QString::fromUtf8(metaObj->className()) + - QLatin1String("::") + - QString::fromUtf8(metaProp.name()); - errorString->append(error); - } else { - - // Try and find a matching guard - while (!guards.isEmpty() && !guards.first()->isConnected(o, n)) - guards.takeFirst()->Delete(); - - Guard *g = 0; - if (!guards.isEmpty()) { - g = guards.takeFirst(); - g->cancelNotify(); - Q_ASSERT(g->isConnected(o, n)); - } else { - g = Guard::New(expression, engine); - g->connect(o, n); - } - - expression->activeGuards.prepend(g); - } - } -} - -void QDeclarativeJavaScriptExpression::clearError() -{ - if (m_vtable.hasValue()) { - m_vtable.value().error = QDeclarativeError(); - m_vtable.value().removeError(); - } -} - -QDeclarativeError QDeclarativeJavaScriptExpression::error() const -{ - if (m_vtable.hasValue()) return m_vtable.constValue()->error; - else return QDeclarativeError(); -} - -QDeclarativeDelayedError *QDeclarativeJavaScriptExpression::delayedError() -{ - return &m_vtable.value(); -} - -void QDeclarativeJavaScriptExpression::clearGuards() -{ - while (Guard *g = activeGuards.takeFirst()) - g->Delete(); -} - -// Must be called with a valid handle scope -v8::Local<v8::Value> QDeclarativeExpressionPrivate::v8value(QObject *secondaryScope, bool *isUndefined) -{ - if (!expressionFunctionValid) { - bool ok = true; - - QDeclarativeRewrite::RewriteBinding rewriteBinding; - rewriteBinding.setName(name); - QString code; - if (expressionFunctionRewritten) - code = expression; - else - code = rewriteBinding(expression, &ok); - - if (ok) v8function = evalFunction(context(), scopeObject(), code, url, line, &v8qmlscope); - setUseSharedContext(false); - expressionFunctionValid = true; - } - - - if (secondaryScope) { - v8::Local<v8::Value> result; - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context()->engine); - QObject *restoreSecondaryScope = 0; - restoreSecondaryScope = ep->v8engine()->contextWrapper()->setSecondaryScope(v8qmlscope, secondaryScope); - result = evaluate(context(), v8function, isUndefined); - ep->v8engine()->contextWrapper()->setSecondaryScope(v8qmlscope, restoreSecondaryScope); - return result; - } else { - return evaluate(context(), v8function, isUndefined); - } -} - -QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) -{ - Q_Q(QDeclarativeExpression); - - if (!context() || !context()->isValid()) { - qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context"); - return QVariant(); - } - - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine()); - QVariant rv; - - ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. - - { - v8::HandleScope handle_scope; - v8::Context::Scope context_scope(ep->v8engine()->context()); - v8::Local<v8::Value> result = v8value(secondaryScope, isUndefined); - rv = ep->v8engine()->toVariant(result, qMetaTypeId<QList<QObject*> >()); - } - - ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. - - return rv; -} - -/*! - Evaulates the expression, returning the result of the evaluation, - or an invalid QVariant if the expression is invalid or has an error. - - \a valueIsUndefined is set to true if the expression resulted in an - undefined value. - - \sa hasError(), error() -*/ -QVariant QDeclarativeExpression::evaluate(bool *valueIsUndefined) -{ - Q_D(QDeclarativeExpression); - return d->value(0, valueIsUndefined); -} - -/*! -Returns true if the valueChanged() signal is emitted when the expression's evaluated -value changes. -*/ -bool QDeclarativeExpression::notifyOnValueChanged() const -{ - Q_D(const QDeclarativeExpression); - return d->notifyOnValueChanged(); -} - -/*! - Sets whether the valueChanged() signal is emitted when the - expression's evaluated value changes. - - If \a notifyOnChange is true, the QDeclarativeExpression will - monitor properties involved in the expression's evaluation, and emit - QDeclarativeExpression::valueChanged() if they have changed. This - allows an application to ensure that any value associated with the - result of the expression remains up to date. - - If \a notifyOnChange is false (default), the QDeclarativeExpression - will not montitor properties involved in the expression's - evaluation, and QDeclarativeExpression::valueChanged() will never be - emitted. This is more efficient if an application wants a "one off" - evaluation of the expression. -*/ -void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange) -{ - Q_D(QDeclarativeExpression); - d->setNotifyOnValueChanged(notifyOnChange); -} - -/*! - Returns the source file URL for this expression. The source location must - have been previously set by calling setSourceLocation(). -*/ -QString QDeclarativeExpression::sourceFile() const -{ - Q_D(const QDeclarativeExpression); - return d->url; -} - -/*! - Returns the source file line number for this expression. The source location - must have been previously set by calling setSourceLocation(). -*/ -int QDeclarativeExpression::lineNumber() const -{ - Q_D(const QDeclarativeExpression); - return d->line; -} - -/*! - Returns the source file column number for this expression. The source location - must have been previously set by calling setSourceLocation(). -*/ -int QDeclarativeExpression::columnNumber() const -{ - Q_D(const QDeclarativeExpression); - return d->column; -} - -/*! - Set the location of this expression to \a line of \a url. This information - is used by the script engine. -*/ -void QDeclarativeExpression::setSourceLocation(const QString &url, int line, int column) -{ - Q_D(QDeclarativeExpression); - d->url = url; - d->line = line; - d->column = column; -} - -/*! - Returns the expression's scope object, if provided, otherwise 0. - - In addition to data provided by the expression's QDeclarativeContext, the scope - object's properties are also in scope during the expression's evaluation. -*/ -QObject *QDeclarativeExpression::scopeObject() const -{ - Q_D(const QDeclarativeExpression); - return d->scopeObject(); -} - -/*! - Returns true if the last call to evaluate() resulted in an error, - otherwise false. - - \sa error(), clearError() -*/ -bool QDeclarativeExpression::hasError() const -{ - Q_D(const QDeclarativeExpression); - return d->hasError(); -} - -/*! - Clear any expression errors. Calls to hasError() following this will - return false. - - \sa hasError(), error() -*/ -void QDeclarativeExpression::clearError() -{ - Q_D(QDeclarativeExpression); - d->clearError(); -} - -/*! - Return any error from the last call to evaluate(). If there was no error, - this returns an invalid QDeclarativeError instance. - - \sa hasError(), clearError() -*/ - -QDeclarativeError QDeclarativeExpression::error() const -{ - Q_D(const QDeclarativeExpression); - return d->error(); -} - -/*! - \fn void QDeclarativeExpression::valueChanged() - - Emitted each time the expression value changes from the last time it was - evaluated. The expression must have been evaluated at least once (by - calling QDeclarativeExpression::evaluate()) before this signal will be emitted. -*/ - -void QDeclarativeExpressionPrivate::expressionChanged(QDeclarativeJavaScriptExpression *e) -{ - QDeclarativeExpressionPrivate *This = static_cast<QDeclarativeExpressionPrivate *>(e); - This->expressionChanged(); -} - -void QDeclarativeExpressionPrivate::expressionChanged() -{ - Q_Q(QDeclarativeExpression); - emit q->valueChanged(); -} - -QString QDeclarativeExpressionPrivate::expressionIdentifier(QDeclarativeJavaScriptExpression *e) -{ - QDeclarativeExpressionPrivate *This = static_cast<QDeclarativeExpressionPrivate *>(e); - return QLatin1String("\"") + This->expression + QLatin1String("\""); -} - -QDeclarativeAbstractExpression::QDeclarativeAbstractExpression() -: m_prevExpression(0), m_nextExpression(0) -{ -} - -QDeclarativeAbstractExpression::~QDeclarativeAbstractExpression() -{ - if (m_prevExpression) { - *m_prevExpression = m_nextExpression; - if (m_nextExpression) - m_nextExpression->m_prevExpression = m_prevExpression; - } - - if (m_context.isT2()) - m_context.asT2()->_s = 0; -} - -QDeclarativeContextData *QDeclarativeAbstractExpression::context() const -{ - if (m_context.isT1()) return m_context.asT1(); - else return m_context.asT2()->_c; -} - -void QDeclarativeAbstractExpression::setContext(QDeclarativeContextData *context) -{ - if (m_prevExpression) { - *m_prevExpression = m_nextExpression; - if (m_nextExpression) - m_nextExpression->m_prevExpression = m_prevExpression; - m_prevExpression = 0; - m_nextExpression = 0; - } - - if (m_context.isT1()) m_context = context; - else m_context.asT2()->_c = context; - - if (context) { - m_nextExpression = context->expressions; - if (m_nextExpression) - m_nextExpression->m_prevExpression = &m_nextExpression; - m_prevExpression = &context->expressions; - context->expressions = this; - } -} - -void QDeclarativeAbstractExpression::refresh() -{ -} - -bool QDeclarativeAbstractExpression::isValid() const -{ - return context() != 0; -} - -QT_END_NAMESPACE - -#include <moc_qdeclarativeexpression.cpp> |